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 se rtp=~/.vim,$VIMRUNTIME
27 " And use spaces not tabs.
29 " And << and >> indent by 2.
32 " Allow backspace to delete before start of line.
37 " Show partial commands in the ruler.
39 " And always show the status line.
44 se cinkeys=0{,0},0),:,!^F,o,O,e
50 " Don't be bugged by messages at the bottom of the screen.
56 " Case-insensitive search.
58 " But override by typing capitals.
61 " Look for ctags in home directory first.
62 se tags=~/.tags,./tags,tags
64 " Don't timeout waiting to interpet, eg, <ESC>OA as an escape code.
67 " Use ^B to search backward when completing.
69 " Use ^L to show matching completions but don't select one.
70 inoremap <C-l> <C-n><C-p>
72 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
73 " Handle options only available in Vim 5 and above.
74 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
78 " Tell Vim we use dark backgrounds in our terminals.
79 if ! has("gui_running")
83 " Allow mouse use in a terminal but only if it can work.
84 if has("xterm_clipboard")
88 " Update more quickly. For use with sign highlighting as polling for
89 " CursorMove makes redrawing slow.
94 " Enable tab-completion prompting for commands.
96 " Don't list object files when globbing files to load.
97 se wildignore+=*.o,*.obj
98 " So there's no need to assign them low priority.
99 se suffixes-=*.o,*.obj
101 " Save sessions in UNIX format with / as file separator. This is
105 " Nuke any pre-existing autocommands.
118 " Save the current window width so we can restore it when we quit.
119 if ! exists("g:oldcols")
120 let g:oldcols=&columns
123 " More GUI options. Add icon and tearoffs.
127 " Allow dynamic window resize even if we aren't in an xterm.
128 se t_WS=
\e[8;%p1%d;%p2%dt
130 " Highlight search results.
133 " Set graphical window title.
134 se titlestring=%{Show_TitleString()}
136 " Syntax highlighting. New versions will use syn enable instead.
146 " Set up our variables.
148 if ! exists("b:iainlist")
151 if ! exists("b:iainhex")
154 if ! exists("b:iainverbose")
155 let b:iainverbose = 0
157 if ! exists("b:iainstatus")
158 " Window Flags: (F)ocused, (I)nsert mode, Cursor (H)old.
159 let b:iainstatus = "Fih"
161 if ! exists("g:iainextracolumns")
162 let g:iainextracolumns = 0
165 if ! exists("g:marksigns")
168 if ! exists("g:firstsign")
169 let g:firstsign = 100
174 " Helper for status line.
175 " Show space, underscore or dollar sign depending on list mode.
181 elseif b:iainlist == 1
190 " Helper for status line.
191 " Show c or C to denote case-sensitivity.
200 " Helper for status line.
201 " Show the size of the tabstop.
206 " Helper for status line.
207 " Show p when paste mode is on.
216 " Show the window title.
217 fun! Show_TitleString()
221 let l:ts1=printf("%2d: %s", bufnr(""), expand('%t'))
223 return printf("%s (%s) %s", l:ts1, getcwd(), v:servername)
226 " Show the status line.
227 fun! Show_StatusLine()
229 let l:sl1='%2n\:\ %<%f\ [%{Show_List()}%{Show_Case()}%{Show_Tabstop()}%{Show_Paste()}%Y%M%R]\ %='
230 let l:sl3='L:%4.6l/%-4.6L\ C:%3.6c\ \|\ %P'
233 let l:hexformat='0\x%02B'
236 let l:sl2=l:hexformat . '\ \|\ P:%4.6o\ '
240 exec "set statusline=" . l:sl1 . l:sl2 . l:sl3
243 " Toggle case-sensitivity.
248 " Grow or shrink the window size.
249 fun! Resize_Columns(op, ...)
251 " Vim 5 hardcodes the size of numbers column to 8.
253 let l:columns = &numberwidth
261 exe "let l:resize=" . &columns . a:op . l:columns
262 let l:resize = "se columns=" . l:resize
264 " HACK: Inside screen there is an extra line for the status bar. Vim
265 " manages the resize by sending an escape sequence to set the number of
266 " lines and number of columns in one action. To do this it will first query
267 " the number of lines and then set <same number of lines> by <new number of
268 " columns>. Because of the extra line for the status bar this results in
269 " the real terminal being shrunk by a line. We ask for the terminal to grow
270 " by a line so it ends up actually being the same.
271 if &term =~ '^screen'
272 let l:resize = l:resize . " lines=" . (&lines + 1)
278 " Toggle number display.
281 let &number = ! &number
285 let l:num_numbers = 0
286 while l:i <= winnr("$")
287 if getwinvar(l:i, "&number") == 1
288 let l:num_numbers = l:num_numbers + 1
293 if l:num_numbers == 0
294 let g:iainextracolumns = 0
296 call Resize_Columns("-")
298 elseif g:iainextracolumns == 0
299 let g:iainextracolumns = 1
301 call Resize_Columns("+")
307 " Restore window size.
308 au Display VimLeave * if exists("g:oldcols") | call Resize_Columns("-", (&columns - g:oldcols)) | endif
311 au Mode BufEnter * if &ft == "make" | call MakeMode_map() | endif
312 au Mode BufLeave * if &ft == "make" | call MakeMode_unmap() | endif
314 " Entering Make mode.
324 fun! MakeMode_unmap()
330 " Show the status line for the first time.
331 call Show_StatusLine()
333 " Function to create mappings with either a hardcoded \ or <Leader>.
334 fun! Mapping(keysequence,mapping)
336 exec "map \\" . a:keysequence . " " . a:mapping
338 exec "map <Leader>" . a:keysequence . " " . a:mapping
342 " Use - and = to create underlines.
343 call Mapping("-", "yyp:s/./-/g<RETURN>:let @/=''<RETURN>:<RETURN>")
344 call Mapping("=", "yyp:s/./=/g<RETURN>:let @/=''<RETURN>:<RETURN>")
346 " Change to ts=2 with \2.
347 call Mapping("2", ":se ts=2<CR>:<CR>")
348 " Change to ts=4 with \4.
349 call Mapping("4", ":se ts=4<CR>:<CR>")
350 " Change to ts=8 with \8.
351 call Mapping("8", ":se ts=8<CR>:<CR>")
352 " Change to ts=16 with \6.
353 call Mapping("6", ":se ts=16<CR>:<CR>")
354 " Change to ts=32 with \3.
355 call Mapping("3", ":se ts=32<CR>:<CR>")
356 " Toggle paste mode with \p.
357 call Mapping("p", ":se paste!<CR>:<CR>")
358 " Swap case-sensitivity with \c.
359 call Mapping("c", ":call Invert_Case()<CR>:<CR>")
360 " Change number mode with \n.
361 call Mapping("n", ":call Number(1)<CR>:<CR>")
362 " Expand or shrink window size with \> and \<.
363 call Mapping(">", ":call Resize_Columns('+')<CR>:<CR>")
364 call Mapping("<", ":call Resize_Columns('-')<CR>:<CR>")
365 " Clear search pattern with \/.
366 call Mapping("/", ":let @/=\"\"<CR>:<CR>")
368 " Forget the Ex mode mapping.
371 " Vim tip 99: What's the highlighting group under the cursor?
372 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>")
374 fun! Uncluttered_Buffer()
375 if exists("uncluttered_buffer")
376 if uncluttered_buffer == 1
395 if &ft == 'gitcommit'
402 fun! Startup_Resize()
405 " Resize for numbers.
408 let l:columns = &numberwidth
418 let l:columns = l:columns + 2
423 if g:oldcols < (80 + l:columns)
424 call Resize_Columns("+", l:columns)
428 " Show numbers by default.
429 au Display VimEnter * if ! Uncluttered_Buffer() | call Number(0) | endif
432 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
433 " Handle options only available in Vim 6 and above.
434 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
438 " Remember quickfix state.
441 " Set indenting by filetype.
444 " Less intrusive syntax highlighting.
448 if has("gui_running")
451 se guifont=DejaVu_Sans_Mono:h10:cANSI
453 se guifont=DejaVu\ Sans\ Mono\ 10
458 if has("gui_running") || &t_Co > 16
465 " Ignore whitespace when diffing.
466 se diffopt=filler,iwhite
468 " Expand window when doing a vertical diff.
473 " Remember that we are opening the quickfix window.
474 au Mode BufWinEnter quickfix let g:quickfixing=1
475 au Mode BufUnload * if &ft == "qf" | let g:quickfixing=0 | endif
477 " Allow in-place editing of crontabs.
478 au Mode FileType crontab set backupcopy=yes
480 " Make * and # work the way you expect in visual mode.
481 vnoremap * y/\V<C-R>=substitute(escape(@@,"/\\"),"\n","\\\\n","ge")<CR><CR>
482 vnoremap # y?\V<C-R>=substitute(escape(@@,"?\\"),"\n","\\\\n","ge")<CR><CR>
484 " Set mark and update highlighting.
486 au Signs BufEnter * call <SID>Highlight_Signs()
487 au Signs CursorHold * call <SID>Highlight_Signs()
490 fun! <SID>Prep_Signs()
491 if ! exists("b:signdot") || ! g:marksigns
494 if ! exists("b:signdash") || ! g:marksigns
497 if ! exists("b:signquote") || ! g:marksigns
500 if ! exists("b:signcaret") || ! g:marksigns
503 if ! exists("b:signless") || ! g:marksigns
506 if ! exists("b:signgreater") || ! g:marksigns
509 if ! exists("b:signleft") || ! g:marksigns
512 if ! exists("b:signright") || ! g:marksigns
515 if ! exists("b:signa") || ! g:marksigns
518 if ! exists("b:signb") || ! g:marksigns
521 if ! exists("b:signc") || ! g:marksigns
524 if ! exists("b:signd") || ! g:marksigns
527 if ! exists("b:signe") || ! g:marksigns
530 if ! exists("b:signf") || ! g:marksigns
533 if ! exists("b:signA") || ! g:marksigns
536 if ! exists("b:signB") || ! g:marksigns
539 if ! exists("b:signC") || ! g:marksigns
542 if ! exists("b:signD") || ! g:marksigns
545 if ! exists("b:signE") || ! g:marksigns
548 if ! exists("b:signF") || ! g:marksigns
553 fun! <SID>Place_Sign(number, line, old, name)
558 exe "sign unplace " . (g:firstsign + a:number) . " buffer=" . bufnr("")
559 " Don't place the sign if it would conflict with the last change sign.
560 exe "sign place " . (g:firstsign + a:number) . " line=" . a:line . " name=" . a:name . " buffer=" . bufnr("")
564 fun! <SID>Highlight_Signs(...)
565 if ! has("signs") || ! g:marksigns || Uncluttered_Buffer()
569 call <SID>Prep_Signs()
571 let b:signdot = <SID>Place_Sign(0, line("'."), b:signdot, "MarkDot")
572 let b:signdash = <SID>Place_Sign(1, line("''"), b:signdash, "MarkDash")
573 let b:signquote = <SID>Place_Sign(2, line("'\""), b:signquote, "MarkQuote")
574 let b:signcaret = <SID>Place_Sign(3, line("'^"), b:signcaret, "MarkCaret")
575 let b:signless = <SID>Place_Sign(4, line("'<"), b:signcaret, "MarkLess")
576 let b:signgreater = <SID>Place_Sign(5, line("'>"), b:signcaret, "MarkGreater")
577 let b:signleft = <SID>Place_Sign(6, line("'["), b:signcaret, "MarkLeft")
578 let b:signright = <SID>Place_Sign(7, line("']"), b:signcaret, "MarkRight")
580 let b:signa = <SID>Place_Sign(8, line("'a"), b:signa, "Marka")
581 let b:signb = <SID>Place_Sign(9, line("'b"), b:signb, "Markb")
582 let b:signc = <SID>Place_Sign(10, line("'c"), b:signc, "Markc")
583 let b:signd = <SID>Place_Sign(11, line("'d"), b:signd, "Markd")
584 let b:signe = <SID>Place_Sign(12, line("'e"), b:signe, "Marke")
585 let b:signf = <SID>Place_Sign(13, line("'f"), b:signf, "Markf")
586 let b:signA = <SID>Place_Sign(14, line("'A"), b:signA, "MarkA")
587 let b:signB = <SID>Place_Sign(15, line("'B"), b:signB, "MarkB")
588 let b:signC = <SID>Place_Sign(16, line("'C"), b:signC, "MarkC")
589 let b:signD = <SID>Place_Sign(17, line("'D"), b:signD, "MarkD")
590 let b:signE = <SID>Place_Sign(18, line("'E"), b:signE, "MarkE")
591 let b:signF = <SID>Place_Sign(19, line("'F"), b:signF, "MarkF")
595 fun! <SID>Cycle_Signs(resize)
600 let g:marksigns = ! g:marksigns
603 " Signs to highlight marks.
604 " Syntax won't work properly in Vim 6.
605 sign define MarkDash text=' texthl=MarkSign
606 sign define MarkDot text=* texthl=MarkDot
607 sign define MarkQuote text=" texthl=MarkSign
608 sign define MarkCaret text=^ texthl=MarkSign
609 sign define MarkLess text=< texthl=MarkSign
610 sign define MarkGreater text=> texthl=MarkSign
611 sign define MarkLeft text=[ texthl=MarkSign
612 sign define MarkRight text=] texthl=MarkSign
613 sign define Marka text=a texthl=MarkSign linehl=MarkLine
614 sign define Markb text=b texthl=MarkSign linehl=MarkLine
615 sign define Markc text=c texthl=MarkSign linehl=MarkLine
616 sign define Markd text=d texthl=MarkSign linehl=MarkLine
617 sign define Marke text=e texthl=MarkSign linehl=MarkLine
618 sign define Markf text=f texthl=MarkSign linehl=MarkLine
619 sign define MarkA text=A texthl=MarkSign linehl=MarkLine
620 sign define MarkB text=B texthl=MarkSign linehl=MarkLine
621 sign define MarkC text=C texthl=MarkSign linehl=MarkLine
622 sign define MarkD text=D texthl=MarkSign linehl=MarkLine
623 sign define MarkE text=E texthl=MarkSign linehl=MarkLine
624 sign define MarkF text=F texthl=MarkSign linehl=MarkLine
627 call Resize_Columns("+", 2)
629 call <SID>Highlight_Signs()
631 exe "sign unplace " . (g:firstsign + 0)
632 exe "sign unplace " . (g:firstsign + 1)
633 exe "sign unplace " . (g:firstsign + 2)
634 exe "sign unplace " . (g:firstsign + 3)
635 exe "sign unplace " . (g:firstsign + 4)
636 exe "sign unplace " . (g:firstsign + 5)
637 exe "sign unplace " . (g:firstsign + 6)
638 exe "sign unplace " . (g:firstsign + 7)
639 exe "sign unplace " . (g:firstsign + 8)
640 exe "sign unplace " . (g:firstsign + 9)
641 exe "sign unplace " . (g:firstsign + 10)
642 exe "sign unplace " . (g:firstsign + 11)
643 exe "sign unplace " . (g:firstsign + 12)
644 exe "sign unplace " . (g:firstsign + 13)
645 exe "sign unplace " . (g:firstsign + 14)
646 exe "sign unplace " . (g:firstsign + 15)
647 exe "sign unplace " . (g:firstsign + 16)
648 exe "sign unplace " . (g:firstsign + 17)
649 exe "sign unplace " . (g:firstsign + 18)
650 exe "sign unplace " . (g:firstsign + 19)
652 sign undefine MarkDash
653 sign undefine MarkDot
654 sign undefine MarkQuote
655 sign undefine MarkCaret
656 sign undefine MarkLess
657 sign undefine MarkGreater
658 sign undefine MarkLeft
659 sign undefine MarkRight
673 call <SID>Prep_Signs()
675 call Resize_Columns("-", 2)
682 let basic='tab:\\_,trail:_,extends:<,precedes:>'
684 let b:iainlist = b:iainlist + 1
690 elseif b:iainlist == 1
691 exec "set lcs=" . basic
694 exec "set lcs=" . basic . ",eol:$"
699 " Cycle between hex and decimal display of toolbar stuff.
700 fun! Cycle_HexStatusLine()
702 let b:iainhex = ! b:iainhex
703 call Show_StatusLine()
706 " Cycle verbose display of toolbar stuff.
707 fun! Cycle_VerboseStatusLine()
709 let b:iainverbose = ! b:iainverbose
710 call Show_StatusLine()
713 " Toggle quickfix window.
714 fun! Cycle_Quickfix()
715 if g:quickfixing == 1
723 " Swap hex/decimal statusline with \x.
724 call Mapping("x", ":call Cycle_HexStatusLine()<CR>:<CR>")
725 " Change statusline verbosity with \v.
726 call Mapping("v", ":call Cycle_VerboseStatusLine()<CR>:<CR>")
727 " Cycle list styles with \l.
728 call Mapping("l", ":call Cycle_List()<CR>:<CR>")
729 " Toggle tags with \t.
730 call Mapping("t", ":Tlist<CR>")
731 " Change foldmethod with \f.
732 call Mapping("f", ":se foldenable!<CR>:<CR>")
733 " Toggle quickfix window with \q.
734 call Mapping("q", ":call Cycle_Quickfix()<CR>:<CR>")
735 " Rerun filetype detection with \s. The s is for syntax, as this will be
736 " updated as a side-effect.
737 call Mapping("s", ":filetype detect<CR>:<CR>")
738 " Toggle marks with \m.
739 call Mapping("m", ":call <SID>Cycle_Signs(1)<CR>:<CR>")
741 fun! <SID>Iain_Colour(colour)
743 if a:colour == "darkblue"
745 elseif a:colour == "darkmagenta"
747 elseif a:colour == "darkred"
749 elseif a:colour == "red"
753 if a:colour == "darkblue"
755 elseif a:colour == "darkmagenta"
757 elseif a:colour == "darkred"
759 elseif a:colour == "red"
767 " Change status bar colour when various things happen.
768 " Flags: H/h: Cursor held/moved.
769 " F/f: Focus gained/lost.
770 " I/i: Insert mode entered/left.
771 fun! Highlight_StatusLine(flag)
772 " Get current status.
775 " Change the status based on the flag. XXX: Does Vim let us to do flags?
776 let re = "[" . tolower(a:flag) . toupper(a:flag) . "]"
777 let b:iainstatus = substitute(b:iainstatus, re, a:flag, "")
779 let l:normalcolour = "darkblue"
780 let l:editingcolour = "darkmagenta"
781 let l:warningcolour = "darkred"
782 let l:readonlycolour = "red"
785 let l:colour = l:normalcolour
786 " Maybe override depending on status.
787 if b:iainstatus =~# "H"
788 if b:iainstatus =~# "I"
789 " Held in insert mode. Add extra highlight if we don't have focus.
790 if b:iainstatus =~# "f"
791 let l:colour = l:warningcolour
793 let l:colour = l:editingcolour
797 if b:iainstatus =~# "I"
798 " Regular insert mode.
799 let l:colour = l:editingcolour
803 " Override again if readonly.
804 if l:colour != l:normalcolour
805 if getbufvar("", "&ro")
806 let l:colour = l:readonlycolour
810 let l:termcolour = <SID>Iain_Colour(l:colour)
812 exec "highlight StatusLine gui=bold term=bold cterm=bold guifg=white guibg=" . l:colour . " ctermfg=white ctermbg=" . l:termcolour
815 au Display VimEnter * call Highlight_StatusLine("")
817 " Show signs by default.
818 au Display VimEnter * call <SID>Cycle_Signs(0)
821 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
822 " Handle options only available in Vim 7 and above.
823 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
827 " Helper to show tab name.
828 fun! <SID>TabName(label, gui)
829 let l:label = a:label
831 let l:label = "No Name"
833 let l:label = "[" . l:label . "]"
836 let l:label = fnamemodify(l:label, ":t")
837 if strlen(l:label) >= 18
838 let l:label = l:label[0:17] . ".."
844 " Find out if any buffer was modified.
845 fun! <SID>TabModified(buflist)
847 while l:i < len(a:buflist)
848 if getbufvar(a:buflist[l:i], "&modified") == 1
858 let l:s = "%#TabLineFill#Tabs:"
861 while l:i < tabpagenr("$")
864 let l:buflist = tabpagebuflist(l:i)
865 let l:winnr = tabpagewinnr(l:i)
866 let l:n = tabpagewinnr(l:i, "$")
867 let l:label = <SID>TabName(bufname(l:buflist[l:winnr - 1]), 0)
868 let l:modified = <SID>TabModified(l:buflist)
870 " Choose highlighting.
871 if l:i == tabpagenr()
872 let l:s .= "%#TabLineSel#[" . l:n . l:modified . " " . l:label . "]"
874 let l:s .= "%#TabLine# " . l:n . l:modified . " " . l:label . " "
879 let l:s .= "%#TabLine#%T"
883 " Per tab label for the GUI.
884 fun! Show_GUITabLine()
885 let l:buflist = tabpagebuflist(v:lnum)
886 let l:winnr = tabpagewinnr(v:lnum)
887 let l:s = tabpagewinnr(v:lnum, "$")
888 let l:label = <SID>TabName(bufname(l:buflist[l:winnr - 1]), 1)
889 let l:modified = <SID>TabModified(l:buflist)
891 let l:s .= l:modified . " " . l:label
895 se tabline=%!Show_TabLine()
896 se guitablabel=%!Show_GUITabLine()
898 au StatusLine CursorHoldI * call Highlight_StatusLine("H")
899 au StatusLine CursorMovedI * call Highlight_StatusLine("h")
900 au StatusLine FocusGained * call Highlight_StatusLine("F")
901 au StatusLine FocusLost * call Highlight_StatusLine("f")
902 au StatusLine InsertEnter * call Highlight_StatusLine("I")
903 au StatusLine InsertLeave * call Highlight_StatusLine("i")
906 au Signs InsertEnter * call <SID>Highlight_Signs()
907 au Signs InsertLeave * call <SID>Highlight_Signs()
910 " Limit the size of the popup menu when completing.
913 " Make diffs vertical by default.
916 " Set size of numbers column.
919 " Add "previous tab" mapping as gb.
920 map gb :tabprevious<CR>:<CR>
927 " Yet more GUI options. Add tabs.
932 let g:p4Presets='P4CONFIG'
936 " Resize after startup.
937 au Display VimEnter * call Startup_Resize()