Skip to content

Expressions

You can use expressions in a number of places inside a bind definition. An expression is a snippet of code surrounded by double curly braces {{like + this}} that occurs within a TOML string.

When the string is comprised entirely of a single expression, it can evaluate to any valid TOML object.

Example

toml
[[define.val]]
action_priority = 3

[[bind]]
# ...other fields here...
priority = "{{val.action_priority + 2}}"

# after expression evaluation, the above would evaluate to
priority = 5

If there is additional text in the string that falls outside of the expression, the expression is interpolated into the string

toml
[[define.val]]
action_priority = 3

[[bind]]
# ...other fields here...
name = "My cool action (priority {{val.action_priority + 2}})"

# after expression evaluation, the above would evaluate to
name = "My cool action (priority 5)"

Valid expressions are a simple derivative of Rhai. The constraints are:

  1. You can only evaluate expressions not statements
  2. You cannot set variables
  3. You cannot use loops
  4. You cannot define named functions

If you find yourself wanting to write more than a few relatively simple lines, your goal is probably better accomplished by writing an extension and running the extension-defined command.

There are two points at which an expression can be evaluated: while parsing the master keybinding file (e.g. making use of foreach) or at runtime: when the user presses a key.

Read-time Evaluation

Read-time expressions are computed directly after a keybinding file has been loaded. The following values are in scope:

  • Any field defined in a [[define.val]] section. These variables are all stored under the top-level val. object.
  • Variables defined by foreach
  • keys([regex]): returns all valid keys (as per key in keybindings.json) matching the regular expression
  • all_modes(): returns an array of strings of all keybinding modes defined by the current keybinding set. It does not include the automatically defined mode "capture". It is rarely advised to define bindings for this mode. The "capture" is used to capture keys typed during master-key.search and master-key.captureKeys. Defining bindings for a key will prevent it from being captured by these commands.
  • not_modes([exclusions]): given an array of strings of excluded modes, returns all keybinding modes defined by the current keybinding set that are not among these exclusions. Like all_modes the mode "capture" is not included.

Run-time Evaluation

Fields for which expressions are evaluated at run time are clearly denoted as such with a ⚡ symbol. They are computed after a user presses the given keybinding. When there are multiple commands run for a keybinding (via runCommands) the expressions for a given command are evaluated after all previous commands have executed.

Run-time expressions have access to the following values:

  • any value available at read-time (see above)
  • code.editorHasSelection: true if there is any selection, false otherwise
  • code.editorHasMultipleSelections: true if there are multiple selections, false otherwise
  • code.firstSelectionOrWord: the first selection, or the word under the first cursor if the selection is empty
  • code.editorLangId: the language id of the current editor or the empty string if there is no current editor (or no language id for that editor)
  • key.mode: the current keybinding mode
  • key.count: The current count, as defined by master-key.updateCount
  • key.captured: The text currently captured by the most recent call to master-key.captureKeys.
  • key.prefix: The currently active keybinding prefix
  • key.record: a boolean flag used to indicate when keys are marked for recording
  • history: a queue containing a record of all previously run master key commands, up to the number configured by Master Key's "Command History Maximum" (defaults to 1024). See master-key.replayFromHistory for details.

Debugging

You can use the function show to print out a message in VSCode's output pane. It accepts two arguments: a string to print and a value. The value is printed after the string and it is also returned as the result of show. This allows you to insert show wherever you want within an expression.

toml
[[bind]]
key = "j"
mode = "normal"
command = "cursorMove"
args.to = "right"
args.value = '{{show("count: ", 1+2)}}'

This would print the string "count: 3" to the output pane whenever the user presses the j key in normal mode.