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, and

  • Default ($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

  1. Bindings from the Default package are always loaded first (from compressed file <install_path>/Packages/Default.sublime-package) in

  2. Bindings from all other shipped Packages are loaded next in alphabetical order by Package name (from compressed .sublime-package files) in

  3. Bindings from all other Packages are loaded in alphabetical order by Package name (from compressed .sublime-package files in

  4. Bindings from loose-file Packages are loaded in alphabetical order by Package name in

  5. 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 True of False. 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:

True or False if the plugin handles this context key and it either does or doesn’t match. If the context is unknown, return None.

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.