Colour tidyup.
[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 " Set colours.
379 if has("gui_running")
380   try
381     if has("win32")
382       se guifont=DejaVu_Sans_Mono:h10:cANSI
383     else
384       se guifont=DejaVu\ Sans\ Mono\ 10
385     endif
386   catch
387   endtry
388 endif
389 if has("gui_running") || &t_Co > 16
390   try
391     colo iain
392   catch
393   endtry
394 endif
395
396 " Ignore whitespace when diffing.
397 se diffopt=filler,iwhite
398
399 " Expand window when doing a vertical diff.
400 if &diff
401   let &columns = 164
402 endif
403
404 " Remember that we are opening the quickfix window.
405 au Mode BufWinEnter quickfix let g:quickfixing=1
406 au Mode BufUnload * if &ft == "qf" | let g:quickfixing=0 | endif
407
408 " Allow in-place editing of crontabs.
409 au Mode FileType crontab set backupcopy=yes
410
411 " Make * and # work the way you expect in visual mode.
412 vnoremap * y/\V<C-R>=substitute(escape(@@,"/\\"),"\n","\\\\n","ge")<CR><CR>
413 vnoremap # y?\V<C-R>=substitute(escape(@@,"?\\"),"\n","\\\\n","ge")<CR><CR>
414
415 " Set mark and update highlighting.
416 au Signs BufEnter * call <SID>Highlight_Signs()
417 au Signs CursorHold * call <SID>Highlight_Signs()
418
419 fun! <SID>Prep_Signs()
420   if ! exists("b:signdot") || ! g:marksigns
421     let b:signdot=0
422   endif
423   if ! exists("b:signdash") || ! g:marksigns
424     let b:signdash=0
425   endif
426   if ! exists("b:signquote") || ! g:marksigns
427     let b:signquote=0
428   endif
429   if ! exists("b:signcaret") || ! g:marksigns
430     let b:signcaret=0
431   endif
432   if ! exists("b:signless") || ! g:marksigns
433     let b:signless=0
434   endif
435   if ! exists("b:signgreater") || ! g:marksigns
436     let b:signgreater=0
437   endif
438   if ! exists("b:signleft") || ! g:marksigns
439     let b:signleft=0
440   endif
441   if ! exists("b:signright") || ! g:marksigns
442     let b:signright=0
443   endif
444   if ! exists("b:signa") || ! g:marksigns
445     let b:signa=0
446   endif
447   if ! exists("b:signb") || ! g:marksigns
448     let b:signb=0
449   endif
450   if ! exists("b:signc") || ! g:marksigns
451     let b:signc=0
452   endif
453   if ! exists("b:signd") || ! g:marksigns
454     let b:signd=0
455   endif
456   if ! exists("b:signe") || ! g:marksigns
457     let b:signe=0
458   endif
459   if ! exists("b:signf") || ! g:marksigns
460     let b:signf=0
461   endif
462   if ! exists("b:signA") || ! g:marksigns
463     let b:signA=0
464   endif
465   if ! exists("b:signB") || ! g:marksigns
466     let b:signB=0
467   endif
468   if ! exists("b:signC") || ! g:marksigns
469     let b:signC=0
470   endif
471   if ! exists("b:signD") || ! g:marksigns
472     let b:signD=0
473   endif
474   if ! exists("b:signE") || ! g:marksigns
475     let b:signE=0
476   endif
477   if ! exists("b:signF") || ! g:marksigns
478     let b:signF=0
479   endif
480 endfun!
481
482 fun! <SID>Place_Sign(number, line, old, name)
483   if a:line == a:old
484     return a:old
485   endif
486
487   exe "sign unplace " . (g:firstsign + a:number) . " buffer=" . bufnr("")
488   " Don't place the sign if it would conflict with the last change sign.
489   exe "sign place " . (g:firstsign + a:number) . " line=" . a:line . " name=" . a:name . " buffer=" . bufnr("")
490   return a:line
491 endfun
492
493 fun! <SID>Highlight_Signs(...)
494   if ! g:marksigns
495     return
496   endif
497
498   call <SID>Prep_Signs()
499
500   let b:signdot = <SID>Place_Sign(0, line("'."), b:signdot, "MarkDot")
501   let b:signdash = <SID>Place_Sign(1, line("''"), b:signdash, "MarkDash")
502   let b:signquote = <SID>Place_Sign(2, line("'\""), b:signquote, "MarkQuote")
503   let b:signcaret = <SID>Place_Sign(3, line("'^"), b:signcaret, "MarkCaret")
504   let b:signless = <SID>Place_Sign(4, line("'<"), b:signcaret, "MarkLess")
505   let b:signgreater = <SID>Place_Sign(5, line("'>"), b:signcaret, "MarkGreater")
506   let b:signleft = <SID>Place_Sign(6, line("'["), b:signcaret, "MarkLeft")
507   let b:signright = <SID>Place_Sign(7, line("']"), b:signcaret, "MarkRight")
508
509   let b:signa = <SID>Place_Sign(8, line("'a"), b:signa, "Marka")
510   let b:signb = <SID>Place_Sign(9, line("'b"), b:signb, "Markb")
511   let b:signc = <SID>Place_Sign(10, line("'c"), b:signc, "Markc")
512   let b:signd = <SID>Place_Sign(11, line("'d"), b:signd, "Markd")
513   let b:signe = <SID>Place_Sign(12, line("'e"), b:signe, "Marke")
514   let b:signf = <SID>Place_Sign(13, line("'f"), b:signf, "Markf")
515   let b:signA = <SID>Place_Sign(14, line("'A"), b:signA, "MarkA")
516   let b:signB = <SID>Place_Sign(15, line("'B"), b:signB, "MarkB")
517   let b:signC = <SID>Place_Sign(16, line("'C"), b:signC, "MarkC")
518   let b:signD = <SID>Place_Sign(17, line("'D"), b:signD, "MarkD")
519   let b:signE = <SID>Place_Sign(18, line("'E"), b:signE, "MarkE")
520   let b:signF = <SID>Place_Sign(19, line("'F"), b:signF, "MarkF")
521 endfun
522
523 " Toggle signs.
524 fun! <SID>Cycle_Signs()
525   call Iain_Vars()
526   let g:marksigns = ! g:marksigns
527
528   if g:marksigns
529     " Signs to highlight marks.
530     " Syntax won't work properly in Vim 6.
531     sign define MarkDash text=' texthl=MarkSign
532     sign define MarkDot text=* texthl=MarkDot
533     sign define MarkQuote text=" texthl=MarkSign
534     sign define MarkCaret text=^ texthl=MarkSign
535     sign define MarkLess text=< texthl=MarkSign
536     sign define MarkGreater text=> texthl=MarkSign
537     sign define MarkLeft text=[ texthl=MarkSign
538     sign define MarkRight text=] texthl=MarkSign
539     sign define Marka text=a texthl=MarkSign linehl=MarkLine
540     sign define Markb text=b texthl=MarkSign linehl=MarkLine
541     sign define Markc text=c texthl=MarkSign linehl=MarkLine
542     sign define Markd text=d texthl=MarkSign linehl=MarkLine
543     sign define Marke text=e texthl=MarkSign linehl=MarkLine
544     sign define Markf text=f texthl=MarkSign linehl=MarkLine
545     sign define MarkA text=A texthl=MarkSign linehl=MarkLine
546     sign define MarkB text=B texthl=MarkSign linehl=MarkLine
547     sign define MarkC text=C texthl=MarkSign linehl=MarkLine
548     sign define MarkD text=D texthl=MarkSign linehl=MarkLine
549     sign define MarkE text=E texthl=MarkSign linehl=MarkLine
550     sign define MarkF text=F texthl=MarkSign linehl=MarkLine
551
552     call Resize_Columns("+", 2)
553     call <SID>Highlight_Signs()
554   else
555     exe "sign unplace " . (g:firstsign + 0)
556     exe "sign unplace " . (g:firstsign + 1)
557     exe "sign unplace " . (g:firstsign + 2)
558     exe "sign unplace " . (g:firstsign + 3)
559     exe "sign unplace " . (g:firstsign + 4)
560     exe "sign unplace " . (g:firstsign + 5)
561     exe "sign unplace " . (g:firstsign + 6)
562     exe "sign unplace " . (g:firstsign + 7)
563     exe "sign unplace " . (g:firstsign + 8)
564     exe "sign unplace " . (g:firstsign + 9)
565     exe "sign unplace " . (g:firstsign + 10)
566     exe "sign unplace " . (g:firstsign + 11)
567     exe "sign unplace " . (g:firstsign + 12)
568     exe "sign unplace " . (g:firstsign + 13)
569     exe "sign unplace " . (g:firstsign + 14)
570     exe "sign unplace " . (g:firstsign + 15)
571     exe "sign unplace " . (g:firstsign + 16)
572     exe "sign unplace " . (g:firstsign + 17)
573     exe "sign unplace " . (g:firstsign + 18)
574     exe "sign unplace " . (g:firstsign + 19)
575
576     sign undefine MarkDash
577     sign undefine MarkDot
578     sign undefine MarkQuote
579     sign undefine MarkCaret
580     sign undefine MarkLess
581     sign undefine MarkGreater
582     sign undefine MarkLeft
583     sign undefine MarkRight
584     sign undefine Marka
585     sign undefine Markb
586     sign undefine Markc
587     sign undefine Markd
588     sign undefine Marke
589     sign undefine Markf
590     sign undefine MarkA
591     sign undefine MarkB
592     sign undefine MarkC
593     sign undefine MarkD
594     sign undefine MarkE
595     sign undefine MarkF
596
597     call <SID>Prep_Signs()
598     call Resize_Columns("-", 2)
599   endif
600 endfun
601
602 " Change list mode.
603 fun! Cycle_List()
604   let basic='tab:\\_,trail:_,extends:<,precedes:>'
605   call Iain_Vars()
606   let b:iainlist = b:iainlist + 1
607   if b:iainlist > 2
608     let b:iainlist = 0
609   endif
610   if b:iainlist == 0
611     set nolist
612   elseif b:iainlist == 1
613     exec "set lcs=" . basic
614     set list
615   else
616     exec "set lcs=" . basic . ",eol:$"
617     set list
618   endif
619 endfun
620
621 " Cycle between hex and decimal display of toolbar stuff.
622 fun! Cycle_HexStatusLine()
623   call Iain_Vars()
624   let b:iainhex = ! b:iainhex
625   call Show_StatusLine()
626 endfun
627
628 " Cycle verbose display of toolbar stuff.
629 fun! Cycle_VerboseStatusLine()
630   call Iain_Vars()
631   let b:iainverbose = ! b:iainverbose
632   call Show_StatusLine()
633 endfun
634
635 " Toggle quickfix window.
636 fun! Cycle_Quickfix()
637   if g:quickfixing == 1
638     cclose
639     let g:quickfixing=0
640   else
641     copen
642   endif
643 endfun
644
645 " Swap hex/decimal statusline with \x.
646 call Mapping("x", ":call Cycle_HexStatusLine()<CR>:<CR>")
647 " Change statusline verbosity with \v.
648 call Mapping("v", ":call Cycle_VerboseStatusLine()<CR>:<CR>")
649 " Cycle list styles with \l.
650 call Mapping("l", ":call Cycle_List()<CR>:<CR>")
651 " Toggle tags with \t.
652 call Mapping("t", ":Tlist<CR>")
653 " Change foldmethod with \f.
654 call Mapping("f", ":se foldenable!<CR>:<CR>")
655 " Toggle quickfix window with \q.
656 call Mapping("q", ":call Cycle_Quickfix()<CR>:<CR>")
657 " Rerun filetype detection with \s.  The s is for syntax, as this will be
658 " updated as a side-effect.
659 call Mapping("s", ":filetype detect<CR>:<CR>")
660 " Toggle marks with \m.
661 call Mapping("m", ":call <SID>Cycle_Signs()<CR>:<CR>")
662
663 fun! <SID>Iain_Colour(colour)
664   if &t_Co == 88
665     if a:colour == "darkblue"
666       return 17
667     elseif a:colour == "darkmagenta"
668       return 33
669     elseif a:colour == "darkred"
670       return 32
671     elseif a:colour == "red"
672       return 64
673     endif
674   elseif &t_Co == 256
675     if a:colour == "darkblue"
676       return 17
677     elseif a:colour == "darkmagenta"
678       return 90
679     elseif a:colour == "darkred"
680       return 88
681     elseif a:colour == "red"
682       return 196
683     endif
684   else
685     return a:colour
686   endif
687 endfun
688
689 " Change status bar colour when various things happen.
690 " Flags: H/h: Cursor held/moved.
691 "        F/f: Focus gained/lost.
692 "        I/i: Insert mode entered/left.
693 fun! Highlight_StatusLine(flag)
694   " Get current status.
695   call Iain_Vars()
696
697   " Change the status based on the flag.  XXX: Does Vim let us to do flags?
698   let re = "[" . tolower(a:flag) . toupper(a:flag) . "]"
699   let b:iainstatus = substitute(b:iainstatus, re, a:flag, "")
700
701   let l:normalcolour = "darkblue"
702   let l:editingcolour = "darkmagenta"
703   let l:warningcolour = "darkred"
704   let l:readonlycolour = "red"
705
706   " Default colour.
707   let l:colour = l:normalcolour
708   " Maybe override depending on status.
709   if b:iainstatus =~# "H"
710     if b:iainstatus =~# "I"
711       " Held in insert mode.  Add extra highlight if we don't have focus.
712       if b:iainstatus =~# "f"
713         let l:colour = l:warningcolour
714       else
715         let l:colour = l:editingcolour
716       endif
717     endif
718   else
719     if b:iainstatus =~# "I"
720       " Regular insert mode.
721       let l:colour = l:editingcolour
722     endif
723   endif
724
725   " Override again if readonly.
726   if l:colour != l:normalcolour
727     if getbufvar("", "&ro")
728       let l:colour = l:readonlycolour
729     endif
730   endif
731
732   let l:termcolour = <SID>Iain_Colour(l:colour)
733
734   exec "highlight StatusLine guifg=white guibg=" . l:colour . " ctermfg=white ctermbg=" . l:termcolour
735 endfun
736
737 au Display VimEnter * call Highlight_StatusLine("")
738
739 " Show signs by default.
740 au Display VimEnter * call <SID>Cycle_Signs()
741 endif
742
743 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
744 " Handle options only available in Vim 7 and above.
745 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
746 if version >= "700"
747 version 7.0
748
749 " Helper to show tab name.
750 fun! <SID>TabName(label, gui)
751   let l:label = a:label
752   if l:label == ""
753     let l:label = "No Name"
754     if a:gui
755       let l:label = "[" . l:label . "]"
756     endif
757   else
758     let l:label = fnamemodify(l:label, ":t")
759     if strlen(l:label) >= 18
760       let l:label = l:label[0:17] . ".."
761     endif
762   endif
763   return l:label
764 endfun
765
766 " Find out if any buffer was modified.
767 fun! <SID>TabModified(buflist)
768   let l:i = 0
769   while i < len(a:buflist)
770     if getbufvar(a:buflist[l:i], "&modified") == 1
771       return "+"
772     endif
773     let l:i = l:i + 1
774   endwhile
775   return ""
776 endfun
777
778 " Tab line.
779 fun! Show_TabLine()
780   let l:s = "%#TabLineFill#Tabs:"
781
782   let l:i = 0
783   while l:i < tabpagenr("$")
784     let l:i = l:i + 1
785     " Get the label.
786     let l:buflist = tabpagebuflist(l:i)
787     let l:winnr = tabpagewinnr(l:i)
788     let l:n = tabpagewinnr(l:i, "$")
789     let l:label = <SID>TabName(bufname(l:buflist[l:winnr - 1]), 0)
790     let l:modified = <SID>TabModified(l:buflist)
791
792     " Choose highlighting.
793     if l:i == tabpagenr()
794       let l:s .= "%#TabLineSel#[" . l:n . l:modified . " " . l:label . "]"
795     else
796       let l:s .= "%#TabLine# " . l:n . l:modified . " " . l:label . " "
797     endif
798   endwhile
799
800   " Padding.
801   let l:s .= "%#TabLine#%T"
802   return l:s
803 endfun
804
805 " Per tab label for the GUI.
806 fun! Show_GUITabLine()
807   let l:buflist = tabpagebuflist(v:lnum)
808   let l:winnr = tabpagewinnr(v:lnum)
809   let l:s = tabpagewinnr(v:lnum, "$")
810   let l:label = <SID>TabName(bufname(l:buflist[l:winnr - 1]), 1)
811   let l:modified = <SID>TabModified(l:buflist)
812
813   let l:s .= l:modified . " " . l:label
814   return l:s
815 endfun
816
817 se tabline=%!Show_TabLine()
818 se guitablabel=%!Show_GUITabLine()
819
820 au StatusLine CursorHoldI * call Highlight_StatusLine("H")
821 au StatusLine CursorMovedI * call Highlight_StatusLine("h")
822 au StatusLine FocusGained * call Highlight_StatusLine("F")
823 au StatusLine FocusLost * call Highlight_StatusLine("f")
824 au StatusLine InsertEnter * call Highlight_StatusLine("I")
825 au StatusLine InsertLeave * call Highlight_StatusLine("i")
826
827 au Signs InsertEnter * call <SID>Highlight_Signs()
828 au Signs InsertLeave * call <SID>Highlight_Signs()
829
830 " Limit the size of the popup menu when completing.
831 se pumheight=20
832
833 " Make diffs vertical by default.
834 se diffopt+=vertical
835
836 " Set size of numbers column.
837 se numberwidth=5
838
839 " Add "previous tab" mapping as gb.
840 map gb :tabprevious<CR>:<CR>
841
842 " Transparency.
843 if has("gui_macvim")
844   se transparency=15
845 endif 
846
847 " Yet more GUI options.  Add tabs.
848 se go+=e
849
850 " Perforce.
851 let g:p4EnableMenu=1
852 let g:p4Presets='P4CONFIG'
853 endif