8. Key Bindings
A Key Binding connects a key combination with the action (Command)
it performs. Key bindings in Sublime Text are defined by files ending in
.sublime-keymap. Key binding files use Sublime-relaxed-JSON format, with
the top-level structure being an array of Key Binding Definition objects (a.k.a.
simply “Key Bindings”). Each Key Binding is a JSON object (dictionary in Python-ese).
A single Key Binding tells Sublime Text:
what Command to execute when it encounters that combination, and
under what circumstances (Context) that Key Binding applies.
8.1. Keymap Files
.sublime-keymap files contain a Sublime-relaxed-JSON format list
(array) of Key Binding Definitions.
Like Preferences, default Key-Binding defaults can be viewed by:
Preferences > Key Bindings
This opens a window with a pair of .sublime-keymap files shown side by side.
The left side is read-only, and editable user-overrides for those Key Bindings are on
the right side of that window. Creating individual overrides is done by copying the
default key-binding object from the left window and pasting and modifying it on the
right side.
Sublime Text recognizes only 2 keymap file-naming patterns:
Default.sublime-keymap, andDefault ($platform).sublime-keymap(used for most other packages)
where $platform is one of these ['Windows', 'OSX', 'Linux'].
Example:
Default (Windows).sublime-keymap
Default.sublime-keymap is applied on all platforms and tends to be used by
language-specific Packages. Default (<platform>).sublime-keymap is applied on
the indicated platform, and tends to be used by most other types of Packages. If
identical keymaps appear in both in the same Package, the platform-specific one
wins.
8.2. How Key Bindings are Chosen
First, Keymap files are loaded in a certain order, and a data structure is built from them internally. Keymap files loaded later are lower in the list.
For each keystroke received, Sublime Text searches the resulting data structure from bottom to top, and the Key Binding with the first matching (Context) wins.
8.2.1. Key Bindings Loading Order
Bindings from the Default package are always loaded first (from compressed file
<install_path>/Packages/Default.sublime-package) in<install_path>
/Packages/Default ($platform).sublime-keymap
Bindings from all other shipped Packages are loaded next in alphabetical order by Package name (from compressed
.sublime-packagefiles) in<install_path>
/Packages/
Bindings from all other Packages are loaded in alphabetical order by Package name (from compressed
.sublime-packagefiles in<data_path>
/Installed Packages/.
Bindings from loose-file Packages are loaded in alphabetical order by Package name in
<data_path>
/Packages/<pkg_name>.
Bindings from User Package always load last:
<data_path>
/Packages/User/Default.sublime-keymap`<data_path>
/Packages/User/Default ($platform).sublime-keymap`
Note
Wherever both of the above 2 files (Default.... and Default
($platform)....) exist in a Package, the platform-specific one wins if they
contain 2 identical key bindings that do different things. Shipped and installed
packages only ever have one of these files, but Sublime Text handles
having both in the User Package gracefully with the above caveat, likely a
side effect of the loading order.
Since Key Bindings are searched in bottom-to-top order, it is important, when implementing many Key Bindings for the same key combination, that the Key Binding with the most specific Context is lowest in the list.
A “command” that can be used to neuter a default Key Bindings is “noop” or any other command that does not exist (no errors are generated from this). That effectively blocks that key sequence from doing anything.
8.3. Key Binding Definitions
Keymap files contain a list of Key Bindings. A Key Binding is itself a dictionary with a specific format that tells Sublime Text what key combination to bind to what command, under what conditions (i.e. in what Context).
Key Bindings are JSON mapping objects (dictionaries) with this structure:
{
"keys": "<key_combination>",
"command": "<command_name>",
"args": {...} // Optional: required only if command requires it.
"context": [ // Optional: limits contexts in which binding will be applied.
{<condition>}
[, {<condition>}]...
]
}
The “args” key, if specified, depends upon the needs of the command. If you can find the Python code that defines the command (or find its documentation), you can see the arguments it expects.
If there is more than one context <condition>, they are joined by AND operator.
If an OR operator needs to be applied, add additional Key Bindings that have their own context conditions. Order the different Key Binding definitions in order from most general to most specific, because they are searched from bottom up or “last-loaded first” order.
8.3.1. <key_combination>
A <key_combination> is a single string that has the format:
[<key_modifier>+[<key_modifier>+]...]<key_name>
8.3.1.1. <key_modifier>
A key modifier can be any of the following:
Key Modifier |
Meaning if Not Obvious |
|---|---|
ctrl or control |
Ctrl key |
alt |
|
option |
Mac only key |
command |
Mac only key |
super |
Windows key on Windows and Linux, or Cmd key on Mac |
primary |
Ctrl key on Windows and Linux, or Cmd key on Mac |
8.3.1.2. <key_name>
Key names are specified either by the (non-shifted) character printed on the key, or a key name:
a n 0 , up keypad0 f1 f11
b o 1 . down keypad1 f2 f12
c p 2 \ left keypad2 f3 f13
d q 3 / right keypad3 f4 f14
e r 4 ; insert keypad4 f5 f15
f s 5 ' delete keypad5 f6 f16
g t 6 ` home keypad6 f7 f17
h u 7 + end keypad7 f8 f18
i v 8 - pageup keypad8 f9 f19
j w 9 = pagedown keypad9 f10 f20
k x [ backspace keypad_period
l y ] tab keypad_divide
m z enter keypad_multiply
pause keypad_minus
escape keypad_plus
space keypad_enter
clear
8.3.2. <command_name>
See Commands for details about how command names are derived.
8.3.3. “args” Key
When the Command whose run() method is being called takes more than the self
and edit arguments, you can package them up here in a dictionary. Each key in
the dictionary needs to be the name of one of the formal arguments of the run()
method. Example:
class ExampleFourCommand(sublime_plugin.TextCommand):
def run(self, edit, text, pos, event=None):
"""Arguments are passed as keyword arguments"""
if event:
pos = self.view.window_to_text((event['x'], event['y']))
self.view.insert(edit, pos, text)
This Text Command will need an additional 2 or 3 arguments. If you were going to use this Key Binding to call it:
{
"keys": "alt+f5",
"command": "example_four",
"args": {
"text": "Hello, World!",
"pos": 10
}
}
then, as you can see, the “args” element there would pass the text and pos
arguments to the command.
Alternately, your command can define a **kwargs parameter after edit and
receive any number of arguments in args as a dictionary.
8.3.4. Variables in Args
Here and there you may run into things like this in a keymap (this author encountered this string in a key binding at 14:59 in this YouTube video.):
{
"keys": "alt+`",
"command": "toggle_terminus_panel",
"args": {
"cwd": "${file_path:${folder}}"
}
}
This comes from a key binding related to the Terminus Package and it happened that
at 14:59 point in the video, a key binding to that Package’s toggle_terminus_panel
command was being displayed on the author’s screen.
The “appearance” is that something in Sublime Text might be looking up variables like
${file_path:${folder}} and passing their value to the command.
However, this is not the case at all. In the above, what gets passed to the command
is exactly this Python string to the Command’s cwd argument:
'${file_path:${folder}}'
The command itself would have to parse that string value and do something with them.
And apparently the toggle_terminus_panel Command from the Terminus Package
does.
8.3.5. Context
The Context part of a Key Binding object provides the condition under which that key binding will be applied. This can enable the same key combination to do different things depending on the context (where the cursor [caret/selection] is located, what text is nearby, etc. etc.). This is how Sublime Text users and Package developers make one key combination apply any of a (possibly) large number of dynamically-determined tasks.
As shown in the syntax diagram above, the optional context portion of a Key
Binding Definition is a list of <condition> objects. All contained
conditions must be true for the Key Binding to be selected.
"context": [ // Optional: limits contexts in which binding will be applied.
{<condition>}
[, {<condition>}]...
]
8.3.5.1. <condition> Syntax
{
// Condition to check
"key": "<condition>", // Required: see <condition> below
// Type of comparison
"operator": "<operator>", // Optional: Default: "equal"
// Value to test against
"operand": "<operand>", // Optional: Default: true
// When there are multiple selections (carets), this indicates whether the
// test needs to be satisfied for all of them (true), or just one (false).
"match_all": false, // Optional: Default: false
}
8.3.5.1.1. <condition> Names
Available condition names are shown in the table below.
Key:
C = commonly used (sorted to top of list for ease of finding)
Val = “operand” key
Op = “operator” key (supported operators: equ = equality; mtch = match)
MA = “match_all” key useful (applies when there is more than one selection)
Key (condition name) |
C |
Val |
Op |
MA |
Description |
|---|---|---|---|---|---|
selector |
x |
str |
equ |
yes |
Selector to match scope name of selection |
preceding_text |
x |
str |
mtch |
yes |
Text before selection |
num_selections |
x |
int |
equ |
no |
Number of selections in current buffer |
selection_empty |
x |
bool |
equ |
yes |
Is current selection empty? |
eol_selector |
x |
str |
equ |
yes |
Is caret at end of line? |
auto_complete_visible |
bool |
equ |
no |
Is auto-complete drop-down is visible? |
|
following_text |
str |
mtch |
yes |
Text after selection |
|
has_next_field |
bool |
equ |
no |
In Snippet field with subsequent fields? |
|
has_prev_field |
bool |
equ |
no |
In Snippet field with previous fields? |
|
is_javadoc |
bool |
equ |
yes |
Is caret in a comment beginning with |
|
is_recording_macro |
bool |
equ |
no |
Is user currently recording a macro? |
|
last_command |
str |
equ |
no |
Last command run |
|
last_modifying_command |
str |
equ |
no |
Last command run that modified a buffer |
|
overlay_visible |
bool |
equ |
no |
Is quick panel visible? |
|
panel |
str |
equ |
no |
Name of current panel |
|
panel_has_focus |
bool |
equ |
no |
Is panel visible and has focus? |
|
panel_visible |
bool |
equ |
no |
Is panel visible? |
|
popup_visible |
bool |
equ |
no |
Is a popup currently being displayed? |
|
read_only |
bool |
equ |
no |
Is buffer marked read-only? |
|
text |
str |
mtch |
yes |
Currently-selected text |
Note
You can create your own key-binding condition names in your own Packages
through the use of the on_query_context() event callback. See
EventListener.on_query_context(),
ViewEventListener.on_query_context(),
and
OdatNurd’s [P101-13] Defining custom contexts... video
for more details.
8.3.5.1.2. <operator> Names
8.3.5.1.2.1. Equality <operator> Names
equal (default) a fixed value (string, number or boolean [true/false])
not_equal a fixed value (string or number)
8.3.5.1.2.2. Match <operator> Names
regex_match a string (regex)
not_regex_match a string (regex)
regex_contains
not_regex_contains
8.3.5.1.3. <operand> (Value to Compare Against)
Boolean true (default)/false (in JSON these are lower case bare true and false)
string (or regex)
number
8.3.5.2. Creating Custom Conditions
You can create your own Context conditions by implementing a ViewEventListener class
with the on_query_context() method implemented.
Note: the is_applicable() method must return True for it to be applicable in a
particular View. See Event Listeners for more details about the
is_applicable() method.
Here is a copy of the portion of the sublime_plugin.ViewEventListener class’
doc-string about the on_query_context() method:
- on_query_context(key: str, operator: QueryOperator, operand: bool | str | int, match_all: bool) bool | None
Called when determining whether to trigger a key binding with the given context key. If the plugin knows how to respond to the context, it should return either
TrueofFalse. If the context is unknown, it should return None.- Parameters:
key – The context key to query. This generally refers to specific state held by a plugin.
operator – The operator to check against the operand; whether to check equality, inequality, etc.
operand – The value against which to check using the
operator.match_all – This should be used if the context relates to the selections: does every selection have to match (
match_all == True), or is at least one matching enough (match_all == False)?
- Returns:
TrueorFalseif the plugin handles this context key and it either does or doesn’t match. If the context is unknown, returnNone.
Important!
If a Command disables itself (e.g. from use in a Key Binding) by returning False
from its is_enabled() method, Sublime Text WILL NOT continue looking for
other possible Key Bindings that might apply. To make that happen, the
is_enabled() method needs to return True and the on_query_context()
method needs to be implemented to decipher if the particular context applies to this
particular Key Binding.
8.4. Diagnosing Binding Problems
When a Key Binding is not doing what you think it should be, you can turn on command logging.
View > Show Console
sublime.log_commands(True)
Now command-logging is enabled and will remain so until we re-start Sublime or call
sublime.log_commands(False)
It will not log items in the command palette.
Mouse operations will cause the “drag_select” command to be logged. You may need to turn off logging temporarily if you want to copy and paste the logged output.
sublime.log_input(True)
works similarly to command logging. This logs in the console the result of keys that you are pressing. Example:
key evt: shift+control+p
If command logging is also turned on, you will also see something like:
command: show_overlay {“overlay”: “command_palette”}
If you use the Windows (super) key, it can happen that another application or even the OS is already using that key sequence and reporting that it was handled, in which case, the key message never makes it to Sublime Text as a message from the OS.
Another thing that can happen is that the context where the Key Binding is supposed to be applied is preventing it because the context is not what we think it is (e.g. wrong file extension).
Note
The PackageDev package is very helpful when setting up Key Bindings because it
has an intuitive command-completion feature in many parts of the
.sublime-keymap files. However, at this writing it is generating exceptions
and Sublime Text appears to be disabling it as a result. See Console for details
when it is installed and enabled.