trejder
trejder

Reputation: 17495

Sublime Text 3 does not pair quotes before semicolon

Sublime Text 3 has quotes auto-pair function, that works perfectly. However, for some reason, it stops working, when following character is a semicolon. So, entering single or double quote here:

echo ^ 

will enter both quotes and place cursor in between them, while doing the same here:

echo ^;

will cause Sublime Text 3 to enter only opening single or double quote.

I'm programming in PHP with a small glitch, that I most often enter semicolon first, then I go back in that line and write actual code. Many snippets and macros also enters semicolon. So, this behaviour of ST3 is a little bit annoying in this case.

Is there any explanation, why auto-pair was limited in Sublime Text 3 to be not working before semicolon? And -- most important -- is there any way to workaround this problematic behaviour?

Upvotes: 0

Views: 286

Answers (1)

MattDMo
MattDMo

Reputation: 102862

By default, Sublime will auto-pair quotes only when the following character is one of \t (tab), (space), ), ], }, >, or at the end of the line. Fortunately, this rule can easily be modified by creating a custom keybinding based on the default one. Open Preferences -> Key Bindings-User and add the following (if the file is empty, surround everything with an opening square bracket [ at the beginning and closing ] at the end [ <content> ]):

// allow matched quotes before semi-colon
// double 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", "match_all": true }
    ]
},

// single 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.single", "match_all": true }
    ]
},

// curly brackets
// parentheses and square brackets already work
{ "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 }
    ]
}

The key line in each rule is this:

{ "key": "following_text", "operator": "regex_contains", "operand": "^(?:\t| |\\)|]|\\}|>|$|;)", "match_all": true },

If you find that you'd like to auto-pair before another character, just put a pipe | after the semi-colon in "operand" and add the character you want.

I should note that this will work in both Sublime Text 2 and 3.

Upvotes: 1

Related Questions