Sublime Forum

So, on the dead keys topic

#1

So, i’m trying to use sublime as a VSCode replacement.

So far so good, the main issue i’m having right now is with Dead Keys. I’m not able to use things like to quote a selected word because after I type a " (for example) it expect a new key. If I press space, the word gets replaced.

For comparisson, in VSCode, i get the selected word quoted as expected.

I did search the forums and found these two (old) posts without an answer:


A few additional internet (and AI) searches recommend to disable dead keys, which is not an applicable solution in my case as i need them to type character with accents.

Considering the current version of ST, is there a proper solution for this ?

0 Likes

#2

On keyboards with backticks being dead keys auto-pairing and auto-quoting can be achieved with key bindings which insert snippets. Maybe this strategy works for other quotation types as well.

ST’s Markdown syntax ships with such key bindings. see: https://github.com/sublimehq/Packages/blob/36763f6f68517049f2e78125dbc0043bc224879d/Markdown/Default.sublime-keymap#L26-L83

With those bindings I can select a piece of text and hit backtick followed by space to wrap it.

A solution might be to remove "selector" key and replace "`" by "\"" to achieve the same for double quotes on your end.

Note: Maybe other binding than \" is needed as ST doesn’t correctly map foreign keyboard layouts.

    // Auto-pair double quotes
    {
        "keys": ["\""],
        "command": "insert_snippet",
        "args": {"contents": "\"$0\""},
        "context": [
            { "key": "setting.auto_match_enabled"},
            { "key": "selection_empty", "match_all": true },
            { "key": "preceding_text", "operator": "not_regex_contains", "operand": "[\\w\"]$", "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"},
            { "key": "selection_empty", "operand": false, "match_all": true },
        ]
    },
    {
        "keys": ["\""],
        "command": "move",
        "args": {"by": "characters", "forward": true},
        "context": [
            { "key": "setting.auto_match_enabled" },
            { "key": "selection_empty", "operand": true, "match_all": true },
            { "key": "following_text", "operator": "regex_contains", "operand": "^\"", "match_all": true }
        ]
    },
    {
        "keys": ["\""],
        "command": "move",
        "args": {"by": "characters", "forward": true},
        "context": [
            { "key": "setting.auto_match_enabled" },
            { "key": "selection_empty", "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 }
        ]
    },
    {
        "keys": ["backspace"],
        "command": "run_macro_file",
        "args": {"file": "res://Packages/Default/Delete Left Right.sublime-macro"},
        "context": [
            { "key": "setting.auto_match_enabled" },
            { "key": "selection_empty", "match_all": true },
            { "key": "preceding_text", "operator": "regex_contains", "operand": "\"$", "match_all": true },
            { "key": "following_text", "operator": "regex_contains", "operand": "^\"", "match_all": true }
        ]
    },
0 Likes

#3

Not sure if I followed the suggestion the right way.

As far as I saw here, the binding for double quote already uses the insert_snippet solution. Below the default ST configuration i have locally:

// Auto-pair quotes
{ "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 },
		{ "key": "preceding_text", "operator": "not_regex_contains", "operand": "[\"a-zA-Z0-9_]$", "match_all": true },
		{ "key": "eol_selector", "operator": "not_equal", "operand": "string.quoted.double - punctuation.definition.string.end", "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 },
		{ "key": "selector", "operator": "not_equal", "operand": "punctuation.definition.string.begin", "match_all": true },
		{ "key": "eol_selector", "operator": "not_equal", "operand": "string.quoted.double - punctuation.definition.string.end", "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 },
		{ "key": "selector", "operator": "not_equal", "operand": "punctuation.definition.string.begin", "match_all": true },
		{ "key": "eol_selector", "operator": "not_equal", "operand": "string.quoted.double - punctuation.definition.string.end", "match_all": true },
	]
},

I did notice you changed a few things, so i copied you’re entire example and pasted as a custom keybinding, but was not able to get a selected text surrounded with quotes.

I did try to surround a selected text with backticks in a mardown file, but the result is the same, i mean, the word gets deleted.

0 Likes

#4

Than my proposal is probably not viable. I hoped it working as selecting a word, typing backtick and space, deletes it on my box without those markdown specific bindings, while correctly being wrapped in backticks otherwise.

As ST doesn’t apply any language specific key mappings, chances are high configured \" and ` bindings just apply to unexpected keys on your box. Maybe you’ll need to chose a totally different (unexpected) binding to make it work.

As on my end I need to type ctrl+# to trigger the binding { "keys": ["ctrl+`"], "command": "show_panel", "args": {"panel": "console", "toggle": true} }, on Windows. I haven’t found the proper key binding to use on Linux so far, even though hardware and config is the same.

This is the weird world of ST.

1 Like