Sublime Forum

Output Panel not printing out gradually

#1

Dear all,

I’m evaluating ST2 by developing a plugin. I periodically need to update an output panel, unfortunately I cannot get this to work properly.

import sublime, sublime_plugin, time

# start new test
class TestPanelCommand(sublime_plugin.TextCommand):
	def run(self, edit):
		panel = self.view.window().get_output_panel('test_panel')
		for i in range(0, 3):
			panel_edit = panel.begin_edit()
			panel.insert(panel_edit, panel.size(), 'hello\n')
			panel.end_edit(panel_edit)
			panel.show(panel.size())
			self.view.window().run_command("show_panel", {"panel": "output.test_panel"})
			time.sleep(3)

I save this code to test.py which I put in the Packages/Default directory, then run it with view.run_command(‘test_panel’).

I would have expected the output panel to show ‘hello’, then wait 3 seconds, then print another ‘hello’, and again. Unfortunately, the output panel just comes out and prints the 3 ‘hello’ at the same time, after 9 seconds.

Is there a way to flush to the output panel, or refresh it? Do you happen to know what I am doing wrong?

Thank you,

r.

0 Likes

#2

You’re blocking the main thread and thus the rendering. If you do something that takes time, you need to start a separate thread. Beware that any operations done on sublime objects needs to be in the main thread. This can be accomplished by the sublime.set_timeout function.

So in the end you get something like this (untested and written by heart, so might have to be tweaked):

[code]import threading
import time
import sublime
import sublime_plugin

class TestPanelCommand(sublime_plugin.TextCommand):
def add_text(self, text):
self.text_to_add += text
sublime.set_timeout(self.update, 0)

def this_command_takes_time(self):
    for i in range(0, 3):
        self.add_text("hello\n")
        time.sleep(3)

def run(self, edit):
    self.panel = self.view.window().get_output_panel('test_panel')
    t = threading.Thread(target=self.this_command_takes_time)
    t.start()

def update(self):
    if len(self.text_to_add):
        panel_edit = self.panel.begin_edit()
        self.panel.insert(panel_edit, self.panel.size(), self.text_to_add())
        self.panel.end_edit(panel_edit)
        self.panel.show(self.panel.size())
        self.text_to_add = ""
        self.view.window().run_command("show_panel", {"panel": "output.est_panel"})

[/code]

0 Likes

#3

tweaked and tested it looks like this.

import threading
import time
import sublime
import sublime_plugin

class TestPanelCommand(sublime_plugin.TextCommand):
    def add_text(self, text):
        self.text_to_add += text
        sublime.set_timeout(self.update, 0)

    def this_command_takes_time(self):
        for i in range(0, 3):
            self.add_text("hello\n")
            time.sleep(3)

    def run(self, edit):
    	self.text_to_add = ''
        self.panel = self.view.window().get_output_panel('test_panel')
        t = threading.Thread(target=self.this_command_takes_time)
        t.start()

    def update(self):
        if len(self.text_to_add):
            panel_edit = self.panel.begin_edit()
            self.panel.insert(panel_edit, self.panel.size(), self.text_to_add)
            self.panel.end_edit(panel_edit)
            self.panel.show(self.panel.size())
            self.text_to_add = ""
            self.view.window().run_command("show_panel", {"panel": "output.test_panel"})

thank you :smile:

r.

0 Likes