Aha!
From the official documentation about key bindings, I had no idea that there are some priorities of contexts. I was thinking that user’s key bindings just silently override the default ones.
I’d suggest to explicitly mention that fact in the documentation, with explicit examples. The following key bindings may be used as examples, with additional comments of why the bindings are specified in this exact order and what each binding (and each “key” within this binding) does.
{ "keys": ["'"], "command": "" },
{ "keys": ["'"], "command": "insert_snippet", "args": {"contents": "'$0'"}, "context":
[
{ "key": "selector", "operator": "not_equal", "operand": "text", "match_all": true },
{ "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 },
{ "key": "preceding_text", "operator": "not_regex_contains", "operand": "['a-zA-Z0-9_]$", "match_all": true },
{ "key": "eol_selector", "operator": "not_equal", "operand": "string.quoted.single - punctuation.definition.string.end", "match_all": true }
]
},
{ "keys": ["'"], "command": "insert_snippet", "args": {"contents": "'${0:$SELECTION}'"}, "context":
[
{ "key": "selector", "operator": "not_equal", "operand": "text", "match_all": true },
{ "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 },
{ "key": "selector", "operator": "not_equal", "operand": "punctuation.definition.string.begin", "match_all": true },
{ "key": "eol_selector", "operator": "not_equal", "operand": "string.quoted.single - punctuation.definition.string.end", "match_all": true },
]
},
By the way, I was about to add that I still don’t understand the purpose of the last binding here, the one with:
"keys": ["'"], "command": "move", "args": {"by": "characters", "forward": true}
but right at the moment of typing this, I realized this exact key binding deals with situations when you have the auto-completed ‘’ (with the caret positioned before the closing single quote) and you automatically type the closing single quote. In this case, this exact key binding does not allow to add another single quote before the existing one.
I believe, it makes perfect sense to explain such things in the official documentation.