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