17. Event Listeners
Event Listeners are sometimes referred to as “Event Handlers”, “Event Hooks” or
“Event Callbacks”, but we will be using the term “Event Listener” because that is how
the EventListener class is named inside sublime_plugin.py.
Event Listeners allow you to react to events, such as:
files being created, loaded, saved or closed;
the content of files being modified;
the selection changing (e.g. cursor movement);
the focused View changing;
Commands that are about to be executed;
Commands that have just finished executing;
reloads of files that changed on disk;
reverting to a buffer content to discard changes
tabs moving between windows
windows being created and closed
projects being opened and closed.
17.1. Creating an Event Listener
You create an Event Listener by creating a class that inherits from one of the 3
sublime_plugin....Listener classes below. Unlike Command- and Input Handler
Classes, the class names of Event Listener classes do not matter, though a class-name
suffix is recommended for code readability. (The reason the name is unimportant is
that a Plugin cannot invoke an Event Handler directly, except by doing
something that raises the event.)
The class’ methods are the events that get called when those events occur. The list of events is predefined. The method name matches the event name. You can include any event methods you want or need. Sublime Text will only invoke the pre-defined event methods.
See the doc-string for these sublime_plugin classes to see all the events that are
available, with their documentation.
- EventListener:
Global Event Listener, one Event Listener object is created that can receive all events.
- ViewEventListener:
One Event Listener is created for each View to which that Listener applies (governed by
is_applicable(cls, settings)method).- TextChangeListener:
One Event Listener is created for each Buffer to which that Listener applies (governed by
is_applicable(cls, settings)method). (New since Build 4081.)
17.2. Example
import sublime
import sublime_plugin
class SampleEventListener(sublime_plugin.EventListener):
"""
Sublime |nbsp| Text will only ever create ONE of these.
You must manually filter events.
All possible events can trigger.
"""
def on_new(self, view):
print('on_new() event fired.')
#view.assign_syntax('Packages/Python/Python.sublime-syntax')
pass
# Normally don't do this -- event fires for every keystroke for all Views.
# def on_modified(self, view):
# if view.match_selector(0, 'source.python'):
# print('A python file has been modified.')
class MyPythonEventListener(sublime_plugin.ViewEventListener):
"""
Sublime |nbsp| Text will create one of these for each View for which
`is_applicable()` returns True.
Event filtering is more automatic.
Gives "free" access to per-listener storage space.
Only View-related events can trigger.
"""
# This decorator allows this method to be called without instantiating the class.
# This method is called every time:
# - settings changes,
# - a View gets focus.
@classmethod
def is_applicable(cls, settings):
print('MyPythonEventListener.is_applicable() fired.')
return 'Python.sublime-syntax' in settings.get('syntax')
def on_close(self):
print('on_close() View event fired.')
filename = self.view.file_name() or 'unsaved file'
print(f'View [{filename}] is being closed.')
# This is more efficient than the on_modified() above, since the event
# will only fire on Views for which `is_applicable()` returned True!
def on_modified(self):
print('A python file has been modified.')
17.3. Notes on on_query_context()
on_query_context() ties directly into Key Bindings (as opposed to Commands), and
they provide the ability to tell Sublime Text under what situations they are relevant
so that it knows that they should be applied, or skipped over in favor of another one.
on_query_context() can “sort of” be implemented by having an is_enabled() be
implemented for a Command. However, there is an important nuance about
on_query_context() that are important to consider: specifically that any key can
be bound to multiple different Commands (or the same Command with multiple different
arguments), each one with a different set of contextual rules that tell Sublime Text
in what specific situation each one applies. Contexts allow Sublime Text to select
from multiple Key Bindings the one that applies the best based on the current state
of things.
If only a Command’s is_enabled() is used, Sublime Text will NOT select an
alternate key binding either. Using on_query_context(), you can guide
Sublime Text to choose the correct binding for the current situation.
See Key Bindings Documentation in the official documentation for more details.