
Introduction
Many posts aimed at new Vim users tend to just paste a large .vimrc file and then explain a few plugins to try. Very little (if any) time is devoted to explaining what all those settings in .vimrc are actually doing.
I’d like to walk through my personal .vimrc file section by section and break down what and why I have the configuration settings I do. Given that my .vimrc has over 15 years’ worth of built-up cruft, this will also be a good exercise for me to clean it up a bit and update where needed as well.
Portable Vim
To be completely transparent, we won’t be really talking about the contents of my ~/.vimrc file, because that file on my computer really only contains the following:
set runtimepath+=~/Dropbox/vim
source ~/Dropbox/vim/vimrc.vim
I like to have my whole Vim setup, plugins and all, available to me no matter what system I’m on, and using Dropbox allows me to keep all my computers in sync. Yes, setting the runtimepath and then sourcing the file will increase your startup time, but for me the slight time bump is worth it. So, the file we will be really looking at is my ~/Dropbox/vim/vimrc.vim file which acts like a normal ~/.vimrc file.
General Configuration
" Don't include vi compatibilityset nocompatible
Right off the bat, the first thing I do is turn off Vi compatibility. If you were never an ardent Vi user (not Vim, Vi) then just turn off Vi compatibility. Then I make the backspace key play a bit nicer on OS X to allow me to backspace over auto-indents, line breaks, and the start of inserts.
" os x backspace fixset backspace=indent,eol,startset modelines=0 " dont need modelines and the potential security hazard
Next I turn off modeline support, mostly because I don’t use modelines personally and I don’t want to open a file from someone else that could potentially harm my system by the usage of modelines. It’s just a risk not worth taking if you aren’t in the habit of using modelines for what they were intended for.
"set t_kbfixdel
Last up in this section I just fix the terminal code support so both my backspace and delete keys work as expected on OS X.
" Setup term color supportif $TERM == "xterm-256color" || $TERM == "screen-256color" || $COLORTERM == "gnome-terminal"set t_Co=256endif
Next I turn on good color support for Vim terminal usage, and as a developer I turn on trailing whitespace support so I can see any trailing whitespace as I type it. We will revisit this setting again when I describe some settings that automatically strip trailing whitespace when a buffer is saved.
" show trailing whitespace charsset listset listchars=tab:>-,trail:.,extends:#,nbsp:.
Using set list turns on the display of unprintable characters, and then set listchars enumerates which characters to display and which character to display them with.
" Better buffer management - hide buffers instead of closing themset hiddenset history=100" Default history is only 20set undolevels=100 " Use more levels of undo
This next grouping relates to how Vim manages its buffers and history. I like Vim to hide my buffers instead of closing them completely. This allows me to keep modified buffers without being forced to save or abandon them. Next I have Vim remember 100 commands in history and set my undo level to 100 as well.
" tab -> spacesset expandtabset tabstop=2" a tab is 2 spacesset softtabstop=2 " tab size when inserting/pastingset shiftwidth=2 " number of spaces to use for autoindentingset shiftround" use multiple of shiftwidth when indenting with '<' and '>'set smarttab" insert tabs on the start of a line according to shiftwidth, not tabstop
The prolific spaces vs. tags section is next up, and I’m firmly in the converting spaces to tabs camp, so my Vim configuration reflects that. The first line expands tabs to spaces, with tab spacing of 2. Shiftwidth sets the number of spaces used when autoindenting.
set autoindent" always set autoindenting onset copyindent" copy the previous indentation on autoindenting
Finally we turn on auto-indentation and tell Vim to use the most recent indentation level when auto-indenting. These auto-indentation rules are just the defaults and will most-likely will be overridden by plugins you use for common programming languages.
" set foldenable" fold by defaultset nofoldenable" dont fold by defaultset foldmethod=indent " fold based on indentationset foldnestmax=10" deepest fold is 10 levelsset foldlevel=1
I prefer to not have my files open with folding turned on, but if you prefer, you can just uncomment set foldenable and remove set nofoldenable. I set my foldmethod to indent as this works well for just about all languages I code in, but other options include manual or custom syntax markers for fold delineation. I tell Vim to only nest 10 folds deep (honestly probably 5 levels is too far in my opinion, but 10 is better than the default of 20).
" Ruler onset ruler" Line numbers onset nu
I like to have line numbers turned on when editing, and also see which line and column I’m currently editing which is turned on by the ruler option.
" use ack for greppingset grepprg=ackset grepformat=%f:%l:%m
Also, I’m a user of Ack instead of grep so I tell Vim to use it instead of grep.
" dont use backup filesset nobackupset noswapfileset directory=~/.vim-tmp,~/.tmp,~/tmp,/var/tmp,/tmp " store swap files here
The next few lines are minor preferences, but pretty self-explanatory. I don’t have Vim make backup for swapfiles by default, but when it does, I set the directory hierarchy to use for creating those files.
" Enable syntax highlightingfiletype on" Enable filetype detectionfiletype indent on " Enable filetype-specific indentingfiletype plugin on " Enable filetype-specific plugins
As a developer, I prefer to have syntax highlighting and I turn it on. I also turn on file type detection and file type specific indentation rules and plugin loading.
" Search Settingsset incsearch " show search matches as you typeset ignorecase " case insensitive searchset smartcase " If a capital letter is included in search, make it case-sensitiveset nohlsearch " dont highlight search results
Next I configure how I want Vim to behave when searching. I have Vim show me the search results incrementally, as I type my search query and perform case-insensitive searches by default unless I include a capital letter in my query. Finally, I prefer not to highlight search results by default.
colorscheme vividchalkset background=dark
My color scheme settings come next and I use a dark background based on my primary usage of Vim from the terminal.
set scrolloff=2
The scrolloff setting is the number of lines of context to keep above and below the cursor when scrolling to the very top and bottom of the screen. I prefer to have a few lines of context visible always instead of having my cursor be at the very top or bottom of the screen.
set shortmess=atI
Customizing the shortmess variable is probably too much to cover here, but is worth a read if you have the time (use :help shortmess), but know that it is just configuring what and how I want alert and system messages to be displayed.
set visualbell " don't beepset noerrorbells " don't beep
I don’t like Vim beeping at me so I turn on the visualbell and I don’t want any error bells triggered at all.
" Auto read when a file is changed on diskset autoread
Setting autoread tells Vim to automatically read a file in memory again if it has been detected to have changed from outside of Vim.
" status lineset laststatus=2
Lastly, I set laststatus=2 to tell Vim to always show the status line (a value of 0 means never and 1 means only if there are at least 2 windows).
Plugin Management
" Use pathogen to easily modify the runtime path to include all" plugins under the ~/.vim/bundle directoryexecute pathogen#infect()
I use Pathogen as my Vim plugin manager. It seems most of the cool kids are now using Vundle which provides some nice, useful additions, but I’ve been on Pathogen for a long time and haven’t had the need to migrate yet. This command just initializes pathogen which loads all my plugins.
Key Mappings
To begin the discussion of keymapping, let’s take our first sidebar and remember that Vim is a modal editor and what this means for keymapping. While you will mostly only be concerned with mapping keys in the default, normal, and visual modes, here is the full list of modes and their corresponding mode symbol for mapping commands:
* n: normal only
* v: visual and select
* o: operator-pending
* x: visual only
* s: select only
* i: insert
* c: command-line
* l: insert, command-line, regexp-search (and others. Collectively called "Lang-Arg" pseudo-mode)
These mode symbols can be used as prefixes on the two mapping commands of map and noremap. Using map will map keys recursively while noremap is a non-recursive mapping.
Now, back to my vimrc file.
" space = pagedown, - = pageupnoremap <Space> <PageDown>noremap - <PageUp>
The next major grouping of my vimrc is my custom key mappings. I begin by mapping the Space spacebar to send a page down command, and the - minus key to send a page up command. I sometimes find this easier than the default of Ctrl-F and Ctrl-B respectively.
" make j and k act normally for wrapped linesnnoremap j gjnnoremap k gk" remap ; to : so you can just do `;w` instead of <Shift-; w> nnoremap ; :
Next I make the normal up/down movement keys of j and k perform the same for wrapped lines as unwrapped lines, and I remap the semicolon key to send the colon key command. Since colon is used for entering Vim commands, and only 3 people on earth seem to know what the default semicolon key does in Vim, we shorten this up to a single keystroke and just use ;.
(As an aside, to impress your friends, the default command for semicolon is to repeat the most recent f, t, F, or T command).
" make regexp search not suck by default -nnoremap / /vvnoremap / /v
Also, I make Vim’s regular expression pattern matching work a bit more sanely by default. This maps the search command of / to use /v by default in both normal and visual modes, which allows you to use a more familiar regular expression syntax instead of the craziness that is Vims regexp syntax.
" remap'd keysmap <c-j> <c-w>jmap <c-k> <c-w>kmap <c-l> <c-w>lmap <c-h> <c-w>hmap <Tab><Tab> <C-W>w
Here I begin to remap some movement keys just to save keystrokes. I map Ctrl-J directly to the standard window movement commands so I can save a keystroke and not have to type Ctrl-w j. Same for k, l and h. I also map window hopping to a double press of the Tab key so I can quickly cycle through windows with a single key.
nnoremap <F2><F2> :vsplit<CR>nnoremap <F3><F3> <C-W>wnnoremap <F4><F4> :set invwrap wrap?<CR> " use f4f4 to toggle wordwrapnnoremap <F5><F5> :set invhls hls?<CR> " use f5f5 to toggle search highlightmap <F7> :b#<CR>
For creating new windows I map a double press of F2 to vertically split my current window and then also map a double press of F3 to cycle again, just like my double Tab command does. Hey, there is no law against having two ways to do the same thing :). I remap double F4 to toggle word-wrapping on and off, and double F5 to toggle search result highlighting on and off.
" allow saving a sudo file if forgot to open as sudocmap w!! w !sudo tee % >/dev/null
Next come mappings for a command mode only way for me to save files that require root access, but which I forgot to open with the proper permissions.
" toggle paste modenmap <leader>o :set paste!<CR>" toggle NERDTree drawermap <leader>d <plug>NERDTreeTabsToggle<CR>
After that is way to quickly toggle paste mode on and off, which is very useful for pasting code snippets from GUI editors or found on the web, followed by a way for me to quickly toggle open the project drawer from the NERDTree plugin.
" remove trailing whitespacennoremap <leader>W :%s/\s\+$//<cr>:let @/=''<CR>
Lastly I map a quick command I can run to remove trailing whitespace on demand by typing \W (my leader key is set to backslash).
Custom Functions
Vim allows for the usage of custom-defined functions through Vimscript and I have one defined for the scratch.vim plugin I use.
" toggle scratch buffer (scratch.vim plugin)function! ToggleScratch()if expand('%') == g:ScratchBufferNamequitelseSscratchendifendfunctionmap <leader>s :call ToggleScratch()<CR>
I define a function called ToggleScratch() and then map that to \s for easy usage. This opens my Scratch buffer if not open in a current window.
Auto Commands
Auto commands in Vim allow you to have certain commands automatically execute based on events. Events can be anything from file type detection to reading a buffer.
" auto remove whitespace on buffer saveautocmd! BufWrite * mark ' | silent! %s/\s\+$// | norm ''
My first few auto commands are simple enough. I have a command set on all filetypes when the buffer is saved to remove any trailing whitespace.
" Turn on spell check for certain filetypes automaticallyautocmd BufRead,BufNewFile *.md setlocal spell spelllang=en_usautocmd BufRead,BufNewFile *.txt setlocal spell spelllang=en_usautocmd FileType gitcommit setlocal spell spelllang=en_us
Next I turn on spell check support for markdown and text files as well as my gitcommit messages to hopefully save myself any potential typo embarrassment.
" Autowrap text to 80 chars for certain filetypesautocmd BufRead,BufNewFile *.md setlocal textwidth=80autocmd BufRead,BufNewFile *.txt setlocal textwidth=80autocmd FileType gitcommit setlocal textwidth=80
Also for markdown, text and gitcommit files I set the max text width to 80 characters on buffer read and new buffers.
Plugin Specific Options
The last section of my vimrc contains customizations to the various plugins I use. Reading the help documentation for any plugin you use should provide documentation on the various settings you can configure to customize the plugin.
" gist-vim configlet g:gist_clip_command = 'pbcopy'let g:gist_detect_filetype = 1let g:gist_open_browser_after_post = 1let g:gist_post_private = 1 " make gists private by default
In my case, I set some basic customizations to the gist.vim plugin to make my gists private by default and open the gist in my browser after creation.
" CtrlP Configlet g:ctrlp_map = '<leader>t'let g:ctrlp_working_path_mode = 'ra'let g:ctrlp_match_window_bottom = 0let g:ctrlp_match_window_reversed = 0let g:ctrlp_custom_ignore = '\v\~$|\.(o|swp|pyc|wav|mp3|ogg|blend)$|(^|[/\\])\.(hg|git|bzr)($|[/\\])|__init__\.py'let g:ctrlp_working_path_mode = 0let g:ctrlp_dotfiles = 0let g:ctrlp_switch_buffer = 0
I use ctrlp.vim as my fuzzy file launcher and configure it mostly to tell it which files and directories to ignore and to map launching it to my \t keystroke.
" Vimux configlet g:vroom_use_vimux = 1
Lastly I configure vim-vroom to play nice with vimux to get some nice interactions between tmux and Vim.
— Craig (@cpjolicoeur)