Skip to content
Switch branches/tags
Go to file
1 contributor

Users who have contributed to this file

" _
" __ _(_)_ __ ___ _ __ ___
" \ \ / / | '_ ` _ \| '__/ __|
" \ V /| | | | | | | | | (__
" \_/ |_|_| |_| |_|_| \___|
" Ian's .vimrc file
" ----------------------------------------------------------------------------
" ----------------------------------------------------------------------------
let mapleader = ','
" Useful macros I use the most
nmap \A :set formatoptions+=a<CR>:echo "autowrap enabled"<CR>
nmap \F :NERDTreeFind<CR>
nmap \M :set noexpandtab tabstop=8 softtabstop=4 shiftwidth=4<CR>
nmap \T :set expandtab tabstop=8 shiftwidth=8 softtabstop=4<CR>
nmap \W mt:Goyo<CR>'tzz
nmap \a :set formatoptions-=a<CR>:echo "autowrap disabled"<CR>
nmap \b :set nocin tw=80<CR>:set formatoptions+=a<CR>
nmap \c :call TmuxPaneClear()<CR>
nmap \e :NERDTreeToggle<CR>
nmap \g :GitGutterToggle<CR>
nmap \i vip:sort<CR>
nmap \l :setlocal number!<CR>:setlocal number?<CR>
nmap \m :set expandtab tabstop=2 shiftwidth=2 softtabstop=2<CR>
nmap \o :set paste!<CR>:set paste?<CR>
nmap \p :ProseMode<CR>
nmap \q :nohlsearch<CR>
nmap \r :call TmuxPaneRepeat()<CR>
nmap \s :setlocal invspell<CR>
nmap \t :set expandtab tabstop=4 shiftwidth=4 softtabstop=4<CR>
nmap \u :setlocal list!<CR>:setlocal list?<CR>
nmap \w :setlocal wrap!<CR>:setlocal wrap?<CR>
nmap \x :cclose<CR>
nmap \z :w<CR>:!open %<CR><CR>
" Turn off linewise keys. Normally, the `j' and `k' keys move the cursor down one entire line. with
" line wrapping on, this can cause the cursor to actually skip a few lines on the screen because
" it's moving from line N to line N+1 in the file. I want this to act more visually -- I want `down'
" to mean the next line on the screen
nmap j gj
nmap k gk
" Marks should go to the column, not just the line. Why isn't this the default?
nnoremap ' `
" You don't know what you're missing if you don't use this.
nmap <C-e> :e#<CR>
" Move between open buffers.
nmap <C-n> :bnext<CR>
nmap <C-p> :bprev<CR>
" Emacs-like bindings in normal mode
nmap <C-x>0 <C-w>c
nmap <C-x>1 <C-w>o
nmap <C-x>1 <C-w>s
nmap <C-x>1 <C-w>v
nmap <C-x>o <C-w><C-w>
nmap <M-o> <C-w><C-w>
" Emacs-like bindings in insert mode
imap <C-e> <C-o>$
imap <C-a> <C-o>0
" Emacs-like bindings in the command line from `:h emacs-keys`
cnoremap <C-a> <Home>
cnoremap <C-b> <Left>
cnoremap <C-f> <Right>
cnoremap <C-d> <Del>
cnoremap <C-e> <End>
cnoremap <M-b> <S-Left>
cnoremap <M-f> <S-Right>
cnoremap <M-d> <S-right><Delete>
cnoremap <Esc>b <S-Left>
cnoremap <Esc>f <S-Right>
cnoremap <Esc>d <S-right><Delete>
cnoremap <C-g> <C-c>
" Use the space key to toggle folds
nnoremap <space> za
vnoremap <space> zf
" Super fast window movement shortcuts
nmap <C-j> <C-W>j
nmap <C-k> <C-W>k
nmap <C-h> <C-W>h
nmap <C-l> <C-W>l
" Resize panes when window/terminal gets resize
autocmd VimResized * :wincmd =
" Search for the word under the cursor in the current directory
nmap <M-k> :Rg <C-R><C-W><CR>
nmap <Esc>k :Rg <C-R><C-W><CR>
nmap ˚ :Rg <C-R><C-W><CR>
" Alt-W to delete a buffer and remove it from the list but keep the window via bufkill.vim
nmap <Esc>w :BD<CR>
nmap <M-w> :BD<CR>
nmap ∑ :BD<CR>
" Quickly fix spelling errors choosing the first result
nmap <Leader>z z=1<CR><CR>
" Fix annoyances in the QuickFix window, like scrolling too much
autocmd FileType qf setlocal number nolist
autocmd Filetype qf wincmd J " Makes sure it's at the bottom of the vim window
" Commands to send common keystrokes using tmux
let g:tmux_console_pane = '0:0.0'
let g:tmux_server_pane = '0:0.0'
function TmuxPaneRepeat()
silent execute ':!tmux send-keys -t' g:tmux_console_pane 'C-p' 'C-j'
function TmuxPaneClear()
silent execute ':!tmux send-keys -t' g:tmux_server_pane 'C-j' 'C-j' 'C-j' 'C-j' 'C-j' 'C-j' 'C-j'
" These are things that I mistype and want ignored.
nmap Q <silent>
nmap q: <silent>
nmap K <silent>
" Make the cursor stay on the same line when window switching
function! KeepCurrentLine(motion)
let theLine = line('.')
let theCol = col('.')
exec 'wincmd ' . a:motion
if &diff
call cursor(theLine, theCol)
nnoremap <C-w>h :silent call KeepCurrentLine('h')<CR>
nnoremap <C-w>l :silent call KeepCurrentLine('l')<CR>
" ----------------------------------------------------------------------------
" ----------------------------------------------------------------------------
" Typing `$c` on the command line expands to `:e` + the current path, so it's easy to edit a file in
" the same directory as the current file.
cnoremap $c e <C-\>eCurrentFileDir()<CR>
function! CurrentFileDir()
return "e " . expand("%:p:h") . "/"
" I can't spell :(
abbr conosle console
abbr comopnent component
" Debugging helpers
autocmd BufEnter *.py iabbr xxx print('XXX
autocmd BufEnter *.py iabbr yyy print('YYY
autocmd BufEnter *.py iabbr zzz print('ZZZ
autocmd BufEnter *.coffee iabbr xxx console.log 'XXX',
autocmd BufEnter *.coffee iabbr yyy console.log 'YYY',
autocmd BufEnter *.coffee iabbr zzz console.log 'ZZZ',
autocmd BufEnter *.js iabbr xxx console.log('XXX',
autocmd BufEnter *.js iabbr yyy console.log('YYY',
autocmd BufEnter *.js iabbr zzz console.log('ZZZ',
autocmd BufEnter *.ts iabbr xxx console.log('XXX',
autocmd BufEnter *.ts iabbr yyy console.log('YYY',
autocmd BufEnter *.ts iabbr zzz console.log('ZZZ',
autocmd BufEnter *.rb iabbr xxx puts "XXX
autocmd BufEnter *.rb iabbr yyy puts "YYY
autocmd BufEnter *.rb iabbr zzz puts "ZZZ
autocmd BufEnter *.rb iabbr ppp require 'pp'; pp
" ----------------------------------------------------------------------------
" ----------------------------------------------------------------------------
set autoindent " Carry over indenting from previous line
set autoread " Don't bother me hen a file changes
set autowrite " Write on :next/:prev/^Z
set backspace=indent,eol,start
" Allow backspace beyond insertion point
set cindent " Automatic program indenting
set cinkeys-=0# " Comments don't fiddle with indenting
set cino= " See :h cinoptions-values
set commentstring=\ \ #%s " When folds are created, add them to this
set copyindent " Make autoindent use the same chars as prev line
set cryptmethod=blowfish2 " Use a stronger cipher than the default
set directory-=. " Don't store temp files in cwd
set encoding=utf8 " UTF-8 by default
set expandtab " No tabs
set fileformats=unix,dos,mac " Prefer Unix
set fillchars=vert:\ ,stl:\ ,stlnc:\ ,fold:-,diff:┄
" Unicode chars for diffs/folds, and rely on
" Colors for window borders
silent! set foldmethod=marker " Use braces by default
set formatoptions=tcqn1 " t - autowrap normal text
" c - autowrap comments
" q - gq formats comments
" n - autowrap lists
" 1 - break _before_ single-letter words
" 2 - use indenting from 2nd line of para
set hidden " Don't prompt to save hidden windows until exit
set history=200 " How many lines of history to save
set hlsearch " Hilight searching
set ignorecase " Case insensitive
set incsearch " Search as you type
set infercase " Completion recognizes capitalization
set laststatus=2 " Always show the status bar
set linebreak " Break long lines by word, not char
set list " Show whitespace as special chars - see listchars
set listchars=tab\ ,extends:›,precedes:‹,nbsp:·,trail:· " Unicode characters for various things
set matchtime=2 " Tenths of second to hilight matching paren
set nomodeline " teh hackerz!!!1
silent! set mouse=nvc " Use the mouse, but not in insert mode
set nobackup " No backups left after done editing
set nonumber " No line numbers to start
set visualbell t_vb= " No flashing or beeping at all
set nowritebackup " No backups made while editing
set printoptions=paper:letter " US paper
set ruler " Show row/col and percentage
set scroll=4 " Number of lines to scroll with ^U/^D
set scrolloff=15 " Keep cursor away from this many chars top/bot
set sessionoptions-=options " Don't save runtimepath in Vim session (see tpope/vim-pathogen docs)
set shiftround " Shift to certain columns, not just n spaces
set shiftwidth=2 " Number of spaces to shift for autoindent or >,<
set shortmess+=A " Don't bother me when a swapfile exists
set showbreak= " Show for lines that have been wrapped, like Emacs
set showmatch " Hilight matching braces/parens/etc.
set sidescrolloff=3 " Keep cursor away from this many chars left/right
set smartcase " Lets you search for ALL CAPS
set softtabstop=2 " Spaces 'feel' like tabs
set suffixes+=.pyc " Ignore these files when tab-completing
set tabstop=2 " The One True Tab
set textwidth=0 " No wrapping by default
set wildmenu " Show possible completions on command line
set wildmode=list:longest,full " List all options and complete
set wildignore=*.class,*.o,*~,*.pyc,.git,node_modules " Ignore certain files in tab-completion
" Essential for filetype plugins.
filetype plugin indent on
" ----------------------------------------------------------------------------
" ----------------------------------------------------------------------------
" I always hit ":W" instead of ":w" because I linger on the shift key...
command! Q q
command! W w
" Trim spaces at EOL and retab. I run `:CLEAN` a lot to clean up files.
command! TEOL %s/\s\+$//
command! CLEAN retab | TEOL
" Close all buffers except this one
command! BufCloseOthers %bd|e#
" ----------------------------------------------------------------------------
" ----------------------------------------------------------------------------
" Use Pathogen for plugin management. See in this directory.
runtime bundle/vim-pathogen/autoload/pathogen.vim
call pathogen#infect()
call pathogen#helptags()
" For any plugins that use this, make their keymappings use comma
let mapleader = ","
let maplocalleader = ","
" FZF (replaces Ctrl-P, FuzzyFinder and Command-T)
set rtp+=/usr/local/opt/fzf
set rtp+=/opt/homebrew/opt/fzf
set rtp+=~/.fzf
nmap ; :Files<CR>
nmap <Leader>r :Tags<CR>
nmap <Leader>b :Buffers<CR>
nmap <Leader>t :Files<CR>
nmap <Leader>a :Rg!<CR>
nmap <Leader>c :Colors<CR>
let $FZF_DEFAULT_COMMAND = 'rg --files --follow -g "!{.git,node_modules}/*" 2>/dev/null'
command! -bang -nargs=* Rg
\ call fzf#vim#grep(
\ 'rg --column --line-number --no-heading --color=always --smart-case -g "!{*.lock,*-lock.json}" '.shellescape(<q-args>), 1,
\ <bang>0 ? fzf#vim#with_preview('up:40%')
\ : fzf#vim#with_preview('right:50%:hidden', '?'),
\ <bang>0)
" FZF color scheme updater from
function! s:update_fzf_colors()
let rules =
\ { 'fg': [['Normal', 'fg']],
\ 'bg': [['Normal', 'bg']],
\ 'hl': [['String', 'fg']],
\ 'fg+': [['CursorColumn', 'fg'], ['Normal', 'fg']],
\ 'bg+': [['CursorColumn', 'bg']],
\ 'hl+': [['String', 'fg']],
\ 'info': [['PreProc', 'fg']],
\ 'prompt': [['Conditional', 'fg']],
\ 'pointer': [['Exception', 'fg']],
\ 'marker': [['Keyword', 'fg']],
\ 'spinner': [['Label', 'fg']],
\ 'header': [['Comment', 'fg']] }
let cols = []
for [name, pairs] in items(rules)
for pair in pairs
let code = synIDattr(synIDtrans(hlID(pair[0])), pair[1])
if !empty(name) && code != ''
call add(cols, name.':'.code)
let s:orig_fzf_default_opts = get(s:, 'orig_fzf_default_opts', $FZF_DEFAULT_OPTS)
let $FZF_DEFAULT_OPTS = s:orig_fzf_default_opts .
\ (empty(cols) ? '' : (' --color='.join(cols, ',')))
augroup _fzf
autocmd VimEnter,ColorScheme * call <sid>update_fzf_colors()
augroup END
" Ctrl-C has a long delay in SQL files -
let g:ftplugin_sql_omni_key = '<Leader>s'
" More space with NERDTree
let g:NERDTreeMinimalUI = 1
let g:NERDTreeMarkBookmarks = 0
let g:NERDTreeAutoDeleteBuffer = 1
let g:NERDTreeStatusLine = -1
" Tell ack.vim to use ripgrep instead
let g:ackprg = 'rg --vimgrep --no-heading'
" GitGutter styling to use · instead of +/-
let g:gitgutter_sign_added = ''
let g:gitgutter_sign_modified = ''
let g:gitgutter_sign_removed = ''
let g:gitgutter_sign_modified_removed = ''
nmap ]g :GitGutterNextHunk<CR>
nmap [g :GitGutterPrevHunk<CR>
augroup VimDiff
autocmd VimEnter,FilterWritePre * if &diff | GitGutterDisable | endif
augroup END
" SuperTab
let g:SuperTabLongestEnhanced = 1
let g:SuperTabLongestHighlight = 1
au Filetype typescript let b:SuperTabDefaultCompletionType = "<C-x><C-o>"
" csv.vim
let g:csv_delim_test = ',|'
let g:csv_no_conceal = 1
highlight link CSVDelimiter Delimiter
highlight link CSVColumnHeaderEven Type
highlight link CSVColumnHeaderOdd Type
" Use incsearch.vim to highlight as I search
map / <Plug>(incsearch-forward)
map ? <Plug>(incsearch-backward)
map g/ <Plug>(incsearch-stay)
" Highlight YAML frontmatter in Markdown files
let g:vim_markdown_frontmatter = 1
" Lightline
let g:lightline = {
\ 'colorscheme': 'wombat',
\ 'active': {
\ 'left': [['mode', 'paste'], ['filename', 'modified']],
\ 'right': [['lineinfo'], ['percent'], ['readonly', 'linter_warnings', 'linter_errors', 'linter_ok']]
\ },
\ 'component_expand': {
\ 'linter_warnings': 'LightlineLinterWarnings',
\ 'linter_errors': 'LightlineLinterErrors',
\ 'linter_ok': 'LightlineLinterOK'
\ },
\ 'component_type': {
\ 'readonly': 'error',
\ 'linter_warnings': 'warning',
\ 'linter_errors': 'error'
\ },
\ }
function! LightlineLinterWarnings() abort
let l:counts = ale#statusline#Count(bufnr(''))
let l:all_errors = l:counts.error + l:counts.style_error
let l:all_non_errors = - l:all_errors
return == 0 ? '' : printf('%d ◆', all_non_errors)
function! LightlineLinterErrors() abort
let l:counts = ale#statusline#Count(bufnr(''))
let l:all_errors = l:counts.error + l:counts.style_error
let l:all_non_errors = - l:all_errors
return == 0 ? '' : printf('%d ✗', all_errors)
function! LightlineLinterOK() abort
let l:counts = ale#statusline#Count(bufnr(''))
let l:all_errors = l:counts.error + l:counts.style_error
let l:all_non_errors = - l:all_errors
return == 0 ? '' : ''
" Update and show lightline but only if it's visible (e.g., not in Goyo)
function! s:MaybeUpdateLightline()
if exists('#lightline')
call lightline#update()
" Update the lightline scheme from the colorscheme. Hopefully.
function! s:UpdateLightlineColorScheme()
let g:lightline.colorscheme = g:colors_name
call lightline#init()
augroup _lightline
autocmd ColorScheme * call s:UpdateLightlineColorScheme()
augroup END
" ----------------------------------------------------------------------------
" ----------------------------------------------------------------------------
" Make sure colored syntax mode is on, and make it Just Work with 256-color terminals.
set background=dark
let g:rehash256 = 1 " Something to do with Molokai?
colorscheme molokai
let g:seoul256_background = 233
if !has('gui_running')
let g:solarized_termcolors = 256
if $TERM == "xterm-256color" || $TERM == "screen-256color" || $COLORTERM == "gnome-terminal"
set t_Co=256
elseif has("terminfo")
colorscheme default
set t_Co=8
set t_Sf=[3%p1%dm
set t_Sb=[4%p1%dm
colorscheme default
set t_Co=8
set t_Sf=[3%dm
set t_Sb=[4%dm
" Disable Background Color Erase when within tmux -
if $TMUX != ""
set t_ut=
syntax on
" Make the damned tildes less visible
highlight link EndOfBuffer Comment
" Custom colors for NERDTree
highlight def link NERDTreeRO NERDTreeFile
" Make menu selections visible
highlight PmenuSel ctermfg=black ctermbg=magenta
" Custom mode for distraction-free editing
function! ProseMode()
call goyo#execute(0, [])
set spell noci nosi noai nolist noshowmode noshowcmd
set complete+=s
colors molokai
command! ProseMode call ProseMode()
autocmd! User GoyoEnter Limelight
autocmd! User GoyoLeave Limelight!
" ----------------------------------------------------------------------------
" ----------------------------------------------------------------------------
" Reset all autocommands
augroup vimrc
au BufNewFile,BufRead *.cson set ft=coffee
au BufNewFile,BufRead *.glsl setf glsl
au BufNewFile,BufRead *.gyp set ft=python
au BufNewFile,BufRead *.html setlocal nocindent smartindent
au BufNewFile,BufRead *.i7x setf inform7
au BufNewFile,BufRead *.ini setf conf
au BufNewFile,BufRead *.input setf gnuplot
au BufNewFile,BufRead *.journal setlocal tw=0 ts=4 sw=4 et
au BufNewFile,BufRead *.json set ft=json tw=0
au BufNewFile,BufRead *.less setlocal ft=less nocindent smartindent
au BufNewFile,BufRead *.lkml setf yaml
au BufNewFile,BufRead *.md setlocal ft=markdown nolist spell
au BufNewFile,BufRead *.md,*.markdown setlocal foldlevel=999 tw=0 nocin
au BufNewFile,BufRead *.ni,*.i7x setlocal ft=inform7 fdm=manual nolist ts=2 sw=2 noet spell
au BufNewFile,BufRead *.plist setf xml
au BufNewFile,BufRead *.rb setlocal noai
au BufNewFile,BufRead *.rxml setf ruby
au BufNewFile,BufRead *.sass setf sass
au BufNewFile,BufRead *.ttml setf xml
au BufNewFile,BufRead *.vert,*.frag set ft=glsl
au BufNewFile,BufRead *.xml setlocal ft=xml ts=2 sw=2 et
au BufNewFile,BufRead *.zone setlocal nolist ts=4 sw=4 noet
au BufNewFile,BufRead *.zsh setf zsh
au BufNewFile,BufRead *.ovpn setf openvpn
au BufNewFile,BufRead *templates/*.html setf htmldjango
au BufNewFile,BufRead .conkyrc set ft=lua
au BufNewFile,BufRead .git/config setlocal ft=gitconfig nolist ts=4 sw=4 noet
au BufNewFile,BufRead .gitconfig* setlocal ft=gitconfig nolist ts=4 sw=4 noet
au BufNewFile,BufRead postgres*.conf setlocal nolist ts=8 sw=8 noet
au BufNewFile,BufRead .vimlocal,.gvimlocal setf vim
au BufNewFile,BufRead .zshlocal setf zsh
au BufNewFile,BufRead /tmp/crontab* setf crontab
au BufNewFile,BufRead COMMIT_EDITMSG setlocal nolist nonumber
au BufNewFile,BufRead Makefile setlocal nolist
au BufNewFile,BufRead dist/* set ft=text
au FileType gitcommit setlocal nolist ts=4 sts=4 sw=4 noet
au FileType inform7 setlocal nolist tw=0 ts=4 sw=4 noet foldlevel=999
au FileType json setlocal conceallevel=0 foldmethod=syntax foldlevel=999
au FileType make setlocal nolist ts=4 sts=4 sw=4 noet
au FileType markdown syn sync fromstart
au Filetype gitcommit setlocal tw=80
au Filetype csv setlocal nocursorline
augroup END
" ----------------------------------------------------------------------------
" ----------------------------------------------------------------------------
" Now load specifics to this host
if filereadable(expand("~/.vimlocal"))
source ~/.vimlocal
" Some plugin seems to search for something at startup, so this fixes that.
silent! nohlsearch