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.
81 " Update more quickly. For use with sign highlighting as polling for
82 " CursorMove makes redrawing slow.
85 " Enable tab-completion prompting for commands.
87 " Don't list object files when globbing files to load.
88 se wildignore+=*.o,*.obj
89 " So there's no need to assign them low priority.
90 se suffixes-=*.o,*.obj
92 " Save sessions in UNIX format with / as file separator. This is
96 " Nuke any pre-existing autocommands.
107 " Save the current window width so we can restore it when we quit.
108 if ! exists("oldcols")
112 " More GUI options. Add icon, tearoffs and toolbar.
115 " Allow dynamic window resize even if we aren't in an xterm.
116 se t_WS=
\e[8;%p1%d;%p2%dt
118 " Highlight search results.
121 " Set graphical window title.
122 se titlestring=%{Show_TitleString()}
124 " Syntax highlighting. New versions will use syn enable instead.
129 " Use a discernably different colour to highlight the cursor which shows
130 " matching brackets. Our regular cursor is green so use blue instead of cyan.
131 hi MatchParen ctermbg=blue
138 " Set up our variables.
140 if ! exists("b:iainlist")
143 if ! exists("b:iainhex")
146 if ! exists("b:iainverbose")
147 let b:iainverbose = 0
149 if ! exists("b:iainstatus")
150 " Window Flags: (F)ocused, (I)nsert mode, Cursor (H)old.
151 let b:iainstatus = "Fih"
153 if ! exists("g:iainextracolumns")
154 let g:iainextracolumns = 0
156 if ! exists("g:marksigns")
159 if ! exists("g:firstsign")
160 let g:firstsign = 100
164 " Helper for status line.
165 " Show space, underscore or dollar sign depending on list mode.
171 elseif b:iainlist == 1
180 " Helper for status line.
181 " Show c or C to denote case-sensitivity.
190 " Helper for status line.
191 " Show the size of the tabstop.
196 " Helper for status line.
197 " Show p when paste mode is on.
206 " Show the window title.
207 fun! Show_TitleString()
211 let l:ts1=printf("%2d: %s", bufnr(""), expand('%t'))
213 return printf("%s (%s) %s", l:ts1, getcwd(), v:servername)
216 " Show the status line.
217 fun! Show_StatusLine()
219 let l:sl1='%2n\:\ %<%f\ [%{Show_List()}%{Show_Case()}%{Show_Tabstop()}%{Show_Paste()}%Y%M%R]\ %='
220 let l:sl3='L:%4.6l/%-4.6L\ C:%3.6c\ \|\ %P'
223 let l:hexformat='0\x%02B'
226 let l:sl2=l:hexformat . '\ \|\ P:%4.6o\ '
230 exec "set statusline=" . l:sl1 . l:sl2 . l:sl3
233 " Toggle case-sensitivity.
238 " Grow or shrink the window size.
239 fun! Resize_Columns(op, ...)
241 " Vim 5 hardcodes the size of numbers column to 8.
243 let l:columns = &numberwidth
251 let l:resize = "se columns" . a:op . "=" . l:columns
253 " HACK: Inside screen there is an extra line for the status bar. Vim
254 " manages the resize by sending an escape sequence to set the number of
255 " lines and number of columns in one action. To do this it will first query
256 " the number of lines and then set <same number of lines> by <new number of
257 " columns>. Because of the extra line for the status bar this results in
258 " the real terminal being shrunk by a line. We ask for the terminal to grow
259 " by a line so it ends up actually being the same.
260 if &term =~ '^screen'
261 let l:resize .= " lines+=1"
267 " Toggle number display.
270 let &number = ! &number
274 let l:num_numbers = 0
275 while l:i <= winnr("$")
276 if getwinvar(l:i, "&number") == 1
277 let l:num_numbers = l:num_numbers + 1
282 if l:num_numbers == 0
283 let g:iainextracolumns = 0
284 call Resize_Columns("-")
285 elseif g:iainextracolumns == 0
286 let g:iainextracolumns = 1
287 call Resize_Columns("+")
292 " Restore window size.
293 au Display VimLeave * if exists("oldcols") | let &columns=oldcols | endif
296 au Mode BufEnter * if &ft == "make" | call MakeMode_map() | endif
297 au Mode BufLeave * if &ft == "make" | call MakeMode_unmap() | endif
299 " Entering Make mode.
309 fun! MakeMode_unmap()
315 " Show the status line for the first time.
316 call Show_StatusLine()
318 " Function to create mappings with either a hardcoded \ or <Leader>.
319 fun! Mapping(keysequence,mapping)
321 exec "map \\" . a:keysequence . " " . a:mapping
323 exec "map <Leader>" . a:keysequence . " " . a:mapping
327 " Use - and = to create underlines.
328 call Mapping("-", "yyp:s/./-/g<RETURN>:let @/=''<RETURN>:<RETURN>")
329 call Mapping("=", "yyp:s/./=/g<RETURN>:let @/=''<RETURN>:<RETURN>")
331 " Change to ts=2 with \2.
332 call Mapping("2", ":se ts=2<CR>:<CR>")
333 " Change to ts=4 with \4.
334 call Mapping("4", ":se ts=4<CR>:<CR>")
335 " Change to ts=8 with \8.
336 call Mapping("8", ":se ts=8<CR>:<CR>")
337 " Change to ts=16 with \6.
338 call Mapping("6", ":se ts=16<CR>:<CR>")
339 " Change to ts=32 with \3.
340 call Mapping("3", ":se ts=32<CR>:<CR>")
341 " Toggle paste mode with \p.
342 call Mapping("p", ":se paste!<CR>:<CR>")
343 " Swap case-sensitivity with \c.
344 call Mapping("c", ":call Invert_Case()<CR>:<CR>")
345 " Change number mode with \n.
346 call Mapping("n", ":call Number()<CR>:<CR>")
347 " Expand or shrink window size with \> and \<.
348 call Mapping(">", ":call Resize_Columns('+')<CR>:<CR>")
349 call Mapping("<", ":call Resize_Columns('-')<CR>:<CR>")
350 " Clear search pattern with \/.
351 call Mapping("/", ":let @/=\"\"<CR>:<CR>")
353 " Forget the Ex mode mapping.
356 " Vim tip 99: What's the highlighting group under the cursor?
357 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>")
359 " Show numbers by default.
360 au Display VimEnter * call Number()
363 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
364 " Handle options only available in Vim 6 and above.
365 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
369 " Remember quickfix state.
372 " Set indenting by filetype.
375 " Less intrusive syntax highlighting.
379 if has("gui_running")
380 se guifont=DejaVu\ Sans\ Mono\ 10
381 " XXX: Sort this out.
383 hi Cursor guibg=green
384 hi LineNr guibg=#303030
385 hi MarkLine guibg=#2e2e2e
386 hi MarkDot guifg=red guibg=#2e2e2e
387 hi MarkSign guifg=lightblue guibg=#2e2e2e
388 hi! link SignColumn LineNr
396 se guifont=DejaVu_Sans_Mono:h10:cANSI
398 hi! link TabLineSel StatusLine
399 hi! link TabLine StatusLineNC
401 " Ignore whitespace when diffing.
402 se diffopt=filler,iwhite
404 " Expand window when doing a vertical diff.
409 " Remember that we are opening the quickfix window.
410 au Mode BufWinEnter quickfix let g:quickfixing=1
411 au Mode BufUnload * if &ft == "qf" | let g:quickfixing=0 | endif
413 " Allow in-place editing of crontabs.
414 au Mode FileType crontab set backupcopy=yes
416 " Make * and # work the way you expect in visual mode.
417 vnoremap * y/\V<C-R>=substitute(escape(@@,"/\\"),"\n","\\\\n","ge")<CR><CR>
418 vnoremap # y?\V<C-R>=substitute(escape(@@,"?\\"),"\n","\\\\n","ge")<CR><CR>
420 " Set mark and update highlighting.
421 au Signs BufEnter * call <SID>Highlight_Signs()
422 au Signs CursorHold * call <SID>Highlight_Signs()
424 fun! <SID>Prep_Signs()
425 if ! exists("b:signdot") || ! g:marksigns
428 if ! exists("b:signdash") || ! g:marksigns
431 if ! exists("b:signquote") || ! g:marksigns
434 if ! exists("b:signcaret") || ! g:marksigns
437 if ! exists("b:signless") || ! g:marksigns
440 if ! exists("b:signgreater") || ! g:marksigns
443 if ! exists("b:signleft") || ! g:marksigns
446 if ! exists("b:signright") || ! g:marksigns
449 if ! exists("b:signa") || ! g:marksigns
452 if ! exists("b:signb") || ! g:marksigns
455 if ! exists("b:signc") || ! g:marksigns
458 if ! exists("b:signd") || ! g:marksigns
461 if ! exists("b:signe") || ! g:marksigns
464 if ! exists("b:signf") || ! g:marksigns
467 if ! exists("b:signA") || ! g:marksigns
470 if ! exists("b:signB") || ! g:marksigns
473 if ! exists("b:signC") || ! g:marksigns
476 if ! exists("b:signD") || ! g:marksigns
479 if ! exists("b:signE") || ! g:marksigns
482 if ! exists("b:signF") || ! g:marksigns
487 fun! <SID>Place_Sign(number, line, old, name)
492 exe "sign unplace " . (g:firstsign + a:number) . " buffer=" . bufnr("")
493 " Don't place the sign if it would conflict with the last change sign.
494 exe "sign place " . (g:firstsign + a:number) . " line=" . a:line . " name=" . a:name . " buffer=" . bufnr("")
498 fun! <SID>Highlight_Signs(...)
503 call <SID>Prep_Signs()
505 let b:signdot = <SID>Place_Sign(0, line("'."), b:signdot, "MarkDot")
506 let b:signdash = <SID>Place_Sign(1, line("''"), b:signdash, "MarkDash")
507 let b:signquote = <SID>Place_Sign(2, line("'\""), b:signquote, "MarkQuote")
508 let b:signcaret = <SID>Place_Sign(3, line("'^"), b:signcaret, "MarkCaret")
509 let b:signless = <SID>Place_Sign(4, line("'<"), b:signcaret, "MarkLess")
510 let b:signgreater = <SID>Place_Sign(5, line("'>"), b:signcaret, "MarkGreater")
511 let b:signleft = <SID>Place_Sign(6, line("'["), b:signcaret, "MarkLeft")
512 let b:signright = <SID>Place_Sign(7, line("']"), b:signcaret, "MarkRight")
514 let b:signa = <SID>Place_Sign(8, line("'a"), b:signa, "Marka")
515 let b:signb = <SID>Place_Sign(9, line("'b"), b:signb, "Markb")
516 let b:signc = <SID>Place_Sign(10, line("'c"), b:signc, "Markc")
517 let b:signd = <SID>Place_Sign(11, line("'d"), b:signd, "Markd")
518 let b:signe = <SID>Place_Sign(12, line("'e"), b:signe, "Marke")
519 let b:signf = <SID>Place_Sign(13, line("'f"), b:signf, "Markf")
520 let b:signA = <SID>Place_Sign(14, line("'A"), b:signA, "MarkA")
521 let b:signB = <SID>Place_Sign(15, line("'B"), b:signB, "MarkB")
522 let b:signC = <SID>Place_Sign(16, line("'C"), b:signC, "MarkC")
523 let b:signD = <SID>Place_Sign(17, line("'D"), b:signD, "MarkD")
524 let b:signE = <SID>Place_Sign(18, line("'E"), b:signE, "MarkE")
525 let b:signF = <SID>Place_Sign(19, line("'F"), b:signF, "MarkF")
529 fun! <SID>Cycle_Signs()
531 let g:marksigns = ! g:marksigns
534 " Signs to highlight marks.
535 " Syntax won't work properly in Vim 6.
536 sign define MarkDash text=' texthl=MarkSign
537 sign define MarkDot text=* texthl=MarkDot
538 sign define MarkQuote text=" texthl=MarkSign
539 sign define MarkCaret text=^ texthl=MarkSign
540 sign define MarkLess text=< texthl=MarkSign
541 sign define MarkGreater text=> texthl=MarkSign
542 sign define MarkLeft text=[ texthl=MarkSign
543 sign define MarkRight text=] texthl=MarkSign
544 sign define Marka text=a texthl=MarkSign linehl=MarkLine
545 sign define Markb text=b texthl=MarkSign linehl=MarkLine
546 sign define Markc text=c texthl=MarkSign linehl=MarkLine
547 sign define Markd text=d texthl=MarkSign linehl=MarkLine
548 sign define Marke text=e texthl=MarkSign linehl=MarkLine
549 sign define Markf text=f texthl=MarkSign linehl=MarkLine
550 sign define MarkA text=A texthl=MarkSign linehl=MarkLine
551 sign define MarkB text=B texthl=MarkSign linehl=MarkLine
552 sign define MarkC text=C texthl=MarkSign linehl=MarkLine
553 sign define MarkD text=D texthl=MarkSign linehl=MarkLine
554 sign define MarkE text=E texthl=MarkSign linehl=MarkLine
555 sign define MarkF text=F texthl=MarkSign linehl=MarkLine
557 call Resize_Columns("+", 2)
558 call <SID>Highlight_Signs()
560 exe "sign unplace " . (g:firstsign + 0)
561 exe "sign unplace " . (g:firstsign + 1)
562 exe "sign unplace " . (g:firstsign + 2)
563 exe "sign unplace " . (g:firstsign + 3)
564 exe "sign unplace " . (g:firstsign + 4)
565 exe "sign unplace " . (g:firstsign + 5)
566 exe "sign unplace " . (g:firstsign + 6)
567 exe "sign unplace " . (g:firstsign + 7)
568 exe "sign unplace " . (g:firstsign + 8)
569 exe "sign unplace " . (g:firstsign + 9)
570 exe "sign unplace " . (g:firstsign + 10)
571 exe "sign unplace " . (g:firstsign + 11)
572 exe "sign unplace " . (g:firstsign + 12)
573 exe "sign unplace " . (g:firstsign + 13)
574 exe "sign unplace " . (g:firstsign + 14)
575 exe "sign unplace " . (g:firstsign + 15)
576 exe "sign unplace " . (g:firstsign + 16)
577 exe "sign unplace " . (g:firstsign + 17)
578 exe "sign unplace " . (g:firstsign + 18)
579 exe "sign unplace " . (g:firstsign + 19)
581 sign undefine MarkDash
582 sign undefine MarkDot
583 sign undefine MarkQuote
584 sign undefine MarkCaret
585 sign undefine MarkLess
586 sign undefine MarkGreater
587 sign undefine MarkLeft
588 sign undefine MarkRight
602 call <SID>Prep_Signs()
603 call Resize_Columns("-", 2)
609 let basic='tab:\\_,trail:_,extends:<,precedes:>'
611 let b:iainlist = b:iainlist + 1
617 elseif b:iainlist == 1
618 exec "set lcs=" . basic
621 exec "set lcs=" . basic . ",eol:$"
626 " Cycle between hex and decimal display of toolbar stuff.
627 fun! Cycle_HexStatusLine()
629 let b:iainhex = ! b:iainhex
630 call Show_StatusLine()
633 " Cycle verbose display of toolbar stuff.
634 fun! Cycle_VerboseStatusLine()
636 let b:iainverbose = ! b:iainverbose
637 call Show_StatusLine()
640 " Toggle quickfix window.
641 fun! Cycle_Quickfix()
642 if g:quickfixing == 1
650 " Swap hex/decimal statusline with \x.
651 call Mapping("x", ":call Cycle_HexStatusLine()<CR>:<CR>")
652 " Change statusline verbosity with \v.
653 call Mapping("v", ":call Cycle_VerboseStatusLine()<CR>:<CR>")
654 " Cycle list styles with \l.
655 call Mapping("l", ":call Cycle_List()<CR>:<CR>")
656 " Toggle tags with \t.
657 call Mapping("t", ":Tlist<CR>")
658 " Change foldmethod with \f.
659 call Mapping("f", ":se foldenable!<CR>:<CR>")
660 " Toggle quickfix window with \q.
661 call Mapping("q", ":call Cycle_Quickfix()<CR>:<CR>")
662 " Rerun filetype detection with \s. The s is for syntax, as this will be
663 " updated as a side-effect.
664 call Mapping("s", ":filetype detect<CR>:<CR>")
665 " Toggle marks with \m.
666 call Mapping("m", ":call <SID>Cycle_Signs()<CR>:<CR>")
668 fun! <SID>Iain_Colour(colour)
670 if a:colour == "darkblue"
672 elseif a:colour == "darkmagenta"
674 elseif a:colour == "darkred"
676 elseif a:colour == "red"
680 if a:colour == "darkblue"
682 elseif a:colour == "darkmagenta"
684 elseif a:colour == "darkred"
686 elseif a:colour == "red"
694 " Change status bar colour when various things happen.
695 " Flags: H/h: Cursor held/moved.
696 " F/f: Focus gained/lost.
697 " I/i: Insert mode entered/left.
698 fun! Highlight_StatusLine(flag)
699 " Get current status.
702 " Change the status based on the flag. XXX: Does Vim let us to do flags?
703 let re = "[" . tolower(a:flag) . toupper(a:flag) . "]"
704 let b:iainstatus = substitute(b:iainstatus, re, a:flag, "")
706 let l:normalcolour = "darkblue"
707 let l:editingcolour = "darkmagenta"
708 let l:warningcolour = "darkred"
709 let l:readonlycolour = "red"
712 let l:colour = l:normalcolour
713 " Maybe override depending on status.
714 if b:iainstatus =~# "H"
715 if b:iainstatus =~# "I"
716 " Held in insert mode. Add extra highlight if we don't have focus.
717 if b:iainstatus =~# "f"
718 let l:colour = l:warningcolour
720 let l:colour = l:editingcolour
724 if b:iainstatus =~# "I"
725 " Regular insert mode.
726 let l:colour = l:editingcolour
730 " Override again if readonly.
731 if l:colour != l:normalcolour
732 if getbufvar("", "&ro")
733 let l:colour = l:readonlycolour
737 let l:termcolour = <SID>Iain_Colour(l:colour)
739 exec "highlight StatusLine guifg=white guibg=" . l:colour . " ctermbg=white ctermfg=" . l:termcolour
742 au Display VimEnter * call Highlight_StatusLine("")
744 " Show signs by default.
745 au Display VimEnter * call <SID>Cycle_Signs()
748 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
749 " Handle options only available in Vim 7 and above.
750 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
754 " Helper to show tab name.
755 fun! <SID>TabName(label, gui)
756 let l:label = a:label
758 let l:label = "No Name"
760 let l:label = "[" . l:label . "]"
763 let l:label = fnamemodify(l:label, ":t")
764 if strlen(l:label) >= 18
765 let l:label = l:label[0:17] . ".."
771 " Find out if any buffer was modified.
772 fun! <SID>TabModified(buflist)
774 while i < len(a:buflist)
775 if getbufvar(a:buflist[l:i], "&modified") == 1
785 let l:s = "%#TabLineFill#Tabs:"
788 while l:i < tabpagenr("$")
791 let l:buflist = tabpagebuflist(l:i)
792 let l:winnr = tabpagewinnr(l:i)
793 let l:n = tabpagewinnr(l:i, "$")
794 let l:label = <SID>TabName(bufname(l:buflist[l:winnr - 1]), 0)
795 let l:modified = <SID>TabModified(l:buflist)
797 " Choose highlighting.
798 if l:i == tabpagenr()
799 let l:s .= "%#TabLineSel#[" . l:n . l:modified . " " . l:label . "]"
801 let l:s .= "%#TabLine# " . l:n . l:modified . " " . l:label . " "
806 let l:s .= "%#TabLine#%T"
810 " Per tab label for the GUI.
811 fun! Show_GUITabLine()
812 let l:buflist = tabpagebuflist(v:lnum)
813 let l:winnr = tabpagewinnr(v:lnum)
814 let l:s = tabpagewinnr(v:lnum, "$")
815 let l:label = <SID>TabName(bufname(l:buflist[l:winnr - 1]), 1)
816 let l:modified = <SID>TabModified(l:buflist)
818 let l:s .= l:modified . " " . l:label
822 se tabline=%!Show_TabLine()
823 se guitablabel=%!Show_GUITabLine()
825 au StatusLine CursorHoldI * call Highlight_StatusLine("H")
826 au StatusLine CursorMovedI * call Highlight_StatusLine("h")
827 au StatusLine FocusGained * call Highlight_StatusLine("F")
828 au StatusLine FocusLost * call Highlight_StatusLine("f")
829 au StatusLine InsertEnter * call Highlight_StatusLine("I")
830 au StatusLine InsertLeave * call Highlight_StatusLine("i")
832 au Signs InsertEnter * call <SID>Highlight_Signs()
833 au Signs InsertLeave * call <SID>Highlight_Signs()
835 " Limit the size of the popup menu when completing.
838 " Make diffs vertical by default.
841 " Set size of numbers column.
844 " Add "previous tab" mapping as gb.
845 map gb :tabprevious<CR>:<CR>
852 " Yet more GUI options. Add tabs.
857 let g:p4Presets='P4CONFIG'