Sublime Forum

Help with key bindings

#1

I wanted to expand auto-pair functionality to template strings (i.e. backticks). I also wanted to populate expression interpolation when typing ‘$’ within backticks. I ported the existing keybindings for auto-pairing and came up with the following:

[
    // Auto-pair backticks
    { "keys": ["`"], "command": "insert_snippet", "args": {"contents": "`$0`"}, "context":
        [
            { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true },
            { "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true },
            { "key": "following_text", "operator": "regex_contains", "operand": "^(?:\t| |\\)|]|;|\\}|$)", "match_all": true }
        ]
    },
    { "keys": ["`"], "command": "insert_snippet", "args": {"contents": "`${0:$SELECTION}`"}, "context":
        [
            { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true },
            { "key": "selection_empty", "operator": "equal", "operand": false, "match_all": true }
        ]
    },
    { "keys": ["`"], "command": "move", "args": {"by": "characters", "forward": true}, "context":
        [
            { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true },
            { "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true },
            { "key": "following_text", "operator": "regex_contains", "operand": "^`", "match_all": true }
        ]
    },
    { "keys": ["backspace"], "command": "run_macro_file", "args": {"file": "res://Packages/Default/Delete Left Right.sublime-macro"}, "context":
        [
            { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true },
            { "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true },
            { "key": "preceding_text", "operator": "regex_contains", "operand": "`$", "match_all": true },
            { "key": "following_text", "operator": "regex_contains", "operand": "^`", "match_all": true }
        ]
    },
    // Expression interpolation
    { "keys": ["$"], "command": "insert_snippet", "args": {"contents": "\\$\\{$0\\}", "forward": true}, "context":
        [
            { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true },
            { "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true },
            { "key": "preceding_text", "operator": "regex_contains", "operand": "`", "match_all": true },
            { "key": "following_text", "operator": "regex_contains", "operand": "`", "match_all": true }
        ]
    },
]

My questions are as follows:

How would I make this keybinding specific to Javascript syntax only (i.e. default Javascript, Javascript - ES6 Syntax, and JavaScript (Babel))?

Currently my template expression interpolation keybinding only works on a single line. How would I extend the keybinding to work anywhere on any line as long as it is between backticks (i.e. multiple lines)?

0 Likes

#2

To limit the key binding to certain languages or pieces of code, you can add a seletor. The following key limits your key bindings to all kinds of source.js.

{ "key": "selector", "operator": "equal", "operand": "source.js", "match_all": true },

Expression interpolation could basically look like this. It adds the snippet whenever you type $ within a string. Maybe you still need to add some preceding_text or following_text keys to add some fine gained control about when to avoid add the snippet, but as a first step it should work.

{ "keys": ["$"], "command": "insert_snippet", "args": {"contents": "\\$\\{$0\\}", "forward": true}, "context":
	[
		{ "key": "setting.auto_match_enabled", "operator": "equal", "operand": true },
		{ "key": "selector", "operator": "equal", "operand": "source.js string.template", "match_all": true },
		{ "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true },
		{ "key": "following_text", "operator": "regex_contains", "operand": "^(?:\t| |`|$)", "match_all": true },
		{ "key": "preceding_text", "operator": "not_regex_contains", "operand": "\\w$", "match_all": true }

	]
},
1 Like