You are on page 1of 59

3/28/2021 Is Vim Really Not For You?

A Beginner Guide

Is Vim Really Not


For You? A
Beginner Guide

“Vim is not for me!” shout out Dave, my colleague developer.

It wasn’t the first time I’ve heard this sentence. The result? Me, explaining to Dave and others
gathering around my desk that learning the basics of Vim can be beneficial to anybody:

https://thevaluable.dev/vim-beginner/ 1/20
3/28/2021 Is Vim Really Not For You? A Beginner Guide

Many CLIs use Vim-like key bindings, like Less for example.
They can easily edit files on remote systems or in docker containers when only Vi (the
ancestor of Vim) or Vim is available.
They can customize Vim like crazy, to match their personal needs and preferences.
They can run Vim everywhere they want.
Vim can edit very large text files without slowing down, like huge log files for
example.
They can learn a new and really fun way for creating and editing content.

To me, Vim is the gamification of coding.

Still, some developers don’t try to understand what Vim is about. At the same time, they have a
strong opinion about it. How can somebody judge something without seriously trying it?

I can’t blame them: I had exactly the same bias years ago. But when I tried to learn to use Vim,
when I tried to understand how it works - not only learning two shortcuts randomly - I fall in
love.

That’s why I would like to share with you today how I learned the very basics of Vim. More
specifically, we’ll see in this article:

How to learn quickly good typing techniques. They are essential if you want to unleash
Vim’s latent power. Even if you don’t use Vim, these techniques have many benefits for
any developer.
The different Vim modes. This is one of the main reason why Vim is so crazy.
The basic Vim shortcuts (keystrokes) for you to be efficient as quickly as possible,
with some tips to remember them easily.
How to speak the Language of Vim.
What Vim’s options are and how to manipulate them.

After that, you’ll speak about Vim with experience and confidence, even if it’s for saying:
“naaaah, Vim is not for me!”.

The goal of this article is not to replace your IDE with Vim from one day to another. I would
recommend to take a step by step approach here.

At the beginning, you can try to use Vim to edit some configuration or other text files. Practicing
what you’ll learn in this article is the key for you to really understand how Vim works and why
it’s so popular, even decades after its creation.

Don’t think that Vim is hard to learn. It’s easy to learn to edit any file, but it’s hard to master.
Vim gurus, coding in the Himalaya for hundred of years, can’t even pretend knowing everything
about Vim. That’s great, because it means that the possibilities of this editor are beyond infinity.

https://thevaluable.dev/vim-beginner/ 2/20
3/28/2021 Is Vim Really Not For You? A Beginner Guide

Doubtful? Follow me. Let’s dive into the wonderful world of Vim together.

Prerequisites: The
Power Is In Your
Fingers
When I decided to learn Vim, I wanted to do it right. Vim allows you to forget your hands and let
you really focus on the most important thing: what you’re writing.

The Mouse: Your False


Best Friend
One of the advantage of Vim is to let your hands on the keyboard, without the constant need to
grab your mouse.

I see you’re afraid: your mouse is like your third hand! It’s so useful and easy! Why would you
not use it?

Your mouse is a bit like an implant a doctor would have put on your body at a very young age,
telling your parent that it’s the best device to do something on a computer. You like it because
you’re deeply used to it, for a very long time.

Ask yourself: why on earth, if the mouse was so perfect, your favorite IDE has keyboard
shortcuts? Maybe because using your keyboard is faster? Easier? More efficient?
More comfortable?

Your mouse is not your best friend. It’s just a friend. Your keyboard is the real brother-from-
another-mother here. The power comes from it, and Vim is perfect for you to harness and unleash
this power.

https://thevaluable.dev/vim-beginner/ 3/20
3/28/2021 Is Vim Really Not For You? A Beginner Guide

Note

If you want to build a complete Mouseless Development Environment, you might be


interested by this book.

That’s why I deeply believe that before learning Vim, you should learn basic typing techniques.
The benefits are great:

You’ll type faster and more accurately.


You’ll be able to increase your speed and accuracy over time.
You won’t focus on your keyboard anymore. Not even a bit.

If you already use these techniques, that’s great! You can directly go to the next chapter.

Efficient Typing: The Two


Rules
We all agree that thinking, for a developer, is more important than knowing how to type. That
said, it’s still nice to feel in control of your tools. As a developer, the keyboard is one of the most
important!

It’s very fulfilling to see your typing improving day after days, months after months, even years
after years. The room for progression is huge, even if it’s pretty quick and easy to learn the
basics.

The first rule you need to learn is placing your hand correctly:

https://thevaluable.dev/vim-beginner/ 4/20
3/28/2021 Is Vim Really Not For You? A Beginner Guide

Source

The keys a , s , d , f and j , k , l , ; are called the row keys. They are the starting points for your
hands. From there, you’ll be able to grab any other key easily.

You’ll notice that there are little bumps on the f and j keys on your keyboard: they are
indicators for you to know where to put your indexes. When they are at the good position, simply
place the other fingers on the other row keys.

The second rule you need to train for: try not looking at your keyboard while you’re typing. If
you don’t remember where a key is, try first to get it without looking, even if it feels random.

I was only typing with two fingers for years. It felt totally foreign to try to follow these rules at
first. Now, I could not type differently, mostly because it’s more comfortable.

It took me only one to two weeks to learn this new way of typing. It’s not because I’m a genius
(definitely not), but because it’s easy.

The First Week


When you decide to use the two rules I described above, you need to try to follow them all the
time. We need % commitment here. When you surprise yourself using your old (and bad)
techniques again, be patient, don’t see it as a failure, and come back to the good ones. This is the
mandatory part of the learning process.

https://thevaluable.dev/vim-beginner/ 5/20
3/28/2021 Is Vim Really Not For You? A Beginner Guide

The first three days are the most difficult. You’ll alternate between good and bad technique
without even noticing it. You’ll do mistakes, and you’ll be slow.

Fortunately, at the end of the week, the amount of mistake will decrease, and you will less and
less need to watch your keyboards.

The Second Week


You’ll notice during the second week the amount of mistakes decreasing even more, and your
need to watch your keyboard will disappear.

At the end of the week, you’ll see your typing speed already improving. The good feelings of
reward will begin to please your sweet brain.

Speed and Accuracy


During your two weeks of initial training, you shouldn’t focus on speed or accuracy. Just type, as
much as you can, and don’t worry about anything else yet, not even the mistakes you make.

After that, you can focus on speed and accuracy: how fast you can type and trying to make as
fewer mistakes as possible.

To train these good typing techniques, from the beginning of your learning experience to the end
of your life, you can use typing software which can drastically help you.

Here’s a list of my favorite ones:

Type Racer
Online Typing Test WPM
Speed Coder

Vim Or Neovim?

https://thevaluable.dev/vim-beginner/ 6/20
3/28/2021 Is Vim Really Not For You? A Beginner Guide

With these fundamentals out of the way, let’s install Neovim.

Neovim? What’s this new weird thing, you might rightfully ask?

Neovim is a refactor of Vim. It’s compatible with everything Vim related. I would definitely
recommend using it, instead of the regular Vim, since it’s optimized out of the box.

Here are the official links for both software:

Neovim
Vim

Because Neovim and Vim are almost identical (with a different philosophy), I’ll continue to call
these two software using the generic term Vim in this article.

Vim’s Configuration
https://thevaluable.dev/vim-beginner/ 7/20
3/28/2021 Is Vim Really Not For You? A Beginner Guide

In Vim, almost everything is configurable. It’s insane, I tell you. You can shape your editor
according to your specific needs and megalomaniac desires.

Depending on if you use Vim or Neovim, your configuration file should be in the following path
by default:

For Vim: ~/.vimrc .


For Neovim: ~/.config/nvim/init.vim or ~/nvim/init.vim (depending on the
value of the environment variable XDG_CONFIG_HOME ).

This configuration file is sweetly named vimrc.

Let’s open your vimrc with your favorite editor (which might be soon replaced by Vim!) and let’s
add some basics things. I’ll explain later the purpose of them:

noremap <Up> <Nop>


noremap <Down> <Nop>
noremap <Left> <Nop>
noremap <Right> <Nop>

and

set clipboard+=unnamedplus

The content of your vimrc and the different plugins for Vim are often written in Vimscript, a
programming language specifically created for the editor. Yet, I wouldn’t advise you to learn this
language, except the basics to configure Vim. It’s quite painful to use. That’s why Neovim wants
to replace it with Lua, which is a very good idea indeed.

Now, let’s launch Vim and, without trying to do anything else, let’s see the basics you need for
you to get started.

The Modes of Vim

https://thevaluable.dev/vim-beginner/ 8/20
3/28/2021 Is Vim Really Not For You? A Beginner Guide

After launching Vim, you will see a welcome screen displaying the very basic commands you
can use. This screen will disappear as soon as you begin to type some content.

Vim is not like your standard editor where you can simply type on your keyboard and your
content will magically appear on your screen. Try to type x , for example: nothing seems to
happen.

This is because Vim has modes, and you can do different things depending on the mode you’re
in. To spot easily the different modes I’m speaking about in this article, I’ll always write them in
uppercase (i.e. NORMAL mode).

Normal Mode
Normally, when you open an editor, you can directly type some content. Not in Vim. Its default
mode is NORMAL mode, where you can edit some existing content.

