Force Sublime Text 3 to auto-pair quotes before semicolon

By default, Sublime Text 3 will not auto-pair quotes (add closing quote, when you enter opening one), when following character is a semicolon (;). This is a little bit unhandy for PHP developers.

But, since nearly everything in Sublime Text 3, this can be easily tweaked, by changing ST3 configuration.

You’ll find all the details in this wonderful Stack Exchange answer, made by MattDMo after my question asking, how to fix this problem.

I have copied the entire answer here to have it handy within my blog.


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.

Leave a Reply