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