



We become what we behold. We shape our tools, and thereafter our tools shape us. Marshall McLuhan

Couldn’t agree more to Marshall McLuhan’s words. When you delve deeper into programming and interacting with the shell becomes mundane, enhancing productivity in editing is an aspect which you cannot overlook. Before I began to cherish the fruits of transparency, freedom, and ownership that Linux(and Open Source) has to offer, I quickly found myself at a point where I had to choose my religion- Holy Church of Emacs or Cult of Vi. I don’t want to start a flame war by commenting on which one is better and why, but I eventually landed in the Vim as my Swiss army knife and living happily thereafter! At the end of 2017, I decided to move to neovim, reasons which are out of the scope of this post. After tinkering for a while, I arrived at a stable configuration and efficient way of organizing vimrc files. So if you are a novice to (Neo)vim space or consider yourself at an intermediate stage, this post will definitely be worth your time.

The Skeleton

After installing neovim using your preferred method, you will be in the need to customize init.vim file located in $XDG_CONFIG_HOME/nvim or ~/.config/nvim . Configuration files will soon start to get long and clunky, thereby posing difficulties in keeping track of things, debugging, etc. I constantly keep on adding/removing plugins, which leaves antiquated settings scattered in my vimrc. Therefore I came up with the following skeleton init.vim file(I use dein as my plugin manager, you could use your preferred one):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

if &compatible

set nocompatible

endif





set runtimepath+=/path/ to /dein. vim





if dein#load_state( '/path/to/dein' )

call dein#begin( '/path/to/dein' )

call dein#add(...)

call dein#add(...)



call dein#end()

call dein#save_state()

endif



source ~/.config/nvim/base. vim

source ~/.config/nvim/mappings. vim

source ~/.config/nvim/plugins. vim



The last three lines, along with the order in which they appear are important. First, we source base.vim which holds configuration for vim, independent of any plugins. For example, you could set/unset variables, call autocmds on specific file_types, etc.

Next comes the mappings.vim file, as its name suggests, it holds custom mappings for neovim, again, independent of any plugins. These are mostly key bindings which you prefer and which suits your needs. Key bindings for custom commands can also be saved in this file, although I recommended against plugin specific commands.

The reason for these files being isolated from plugins is that you can take these files into any system, source them and feel(almost) at home without installing plugins on the target system. Especially useful if you frequently ssh into remote systems, but you want to keep the vim clean for others to use.

Next comes the plugins.vim file, which holds all configuration related to each and every plugin. This includes custom key mappings related to file_type plugins, declaring global variables, buffer-local variables, etc for every plugin. Each plugin configuration begins after the following line so that it is easier to locate and modify changes(you can customize this your way, just make sure it is visually differentiable):

1





Another advantage of this segregation of configuration is that in case something goes wrong, you are now in a better position to debug, as you know the order of execution. Key binding not working as expected? quickly run :verbose nmap and the logs will show in the reverse order of our sourced files what happened when. Same goes for variables and other stuff. As a piece of advice, always comment out the settings of the plugin which you intend to uninstall. You never know when you will need them again 😉

Below, are some of my snippets for each file:

base.vim 1

2

3

4

5

6

syntax enable

set nu

set rnu

set smartcase

set incsearch

...



mappings.vim 1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17



inoremap jk <esc>



let mapleader= " "





nnoremap <C-J> <C-W> <C-W>

nnoremap <C-K> <C-W> W

nnoremap <C-L> <C-W> >

nnoremap <C-H> <C-W> <





tnoremap <C-j> <C-k> <C-\> <C-N>

tnoremap <C-h> <C-\> <C-N> <C-w> h

tnoremap <C-j> <C-\> <C-N> <C-w> j

tnoremap <C-k> <C-\> <C-N> <C-w> k

tnoremap <C-l> <C-\> <C-N> <C-w> l



plugins.vim 1

2

3

4

5

6

7

8

9

10



colorscheme one

set background=light





let g:one_allow_italics = 1





let g:startify_fortune_use_unicode = 1

...



You can check out the complete configuration files at dotfiles.

Installing plugins

Next comes the most important part, installing plugins. Default vim features are sufficient for majority use cases, but when it comes to programming, you need to install plugins to get IDE-like features such as autocompletion, goto definitions, documentation, etc. First, let’s start off with a completion engine as I’m sure most of you will feel numb without one!

For this example, I will be using deoplete for completion and ALE for linting. Also, install the specific language sources for the completor if any, or configure Language Server Protocol to work with it. Optionally, install a snippets plugin if you are into snippets like I do(here, neosnippet)

base.vim 1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

...



call dein#add( 'Shougo/deoplete.nvim' )



call dein#add( 'w0rp/ale' )



call dein#add( 'Shougo/neosnippet.vim' )

call dein#add( 'Shougo/neosnippet-snippets' )

call dein#add( 'honza/vim-snippets' )



call dein#add( 'zchee/deoplete-jedi' , { 'on_ft' : 'python' })