You can use keystrokes to move where you want and edit what you want: inserting, changing or
deleting words, sentences, or even paragraphs. Without using your mouse once!

https://thevaluable.dev/vim-beginner/ 9/20
3/28/2021 Is Vim Really Not For You? A Beginner Guide

Think of it as a system of shortcuts which allows you to target exactly what you want to edit. The
difference between your default GUI editor and Vim when we speak about shortcuts (or
keystrokes) is significant: they make sense in Vim, most of the time. They follow a certain logic,
and they are composable. That’s why Vim is easy to learn.

For example, the shortcut CTRL+shift+n to find a file in your favorite GUI editor is difficult to
remember because it’s difficult to link what you know (opening a file) and what you want to
learn (the keystroke).

We will come back to the NORMAL mode later, when we will learn the main Vim’s keystrokes.

Insert Mode
Look at your cursor in Vim: it should normally be a square. Now, let’s hit our first NORMAL
mode keystroke: i , for i nsert.

What’s this dark magic? Your cursor became a pipe! In the bottom left corner, the indicator --
INSERT-- appeared! How impressive! How marvelous! Do you think I’m exaggerating? Yes I
do!

Welcome to the INSERT mode.

You can finally type your content in this mode: go ahead, type anything you want. To come back
to NORMAL mode and stop inserting, simply hit ESC or CTRL-c . The cursor becomes a square
again, and the --INSERT-- indicator disappears. Don’t be sad, it will come back.

That’s how you work with Vim: juggling between NORMAL mode to edit existing content and
INSERT mode to insert some newcontent.

Visual Mode
There is a third important mode in Vim you’ll often use: VISUAL mode. Its goal? Selecting your
content. From there, you can modify, edit or copy your selection.

To enter VISUAL mode, you might have guessed it already, you need to type v in NORMAL
mode. You’ll see the indicator --VISUAL-- appearing in the bottom left corner of your Vim
instance. Again, to come back to our default mode, NORMAL mode, press ESC or CTRL-c .

https://thevaluable.dev/vim-beginner/ 10/20
3/28/2021 Is Vim Really Not For You? A Beginner Guide

You can as well select entire lines if you start the visual mode linewise with the
keystroke SHIFT+v . That’s not all: you can start visual mode blockwise, using the
keystroke CTRL+v . It’s pretty useful when you have to deal with tables or lists, for example.

Command-Line Mode
You can compare the COMMAND LINE mode as a menu on a GUI. A big and powerful one.

If you type : in NORMAL mode, your cursor will end up automatically at the bottom of Vim.
From there, you can type any command you want. These commands are sometimes called Ex
command.

Here are the most basic ones:

:help to open Vim’s help. Arguably the most useful command. This help is insanely
complete. If you don’t remember how to quit Vim for example, you can type :help
quit .
:q to q uit the current window. If there is only one window (it’s the default), you’ll
finally quit Vim.
:q! to quit without saving. Imagine that you yell at your editor you want to quit,
whatever the consequences!
:w to w rite (save the current file open).
You can even combine some ex command: :wq to write and quit. Or just use :x .
:e <path> to edit a file. The path can be absolute or relative.

Now that you know how to access Vim’s help, I’ll put at the end of each section the help
commands you can use to go deeper. For example, here’s the ones for this section:

Vim help

:help helphelp :help vim-modes :help insert.txt :help visual.txt :help


cmdline.txt :help write-quite :help ex-cmd-index

Don’t worry if you don’t understand what’s written in the help itself, or if it’s too daunting. Bear
with me in this article, and later, when you’re more comfortable with Vim, you can come back to
this delightful help.

https://thevaluable.dev/vim-beginner/ 11/20
3/28/2021 Is Vim Really Not For You? A Beginner Guide

General Vim
Keystrokes

Now that we understand the general concept of Vim and its modes, let’s see the most important
keystrokes in NORMAL mode you need to be aware of. I encourage you to try them in Vim as
you read.

Writing Your Own


Cheatsheet
You can find countless cheatsheets on the Internet which will give you as many keystrokes as
you want. When I was learning how to use Vim, I used one of them.

https://thevaluable.dev/vim-beginner/ 12/20
3/28/2021 Is Vim Really Not For You? A Beginner Guide

At the same time, I was writing my own cheatsheet.

Why? Personally, it helped me a lot memorizing these keystrokes. Writing is a powerful way to
make the information yours.

Organize your cheatsheet as you like, and use whatever you want (paper, evernote,
mindmaps…). For mine, I’m using Joplin, a free and open source note taking system.

Bonus points if you write your cheatsheet… in Vim!

The rest of the article will give you the basics keystroke you need at the beginning. Be aware that
Vim is full of subtleties which give you power and efficiency, depending on the context. It’s a
never ending learning process which makes this editor so interesting, so fun to use, and so
rewarding!

Searching
I wrote a whole article about searching in Vim, but, for now, the keystroke / should be enough.
If you use it, your cursor will end up the bottom of the screen. From there, type your search and
press ENTER .

You can go to the n ext found occurrence by typing n . To go to the previous one, use N .

You can also use these two keystrokes in NORMAL mode to search the word under the cursor:

* - Search forward.
# - Search backward.

Undo and Redo


What would we do without the essential undo and redo?

u will u ndo your last edit.


CTRL-r will r edo. You can think of it as you being in control ( CTRL ) of your content.

Insert Mode
https://thevaluable.dev/vim-beginner/ 13/20
3/28/2021 Is Vim Really Not For You? A Beginner Guide

We saw previously that the keystroke i moved your soul in the reassuring world of INSERT
mode.

There are other handy keystrokes to do so, introducing welcome subtleties:

i - i nsert content before the current character.


