sublime_merge icon indicating copy to clipboard operation
sublime_merge copied to clipboard

Commit message with shortcut to insert bracket or insert bracket around text

Open billy1624 opened this issue 3 years ago • 2 comments

Hi, it would be nice if in commit message of Sublime Merge, it will insert the closing bracket automatically right after user enter the open bracket. For example, when user enter ( it will insert a ) right after the cursor.

Also, it would be very helpful to highlight a text then press on the open bracket, e.g. (, then the highlighted text will be enclosed in the bracket.

The "bracket" I refer to above is not only () but also {}, [], <>.

Thanks for reading :D

billy1624 avatar Oct 26 '22 10:10 billy1624

@billy1624, a workaround is to add these key bindings:

Default.sublime-keymap
click to view
[
    // Auto-pair quotes
    { "keys": ["\""], "command": "insert_snippet", "args": {"contents": "\"$0\""}, "context":
        [
            { "key": "control", "operand": "text_control" },
            // { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, // <- seems unsupported in SM
            { "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": "control", "operand": "text_control" },
            // { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, // <- seems unsupported in SM
            { "key": "selection_empty", "operator": "equal", "operand": false, "match_all": true }
        ]
    },
    { "keys": ["\""], "command": "move", "args": {"by": "characters", "forward": true}, "context":
        [
            { "key": "control", "operand": "text_control" },
            // { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, // <- seems unsupported in SM
            { "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": "control", "operand": "text_control" },
            // { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, // <- seems unsupported in SM
            { "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 },
        ]
    },

    // Auto-pair single quotes
    { "keys": ["'"], "command": "insert_snippet", "args": {"contents": "'$0'"}, "context":
        [
            { "key": "control", "operand": "text_control" },
            // { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, // <- seems unsupported in SM
            { "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": "control", "operand": "text_control" },
            // { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, // <- seems unsupported in SM
            { "key": "selection_empty", "operator": "equal", "operand": false, "match_all": true }
        ]
    },
    { "keys": ["'"], "command": "move", "args": {"by": "characters", "forward": true}, "context":
        [
            { "key": "control", "operand": "text_control" },
            // { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, // <- seems unsupported in SM
            { "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 },
        ]
    },
    { "keys": ["backspace"], "command": "run_macro_file", "args": {"file": "res://Packages/Default/Delete Left Right.sublime-macro"}, "context":
        [
            { "key": "control", "operand": "text_control" },
            // { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, // <- seems unsupported in SM
            { "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.single - punctuation.definition.string.end", "match_all": true },
        ]
    },

    // Auto-pair brackets
    { "keys": ["("], "command": "insert_snippet", "args": {"contents": "($0)"}, "context":
        [
            { "key": "control", "operand": "text_control" },
            // { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, // <- seems unsupported in SM
            { "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": "control", "operand": "text_control" },
            // { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, // <- seems unsupported in SM
            { "key": "selection_empty", "operator": "equal", "operand": false, "match_all": true }
        ]
    },
    { "keys": [")"], "command": "move", "args": {"by": "characters", "forward": true}, "context":
        [
            { "key": "control", "operand": "text_control" },
            // { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, // <- seems unsupported in SM
            { "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": "control", "operand": "text_control" },
            // { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, // <- seems unsupported in SM
            { "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 }
        ]
    },

    // Auto-pair square brackets
    { "keys": ["["], "command": "insert_snippet", "args": {"contents": "[$0]"}, "context":
        [
            { "key": "control", "operand": "text_control" },
            // { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, // <- seems unsupported in SM
            { "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": "control", "operand": "text_control" },
            // { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, // <- seems unsupported in SM
            { "key": "selection_empty", "operator": "equal", "operand": false, "match_all": true }
        ]
    },
    { "keys": ["]"], "command": "move", "args": {"by": "characters", "forward": true}, "context":
        [
            { "key": "control", "operand": "text_control" },
            // { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, // <- seems unsupported in SM
            { "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": "control", "operand": "text_control" },
            // { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, // <- seems unsupported in SM
            { "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 }
        ]
    },

    // Auto-pair curly brackets
    { "keys": ["{"], "command": "insert_snippet", "args": {"contents": "{$0}"}, "context":
        [
            { "key": "control", "operand": "text_control" },
            // { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, // <- seems unsupported in SM
            { "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true },
            { "key": "following_text", "operator": "regex_contains", "operand": "^(?:\t| |\\)|]|\\}|$)", "match_all": true }
        ]
    },
    { "keys": ["{"], "command": "wrap_block", "args": {"begin": "{", "end": "}"}, "context":
        [
            { "key": "control", "operand": "text_control" },
            { "key": "indented_block", "match_all": true },
            // { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, // <- seems unsupported in SM
            { "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true },
            { "key": "following_text", "operator": "regex_match", "operand": "^$", "match_all": true },
        ]
    },
    { "keys": ["{"], "command": "insert_snippet", "args": {"contents": "{${0:$SELECTION}}"}, "context":
        [
            { "key": "control", "operand": "text_control" },
            // { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, // <- seems unsupported in SM
            { "key": "selection_empty", "operator": "equal", "operand": false, "match_all": true }
        ]
    },
    { "keys": ["}"], "command": "move", "args": {"by": "characters", "forward": true}, "context":
        [
            { "key": "control", "operand": "text_control" },
            // { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, // <- seems unsupported in SM
            { "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": "control", "operand": "text_control" },
            // { "key": "setting.auto_match_enabled", "operator": "equal", "operand": true }, // <- seems unsupported in SM
            { "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 }
        ]
    },
]

As to how I generated these: I copied the auto-pair keybindings from Sublime Text's Default (Linux).sublime-keymap file, added the Sublime Merge compatibility line ({ "key": "control", "operand": "text_control" },) and removed the settings check that doesn't seem to work in SM ({ "key": "setting.auto_match_enabled", [..])

srbs avatar Nov 02 '22 12:11 srbs

Very cool! I just tried, it works perfectly :) Thanks!! @srbs

I genuinely hope this is a built-in feature.

billy1624 avatar Nov 02 '22 12:11 billy1624