Vim is a Command Line Interfacetext editor.
Famous StackOverflow answer on learning Vim: Your problem with Vim is that you don’t grok vi
Terminology
- Tabs: containers for windows
- Windows: to view buffers
- Buffers: act as file proxies (1-to-1) and arglist viewer
Command line
Start Vim with no config
vi -u NONE
Start Vim with vertical splits
vi -O <filename>
Movement
Navigation in buffers:
| Key | Movement |
|---|
| <CTRL-U> | Up half a screen |
| <CTRL-D> | Down half a screen |
| H | Top (high) of screen |
| M | Middle of screen |
| L | End (low) of screen |
| zt | Put cursor to top |
| zz | Put cursor to middle |
| zb | Put cursor to bottom |
| <CTRL-Y> | Up (Backwards) a line |
| <CTRL-E> | Down (Forwards) a line |
| <CTRL-B> | Up (Backwards) a full screen |
| <CTRL-F> | Down (Forwards) a full screen |
Modes
| Mode | Sample Keystrokes |
|---|
| Normal Mode | Esc |
| Insert Mode | i, a, c |
| Visual Mode | v, V, <Ctrl-v> |
| Command-line Mode | :, / |
Operators
| c | change |
| d | delete |
| y | yank in to register |
| ~ | switch case |
| gu | make lowercase |
| gU | make uppercase |
| ! | filter to external program |
| < | shift left |
| > | shift right |
| = | indent |
Text Objects
| Key Pressed | Text Object Selected |
|---|
| aw | a word |
| iw | inner word |
| aW | a WORD |
| iW | inner WORD |
| ap | a paragraph |
| ip | inner paragraph |
| ab | a bracket |
| ib | inner bracket |
| at | a tag block |
| it | inner tag block |
NB. Capitals skip punctuation
Motions
| Key Pressed | Action Performed |
|---|
| % | go to first matching paren/bracket |
| [count]+ | down to first non-blank char of line |
| [count]$ | to end of line |
| [count]f/F{char} | to next occurance of {char} |
| [count]t/T{char} | to before next occurance of {char} |
| [count]h/j/k/l | left, down, up, right |
| [count]]m | to beginning of next method |
| [count]w/W | go a word / WORD to the right |
| [count]b/B | go a word / WORD to the left |
| [count]e/E | go to end of word / WORD right |
NB. Capitals skip punctuation
Examples of combining count, operator, object and motion
| Keys Pressed | Action Performed |
|---|
| 6+ | 6x go down to line start |
| gUaW | capitalize a WORD |
| 3ce | 3x change to word end |
| 4$ | 4x end of line |
| d]m | delete to start of next method |
| % | jump to next paren./bracket |
Buffers & Arglist
Buffers are for everything you open in a Vim session.
Arglist is the files Vim was supplied with when opened first.
| Key | Action |
|---|
| <CTRL-^> | Switch buffers |
| :bn | Next buffer |
| :b {filename} | go to buffer with {filename} |
| :bd | Delete buffer |
| :buffers | Show all buffers |
| :n | go to next file (based on arglist) |
| :arga {filename} | Add {filename} to arglist |
| :argl {files} | male a local arg copy via {files} |
| :args | show all args on arglist |
Clipboard
From normal mode (press ESC to enter):
| Key | Action |
|---|
| v | Start selection (Enables [v]isual mode) |
| <Shift-v> | Start line selection |
| <CTRL-v> | Start block selection |
| yy | yank (copy) current selection |
| P | paste before |
| p | paste after |
| :registers | see what is stored to be pasted |
Searching
is carriage return (aka. Enter key).
| Key | Action |
|---|
| /{patt}[/]<CR> | search for {patt} |
| /<CR> | search for last used pattern |
| ?{patt}[?]<CR> | search backwards for {patt} |
| ?<CR> | search backwards for last used pattern |
| [count]n | repeat search [count] times |
| [count]N | repeat search backwards [count] times |
| * | search forward for word under cursor |
| # | search backward for word under cursor |
| gd | go to local declaration |
| :hls! | toggle search highlighting |
Marks
is carriage return (aka. Enter key).
| Key | Action |
|---|
| m{a-zA-Z} | set a mark at a char of {a-z} or {A-Z} |
| `{a-zA-z} | jump to mark set at char |
| :marks | show all marks set |
| `. | jump to last change |
| Key | Action |
|---|
| g<CTRL-]> | Show definitions |
| <CTRL-]> | Jump to keyword definition |
| <CTRL-t> | pop from tag stack |
Jumplist & Changelist
Jumplist:
| Key | Action |
|---|
| <CTRL-O> | Cycle through jumps (backwards) |
| <CTRL-I> | Cycle through jumps (forwards) |
| :jumps | List all jumps |
Changelist:
| Key | Action |
|---|
| g; | Cycle through changes |
| g, | Cycle through changes |
| :changes | List all jumps |
Quickfix list:
| Key | Action |
|---|
| :cn | Next on QuickFix list |
| :cn | Previous on QuickFix list |
Windows
Windows are viewports for buffers
| Key | Action |
|---|
| <Ctrl-w> s | Split window |
| <Ctrl-w> v | Split window vertically |
| <Ctrl-w> q | Close window |
| <Ctrl-w> w | Move cursor to alternate windows |
| <Ctrl-w> o | Make buffer only one in window |
| <Ctrl-w> x | Swap windows |
| <Ctrl-w> r | Rotate windows |
| :windo {CMD} | Execute command for all windows |
| :sf {FILE} | split window and find file |
| :vert {CMD} | Make any split {cmd} be vertical |
Tabs
Tabs are collections of windows.
| Key | Action |
|---|
| gt | Go to next tab |
| gT | Go to previous tab |
| :tabc | Close Tab |
| :tabe | Open Tab |
| :tabo | Close all other tabs |
Vim as an IDE
| Key | Action |
|---|
| :20vs . | Use netw to view files in 20 char split |
| :find <filename> | Can find and open <filename> |
| :vert sf <filename> | split a search for <filename>, open in split |
| <CTRL-W> x | swap windows |
| :tabf <filename> | open tab with <filename> (not affect existing win) |
| :vert sf <filename> | split a search for <filename>, open in split |
| p | On <filename> in netrc, will preview |
| <Ctrl-w> z | Close preview window |
| <Ctrl-w> o | Make buffer only one in window |
| :args | See what vim was opened with |
| :args */.yaml | Make arglist all YAML files |
| :sall | Split all files in arglist |
| :vert sa | Vertically split all files |
| :windo difft | do a diff for every file in window |
| <CTRL-X> | |
| <CTRL-L> | |
| gT | go back to previous tab |
| gt | go to next tab |
| :vimgrep TODO % | find all todos in current file |
| :cn | next on quickfix list |
| @ | repeat command |
| :args */.py | add all python files to arglist |
| :vim TODO ## | vimgrep through all on argslist |
| :cn | can see all files on arglist are search and move |
| :cdo s/TODO/DONE/g | replace all TODOs with DONE on every line |
| :cp | can see previous in QuickFix (all are changed) |
See also: Emacs