vi Long Reference

Newsgroups: comp.unix.questions
From: (Narayan Natarajan)
Subject: Help For vi
Organization: University of Toledo
Date: Thu, 4 Aug 1994 19:41:51 GMT
Lines: 558

I am sure there are a zillion people asking questions on vi.
Here I made a shell script that ran from within vi as a 'pseudo' on-line
help when the user hit a F1 or F2 key.
For this I'd created a large file of vi commands with loads of help.
Although this was incomplete, it still has proved quite useful to many users.

I do not think I have any errors in this text, if anyone can find any 
Please take the time to let me know.

( Also I am sure the presentation of data could be improved, well don't have
*that* much time B-D )

Here is the stuff in the file as to commands go:

by me: to format a file in vi go:    :%!fmt  and enter.
this formats the whole file that is on the screen.


				|        MOVE        |

				|     BASIC MOVES    |

h	left one character
j	down one line
k	up one line
l	right one character
G	GO to the last line in the file
#G	GO to line #.  (e.g., 3G , 5G , 175G )
:#	ditto
#move	repeat move # times; apply to any move.

				|    SCREEN OPS.     |

^G		Show status of current file 
^L		Refresh screen
^D		DOWN one half-screen ( in insert mode it shifts one tab BACK)
^U		UP one half-screen
^F		FORWARD one full-screen
^B		BACKWARD one full-screen
^E		Move window down one line without moving cursor
^Y		Move the window up one line without moving cursor
H		to the HIGHEST position in the window
M		to the MIDDLE position in the window
L		to the LOWEST position in the window

				|     PARAGRAPH      |

{		Move to the beginning of a paragraph
}		Move to the end of a paragraph
(		(left paren) to the beginning of a sentence
)		(right paren) to the beginning of the next sentence
[[		to the beginning of a section
]]		to the end of a section

				|        LINE        |

$		to the end of the line
^		to the first non-white character on the line
0		to column zero
#|		to an exact column on the line (column #) e.g.  5| 1|

w		beginning of the next WORD   
		(word is de-limited by non-al.num chr)
e		END of the next word
b		BACK to beginning of previous word
W,E,B		ditto, like above w,e,b, (word delimited by space)
+		to first non-white char of next line
-		to first non-white char of previous line

				|        EDIT        |

ESC		ESCAPE from insert mode (if something is wrong ^C works too )
.		(dot) repeat last change
o		OPEN a line below the cursor
O		OPEN a line above the cursor
i		INSERT starting before the cursor
I		INSERT at the beginning of the line
a		APPEND starting after the cursor
A		APPEND at the end of the line
J		JOIN two lines
#s		SUBSTITUTE for # characters (default one char)
#S		SUBSTITUTE for # whole lines (default one char)
#r		REPLACE # characters, default 1 char (NO need to press ESC)
R		enter over-type mode
c[move]		CHANGE to where the 'move' specifies 
cc		CHANGE whole line
C		CHANGE till end of line

Note:    	In all of above text insertion modes (i,a,o,c,r), a number may
		be given before entering, this will duplicate the edit as many
while in one of the above text insertion modes :

^D		kill one indent
^^D		 kill all indent for current line (type carat '^' then a CTRL-D)
^W		word erase ( note : can be set by 'stty' command )
^U		line erase ( note : can be set by 'stty' command )
^H		same as backspace ( note : can be set by 'stty' command )

		 		|        EXIT        |

ZZ               	Exit and save any changes 
:[#,#]w[!] [filename]	WRITE  without quitting (to "filename" if given)
                	use #,# to specify 'from' and 'to' addresses, and ! bang
                    	to force.
                        Example : 
                        :1,5 w abcd                write  1-5 lines    
                        :/from/,/to/ w efg         'from' to 'to' 
                        :/from/,+5 w hij           'from' to 5 lines after

:x              	WRITE and QUIT
:wq             	WRITE and QUIT

:w !UNIX-CMD      	WRITE output and pipe through a UNIX command
                	Example :
               		:1,10 w !lpr          sends first 10 lines to printer

:q[!]           	QUIT without saving changes ( ! 'bang' force quit ) 

				|        UNDO         |

u		UNDO last change
U		UNDO all changes made to the current line
		as long as your cursor has not moved off the line 
"[1-9]PASTE	use a PASTE command to paste one of the numbered buffers.
		The numbered buffers store the last 9 deletes in first in
		last out method. For e.g "1P "2p

				|        CUT         |

#dd		DELETE # lines, default : one line
d	DEL to where "move" or "search" 
		specifies (e.g. dfe del till 'e' found, dta del till 'a',
		d20| del till 20th col)
d#move		DELETE to where the  #move  specifies (e.g. d3k del 3 lines
		above incl. of current line)
