15a641406b7494a2e0cc4c95ae504446df19f3e2
[profile.git] / .vimrc
1 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
2 " Multi-version vimrc compatible with version 4 and above.
3 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
4
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.
8
9 " Vim 4 complains if version isn't set in the configuration file.
10 version 4.0
11
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.
18 se nocp
19
20 " Tabstop 2.
21 se ts=2
22 " And use spaces not tabs.
23 se expandtab
24 " And << and >> indent by 2.
25 se sw=2
26
27 " Allow backspace to delete before start of line.
28 se bs=2
29
30 " Show the ruler.
31 se ruler
32 " Show partial commands in the ruler.
33 se showcmd
34 " And always show the status line.
35 se laststatus=2
36
37 " Use C indent style.
38 se cindent
39 se cinkeys=0{,0},0),:,!^F,o,O,e
40 se cinoptions=b1,c2
41
42 " GUI options.
43 se go=aglmr
44
45 " Don't be bugged by messages at the bottom of the screen.
46 se shm=aot
47
48 " Find as you type.
49 se incsearch
50
51 " Case-insensitive search.
52 se ignorecase
53 " But override by typing capitals.
54 se smartcase
55
56 " Look for ctags in home directory first.
57 se tags=~/.tags,./tags,tags
58
59 " Don't timeout waiting to interpet, eg, <ESC>OA as an escape code.
60 se ttimeoutlen=100
61
62 " Use ^B to search backward when completing.
63 inoremap <C-b> <C-p>
64 " Use ^L to show matching completions but don't select one.
65 inoremap <C-l> <C-n><C-p>
66
67 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
68 " Handle options only available in Vim 5 and above.
69 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
70 if version >= "500"
71 version 5.0
72
73 " Tell Vim we use dark backgrounds in our terminals.
74 if ! has("gui_running")
75   se bg=dark
76 endif
77
78 " Allow mouse use in a terminal.
79 se mouse=nvir
80
81 " Update more quickly.  For use with sign highlighting as polling for
82 " CursorMove makes redrawing slow.
83 se updatetime=500
84
85 " Enable tab-completion prompting for commands.
86 se wildmenu
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
91
92 " Save sessions in UNIX format with / as file separator.  This is
93 " cross-platform.
94 se ssop+=unix,slash
95
96 " Nuke any pre-existing autocommands.
97 augroup Display
98 autocmd!
99 augroup Mode
100 autocmd!
101 augroup Signs
102 autocmd!
103 augroup StatusLine
104 autocmd!
105 augroup END
106
107 " Save the current window width so we can restore it when we quit.
108 if ! exists("oldcols")
109   let oldcols=&columns
110 endif
111
112 " More GUI options.  Add icon, tearoffs and toolbar.
113 se go+=itT
114
115 " Allow dynamic window resize even if we aren't in an xterm.
116 se t_WS=\e[8;%p1%d;%p2%dt
117
118 " Highlight search results.
119 se hlsearch
120
121 " Set graphical window title.
122 se titlestring=%{Show_TitleString()}
123
124 " Syntax highlighting.  New versions will use syn enable instead.
125 if version < "600"
126   syn on
127 endif
128
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
132
133 " Catch typos.
134 command! W :w
135 command! Wq :wq
136 command! Wqa :wqa
137
138 " Set up our variables.
139 fun! Iain_Vars()
140   if ! exists("b:iainlist")
141     let b:iainlist = 0
142   endif
143   if ! exists("b:iainhex")
144     let b:iainhex = 0
145   endif
146   if ! exists("b:iainverbose")
147     let b:iainverbose = 0
148   endif
149   if ! exists("b:iainstatus")
150     " Window Flags: (F)ocused, (I)nsert mode, Cursor (H)old.
151     let b:iainstatus = "Fih"
152   endif
153   if ! exists("g:iainextracolumns")
154     let g:iainextracolumns = 0
155   endif
156   if ! exists("g:marksigns")
157     let g:marksigns = 0
158   endif
159   if ! exists("g:firstsign")
160     let g:firstsign = 100
161   endif
162 endfun
163
164 " Helper for status line.
165 " Show space, underscore or dollar sign depending on list mode.
166 fun! Show_List()
167   call Iain_Vars()
168   if b:iainlist == 0
169     " No list.
170     return " "
171   elseif b:iainlist == 1
172     " Just tabs.
173     return "_"
174   else
175     " Full list.
176     return "\$"
177   endif
178 endfun
179
180 " Helper for status line.
181 " Show c or C to denote case-sensitivity.
182 fun! Show_Case()
183   if &ic
184     return "c"
185   else
186     return "C"
187   endif
188 endfun
189
190 " Helper for status line.
191 " Show the size of the tabstop.
192 fun! Show_Tabstop()
193   return &ts
194 endfun
195
196 " Helper for status line.
197 " Show p when paste mode is on.
198 fun! Show_Paste()
199   if &paste
200     return "p"
201   else
202     return ""
203   endif
204 endfun
205
206 " Show the window title.
207 fun! Show_TitleString()
208   if bufname("") == ""
209     let l:ts1='Vim'
210   else
211     let l:ts1=printf("%2d: %s", bufnr(""), expand('%t'))
212   endif
213   return printf("%s (%s) %s", l:ts1, getcwd(), v:servername)
214 endfun
215
216 " Show the status line.
217 fun! Show_StatusLine()
218   call Iain_Vars()
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'
221   let l:hexformat='%b'
222   if b:iainhex
223     let l:hexformat='0\x%02B'
224   endif
225   if b:iainverbose
226     let l:sl2=l:hexformat . '\ \|\ P:%4.6o\ '
227   else
228     let l:sl2=''
229   endif
230   exec "set statusline=" . l:sl1 . l:sl2 . l:sl3
231 endfun
232
233 " Toggle case-sensitivity.
234 fun! Invert_Case()
235   let &ic = ! &ic
236 endfun
237
238 " Grow or shrink the window size.
239 fun! Resize_Columns(op, ...)
240   if a:0 == 0
241     " Vim 5 hardcodes the size of numbers column to 8.
242     if version >= "700"
243       let l:columns = &numberwidth
244     else
245       let l:columns = 8
246     endif
247   else
248     let l:columns = a:1
249   endif
250
251   let l:resize = "se columns" . a:op . "=" . l:columns
252
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"
262   endif
263
264   exec l:resize
265 endfun
266
267 " Toggle number display.
268 fun! Number()
269   call Iain_Vars()
270   let &number = ! &number
271
272   if version >= "700"
273     let l:i = 0
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
278       endif
279       let l:i = l:i + 1
280     endwhile
281
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("+")
288     endif
289   endif
290 endfun
291
292 " Restore window size.
293 au Display VimLeave * if exists("oldcols") | let &columns=oldcols | endif
294
295 " Map Makefile mode.
296 au Mode BufEnter * if &ft == "make" | call MakeMode_map() | endif
297 au Mode BufLeave * if &ft == "make" | call MakeMode_unmap() | endif
298
299 " Entering Make mode.
300 fun! MakeMode_map()
301         call Iain_Vars()
302   let b:iainlist=1
303   call Cycle_List()
304   set ts=8
305   set noexpandtab
306 endfun
307
308 " Leaving Make mode.
309 fun! MakeMode_unmap()
310   call Cycle_List()
311   set ts=2
312   set expandtab
313 endfun
314
315 " Show the status line for the first time.
316 call Show_StatusLine()
317
318 " Function to create mappings with either a hardcoded \ or <Leader>.
319 fun! Mapping(keysequence,mapping)
320   if version < "600"
321     exec "map \\" . a:keysequence . " " . a:mapping
322   else
323     exec "map <Leader>" . a:keysequence . " " . a:mapping
324   endif
325 endfun
326
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>")
330
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>")
352
353 " Forget the Ex mode mapping.
354 map Q <NOP>
355
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>")
358
359 " Show numbers by default.
360 au Display VimEnter * call Number()
361 endif
362
363 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
364 " Handle options only available in Vim 6 and above.
365 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
366 if version >= "600"
367 version 6.0
368
369 " Remember quickfix state.
370 let g:quickfixing=0
371
372 " Set indenting by filetype.
373 filetype indent on
374
375 " Less intrusive syntax highlighting.
376 syn enable
377
378 " Nice GUI colour.
379 if has("gui_running")
380   se guifont=DejaVu\ Sans\ Mono\ 10
381   " XXX: Sort this out.
382   colo darkblue
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
389 elseif &t_Co > 16
390   try
391     colo iain
392   catch
393   endtry
394 endif
395 if has("win32")
396   se guifont=DejaVu_Sans_Mono:h10:cANSI
397 endif
398 hi! link TabLineSel StatusLine
399 hi! link TabLine StatusLineNC
400
401 " Ignore whitespace when diffing.
402 se diffopt=filler,iwhite
403
404 " Expand window when doing a vertical diff.
405 if &diff
406   let &columns = 164
407 endif
408
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
412
413 " Allow in-place editing of crontabs.
414 au Mode FileType crontab set backupcopy=yes
415
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>
419
420 " Set mark and update highlighting.
421 au Signs BufEnter * call <SID>Highlight_Signs()
422 au Signs CursorHold * call <SID>Highlight_Signs()
423
424 fun! <SID>Prep_Signs()
425   if ! exists("b:signdot") || ! g:marksigns
426     let b:signdot=0
427   endif
428   if ! exists("b:signdash") || ! g:marksigns
429     let b:signdash=0
430   endif
431   if ! exists("b:signquote") || ! g:marksigns
432     let b:signquote=0
433   endif
434   if ! exists("b:signcaret") || ! g:marksigns
435     let b:signcaret=0
436   endif
437   if ! exists("b:signless") || ! g:marksigns
438     let b:signless=0
439   endif
440   if ! exists("b:signgreater") || ! g:marksigns
441     let b:signgreater=0
442   endif
443   if ! exists("b:signleft") || ! g:marksigns
444     let b:signleft=0
445   endif
446   if ! exists("b:signright") || ! g:marksigns
447     let b:signright=0
448   endif
449   if ! exists("b:signa") || ! g:marksigns
450     let b:signa=0
451   endif
452   if ! exists("b:signb") || ! g:marksigns
453     let b:signb=0
454   endif
455   if ! exists("b:signc") || ! g:marksigns
456     let b:signc=0
457   endif
458   if ! exists("b:signd") || ! g:marksigns
459     let b:signd=0
460   endif
461   if ! exists("b:signe") || ! g:marksigns
462     let b:signe=0
463   endif
464   if ! exists("b:signf") || ! g:marksigns
465     let b:signf=0
466   endif
467   if ! exists("b:signA") || ! g:marksigns
468     let b:signA=0
469   endif
470   if ! exists("b:signB") || ! g:marksigns
471     let b:signB=0
472   endif
473   if ! exists("b:signC") || ! g:marksigns
474     let b:signC=0
475   endif
476   if ! exists("b:signD") || ! g:marksigns
477     let b:signD=0
478   endif
479   if ! exists("b:signE") || ! g:marksigns
480     let b:signE=0
481   endif
482   if ! exists("b:signF") || ! g:marksigns
483     let b:signF=0
484   endif
485 endfun!
486
487 fun! <SID>Place_Sign(number, line, old, name)
488   if a:line == a:old
489     return a:old
490   endif
491
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("")
495   return a:line
496 endfun
497
498 fun! <SID>Highlight_Signs(...)
499   if ! g:marksigns
500     return
501   endif
502
503   call <SID>Prep_Signs()
504
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")
513
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")
526 endfun
527
528 " Toggle signs.
529 fun! <SID>Cycle_Signs()
530   call Iain_Vars()
531   let g:marksigns = ! g:marksigns
532
533   if 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
556
557     call Resize_Columns("+", 2)
558     call <SID>Highlight_Signs()
559   else
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)
580
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
589     sign undefine Marka
590     sign undefine Markb
591     sign undefine Markc
592     sign undefine Markd
593     sign undefine Marke
594     sign undefine Markf
595     sign undefine MarkA
596     sign undefine MarkB
597     sign undefine MarkC
598     sign undefine MarkD
599     sign undefine MarkE
600     sign undefine MarkF
601
602     call <SID>Prep_Signs()
603     call Resize_Columns("-", 2)
604   endif
605 endfun
606
607 " Change list mode.
608 fun! Cycle_List()
609   let basic='tab:\\_,trail:_,extends:<,precedes:>'
610   call Iain_Vars()
611   let b:iainlist = b:iainlist + 1
612   if b:iainlist > 2
613     let b:iainlist = 0
614   endif
615   if b:iainlist == 0
616     set nolist
617   elseif b:iainlist == 1
618     exec "set lcs=" . basic
619     set list
620   else
621     exec "set lcs=" . basic . ",eol:$"
622     set list
623   endif
624 endfun
625
626 " Cycle between hex and decimal display of toolbar stuff.
627 fun! Cycle_HexStatusLine()
628   call Iain_Vars()
629   let b:iainhex = ! b:iainhex
630   call Show_StatusLine()
631 endfun
632
633 " Cycle verbose display of toolbar stuff.
634 fun! Cycle_VerboseStatusLine()
635   call Iain_Vars()
636   let b:iainverbose = ! b:iainverbose
637   call Show_StatusLine()
638 endfun
639
640 " Toggle quickfix window.
641 fun! Cycle_Quickfix()
642   if g:quickfixing == 1
643     cclose
644     let g:quickfixing=0
645   else
646     copen
647   endif
648 endfun
649
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>")
667
668 fun! <SID>Iain_Colour(colour)
669   if &t_Co == 88
670     if a:colour == "darkblue"
671       return 17
672     elseif a:colour == "darkmagenta"
673       return 33
674     elseif a:colour == "darkred"
675       return 32
676     elseif a:colour == "red"
677       return 64
678     endif
679   elseif &t_Co == 256
680     if a:colour == "darkblue"
681       return 17
682     elseif a:colour == "darkmagenta"
683       return 90
684     elseif a:colour == "darkred"
685       return 88
686     elseif a:colour == "red"
687       return 196
688     endif
689   else
690     return a:colour
691   endif
692 endfun
693
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.
700   call Iain_Vars()
701
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, "")
705
706   let l:normalcolour = "darkblue"
707   let l:editingcolour = "darkmagenta"
708   let l:warningcolour = "darkred"
709   let l:readonlycolour = "red"
710
711   " Default colour.
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
719       else
720         let l:colour = l:editingcolour
721       endif
722     endif
723   else
724     if b:iainstatus =~# "I"
725       " Regular insert mode.
726       let l:colour = l:editingcolour
727     endif
728   endif
729
730   " Override again if readonly.
731   if l:colour != l:normalcolour
732     if getbufvar("", "&ro")
733       let l:colour = l:readonlycolour
734     endif
735   endif
736
737   let l:termcolour = <SID>Iain_Colour(l:colour)
738
739   exec "highlight StatusLine guifg=white guibg=" . l:colour . " ctermbg=white ctermfg=" . l:termcolour
740 endfun
741
742 au Display VimEnter * call Highlight_StatusLine("")
743
744 " Show signs by default.
745 au Display VimEnter * call <SID>Cycle_Signs()
746 endif
747
748 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
749 " Handle options only available in Vim 7 and above.
750 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
751 if version >= "700"
752 version 7.0
753
754 " Helper to show tab name.
755 fun! <SID>TabName(label, gui)
756   let l:label = a:label
757   if l:label == ""
758     let l:label = "No Name"
759     if a:gui
760       let l:label = "[" . l:label . "]"
761     endif
762   else
763     let l:label = fnamemodify(l:label, ":t")
764     if strlen(l:label) >= 18
765       let l:label = l:label[0:17] . ".."
766     endif
767   endif
768   return l:label
769 endfun
770
771 " Find out if any buffer was modified.
772 fun! <SID>TabModified(buflist)
773   let l:i = 0
774   while i < len(a:buflist)
775     if getbufvar(a:buflist[l:i], "&modified") == 1
776       return "+"
777     endif
778     let l:i = l:i + 1
779   endwhile
780   return ""
781 endfun
782
783 " Tab line.
784 fun! Show_TabLine()
785   let l:s = "%#TabLineFill#Tabs:"
786
787   let l:i = 0
788   while l:i < tabpagenr("$")
789     let l:i = l:i + 1
790     " Get the label.
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)
796
797     " Choose highlighting.
798     if l:i == tabpagenr()
799       let l:s .= "%#TabLineSel#[" . l:n . l:modified . " " . l:label . "]"
800     else
801       let l:s .= "%#TabLine# " . l:n . l:modified . " " . l:label . " "
802     endif
803   endwhile
804
805   " Padding.
806   let l:s .= "%#TabLine#%T"
807   return l:s
808 endfun
809
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)
817
818   let l:s .= l:modified . " " . l:label
819   return l:s
820 endfun
821
822 se tabline=%!Show_TabLine()
823 se guitablabel=%!Show_GUITabLine()
824
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")
831
832 au Signs InsertEnter * call <SID>Highlight_Signs()
833 au Signs InsertLeave * call <SID>Highlight_Signs()
834
835 " Limit the size of the popup menu when completing.
836 se pumheight=20
837
838 " Make diffs vertical by default.
839 se diffopt+=vertical
840
841 " Set size of numbers column.
842 se numberwidth=5
843
844 " Add "previous tab" mapping as gb.
845 map gb :tabprevious<CR>:<CR>
846
847 " Transparency.
848 if has("gui_macvim")
849   se transparency=15
850 endif 
851
852 " Yet more GUI options.  Add tabs.
853 se go+=e
854
855 " Perforce.
856 let g:p4EnableMenu=1
857 let g:p4Presets='P4CONFIG'
858 endif