Skip to main content

Vim

Introduction

Vim is a very powerful and highly configurable editor with both a CLI and a GUI interface. Vim is an improved and extended version of the original vi editor defined in the POSIX standard.

Vim has become very popular among programmers to edit code as it allows the user to customize and extend its behavior as they see fit. If you ever wonder \"Can Vim do this?\", the general answer is yes.

A part from the fact that Vim is powerful, another very good reason to learn how to use it is the fact that Vi is a standard tool. That means that whenever you ssh into a server and don\'t have a graphical interface, you will always have vi (and sometimes Vim entirely) at your disposal.

In this documentation, we will attempt to help you get familiar with Vim\'s most useful features to help you harness to power you need to be efficient when using Vim to edit code.

As you may have noticed, Vim does not work like many editors. When you launch Vim, you cannot just start typing and get what you expect: what you type being added to the file. This is because Vim is a modal editor. Modal editors, as their name implies have different modes in which different key presses have different effects.

For example pressing u can do radically different things:

  • in normal mode it will undo the last edit.
  • in visual mode it will make the highlighted text lowercase.
  • in insert mode it will add a \'u\' to the buffer.

Vim has 7 basic modes and 7 additional modes which are variations of the basic modes. You are starting to see how powerful Vim can be but in this documentation we will only speak about 4 of the modes:

  • normal mode (or command mode)
  • insert mode
  • visual mode
  • command-line mode

If you want more information about the different modes which are available in Vim you can check out the help section which explains them in detail by using this command in your editor:

:help vim-modes-intro

Getting Help

Vim is a very powerful editor which comes with a burden: there are many settings you can tweak and commands you can use. It is very easy to forget how something in Vim works. Fear not! Vim\'s most powerful feature is its internal documentation system.

To get basic help and understand the basics of Vim you can use vimtutor which, like its name implies, is a simple tutorial for Vim. To start this tutorial, instead of opening Vim by executing the vim program, do it by executing vimtutor.

Once you have gone through this tutorial and know the basic you will still need a way to find some specific information when you need it.

There are two basic times when we will go through the manual:

  • when we now what we are searching for: \"what does u do when I am in visual mode?\"
  • when we don\'t exactly know what we are searching for but we know something related to it: \"what are the different ways to change text to lowercase?\"

Vim offers a nice system to handle these cases through two commands: :help and :helpgrep.

:help

The general form of the :help command is the following:

:help command

This will give you information for command in normal mode.

For example:

:help u

will bring us to information about undoing the last edit in a split pane (this is obviously configurable, but we will get to that). In this pane we can navigate like we would in a normal pane and close it with :q when we are done.

command can be prepended by a context to get information applied to a that context.

By using:

:help v_u

will bring us to information about pressing u in visual mode which makes the highlighted text lowercase.

If you are not sure about exactly what command you want to see the help for you can start typing your help command and use <CTRL>-D to get view the available help sections start with what you wrote.

:helpgrep

When you don\'t know exactly what you are looking for, you can use :helpgrep which, as its name implies, will search for a pattern in the whole documentation, store all the occurrences in a list and jump to the first one.

For example, if we want to find the different places the help pages talk about lowercase text we could just use this:

:helpgrep lowercase

This will open a second pane and jump to the first time the pattern (:helpgrep uses Vim regular expressions (:help regexp)) \'lowercase\' in the help pages.

Not only does :helpgrep jump to the first occurrence but it also saves all the occurrences in a list: the quickfix list.

We will talk more about the quickfix list later on but for now you will probably need these commands:

:cn
:cp
:cwindow

:cn will jump to the next occurrence. :cp will bring you to the previous occurrence. :cwindow will open a window with a list of all matches where you can move around like a normal Vim buffer and press <Enter> to go to a specific match.

Like normal panes, when you are finished you can close the helpgrep pane with :q.

If you want more information on the help system in Vim you can go meta and ask help for the help system itself.

:help help

Basic Configuration

When launched, Vim will read its configuration from various locations we will talk about in this documentation. The best-known and easiest way to configure Vim in a simple way is to edit its \"run commands\" file which is generally located in your $HOME directory under the name .vimrc.

Actually, Vim is much more than just and editor: it has its own scripting language called vimscript which allows you to define custom bindings, functions, operators (but we will get to that). The .vimrc file is just a vimscript file which will be sourced when Vim starts. This means you can do almost anything you want in this file.

