The Vim logo, licensed under the VIM LICENSE

vi cheat sheet

Notes published the
7 - 9 minutes to read, 1790 words
Categories: editing
Keywords: cheat sheet editing vim

Target audience

These notes are for those that want or need to begin to use a vi-based editor and have zero experience with it.

It is also for those that need to use a vi editor right now and do not have enough time to learn how to use it properly.

Note 📝
This is a cheat sheet; it is not accurate, complete, and omits a lot of details. But it should be complete enough for a quick start.

Why should you want to learn to use a vi-compatible editor?

vi is ubiquitous

vi is part of the POSIX standard and is normally available on all GNU/Linux and BSD systems. It can be found on most servers, but also on embedded devices (busybox provides, for example, a vi editor), and there are ports for Windows, DOS, OS/2, Amiga, android and other systems.

It is fast and efficient

Unlike Emacs, which stands for "Eight Megs And Constantly Swapping", vi is efficient.</sarcasm>

Jokes apart, compared to other editors, vim does not use many resources. When dealing with big files, or on a busy system, this can make the difference between being able to edit a given file or not.

Which vi should I use?

Seems like a dumb question, but there are multiple vi implementations, even for a specific platform.

While it should not make any difference, I suggest learning vi with nvim.

Neovim vi features are generally compatible with other vi editors, but it has the advantage of having better defaults.

For example it

  • enables filetype detection

  • syntax highlightning

  • automatic indendation

  • navigation with arrow keys(!)

and other settings that one would expect on most modern editors.

Other vi editors tend to have a more minimalistic approach, and configuring a vi editor is not always as easy as it seems.⁠[1])

Even if it is trivial to change those settings, if one does not know that those can be enabled, they are not changed, those good defaults are important, especially when one does not know the program very well and is learning how to use it.

If Neovim is not an option, vim is probably the currently most used vi editor. Compared to Neovim, it provides also a graphical vim editor (gvim), which I really enjoyed using on Windows systems.

The first and most important concept to understand when beginning to work with vi

vi has different modes.

When the editor is started, vi is in normal mode.

In this mode it is possible to execute commands, like deleting one or multiple lines, searching patterns, executing external programs, replacing text, jumping to a specific position, closing the document, and so on.

The most important thing to know is that it is not possible to insert text directly from the normal mode.

When in insert mode, one can type content directly as one would do with a normal editor.

Note that even if it is called insert mode, it is possible to edit text, thus also removing and replacing content, not only adding it.

The easiest way to change from "normal mode" to "insert mode", is with i (mnemonic for insert). For changing from "insert mode" to "normal mode", use Esc

nvim adds -- INSERT -- at the bottom, to make it easier to realize in which mode one is. If in doubt, press Esc to be sure to be in normal mode.

Note: Pressing Esc only once might not be enough, as there are other modes that one could activate accidentally

Toggle between command and insert(/edit) mode

  • Esc and i

  • a works like i, but appends, ie it moves to the end of the cursor

  • A and I works like they lowercase counterpart, but work on a line-basis, and not character basis

Saving file and close the editor

Once we know how to open the editor and insert text, it would be nice to be able to save the changes (or dismiss them) and close the editor, which seems to be one of the most asked questions about vim

Both operations are done in "normal mode". It is possible to define keybindings, like Ctrl+S that can be used from insert mode too but realized only later that this was possible.

