Sharing Our Passion for Technology
& Continuous Learning
Vim in Twelve More Keys
Vim in Twelve More Keys
This is part 2 in a series on vim. I recommend you read the first part here.
Last time we covered how to get work done in vim. If you used the tips from last time, you're probably already faster than you were with your old editor. You may, however, have noticed some clunkiness when working with certain kinds of text. I'm here to help you work around these issues and let you get into a good flow-state while wrangling text.
Let's jump right in.
. (... eliding things)
If you remember last time, I covered how dw
will delete a word. It even takes a count, so d2w
deletes 2 words. D
Deletes the rest of the line starting at the cursor. dd
ddeletes the entire line. These are all well and good, but there is an awkward middle ground where you want to delete 5+ words, but not everything. We could mash dw
until we have eliminated the text. We could count the number of words and use dXw
. But, seriously? Counting? That's supposed to be the computer's job. This is not what I signed up for.
Luckily there is a better way.
The .
key repeats the last verb + motion combination you used. If you delete a word with /dw
, .
deletes another word. If you delete a line with dd
, .
deletes another line. A common pattern is to perform an action once and then hit .
until the desired effect has been achieved. Vim also keeps track of any text you might have inserted. So, if you change a word (cw
) to cheese
, .
will change another word to cheese
.
.
elides out many key presses.
u and ctrl + r (uh oh)
So, we now have a way to very quickly delete as many words or lines as we want. This solves one problem, but creates another. You will eventually delete too many things. Does vim have a way around this?
Of course it does. To undo simply press u
. To redo press ctrl + r
. That's the simple case anyway, but vim's undo system actually solves another problem as well.
g- and g+ (we gotta go back)
Have you ever undone a bunch of changes to get something you deleted and then made a change that clobbers everything you've done since then? I have.
Fortunately this isn't a problem with vim. Vim has a branching undo system. This means all your changes are still there. We just have to get at them.
How do we do that? What does any of this mean?
Most undo systems just keep track of the most recent branch of changes. If you go back in time and change something. *POOF* Everything since then is lost to the void. You have to get back the hard way.
Vim, on the other hand, keeps track of all the changes by the time they happened. g-
will take you back in time to the most recent change. g+
will take you forward in time one change.
; and (The Mnemonic Creator's Guild got mad at at me for submitting this one)
Alright, we can delete all the things. We can undo/redo our changes. We can time-travel. This is cool and all, but the navigation still feels clunky. We've covered how to repeat commands, but how do we repeat a motion? The best way to travel horizontally across a line is with f
. Lines, it turns out, can have multiple instances of the same character.
While typing ftftft
is a better way to get to the third t on a line than /t<CR>/t<CR>/t<CR>
, it's not as good as it could be. As you may have suspected by this point, ;
lets you repeat the last find you preformed. What was ftftft
becomes ft;;
. A savings of 2 keystrokes over repeating ft
and 5 keystrokes over the /
method. ,
does the same thing backwards. So starting from the 3rd t
on a line, we can get back to the first just by typing ,,
.
n (Next!)
Up until now, the best way we've covered to travel vertically in a file is to use /
. But what if the word I want to search for occurs more than once in the file? This happens occasionally. What if I'm editing a post for my high-end cheese blog? Typing /cheese
over and over to jump around in the file kind of stinks. This is no Gouda.
What we're looking for is a way to repeat a search with a single keystroke, sort of like .
did for commands or ;
did horizontally across the line. That's what n
does. n
repeats the last search you made. N
searches backwards in the file.
q and @ (The Mnemonic Creator's Guild officially refuses to work with me now)
This blog post has been mostly about repeating things easily. So far these have all been pretty low level. Can we repeat a task?
Why, yes. Yes we can. This is what q
does. q
records a macro. A macro is a set of commands to save off and replay later.
Let's say you have a csv file someone emailed you that needs to be fed into a 3rd party service. This service requires the columns to be in a very specific order because... of course it does. Whoever generated the file swapped the 3rd and 4th columns because... of course they did. You just want to get back to your code. What's the quickest way forward? Regex? Perl? Awk?
How about: qqf,;ldf,;pj0q
?
Ok what was that? How did a sneeze end up in a blog post?
Let's take it bit by bit.
qq
records a macro named q
f
finds the first ,
;
repeat the last find (we're now at the second ,
)
l
moves one character right
df,
deletes everything up to and including the next ,
;
move to next ,
p
paste what we just deleted
j
move one line down
0
move to the beginning of the line
q
finish recording macro
We can replay this macro by typing @{name}
. So in this case @q
. @
also accepts a count, so we can just type 10@q
...
...and get back to our code.