"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " Multi-version vimrc compatible with version 4 and above. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " Note that "if | call Something() | endif" syntax is unsupported " in Vim 4 so we write all our functions out the long way. It does work in " autocommand definitions, however. " Vim 4 complains if version isn't set in the configuration file. version 4.0 """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " Handle options safe to use in version 4. Vim 4 parses but ignores the " "if version" syntax used later in this file so we don't use it. No attempt " is made to make this configuration compatible with Vim 3. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " No compatibility mode. se nocp " Tabstop 2. se ts=2 " And use spaces not tabs. se expandtab " And << and >> indent by 2. se sw=2 " Allow backspace to delete before start of line. se bs=2 " Show the ruler. se ruler " Show partial commands in the ruler. se showcmd " And always show the status line. se laststatus=2 " Use C indent style. se cindent se cinkeys=0{,0},0),:,!^F,o,O,e se cinoptions=b1,c2 " GUI options. se go=aglmr " Don't be bugged by messages at the bottom of the screen. se shm=aot " Find as you type. se incsearch " Case-insensitive search. se ignorecase " But override by typing capitals. se smartcase " Look for ctags in home directory first. se tags=~/.tags,./tags,tags " Don't timeout waiting to interpet, eg, OA as an escape code. se ttimeoutlen=100 " Use ^B to search backward when completing. inoremap " Use ^L to show matching completions but don't select one. inoremap """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " Handle options only available in Vim 5 and above. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" if version >= "500" version 5.0 " Tell Vim we use dark backgrounds in our terminals. if ! has("gui_running") se bg=dark endif " Allow mouse use in a terminal. se mouse=nvir " Update more quickly. For use with sign highlighting as polling for " CursorMove makes redrawing slow. if has("signs") se updatetime=500 endif " Enable tab-completion prompting for commands. se wildmenu " Don't list object files when globbing files to load. se wildignore+=*.o,*.obj " So there's no need to assign them low priority. se suffixes-=*.o,*.obj " Save sessions in UNIX format with / as file separator. This is " cross-platform. se ssop+=unix,slash " Nuke any pre-existing autocommands. augroup Display autocmd! augroup Mode autocmd! if has("signs") augroup Signs autocmd! endif augroup StatusLine autocmd! augroup END " Save the current window width so we can restore it when we quit. if ! exists("g:oldcols") let g:oldcols=&columns endif " More GUI options. Add icon, tearoffs and toolbar. se go+=itT " Allow dynamic window resize even if we aren't in an xterm. se t_WS=[8;%p1%d;%p2%dt " Highlight search results. se hlsearch " Set graphical window title. se titlestring=%{Show_TitleString()} " Syntax highlighting. New versions will use syn enable instead. if version < "600" syn on endif " Catch typos. command! W :w command! Wq :wq command! Wqa :wqa " Set up our variables. fun! Iain_Vars() if ! exists("b:iainlist") let b:iainlist = 0 endif if ! exists("b:iainhex") let b:iainhex = 0 endif if ! exists("b:iainverbose") let b:iainverbose = 0 endif if ! exists("b:iainstatus") " Window Flags: (F)ocused, (I)nsert mode, Cursor (H)old. let b:iainstatus = "Fih" endif if ! exists("g:iainextracolumns") let g:iainextracolumns = 0 endif if has("signs") if ! exists("g:marksigns") let g:marksigns = 0 endif if ! exists("g:firstsign") let g:firstsign = 100 endif endif endfun " Helper for status line. " Show space, underscore or dollar sign depending on list mode. fun! Show_List() call Iain_Vars() if b:iainlist == 0 " No list. return " " elseif b:iainlist == 1 " Just tabs. return "_" else " Full list. return "\$" endif endfun " Helper for status line. " Show c or C to denote case-sensitivity. fun! Show_Case() if &ic return "c" else return "C" endif endfun " Helper for status line. " Show the size of the tabstop. fun! Show_Tabstop() return &ts endfun " Helper for status line. " Show p when paste mode is on. fun! Show_Paste() if &paste return "p" else return "" endif endfun " Show the window title. fun! Show_TitleString() if bufname("") == "" let l:ts1='Vim' else let l:ts1=printf("%2d: %s", bufnr(""), expand('%t')) endif return printf("%s (%s) %s", l:ts1, getcwd(), v:servername) endfun " Show the status line. fun! Show_StatusLine() call Iain_Vars() let l:sl1='%2n\:\ %<%f\ [%{Show_List()}%{Show_Case()}%{Show_Tabstop()}%{Show_Paste()}%Y%M%R]\ %=' let l:sl3='L:%4.6l/%-4.6L\ C:%3.6c\ \|\ %P' let l:hexformat='%b' if b:iainhex let l:hexformat='0\x%02B' endif if b:iainverbose let l:sl2=l:hexformat . '\ \|\ P:%4.6o\ ' else let l:sl2='' endif exec "set statusline=" . l:sl1 . l:sl2 . l:sl3 endfun " Toggle case-sensitivity. fun! Invert_Case() let &ic = ! &ic endfun " Grow or shrink the window size. fun! Resize_Columns(op, ...) if a:0 == 0 " Vim 5 hardcodes the size of numbers column to 8. if version >= "700" let l:columns = &numberwidth else let l:columns = 8 endif else let l:columns = a:1 endif exe "let l:resize=" . &columns . a:op . l:columns let l:resize = "se columns=" . l:resize " HACK: Inside screen there is an extra line for the status bar. Vim " manages the resize by sending an escape sequence to set the number of " lines and number of columns in one action. To do this it will first query " the number of lines and then set by . Because of the extra line for the status bar this results in " the real terminal being shrunk by a line. We ask for the terminal to grow " by a line so it ends up actually being the same. if &term =~ '^screen' let l:resize = l:resize . " lines=" . (&lines + 1) endif exe l:resize endfun " Toggle number display. fun! Number(resize) call Iain_Vars() let &number = ! &number if version >= "700" let l:i = 0 let l:num_numbers = 0 while l:i <= winnr("$") if getwinvar(l:i, "&number") == 1 let l:num_numbers = l:num_numbers + 1 endif let l:i = l:i + 1 endwhile if l:num_numbers == 0 let g:iainextracolumns = 0 if a:resize call Resize_Columns("-") endif elseif g:iainextracolumns == 0 let g:iainextracolumns = 1 if a:resize call Resize_Columns("+") endif endif endif endfun " Restore window size. au Display VimLeave * if exists("g:oldcols") | call Resize_Columns("-", (&columns - g:oldcols)) | endif " Map Makefile mode. au Mode BufEnter * if &ft == "make" | call MakeMode_map() | endif au Mode BufLeave * if &ft == "make" | call MakeMode_unmap() | endif " Entering Make mode. fun! MakeMode_map() call Iain_Vars() let b:iainlist=1 call Cycle_List() set ts=8 set noexpandtab endfun " Leaving Make mode. fun! MakeMode_unmap() call Cycle_List() set ts=2 set expandtab endfun " Show the status line for the first time. call Show_StatusLine() " Function to create mappings with either a hardcoded \ or . fun! Mapping(keysequence,mapping) if version < "600" exec "map \\" . a:keysequence . " " . a:mapping else exec "map " . a:keysequence . " " . a:mapping endif endfun " Use - and = to create underlines. call Mapping("-", "yyp:s/./-/g:let @/='':") call Mapping("=", "yyp:s/./=/g:let @/='':") " Change to ts=2 with \2. call Mapping("2", ":se ts=2:") " Change to ts=4 with \4. call Mapping("4", ":se ts=4:") " Change to ts=8 with \8. call Mapping("8", ":se ts=8:") " Change to ts=16 with \6. call Mapping("6", ":se ts=16:") " Change to ts=32 with \3. call Mapping("3", ":se ts=32:") " Toggle paste mode with \p. call Mapping("p", ":se paste!:") " Swap case-sensitivity with \c. call Mapping("c", ":call Invert_Case():") " Change number mode with \n. call Mapping("n", ":call Number(1):") " Expand or shrink window size with \> and \<. call Mapping(">", ":call Resize_Columns('+'):") call Mapping("<", ":call Resize_Columns('-'):") " Clear search pattern with \/. call Mapping("/", ":let @/=\"\":") " Forget the Ex mode mapping. map Q " Vim tip 99: What's the highlighting group under the cursor? call Mapping("h", ":echo \"hi<\" . synIDattr(synID(line(\".\"),col(\".\"),1),\"name\") . '> trans<' . synIDattr(synID(line(\".\"),col(\".\"),0),\"name\") . \"> lo<\" . synIDattr(synIDtrans(synID(line(\".\"),col(\".\"),1)),\"name\") . \">\"") fun! Startup_Resize() let l:columns = 0 " Resize for numbers. if &number if version >= "700" let l:columns = &numberwidth else let l:columns = 8 endif endif " Resize for signs. if has("signs") if g:marksigns if version >= "600" let l:columns = l:columns + 2 endif endif endif if g:oldcols < (80 + l:columns) call Resize_Columns("+", l:columns) endif endfun " Show numbers by default. au Display VimEnter * call Number(0) " Resize after startup. au Display VimEnter * call Startup_Resize() endif """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " Handle options only available in Vim 6 and above. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" if version >= "600" version 6.0 " Remember quickfix state. let g:quickfixing=0 " Set indenting by filetype. filetype indent on " Less intrusive syntax highlighting. syn enable " Set colours. if has("gui_running") try if has("win32") se guifont=DejaVu_Sans_Mono:h10:cANSI else se guifont=DejaVu\ Sans\ Mono\ 10 endif catch endtry endif if has("gui_running") || &t_Co > 16 try colo iain catch endtry endif " Ignore whitespace when diffing. se diffopt=filler,iwhite " Expand window when doing a vertical diff. if &diff let &columns = 164 endif " Remember that we are opening the quickfix window. au Mode BufWinEnter quickfix let g:quickfixing=1 au Mode BufUnload * if &ft == "qf" | let g:quickfixing=0 | endif " Allow in-place editing of crontabs. au Mode FileType crontab set backupcopy=yes " Make * and # work the way you expect in visual mode. vnoremap * y/\V=substitute(escape(@@,"/\\"),"\n","\\\\n","ge") vnoremap # y?\V=substitute(escape(@@,"?\\"),"\n","\\\\n","ge") " Set mark and update highlighting. if has("signs") au Signs BufEnter * call Highlight_Signs() au Signs CursorHold * call Highlight_Signs() endif fun! Prep_Signs() if ! exists("b:signdot") || ! g:marksigns let b:signdot=0 endif if ! exists("b:signdash") || ! g:marksigns let b:signdash=0 endif if ! exists("b:signquote") || ! g:marksigns let b:signquote=0 endif if ! exists("b:signcaret") || ! g:marksigns let b:signcaret=0 endif if ! exists("b:signless") || ! g:marksigns let b:signless=0 endif if ! exists("b:signgreater") || ! g:marksigns let b:signgreater=0 endif if ! exists("b:signleft") || ! g:marksigns let b:signleft=0 endif if ! exists("b:signright") || ! g:marksigns let b:signright=0 endif if ! exists("b:signa") || ! g:marksigns let b:signa=0 endif if ! exists("b:signb") || ! g:marksigns let b:signb=0 endif if ! exists("b:signc") || ! g:marksigns let b:signc=0 endif if ! exists("b:signd") || ! g:marksigns let b:signd=0 endif if ! exists("b:signe") || ! g:marksigns let b:signe=0 endif if ! exists("b:signf") || ! g:marksigns let b:signf=0 endif if ! exists("b:signA") || ! g:marksigns let b:signA=0 endif if ! exists("b:signB") || ! g:marksigns let b:signB=0 endif if ! exists("b:signC") || ! g:marksigns let b:signC=0 endif if ! exists("b:signD") || ! g:marksigns let b:signD=0 endif if ! exists("b:signE") || ! g:marksigns let b:signE=0 endif if ! exists("b:signF") || ! g:marksigns let b:signF=0 endif endfun! fun! Place_Sign(number, line, old, name) if a:line == a:old return a:old endif exe "sign unplace " . (g:firstsign + a:number) . " buffer=" . bufnr("") " Don't place the sign if it would conflict with the last change sign. exe "sign place " . (g:firstsign + a:number) . " line=" . a:line . " name=" . a:name . " buffer=" . bufnr("") return a:line endfun fun! Highlight_Signs(...) if ! has("signs") || ! g:marksigns return endif call Prep_Signs() let b:signdot = Place_Sign(0, line("'."), b:signdot, "MarkDot") let b:signdash = Place_Sign(1, line("''"), b:signdash, "MarkDash") let b:signquote = Place_Sign(2, line("'\""), b:signquote, "MarkQuote") let b:signcaret = Place_Sign(3, line("'^"), b:signcaret, "MarkCaret") let b:signless = Place_Sign(4, line("'<"), b:signcaret, "MarkLess") let b:signgreater = Place_Sign(5, line("'>"), b:signcaret, "MarkGreater") let b:signleft = Place_Sign(6, line("'["), b:signcaret, "MarkLeft") let b:signright = Place_Sign(7, line("']"), b:signcaret, "MarkRight") let b:signa = Place_Sign(8, line("'a"), b:signa, "Marka") let b:signb = Place_Sign(9, line("'b"), b:signb, "Markb") let b:signc = Place_Sign(10, line("'c"), b:signc, "Markc") let b:signd = Place_Sign(11, line("'d"), b:signd, "Markd") let b:signe = Place_Sign(12, line("'e"), b:signe, "Marke") let b:signf = Place_Sign(13, line("'f"), b:signf, "Markf") let b:signA = Place_Sign(14, line("'A"), b:signA, "MarkA") let b:signB = Place_Sign(15, line("'B"), b:signB, "MarkB") let b:signC = Place_Sign(16, line("'C"), b:signC, "MarkC") let b:signD = Place_Sign(17, line("'D"), b:signD, "MarkD") let b:signE = Place_Sign(18, line("'E"), b:signE, "MarkE") let b:signF = Place_Sign(19, line("'F"), b:signF, "MarkF") endfun " Toggle signs. fun! Cycle_Signs(resize) if ! has("signs") return endif call Iain_Vars() let g:marksigns = ! g:marksigns if g:marksigns " Signs to highlight marks. " Syntax won't work properly in Vim 6. sign define MarkDash text=' texthl=MarkSign sign define MarkDot text=* texthl=MarkDot sign define MarkQuote text=" texthl=MarkSign sign define MarkCaret text=^ texthl=MarkSign sign define MarkLess text=< texthl=MarkSign sign define MarkGreater text=> texthl=MarkSign sign define MarkLeft text=[ texthl=MarkSign sign define MarkRight text=] texthl=MarkSign sign define Marka text=a texthl=MarkSign linehl=MarkLine sign define Markb text=b texthl=MarkSign linehl=MarkLine sign define Markc text=c texthl=MarkSign linehl=MarkLine sign define Markd text=d texthl=MarkSign linehl=MarkLine sign define Marke text=e texthl=MarkSign linehl=MarkLine sign define Markf text=f texthl=MarkSign linehl=MarkLine sign define MarkA text=A texthl=MarkSign linehl=MarkLine sign define MarkB text=B texthl=MarkSign linehl=MarkLine sign define MarkC text=C texthl=MarkSign linehl=MarkLine sign define MarkD text=D texthl=MarkSign linehl=MarkLine sign define MarkE text=E texthl=MarkSign linehl=MarkLine sign define MarkF text=F texthl=MarkSign linehl=MarkLine if a:resize call Resize_Columns("+", 2) endif call Highlight_Signs() else exe "sign unplace " . (g:firstsign + 0) exe "sign unplace " . (g:firstsign + 1) exe "sign unplace " . (g:firstsign + 2) exe "sign unplace " . (g:firstsign + 3) exe "sign unplace " . (g:firstsign + 4) exe "sign unplace " . (g:firstsign + 5) exe "sign unplace " . (g:firstsign + 6) exe "sign unplace " . (g:firstsign + 7) exe "sign unplace " . (g:firstsign + 8) exe "sign unplace " . (g:firstsign + 9) exe "sign unplace " . (g:firstsign + 10) exe "sign unplace " . (g:firstsign + 11) exe "sign unplace " . (g:firstsign + 12) exe "sign unplace " . (g:firstsign + 13) exe "sign unplace " . (g:firstsign + 14) exe "sign unplace " . (g:firstsign + 15) exe "sign unplace " . (g:firstsign + 16) exe "sign unplace " . (g:firstsign + 17) exe "sign unplace " . (g:firstsign + 18) exe "sign unplace " . (g:firstsign + 19) sign undefine MarkDash sign undefine MarkDot sign undefine MarkQuote sign undefine MarkCaret sign undefine MarkLess sign undefine MarkGreater sign undefine MarkLeft sign undefine MarkRight sign undefine Marka sign undefine Markb sign undefine Markc sign undefine Markd sign undefine Marke sign undefine Markf sign undefine MarkA sign undefine MarkB sign undefine MarkC sign undefine MarkD sign undefine MarkE sign undefine MarkF call Prep_Signs() if a:resize call Resize_Columns("-", 2) endif endif endfun " Change list mode. fun! Cycle_List() let basic='tab:\\_,trail:_,extends:<,precedes:>' call Iain_Vars() let b:iainlist = b:iainlist + 1 if b:iainlist > 2 let b:iainlist = 0 endif if b:iainlist == 0 set nolist elseif b:iainlist == 1 exec "set lcs=" . basic set list else exec "set lcs=" . basic . ",eol:$" set list endif endfun " Cycle between hex and decimal display of toolbar stuff. fun! Cycle_HexStatusLine() call Iain_Vars() let b:iainhex = ! b:iainhex call Show_StatusLine() endfun " Cycle verbose display of toolbar stuff. fun! Cycle_VerboseStatusLine() call Iain_Vars() let b:iainverbose = ! b:iainverbose call Show_StatusLine() endfun " Toggle quickfix window. fun! Cycle_Quickfix() if g:quickfixing == 1 cclose let g:quickfixing=0 else copen endif endfun " Swap hex/decimal statusline with \x. call Mapping("x", ":call Cycle_HexStatusLine():") " Change statusline verbosity with \v. call Mapping("v", ":call Cycle_VerboseStatusLine():") " Cycle list styles with \l. call Mapping("l", ":call Cycle_List():") " Toggle tags with \t. call Mapping("t", ":Tlist") " Change foldmethod with \f. call Mapping("f", ":se foldenable!:") " Toggle quickfix window with \q. call Mapping("q", ":call Cycle_Quickfix():") " Rerun filetype detection with \s. The s is for syntax, as this will be " updated as a side-effect. call Mapping("s", ":filetype detect:") " Toggle marks with \m. call Mapping("m", ":call Cycle_Signs(1):") fun! Iain_Colour(colour) if &t_Co == 88 if a:colour == "darkblue" return 17 elseif a:colour == "darkmagenta" return 33 elseif a:colour == "darkred" return 32 elseif a:colour == "red" return 64 endif elseif &t_Co == 256 if a:colour == "darkblue" return 17 elseif a:colour == "darkmagenta" return 90 elseif a:colour == "darkred" return 88 elseif a:colour == "red" return 196 endif else return a:colour endif endfun " Change status bar colour when various things happen. " Flags: H/h: Cursor held/moved. " F/f: Focus gained/lost. " I/i: Insert mode entered/left. fun! Highlight_StatusLine(flag) " Get current status. call Iain_Vars() " Change the status based on the flag. XXX: Does Vim let us to do flags? let re = "[" . tolower(a:flag) . toupper(a:flag) . "]" let b:iainstatus = substitute(b:iainstatus, re, a:flag, "") let l:normalcolour = "darkblue" let l:editingcolour = "darkmagenta" let l:warningcolour = "darkred" let l:readonlycolour = "red" " Default colour. let l:colour = l:normalcolour " Maybe override depending on status. if b:iainstatus =~# "H" if b:iainstatus =~# "I" " Held in insert mode. Add extra highlight if we don't have focus. if b:iainstatus =~# "f" let l:colour = l:warningcolour else let l:colour = l:editingcolour endif endif else if b:iainstatus =~# "I" " Regular insert mode. let l:colour = l:editingcolour endif endif " Override again if readonly. if l:colour != l:normalcolour if getbufvar("", "&ro") let l:colour = l:readonlycolour endif endif let l:termcolour = Iain_Colour(l:colour) exec "highlight StatusLine gui=bold term=bold cterm=bold guifg=white guibg=" . l:colour . " ctermfg=white ctermbg=" . l:termcolour endfun au Display VimEnter * call Highlight_StatusLine("") " Show signs by default. au Display VimEnter * call Cycle_Signs(0) endif """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " Handle options only available in Vim 7 and above. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" if version >= "700" version 7.0 " Helper to show tab name. fun! TabName(label, gui) let l:label = a:label if l:label == "" let l:label = "No Name" if a:gui let l:label = "[" . l:label . "]" endif else let l:label = fnamemodify(l:label, ":t") if strlen(l:label) >= 18 let l:label = l:label[0:17] . ".." endif endif return l:label endfun " Find out if any buffer was modified. fun! TabModified(buflist) let l:i = 0 while i < len(a:buflist) if getbufvar(a:buflist[l:i], "&modified") == 1 return "+" endif let l:i = l:i + 1 endwhile return "" endfun " Tab line. fun! Show_TabLine() let l:s = "%#TabLineFill#Tabs:" let l:i = 0 while l:i < tabpagenr("$") let l:i = l:i + 1 " Get the label. let l:buflist = tabpagebuflist(l:i) let l:winnr = tabpagewinnr(l:i) let l:n = tabpagewinnr(l:i, "$") let l:label = TabName(bufname(l:buflist[l:winnr - 1]), 0) let l:modified = TabModified(l:buflist) " Choose highlighting. if l:i == tabpagenr() let l:s .= "%#TabLineSel#[" . l:n . l:modified . " " . l:label . "]" else let l:s .= "%#TabLine# " . l:n . l:modified . " " . l:label . " " endif endwhile " Padding. let l:s .= "%#TabLine#%T" return l:s endfun " Per tab label for the GUI. fun! Show_GUITabLine() let l:buflist = tabpagebuflist(v:lnum) let l:winnr = tabpagewinnr(v:lnum) let l:s = tabpagewinnr(v:lnum, "$") let l:label = TabName(bufname(l:buflist[l:winnr - 1]), 1) let l:modified = TabModified(l:buflist) let l:s .= l:modified . " " . l:label return l:s endfun se tabline=%!Show_TabLine() se guitablabel=%!Show_GUITabLine() au StatusLine CursorHoldI * call Highlight_StatusLine("H") au StatusLine CursorMovedI * call Highlight_StatusLine("h") au StatusLine FocusGained * call Highlight_StatusLine("F") au StatusLine FocusLost * call Highlight_StatusLine("f") au StatusLine InsertEnter * call Highlight_StatusLine("I") au StatusLine InsertLeave * call Highlight_StatusLine("i") if has("signs") au Signs InsertEnter * call Highlight_Signs() au Signs InsertLeave * call Highlight_Signs() endif " Limit the size of the popup menu when completing. se pumheight=20 " Make diffs vertical by default. se diffopt+=vertical " Set size of numbers column. se numberwidth=5 " Add "previous tab" mapping as gb. map gb :tabprevious: " Transparency. if has("gui_macvim") se transparency=15 endif " Yet more GUI options. Add tabs. se go+=e " Perforce. let g:p4EnableMenu=1 let g:p4Presets='P4CONFIG' endif