a - insert content a fter the current character.
A - insert content A fter everything. It will move your cursor to the end of the line and
enter INSERT mode.
o - o pen a new line, below the current one, and allow you to insert your content.
O - O pen a new line above the current one.
esc or CTRL-c or CTRL-[ - bring you back to NORMAL mode if you are in INSERT
mode.

Vim help

:help search-commands
:help undo-redo

Vim’s Motions
Motions in Vim allow you to move your cursor horizontally (on a line) or vertically.

Note that you can combine motions with a count: if you want to make your motion times for
example, you can do <your_motion> . Replace <your_motion> with whatever motion you
want.

You can use motions in NORMAL mode and VISUAL mode.

Forget the Arrow Keys


To be totally honest with you, this was the hardest part for me: not using the arrow keys to move
your cursor.

As I said in the first part of the article, your fingers should be on the row keys. First, for your
typing to improve, and second because the Vim’s keystrokes you can use in NORMAL mode are
all around the row keys. Your hands shouldn’t move too much; only your fingers should.
https://thevaluable.dev/vim-beginner/ 14/20
3/28/2021 Is Vim Really Not For You? A Beginner Guide

Now, try to reach the arrow keys from the row keys: yes, you need to move your hand! This is
definitely not what we want.

That’s why, instead of using the arrow keys, we should use the keys h , j , k and l to move
respectively left, down, up and right.

It’s difficult at first: you’ll try to use the arrow keys to move your cursor, and more than once.
That’s why we previously disabled them in the configuration!

How to remember what does h , j , k and l ?

h moves your cursor to the left, and l moves it to the right. It makes sens, since h is
on the left of the sequence hjkl , and l is on the right.
j moves your cursor down. You can remember it since j looks like an arrow which
points down (with a bit of imagination). Another mnemonic method: the key j has a little
bump at the bottom of the key, which means the cursor will go down.
k is the only letter left, so it has to go up. I always imagine a Ninja Turtle jumping up,
saying “Kowabunga”! It’s not even the good spelling (it would be “Cowabunga”) but it
works for me. Please, don’t judge me.

I see your mind full of questions. Fear not, my friend! I’ve got you covered for this one, with
a revolutionary AAA game everybody will speak about in twenty years. To play it,
you must use hjkl .

If you prefer puzzle games, try this wonderful sokoban. You can use hjkl or the arrow keys this
time, but try to only use hjkl .

Moving Horizontally
Here some basic keystrokes to move quickly on a line in NORMAL mode:

w - move forward to the next w ord. A word - by default - is a sequence containing


letters, digits, or underscores.
b - move b ack your cursor to the previous word
- move to the beginning of the current line.
ˆ - move to the first non-blank character on the current line.
- move to the end of the current line.
% - move to the matching bracket when the cursor is already on a bracket.

You can as well move on a specific character on your line using:

f<character> - f ind a character after your cursor.


https://thevaluable.dev/vim-beginner/ 15/20
3/28/2021 Is Vim Really Not For You? A Beginner Guide

F<character> - f ind a character before your cursor.


t<character> - move t o a character after your cursor.
T<character> - move t o a character before your cursor.

After using one of the last four keystrokes, you can move on the character you’ve chosen
with ; to go forward, and , to go backward. A very powerful way to move horizontally!

Moving Vertically
You can move vertically simply by searching the word you want to move on (see above to learn
how to search). There are other ways to move vertically:

<line_number>G - move your cursor to the beginning of an arbitrary line. For


example, G will move the cursor on line .
G - move your cursor to the last line of your file.
G or gg - move your cursor to the first line of your file.

You can as well use different keystrokes to scroll. Here are the very basics:

CTRL-e - scroll the window downwards.


CTRL-u - move your cursor u pward half a screen.
CTRL-d - move your cursor d ownward half a screen.

Vim help

:help cursor-motions
:help left-right-motions
:help up-down-motions
:help scrolling

The Language of
Vim
https://thevaluable.dev/vim-beginner/ 16/20
3/28/2021 Is Vim Really Not For You? A Beginner Guide

In Vim, keystrokes can be seen as “sentences”, describing an action. That’s what I meant when I
was saying that the keystrokes are composable. I know, it sounds weird, but it’s brilliant.

These “sentences” are so common that you’ll associate easily what you know already (the
sentence) by what you need to learn (the keystrokes).

Even better: knowing that Vim has a “keystroke language” will push you to combine them
instinctively to do what you need to do, and, in many cases, it will work!

Operators
Operators are the verbs of the Vim language. They need to be combined with motions or text-
objects to work. Here are some important operators:

d for d elete
c for c hange
y for y ank (copy)

When using the yank operator, you can p ut what you’ve copied using the keystrokes p or P .

https://thevaluable.dev/vim-beginner/ 17/20
3/28/2021 Is Vim Really Not For You? A Beginner Guide

You can combine operators and motions as follows:

d will d elete from your cursor to the end of line. You can use as well the alias D .
dgg will d elete everything from the cursor to the beginning of the file.
ggdG will delete everything in the file!

Text Objects
If operators are the verbs, text objects are the nouns. Simply put, a text object is a set of
character. In Vim, a word is a text object, as well as a sentence or a paragraph .

For example, you can use operators and text objects as follows:

diw will d elete i nside the w ord. It will delete the current word under the cursor.
ciw will c hange i nside the w ord. It will delete the current word under the cursor
and switch to INSERT mode. In short, you… change the word!
dip will d elete i nside the p aragraph.

You can try to change a word or delete a word, it works as well and introduce some subtleties. I
let you find what could be the keystrokes for these!

Vim help

:help operator
:help text-objects

Vim’s Options
You can modify Vim’s behavior by modifying its options.

You can think of an option as a variable. It can be a boolean (which can be switched on and off),
a string, or a number. You can display their values or modifying them using the COMMAND-
LINE mode.

If you want to permanently modify some options, assign their new values directly in your vimrc,
as we did with the option clipboard at the beginning of this article.
https://thevaluable.dev/vim-beginner/ 18/20
3/28/2021 Is Vim Really Not For You? A Beginner Guide

Here are the commands you can use:

:set no<option> - Unset the option.


:set <option>! - Toggle the option.
:set <option>? - Return the option’s value.
:set <option>=<value> - Set a value <value> (string or number).
:set <option>+=<value> - Add the value <value> for a number option, append a
string <value> for a string option.
:set <option>& - Reset the option to its default value.

For example, if you want to display the filetype of the your current file open, you can run:

:set filetype?

Drop the prefix : if you want to set these options in your vimrc.

Vim help

:help options
:help option-list

The Beginning of the


Vim Journey
Congratulations! You’ve been initiated to the dark knowledge of Vim. Let’s summarize what we
learned in this article:

Having proper typing techniques will make you faster, more accurate, and will allow
you to focus solely on your content, not on your keyboard or on your hands. You’ll feel as
well more in control (a good way to lower your stress).
Write your own cheatsheet as you learn new keystrokes, and try to find your own
mnemonics to retain them. It will accelerate your learning process. To remember easily,
associate what you already know with what you want to learn.
You can use a combination of operators, motions, and text objects to edit your text in
NORMAL mode.

https://thevaluable.dev/vim-beginner/ 19/20
3/28/2021 Is Vim Really Not For You? A Beginner Guide

You need to use the row keys h , j , k and l to navigate in Vim, to really appreciate
its comfort, its power, and its fun!
Try for yourself the keystrokes explained here, for you to memorize them using
your muscle memory.
Vim’s options can be switched on, off, toggled, or unset (for booleans). You can as well
modify their values (for strings and numbers). It’s always interesting to display their
values to be sure Vim behave as you expect.

Even if you still don’t like using Vim at that point, at least you tried. You’ll be able to use it when
you’re lost on a distant remote server and, more important, you can now claim, legitimately, that
you don’t like Vim!

What’s next in your Vim learning journey?

You can read the second part of this series of article, Vim for intermediate users.
You should go through vimtutor . If you use Neovim, you just have to execute the ex
command :Tuto . If you use Vim, simply type vimtutor in your shell.
I would heavily recommend reading the book Practical Vim, from Drew Neil (see
below). You’ll learn a lot from it.
Vim is a game: the goal is to use as few keystrokes as you can to accomplish what you
want to do. In that spirit, Vim Golfcan be pretty fun.

If you didn’t become a Vim Hater, you’re now on the path to become a Vim Master.

Related Sources
Learn Vim Progressively - Yann Esposito
Vimcasts - Drew Neil
Practical Vim - Drew Neil
vim-galore - Marco Hinz
Habits of Effective Text Editing - Bram Moolenaar

https://thevaluable.dev/vim-beginner/ 20/20
3/28/2021 A Vim Guide for Intermediate Users

A Vim Guide for


Intermediate Users

Welcome to the second part of this series aimed to make you a better Vim user! If you have no
idea about Vim, you should begin with the first part. In this article, I’ll explain many more
concepts, some of them making Vim truly special compared to other editors. Who wasn’t blown
away discovering Vim’s macros?

Specifically, we’ll see together:

Ways you can organize open files in Vim using buffers, windows, tabs, and the
argument list.

https://thevaluable.dev/vim-intermediate/ 1/17
3/28/2021 A Vim Guide for Intermediate Users

Useful motions to jump quickly from one place to another in your entire codebase.
Mapping new keystrokes to old keystrokes or commands.
Powerful functionalities to repeat some of your keystrokes.
Ways of manipulating the command line history.
Plugins which offers different ways to manage some ideas we saw before.

The amount of information in this article can feel overwhelming. My advice: take your time and
don’t try to swallow everything at once. Experiment with Vim as you read along, try to
understand how it works, and you’ll have a powerful tool you can control entirely with your
keyboard.

Speaking about keyboard...

If you want to build a complete Mouseless Development Environment, you might be


interested by this book.

You’ll see at the end of each sections some related Vim’s help commands. You can read these
help sections directly in Vim when you’re ready to dive deeper.

Vim’s Spatial
Organization
If you’re using an IDE, you’re certainly used to manage your files with tabs. Vim use other ways
to represent and organize open files. Indeed, there are four layers of abstraction you can use for
that: the buffers, the windows, the tabs, and the argument list.

Buffers
A buffer directly match an open file in memory. To make a comparison with a standard IDE, a
buffer would be the content of a tab. The big difference: when you close a tab in an IDE, you
close the file as well. Not in Vim; if you close a window containing a buffer, the buffer is still
there, hidden.

In fact, a buffer can have three different states:

https://thevaluable.dev/vim-intermediate/ 2/17
3/28/2021 A Vim Guide for Intermediate Users

active - The buffer is displayed in a window.


hidden - The buffer is not displayed, but it exists and the file is still open.
inactive - The buffer is not displayed and empty. It’s not linked to any file.

The content of a file in a hidden buffer is not directly visible in Vim. At that point, you might
wonder: how do we know that this buffer is still open, if we can’t see it?

To see all opened buffered, we can look at the buffer list. You can use the
command :buffers to display it. Each line contains:

1. The buffer unique ID.


2. Indicators displaying different informations (for example a for active, h for hidden, or
(space) for inactive).
3. The name of the buffer, if any. It can be the filepath of the file linked to the buffer.
4. The line number where the cursor is.

For example: %a "layouts/shortcodes/notice.html" line means that the buffer


ID is in state a (active), its name is layouts/shortcodes/notice.html and the cursor in
this specific buffer is on line . You can as well know what’s the current buffer displayed with
the flag % just before its state.

To navigate through the buffer list, you can use these commands:

:buffer <ID_or_name> - Move to the buffer using its ID or its name.


:bnext or :bn - Move to the next buffer.
:bprevious or :bp - Move to the previous buffer.
:bfirst or :bf - move to the first buffer.
:blast or :bl - move to the last buffer.
CTRL-^ - switch to the alternate buffer. It’s indicated in your buffer list with the
symbol # .
<ID>CTRL-^ - Switch to a specific buffer with ID <ID> . For example, CTRL-
^ switch to the buffer with ID .

You can as well apply a command to all buffers using :bufdo <command> .

Not all buffers are displayed in the buffer list. To display unlisted buffers, you can use the
command :buffers! or ls! . You’ll see unlisted buffer with an indicator u just after its ID.

Now, let’s ask this existential question: how can we create buffers?

If you create a window, a buffer will be created automatically (see below).


:badd <filename> - Add <filename> to the buffer list.

If we can create buffers, we should be able to delete them:


https://thevaluable.dev/vim-intermediate/ 3/17
3/28/2021 A Vim Guide for Intermediate Users

:bdelete <ID_or_name> - Delete a buffer by ID or name. You can specify more than
one ID or name separated with spaces to delete multiple buffers.
: , bdelete - Delete buffers from ID to included.
:%bdelete - Delete all buffers.

If you modify a file, forget to save it, and close the window making the buffer hidden, you won’t
be able to quit Vim. It will complain that you’re hidden buffer is not saved; to get around that, I
would recommend to set the option hidden in your vimrc (by default ~/.vimrc ), as follow:

set hidden

You can try it directly in your current session by running the command :set hidden! to toggle
the option on and off. You can play around with it and see what suits best for you.

To see the value of any option, you can use a question mark. For example: :set
hidden? or :set filetype? .

Vim help

:help buffers
:help :buffers

Windows
A window in Vim is nothing more than a space you can use to display the content of a buffer.
Don’t forget: when you close the window, the buffer stays open.

When you open Vim, one window with one empty buffer are automatically created.

To create windows, you can use the :new command, or one of these keystrokes:

CTRL-W s - Split the current window horizontally.


CTRL-W v - Split the current window vertically.
CTRL-W n - Split the current windows horizontally and edit a new file.
CTRL-W ^ - Split the current with the alternate file (buffer with the # indicator in your
buffer list).
<buffer_ID>CTRL-W ^ - Split windows with the buffer of ID <ID> . For example,
CTRL-W ^ will open a window with the buffer of ID .

https://thevaluable.dev/vim-intermediate/ 4/17
3/28/2021 A Vim Guide for Intermediate Users

To move your cursor from one window to another, you can use:

CTRL-W <Down> or CTRL-W j


CTRL-W <Up> or CTRL-W k
CTRL-W <Left> or CTRL-W h
CTRL-W <right> or CTRL-W l

You always dreamt to move the windows? Me too. Here’s how to do it:

CTRL-W r - Rotate the windows.


CTRL-W x - Exchange with the next window

Who wants windows without being able to resize them? Here are the keystrokes you need:

CTRL-W = - Resize windows for them to fit on the screen with the same size.
CTRL-W - - Decrease window’s height.
CTRL-W + - Increase window’s height.
CTRL-W < - Decrease window’s width.
CTRL-W > - Increase window’s width.

Using these keystrokes to move the cursor from window to window and to move the windows
themselves is pretty tedious . We’ll see later a plugin which can help to make the whole operation
smoother.

If you want to quit windows, you can use the commands:

:q - To q uit the current window. People lied to you! :q doesn’t quit Vim, but a
window. You quit Vim only if there is only one window open.
:q! - To q uit the current window, even if there is only one window open with an
unsaved buffer ! .

Vim help

:help windows
:help opening-window
:help window-move-cursor
:help window-moving
:help window-resize

Vim Tabs
https://thevaluable.dev/vim-intermediate/ 5/17
3/28/2021 A Vim Guide for Intermediate Users

We saw that a buffer is an open file, and a window is the container for an active buffer. We can
see tabs as a container for a bunch of windows. In that way, it’s very different than the concept of
tabs in a standard IDE!

Here are the commands to create and delete tabs:

:tabnew or :tabe - Open a new tab.


:tabclose or :tabc - Close the current tab.
:tabonly or :tabo - Close every other tab except the current one.

To move from tab to tab, you can use these keystrokes:

gt - g o to the next t ab.


gT - g o to the previous tab.

You can also add a count before the last two keystrokes. For example, gT go to the first tab.
Yep, tabs are indexed from .

Vim help

:help tab-page

The Argument List


(arglist)
The argument list (also called arglist) is the fourth and last container allowing you to organize
your open files. It’s useful to see it as a stable subset of the buffer list, as Drew Neil point it out
in one of his vimcast. As a result, it follows these two rules:

1. Every file in the arglist will be in the buffer list.


2. Some buffers in the buffer list won’t be in the arglist.

The files you want to open when you run Vim - such as executing vim file file file -
will be automatically added to the arglist and, as we just saw, to the buffer list.

The arglist can be useful to isolate some files from the buffer list to do some operations on them.
Here are some commands you can use to manipulate the arglist:

https://thevaluable.dev/vim-intermediate/ 6/17
3/28/2021 A Vim Guide for Intermediate Users

:args - Display the arglist.


:argadd - Add file to the arglist.
:argdo - Execute a command on every file in the arglist.

To edit the files in the arglist, you can use these commands:

:next - Move to the next file in the arglist.


:prev - Move to the previous file in the arglist.
:first - Move to the first file in the arglist.

I don’t use very often the arglist personally, but many users do. The buffer list can be modified
by other actions unrelated directly to buffers, like opening new windows. The arglist stays the
same, except if you explicitly modify it. That’s why it’s stable.

Vim help

:help arglist

Mapping Keystrokes
We’ve seen a great deal of keystrokes and commands. It would be nice to be able to modify these
keystrokes, or to assign new keystrokes to precise commands.

You can use mapping commands for every Vim mode:

:nmap - Create new mapping for NORMAL mode.


:imap - Create new mapping for INSERT mode.
:xmap - Create new mapping for VISUAL mode.

It might sound confusing to have different mappings for different modes, but it’s actually very
easy to remember, thanks to our muscle memory.

Let’s try an example together by mapping w to dd . By default, dd delete a line, and w is a


motion to move your cursor from word to word.

1. Run the command :nmap w dd


2. Try to hit the keystroke dd . It will delete a line.
3. Try to hit w . It deletes a line to.

https://thevaluable.dev/vim-intermediate/ 7/17
3/28/2021 A Vim Guide for Intermediate Users

However, w can’t be used anymore to move from word to word. Let’s try to fix that by
running: :nmap w v .

Try to hit v now. It deletes a line too! You just did a recursive mapping: v maps to w which
maps to dd . It would be nice to

1. Map w to dd
2. Map v to the motion made by w before its mapping with dd .

To do that, you can use the following mapping commands:

:nnoremap - Create mapping for NORMAL mode (non recursive)


:inoremap - Create mapping for INSERT mode (non recursive)
:vnoremap - Create mapping for VISUAL mode (non recursive)

To do the silly mapping we wanted to do before, restart Vim to have the default mapping, then
execute these commands:

:nnoremap w dd
:nnoremap v w

This time, w delete a line and v moves from word to word.

You can as well use special characters in your mapping. For example:

<space> for SPACE


<c-w> for CTRL-W .
<cr> for c arriage r eturn ( ENTER ).

To see the complete list, run the command :help key-notation

Now that you have the Power, I would advise you not to change the default Vim mapping as
much as you can. The previous example of mapping I’ve given is a good one to show you
what not to do. It’s very practical to use as much as you can the default mapping, because you
can use them on any instance of Vim possible, even in a docker container or on a remote server.

If you want to create new mappings, you should use a special key called the leader key. It’s a
way to create mapping namespaces: first, you use your leader key, then you use your keystroke.
Thanks to the leader key, your new keystroke will never conflict with the default Vim keystrokes.

To set up your leader key, you need to set the variable mapleader. Here’s an example:

https://thevaluable.dev/vim-intermediate/ 8/17
3/28/2021 A Vim Guide for Intermediate Users

:let mapleader = "<space>"

Every mapping command we saw are often written in your vimrc to set them when you open
vim. For example, you can write the following to it:

let mapleader = "<space>"


nnoremap <leader>bn :bn<cr> ;buffer next
nnoremap <leader>tn gt ;new tab

The keystrokes <space> bn will move to the next buffer, and <space> tn will move to the
next tab. Notice that when you want to map a keystroke to a command, you need to add <cr> at
the end exactly like you would type ENTER (or carriage return) to execute the command.
Awesomeness!

Vim help

:help mapping
:help leader
:help key-notation

Jump! Jump! Jump!


There are special motions in Vim called jump-motion. These motions jump several lines away,
like the keystroke G we saw in the last article.

Moving using k or j is not considered as a jump-motion.

Jump list
Each time we use a jump motion, the position of the cursor before the jump is saved in the jump
list. You can move through this jump list with the following keystrokes:

CTRL-o - Go to the previous ( o lder) cursor position.


CTRL-i - Go to the next cursor position ( i is near o ).

https://thevaluable.dev/vim-intermediate/ 9/17
3/28/2021 A Vim Guide for Intermediate Users

You can move from line to line and even from buffer to buffer with these holy commands. I use
them all the time, and you will, too.

To display your jump list, use the command :jumps .

Change list
Another useful list is the change list. Each time you insert something (using INSERT mode), the
position of your cursor is saved in the change list.

You can navigate through the change list using these keystrokes.

g; - Jump to the next change.


g, - Jump to the previous change

Discovering them was like seeing the light for the first time.

Methods Jumping
Since we’re developers, it’s nice to be able to jump from method to method. You can do that with
the following keystrokes:

[m - move to the start of a method.


]m - move to the end of a method.

These methods should have similar syntax than Java’s methods for these keystrokes to work.

Vim help

:help jump-motions
:help jumplist
:help changelist

https://thevaluable.dev/vim-intermediate/ 10/17
3/28/2021 A Vim Guide for Intermediate Users

Repeating
Keystrokes
You know what’s great? Automation. You know what’s great with Vim? Keystrokes automation.
That’s a very powerful feature, so get ready.

Single Repeat
Automating tedious tasks is our job, as developers. That’s why some call us lazy; I call that
focusing on the important.

When I heard about the sacred single repeat, my life in Vim changed. Here’s how you can fell
like a powerful superhuman:

. - Repeat the last change.


@: - Repeat the last command executed.

The period is now my best friend. It’s simple and diabolically effective.

Vim help

:help single-repeat

Complex Repeat: The


Macro
I deceived you with my period keystroke? Wait to see this one. Macros will bring even more
power at your fingertips.

In Vim, you can record series of keystrokes and repeat them in order. The process includes
multiple steps:
https://thevaluable.dev/vim-intermediate/ 11/17
3/28/2021 A Vim Guide for Intermediate Users

1. q<lowecase_letter> - Begin recording keystrokes in a register. You can think of a


register as a place in memory, or as a clipboard.
2. Every keystrokes you’ll do onward will be saved.
3. q - Stop the recording.
4. @<lowercase_letter> - Execute the keystrokes you’ve recorded.

For example, let’s say that you need to repeat keystrokes you need to do on multiple lines:

1. Hit qa .
2. Do what you have to do. For example: ^cawhello<Esc> .
3. Hit q again.
4. To execute your series of keystrokes, hit @a . For the example above, go on a new line.

Here, I use q (for the <lowercase_letter> ) as an example; you can actually use whatever
lowercase letter you want. If you need to repeat your keystrokes again after the first repeat, you
can even use @@ which repeat your previous @ command.

Vim help

:help complex-repeat

Command Line
Window
You can access the history of your Ex commands directly in Vim:

q: - Open command line history.


q/ and q? - Open search history.
CTRL+f - Open command line history while in COMMAND LINE mode.

Using the keystrokes above, you can modify any command line you want and execute it
with ENTER . Very handy when you need to repeat a command line with slight differences. It’s
nice as well if you want to type a complex command using Vim’s editing power.

Vim help

https://thevaluable.dev/vim-intermediate/ 12/17
3/28/2021 A Vim Guide for Intermediate Users

:help cmdline-window

Undo Tree
We saw in the previous article how to undo and redo a command. Vim allows you as well to save
all these undos in a file, for each file you modify. It means that even if you close Vim and come
back to your file, you’ll have access to your last change by “undoing” them.

You need to configure it in your vimrc file, by adding the following:

" save undo trees in files


set undofile
set undodir=~/.vim/undo

" number of undo saved


set undolevels=10000

You don’t have to save your undos in ~/.vim/undo . Change it without regret if you need to.

We set the option undolevels to to save undos maximum per file.

That’s not all: you could think that Vim will only save a list of undos, but it actually saves a
whole undo tree.

Let’s take an example: when you do three changes, then undo two of them, and do one (or more)
changes, a new branch will be created. You can picture it like this:

@
|
| o -> third change
| |
| o -> second change
|/
o -> first change
|
o

https://thevaluable.dev/vim-intermediate/ 13/17
3/28/2021 A Vim Guide for Intermediate Users

The third and second changes have been undo, @ represent where you are now. You can revert to
any of these changes, which means that you can revert to any last changes you’ve made.

It’s a bit difficult to navigate in this tree with vanilla Vim, but we’ll see in the next section a very
useful plugin to come back to any changes you’ve made. You’ll even be able to search in the
entire undo tree for a piece of content you want to find back!

Vim help

:help undo-redo
:help undo-persistence
:help undo-tree

Plugins
Everything we saw until now can be managed differently using a couple of plugins. If I would
learn Vim all over again, I would first get comfortable with everything we saw till now. That
said, here are some plugins which can makes things even easier.

Plugin Manager
It’s easier to manage Vim’s plugins with a good plugin manager. I would recommend vim-plug :
you’ll find instructions to install it on its Github page.

Then, add the following at the beginning of your .vimrc :

" Specify a directory for plugins


" - For Neovim: stdpath('data') . '/plugged'
" - Avoid using standard Vim directory names like 'plugin'
call plug#begin('~/.vim/plugged')
call plug#end()

Again, you can replace ~/.vim/plugged depending on where your dotfiles for Vim are.

For example, if you want to install the plugin vim-bbye , you need to:

https://thevaluable.dev/vim-intermediate/ 14/17
3/28/2021 A Vim Guide for Intermediate Users

1. Find the Github repository of the plugin, in that case https://github.com/moll/vim-


bbye .
2. Take the username and the repository’s name from the url: moll/vim-bbye .
3. Add Plug 'moll/vim-bbye' between call
plug#begin('~/.vim/plugged') and call plug#end() .
4. Source your .vimrc with the command :source <path_to_vimrc> . If your current
buffer is already your vimrc , you can run :source % .
5. Run :PlugInstall .
6. Your plugin is installed!

To update every plugins you have, you can use the command :PlugUpdate . It will install the
plugins not installed yet, too.

Closing Buffers Without


Closing Windows
By default, when you use :bdelete to close a buffer, the window will be closed too. If you
want to keep your window layout, you can use the plugin vim-bbye.

It’s a very small plugin which gives you a new command, :Bdelete (with an uppercase B ),
allowing you to close a buffer without closing a window.

Easily Resizing Windows


I’m not a big fan with the vanilla way to resize windows. The plugin winresizer gives you a new
mode to resize them.

To enter this new mode, you need to use the keystroke CTRL-e . If you don’t like it, you can add
this line to your vimrc for example:

let g:winresizer_start_key = "<leader>w"

Now, you can use this new resize mode with the keystrole LEADER w . It’s just an example, use
whatever keystroke works for you.

When you are in this new resize mode, you’ll see some help at the bottom of Vim. You can
use hjkl to resize the window, e to change mode from resize mode, focus mode
https://thevaluable.dev/vim-intermediate/ 15/17
3/28/2021 A Vim Guide for Intermediate Users

or move mode. The last one allows you to swap windows.

Navigating through your


buffer
I use the plugin fzf.vim intensively. It allows you fuzzy search buffers or even files in your
current path (set up with the option path ).

You’ll need to have fzf installed to use it. Then, you can use the command line :Buffers (with
a B uppercase) to fuzzy find and select the buffer you want.

That’s only a tiny subset of what fzf can do for you.

Manipulating the Undo


Tree
As promised, here’s a very useful plugin to come back to any change you want: MundoTree. The
command :MundoToggle will show you the undo tree of your current buffer in a new buffer.

From there, you can select whatever change you want to come back to.

The Path to Mastery


There are many important Vim features I didn’t write about in this article. You’ll find at the end
of the article the help commands for some of them. I might cover them in a next article, if some
readers are interested.

I strongly believe that knowing, even on a very high level, the principles and fundamentals of a
concept can help you understand anything built upon this concept. As such, knowing how vanilla
Vim works and getting a good grasp on its functionalities is important to understand what plugin
can be useful for your own needs.

https://thevaluable.dev/vim-intermediate/ 16/17
3/28/2021 A Vim Guide for Intermediate Users

What did we learn in this article:

When you’re comfortable with the concepts of this article, you’ll normally be able to
understand another article of mine focused on searching and replacing in Vim.

What did we learn in this article?

Buffers are open files, windows are containers for buffers, tabs are sets of windows,
and the argument list is a subset of the buffer list.
You can map keystrokes for any Vim mode recursively, but it’s good practice to avoid
doing so.
You can use powerful keystrokes to go through the jump list or the change list.
Using the period . or Vim’s macros to automate repeating editing tasks is really
powerful.
You can use the command line windows to re-run or modify commands already
executed, using the command line history.
Vim’s undo tree allows you to come back to any modification made in any file, even
after closing Vim.
The plugins vim-bbye and winresize can help you to manage your buffers and
windows in a easier way.

This article wasn’t enough? You’re never tired to read articles about Vim and you want always
more? In that case, you can read the next part of this series: Vim for advanced users.

Are you faster with Vim than with any other editor or IDE? The question is not really important
to me. I love using Vim because of its flexibility and overall approach to editing. That’s what
gives me the real productivity boost I’m craving for.

Related Sources
Vimcast - Working with buffers - Drew Neil
Vimcast - Meet the arglist - Drew Neil
Practical Vim - Drew Neil
Youtube channel - ThePrimeagen - Theprimeagen

https://thevaluable.dev/vim-intermediate/ 17/17
3/28/2021 A Vim Guide for Advanced Users

A Vim Guide for


Advanced Users

Welcome to the third part of this series aimed to help you unleash a power never seen on Earth
using the Almighty Vim. If you don’t understand what’s happening in this article, I recommend
you to read the previous ones of the series first:

1. Vim for Beginners


2. Vim for Intermediate Users

We’ll see together in this article:

https://thevaluable.dev/vim-advanced/?utm_medium=email&utm_source=topic+optin&utm_campaign=awareness&utm_content=20210327+pro… 1/22
3/28/2021 A Vim Guide for Advanced Users

Some nice keystrokes beginning with g .


What ranges are and how to use them.
The quickfix list and the location lists.
The marvelous substitute command.
The crazy useful :global (or :g ) command.
What marks are and what you can do with them.
How to increase and decrease numbers with a single keystroke.
How to sort text with a nice command.

But before going into the juicy content of this article, I’ve some recommendations for you, dear
reader:

1. Fire up your Vim and play around with the commands and keystrokes while reading.
It’s the best way for you to remember everything which blew you away. You’ll then be
able to be blown away whenever you like for the rest of your life.
2. Don’t use a cheatsheet; write your own as you read. It will allow you to come back
easily to the commands you find the most useful for your own needs.

Enough rambling. Let’s begin!

Useful “g”
Keystrokes
Let’s begin gently with a mixed bag of keystrokes starting with g . There are many of these “g”
commands in Vim, and we already saw some of them in the previous articles. Can you recall
them?

You can use these keystrokes in NORMAL mode:

gf - Edit the file located at the filepath under your cursor.


You can use CTRL+W CTRL+F to open the file in a new window.
It can open the URL under your cursor if you have the plugin netrw .
gx - Open the file located at the filepath under your cursor.
It will use the default application used by your OS for this filetype.
It works with URLs too. It will open your favorite browser and load the website.
It only works if you have the plugin netrw .
gi - Move to the last insertion you did and switch to INSERT mode.
Pretty useful if you stopped your editing to look at some other file.
https://thevaluable.dev/vim-advanced/?utm_medium=email&utm_source=topic+optin&utm_campaign=awareness&utm_content=20210327+pro… 2/22
3/28/2021 A Vim Guide for Advanced Users

It uses marks under the hood: more on that later in this article.
gv - Start VISUAL mode and use the selection made during the last VISUAL mode.
gn - Select the match of your last search:
1. Move to the last searched match.
2. Switch to VISUAL mode (if you weren’t in VISUAL mode already).
3. Select the match.
4. You can continue to hit n (or gn ) to select the area between the current match and
the next match.
gI - Insert text at the beginning of the line, no matter what the first characters are.
The keystroke I insert text just before the first non-blank characters of the line.
gu - Lowercase using a motion (for example, guiw ).
gU - Uppercase using a motion (for example, gUiw ).

To try out gf and gx , you can write for example https://www.google.com/ in Vim, place
your cursor on it, and hit the keystrokes. Don’t forget the trailing slash in your URL.

You’ll soon discover an inconvenience with gx : when you use it on a filepath, Vim will hang till
you close the file. That’s why I’ve created the following mapping you can add to your .vimrc :

nnoremap gX :silent :execute


\ "!xdg-open" expand('%:p:h') . "/" . expand("
<cfile>") " &"<cr>

It maps the keystroke gX to use xdg-open with the filepath under your cursor. It will open the
file with your favorite application in the background. The program xdg-open will only work on
Linux-based systems; for MacOS, try open instead.

Vim help

:help reference
:help g

Ranges
Now that we’re done with the appetizers, let’s discover the first real dish of our Vim feast: the
ranges. You can apply them to many commands, making them terribly powerful.

https://thevaluable.dev/vim-advanced/?utm_medium=email&utm_source=topic+optin&utm_campaign=awareness&utm_content=20210327+pro… 3/22
3/28/2021 A Vim Guide for Advanced Users

Basics
In Vim’s help, every command accepting a range will have the string of characters [range] in
front of them. Multiple line specifiers are possible, separated by commas , .

Here are the most interesting ranges you can use:

<number> - Any number <number> in your range refers to a line number.


. - Represent the current line (often the default range).
- Represent the last line of the current buffer.
% - Represent the entire file (same as , ).
* - Use the last selection you’ve made during the last VISUAL mode.

For example, using the command :d :

: , d - Delete line to included.


: , d - Delete every line from the second one till the end of the file.
:., d - Delete every line from the current one till the end of the file.
:%d - Delete every line.

You can also do some arithmetic with ranges if you want. For example, let’s imagine your cursor
is on the line : the range .,.+ will be equivalent to the range , .

Visual Mode and Range


If you switch to COMMAND-LINE mode after doing some selection in VISUAL mode, you’ll
see these two symbols appearing: '< and '> with a comma , in between. This is a range too!

The symbols '< represents the first line you’ve selected and '> the last line. Each of these are
marks; again, we’ll see more about marks below.

In practice, the ranges '<,'> and * are synonym, but you’ll have more flexibility with the first.
For example, you can execute a command from the first line you’ve selected till the end of the
file with the range '<, .

Vim help

:help [range]
:help v_:

https://thevaluable.dev/vim-advanced/?utm_medium=email&utm_source=topic+optin&utm_campaign=awareness&utm_content=20210327+pro… 4/22
3/28/2021 A Vim Guide for Advanced Users

:help '<
:help '>

Vim’s Quickfix And


Location List
Now, let’s talk about a very useful data structure available in Vim, the quickfix list.

Don’t confuse the quickfix list and the quickfix window: these are two different entities. The first
is a data structure, the second can display this data structure.

Quickfix Lists
You can think of a quickfix list as a set of positions in one or multiple files.

Basics
Let’s take an example: what happens if you run the command :vimgrep hello * ?

1. It will search the pattern “hello” in every file of your working directory.
2. It will populate a quickfix list with every position matching your pattern “hello”.
3. It will move your cursor to the first position of the quickfix list.

If you want to know more about vimgrep and other tools you can search with, I wrote an article
about that. Other commands (like :make or :grep ) also populate automatically a quickfix list.

Let’s expand the mystery around marks: these positions in the quickfix list are in fact hidden
mark!

The quickfix list is often used to display specific errors in a codebase, often spit out from a
compiler or a linter (via the command :make for example), but not only, as we just saw. I call
the entries of a quickfix list “positions” to be more general, but sometimes Vim’s help will refer
to them as “errors”. Don’t be confused: it’s the same idea.

https://thevaluable.dev/vim-advanced/?utm_medium=email&utm_source=topic+optin&utm_campaign=awareness&utm_content=20210327+pro… 5/22
3/28/2021 A Vim Guide for Advanced Users

Among other conditions, a quickfix list entry needs to have a filename for you to be able to jump
to its position. Otherwise, the entry doesn’t point to anything. Difficult to move to anything.

Useful Commands
Here are the commands you can use to navigate through the current quickfix list:

:cl or :clist - Display all valid entries of the current quickfix list. You can add a
range as argument (only numbers).
:cc <number> - Move to the <number> th entry of the current quickfix list.
:cnext or :cn - Move to the next entry of the current quickfix list.
:cprevious or :cp - Move to the previous entry of the current quickfix list.
:cfirst or :cfir - Move to the first entry of the current quickfix list.
:clast or :clas - Move to the last entry of the current quickfix list.

Here are additional commands which make quickfix lists really powerful:

:cdo <cmd> - Execute a command <cmd> on each valid entry of the current quickfix
list.
:cexpr <expr> or :cex <expr> - Create a quickfix list using the result of evaluating
the Vimscript expression <expr> .
:caddexpr <expr> or :cadde <expr> - Appends the result of evaluating the
Vimscript expression <expr> to the current quickfix list.

If you have no clue how to use the last two commands, you can do for example:

:cex [] - Empty the current quickfix list.


:cex system("<cmd>") - Populate your quickfix list with any shell
command <cmd> . You can try it with ls for example.

The Quickfix Window


What about displaying the current quickfix list in a new buffer? You can do that with the
following command:

:copen or :cope - Open a window (with a special buffer) to show the current
quickfix list.

You can only have one quickfix window open. To move to the position of the selected entry of
the quickfix list in the quickfix window, hit ENTER or .cc .

https://thevaluable.dev/vim-advanced/?utm_medium=email&utm_source=topic+optin&utm_campaign=awareness&utm_content=20210327+pro… 6/22
3/28/2021 A Vim Guide for Advanced Users

Location Lists
A location list is similar to a quickfix list, except that the first is local to a window and the
second is global to your Vim instance. In other words, you can have multiple location lists
available at the same time (one per window open), but you can only have access to one quickfix
list.

The commands for location lists are similar to the ones for the quickfix lists; often, you’ll only
have to replace the first c (qui c fix) of the command with l ( l ocation).

For example:

:lli or :llist - Display all valid entries of the current location list. You can add a
range as argument (only numbers).
:ll <number> - Move to the entry <number> of the current location list.
:lnext or :lne - Move to the next entry of the current quickfix list.

To populate your location list you can also use the commands :lvimgrep or :lmake for
example.

Often, Vim users will use the quickfix list for anything related to errors in their codebase, and the
location list for search results. But it’s up to you at the end of the day. With Vim, you’re the
master of your destiny.

Vim help

:help quickfix
:help quickfix-window
:help location-list
:help location-list-window
:help expr
:help system()

Vim’s Registers
The registers are another big dish in our Vim feast. You can think of registers as places where
you can read or write some text. I like to think about them as Vim’s clipboards.

https://thevaluable.dev/vim-advanced/?utm_medium=email&utm_source=topic+optin&utm_campaign=awareness&utm_content=20210327+pro… 7/22
3/28/2021 A Vim Guide for Advanced Users

Specifying a Register
Here’s a command and a NORMAL mode keystroke to display and specify registers:

:registers or :reg - Display the content of your registers.


"<reg> - This keystroke specifies the register <reg> to be read or written.

How do you know when the register <reg> is read or written using the keystroke " ? It depends
of the keystroke you use afterward. For example:

To write the register a :


1. Hit "a in NORMAL mode to specify what register you want to write on.
2. Yank, change, or delete some content (for example by using dd in NORMAL
mode) to write it to a .
To read the register a :
1. Hit "a in NORMAL mode to specify what register you want to read.
2. Use a put keystroke in NORMAL mode (for example p or P ) to spit out the
content of the register in your current buffer.

We take the example of register a here, but it will work for any writable register.

The Types of Registers


There are different types of registers in Vim:

1. The unnamed register ( " ) - Contain the last deleted, changed, or yanked content, even
if one register was specified.
2. The numbered registers (from to )
contains the content of the last yank.
to is a stack containing the content you’ve deleted or changed.
1. Each time you delete or change some content, it will be added to the
register .
2. The previous content of the register will be assigned to register , the
previoius content of to …
3. When something is added to the register , the content of the register is
lost.
None of these registers are written if you’ve specified one before with the
keystroke " .
3. The small delete register ( - )
Contains any deleted or changed content smaller than one line.

https://thevaluable.dev/vim-advanced/?utm_medium=email&utm_source=topic+optin&utm_campaign=awareness&utm_content=20210327+pro… 8/22
3/28/2021 A Vim Guide for Advanced Users

It’s not written if you specified a register with " .


4. The named registers (range from a to z )
Vim will never write to them if you don’t specify them with the keystroke " .
You can use the uppercase name of each register to append to it (instead of
overwriting it).
5. The read only registers ( . , % and : )
. contains the last inserted text.
% contains the name of the current file.
: contains the most recent command line executed.
6. The alternate buffer register ( # ) - Contain the alternate buffer for the current
window.
7. The expression register ( = ) - Store the result of an expression. More about this
register below.
8. The selection registers ( + and * )
+ is synchronized with the system clipboard.
* is synchronized with the selection clipboard (only on *nix systems).
9. The black hole register ( _ ) - Everything written in there will disappear forever.
10. The last search pattern register ( / ) - This register contains your last search.

As you can see, even if you don’t specify any register with the keystroke " , the content you
delete, change, or yank will automatically overwrite one (or multiple) of them. So if you don’t
want the content you write to your registers to be silently overwritten by Vim, always write in the
named registers.

Using a put command without specifying any register will spit the content of the unnamed
register by default. But you might have this line in your vimrc :

clipboard+=unnamedplus

In that case, the content you change, delete, or yank will go directly in the unnamed
register and the + register. Using put commands will directly output the + register too. Many
find it useful (including me) to access your OS clipboard more easily, without the need to specify
the + register for reading or writing it.

Appending a Recording
We’ve seen in the previous article that you can record your keystrokes using q . Now that you
know how to use registers, you can manipulate these keystrokes:

If you made a mistake during the recording, you can spit the whole register, modify it,
and save it back.

https://thevaluable.dev/vim-advanced/?utm_medium=email&utm_source=topic+optin&utm_campaign=awareness&utm_content=20210327+pro… 9/22
3/28/2021 A Vim Guide for Advanced Users

You can append to your recording by using the uppercase variant of your register. For
example:
1. Hit qa and record whatever keystrokes you want. Stop the recording by
hitting q again.
2. You realize that you forgot a couple of keystrokes.
3. Execute your keystrokes to be sure you’re at the last position of your recording.
4. Hit qA to append to your register a . When you’re done, hit q again.

You’ve just gained even more flexibility for your macros.

Using Registers in
INSERT and COMMAND
LINE modes
The magical keystroke " is great for NORMAL mode, but what about spitting the content of a
register in INSERT mode or COMMAND LINE mode? For that, you can use CTRL+R <reg> to
put the content of register <reg> in your current buffer.

For example, if you hit CTRL+R % in INSERT mode, you’ll put the content of the register % in
your current buffer.

The Insane Expression


Register
If you don’t know the expression register, I’m about to revolution your life. I hope you’re ready.

Try this:

1. Switch to INSERT mode and hit the keystroke CTRL+r = . You’ll move to Vim’s
command-line.
2. From there, you can type any Vimscript expression you want, like system("ls") we
saw above, or + .
3. Hit ENTER to run the expression, and you’ll see the output of the shell
command ls directly inserted in your buffer!

https://thevaluable.dev/vim-advanced/?utm_medium=email&utm_source=topic+optin&utm_campaign=awareness&utm_content=20210327+pr… 10/22
3/28/2021 A Vim Guide for Advanced Users

It’s useful to evaluate some custom functions you’ve defined while staying in insert mode. If you
use Neovim, you can use the function luaeval() to evaluate some Lua too.

Clearing a Register
A last little trick about registers: if you want to empty one, you can do:

qaq

Beginning a recording also deletes everything which is in this register. So you just need to stop
the recording by hitting q again to have an empty register.

Vim help

:help registers
:help clipboard
:help clipboard-unnamed
:help clipboard-unnamedplus

The Substitute
Commands
Let’s continue our ascension to become The Vim God (or Goddess). The substitute command is
next on the menu.

Basics
If you’re already familiar with the CLI sed , this command will remind you some good old
memories.

https://thevaluable.dev/vim-advanced/?utm_medium=email&utm_source=topic+optin&utm_campaign=awareness&utm_content=20210327+pro… 11/22
3/28/2021 A Vim Guide for Advanced Users

A substitution is a way to replace some content with some other content, using a range and a
count. The count will decide how many lines is affected by your substitution from the last line of
your range.

Like many other commands, the default range is the current line if you don’t specify it.

Here’s the pattern of the command itself:

:s/pattern/replacement/flags

What does this mean?

The pattern is the search you want to match.


The replacement will replace the first match of the pattern on each line.
The flag modify the behavior of the command.

There’s another element, represented here with a slash / : the separator. It doesn’t have to be a
slash, it can be any character except:

An alphanumerical character (a character included in the range a-z , A-Z , and - ).


A double quote " .
A pipe | .

The replacement is not mandatory: if you omit it, the substitute command will delete the
pattern matched.

You can also run :s without any range, pattern, replacement, flags, or count. In that case, it will
repeat the last substitution you’ve done without the flags; you can add new flags (except & ) and
a count if you want to.

Let’s see some examples to understand how it works:

:s/pattern/replacement/ - Substitute the first occurrence of pattern on the


current line with replacement .
:s#pattern#replacement# - Equivalent substitution to the one just above. Handy if
you have some URLs in your pattern or your replacement .
:s/pattern/ - delete the first occurrence of pattern on the current line.
:s/pattern/replacement/g - Substitute every occurrence of pattern on the
current line.

You can also add a range as prefix and a count as suffix:

https://thevaluable.dev/vim-advanced/?utm_medium=email&utm_source=topic+optin&utm_campaign=awareness&utm_content=20210327+pr… 12/22
3/28/2021 A Vim Guide for Advanced Users

:%s/pattern/replacement/ - Substitute every first occurrence of pattern on each


line of the current buffer.
:%s/pattern/replacement/g - Substitute every occurrence of pattern on each line
of the current buffer.
: , s/pattern/replacement/ - Substitute every first occurrence of pattern on
the first ten lines of the current buffer.
:s/pattern/replacement/ - Substitute every first occurrence of pattern for
the current line and the next lines.
: , s/pattern/replacement/ - Substitute every first occurrence of pattern on
the first ten lines and on the five lines below the last line of the range.
:s g - Repeat the last substitution without its flag, and add a new flag g . It will
affect the lines after the last line of the last substitute command.

Vim’s “Magical” Patterns


A pattern in that case is a regular expression. But it’s not the good old regex engine you’re
familiar with from high level programming languages. Vim has its own regex engine (actually, it
has two!) which can be quite confusing.

Regexes in Vim are more or less magic. You think I’m kidding? I’m not. Here’s what I find
useful to remember:

To have access to all regex metacharacters, you can prefix your pattern with \v ( v ery
magic).
To have access to almost all regex metacharacters (except ( , ) and | ), use the
command :sm instead of :s ( s ubstitute m agic).
To have access to none of the metacharacters (except ), use :sno instead
of :s ( s ubstitute no magic).
To have access to none of the metacharacters, you can prefix your pattern
with \V ( V ery nomagic).

For example, if I want to delete all opening parenthesis in my buffer, I can run one of these three
equivalent commands:

:%s/\V(/
:%sm/(/
:%s/\(/

If you know your regex metacharacters, you might wonder what’s the metacharacter ~ . It’s the
latest substituted string in Vim’s world. In fact, you can use many more metacharacters
(called atoms) and character classes in your Vim’s regex.

https://thevaluable.dev/vim-advanced/?utm_medium=email&utm_source=topic+optin&utm_campaign=awareness&utm_content=20210327+pr… 13/22
3/28/2021 A Vim Guide for Advanced Users

If you’ve no clue what a regex is, I’ve recorded a couple of videos explaining the basics (using
Grep).

Additional Commands
Here are two other commands I find useful:

:&& - Repeat the last substitute with its flags.


:~ - Repeat the last substitute command with the same replacement, but with the last
used search pattern.

For example, let’s say that you execute successively the following in Vim:

:s/pattern/replacement/
/hello
:~

The last command will substitute hello with replacement .

You can also use these useful keystrokes in NORMAL mode:

& - Repeat the last substitute, without its range and its flags.
g& - Repeat the last substitute, with its range as well as its flags, and replace its pattern
with the last search pattern.

The Substitutes Flags


Here are some flags which can be useful:

& - Use the flag(s) from the previous substitute command.


c - Ask you to confirm each substitution.
g - Replace all occurrences in each line (not only the first one).
i - The pattern is case-insensitive.
I - The pattern is case-sensitive.
n - Only report the number of match without substitute.

You can now substitute like crazy to your heart’s content!

https://thevaluable.dev/vim-advanced/?utm_medium=email&utm_source=topic+optin&utm_campaign=awareness&utm_content=20210327+pr… 14/22
3/28/2021 A Vim Guide for Advanced Users

Vim help

:help :substitute
:help :sm
:help :sno
:help :s_flags
:help pattern
:help pattern-overview
:help regex
:help /magic

The Global
Command
You don’t have enough? You want even more power? Behold the Holy Global Command! It
works similarly to the substitute command, except that it will execute a command instead of
replacing a pattern.

Basics
Here’s the pattern of the command itself:

:g/pattern/command

You can also prefix it with a range if you want to.

As an example, let’s imagine that you have the urge to delete all the lines of your current buffer
containing the pattern “useless”. To do that, you can run:

:g/useless/d

Nice, but I can give you even more power.

https://thevaluable.dev/vim-advanced/?utm_medium=email&utm_source=topic+optin&utm_campaign=awareness&utm_content=20210327+pr… 15/22
3/28/2021 A Vim Guide for Advanced Users

Normal mode Commands


Do you know the command :norm ? You can give to it some NORMAL mode keystrokes and it
will apply them for you, as if you were hitting them in NORMAL mode. For example, the
following will delete the word under the cursor:

:norm daw

Let’s now combine a normal mode command with the global command:

:g/useless/norm gu$

This will lowercase every line containing the pattern useless .

When I first heard about that, I saw the Universe, the Big Bang, the cycle of creation and
destruction. I understood life and death. I became blessed, chanting the power of Vim in every
free cities.

A last tip: :norm use the key mappings you’ve defined. If you only want to use Vim’s default
mapping, you can use norm! instead.

If you write a plugin, always use norm! . You don’t know what mappings have your users.

Vim help

:help :global
:help :normal

Marks
It’s time to answer the question haunting your incredible mind: what are marks?

https://thevaluable.dev/vim-advanced/?utm_medium=email&utm_source=topic+optin&utm_campaign=awareness&utm_content=20210327+pr… 16/22
3/28/2021 A Vim Guide for Advanced Users

Basics
You can think of a mark as a specific position in a buffer. To set one, you can use m in
NORMAL mode followed by a character in the following ranges:

a-z - These marks are local to one buffer.


A-Z - These marks are global to multiple buffers.

If you have a “viminfo” file set via the option viminfo in Vim, or if you have a “shada” file set
via the option shada in Neovim, these marks are persisted. This means that you can come back
to them even if you closed the file.

If you wonder what are Vim’s options and how to display their values, I wrote about it in the first
article of this series.

There are also read-only marks in the range - . They are only available when using
a viminfo file (for Vim) or a shada file (for Neovim). They store the position of your cursor
each time you quit a file: the mark has the last position, the mark has the position before the
last one, and so on.

To move to a mark, you can use these keystrokes in NORMAL mode:

'<mark> - Move to the first non-blank character of the line where the
mark <mark> was set.
` - Move to the exact position where the mark <mark> was set.
g' <mark> g` <mark> - Move to the mark <mark> without changing the jump list
(I’ve written about the jump list in the previous article of this series).

Useful Commands
As you might imagine, there are also some useful commands for displaying or manipulating
marks:

:marks - Display the marks set.


:marks <marks> - Display some specific marks <marks> .
:delmarks <mark> or :delm <mark> - Delete the mark <mark> .
:delmarks! or delm! - Delete all the marks in the range a-z .

For example, :marks <> will display the two marks < and > .

https://thevaluable.dev/vim-advanced/?utm_medium=email&utm_source=topic+optin&utm_campaign=awareness&utm_content=20210327+pr… 17/22
3/28/2021 A Vim Guide for Advanced Users

You can also use marks as ranges. For example:

:`a,`bs/pattern/replacement/

This will substitute the first match of pattern with replacement from the exact position of the
mark a to the exact position of the mark b .

Special Marks
Let’s now introduce special marks with these keystrokes:

m< or m> - Set the marks '< and '> we saw above. It can be handy for the
keystroke gv .
`[ - Move to the first character of the previously changed, deleted, or yanked content.
`] - Move to the last character of the previously changed, deleted, or yanked content.
`` - Move to the position before the latest jump from the jump list (or where you’ve
set it with m' or m` ).
`" - Move to the position were you’ve closed the current file for the last time.
`^ - Move to the position where you’ve used INSERT mode for the last time (this
mark is used by the keystroke gi under the hood).

For every keystroke described above using ` , you can use ' instead with the differences we
saw above.

Vim help

:help mark-motions

Manipulating
Numbers
After these register, substitution, and mark shenanigans, here’s a lighter subject: adding (or
subtracting) numbers.

https://thevaluable.dev/vim-advanced/?utm_medium=email&utm_source=topic+optin&utm_campaign=awareness&utm_content=20210327+pr… 18/22
3/28/2021 A Vim Guide for Advanced Users

Here’s a bunch of NORMAL mode keystrokes to do exactly that:

CTRL+a - Increase the first digit or number on the line.


CTRL+x - Decrease the first digit or number on the line.

You can also use these keystrokes in VISUAL mode:

g CTRL+a - Same as CTRL+a unless you have several lines selected. In that case, the
first number of each line will be incremented sequentially.
g CTRL+x - Same as CTRL+x unless you have several lines selected. In that case, the
first number of each line will be decremented sequentially.

To illustrate a bit better the last two keystrokes, let’s say that you have this amazing content in
your beloved Vim:

1. Take some red flowers.


1. Add some eggs.
1. Forget about it and go back to your computer.

If you select in VISUAL mode the last two lines and hit g CTRL+a , you’ll get:

1. Take some red flowers.


2. Add some eggs.
3. Forget about it and go back to your computer.

You can also prefix a count to the command to add a precise amount. For example,
CTRL+a will add to the first number of the current line.

An important note: these keystrokes can also work on unsigned binary, octal, and hexadecimal
numbers, as well as alphabetical characters. Their behaviors depend on the value of the
option nrformats . For these keystrokes to behave as described in this article, you shouldn’t
have alpha as part of the value of nrformats , or you’ll increment (or decrement) the
first alphabetical character of the line.

Personally, I think it’s better to exclude alphabetical characters, but in any case, I would
recommend you to read Vim’s help to learn more about that. As always.

Vim help

:help CTRL-A
:help CTRL-X
:help nrformats

https://thevaluable.dev/vim-advanced/?utm_medium=email&utm_source=topic+optin&utm_campaign=awareness&utm_content=20210327+pr… 19/22
3/28/2021 A Vim Guide for Advanced Users

Sorting Text
What about a little dessert? A nice command to sort text directly in Vim, perhaps? Here are the
commands:

:sort or :sor - Sort lines depending on a range. If no range is given, all lines are
sorted. :sort! or :sor! - Reverse the order.

You can add some options to this command. Here are the most useful ones:

i - Ignore Case.
n - Sort depending on the first decimal on the line.
f - Sort depending on the first float on the line.
/pattern/ - Sort depending on what comes after the match.
r - Combined with /pattern/ , the sort depending on the matching pattern.

For example, if you have a CSV (with comma , as separator) and you want to sort every line
depending on the second column, you can run something like this:

:sort /[^,]*,/

How about sorting the following list depending on the numbers of each line?

Take some red flowers (1).


Forget about it and go back to your computer (3).
Add some eggs (2).

Running :sort n will have the following result:

Take some red flowers (1).


Add some eggs (2).
Forget about it and go back to your computer (3).

As always, there are many subtleties involved here. If you want to dig deeper, you know what
you should do: fire up this Vim’s help and enjoy the depth of its infinity!

https://thevaluable.dev/vim-advanced/?utm_medium=email&utm_source=topic+optin&utm_campaign=awareness&utm_content=20210327+pr… 20/22
3/28/2021 A Vim Guide for Advanced Users

Vim help

:help sort

Are You a Vim


Master Now?
We can now make two assumptions:

1. Compared to your old self, you might be more of a master than before.
2. Compared to many, you still have a long road ahead of practice and learning.

But here’s the most important: you shouldn’t care about the second point. Always compare
yourself to your past self, not to the others. Continue to walk on your own road, and you’ll get
your enlightenment. You’ll then build your own Mouseless Development environment, you’ll
move to a comfy cave in the Himalaya, alone, living a life of vow, giving your whole soul to the
study of the Almighty Vim.

Speaking of mouseless...

If you want to build a complete Mouseless Development Environment, you might be


interested by this book.

What did we learn in this article?

The letter “g” in Vim is a bit like a magic wand:


There are many useful keystrokes which begin with “g”.
The flag g is often used with the substitute command.
The global command :g is really powerful to apply a command to some precise
content.
Ranges allow you to execute many commands on a bunch of contiguous lines.
The quickfix list is a global list of positions in different files. You can apply any
command to them with :cdo .
You can see the entries of a quickfix list using the quickfix window.
Location lists are similar to quickfix lists, except that you can have one location list
(and one location window) per window open.
https://thevaluable.dev/vim-advanced/?utm_medium=email&utm_source=topic+optin&utm_campaign=awareness&utm_content=20210327+pr… 21/22
3/28/2021 A Vim Guide for Advanced Users

You can use the substitute command :s to replace a pattern (regex) with a
replacement. Prefer :sm if you want to use a regex or :sno if you don’t.
You can use marks to add some surgical precision in what you want to do.

To reward your tenacity and resilience for reading the whole article, I’ve a last tip for you: :help
ex-cmd-index will list all the commands available in Vim.

Vim is easy to learn but hard to master: that’s great, because we never stop improving!

Related Sources
At least one Vim trick you might not know - Hillel Wayne
Vim Macro Trickz - Hillel Wayne
Vim Search, Find and Replace: a Detailed Guide - Your obedient servant

https://thevaluable.dev/vim-advanced/?utm_medium=email&utm_source=topic+optin&utm_campaign=awareness&utm_content=20210327+pr… 22/22

You might also like