f572ab2860d615ce30963d421da986f4f2c3245b
[profile.git] / .vimrc
1 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
2 " Multi-version vimrc compatible with version 4 and above.   vim6:set fdm=marker:
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 " Some of these settings should strictly be wrapped inside "if has()" blocks
17 " but that would cause them not to be ignored by Vim 4.
18 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
19 "{{{1
20 " No compatibility mode.
21 se nocp
22
23 " Tabstop 2.
24 se ts=2
25 " And use spaces not tabs.
26 se expandtab
27 " And << and >> indent by 2.
28 se sw=2
29 " Backspace deletes full tab width at the start of a line.
30 se smarttab
31
32 " Allow backspace to delete before start of line.
33 se bs=2
34
35 " Don't jump to the start of the line when using H, L etc.
36 se nosol
37
38 " Show the ruler.
39 se ruler
40 " Show partial commands in the ruler.
41 se showcmd
42 " And always show the status line.
43 se laststatus=2
44
45 " Use C indent style.
46 se cindent
47 se cinkeys=0{,0},0),:,!^F,o,O,e
48 se cinoptions=b1,c2
49
50 " GUI options.
51 se go=aglmr
52
53 " Don't be bugged by messages at the bottom of the screen.
54 se shm=aot
55
56 " Find as you type.
57 se incsearch
58
59 " Case-insensitive search.
60 se ignorecase
61 " But override by typing capitals.
62 se smartcase
63
64 " Look for ctags in home directory first.
65 se tags=~/.tags,./tags,tags
66
67 " Don't timeout waiting to interpet, eg, <ESC>OA as an escape code.
68 se ttimeoutlen=100
69
70 " Remember undo list for closed (but not wiped) buffers.
71 se hidden
72
73 " Use ^B to search backward when completing.
74 inoremap <C-b> <C-p>
75 " Use ^L to show matching completions but don't select one.
76 inoremap <C-l> <C-n><C-p>
77
78 " Swap jump keys.
79 nnoremap ' `
80 nnoremap ` '
81
82 " Select previous widnow.
83 nnoremap <C-w>^ <C-w>p
84 nnoremap <C-w><C-^> <C-w>p
85 "}}}1
86
87 " Find stuff.
88 if (has("win32") || has("win64")) && version >= "504"
89   se rtp=~/.vim,$VIMRUNTIME
90 endif
91
92 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
93 " Handle options only available in Vim 5 and above.
94 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
95 if version >= "500" "{{{1
96 version 5.0
97
98 " Tell Vim we use dark backgrounds in our terminals.
99 if ! has("gui_running")
100   se bg=dark
101 endif
102
103 " Allow mouse use in a terminal but only if it can work.
104 if has("xterm_clipboard")
105   se mouse=nvir
106 endif
107
108 " Update more quickly.  For use with sign highlighting as polling for
109 " CursorMove makes redrawing slow.
110 if has("signs")
111   se updatetime=500
112 endif
113
114 " Enable tab-completion prompting for commands.
115 if has("wildmenu")
116   se wildmenu
117   " Don't list object files when globbing files to load.
118   se wildignore+=*.o,*.obj
119   " So there's no need to assign them low priority.
120   se suffixes-=*.o,*.obj
121 endif
122
123 " Save sessions in UNIX format with / as file separator.  This is
124 " cross-platform.
125 if has("mksession")
126   se ssop+=unix,slash
127 endif
128
129 " How often do we need to use ^A/^X on octals?
130 se nf=hex
131
132 " Nuke any pre-existing autocommands.
133 if has("autocmd")
134   augroup Display
135   autocmd!
136   augroup Mode
137   autocmd!
138   if has("signs")
139     augroup Signs
140     autocmd!
141   endif
142   augroup StatusLine
143   autocmd!
144   augroup File
145   autocmd!
146   augroup END
147 endif
148
149 " Save the current window dimensions so we can restore them when we quit.
150 if ! exists("g:oldcols")
151   let g:oldcols=&columns
152 endif
153 if ! exists("g:oldlines")
154   let g:oldlines=&lines
155 endif
156
157 " More GUI options.  Add icon and tearoffs.
158 if has("gui")
159   se go+=i
160   se go+=t
161 endif
162
163 " Allow dynamic window resize even if we aren't in an xterm.
164 se t_WS=\e[8;%p1%d;%p2%dt
165
166 " Highlight search results.
167 if has("extra_search")
168   se hlsearch
169 endif
170
171 " Syntax highlighting.  New versions will use syn enable instead.
172 if version < "600"
173   syn on
174 endif
175
176 if has("user_commands")
177   " Catch typos.
178   command! W :w
179   command! Wq :wq
180   command! Wqa :wqa
181 endif
182
183 " Forget the Ex mode mapping.
184 map Q <NOP>
185
186 if has("autocmd")
187   " Position the compview plugin window.
188   au Display BufEnter -SearchResults- set buftype=nowrite | set nonumber | wincmd J
189 endif
190 endif "}}}1
191
192 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
193 " Handle options only available in Vim 5.2 and above.
194 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
195 if version >= "502" "{{{1
196 version 5.2
197
198 " Helper to initialise a variable.
199 fun! Prep_Var(var, value) "{{{2
200   if exists(a:var)
201     return
202   endif
203   exe "let " . a:var . "=" . a:value
204 endfun "}}}2
205
206 " Set up our variables.
207 fun! Iain_Vars() "{{{2
208   call Prep_Var("w:iainlist", 0)
209   call Prep_Var("b:iainhex", 0)
210   call Prep_Var("b:iainverbose", 0)
211   " Window Flags: (F)ocused, (I)nsert mode, Cursor (H)old.
212   call Prep_Var("b:iainstatus", "'Fih'")
213   call Prep_Var("g:iainextracolumnsnumber", "''")
214   call Prep_Var("g:iainextracolumnslist", "''")
215   call Prep_Var("b:iainalt", 0)
216   if has("signs")
217     call Prep_Var("g:marksigns", 0)
218     call Prep_Var("g:firstsign", 100)
219   endif
220   call Prep_Var("g:resizable", "''")
221 endfun "}}}2
222
223 " Show the window title.
224 fun! Show_TitleString() "{{{2
225   if bufname("") == ""
226     let l:ts1='Vim'
227   else
228     " Vim 5 doesn't have printf.
229     let l:ts1=bufnr("")
230     if l:ts1 < 10
231       let l:ts1=" " . l:ts1
232     endif
233     let l:ts1=l:ts1 . ": " . expand('%t')
234   endif
235   let l:ts1=l:ts1 . " (" .  getcwd() . ")"
236   if has("clientserver")
237     let l:ts1=l:ts1 . " " . v:servername
238   endif
239   return l:ts1
240 endfun "}}}2
241
242 " Toggle case-sensitivity.
243 fun! Invert_Case() "{{{2
244   let &ic = ! &ic
245 endfun "}}}2
246
247 " Can we resize this window?
248 fun! Can_Resize() "{{{2
249   call Iain_Vars()
250
251   if g:resizable == "0" || g:resizable == "1"
252     return g:resizable
253   endif
254
255   " Do we KNOW we can(not) resize?
256   if has("gui_running")
257     let g:resizable = 1
258   elseif $RESIZABLE == &term
259     let g:resizable = 1
260   elseif $RESIZABLE == "0"
261     let g:resizable = 0
262   else
263     " Assume we can.  Allow overriding.
264     let g:resizable = 1
265   endif
266   return g:resizable
267 endfun "}}}2
268
269 " Grow or shrink the window width.
270 fun! Resize_Columns(op, ...) "{{{2
271   if a:op == ""
272     return
273   endif
274
275   if ! Can_Resize()
276     return
277   endif
278
279   if a:0 == 0
280     " Vim 5 hardcodes the size of numbers column to 8.
281     if version >= "700" && has("linebreak")
282       let l:columns = &numberwidth
283     else
284       let l:columns = 8
285     endif
286   else
287     let l:columns = a:1
288   endif
289
290   exe "let l:resize=" . &columns . a:op . l:columns
291   let l:resize = "se columns=" . l:resize
292
293   " HACK: Inside screen there is an extra line for the status bar.  Vim
294   " manages the resize by sending an escape sequence to set the number of
295   " lines and number of columns in one action.  To do this it will first query
296   " the number of lines and then set <same number of lines> by <new number of
297   " columns>.  Because of the extra line for the status bar this results in
298   " the real terminal being shrunk by a line.  We ask for the terminal to grow
299   " by a line so it ends up actually being the same.
300   if &term =~ '^screen'
301     let l:resize = l:resize . " lines=" . (&lines + 1)
302   endif
303
304   exe l:resize
305 endfun "}}}2
306
307 " Grow or shrink the window height.
308 fun! Resize_Lines(op, lines) "{{{2
309   if a:op == ""
310     return
311   endif
312
313   if ! Can_Resize()
314     return
315   endif
316
317   exe "let l:resize=" . &lines . a:op . a:lines
318   if &term =~ '^screen'
319     let l:resize = l:resize + 1
320   endif
321   let l:resize = "se lines=" . l:resize
322
323   exe l:resize
324 endfun "}}}2
325
326 " Set extra columns depending on window status.
327 fun! Extra_Columns(extra, var, ...) "{{{2
328   " Vim 6 doesn't have winnr("$").  Determine which windows are open
329   " ourselves by using :windo to incremement a counter.  As Vim 5
330   " doesn't have :windo we require Vim 6 for this.
331   if v:version < "600"
332     return ""
333   endif
334   if ! has("windows")
335     return ""
336   endif
337
338   " Remember which window we're in.
339   let l:winnr = winnr()
340   let l:num_windows = 0
341   windo let l:num_windows = l:num_windows + 1
342   " Switch back to the window we were in.
343   exe l:winnr . "wincmd w"
344
345   call Iain_Vars()
346
347   if a:0 == 0
348     let l:condition = ""
349   else
350     let l:condition = a:1
351   endif
352
353   let l:n = 0
354   let l:i = 1
355   let l:windows = ""
356   while l:n < l:num_windows
357     " If window w exists then getwinvar(w, "&modified") will be 0 or 1.
358     if getwinvar(l:i, "&modified") =~ '^\d'
359       let l:n = l:n + 1
360
361       let l:val = 0
362       exe "if getwinvar(" . l:i . ", '" . a:var . "') " . l:condition . " | let l:val = 1 | endif"
363       if l:val
364         exe "let l:windows = '" . l:windows . ":" . l:i . "'"
365       endif
366     endif
367     let l:i = l:i + 1
368   endwhile
369
370   let l:extra = "g:iainextracolumns" . a:extra
371   exe "let l:val = " . l:extra
372   exe "let " . l:extra . " = '" . l:windows . "'"
373
374   if l:windows == l:val
375     return ""
376   endif
377
378   if l:windows == ""
379     return "-"
380   elseif l:val == ""
381     return "+"
382   endif
383 endfun "}}}2
384
385 " Toggle number display.
386 fun! Number(resize) "{{{2
387   call Iain_Vars()
388   let &number = ! &number
389
390   " Ensure we keep track of any extra columns even if we aren't resizing.
391   " This prevents confusion when number is set at startup.
392   let l:extra = Extra_Columns("number", "&number")
393
394   if a:resize
395     call Resize_Columns(l:extra)
396   endif
397 endfun "}}}2
398
399 " Restore window size.
400 if has("autocmd") && ! has("gui_running")
401   au Display VimLeave * if exists("g:oldcols") | call Resize_Columns("-", (&columns - g:oldcols)) | endif
402   au Display VimLeave * if exists("g:oldlines") | call Resize_Lines("-", (&lines - g:oldlines)) | endif
403 endif
404
405 " Map Makefile mode.
406 if has("autocmd")
407   au Mode BufEnter * if &ft == "make" | call MakeMode_map() | endif
408   au Mode BufLeave * if &ft == "make" | call MakeMode_unmap() | endif
409 endif
410
411 " Entering Make mode.
412 fun! MakeMode_map() "{{{2
413   call Iain_Vars()
414   let w:iainlist=1
415   call Cycle_List()
416   set ts=8
417   set noexpandtab
418 endfun "}}}2
419
420 " Leaving Make mode.
421 fun! MakeMode_unmap() "{{{2
422   call Cycle_List()
423   set ts=2
424   set expandtab
425 endfun "}}}2
426
427 " Function to create mappings with either a hardcoded \ or <Leader>.
428 fun! Mapping(keysequence, mapping, ...) "{{{2
429   if version < "600"
430     let l:args = "\\" . a:keysequence . " " . a:mapping . ":<CR>"
431   else
432     let l:args = "<silent> <Leader>" . a:keysequence . " " . a:mapping
433   endif
434   if a:0 == 0
435     " General mapping.
436     exec "map " . l:args
437   else
438     " Specific mapping(s).
439     let l:i = 1
440     while l:i <= a:0
441       exec "let l:map = a:" . l:i . " . \"map\""
442       exec l:map . " " . l:args
443       let l:i = l:i + 1
444     endwhile
445   endif
446 endfun "}}}2
447
448 " Use - and = to create underlines.
449 call Mapping("-", "yyp:s/./-/g<CR>:let @/=''<CR>")
450 call Mapping("=", "yyp:s/./=/g<CR>:let @/=''<CR>")
451
452 " Set 2-column tabs with \2.
453 call Mapping("2", ":se ts=2<CR>:se sw=2<CR>")
454 " Set 4-column tabs with \4.
455 call Mapping("4", ":se ts=4<CR>:se sw=4<CR>")
456 " Set 8-column tabs with \8.
457 call Mapping("8", ":se ts=8<CR>:se sw=8<CR>")
458 " Set 16-column tabs with \6.
459 call Mapping("6", ":se ts=16<CR>:se sw=16<CR>")
460 " Set 32-column tabs with \3.
461 call Mapping("3", ":se ts=32<CR>:se sw=32<CR>")
462 " Toggle paste mode with \p.
463 call Mapping("p", ":se paste!<CR>")
464 " Swap case-sensitivity with \c.
465 call Mapping("C", ":call Invert_Case()<CR>")
466 " Change number mode with \n.
467 call Mapping("n", ":call Number(1)<CR>")
468 " Expand or shrink window size with \> and \<.
469 call Mapping(">", ":call Resize_Columns('+')<CR>")
470 call Mapping("<", ":call Resize_Columns('-')<CR>")
471 " Clear search pattern with \/.
472 call Mapping("/", ":let @/=\"\"<CR>")
473 " Toggle alternate buffer name with \#.
474 call Mapping("#", ":call Cycle_Alt()<CR>")
475
476 " Set graphical window title.
477 if has("win32") || has("win64")
478   " Windows taskbar entries are probably too small to show full titles.
479   se titlestring=%t
480 else
481   se titlestring=%{Show_TitleString()}
482 endif
483
484 " Vim tip 99: What's the highlighting group under the cursor?
485 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>")
486
487 fun! Uncluttered_Buffer() "{{{2
488   if exists("uncluttered_buffer")
489     if uncluttered_buffer == 1
490       return 1
491     endif
492   endif
493
494   if version >= "600"
495     if &buftype != ''
496       return 1
497     endif
498   endif
499
500   if &ft == 'perforce'
501     return 1
502   endif
503
504   if &ft == 'svn'
505     return 1
506   endif
507
508   if &ft == 'gitcommit'
509     return 1
510   endif
511
512   return 0
513 endfun "}}}2
514
515 fun! Startup_Resize() "{{{2
516   let l:columns = 0
517
518   " Resize for numbers.
519   if &number
520     if version >= "700" && has("linebreak")
521       let l:columns = &numberwidth
522     else
523       let l:columns = 8
524     endif
525   endif
526
527   " Resize for signs.
528   if has("signs")
529     if g:marksigns
530       if version >= "600"
531         let l:columns = l:columns + 2
532       endif
533     endif
534   endif
535
536   if g:oldcols < (80 + l:columns)
537     call Resize_Columns("+", l:columns)
538   endif
539 endfun "}}}2
540
541 " Change status bar colour when various things happen.
542 " Flags: H/h: Cursor held/moved.
543 "        F/f: Focus gained/lost.
544 "        I/i: Insert mode entered/left.
545 fun! Highlight_StatusLine(flag) "{{{2
546   if ! has("statusline")
547     return
548   endif
549   " Get current status.
550   call Iain_Vars()
551
552   " Change the status based on the flag.  XXX: Does Vim let us to do flags?
553   let l:ic = &ic
554   set ic
555   let b:iainstatus = substitute(b:iainstatus, a:flag, a:flag, "")
556   let &ic = l:ic
557
558   let l:normalcolour = "darkblue"
559   let l:editingcolour = "darkmagenta"
560   let l:replacecolour = "purple"
561   let l:warningcolour = "darkred"
562   let l:readonlycolour = "red"
563
564   if b:iainstatus =~# "I"
565     if v:insertmode == "r"
566       let l:editingcolour = l:replacecolour
567     endif
568   endif
569
570   " Default colour.
571   let l:colour = l:normalcolour
572   " Maybe override depending on status.
573   if b:iainstatus =~# "H"
574     if b:iainstatus =~# "I"
575       " Held in insert mode.  Add extra highlight if we don't have focus.
576       if b:iainstatus =~# "f"
577         let l:colour = l:warningcolour
578       else
579         let l:colour = l:editingcolour
580       endif
581     endif
582   else
583     if b:iainstatus =~# "I"
584       " Regular insert mode.
585       let l:colour = l:editingcolour
586     endif
587   endif
588
589   " Override again if readonly.
590   if l:colour != l:normalcolour
591     if getbufvar("", "&ro")
592       let l:colour = l:readonlycolour
593     endif
594   endif
595
596   let l:termcolour = Iain_Colour(l:colour)
597
598   exec "highlight StatusLine gui=none term=none cterm=none guifg=white guibg=" . l:colour . " ctermfg=white ctermbg=" . l:termcolour
599   exec "highlight User1 gui=bold term=bold cterm=bold guifg=white guibg=" . l:colour . " ctermfg=white ctermbg=" . l:termcolour
600 endfun "}}}2
601
602 fun! Iain_Colour(colour) "{{{2
603   if &t_Co == 88
604     if a:colour == "darkblue"
605       return 17
606     elseif a:colour == "darkmagenta"
607       return 33
608     elseif a:colour == "purple"
609       return 35
610     elseif a:colour == "darkred"
611       return 32
612     elseif a:colour == "red"
613       return 64
614     endif
615   elseif &t_Co == 256
616     if a:colour == "darkblue"
617       return 17
618     elseif a:colour == "darkmagenta"
619       return 90
620     elseif a:colour == "purple"
621       return 57
622     elseif a:colour == "darkred"
623       return 88
624     elseif a:colour == "red"
625       return 196
626     endif
627   else
628     " Colours which cterm*g doesn't recognise.
629     if a:colour == "purple"
630       return "magenta"
631     endif
632     return a:colour
633   endif
634 endfun "}}}2
635
636 if has("autocmd")
637   au StatusLine VimEnter * call Highlight_StatusLine("")
638
639   " Show numbers by default.
640   au Display VimEnter * if ! Uncluttered_Buffer() | call Number(0) | endif
641 endif
642 endif "}}}1
643
644 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
645 " Handle options only available in Vim 5.4 and above.
646 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
647 if version >= "504" "{{{1
648 version 5.4
649
650 " Reuse windows when using sbuffer.
651 se switchbuf=useopen
652
653 " Vim 5 requires a 'n setting for viminfo.
654 if ! &viminfo
655   se viminfo='100
656 endif
657
658 " Allow persistent variable saving for localvimrc.
659 se viminfo+=!
660
661 " Do we have Unicode?
662 fun! Has_Unicode() "{{{2
663   if ! has('multi_byte')
664     return 0
665   endif
666
667   if version < "602"
668     return 0
669   endif
670
671   if &tenc =~? '^u\(tf\|cs\)'
672     return 1
673   endif
674
675   if ! strlen(&tenc) && &enc =~? '^u\(tf\|cs\)'
676     return 1
677   endif
678
679   return 0
680 endfun "}}}2
681
682 " Helper for status line.
683 " Show file encoding
684 fun! Show_Encoding() "{{{2
685   if version < "600"
686     return ""
687   endif
688
689   let l:enc = &fenc
690   let l:symbol = ""
691   if l:enc == ""
692     let l:enc = &enc
693     if l:enc == ""
694       return ""
695     endif
696     if bufname("%") == ""
697       if Has_Unicode()
698         let l:symbol = '•'
699       else
700         let l:symbol = '*'
701       endif
702     endif
703   endif
704
705   if has("multi_byte")
706     if &bomb
707       if Has_Unicode()
708         let l:symbol = "☻"
709       else
710         let l:symbol = "@"
711       endif
712     endif
713   endif
714
715   " Don't return anything if the encoding is utf-8.
716   if l:enc == "utf-8"
717     if l:symbol == ""
718       return ""
719     endif
720   endif
721
722   return l:symbol . l:enc . ","
723 endfun "}}}2
724
725 " Helper for status line.
726 " Show space, underscore or dollar sign depending on list mode.
727 fun! Show_List() "{{{2
728   call Iain_Vars()
729   if w:iainlist == 0
730     " No list.
731     return ""
732   elseif Has_Unicode()
733     if w:iainlist == 1
734       " Just tabs.
735       return "»"
736     else
737       " Full list.
738       return "¶"
739     endif
740   else
741     if w:iainlist == 1
742       return "_"
743     else
744       return "\$"
745     endif
746   endif
747 endfun "}}}2
748
749 " Helper for status line.
750 " Show c or C to denote case-sensitivity.
751 fun! Show_Case() "{{{2
752   if &ic
753     return "c"
754   else
755     return "C"
756   endif
757 endfun "}}}2
758
759 " Helper for status line.
760 " Mark DOS buffers.
761 fun! Show_DOS() "{{{2
762   if &ff == "unix"
763     return ""
764   endif
765   return &ff . ","
766 endfun "}}}2
767
768 " Helper for status line.
769 " Show the size of the tabstop.
770 fun! Show_Tabstop() "{{{2
771   return &ts
772 endfun "}}}2
773
774 " Helper for status line.
775 " Show p when paste mode is on.
776 fun! Show_Paste() "{{{2
777   if &paste
778     return "p"
779   else
780     return ""
781   endif
782 endfun "}}}2
783
784 " Helper for status line.
785 " Show v when virtualedit mode is block, insert or onemore.
786 " Show V when virtualedit mode is all.
787 fun! Show_VirtualEdit() "{{{2
788   if ! has("virtualedit")
789     return ""
790   endif
791
792   if &ve == "all"
793     return "V"
794   elseif &ve != ''
795     return "v"
796   else
797     return ""
798   endif
799 endfun "}}}2
800
801 " Helper for status line.
802 " Show U when persistent undo is on.
803 " Show u when persistent undo is off but an undofile exists.
804 fun! Show_Undo() "{{{2
805   if ! exists("&undofile")
806     return ""
807   endif
808
809   if &undofile
810     return "U"
811   elseif filereadable(undofile(expand("%")))
812     return "u"
813   else
814     return ""
815   endif
816 endfun "}}}2
817
818 " Helper for status line.
819 " Show alternate buffer number and name.
820 fun! Show_Alt() "{{{2
821   let l:alt = bufnr("#")
822   if l:alt < 0 || l:alt == bufnr("") || ! b:iainalt
823     return ""
824   endif
825
826   return " " . l:alt . ": " . expand("#:t")
827 endfun "}}}2
828
829 " Helper for status line.
830 " Show scrollbind or cursorbind.
831 fun! Show_Bind() "{{{2
832   if has("cursorbind")
833     if &cursorbind
834       if Has_Unicode()
835         return "⇄"
836       else
837         return ">"
838       endif
839     elseif &scrollbind
840       if Has_Unicode()
841         return "⇅"
842       else
843         return "^"
844       endif
845     endif
846   endif
847   return ""
848 endfun "}}}2
849
850 " Helper for status line.
851 " Show marker if searchforward is unset.
852 fun! Show_SearchForward() "{{{2
853   if version >= "702"
854     if ! v:searchforward
855       if Has_Unicode()
856         return "∆"
857       else
858         return "^"
859       endif
860     endif
861   endif
862   return ""
863 endfun "}}}2
864
865 " Helper for status line.
866 " Show marks set in cursor line.
867 fun! Show_Marks() "{{{2
868   if ! exists("g:iainsigns")
869     return ""
870   endif
871
872   let l:marks = ""
873
874   let l:signs = g:iainsigns
875   let l:sign = ""
876   let l:cursorline = line(".")
877   while strlen(l:signs)
878     let l:sign = matchstr(l:signs, '^[A-Za-z]\+\(:.\)*[.=>-][^ ]\+')
879     let l:sign = substitute(l:sign, '^[A-Za-z]\+', "", "")
880     let l:ascii = matchstr(l:sign, '^:.')
881     let l:mark = substitute(l:sign, '^\(:.\)*[.=>-]', "", "")
882     if strlen(l:ascii)
883       let l:ascii = substitute(l:ascii, '^:', "", "")
884     else
885       let l:ascii = l:mark
886     endif
887     let l:ascii = substitute(l:ascii, '"', '\\"', "")
888
889     if l:ascii == "o"
890       let l:line = "."
891     else
892       let l:line = "'" . l:ascii
893     endif
894
895     " Ignore cursor line which will always match.
896     if l:line != "."
897       if l:cursorline == line(l:line)
898         let l:marks = l:marks . l:mark
899       endif
900     endif
901
902     let l:signs = substitute(l:signs, '^[^ ]\+ *', "", "")
903   endwhile
904
905   if l:marks == ""
906     return ""
907   else
908     return "M:" . l:marks . " "
909   endif
910 endfun "}}}2
911
912 " Show the status line.
913 fun! Show_StatusLine() "{{{2
914   if ! has("statusline")
915     return
916   endif
917   call Iain_Vars()
918
919   " User{N} highlights %{N}*.
920   " Named highlight groups %#group% aren't available until Vim 7.
921   let l:normal = '%0*'
922   let l:bold = '%1*'
923
924   " sl1 contains left-aligned stuff.
925   " sl2 contains stuff shown only when verbose mode is enabled.
926   " sl3 contains right-aligned stuff.
927   let l:sl1='%2n\:\ %<' . l:bold . '%f' . l:normal . '\ [%{Show_Encoding()}%{Show_DOS()}%{Show_List()}%{Show_Bind()}%{Show_Case()}%{Show_Tabstop()}%{Show_Paste()}%{Show_VirtualEdit()}%{Show_Undo()}%Y%M%R%{Show_SearchForward()}]%{Show_Alt()}\ '
928   let l:sl3='%{Show_Marks()}L:' . l:bold . '%4.6l' . l:normal . '/%-4.6L\ C:' . l:bold . '%3.6c%V' . l:normal . '\ \|\ %P'
929   let l:hexformat='%b'
930   if b:iainhex
931     let l:hexformat='0\x%02B'
932   endif
933   if b:iainverbose
934     let l:sl1=l:sl1 . v:version . '\ %='
935     let l:sl2=l:hexformat . '\ \|\ P:%4.6o\ '
936   else
937     let l:sl1=l:sl1 . '%='
938     let l:sl2=''
939   endif
940   exec "set statusline=" . l:sl1 . l:sl2 . l:sl3
941 endfun "}}}2
942
943 " Show the status line for the first time.
944 call Show_StatusLine()
945 endif "}}}1
946
947 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
948 " Handle options only available in Vim 6 and above.
949 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
950 if version >= "600" "{{{1
951 version 6.0
952
953 if has("win32") || has("win64")
954   se encoding=utf-8
955 endif
956
957 " Remember quickfix state.
958 if has("quickfix")
959   let g:quickfixing=0
960 endif
961
962 " Set indenting by filetype.
963 filetype indent on
964
965 " Less intrusive syntax highlighting.
966 if has("syntax")
967   " The :syntax enable command tries to source the syntax.vim runtime script.
968   " Parsing this .vimrc will fail if for some reason the runtime doesn't
969   " exist, as could be the case if the binary was installed with no support
970   " files.  GNU On Windows is one example of an incomplete installation.
971   try
972     syn enable
973   catch
974   endtry
975 endif
976
977 " Set colours.
978 if has("gui_running")
979   if has("win32") || has("win64")
980     exe "silent se guifont=DejaVu_Sans_Mono:h10:cANSI"
981   else
982     exe "silent se guifont=DejaVu\\ Sans\\ Mono\\ 10"
983   endif
984 endif
985 if has("gui_running") || &t_Co > 16
986   exe "silent colo iain"
987 endif
988
989 " Ignore whitespace when diffing.
990 if has("diff")
991   se diffopt=filler,iwhite
992 endif
993
994 if has("autocmd")
995   if has("quickfix")
996     " Remember that we are opening the quickfix window.
997     au Mode BufWinEnter quickfix let g:quickfixing=1
998     au Mode BufUnload * if &ft == "qf" | let g:quickfixing=0 | endif
999   endif
1000
1001   " Allow in-place editing of crontabs.
1002   au Mode FileType crontab set backupcopy=yes
1003 endif
1004
1005 " Make * and # work the way you expect in visual mode.
1006 vnoremap * y/\V<C-R>=substitute(escape(@@,"/\\"),"\n","\\\\n","ge")<CR><CR>
1007 vnoremap # y?\V<C-R>=substitute(escape(@@,"?\\"),"\n","\\\\n","ge")<CR><CR>
1008
1009 " Set mark and update highlighting.
1010 if has("signs")
1011   au Signs BufReadPost * call <SID>Highlight_Signs()
1012   au Signs CursorHold * call <SID>Highlight_Signs()
1013 endif
1014
1015 " Helper to set buffer variable for a given sign.
1016 fun! <SID>Prep_Sign(sign) "{{{2
1017   if ! exists("b:sign" . a:sign) || ! g:marksigns
1018     exe "let b:sign" . a:sign . "=0"
1019    endif
1020 endfun "}}}2
1021
1022 fun! <SID>Place_Sign(number, line, old, name) "{{{2
1023   if a:line == a:old
1024     return a:old
1025   endif
1026
1027   exe "sign unplace " . (g:firstsign + a:number) . " buffer=" . bufnr("")
1028   " Don't place the sign if it would conflict with the last change sign.
1029   exe "sign place " . (g:firstsign + a:number) . " line=" . a:line . " name=" . a:name . " buffer=" . bufnr("")
1030   return a:line
1031 endfun "}}}2
1032
1033 fun! <SID>Highlight_Signs(...) "{{{2
1034   if ! has("signs") || ! g:marksigns || Uncluttered_Buffer()
1035     return
1036   endif
1037
1038   let l:signs = g:iainsigns
1039   let l:sign = ""
1040   let l:i = 0
1041   while strlen(l:signs)
1042     let l:sign = matchstr(l:signs, '^[A-Za-z]\+\(:.\)*[.=>-][^ ]\+')
1043
1044     let l:name = substitute(l:sign, '[:.=>-].*', "", "")
1045     let l:var = tolower(l:name)
1046     let l:sign = substitute(l:sign, '^[A-Za-z]\+', "", "")
1047     let l:ascii = matchstr(l:sign, '^:.')
1048     let l:mark = substitute(l:sign, '^\(:.\)*[.=>-]', "", "")
1049     if strlen(l:ascii)
1050       let l:ascii = substitute(l:ascii, '^:', "", "")
1051     else
1052       let l:ascii = l:mark
1053     endif
1054     let l:ascii = substitute(l:ascii, '"', '\\"', "")
1055
1056     if l:ascii == "o"
1057       let l:line = "."
1058     else
1059       let l:line = "'" . l:ascii
1060     endif
1061
1062     call <SID>Prep_Sign(l:var)
1063     exe "let " . l:var . " = <SID>Place_Sign(" . l:i . ", line(\"" . l:line . "\"), b:sign" . l:var . ", \"Mark" . l:name . "\")"
1064     let l:i = l:i + 1
1065
1066     let l:signs = substitute(l:signs, '^[^ ]\+ *', "", "")
1067   endwhile
1068 endfun "}}}2
1069
1070 " Toggle signs.
1071 fun! <SID>Cycle_Signs(resize) "{{{2
1072   if ! has("signs")
1073     return
1074   endif
1075   call Iain_Vars()
1076   let g:marksigns = ! g:marksigns
1077
1078   " Retrofit arrays on to Vim 6.
1079   if ! exists("g:iainsigns")
1080     " Signs are defined in g:iainsigns.  The syntax is as follows:
1081     "
1082     " Sign ::= Name (':' Mark)* Type Symbol
1083     " Type ::= '=' | '-' | '.'
1084     "
1085     " Signs with Type '=' will be highlighted with the MarkSign group.
1086     " Signs with Type '-' will be highlighted with the MarkLine group.
1087     " Signs with Type '.' will be highlighted with the MarkDot group.
1088     " Signs with Type '>' will be highlighted with the MarkArrow group.
1089     " Define the Mark where Symbol is not also the mark name, eg "']".
1090     let g:iainsigns = "Less=< Greater=> Left=( Right=) SquareLeft=[ SquareRight=] BraceLeft={ BraceRight=} a-a b-b c-c d-d e-e f-f A-A B-B C-C D-D E-E F-F"
1091     if Has_Unicode()
1092       let g:iainsigns = g:iainsigns . " Quote:\"=” Dash:'=’ Caret:^.ʌ Dot:..•"
1093       if version < "704"
1094         let g:iainsigns = g:iainsigns ." Cursor:o>▶"
1095       endif
1096     else
1097       let g:iainsigns = g:iainsigns . " Quote=\" Dash=' Caret.^ Dot:..*"
1098       if version < "704"
1099         let g:iainsigns = g:iainsigns ." Cursor>o"
1100       endif
1101     endif
1102   endif
1103
1104   if g:marksigns
1105     " Signs to highlight marks.
1106     " Syntax won't work properly in Vim 6.
1107     let l:signs = g:iainsigns
1108     let l:sign = ""
1109     while strlen(l:signs)
1110       let l:sign = matchstr(l:signs, '^[A-Za-z]\+\(:.\)*[.=>-][^ ]\+')
1111
1112       let l:name = substitute(l:sign, '[:.=>-].*', "", "")
1113       let l:sign = substitute(l:sign, '^[A-Za-z]\+', "", "")
1114       let l:ascii = matchstr(l:sign, '^:.')
1115       let l:mark = substitute(l:sign, '^\(:.\)*[.=>-]', "", "")
1116       if strlen(l:ascii)
1117         let l:ascii = substitute(l:ascii, '^:', "", "")
1118         let l:ascii = matchstr(l:ascii, '^.')
1119       else
1120         let l:ascii = l:mark
1121       endif
1122       let l:ascii = substitute(l:ascii, '"', '\\"', "")
1123       let l:type = substitute(l:sign, '^:.', "", "")
1124       let l:type = matchstr(l:type, '^.')
1125
1126       let l:hl = ""
1127       if l:type == "="
1128         let l:hl = "texthl=MarkSign text="
1129       elseif l:type == "."
1130         let l:hl = "texthl=MarkDot text="
1131       elseif l:type == "-"
1132         let l:hl = "texthl=MarkLine text="
1133       elseif l:type == ">"
1134         let l:hl = "texthl=MarkArrow text="
1135       endif
1136
1137       exe "sign define Mark" . l:name . " " . l:hl . l:mark
1138
1139       let l:signs = substitute(l:signs, '^[^ ]\+ *', "", "")
1140     endwhile
1141
1142     if a:resize
1143       call Resize_Columns("+", 2)
1144     endif
1145     call <SID>Highlight_Signs()
1146   else
1147     let l:i = 0
1148     while l:i < 25
1149       exe "sign unplace " . (g:firstsign + l:i)
1150       let l:i = l:i + 1
1151     endwhile
1152
1153     let l:signs = g:iainsigns
1154     let l:sign = ""
1155     while strlen(l:signs)
1156       let l:sign = matchstr(l:signs, '^[A-Za-z]\+')
1157
1158       exe "sign undefine Mark" . l:sign
1159       call <SID>Prep_Sign(tolower(l:sign))
1160       let l:signs = substitute(l:signs, '^[^ ]\+ *', "", "")
1161     endwhile
1162
1163     if a:resize
1164       call Resize_Columns("-", 2)
1165     endif
1166   endif
1167 endfun "}}}2
1168
1169 " Change list mode.
1170 fun! Cycle_List() "{{{2
1171   " Pretty UTF-8 listchars.
1172   if Has_Unicode()
1173     let basic='tab:»·,trail:…,extends:«,precedes:»'
1174     let eol='eol:¶'
1175     if version >= "700"
1176       let basic=basic . ',nbsp:•'
1177     endif
1178   else
1179     let basic='tab:\\_,trail:_,extends:<,precedes:>'
1180     let eol='eol:$'
1181     if version >= "700"
1182       let basic=basic . ',nbsp:+'
1183     endif
1184   endif
1185   call Iain_Vars()
1186   let w:iainlist = w:iainlist + 1
1187   if w:iainlist > 2
1188     let w:iainlist = 0
1189   endif
1190   if w:iainlist == 0
1191     setlocal nolist
1192   elseif w:iainlist == 1
1193     exec "setlocal lcs=" . basic
1194     setlocal list
1195   else
1196     exec "setlocal lcs=" . basic . "," . eol
1197     setlocal list
1198   endif
1199
1200   call Resize_Columns(Extra_Columns("list", "iainlist", " == 2"), 1)
1201   call Extra_Whitespace_Match()
1202 endfun "}}}2
1203
1204 " Cycle between hex and decimal display of toolbar stuff.
1205 fun! Cycle_HexStatusLine() "{{{2
1206   call Iain_Vars()
1207   let b:iainhex = ! b:iainhex
1208   call Show_StatusLine()
1209 endfun "}}}2
1210
1211 " Cycle verbose display of toolbar stuff.
1212 fun! Cycle_VerboseStatusLine() "{{{2
1213   call Iain_Vars()
1214   let b:iainverbose = ! b:iainverbose
1215   call Show_StatusLine()
1216 endfun "}}}2
1217
1218 " Toggle quickfix window.
1219 fun! Cycle_Quickfix() "{{{2
1220   if ! has("quickfix")
1221     return
1222   endif
1223   if g:quickfixing == 1
1224     cclose
1225     let g:quickfixing=0
1226   else
1227     copen
1228   endif
1229 endfun "}}}2
1230
1231 " Toggle showing alternate buffer information.
1232 fun! Cycle_Alt() "{{{2
1233   call Iain_Vars()
1234   let b:iainalt = ! b:iainalt
1235   call Show_StatusLine()
1236 endfun "{{{2
1237
1238 " To be overridden later if applicable.
1239 fun! Extra_Whitespace_Match() "{{{2
1240   " NOP.
1241 endfun "}}}2
1242
1243 " Swap hex/decimal statusline with \x.
1244 call Mapping("x", ":call Cycle_HexStatusLine()<CR>")
1245 " Change statusline verbosity with \v.
1246 call Mapping("V", ":call Cycle_VerboseStatusLine()<CR>")
1247 " Cycle list styles with \l.
1248 call Mapping("l", ":call Cycle_List()<CR>")
1249 " Toggle tags with \t.
1250 call Mapping("t", ":Tlist<CR>")
1251 " Change foldmethod with \f.
1252 call Mapping("f", ":se foldenable!<CR>")
1253 " Toggle quickfix window with \q.
1254 call Mapping("q", ":call Cycle_Quickfix()<CR>")
1255 " Rerun filetype detection with \s.  The s is for syntax, as this will be
1256 " updated as a side-effect.
1257 call Mapping("S", ":filetype detect<CR>")
1258 " Toggle marks with \m.
1259 call Mapping("m", ":call <SID>Cycle_Signs(1)<CR>")
1260
1261 if has("autocmd")
1262   " Show signs by default.
1263   au Display VimEnter * call <SID>Cycle_Signs(0)
1264 endif
1265
1266 " move.
1267 nmap <A-u> <Plug>MoveLineHalfPageUp
1268 nmap <A-d> <Plug>MoveLineHalfPageDown
1269 vmap <A-u> <Plug>MoveBlockHalfPageUp
1270 vmap <A-d> <Plug>MoveBlockHalfPageDown
1271 endif "}}}1
1272
1273 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1274 " Handle options only available in Vim 7 and above.
1275 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1276 if version >= "700" "{{{1
1277 version 7.0
1278
1279 " Narrow buffer with \w.
1280 call Mapping("w", ":NarrowRegion<CR>", "n", "v")
1281 " Narrow window with \W.
1282 call Mapping("W", ":NarrowWindow<CR>", "n", "v")
1283
1284 " Helper to show tab name.
1285 fun! <SID>TabName(label, gui) "{{{2
1286   let l:label = a:label
1287   if l:label == ""
1288     let l:label = "No Name"
1289     if a:gui
1290       let l:label = "[" . l:label . "]"
1291     endif
1292   else
1293     let l:label = fnamemodify(l:label, ":t")
1294     if strlen(l:label) >= 18
1295       let l:label = l:label[0:17] . ".."
1296     endif
1297   endif
1298   return l:label
1299 endfun "}}}2
1300
1301 " Find out if any buffer was modified.
1302 fun! <SID>TabModified(buflist) "{{{2
1303   let l:i = 0
1304   while l:i < len(a:buflist)
1305     if getbufvar(a:buflist[l:i], "&modified") == 1
1306       return "+"
1307     endif
1308     let l:i = l:i + 1
1309   endwhile
1310   return ""
1311 endfun "}}}2
1312
1313 " Tab line.
1314 fun! Show_TabLine() "{{{2
1315   let l:s = "%#TabLineFill#Tabs:"
1316
1317   let l:i = 0
1318   while l:i < tabpagenr("$")
1319     let l:i = l:i + 1
1320     " Get the label.
1321     let l:buflist = tabpagebuflist(l:i)
1322     let l:winnr = tabpagewinnr(l:i)
1323     let l:n = tabpagewinnr(l:i, "$")
1324     let l:label = <SID>TabName(bufname(l:buflist[l:winnr - 1]), 0)
1325     let l:modified = <SID>TabModified(l:buflist)
1326
1327     " Choose highlighting.
1328     if l:i == tabpagenr()
1329       let l:s .= "%#TabLineSel#[" . l:n . l:modified . " " . l:label . "]"
1330     else
1331       let l:s .= "%#TabLine# " . l:n . l:modified . " " . l:label . " "
1332     endif
1333   endwhile
1334
1335   " Padding.
1336   let l:s .= "%#TabLine#%T"
1337   return l:s
1338 endfun "}}}2
1339
1340 " Per tab label for the GUI.
1341 fun! Show_GUITabLine() "{{{2
1342   let l:buflist = tabpagebuflist(v:lnum)
1343   let l:winnr = tabpagewinnr(v:lnum)
1344   let l:s = tabpagewinnr(v:lnum, "$")
1345   let l:label = <SID>TabName(bufname(l:buflist[l:winnr - 1]), 1)
1346   let l:modified = <SID>TabModified(l:buflist)
1347
1348   let l:s .= l:modified . " " . l:label
1349   return l:s
1350 endfun "}}}2
1351
1352 " Handle searching in a BufExplorer window.
1353 fun! <SID>BufExplorer_Search(n) "{{{2
1354   if a:n == 0
1355     let l:re = '^  *\d %'
1356   else
1357     let l:re = "^ *" . a:n
1358   endif
1359
1360   " Find matching line.
1361   let l:line = search(l:re, 'w')
1362   if ! l:line
1363     return
1364   endif
1365
1366   if a:n == 0
1367     return
1368   endif
1369
1370   " Peek ahead to the next matching line.
1371   let l:next = search(l:re, 'w')
1372
1373   " Select the buffer if the match is unambiguous.
1374   if l:next == l:line
1375     exe "normal \<CR>"
1376     return
1377   endif
1378
1379   " Go back.
1380   call cursor(l:line, 0)
1381 endfun! "}}}2
1382
1383 " Entering a BufExplorer window.
1384 fun! <SID>BufExplorer_Map() "{{{2
1385   for l:n in [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" ]
1386     exec "nnoremap <buffer> <silent>" . l:n . " :call <SID>BufExplorer_Search(" . l:n . ")<CR>"
1387   endfor
1388 endfun "}}}2
1389
1390 if has("windows")
1391   se tabline=%!Show_TabLine()
1392   se guitablabel=%!Show_GUITabLine()
1393 endif
1394
1395 if has("autocmd")
1396   au StatusLine CursorHoldI * call Highlight_StatusLine("H")
1397   au StatusLine CursorMovedI * call Highlight_StatusLine("h")
1398   au StatusLine FocusGained * call Highlight_StatusLine("F")
1399   au StatusLine FocusLost * call Highlight_StatusLine("f")
1400   au StatusLine InsertEnter * call Highlight_StatusLine("I")
1401   au StatusLine InsertChange * call Highlight_StatusLine("I")
1402   au StatusLine InsertLeave * call Highlight_StatusLine("i")
1403
1404   if has("signs")
1405     au Signs CursorHoldI * call <SID>Highlight_Signs()
1406     au Signs InsertEnter * call <SID>Highlight_Signs()
1407     au Signs InsertLeave * call <SID>Highlight_Signs()
1408   endif
1409
1410   au Mode BufEnter \[BufExplorer\] call <SID>BufExplorer_Map()
1411 endif
1412
1413 " Limit the size of the popup menu when completing.
1414 if has("insert_expand")
1415   se pumheight=20
1416 endif
1417
1418 " Make diffs vertical by default.
1419 if has("diff")
1420   se diffopt+=vertical
1421 endif
1422
1423 " Set size of numbers column.
1424 if has("linebreak")
1425   se numberwidth=5
1426 endif
1427
1428 " Add "previous tab" mapping as gb.
1429 map gb :tabprevious<CR>:<CR>
1430
1431 " Transparency.
1432 if has("gui_macvim")
1433   se transparency=15
1434 endif
1435
1436 " Yet more GUI options.  Add tabs.
1437 if has("gui")
1438   se go+=e
1439 endif
1440
1441 " Perforce.
1442 let g:p4EnableMenu=1
1443 let g:p4Presets='P4CONFIG'
1444
1445 " BufExplorer.
1446 let g:bufExplorerShowRelativePath=1
1447 let g:bufExplorerSplitOutPathName=0
1448
1449 " NERDcommenter.
1450 let g:NERDSpaceDelims=1
1451
1452 " localvimrc.
1453 let g:localvimrc_persistent=1
1454
1455 " Gitv.
1456 let g:Gitv_OpenHorizontal='auto'
1457 let g:Gitv_WipeAllOnClose=1
1458 endif "}}}1
1459
1460 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1461 " Handle options only available in Vim 7.2 and above.
1462 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1463 if version >= "702" "{{{1
1464 if has("autocmd")
1465   " http://vim.wikia.com/wiki/Highlight_unwanted_spaces
1466   augroup WhitespaceMatch
1467   autocmd!
1468   au Display BufWinEnter * call Extra_Whitespace_Match()
1469   au Display Syntax * call Extra_Whitespace_Match()
1470   au Display BufWinLeave * call clearmatches()
1471   augroup END
1472
1473   fun! Extra_Whitespace_Match() "{{{2
1474     " \s\+            <whitespace>
1475     "            $    <before end of line>
1476     "        \@<!     <unless preceded by>
1477     "     \%#         <cursor position, ie when typing>
1478     let l:pattern = '\s\+\%#\@<!$'
1479     " Don't match single space in first column of diff.
1480     if &ft =~# '^diff$\|git'
1481       "         \@!  <unless also matching>
1482       " \(^\s$\)     <a single whitespace>
1483       let l:pattern = '\(^\s$\)\@!' . l:pattern
1484     endif
1485
1486     let l:hl = 'ctermfg=red guifg=red'
1487     if ! &list
1488       " Underline if we aren't using listchars.
1489       let l:hl = l:hl . ' cterm=underline gui=underline'
1490     endif
1491     highlight clear ExtraWhitespace
1492     exe "highlight ExtraWhitespace " . l:hl
1493     if exists('w:whitespace_match_number')
1494       try
1495         call matchdelete(w:whitespace_match_number)
1496       catch
1497       endtry
1498       call matchadd('ExtraWhitespace', l:pattern, 10, w:whitespace_match_number)
1499     else
1500       let w:whitespace_match_number = matchadd('ExtraWhitespace', l:pattern)
1501     endif
1502   endfun "}}}2
1503
1504   call Extra_Whitespace_Match()
1505 endif
1506
1507 endif "}}}1
1508
1509 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1510 " Handle options only available in Vim 7.3 and above.
1511 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1512 if version >= "703" "{{{1
1513 version 7.3
1514
1515 " Toggle persistent undo with \u.
1516 call Mapping("u", ":call <SID>Cycle_Undo()<CR>")
1517 " Remove persistent undo file with \U.
1518 call Mapping("U", ":call <SID>Clear_Undo()<CR>")
1519
1520 " Toggle gundo window with \g.
1521 call Mapping("g", ":call gundo#GundoToggle()<CR>")
1522
1523 " Use a persistent undo file if it exists.
1524 fun! <SID>Check_Undo() "{{{2
1525   if filereadable(undofile(expand("%")))
1526     setlocal undofile
1527   endif
1528 endfun "}}}2
1529
1530 " Toggle persistent undo for this buffer.
1531 fun! <SID>Cycle_Undo() "{{{2
1532   if has("persistent_undo")
1533     let &undofile = ! &undofile
1534   endif
1535 endfun "}}}2
1536
1537 " Remove the persistent undo file for this buffer.
1538 fun! <SID>Clear_Undo() "{{{2
1539   if ! has("persistent_undo")
1540     return
1541   endif
1542
1543   setlocal noundofile
1544
1545   let l:f = expand("%")
1546   if l:f == ""
1547     return
1548   endif
1549
1550   let l:u = undofile(l:f)
1551   if l:u == ""
1552     return
1553   endif
1554
1555   if ! filereadable(l:u) || ! filewritable(l:u)
1556     return
1557   endif
1558
1559   call delete(l:u)
1560 endfun "}}}2
1561
1562 " Toggle ColorColumn at cursor position.
1563 fun! <SID>Cycle_ColorColumn() "{{{2
1564   if ! has("syntax")
1565     return
1566   endif
1567
1568   let l:cc = &colorcolumn
1569   let l:column = col(".")
1570   let l:re = ",*\\<" . l:column . "\\>"
1571   if l:cc =~# l:re
1572     let l:cc = substitute(l:cc, l:re, "", "g")
1573   else
1574     let l:cc = l:cc . "," . l:column
1575   endif
1576   let &colorcolumn = substitute(l:cc, "^,*", "", "")
1577 endfun "}}}2
1578
1579 if has("syntax")
1580   " Enable showing ColorColumn at cursor position with \CC.
1581   call Mapping("CC", ":call <SID>Cycle_ColorColumn()<CR>")
1582   " Remove last shown ColorColumn with \Cc.
1583   call Mapping("Cc", ":let &colorcolumn=substitute(&colorcolumn, \",*[0-9]*$\", \"\", \"\")<CR>")
1584   " Remove all ColorColumns with \Cx.
1585   call Mapping("Cx", ":se colorcolumn=<CR>")
1586 endif
1587
1588 " Use persistent undo if available.
1589 if has("autocmd")
1590   if has("persistent_undo")
1591     au File BufReadPost * call <SID>Check_Undo()
1592   endif
1593
1594   if has("cursorbind")
1595     au Display WinEnter * if &diff | se cursorbind | endif
1596   endif
1597 endif
1598
1599 " Mapping to reload the gundo window.
1600 if has("autocmd")
1601   au Mode BufEnter * if &ft == "gundo" | try | nnoremap <silent> <buffer> <unique> r :call gundo#GundoToggle()<CR>:call gundo#GundoToggle()<CR> | catch | endtry | endif
1602 endif
1603
1604 endif "}}}1
1605 "
1606 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1607 " Handle options only available in Vim 7.4 and above.
1608 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1609 if version >= "704" "{{{1
1610 version 7.4
1611
1612 if has("syntax")
1613   se cursorline
1614 endif
1615
1616 endif "}}}1
1617
1618 " Resize after startup.
1619 if version >= "500" "{{{1
1620 if has("autocmd")
1621   au Display VimEnter * call Startup_Resize()
1622 endif
1623 endif "}}}1