A coworker recently asked me about my transition to using Vim as my primary editor. He mentioned he might be trying to switch soon and wanted to know how it went for me. I told him I'm happy to help give suggestions and supplement knowledge where I can, but it got me thinking about just how daunting it can be to switch to something like Vim, and how hard it is to see the value that an editor like Vim can provide.
I'll start by saying that I do not recommend Vim to people. I always hated the whole Emacs vs Vim vs * debate, and I don't want to contribute to that noise. In fact, I still highly recommend Sublime Text (over Atom, though others may disagree) to people who ask for good editors for getting into programming.
Disclaimer: This is a post about how I would suggest getting set up with Vim from scratch. It is my own opinions and use cases, and is not authoritative. I'm still learning, these are my suggestions of the path-of-least-resistance for using Vim.
I now use NeoVim, a community maintained fork of Vim focused on maintainability. While that doesn't mean much to the end user, it does mean that it is a project likely to have some longevity to it. On top of that, it has very good default options baked in, and will give you a solid basis wherever you install it, ensuring things like native clipboard support are enabled.
The asterisk of NeoVim
It's not the exact same as Vim. In everyday use, its very close, and almost all Vim packages will work with NeoVim, but it has some well known issues supporting python-heavy Vim packages. This has largely not been an issue for me, and I will get into that later.
Skip this if you generally know your way around vim. If you're learning, great! Here's my "this is what you need to know" rundown of vim.
Modes. You'll spend almost all of your time in three modes: Normal, Insert and Visual. Normal is when you're just poking around at things, moving your cursor around. Insert is when you are adding to the file, this is your general typing and programming mode. Visual is when you're making selections in the file to act upon.
Navigate text with
hjkl or the arrow keys. Its your call, but
hjkl will be faster in the long run. Keeps you on the home row.
By default, press
i to enter insert mode. You can also press
a to enter inset mode after the currently highlighted character, or
A to jump to the end of the line. Press
esc to get out of insert mode back to normal mode.
You can press
v to enter visual mode and start selecting text. Lets say you want to delete 10 characters. Press
v, highlight the characters, and press
d. Gone, done, easy. Press
esc to get out of this mode, too.
You can also press capital
V to enter line selection visual mode. This is great for deleting or moving large chunks like functions. Press
V, select some lines, and do an operation on them.
You can copy/paste with
y for copy and
p for paste.
y stands for "yank". If you want to cut and paste,
d is delete, which also copies to what is essentially a clipboard, so
p are your cut and paste. Bread and butter for shifting code around.
I don't want to cover too much of this here, but that should be enough to get you going. There are countless resources for how to do XYZ in vim, googling will be useful. It may be overwhelming at first, but you'll eventually find other editing styles to be a hindrance. Turns out relying on the mouse takes up a whole lot of time from moving your hands back and forth.
init.vim / .vimrc
If you are using NeoVim, your configuration file will live at
~/.config/nvim/init.vim. This took me WAY too long to figure out. As stated in "the asterisk of NeoVim" section above, NeoVim has small differences, one of which is that it doesn't use a base
.vimrc like regular Vim does. Its a small change, just the file location, but it cost me a nonzero amount of time to figure that one out.
init.vim (assume I'm talking about a
.vimrc as well) contains startup configuration for your Vim instance. It gets read and executed when you start up the editor. Here is a trimmed down example of mine, may be a starting point. It is annotated as much as I can, and I have pulled out plugin specific config here:
" Basic setup set nocompatible " Enable compatibility set backspace=2 set exrc " allow for per-directory vimrc files let mapleader="," " map leader to comma set backupcopy=yes " Fix for watch mode in webpack set noswapfile " UI set ruler " Enable caret position set number " Set line number gutter set listchars=tab:→\ ,trail:• " set trailing space and tab charactersi set list " File type management filetype plugin indent on " Run settings for the given filetype " Searching set ignorecase set autoindent set incsearch set hlsearch " Editing set tabstop=2 " tab = 2 spaces set shiftwidth=2 " treat 2 spaces as a tab set expandtab " convert all tabs to spaces set showmatch " display when a contextualizing symbol has a match set smartindent " Wild menu set wildmode=longest,list,full set wildmenu set hidden nnoremap <CR> :noh<CR><CR> nnoremap <C-N> :bnext<CR> " Next buffer (file) nnoremap <C-H> :bprev<CR> " Previous buffer (file) nnoremap <C-X> :bdelete<CR> " Close buffer " never display, e.g., any node_modules directory: set wildignore+=*/**/node_modules set wildignore+=*.class set wildignore+=*/target/* set wildignore+=*.ico,*.jpg,*.gif,*.png set wildignore+=*/**/coverage* set wildignore+=*/dist/* " Quick remaps inoremap jk <esc> " Map `jk` to exit input mode
Hopefully most of those configurations speak for themselves.
If you're like me and your personal code style preferences differ from a project you are working on (say, for work), you may want to change your preferences per-directory. You can specify a
.nvimrc or a
.vimrc based on your preferred vim version at the root level of any project. This will override your global config settings.
Here's the secret sauce. Vim is minimalist up front, but can be extended to do so much. When moving over from Sublime, I thought I was going to miss the packages I relied on so much. Turns out, there were parallels for these packages, and in some cases, they had even more functionality.
I will list some basics to get you started below.
There are two big competitors for Vim package management: Pathogen and Vundle. I use Pathogen, and I find it easy to use, and will happily suggest it.
See installation instructions for Pathogen at their repository. It differs a bit again for NeoVim, just the file location again.
Once you have it installed and have the load script in your init file, you can just clone vim plugin git repos to your vim configuration folder's
bundle subfolder (
path/to/vim/config/bundle) and they will be loaded into vim. Each package may have different config steps to customize in your init script, but almost all of them work out of the box.
Ctrl P Fuzzy Find
The #1 thing I used in sublime was the fuzzy find for files. Well say hello to CtrlP for vim. Install it using whatever method (Pathogen, Vundle, as described above) and now your Vim will index files and let you fuzzy-find when you hit Ctrl+P
NERDTree File Explorer
This is a super useful plugin that gives a highly detailed and interactive file overview when working in a directory. Great for traversing project files. It is the analogue to a file tree that would appear in editors like Sublime or IDEs.
Ag for Hyper Fast Search
ack on steroids. Even if not for the vim plugin, having the Ag utility is stunningly great for searching codebases. Its full name is The Silver Searcher. You can install it as a command line utility, and bring it into vim with Ag.vim.
I will continue to revise this list should I find more crucial packages or change preferences significantly.
Go forth and code
Vim is a great tool. It has improved my workflow and made me feel in a way "closer" to the code I'm working on. At the very least, it has given me more excitement about working on stuff, and it means I can work from anywhere with a terminal.
Try it out, explore more packages, check out color schemes (I suggest Lucius Light), and customize to your liking. It may take a month or so to get into the flow, but if you stick with it, I promise that you'll end up more productive on the other side.