" .vimrc " Author: Steve Losh " Source: http://bitbucket.org/sjl/dotfiles/src/tip/vim/ " " This file changes a lot. I'll try to document pieces of it whenever I have " a few minutes to kill. " Preamble ---------------------------------------------------------------- {{{ " Dear /bin/bash: fuck you and your bullshit, arcane command-line behaviour. " " Basically, I want to set this to a non-login, non-interactive bash shell. " Using a login/interactive bash as Vim's 'shell' breaks subtle things, like " ack.vim's command-line argument parsing. However, I *do* want bash to load " ~/.bash_profile so my aliases get loaded and such. " " You might think you could do this with the --init-file command line option, " which is used to specify an init file. Or with --rcfile. But no, those only " get loaded for interactive/login shells. " " So how do we tell bash to source a goddamned file when it loads? With an " *environment variable*. Jesus, you have multiple command line options for " specifying files to load and none of them work? " " Computers are bullshit. let $BASH_ENV = "~/.bash_profile" set shell=/bin/bash filetype off call pathogen#infect() filetype plugin indent on set nocompatible " }}} " Basic options ----------------------------------------------------------- {{{ set encoding=utf-8 set modelines=0 set autoindent set showmode set showcmd set hidden set visualbell set ttyfast set ruler set backspace=indent,eol,start set nonumber set norelativenumber set laststatus=2 set history=1000 set undofile set undoreload=10000 set list set listchars=tab:▸\ ,eol:¬,extends:❯,precedes:❮ set lazyredraw set matchtime=3 set showbreak=↪ set splitbelow set splitright set autowrite set autoread set shiftround set title set linebreak set colorcolumn=+1 " Spelling " " There are three dictionaries I use for spellchecking: " " /usr/share/dict/words " Basic stuff. " " ~/.vim/custom-dictionary.utf-8.add " Custom words (like my name). This is in my (version-controlled) dotfiles. " " ~/.vim-local-dictionary.utf-8.add " More custom words. This is *not* version controlled, so I can stick " work stuff in here without leaking internal names and shit. " " I also remap zG to add to the local dict (vanilla zG is useless anyway). set dictionary=/usr/share/dict/words set spellfile=~/.vim/custom-dictionary.utf-8.add,~/.vim-local-dictionary.utf-8.add nnoremap zG 2zg " iTerm2 is currently slow as balls at rendering the nice unicode lines, so for " now I'll just use ASCII pipes. They're ugly but at least I won't want to kill " myself when trying to move around a file. set fillchars=diff:⣿,vert:│ set fillchars=diff:⣿,vert:\| " Don't try to highlight lines longer than 800 characters. set synmaxcol=800 " Time out on key codes but not mappings. " Basically this makes terminal Vim work sanely. set notimeout set ttimeout set ttimeoutlen=10 " Make Vim able to edit crontab files again. set backupskip=/tmp/*,/private/tmp/*" " Better Completion set complete=.,w,b,u,t set completeopt=longest,menuone,preview " Save when losing focus au FocusLost * :silent! wall " Resize splits when the window is resized au VimResized * :wincmd = " Leader let mapleader = "," let maplocalleader = "\\" " Cursorline {{{ " Only show cursorline in the current window and in normal mode. augroup cline au! au WinLeave,InsertEnter * set nocursorline au WinEnter,InsertLeave * set cursorline augroup END " }}} " cpoptions+=J, dammit {{{ " Something occasionally removes this. If I manage to find it I'm going to " comment out the line and replace all its characters with 'FUCK'. augroup twospace au! au BufRead * :set cpoptions+=J augroup END " }}} " Trailing whitespace {{{ " Only shown when not in insert mode so I don't go insane. augroup trailing au! au InsertEnter * :set listchars-=trail:⌴ au InsertLeave * :set listchars+=trail:⌴ augroup END " }}} " Wildmenu completion {{{ set wildmenu set wildmode=list:longest set wildignore+=.hg,.git,.svn " Version control set wildignore+=*.aux,*.out,*.toc " LaTeX intermediate files set wildignore+=*.jpg,*.bmp,*.gif,*.png,*.jpeg " binary images set wildignore+=*.o,*.obj,*.exe,*.dll,*.manifest " compiled object files set wildignore+=*.spl " compiled spelling word lists set wildignore+=*.sw? " Vim swap files set wildignore+=*.DS_Store " OSX bullshit set wildignore+=*.luac " Lua byte code set wildignore+=migrations " Django migrations set wildignore+=*.pyc " Python byte code set wildignore+=*.orig " Merge resolution files " Clojure/Leiningen set wildignore+=classes set wildignore+=lib " }}} " Line Return {{{ " Make sure Vim returns to the same line when you reopen a file. " Thanks, Amit augroup line_return au! au BufReadPost * \ if line("'\"") > 0 && line("'\"") <= line("$") | \ execute 'normal! g`"zvzz' | \ endif augroup END " }}} " Tabs, spaces, wrapping {{{ set tabstop=8 set shiftwidth=4 set softtabstop=4 set expandtab set wrap set textwidth=80 set formatoptions=qrn1j set colorcolumn=+1 " }}} " Backups {{{ set backup " enable backups set noswapfile " it's 2013, Vim. set undodir=~/.vim/tmp/undo// " undo files set backupdir=~/.vim/tmp/backup// " backups set directory=~/.vim/tmp/swap// " swap files " Make those folders automatically if they don't already exist. if !isdirectory(expand(&undodir)) call mkdir(expand(&undodir), "p") endif if !isdirectory(expand(&backupdir)) call mkdir(expand(&backupdir), "p") endif if !isdirectory(expand(&directory)) call mkdir(expand(&directory), "p") endif " }}} " Color scheme {{{ syntax on set background=dark let g:badwolf_tabline = 2 let g:badwolf_html_link_underline = 0 colorscheme badwolf " Reload the colorscheme whenever we write the file. augroup color_badwolf_dev au! au BufWritePost badwolf.vim color badwolf augroup END " Highlight VCS conflict markers match ErrorMsg '^\(<\|=\|>\)\{7\}\([^=].\+\)\?$' " }}} " }}} " Abbreviations ----------------------------------------------------------- {{{ function! EatChar(pat) let c = nr2char(getchar(0)) return (c =~ a:pat) ? '' : c endfunction function! MakeSpacelessIabbrev(from, to) execute "iabbrev ".a:from." ".a:to."=EatChar('\\s')" endfunction function! MakeSpacelessBufferIabbrev(from, to) execute "iabbrev ".a:from." ".a:to."=EatChar('\\s')" endfunction call MakeSpacelessIabbrev('sl/', 'http://stevelosh.com/') call MakeSpacelessIabbrev('bb/', 'http://bitbucket.org/') call MakeSpacelessIabbrev('bbs/', 'http://bitbucket.org/sjl/') call MakeSpacelessIabbrev('gh/', 'http://github.com/') call MakeSpacelessIabbrev('ghs/', 'http://github.com/sjl/') iabbrev ldis ಠ_ಠ iabbrev lsad ಥ_ಥ iabbrev lhap ಥ‿ಥ iabbrev lmis ಠ‿ಠ iabbrev sl@ steve@stevelosh.com iabbrev vrcf `~/.vimrc` file iabbrev pcf Participatory Culture Foundation " }}} " Convenience mappings ---------------------------------------------------- {{{ " Fuck you, help key. noremap :checktime inoremap :checktime " Stop it, hash key. inoremap # X# " Kill window nnoremap K :q " Man nnoremap M K " Toggle line numbers nnoremap n :setlocal number! " Sort lines nnoremap s vip:!sort vnoremap s :!sort " Tabs nnoremap ( :tabprev nnoremap ) :tabnext " Wrap nnoremap W :set wrap! " Copying text to the system clipboard. " " For some reason Vim no longer wants to talk to the OS X pasteboard through "*. " Computers are bullshit. function! g:FuckingCopyTheTextPlease() let old_z = @z normal! gv"zy call system('pbcopy', @z) let @z = old_z endfunction noremap p :silent! set paste"*p:set nopaste " noremap p mz:r!pbpaste`z vnoremap y :call g:FuckingCopyTheTextPlease() " I constantly hit "u" in visual mode when I mean to "y". Use "gu" for those rare occasions. " From https://github.com/henrik/dotfiles/blob/master/vim/config/mappings.vim vnoremap u vnoremap gu u " Rebuild Ctags (mnemonic RC -> CR -> ) nnoremap :silent !myctags >/dev/null 2>&1 &:redraw! " Highlight Group(s) nnoremap :echo "hi<" . synIDattr(synID(line("."),col("."),1),"name") . '> trans<' \ . synIDattr(synID(line("."),col("."),0),"name") . "> lo<" \ . synIDattr(synIDtrans(synID(line("."),col("."),1)),"name") . ">" " Clean trailing whitespace nnoremap ww mz:%s/\s\+$//:let @/=''`z " Send visual selection to paste.stevelosh.com vnoremap :w !curl -sF 'sprunge=<-' 'http://paste.stevelosh.com' \| tr -d '\n ' \| pbcopy && open `pbpaste` " Select entire buffer nnoremap vaa ggvGg_ nnoremap Vaa ggVG " "Uppercase word" mapping. " " This mapping allows you to press in insert mode to convert the current " word to uppercase. It's handy when you're writing names of constants and " don't want to use Capslock. " " To use it you type the name of the constant in lowercase. While your " cursor is at the end of the word, press to uppercase it, and then " continue happily on your way: " " cursor " v " max_connections_allowed| " " MAX_CONNECTIONS_ALLOWED| " ^ " cursor " " It works by exiting out of insert mode, recording the current cursor location " in the z mark, using gUiw to uppercase inside the current word, moving back to " the z mark, and entering insert mode again. " " Note that this will overwrite the contents of the z mark. I never use it, but " if you do you'll probably want to use another mark. inoremap mzgUiw`za " Panic Button nnoremap mzggg?G`z " zt is okay for putting something at the top of the screen, but when I'm " writing prose I often want to put something at not-quite-the-top of the " screen. zh is "zoom to head level" nnoremap zh mzzt10`z " Diffoff nnoremap D :diffoff! " Formatting, TextMate-style nnoremap Q gqip vnoremap Q gq " Reformat line. " I never use l as a macro register anyway. nnoremap ql gqq " Easier linewise reselection of what you just pasted. nnoremap V V`] " Indent/dedent/autoindent what you just pasted. nnoremap > V`]< nnoremap > V`]> nnoremap =- V`]= " Keep the cursor in place while joining lines nnoremap J mzJ`z " Join an entire paragraph. " " Useful for writing GitHub comments in actual Markdown and then translating it " to their bastardized version of Markdown. nnoremap J mzvipJ`z " Split line (sister to [J]oin lines) " The normal use of S is covered by cc, so don't worry about shadowing it. nnoremap S i^mwgk:silent! s/\v +$//:noh`w " HTML tag closing inoremap :call InsertCloseTag()a " Source vnoremap S y:execute @@:echo 'Sourced selection.' nnoremap S ^vg_y:execute @@:echo 'Sourced line.' " Marks and Quotes noremap ' ` noremap æ ' noremap ` " Select (charwise) the contents of the current line, excluding indentation. " Great for pasting Python lines into REPLs. nnoremap vv ^vg_ " Sudo to write cnoremap w!! w !sudo tee % >/dev/null " Typos command! -bang E e command! -bang Q q command! -bang W w command! -bang QA qa command! -bang Qa qa command! -bang Wa wa command! -bang WA wa command! -bang Wq wq command! -bang WQ wq " I suck at typing. vnoremap - = " Toggle paste " For some reason pastetoggle doesn't redraw the screen (thus the status bar " doesn't change) while :set paste! does, so I use that instead. " set pastetoggle= nnoremap :set paste! " Toggle [i]nvisible characters nnoremap i :set list! " Unfuck my screen nnoremap U :syntax sync fromstart:redraw! " Pushing nnoremap Go :Start! git push origin nnoremap Gu :Start! git push upstream nnoremap Hd :Start! hg push default nnoremap Hu :Start! hg push upstream " Zip Right " " Moves the character under the cursor to the end of the line. Handy when you " have something like: " " foo " " And you want to wrap it in a method call, so you type: " " println()foo " " Once you hit escape your cursor is on the closing paren, so you can 'zip' it " over to the right with this mapping. " " This should preserve your last yank/delete as well. nnoremap zl :let @z=@"x$p:let @"=@z " Ranger nnoremap r :silent !ranger %:h:redraw! nnoremap R :silent !ranger:redraw! " Jump (see the J mini-plugin later on) nnoremap j :J " Insert Mode Completion {{{ inoremap inoremap inoremap " }}} " }}} " Quick editing ----------------------------------------------------------- {{{ nnoremap ev :vsplit $MYVIMRC nnoremap eV :vsplit scp://vagrant// nnoremap ef :vsplit ~/.config/fish/config.fish nnoremap ed :vsplit ~/.vim/custom-dictionary.utf-8.add nnoremap eo :vsplit ~/Dropbox/Org4j nnoremap eh :vsplit ~/.hgrc nnoremap eg :vsplit ~/.gitconfig nnoremap ep :vsplit ~/.pentadactylrc nnoremap em :vsplit ~/.mutt/muttrc nnoremap ez :vsplit ~/lib/dotfiles/zsh4j nnoremap ek :vsplit ~/lib/dotfiles/keymando/keymandorc.rb nnoremap et :vsplit ~/.tmux.conf nnoremap es :vsplit ~/.slate " }}} " Searching and movement -------------------------------------------------- {{{ " Use sane regexes. nnoremap / /\v vnoremap / /\v set ignorecase set smartcase set incsearch set showmatch set hlsearch set gdefault set scrolloff=3 set sidescroll=1 set sidescrolloff=10 set virtualedit+=block noremap :noh:call clearmatches() runtime macros/matchit.vim map % silent! unmap [% silent! unmap ]% " Made D behave nnoremap D d$ " Don't move on * " I'd use a function for this but Vim clobbers the last search when you're in " a function so fuck it, practicality beats purity. nnoremap * :let stay_star_view = winsaveview()*:call winrestview(stay_star_view) " Jumping to tags. " " Basically, jumps to tags (like normal) and opens the tag in a new " split instead. " " Both of them will align the destination line to the upper middle part of the " screen. Both will pulse the cursor line so you can see where the hell you " are. will also fold everything in the buffer and then unfold just " enough for you to see the destination line. function! JumpToTag() execute "normal! \mzzvzz15\" execute "keepjumps normal! `z" Pulse endfunction function! JumpToTagInSplit() execute "normal! \v\mzzMzvzz15\" execute "keepjumps normal! `z" Pulse endfunction nnoremap :silent! call JumpToTag() nnoremap :silent! call JumpToTagInSplit() " Keep search matches in the middle of the window. nnoremap n nzzzv nnoremap N Nzzzv " Same when jumping around nnoremap g; g;zz nnoremap g, g,zz nnoremap zz " Easier to type, and I never use the default behavior. noremap H ^ noremap L $ vnoremap L g_ " Heresy inoremap I inoremap A cnoremap cnoremap " gi already moves to "last place you exited insert mode", so we'll map gI to " something similar: move to last change nnoremap gI `. " Fix linewise visual selection of various text objects nnoremap VV V nnoremap Vit vitVkoj nnoremap Vat vatV nnoremap Vab vabV nnoremap VaB vaBV " Directional Keys {{{ " It's 2013. noremap j gj noremap k gk noremap gj j noremap gk k " Easy buffer navigation noremap h noremap j noremap k noremap l noremap v v " }}} " Visual Mode */# from Scrooloose {{{ function! s:VSetSearch() let temp = @@ norm! gvy let @/ = '\V' . substitute(escape(@@, '\'), '\n', '\\n', 'g') let @@ = temp endfunction vnoremap * :call VSetSearch()// vnoremap # :call VSetSearch()?? " }}} " List navigation {{{ nnoremap :cprevzvzz nnoremap :cnextzvzz nnoremap :lprevzvzz nnoremap :lnextzvzz " }}} " }}} " Folding ----------------------------------------------------------------- {{{ set foldlevelstart=0 " Space to toggle folds. nnoremap za vnoremap za " Make zO recursively open whatever fold we're in, even if it's partially open. nnoremap zO zczO " "Focus" the current line. Basically: " " 1. Close all folds. " 2. Open just the folds containing the current line. " 3. Move the line to a little bit (15 lines) above the center of the screen. " 4. Pulse the cursor line. My eyes are bad. " " This mapping wipes out the z mark, which I never use. " " I use :sus for the rare times I want to actually background Vim. nnoremap mzzMzvzz15`z:Pulse function! MyFoldText() " {{{ let line = getline(v:foldstart) let nucolwidth = &fdc + &number * &numberwidth let windowwidth = winwidth(0) - nucolwidth - 3 let foldedlinecount = v:foldend - v:foldstart " expand tabs into spaces let onetab = strpart(' ', 0, &tabstop) let line = substitute(line, '\t', onetab, 'g') let line = strpart(line, 0, windowwidth - 2 -len(foldedlinecount)) let fillcharcount = windowwidth - len(line) - len(foldedlinecount) return line . '…' . repeat(" ",fillcharcount) . foldedlinecount . '…' . ' ' endfunction " }}} set foldtext=MyFoldText() " }}} " Filetype-specific ------------------------------------------------------- {{{ " Assembly {{{ augroup ft_asm au! au FileType asm setlocal noexpandtab shiftwidth=8 tabstop=8 softtabstop=8 augroup END " }}} " C {{{ augroup ft_c au! au FileType c setlocal foldmethod=marker foldmarker={,} augroup END " }}} " Clojure {{{ let g:clojure_fold_extra = [ \ 'defgauge', \ 'defmeter', \ 'defhistogram', \ 'defcounter', \ 'deftimer', \ \ 'defdb', \ 'defentity', \ 'defaspect', \ 'add-aspect', \ 'defmigration', \ \ 'defsynth', \ 'definst', \ 'defproject', \ \ 'defroutes', \ \ 'defrec', \ \ 'defparser', \ \ 'defform', \ 'defform-', \ \ 'defpage', \ 'defsketch' \ \ ] let g:clojure_highlight_extra_defs = [ \ 'defparser', \ 'deftest', \ 'match', \ \ 'defproject', \ \ 'defquery', \ 'defqueries', \ \ 'defform', \ \ 'deferror', \ 'when-found', \ 'when-valid', \ \ 'defroutes' \ ] let g:clojure_highlight_extra_exceptions = [ \ 'try+', \ 'throw+', \ ] augroup ft_clojure au! au BufNewFile,BufRead *.edn set filetype=clojure au BufNewFile,BufRead riemann.config set filetype=clojure au FileType clojure silent! call TurnOnClojureFolding() au FileType clojure compiler clojure au FileType clojure setlocal report=100000 " Things that should be indented 2-spaced au FileType clojure setlocal lispwords+=when-found,defform,when-valid,try au FileType clojure RainbowParenthesesActivate au syntax clojure RainbowParenthesesLoadRound au syntax clojure RainbowParenthesesLoadSquare au syntax clojure RainbowParenthesesLoadBraces " Since YCM is hosefucked for Clojure, we'll use omnicompletion on au FileType clojure inoremap " And close the omnicomplete preview window after we're done with it. au InsertLeave *.clj if pumvisible() == 0|pclose|endif " Friendlier Paredit mappings. au FileType clojure noremap () :call PareditWrap("(", ")") au FileType clojure noremap )( :call PareditSplice() au FileType clojure noremap (( :call PareditMoveLeft() au FileType clojure noremap )) :call PareditMoveRight() au FileType clojure noremap (j :call PareditJoin() au FileType clojure noremap (s :call PareditSplit() au FileType clojure noremap [ :call PareditSmartJumpOpening(0) au FileType clojure noremap ] :call PareditSmartJumpClosing(0) " ))) " Indent top-level form. au FileType clojure nmap = mz99[(v%='z " ]) augroup END " }}} " Clojurescript {{{ augroup ft_clojurescript au! au BufNewFile,BufRead *.cljs set filetype=clojurescript au FileType clojurescript call TurnOnClojureFolding() " Indent top-level form. au FileType clojurescript nmap = v((((((((((((=% augroup END " }}} " Common Lisp {{{ " function! SendToTmuxStripped(text) " call SendToTmux(substitute(a:text, '\v\n*$', '', '')) " endfunction function! SetLispWords() if exists("g:did_set_lisp_words") return endif let g:did_set_lisp_words = 1 set lispwords+=switch set lispwords+=cswitch set lispwords+=eswitch endfunction augroup ft_commonlisp au! au BufNewFile,BufRead *.asd setfiletype lisp au FileType lisp call SetLispWords() " Set up some basic tslime mappings until I shave the fuckin " Fireplace/Common Lisp yak. " " key desc mnemonic " \t - connect tslime [t]slime " \f - send current form [f]orm " \e - send top-level form [e]val " \r - send entire file [r]eload file " \c - send ctrl-l [c]lear " Send the current form to the REPL au FileType lisp nnoremap f :let lisp_tslime_view = winsaveview()vab"ry:call SendToTmuxStripped(@r):call winrestview(lisp_tslime_view) " Send the current top-level form to the REPL au FileType lisp nnoremap e :let lisp_tslime_view = winsaveview():silent! normal! l:call PareditFindDefunBck()vab"ry:call SendToTmuxStripped(@r):call winrestview(lisp_tslime_view) " Send the entire buffer to the REPL au FileType lisp nnoremap r :let lisp_tslime_view = winsaveview()ggVG"ry:call SendToTmuxStripped(@r):call winrestview(lisp_tslime_view) " Clear the REPL au FileType lisp nnoremap c :call SendToTmuxRaw("x22x12") au FileType lisp RainbowParenthesesActivate au syntax lisp RainbowParenthesesLoadRound au syntax lisp RainbowParenthesesLoadSquare au syntax lisp RainbowParenthesesLoadBraces au FileType lisp silent! call TurnOnLispFolding() au FileType lisp noremap () :call PareditWrap("(", ")") au FileType lisp noremap )( :call PareditSplice() au FileType lisp noremap (( :call PareditMoveLeft() au FileType lisp noremap )) :call PareditMoveRight() au FileType lisp noremap (j :call PareditJoin() au FileType lisp noremap (s :call PareditSplit() au FileType lisp noremap )j :call PareditJoin() au FileType lisp noremap )s :call PareditSplit() au FileType lisp noremap [[ :call PareditSmartJumpOpening(0) au FileType lisp noremap ]] :call PareditSmartJumpClosing(0) " )) " Indent top-level form. au FileType lisp nmap = mz99[(v%='z " ]) augroup END " }}} " Confluence {{{ augroup ft_c au! au BufRead,BufNewFile *.confluencewiki setlocal filetype=confluencewiki " Wiki pages should be soft-wrapped. au FileType confluencewiki setlocal wrap linebreak nolist augroup END " }}} " Cram {{{ let cram_fold=1 augroup ft_cram au! au BufNewFile,BufRead *.t set filetype=cram au Syntax cram setlocal foldlevel=1 au FileType cram nnoremap ee :e augroup END " }}} " CSS and LessCSS {{{ augroup ft_css au! au BufNewFile,BufRead *.less setlocal filetype=less au Filetype less,css setlocal foldmethod=marker au Filetype less,css setlocal foldmarker={,} au Filetype less,css setlocal omnifunc=csscomplete#CompleteCSS au Filetype less,css setlocal iskeyword+=- " Use S to sort properties. Turns this: " " p { " width: 200px; " height: 100px; " background: red; " " ... " } " " into this: " p { " background: red; " height: 100px; " width: 200px; " " ... " } au BufNewFile,BufRead *.less,*.css nnoremap S ?{jV/\v^\s*\}?$k:sort:noh " Make { insert a pair of brackets in such a way that the cursor is correctly " positioned inside of them AND the following code doesn't get unfolded. au BufNewFile,BufRead *.less,*.css inoremap { {}.kA augroup END " }}} " Django {{{ augroup ft_django au! au BufNewFile,BufRead urls.py setlocal nowrap au BufNewFile,BufRead urls.py normal! zR au BufNewFile,BufRead dashboard.py normal! zR au BufNewFile,BufRead local_settings.py normal! zR au BufNewFile,BufRead admin.py setlocal filetype=python.django au BufNewFile,BufRead urls.py setlocal filetype=python.django au BufNewFile,BufRead models.py setlocal filetype=python.django au BufNewFile,BufRead views.py setlocal filetype=python.django au BufNewFile,BufRead settings.py setlocal filetype=python.django au BufNewFile,BufRead settings.py setlocal foldmethod=marker au BufNewFile,BufRead forms.py setlocal filetype=python.django au BufNewFile,BufRead common_settings.py setlocal filetype=python.django au BufNewFile,BufRead common_settings.py setlocal foldmethod=marker augroup END " }}} " DTrace {{{ augroup ft_dtrace au! autocmd BufNewFile,BufRead *.d set filetype=dtrace augroup END " }}} " Firefox {{{ augroup ft_firefox au! au BufRead,BufNewFile ~/Library/Caches/*.html setlocal buftype=nofile augroup END " }}} " Fish {{{ augroup ft_fish au! au BufNewFile,BufRead *.fish setlocal filetype=fish au FileType fish setlocal foldmethod=marker foldmarker={{{,}}} augroup END " }}} " Haskell {{{ augroup ft_haskell au! au BufEnter *.hs compiler ghc augroup END " }}} " HTML, Django, Jinja, Dram {{{ let g:html_indent_tags = ['p', 'li'] augroup ft_html au! au BufNewFile,BufRead *.html setlocal filetype=htmldjango au BufNewFile,BufRead *.dram setlocal filetype=htmldjango au FileType html,jinja,htmldjango setlocal foldmethod=manual " Use f to fold the current tag. au FileType html,jinja,htmldjango nnoremap f Vatzf " Use t to fold the current templatetag. au FileType html,jinja,htmldjango nmap t viikojozf " Indent tag au FileType html,jinja,htmldjango nnoremap = Vat= " Django tags au FileType jinja,htmldjango inoremap {%%} " Django variables au FileType jinja,htmldjango inoremap {{}} augroup END " }}} " Java {{{ augroup ft_java au! au FileType java setlocal foldmethod=marker au FileType java setlocal foldmarker={,} augroup END " }}} " Javascript {{{ augroup ft_javascript au! au FileType javascript setlocal foldmethod=marker au FileType javascript setlocal foldmarker={,} au FileType javascript call MakeSpacelessBufferIabbrev('clog', 'console.log();') " Make { insert a pair of brackets in such a way that the cursor is correctly " positioned inside of them AND the following code doesn't get unfolded. au Filetype javascript inoremap { {}.kA " } " Prettify a hunk of JSON with p au FileType javascript nnoremap p ^vg_:!python -m json.tool au FileType javascript vnoremap p :!python -m json.tool augroup END " }}} " Lilypond {{{ augroup ft_lilypond au! au FileType lilypond setlocal foldmethod=marker foldmarker={,} augroup END " }}} " Mail {{{ augroup ft_mail au! au Filetype mail setlocal spell augroup END " }}} " Markdown {{{ augroup ft_markdown au! au BufNewFile,BufRead *.m*down setlocal filetype=markdown foldlevel=1 " Use 1/2/3 to add headings. au Filetype markdown nnoremap 1 yypVr=:redraw au Filetype markdown nnoremap 2 yypVr-:redraw au Filetype markdown nnoremap 3 mzI###`zllll au Filetype markdown nnoremap 4 mzI####`zlllll au Filetype markdown nnoremap p VV:'<,'>!python -m json.tool au Filetype markdown vnoremap p :!python -m json.tool augroup END " }}} " Mercurial {{{ augroup ft_mercurial au! au BufNewFile,BufRead *hg-editor-*.txt setlocal filetype=hgcommit augroup END " }}} " Mutt {{{ augroup ft_muttrc au! au BufRead,BufNewFile *.muttrc set ft=muttrc au FileType muttrc setlocal foldmethod=marker foldmarker={{{,}}} augroup END " }}} " Nand2Tetris HDL {{{ augroup ft_n2thdl au! au BufNewFile,BufRead *.hdl set filetype=n2thdl augroup END " }}} " Nginx {{{ augroup ft_nginx au! au BufRead,BufNewFile /etc/nginx/conf/* set ft=nginx au BufRead,BufNewFile /etc/nginx/sites-available/* set ft=nginx au BufRead,BufNewFile /usr/local/etc/nginx/sites-available/* set ft=nginx au BufRead,BufNewFile vhost.nginx set ft=nginx au FileType nginx setlocal foldmethod=marker foldmarker={,} augroup END " }}} " OrgMode {{{ augroup ft_org au! au Filetype org nmap Q vahjgq au Filetype org setlocal nolist augroup END " }}} " Pentadactyl {{{ augroup ft_pentadactyl au! au BufNewFile,BufRead .pentadactylrc set filetype=pentadactyl au BufNewFile,BufRead ~/Library/Caches/TemporaryItems/pentadactyl-*.tmp set nolist wrap linebreak columns=100 colorcolumn=0 augroup END " }}} " Postgresql {{{ augroup ft_postgres au! au BufNewFile,BufRead *.sql set filetype=pgsql au BufNewFile,BufRead *.pgsql set filetype=pgsql au FileType pgsql set foldmethod=indent au FileType pgsql set softtabstop=2 shiftwidth=2 au FileType pgsql setlocal commentstring=--\ %s comments=:-- " Send to tmux with localleader e au FileType pgsql nnoremap e :let psql_tslime_view = winsaveview()vip"ry:call SendToTmux(@r):call winrestview(psql_tslime_view) " kill pager with q au FileType pgsql nnoremap q :call SendToTmuxRaw("q") augroup END " }}} " Puppet {{{ augroup ft_puppet au! au Filetype puppet setlocal foldmethod=marker au Filetype puppet setlocal foldmarker={,} augroup END " }}} " Python {{{ augroup ft_python au! au FileType python setlocal define=^\s*\\(def\\\\|class\\) au FileType man nnoremap :q " Jesus tapdancing Christ, built-in Python syntax, you couldn't let me " override this in a normal way, could you? au FileType python if exists("python_space_error_highlight") | unlet python_space_error_highlight | endif au FileType python iabbrev afo assert False, "Okay" augroup END " }}} " QuickFix {{{ augroup ft_quickfix au! au Filetype qf setlocal colorcolumn=0 nolist nocursorline nowrap tw=0 augroup END " }}} " ReStructuredText {{{ augroup ft_rest au! au Filetype rst nnoremap 1 yypVr=:redraw au Filetype rst nnoremap 2 yypVr-:redraw au Filetype rst nnoremap 3 yypVr~:redraw au Filetype rst nnoremap 4 yypVr`:redraw augroup END " }}} " Riemann Config Files {{{ augroup ft_riemann au! au BufNewFile,BufRead riemann.config set filetype=clojure au BufNewFile,BufRead riemann.config nnoremap = mzgg=G`z augroup END " }}} " Rubby {{{ augroup ft_ruby au! au Filetype ruby setlocal foldmethod=syntax au BufRead,BufNewFile Capfile setlocal filetype=ruby augroup END " }}} " Scala {{{ function! DispatchMavenTest() let view = winsaveview() let zreg = @z " Move to the top of the file normal! gg " Find the spec name call search('\vclass (.*Spec)') normal! w"zyiw let spec = @z execute "Dispatch mvn -q -B test -Dtest=" . spec let @z = zreg call winrestview(view) endfunction augroup ft_scala au! au Filetype scala setlocal foldmethod=marker foldmarker={,} au Filetype scala setlocal textwidth=100 au Filetype scala setlocal shiftwidth=2 au Filetype scala compiler maven au Filetype scala let b:dispatch = 'mvn -B package install' au Filetype scala nnoremap s mz:%!sort-scala-imports`z au Filetype scala nnoremap M :call scaladoc#Search(expand("")) au Filetype scala vnoremap M "ry:call scaladoc#Search(@r) au Filetype scala nnoremap t :call DispatchMavenTest() au Filetype scala nmap ( ysiwbi au Filetype scala nmap [ ysiwri ")] augroup END " }}} " Standard In {{{ augroup ft_stdin au! " Treat buffers from stdin (e.g.: echo foo | vim -) as scratch. au StdinReadPost * :set buftype=nofile augroup END " }}} " stevelosh.com Blog Entries {{{ augroup ft_steveloshcom au! au BufRead,BufNewFile */stevelosh/content/blog/20*/*/*.html set ft=markdown spell au BufRead,BufNewFile */stevelosh/content/projects/*.html set ft=markdown spell augroup END " }}} " TimL {{{ " let g:timl_fold_extra = [ " \ 'defgauge', " \ 'defmeter', " \ 'defhistogram', " \ 'defcounter', " \ 'deftimer' " \ ] " let g:timl_highlight_extra_defs = [ " \ 'defparser', " \ 'deftest', " \ 'match', " \ " \ 'defroutes' " \ ] augroup ft_timl au! au FileType timl silent! call TurnOnClojureFolding() " Things that should be indented 2-spaced " au FileType clojure setlocal lispwords+=when-found,defform,when-valid au FileType timl RainbowParenthesesActivate au syntax timl RainbowParenthesesLoadRound au syntax timl RainbowParenthesesLoadSquare au syntax timl RainbowParenthesesLoadBraces " Friendlier Paredit mappings. au FileType timl noremap () :call PareditWrap("(", ")") au FileType timl noremap )( :call PareditSplice() au FileType timl noremap (( :call PareditMoveLeft() au FileType timl noremap )) :call PareditMoveRight() au FileType timl noremap (j :call PareditJoin() au FileType timl noremap (s :call PareditSplit() au FileType timl noremap [ :call PareditSmartJumpOpening(0) au FileType timl noremap ] :call PareditSmartJumpClosing(0) " ))) au FileType timl call PareditInitBuffer() " Indent top-level form. au FileType timl nmap = mz99[(v%='z " ]) augroup END " }}} " Vagrant {{{ augroup ft_vagrant au! au BufRead,BufNewFile Vagrantfile set ft=ruby augroup END " }}} " Vim {{{ augroup ft_vim au! au FileType vim setlocal foldmethod=marker au FileType help setlocal textwidth=78 au BufWinEnter *.txt if &ft == 'help' | wincmd L | endif augroup END " }}} " YAML {{{ augroup ft_yaml au! au FileType yaml set shiftwidth=2 augroup END " }}} " XML {{{ augroup ft_xml au! au FileType xml setlocal foldmethod=manual " Use f to fold the current tag. au FileType xml nnoremap f Vatzf " Indent tag au FileType xml nnoremap = Vat= augroup END " }}} " }}} " Plugin settings --------------------------------------------------------- {{{ " Ack {{{ nnoremap a :Ack! let g:ackprg = 'ag --smart-case --nogroup --nocolor --column' " }}} " Autoclose {{{ nmap x ToggleAutoCloseMappings " }}} " Clam {{{ nnoremap ! :Clam vnoremap ! :ClamVisual let g:clam_autoreturn = 1 let g:clam_debug = 1 " }}} " Commentary {{{ nmap c CommentaryLine xmap c Commentary augroup plugin_commentary au! au FileType htmldjango setlocal commentstring={#\ %s\ #} au FileType clojurescript setlocal commentstring=;\ %s au FileType lisp setlocal commentstring=;\ %s au FileType puppet setlocal commentstring=#\ %s au FileType fish setlocal commentstring=#\ %s augroup END " }}} " Ctrl-P {{{ let g:ctrlp_dont_split = 'NERD_tree_2' let g:ctrlp_jump_to_buffer = 0 let g:ctrlp_working_path_mode = 0 let g:ctrlp_match_window_reversed = 1 let g:ctrlp_split_window = 0 let g:ctrlp_max_height = 20 let g:ctrlp_extensions = ['tag'] let g:ctrlp_map = ',' nnoremap . :CtrlPTag nnoremap E :CtrlP ../ let g:ctrlp_prompt_mappings = { \ 'PrtSelectMove("j")': ['', '', ''], \ 'PrtSelectMove("k")': ['', '', ''], \ 'PrtHistory(-1)': [''], \ 'PrtHistory(1)': [''], \ 'ToggleFocus()': [''], \ } let ctrlp_filter_greps = "". \ "egrep -iv '\\.(" . \ "jar|class|swp|swo|log|so|o|pyc|jpe?g|png|gif|mo|po" . \ ")$' | " . \ "egrep -v '^(\\./)?(" . \ "deploy/|lib/|classes/|libs/|deploy/vendor/|.git/|.hg/|.svn/|.*migrations/|docs/build/" . \ ")'" let my_ctrlp_user_command = "" . \ "find %s '(' -type f -or -type l ')' -maxdepth 15 -not -path '*/\\.*/*' | " . \ ctrlp_filter_greps let my_ctrlp_git_command = "" . \ "cd %s && git ls-files --exclude-standard -co | " . \ ctrlp_filter_greps let my_ctrlp_ffind_command = "ffind --semi-restricted --dir %s --type e -B -f" let g:ctrlp_user_command = ['.git/', my_ctrlp_ffind_command, my_ctrlp_ffind_command] " }}} " DelimitMate {{{ let delimitMate_excluded_ft = "clojure,lisp" " }}} " Dispatch {{{ nnoremap d :Dispatch nnoremap m :Dispatch " }}} " Fugitive {{{ let g:fugitive_github_domains = ['github.banksimple.com'] nnoremap gd :Gdiff nnoremap gs :Gstatus nnoremap gw :Gwrite nnoremap ga :Gadd nnoremap gb :Gblame nnoremap gco :Gcheckout nnoremap gci :Gcommit nnoremap gm :Gmove nnoremap gr :Gremove nnoremap gl :Shell git gl -18:wincmd \| augroup ft_fugitive au! au BufNewFile,BufRead .git/index setlocal nolist augroup END " "Hub" vnoremap H :Gbrowse " }}} " GnuPG {{{ let g:GPGPreferArmor = 1 " }}} " Gundo {{{ nnoremap :GundoToggle let g:gundo_debug = 1 let g:gundo_preview_bottom = 1 let g:gundo_tree_statusline = "Gundo" let g:gundo_preview_statusline = "Gundo Preview" " }}} " Haskellmode {{{ let g:haddock_browser = "open" let g:haddock_browser_callformat = "%s %s" let g:ghc = "/usr/local/bin/ghc" " }}} " HTML5 {{{ let g:event_handler_attributes_complete = 0 let g:rdfa_attributes_complete = 0 let g:microdata_attributes_complete = 0 let g:atia_attributes_complete = 0 " }}} " Linediff {{{ vnoremap l :Linediff nnoremap L :LinediffReset " }}} " Makegreen {{{ nnoremap \| :call MakeGreen('') " }}} " Maven {{{ let g:maven_disable_mappings = 1 " }}} " NERD Tree {{{ noremap :NERDTreeToggle inoremap :NERDTreeToggle augroup ps_nerdtree au! au Filetype nerdtree setlocal nolist au Filetype nerdtree nnoremap H :vertical resize -10 au Filetype nerdtree nnoremap L :vertical resize +10 " au Filetype nerdtree nnoremap K :q augroup END let NERDTreeHighlightCursorline = 1 let NERDTreeIgnore = ['.vim$', '\~$', '.*\.pyc$', 'pip-log\.txt$', 'whoosh_index', \ 'xapian_index', '.*.pid', 'monitor.py', '.*-fixtures-.*.json', \ '.*\.o$', 'db.db', 'tags.bak', '.*\.pdf$', '.*\.mid$', \ '.*\.midi$'] let NERDTreeMinimalUI = 1 let NERDTreeDirArrows = 1 let NERDChristmasTree = 1 let NERDTreeChDirMode = 2 let NERDTreeMapJumpFirstChild = 'gK' " }}} " OrgMode {{{ let g:org_heading_shade_leading_stars = 0 " let g:org_plugins = ['ShowHide', '|', 'Navigator', 'EditStructure', '|', 'Todo', 'Date', 'Misc'] " let g:org_todo_keywords = ['TODO', '|', 'DONE'] " let g:org_debug = 1 " }}} " Paredit {{{ let g:paredit_smartjump = 1 let g:paredit_shortmaps = 0 let g:paredit_electric_return = 1 " }}} " Powerline {{{ let g:Powerline_symbols = 'fancy' let g:Powerline_cache_enabled = 1 let g:Powerline_colorscheme = 'badwolf' " }}} " Python-Mode {{{ let g:pymode_doc = 1 let g:pymode_doc_key = 'M' let g:pydoc = 'pydoc' let g:pymode_syntax = 1 let g:pymode_syntax_all = 0 let g:pymode_syntax_builtin_objs = 1 let g:pymode_syntax_print_as_function = 0 let g:pymode_syntax_space_errors = 0 let g:pymode_run = 0 let g:pymode_lint = 0 let g:pymode_breakpoint = 0 let g:pymode_utils_whitespaces = 0 let g:pymode_virtualenv = 0 let g:pymode_folding = 0 let g:pymode_options_indent = 0 let g:pymode_options_fold = 0 let g:pymode_options_other = 0 let g:pymode_options = 0 let g:pymode_rope = 1 let g:pymode_rope_global_prefix = "R" let g:pymode_rope_local_prefix = "r" let g:pymode_rope_auto_project = 1 let g:pymode_rope_enable_autoimport = 0 let g:pymode_rope_autoimport_generate = 1 let g:pymode_rope_autoimport_underlineds = 0 let g:pymode_rope_codeassist_maxfixes = 10 let g:pymode_rope_sorted_completions = 1 let g:pymode_rope_extended_complete = 1 let g:pymode_rope_autoimport_modules = ["os", "shutil", "datetime"] let g:pymode_rope_confirm_saving = 1 let g:pymode_rope_vim_completion = 1 let g:pymode_rope_guess_project = 1 let g:pymode_rope_goto_def_newwin = 0 let g:pymode_rope_always_show_complete_menu = 0 " }}} " Scratch {{{ command! ScratchToggle call ScratchToggle() function! ScratchToggle() if exists("w:is_scratch_window") unlet w:is_scratch_window exec "q" else exec "normal! :Sscratch\\L" let w:is_scratch_window = 1 endif endfunction nnoremap :ScratchToggle " }}} " Secure Modelines {{{ let g:secure_modelines_allowed_items = [ \ "textwidth", "tw", \ "foldmethod", "fdm", \ "foldnextmax", "fdn", \ ] " }}} " Sparkup {{{ let g:sparkupNextMapping = '' "}}} " Supertab {{{ let g:SuperTabDefaultCompletionType = "" let g:SuperTabLongestHighlight = 1 let g:SuperTabCrMapping = 1 "}}} " Syntastic {{{ let g:syntastic_enable_signs = 1 let g:syntastic_check_on_open = 0 let g:syntastic_check_on_wq = 0 let g:syntastic_auto_jump = 0 let g:syntastic_java_checker = 'javac' let g:syntastic_mode_map = { \ "mode": "active", \ "active_filetypes": [], \ "passive_filetypes": ['java', 'html', 'rst'] \ } let g:syntastic_stl_format = '[%E{%e Errors}%B{, }%W{%w Warnings}]' let g:syntastic_jsl_conf = '$HOME/.vim/jsl.conf' let g:syntastic_scala_checkers = ['fsc'] nnoremap C :SyntasticCheck " }}} " Splice {{{ let g:splice_prefix = "-" let g:splice_initial_mode = "grid" let g:splice_initial_layout_grid = 0 let g:splice_initial_layout_loupe = 0 let g:splice_initial_layout_compare = 0 let g:splice_initial_layout_path = 0 let g:splice_initial_diff_grid = 1 let g:splice_initial_diff_loupe = 0 let g:splice_initial_diff_compare = 1 let g:splice_initial_diff_path = 0 let g:splice_initial_scrollbind_grid = 0 let g:splice_initial_scrollbind_loupe = 0 let g:splice_initial_scrollbind_compare = 0 let g:splice_initial_scrollbind_path = 0 let g:splice_wrap = "nowrap" " }}} " tslime {{{ let g:tslime_ensure_trailing_newlines = 1 let g:tslime_normal_mapping = 'T' let g:tslime_visual_mapping = 't' let g:tslime_vars_mapping = 't' " }}} " YankRing {{{ function! YRRunAfterMaps() " Make Y yank to end of line. nnoremap Y :YRYankCount 'y$' " Fix L and H in operator-pending mode, so yH and such works. omap L YRMapsExpression("", "$") omap H YRMapsExpression("", "^") " Don't clobber the yank register when pasting over text in visual mode. vnoremap p :YRPaste 'p', 'v'gv:YRYankRange 'v' endfunction " }}} " }}} " Text objects ------------------------------------------------------------ {{{ " Shortcut for [] {{{ onoremap ir i[ onoremap ar a[ vnoremap ir i[ vnoremap ar a[ " }}} " Next and Last {{{ " " Motion for "next/last object". "Last" here means "previous", not "final". " Unfortunately the "p" motion was already taken for paragraphs. " " Next acts on the next object of the given type, last acts on the previous " object of the given type. These don't necessarily have to be in the current " line. " " Currently works for (, [, {, and their shortcuts b, r, B. " " Next kind of works for ' and " as long as there are no escaped versions of " them in the string (TODO: fix that). Last is currently broken for quotes " (TODO: fix that). " " Some examples (C marks cursor positions, V means visually selected): " " din' -> delete in next single quotes foo = bar('spam') " C " foo = bar('') " C " " canb -> change around next parens foo = bar('spam') " C " foo = bar " C " " vin" -> select inside next double quotes print "hello ", name " C " print "hello ", name " VVVVVV onoremap an :call NextTextObject('a', '/') xnoremap an :call NextTextObject('a', '/') onoremap in :call NextTextObject('i', '/') xnoremap in :call NextTextObject('i', '/') onoremap al :call NextTextObject('a', '?') xnoremap al :call NextTextObject('a', '?') onoremap il :call NextTextObject('i', '?') xnoremap il :call NextTextObject('i', '?') function! s:NextTextObject(motion, dir) let c = nr2char(getchar()) let d = '' if c ==# "b" || c ==# "(" || c ==# ")" let c = "(" elseif c ==# "B" || c ==# "{" || c ==# "}" let c = "{" elseif c ==# "r" || c ==# "[" || c ==# "]" let c = "[" elseif c ==# "'" let c = "'" elseif c ==# '"' let c = '"' else return endif " Find the next opening-whatever. execute "normal! " . a:dir . c . "\" if a:motion ==# 'a' " If we're doing an 'around' method, we just need to select around it " and we can bail out to Vim. execute "normal! va" . c else " Otherwise we're looking at an 'inside' motion. Unfortunately these " get tricky when you're dealing with an empty set of delimiters because " Vim does the wrong thing when you say vi(. let open = '' let close = '' if c ==# "(" let open = "(" let close = ")" elseif c ==# "{" let open = "{" let close = "}" elseif c ==# "[" let open = "\\[" let close = "\\]" elseif c ==# "'" let open = "'" let close = "'" elseif c ==# '"' let open = '"' let close = '"' endif " We'll start at the current delimiter. let start_pos = getpos('.') let start_l = start_pos[1] let start_c = start_pos[2] " Then we'll find it's matching end delimiter. if c ==# "'" || c ==# '"' " searchpairpos() doesn't work for quotes, because fuck me. let end_pos = searchpos(open) else let end_pos = searchpairpos(open, '', close) endif let end_l = end_pos[0] let end_c = end_pos[1] call setpos('.', start_pos) if start_l == end_l && start_c == (end_c - 1) " We're in an empty set of delimiters. We'll append an "x" " character and select that so most Vim commands will do something " sane. v is gonna be weird, and so is y. Oh well. execute "normal! ax\\" execute "normal! vi" . c elseif start_l == end_l && start_c == (end_c - 2) " We're on a set of delimiters that contain a single, non-newline " character. We can just select that and we're done. execute "normal! vi" . c else " Otherwise these delimiters contain something. But we're still not " sure Vim's gonna work, because if they contain nothing but " newlines Vim still does the wrong thing. So we'll manually select " the guts ourselves. let whichwrap = &whichwrap set whichwrap+=h,l execute "normal! va" . c . "hol" let &whichwrap = whichwrap endif endif endfunction " }}} " Numbers {{{ " Motion for numbers. Great for CSS. Lets you do things like this: " " margin-top: 200px; -> daN -> margin-top: px; " ^ ^ " TODO: Handle floats. onoremap N :call NumberTextObject(0) xnoremap N :call NumberTextObject(0) onoremap aN :call NumberTextObject(1) xnoremap aN :call NumberTextObject(1) onoremap iN :call NumberTextObject(1) xnoremap iN :call NumberTextObject(1) function! s:NumberTextObject(whole) let num = '\v[0-9]' " If the current char isn't a number, walk forward. while getline('.')[col('.') - 1] !~# num normal! l endwhile " Now that we're on a number, start selecting it. normal! v " If the char after the cursor is a number, select it. while getline('.')[col('.')] =~# num normal! l endwhile " If we want an entire word, flip the select point and walk. if a:whole normal! o while col('.') > 1 && getline('.')[col('.') - 2] =~# num normal! h endwhile endif endfunction " }}} " }}} " Mini-plugins ------------------------------------------------------------ {{{ " Stuff that should probably be broken out into plugins, but hasn't proved to be " worth the time to do so just yet. " Synstack {{{ " Show the stack of syntax hilighting classes affecting whatever is under the " cursor. function! SynStack() echo join(map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")'), " > ") endfunc nnoremap :call SynStack() " }}} " Diffwhite Toggle {{{ set diffopt-=iwhite let g:diffwhitespaceon = 0 function! ToggleDiffWhitespace() if g:diffwhitespaceon set diffopt-=iwhite let g:diffwhitespaceon = 0 else set diffopt+=iwhite let g:diffwhitespaceon = 1 endif diffupdate endfunc " TODO: Figure out the diffexpr shit necessary to make this buffer-local. " nnoremap W :call ToggleDiffWhitespace() " }}} " Error Toggles {{{ command! ErrorsToggle call ErrorsToggle() function! ErrorsToggle() " {{{ if exists("w:is_error_window") unlet w:is_error_window exec "q" else exec "Errors" lopen let w:is_error_window = 1 endif endfunction " }}} command! -bang -nargs=? QFixToggle call QFixToggle(0) function! QFixToggle(forced) " {{{ if exists("g:qfix_win") && a:forced == 0 cclose unlet g:qfix_win else copen 10 let g:qfix_win = bufnr("$") endif endfunction " }}} nmap :ErrorsToggle nmap :QFixToggle " }}} " Nyan! {{{ function! NyanMe() " {{{ hi NyanFur guifg=#BBBBBB hi NyanPoptartEdge guifg=#ffd0ac hi NyanPoptartFrosting guifg=#fd3699 guibg=#fe98ff hi NyanRainbow1 guifg=#6831f8 hi NyanRainbow2 guifg=#0099fc hi NyanRainbow3 guifg=#3cfa04 hi NyanRainbow4 guifg=#fdfe00 hi NyanRainbow5 guifg=#fc9d00 hi NyanRainbow6 guifg=#fe0000 echohl NyanRainbow1 echon "≈" echohl NyanRainbow2 echon "≋" echohl NyanRainbow3 echon "≈" echohl NyanRainbow4 echon "≋" echohl NyanRainbow5 echon "≈" echohl NyanRainbow6 echon "≋" echohl NyanRainbow1 echon "≈" echohl NyanRainbow2 echon "≋" echohl NyanRainbow3 echon "≈" echohl NyanRainbow4 echon "≋" echohl NyanRainbow5 echon "≈" echohl NyanRainbow6 echon "≋" echohl None echo "" echohl NyanRainbow1 echon "≈" echohl NyanRainbow2 echon "≋" echohl NyanRainbow3 echon "≈" echohl NyanRainbow4 echon "≋" echohl NyanRainbow5 echon "≈" echohl NyanRainbow6 echon "≋" echohl NyanRainbow1 echon "≈" echohl NyanRainbow2 echon "≋" echohl NyanRainbow3 echon "≈" echohl NyanRainbow4 echon "≋" echohl NyanRainbow5 echon "≈" echohl NyanRainbow6 echon "≋" echohl NyanFur echon "╰" echohl NyanPoptartEdge echon "⟨" echohl NyanPoptartFrosting echon "⣮⣯⡿" echohl NyanPoptartEdge echon "⟩" echohl NyanFur echon "⩾^ω^⩽" echohl None echo "" echohl NyanRainbow1 echon "≈" echohl NyanRainbow2 echon "≋" echohl NyanRainbow3 echon "≈" echohl NyanRainbow4 echon "≋" echohl NyanRainbow5 echon "≈" echohl NyanRainbow6 echon "≋" echohl NyanRainbow1 echon "≈" echohl NyanRainbow2 echon "≋" echohl NyanRainbow3 echon "≈" echohl NyanRainbow4 echon "≋" echohl NyanRainbow5 echon "≈" echohl NyanRainbow6 echon "≋" echohl None echon " " echohl NyanFur echon "” ‟" echohl None sleep 1 redraw echo " " echo " " echo "Noms?" redraw endfunction " }}} command! NyanMe call NyanMe() " }}} " Hg {{{ function! s:HgDiff() " {{{ diffthis let fn = expand('%:p') let ft = &ft wincmd v edit __hgdiff_orig__ setlocal buftype=nofile normal ggdG execute "silent r!hg cat --rev . " . fn normal ggdd execute "setlocal ft=" . ft diffthis diffupdate endfunction " }}} command! -nargs=0 HgDiff call s:HgDiff() nnoremap Hd :HgDiff function! s:HgBlame() " {{{ let fn = expand('%:p') wincmd v wincmd h edit __hgblame__ vertical resize 28 setlocal scrollbind winfixwidth nolist nowrap nonumber buftype=nofile ft=none normal ggdG execute "silent r!hg blame -undq " . fn normal ggdd execute ':%s/\v:.*$//' wincmd l setlocal scrollbind syncbind endfunction " }}} command! -nargs=0 HgBlame call s:HgBlame() nnoremap Hb :HgBlame " }}} " J {{{ function! s:JumpTo(dest) call system("tmux split-window -h 'j " . a:dest . "; and myctags &; and vim .'") endfunction command! -nargs=1 J call s:JumpTo() " }}} " Ack motions {{{ " Motions to Ack for things. Works with pretty much everything, including: " " w, W, e, E, b, B, t*, f*, i*, a*, and custom text objects " " Awesome. " " Note: If the text covered by a motion contains a newline it won't work. Ack " searches line-by-line. nnoremap A :set opfunc=AckMotiong@ xnoremap A :call AckMotion(visualmode()) nnoremap :Ack! '\b\b' xnoremap :call AckMotion(visualmode()) function! s:CopyMotionForType(type) if a:type ==# 'v' silent execute "normal! `<" . a:type . "`>y" elseif a:type ==# 'char' silent execute "normal! `[v`]y" endif endfunction function! s:AckMotion(type) abort let reg_save = @@ call s:CopyMotionForType(a:type) execute "normal! :Ack! --literal " . shellescape(@@) . "\" let @@ = reg_save endfunction " }}} " Indent Guides {{{ let g:indentguides_state = 0 function! IndentGuides() " {{{ if g:indentguides_state let g:indentguides_state = 0 2match None else let g:indentguides_state = 1 execute '2match IndentGuides /\%(\_^\s*\)\@<=\%(\%'.(0*&sw+1).'v\|\%'.(1*&sw+1).'v\|\%'.(2*&sw+1).'v\|\%'.(3*&sw+1).'v\|\%'.(4*&sw+1).'v\|\%'.(5*&sw+1).'v\|\%'.(6*&sw+1).'v\|\%'.(7*&sw+1).'v\)\s/' endif endfunction " }}} hi def IndentGuides guibg=#303030 ctermbg=234 nnoremap I :call IndentGuides() " }}} " Block Colors {{{ let g:blockcolor_state = 0 function! BlockColor() " {{{ if g:blockcolor_state let g:blockcolor_state = 0 call matchdelete(77881) call matchdelete(77882) call matchdelete(77883) call matchdelete(77884) call matchdelete(77885) call matchdelete(77886) else let g:blockcolor_state = 1 call matchadd("BlockColor1", '^ \{4}.*', 1, 77881) call matchadd("BlockColor2", '^ \{8}.*', 2, 77882) call matchadd("BlockColor3", '^ \{12}.*', 3, 77883) call matchadd("BlockColor4", '^ \{16}.*', 4, 77884) call matchadd("BlockColor5", '^ \{20}.*', 5, 77885) call matchadd("BlockColor6", '^ \{24}.*', 6, 77886) endif endfunction " }}} " Default highlights {{{ hi def BlockColor1 guibg=#222222 ctermbg=234 hi def BlockColor2 guibg=#2a2a2a ctermbg=235 hi def BlockColor3 guibg=#353535 ctermbg=236 hi def BlockColor4 guibg=#3d3d3d ctermbg=237 hi def BlockColor5 guibg=#444444 ctermbg=238 hi def BlockColor6 guibg=#4a4a4a ctermbg=239 " }}} nnoremap B :call BlockColor() " }}} " Pulse Line {{{ function! s:Pulse() " {{{ redir => old_hi silent execute 'hi CursorLine' redir END let old_hi = split(old_hi, '\n')[0] let old_hi = substitute(old_hi, 'xxx', '', '') let steps = 8 let width = 1 let start = width let end = steps * width let color = 233 for i in range(start, end, width) execute "hi CursorLine ctermbg=" . (color + i) redraw sleep 6m endfor for i in range(end, start, -1 * width) execute "hi CursorLine ctermbg=" . (color + i) redraw sleep 6m endfor execute 'hi ' . old_hi endfunction " }}} command! -nargs=0 Pulse call s:Pulse() " }}} " Highlight Word {{{ " " This mini-plugin provides a few mappings for highlighting words temporarily. " " Sometimes you're looking at a hairy piece of code and would like a certain " word or two to stand out temporarily. You can search for it, but that only " gives you one color of highlighting. Now you can use N where N is " a number from 1-6 to highlight the current word in a specific color. function! HiInterestingWord(n) " {{{ " Save our location. normal! mz " Yank the current word into the z register. normal! "zyiw " Calculate an arbitrary match ID. Hopefully nothing else is using it. let mid = 86750 + a:n " Clear existing matches, but don't worry if they don't exist. silent! call matchdelete(mid) " Construct a literal pattern that has to match at boundaries. let pat = '\V\<' . escape(@z, '\') . '\>' " Actually match the words. call matchadd("InterestingWord" . a:n, pat, 1, mid) " Move back to our original location. normal! `z endfunction " }}} " Mappings {{{ nnoremap 1 :call HiInterestingWord(1) nnoremap 2 :call HiInterestingWord(2) nnoremap 3 :call HiInterestingWord(3) nnoremap 4 :call HiInterestingWord(4) nnoremap 5 :call HiInterestingWord(5) nnoremap 6 :call HiInterestingWord(6) " }}} " Default Highlights {{{ hi def InterestingWord1 guifg=#000000 ctermfg=16 guibg=#ffa724 ctermbg=214 hi def InterestingWord2 guifg=#000000 ctermfg=16 guibg=#aeee00 ctermbg=154 hi def InterestingWord3 guifg=#000000 ctermfg=16 guibg=#8cffba ctermbg=121 hi def InterestingWord4 guifg=#000000 ctermfg=16 guibg=#b88853 ctermbg=137 hi def InterestingWord5 guifg=#000000 ctermfg=16 guibg=#ff9eb8 ctermbg=211 hi def InterestingWord6 guifg=#000000 ctermfg=16 guibg=#ff2c4b ctermbg=195 " }}} " }}} " MarkChanged {{{ sign define line_changed text=+ texthl=DiffAdded function! MarkChanged(s, e) for i in range(a:s, a:e) exe ":sign place " . i . " line=" . i . " name=line_changed file=" . expand("%:p") endfor endfunction function! MarkUnchanged(s, e) for i in range(a:s, a:e) call cursor(i, 0) silent! sign unplace endfor endfunction command! -range MarkChanged call MarkChanged(, ) command! -range MarkUnchanged call MarkUnchanged(, ) " nnoremap m :MarkChanged " vnoremap m :MarkChanged " nnoremap M :MarkUnchanged " vnoremap M :MarkUnchanged " }}} " MS to UTC {{{ function! MS2UTC(ms) let seconds = strpart(a:ms, 0, strlen(a:ms) - 3) return substitute(system("date -ur " . seconds), "\n\n*", "", "") endfunction function! MS2UTCWord() return MS2UTC(expand("")) endfunction nnoremap U :echo MS2UTCWord() " }}} " }}} " Environments (GUI/Console) ---------------------------------------------- {{{ if has('gui_running') " GUI Vim set guifont=Menlo\ Regular\ for\ Powerline:h12 " Remove all the UI cruft set go-=T set go-=l set go-=L set go-=r set go-=R highlight SpellBad term=underline gui=undercurl guisp=Orange " Different cursors for different modes. set guicursor=n-c:block-Cursor-blinkon0 set guicursor+=v:block-vCursor-blinkon0 set guicursor+=i-ci:ver20-iCursor if has("gui_macvim") " Full screen means FULL screen set fuoptions=maxvert,maxhorz " Use the normal HIG movements, except for M-Up/Down let macvim_skip_cmd_opt_movement = 1 no no! no no! no no! no no! no ino imap { no ino imap } imap inoremap my0c`y else " Non-MacVim GUI, like Gvim end else " Console Vim " For me, this means iTerm2, possibly through tmux " Mouse support set mouse=a endif " }}}