Skip to content
Switch branches/tags
Go to file
Cannot retrieve contributors at this time
1344 lines (1130 sloc) 43.9 KB
" If there is a global vimrc, first read it. This is used on Debian-based
" distros that have a global vimrc. The filepath for addons is specified in
" this global file. Addons are then enabled and disabled with the
" vim-addon-manager command. This global file resets some of my settings
" below, so this needs to be done before anything else is done.
if filereadable("/etc/vim/vimrc") " debian
source /etc/vim/vimrc
if filereadable("/etc/vimrc") " arch linux
" source /etc/vimrc
set nocompatible " Explicitly turn off compatibility mode
filetype off
" This has to come first because it resets all highlighting.
set background=dark
colorscheme darkblue
"colorscheme default
"colorscheme delek
"colorscheme desert
"colorscheme torte
" Set my leader key to be space instead of \, and
" set my local leader key to be return.
" This needs to be set as soon as possible because
" things mapped with <Leader> are mapped with the
" current leader and don't get changed to be a new
" leader when you set a new leader. So we need to
" set this as soon as possible so that the leader
" gets mapped correctly when we are setting mappings
" that use the leader.
let mapleader = " "
let maplocalleader = "\r"
" load vundles if we have any
if isdirectory(expand("~/.vim/bundle/vundle/.git"))
set runtimepath+=~/.vim/bundle/vundle/
call vundle#rc()
" Vundle
" Brief help
" :BundleList - list configured bundles
" :BundleInstall(!) - install (update) bundles
" :BundleSearch(!) foo - search (or refresh cache first) for foo
" :BundleClean(!) - confirm (or auto-approve) removal of unused bundles
" see :h vundle for more details or wiki for FAQ
" These are the types of repos you add with Vundle:
" (1) original repos on GitHub
"Bundle 'tpope/vim-rails.git'
" (2) vim-scripts repos
"Bundle 'FuzzyFinder'
" (3) non-GitHub repos
"Bundle 'git://'
" (4) Git repos on your local machine (i.e. when working on your own plugin)
"Bundle 'file:///Users/gmarik/path/to/plugin'
Bundle 'gmarik/vundle'
" Syntasic
" :help syntastic to get more help
Bundle 'scrooloose/syntastic'
" To toggle between active/passive type checking we can enable the following key bindings
"map <silent> <Leader>e :Errors<CR>
" Always populate the location list even if :Errors is not run.
" (This is disabled by default to reduce conflicts with other plugins.)
" With this enabled, you can jump to different errors
let g:syntastic_always_populate_loc_list = 1
" don't use the :sign interface to mark errors
"let g:syntastic_enable_signs = 0
" enable debugging
"let g:syntastic_debug = 1
"let g:syntastic_debug_file = "~/syntastic.log"
let g:syntastic_ruby_checkers = ['mri', 'rubocop']
" Ideally I would include 'flow' in this list, but it runs as `flow check`
" instead of just `flow`, so it takes too long to run.
let g:syntastic_javascript_checkers = ['jshint', 'jslint', 'eslint']
" Add merlin to the list of ocaml checkers.
let g:syntastic_ocaml_checkers = ['merlin']
" Haskell syntax highlighting.
" Don't use this because of this annoying bug:
" Bundle 'neovimhaskell/haskell-vim'
" Commands
" :HaskellAddModuleComment " Adds an empty module comment to the top of
" " the file.
" :CabalAddExecutable " Adds an executable section to a cabal file.
" :CabalAddLibrary " Adds a library section to a cabal file.
" :CabalAddFlag " Adds a flag section to a cabal file.
" Haskell syntax highlighting config options:
let g:haskell_enable_quantification = 1 " enable highlighting of forall
"let g:haskell_enable_recursivedo = 1 " enable highlighting of mdo and rec
"let g:haskell_enable_arrowsyntax = 1 " enable highlighting of proc
let g:haskell_enable_pattern_synonyms = 1 " enable highlighting of pattern
let g:haskell_enable_typeroles = 1 " enable highlighting of type roles
"let g:haskell_enable_static_pointers = 1 " enable highlighting of static
" Indentation options:
let g:haskell_indent_after_bare_where = 2 " indentation after a bare where clause
let g:haskell_indent_before_where = 0
let g:haskell_indent_case = 2 " indentation of cases in case statement.
let g:haskell_indent_do = 2 " indentation of things in do statement.
let g:haskell_indent_guard = 2
let g:haskell_indent_if = 2 " indentation of 'then' and 'else' in if statements.
let g:haskell_indent_in = 0 " indentation of 'in' statement.
let g:haskell_indent_let = 4 " indentation of additional lines in let statement.
let g:haskell_indent_where = 2 " indentation of clauses in where statement.
let g:cabal_indent_section = 2 " indentation of sections in cabal file
" Get more commands for doing things to surrounding text.
Bundle 'tpope/vim-surround'
" Get the ability to repeat these surround commands.
Bundle 'tpope/vim-repeat'
" Shows git-diff stuff in the sign column and allows you to stage/revert
" hunks.
" :GitGutterDisable -- disable git gutter
" :GitGutterLineHighlightsToggle -- toggle whether lines are highlighted
" ]c and [c -- jump to next hunk
" <Leader>hs -- stage the hunk
" <Leader>hr -- revert the hunk
" <Leader>hp -- preview the hunk?
" These two are needed if gitgutter becomes slow.
" let g:gitgutter_realtime = 0 -- Make it so that the gutter is not updated in realtime.
" let g:gitgutter_eager = 0 -- Make it so that the gutter is not updated when switching tabs.
Bundle 'airblade/vim-gitgutter'
" Git gutter needs to use raw grep because I have colors turned on in my grep.
let g:gitgutter_escape_grep = 1
" By default, gitgutter make the signcolumn highlighting match the line
" number highlighting. This tells it not to do that.
let g:gitgutter_override_sign_column_highlight = 0
" This adds mappings like the following:
" [a, ]a :previous, :next
" [b, ]b :bprevious, :bnext
" [l, ]l :lprevious, :lnext = Jump to next location in
" the location list. This is
" helpful because syntastic
" adds errors to the location
" list. We can jump to them
" fast with this.
" [q, ]q :cprevious, :cnext
" [<Space>, ]<Space> add a blank line above or below the cursor
Bundle 'tpope/vim-unimpaired'
" This adds the key command 'gcc' to comment out the
" current line. It also adds the command 'gc' in visual
" mode to comment out a block.
" In order to set the comment character for a specific filetype,
" just use an autocommand like the following.
" autocmd FileType apache set commentstring=#\ %s
Bundle 'tpope/vim-commentary'
autocmd FileType puppet set commentstring=#%s
" Ledger syntax for vim
let g:ledger_bin = 'hledger'
Bundle 'ledger/vim-ledger'
autocmd BufEnter .hledger.journal setlocal filetype=ledger
" JSON syntax highlighting
Bundle 'elzr/vim-json'
" Don't let the plugin conceal double quotes
let g:vim_json_syntax_conceal = 0
" Nix
Bundle 'LnL7/vim-nix'
" Idris
Bundle 'idris-hackers/idris-vim'
let g:idris_indent_if = 2
let g:idris_indent_case = 2
let g:idris_indent_let = 4
let g:idris_indent_where = 2
let g:idris_indent_do = 2
let g:idris_indent_rewrite = 2
" PureScript
Bundle 'purescript-contrib/purescript-vim'
let g:purescript_indent_if = 2
let g:purescript_indent_case = 2
let g:purescript_indent_let = 4
let g:purescript_indent_where = 2
let g:purescript_indent_do = 2
let g:purescript_indent_in = 0
autocmd FileType purescript setlocal complete=.,w,b,u,t
" Dhall
Bundle 'vmchale/dhall-vim'
" Rust
Bundle 'rust-lang/rust.vim'
" Typescript
Bundle 'leafgarland/typescript-vim'
""""""""""""" General Settings """"""""""""""
" make sure that ~/.vim is first in the runtimepath. Commands like zg will
" store files by default in the first entry in the runtime path.
" (In this case, it will store the default spell file in a file like
" spell/en.utf-8.spl in the first entry in runtimepath.)
let &runtimepath=("~/.vim/," . &runtimepath)
" I am moving syntax on down to here because putting it above was
" causing puppetlabs/puppet-syntax-vim to not pickup the ftdetect
" settings for puppet files. But this causes all highlights that
" have been defined to be undefined, so all of my highlights have
" to go below.
syntax on
filetype plugin indent on
set fileencodings=utf-8
setglobal fileencoding=utf-8
set encoding=utf-8
" nvim should work without this
if !has('nvim')
set ttymouse=xterm2 " mouse scrolling in vim
set mouse=a
set foldenable
set tabstop=4 " 4-space tab indent width
set shiftwidth=4 " allows you to use < and > to indent/unindent blocks
set softtabstop=4 " see multiple space characters as a tab
set shiftround " Indent to nearest tab stop
set autoindent " carries over previous indent to the next line
set smarttab " A tab infront of a line inserts spaces or tabs according to expandtab
set autoread " when file detected changed outside of Vim, automatically read it again
if version <= 702
set switchbuf=usetab,useopen
set switchbuf=usetab,useopen,newtab
" Tell vim to remember certain things when we exit
" '100 : marks will be remembered for up to 100 previously edited files
" "100 : will save up to 100 lines for each register
" :20 : up to 20 lines of command-line history will be remembered
" % : saves and restores the buffer list
" n... : where to save the viminfo files
" nvim appears to have problems with this
if has('nvim')
set viminfo='100,\"100,:20,%,n~/.neoviminfo
set viminfo='100,\"100,:20,%,n~/.viminfo
set wildmode=list:longest " When autocompleting things, do it like the shell
set wildmenu " Autocomplete things on the menu?
set scrolloff=3 " Scroll when the cursor is 3 lines from top or bottom
set backupdir=~/.vim-tmp,~/.tmp,~/tmp,/var/tmp,/tmp
set directory=~/.vim-tmp,~/.tmp,~/tmp,/var/tmp,/tmp
set ruler " know how far you are in a file
set enc=utf-8
set fenc=utf-8
set backspace=indent,eol,start " make sure backspace works correctly
set guifont=Bitstream\ Vera\ Sans\ Mono\ 14 "font names to be used in gui
" this combination works out well to only apply case to searches
" if there is an uppercase letter in your search string
set ignorecase
set smartcase
" this uses the tags file if it is found anywhere above this directory
" in a file called tags. If it can't find it, it then looks for a file
" called build/tags in any directory above this one
set tags+=tags;$HOME,build/tags;$HOME
" always show a tabline
set showtabline=2
" set the maximum number of files you can open in tabs
if &tabpagemax < 50
set tabpagemax=50
" Use an undo file to save undos through closing file
if version >= 703
set undodir=~/.vim-undo,/var/tmp,/tmp
set undofile
" Show relative line numbers.
set number
set relativenumber
" Only show the status bar when there are two or more windows on the screen.
set laststatus=1
"""""""""""""""" Spelling """""""""""""""""""
" Make sure my spell checking is done in English. (This is the default).
set spelllang=en
" Vim searches for additional spell files in the "spell/" subdirectory of the
" directories in "runtimepath" (usually, "~/.vim/" is on the "runtimepath", so
" it will look in "~/.vim/spell/"). By default, it looks for files of the
" name "LL.EEE.add", where "LL" is the language name (by default "en") and
" where "EEE" is the encoding (by default "utf-8").
" Commands:
" - :setlocal spell Turn on spell checking for
" the current buffer.
" - :set spellfile=~/.vim/myspellfile.utf-8.add Change the spell file to
" a custom spellfile. It
" must end in
" ".{encoding}.add".
" - zg Add word under cursor to spell file as "correct word"
" - zw Add word under cursor to spell file as "incorrect word"
" - zug Undo "zg"
" - zuw Undo "zw"
" - ]s Move to the next misspelled word after the cursor.
" - [s Move to the previous misspelled word before the cursor.
"""""""""""" Highlighting """""""""""""""""""
" NOTE: Highlighting has to be set here. It must come after ":syntax on",
" because ":syntax on" will reset all the highlighting. So I can't put
" any highlighting stuff above in the Vundle settings. It all must go below.
" Give us some additional colors for highlighting haskell code.
" This is for vim2hs.
highlight hsType ctermfg=green
highlight hsStructure ctermfg=darkMagenta
highlight hsExprKeyword ctermfg=3
highlight hsConditional ctermfg=3
"highlight hsDelimiter ctermfg=...
highlight hsOperator ctermfg=blue
" This lets ghcmod give us nice yellow background highlighting when
" looking at an expression's type. This is for the ghcmod plugin.
highlight ghcmodType ctermfg=0 ctermbg=yellow guifg=black guibg=yellow
" highlight tab line differently
highlight TabLine term=bold,reverse cterm=bold ctermfg=black ctermbg=white
highlight TabLineFill term=bold,reverse cterm=bold ctermfg=white ctermbg=white
highlight TabLineSel term=reverse ctermfg=white ctermbg=lightblue
" highlight the status line for the current terminal darker than by default
highlight StatusLine ctermfg=5
" highlight the popup menu a little differently
highlight PmenuSel ctermbg=lightblue
" make sure the normal background is black
highlight Normal guibg=black
" Make sure Special items are not Red. The scala syntax highlighting makes
" objects (strings that start with a captial letter) this "Special" value, and
" it makes them dark red. It makes them look like comments. This makes them
" a brighter red so they stand out from comments.
highlight Special ctermfg=red
" Set highlighting for sign column. This looks like it is the default on
" Arch Linux and is set in the colorscheme file, but for some reason it is
" different on Debian. Set it here so it is the same on both.
highlight SignColumn term=standout ctermfg=14 ctermbg=238
"""""" Settings for specific syntaxes """""""
" settings specifically for java from
let java_highlight_java_lang_ids=1
let java_highlight_all=1
"let java_highlight_functions="style"
"let java_allow_cpp_keywords=1
" make sure xml files are folded
let g:xml_syntax_folding=1
" make sure javascript files are folded
"let g:javaScript_fold=1
" do php folding
let g:php_folding=2
" this is needed for running taglist in screen:
let Tlist_Inc_Winwidth = 0
"""""""""""""""""" Maps """""""""""""""""""""
" use F5 for turning off and on hlsearch,
" in both input mode (imap?) and command mode (map?)
map <F5> :set hlsearch!<CR>
imap <F5> <ESC>:set hlsearch!<CR>a
" use F6 for turning on and off paste mode
map <F6> :set paste!<CR>
imap <F6> <ESC>:set paste!<CR>a
set pastetoggle=<F6>
" use F7 for turning on and off list mode
map <F7> :set list!<CR>
imap <F7> <ESC>:set list!<CR>a
" use F8 for turning on and off spell check mode for the current buffer
map <F8> :setlocal spell!<CR>
imap <F8> <ESC>:setlocal spell!<CR>a
" use <C-h> and <C-l> to go forward and backward in tabs
" nnoremap just makes a normal mode mapping
nnoremap <C-h> gT
nnoremap <C-l> gt
if v:version < 704
map <silent> <C-u> :let b:new_tab_number = tabpagenr() \| exec ":tabm " . b:new_tab_number \| unlet b:new_tab_number<CR>
map <silent> <C-u> :let b:new_tab_number = tabpagenr() + 1 \| exec ":tabm " . b:new_tab_number \| unlet b:new_tab_number<CR>
map <silent> <C-y> :let b:new_tab_number = tabpagenr() - 2 \| if (b:new_tab_number < 0) \| let b:new_tab_number = 0 \| endif \| exec ":tabm " . b:new_tab_number \| unlet b:new_tab_number<CR>
" go to tab number (really only for gvim)
nnoremap <A-1> 1gt
nnoremap <A-2> 2gt
nnoremap <A-3> 3gt
nnoremap <A-4> 4gt
nnoremap <A-5> 5gt
nnoremap <A-6> 6gt
nnoremap <A-7> 7gt
nnoremap <A-8> 8gt
nnoremap <A-9> 9gt
nnoremap <A-0> 10gt
" use <C-Enter> to jump to the tag under the cursor in a new tab.
" Also check out "<C-w>T", it takes a split screen off to a new tab.
"nnoremap <C-{> <C-w><C-]><C-w>T
" this can also be something like this:
map <C-\> :tab split<CR>:exec("tag ".expand("<cword>"))<CR>
" Allow saving of files as sudo when I forgot to start vim using sudo.
cmap sudow w !sudo tee > /dev/null %
" Q is used to mess with macros. q is used to close tabs/windows.
" Q's original function is to go into EX-mode. I almost never want
" to go to EX mode, so I made this mapping.
noremap Q q
map q :q<CR>
" use CTRL-s for saving
" this doesn't work...
"nmap <c-s> :w<CR>
"imap <c-s> <Esc>:w<CR>a
" In input mode, what about we try using jj as escape?
" Note: This doesn't work well when pasting text to a vim buffer when running
" vim over ssh. If I go into input mode and try to paste a string with jj in it, vim goes back into
" normal mode, when really it should paste the whole string. This
" occasionally occurs when pasting hashes, which sometimes have the string jj
" in them.
"inoremap jj <Esc>
" I want to jump to the exact position in the line
nnoremap '' ``
" I want to jump to the exact position in the line for marks
nnoremap ' `
nnoremap ` '
" Let zz do :w
nnoremap zz :w<CR>
vnoremap <C-F> <PageDown>
""""""""""""""" Functions """""""""""""""""""
function! Resize(dir)
" TODO: could also do something like this for horizontal split screen
let above = 0
let below = 0
let this = winnr()
if a:dir == 'C-J' || a:dir == 'C-K'
execute "normal \<c-w>k"
let up = winnr()
if up != this
execute "normal \<c-w>j"
let above = 1
execute "normal \<c-w>j"
let down = winnr()
if down != this
execute "normal \<c-w>k"
let below = 1
"elseif '>' == a:dir || '<' == a:dir
" execute "normal \<c-w>h"
" let left = winnr()
" if left != this
" execute "normal \<c-w>l"
" let x = 'right'
" else
" let x = 'left'
" endif
echo "oops. check your ~/.vimrc here."
if ( ('C-J' == a:dir || 'C-K' == a:dir) && above == 0 && below == 0 )
" this is the only window on the screen
elseif ('C-J' == a:dir && above == 1 && below == 0)
" there are no windows below this on the screen
execute "normal 3\<c-w>-"
elseif ('C-J' == a:dir && above == 0 && below == 1)
" there are no windows below this on the screen but we are on the top
execute "normal 3\<c-w>+"
elseif ('C-K' == a:dir && above == 0 && below == 1)
" there are no windows above this on the screen and we are on the top
execute "normal 3\<c-w>-"
elseif ('C-K' == a:dir && above == 1 && below == 0)
" there are windows above this on the screen, and we are on the bottom
execute "normal 3\<c-w>+"
elseif ('C-J' == a:dir && above == 1 && below == 1)
" this is a middle window and we are trying to drop it down
execute "normal \<c-w>j3\<c-w>-\<c-w>p"
elseif ('C-K' == a:dir && above == 1 && below == 1)
" this is a middle window and we are trying to raise it up
execute "normal \<c-w>k3\<c-w>-\<c-w>p"
echo "oops. check your ~/.vimrc"
" mappings for changing window size
nnoremap <silent> <C-J> :call Resize('C-J')<CR>
nnoremap <silent> <C-K> :call Resize('C-K')<CR>
" run glg from within vim
function! Glg(...)
execute "silent !git log --decorate --graph --color " . join(a:000) . " | less -R"
command! -nargs=* Glg call Glg(<f-args>)
cabbrev glg Glg
" run git diff from within vim
function! Gdf(...)
execute "silent !git diff --color " . join(a:000) . " | less -R"
command! -nargs=* Gdf call Gdf(<f-args>)
cabbrev gdf Gdf
" run git push from within vim
function! Gpsh(...)
execute "!git push " . join(a:000)
command! -nargs=* Gpsh call Gpsh(<f-args>)
cabbrev gpsh Gpsh
" run git commit -a -m from within vim
function! Gcam(...)
execute "!git commit -a -m \"" . join(a:000) . "\""
command! -nargs=* Gcam call Gcam(<f-args>)
cabbrev gcam Gcam
" run git commit -a -m from within vim
function! Gcamp(...)
execute "!git commit -a -m \"" . join(a:000) . "\" && git push"
command! -nargs=* Gcamp call Gcamp(<f-args>)
cabbrev gcamp Gcamp
" Open a bunch of tabs at once. Also interpret globbing characters.
function! Tabopen_all_files(...)
let i = 1
let firstnewtab = 0
" loop over arguments passed to this function, both file names, new tab
" names, and filename globs
while i <= a:0
let filelist = split(glob(a:{i}), "\n")
if len(filelist) == 0
" if there are no files in the glob, then we just pass it to
" tabedit
execute "tabedit " . a:{i}
if i == 1
let firstnewtab = tabpagenr()
" loop over files in the glob, opening each one
let j = 0
while j < len(filelist)
execute "tabedit " . filelist[j]
" if this is the first new tab that we're opening,
" we have to save the tab number so we can come back here
" after we're done opening all the other tabs
if i == 1 && j == 0
let firstnewtab = tabpagenr()
let j = j + 1
let i = i + 1
" if we opened any tabs, then we need to go back to
" the first one we opened
if firstnewtab
execute "normal " . firstnewtab . "gt"
" create a command ":Tabopen" that will call our tab-opening function
" and create an abbreviation for it with the name "tabo". So, to use this
" just type ":tabo " and it will get replaced with ":Tabopen ".
command! -nargs=+ -complete=file Tabopen call Tabopen_all_files(<f-args>)
cabbrev tabo Tabopen
" Convert all arguments to function from relative references to a file
" based on the file currently being edited, so absolute references based
" on current working directory.
" For instance, if we are in /some/path/, and we are editing
" /some/path/src/nice.c, then if we call this with :tabopen join.c,
" the :tabopen function will get the argument src/join.c.
function! RelativeFunc(function, ...)
let file_basename = expand("%:p:h")
let relativefiles = copy(a:000)
let i = 0
while i < len(relativefiles)
"let relativefiles[i] = file_basename . "/" . relativefiles[i]
let relativefiles[i] = substitute(file_basename . "/" . relativefiles[i], getcwd() . "/", "", "")
let relativefiles[i] = simplify(relativefiles[i])
let i = i + 1
call call(a:function, relativefiles)
" A complete function for completing file names relative to the current
" file being edited.
" For instance, if we are in /some/path/, and we are editing
" /some/path/src/nice.c, if we try to complete a path using this func,
" we will intially get a list of files in /some/path/src/, NOT /some/path/.
function! RelativeFilesComplete(ArgLead, CmdLine, CursorPos)
let file_basename = expand("%:p:h")
let path = file_basename . "/" . a:ArgLead
if isdirectory(path) && path[len(path) - 1] != "/"
let path = path . "/"
let relativefiles = split(glob(path . "*"), "\n")
let index = 0
while index < len(relativefiles)
if isdirectory(relativefiles[index])
let relativefiles[index] .= "/"
let relativefiles[index] = substitute(relativefiles[index], file_basename . "/" , "", "")
let index += 1
return relativefiles
command! -nargs=+ -complete=customlist,RelativeFilesComplete
\ RelativeTabopen call RelativeFunc(function('Tabopen_all_files'), <f-args>)
cabbrev rt RelativeTabopen
" This renames a file. It is relative to the CWD. It deletes the old file.
" It also saves the undo history.
" TODO: It would also be nice to make this a shared vim plugin, instead of
" hard-coding it here.
function! Rename(name)
let l:name = a:name
let l:oldfile = expand('%:p')
" If the l:name is the name of a directory, than append the basename of
" l:oldfile to it and use it.
if isdirectory(l:name)
let l:name = l:name . fnamemodify(l:oldfile, ':p:t')
if bufexists(fnamemodify(l:name, ':p'))
echohl ErrorMsg
echomsg 'A buffer with that name already exists (use ! to override).'
echohl None
return 0
let l:status = 1
let v:errmsg = ''
silent! exe 'saveas' . ' ' . l:name
if v:errmsg =~# '^$\|^E329'
let l:lastbufnr = bufnr('$')
if expand('%:p') !=# l:oldfile && filewritable(expand('%:p'))
if fnamemodify(bufname(l:lastbufnr), ':p') ==# l:oldfile
silent exe l:lastbufnr . 'bwipe!'
echohl ErrorMsg
echomsg 'Could not wipe out the old buffer for some reason.'
echohl None
let l:status = 0
if delete(l:oldfile) != 0
echohl ErrorMsg
echomsg 'Could not delete the old file: ' . l:oldfile
echohl None
let l:status = 0
echohl ErrorMsg
echomsg 'Rename failed for some reason.'
echohl None
let l:status = 0
echoerr v:errmsg
let l:status = 0
return l:status
command! -nargs=1 -complete=customlist,RelativeFilesComplete
\ Rename call RelativeFunc(function('Rename'), <f-args>)
cabbrev rename Rename
" This copies a file. It is relative to the CWD. It's like :Rename but it
" doesn't delete the old file.
" TODO: It would also be nice to make this a shared vim plugin, instead of
" hard-coding it here.
function! Copy(name)
let l:name = a:name
let l:oldfile = expand('%:p')
" If the l:name is the name of a directory, than append the basename of
" l:oldfile to it and use it.
if isdirectory(l:name)
let l:name = l:name . fnamemodify(l:oldfile, ':p:t')
" I don't think I actually need this check...
" if bufexists(fnamemodify(l:name, ':p'))
" echohl ErrorMsg
" echomsg 'A buffer with that name already exists (use ! to override).'
" echohl None
" return 0
" endif
let v:errmsg = ''
let l:cpo_save = &cpoptions
set cpoptions-=A
silent! exe 'write ' . l:name
let &cpoptions = l:cpo_save
if v:errmsg != ''
echohl ErrorMsg
echomsg 'Copying file ' . l:oldfile . ' to ' . l:name . ' failed:'
echoerr v:errmsg
return 0
silent! exe 'tabedit ' . l:name
if v:errmsg != ''
echohl ErrorMsg
echomsg 'tabopen file ' . l:oldfile . ' failed:'
echoerr v:errmsg
return 0
return 1
command! -nargs=1 -complete=customlist,RelativeFilesComplete
\ Copy call RelativeFunc(function('Copy'), <f-args>)
cabbrev cp Copy
" Make a new directory. It is relative to the directory of the currently
" opened buffer.
" TODO: It would also be nice to make this a shared vim plugin, instead of
" hard-coding it here.
function! Mkdir(name)
let l:name = a:name
" If the l:name already exists, show an error message.
if isdirectory(l:name) || filereadable(l:name)
echohl ErrorMsg
echomsg 'Tried to create directory "' . l:name . '", but it already exists.'
return 0
silent let l:output = system('mkdir -p ' . l:name)
if v:shell_error != 0
echohl ErrorMsg
echomsg 'Tried to create directory "' . l:name . '", but failed with error code "' . v:shell_error . '" and output:'
echoerr l:output
return 0
return 1
command! -nargs=1 -complete=customlist,RelativeFilesComplete
\ Mkdir call RelativeFunc(function('Mkdir'), <f-args>)
cabbrev mkdir Mkdir
" Execute the line under the cursor.
"function! ExecuteLine()
" let thisline = getline('.')
" execute '!' . thisline
"nnoremap <silent> <C-R> :call ExecuteLine()<CR>
" use command VGrep to list files in a vertical split. The '!' after grep
" makes the command not jump to the first occurance that was found.
command! -nargs=+ Vgrep execute 'silent grep! <args>' | vert copen 30
command! -nargs=+ Vlgrep execute 'silent lgrep! <args>' | vert copen 30
" use command Grep to list files in a new tab
command! -nargs=+ Grep execute 'silent grep! <args>' | tab copen
command! -nargs=+ LGrep execute 'silent lgrep! <args>' | tab copen
map <Leader>f :execute("Grep -I -r ".expand("<cword>")." .")<CR>
" Create command for curl'ing a file into the current buffer
command! -nargs=+ Curl execute 'read !curl <args> 2>/dev/null'
cabbrev curl Curl
" Autocommand to change what <CR> does on quickfix buffer.
" (It changes <CR> to open the first result in a new tab).
autocmd BufWinEnter * if &buflisted && &filetype == "qf" | noremap <buffer> <CR> <CR><C-W>T| endif
" Autocommand
" I don't think I need this anymore because I mapped :q to q.
"autocmd BufWinEnter * if &buflisted && &filetype == "qf" | noremap <buffer> q :q<CR>| endif
" source ~/.vim/plugin/cscope_maps.vim
" source ~/.vim/syntax/javascript.vim
" show when autocmds are called
"set verbose=9
" Make vim jump to the last position that you were editing in the file.
" When we reload, tell vim to restore the cursor to the saved position.
" This long, ugly thing is needed because funny things happen when you
" use folding.
" augroup JumpCursorOnEdit
" au!
" autocmd BufReadPost *
" \ if expand("<afile>:p:h") !=? $TEMP |
" \ if line("'\"") > 1 && line("'\"") <= line("$") |
" \ let JumpCursorOnEdit_foo = line("'\"") |
" \ let b:doopenfold = 1 |
" \ if (foldlevel(JumpCursorOnEdit_foo) > foldlevel(JumpCursorOnEdit_foo - 1)) |
" \ let JumpCursorOnEdit_foo = JumpCursorOnEdit_foo - 1 |
" \ let b:doopenfold = 2 |
" \ endif |
" \ exe JumpCursorOnEdit_foo |
" \ endif |
" \ endif
" " Need to postpone using "zv" until after reading the modelines.
" autocmd BufWinEnter *
" \ if exists("b:doopenfold") |
" \ exe "normal zv" |
" \ if(b:doopenfold > 1) |
" \ exe "+".1 |
" \ endif |
" \ unlet b:doopenfold |
" \ endif
" augroup END
" This is a newer function that apparently works better.
function! ResCur()
if line("'\"") <= line("$")
normal! g`"
return 1
if has("folding")
function! UnfoldCur()
if !&foldenable
let cl = line(".")
if cl <= 1
let cf = foldlevel(cl)
let uf = foldlevel(cl - 1)
let min = (cf > uf ? uf : cf)
if min
execute "normal!" min . "zo"
return 1
augroup resCur
if has("folding")
autocmd BufWinEnter * if ResCur() | call UnfoldCur() | endif
autocmd BufWinEnter * call ResCur()
augroup END
"""""""" Specific filetype settings """""""""
" This uses the execute command to create an autocmd
" that sets the fold_method if the syntax matches.
" You have to use execute so that the variables get
" evaluated now instead of when the autocmd executes.
function! Add_auto_foldmethod(syntax_of_file, fold_method)
execute "autocmd Syntax * "
\ "if expand(\"<amatch>\") == \"" . a:syntax_of_file . "\" | "
\ "execute \"set foldmethod=" . a:fold_method . "\" | "
\ " endif "
" TODO: I can probably change all of these to the au FileType command being
" used at the bottom for xml.
"call Add_auto_foldmethod('asm', 'indent')
call Add_auto_foldmethod('ant', 'syntax')
call Add_auto_foldmethod('c', 'syntax')
call Add_auto_foldmethod('cpp', 'syntax')
call Add_auto_foldmethod('css', 'indent')
call Add_auto_foldmethod('erlang', 'syntax')
call Add_auto_foldmethod('haskell', 'syntax')
call Add_auto_foldmethod('java', 'syntax')
call Add_auto_foldmethod('javascript', 'indent')
call Add_auto_foldmethod('json', 'syntax')
call Add_auto_foldmethod('objc', 'syntax')
call Add_auto_foldmethod('php', 'syntax')
call Add_auto_foldmethod('puppet', 'indent')
call Add_auto_foldmethod('python', 'indent')
call Add_auto_foldmethod('rust', 'syntax')
call Add_auto_foldmethod('sas', 'syntax')
call Add_auto_foldmethod('scala', 'indent')
"call Add_auto_foldmethod('xml', 'syntax')
call Add_auto_foldmethod('xsd', 'syntax')
call Add_auto_foldmethod('yaml', 'indent')
au FileType xml set foldmethod=syntax
" Kind of like above, add a method specifying whether or not we
" want to highlight spaces at the end of a line
function! Add_eol_whitespace_highlighting(syntax_of_file)
" autocmd InsertEnter/Leave doesn't seem to work just by giving the group
" (like "c"), so we have to do this horrible, horrible thing. In order to
" understand this, first run "autocmd Syntax", and then look at "autocmd
" InsertEnter" or "autocmd InsertLeave". It should make a little more
" sense.
execute "autocmd Syntax * "
\ "if expand(\"<amatch>\") == \"" . a:syntax_of_file . "\" | "
\ "execute \"autocmd InsertEnter <buffer> "
\ " syn clear EOLWS | syn match EOLWS excludenl /\\\\s\\\\+\\\\%#\\\\@!$/ containedin=ALL\" | "
\ " endif "
execute "autocmd Syntax * "
\ "if expand(\"<amatch>\") == \"" . a:syntax_of_file . "\" | "
\ "execute \"autocmd InsertLeave <buffer> "
\ " syn clear EOLWS | syn match EOLWS excludenl /\\\\s\\\\+$/ containedin=ALL\" | "
\ " endif "
" create the highlight group we are using
execute "autocmd Syntax " . a:syntax_of_file .
\ " highlight EOLWS ctermbg=white guibg=white"
" now just run the command to actually highlight spaces at the end of lines so
" we see them as soon as we open the file
execute "autocmd Syntax " . a:syntax_of_file .
\ " syn clear EOLWS | syn match EOLWS excludenl /\\s\\+$/ containedin=ALL"
call Add_eol_whitespace_highlighting("bash")
call Add_eol_whitespace_highlighting("c")
call Add_eol_whitespace_highlighting("cpp")
call Add_eol_whitespace_highlighting("css")
call Add_eol_whitespace_highlighting("dockerfile")
call Add_eol_whitespace_highlighting("elm")
call Add_eol_whitespace_highlighting("erlang")
call Add_eol_whitespace_highlighting("hamlet")
call Add_eol_whitespace_highlighting("haskell")
call Add_eol_whitespace_highlighting("html")
call Add_eol_whitespace_highlighting("java")
call Add_eol_whitespace_highlighting("javascript")
call Add_eol_whitespace_highlighting("json")
call Add_eol_whitespace_highlighting("julius")
call Add_eol_whitespace_highlighting("markdown")
call Add_eol_whitespace_highlighting("nix")
call Add_eol_whitespace_highlighting("ledger")
call Add_eol_whitespace_highlighting("lucius")
call Add_eol_whitespace_highlighting("ocaml")
call Add_eol_whitespace_highlighting("php")
call Add_eol_whitespace_highlighting("puppet")
call Add_eol_whitespace_highlighting("purescript")
call Add_eol_whitespace_highlighting("python")
call Add_eol_whitespace_highlighting("r")
call Add_eol_whitespace_highlighting("rust")
call Add_eol_whitespace_highlighting("ruby")
call Add_eol_whitespace_highlighting("scala")
call Add_eol_whitespace_highlighting("sh")
call Add_eol_whitespace_highlighting("terraform")
call Add_eol_whitespace_highlighting("vim")
call Add_eol_whitespace_highlighting("yaml")
" Make sure I can get spell checking when the file I am editing does not have
" a syntax associated with it.
" Python needs spaces instead of tabs.
autocmd BufRead,BufNewFile *.py set expandtab
" maybe this could also be done with
autocmd FileType python set expandtab
" set autocomplete for python from the neocomplete plugin
"autocmd FileType python setlocal omnifunc=pythoncomplete#Complete
" Haskell also needs spaces instead of tabs.
autocmd BufRead,BufNewFile *.hs setlocal expandtab
autocmd BufRead,BufNewFile *.lhs setlocal expandtab
" maybe this could also be done with
autocmd FileType haskell setlocal expandtab
" Set the indenter to hindent
" autocmd BufRead,BufNewFile *.hs setlocal formatprg=hindent
" autocmd FileType haskell setlocal formatprg=hindent
" Since formatprg is a global option (and not a global-local option), we have
" to do this dance to get formatprg be the correct value:
autocmd BufEnter *.hs set formatprg=hindent
autocmd BufLeave *.hs set formatprg=
autocmd FileType haskell setlocal tabstop=2
autocmd FileType haskell setlocal shiftwidth=2
autocmd FileType haskell setlocal softtabstop=2
autocmd BufRead,BufNewFile *.hs setlocal tabstop=2
autocmd BufRead,BufNewFile *.hs setlocal shiftwidth=2
autocmd BufRead,BufNewFile *.hs setlocal softtabstop=2
" hamlet files (for yesod) also need spaces instead of tabs
autocmd BufRead,BufNewFile *.hamlet set expandtab
" Cabal files also needs spaces instead of tabs.
autocmd BufRead,BufNewFile *.cabal set expandtab
autocmd FileType cabal set expandtab
autocmd BufRead,BufNewFile *.cabal setlocal filetype=cabal
" SConscript and SConstruct files are python files
autocmd BufRead,BufNewFile SConstruct set ft=python
autocmd BufRead,BufNewFile SConscript set ft=python
" special settings for sas files
autocmd FileType sas set tabstop=3 " 3-space tab indent width
autocmd FileType sas set shiftwidth=3 " allows you to use < and > to indent/unindent blocks
autocmd FileType sas set softtabstop=3 " see multiple space characters as a tab
" settings for c#
autocmd FileType cs set omnifunc=syntaxcomplete#Complete
autocmd FileType cs set foldmethod=marker
autocmd FileType cs set foldmarker={,}
autocmd FileType cs set foldtext=substitute(getline(v:foldstart),'{.*','{...}',)
autocmd FileType cs set foldlevelstart=2
" settings for R
autocmd FileType r setlocal tabstop=2
autocmd FileType r setlocal shiftwidth=2
autocmd FileType r setlocal softtabstop=2
autocmd FileType r setlocal expandtab
" autocmd FileType r setlocal foldmethod=syntax
" settings for ruby
let ruby_no_expensive=1
autocmd FileType ruby setlocal tabstop=2
autocmd FileType ruby setlocal shiftwidth=2
autocmd FileType ruby setlocal softtabstop=2
autocmd FileType ruby setlocal expandtab
autocmd FileType ruby setlocal foldmethod=syntax
" settings for puppet
autocmd FileType puppet setlocal tabstop=2
autocmd FileType puppet setlocal shiftwidth=2
autocmd FileType puppet setlocal softtabstop=2
autocmd FileType puppet setlocal expandtab
autocmd FileType puppet setlocal foldmethod=indent
" settings for scala
autocmd FileType scala setlocal tabstop=2
autocmd FileType scala setlocal shiftwidth=2
autocmd FileType scala setlocal softtabstop=2
autocmd FileType scala setlocal expandtab
autocmd FileType scala setlocal foldmethod=indent
" settings for html
autocmd FileType html setlocal tabstop=2
autocmd FileType html setlocal shiftwidth=2
autocmd FileType html setlocal softtabstop=2
"autocmd FileType html setlocal expandtab
autocmd FileType html setlocal foldmethod=indent
let b:markdownFoldLevelInSyntaxBlock=0
" This function returns the appropriate indentation level for the current
" line. It is used with the &foldexpr setting for markdown files. It folds
" code blocks appropriately.
function! MarkdownFoldLevel()
let h = matchstr(getline(v:lnum), '^\s*```')
" If we are already in a markdown syntax block, and there is not "```" on
" the current line, then just keep the indentation the same.
if b:markdownFoldLevelInSyntaxBlock && empty(h)
return "="
" If we are already in a markdown syntax block, and there is a closing
" "```" on the current line, then close the syntax block and decrease the
" indentation by one.
if b:markdownFoldLevelInSyntaxBlock && !empty(h)
let b:markdownFoldLevelInSyntaxBlock=0
return "s1"
" If we are not already in a markdown syntax block, and there is an
" opening "```" on the current line, then set that we are in a syntax
" block and increase the indentation by one.
if !empty(h)
let b:markdownFoldLevelInSyntaxBlock=1
return "a1"
" If we are not in a markdown syntax block, and there is not a "```" on
" the current line, then check if this is a header line, and increase the
" indentation by that amount.
let g = matchstr(getline(v:lnum), '^#\+')
if empty(g)
return "="
return ">" . len(g)
" settings for markdown
autocmd BufNewFile,BufRead *.md set filetype=markdown
autocmd FileType markdown setlocal expandtab
autocmd FileType markdown setlocal foldexpr=MarkdownFoldLevel()
autocmd FileType markdown setlocal foldmethod=expr
" settings for nix files
autocmd BufRead,BufNewFile *.nix set expandtab
autocmd BufRead,BufNewFile *.nix set tabstop=2
autocmd BufRead,BufNewFile *.nix set shiftwidth=2
autocmd BufRead,BufNewFile *.nix set softtabstop=2
autocmd BufRead,BufNewFile *.nix setlocal commentstring=#%s
autocmd FileType nix set expandtab
autocmd FileType nix set tabstop=2
autocmd FileType nix set shiftwidth=2
autocmd FileType nix set softtabstop=2
autocmd FileType nix setlocal commentstring=#%s
autocmd FileType nix setlocal indentexpr=
" settings for ledger files
autocmd FileType ledger set expandtab
" settings for matlab files
autocmd FileType matlab setlocal commentstring=%%s
" settings for ocaml files.
" For some reason this doesn't work if we don't use "BufEnter".
" autocmd! BufRead,BufNewFile,BufEnter *.ml,*.mli,*mll,*.mly set filetype=ocaml
" settings for purescript files
autocmd FileType purescript set expandtab
autocmd FileType purescript set tabstop=2
autocmd FileType purescript set shiftwidth=2
autocmd FileType purescript set softtabstop=2
autocmd FileType purescript setlocal formatoptions+=1crq formatoptions-=t
autocmd FileType purescript setlocal commentstring=--%s
autocmd FileType purescript setlocal comments=:--
" settings for javascript files
autocmd FileType javascript set expandtab
autocmd FileType javascript set tabstop=2
autocmd FileType javascript set shiftwidth=2
autocmd FileType javascript set softtabstop=2
" settings for rust files
autocmd FileType rust set expandtab
autocmd FileType rust set tabstop=4
autocmd FileType rust set shiftwidth=4
autocmd FileType rust set softtabstop=4
" settings for erlang files
autocmd FileType erlang set expandtab
autocmd FileType erlang set tabstop=2
autocmd FileType erlang set shiftwidth=2
autocmd FileType erlang set softtabstop=2
" settings for pug files
autocmd FileType pug set expandtab
autocmd FileType pug set tabstop=2
autocmd FileType pug set shiftwidth=2
autocmd FileType pug set softtabstop=2
" settings for terraform files
autocmd FileType terraform setlocal tabstop=2
autocmd FileType terraform setlocal shiftwidth=2
autocmd FileType terraform setlocal softtabstop=2
autocmd FileType terraform setlocal expandtab
autocmd FileType terraform setlocal commentstring=#%s
autocmd FileType terraform setlocal comments=:#
autocmd FileType terraform setlocal formatoptions+=r formatoptions+=o
" settings for Dockerfiles
autocmd FileType dockerfile setlocal expandtab
" settings for YAML files
autocmd FileType yaml setlocal expandtab
autocmd FileType yaml setlocal tabstop=2
autocmd FileType yaml setlocal shiftwidth=2
autocmd FileType yaml setlocal softtabstop=2
" OCaml Specific Settings "
" Load in the merlin vim settings and ocp-indent settings.
if executable('opam')
let g:opamshare = substitute(system('opam config var share'),'\n$','','''')
" merlin
let g:merlindir = g:opamshare . "/merlin/vim"
if isdirectory(g:merlindir)
execute "set rtp+=" . g:merlindir
" This should get executed so that the merlin documentation is
" available.
" :execute "helptags " . g:opamshare . "/merlin/vim/doc"
let g:ocpindentdir = g:opamshare . "/ocp-indent/vim"
if isdirectory(g:ocpindentdir)
" This needs to go on the front of the run time path so that it gets
" loaded before the stock vim indentation files.
execute "set rtp^=" . g:ocpindentdir
autocmd FileType ocaml setlocal tabstop=2
autocmd FileType ocaml setlocal shiftwidth=2
autocmd FileType ocaml setlocal softtabstop=2
autocmd FileType ocaml setlocal expandtab
autocmd FileType ocaml setlocal commentstring=(*%s*)
" Extra Options "
" turn these on if you want to use vim over a slow link
"set lazyredraw
"set nottyfast
" Local Options "
" load a local .vimrc from "~/.vimrc-local" if it exists
let vimrc_dir = fnamemodify(expand($MYVIMRC), ":h")
let local_vimrc = vimrc_dir . "/.vimrc-local"
if filereadable(local_vimrc)
execute "source " . local_vimrc