Fixing some of Sublime Text's annoyances

A quick post. While I use Vim a lot, I often keep Sublime Text handy for when its power is particularly suitable to a task.

Just thought to share some of the modifications I made to Sublime Text, which resolves some of the annoyances that are pretty subtle – things that don’t quite warrant distributing as a package (for now at least), but things that actually affect the overall experience of using Sublime Text.

Basically, this focuses on two quirks:

  • Behavior of the Esc key
  • Behavior of the auto-complete for matching braces (and brackets and quotes)

These fixes should go into your keymap file.

This can be accessed via Preferences > Key Bindings -- User.

Behavior of the Esc key

The Esc key intuitively dismisses dialogs. In Sublime Text’s case, these are the panels that appear at the bottom such as the ‘Search’ panel, the ‘Find and Replace’ panel, the ‘Incremental Search’ panel, and so on. However, often when we call up these dialogs, and decide to cancel and hence hit the Esc key, it refuses to go away.

In a similar vein, after using those panels, we often hit to activate the functionality of that panel (e.g. to actually find after typing in the search term). It would be nice to make those panels disappear too, after we are done.

The following key-bindings fixes this:

// -------------------------------------------------------------------------
// Handle escape key behaviour better (generic sublime panels)
// -------------------------------------------------------------------------

{ "keys": ["escape"], "command": "hide_panel", "args": { "close_panel": true },
  "context":
  [
    { "key": "panel", "operand": "find" },
    { "key": "panel_has_focus" }
  ]
},
{ "keys": ["escape"], "command": "hide_panel", "args": { "close_panel": true },
  "context":
  [
    { "key": "panel", "operand": "find_in_files" },
    { "key": "panel_has_focus" }
  ]
},
{ "keys": ["escape"], "command": "hide_panel", "args": { "close_panel": true },
  "context":
  [
    { "key": "panel", "operand": "incremental_find" },
    { "key": "panel_has_focus" }
  ]
},
{ "keys": ["escape"], "command": "hide_panel", "args": { "close_panel": true },
  "context":
  [
    { "key": "panel", "operand": "replace" },
    { "key": "panel_has_focus" }
  ]
},
{ "keys": ["enter"], "command": "hide_panel", "args": { "close_panel": true },
  "context":
  [
    { "key": "panel", "operand": "find" },
    { "key": "panel_has_focus" }
  ]
},
{ "keys": ["enter"], "command": "hide_panel", "args": { "close_panel": true },
  "context":
  [
    { "key": "panel", "operand": "incremental_find" },
    { "key": "panel_has_focus" }
  ]
},
{ "keys": ["enter"], "command": "hide_panel", "args": { "close_panel": true },
  "context":
  [
    { "key": "panel", "operand": "replace" },
    { "key": "panel_has_focus" }
  ]
},
Watch out for the final comma above. You may need to remove it depending on where you place the above.

Behavior of the auto-complete for matching characters

When you enter a bracket, parenthesis, curly brace, quote or double-quote in sublime, it automatically completes the matching pair for you. This means that if you type, say, a quote in the middle of a sentence, after you finish what’s inside the quote, you have to move over the auto-completed closing quote to continue typing the stuff outside the quote.

This is accomplished via the right-arrow, or the end key. Either way, it’s annoying because those keys are far away.

Of course, you could simply “type over” the matching character, but sometimes, it’s just nice to step over it in a generic manner rather than reaching for the same character.

We will make the enter and tab keys “step over” the matching character.

// -------------------------------------------------------------------------
// Auto-complete behaviour for ), ], '', ""
// Bind to <enter>, <tab> to step over the auto-completed character(s)
// -------------------------------------------------------------------------

{ "keys": ["enter"], "command": "move", "args": {"by": "characters", "forward": true},
  "context":
  [
      { "key": "following_text", "operator": "regex_contains", "operand": "^[)\\]'\"}]", "match_all": true },
      { "key": "preceding_text", "operator": "regex_contains", "operand": "[(['\"{]", "match_all": true },
      { "key": "auto_complete_visible", "operator": "equal", "operand": false }
  ]
},
{ "keys": ["tab"], "command": "move", "args": {"by": "characters", "forward": true},
  "context":
  [
      { "key": "following_text", "operator": "regex_contains", "operand": "^[)\\]'\"}]", "match_all": true },
      { "key": "preceding_text", "operator": "regex_contains", "operand": "[(['\"{]", "match_all": true },
      { "key": "auto_complete_visible", "operator": "equal", "operand": false }
  ],
}

Again, watch out for the final comma above. You may need to remove it depending on where you place the above.

If anybody is frustrated with the default behavior of Sublime (in these aspects), hope this helps in some small way!