Nandishwar Singh

Home / Learn Linux / Lesson 10

Editing files with Vim

Open, edit, save and quit, then the moves that make Vim fast.

Lesson
10 of 30
Time
About 40 minutes

On this page

  1. Why Vim
  2. Modes: why Vim feels strange
  3. Survival: open, type, save, quit
  4. Moving in Normal mode
  5. Getting into Insert mode
  6. Deleting, changing, copying
  7. Selecting: Visual mode
  8. Search and replace
  9. Make Vim nicer: ~/.vimrc
  10. Root's files: sudoedit
  11. When Vim says ATTENTION
  12. Learn the rest: vimtutor
  13. Common mistakes
  14. Practice
  15. Cheat sheet

Why Vim

Sooner or later you'll SSH into a server and need to change a config file. There's no mouse and no desktop, and the one editor you can count on finding on every Linux and Unix machine is vi, or its modern version, Vim. Learn the basics once and you can edit files anywhere.

Ubuntu also has nano, which is simpler and shows its keys at the bottom of the screen (^O means Ctrl+O to save, ^X to exit). Use it if you prefer, but learn enough Vim to survive, because some servers won't have anything else.

Make a practice file first:

$ mkdir ~/vim-lab
$ cd ~/vim-lab
$ printf "# web server settings\nport = 8080\nhost = localhost\nworkers = 2\ndebug = true\nlog = /var/log/web.log\n" > server.conf
$ cat -n server.conf
     1  # web server settings
     2  port = 8080
     3  host = localhost
     4  workers = 2
     5  debug = true
     6  log = /var/log/web.log

Modes: why Vim feels strange

In most editors, every key you press types a letter. In Vim, keys are commands until you say you want to type. That's the one idea that makes Vim click. It has modes:

ModeYou're in it whenKeys do
NormalYou open a file, or press EscMove, delete, copy, paste
InsertYou press i (and others below)Type text, like any editor
Command-lineYou press : in Normal modeSave, quit, search and replace
VisualYou press v or VSelect text

The bottom line of the screen shows -- INSERT -- or -- VISUAL -- when you're in those modes. **When in doubt, press Esc** (twice doesn't hurt). It always takes you back to Normal mode.

Survival: open, type, save, quit

$ vim server.conf

Then:

  1. Press i to start typing. The bottom line shows -- INSERT --.
  2. Type your change. Arrow keys and Backspace work as you'd expect.
  3. Press Esc to go back to Normal mode.
  4. Type :wq and Enter to write the file and quit.
Type (in Normal mode)Does
:wSave
:qQuit (refuses if there are unsaved changes)
:wq or ZZSave and quit
:q!Quit and throw away your changes
uUndo
Ctrl+RRedo

If you're stuck and the file is a mess, Esc then :q! gets you out with nothing changed. That's the most important line in this lesson.

Try it

  1. Open server.conf, change 8080 to 9090, save and quit. Check the result with cat.
Answer

vim server.conf, move to the 8080 with the arrow keys, press i, change the number, Esc, :wq and Enter.

$ cat ~/vim-lab/server.conf
# web server settings
port = 9090
host = localhost
workers = 2
debug = true
log = /var/log/web.log

Moving in Normal mode

The arrow keys work, but these are faster once your fingers know them:

KeysMove to
h j k lLeft, down, up, right
w / bNext word / back a word
eEnd of the word
0 / ^ / $Start of the line / first character / end of the line
gg / GFirst line / last line
5G or :5Line 5
Ctrl+D / Ctrl+UHalf a page down / up
%The bracket that matches this one

Turn on line numbers with :set number so you can jump to a line someone mentions, like the line number in an error message. :set nonumber turns them off.

Most commands take a count in front. 3j moves three lines down, 2w two words forward.

Try it

  1. Open server.conf and jump to the last line, then to line 3, then to the end of that line.
Answer

G, then 3G (or :3 and Enter), then $.

Getting into Insert mode

i is only one of several ways in, and the others save keystrokes:

KeysStart typing
i / aBefore / after the cursor
I / AAt the start / end of the line
o / OOn a new line below / above

A is the one you'll use most for config files: jump to the end of a line and add something. o adds a new setting on the line below.

Try it

  1. Add a new line timeout = 30 after workers = 2.
Answer

Go to the workers line (4G), press o, type timeout = 30, Esc, then :wq.

$ cat ~/vim-lab/server.conf
# web server settings
port = 9090
host = localhost
workers = 2
timeout = 30
debug = true
log = /var/log/web.log

Deleting, changing, copying

Editing commands are a verb plus a motion: d (delete) plus w (word) is dw, "delete a word". Doubling the verb works on the whole line.

KeysDoes
xDelete the character under the cursor
ddDelete (cut) the line
dw, d$ (or D)Delete a word, delete to the end of the line
cw, ccChange a word, change the whole line (deletes it and starts Insert mode)
r then a keyReplace one character
yy, ywCopy ("yank") the line, a word
p / PPaste after / before the cursor
.Repeat the last change

Counts work here too: 3dd deletes three lines, 5x five characters. And everything you delete goes into a register, so dd then p moves a line: cut it, move, paste.

Try it

  1. Delete the debug = true line.
  2. Copy the host line and paste it below itself, then change the copy to host = 0.0.0.0.
Answer
  1. Go to it (/debug and Enter), press dd.
  2. Go to the host line, yy then p. On the new line, cc, type host = 0.0.0.0, Esc, and :wq.
$ cat ~/vim-lab/server.conf
# web server settings
port = 9090
host = localhost
host = 0.0.0.0
workers = 2
timeout = 30
log = /var/log/web.log

Selecting: Visual mode

When a motion isn't enough, select first:

