How to Use Vim and vi: Edit, Save and Exit

How to Use Vim and vi: Edit, Save and Exit

Reading time1 min
#linux#vim#vi#text-editor#terminal

How to Use Vim and vi: Edit, Save and Exit

Vim is installed on almost every Linux server, and vi is usually a minimal build of Vim. It is also what git commit, crontab -e or visudo may open when no other editor is configured. A handful of commands is enough to edit config files comfortably, and to avoid the classic situation where a file is open, typing does strange things and nothing seems to close it.

How to exit Vim

Press Esc (twice does no harm) to get back to Normal mode. Then type one of these:

CommandWhat it does
:qquit, works only when there are no unsaved changes
:q!quit and throw away changes
:wqsave and quit
:x or ZZsave only if something changed, then quit
ZQquit without saving
:wqasave all open files and quit
:qa!quit everything, discard all changes

Commands that start with : appear at the bottom of the screen and need Enter. ZZ and ZQ (capital letters) act immediately.

The error messages you are likely to see:

  • E37: No write since last change (add ! to override): there are unsaved changes. Use :wq to keep them or :q! to drop them.
  • E45: 'readonly' option is set (add ! to override): the file was opened read-only, for example with view. If you own it, :w! saves anyway.
  • E212: Can't open file for writing: you have no permission, typically a file in /etc opened without sudo. Save a copy with :w /tmp/hosts.new and quit, or in Vim (not Neovim) write through sudo with :w !sudo tee % > /dev/null. Next time, open the file with sudoedit /etc/hosts.

If the screen stops reacting, you may have pressed Ctrl+S, which pauses terminal output. Ctrl+Q resumes it. Ctrl+Z suspends Vim and drops you to the shell; fg brings it back.

Modes

Vim is modal. The same key does different things depending on the mode:

  • Normal: the default. Keys are commands, so dd deletes a line and u undoes.
  • Insert: keys insert text. The bottom line shows -- INSERT --.
  • Visual: select text with v (characters), V (lines) or Ctrl+v (a block).
  • Command-line: after typing :, / or ?.

Esc always takes you back to Normal mode.

Open a file

vim notes.txt              # opens it, or creates it on first save
vim +42 app.py             # cursor on line 42
vim +/listen nginx.conf    # cursor on the first match
view /etc/fstab            # read-only
vimdiff a.conf b.conf      # side-by-side diff

Write text

From Normal mode, enter Insert mode with:

  • i insert before the cursor, a after it
  • I insert at the start of the line, A at the end
  • o open a new line below, O above

Type the text, press Esc, then save with :w. To save under another name, :w new.txt writes a copy and keeps you in the current file, while :saveas new.txt switches to the new file.

Modern Vim handles pasting into the terminal automatically. If pasted code still turns into a staircase of growing indentation, run :set paste before pasting and :set nopaste after.

Move around (Normal mode)

  • h j k l: left, down, up, right (arrow keys work too)
  • w and b: next and previous word, e to the end of a word
  • 0, ^, $: start of line, first non-blank character, end of line
  • gg and G: first and last line, 42G or :42 for line 42
  • Ctrl+d and Ctrl+u: half a page down and up
  • %: jump to the matching bracket

Edit (Normal mode)

  • x: delete the character under the cursor
  • dd: delete (cut) the line, 5dd for five lines
  • dw: delete a word, D to the end of the line
  • cw: change a word (delete it and enter Insert mode)
  • r: replace one character
  • yy: copy (yank) the line, yw a word
  • p and P: paste after and before the cursor
  • u undo, Ctrl+r redo
  • .: repeat the last change
  • >> and <<: indent and unindent the line

Operators like d, c and y combine with any motion, and a number repeats it: d$ deletes to the end of the line, y3w copies three words, ci" changes the text inside quotes, 3dd deletes three lines. This is where Vim gets fast.

Visual mode

Press v, V or Ctrl+v, move to extend the selection, then act on it: d to delete, y to copy, > to indent, or : to run a command on the selected lines. To comment out several lines: Ctrl+v, move down with j, press I, type # , then Esc, and the text appears on every line.

Search and replace

/listen          search forward, n for next, N for previous
?error           search backward
*                search for the word under the cursor
:%s/old/new/g    replace everywhere in the file
:%s/old/new/gc   replace everywhere, confirm each one
:10,20s/^/# /    add "# " at the start of lines 10 to 20
:noh             clear search highlighting

Add \c to a pattern to ignore case for one search, for example /error\c.

The swap file warning

E325: ATTENTION ... Found a swap file by the name ".config.yml.swp" means the file is either open in another Vim session or a previous session crashed. The prompt offers:

  • O open read-only, E edit anyway
  • R recover unsaved changes from the swap file
  • D delete the swap file (only offered when the session that created it is gone)
  • Q quit, A abort

If another session has the file open, quit and finish there; two editors on one file will overwrite each other. After a crash, choose R, check the content, save, and delete the .swp file.

A minimal ~/.vimrc

set number
syntax on
set expandtab tabstop=4 shiftwidth=4
set ignorecase smartcase
set hlsearch incsearch

vi, Vim and the default editor

vi on Debian and Ubuntu is often vim-tiny, and on the RHEL family it is vim-minimal. The commands above work in both, but syntax highlighting and other features need the full package: sudo apt install vim or sudo dnf install vim-enhanced. The full package also includes vimtutor, an interactive lesson of about half an hour that is the fastest way to build the muscle memory.

To choose which editor other tools open, set EDITOR and VISUAL in ~/.bashrc, or pick per tool:

export EDITOR=vim VISUAL=vim
git config --global core.editor vim
sudo update-alternatives --config editor    # system default on Debian, Ubuntu

Set them to nano instead if you would rather not use Vim at all.

Quick reference

Esc              back to Normal mode
:w               save
:wq  :x  ZZ      save and quit
:q!  ZQ          quit without saving
i  a  o          start typing (before, after, new line)
dd  yy  p        cut line, copy line, paste
u  Ctrl+r        undo, redo
/text  n  N      search, next, previous
:%s/a/b/g        replace all
gg  G  :42       first line, last line, line 42
:set number      show line numbers