" Title: vimrc " Author: Thiago de Arruda (github.com/tarruda) " Description: " This file initializes my vim customizations/addons. It was tested on vim " 7.3 compiled with most features. A lot here was taken from this vimrc: " https://bitbucket.org/sjl/dotfiles/src/tip/vim/vimrc " Basic initialization {{{ " if !exists('g:vimrc_done_basic_init') let g:is_windows = has('win32') || has('win64') " Little hack to set the $MYVIMRC from the $VIMINIT in the case it was used to " initialize vim. let s:default_vimrc = 1 if empty($MYVIMRC) let $MYVIMRC = substitute($VIMINIT, "^source ", "", "g") let s:default_vimrc = 0 endif " Extract the directory from $MYVIMRC if g:is_windows let g:rc_dir = strpart($MYVIMRC, 0, strridx($MYVIMRC, '\')) else let g:rc_dir = strpart($MYVIMRC, 0, strridx($MYVIMRC, '/')) endif if s:default_vimrc " Set .vim as the rc_dir let g:rc_dir = g:rc_dir.'/.vim' endif let $RCDIR = g:rc_dir let g:vam_plugins_dir = g:rc_dir.'/addons' let &runtimepath = g:rc_dir.','.g:vam_plugins_dir.'/vim-addon-manager,'.g:vam_plugins_dir.'/eclim,'.$VIMRUNTIME let g:has_python = has('python') || has('python3') endif " }}} " Global settings {{{ " let $PAGER='' " use vim to read man pages set nocompatible let mapleader = "," set backspace=indent,eol,start " backspace over everything in insert mode set nobackup " no need for backup files(use undo files instead) set undofile " create '..un~' for persiting undo history set dir=.,/tmp " swap files storage, first try in the cwd then in /tmp set undodir=. " undo files storage, only allow the same directory set history=500 " 500 lines of command-line history set ruler " display cursor position at bottom set mouse=a " enable terminal mouse extensions if &term =~ 'tmux' " requires my custom terminfo file set ttymouse=xterm2 " integrate mouse extensions with tmux set ttyfast " normally this is only set for certain known terminals endi set noerrorbells visualbell t_vb= " disable annoying terminal sounds set encoding=utf-8 " universal text encoding, compatible with ascii set list if has('win32unix') && ! has('gui_running') " cygwin on terminal " cygwin's urxvt seems to have trouble displaying some unicode chars set listchars=tab:▸\ , else set listchars=tab:▸\ ,extends:❯,precedes:❮ " ,eol:¬ set showbreak=↪ set fillchars=diff:⣿,vert:│ endif set showcmd " display incomplete commands set completeopt=menu,menuone,longest " disable preview scratch window set complete=.,w,b,u,t " h: 'complete' set pumheight=15 " limit completion menu height set nonumber " don't display line numbers on the left set relativenumber " shows relative line numbers for easy motions set splitbelow " put horizontal splits below set splitright " put vertical splits to the right set expandtab " expand tabs into spaces set softtabstop=2 " number of spaces used with tab/bs set tabstop=2 " display tabs with the width of two spaces set shiftwidth=2 " indent with two spaces set modelines=0 " running code in comments is not cool set ignorecase " ignore case when searching set smartcase " disable 'ignorecase' if search pattern has uppercase characters set incsearch " highlight matches while typing search pattern set hlsearch " highlight previous search matches set showmatch " briefly jump to the matching bracket on insert set matchtime=2 " time in decisecons to jump back from matching bracket set textwidth=80 " number of character allowed in a line set wrap " automatically wrap text when 'textwidth' is reached set foldmethod=indent " by default, fold using indentation set nofoldenable " don't fold by default set foldlevel=0 " if fold everything if 'foldenable' is set set foldnestmax=10 " maximum fold depth set synmaxcol=500 " maximum length to apply syntax highlighting set timeout " enable timeout of key codes and mappings(the default) set timeoutlen=3000 " big timeout for key sequences set ttimeoutlen=10 " small timeout for key sequences since these will be normally scripted set clipboard= " disable automatic clipboard integration syntax on " enable syntax highlighting filetype plugin indent on " enable file-specific plugins/settings set backupskip=/tmp/*,/private/tmp/* " make it possible to use vim to edit crontab augroup global_settings au! au VimResized * :wincmd = " resize windows when vim is resized " return to the same line when file is reopened au BufReadPost * \ if line("'\"") > 0 && line("'\"") <= line("$") | \ execute 'normal! g`"zvzz' | \ endif augroup END " if available, store temporary files in shared memory if isdirectory('/run/shm') let $TMPDIR = '/run/shm' elseif isdirectory('/dev/shm') let $TMPDIR = '/dev/shm' endif " }}} " Terminal keycode sequences {{{ :set =OP if ! has('gui_running') " this is used to represent ctrl+tab in terminal vim :set =[34~ endif if &term == 'tmux' :set = :set = :set = :set = :set =y :set =d " Prefix used by tmux to send 'special commands' to vim. I use this so there's " no possibility of tmux accidentally hitting my own mappings. Think of it as " a namespace used for tmux-related commands :set =tmux elseif &term =~ 'rxvt-unicode' || &term =~ 'xterm' " with urxvt configured to use xterm control/alt sequences " this should normalize vim/gvim mappings :set =k :set =j :set =l :set =h :set =p :set =y :set =d endif " }}} " Custom commands {{{ " Allows saving files which needs root permission with ':w!!'. This uses one of " the forms of the ':w' command, which instead of writing to a file, takes all " lines in a range(or the whole buffer if not range is specified) and pipes as " standard input for the command after '!'. In this case 'tee' will redirect its " standard input(the entire buffer) to the file being edited(%) cnoremap w!! w !sudo tee % >/dev/null " Convenient command to see the difference between the current buffer and the " file it was loaded from, thus the changes you made. Only define it when not " defined already. command! DiffOrig vert new | set bt=nofile | r # | 0d_ | diffthis \ | wincmd p | diffthis command! -nargs=? -complete=help Help call OpenHelpInCurrentWindow() command! -nargs=? -complete=customlist,ScratchPadComplete ScratchPad call OpenScratchPad() " }}} " Utility functions {{{ " Restore cursor position, window position, and last search after running a " command. " from: http://stackoverflow.com/questions/12374200/using-uncrustify-with-vim function! Preserve(command) " Save the last search. let search = @/ " Save the current cursor position. let cursor_position = getpos('.') " Save the current window position. normal! H let window_position = getpos('.') call setpos('.', cursor_position) " Execute the command. execute a:command " Restore the last search. let @/ = search " Restore the previous window position. call setpos('.', window_position) normal! zt " Restore the previous cursor position. call setpos('.', cursor_position) endfunction " Specify path to your Uncrustify configuration file. let g:uncrustify_cfg_file_path = \ shellescape(fnamemodify('~/.uncrustify.cfg', ':p')) " Don't forget to add Uncrustify executable to $PATH (on Unix) or " %PATH% (on Windows) for this command to work. function! Uncrustify(language) call Preserve(':silent %!uncrustify' \ . ' -q ' \ . ' -l ' . a:language \ . ' -c ' . g:uncrustify_cfg_file_path) endfunction function! OpenHelpInCurrentWindow(topic) view $VIMRUNTIME/doc/help.txt setl filetype=help setl buftype=help setl nomodifiable exe 'keepjumps help ' . a:topic endfunction " ScratchPad {{{ augroup scratchpad au! au BufNewFile,BufRead .scratchpads/scratchpad.* call ScratchPadLoad() augroup END function! ScratchPadSave() let ftype = matchstr(expand('%'), 'scratchpad\.\zs\(.\+\)$') if ftype == '' return endif write endfunction function! ScratchPadLoad() nnoremap q :w:close setlocal bufhidden=hide buflisted noswapfile endfunction function! OpenScratchPad(ftype) if a:0 > 0 let ftype = a:ftype else let pads = split(globpath('.scratchpads', 'scratchpad.*'), '\n') if len(pads) > 0 let ftype = matchstr(pads[0], 'scratchpad\.\zs\(.\+\)$') else let ftype = expand('%:e') endif endif if ftype == '' echoerr 'Scratchpad need a filetype' return endif let scratchpad_name = '.scratchpads/scratchpad.' . ftype let scr_bufnum = bufnr(scratchpad_name) if scr_bufnum == -1 " open the scratchpad exe "new " . scratchpad_name let dir = expand('%:p:h') if !isdirectory(dir) call mkdir(dir) endif else " Scratch buffer is already created. Check whether it is open " in one of the windows let scr_winnum = bufwinnr(scr_bufnum) if scr_winnum != -1 " Jump to the window which has the scratchpad if we are not " already in that window if winnr() != scr_winnum exe scr_winnum . "wincmd w" endif else exe "split +buffer" . scr_bufnum endif endif endfunction " }}} function! GetVisualSelection() let [lnum1, col1] = getpos("'<")[1:2] let [lnum2, col2] = getpos("'>")[1:2] let lines = getline(lnum1, lnum2) let lines[-1] = lines[-1][: col2 - 2] let lines[0] = lines[0][col1 - 1:] return join(lines, "\n") endfunction if &term == 'tmux' " tranparent window/pane movement function! TmuxMove(direction) " Check if we are currently focusing on a edge window. " To achieve that, move to/from the requested window and " see if the window number changed let oldw = winnr() silent! exe 'wincmd ' . a:direction let neww = winnr() silent! exe oldw . 'wincmd' if oldw == neww " The focused window is at an edge, so ask tmux to switch panes if a:direction == 'j' call system("tmux select-pane -D") elseif a:direction == 'k' call system("tmux select-pane -U") elseif a:direction == 'h' call system("tmux select-pane -L") elseif a:direction == 'l' call system("tmux select-pane -R") endif end endfunction if executable('xclip') && $DISPLAY != '' " use the x11 clipboard as the main storage for shared yank data " tmux should also be configured to use it function! TmuxYank() call system('xclip -i -selection clipboard', @t) endfunction function! TmuxPaste() let @t = system('xclip -o -selection clipboard') endfunction else function! TmuxYank() " FIXME for some reason, the form 'tmux load-buffer -' will hang when used " with 'system()' which takes a second argument as stdin, so we have to " use a temporary file to load data into tmux. Fixing this it is more a " matter of aesthetics than peformance, because vim will also create a " temporary file instead of piping the data directly. let tmpfile = tempname() call writefile(split(@t, '\n'), tmpfile, 'b') call system('cat '.shellescape(tmpfile).' | tmux load-buffer -') call delete(tmpfile) endfunction function! TmuxPaste() let @t = system('tmux show-buffer') endfunction endif endif " }}} " Mappings {{{ " Quickly open/close quickfix and location list, based on " github:Valloric/ListToogle augroup quick_loc_list au! BufWinEnter quickfix nnoremap q :cclose:lclose augroup END nnoremap q :botright copen 10 nnoremap l :botright lopen 10 nmap T @t nnoremap :m .+1== nnoremap :m .-2== " Quickly open a scratchpad nnoremap sp :ScratchPad " Move selections vnoremap :m '>+1gv=gv vnoremap :m '<-2gv=gv " Remap the help key inoremap :Help nnoremap :Help vnoremap :Help " search/replace the word under the cursor nnoremap z :let @z = expand("")q:i%s/\C\v<"zpa>//ghi " Quickly toggle spell on/off nnoremap s :set spell! " Clear search highlight with ,c nnoremap c :noh " Capitalize the first word of every sentence in a selection and format it. " Useful for quickly formatting comments. The capitalize part was taken from: " http://societyserver.org/mbaehr/vim-tips--capitalize-the-first-word-of-every-sentence vnoremap f :s/\v(\w)(\_[^.?!:;]*)/\u\1\2/g:nohgvgq " quickly edit vimrc nnoremap e :e $MYVIMRC " quickly reload vimrc nnoremap r :source $MYVIMRC:e if &term == 'tmux' " tmux will handle the actual mappings so we just nnoremap move-down :silent call TmuxMove('j') nnoremap move-up :silent call TmuxMove('k') nnoremap move-left :silent call TmuxMove('h') nnoremap move-right :silent call TmuxMove('l') inoremap move-down :silent call TmuxMove('j') inoremap move-up :silent call TmuxMove('k') inoremap move-left :silent call TmuxMove('h') inoremap move-right :silent call TmuxMove('l') vnoremap move-down :silent call TmuxMove('j') vnoremap move-up :silent call TmuxMove('k') vnoremap move-left :silent call TmuxMove('h') vnoremap move-right :silent call TmuxMove('l') nnoremap paste-tmux :call TmuxPaste()"tp inoremap paste-tmux :call TmuxPaste()"tp vnoremap paste-tmux d:call TmuxPaste()h"tp vnoremap "ty:call TmuxYank() vnoremap "td:call TmuxYank() else nnoremap :wincmd j nnoremap :wincmd k nnoremap :wincmd h nnoremap :wincmd l nnoremap :wincmd j nnoremap :wincmd k nnoremap :wincmd h nnoremap :wincmd l inoremap :wincmd j inoremap :wincmd k inoremap :wincmd h inoremap :wincmd l inoremap :wincmd j inoremap :wincmd k inoremap :wincmd h inoremap :wincmd l vnoremap :wincmd j vnoremap :wincmd k vnoremap :wincmd h vnoremap :wincmd l vnoremap :wincmd j vnoremap :wincmd k vnoremap :wincmd h vnoremap :wincmd l nnoremap "+p inoremap "+p vnoremap "+p vnoremap "+y vnoremap "+d endif " }}} " Filetype settings {{{ augroup filetype_settings au! " Filetype detection {{{ " my vimrc may not have the usual path au BufNewFile,BufRead $MYVIMRC setl filetype=vim au BufNewFile,BufRead *.vimp setl filetype=vim " vimperator files " tmux rc file au BufNewFile,BufRead .tmux.conf,tmuxrc,site-tmuxrc setl filetype=tmux " html with mustaches au BufNewFile,BufRead *.html.mustache,*.html.handlebars,*.html.hbs,*.html.hogan,*.html.hulk setl filetype=html.mustache " extra zsh files without extensions au BufNewFile,BufRead $ZDOTDIR/functions/**/* setl filetype=zsh au BufNewFile,BufRead $ZDOTDIR/completion-functions/* setl filetype=zsh au BufNewFile,BufRead $ZDOTDIR/plugins/**/functions/* setl filetype=zsh " }}} " Vim {{{ au FileType vim \ setl foldmethod=marker \ | setl foldenable " }}} " C/C++ {{{ au FileType c,cpp \ nnoremap ff :call Uncrustify('c') \ | setl commentstring=//%s " }}} " Moonscript {{{ au FileType moon \ setl commentstring=--%s " }}} " Zsh/sh {{{ au FileType sh,bash,zsh setl noexpandtab au FileType zsh \ runtime! indent/sh.vim \ | setl foldmethod=marker \ | setl foldenable " \ | setl listchars=tab:\ \ ,eol:¬,extends:❯,precedes:❮ " }}} " Haskell {{{ au FileType haskell \ setl softtabstop=4 \ | setl shiftwidth=4 \ | setl textwidth=75 \ | nnoremap h :Hoogle " }}} " Nasm {{{ au FileType nasm \ setl softtabstop=4 \ | setl shiftwidth=4 \ | setl textwidth=150 " }}} " Python {{{ au FileType python \ setl softtabstop=4 \ | setl shiftwidth=4 \ | setl textwidth=79 " }}} " Muttrc {{{ au FileType muttrc \ setl foldmethod=marker \ | setl foldenable " }}} " Mail {{{ au FileType mail \ setl foldmethod=marker \ | setl foldenable \ | setl omnifunc=CompleteGoogleContact " }}} " Mail {{{ au FileType man \ setl foldmethod=indent \ | setl foldenable \ | setl foldnestmax=1 " }}} augroup END " }}} " Appearance {{{ " if has('gui_running') " gvim colorscheme molokai if g:is_windows set guifont=Ubuntu\ Mono:h16 elseif has('win32unix') " cygwin set guifont=Consolas\ 16 else set guifont=Ubuntu\ Mono\ 16,Inconsolata\ 16,Monospace\ 14 endif set guioptions= else if &term =~ 'tmux' || &term =~ 'rxvt-unicode-256color' \ || &term =~ 'xterm-256color' colorscheme twilight-term256 endif if &term =~ 'tmux' || &term =~ 'rxvt-unicode-256color' \ || &term =~ 'xterm-256color-italic' " for tmux, this will only work if the client terminal supports italic " escape sequences highlight Comment cterm=italic endif endif " }}} " Addons {{{ function! LoadAddons() let s:vim_addons = [] " Vim-Dispatch {{{ " call add(s:vim_addons, 'github:tpope/vim-dispatch.git') " }}} " Slimux {{{ if $TMUX != '' call add(s:vim_addons, 'github:epeli/slimux') nnoremap :SlimuxSendKeysLast nnoremap :SlimuxREPLSendLine inoremap :SlimuxREPLSendLinei vnoremap :SlimuxREPLSendSelection nnoremap ggvG$:SlimuxREPLSendSelection endif " }}} " Vimproc {{{ call add(s:vim_addons, 'github:Shougo/vimproc.vim') " }}} " CtrlP {{{ call add(s:vim_addons, 'github:kien/ctrlp.vim') set wildignore+=*.o,*.so,*.dll,*.exe,*.bak,*.swp,*.class,*.pyc,*.pyd,*.pyo,*~ set wildignore+=*.zip,*.tgz,*.gz,*.bz2,*.lz,*.rar,*.7z,*.jar let g:ctrlp_custom_ignore = { \ 'dir': '\v[\/](\.(git|hg|svn|bzr)|node_modules)$', \ } let g:ctrlp_extensions = ['tag'] let g:ctrlp_cmd = 'Ctrlp' fun! s:search() SourceLocalVimrcOnce CtrlP endf command! Ctrlp call s:search() nnoremap p :CtrlPTag " }}} " Syntastic {{{ let g:syntastic_error_symbol = '✗' let g:syntastic_warning_symbol = '⚠' let g:syntastic_always_populate_loc_list = 1 let g:syntastic_coffee_checkers=['coffee'] let g:syntastic_haskell_checkers=['ghc_mod', 'hlint'] let g:syntastic_python_checkers = ['pylint'] let g:syntastic_scala_checkers = [] let g:syntastic_ignore_files=['\.scratchpads/scratchpad\.\.*'] call add(s:vim_addons, 'github:scrooloose/syntastic') " }}} " Lua {{{ call add(s:vim_addons, 'github:leafo/moonscript-vim') " }}} " UltiSnips {{{ if g:has_python let g:UltiSnipsEditSplit = 'normal' let g:UltiSnipsSnippetsDir = g:rc_dir . '/UltiSnips' let g:UltiSnipsExpandTrigger="" let g:UltiSnipsJumpForwardTrigger="" let g:UltiSnipsJumpBackwardTrigger="" let g:UltiSnipsListSnippets="" call add(s:vim_addons, 'github:SirVer/ultisnips') endif " }}} " YouCompleteMe {{{ if g:has_python call add(s:vim_addons, 'github:Valloric/YouCompleteMe') au FileType c,cpp nnoremap :YcmCompleter GoToDefinitionElseDeclaration endif " }}} " NERDTree {{{ call add(s:vim_addons, 'github:scrooloose/nerdtree') " close VIM if NERDTree is the only buffer left autocmd BufEnter * if (winnr("$") == 1 && exists("b:NERDTreeType") && b:NERDTreeType == "primary") | q | endif " toggle NERDTree nnoremap :NERDTreeToggle " }}} " Gundo {{{ if g:has_python call add(s:vim_addons, 'github:sjl/gundo.vim.git') nnoremap u :GundoToggle endif " }}} " Typescript-vim {{{ call add(s:vim_addons, 'github:leafgarland/typescript-vim') setl textwidth=80 setl shiftwidth=2 setl expandtab " }}} " Haskell {{{ let g:haskell_autotags = 1 let g:hoogle_search_jump_back = 0 let g:hoogle_search_count = 30 let g:haskell_tags_generator = 'fast-tags' call add(s:vim_addons, 'github:dag/vim2hs') call add(s:vim_addons, 'github:eagletmt/ghcmod-vim') call add(s:vim_addons, 'github:Twinside/vim-hoogle') " }}} " Project-local vimrc {{{ call add(s:vim_addons, 'github:MarcWeber/vim-addon-local-vimrc') let g:local_vimrc = { \ 'names': ['.lvimrc'], \ 'hash_fun': 'LVRHashOfFile' \ } " }}} " gnupg {{{ let g:GPGPreferSymmetric = 1 call add(s:vim_addons, 'github:jamessan/vim-gnupg.git') " }}} " Omnisharp {{{ if g:has_python let g:Omnisharp_stop_server = 0 call add(s:vim_addons, 'github:nosami/Omnisharp.git') endif " }}} " Fugitive {{{ nnoremap gs :Gstatus nnoremap gd :Gdiff nnoremap gb :Gblame nnoremap gw :Gwrite nnoremap gr :Gread nnoremap dp :diffput:diffupdate vnoremap dp :diffput:diffupdate nnoremap dg :diffget:diffupdate vnoremap dg :diffget:diffupdate call add(s:vim_addons, 'github:tpope/vim-fugitive') " }}} " Other {{{ call add(s:vim_addons, 'github:Raimondi/delimitMate') " autoclose brackets,quotes... call add(s:vim_addons, 'github:tpope/vim-tbone') call add(s:vim_addons, 'github:tpope/vim-unimpaired') call add(s:vim_addons, 'github:plasticboy/vim-markdown') call add(s:vim_addons, 'github:tpope/vim-repeat') call add(s:vim_addons, 'github:tpope/vim-surround') call add(s:vim_addons, 'github:tpope/vim-commentary') call add(s:vim_addons, 'github:juvenn/mustache.vim') call add(s:vim_addons, 'github:pangloss/vim-javascript') call add(s:vim_addons, 'github:kchmck/vim-coffee-script') call add(s:vim_addons, 'github:digitaltoad/vim-jade.git') call add(s:vim_addons, 'github:kelan/gyp.vim') call add(s:vim_addons, 'github:groenewege/vim-less') call add(s:vim_addons, 'github:danro/rename.vim') call add(s:vim_addons, 'github:mattn/webapi-vim') call add(s:vim_addons, 'github:mattn/gist-vim') call add(s:vim_addons, 'github:godlygeek/csapprox') call add(s:vim_addons, 'github:godlygeek/tabular.git') call add(s:vim_addons, 'github:mileszs/ack.vim') call add(s:vim_addons, 'github:PProvost/vim-ps1.git') call add(s:vim_addons, 'github:alunny/pegjs-vim.git') call add(s:vim_addons, 'github:vim-scripts/Decho.git') call add(s:vim_addons, 'github:Valloric/python-indent.git') " }}} " load 'after' directory let &runtimepath = &runtimepath.','.g:rc_dir.'/after' " }}} " Package management(vim-addon-manager setup) {{{ let g:vim_addon_manager = {} let g:vim_addon_manager.auto_install = 1 let g:vim_addon_manager.log_to_buf = 1 let g:vim_addon_manager.shell_commands_run_method = 'system' let g:vim_addon_manager.plugin_root_dir = g:vam_plugins_dir if !isdirectory(g:vim_addon_manager.plugin_root_dir) call mkdir(g:vim_addon_manager.plugin_root_dir, "p") endif if !isdirectory(g:vim_addon_manager.plugin_root_dir.'/vim-addon-manager/autoload') execute '!git clone git://github.com/MarcWeber/vim-addon-manager ' \ shellescape(g:vim_addon_manager.plugin_root_dir.'/vim-addon-manager', 1) endif let g:vim_addon_manager.scms = {'scms': {}} if executable('git') fun! VamGitClone(repository, targetDir) return vam#utils#RunShell('git clone $.url $p', a:repository, a:targetDir) endfun let g:vim_addon_manager.scms.git = {'clone': ['VamGitClone']} else let g:vim_addon_manager.drop_git_sources = 1 endif call vam#ActivateAddons(s:vim_addons) let g:vimrc_done_basic_init = 1 endfunction if !exists('g:vimrc_done_basic_init') && !exists('g:disable_addons') call LoadAddons() endif " }}}