Use

  • :w to write changes (thus save them)

  • :q/:quit to quit the editor, it triggers an error if there are unsaved changes

  • :q!/:quit! or ZQ to quit the editor, unsaved changes are discarded

  • :cq to quit the editor with error code 1 (very useful when scripting), unsaved changes are discarded

  • :x/:exit, ZZ or `:wq] to exit, ie write and quit,

Notice that some commands have both a short ad log-form. The short for is usually a mnemonic for the word that describes the action one wants to execute.

I got accustomed to using :x but while opening and closing a lot of files, realized how easier it is to type ZZ. Otherwise, I tend to use :cq if want to dismiss changes.

At least on my keyboards, :cq is easier to type than :q!, and in case I’ve invoked the editor inside a more complex command, like

command1 && nvim file.txt && command2

or

set -o errexit
command1
nvim file.txt
command2

then command2 will not get executed. The most common use-case I have is aborting git commits when writing the commit message.

Text Navigating

Once it is clear how to edit files and save my changes, the next step is how to navigate a document.

The "official" way of navigating between text is getting into normal mode, and use h (for left), j (for down), k (for up) and l (for right).

Especially when learning how to use vim, it seems to make more sense to use the arrow keys, unless

  • one is already accustomed to those keybindings

  • one does not use nvim and does not want to change any settings

In nvim it is possible to navigate from the insert and normal mode directly with

  • arrows (, , and )

  • Ctrl followed by an arrow key

  • Home, End

  • PgUp🠕 and PgDn🠗

like in most graphical editors

Note that pressing the right arrow at the end of the line (or left arrow at the beginning of the line) won’t change the position to another line (but it can surely be configured to work differently)

Once one is proficient enough, it will come more natural to use the normal mode more often and other keys for navigating.

From normal mode it is possible to navigate with the following keys:

  • $ moves to the end of the line (note that $ is also used in regular expressions with the same meaning)

  • 0 moves to the beginning of the line

  • gg moves to the first line of the document

  • G moves to the last line of the document

  • nG, or ngg goes to line n

All those commands can be prefixed by a number to repeat the movement multiple times.

  • h (for left), j (for down), k (for up) and l (for right)

  • b moves to begin of word

  • B is like B, but uses only spaces as separators

  • w moves to next word

  • e moves to the end of the current word

  • B, W and E works like they lowercase counterpart, but use only spaces as separators

In case you are asking yourself how a word is defined:

A word consists of a sequence of letters, digits, and underscores, or a sequence of other non-blank characters, separated with white space (spaces, tabs, <EOL>). […​] An empty line is also considered to be a word.

— `vi --cmd ':h word'`

For example, 5l moves the cursor for five characters on the right instead of one.

Those commands not only move the cursor but also change to insert mode

  • A brings to the end of the line and changes to insert mode

  • I brings to the end of the line and changes to insert mode

  • O inserts a new line before the current and changes to insert mode

  • o inserts a new line after the current and changes to insert mode

Search and replace

From normal mode

  • /regex for searching forward, n to move to next match

  • ?regex for searching backward, n to move to next match

  • :s/search/replace/g will search and replace the next match on the whole line (otherwise remove g)

  • :%s/search/replace/g will search and replace in the entire file

  • :8,10 s/search/replace/g

  • prefix search with \v and use | as separator for multiple searches: /\vword1|word2|word3, or just use the \| separator: /word1\|word2\|word3

Cut, copy and paste

Cut

Deleting means cutting, and is done with d.

It can be combined with other commands, for example

  • dw delete until next word

  • de delete until end of word

  • dW and dE works like they lowercase counterpart, but use only spaces as separators

  • d$ delete until the end of the line

And dd for deleting current line (line ending included, contrary to 0d$)

Paste

There are two commands:

  • p for pasting after current position

  • P for pasting before current position

Copy

One could delete and immediately paste once. For example, for copying until the end of the word, one could use deP (but notice one need to use dep if the word is the last on the line).

A better alternative would be to use the appropriate command: y for yanking.

If you are wondering what yanking has to do with copying, you are not alone.

Just like d, it can be combined with other commands:

  • yw to yank until next word

  • ye to yank until end of word

  • yW and dE works like their lowercase counterpart, but use only spaces as separators

  • y$ to yank until the end of the line

Last but not least

The documentation: :h opens the help page

For example :h d opens the help page for the delete command and :h / opens the help page for search commands.


1. I’m still trying to enable a specific vi configuration (as there are environments where I do not have the luxury to use nvim…​ even if I should try to change that) that works from a normal GNU/Linux setup, PowerShell, cmd.exe, Cygwin, WSL, Cygwin executed from PowerShell prompt, git-bash executed from Cygwin bash, …​ It is frustrating because different terminals have different capabilities…​ and detecting the environment and finding the corresponding setting is not always trivial

Do you want to share your opinion? Or is there an error, some parts that are not clear enough?

You can contact me anytime.