Minimal Vim

May 20, 2019

In my previous blog post, I wrote about searching files in Vim. In the next five sections, I will go over creating a minimal Vim setup with a few dependencies. Although minimal does not necessarily mean faster, I’ll keep in mind making Vim perform and open as fast as possible.

General Settings

There are a few must-have settings that are necessary for modern text editing. Actually, while writing this blog post, I revisited my .vimrc file and removed some of the unneeded settings. I’m currently experimenting Vim without all the options I think I don’t need right now. I’m also trying to comment my settings as much as possible.

There are many settings frameworks or distributions such as vim-sensible or SpaceVim (although they are completely different kinds of frameworks). Personally, I don’t like to use these frameworks as a matter of fact since the need and the use case may differ from one person to another and I prefer to tweak my configuration to my own use case. Anyway, As a general rule I like to abide by, I tend to not put any settings that I don’t understand in my .vimrc.

Try not to put settings you don’t understand in your .vimrc

In the next block of code, there are some [somewhat opinionated] commented settings that you may need to have in your configuration file (I recommend reading Vim’s manual for each entry before using it):

"more characters will be sent to the screen for redrawing
set ttyfast
"time waited for key press(es) to complete. It makes for a faster key response
set ttimeout
set ttimeoutlen=50
"make backspace behave properly in insert mode
set backspace=indent,eol,start
"display incomplete commands
set showcmd
"a better menu in command mode
set wildmenu
set wildmode=longest:full,full
"hide buffers instead of closing them even if they contain unwritten changes
set hidden
"disable soft wrap for lines
set nowrap
"always display the status line
set laststatus=2
"display line numbers on the left side
set number
"highlight current line
set cursorline
"display text width column
set colorcolumn=81
"new splits will be at the bottom or to the right side of the screen
set splitbelow
set splitright

"always set autoindenting on
set autoindent

"incremental search
set incsearch
"highlight search
set hlsearch
"searches are case insensitive unless they contain at least one capital letter
set ignorecase
set smartcase

Plugins

Even though Vim is a powerful text editor, it cannot survive the competition with other modern text editors and IDEs without plugins. Luckily, Vim is powerful enough to be extensible in many ways. This enabled the Vim plugin ecosystem to thrive and grow. To manage plugins, I use vim-plug which is easier to maintain (since it’s only a single file), runs plugin updates asynchronously, and it’s faster to load compared to other plugin managers.

Regardless of the plugin manager, I always try to avoid using plugins as much as possible. This is mainly because more plugins means more startup time for Vim. More plugins also means more dependencies to manage.

Using vim-plugins-profile, the next screenshot shows the top 10 plugins that are taking most of Vim’s startup time for me:

Vim plugins profiled

After profiling Vim’s startup time, I replaced tcomment_vim with vim-commentary and it actually made a noticeable difference on the startup time of Vim.

By the way, Vim actually can profile its startup time and dump it to a file with vim --startuptime vim.log.

Functions

Functions are also an integral part of any .vimrc file to complement the work of plugins. However, functions like any other pіece of code, can slow you down sometimes. Currently, I only have two functions in my Vim configuration file. One function for creating and moving between split windows and another function for Goyo’s leave event.

You can profile your functions and check which part of each function that may slow Vim down while executing it. As I mentioned above, I only have a few functions in my ~/.vimrc file. So, I profiled them and got the result using Vim’s profile command. Here’s an example on how to profile the function WinMove(key) using Vim’s profile command:

vim --cmd 'profile start vimrc.profile' \
    --cmd 'profile! file ~/.vimrc' \
    -c "call WinMove('j')"

And here’s an excerpt of the profiling result:

FUNCTION  WinMove()
    Defined: ~/.vimrc line 181
Called 1 time
Total time:   0.000384
 Self time:   0.000081

Status Line

IMHO, the Vim community has invested a lot of time and effort to make colorful status lines with lots of weird symbols and many functionalities. Don’t get me wrong, I love the aesthetics of a beautiful, colorful status line; however, I kind of feel like it can be a bit distracting while writing. What I really think is that the status line should not get in the way of the developer; it should be a complementary tool not an essential one.

For me, I’ve updated my status line to have only a few functions that I really need while writing. It even differs from the stock status line that comes with Vim. Here’s how I currently configure my status line:

"you need this to always display the status line
set laststatus=2

"modifiedflag, charcount, filepercent, filepath
set statusline=%=%m\ %c\ %P\ %f

And this is how it looks like:

Minimal statuline

File Explorer

I see a lot of Vim users put the plugin NERDTree in their Vim configuration and many online tutorials and articles advice to install it. In fact, when I was starting with Vim, I used to have it in my .vimrc as well. However, after a while, I found out that Vim actually comes with a file explorer called netrw out of the box.

To open netrw on the side (a vertical split) like NERDTree, you can run the command :Vexplore, or :Sexplore to open it in a horizontal split window. As with using Vim in general, the more you use it, the more you realize that you know nothing about it. As of writing this post, I’ve learned more features that I didn’t know existed in netrw. You can always learn about the commands and key maps of netrw using :h netrw.

netrw preview

Just like NERDTree, You can manipulate files and directories (browse, execute, rename, delete, …) from inside netrw. Moreover, you can configure it to behave exactly like NERDTree. Here are the relevant settings in my .vimrc:

let g:netrw_banner=0
let g:netrw_winsize=20
let g:netrw_liststyle=3
let g:netrw_localrmdir='rm -r'

"toggle netrw on the left side of the editor
nnoremap <leader>n :Lexplore<CR>

My .vimrc file is now exactly 149 lines after I removed unused plugins and redundant settings. You can find my full .vimrc file in my dotfiles repository on GitHub. Thanks for reading!