call dein#add( 'sebastianmarkow/deoplete-rust' , { 'on_ft' : 'rust' })



call dein#add( 'zchee/deoplete-clang' )

...



Alternatives: ncm2(WIP), Neomake

Complementary Plugins:

I call these complementary because they enhance the productivity of our vanilla vim/neovim. It is a personal preference, some may blame them to be bloat while others may find it necessary. These include plugins which offer sane defaults, extra keybindings/motions/text objects, etc.

base.vim 1

2

3

4

5

6

7

8

9

10

...



call dein#add( 'jiangmiao/auto-pairs' )



call dein#add( 'justinmk/vim-sneak' )



call dein#add( 'justinmk/vim-dirvish' )



call dein#add( 'tpope/vim-fugitive' , { 'on_cmd' : 'Gstatus' , 'augroup' : 'fugitive' , 'on_source' : 'gitv' })

...



Others: All tpope and Shougo plugins!

Language Specific:

Next, we move on towards configuring language specific plugins. It is impossible to cover all languages, but here, I will mention those programming languages which I use, at the time of writing this post. The purpose of this is to show, in general, how will you configure your vimrc / init.vim in a maintainable way as you learn new programming languages.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16



call dein#add( 'davidhalter/jedi-vim' , { 'on_ft' : 'python' })



call dein#add( 'rust-lang/rust.vim' , { 'on_ft' : 'rust' })

call dein#add( 'sebastianmarkow/deoplete-rust' , { 'on_ft' : 'rust' })

call dein#add( 'mattn/webapi-vim' , { 'on_ft' : 'rust' })



call dein#add( 'vim-pandoc/vim-pandoc' , { 'name' : 'vim_pandoc' , 'on_source' : 'pandoc-after' })

call dein#add( 'dhruvasagar/vim-table-mode' , { 'on_cmd' : 'TableModeToggle' })

call dein#add( 'lervag/vimtex' , { 'on_ft' : [ 'plaintex' , 'tex' ]})

call dein#add( 'vim-pandoc/vim-pandoc-syntax' , { 'depends' : 'vim_pandoc' })

call dein#add( 'vim-pandoc/vim-pandoc-after' , { 'depends' : 'vim_pandoc' })

call dein#add( 'junegunn/goyo.vim' , { 'on_cmd' : 'Goyo' })

call dein#add( 'ron89/thesaurus_query.vim' ,{ 'on_ft' : [ 'pandoc' , 'text' ]})

call dein#add( 'rhysd/vim-grammarous' ,{ 'on_ft' :[ 'pandoc' , 'text' ]})

call dein#add( 'junegunn/limelight.vim' , { 'on_cmd' : 'Limelight' })



Fuzzy Finder:

For me, vim is incomplete without a fuzzy finder, and I am not joking. Efficiency reaches to a next level when you have a decently configured fuzzy file finder. I had been a long time user of Ctrlp until I switched to fzf.vim. Couple it with ripgrep, it is the fastest finder setup in my opinion. It’s fast and snappier than most of the other fuzzy systems that I had given a spin.

1

2

call dein#add( 'junegunn/fzf' , { 'build' : './install --all' , 'merged' : 0 })

call dein#add( 'junegunn/fzf.vim' , { 'depends' : 'fzf' })



I have configured leaderkey bindings for various actions in fzf, which can be found in my dotfiles repository.

Eyecandy

Some people may prefer customizing the looks, whereas others prefer simple and clean. If you are into customizing the looks, airline is a good option. Lightline is also a very good alternative. So go ahead, and pick the one which you prefer. You can find some good vim color schemes at vimcolors.com. Be sure to check them out.

One notable plugin to mention is vim-diminactive, which greatly assists in differentiating between different splits. It’s a must-have if you find yourself wasting too much time to figure out which split has focus.

Handy Commands

These are some useful commands which you will find helpful for your daily use. To view additional information about a particular command, type :h [command] .

![command] : Execute shell command

: Execute shell command messages : View the status/info/warn/error messages from statusbar.

: View the status/info/warn/error messages from statusbar. cd/lcd/tcd : Change working directory/window local directory/tab local directory.

: Change working directory/window local directory/tab local directory. verbose : To find out what has happened during startup and exit.

: To find out what has happened during startup and exit. namp/vmap/smap/imap/_etc : To view mappings for specified mode.

: To view mappings for specified mode. set [variable]? : Query the value of the variable, for example, ‘:set autochdir?’

: Query the value of the variable, for example, ‘:set autochdir?’ echo has(_feature_) : To check if a particular feature is enabled or not.

: To check if a particular feature is enabled or not. python [statement] : Execute the python statement and print it’s output in statusbar.

: Execute the python statement and print it’s output in statusbar. h vim_diff : List difference between vim and neovim(works only in neovim).

and many others.

Vimawesome: Plugins for vim

Vimcolors: Colorschemes for vim

Terminal.sexy: Test colorschemes

Neovim Specific: Neovim specific plugins/projects/colorschemes

Hope this article was useful. Comments, suggestions and criticisms are welcomed.