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