d/	delete till pattern is found (forward)
d?	delete till pattern is found (backward)
d'    	delete till mark 'chr' (see miscellaneous to learn how to mark)
D		delete till end of line
#x		X-OUT one character under cursor ( or # chars )
#X		X-OUT char before the cursor ( or # chars )

				|        YANK        |

y	YANK to where "move" or "search" specifies
		(e.g. yw yank word, yfg yank till 'g' found)
y#move		YANK to where the  #move  specifies (e.g. y3j yank 3 lines dn
		incl. of the current line)
y/pattern/	YANK till 'pattern' found (forward)
y?pattern?	YANK till 'pattern' found (backward)
y'    	YANK till mark 'chr' (see miscellaneous to learn how to mark)
Y or yy		YANK one line
#Y, #yy		YANK # lines below
"[char]YANK	copy the yank into char 

				|       PASTE        |

P       	(upper p) PASTE buffer before the cursor
p       	(lower p) PASTE buffer after the cursor
"PASTE 	PASTE the named buffer (a-z) using one of the cmds. above.
"#PASTE 	PASTE the numbered buffer (1-9) using one of the cmds. above.

				|	SEARCHES     |

f char	FIND next occurrence of char on the line
t char	Move 'TIL next occurrence of char on the line
F char	FIND previous occurrence of char on the line
T char	Move 'TIL previous occurrence of char on the line
;	Repeat the last  f, t, F, or T
,	Reverse the last  f, t, F, or T
%	Show matching () or {} or []
n	Repeat last / or ? command
N	Reverse last / or ? command
/string	Find string looking forward; additionally :
	will move cursor to first str2 after string
?string	Find string looking backward; the ';' option as above
/ or ?	Use string used for previous search


^       begining of line    $        end of line    .      any char
*       any # of chars      \<       beg of word    \>     end of word
[str]   any chr in str      [^str]	 not in st     [x-y]   btn x & y

				|    : COMMANDS	     |

NOTE : If you get stuck with a : prompt at the bottom of the screen 
it means that you have entered the ed editor. type in 'vi' at the prompt to
reenter vi editor. ( you can enter ed by hitting ^$)

:#,#[!][filenm]	General fmt. 
				The #s are move cmds. or line numbers to 
				indicate a 'from' and a 'to' position
				One of the #s can be :
				+#	#below	-#	#above
				.	current ln.	$	last ln.

:s///[#gc]	SUBSTITUTE  with  once in a
				line, if 'g' specified then replace all within
				line.'c' is for confirmation, # is to replace
				in # lines. Read  &  for
				more info on them.

                  	 may have sub expressions, defined by
\(exp1\)[junk]\(exp2\)    	a \( and \) pair ( upto 9 expressions )

                  	 may have expression descriptors,
\# junk \# \# junk        	 defined by a \#, where # is a number 1 - 9.
                         	For Example:
				s/\(.*\)=\(.*\)/\2 = \1/
				will switch LHS with RHS of an 'equal to'
				sign in a line of the form :
				[something] = [something]

:#1,#2g//  	This will look up every occurence of 
				in between lines #1 and #2 and run the
				. The ex command:
				looks up  ( // means last search) and
				replaces with . Use other commands
				as listed below, such as p,d

:#1,#2 c <.>      	CHANGE lines from #1,#2, with , to quit
				from this mode, enter a '.'(period) all by 
				itself at the beginning of a line.

:#1,#2 co #3			COPY lines in same fashion as above
:#1,#2 t #3			does the same thing as 'co'

:#1,#2 d			DELETE lines from #1 to #2 eg: :'a,'bd
				deletes lines from mark a through b

:#1,#2 y "		YANK lines into buffer named 
                 		if uppercase alphabet is used then yank
                		appends the buffer

:e[!] [filename]   		EDIT current file (! force, edit 'filename'
				if given)
:e#             		EDIT alternate file (you have to edit
                 		another file then use the e# to edit the
               			first file again)