Before we go into a list of basic configuration options, you need to know how to set these options, unset them and query their current value.

There are two types of options: the booleans ones and the ones which take a value.

Our first example will be the number option which enables or disables line numbering on the left side of your pane.

:set number
:set nonumber
:set number?

The first line enables the option.

Preprending the option with no unsets it.

Suffixing it with ? will query its value and the answer will be the option name which will be prepended by no if it is unset.

For options which require a value, textwidth for example, it is done like this:

:set textwidth=80
:set textwidth?

The first line will set textwidth to 80 and the second one will query textwidth\'s value which will answer textwidth=80.

When you edit your .vimrc file and you want to test the effects of your edits, you don\'t have to exit and re-renter Vim. You can use the :source command which will read and evaluate the file given to it as a parameter. Also, Vim sets a variable containing the path to its configuration called MYVIMRC.

To use your new configuration, you can use this command:

:source $MYVIMRC

To get you started with Vim configuration, here is a list of useful options you might want to set. If you want more info on any of these options, you can of course use the :help command to see their documentation.

  • Display:
    • number
    • relativenumber
    • wrap
    • encoding
    • linebreak
    • scrolloff
    • splitright
    • splitbelow
    • showcmd
    • lazyredraw
  • Indentation:
    • autoindent
    • cindent
    • smartindent
    • expandtab
    • shiftround
    • shitftwidth
    • smarttab
    • tabstop
    • softtabstop
  • Searching:
    • hlsearch
    • incsearch
    • ignorecase
    • smartcase

Keybindings

Binding basics

You may have noticed that there are some commands you type pretty often and it would be nice to call them easily. This is where custom keybindings are useful.

For example, the coding style forbids having trailing whitespace in your files, to make sure you don\'t have any, you can use the following substitution command:

:%s/\s\+$//e

This is a pain to type and is prone to error. Let\'s see how we could configure Vim to bind this to a set of key presses.

The basic way of mapping keys in Vim is to use the :map command. This will allow you to map keys for multiple modes which is generally not what we want as we will want to have different mappings for different modes.

That is when modal mapping comes into play, allowing us to map a key combination for specific modes. In our example, we are going to want to map our keybinding for normal mode which can be done using :nmap. For info about the syntax for other modes, you can see :help map-modes.

One last problem occurs, what if one of the characters in to command part of our binding is another binding, or even worse, a keys of the binding itself?

Take this for example:

:nmap dd O<esc>jddk

This looks like a nice binding to clear a line:

  • open a new line above the current one
  • get back to normal mode
  • go to the line below the current one (the initial line)
  • delete it
  • go back to the new line

If you try this, you will see Vim hang. You can stop it by pressing \<Ctrl>-c.

The problem is that here, you are using dd in a mapping of dd and Vim keybindings are recursive.

Fear not, Vim has a very simple solution: use :nnoremap which is the same thing as :nmap but without recursion and behaves as expected.

:nnoremap dd O<esc>jddk

Coming back to our example to remove trailing whitespace, what we want to do is type :%s/\s\+$//e followed by <Enter>. The <Enter> part i represented by <Cr> in Vim which stands for carriage return. Our binding could look something like this if we wanted to bind it to <Space> c:

:nnoremap <Space>c :%s/\s\+$//e <Cr>

One key to bind them all

You will probably start having a bunch of different bindings for a bunch of different stuff you want to do and might not have enough keys on your keyboard to bind them all without unbinding basic commands or remembering insanely long key combinations.

In order to avoid that problem, you can namespace your bindings be having a special key called the leader which you can use as the first key of all your bindings.

Any key can be your leader but many choose the space bar which we can bind to nop in normal mode and the use as a leader. We can now rework our previous example which would now look like this but behave itself in exactly the same way.

let mapleader = "\<Space>"
:nnoremap <Space> <nop>

:nnoremap <Leader>c :%s/\s\+$//e <Cr>

Now you can create lots of bindings and prefix them with <Leader> and if you ever want to change the first key it will be easy to do so.

A small list of things you might want to have bindings for could be:

  • edit your vimrc file
  • source your vimrc file
  • open a new tab/split
  • open the file explorer
  • remove empty lines in the beginning/end of files

If you want to have buffer-local mappings for specific file-types (commenting lines or such things) you can check out :help LocalLeader.

As this documentation is, of course, not exhaustive, here are a bunch of interesting links to go further down the rabbit hole: