vi and vim cheat sheet

Home

1 vi normal mode

The normal is the default when you start up vi or vim. Keys pressed here are interpretted as commands and do something rather than get entered as editing changes.

You have to enter a mode in order to add text to a document, for instance you enter the command i to switch to insert mode. Other commands in normal mode include d and related commands to delete things, y commands to yank (copy) them, and p to paste them back into the document, and : commands to execute some commands on the file. All this described below.

2 Cursor movement in normal mode:

2.1 Character or line at a time

           k
	   ^
           |
h  <--------------> l
           |
	   v
           j

(Or use left and right errors)

2.2 Word at a time or page at a time


         C-u
          ^
          |
b <--------------> w
          |             
          v
         C-d

2.3 Beginning or end of line



0 <--------------> $


2.4 High, Middle Low part of the screen

H
|
|
L		  

2.5 Whole document


  top of file
      1G
      ^
      |
      |             
      V
      G
bottom of file

3 Summarizing Moving Around (normal mode)

  • h move left one character
  • j move down one line
  • k move up one line
  • l move right one character
  • C-u page up
  • C-d page down

  • w move forward one word
  • b move backward one word

  • $ move to end of line
  • 0 move to front of line
  • ^ move to the first non-empty character

  • H move to highest pt of screen
  • M move to middle of screen
  • L move to bottom of screen

  • G move ('go') to end of document
  • 8G move ('go') to the 8th line in the document
  • 1G move ('go') to the 1st line in the document, i.e. the top
  • gg move ('go') to the top (same thing as 1G)

  • % when over a parenthesis, bracket or brace, move to the matching one (opening or closing). If the cursor does not move, you have a mismatch or syntax error

  • fo find the character 'o' on the current line only.

4 esc

When in another mode (i.e. not normal mode) the Escape key gets you out of input modes and back into command/normal mode. Escape also gets you out of the middle of a command sequence you don't want.

5 Yank and Pop (normal mode) this is actually copy

yank is a 2 character command, analogous to copy and paste

  • y yanks "copies" something, depending on the second letter
  • yl yanks a character
  • yw yanks a word
  • yy yanks a entire line

  • 3yl yanks 3 characters
  • 4yw yanks 4 words
  • 5yy yanks 5 lines

  • p puts back (pastes) what was yanked at the current line
  • P puts back (pastes) what was yanked before the current line
  • yyp duplicates a line

6 Editing through delete and change.

6.1 Deleting (normal mode)

Like yank, deleting is a 2 character command

  • dl deletes a letter
  • dw deletes a word
  • d$ deletes to end of line
  • d0 deletes to beginning of line
  • de delete to the end of the word (how is that different form dw?)
  • D deletes from the cursor to the end of the line
  • dd deletes the entire line
  • 3dd deletes 3 lines (from current line forward)
  • 3dw deletes 3 words (from current word forward)

  • x delete the single character under the cursor

  • 3x delete 3 characters under the cursor.
  • cw change word (to right of the cursor) by entering "change" you automatically are put into INSERT mode. cw is the same as dw followed by i as you delete a word and enter insert mode.

6.2 Combining delete and yank to move a section

Place the cursor at the top of the section you want to copy or delete (cut)

  • 7dd will delete the current and 7 lines
  • move to where you want to paste
  • p pastes back (puts back) the lines.

  • 7yy will copy the current and 7 lines
  • move to where you want to paste
  • p pastes the last yanked lines.

6.3 Insert and Append (insert mode)

  • i insert
  • I insert at the beginning of the line
  • a append
  • A append at the end of the line
  • o like append but opens a new line below the current line (so A-hammer is the same as o)
  • O like append but opens a new line above the current line
  • :r to read in a file at the current position of cursor

6.4 Changing / substituting text (normal mode)

