VI Cheat


Most commands in vi have the following form
[n] operator

5x delete 5 characters
3fG forward to third G on line
2tO forward to character before second O on line
3Tc backward to after the third c
20j move cursor down 20 lines
5H move cursor 5 lines from top of screen
5rx replace next 5 characters with x
5$ move to end of 5th line down (line 1 is current)

Editing commands (c, d, y, >, <, !) have the following form
[n] operator [m] object
An object in vi would be a character or a word or a line or a sentence etc. Basic operators for editing are

c begin a change
d begin a delete
y begin a yank

If the current line is the object of the operator then the object is the same as the operator: cc, dd, yy.
If both n and m are specified the effect is n * m, that is n multiplied by m.

cw change word
c$ change to end of current line
5dd delete next five lines
d5G delete to line 5
dG delete to end of file
de delete to end of word
d^ delete to beginning of current line
yy yank current line
y'z yank to line marked with z
yL yank to bottom of screen

Commands in vi are not echoed to the screen except the following.
These are echoed on the status line.

/ search forward for pattern
? search backward for pattern
: invoke an ex command
! invoke a unix (OS) command that takes as its input an object in the buffer, and replaces it with output from the command

The above commands are completed by pressing the return key. A buffer in vi would refer to the file as it's kept in memory <, >, and ! can also be combined with a movement command like c, d, and y

>> indent current line one shiftwidth
5<< outdent 5 lines starting with current
/hello search forward for word 'hello'

Back to top
(Part I/b)


( commands and command combinations to get you started in vi )

by character
h cursor left
j cursor down
k cursor up
l cursor right
space cursor right
by line
[n]G to line n
0, $ first, last position on line
+, - first character on next, previous line
^, _ first character on current line (other than tab or space)
by screen
^F, ^B scroll forward, backward one screen
^D, ^U scroll forward, backward half screen
^E, ^Y show one more line at bottom, top of screen
z<enter> position line with cursor at top of screen
z. position line with cursor at middle of screen
z- position line with cursor at bottom of screen
marking position on screen
mz mark current position with z
`z move cursor to mark z
'z move cursor to first non-whitespace character on line containing mark z
miscellaneous movement
fG forward to character G
Fd backward to character d
tg forward to character before g
Tw backward to character after w
w beginning of next word
W beginning of next WORD (punctuation is part of word)
b back one word
B back one WORD (punctuation is part of word)
e end of word
E end of WORD (punctuation is part of word)
), ( next, previous sentence
]], [[ next, previous section
}, { next, previous paragraph
( this will depend on your settings for what constitutes a "section" and "paragraph" )

inserting text
a append after cursor
A append at end of line (same as $a)
i insert before cursor
I insert at beginning of line (same as _i)
o open line below cursor
O open line above cursor
^[ terminate insert mode (escape)

Back to top
(Part I/c)


( ^A stands for <control-A> ) If there is an X in the count column then the command can be preceded by a number and the command then is executed count times. If the command is an editing command such as a or i, then you'll have to hit escape for the execution to happen count times. See example in Part I/a.
A word consists of [a-zA-Z_] and a WORD consists of previous plus punctuation, basically delimited by whitespace.

Count Command Action
X a append after cursor
X A append at end of line (same as $a)
^A unused
X b back up one word
X B back up one WORD
X ^B scroll up one screen
X c begin a change (combine with movement command)
X C change line from cursor to end of line (same as c$)
^C abort current ex command;
in insert mode : end insert mode
X d begin a delete (combine with movement command)
X D delete from cursor to end of line (same as d$)
X ^D scroll down a half screen;
in insert mode : back up one shiftwidth
X e goto end of word
X E goto end of WORD
X ^E show one more line at bottom of screen
X f forward to next typed character
X F backward to next typed character
X ^F scroll down one screen
g unused
X G goto count line; default is end of file
^G print file info on status line (bottom of screen)
X h cursor left
X H goto top of screen;
count will place you that many lines from top of screen
X ^H cursor left;
in insert mode : backspace
X i insert before cursor
X I insert at beginning of line (same as _i)
^I unused;
in insert mode : tab key
X j cursor down
X J join two lines
X ^J cursor down;
in insert mode : same as enter
X k cursor up
K unused
^K unused
X l cursor right
X L goto bottom of screen;
count will place you that many lines from bottom of screen
^L redraw screen, usually
m mark current cursor position with character typed (a-z)
M goto middle of screen
X ^M goto first character on next line;
in insert mode : same as enter key
n repeat last search command
N repeat last search command in reverse direction
X ^N cursor down
X o open a new line below the cursor
X O open a new line above the cursor
^O unused
X p put yanked or deleted text after or below cursor
X P put yanked or deleted text before or above cursor
X ^P cursor up
q unused
Q quit vi, invoke ex (not very useful) return with vi
^Q unused (some terminals, stop data flow)
X r change character under cursor to character typed
X R replace characters (overwrite mode)
^R redraw screen, usually
X s substitute characters under cursor to ones typed
X S substitute entire line
^S unused (on some terminals, resume data flow)
X t forward to before next character typed
X T backward to after next character typed
^T goto previous tag;
in insert mode : move right one shiftwidth
u undo last change
U restore current line
X ^U scroll screen up a half screen;
in insert mode : delete back to start of insert (depends on terminal settings)
v unused
V unused
^V unused;
in insert mode : quote next character
X w forward one word
X W forward one WORD
^W unused;
in insert mode : back up to beginning of word (depends on terminal settings)
X x delete character under cursor
X X delete back one character
^X unused
X y begin a yank (combine with movement command)
X Y yank current line (same as yy) (map it to y$ to be consistent with D and C)
X ^Y show one more line at top of screen
z<enter> reposition line with cursor to top of screen
z. reposition line with cursor to middle of screen
z- reposition line with cursor to bottom of screen
ZZ quit vi, write file if changes were made
^Z suspend vi on systems that have job control (depends on terminal settings)
^@ unused
^[ terminate insert mode (escape key)
^ unused?
^] goto tag under cursor
^^ edit alternate file
^_ unused?
^? unused? delete key?
X space cursor right
! filter program through external filter, requires an object to work on
(combine with movement command) (press enter to execute)
" use register for next delete, yank or put, registers are (a-zA-Z0-9)
# unused?
X $ goto end of line
% goto matching bracket () [] {}
& repeat last substitute
' to first non-blank character on line with mark (a-z)
X ( beginning of next sentence
X ) beginning of current sentence
(sentence is delimited by ., !, ? and followed by at least one space)
* unused?
X + down one line to first non-blank character (j_)
X , repeat f, F, t, T commands in reverse direction
X - up one line to first non-blank character (k_)
. repeat previous command
/ search forward for text entered
(repeat previous search if no argument supplied) (press enter to execute)
0 goto beginning of line
: enter an ex command (press enter to execute)
X ; repeat f, F, t, T commands
X < begin a shift left (combine with movement command)
= unused
(unless in lisp mode in which case it formats to standard lisp formatting)
X > begin a shift right
? search backward for text entered
(repeat previous search backward if no argument supplied) (press enter to execute)
@ execute a register (0-9a-z".)
X [[ beginning of current section (as delimited by the sect= option)
X ]] beginning of next section (as delimited by the sect= option)
^ goto first non-blank character on line
X _ goto first non-blank character on line
` goto mark (a-z)
X { beginning of current paragraph
(as delimited by a blank line or the para= option)
X | goto count column, default is beginning of line
X } beginning of next paragraph (as delimited by a blank line or the para= option)
X ~ change case of character under cursor

