psprint
psprint

Reputation: 359

Key bindings local to a view in Sublime Text 3

Is it possible to configure a key binding that's active only in a given view? From a plugin? It should be inactive in all other views except the selected one.

Upvotes: 2

Views: 115

Answers (1)

OdatNurd
OdatNurd

Reputation: 22791

This is possible via a context in a key binding that makes the binding active only in very specific situations, and depending on your needs you don't even need a special plugin to do so (though it sounds like for your case you do).

As a brief overview, key bindings can optionally contain 1 or more contexts that determine if the binding should be active or not. If multiple contexts are applied to the same key, then all of them must be satisfied before the binding is made active. It's possible to have the same key sequence bound to multiple commands (or variations on the same command) so long as they have context that disambiguates them.

If there are multiple keys bound to the same key, they're considered in order (starting at the last defined binding and moving upward) until one with a context that applies it seen, or one with no context is seen. Hence, ordering of bindings can be important; put the most specific ones later in the file and the least specific sooner.

For example, given this key binding:

    { "keys": ["ctrl+shift+h"],
      "command": "echo",
      "args": {"msg": "Key binding triggered"},
      "context": [
          { "key": "setting._my_setting", "operator": "equal", "operand": true },
      ],
    },

This binding is only active in places where the setting _my_setting has a boolean value of true; if the value is false or the setting is not set, the binding is not active.

So initially, the binding will not be active, and pressing that key will trigger whatever other command happens to be bound to this key sequence.

However, if you were to open the console and run:

view.settings().set("_my_setting", True)

Now the binding is active in whatever file was focused when you did it, but disabled everywhere else.

There's nothing magic about the name of the setting or how it interacts except that this context (which is built into Sublime) can only be used for Boolean settings. So in particular it follows the hierarchy of settings and you can add the setting in one or more the following places:

  • Preferences.sublime-settings to make the binding active/inactive everywhere
  • Project specific setting to make the binding active/inactive in files contained in a particular window
  • Syntax specific settings to make the binding active/inactive in files of a specific type
  • In the view settings (as in the example above in a plugin) to make the binding active/inactive in specific views.

Items further down the list override items sooner (so view settings trump everything, syntax settings trump project and defaults, etc).

For more fine grained control or to use other settings than just boolean ones, you need to implement an EventListener or ViewEventListener in a plugin and handle the on_query_context event, which allows you to create a custom context for use in bindings.

More information on that is available in the API documentation; you can also check out this video on defining custom contexts as well (disclaimer: I'm the author of the video)

Upvotes: 2

Related Questions