Coding with Honour
Vim wizardry #1

(I wrote this as a response to an Ask Hacker News post about learning Vim, but I thought it deserved a life of its own.)

This is one of my favourite Vim features. Say you have the following code:

do_something_with(some + long * complicated * expression)
                           ^

Say your cursor is where the caret indicates. Typing ci) (“change inside parens”) in normal mode will:

  • delete all the text between the two matching parens

  • place you in insert mode with the cursor between the two (now adjacent) parens

  • put the deleted text in the yank buffer so that p will paste it.

The use case here is obviously so you can assign a name to that long complicated expression. ci) is much easier than selecting it with the mouse, and keeps your hands on the keyboard where they belong ;)

With nested parentheses, it does what you expect (affects the text contained by the innermost matching pair to contain your cursor - try it and see).

Other equally useful variants:

  • i" - “inside double quotes” - everything between double quotes

  • i' - “inside single quotes”

  • iw - “inside word” - the word the cursor is on

  • is - “inside sentence” - great for editing prose

  • ip - “inside paragraph”

There are also similar motions beginning with “a”:

  • a) - like i) but includes the parens (e.g. da) deletes everything inside parens and the parens themselves)

  • a" - similarly

  • aw - like iw but includes trailing whitespace.

For another great taste that goes great with this, see the surround.vim plugin. To whet your appetite: six keystrokes to wrap your current selection in <div> tags; four to change a string from “double-quoted” to ‘single-quoted’.

Regex style in Ruby

Reading Patrick McKenzie’s excellent practical example of metaprogramming, I came across a line of code I didn’t understand:

That line taught me three new things about Ruby:

  1. The syntax for the subscript operator [] allows multiple arguments. (It turns out I already knew this in another context: [1,1,2,3,5,7][2,3] => [2,3,5])
  2. You can subscript a String with a Regexp, returning the first match: "goal"[/[aeiou]/] => "o" (nil is returned if there is no match).
  3. If you throw in an index n, then you get the nth capturing group of the first match: "xaabb"[/(.)\1/, 1] => "a" (or nil again if no match).

That last one is interesting, because it means there’s a concise way I didn’t previously know about to achieve a common regex task: checking if an input string matches a given format, and if so, extracting part of the format. Say we want to pull out the domain from an email address, but complain if we can’t find it:

Before learning this trick I would have either used a temporary match object a la Java, or gritted my teeth and used a global variable Perl-style:

Both of those seem rather verbose. They can be golfed into one-liners, but the readability starts to suffer:

So I’m left wondering what’s the most readable and/or idiomatic style for regexes in Ruby. TMTOWTDI indeed! Even now I know what it means, "xaabb"[/(.)\1/,1] makes me double-take slightly - it’s an unusual way to use [] - but I guess it’s just another Ruby idiosyncracy I’ll come to know and love.