" This file is UTF-8, of course
scriptencoding utf-8
" Don't make any effort to be compatible with vi, use more sensible settings
set nocompatible
" If our version isn't ancient and Pathogen is available, call it to load all
" the plugins in .vim/bundle; these are saved as submodules
if v:version >= 701
silent! call pathogen#infect()
silent! call pathogen#helptags()
endif
" Load plugins and indentation for file types
if has('autocmd')
filetype indent plugin on
endif
" Use backup features if on a UNIX-like system and not using sudo(8)
if !strlen($SUDO_USER) && has('unix')
" Keep backups with a .bak extension in ~/.vim/backup; the double-slash at
" the end of the directory is supposed to prod Vim into keeping the full
" path to the file in its backup filename to avoid collisions, but I don't
" think it actually works for backups, just undo and swap files
set backup
set backupext=.bak
set backupdir^=~/.vim/backup//
" This option already includes various temporary directories, but we
" append to it so that we don't back up anything in a shared memory
" filesystem either
set backupskip+=*/shm/*
" Create the backup directory if necessary and possible
if !isdirectory($HOME . '/.vim/backup') && exists('*mkdir')
call mkdir($HOME . '/.vim/backup', 'p', 0700)
endif
" Don't use backups at all otherwise
else
set nobackup
set nowritebackup
endif
" Options dependent on the syntax feature
if has('syntax')
" Use syntax highlighting with 100 lines of context
syntax enable
syntax sync minlines=100
" Use my custom color scheme if possible, otherwise I'm happy with whatever
" the default is, and it usually cares about my background
set background=dark
silent! colorscheme sahara
endif
" Use all ancestors of current directory for :find
if has('file_in_path')
set path=**
endif
" Command-line based features
if has('cmdline_info')
" Show my current position in the status bar
set ruler
" Show the keystrokes being entered in the screen
set showcmd
" Show the mode we're using if not normal mode (e.g. --INSERT--)
set showmode
endif
" Don't try to complete strings from included files, just use the strings in
" the open buffers; I'll open the file if I want to complete from it
set complete-=i
" Rebind Ctrl-C in insert mode to undo the current insert operation
inoremap <C-c> <C-c>u
" A few very important custom digraphs
if has('digraphs')
digraph ./ 8230 " Ellipsis (HORIZONTAL ELLIPSIS U+2026)
digraph %% 8984 " Mac command key (PLACE OF INTEREST SIGN U+2318)
digraph 8: 9731 " Snowman (SNOWMAN U+2603)
endif
" Try Mac line-endings if UNIX or DOS don't make sense; this has never
" happened to me but who knows, it might one day
set fileformats+=mac
" Use UTF-8 by default wherever possible
if has('multi_byte')
set encoding=utf-8
endif
" Adopt the indent of the last line on new lines; interestingly, plugins that
" do clever things with indenting will often assume this is set
set autoindent
" Use spaces instead of tabs
set expandtab
" Indent with four spaces when an indent operation is used
set shiftwidth=4
" Insert four spaces when Tab is pressed
set softtabstop=4
" How many spaces to show for a literal tab when 'list' is unset
set tabstop=4
" Indent intelligently to 'shiftwidth' at the starts of lines with Tab, but
" use 'tabstop' everywhere else
set smarttab
" When indenting lines with < or >, round the indent to a multiple of
" 'shiftwidth', so even if the line is indented by one space it will indent
" up to 4 and down to 0, for example
set shiftround
" Don't join lines with two spaces at the end of sentences; I don't two-space,
" despite the noble Steve Losh's exhortations
set nojoinspaces
" Don't jump my screen around when I join lines, keep my cursor in the same
" place; this is done by dropping a mark first and then immediately returning
" to it; note that it wipes out your z mark, if you happen to use it
nnoremap J mzJ`z
" If we can, add j to the format options to get rid of comment leaders when
" joining lines
if v:version > 703 || v:version == 703 && has('patch541')
set formatoptions+=j
endif
"
" Quick way to toggle flags in 'formatoptions' that I often want to change;
" specifically:
"
" a - Automatically format paragraphs, reapplying the wrap on every text
" insertion or deletion; sometimes I want this and sometimes I
" don't, it particularly varies when typing prose in Markdown that
" includes headings and code
" c - Automatically wrap comments at 'textwidth' (which I allow the filetypes
" to set for me)
" t - Automatically wrap text at 'textwidth' (as above)
"
" So I just have to type e.g. \a to toggle the auto-format flag on and off;
" very handy
"
if has('eval')
function! ToggleFormatFlag(flag)
let l:operation = (&formatoptions =~ a:flag) ? '-=' : '+='
silent! exec 'setlocal formatoptions' . l:operation . a:flag
setlocal formatoptions?
endfunction
nnoremap <silent> <leader>a :<C-U>call ToggleFormatFlag('a')<CR>
nnoremap <silent> <leader>c :<C-U>call ToggleFormatFlag('c')<CR>
nnoremap <silent> <leader>t :<C-U>call ToggleFormatFlag('t')<CR>
endif
" Strip trailing whitespace with \x
if has('eval')
function! StripTrailingWhitespace()
let l:search = @/
%substitute/\s\+$//e
let @/ = l:search
nohlsearch
endfunction
nnoremap <silent> <leader>x :<C-U>call StripTrailingWhitespace()<CR>
endif
" Keep plenty of command and search history, because disk space is cheap
set history=2000
" Don't show whitespace characters or end-of-line characters visually by
" default, but make \l toggle between them
set nolist
nnoremap <leader>l :setlocal list!<CR>
" Try to run the version of matchit.vim included in the distribution, if there
" is one; extends % to match more than it does by default
silent! runtime macros/matchit.vim
" Match all forms of brackets in pairs (including angle brackets)
set matchpairs=(:),{:},[:],<:>
" Don't show the Vim startup message, I have registered Vim and donated to
" Uganda
set shortmess+=I
" Let me backspace over pretty much anything, even if it's not text I inserted
" in the current session
set backspace=indent,eol,start
" Don't use modelines at all, they're apparently potential security problems
" and I've never used them anyway
set nomodeline
" Don't assume a number with a leading zero is octal; it's far more likely a
" zero-padded decimal, so increment and decrement with ^A and ^X on that basis
set nrformats-=octal
" Always tell me the number of lines changed by a command
set report=0
" Always use forward slashes, I very seldom need to use Vim on Windows for
" more than scratch space anyway
set shellslash
" Don't show line numbers by default, but \n toggles them
set nonumber
nnoremap <leader>n :setlocal number!<CR>
" Start paste mode with F10 to prevent console Vim from confusing a swathe of
" pre-formatted pasted text with actual keyboard input, and thereby attempting
" to indent it inappropriately. If unimpaired.vim is available, it's generally
" nicer to use yo or yO.
set nopaste
set pastetoggle=<F10>
" If the Vim buffer for a file doesn't have any changes and Vim detects the
" file has been altered, quietly update it
set autoread
" Save a file automatically if I change buffers or perform operations with the
" argument list; this is particularly helpful for me as I don't use 'hidden'
set autowrite
" Allow the cursor to get to the top or bottom of the screen before scrolling
" vertically, but set a reasonably wide gutter for scrolling horizontally; no
" particular reason, just suits me better
set scrolloff=0
set sidescrolloff=16
" Some special settings for searching, if available
if has('extra_search')
" Searching as I enter my pattern, \i toggles this
set incsearch
nnoremap <leader>i :set incsearch!<CR>
" Highlight search results, \h toggles this
set hlsearch
nnoremap <leader>h :set hlsearch!<CR>
" Pressing ^L will clear highlighting until the next search-related
" operation; quite good because the highlighting gets distracting after
" you've found what you wanted
nnoremap <silent> <C-l> :nohlsearch<CR><C-l>
" Clear search highlighting as soon as I enter insert mode, and restore it
" once I leave it
if has('autocmd')
augroup highlight
autocmd!
silent! autocmd InsertEnter * set nohlsearch
silent! autocmd InsertLeave * set hlsearch
augroup END
endif
endif
" Configure spell checking features, if available
if has('spell')
" Don't check spelling by default, but bind \s to toggle this
set nospell
nnoremap <leader>s :setlocal spell!<CR>
" Use New Zealand English for spelling by default (it's almost identical
" to British English), but bind \u to switch to US English and \z to
" switch back
set spelllang=en_nz
nnoremap <leader>u :setlocal spelllang=en_us<CR>
nnoremap <leader>z :setlocal spelllang=en_nz<CR>
endif
" Don't keep .viminfo information for files in temporary directories or shared
" memory filesystems; this is because they're used as scratch spaces for tools
" like sudoedit(8) and pass(1) and hence could present a security problem
if has('viminfo') && has('autocmd')
augroup viminfoskip
autocmd!
silent! autocmd BufNewFile,BufReadPre
\ /tmp/*,$TMPDIR/*,$TMP/*,$TEMP/*,*/shm/*
\ setlocal viminfo=
augroup END
endif
" Preserve the flags for a pattern when repeating a substitution with &; I don't
" really understand why this isn't a default, but there it is
nnoremap & :&&<CR>
vnoremap & :&&<CR>
" Swap files are used if using Unix and not using sudo(8); I very seldom need
" them, but they are occasionally useful after a crash, and they don't really
" get in the way if kept in their own directory
if !strlen($SUDO_USER) && has('unix')
" Use swap files but keep them in ~/.vim/swap; the double-slash at the end
" of the directory prods Vim into keeping the full path to the file in its
" undo filename to avoid collisions; the same thing works for undo files
set swapfile
set directory^=~/.vim/swap//
" Create the ~/.vim/swap directory if necessary and possible
if !isdirectory($HOME . '/.vim/swap') && exists('*mkdir')
call mkdir($HOME . '/.vim/swap', 'p', 0700)
endif
" Don't keep swap files for files in temporary directories or shared memory
" filesystems; this is because they're used as scratch spaces for tools
" like sudoedit(8) and pass(1) and hence could present a security problem
if has('autocmd')
augroup swapskip
autocmd!
silent! autocmd BufNewFile,BufReadPre
\ /tmp/*,$TMPDIR/*,$TMP/*,$TEMP/*,*/shm/*
\ setlocal noswapfile
augroup END
endif
" Otherwise, don't use swap files at all
else
set noswapfile
endif
" Don't bother about checking whether Escape is being used as a means to enter
" a Meta-key combination, just register Escape immediately
set noesckeys
" Don't bother drawing the screen while executing macros or other automated or
" scripted processes, just draw the screen as it is when the operation
" completes
set lazyredraw
" Improve redrawing smoothness by assuming that my terminal is reasonably
" fast
set ttyfast
" Never use any kind of bell, visual or not
set visualbell t_vb=
" Require less than one second between keys for mappings to work correctly
set timeout
set timeoutlen=1000
" Require less than a twentieth of a second between keys for key codes to work
" correctly; I don't use Escape as a meta key anyway
set ttimeout
set ttimeoutlen=50
" Tolerate typos like :Wq, :Q, or :Qa and do what I mean, including any
" arguments or modifiers; I fat-finger these commands a lot because I type
" them so rapidly, and they don't correspond to any other commands I use
if has('user_commands')
command! -bang -complete=file -nargs=? E e<bang> <args>
command! -bang -complete=file -nargs=? W w<bang> <args>
command! -bang -complete=file -nargs=? WQ wq<bang> <args>
command! -bang -complete=file -nargs=? Wq wq<bang> <args>
command! -bang Q q<bang>
command! -bang Qa qa<bang>
command! -bang QA qa<bang>
command! -bang Wa wa<bang>
command! -bang WA wa<bang>
endif
" Keep screeds of undo history
set undolevels=2000
" Keep undo history in a separate file if the feature is available, we're on
" Unix, and not using sudo(8); this goes really well with undo visualization
" plugins like Gundo or Undotree.
if !strlen($SUDO_USER) && has('unix') && has('persistent_undo')
" Keep per-file undo history in ~/.vim/undo; the double-slash at the end
" of the directory prods Vim into keeping the full path to the file in its
" undo filename to avoid collisions; the same thing works for swap files
set undofile
set undodir^=~/.vim/undo//
" Create the ~/.vim/undo directory if necessary and possible
if !isdirectory($HOME . '/.vim/undo') && exists('*mkdir')
call mkdir($HOME . '/.vim/undo', 'p', 0700)
endif
" Don't track changes to sensitive files
if has('autocmd')
augroup undoskip
autocmd!
silent! autocmd BufWritePre
\ /tmp/*,$TMPDIR/*,$TMP/*,$TEMP/*,*/shm/*
\ setlocal noundofile
augroup END
endif
endif
" When in visual block mode, let me move the cursor anywhere in the buffer;
" don't restrict me only to regions with text
if has('virtualedit')
set virtualedit+=block
endif
" Configuration for the command completion feature; rather than merely cycling
" through possible completions with Tab, show them above the command line
if has('wildmenu')
" Use the wild menu, both completing and showing all possible completions
" with a single Tab press, just as I've configured Bash to do
set wildmenu
set wildmode=longest:list
" Don't complete certain files that I'm not likely to want to manipulate
" from within Vim:
if has('wildignore')
set wildignore+=*.a,*.o
set wildignore+=*.bmp,*.gif,*.ico,*.jpg,*.png
set wildignore+=.DS_Store,.git,.hg,.svn
set wildignore+=*~,*.swp,*.tmp
endif
" Complete files without case sensitivity, if the option is available
if exists('&wildignorecase')
set wildignorecase
endif
endif
" Configuration for window features
if has('windows')
" Show the status in a distinct bar above the command line only if there's
" more than one window on the screen or in the current tab
set laststatus=1
" Don't resize windows we're not splitting (Tmux-like; think Mondrian)
set noequalalways
" New split windows appear below or to the right of the existing window,
" not above or to the left per the default
set splitbelow
if has('vertsplit')
set splitright
endif
" Only show the tab bar if there's more than one tab
if exists('&showtabline')
set showtabline=1
endif
" Get rid of visually noisy folding characters
if has('folding')
let &fillchars = 'diff: ,fold: ,vert: '
endif
endif
" Use the tilde as an operator with motions, rather than just swapping the
" case of the character under the cursor
set tildeop
" When wrapping text, if a line is so long that not all of it can be shown on
" the screen, show as much as possible anyway; by default Vim fills the left
" column with @ symbols instead, which I don't find very helpful
set display=lastline
" Don't wrap by default, but use \w to toggle it on or off quickly
set nowrap
nnoremap <leader>w :set wrap!<CR>
" Clearly show when the start or end of the row does not correspond to the
" start and end of the line
set listchars+=precedes:<,extends:>
" Don't write the output of :make to the terminal
set shellpipe=>
" When wrapping, j and k should move by screen row, and not to the same
" column number in the previous logical line, which feels very clumsy and is
" seldom particularly helpful; you can use n| to jump to the nth column in a
" line anyway if you need to
nnoremap j gj
nnoremap k gk
" Break lines at word boundaries if possible and not simply at the last
" character that will fit on the screen, preceding the next line with three
" periods to make it obvious that it's a continuation of the previous line
if has('linebreak')
set linebreak
set showbreak=...
if v:version > 704 || v:version == 704 && has('patch338')
set breakindent
endif
" Bind \b to turn off linebreak and toggle the showbreak characters on and
" off for convenience of copypasting multiple lines from terminal emulators.
if has('eval')
function! ToggleBreak()
if &linebreak
set nolinebreak
set showbreak=
if v:version > 704 || v:version == 704 && has('patch338')
set nobreakindent
endif
else
set linebreak
set showbreak=...
if v:version > 704 || v:version == 704 && has('patch338')
set breakindent
endif
endif
endfunction
nnoremap <silent> <leader>b :<C-U>call ToggleBreak()<CR>
endif
endif
" I really like ZZ and ZQ, so I wrote a couple more mappings; ZW forces a
" write of the current buffer, but doesn't quit, and ZA forces a write of all
" buffers but doesn't quit
nnoremap ZW :w!<CR>
nnoremap ZA :wa!<CR>
" Change and delete with C and D both cut off the remainder of the line from
" the cursor, but Y yanks the whole line, which is inconsistent (and can be
" done with yy anyway); this fixes it so it only yanks the rest of the line
nnoremap Y y$
" Allow jumping between windows and tabs to find an open instance of a given
" buffer with :sbuffer.
if v:version >= 701
set switchbuf=useopen,usetab
else
set switchbuf=useopen
endif
" Fedora's default environment adds a few auto commands that I don't like,
" including the 'return to previous position in buffer' one; fortunately
" they're nice enough to group the commands, so I can just clear them
if has('autocmd')
augroup fedora
autocmd!
augroup END
endif
" When opening a large file, take some measures to keep things loading quickly
if has('eval') && has('autocmd')
" Threshold is 10 MiB
let g:bigfilesize = 10 * 1024 * 1024
" Declare function for turning off slow options
function! BigFileMeasures()
let l:file = expand('<afile>')
if getfsize(l:file) > g:bigfilesize
setlocal nobackup
setlocal nowritebackup
setlocal noswapfile
if has('persistent_undo')
setlocal noundofile
endif
if exists('&synmaxcol')
setlocal synmaxcol=256
endif
endif
endfunction
" Define autocmd for calling to check filesize
augroup bigfilesize
autocmd!
autocmd BufReadPre * call BigFileMeasures()
augroup end
endif