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