Feature 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 if has("signs")
84   se updatetime=500
85 endif
86
87 " Enable tab-completion prompting for commands.
88 se wildmenu
89 " Don't list object files when globbing files to load.
90 se wildignore+=*.o,*.obj
91 " So there's no need to assign them low priority.
92 se suffixes-=*.o,*.obj
93
94 " Save sessions in UNIX format with / as file separator.  This is
95 " cross-platform.
96 se ssop+=unix,slash
97
98 " Nuke any pre-existing autocommands.
99 augroup Display
100 autocmd!
101 augroup Mode
102 autocmd!
103 if has("signs")
104   augroup Signs
105   autocmd!
106 endif
107 augroup StatusLine
108 autocmd!
109 augroup END
110
111 " Save the current window width so we can restore it when we quit.
112 if ! exists("oldcols")
113   let oldcols=&columns
114 endif
115
116 " More GUI options.  Add icon, tearoffs and toolbar.
117 se go+=itT
118
119 " Allow dynamic window resize even if we aren't in an xterm.
120 se t_WS=\e[8;%p1%d;%p2%dt
121
122 " Highlight search results.
123 se hlsearch
124
125 " Set graphical window title.
126 se titlestring=%{Show_TitleString()}
127
128 " Syntax highlighting.  New versions will use syn enable instead.
129 if version < "600"
130   syn on
131 endif
132
133 " Use a discernably different colour to highlight the cursor which shows 
134 " matching brackets.  Our regular cursor is green so use blue instead of cyan.
135 hi MatchParen ctermbg=blue
136
137 " Catch typos.
138 command! W :w
139 command! Wq :wq
140 command! Wqa :wqa
141
142 " Set up our variables.
143 fun! Iain_Vars()
144   if ! exists("b:iainlist")
145     let b:iainlist = 0
146   endif
147   if ! exists("b:iainhex")
148     let b:iainhex = 0
149   endif
150   if ! exists("b:iainverbose")
151     let b:iainverbose = 0
152   endif
153   if ! exists("b:iainstatus")
154     " Window Flags: (F)ocused, (I)nsert mode, Cursor (H)old.
155     let b:iainstatus = "Fih"
156   endif
157   if ! exists("g:iainextracolumns")
158     let g:iainextracolumns = 0
159   endif
160   if has("signs")
161     if ! exists("g:marksigns")
162       let g:marksigns = 0
163     endif
164     if ! exists("g:firstsign")
165       let g:firstsign = 100
166     endif
167   endif
168 endfun
169
170 " Helper for status line.
171 " Show space, underscore or dollar sign depending on list mode.
172 fun! Show_List()
173   call Iain_Vars()
174   if b:iainlist == 0
175     " No list.
176     return " "
177   elseif b:iainlist == 1
178     " Just tabs.
179     return "_"
180   else
181     " Full list.
182     return "\$"
183   endif
184 endfun
185
186 " Helper for status line.
187 " Show c or C to denote case-sensitivity.
188 fun! Show_Case()
189   if &ic
190     return "c"
191   else
192     return "C"
193   endif
194 endfun
195
196 " Helper for status line.
197 " Show the size of the tabstop.
198 fun! Show_Tabstop()
199   return &ts
200 endfun
201
202 " Helper for status line.
203 " Show p when paste mode is on.
204 fun! Show_Paste()
205   if &paste
206     return "p"
207   else
208     return ""
209   endif
210 endfun
211
212 " Show the window title.
213 fun! Show_TitleString()
214   if bufname("") == ""
215     let l:ts1='Vim'
216   else
217     let l:ts1=printf("%2d: %s", bufnr(""), expand('%t'))
218   endif
219   return printf("%s (%s) %s", l:ts1, getcwd(), v:servername)
220 endfun
221
222 " Show the status line.
223 fun! Show_StatusLine()
224   call Iain_Vars()
225   let l:sl1='%2n\:\ %<%f\ [%{Show_List()}%{Show_Case()}%{Show_Tabstop()}%{Show_Paste()}%Y%M%R]\ %='
226   let l:sl3='L:%4.6l/%-4.6L\ C:%3.6c\ \|\ %P'
227   let l:hexformat='%b'
228   if b:iainhex
229     let l:hexformat='0\x%02B'
230   endif
231   if b:iainverbose
232     let l:sl2=l:hexformat . '\ \|\ P:%4.6o\ '
233   else
234     let l:sl2=''
235   endif
236   exec "set statusline=" . l:sl1 . l:sl2 . l:sl3
237 endfun
238
239 " Toggle case-sensitivity.
240 fun! Invert_Case()
241   let &ic = ! &ic
242 endfun
243
244 " Grow or shrink the window size.
245 fun! Resize_Columns(op, ...)
246   if a:0 == 0
247     " Vim 5 hardcodes the size of numbers column to 8.
248     if version >= "700"
249       let l:columns = &numberwidth
250     else
251       let l:columns = 8
252     endif
253   else
254     let l:columns = a:1
255   endif
256
257   let l:resize = "se columns" . a:op . "=" . l:columns
258
259   " HACK: Inside screen there is an extra line for the status bar.  Vim
260   " manages the resize by sending an escape sequence to set the number of
261   " lines and number of columns in one action.  To do this it will first query
262   " the number of lines and then set <same number of lines> by <new number of
263   " columns>.  Because of the extra line for the status bar this results in
264   " the real terminal being shrunk by a line.  We ask for the terminal to grow
265   " by a line so it ends up actually being the same.
266   if &term =~ '^screen'
267     let l:resize .= " lines+=1"
268   endif
269
270   exec l:resize
271 endfun
272
273 " Toggle number display.
274 fun! Number(resize)
275   call Iain_Vars()
276   let &number = ! &number
277
278   if version >= "700"
279     let l:i = 0
280     let l:num_numbers = 0
281     while l:i <= winnr("$")
282       if getwinvar(l:i, "&number") == 1
283         let l:num_numbers = l:num_numbers + 1
284       endif
285       let l:i = l:i + 1
286     endwhile
287
288     if l:num_numbers == 0
289       let g:iainextracolumns = 0
290       if a:resize
291         call Resize_Columns("-")
292       endif
293     elseif g:iainextracolumns == 0
294       let g:iainextracolumns = 1
295       if a:resize
296         call Resize_Columns("+")
297       endif
298     endif
299   endif
300 endfun
301
302 " Restore window size.
303 au Display VimLeave * if exists("oldcols") | call Resize_Columns("-", (&columns - oldcols)) | endif
304
305 " Map Makefile mode.
306 au Mode BufEnter * if &ft == "make" | call MakeMode_map() | endif
307 au Mode BufLeave * if &ft == "make" | call MakeMode_unmap() | endif
308
309 " Entering Make mode.
310 fun! MakeMode_map()
311         call Iain_Vars()
312   let b:iainlist=1
313   call Cycle_List()
314   set ts=8
315   set noexpandtab
316 endfun
317
318 " Leaving Make mode.
319 fun! MakeMode_unmap()
320   call Cycle_List()
321   set ts=2
322   set expandtab
323 endfun
324
325 " Show the status line for the first time.
326 call Show_StatusLine()
327
328 " Function to create mappings with either a hardcoded \ or <Leader>.
329 fun! Mapping(keysequence,mapping)
330   if version < "600"
331     exec "map \\" . a:keysequence . " " . a:mapping
332   else
333     exec "map <Leader>" . a:keysequence . " " . a:mapping
334   endif
335 endfun
336
337 " Use - and = to create underlines.
338 call Mapping("-", "yyp:s/./-/g<RETURN>:let @/=''<RETURN>:<RETURN>")
339 call Mapping("=", "yyp:s/./=/g<RETURN>:let @/=''<RETURN>:<RETURN>")
340
341 " Change to ts=2 with \2.
342 call Mapping("2", ":se ts=2<CR>:<CR>")
343 " Change to ts=4 with \4.
344 call Mapping("4", ":se ts=4<CR>:<CR>")
345 " Change to ts=8 with \8.
346 call Mapping("8", ":se ts=8<CR>:<CR>")
347 " Change to ts=16 with \6.
348 call Mapping("6", ":se ts=16<CR>:<CR>")
349 " Change to ts=32 with \3.
350 call Mapping("3", ":se ts=32<CR>:<CR>")
351 " Toggle paste mode with \p.
352 call Mapping("p", ":se paste!<CR>:<CR>")
353 " Swap case-sensitivity with \c.
354 call Mapping("c", ":call Invert_Case()<CR>:<CR>")
355 " Change number mode with \n.
356 call Mapping("n", ":call Number(1)<CR>:<CR>")
357 " Expand or shrink window size with \> and \<.
358 call Mapping(">", ":call Resize_Columns('+')<CR>:<CR>")
359 call Mapping("<", ":call Resize_Columns('-')<CR>:<CR>")
360 " Clear search pattern with \/.
361 call Mapping("/", ":let @/=\"\"<CR>:<CR>")
362
363 " Forget the Ex mode mapping.
364 map Q <NOP>
365
366 " Vim tip 99: What's the highlighting group under the cursor?
367 call Mapping("h", ":echo \"hi<\" . synIDattr(synID(line(\".\"),col(\".\"),1),\"name\") . '> trans<' . synIDattr(synID(line(\".\"),col(\".\"),0),\"name\") . \"> lo<\" . synIDattr(synIDtrans(synID(line(\".\"),col(\".\"),1)),\"name\") . \">\"<CR>")
368
369 fun! <SID>Startup_Resize()
370   " Resize for numbers.
371   if version >= "700"
372     let l:columns = &numberwidth
373   else
374     let l:columns = 8
375   endif
376
377   " Resize for signs.
378   if has("signs")
379     if version >= "600"
380       let l:columns += 2
381     endif
382   endif
383
384   call Resize_Columns("+", l:columns)
385 endfun
386
387 " Show numbers by default.
388 au Display VimEnter * call Number(0)
389
390 " Resize after startup.
391 au Display VimEnter * call <SID>Startup_Resize()
392 endif
393
394 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
395 " Handle options only available in Vim 6 and above.
396 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
397 if version >= "600"
398 version 6.0
399
400 " Remember quickfix state.
401 let g:quickfixing=0
402
403 " Set indenting by filetype.
404 filetype indent on
405
406 " Less intrusive syntax highlighting.
407 syn enable
408
409 " Set colours.
410 if has("gui_running")
411   try
412     if has("win32")
413       se guifont=DejaVu_Sans_Mono:h10:cANSI
414     else
415       se guifont=DejaVu\ Sans\ Mono\ 10
416     endif
417   catch
418   endtry
419 endif
420 if has("gui_running") || &t_Co > 16
421   try
422     colo iain
423   catch
424   endtry
425 endif
426
427 " Ignore whitespace when diffing.
428 se diffopt=filler,iwhite
429
430 " Expand window when doing a vertical diff.
431 if &diff
432   let &columns = 164
433 endif
434
435 " Remember that we are opening the quickfix window.
436 au Mode BufWinEnter quickfix let g:quickfixing=1
437 au Mode BufUnload * if &ft == "qf" | let g:quickfixing=0 | endif
438
439 " Allow in-place editing of crontabs.
440 au Mode FileType crontab set backupcopy=yes
441
442 " Make * and # work the way you expect in visual mode.
443 vnoremap * y/\V<C-R>=substitute(escape(@@,"/\\"),"\n","\\\\n","ge")<CR><CR>
444 vnoremap # y?\V<C-R>=substitute(escape(@@,"?\\"),"\n","\\\\n","ge")<CR><CR>
445
446 " Set mark and update highlighting.
447 if has("signs")
448   au Signs BufEnter * call <SID>Highlight_Signs()
449   au Signs CursorHold * call <SID>Highlight_Signs()
450 endif
451
452 fun! <SID>Prep_Signs()
453   if ! exists("b:signdot") || ! g:marksigns
454     let b:signdot=0
455   endif
456   if ! exists("b:signdash") || ! g:marksigns
457     let b:signdash=0
458   endif
459   if ! exists("b:signquote") || ! g:marksigns
460     let b:signquote=0
461   endif
462   if ! exists("b:signcaret") || ! g:marksigns
463     let b:signcaret=0
464   endif
465   if ! exists("b:signless") || ! g:marksigns
466     let b:signless=0
467   endif
468   if ! exists("b:signgreater") || ! g:marksigns
469     let b:signgreater=0
470   endif
471   if ! exists("b:signleft") || ! g:marksigns
472     let b:signleft=0
473   endif
474   if ! exists("b:signright") || ! g:marksigns
475     let b:signright=0
476   endif
477   if ! exists("b:signa") || ! g:marksigns
478     let b:signa=0
479   endif
480   if ! exists("b:signb") || ! g:marksigns
481     let b:signb=0
482   endif
483   if ! exists("b:signc") || ! g:marksigns
484     let b:signc=0
485   endif
486   if ! exists("b:signd") || ! g:marksigns
487     let b:signd=0
488   endif
489   if ! exists("b:signe") || ! g:marksigns
490     let b:signe=0
491   endif
492   if ! exists("b:signf") || ! g:marksigns
493     let b:signf=0
494   endif
495   if ! exists("b:signA") || ! g:marksigns
496     let b:signA=0
497   endif
498   if ! exists("b:signB") || ! g:marksigns
499     let b:signB=0
500   endif
501   if ! exists("b:signC") || ! g:marksigns
502     let b:signC=0
503   endif
504   if ! exists("b:signD") || ! g:marksigns
505     let b:signD=0
506   endif
507   if ! exists("b:signE") || ! g:marksigns
508     let b:signE=0
509   endif
510   if ! exists("b:signF") || ! g:marksigns
511     let b:signF=0
512   endif
513 endfun!
514
515 fun! <SID>Place_Sign(number, line, old, name)
516   if a:line == a:old
517     return a:old
518   endif
519
520   exe "sign unplace " . (g:firstsign + a:number) . " buffer=" . bufnr("")
521   " Don't place the sign if it would conflict with the last change sign.
522   exe "sign place " . (g:firstsign + a:number) . " line=" . a:line . " name=" . a:name . " buffer=" . bufnr("")
523   return a:line
524 endfun
525
526 fun! <SID>Highlight_Signs(...)
527   if ! has("signs") || ! g:marksigns
528     return
529   endif
530
531   call <SID>Prep_Signs()
532
533   let b:signdot = <SID>Place_Sign(0, line("'."), b:signdot, "MarkDot")
534   let b:signdash = <SID>Place_Sign(1, line("''"), b:signdash, "MarkDash")
535   let b:signquote = <SID>Place_Sign(2, line("'\""), b:signquote, "MarkQuote")
536   let b:signcaret = <SID>Place_Sign(3, line("'^"), b:signcaret, "MarkCaret")
537   let b:signless = <SID>Place_Sign(4, line("'<"), b:signcaret, "MarkLess")
538   let b:signgreater = <SID>Place_Sign(5, line("'>"), b:signcaret, "MarkGreater")
539   let b:signleft = <SID>Place_Sign(6, line("'["), b:signcaret, "MarkLeft")
540   let b:signright = <SID>Place_Sign(7, line("']"), b:signcaret, "MarkRight")
541
542   let b:signa = <SID>Place_Sign(8, line("'a"), b:signa, "Marka")
543   let b:signb = <SID>Place_Sign(9, line("'b"), b:signb, "Markb")
544   let b:signc = <SID>Place_Sign(10, line("'c"), b:signc, "Markc")
545   let b:signd = <SID>Place_Sign(11, line("'d"), b:signd, "Markd")
546   let b:signe = <SID>Place_Sign(12, line("'e"), b:signe, "Marke")
547   let b:signf = <SID>Place_Sign(13, line("'f"), b:signf, "Markf")
548   let b:signA = <SID>Place_Sign(14, line("'A"), b:signA, "MarkA")
549   let b:signB = <SID>Place_Sign(15, line("'B"), b:signB, "MarkB")
550   let b:signC = <SID>Place_Sign(16, line("'C"), b:signC, "MarkC")
551   let b:signD = <SID>Place_Sign(17, line("'D"), b:signD, "MarkD")
552   let b:signE = <SID>Place_Sign(18, line("'E"), b:signE, "MarkE")
553   let b:signF = <SID>Place_Sign(19, line("'F"), b:signF, "MarkF")
554 endfun
555
556 " Toggle signs.
557 fun! <SID>Cycle_Signs(resize)
558   if ! has("signs")
559     return
560   endif
561   call Iain_Vars()
562   let g:marksigns = ! g:marksigns
563
564   if g:marksigns
565     " Signs to highlight marks.
566     " Syntax won't work properly in Vim 6.
567     sign define MarkDash text=' texthl=MarkSign
568     sign define MarkDot text=* texthl=MarkDot
569     sign define MarkQuote text=" texthl=MarkSign
570     sign define MarkCaret text=^ texthl=MarkSign
571     sign define MarkLess text=< texthl=MarkSign
572     sign define MarkGreater text=> texthl=MarkSign
573     sign define MarkLeft text=[ texthl=MarkSign
574     sign define MarkRight text=] texthl=MarkSign
575     sign define Marka text=a texthl=MarkSign linehl=MarkLine
576     sign define Markb text=b texthl=MarkSign linehl=MarkLine
577     sign define Markc text=c texthl=MarkSign linehl=MarkLine
578     sign define Markd text=d texthl=MarkSign linehl=MarkLine
579     sign define Marke text=e texthl=MarkSign linehl=MarkLine
580     sign define Markf text=f texthl=MarkSign linehl=MarkLine
581     sign define MarkA text=A texthl=MarkSign linehl=MarkLine
582     sign define MarkB text=B texthl=MarkSign linehl=MarkLine
583     sign define MarkC text=C texthl=MarkSign linehl=MarkLine
584     sign define MarkD text=D texthl=MarkSign linehl=MarkLine
585     sign define MarkE text=E texthl=MarkSign linehl=MarkLine
586     sign define MarkF text=F texthl=MarkSign linehl=MarkLine
587
588     if a:resize
589       call Resize_Columns("+", 2)
590     endif
591     call <SID>Highlight_Signs()
592   else
593     exe "sign unplace " . (g:firstsign + 0)
594     exe "sign unplace " . (g:firstsign + 1)
595     exe "sign unplace " . (g:firstsign + 2)
596     exe "sign unplace " . (g:firstsign + 3)
597     exe "sign unplace " . (g:firstsign + 4)
598     exe "sign unplace " . (g:firstsign + 5)
599     exe "sign unplace " . (g:firstsign + 6)
600     exe "sign unplace " . (g:firstsign + 7)
601     exe "sign unplace " . (g:firstsign + 8)
602     exe "sign unplace " . (g:firstsign + 9)
603     exe "sign unplace " . (g:firstsign + 10)
604     exe "sign unplace " . (g:firstsign + 11)
605     exe "sign unplace " . (g:firstsign + 12)
606     exe "sign unplace " . (g:firstsign + 13)
607     exe "sign unplace " . (g:firstsign + 14)
608     exe "sign unplace " . (g:firstsign + 15)
609     exe "sign unplace " . (g:firstsign + 16)
610     exe "sign unplace " . (g:firstsign + 17)
611     exe "sign unplace " . (g:firstsign + 18)
612     exe "sign unplace " . (g:firstsign + 19)
613
614     sign undefine MarkDash
615     sign undefine MarkDot
616     sign undefine MarkQuote
617     sign undefine MarkCaret
618     sign undefine MarkLess
619     sign undefine MarkGreater
620     sign undefine MarkLeft
621     sign undefine MarkRight
622     sign undefine Marka
623     sign undefine Markb
624     sign undefine Markc
625     sign undefine Markd
626     sign undefine Marke
627     sign undefine Markf
628     sign undefine MarkA
629     sign undefine MarkB
630     sign undefine MarkC
631     sign undefine MarkD
632     sign undefine MarkE
633     sign undefine MarkF
634
635     call <SID>Prep_Signs()
636     if a:resize
637       call Resize_Columns("-", 2)
638     endif
639   endif
640 endfun
641
642 " Change list mode.
643 fun! Cycle_List()
644   let basic='tab:\\_,trail:_,extends:<,precedes:>'
645   call Iain_Vars()
646   let b:iainlist = b:iainlist + 1
647   if b:iainlist > 2
648     let b:iainlist = 0
649   endif
650   if b:iainlist == 0
651     set nolist
652   elseif b:iainlist == 1
653     exec "set lcs=" . basic
654     set list
655   else
656     exec "set lcs=" . basic . ",eol:$"
657     set list
658   endif
659 endfun
660
661 " Cycle between hex and decimal display of toolbar stuff.
662 fun! Cycle_HexStatusLine()
663   call Iain_Vars()
664   let b:iainhex = ! b:iainhex
665   call Show_StatusLine()
666 endfun
667
668 " Cycle verbose display of toolbar stuff.
669 fun! Cycle_VerboseStatusLine()
670   call Iain_Vars()
671   let b:iainverbose = ! b:iainverbose
672   call Show_StatusLine()
673 endfun
674
675 " Toggle quickfix window.
676 fun! Cycle_Quickfix()
677   if g:quickfixing == 1
678     cclose
679     let g:quickfixing=0
680   else
681     copen
682   endif
683 endfun
684
685 " Swap hex/decimal statusline with \x.
686 call Mapping("x", ":call Cycle_HexStatusLine()<CR>:<CR>")
687 " Change statusline verbosity with \v.
688 call Mapping("v", ":call Cycle_VerboseStatusLine()<CR>:<CR>")
689 " Cycle list styles with \l.
690 call Mapping("l", ":call Cycle_List()<CR>:<CR>")
691 " Toggle tags with \t.
692 call Mapping("t", ":Tlist<CR>")
693 " Change foldmethod with \f.
694 call Mapping("f", ":se foldenable!<CR>:<CR>")
695 " Toggle quickfix window with \q.
696 call Mapping("q", ":call Cycle_Quickfix()<CR>:<CR>")
697 " Rerun filetype detection with \s.  The s is for syntax, as this will be
698 " updated as a side-effect.
699 call Mapping("s", ":filetype detect<CR>:<CR>")
700 " Toggle marks with \m.
701 call Mapping("m", ":call <SID>Cycle_Signs(1)<CR>:<CR>")
702
703 fun! <SID>Iain_Colour(colour)
704   if &t_Co == 88
705     if a:colour == "darkblue"
706       return 17
707     elseif a:colour == "darkmagenta"
708       return 33
709     elseif a:colour == "darkred"
710       return 32
711     elseif a:colour == "red"
712       return 64
713     endif
714   elseif &t_Co == 256
715     if a:colour == "darkblue"
716       return 17
717     elseif a:colour == "darkmagenta"
718       return 90
719     elseif a:colour == "darkred"
720       return 88
721     elseif a:colour == "red"
722       return 196
723     endif
724   else
725     return a:colour
726   endif
727 endfun
728
729 " Change status bar colour when various things happen.
730 " Flags: H/h: Cursor held/moved.
731 "        F/f: Focus gained/lost.
732 "        I/i: Insert mode entered/left.
733 fun! Highlight_StatusLine(flag)
734   " Get current status.
735   call Iain_Vars()
736
737   " Change the status based on the flag.  XXX: Does Vim let us to do flags?
738   let re = "[" . tolower(a:flag) . toupper(a:flag) . "]"
739   let b:iainstatus = substitute(b:iainstatus, re, a:flag, "")
740
741   let l:normalcolour = "darkblue"
742   let l:editingcolour = "darkmagenta"
743   let l:warningcolour = "darkred"
744   let l:readonlycolour = "red"
745
746   " Default colour.
747   let l:colour = l:normalcolour
748   " Maybe override depending on status.
749   if b:iainstatus =~# "H"
750     if b:iainstatus =~# "I"
751       " Held in insert mode.  Add extra highlight if we don't have focus.
752       if b:iainstatus =~# "f"
753         let l:colour = l:warningcolour
754       else
755         let l:colour = l:editingcolour
756       endif
757     endif
758   else
759     if b:iainstatus =~# "I"
760       " Regular insert mode.
761       let l:colour = l:editingcolour
762     endif
763   endif
764
765   " Override again if readonly.
766   if l:colour != l:normalcolour
767     if getbufvar("", "&ro")
768       let l:colour = l:readonlycolour
769     endif
770   endif
771
772   let l:termcolour = <SID>Iain_Colour(l:colour)
773
774   exec "highlight StatusLine gui=bold term=bold cterm=bold guifg=white guibg=" . l:colour . " ctermfg=white ctermbg=" . l:termcolour
775 endfun
776
777 au Display VimEnter * call Highlight_StatusLine("")
778
779 " Show signs by default.
780 au Display VimEnter * call <SID>Cycle_Signs(0)
781 endif
782
783 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
784 " Handle options only available in Vim 7 and above.
785 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
786 if version >= "700"
787 version 7.0
788
789 " Helper to show tab name.
790 fun! <SID>TabName(label, gui)
791   let l:label = a:label
792   if l:label == ""
793     let l:label = "No Name"
794     if a:gui
795       let l:label = "[" . l:label . "]"
796     endif
797   else
798     let l:label = fnamemodify(l:label, ":t")
799     if strlen(l:label) >= 18
800       let l:label = l:label[0:17] . ".."
801     endif
802   endif
803   return l:label
804 endfun
805
806 " Find out if any buffer was modified.
807 fun! <SID>TabModified(buflist)
808   let l:i = 0
809   while i < len(a:buflist)
810     if getbufvar(a:buflist[l:i], "&modified") == 1
811       return "+"
812     endif
813     let l:i = l:i + 1
814   endwhile
815   return ""
816 endfun
817
818 " Tab line.
819 fun! Show_TabLine()
820   let l:s = "%#TabLineFill#Tabs:"
821
822   let l:i = 0
823   while l:i < tabpagenr("$")
824     let l:i = l:i + 1
825     " Get the label.
826     let l:buflist = tabpagebuflist(l:i)
827     let l:winnr = tabpagewinnr(l:i)
828     let l:n = tabpagewinnr(l:i, "$")
829     let l:label = <SID>TabName(bufname(l:buflist[l:winnr - 1]), 0)
830     let l:modified = <SID>TabModified(l:buflist)
831
832     " Choose highlighting.
833     if l:i == tabpagenr()
834       let l:s .= "%#TabLineSel#[" . l:n . l:modified . " " . l:label . "]"
835     else
836       let l:s .= "%#TabLine# " . l:n . l:modified . " " . l:label . " "
837     endif
838   endwhile
839
840   " Padding.
841   let l:s .= "%#TabLine#%T"
842   return l:s
843 endfun
844
845 " Per tab label for the GUI.
846 fun! Show_GUITabLine()
847   let l:buflist = tabpagebuflist(v:lnum)
848   let l:winnr = tabpagewinnr(v:lnum)
849   let l:s = tabpagewinnr(v:lnum, "$")
850   let l:label = <SID>TabName(bufname(l:buflist[l:winnr - 1]), 1)
851   let l:modified = <SID>TabModified(l:buflist)
852
853   let l:s .= l:modified . " " . l:label
854   return l:s
855 endfun
856
857 se tabline=%!Show_TabLine()
858 se guitablabel=%!Show_GUITabLine()
859
860 au StatusLine CursorHoldI * call Highlight_StatusLine("H")
861 au StatusLine CursorMovedI * call Highlight_StatusLine("h")
862 au StatusLine FocusGained * call Highlight_StatusLine("F")
863 au StatusLine FocusLost * call Highlight_StatusLine("f")
864 au StatusLine InsertEnter * call Highlight_StatusLine("I")
865 au StatusLine InsertLeave * call Highlight_StatusLine("i")
866
867 if has("signs")
868   au Signs InsertEnter * call <SID>Highlight_Signs()
869   au Signs InsertLeave * call <SID>Highlight_Signs()
870 endif
871
872 " Limit the size of the popup menu when completing.
873 se pumheight=20
874
875 " Make diffs vertical by default.
876 se diffopt+=vertical
877
878 " Set size of numbers column.
879 se numberwidth=5
880
881 " Add "previous tab" mapping as gb.
882 map gb :tabprevious<CR>:<CR>
883
884 " Transparency.
885 if has("gui_macvim")
886   se transparency=15
887 endif 
888
889 " Yet more GUI options.  Add tabs.
890 se go+=e
891
892 " Perforce.
893 let g:p4EnableMenu=1
894 let g:p4Presets='P4CONFIG'
895 endif