:e #             		EDIT alternate file and  resume at
				last cursor postion.

:#1,#2 m #3			MOVE lines #1 thru #2 and place them
				at #3. e.g :10,15m25 will take 5 lines to
				line 25

:#1,#2 p			PRINT lines (no change to the file)

:#1r[!] [filename]    		READ current file ( above options apply ) 
            			if filename and #1 given then insert file at #1
            			(top of file is line zero and bottom is $ )

:r !UNIX-CMD    		READ from the UNIX-CMD as input to the file.

:n[filenames][!]		edit NEXT file in the list of arguments
              			if a list of files given then vi edits the
				files one at a time.

				EXAMPLE: :n a.c b.c c.c d.c
				will edit 4 files starting with a.c
				NOTE : vi can edit multiple files on invocation
				as for e.g. : vi *.c

:args        			shows the files that vi is editing currently
				after the above :n command, keying :args
				will display :  [a.c] b.c c.c d.c
				the [] enclose the current file

:rew [!]       			REWIND, start at the first file in the list
				see :n command

:st[op]				STOP vi and exit to shell, to reenter
				type fg at UNIX prompt
:sh     			start a shell (usually a bourne shell)  

:!		run UNIX command outside the vi, for ex: 
			:1,10 w !lpr
			will send first 10 lines to the printer without
			having to create another file.

Examples :

:1,.m $  	move lines from line #1 to current line to end of file


:g/bad/d 	delete all lines with string 'bad' in them

:g/bad/p 	print all lines with string 'bad' in them

:g/bad/co $	copy lines matching string 'bad' to end of file (screws up
		use with 1 instead of $ )

:g/hello/ y"A	yank all occurences of 'hello' into buffer 'a', note the
		uppercase, if lowercase was used then only the last occurence
		will exist after the command.

&			Do last search-replace again

%			same as 1,$ , eg: :%s/a/b/ will substitute the first
			occurrence of 'a' with 'b' throughout the file


^       begining of line    $        end of line    .      any char
*       any # of chars      \<       beg of word    \>     end of word
[str]   any chr in str      [^str]   not in st     [x-y]   btn x & y

Some specials include :

&	the matched keyword itself, eg: s/tr/&ace/ would subs. tr with
\U	make what follows uppercase :s/case/\U&/ will make case CASE
\u	make only first char uppercase 
\L	convert to lowercase 
\l	convert first char only

				|   MISCELLANEOUS    |
               	As a special case, when the last command refers to a
			numbered text buffer, the '.' command increments the
			number of the buffer before repeating the command. 
			For ex:
			will put buf.1, undo it, put buf.2 undo it.