Then press d to delete, y to copy, or > / < to indent or unindent the selection. A classic trick: comment out several lines by selecting them with Ctrl+V down the first column, pressing I, typing # , then Esc.

Try it

  1. Comment out the port and host lines in one go.
Answer

Go to the port line, Ctrl+V, j to also select the host line, I, type # , then Esc. The # appears on both lines after you press Esc.

$ cat ~/vim-lab/server.conf
# web server settings
# port = 9090
# host = localhost
host = 0.0.0.0
workers = 2
timeout = 30
log = /var/log/web.log

Search and replace

TypeDoes
/word / ?wordSearch forward / backward
n / NNext / previous match
*Search for the word under the cursor
:s/old/new/Replace the first old on this line
:s/old/new/gReplace every old on this line
:%s/old/new/gReplace every old in the whole file
:%s/old/new/gcThe same, but ask about each one

The % means "every line". The patterns are the same regular expressions as grep and sed (lesson 12).

Try it

  1. Replace every web with api in the file.
Answer

:%s/web/api/g and Enter.

$ cat ~/vim-lab/server.conf
# api server settings
# port = 9090
# host = localhost
host = 0.0.0.0
workers = 2
timeout = 30
log = /var/log/api.log

Make Vim nicer: ~/.vimrc

Vim reads ~/.vimrc when it starts. A few lines make it far friendlier:

$ cat > ~/.vimrc << EOF
> set number
> syntax on
> set tabstop=4 shiftwidth=4 expandtab
> set ignorecase smartcase
> set hlsearch
> EOF
$ cat ~/.vimrc
set number
syntax on
set tabstop=4 shiftwidth=4 expandtab
set ignorecase smartcase
set hlsearch

Line numbers, colours, four-space indents, case-insensitive search unless you type a capital letter, and highlighted search results. Any :set command you type inside Vim works in this file without the colon.

Root's files: sudoedit

To edit a file that only root can change, don't run sudo vim. That runs the whole editor as root, along with any plugins and settings. Use sudoedit, which copies the file, opens the copy in your editor as you, and puts it back as root when you quit:

$ sudoedit /etc/hosts

sudoedit uses the editor named in the EDITOR variable, and Ubuntu's default is nano. To make it Vim, add this to ~/.bashrc:

$ echo 'export EDITOR=vim' >> ~/.bashrc
$ source ~/.bashrc

If you forgot and opened a root file in Vim as yourself, you'll get a warning that it's read-only. :w !sudo tee % > /dev/null saves it anyway: it sends the buffer to sudo tee and writes it to the current file (%), the same sudo tee trick from lesson 8.

When Vim says ATTENTION

While a file is open, Vim keeps a hidden swap file next to it, like .server.conf.swp, so nothing is lost if your SSH connection drops. If you open a file that has a swap file, Vim stops with E325: ATTENTION and asks what to do:

Learn the rest: vimtutor

Vim comes with a 30-minute interactive lesson. Run vimtutor, and it opens a practice copy of the tutorial that you edit as you read. It's the fastest way to make all of this stick, and you can do it again any time.

Common mistakes

Practice

Start from a fresh copy of the practice file, then do these in order, each one on the result of the last:

$ printf "# web server settings\nport = 8080\nhost = localhost\nworkers = 2\ndebug = true\nlog = /var/log/web.log\n" > server.conf
  1. Change workers = 2 to workers = 8 using cw on the number.
Answer

/workers Enter, $ to the end of the line (the cursor lands on 2), cw, type 8, Esc, :wq. (r8 would also work, since it's one character.)

$ grep workers ~/vim-lab/server.conf
workers = 8
  1. Move the log line so it's the second line of the file.
Answer

G to the last line (the log line), dd to cut it, gg to the first line, p to paste below it, then :wq.

$ cat ~/vim-lab/server.conf
# web server settings
log = /var/log/web.log
port = 8080
host = localhost
workers = 8
debug = true
  1. Add ; to the end of every line except the comment, with one command.
Answer

:2,$s/$/;/ and Enter. 2,$ means line 2 to the last line, and $ in the pattern means the end of each line.

$ cat ~/vim-lab/server.conf
# web server settings
log = /var/log/web.log;
port = 8080;
host = localhost;
workers = 8;
debug = true;
  1. Delete lines 3 to 5 with one command in Normal mode.
Answer

3G then 3dd. Or from the command line: :3,5d.

$ cat ~/vim-lab/server.conf
# web server settings
log = /var/log/web.log;
debug = true;
  1. Make a mess on purpose (press random keys in Normal mode), then get the file back exactly as it was without saving.
Answer

Esc then :q!. Or undo everything with u repeatedly, or :e!, which reloads the file from disk.

  1. Make EDITOR=vim permanent, then open /etc/hosts with sudoedit and quit without changes.
Answer
$ echo 'export EDITOR=vim' >> ~/.bashrc
$ source ~/.bashrc
$ sudoedit /etc/hosts

Vim opens the file. :q to leave.

Cheat sheet

KeysWhat they do
i, a, I, A, o, OStart typing: before, after, line start, line end, new line below, above
EscBack to Normal mode
:w, :q, :wq, ZZ, :q!Save, quit, both, both, quit without saving
h j k l, w b eMove by character, by word
0 ^ $, gg G, 5GLine start/first char/end, file start/end, line 5
x, dd, dw, DDelete char, line, word, to line end
cw, cc, rChange word, line, one character
yy, p, PCopy line, paste after, before
u, Ctrl+R, .Undo, redo, repeat
v, V, Ctrl+VSelect characters, lines, a block
/word, n, N, *Search, next, previous, word under cursor
:%s/old/new/gReplace everywhere (gc to confirm each)
:set numberLine numbers
~/.vimrcYour settings
sudoedit fileEdit a root-owned file safely
vimtutorThe built-in 30-minute lesson