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’.
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])
You can subscript a String with a Regexp, returning the first match: "goal"[/[aeiou]/] => "o" (nil is returned if there is no match).
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.
This is the personal blog of the London-based geek and beer enthusiast commonly known as Sam Stokes.
I plan to write mostly about software development, programming languages, technology and startups. Beer, music and London might occasionally feature.