vim Hints and Tips
vi is available on just about every UNIX and UNIX-like
system you will ever encounter,
it can be used without a graphical environment,
and it includes features specifically included to be useful
in writing source code,
but it is a somewhat primitive editor.
Newer and more capable variants exist,
and in fact vi on the classroom/lab machines starts one of them,
namely vim (“vi improved”).
(In the rest of the document, I'll use vi to mean the
original program and its variants including vim,
and vim for the improved version.)
There is even a graphical version, gvim,
though it does require a graphical environment so is less useful
when working remotely.
Start it by giving its name (vim or vi)
followed by the name of the file to edit (existing or new).
ADVICE:
I highly recommend that if you plan to use this editor
you take the time to learn a little about it beyond the bare minimum!
If you don't, you are likely to find vim quite tedious.
But a little time spent up front learning some shortcuts will save
much time and tedium in the long run.
The rest of this document presents an assortment of tips that
should help.
There are several ways to learn more:
- An interactive tutorial can be started by typing vimtutor
from the command line.
- From within within vim, typing
:help and pressing ENTER brings up the built-in help.
There's lots of good information here,
though navigating it is pretty quirky
(but explained in the first screen or so).
- You may also at some point want to look at the
vim home page.
A note about notation:
In the rest of this document,
- Typewriter font (like this) denotes text you should
type exactly as shown.
- Italics (like this) denotes something
you should supply (e.g., a filename),
The first thing to know is that
vi, unlike many editors, has two distinct “modes”,
and what happens
when you press keys depends on which mode you are in.
The modes are:
- Insert mode, in which the characters you enter are inserted
into your file.
- Command mode, in which the characters you enter are
interpreted as commands (many listed below).
Commands that begin : should be followed by
pressing ENTER.
(Why this distinction?
My guess is that the original designer of vi wanted something
optimized for editing text, as opposed to simply entering it.)
Several commands put you into insert mode (i, a, etc.).
vim displays
INSERT at the bottom of the screen if you are in insert mode.
To get out of insert mode, press ESC.
If you try to type commands while in insert mode,
the commands will
just be entered in your file.
Press ESC, delete the commands
from your file, and try the commands again.
If you try to enter text while not in insert mode,
the text will be
interpreted as commands, often with surprising results.
If this happens, first get out of insert mode if necessary
and then use “undo” (u) repeatedly to clean up.
Some basic commands:
- i
puts you in insert mode, before the character under the
cursor. To go back to command mode, press ESC.
- The arrow keys
move the cursor around, at least in vim.
In vim, these work in both modes.
In vi, if they work at all they only do so in
command mode.
If they don't work,
you can use h, j, k, and l.
- The backspace key
in insert mode (in vim) deletes characters.
- :w
saves the file.
You can do this any time -- not just before exiting --
and it's a good idea to do so periodically, just in case.
You can also say
:w otherfile to save it with another name.
- :q
exits vi.
- :q!
exits vi without saving.
(Useful if you've made a complete mess and
want to quit without saving it.)
The commands in the previous section are enough to get you
started, but if they're all you know,
you will likely find using vim very tedious.
Before looking at more commands it's useful to know
some basic principles:
- Any command can be preceded by a number,
to repeat it however many times
(e.g., 4j to move down 4 lines).
- . by itself repeats the previous command.
- Many vi commands are made up of an “operator”
and a “motion”,
where the command is something such as delete or change,
and the motion is a navigation operation.
- What such a command does is apply the operator to text
from where the cursor is to where the motion would go.
(For example,
d is the operator to delete,
and w
is the command to move to the next “word”,
so dw deletes a “word”.)
- Giving an operator command twice applies it to the whole
line containing the cursor (so dd deletes
a whole line).
You can move around just using the arrow keys,
but it can be tedious (and may not even work in plain vi).
There are several faster ways:
- vi defines a number of “motion” commands
that let you move around.
Some of the more useful:
- 0 takes you to the start of
the current line, $ to the end.
- w moves to the next “word”
(ending with whitespace or punctuation).
- gg goes to the start of the file, G to the
end.
- h, j, k, and l
can be used instead of the arrow keys.
(This may appeal to fanatical touch typists.)
- : followed by a number goes to that line.
(Useful to find the line mentioned in a compiler message.)
- The page-up and page-down keys seem to work and do what their
names suggest, in vim anyway.
- %
with the cursor on a parenthesis or curly brace finds the
“matching” parenthesis or brace.
If instead it beeps,
there is no matching parenthesis or brace.
Useful in spotting programming errors,
since in programs parentheses and braces
usually come in “matching” pairs.
- Sometimes it's easiest just to search for text near where
you want to go:
- Type /searchstring and press ENTER
to search for the next occurrence
of searchstring.
If the search string contains a / character,
precede it with the “escape” character
\.
- To repeat the search,
enter the single character n.
- To search backward, replace the / character with
?.
- To repeat an earlier search, type / and then
press the up arrow repeatedly to search through
previous searches.
- *
searches for the next occurrence of the “word” under
the cursor. Use n to repeat the search.
You can edit text just by going into insert mode and
using the arrow keys and backspace and retyping,
but it can be tedious.
Commands you may find useful:
- x
deletes the character the cursor is on.
- The d command deletes.
dd
deletes the line the cursor is on.
You can delete multiple lines by preceding the command
with a number of lines to delete, e.g., 4dd to
delete 4 lines,
or you can type dd to delete the first,
and then . repeatedly to delete more.
dw deletes a “word”
(as described under “Navigation”).
- The c command changes. cc
deletes the contents of the current line and puts you in
insert mode to enter replacement text.
cw deletes from the cursor position to the
end of the “word” (as for dw)
and then puts you in insert mode to enter replacement text.
As always, press ESC to get out of insert mode.
- rX
replaces the character the cursor points to with X
(X can be any character).
Does not put you
in insert mode, so useful if you only want to change one
character.
- u
undoes the previous command.
control-R redoes it.
Plain vi
only retains the most recent command;
vim retains many commands,
so you can “undo” repeatedly to undo a series of commands.
- a
puts you in insert mode, after the character under the
cursor.
- A
puts you in insert mode at the end of the current line.
- I
puts you in insert mode at the start of the current line.
- O
inserts a blank line before the current line and puts you
in insert mode.
Editing is also a lot less tedious if you know how to cut,
copy, and paste.
- One way is with plain-vi commands, using a buffer that
holds the most recently cut or copied text:
- dd (maybe preceded with a line count)
and dw “cut” text, as described above,
but put it in the buffer.
- yy (also maybe with a line count)
“yanks” (copies) text into the buffer.
- p “pastes” the text in the buffer,
inserting it after the cursor.
- P “pastes” the text in the buffer,
inserting it before the current line.
(I find that this usually works better
if working with whole lines of text.)
- But for more than a line or two you will probably like
“visual mode” (which plain vi doesn't have).
To use it:
- Put the cursor at
the start of the block of text you want to
cut or copy and type v.
- Move the cursor to the end of the block, using
any of the navigation methods.
The selected text should show up highlighted.
- Type d to delete (cut) the text
or y to “yank” (copy) it.
- To paste in the cut/copied text,
use p or P as described above.
:help visual-mode for more information.
- If you're in a graphical environment and want to
paste in text from another window:
- Select the text and copy it as you usually do
(control-C in most programs).
- Get into insert mode where you want to paste the text.
- Paste it in either using the “edit” menu of the terminal
window or with control-shift-V.
But see below under “indentation” for how to avoid what might
be ugly indentation.
Searching is described earlier, under “navigation”.
There are a couple of ways to do search and replace:
- One way combines commands described earlier
(but only works on “words”):
- Search as described earlier.
- Use cw to change the word.
- To repeat, use n to find the next occurrence
and . to repeat the cw.
- Another way is a global search and replace:
:%s/old/new/gc.
Replaces all occurrences of old with new,
prompting to confirm each change.
(If you don't want the prompt, leave off the ending c.)
You can also do this to a single line or a range of lines.
:help substitute for more about that.
If you're editing program source code with a filename
ending in a suffix vim knows about
(e.g., .scala or .c),
vim will try to automatically indent according
to its rules for the language.
(There are ways to customize this, but they're a little beyond
the scope of this document.)
Some things to know:
- Pasting in text from another window sometimes produces
very strangely indented text.
To keep this from happening,
before doing the insert type :set paste,
and after doing the insertion
type :set nopaste
to get back to normal automatic indentation.
- The = command reindents according to vim's
rules based on file suffix.
== reindents the current line,
and you can use . to repeat on additional lines.
(Helpful if you've modified a program in a way that
leaves the indentation out of whack.)
gg=G reindents the whole file.
(gg moves to the start, then =G reindents
to the end.)
- If you type just q rather than :q,
vim thinks you want to record a macro.
The status line at the bottom of the screen
will show “recording”.
Press q to make it stop.
(If you want to know more about macros,
:help record tells you a little.)
- If you type q: rather than :q,
vim thinks you want it to display
a history of commands and shows them to you in a subwindow.
Type :q to make that go away.
- Sometimes when you start vim to edit an existing file,
you get
a screenful of messages starting “ATTENTION” and
“Found a swap file”.
- What this means:
vim creates a hidden file that saves information
that can help with recovery if it crashes.
This file is deleted when you exit the program normally
(with q), but if vim crashes
it is kept, in the hope that it will be useful in
recovering from the crash.
And if you exit from vim by
just closing the terminal window
(rather than exiting with :q),
vim interprets that as a crash.
- What you should do:
At the end of all those messages there should be a prompt
asking you whether you want to open the file anyway or what.
If you respond R vim
will try to recover unsaved changes; otherwise not.
To actually delete this hidden file, so you don't get
that same screenful of messages next time, respond D.
vi can work with multiple files; among other things this
makes it easy to copy and paste from one file to another:
- To start with more than one file, just list all
their names, e.g., vim file1 file2.
- To cycle through multiple files,
:n to move to the next file,
:prev to move to the previous file,
:rewind or :rew to go back to the first file.
To exit, use :q repeatedly.
- vim can also “split the screen”,
so you can see more than one file at a time,
or two places in the same file.
:split splits the editing window in half;
:q in either window dismisses it.
Simplest way to move between windows is
with control-W twice.
You can also use :split file to
split the screen and start editing file in
the top half.
- :r filename inserts the contents of filename
after the current line.
Precede the r with a line number to insert somewhere else.
There are a number of things you can to do change how vim
behaves or what it displays.
Here are some of them.
If there's one you like and want to always use,
put it in a file .vimrc in your home directory.
- :set visualbell tells vim not to beep on errors
but to instead flash the screen.
- :set number displays all line numbers.
- :colorscheme name changes the “color scheme”.
To see what's available, type :colorscheme and press
TAB repeatedly to cycle through the available choices;
press ENTER when you come to the one you want.
2021-09-08