1. The Vim Way

  • Vim is optimized for repetition.
  • Craft our actions so that they perform a useful unit of work when replayed.

1.2 Don’t Repeat Yourself

  • Two for the Price of One
Compound Command Equivalent in LongHand Description
C c$ Change til end of line
s cl Change letter
S ^C Change entire line from the start of text
I ^i Insert from the start of text on this line
A $a Append at the end of line
D d$ Delete until the end of line
o A<CR> Insert at new line below
O ko Insert at new line above

1.4 Act, Repeat, Reverse

Intent Act Repeat Reverse
Make a change [edit] . u
Scan line for next character f{char}/t{char} ; ,
Scan line for previous character F{char}/T{char} ; ,
Scan document for next match /pattern<CR> n N
Scan document for previous match ?pattern<CR> n N
Perform substitution :s/target/replacement & u
Execute a sequence of changes qx{changes}q @x u

1.6 Meet the Dot Formula

  • The ideal: one keystroke to move, one keystroke to execute (the Dot formula).

2. Normal Mode

2.8 Chunk Your Undos

  • i{insert some text}<ESC> consitutes a change.
  • Moving around in insert mode resets change.
    • If we use the <Up>, <Down>, <Left>, or <Right> cursor keys while in insert mode, a new undo chunk is created. It’s just as though we had switched back to Normal mode to move around with the h, j, k or l commands, except that we don’t have to leave Insert mode.

2.10 Use Counts to Do Simple Arithmetic

  • The <C-a> and <C-x> commands perform addition and subtraction to the number at or after the cursor. (e.g., <C-a> increase the value by 1, 10<C-x> decrease value by 10.)
  • Vim considers any number with leading zeros to be octal numbers, so adding 1 to 007 will result in 010. To disable this behavior and treat numbers with leading zeros as decimals, add set nrformats-=octal to .vimrc file.

2.11 Don’t Count If You Can Repeat

  • Counting is tedious. Instead of using count and motion, try to use the dot command instead.
  • Although counting takes less key strokes, the time it takes to count is likely longer than using dot command.
  • Using the dot command also gives us a smaller unit of undo.

2.12 Combine and Conquer

  • When an operator command is invoked in duplicate, it acts upon the current line.
Operator Description
c change
d delete
y yank into register (does not change the text)
~ swap case (only if ‘tildeop’ is set)
g~ swap case
gu make lowercase
gU make uppercase
! filter through an external program
= filter through ‘equalprg’ or C-indenting if empty
gq text formatting
g? ROT13 encoding
> shift right
< shift left
zf define a fold
g@ call function set with the ‘operatorfunc’ option
  • Custom oprators work with existing motions example: Tim Pope’s commentary.vim.
  • Custom motions work with existing operators example: Kana Natsuno’s textobj-entire.

Meet Operator-Pending Mode

  • If we think of Vim as a finite-state machine, then Operator-Pending mode is a state that accepts only motion commands.
  • While Operator-Pending mode is active, we can return to Normal mode in the usual manner by pressing <ESC>, which aborts the operation.
  • For commands that are invoked by two or more keystrokes, they don’t initiate Operator-Pending mode. We can think of them as namespaces that expand the number of available command mappings.

3. Insert Mode

3.13 Make Corrections Instantly from Insert Mode

  • Just because we can switch modes doesn’t mean that we should.
  • Commands listed beblow behaves the same as bash shell.
Keystrokes Effect
<C-h> Delete back one character (backspace)
<C-w> Delete back one word
<C-u> Delete back to start of line

3.14 Get Back to Normal Mode

