Sublime Forum

output_panel on construct of EventListener

#1

I’m trying to show a output_panel in the construct of the EventListener, I need to show a feedback to the user when the plugin is installing some dependencies (not a package) and the init construct seems to be the better place because it runs only once.

I’m doing something like this:

class PluginListener(sublime_plugin.EventListener):
    def __init__(self):
		name = "PluginName"
        panel_name = 'output.' + name

        panel = sublime.create_output_panel(name)
        panel.set_name(name)

        sublime.run_command("show_panel", {"panel": panel_name})
        panel.set_read_only(False)
        panel.run_command("append", {"characters": "Some Text"})
        panel.set_read_only(True)

I’ve also tried creating an active windows first with sublime.active window() but it doesn’t work either.

How should I do this?

0 Likes

#2

I’ve realized that is better to use the on_load event, it runs once too and it avoid the conflicts

I keep with the doubt, on_load runs when a file is loaded I need to run a event when the plugin ins loaded

0 Likes

#3

create_output_panel is method of Window, not sublime.

import sublime, sublime_plugin

class ExampleCommand(sublime_plugin.EventListener):
  def __init__(self):
    win = sublime.active_window()
    pan = win.create_output_panel('my_panel')
    pan.run_command("append", {"characters": "Hello World"})
    win.run_command('show_panel', {'panel':'output.my_panel'})
0 Likes

#4

Thanks @alkuzad I’ve tried that too (I mentioned in the first post)

I’ve copied your code and is the same result, it doesn’t display anything

0 Likes

#5

There are multiple problems with your code. You didn’t say what version of Sublime you are using, so I’ll assume you are using 3.

First, I get the impression you are trying to install your dependencies when the plugin loads, is that correct? If so, doing it in __init__ is a bad idea. The communication between the plugin_host and sublime may not yet be established. You should restrict all such behavior to a global function called plugin_loaded().

Second, as mentioned, create_output_panel is a window method. Also, the name that you use should not start with output., that is only necessary for the show_panel command.

def plugin_loaded():
    w = sublime.active_window()
    panel = w.create_output_panel('my_panel')
    panel.run_command('append', {'characters': 'test text'})
    w.run_command("show_panel", {"panel": 'output.my_panel'})

Also, beware that if your dependency installation takes time, then code running in plugin_loaded will cause Sublime to hang. If so, it should probably run in a background thread.

3 Likes

#6

Thanks @sapphirehamster

I’m using ST3 (3103) as you suppose.

The name with .output was only used in the show_panel command look above, there are two variables.

I’ve tested the code and it’s what I was looking for, however I’ve other doubt, I thought It will work, but I’m having problem running the panel calling it from a module.

I’m doing this:

main.py

from . import otherfile

def plugin_loaded():
    window = sublime.active_window()
    otherfile.namefunction(window)

and in the otherfile.py this:

def namefunction(window):
    panel = window.create_output_panel('my_panel')
    panel.run_command('append', {'characters': 'test text'})
    window.run_command("show_panel", {"panel": 'output.my_panel'})

the problem is that panel is never showing. l’ve also tried creating a command in the main.py and calling it from the otherfile.py with run_command but isn’t either working

how can I solve this?

0 Likes

#7

Sublime 3 automatically creates a Python package with the name of your plugin, and all imports should be relative to that. Either:

import MyPlugin.otherfile

or

from . import otherfile

There should have been an import error somewhere in the console.

0 Likes

#8

I’m sorry my mistake, I’m doing from . import otherfile

I know it’s not an import error because when I put a print("executing") in the otherfile.py file it’s displayed in the console

A wierd thing is when I’ve the main.py file open and I press ctrl + s the panel is displayed, however if I close ST and I open it, nothing again

0 Likes

#9

Hm, I’m not sure, that code works for me even when restarting Sublime.

0 Likes

#10

Thanks @sapphirehamster my problem was I had a typo in def plugin_loaded(): I created a clean plugin and I realized that. I’m testing the same code in ST2 but it seems not working, there are something equivalent for plugin_loaded?

0 Likes

#11

plugin_loaded does not exist in ST2. You can just call it manually there on module load however, because ST waits until the API is available before plugins are loaded there (which is also why it’s slower). Just add this at the bottom of your file:

if int(sublime.version()) < 3000:
    plugin_loaded()
0 Likes

#12

So if call the function with:

if(__name__ == 'plugin_name'):
    function_name()

it will work, but the api won’t be available right?

0 Likes

#13

Not sure what you would want to accomplish with it.

0 Likes

#14

Never mind, your snippet works. But I’m back to the problem I was having with ST3.

ST2 doesn’t load sublime.active_window() properly, if I print the result of type(sublime.active_window()) it returns NoneType. But works when I press ctrl + s in the main file of the plugin

def plugin_loaded():
    window = sublime.active_window()
    print(type(window))

if int(sublime.version()) < 3000:
    plugin_loaded()

do you know what it can be?

0 Likes

#15

Not really. The active_window APi is incosistent at times any may return None. In ST2 even moreso than in ST3.

I suggest either spawning a thread or better yet using sublime.set_timeout (threading is not as well supported in ST2) to asynchronously wait until the active window is available. If you only target ST3 (which I recommend since ST2 is pretty much dead), you can stick to using a thread.

0 Likes

#16

Thanks sublime.set_timeout with 300ms was the solution. I’ll think about let to support ST2, more now seeing that ST3 is receiving updates and ST2 becomes more older.

0 Likes