I’ve never been much of a Vim user, but people I respect swear by it. Among its “super powers” is lightning fast navigation in normal mode. I like being able to hit 5,j and move up 5 lines, because often one line at a time is too slow, and ~40 lines with Page Up is too fast.

But using Vintage Mode for this alone seemed like overkill, so I decided I would find a Sublime Text plugin that could chain multiple calls to “move cursor up a line”, and so forth, and put these in my keymap. I stumbled upon this one in the ST forums, which does the job nicely. To enable it, simply put this file, run_multiple_commands.py, into the User directory under your Sublime Text packages.

If you want to chain calls to the ST API in your keymap, it helps to know what those calls look like. Fortunately, there’s an easy way to find out. Bring up the console with ctrl+`, and enter sublime.log_commands(True). Now, every call you make to the API by pressing key(s) or clicking your mouse will get logged to the console, and you can copy it almost as is into your keymap. Here’s my keymap, and here’s an excerpt with some entries that run multiple commands.

{ "keys": ["alt+up"],
"command": "run_multiple_commands",
"args": {
  "commands": [
  {"command": "move", "args": {"by": "lines", "forward": false}, "context": "window" },
  {"command": "move", "args": {"by": "lines", "forward": false}, "context": "window" },
  {"command": "move", "args": {"by": "lines", "forward": false}, "context": "window" },
  {"command": "move", "args": {"by": "lines", "forward": false}, "context": "window" },
  {"command": "move", "args": {"by": "lines", "forward": false}, "context": "window" }
  ]
}
},

...

{ "keys": ["ctrl+alt+left"],
"command": "run_multiple_commands",
"args": {
  "commands": [
  {"command": "move", "args": {"by": "wordends", "forward": false}, "context": "window" },
  {"command": "move", "args": {"by": "wordends", "forward": false}, "context": "window" },
  {"command": "move", "args": {"by": "wordends", "forward": false}, "context": "window" },
  ]
}
},

Exponential Navigation

I can hit alt+up/down to move 5 lines up or down, adding shift to highlight these lines, and I can do the same with ctrl+alt+left/right to move 3 words left or right.

I’ve been using this system for over a year. Arriving at 5 lines for vertical movement and 3 words for lateral movement was part intuition and part trial and error. The intuition behind it was enabling navigation whose sensitivity struck a exponential middle ground between:

  • up/down?Page Up/Page Down
    • 1 line → 5 lines → ~40 lines
  • alt+left/right?super+left/right
    • 1 word → 3 words → ~15 words

In practice, the system is natural and smooth. After a while, choosing which of the 3 “levels” of sensitivity is most appropriate requires almost no cognitive effort, but at the same time it doesn’t feel imprecise. If you’re moving down to something 19 lines away, you hit alt+down a few times, watching the cursor as you go, hit up, and you’re there. It turns out a few times was 4, but you didn’t have to think about it, because you had visual feedback the whole way.

If your file is 250 lines long, 10 movements will get you to any line in the file. Typically, this will be more like 4. It’s fast and relatively mindless, which is what I want in navigation. I’d rather focus on the code.