Keystrokes Effect (while under Insert mode)
<ESC> Switch to Normal mode
<C-[> Switch to Normal mode
<C-o> Switch to Insert Normal mode
  • Insert Normal mode is a special version of Normal mode, which gives us one bullet. We can fire off a single command, after which we’ll be returned to Insert mode immediatesly.
  • e.g., The zz command redraws the screen with the current line in the middle of the window. Use <C-o>zz to redraw current line at the middle of the screen while in Insert mode.

3.15 Paste from a Register Without Leaving Insert Mode

  • <C-r>0 pastes content yanked while in Insert mode.
  • In general, <C-r>{register} pastes a few words at {register}.
  • <C-r><C-p>{register} pastes in Insert mode and fix unwanted indentation. e.g.:
def greeting():
    print('Hello, world.')  # yy

    print('Hello, world.')  # <C-r>0
print('Hello, world.')  # <C-r><C-p>0

3.16 Do Back-of-the-Envelope Calculations in Place

  • The expression register can evaluate a piece of Vim script code and return the result. It’s triggered by the = symbol. While in Insert mode, this can be triggered by <C-r>= (e.g., <C-r>=3*2 insert 6 into text).

3.17 Insert Unusual Characters by Character Code

  • <C-v>{code} inserts character with code {code} (e.g., <C-v>065 inserts “A”, <C-v>u00bf inserts “¿").
  • Place cursor on a character (e.g. ¿) and use ga command to find out its numerical code.

3.18 Insert Unusual Characters by Digraph

  • Use <C-k>{char1}{char2} to insert characters by digraph (e.g., <C-k>?I inserts “¿", <C-k>12 inserts “½”).
  • Use :h digrah-table to look up available digraphs.

3.19 Overwrite Existing Text with Replace Mode

  • Use gR or gr for Virtual Replace mode. In Virtual Replace mode, a tabstop is treated as multiple characters instead of one character.

4. Visual Mode

4.20 Grok Visual Mode

  • Visual mode is just another mode, most of our navigation commands in Normal mode still works in Visual Mode. Each time we move our cursor in Visual mode, we change the bounds of the selection.
  • In Normal mode, we start with an operator then define the motion. In Visual mode, we only invoke the operator and it will be performed on selected text.
  • In Visual mode, use <C-g> to trigger Select mode, which will start replacing text in Visual mode after we start typing. However, a easier way to achieve this is just to use the c command.

4.21 Define a Visual Selection

  • Three kinds of Visual modes in Vim:
    1. Character-wise: select a single character up to a range of characters within a line or spanning multiple lines.
    2. Line-wise: select entire lines. 3. Block-wise: select columnar regions.
Command Effect
v Enable character-wise Visual mode
V Enable line-wise Visual mode
<C-v> Enable block-wise Visual mode
o (When in Visual mode) go to the other end of selected text
gv Reselect the last visual selection

4.23 Prefer Operators to Visual Commands Where Possible

  • The dot command works well with line-wise Visual mode, but sometimes doesn’t work well with character-wise Visual mode.
  • Perfer operator commands over their Visual mode equivalents when working through a repetitive set of changes.

4.24 Edit Tabular Data with Visual-Block Mode

  • When in Visual mode, using r{char} command will replace all selected text with {char}.

4.25 Change Columns of Text

  • When in block-wise Visual mode, use c to change all selected text on each line.

4.26 Append After a Ragged Visual Block

  • When in block-wise Visual mode, use A to append content at the end of each line. This does not work in line-wise or character-wise visual mode.
  • Since i and a will form the first half of a text object (“inside” and “a”) in Visual mode (or Operator-Pending mode), only I and A switch to Insert mode while in Visual mode.

5. Command-Line Mode

5.27 Meet Vim’s Command Line

Some Ex Commands That Operate on the Text in a Buffer

Command Effect
:[range]delete [x] Delete specified lines [into register x]
:[range]yank [x] Yank specified lines [into register x]
:[line]put [x] Put the text from register x after the specified line
:[range]copy {address} Copy the specified lines to below the line specified by {address}
:[range]move {address} Move the specified lines to below the line specified by {address}
:[range]join Join the specified lines
:[range]normal {commands} Execute Normal mode {commands} on each specified line
:[range]substitute/{pattern}/{string}/{flags} Replace occurrences of {pattern} with {string} on each specified line
:[range]global/{pattern}/[cmd] Execute the Ex command [cmd] on all specified lines where the {pattern} matches

5.28 Execute a Command on One or More Consecutive Lines

  • We can specify the start and end of a range with either a line number, a mark, or a pattern.
  • The :print (:p) command echoes the specified lines below Vim’s command line.

Use Line Numbers as an Address

  • :5 will jump to line 5.
  • :5p will jump to line 5 and print its content.

Specify a Range of Lines by Address

  • 2,5p prints the content on lines in range [2, 5] (1 based index).
  • '< and '> stands for the beginning and the end of visual selection respectively. These marks persists even after leaving Visual mode, they will use the last visual selection.
  • Use patterns as address: :/<html>/,/<\/html>/p will print contents starts with line <html> and ends with </html>.
  • :{address}+n is the general form of an offset. If n is ommited, it defaults to 1. The {address} could be a line number, a mark, or a pattern.
  • :/<html>/+1,/<\/html>/-1p modifies the original address using an offset, this will print the content inside the html tag.
  • :.,.+5p will print the current line and 5 lines below.


Symbol Address
l First line of the file
$ Last line of the file
0 Virtual line above first line of the file
. Line where the cursor is placed
'm Line containing mark m
'< Start of visual selection
'> End of visual selection
% The entire file
  • A [range] always represents a set of contiguous lines. It’s also possible to execute an Ex command on a set of noncontiguous lines using the :global command.

5.29 Duplicate or Move Lines Using :t and :m Commands

  • :t is the shorthand of :copy, :m is the shorthand of :move.
  • :[range]t {address} copies lines in range and place them in address. Similarly, :[range]m {address} moves lines in range to address.
Command Effect
:6t Copy line 6 to just below the current line
:t6 Copy the current line to just below line 6
:t. Duplicate the current line (similar to Normal mode yyp)
:t$ Copy the current line to the end of the file
`:‘<,‘>t0 | Copy the visually selected lines to the start of the file |
  • Note that [range] can sometimes be ommitted, it defaults to ., but {address} cannot be omitted.
  • yyp overrides the current value in the default register, :t. does not.

5.30 Run Normal Mode Commands Across a Range

  • Use :[range]normal {action} to run Normal mode commands across a range.
  • Before executing the specified Normal mode command on each line, Vim moves the cursor to the beginning of the line.

5.31 Repeat the Last Ex Command

  • @: repeats the last Ex command.
  • After executing @: for the first time, we can use @@ to repeat it.
  • Use <C-o> to reverse the effect of last Ex command.

5.32 Tab-Complete Your Ex Commands

  • The <C-d> command asks Vim to reveal a list of possible completions.
  • Use <S-Tab> to scroll backward through the suggestions.

5.33 Insert the Current Word at the Command Prompt

  • Use <C-r><C-w> to copy the word under the cursor and insert s it at the command-line prompt.
Command Description
<C-r><C-f> Insert the Filename under the cursor.
<C-r><C-p> Insert the Filename under the cursor, expanded with ‘path’ as in
<C-r><C-w> Insert the Word under the cursor.
<C-r><C-a> Insert the WORD under the cursor.

5.34 Recall Commands from History

  • Ex command line is preserved even after we quit Vim.
  • Use {cmd1} | {cmd2} to execute multiple commands.
Command Description
q/ Open the command-line window with history of searches.
q: Open the command-line window with history of Ex commands.
<C-f> Switch from Command-Line mode to the command-line window.

5.35 Run Commands in the Shell

  • % represents the current file in Vim’s command-line.
  • :shell brings up shell, and alternative would be using <C-z> to suspend Vim, and use the $ fg command in shell to resume the process. We can use $ jobs to list suspended processes.
  • :read !{cmd} lets us direct standard output into a buffer, :write !{cmd} directs buffer into standard input of {cmd}.
  • WARNING: while :write !sh and :write ! sh directs buffer content into command sh, :write! sh writes content of buffer into a file named “sh” (the bang tells it to override content of any existing “sh”).
  • :[range] !{cmd} takes lines specified in [range] and pass them as standard input for the {cmd}, and then the output from {cmd} overrides the original content of [range] (e.g., 0,$ !sort will sort the entire file).
  • Vim defines a filter as “a program that accepts text as standard input, changse it in some way, and sends it to standard output.
  • !{motion} (in Normal mode) is a shortcut for typing out :[range]. e.g, !2j will open up Ex command-line with :.,+2!.

5.36 Run Multiple Ex Commands as a Batch

  • Use :source script.vim to run Vim script on current file.
  • If Vim has multiple files open (use :args to check all files), we can use :argdo source script.vim to run Vim script on multiple files at once.


While in insert mode:

Command Effect
<Alt-o> opens a new line below the one you are currently editing
<Alt-A> appends to the end of the current line
<Alt-p> pastes content at current register (same as <C-r>0)
<Alt-j> moves down (and exit Insert mode)
<Alt-k> moves up (and exit Insert mode)

Tmux Notes

Shell Commands

Command Description
tmux new -s [session-name] -n [window-name] -d Creates a new session and window with name in the background (does not attach automatically).
tmux kill-session [session-name] Kills session with name.


Command Description
<PREFIX-d> Detach current session.
<PREFIX-$> Rename session.


Command Description
<PREFIX-n> Go to next window.
<PREFIX-p> Go to previous window.
<PREFIX-{number}> Go to the {number}th window.
<PREFIX-w> Displays a selectable list of windows in the current session.
<PREFIX-f> Find window by name.
<PREFIX-,> Rename window.
<PREFIX-&> Kill current window.
:new-window -n {window-name} "{program-to-execute}" Opens a new window, and execute program. If program exits, window disappears.


Command Description
<PREFIX-o> Cycle through panes.
<PREFIX-␣> Cycle through built-in pane styles.
<PREFIX-x> Kill current pane.
<PREFIX-q> Momentarily displays pane numbers in each pane.
<PREFIX-!> Turn pane into a window.

Copying and Pasting

  • <PREFIX-[> enables Copy mode, press to start selecting text, and press <CR> to copy text. Use <PREFIX-]> to paste text.
  • Use :capture-pane command to copy content on the entire pane, :show-buffer (or $ tmux show-buffer in shell) to view the content in the buffer.
  • Use save-buffer {path-to-file} to save content in buffer to given destination.
  • :list-buffers lists all text copied in buffers. :choose-buffer will give you can option to choose a buffer and insert it into current cursor position.


Command Description
<PREFIX-t> Shows clock.
<PREFIX-?> List all predefined tmux keybindings.
  • Use tmux -f {path-to-config-file} a to start tmux while referencing a specific config file. The a at the end of command stands for “attach”, so even if there is already a session with given name, it will simply attach to that session instead of creating a new one.