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
set runtimepath+=~/Dropbox/vimsource ~/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
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 too 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
" 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 insterting/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.
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
" 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.
syntax on" 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
set shortmess=atI
Customizing the
set visualbell " don't beepset noerrorbells " don't beep
I don’t like Vim beeping at me so I turn on the
" Auto read when a file is changed on diskset autoread
Setting
" status lineset laststatus=2
Lastly, I set
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
Now, back to my
" space = pagedown, - = pageupnoremap <Space> <PageDown>noremap - <PageUp>
The next major grouping of my
" 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
" 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
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 hilightmap <F7> :b#<CR>
For creating new windows I map a double press of
" 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
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
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
" 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
" 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)