I try to avoid editor advocacy as a rule but when I do see people using vi/vim, I am an advocate of squeezing out some of its potential.
Most introductions to vim focus on getting you able to type words in and move around in the file and neglect to mention that vim has “physics”.
The two primary physics of vim that I’m aware of are:
- motion - like “hjkl” (one character in any direction) while in normal mode.
- edit - like “ifoo[esc]” (insert foo at current cursor position) again while in normal mode.
Secondarily, you have some extra stuff related to:
- viewport - like “zt” (zoom cursor to top) while in normal mode
- commands - like “:%s/a/b/g” (substitute all ‘a’ characters to ‘b’) in “command” mode
- “normal mode” commands - like “y”, “p” (yank, paste)
- register modification - like “”ay” (register: ‘a’, yank)
Basically anything that changes the text when you start it from normal mode is an edit. Anything that changes your cursor position but doesn’t change the text is a motion.
Things that don’t move your cursor, don’t affect the text, and just change what shows up on the screen are viewport operations. Commands/registers are where you get into the dark underbelly of vim’s power. I mention them here like you would mention calculus in an algebra class… it’s important to know that it’s there so you can hand-wave and say: “You’ll learn why this thing behaves funny later on”.
Viewport Operations
The simplest of these things to explain are the major viewport commands although most people are not even aware of them.
- z[cr] / zt - zoom / move cursor to top of screen
- zz - zoom / move cursor to middle of screen
- zb - zoom / move cursor to bottom of screen
- [c-y] - shift view line up
- [c-e] - shift view line down
- [c-b] - shift view page up
- [c-f] - shift view page down
These are the simplest because they don’t actually change anything in the file, they don’t change your cursor position, they don’t change text, they are basically invisible in the “editing physics” of vim. If you work with split windows then this also includes things like the
Motion Operations
The next simplest thing to explain is motion. Key point here is that ANYTHING THAT MOVES YOUR CURSOR (that isn’t an edit) IS A MOTION.
- hjkl - motion, move cursor
- ←,→,↑,↓ - motion, move cursor
- 0,$,^,[home],[end] - motion, beginning, end of line
- /foo[cr] - motion, search
- fa,ta - motion, “find ‘a’” / “until ‘a’”
- w,b - motion - next, previous word
- HLM - motion - High, Low, Middle move cursor
- *,# - motion - previous, next search word under cursor
- n,N - motion - next, previous search
- etc, etc, etc.
The interesting thing is that there are so many different motion commands. That’s why when you see an experienced vim user, they jump around in a file like their cursor is under mind control. With so many different ways to move around it pretty much is, and without using the mouse and without relying on keyboard repeat.
The counterexample to this is how basic editors require you to mash down the right or left arrow, overshoot the point in the line you’re looking for, tap tap tap backwards in order to get your cursor where you want it, then start typing or deleting, etc. Basic editors only allow cursor motion via arrow keys or mouse clicks which is severely limiting compared to the number of ways you can move around in vim.
When I’m looking for “the beginning of the function” in vim, I do “/function foo[cr]” and it takes me right there. If I want to get the beginning of the function arguments list, I do “f(” (find left-paren). No no holding down the right arrow, no moving my hand to the mouse, no popping up a dialog box. I’m just right where I want to be.
Motion is the workhorse of vim and one of the big advantages of using vim compared to any other “basic” editor.
Edit Operations
Honestly, editing in vim is kindof boring.
- iIoOaA - basic ways to get into insert mode
- R - get into replace mode (overtype)
- r - replace one character
- c[motion],d[motion] - change / delete text
- pP - paste text
- . - repeat last edit
- 3
- repeat the subsequent edit 3 times
If you’re paying close attention you’ll see that the “c” (change) and “d” (delete) commands take a
Going back to the example of finding a function (/function foo[cr], f(), if you want to move to the end of the function argument list, f) (find right-paren). If you want to df), you’ve just done an edit to delete until you find a paren. If you want to change what’s in there: cf). The “move” is f), the “edit” is either “d” or “c”. Zero friction between moving and editing.
This cannot be overstated: Learn your motions.
Motion is a fundamental “physic” of vim. As universal and inexorable as gravity, motion magnifies both your editing speed and your editing power. Speed because you can get your cursor precisely where you want as quickly as possible. Power because the basic editing tools of “c” (change) and “d” (delete) take ANY motion as a parameter, even the usually useless ones.
Take for example “HML” (move cursor to high, medium, low position on the screen). “dH” deletes from wherever your cursor is to the top of the screen. Why would you want to do that? I have no clue. But because “d” doesn’t care, it just does what you say to. Delete the motion.
A more relevant example might be: “Hd/foo[cr]”. Go “high” then delete everything until “foo”. Remember, search is a motion because it moves the cursor!
Motion in vim is your key to speed and power.
Repetition
The other interesting thing about editing in vim is that if you can find a way to compose your goal in a single “edit” (ie: I//[esc] insert “//” at the beginning of the line), you can repeat that same edit by moving somewhere, then pressing the . (period / repeat) key.
That becomes incredibly useful when commenting things out, when changing “FooType a;” to “BarType a;” in selected places… just queue up the change that you want (cwBarType[esc], do some searches (/FooType[cr]), hit “n” (next) until you find the right ones, then “.” to make the change. “nnn.n.nn.”. Next next next, change, next, change, next, change, next, next, change. It’s quick, useful, and reduces the possiblity for simple typing errors. You’re taken directly to the spot you want to evaluate, and the only button you have to push is “.” in order to repeat the same change you made before.
The naysayers will say “well my editor has a dialog box for search and replace”, which is all well and good. But the repeat “.” command allows you to repeat any edit. And many edits can involve arbitrary motion commands, meaning you’re not limited to replace AAA with BBB, but you can use the “cw” (change word) or “df,” (delete finding a comma) edits which is strictly more powerful than the usual simple search and replace dialog.
The repeat command (prefix an edit or a motion with a “count”) is interesting to explore too. “80i-[esc]” will repeat the “insert a single dash” edit 80 times. “i-[esc]79.” or you can insert the dash once and then repeat the edit 79 times. This works equally well with “J” or “d” or any other editing command. Although the results might not be useful, vim won’t stop you from doing it.
For things that are “too big” for one simple edit, you end up getting into macro-recording (“q, @”) which isn’t very complicated but doesn’t actually fit into the category of “editing”.
Commands, Registers, other “modes”
That leaves commands, registers, and other “modes”, all of which most people can live without in the sense that if you know “enough” about visual selection, and a basic “:%s/foo/bar/g” you’ll get by just fine.
Do some reading on “:help modes”, take a peek at “:registers” and “:help registers” as well as “:help recording” and “:help macro” if you’re interested in yet more tricks to speed up certain editing operations.
Summary
What helped me the most when learning vim was the advice: “Think Bigger”.
In most other editors, you think in mashing letters to insert them and the biggest motions you have are page-up and page-down.
Vim is different and especially powerful because it lets you think in terms of characters (hjkl), words (wbe), sentences (()), paragraphs ({}), programming blocks (vi{, vi(), etc.), precisely “find me then next ‘y’ on this line” (fy, Fy), and hugely (ggdG), usually with tremendous precision and no more than a few keystrokes.
Instead of thinking “I need to delete about 100 characters” think “I need to delete until the end of the line (d$)”.
Instead of thinking “I need to highlight a bunch of lines” think “I need to select the contents of this block (vi{)”.
By training yourself to think bigger you’ll eventually be able to edit better.
16:34 CST | category / entries
permanent link | comments?