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.
Modal Editor
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
.
Useful links
As this documentation is, of course, not exhaustive, here are a bunch of interesting links to go further down the rabbit hole: