Topics on this page in alphabetic order
- Advanced deletion
- Advanced movement commands
- Applying commands to certain lines
- Automating things
- The basics
- Change existing text
- Changing text
- Copying, cutting and pasting
- Delete text
- Go to lines, find matching text
- Insert text
- Line numbers
- Mapping actions to function keys
- Marking your work
- More useful tips for programmers
- Recording commands
- Repeat counts
- Search and replace
- Setting up your personal favourite settings
- Shell and filter commands
- Spellcheck file
- Splitting and joining lines
- Tab management
- Tags
- Undoing things
- Visual mode commands
- Visual mode
- Why use vi?
Why use vi?
When I first tried using vi I thought that you could not have a more obscure and difficult-to-use text editor, but I found that after memorising half-a-dozen commands that it was really quite simple to use. And, quite powerful. For example, you can do something like "find all lines with 'swordfish' in them, and for those lines only, change 'cat' to 'dog'". Try doing that with your normal editor!
The other reason is you can usually find vi on almost any Unix installation. If you get used to "my favourite editor" - whatever that is - and connect to a different site for troubleshooting, you may well find it is not installed, or only runs under Xwindows, or some other such restriction.
Further, you can do quite fancy things (see below) like do a "make" from inside vi, and then with a single keystroke go to each error message (even in different files), with the cursor being placed on the line in error, so you can fix it. This is quite a time-saver. Similarly with doing "grep" on a group of files.
The basics
If you start doing something and change your mind you can generally press Ctrl+C to cancel it.
Edit a file, look at it, stop editing
Edit a file from command prompt | vi |
Edit a file from command prompt for reading only | vi -R |
Edit a file from within vi | :e |
Edit a new file from within vi, discard changes to current file | :e! |
Reload current file, discarding changes | :e! |
Go forwards a page | Ctrl+F (or PgDn) |
Go backwards a page | Ctrl+B (or PgUp) |
Move around single lines or characters | Arrow keys |
Save changes | :w |
Save changes and override protected (read-only) files | :w! |
Save changes and exit vi | ZZ |
Quit | :q |
Quit and discard changes | :q! |
Get general help | :help |
Get help on a command (eg. :set) | :help set |
Notes
- Whether keys like PgUp and PgDn work will depend on your keymappings. I find recently that they tend to work without needing to make any changes. In some cases you may need to type "vim (file)" at the command prompt rather than "vi (file)" if both are installed. Otherwise you may set up an alias (at your shell prompt) to equate vi to vim.
- Any command starting with these characters:
- : (colon) - starts a command sequence
- / (slash) - starts a forwards search
- ? (question mark) - starts a backwards search
to execute them. Until you have done that you can backspace and make corrections. These commands are echoed on the bottom line of the screen, so you can see what you are typing. If you have started typing one of those, you see the command being echoed, and change your mind, press Ctrl+C to cancel the command.
Simple example
Let's edit comm.c and then exit ...
vi -R comm.c
(PgDn to look at file)
:q
If you are experimenting then it might be wise to either edit a file you don't care about (eg. a copy) or use the -R option (read-only).
Alternatively, set read-only mode once you have edited the file:
Set read-only mode | :set ro |
Go to lines, find matching text
Go to line 1234 (do not see typing) | 1234G |
Go to line 1234 (see typing) | :1234 |
Go to start of file | 1G |
Go to end of file | G |
Find (forwards) a line containing "swordfish" | /swordfish |
Find (forwards) a line using a regular expression | /you see .* here |
Repeat last search | n |
Repeat last search in opposite direction | N |
Find (backwards) a line containing "swordfish" | ?swordfish |
Find (backwards) a line using a regular expression | ?you see .* here |
Search case insensitive (Ignore Case) | :set ic |
Search with case sensitivity | :set noic |
Wrap searches back to start of file | :set wrapscan |
Do not wrap searches | :set nowrapscan |
Notes - these are probably the most frequent things I do. 'Go to line number', especially if you have a compiler error which gives a line number is very handy. Type the line number directly followed by "G", and you are taken there. Or, if you don't know the line, type "/" followed by a word or regular expression you are looking for. The second way of going to a line number (:1234) is probably easier to use because you can see the number as you type it. If you type "1234G" the number (1234) is not echoed to the screen as you type.
Highlighting - searching with "/" or "?" normally highlights the found word. Sometimes this can be quite annoying, especially if you have searched for something which occurs frequently, like a space. You can turn this off:
:hi clear search
Case-sensitivity - using ":set ic" lets you search with or without matching the exact case of the word you are searching for (eg. if you search for "dog" do you want to match "DOG"?).
Simple example
Let's edit comm.c and go to line 5522. Then find "const".
vi comm.c
:5522
/const
:q
Line numbers
Sometimes it is handy to know what line you are at, or what each line number is.
Show line numbers on the left | :set nu |
Do not show line numbers on the left | :set nonu |
Show the current line number | :.= |
Show total lines in file | := |
Show file name, total lines, and current line number | Ctrl+G |
Show line number of first matching pattern | :/pattern/= |
Notes - showing lines numbers is particularly useful when you are relating things like error messages (or instructions) to a line number. Also the Ctrl+G trick is useful to remind yourself of what file you are editing.
Simple example
Let's edit comm.c, show line numbers, find the first line with "const" in it (line 70) and go to it:
vi comm.c
:set nu
:/const/=
:70
:q
Changing text
OK, we can move around the file and find things. Let's start changing stuff ...
Undoing things
When you start going into "change things" mode you will probably need to undo your mistakes. Two useful commands:
Undo last change | u |
Undo all changes on current line | U |
If things get out of hand, remember:
Quit editor without saving changes | :q! |
Reload current file, discarding changes | :e! |
Insert text
All of the changing commands (except "replace next character") go into "insert mode" (usually shown by "-- INSERT --" or "-- REPLACE --" at the bottom of the screen). To exit from Insert Mode, press the Esc key.
Insert after cursor | i |
Insert before cursor | a |
Insert at beginning of line | I |
Insert at end of line (append) | A |
Open (start) new line below cursor | o |
Open (start) new line above cursor | O |
The last two are the letter "oh" not a zero. I use the "O" and "o" commands quite a bit to start entering a new line above or below where the cursor currently is.
Change existing text
Replace next character | r |
Type over following characters | R |
Replace to end of line | C |
Note - the "r" command is useful if you just want to make a minor correction (eg. change "A" to "B"). This does not go into Insert Mode, so you don't need to then cancel Insert Mode. To change the character under the cursor to a "B" you would just type "rB".
Delete text
Delete character under cursor | x |
Delete character to left of cursor | X |
Delete to end of line | D |
Delete entire line | dd |
These are your basic deletion commands. "x" to scrub out the character under the cursor, "dd" to delete the entire line.
Advanced deletion
Delete next 5 lines | 5dd |
Delete to end of line | d$ |
Delete to start of line | d0 |
Delete to word "swordfish" | d/swordfish |
Delete to the letter "x" | dfx |
Delete lines 10 to 20 | :10,20d |
Delete current line and another 5 lines | :.,+5d |
Delete all lines | :%d |
Delete current word | dw |
Find line containing pattern, delete it | :/pattern/d |
Find line containing "dog", delete until line containing "cat" | :/dog/,/cat/d |
Delete from current line to line containing "foo" | :.,/foo/d |
Copying, cutting and pasting
If you delete some text using the deletion commands described above you have "cut" the text. However it is saved in an internal buffer and can be pasted somewhere else. Simply move the cursor to where you want it and:
Paste after cursor | p |
Paste before cursor | P |
vi calls copying "yanking", and thus uses the letter Y.
To copy text without deleting it you need to "yank" it. The yank commands are similar to the deletion commands, like this:
Yank to end of line | y$ |
Yank to start of line | y0 |
Yank to word "swordfish" | y/swordfish |
Yank to letter "g" | yfg |
Yank entire line | Y |
Yank lines 5 to 10 | 5,10y |
After yanking you can paste as described above (or there is no point to yanking in the first place).
Advanced movement commands
Go forwards a word | w |
Go backwards a word | b |
Go to end of word | e |
Go to start of line | 0 |
Go to end of line | $ |
Go to top of screen | H |
Go to middle of screen | M |
Go to bottom of screen | L |
Go (forwards) to letter "x" on current line | fx |
Go (backwards) to letter "x" on current line | Fx |
Go to next occurrence of word under cursor | * |
Go to previous occurrence of word under cursor | # |
Find a control character (eg. Tab) | /(Ctrl+V)(Tab) |
Go backwards a sentence | ( |
Go forwards a sentence | ) |
Go backwards a paragraph | { |
Go forwards a paragraph | } |
The command "go to start of line" is a zero, not an "oh". You can use Ctrl+V in insert or command mode to literally insert the next character.
Repeat counts
Most commands have a "repeat count" that you can optionally type first. To do a repeat count just type the number before the command. It will not be echoed, so type carefully!
For example:
Delete 5 lines | 5dd |
Delete 5 characters | 5x |
Delete 5 words | 5dw |
Replace next 5 characters | 5r |
Yank (copy) next 7 lines | 7Y |
Go to line 1000 | 1000G |
Paste copy buffer 10 times | 10p |
Insert 40 hyphens | 40i- |
Insert the line "swordfish" 10 times | 10oswordfish |
Find the 5th occurrence of "swordfish" | 5/swordfish |
In the above examples
Splitting and joining lines
Split a line (insert a return) | i |
Join two lines (current and next) | J |
Join next 10 lines | 10J |
Join lines 10 to 20 | :10,20j |
Splitting is basically breaking a line into two by inserting a newline. Joining is reversing that process by removing the newline.
Search and replace
Change "nick" to "fred" on current line | :s/nick/fred/ |
Change "nick" to "fred" on the next 5 lines | :.,+4 s/nick/fred/ |
Change "nick" to "fred" on lines 100 to 200, all occurrences | :100,200 s/nick/fred/g |
Capitalise every word in the entire file | :% s/\<./\u&/g |
Insert ">" at the start of every line | :% s/^/>/ |
Insert "// nick" at the end of every line | :% s;$;// nick; |
Special characters for line sequences:
.
is the current line$
is the last line%
is every line+5
means 5 lines from current line-5
means 5 lines before current line
Applying commands to certain lines
You can use the ":g" (global) command to find matching lines (using a regular expression) and then apply a command to those lines. For example:
Find lines containing "fruit" and change "apple" to "orange" on them | :g/fruit/s/apple/orange/g |
Delete all blank lines | :g/^$/d |
Find lines NOT containing "nick", append "oops" to them | :g! /nick/normal A oops |
The third example above shows you you can use the "normal" command inside a command, to tell vi to use a normal character (in this case A for append) as part of a command.
Shell and filter commands
List directory | :! ls |
See processes | :! ps |
Sort lines 20 to 30 | :20,30 ! sort |
Sort entire file | !G sort |
Translate next sentence to upper case | !) tr '[a-z]' '[A-Z]' |
Word count file (save first) | :!wc % |
Look up manual entry for strstr | :!man strstr |
Insert "ls" command output into window | :r !ls |
Tags
Tags let you go to the definition of a function (in C or C++) without having to scan lots of source files (with grep) and work out which ones contain the function and which merely refer to it.
First, make a tag file, like this:
ctags *.c *.cpp *.h
(In recent versions of Linux I have had to use gctags instead of ctags).
This should produce a file "tags" in the current directory.
Now you can go straight to a function, without knowing which file it is in, like this:
vi -t game_loop
Once inside vi you can put the cursor on a word and go to its definition:
Go to function under cursor | Ctrl+] |
Go back | Ctrl+T |
Go to function xyz | :tag xyz |
Automating things
Compiling from within vi and going to errors
You can save your changes, run "make" to compile, and view errors, very easily ...
Save file | :w |
Run "make" | :make |
Go to next error | :cn |
Go to previous error | :cp |
This is fabulously powerful. It lets you skim through all your errors, with vi opening the right file and positioning the cursor on the line in error.
See below for how to map actions (like ":cn") to function keys to speed up the process.
Mapping actions to function keys
Map the action :cnext to | :map |
Map the action :cprevious to | :map |
Map the action :make to | :map |
Map the action :close to | :map |
After entering the above commands you could compile by simply hitting F8, then look at each error by hitting F6.
More useful tips for programmers
Go to definition of word under cursor | gd |
Go to global definition | gD |
Find matching bracket, brace, #if, #endif | % |
Do a grep | :grep foo *.c |
After grep, go to next occurrence | :cn |
Get a file (eg. an #include file) whose name is under cursor | gf |
Auto complete (in insert mode) - match forwards | Ctrl+X Ctrl+N |
Auto complete (in insert mode) - match previous | Ctrl+X Ctrl+P |
Make an abbreviation (eg. cca = "const char *") | :ab cca const char * |
Turn syntax colouring on | :syntax on |
Turn syntax colouring off | :syntax off |
Execute any shell command | :! command |
Indent selected lines with C-style indenting | = |
For formatting of C code there are also other options you can use like "autoindent", "smartindent", "cindent", and "indentexpr". (Use :help (topic) to see more about those options). You can turn these on (eg. :set cindent) to automatically indent your coding as you type. Also, in conjunction with syntax colouring, you can see if you have made a syntax error (eg. not closed a quote, left off a bracket), as the syntax colouring algorithm will highlight in red sequences that do not seem correct.
Spellcheck file
Save file first | :w! |
Spell check it | :! ispell % |
Edit fixed file | :e % |
Tab management
Tabs can be annoying in source files, as they do not necessarily line up when you use different value tab stops. You can manage them in vi like this:
Set tabs to every 4 characters | :set ts=4 |
Convert tabs to spaces in future | :set et |
Do not expand tabs | :set noet |
Fix existing tabs (convert to spaces) | :%retab |
Show tabs visually, and end-of-lines | :set list |
Do not show tabs and end-of-lines | :set nolist |
Visual mode
vi can be a bit difficult to follow when you are trying to do something to a block of lines (for example, do I want line 8843 through to 8903 or 8904?), so vim has a "visual mode" where you can actually see lines highlighted in inverse.
First, "mark" a block of lines (or characters) by going to the start of the block, and then using one of the following:
Character mode | v |
Line mode | V |
Block mode | Ctrl+V |
Re-mark previous block | gv |
The differences are:
- Character mode - from somewhere inside one line to somewhere inside another (ie. can be a part line)
- Line mode - will be whole lines
- Block mode - from (say) column 5 at line 10, to column 60 in line 20 (a square block of text)
Then use the cursor movement commands (search, arrow, go to line, whatever) to mark the other end of the block, and either:
Do some command | (see below) |
Cancel visual mode | Esc |
Go to other end of block | o |
Other ways of establishing a visual block
A word (with white space) | vaw |
Inner word | viw |
A WORD (with white space) | vaW |
Inner WORD | viW |
A sentence (with white space) | vas |
Inner sentence | vis |
A paragraph (with white space) | vap |
Inner paragraph | vip |
A ( ... ) block (includes brackets) | vab |
Inner ( ... ) block | vib |
A { ... } block (includes braces) | vaB |
Inner { ... } block | viB |
A "word" is a sequence of letters, numbers, underscores. A "WORD" is a sequence that is terminated by spaces. The difference would apply in cases like a(b) - if the cursor is on "a" a "word" is "a" however a "WORD" is "a(b)".
Here is an example, from C source code. Say you have the following code, and you want to select the code inside the inner { ... } characters. Put the cursor in the middle (eg. on CON_EDITING) and type "viB" and the "inner block" (text in bold) will be highlighted.
if ( d->pagepoint )
{
if ( !pager_output(d) )
{
if ( d->character
&& ( d->connected == CON_PLAYING
|| d->connected == CON_EDITING ) )
save_char_obj( d->character );
d->outtop = 0;
close_socket(d, FALSE);
}
}
Here is another method of selecting a visual block of C code. Say we have the following code and we want to highlight everything inside the "while" loop. Put the cursor on the first "{" and type "v%". That will go into visual mode and move to the end of the block. The highlighted code will be in bold.
while ( usecDelta >= 1000000 )
{
usecDelta -= 1000000;
secDelta += 1;
}
Visual mode commands
See below for meanings of notes in brackets.
Switch case | ~ |
Delete | d |
Change (4) | c |
Yank | y |
Shift right (4) | > |
Shift left (4) | < |
Filter through external command (1) | ! |
Filter through 'equalprg' option command (1) | = |
Format lines to 'textwidth' length (1) | gq |
You can also do the following on the selected block:
Start ex command for highlighted lines (1) | : |
Change (4) | r |
Change | s |
Change (2)(4) | C |
Change (2) | S |
Change (2) | R |
Delete | x |
Delete (3) | D |
Delete (2) | X |
Yank (2) | Y |
Join (1) | J |
Make uppercase | U |
Make lowercase | u |
Find tag | Ctrl+] |
Block insert | I |
Block append | A |
Notes
- Always whole lines
- Whole lines when not using CTRL-V.
- Whole lines when not using CTRL-V, delete until the end of the line when using CTRL-V.
- When using CTRL-V operates on the block only.
An example of visual mode?
OK, let's say we have a visual block highlighted. Try these:
Delete it | d |
Copy it | Y |
Change "apple" to "orange" in the block | :s/apple/orange/g |
Turn into C++ comments | :s.^.//. |
Turn into C comments | :s-^.*$-/* & */- |
Marking your work
If you need to jump backwards and forwards between a couple of places you can "mark" them ...
Mark current position as "x" | mx |
Go to position "x" | `x |
Show list of known marks | :marks |
That character before the "x" is a back-quote - on my keyboard on the top-left corner, under the tilde (~) symbol. Marks can be in a different file to the current one.
Recording commands
Finally, let's do an example of recording commands for repeating later.
Record a sequence | q(letter)(commands)q |
Play back sequence | @(letter) |
See what is in registers | :reg |
You record a sequence into a lower-case register (a-z), eg.
qa:s/fish/chips/q
The command above (starting and ending with "q") records into register "a" the sequence ":s/fish/chips/".
Then whenever you want to repeat that command you can type "@a".
Example of recording
Whilst writing this page I wanted to convert every second sequence of:
(something)
to:
(something)
qa
2/
:s///
:s$$
$
$
q
The sequence above did the following:
- Start recording (q) under register "a"
- Search for the second occurence of (hence the leading "2" on the line)
- Change "" to "
"
- On the same line change "" to " ". I used a $ as the search delimiter because the character "/" was in the text to be searched for.
- Go to the end of the current line ($) so the next search would begin at the next
- Stop recording (q)
Then I moved to the start of the file (1G), turned search wrapping off (:set nowrapscan) and typed "999@a". This executed macro "a" 999 times. In fact, it stopped before 999 times because the search failed after it got to the end of file.
Setting up your personal favourite settings
If you have some personal favourite settings like:
- Spaces for tabs
- Whether searches are highlighted or not
- Syntax colouring on or off
- Mapping function keys to special functions
you can have them processed automatically by putting them into a file named ".vimrc" in your home directory (see ":help vimrc" inside vim for more details).
For example, your .vimrc file might have in it:
|
From: http://www.gammon.com.au/smaug/vi.htm
3 comments:
Really awesome information, thanks! Seeing the power of chaining commands together is fascinating!
Just one thing: your examples are hard to read. I had to disable CSS in order to read them.
Sorry for the convenience, because I just copied the stuff from other websites, which are listed at the end of this post. And I did not modify anything of the copied contents.
hey great compilation.
as mentioned above you should change the text color within the tables...
just appent sth like
table{
color: black;
}
at the end of your css
Post a Comment