Exploring Vim: Setting Up Your Vim To Be More Awesome At Vim, Or... The Very Basic Things You Need to Know About Configuring Vim
Tags: vim, neovim, webdev, productivity
Published: 2018-11-14 15:56:48

---
title: "Exploring Vim: Setting Up Your Vim To Be More Awesome At Vim, Or... The Very Basic Things You Need to Know About Configuring Vim"
published: true
description: I am in a journey to improve my vim skills. Join me and discover vim, an editor that lets you write code at the speed thought. In this article you'll learn the very basics on how to configure and customize vim
tags: [vim,neovim,webdev,productivity]
canonical_url: https://www.barbarianmeetscoding.com/blog/2018/10/24/exploring-vim-setting-up-your-vim-to-be-more-awesome-at-vim
cover_image: https://www.barbarianmeetscoding.com/images/witcher-care-sword.jpg
series: "Exploring Vim"
---

*This article was originally posted in [barbarianmeetscoding.com](https://www.barbarianmeetscoding.com/blog/2018/10/24/exploring-vim-setting-up-your-vim-to-be-more-awesome-at-vim). 😊*

> ### Welcome to the Exploring Vim Series!
>
> If you haven't checked them out yet. Take a look at the previous [articles in this series](https://www.barbarianmeetscoding.com/blog/categories/exploring-vim). Happy vim-ing!
>

Before we proceed in our journey to vim awesomeness I thought it would be nice to get something out of the way as soon as possible so we don't need to wedge it in uncomfortably in passing on every single one of the future articles in this series: **How to setup, configure vim and keep it tidy, sharp and strong like a well oiled blade**.

This is not going to be a thorough reference on how to configure vim but a swift, short and sweet guide to get you up to speed within minutes and on your way to learning and using vim more effectively.

<img class="center shadow-small margin-small" src="https://www.barbarianmeetscoding.com/images/witcher-care-sword.jpg" title="Sharpen Thy Sword" alt="A witcher never ever forgets to take care of his blade">
<p style="font-size:0.5em;color:gray;"><em>Wallpaper from thewitcher.com plus a quote from the heartwarming reunion of Ciri and Geralt. Sorry I've just finished the Witcher 3, couldn't stop myself :D</em></p>

## How Do You Configure Vim?

You can configure vim in three ways:

1.  Using _Ex commands_ in command line mode
2.  Using a vim configuration file (`:h vimrc`)
3.  Through a set of limited options provided via the terminal when running vim. (`:h vim-arguments`)

**Ex commands** are the subset of commands in command-line mode that are prefixed with `:`. For instance, try opening vim, type:

```vim
:colo elflord
```

and press _ENTER_. You'll notice how when you type `:` whatever you write appears at the bottom of the screen within Vim (that's where your commands appear when you're in command-line mode). After pressing _ENTER_ this ex command will configure your current session of vim and change the color scheme to the one used commonly by powerful elf lords.

Noticed how we used `:colo` instead of `:colorscheme`? You can use shorthand to refer to _Ex comands_ and vim will do its best to fulfill your wishes, oh master.

### How Can You Write Reusable Configurations?

You could potentially configure your vim session using one-off _Ex commands_ but that would be a pain in the butt and wouldn't be of much use for future sessions. Instead vim offers you the possibilily of putting all these _Ex command_ configurations inside a file that is loaded whenever you start vim. The `vimrc` (`:h vimrc`) file:

```vim
" Sample vimrc file.
" This is a comment :D
set nocompatible           " disable backwards compatibility with vi
filetype plugin indent on  " enable filetype plugins and indent
syntax enable              " enable syntax highlighting
```

Notice how no commands are prepended with `:`? That's because vim assumes that whatever you put inside your vimrc are ex commands.

There's different types of options with diverse shapes and forms. Boolean options are quite common, like the one referenced via `nocompatible` above. You can modify them using the `:set` command in quite an interesting and novel way:

```vim
set compatible     " enable option
set nocompatible   " prepend 'no' to disable the option
set compatible!    " append ! to toggle the option
set compatible?    " find out whether the option is enabled
set compatible&    " reset to default vim option
```

You can use vim's help to find more information about the available options and how to configure them. Try `:h option-list` to see a summary of all available options, and `:h options` for the full deal. The help is veeery nice and detailed. Test `:h compatible` to get a taste (note that this option only available in vim because neovim doesn't even offer the option of backwards compatibility with vi, if you're in neovim try `:h 'filetype'` instead):

<img class="center shadow-small" src="https://www.barbarianmeetscoding.com/images/vim-help-compatible.jpg" title="Nice Help!" alt="A screenshot of vim's help for the compatible option">

## The One Thing You Should Know: How To Define Your Own Key Mappings!

One thing that you'll find super useful early on is learning how to configure your own key mappings. If not to write your own mappings, at least to understand what the mapping ex command does when someone recommends you to put it in your _vimrc_ file. You don't need to grok this right away but you can get the gist of it and come back if you need it in the future.

The main commands used for mapping are `map` and `noremap` where `map` stands for _mapping_ and `noremap` stands for _non-recursive mapping_. Let's take a look at how they work and after that we'll see what the recursive part means.

Let's say that you've gone completely nuts and you want to remap the `hjkl` keys to the keys one keyboard row up. You would write something like this in your vimrc file:

```vim
map y h
map u j
map i k
map o l
```

Or alternatively type the ex command as `:map y h`. What this command does is create new custom key mappings so that whenever you type `yuio` vim will understand it as `hjkl`.

But vim has modes! In which modes do the key mappings above apply?

The `map` command is somewhat of a shortcut in the sense that it applies the mapping to three vim modes at once: the normal, visual and operator-pending modes. You can be more specific by providing the mode you want the mapping to apply to yourself. For instance:

```vim
" To make a mapping apply to a given mode, prepend it to the map command
" apply mapping only to visual mode
nmap y h
" apply mapping only to visual mode
vmap y h
" apply mapping only to insert mode
" (and now you can never insert the y letter again xD)
" (you're welcome! moahahaha!)
imap y h
```

Ok, so `map` does key mappings. Then what does `noremap` do? And what the heck are recursive and non recursive mappings?

`map` defines recursive mappings. When vim tries to make sense of a recursive mapping, it will take a look at the characters you type and expand them recursively as it finds new mappings. In the example above, when you type `y` vim will take a look at `h` and try to determine if there's any other mapping for `h`. If there is, it will expand that mapping. If there isn't (like in our example) it will just use `h`. Don't get it yet? Don't worry! Recursion is always hard to wrap our heads around. Take a look at this example below which is more illustrative of the recursivity of these mappings and easier to understand:

```vim
" normally h means *left* and l means *right*
" this maps h to *right* instead of *left*
map h l
" this maps y to h.
" Normally that would mean that y would map to *right*
" However, this is recursive mapping, h will expand to l
" And therefore y will mean *right*
map y h
```

So how could we change the `h` mapping while keeping the **original behavior** of `h` so that we can map it to `y`? That's where non recursive mappings come in. Non recursive mappings allows us to have vim bind keys to default vim key bindings. Or in other words, non recursive mappings ignore all other mappings and just do what you explicitly tell them to do. (They are not recursively expanded):

```vim
" this still maps h to *right* instead of *left*
map h l
" this maps y to h non-recursively
" which means that vim uses *h* default behavior which is *left*
noremap y h

" so h now gets the new meaning of *right*
" and y means *left*
```

When to use recursive and non recursive mappings? 99% of the times you want to use non-recursive mappings. Non-recursive mappings guarantee that a given mapping will get the precise behavior you want as they are completely unaffected by other mappings. A newly installed plugin can change a mapping, you yourself can change the meaning of a mapping, in any of these scenarios your non-recursive mapping will be unaffected. Using a recursive mapping can feel like someone pulled the rug from under you if it suddenly stops working as you expect it to work. Even worse it can also create an endless loop. What's the 1% left? I honestly can't think of a use case where I would want to use normal mappings. If you do please write a comment!

You are not limited to map just one key to another key. You can create more complex mappings like so:

```vim
" This mapping comments a line in JavaScript
map c I//<Space><ESC>=<CR>
" It means, drop into insert mode at the beginning of the current line
" then add a couple of forward slashes (//) and go back to normal mode
" then adjust the indentation of the current line
```

Or even map keys to ex commands:

```vim
" Mapping C-r to refreshing your vimrc configuration
map r :source $MYVIMRC<CR>
" Don't do this though. r is replace character in vim
" You'll probably replace characters far often than you
" refresh your vim config file
```

Here's a real world mapping from the [vim-surround](https://github.com/tpope/vim-surround/blob/master/plugin/surround.vim) plugin for your enjoyment. If you have the patience and drive try to understand what it does and what the strange characters such as `<silent>`, `<Plug>`, etc.... mean. If you're not one for exercises, then move along to the next paragraph!

```vim
" Used for changing the surrounding characters or tags of a bit of text
nnoremap <silent> <Plug>Csurround  :<C-U>call <SID>changesurround()<CR>
```

Now let's wrap this mapping thing up! The `map` command without a second argument let's you see whether there are any mappings tied to a given key sequence. Using `map` without arguments at all will show you all custom mappings available. You can combine it with `verbose` as in `:verbose map` to see the file that last modified a mapping. Note that only custom mappings will be shown by this command. If you want to check for vim's built-in mappings you'll need to use `:h index` (this is useful when you want to make sure that you're not overwriting some vim built-in functionality).

Finally you can use the `unmap` command to remove mappings. It works in a similar way to `map` and `noremap` as you can make it apply to specific modes using alternative commands like `nunmap`, `iunmap`, etc.

You can find more information about the mapping and the map commands using vim's help `:h mapping` or `:h map-commands`

## Defining Your Own Commands

Vim comes with loads of commands but you can also create your own. This is a command that refreshes your vim configuration:

```vim
" User-defined commands must start with a capital letter
command! RefreshConfig source $MYVIMRC
```

Put it in your `vimrc` and you'll be able to use it like any other ex command: `:RefreshConfig`. Why use a command instead of a custom key mapping?

I like to create custom commands for stuff that I use often but not that often that it should have its own key mapping. With a custom command I get the convenience of tab completion and they're easier to remember, yet they don't clog down my key bindings which I reserve for things that I do very often when writing and editing code.

Just like with `map`, executing `:command` without arguments will list all user-defined commands available, and executing `:command {cmd}` with a single argument `{cmd}` will list all user-defined commands that start with `{cmd}`.

To find more information about custom commands take a look at `:h user-commands` (also `:h 40.2` which has a getting started guide for user-defined commands).

## The Leader Key

As you go customizing vim to fit your needs and installing plugins you may run out of space for mapping custom key bindings. The leader key offers you a new namespace specifically reserved for user-defined bindings to unleash mayhem and destruction when you type `<Leader><custom key sequence>`. By default the leader key is assigned to backslash `\\` which can be tricky to type. Often vim users will map that key to a different one more easily reachable. You can map it to a different key using the following command:

```vim
let mapleader = ","
```

Vim users often map the leader key to `,`. If you want to do that, be aware that this shadows a default key binding which is quite useful in vim: repeat a character search backwards, that is, the opposite of `;`. I prefer to map my leader key to `<Space>` which is always below my right thumb and doesn't break any built-in vim functionality (as far as I know):

```vim
" I have no clue why the first \ is needed
" in the line below but if I just map <Space>
" it doesn't work on my Mac
let mapleader = "\<Space>";
```

You can use the leader key in your your own mappings referring to it as `<Leader>`:

```vim
" remap J (join line) to go down 5 lines for faster movement
nnoremap J 5j

" but now I broke J (join line) which is quite nice if you write
" a lot of prose like I do (blog posts, books and such)
" So I remap it to <Leader>j
nnoremap <Leader>j J
```

## Extending Vim With Plugins

In addition to using your vimrc to customize and extend vim, vim supports third-party (oftentimes community driven and developed) [plugins](https://vimawesome.com/) that extend it with new and awesome functionality. Unfortunately, vim doesn't come with a nicely integrated plugin brower/installer and there is no standard plugin manager. Instead, what you do is use one of the most common plugin managers that are available in the vim ecosystem: [vim-pathogen](https://github.com/tpope/vim-pathogen), [Vundle.vim](https://github.com/VundleVim/Vundle.vim) or [vim-plug](https://github.com/junegunn/vim-plug) are the most used ones.

> ### Vim 8 Improves Plugin Support</h3>
>
> Vim 8 has built-in support for plugins that was unavailable in previous versions of vim. The idea is to drop your plugins into a special folder and Vim will load them when starting up. This is better than what was available before but I think that having a plugin manager simplifies things a lot. Instead of having to clone repos on this special folder you specify declaratively which plugins you want to have in your vimrc file and you're good to go.
>
> All of this above is also supported in Neovim. In fact, this is one of the reasons why Neovim exists.
>
> The nitty gritty of packages and different types of plugins is out of the scope of this article, but I promise to write a more in depth article on this topic!

I use [minpac](https://github.com/k-takata/minpac) (cause [Drew Neil told me to](https://amzn.to/2C1lozu)) and I've used [vim-pathogen](https://github.com/tpope/vim-pathogen) and [Vundle.vim](https://github.com/VundleVim/Vundle.vim) in the past. For my simple use case, which is to use plugins that are hosted on GitHub repos I haven't experienced any difference from any of these options. So you can choose whichever you want.

All of these plugin managers follow the same principles to extend vim:

1.  Install plugin manager (which is a vim plugin in itself)
2.  Add it to your `vimrc`
3.  Add list of plugins you want to install in a declarative way in your `vimrc`. You'll use the DSL defined by your plugin of choice
4.  Use plugin commands to install, update and remove plugins
5.  Installing plugins typically consists in cloning git repos inside vim plugin folders

This is an example from my vimrc:

```vim
" Package manager minpac
" Initialize package manager
packadd minpac
call minpac#init()

" have minpac manage minpac :D
" use opt so that we can load the plugin via packadd before any other plugin
call minpac#add('k-takata/minpac', {'type': 'opt'})
"""""""" Add other plugins here:
" Colorschemes
call minpac#add('KeitaNakamura/neodark.vim')
call minpac#add('tomasr/molokai')
call minpac#add('Lokaltog/vim-distinguished')
call minpac#add('fenetikm/falcon')
call minpac#add('haishanh/night-owl.vim')
call minpac#add('rakr/vim-one')

" Editing
call minpac#add('tpope/vim-repeat')       " Enable repeating supported plugin maps with .
call minpac#add('tpope/vim-unimpaired')   " pairs of handy bracket mappings
call minpac#add('tpope/vim-surround')     " Quoting parenthesing made simple
call minpac#add('scrooloose/nerdcommenter') " Comments

" Customize UI
call minpac#add('itchyny/lightline.vim')  " Custom Status line

" File system
call minpac#add('junegunn/fzf')            " fuzzy file search
call minpac#add('junegunn/fzf.vim')        " fuzzy file search
call minpac#add('scrooloose/nerdtree')     " File tree explorer
call minpac#add('tpope/vim-projectionist') " Semantic based navigation configurable per project
call minpac#add('mhinz/vim-grepper')       " Search files

" etc...
```

So, choose whichever one you fancy the most and peruse the archives of [vimawesome.org](https://vimawesome.com/) for plugins to tailor vim to the type of applications you usually develop. I have some notes [on useful plugins in my wiki](https://www.barbarianmeetscoding.com/wiki/vim-plugins) (although it's very much a WIP) and you're welcome to take a sneak peek in my current [vimrc on GitHub](https://github.com/Vintharas/BarbaricNeoVim/blob/master/init.vim).

## Keeping Your vimrc In Check

And one last piece of advice which as a good hypocrite I haven't yet implemented myself. A good idea to keep your vimrc in check is to break it down into smaller bits (just like with software modularization FTW). You can create context specific vim configuration files and load them into your vimrc using the `source` command:

```vim
" my vim config broken down
source plugins.vim
source navigation-mappings.vim
source editing-mappings.vim
source javascript.vim
" etc, etc...
```

> ### Update: I have now implemented this in my vimrc! Yey!
>
> The paths to the files need to be absolute paths. I have created a shell variable `$VIMCONFIG` inside my `.zshrc` that is pointed to my vim config folder: (in my case, `/Users/vintharas/.config/nvim`) and updated the sample above using that variable (i.e. `source $VIMCONFIG/navigation-mappings.vim`, etc). You are welcome to take a sneak peek at my [vimrc](https://github.com/Vintharas/BarbaricNeoVim/blob/master/init.vim)
>

This also gives you the ability to have some of these files removed from the vimrc and loaded only on demand when they are necessary.

And that is all for today! See you again soon! Have a wonderful day ahead!

## Update! Videos!!

Here are Some Videos To Walk You Through Setting Up Your Vim. Enjoy!

{% youtube QBMrKU-BWUk %}

## Curious About Setting Up Vim?

We'll revisit configuring and customizing vim in future articles but if you can't just wait I have a recommendation for you. There's this **amazing** book called: [Learn Vimscript the Hard Way](http://learnvimscriptthehardway.stevelosh.com/) by [Steve Losh](https://twitter.com/stevelosh/) which is just insanely good. Definitely worth a reading as you get more comfortable with vim.