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
[[define.val]]
action_priority = 3
[[bind]]
# ...other fields here...
priority = "{{val.action_priority + 2}}"
# after expression evaluation, the above would evaluate to
priority = 5If there is additional text in the string that falls outside of the expression, the expression is interpolated into the string
[[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:
- You can only evaluate expressions not statements
- You cannot set variables
- You cannot use loops
- 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-levelval.object. - Variables defined by
foreach keys([regex]):returns all valid keys (as perkeyinkeybindings.json) matching the regular expressionall_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 duringmaster-key.searchandmaster-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. Likeall_modesthe 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 otherwisecode.editorHasMultipleSelections: true if there are multiple selections, false otherwisecode.firstSelectionOrWord: the first selection, or the word under the first cursor if the selection is emptycode.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 modekey.count: The current count, as defined bymaster-key.updateCountkey.captured: The text currently captured by the most recent call tomaster-key.captureKeys.key.prefix: The currently active keybinding prefixkey.record: a boolean flag used to indicate when keys are marked for recordinghistory: 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.
[[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.
