Sublime Text and Clojure: Don't pair single quotes

clojure, lisp, quotes, sublimetext, sublimetext2

Solution

You should be able to, though it's kind of a pain. First, you will have to disable the built in auto pairing (don't worry, when we are finished, auto pairing for everything else should work). To do this, set the following in your user settings.

"auto_match_enabled": false

Then add the following to your settings.

"my_auto_match_enabled": false

Next, we need to add a new set of keybindings. I only did one from what you posted, but I'll explain what I did since it may not be obvious.

{ "keys": ["'"], "command": "insert_snippet", "args": {"contents": "'${0:$SELECTION}'"}, "context":
    [
        { "key": "setting.my_auto_match_enabled", "operator": "equal", "operand": true },
        { "key": "selection_empty", "operator": "equal", "operand": false, "match_all": true },
        { "key": "selector", "operator": "not_equal", "operand": "source.clojure", "match_all": true }
    ]
}

First, note that I switched the first context key from `setting.auto_match_enabled` to `setting.my_auto_match_enabled`. Next, I added the last context entry which will limit the scope. With this, the snippet will only run when you are not in a `source.clojure` scope. You may have to modify this as I don't know what the scope name in clojure is, I just guessed =). You will have to do this for all of your single quote entries. Now, because we disabled the built in auto pairing, we have to readd all of those entries as well. In these entries, we will again change `setting.auto_match_enabled` to `setting.my_auto_match_enabled`. After that, everything should work. Note it doesn't actually have to be `my_auto_match_enabled`, that's just what I chose. You may change it as you see fit.

With all that being said, I didn't completely test all of this, so comment if you run into issues.

Explanation:

So now you might be asking yourself, why do I need to disable the built in auto matching code? Well here's the answer. Even if we were to block the auto complete in our user settings, using a similar scoping rule, it would still fall back to the default, thus inserting the auto paired quotes regardless of what we do in the user folder. Now you might be thinking, but what if we modify the default settings file. Though we could do this, again inserting that same context setting, we would have to make sure to restore that file on any subsequent updates. So I guess in the end it is up to you. If you edit the default file, just keep in mind that if you ever need to revert, you will have to change the file again.

Sublime Text 3:

In ST3, you can perform the actually modify the "default" file. This is due to a change in how packages are loaded in ST3. Rather than needing to be extracted to the Packages folder, plugins are run directly from the .sublime-package files (which are just renamed zips). In addition, any file in the Packages directory takes precedence over the .sublime-package file. So, in ST3, you would create `Packages/Default/Default (your os here).sublime-keymap`, and add the context line. It is safe from any subsequent updates as updates no longer modify the Packages directory.

Problem

Is there a way to get a syntax type to define keyboard shortcuts, or to set a keyboard shortcut to depend on the syntax type (perhaps under the `"context"`) setting? My quoted lists `'(1 2 3)` get entered in like this: `'(1 2 3)'` because Sublime applies this helpful (but not in this case) behavior. Here is the relevant bit of the `Default (OSX).sublime-keymap` file ``` // Auto-pair 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 } ] }, { "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 } ] }, ```

Original source