Most vi commands can be remapped. Here are some good ones.
map ^N :n^M
map ^P :rew^M
map Y y$
map ^K :q!^M
map g 1G
Control characters will have to be quoted with ^V, that is <control-V>

Back to top
(Part II/a)


0 beginning of file
$ end of file
1,$ all lines in file
% stands for filename, hence it means the entire file (1,$)
# stands for alternate file
x,y lines x through y
x;y lines x through y, current line reset to x
. current line
n absolute line number n
x-n n lines before x
x+n n lines after x
+[n] n lines ahead (default is one)
-[n] n lines back (default is one)
'x line marked with x
'' previous mark (that's two single quotes)
/pattern/ forward to line matching pattern
?pattern? backward to line matching pattern

Back to top
(Part II/b)


 | abbreviate  ab      | move        m      | tag               ta   | | append      a       | next        n      | unabbreviate      una  | | args        ar      | number      # nu   | undo              u    | | change      c       | open        o      | unmap             unm  | | chdir       cd chd  | preserve    pre    | version           ve   | | copy        t co    | print       p      | visual            vi   | | delete      d       | put         pu     | write             w    | | edit        e       | quit        q      | xit               x    | | file        f       | read        r      | yank              ya   | | global      g v     | recover     rec    | (window)          z    | | insert      i       | rewind      rew    | (escape to OS)    !    | | join        j       | set         se     | (lshift)          <    | | list        l       | shell       sh     | (rshift)          >    | | map                 | source      so     | (line number)     =    | | mark        k ma    | substitute  s & ~  | (execute buffer)  * @  | 

Back to top
(Part II/c)


( anything in [] is optional , anything in {} is the rest of the name of the command which is also optional )
The default for address is the current line, except for g, g! , v, w; for these the default is the entire file.

ab{breviate} [word text]

    define string when typed to be translated into text.     if string and text not specified, list all abbreviations     abbreviations are usually put into your .exrc file     eg. :ab Xvi vi is the best editor         :ab charcater character         :ab teh the         :ab hvae have 


    append text at address. ! switches autoindent. 


    print filename arguments. 

cd [path]

    without path change to home directory, with path change to path 


    replace lines with text. ! switches autoindent. 


    copy lines from address to destination.     eg. :1,10co50      copy lines 1 to to 10 to below line 50 

[address[,address]]d{elete} [buffer][count]

    delete lines in address, if buffer is specified save lines to buffer.     count specifies the number of lines to delete starting with address.     eg. :/include/,/main/d      delete lines between include and main                                 including include and main         :/include/+,/main/-d    as above but not including include nor main         :3d     delete line 3         :d3     delete 3 lines starting with current         :.,$d a delete to end of file from current line into buffer a         :d a3   delete next three lines starting with current into buffer a 

e{dit}[!] [+n] [file]     begin editing file. ! will discard changes to current file.     n specifies line to begin editing file (default 1).     eg. :e file     edit file         :e #        edit previous file 

f{ile} [filename]

    change name of file to filename. without argument print current     filename.     eg. :f    appends .new to current filename, renaming file to            


    execute commands on lines that contain pattern, if address is specified     within the address range. ! execute on lines not containing pattern.     without commands print matching lines.     eg. :g/#include/d      delete all lines that have include directives         :g!/#define/p      print lines that are not define statements         :g/^/*/p          print lines that start with /*         :g/^[ ^I]*$/d       delete empty lines as well as lines with only tabs                             or spaces         :g/strcmp/d5        delete lines that have strcmp in them as well                             as the following 4 lines 


    insert text at line before address. ! switches autoindent. 


    join lines in specified range. ! preserves white space.      eg. :1,5j!     join lines 1 to 5, preserve white space 

[address[,address]]k char

    synonymn for mark, character can follow k with no intervening space. 


    print lines so that tabs show as ^I and end of lines are marked with $. 

map[!] [char commands]

    define a keyboard macro for named char that is a synonymn for commands.     !  will create a mapping for input mode. with no arguments print mapped     keys.     eg. :map ^N :n^M    (to get a control character type ^V followed by the                         control character) 

[address[,address]]ma{rk} char

    mark lines with char. char is a single lowercase letter.     eg. :ma z   mark line with z         :'z     return to line with mark z 

[address[,address]]m{ove} destination

    move lines specified by address to destination.     eg. :.,/include/m /string/  move lines from current to include line below                                 line with string 

n{ext}[!] [[+commands] filelist]

    edit next file from argument list. if filelist is provided, replace     argument list with filelist. ! will discard changes to current file. 


    print lines specified by address, precede each line by its line number.     count specifies the number of lines to print. 


    enter vi's open mode with lines specified by address, or at lines     containing pattern. 


    save current buffer as if the system had crashed 


    print lines specified by address. count is the number of lines to print.     eg. :304;+5p    print five lines starting with 100, reset current line to                     100 

[address[,address]]pu{t} [buffer]

    restore lines that were previously deleted or yanked and put them after     current line. put line from buffer if specified. 


    quit. ! discard changes to file. 

[address[,address]]r{ead} file

    copy text from file on line below specified by address.     eg. :0r data    read in file "data" at top of file 

[address[,address]]r{ead} !command

    read the output of command into file after line specified by address.     eg. :$r !ls -aFC    run "ls" and read in its output at end of file 

rec{over} [file]

    recover file from system save area. 


    rewind argument list to first argument. ! discards changes to current     file. 

se{t} parm1 parm2

    set value to an option with each parm. if no parm is supplied print all     changed options. for boolean options parm is phrased as option or     nooption, other options are option=value. all will print all available     options.     set commands are usually put into your .exrc     eg. :se autowrite tabstop=4 autoindent shiftwidth=4 wrapmargin=5         :se all     print all available options 


    create a new shell. resume editing when shell exits. 

so{urce} file

    read and execute ex commands from file     eg. so ~/old.exrc 


    replace pattern with replacement. if pattern and replacement are omitted     repeat last substitution. count specifies the number of lines on which to     substitute starting with address.     options     c   prompt for confirmation     g   substitute all instances on line     p   print last line on which substitution was made     eg. :%s/[hH]ello/Hi/g       replace hello or Hello with hi, all ocurrences         :.,$s/[uU][nN][iI][xX]/U&/10   upcase unix on next 10 lines         :%s/<./u&/g    turn the first letter of all words to uppercase         :1,/main/s/int/long/g   substitute occurances of int before main with                                 long 

[address[,address]]t destination

    synonymn for copy 

ta{g} tag

    switch to file containing tag.     eg. :!ctags *.c     run ctags on all .c files in directory         :ta func        switch to file containing func, put cursor on it 

una{bbreviate} word

    remove word from list of abbreviations. 


    undo changes made by last editing command. 

unm{ap}[!] char

    remove char from keyboard macros. ! remove macros for input mode. 


    synonymn for global!     eg. :v/./,/./-j     join empty lines to have only single empty line                         between lines of text 


    version of editor. 

[address[,address]]vi [type][count]

    enter visual mode at line specified by address. exit with Q. count     specifies initial window size.     -   place line at bottom of window     .   place line in center of window     ^   print previous window 

vi [+n] file

    begin editing file in visual mode at line n. 

[address[,address]]w{rite}[!] [[>>] file]

    write lines specified by address to file. >> is used to append to file.     with no address write all of the file. ! forces the write.     eg. :1,25w new_file     write lines 1 to 25 to "new_file"         :50,$w >> new_file  append line 50 to end of file to new_file 

[address[,address]]w !command

    write lines specified by address to command. 


    write lines specified by address to file and quit. ! forces the write 


    exit file. save changes. 

[address[,address]]ya{nk} [buffer][count]

    place lines specified by address in buffer char. count is the number of     lines to yank starting with address.     eg. :20,100ya z     yank lines 20 to 100 into buffer z 


    print a window of text. count is the number of lines to display starting     with address.     type     +   place line at top of window(default)     -   place line at bottom of window     .   place line in center of window     ^   print previous window     =   place line in center of window. leave line as current line. 


    execute command. if address is specified apply lines from address as input     to command, and replace lines with output.     eg. :!ls -aFC           run ls, will not read output into file         :0!ls -aFC          run ls, read in its output to beginning of file         :11,35!sort -fd     sort lines from 11 to 35         :%!spell -b         run the spellchecker on entire file 


    print line number of matching address. with no address print line number     of last line. 


    shitft lines left(<) or right(>). count specifies the number of lines to     shift starting with address.     eg. :1,9>   indent lines 1 through 9 one shiftwidth 


    print line specified by address. 


    print next line. 


    repeat previous substitution. count specifies the number of lines to     substitute on starting with address.     eg. :s/msdos/UNIX   substitute msdos with UNIX         :g/OS/&         redo substitutions on all lines with "OS" 


    replace previous regular expression with the previous replacement from     substitute. 


    execute named buffer 


    synonym for number 

The following can be used as addresses in ex, as well as in commands :g, :s, :v, and in the vi commands ?, and /

Back to top
(Part III)


. match any single character except newline
* match any number (including none) of the single atom immediately preceding
^ match beginning of line if at start of expression
$ match end of line if at end of expression
[] match anything enclosed in [], called a character class
[^] match anything not enclosed in []
( ) store pattern for later replay
< match following characters at beginning of word
> match preceding characters at end of word
escape character following (needed for eg. . to match a .)
n reuse previous pattern, n is a number between 1 and 9 eg. 1
& reuse previous search pattern
~ reuse previous replacement pattern
u change character to upper case
U change characters to upper case
l change character to lower case
L change characters to lower case
e turn off previous u or l
E turn off previous U or L

Perl matches Perl
^Perl matches Perl at beginning of line
Perl$ matches Perl at end of line
^Perl$ matches Perl as the only word on line
^$ matches the empty line
^..*$ matches a line with at least one character
.* matches any string of characters including none
^[ ^I]*$ as above but line can also contain spaces and/or tabs(^I)
[pP]erl matches perl or Perl
[aA][nN] matches an, aN, An, AN
p[aeiou]g second letter is a vowel
i[^aeiou]g second letter is not a vowel
p.g second letter is anything
^....$ matches a line with exactly four characters
^. matches any line beginning with a dot
^.[0-9a-z] same with a lowercase letter or digit following
^[^.] matches any line that does not begin with a dot
;$ matches a line ending with a semicolon
figs* matches fig, figs, figss, figsss etc.
[a-z][a-z]* matches one or more lowercase letters
[a-zA-Z] matches any character
[^0-9a-zA-Z] matches any symbol (not a letter or number)
<the matches the, theater, then
the> matches the, breathe
<the> matches the
:%s/<./u&/g turn the first letter of all words to uppercase
:%s/<[a-z][!-~]*>/u&/g as above
:%s/<[a-z]/u&/g as above
:%s/.*/L&/ turn entire file to lowercase
:%s/<[^>]*>//g remove strings from file that start with a less than sign and end with a greater than sign (html tags)
., ^, &, $ must be preceded by a to make literal when magic is on. * must be preceded by a under certain circumstances although it never hurts to precede it with a backslash whenever you mean a * not its regexp meaning. % and # should also be escaped as they mean current and alternate file to ex. Regular expressions only work in a s/pattern/replacement/ for the pattern and not the replacement, for obvious reasons.

No comments: