Vim fixes.
[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 but only if it can work.
79 if has("xterm_clipboard")
80   se mouse=nvir
81 endif
82
83 " Update more quickly.  For use with sign highlighting as polling for
84 " CursorMove makes redrawing slow.
85 if has("signs")
86   se updatetime=500
87 endif
88
89 " Enable tab-completion prompting for commands.
90 se wildmenu
91 " Don't list object files when globbing files to load.
92 se wildignore+=*.o,*.obj
93 " So there's no need to assign them low priority.
94 se suffixes-=*.o,*.obj
95
96 " Save sessions in UNIX format with / as file separator.  This is
97 " cross-platform.
98 se ssop+=unix,slash
99
100 " Nuke any pre-existing autocommands.
101 augroup Display
102 autocmd!
103 augroup Mode
104 autocmd!
105 if has("signs")
106   augroup Signs
107   autocmd!
108 endif
109 augroup StatusLine
110 autocmd!
111 augroup END
112
113 " Save the current window width so we can restore it when we quit.
114 if ! exists("g:oldcols")
115   let g:oldcols=&columns
116 endif
117
118 " More GUI options.  Add icon and tearoffs.
119 se go+=i
120 se go+=t
121
122 " Allow dynamic window resize even if we aren't in an xterm.
123 se t_WS=\e[8;%p1%d;%p2%dt
124
125 " Highlight search results.
126 se hlsearch
127
128 " Set graphical window title.
129 se titlestring=%{Show_TitleString()}
130
131 " Syntax highlighting.  New versions will use syn enable instead.
132 if version < "600"
133   syn on
134 endif
135
136 " Catch typos.
137 command! W :w
138 command! Wq :wq
139 command! Wqa :wqa
140
141 " Set up our variables.
142 fun! Iain_Vars()
143   if ! exists("b:iainlist")
144     let b:iainlist = 0
145   endif
146   if ! exists("b:iainhex")
147     let b:iainhex = 0
148   endif
149   if ! exists("b:iainverbose")
150     let b:iainverbose = 0
151   endif
152   if ! exists("b:iainstatus")
153     " Window Flags: (F)ocused, (I)nsert mode, Cursor (H)old.
154     let b:iainstatus = "Fih"
155   endif
156   if ! exists("g:iainextracolumns")
157     let g:iainextracolumns = 0
158   endif
159   if has("signs")
160     if ! exists("g:marksigns")
161       let g:marksigns = 0
162     endif
163     if ! exists("g:firstsign")
164       let g:firstsign = 100
165     endif
166   endif
167 endfun
168
169 " Helper for status line.
170 " Show space, underscore or dollar sign depending on list mode.
171 fun! Show_List()
172   call Iain_Vars()
173   if b:iainlist == 0
174     " No list.
175     return " "
176   elseif b:iainlist == 1
177     " Just tabs.
178     return "_"
179   else
180     " Full list.
181     return "\$"
182   endif
183 endfun
184
185 " Helper for status line.
186 " Show c or C to denote case-sensitivity.
187 fun! Show_Case()
188   if &ic
189     return "c"
190   else
191     return "C"
192   endif
193 endfun
194
195 " Helper for status line.
196 " Show the size of the tabstop.
197 fun! Show_Tabstop()
198   return &ts
199 endfun
200
201 " Helper for status line.
202 " Show p when paste mode is on.
203 fun! Show_Paste()
204   if &paste
205     return "p"
206   else
207     return ""
208   endif
209 endfun
210
211 " Show the window title.
212 fun! Show_TitleString()
213   if bufname("") == ""
214     let l:ts1='Vim'
215   else
216     let l:ts1=printf("%2d: %s", bufnr(""), expand('%t'))
217   endif
218   return printf("%s (%s) %s", l:ts1, getcwd(), v:servername)
219 endfun
220
221 " Show the status line.
222 fun! Show_StatusLine()
223   call Iain_Vars()
224   let l:sl1='%2n\:\ %<%f\ [%{Show_List()}%{Show_Case()}%{Show_Tabstop()}%{Show_Paste()}%Y%M%R]\ %='
225   let l:sl3='L:%4.6l/%-4.6L\ C:%3.6c\ \|\ %P'
226   let l:hexformat='%b'
227   if b:iainhex
228     let l:hexformat='0\x%02B'
229   endif
230   if b:iainverbose
231     let l:sl2=l:hexformat . '\ \|\ P:%4.6o\ '
232   else
233     let l:sl2=''
234   endif
235   exec "set statusline=" . l:sl1 . l:sl2 . l:sl3
236 endfun
237
238 " Toggle case-sensitivity.
239 fun! Invert_Case()
240   let &ic = ! &ic
241 endfun
242
243 " Grow or shrink the window size.
244 fun! Resize_Columns(op, ...)
245   if a:0 == 0
246     " Vim 5 hardcodes the size of numbers column to 8.
247     if version >= "700"
248       let l:columns = &numberwidth
249     else
250       let l:columns = 8
251     endif
252   else
253     let l:columns = a:1
254   endif
255
256   exe "let l:resize=" . &columns . a:op . l:columns
257   let l:resize = "se columns=" . l:resize
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 = l:resize . " lines=" . (&lines + 1)
268   endif
269
270   exe 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("g:oldcols") | call Resize_Columns("-", (&columns - g: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! Startup_Resize()
370   let l:columns = 0
371
372   " Resize for numbers.
373   if &number
374     if version >= "700"
375       let l:columns = &numberwidth
376     else
377       let l:columns = 8
378     endif
379   endif
380
381   " Resize for signs.
382   if has("signs")
383     if g:marksigns
384       if version >= "600"
385         let l:columns = l:columns + 2
386       endif
387     endif
388   endif
389
390   if g:oldcols < (80 + l:columns)
391     call Resize_Columns("+", l:columns)
392   endif
393 endfun
394
395 " Show numbers by default.
396 au Display VimEnter * call Number(0)
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 l: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
901
902 if version >= "500"
903 " Resize after startup.
904 au Display VimEnter * call Startup_Resize()
905 endif