1 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
2 " Multi-version vimrc compatible with version 4 and above.
3 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
5 " Note that "if <condition> | call Something() | endif" syntax is unsupported
6 " in Vim 4 so we write all our functions out the long way. It does work in
7 " autocommand definitions, however.
9 " Vim 4 complains if version isn't set in the configuration file.
12 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
13 " Handle options safe to use in version 4. Vim 4 parses but ignores the
14 " "if version" syntax used later in this file so we don't use it. No attempt
15 " is made to make this configuration compatible with Vim 3.
16 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
17 " No compatibility mode.
22 " And use spaces not tabs.
24 " And << and >> indent by 2.
27 " Allow backspace to delete before start of line.
32 " Show partial commands in the ruler.
34 " And always show the status line.
39 se cinkeys=0{,0},0),:,!^F,o,O,e
45 " Don't be bugged by messages at the bottom of the screen.
51 " Case-insensitive search.
53 " But override by typing capitals.
56 " Look for ctags in home directory first.
57 se tags=~/.tags,./tags,tags
59 " Don't timeout waiting to interpet, eg, <ESC>OA as an escape code.
62 " Use ^B to search backward when completing.
64 " Use ^L to show matching completions but don't select one.
65 inoremap <C-l> <C-n><C-p>
67 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
68 " Handle options only available in Vim 5 and above.
69 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
73 " Tell Vim we use dark backgrounds in our terminals.
74 if ! has("gui_running")
78 " Allow mouse use in a terminal but only if it can work.
79 if has("xterm_clipboard")
83 " Update more quickly. For use with sign highlighting as polling for
84 " CursorMove makes redrawing slow.
89 " Enable tab-completion prompting for commands.
91 " Don't list object files when globbing files to load.
92 se wildignore+=*.o,*.obj
93 " So there's no need to assign them low priority.
94 se suffixes-=*.o,*.obj
96 " Save sessions in UNIX format with / as file separator. This is
100 " Nuke any pre-existing autocommands.
113 " Save the current window width so we can restore it when we quit.
114 if ! exists("g:oldcols")
115 let g:oldcols=&columns
118 " More GUI options. Add icon and tearoffs.
122 " Allow dynamic window resize even if we aren't in an xterm.
123 se t_WS=
\e[8;%p1%d;%p2%dt
125 " Highlight search results.
128 " Set graphical window title.
129 se titlestring=%{Show_TitleString()}
131 " Syntax highlighting. New versions will use syn enable instead.
141 " Set up our variables.
143 if ! exists("b:iainlist")
146 if ! exists("b:iainhex")
149 if ! exists("b:iainverbose")
150 let b:iainverbose = 0
152 if ! exists("b:iainstatus")
153 " Window Flags: (F)ocused, (I)nsert mode, Cursor (H)old.
154 let b:iainstatus = "Fih"
156 if ! exists("g:iainextracolumns")
157 let g:iainextracolumns = 0
160 if ! exists("g:marksigns")
163 if ! exists("g:firstsign")
164 let g:firstsign = 100
169 " Helper for status line.
170 " Show space, underscore or dollar sign depending on list mode.
176 elseif b:iainlist == 1
185 " Helper for status line.
186 " Show c or C to denote case-sensitivity.
195 " Helper for status line.
196 " Show the size of the tabstop.
201 " Helper for status line.
202 " Show p when paste mode is on.
211 " Show the window title.
212 fun! Show_TitleString()
216 let l:ts1=printf("%2d: %s", bufnr(""), expand('%t'))
218 return printf("%s (%s) %s", l:ts1, getcwd(), v:servername)
221 " Show the status line.
222 fun! Show_StatusLine()
224 let l:sl1='%2n\:\ %<%f\ [%{Show_List()}%{Show_Case()}%{Show_Tabstop()}%{Show_Paste()}%Y%M%R]\ %='
225 let l:sl3='L:%4.6l/%-4.6L\ C:%3.6c\ \|\ %P'
228 let l:hexformat='0\x%02B'
231 let l:sl2=l:hexformat . '\ \|\ P:%4.6o\ '
235 exec "set statusline=" . l:sl1 . l:sl2 . l:sl3
238 " Toggle case-sensitivity.
243 " Grow or shrink the window size.
244 fun! Resize_Columns(op, ...)
246 " Vim 5 hardcodes the size of numbers column to 8.
248 let l:columns = &numberwidth
256 exe "let l:resize=" . &columns . a:op . l:columns
257 let l:resize = "se columns=" . l:resize
259 " HACK: Inside screen there is an extra line for the status bar. Vim
260 " manages the resize by sending an escape sequence to set the number of
261 " lines and number of columns in one action. To do this it will first query
262 " the number of lines and then set <same number of lines> by <new number of
263 " columns>. Because of the extra line for the status bar this results in
264 " the real terminal being shrunk by a line. We ask for the terminal to grow
265 " by a line so it ends up actually being the same.
266 if &term =~ '^screen'
267 let l:resize = l:resize . " lines=" . (&lines + 1)
273 " Toggle number display.
276 let &number = ! &number
280 let l:num_numbers = 0
281 while l:i <= winnr("$")
282 if getwinvar(l:i, "&number") == 1
283 let l:num_numbers = l:num_numbers + 1
288 if l:num_numbers == 0
289 let g:iainextracolumns = 0
291 call Resize_Columns("-")
293 elseif g:iainextracolumns == 0
294 let g:iainextracolumns = 1
296 call Resize_Columns("+")
302 " Restore window size.
303 au Display VimLeave * if exists("g:oldcols") | call Resize_Columns("-", (&columns - g:oldcols)) | endif
306 au Mode BufEnter * if &ft == "make" | call MakeMode_map() | endif
307 au Mode BufLeave * if &ft == "make" | call MakeMode_unmap() | endif
309 " Entering Make mode.
319 fun! MakeMode_unmap()
325 " Show the status line for the first time.
326 call Show_StatusLine()
328 " Function to create mappings with either a hardcoded \ or <Leader>.
329 fun! Mapping(keysequence,mapping)
331 exec "map \\" . a:keysequence . " " . a:mapping
333 exec "map <Leader>" . a:keysequence . " " . a:mapping
337 " Use - and = to create underlines.
338 call Mapping("-", "yyp:s/./-/g<RETURN>:let @/=''<RETURN>:<RETURN>")
339 call Mapping("=", "yyp:s/./=/g<RETURN>:let @/=''<RETURN>:<RETURN>")
341 " Change to ts=2 with \2.
342 call Mapping("2", ":se ts=2<CR>:<CR>")
343 " Change to ts=4 with \4.
344 call Mapping("4", ":se ts=4<CR>:<CR>")
345 " Change to ts=8 with \8.
346 call Mapping("8", ":se ts=8<CR>:<CR>")
347 " Change to ts=16 with \6.
348 call Mapping("6", ":se ts=16<CR>:<CR>")
349 " Change to ts=32 with \3.
350 call Mapping("3", ":se ts=32<CR>:<CR>")
351 " Toggle paste mode with \p.
352 call Mapping("p", ":se paste!<CR>:<CR>")
353 " Swap case-sensitivity with \c.
354 call Mapping("c", ":call Invert_Case()<CR>:<CR>")
355 " Change number mode with \n.
356 call Mapping("n", ":call Number(1)<CR>:<CR>")
357 " Expand or shrink window size with \> and \<.
358 call Mapping(">", ":call Resize_Columns('+')<CR>:<CR>")
359 call Mapping("<", ":call Resize_Columns('-')<CR>:<CR>")
360 " Clear search pattern with \/.
361 call Mapping("/", ":let @/=\"\"<CR>:<CR>")
363 " Forget the Ex mode mapping.
366 " Vim tip 99: What's the highlighting group under the cursor?
367 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\") . \">\"<CR>")
369 fun! Uncluttered_Buffer()
370 if exists("uncluttered_buffer")
371 if uncluttered_buffer == 1
390 if &ft == 'gitcommit'
397 fun! Startup_Resize()
400 " Resize for numbers.
403 let l:columns = &numberwidth
413 let l:columns = l:columns + 2
418 if g:oldcols < (80 + l:columns)
419 call Resize_Columns("+", l:columns)
423 " Show numbers by default.
424 au Display VimEnter * if ! Uncluttered_Buffer() | call Number(0) | endif
427 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
428 " Handle options only available in Vim 6 and above.
429 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
433 " Remember quickfix state.
436 " Set indenting by filetype.
439 " Less intrusive syntax highlighting.
443 if has("gui_running")
446 se guifont=DejaVu_Sans_Mono:h10:cANSI
448 se guifont=DejaVu\ Sans\ Mono\ 10
453 if has("gui_running") || &t_Co > 16
460 " Ignore whitespace when diffing.
461 se diffopt=filler,iwhite
463 " Expand window when doing a vertical diff.
468 " Remember that we are opening the quickfix window.
469 au Mode BufWinEnter quickfix let g:quickfixing=1
470 au Mode BufUnload * if &ft == "qf" | let g:quickfixing=0 | endif
472 " Allow in-place editing of crontabs.
473 au Mode FileType crontab set backupcopy=yes
475 " Make * and # work the way you expect in visual mode.
476 vnoremap * y/\V<C-R>=substitute(escape(@@,"/\\"),"\n","\\\\n","ge")<CR><CR>
477 vnoremap # y?\V<C-R>=substitute(escape(@@,"?\\"),"\n","\\\\n","ge")<CR><CR>
479 " Set mark and update highlighting.
481 au Signs BufEnter * call <SID>Highlight_Signs()
482 au Signs CursorHold * call <SID>Highlight_Signs()
485 fun! <SID>Prep_Signs()
486 if ! exists("b:signdot") || ! g:marksigns
489 if ! exists("b:signdash") || ! g:marksigns
492 if ! exists("b:signquote") || ! g:marksigns
495 if ! exists("b:signcaret") || ! g:marksigns
498 if ! exists("b:signless") || ! g:marksigns
501 if ! exists("b:signgreater") || ! g:marksigns
504 if ! exists("b:signleft") || ! g:marksigns
507 if ! exists("b:signright") || ! g:marksigns
510 if ! exists("b:signa") || ! g:marksigns
513 if ! exists("b:signb") || ! g:marksigns
516 if ! exists("b:signc") || ! g:marksigns
519 if ! exists("b:signd") || ! g:marksigns
522 if ! exists("b:signe") || ! g:marksigns
525 if ! exists("b:signf") || ! g:marksigns
528 if ! exists("b:signA") || ! g:marksigns
531 if ! exists("b:signB") || ! g:marksigns
534 if ! exists("b:signC") || ! g:marksigns
537 if ! exists("b:signD") || ! g:marksigns
540 if ! exists("b:signE") || ! g:marksigns
543 if ! exists("b:signF") || ! g:marksigns
548 fun! <SID>Place_Sign(number, line, old, name)
553 exe "sign unplace " . (g:firstsign + a:number) . " buffer=" . bufnr("")
554 " Don't place the sign if it would conflict with the last change sign.
555 exe "sign place " . (g:firstsign + a:number) . " line=" . a:line . " name=" . a:name . " buffer=" . bufnr("")
559 fun! <SID>Highlight_Signs(...)
560 if ! has("signs") || ! g:marksigns || Uncluttered_Buffer()
564 call <SID>Prep_Signs()
566 let b:signdot = <SID>Place_Sign(0, line("'."), b:signdot, "MarkDot")
567 let b:signdash = <SID>Place_Sign(1, line("''"), b:signdash, "MarkDash")
568 let b:signquote = <SID>Place_Sign(2, line("'\""), b:signquote, "MarkQuote")
569 let b:signcaret = <SID>Place_Sign(3, line("'^"), b:signcaret, "MarkCaret")
570 let b:signless = <SID>Place_Sign(4, line("'<"), b:signcaret, "MarkLess")
571 let b:signgreater = <SID>Place_Sign(5, line("'>"), b:signcaret, "MarkGreater")
572 let b:signleft = <SID>Place_Sign(6, line("'["), b:signcaret, "MarkLeft")
573 let b:signright = <SID>Place_Sign(7, line("']"), b:signcaret, "MarkRight")
575 let b:signa = <SID>Place_Sign(8, line("'a"), b:signa, "Marka")
576 let b:signb = <SID>Place_Sign(9, line("'b"), b:signb, "Markb")
577 let b:signc = <SID>Place_Sign(10, line("'c"), b:signc, "Markc")
578 let b:signd = <SID>Place_Sign(11, line("'d"), b:signd, "Markd")
579 let b:signe = <SID>Place_Sign(12, line("'e"), b:signe, "Marke")
580 let b:signf = <SID>Place_Sign(13, line("'f"), b:signf, "Markf")
581 let b:signA = <SID>Place_Sign(14, line("'A"), b:signA, "MarkA")
582 let b:signB = <SID>Place_Sign(15, line("'B"), b:signB, "MarkB")
583 let b:signC = <SID>Place_Sign(16, line("'C"), b:signC, "MarkC")
584 let b:signD = <SID>Place_Sign(17, line("'D"), b:signD, "MarkD")
585 let b:signE = <SID>Place_Sign(18, line("'E"), b:signE, "MarkE")
586 let b:signF = <SID>Place_Sign(19, line("'F"), b:signF, "MarkF")
590 fun! <SID>Cycle_Signs(resize)
595 let g:marksigns = ! g:marksigns
598 " Signs to highlight marks.
599 " Syntax won't work properly in Vim 6.
600 sign define MarkDash text=' texthl=MarkSign
601 sign define MarkDot text=* texthl=MarkDot
602 sign define MarkQuote text=" texthl=MarkSign
603 sign define MarkCaret text=^ texthl=MarkSign
604 sign define MarkLess text=< texthl=MarkSign
605 sign define MarkGreater text=> texthl=MarkSign
606 sign define MarkLeft text=[ texthl=MarkSign
607 sign define MarkRight text=] texthl=MarkSign
608 sign define Marka text=a texthl=MarkSign linehl=MarkLine
609 sign define Markb text=b texthl=MarkSign linehl=MarkLine
610 sign define Markc text=c texthl=MarkSign linehl=MarkLine
611 sign define Markd text=d texthl=MarkSign linehl=MarkLine
612 sign define Marke text=e texthl=MarkSign linehl=MarkLine
613 sign define Markf text=f texthl=MarkSign linehl=MarkLine
614 sign define MarkA text=A texthl=MarkSign linehl=MarkLine
615 sign define MarkB text=B texthl=MarkSign linehl=MarkLine
616 sign define MarkC text=C texthl=MarkSign linehl=MarkLine
617 sign define MarkD text=D texthl=MarkSign linehl=MarkLine
618 sign define MarkE text=E texthl=MarkSign linehl=MarkLine
619 sign define MarkF text=F texthl=MarkSign linehl=MarkLine
622 call Resize_Columns("+", 2)
624 call <SID>Highlight_Signs()
626 exe "sign unplace " . (g:firstsign + 0)
627 exe "sign unplace " . (g:firstsign + 1)
628 exe "sign unplace " . (g:firstsign + 2)
629 exe "sign unplace " . (g:firstsign + 3)
630 exe "sign unplace " . (g:firstsign + 4)
631 exe "sign unplace " . (g:firstsign + 5)
632 exe "sign unplace " . (g:firstsign + 6)
633 exe "sign unplace " . (g:firstsign + 7)
634 exe "sign unplace " . (g:firstsign + 8)
635 exe "sign unplace " . (g:firstsign + 9)
636 exe "sign unplace " . (g:firstsign + 10)
637 exe "sign unplace " . (g:firstsign + 11)
638 exe "sign unplace " . (g:firstsign + 12)
639 exe "sign unplace " . (g:firstsign + 13)
640 exe "sign unplace " . (g:firstsign + 14)
641 exe "sign unplace " . (g:firstsign + 15)
642 exe "sign unplace " . (g:firstsign + 16)
643 exe "sign unplace " . (g:firstsign + 17)
644 exe "sign unplace " . (g:firstsign + 18)
645 exe "sign unplace " . (g:firstsign + 19)
647 sign undefine MarkDash
648 sign undefine MarkDot
649 sign undefine MarkQuote
650 sign undefine MarkCaret
651 sign undefine MarkLess
652 sign undefine MarkGreater
653 sign undefine MarkLeft
654 sign undefine MarkRight
668 call <SID>Prep_Signs()
670 call Resize_Columns("-", 2)
677 let basic='tab:\\_,trail:_,extends:<,precedes:>'
679 let b:iainlist = b:iainlist + 1
685 elseif b:iainlist == 1
686 exec "set lcs=" . basic
689 exec "set lcs=" . basic . ",eol:$"
694 " Cycle between hex and decimal display of toolbar stuff.
695 fun! Cycle_HexStatusLine()
697 let b:iainhex = ! b:iainhex
698 call Show_StatusLine()
701 " Cycle verbose display of toolbar stuff.
702 fun! Cycle_VerboseStatusLine()
704 let b:iainverbose = ! b:iainverbose
705 call Show_StatusLine()
708 " Toggle quickfix window.
709 fun! Cycle_Quickfix()
710 if g:quickfixing == 1
718 " Swap hex/decimal statusline with \x.
719 call Mapping("x", ":call Cycle_HexStatusLine()<CR>:<CR>")
720 " Change statusline verbosity with \v.
721 call Mapping("v", ":call Cycle_VerboseStatusLine()<CR>:<CR>")
722 " Cycle list styles with \l.
723 call Mapping("l", ":call Cycle_List()<CR>:<CR>")
724 " Toggle tags with \t.
725 call Mapping("t", ":Tlist<CR>")
726 " Change foldmethod with \f.
727 call Mapping("f", ":se foldenable!<CR>:<CR>")
728 " Toggle quickfix window with \q.
729 call Mapping("q", ":call Cycle_Quickfix()<CR>:<CR>")
730 " Rerun filetype detection with \s. The s is for syntax, as this will be
731 " updated as a side-effect.
732 call Mapping("s", ":filetype detect<CR>:<CR>")
733 " Toggle marks with \m.
734 call Mapping("m", ":call <SID>Cycle_Signs(1)<CR>:<CR>")
736 fun! <SID>Iain_Colour(colour)
738 if a:colour == "darkblue"
740 elseif a:colour == "darkmagenta"
742 elseif a:colour == "darkred"
744 elseif a:colour == "red"
748 if a:colour == "darkblue"
750 elseif a:colour == "darkmagenta"
752 elseif a:colour == "darkred"
754 elseif a:colour == "red"
762 " Change status bar colour when various things happen.
763 " Flags: H/h: Cursor held/moved.
764 " F/f: Focus gained/lost.
765 " I/i: Insert mode entered/left.
766 fun! Highlight_StatusLine(flag)
767 " Get current status.
770 " Change the status based on the flag. XXX: Does Vim let us to do flags?
771 let re = "[" . tolower(a:flag) . toupper(a:flag) . "]"
772 let b:iainstatus = substitute(b:iainstatus, re, a:flag, "")
774 let l:normalcolour = "darkblue"
775 let l:editingcolour = "darkmagenta"
776 let l:warningcolour = "darkred"
777 let l:readonlycolour = "red"
780 let l:colour = l:normalcolour
781 " Maybe override depending on status.
782 if b:iainstatus =~# "H"
783 if b:iainstatus =~# "I"
784 " Held in insert mode. Add extra highlight if we don't have focus.
785 if b:iainstatus =~# "f"
786 let l:colour = l:warningcolour
788 let l:colour = l:editingcolour
792 if b:iainstatus =~# "I"
793 " Regular insert mode.
794 let l:colour = l:editingcolour
798 " Override again if readonly.
799 if l:colour != l:normalcolour
800 if getbufvar("", "&ro")
801 let l:colour = l:readonlycolour
805 let l:termcolour = <SID>Iain_Colour(l:colour)
807 exec "highlight StatusLine gui=bold term=bold cterm=bold guifg=white guibg=" . l:colour . " ctermfg=white ctermbg=" . l:termcolour
810 au Display VimEnter * call Highlight_StatusLine("")
812 " Show signs by default.
813 au Display VimEnter * call <SID>Cycle_Signs(0)
816 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
817 " Handle options only available in Vim 7 and above.
818 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
822 " Helper to show tab name.
823 fun! <SID>TabName(label, gui)
824 let l:label = a:label
826 let l:label = "No Name"
828 let l:label = "[" . l:label . "]"
831 let l:label = fnamemodify(l:label, ":t")
832 if strlen(l:label) >= 18
833 let l:label = l:label[0:17] . ".."
839 " Find out if any buffer was modified.
840 fun! <SID>TabModified(buflist)
842 while l:i < len(a:buflist)
843 if getbufvar(a:buflist[l:i], "&modified") == 1
853 let l:s = "%#TabLineFill#Tabs:"
856 while l:i < tabpagenr("$")
859 let l:buflist = tabpagebuflist(l:i)
860 let l:winnr = tabpagewinnr(l:i)
861 let l:n = tabpagewinnr(l:i, "$")
862 let l:label = <SID>TabName(bufname(l:buflist[l:winnr - 1]), 0)
863 let l:modified = <SID>TabModified(l:buflist)
865 " Choose highlighting.
866 if l:i == tabpagenr()
867 let l:s .= "%#TabLineSel#[" . l:n . l:modified . " " . l:label . "]"
869 let l:s .= "%#TabLine# " . l:n . l:modified . " " . l:label . " "
874 let l:s .= "%#TabLine#%T"
878 " Per tab label for the GUI.
879 fun! Show_GUITabLine()
880 let l:buflist = tabpagebuflist(v:lnum)
881 let l:winnr = tabpagewinnr(v:lnum)
882 let l:s = tabpagewinnr(v:lnum, "$")
883 let l:label = <SID>TabName(bufname(l:buflist[l:winnr - 1]), 1)
884 let l:modified = <SID>TabModified(l:buflist)
886 let l:s .= l:modified . " " . l:label
890 se tabline=%!Show_TabLine()
891 se guitablabel=%!Show_GUITabLine()
893 au StatusLine CursorHoldI * call Highlight_StatusLine("H")
894 au StatusLine CursorMovedI * call Highlight_StatusLine("h")
895 au StatusLine FocusGained * call Highlight_StatusLine("F")
896 au StatusLine FocusLost * call Highlight_StatusLine("f")
897 au StatusLine InsertEnter * call Highlight_StatusLine("I")
898 au StatusLine InsertLeave * call Highlight_StatusLine("i")
901 au Signs InsertEnter * call <SID>Highlight_Signs()
902 au Signs InsertLeave * call <SID>Highlight_Signs()
905 " Limit the size of the popup menu when completing.
908 " Make diffs vertical by default.
911 " Set size of numbers column.
914 " Add "previous tab" mapping as gb.
915 map gb :tabprevious<CR>:<CR>
922 " Yet more GUI options. Add tabs.
927 let g:p4Presets='P4CONFIG'
931 " Resize after startup.
932 au Display VimEnter * call Startup_Resize()