Yes normal mode, but this enters insert mode in various ways. Change is also a two letter command

  • cw change word (equivalent to dw i)
  • cl change letter (easier to use r for 'replace) equivalent to xi<esc>
  • r replace a single letter (same as cl)
  • 3r replace the 3 characters
  • C changes everything from the cursor to the end of the line
  • J join the current line with

7 Undo (normal mode)

  • u undoes the last thing you did
  • U undoes ALl changes to the current line >as long as no other lines changed
  • . repeat Repeats the previous action (except cursor movements)
  • C-r to redo
  • if you press u after being in insert mode, then u will undo the WHOLE insert change.

8 Searching and replacing (normal mode)

  • / search forward for matching text
  • ? search backward for matching text
  • n repeats last search in the same direction ('next')
  • N same ir reverse direction

so /gem hammer n n n will search for gem and again 3 times.

8.1 find and replace, a.k.a. global substitute

vi (and vim) were built ontop of the line editor, ed. Since UofT circa 1982 used ed extensively, I should be very familiar with search and replace, as it uses the :s or :substitute command.

:s/findstring/ will move the cursor to the next instance of "findstring" Actually it will not move the cursor, only highlight all instances of the string you were looking for.

More power comes from searching for a text pattern, and replacing it with a text string. There are many options, but these are what you probably want:

  • :s/foo/bar/ Find each occurrence of 'foo' (in current line only), replace with 'bar'.
  • :%s/foo/bar/g
  • :%s/foo/bar/g
  • :%s/foo/bar/g in all lines
  • :%s/foo/bar/gc in all lines and ask for confirmation first.
  • :%s/\<foo\>/bar/gc Change only whole words exactly matching 'foo' to 'bar' ask for confirmation. Notice that the < and > characters needed to be escaped with the \ character.
  • :%s/foo/bar/gci all lines (g), case insensitive (i), ask for confirmation (c)
  • :%s/foo\c/bar/gc is the same because \c makes the search case insensitive. This may be wanted after using :set noignorecase to make searches case sensitive (the default).
  • :%s/foo/bar/gcI same as gci
  • g means globaleach occurrence in the line is changed, rather than just the first.
  • c confirmation. You need to confirm for each match what to do.

Vim will output something like: replace with foobar (y/n/a/q/l/E/Y)? (where foobar is the replacement part of the :s/…/…/ command. You can type

  • y yes substitute this match,
  • n no skip this match,
  • a all to substitute this and all remaining matches ("all" remaining matches),
  • q to quit the command,
  • l to substitute this match and quit (think of "last"),
  • ^E to scroll the screen up by holding the Ctrl-Shift-E and
  • ^Y to scroll the screen down by holding the Ctrl-Shift-Y
  1. Details:

    However, the last two choices are only available, if your Vim is a normal, big or huge built or the insertexpand feature was enabled at compile time (look for +insertexpand in the output of :version).

    Also when using the c flag, Vim will jump to the first match it finds starting from the top of the buffer and prompt you for confirmation to perform replacement on that match. Vim applies the IncSearch highlight group to the matched text to give you a visual cue as to which match it is operating on. Additionally, if more than one match is found and you have search highlighting enabled with :set hlsearch, Vim highlights the remaining matches with the Search highlight group. If you do use search highlighting, you should make sure that these two highlight groups are visually distinct or you won't be able to easily tell which match Vim is prompting you to substitute.

9 command mode (i.e. colon : )

You must be in normal mode for : to work. The colon character jumps your focus to the command area at the bottom of your screen. There you enter the command you want.

  • :w writes
  • :q quits
  • :wq writes and quits
  • :ZZ writes and exits
  • :q! quites without writting
  • :gg move up to the top of the file (I think)
  • :uu undo twice
  • =
  • :r filename Insert (or read) the file filename.
  • :r headers.py Insert the file headers.py below the cursor.
  • :0r headers.py Insert the file headers.py before the first line.
  • :r !uname -a Insert the output of uname -a below the cursor.
  • :$r !pwd Insert the current working directory below the last line.
  • :!date execute the shell command date and return to vim
  • :!unixcmd execute any unix shell command and return to vim
  • :Explore (available in vim only, and is a file explorer)
    • hammer to enter a new different
    • / to search

You can add a plugin to vim, like nerdtree. To close a VIM window use:

  • C-w c (window close)

9.1 split window horizontally

  • :sp (normal mode, so :sp)
  • C-Wj move to the to windows
  • C-Wk move to the bottom window
  • :tabnew

9.2 :help :w

gives you documentation on the keybinding :w

10 visual mode (v)

v followed by moving the cursor, selects that block, It is the same as an emacs "mark" command C-<space>

C-v to visual block mode. Then select over two characters, then select down as much as you need, the hit d for delete

This could be used to uncomment a block of code, but there is no way to do the reverse, and comment code using visual block mode.

This lets you copy a region, by selecting frist, then poressing 'y' to yank. the you can move somewhere and press 'p' for paste.

after selecting a region, can press ~ to change all to upper and lower case. it is a toggle.

11 modifiers ("i" for inside, "a" for "around")

This one combination key can make a big difference. Basically you can take what you already know with cw, dw, i.e. change and delete, and do it inside a construct. The constructs (or delimiters) could be tick, back-ticks, dirks, bra-kets, open, curly, I think that is it.

  • ' tick
  • ` back-tick
  • " dirk
  • [] bra-kets
  • () open close
  • {} curly

So the sequence is c or d then i (inside) or a (around) then the construct

  • ci change inside whatever. whaterver could be quotes, single or double, brakets, round, square or curly
  • ci' changes inside quotes
  • ci( changes inside round brackets
  • ci[ changes inside square brackets
  • ci{ changes inside curly brackets
  • ciw changes in word will delete the whole word the cursor is on, and switch to insert
  • caw changes all word (includes whitespaces within double "
  • di' deletes a single-quoted string, leaving the single quotation marks
  • da' deletes a single-quoted string, including the quotation marks
  • di[ deletes all stuff in the square brakets []
  • da[ deletes all stuff in the square brakets [] including the brakets
  • di{ deletes all stuff in the square brakets {}
  • da{ deletes all stuff in the square brakets {} including the brakets
  • di( deletes the contents inside the parenthesis ()
  • da( deletes the contents and around or including the parenthesis ()
  • yi) yanks everything inside the parenthesis
  • ya" yanks everything withing the dirks, including the dirks
  • yi} yanks everything inside the curly brackets.

Blow your mind time… You DON'T have to be within the construct for this technique to work. VIM will find the first occurance of that construct on the current line, and operate on it.

That bears repeating. VIM will find the first occurance of that construct oin the current line, and operate on it.

Practice changing the string inside each of these constructs:

first word second word { string } last word
first word second word ( string ) last word
first word second word " string " last word
first word second word ' string ' last word
first word second word {(" it ")} last word
  1. Troubleshooting modifiers

    Make sure you're not using a keyboard layout with "dead keys"; i.e. does pressing a single ' or " actually insert that character, or do you need to use "<Space>? If it's the latter, your keyboard layout has dead keys, and you must use ci"<Space> for Vim normal mode commands as well. '"

    Make sure that the characters are actually ' (0x27) and " (0x22) and not “ (U+201C or 0xe2 0x80 0x9c in UTF-8) or ‘ (U+2018, 0xe2 0x80 0x98) or any other quote variant.

    Check it by using the g8 or ga command, or for more information use the unicode.vim plugin (also see See the Unicode code point of the current character).

11.1 duplicating appends on multiple lines

after appending, or inserting some string, hit the following: $ i string <esc> j j . This adds "string" to the end of the current line, then jumps down two lines ( j j ) and adds "string" again to that line ("dot")

This will add "string" to the end of the line that is two down (j j)

12 setup using .vimrc

~/.vimrc has startup settings. There are plenty. For instance here is my .vimrc file:

" Comments in Vimscript start with a `"`.

" If you open this file in Vim, it'll be syntax highlighted for you.

" Vim is based on Vi. Setting `nocompatible` switches from the default
" Vi-compatibility mode and enables useful Vim functionality. This
" configuration option turns out not to be necessary for the file named
" '~/.vimrc', because Vim automatically enters nocompatible mode if that file
" is present. But we're including it here just in case this config file is
" loaded some other way (e.g. saved as `foo`, and then Vim started with
" `vim -u foo`).
set nocompatible

" Turn on syntax highlighting.
syntax on

" Disable the default Vim startup message.
set shortmess+=I

" Show line numbers.
set number

" This enables relative line numbering mode. With both number and
" relativenumber enabled, the current line shows the true line number, while
" all other lines (above and below) are numbered relative to the current line.
" This is useful because you can tell, at a glance, what count is needed to
" jump up or down to a particular line, by {count}k to go up or {count}j to go
" down.
set relativenumber

" Always show the status line at the bottom, even if you only have one window open.
set laststatus=2

" The backspace key has slightly unintuitive behavior by default. For example,
" by default, you can't backspace before the insertion point set with 'i'.
" This configuration makes backspace behave more reasonably, in that you can
" backspace over anything.
set backspace=indent,eol,start

" By default, Vim doesn't let you hide a buffer (i.e. have a buffer that isn't
" shown in any window) that has unsaved changes. This is to prevent you from "
" forgetting about unsaved changes and then quitting e.g. via `:qa!`. We find
" hidden buffers helpful enough to disable this protection. See `:help hidden`
" for more information on this.
set hidden

" This setting makes search case-insensitive when all characters in the string
" being searched are lowercase. However, the search becomes case-sensitive if
" it contains any capital letters. This makes searching more convenient.
set ignorecase
set smartcase

" Enable searching as you type, rather than waiting till you press enter.
set incsearch

" Unbind some useless/annoying default key bindings.
nmap Q <Nop> " 'Q' in normal mode enters Ex mode. You almost never want this.

" Disable audible bell because it's annoying.
set noerrorbells visualbell t_vb=

" Enable mouse support. You should avoid relying on this too much, but it can
" sometimes be convenient.
set mouse+=a

" Since I am also an emacs user, I prefer to use the arrow keys.  Therefore
" I will NOT follow the advice below, and allow arrow keys for movement
"
" Users for whom vi or vim is their preferred editor, read on, and uncomment
" as needed:
" Try to prevent bad habits like using the arrow keys for movement. This is
" not the only possible bad habit. For example, holding down the h/j/k/l keys
" for movement, rather than using more efficient movement commands, is also a
" bad habit. The former is enforceable through a .vimrc, while we don't know
" how to prevent the latter.
" Do this in normal mode...
" nnoremap <Left>  :echoe "Use h"<CR>
" nnoremap <Right> :echoe "Use l"<CR>
" nnoremap <Up>    :echoe "Use k"<CR>
" nnoremap <Down>  :echoe "Use j"<CR>
" ...and in insert mode
" inoremap <Left>  <ESC>:echoe "Use h"<CR>
" inoremap <Right> <ESC>:echoe "Use l"<CR>
" inoremap <Up>    <ESC>:echoe "Use k"<CR>
" inoremap <Down>  <ESC>:echoe "Use j"<CR>

colorscheme desert

12.1 colorsheme

Easy to change colorscheme to one of the built-in themes. All you do is: :colorscheme<space><tab>

As in :colorscheme desert

To find a different scheme, you can search vimcolors.com

Add this to your .vimrc colorscheme <desert> You can use: echo 'colorscheme <desert>' >> ~/.vimrc

12.1.1 :colorscheme can be shortened to :colo

12.2 What colorschemes are available?

You could "tab" through them all. Or, You can find your installed vim colorscheme files in the colors subdirectory of your vim installation directory. All the files end with the file extension .vim, and begin with the name of the colorscheme. As an example, I just found all these files in the /usr/share/vim/vim81/colors directory. (mac)

12.3 Home

13 other vim operating modes

13.1 insert mode (i)

<esc> to exit

13.2 replace mode (r)

aka overwrite mode <esc> to exit

13.3 seleciton (visual) (r)

13.4 selection (visual line) (shift-v)

13.5 selection (visual block) (C-v)

Commands used are after you select the block to do that hit

  • C-v
  • select the block, i.e. move your cursor, to where you want a block end
  • I to insert

Then you will be in INSERT mode.

  • go ahead and insert the text, then esc

You will have inserted the new text on ALL the lines in the block, even though you edited just the first line.

13.5.1 Replace a block

  • select block
  • r to replace the selected block
  • R to Replace (overwrite mode) this overwrite mode is different then the usual overwrite mode using r and replacing a character, or 3r replacing three characters

13.5.2 Summarizing:

  • C-v
  • move cursor
  • I
  • edit
  • esc
  1. That was I to insert, to the left of the Visual BLock

    You also have:

  2. R to replace
  3. A to add the the right of the Visual Block
  4. c to change the Visual Block

    every line in the block will be changed.

  5. $ to change to each end of line, wherever it may
    • C-v as usual
    • $ then move cursor down a few lines
    • A to append at the end of the line (where the $ had selected things. THIS IS A VERY GOOD WAY TO ADD ; to the end of every line.

13.6 command line mode (:)

13.7 Home