m char          	MARK this location and name it char
' char          	(quote character) return to *line* named char
` char          	(quote character) return to *place* named char
'' or ``        	(quote quote) return from last movement

"[a-z][1-9]DEL  	DELETE, YANK  or PASTE text from buffers 'a' thru
"[a-z][1-9]YANK		'z' or '1' thru '9'(one at a time only)
"[a-z][1-9]PASTE	(e.g.  "ad} "5dw, "by3y  "2Y,  "dp  "5P )

~               	(tilde) Convert case of current character

z       	Position the current line to top of window
z.              	Position the current line to middle of window
z-              	Position the current line to bottom of window

>movement       	Shift right to where the movement command specifies
      	run a UNIX command on the lines till movesrch specifies
                        ( is different from :! in that the output of command
                        replaces the input , input is all lines in movesrch)
                	e.g.:  !Gsort sorts lines of a file from current pos.
                        till end of file.
:ab lhs rhs     	abbreviate rhs to lhs, lhs is expanded by typing a space
				:ab fg foreground
			in insert mode when you type fg_ (_ is space) it will
			be expanded to foreground.
:una lhs        	unabbreviate lhs

				|    SET OPTIONS     |
The set options affect vi editor's environment in order to tailor it to
user's needs.

	To get a list of all set options type 
		:set all

	To get a list of all options that have been changed type
Here are some of the many options that can be set in vi:
(default values in () )


autoindent	ai|(noai)	Supply indentations automatically
ignorecase	ic|(noic)	Ignore Letter case while searching
number    	nu|(nonu)	Display line numbers
shiftwidth	sw=8    	Shift distance for tab,>,< and input ^D
tabstop   	ts=8     	Tab stop distance (nice to have it match with
showmatch 	sm|(nosm)	Show matching ( or { as ) or } is typed
showmode  	smd|(nosmd)	Show the current input mode on the message line
				for ex: in 'a' command APPEND MODE is displayed
wrapmargin	wm=0      	vi automatically inserts a newline when it finds
				natural break within 'wm' spaces (good for
				editing text).

				|      MACROS        |
vi can, if set up correctly, execute a set of commands with a few keystrokes.
This can be achieved in two ways:

1.	The macro body can be put in a buffer register, say a, then typing
	last macro.
	for ex:
		type the following macro on a new line as text in vi using an
		INSERT mode:
		(the esc key has to be typed after a ^V, hit esc once more to
		exit INSERT mode).
		Now with cursor on 'a' yank the text into buffer a by keying:
		append a 'meow' to your text.

2.	A key can be mapped using the map command to perform a sequence of
	commands.(Keys can be 'unmap'ped using :unmap lhs)
	Mapping is typically as follows:

	:map[!] lhs rhs

	lhs : this should be one keystroke, can be a character or a
		function key.
		examples :

		characters : a, b, c, A, B, ^, >

		control keys : ^A, ^B (type ^V to escape before typing ^A etc.)

		function keys :  #[0-9] are available, these correspond to F0,
				F1 etc. keys on all keyboards)
	rhs : This should be a sequence of characters no longer than 100
		example :
		inserts a '/*' at the beginning of the line and a '*/' at
		its end (make a C code into a comment).
	!   : This option makes the key active in INSERT mode


	:map V k/\/\*/

	this will map V to search for a '/*' and '*/' and delete them
	(decomment a line in C)

	:map #2 :!budvisor^M

	this is what this program writes in the '.exrc' file so that you can
	invoke budvisor by hitting the F2 key.

	To list all command mode macros type :
	To list all insert mode macros type :

				|  TIPS & TRICKS     |

	Here are a few of many tips:
>	To invert order of characters      -	xp

>	To pluralize a word                -	eas

>	To delete till begining of line	   -	d0

>	To browse all lines with 'pattern' -	:g/pattern/p

>	To browse through numbered buffers - 	"1pu.u.u (u and . alternating)

>	To substitute 'str' with 'replace' globally -

>	Use word erase, line erase while inserting to backup, for ex:
		hello tim^W	-	would back cursor to 't' of tim
		hello tim^U	-	backs up cursor to beginning of line
	Since these keys can be redefined check their status by the Unix
	command :
		stty -a
	look for : werase , kill

>	To copy a set of lines from a file:
	(1)	save current file use :w
	(2)	edit the file with reqd. data, use :e 
	(3)	now yank lines into a buffer e.g. "a3Y would
		yank 3 lines into buffer `a`.
	(4) 	edit original file use :e! 
	(5) 	place cursor where using command "ap or "aP the text in
		the buffer 'a' will be pasted.

>	To switch back to the place in previous file being edited use:
		CTRL^ (hold control key while pressing ^ key)
	this is a short key for :e #

>	To comment in C language (/*...*/) you can map characters say v
	& V in the following manner:

		map v I/*^[$a*/^[^M
		map V /\/\*/^MNxx/\*\//^Mxx``

	v will comment a single line by placing /* and */ at the
	beginning and end of the line respectively, and V will remove
	these from a commented line or paragraph (you must be at or
	within the comments).

>	To print a certain range of lines straight to printer without
	having to save in between in a file :

	:#1,#2 w !lpr

	would send lines from #1 to #2 to the default printer.

>	Deleted lines can be recovered by going through the numbered buffers:
	The nubered buffers 1 through 9 hold the last 9 deletes.
	To look through the buffers :

	(1) type :       "1p           : this will echo the buffer #1
	(2) type :       u             : this will undo the paste
	(3) type :       .             : this will exec. the last cmd "1p ..but
				   : in this unique case adds 1 and execs. 
				   : "2p another . would exec. "3p 
	(4) when you hit the correct buffer ... keep it!