Wills' Projects: Vi, VIm, and Friends
A Brief History
Historically, vi (the "VIsual editor") is a front end to a family of other editors including 'ex' and 'ed'. These are roughly analogous to DOS' edlin.
vi's sources were originally licensed in such a proprietary way that the only way to have vi on Linux-based systems was to use a clone. The most revered is VIm (Vi IMproved), which amongst other plus points has a "minimal" implementation for use as /bin/vi, and extended features [and a "compatibility" mode] when built for use as /usr/bin/vim and/or /usr/bin/gvim (the GUI version).
Even VIm's "minimal" implementation is a bit bloaty for embedded class systems, however, and the alternative you'll find in use will either be a workalike (BWIM editor with vi key bindings), or the vi applet belonging to the 'busybox' utility. As one might suspect, busybox-vi does not implement everything listed here; in other cases, the behaviour differs in some slight way.
Basic Philosophy
Designed for use over a slow network link, vi is one of the most powerful text editors you will ever use. Because you'll probably very rarely use meta-keys other than shift, you should never need to move your hands far from the 'home' position - making vi incredibly efficient in the hands of a touch typist.
Bare Essentials
vi starts in "command mode" by default, where any keypress performs some operation. Some operations leave vi in command mode, and some enter insert mode - from which the Escape key exits at the end of your text entry. Pressing shift often invokes a related variant of some operations (although sometimes it's a different command entirely) - see notes in brackets.
All vi clones support at least the following:
| Keys/Command | Behaviour |
|---|---|
| h,j,k,l | Single-character movement [left, down, up, right]. |
| i(I)...<Esc> | Insert at cursor (at start of line - ignore spaces). |
| a(A)...<Esc> | Append text [after cursor] (at end of line). |
| r<c> | Replace character under cursor with <c> |
| s...<Esc> | Substitute character under cursor for specified text. |
| x | Delete character at cursor [place into cut buffer]. |
| p(P) | Paste cut buffer into text after (at) cursor/current line |
| /...<Enter> | Search for specified regexp (use ? for backwards) |
| n | Find next match (N to reverse direction) |
| u | Undo/redo (vi - see Vim Specifics) |
| ^L,^R | Redraw editor screen [when background processes have corrupted the display] |
Although there are 'vi' commands to save, it's often less confusing to use the 'ex' command line by pressing : in command mode, where the following are useful:
| Keys/Command | Behaviour |
|---|---|
| :<n> | Go to line <n> |
| :w | Enter 'ex' command mode; save the file. |
| :wq | Enter 'ex' command mode; save file and quit |
| :q | Enter 'ex' command mode; quit (unless not saved) |
| :q! | Enter 'ex' command mode; quit (even if unsaved) |
| :w! | Enter 'ex' command mode; save (if flagged read-only) |
All 'vi' commands can be repeated by prefixing a number; for example 10j moves ten characters to the left, and 4r replaces a four-character string [with four copies of the character you specify] - compare and contrast to 4s, whereby insert mode means any alternative text [ie, a replacement string of any length].
Advanced Movement
| Keys/Command | Behaviour |
|---|---|
| H,M,L | Move cursor to highest/middle/lowest line of screen |
| <n>gg | Go to line <n> [in file] |
| G | move to end of file |
| ^,$ | Go to start/end of line (cf. regular expressions) |
| w,e,b | Move forward/back one word |
| {,},2{,2} | Move forward/back one [two] paragraph[s] |
| m<c> | Set marker with name <c> |
| `<c> | Go to mark named <c> |
| `` | Go to position of last change |
| % | Find matching brackets - works for (/),[/],{/} |
| ^D,^U | Move up/down half a screenful |
Complex Operations
As well as repeating a command by using a numeric prefix, the more complex commands require an "operating region". There is often a default region, which you override by specifying a movement command.
| Keys/Command | Behaviour |
|---|---|
| <<,>> | Indent or outdent current line |
| <%,>% | Indent or outdent region - eg. block of code. |
| dd | Delete (current line) |
| 3dw | Delete three words |
| cc...<Esc> | Change (current line) |
| c}...<Esc> | Rewrite rest of paragraph |
| yy | "Yank" (current line) into cut buffer |
| 3yw,3ye | Yank "words" into cut buffer |
Miscellany - Cut Buffers
If you've done several delete/change/subsitute/etc commands, 'undo' might not do what you want (especially in 'vi'). There is a ten-level history of such changes, all recoverable with prefixes to p or P [ie., the paste command]. There are also twenty-six lettered buffers, which you can employ at will, viz:
| Keys/Command | Behaviour |
|---|---|
| "1p | Paste the last change-history buffer (same as p alone) |
| "<n>P | Same, but for buffer <n> |
| "ayy | Yank current line to buffer 'a' |
| "<c>2yy | Yank [two] lines to buffer <c> |
Miscellany - Other
Also useful:
| Keys/Command | Behaviour |
|---|---|
| :help | Help page {VIm only - not a standard 'ex' command} |
| ^G | Show current file, file size, whether modified |
| J | Join two lines |
| K | Search the manual pages for keyword under cursor {VIm} |
| xp | (Compound) Swap two characters |
| eas<Esc> | (Compound) Pluralise word |
| ~ | Change character case, and move to next |
| :set nu | Short for 'number' - line numbers. (nonu -> off) |
| :set all | Show all settings |
| :set | Show only settings which are not at default |
| :e! | Abandon current changes; reload current file |
| :e <filename> | Load specified file (use e! if current buffer unsaved) |
| :r <filename> | Read (insert) specified file |
| :n <filenames> | Edit each file in turn - add ! as above |
| :n | Short for 'next' - move to next file in list |
| :prev | Short for 'previous' - move back one file in list |
| :!... | Execute command ... in shell |
| !!... | Execute command ...; paste output into current line |
VIm Specifics
VIm has a number of extensions which reflect functionality in modern text editors, including multi-level undo. Relevant controls include:
| Keys/Command | Behaviour |
|---|---|
| u | Undo (always) |
| U | Undo/redo (as per u in classic vi) |
| ^R | Redo (beware your terminal reacting to ^R) |
| :set compatible | Turn (most) VIm extensions off |
| :set ff=unix | Force VIm to save with unix newlines (for DOS files) |
| :split | Enter split-screen mode, filename optional. :qa quits editor |
| ^Wj,^Wk | Move up/down between 'split' windows |




