How to prevent Sublime Text 2 from swallowing closing brackets, quotes and parentheses?
Sublime has this behaviour which is really annoying sometimes when you have to type in constructions with lots of brackets. When you type (
it adds ()
and puts the cursor in the middle, all fine, if you however will type )
it will silently swallow the closing bracket.
This is really annoying when typing long regexps because the brackets gets unbalanced pretty quick and this is driving me crazy. So you end up with constructions like (([a-z])
.
So the question is - is there a way to disable this? If I type a closing bracket I want it to stay, not be swallowed.
I have checked through Sublime configs, googled, but nobody seems to mind this behaviour. Am I using it wrong?
Update
You might want to check out Sublime: Jump out of matching brackets shortcut as well.
Full version that allows you to type through with ()
but will not swallow the closing symbol if you have entered any text:
{ "keys": ["\""], "command": "insert", "args": {"characters": "\""}, "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": "preceding_text", "operator": "regex_contains", "operand": "[^\"]$", "match_all": true }
]
},
{ "keys": [")"], "command": "insert", "args": {"characters": ")"}, "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": "preceding_text", "operator": "regex_contains", "operand": "[^(]$", "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": "preceding_text", "operator": "regex_contains", "operand": "\\($", "match_all": true }
]
},
{ "keys": ["'"], "command": "insert", "args": {"characters": "'"}, "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": "preceding_text", "operator": "regex_contains", "operand": "'$", "match_all": true }
]
},
{ "keys": ["]"],"command": "insert", "args": {"characters": "]"}, "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": "preceding_text", "operator": "regex_contains", "operand": "[$", "match_all": true }
]
},
{ "keys": ["}"], "command": "insert", "args": {"characters": "}"}, "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": "preceding_text", "operator": "regex_contains", "operand": "{$", "match_all": true }
]
}
add this to your user keybindings file
{ "keys": [")"], "command": "insert", "args": {"characters": ")"}, "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 }
]
}
it will override the one keybinding that instead of inserting a closing bracket just moves the cursor one position forward. so essentially it should do exactly what you want.
if you want to disable this behaviour completely, for all kinds of brackets and quotes, here is the complete user keybindings part:
{ "keys": ["\""], "command": "insert", "args": {"characters": "\""}, "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 }
]
},
{ "keys": [")"], "command": "insert", "args": {"characters": ")"}, "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 }
]
},
{ "keys": ["'"], "command": "insert", "args": {"characters": "'"}, "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 }
]
},
{ "keys": ["]"],"command": "insert", "args": {"characters": "]"}, "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 }
]
},
{ "keys": ["}"], "command": "insert", "args": {"characters": "}"}, "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 }
]
}
EDIT:
In case you want to skip the closing bracket if the cursor is right after an opening bracket and print it in all other cases, you can split your keybindings up to distinguish beetween these two possibilities:
{ "keys": [")"], "command": "insert", "args": {"characters": ")"}, "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": "preceding_text", "operator": "regex_contains", "operand": "[^(]$", "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": "preceding_text", "operator": "regex_contains", "operand": "\\($", "match_all": true }
]
},
The first one inserts the charcater if the preceding text doesn't end with an opening bracket. The second one moves the cursor one position forward if it does end with an opening bracket. If you are a little familiar with regular expressions you can do the same for all other kinds of brackets and quotes.
Redefine the )
key binding:
{ "keys": [")"], "command": "insert", "args": {"characters": ")"} }
Edit: Another way is to enable/disable the auto_match_enabled
setting (thus changing the auto-pairing behavior), you can toggle it at will using a keyboard shortcut:
{ "keys": ["alt+m"], "command": "toggle_setting", "args": {"setting": "auto_match_enabled"} }