Vim For Developers: Part 4 — Custom Configurations

David Ondrich
6 min readJul 17, 2020
It’s a metaphor

Check out the previous posts in this series if you haven’t already!
Vim for Developers: Part 0 — Why Vim?
Vim for Developers: Part 1 — The Basics
Vim for Developers: Part 2 — Advanced Basics
Vim for Developers: Part 3 — Advanced Vim

TL;DR — If you’re somewhat familiar with NeoVim/Vim and you’re just looking for a badass config, you can check out my dotfiles here.

Making Vim Your Own

We’ve covered a lot in this series so far. We’ve learned many commands, some you’ll learn to love more than others. And for every command we’ve seen, there are 10 more (maybe 100 more) out there waiting to be discovered.

Some things about Vim you might not love so much, and that’s okay! Some of the commands can feel like an arduous task, and for some the juice doesn’t feel worth the squeeze. Fear not!

Vim provides a way to customize almost any command, and the looks, and the feels of your Vim setup. Basically, you can customize anything and everything.

init.vim or .vimrc

These configuration files are found in two separate places for Vim and Neovim. One of the few differences between the programs.

For Vim the file can be found at:

~/.vimrc

And for NeoVim at:

~/.config/nvim/init.vim

If you navigate to the respective directory and don’t find the file it’s no big deal, just create your own with the correct name and it will be loaded when you start a new Vim session.

Real World Config

Like I said, there are endless customizations possible through your config file, and you’ll probably want to make your config your own. To get a gist of how you’d go about doing just that, I thought we’d walk through my own config (available on my GitHub).

I’m going to paste my config below, and walk through each line. However, I’m going to exclude all the lines concerning plugins, and most of the comments. We will get to plugins in the next post in this series. And away we go!

" ---------- Custom Hotkeys -
let mapleader = "," " map leader key as ,
:imap jj <Esc>
:nmap <Space><Space> :
:nmap <leader>s :split<Cr>
:nmap <leader>vs :vsplit<Cr>
" ---------- Terminal Controls ----
:nmap <leader>vt :vsplit term://zsh<Cr>
:nmap <leader>ht :split term://zsh<Cr>
:tnoremap jj <C-\><C-n> " Exit Insert Mode
" ---------- Basics ---------
set encoding=utf8
set autoindent
set smartindent
set shiftwidth=4
set smarttab
set clipboard=unnamed
set number
set relativenumber
set incsearch " jump to search match as typing
set nohlsearch " don't highlight my searches
set ignorecase
set smartcase
set noswapfile
autocmd BufWritePre * %s/\s\+$//e "Auto-remove trailing whitespace on save
" ---------- Theme ---------
" Display tabs and trailing spaces visually
set list listchars=tab:\ \ ,trail:·
syntax enable

She’s a beaut.

" ---------- Custom Hotkeys -

This is a comment to help organize the config file. Commented lines are preceded with a "

let mapleader = "," " map leader key as ,

This might be the most important line in the config file. The leader key is a special key that you can use to prefix commands. It’s helpful since most of the usual key pairs (i.e. shift + a letter, or ctrl + a letter) already do something else. The leader acts as a way to expand the possible, yet simple, key bindings. I’ve chosen , because I like it 🤷‍♂ but there are other common ones, like ; or ' It’s usually a key you don’t have to access with the shift key.

:imap jj <Esc>

Here we see our first custom binding. :imap stands for Insert Mode map. Then it’s followed by the custom binding, in this case jj , then the key you’re mapping to, in this case <Esc> . Last-generation MacBook Pro users rejoice! We have an easier way to hit the Escape key. I chose jj because my finger is usually resting on the j and I rarely need to actually type jj in Insert Mode, but again whatever works for your fingers!

:nmap <Space><Space> :

Similar to above but slightly different we see :nmap . You guessed it! Normal Mode map. Here I’m mapping spacebar x2 to : . This allows me to quickly enter commands.

:nmap <leader>s :split<Cr>
:nmap <leader>vs :vsplit<Cr>

Here we see the emergence of our leader key. That’s how you reference it: <leader> . These two commands split the pane in the Normal Mode. ,s for horizontal split, and ,vs for vertical split. Even your custom bindings should have mnemonics, unless you’re a raging lunatic.

" ---------- Terminal Controls ----
:nmap <leader>vt :vsplit term://zsh<Cr>
:nmap <leader>ht :split term://zsh<Cr>
:tnoremap jj <C-\><C-n> " Exit Insert Mode

We haven’t discussed it but you can open a terminal session in Vim. Which is already in a terminal session. Woah. Meta. These commands split the window, much like you would do normally, but they start a Z shell session in that split. The benefits being you can use your Vim commands on the terminal window. Here I have :tnoremap which is terminal Normal Mode map.

These next settings usually differ between NeoVim and Vim. The functionality is generally the same, only the setting names differ. Just a heads up for the Vim folks.

set encoding=utf8

Sets the encoding to utf-8 as you might have guessed.

set autoindent

Uses the same indent as the line above it.

set smartindent

Like autoindent but it can recognize some code syntax and automagically indent more/less/stay the same.

set shiftwidth=4

Sets the default “tab” to 4 spaces.

set smarttab

Tells your tab key to listen to shiftwidth

set clipboard=unnamed

This one is key!!! It tells Vim to use your system clipboard for copy/paste/cut

set number

Turns on line numbers. Cool.

set relativenumber

Turns on line numbers relative to your cursor. Very Cool.

set incsearch

Jumps to matching search terms while typing, however won’t move cursor there until you hit enter

set nohlsearch

Doesn’t keep searches highlighted. You may remember the :noh for clearing search highlights… this is that, but always.

set ignorecase

Ignores case in your search.

set smartcase

Includes case in your search if you use any caps.

set noswapfile

You might have noticed Vim creating .swp files. They hold changes that you’ve made to a buffer and allow you to recover those changes should you need. I’m a frequent saver and got tired of randomly committing .swp files to repos. This turns them off.

autocmd BufWritePre * %s/\s\+$//e "Auto-remove trailing whitespace on save

This fancy little command I’m proud of. autocmd BufWritePre is an auto-command (a hook) that runs before a buffer is written (saved). The * is a glob for all buffer writes. %s/\s\+$//e is a regex that searches for trailing whitespace and removes it.

set list listchars=tab:\ \ ,trail:·

Sets trailing whitespace characters to little · characters, even though they’ll be removed by the previous autocmd

syntax enable

Finally, this enables syntax highlighting, usually paired with a theme.

There You Have It

That’s all folks! The point of this post really wasn’t to make you fluent in the language of Vim config files. Trust me, you’ll need to look up how to do most things for a long time, and always.

The point of this post was really to show you what kind of customizations you can achieve through the config file, and some common changes people do to make their Vim experience 10x.

One thing you’ll notice about my config file, especially if you’ve checked out some others floating around the web, is that it’s tiny. Granted, I omitted the plugins, but still by Vim config file standards this is small. It’s important to remember that while you certainly can change anything and everything in Vim, it doesn’t necessarily mean you should.

Why’s that? It goes back to Vim’s real benefit being its ubiquity. You can really only take full advantage of that if you become a master at vanilla Vim commands. Sure you’ll usually have you dotfiles just a git clone away, but not always. Don’t go config-crazy and forget where you came from!

Up Next

Coming up next we’re going to kick Vim into full IDE-mode and learn all about extending functionality with plugins.

Vim For Developers: Part 5 — Plugins

--

--