bc459b3b6566b1b8eb6e3bd6e499c1a931bb4a0b
[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     exec "map \\" . a:keysequence . " " . a:mapping
431   else
432     exec "map <Leader>" . a:keysequence . " " . a:mapping
433   endif
434 endfun "}}}2
435
436 " Use - and = to create underlines.
437 call Mapping("-", "yyp:s/./-/g<RETURN>:let @/=''<RETURN>:<RETURN>")
438 call Mapping("=", "yyp:s/./=/g<RETURN>:let @/=''<RETURN>:<RETURN>")
439
440 " Change to ts=2 with \2.
441 call Mapping("2", ":se ts=2<CR>:<CR>")
442 " Change to ts=4 with \4.
443 call Mapping("4", ":se ts=4<CR>:<CR>")
444 " Change to ts=8 with \8.
445 call Mapping("8", ":se ts=8<CR>:<CR>")
446 " Change to ts=16 with \6.
447 call Mapping("6", ":se ts=16<CR>:<CR>")
448 " Change to ts=32 with \3.
449 call Mapping("3", ":se ts=32<CR>:<CR>")
450 " Toggle paste mode with \p.
451 call Mapping("p", ":se paste!<CR>:<CR>")
452 " Swap case-sensitivity with \c.
453 call Mapping("C", ":call Invert_Case()<CR>:<CR>")
454 " Change number mode with \n.
455 call Mapping("n", ":call Number(1)<CR>:<CR>")
456 " Expand or shrink window size with \> and \<.
457 call Mapping(">", ":call Resize_Columns('+')<CR>:<CR>")
458 call Mapping("<", ":call Resize_Columns('-')<CR>:<CR>")
459 " Clear search pattern with \/.
460 call Mapping("/", ":let @/=\"\"<CR>:<CR>")
461 " Toggle alternate buffer name with \#.
462 call Mapping("#", ":call Cycle_Alt()<CR>:<CR>")
463
464 " Set graphical window title.
465 if has("win32") || has("win64")
466   " Windows taskbar entries are probably too small to show full titles.
467   se titlestring=%t
468 else
469   se titlestring=%{Show_TitleString()}
470 endif
471
472 " Vim tip 99: What's the highlighting group under the cursor?
473 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>")
474
475 fun! Uncluttered_Buffer() "{{{2
476   if exists("uncluttered_buffer")
477     if uncluttered_buffer == 1
478       return 1
479     endif
480   endif
481
482   if version >= "600"
483     if &buftype != ''
484       return 1
485     endif
486   endif
487
488   if &ft == 'perforce'
489     return 1
490   endif
491
492   if &ft == 'svn'
493     return 1
494   endif
495
496   if &ft == 'gitcommit'
497     return 1
498   endif
499
500   return 0
501 endfun "}}}2
502
503 fun! Startup_Resize() "{{{2
504   let l:columns = 0
505
506   " Resize for numbers.
507   if &number
508     if version >= "700" && has("linebreak")
509       let l:columns = &numberwidth
510     else
511       let l:columns = 8
512     endif
513   endif
514
515   " Resize for signs.
516   if has("signs")
517     if g:marksigns
518       if version >= "600"
519         let l:columns = l:columns + 2
520       endif
521     endif
522   endif
523
524   if g:oldcols < (80 + l:columns)
525     call Resize_Columns("+", l:columns)
526   endif
527 endfun "}}}2
528
529 " Change status bar colour when various things happen.
530 " Flags: H/h: Cursor held/moved.
531 "        F/f: Focus gained/lost.
532 "        I/i: Insert mode entered/left.
533 fun! Highlight_StatusLine(flag) "{{{2
534   if ! has("statusline")
535     return
536   endif
537   " Get current status.
538   call Iain_Vars()
539
540   " Change the status based on the flag.  XXX: Does Vim let us to do flags?
541   let l:ic = &ic
542   set ic
543   let b:iainstatus = substitute(b:iainstatus, a:flag, a:flag, "")
544   let &ic = l:ic
545
546   let l:normalcolour = "darkblue"
547   let l:editingcolour = "darkmagenta"
548   let l:replacecolour = "purple"
549   let l:warningcolour = "darkred"
550   let l:readonlycolour = "red"
551
552   if b:iainstatus =~# "I"
553     if v:insertmode == "r"
554       let l:editingcolour = l:replacecolour
555     endif
556   endif
557
558   " Default colour.
559   let l:colour = l:normalcolour
560   " Maybe override depending on status.
561   if b:iainstatus =~# "H"
562     if b:iainstatus =~# "I"
563       " Held in insert mode.  Add extra highlight if we don't have focus.
564       if b:iainstatus =~# "f"
565         let l:colour = l:warningcolour
566       else
567         let l:colour = l:editingcolour
568       endif
569     endif
570   else
571     if b:iainstatus =~# "I"
572       " Regular insert mode.
573       let l:colour = l:editingcolour
574     endif
575   endif
576
577   " Override again if readonly.
578   if l:colour != l:normalcolour
579     if getbufvar("", "&ro")
580       let l:colour = l:readonlycolour
581     endif
582   endif
583
584   let l:termcolour = Iain_Colour(l:colour)
585
586   exec "highlight StatusLine gui=none term=none cterm=none guifg=white guibg=" . l:colour . " ctermfg=white ctermbg=" . l:termcolour
587   exec "highlight User1 gui=bold term=bold cterm=bold guifg=white guibg=" . l:colour . " ctermfg=white ctermbg=" . l:termcolour
588 endfun "}}}2
589
590 fun! Iain_Colour(colour) "{{{2
591   if &t_Co == 88
592     if a:colour == "darkblue"
593       return 17
594     elseif a:colour == "darkmagenta"
595       return 33
596     elseif a:colour == "purple"
597       return 35
598     elseif a:colour == "darkred"
599       return 32
600     elseif a:colour == "red"
601       return 64
602     endif
603   elseif &t_Co == 256
604     if a:colour == "darkblue"
605       return 17
606     elseif a:colour == "darkmagenta"
607       return 90
608     elseif a:colour == "purple"
609       return 57
610     elseif a:colour == "darkred"
611       return 88
612     elseif a:colour == "red"
613       return 196
614     endif
615   else
616     " Colours which cterm*g doesn't recognise.
617     if a:colour == "purple"
618       return "magenta"
619     endif
620     return a:colour
621   endif
622 endfun "}}}2
623
624 if has("autocmd")
625   au StatusLine VimEnter * call Highlight_StatusLine("")
626
627   " Show numbers by default.
628   au Display VimEnter * if ! Uncluttered_Buffer() | call Number(0) | endif
629 endif
630 endif "}}}1
631
632 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
633 " Handle options only available in Vim 5.4 and above.
634 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
635 if version >= "504" "{{{1
636 version 5.4
637
638 " Reuse windows when using sbuffer.
639 se switchbuf=useopen
640
641 " Vim 5 requires a 'n setting for viminfo.
642 if ! &viminfo
643   se viminfo='100
644 endif
645
646 " Allow persistent variable saving for localvimrc.
647 se viminfo+=!
648
649 " Do we have Unicode?
650 fun! Has_Unicode() "{{{2
651   if ! has('multi_byte')
652     return 0
653   endif
654
655   if version < "602"
656     return 0
657   endif
658
659   if &tenc =~? '^u\(tf\|cs\)'
660     return 1
661   endif
662
663   if ! strlen(&tenc) && &enc =~? '^u\(tf\|cs\)'
664     return 1
665   endif
666
667   return 0
668 endfun "}}}2
669
670 " Helper for status line.
671 " Show file encoding
672 fun! Show_Encoding() "{{{2
673   if version < "600"
674     return ""
675   endif
676
677   let l:enc = &fenc
678   let l:symbol = ""
679   if l:enc == ""
680     let l:enc = &enc
681     if l:enc == ""
682       return ""
683     endif
684     if bufname("%") == ""
685       if Has_Unicode()
686         let l:symbol = '•'
687       else
688         let l:symbol = '*'
689       endif
690     endif
691   endif
692
693   if has("multi_byte")
694     if &bomb
695       if Has_Unicode()
696         let l:symbol = "☻"
697       else
698         let l:symbol = "@"
699       endif
700     endif
701   endif
702
703   " Don't return anything if the encoding is utf-8.
704   if l:enc == "utf-8"
705     if l:symbol == ""
706       return ""
707     endif
708   endif
709
710   return l:symbol . l:enc . ","
711 endfun "}}}2
712
713 " Helper for status line.
714 " Show space, underscore or dollar sign depending on list mode.
715 fun! Show_List() "{{{2
716   call Iain_Vars()
717   if w:iainlist == 0
718     " No list.
719     return ""
720   elseif Has_Unicode()
721     if w:iainlist == 1
722       " Just tabs.
723       return "»"
724     else
725       " Full list.
726       return "¶"
727     endif
728   else
729     if w:iainlist == 1
730       return "_"
731     else
732       return "\$"
733     endif
734   endif
735 endfun "}}}2
736
737 " Helper for status line.
738 " Show c or C to denote case-sensitivity.
739 fun! Show_Case() "{{{2
740   if &ic
741     return "c"
742   else
743     return "C"
744   endif
745 endfun "}}}2
746
747 " Helper for status line.
748 " Show the size of the tabstop.
749 fun! Show_Tabstop() "{{{2
750   return &ts
751 endfun "}}}2
752
753 " Helper for status line.
754 " Show p when paste mode is on.
755 fun! Show_Paste() "{{{2
756   if &paste
757     return "p"
758   else
759     return ""
760   endif
761 endfun "}}}2
762
763 " Helper for status line.
764 " Show v when virtualedit mode is block, insert or onemore.
765 " Show V when virtualedit mode is all.
766 fun! Show_VirtualEdit() "{{{2
767   if ! has("virtualedit")
768     return ""
769   endif
770
771   if &ve == "all"
772     return "V"
773   elseif &ve != ''
774     return "v"
775   else
776     return ""
777   endif
778 endfun "}}}2
779
780 " Helper for status line.
781 " Show U when persistent undo is on.
782 " Show u when persistent undo is off but an undofile exists.
783 fun! Show_Undo() "{{{2
784   if ! exists("&undofile")
785     return ""
786   endif
787
788   if &undofile
789     return "U"
790   elseif filereadable(undofile(expand("%")))
791     return "u"
792   else
793     return ""
794   endif
795 endfun "}}}2
796
797 " Helper for status line.
798 " Show alternate buffer number and name.
799 fun! Show_Alt() "{{{2
800   let l:alt = bufnr("#")
801   if l:alt < 0 || l:alt == bufnr("") || ! b:iainalt
802     return ""
803   endif
804
805   return " " . l:alt . ": " . expand("#:t")
806 endfun "}}}2
807
808 " Helper for status line.
809 " Show scrollbind or cursorbind.
810 fun! Show_Bind() "{{{2
811   if has("cursorbind")
812     if &cursorbind
813       if Has_Unicode()
814         return "⇄"
815       else
816         return ">"
817       endif
818     elseif &scrollbind
819       if Has_Unicode()
820         return "⇅"
821       else
822         return "^"
823       endif
824     endif
825   endif
826   return ""
827 endfun "}}}2
828
829 " Helper for status line.
830 " Show marker if searchforward is unset.
831 fun! Show_SearchForward() "{{{2
832   if version >= "702"
833     if ! v:searchforward
834       if Has_Unicode()
835         return "∆"
836       else
837         return "^"
838       endif
839     endif
840   endif
841   return ""
842 endfun "}}}2
843
844 " Helper for status line.
845 " Show marks set in cursor line.
846 fun! Show_Marks() "{{{2
847   if ! exists("g:iainsigns")
848     return ""
849   endif
850
851   let l:marks = ""
852
853   let l:signs = g:iainsigns
854   let l:sign = ""
855   let l:cursorline = line(".")
856   while strlen(l:signs)
857     let l:sign = matchstr(l:signs, '^[A-Za-z]\+\(:.\)*[.=>-][^ ]\+')
858     let l:sign = substitute(l:sign, '^[A-Za-z]\+', "", "")
859     let l:ascii = matchstr(l:sign, '^:.')
860     let l:mark = substitute(l:sign, '^\(:.\)*[.=>-]', "", "")
861     if strlen(l:ascii)
862       let l:ascii = substitute(l:ascii, '^:', "", "")
863     else
864       let l:ascii = l:mark
865     endif
866     let l:ascii = substitute(l:ascii, '"', '\\"', "")
867
868     if l:ascii == "o"
869       let l:line = "."
870     else
871       let l:line = "'" . l:ascii
872     endif
873
874     " Ignore cursor line which will always match.
875     if l:line != "."
876       if l:cursorline == line(l:line)
877         let l:marks = l:marks . l:mark
878       endif
879     endif
880
881     let l:signs = substitute(l:signs, '^[^ ]\+ *', "", "")
882   endwhile
883
884   if l:marks == ""
885     return ""
886   else
887     return "M:" . l:marks . " "
888   endif
889 endfun "}}}2
890
891 " Show the status line.
892 fun! Show_StatusLine() "{{{2
893   if ! has("statusline")
894     return
895   endif
896   call Iain_Vars()
897
898   " User{N} highlights %{N}*.
899   " Named highlight groups %#group% aren't available until Vim 7.
900   let l:normal = '%0*'
901   let l:bold = '%1*'
902
903   " sl1 contains left-aligned stuff.
904   " sl2 contains stuff shown only when verbose mode is enabled.
905   " sl3 contains right-aligned stuff.
906   let l:sl1='%2n\:\ %<' . l:bold . '%f' . l:normal . '\ [%{Show_Encoding()}%{Show_List()}%{Show_Bind()}%{Show_Case()}%{Show_Tabstop()}%{Show_Paste()}%{Show_VirtualEdit()}%{Show_Undo()}%Y%M%R%{Show_SearchForward()}]%{Show_Alt()}\ '
907   let l:sl3='%{Show_Marks()}L:' . l:bold . '%4.6l' . l:normal . '/%-4.6L\ C:' . l:bold . '%3.6c%V' . l:normal . '\ \|\ %P'
908   let l:hexformat='%b'
909   if b:iainhex
910     let l:hexformat='0\x%02B'
911   endif
912   if b:iainverbose
913     let l:sl1=l:sl1 . v:version . '\ %='
914     let l:sl2=l:hexformat . '\ \|\ P:%4.6o\ '
915   else
916     let l:sl1=l:sl1 . '%='
917     let l:sl2=''
918   endif
919   exec "set statusline=" . l:sl1 . l:sl2 . l:sl3
920 endfun "}}}2
921
922 " Show the status line for the first time.
923 call Show_StatusLine()
924 endif "}}}1
925
926 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
927 " Handle options only available in Vim 6 and above.
928 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
929 if version >= "600" "{{{1
930 version 6.0
931
932 if has("win32") || has("win64")
933   se encoding=utf-8
934 endif
935
936 " Remember quickfix state.
937 if has("quickfix")
938   let g:quickfixing=0
939 endif
940
941 " Set indenting by filetype.
942 filetype indent on
943
944 " Less intrusive syntax highlighting.
945 if has("syntax")
946   " The :syntax enable command tries to source the syntax.vim runtime script.
947   " Parsing this .vimrc will fail if for some reason the runtime doesn't
948   " exist, as could be the case if the binary was installed with no support
949   " files.  GNU On Windows is one example of an incomplete installation.
950   try
951     syn enable
952   catch
953   endtry
954 endif
955
956 " Set colours.
957 if has("gui_running")
958   if has("win32") || has("win64")
959     exe "silent se guifont=DejaVu_Sans_Mono:h10:cANSI"
960   else
961     exe "silent se guifont=DejaVu\\ Sans\\ Mono\\ 10"
962   endif
963 endif
964 if has("gui_running") || &t_Co > 16
965   exe "silent colo iain"
966 endif
967
968 " Ignore whitespace when diffing.
969 if has("diff")
970   se diffopt=filler,iwhite
971 endif
972
973 if has("autocmd")
974   if has("quickfix")
975     " Remember that we are opening the quickfix window.
976     au Mode BufWinEnter quickfix let g:quickfixing=1
977     au Mode BufUnload * if &ft == "qf" | let g:quickfixing=0 | endif
978   endif
979
980   " Allow in-place editing of crontabs.
981   au Mode FileType crontab set backupcopy=yes
982 endif
983
984 " Make * and # work the way you expect in visual mode.
985 vnoremap * y/\V<C-R>=substitute(escape(@@,"/\\"),"\n","\\\\n","ge")<CR><CR>
986 vnoremap # y?\V<C-R>=substitute(escape(@@,"?\\"),"\n","\\\\n","ge")<CR><CR>
987
988 " Set mark and update highlighting.
989 if has("signs")
990   au Signs BufReadPost * call <SID>Highlight_Signs()
991   au Signs CursorHold * call <SID>Highlight_Signs()
992 endif
993
994 " Helper to set buffer variable for a given sign.
995 fun! <SID>Prep_Sign(sign) "{{{2
996   if ! exists("b:sign" . a:sign) || ! g:marksigns
997     exe "let b:sign" . a:sign . "=0"
998    endif
999 endfun "}}}2
1000
1001 fun! <SID>Place_Sign(number, line, old, name) "{{{2
1002   if a:line == a:old
1003     return a:old
1004   endif
1005
1006   exe "sign unplace " . (g:firstsign + a:number) . " buffer=" . bufnr("")
1007   " Don't place the sign if it would conflict with the last change sign.
1008   exe "sign place " . (g:firstsign + a:number) . " line=" . a:line . " name=" . a:name . " buffer=" . bufnr("")
1009   return a:line
1010 endfun "}}}2
1011
1012 fun! <SID>Highlight_Signs(...) "{{{2
1013   if ! has("signs") || ! g:marksigns || Uncluttered_Buffer()
1014     return
1015   endif
1016
1017   let l:signs = g:iainsigns
1018   let l:sign = ""
1019   let l:i = 0
1020   while strlen(l:signs)
1021     let l:sign = matchstr(l:signs, '^[A-Za-z]\+\(:.\)*[.=>-][^ ]\+')
1022
1023     let l:name = substitute(l:sign, '[:.=>-].*', "", "")
1024     let l:var = tolower(l:name)
1025     let l:sign = substitute(l:sign, '^[A-Za-z]\+', "", "")
1026     let l:ascii = matchstr(l:sign, '^:.')
1027     let l:mark = substitute(l:sign, '^\(:.\)*[.=>-]', "", "")
1028     if strlen(l:ascii)
1029       let l:ascii = substitute(l:ascii, '^:', "", "")
1030     else
1031       let l:ascii = l:mark
1032     endif
1033     let l:ascii = substitute(l:ascii, '"', '\\"', "")
1034
1035     if l:ascii == "o"
1036       let l:line = "."
1037     else
1038       let l:line = "'" . l:ascii
1039     endif
1040
1041     call <SID>Prep_Sign(l:var)
1042     exe "let " . l:var . " = <SID>Place_Sign(" . l:i . ", line(\"" . l:line . "\"), b:sign" . l:var . ", \"Mark" . l:name . "\")"
1043     let l:i = l:i + 1
1044
1045     let l:signs = substitute(l:signs, '^[^ ]\+ *', "", "")
1046   endwhile
1047 endfun "}}}2
1048
1049 " Toggle signs.
1050 fun! <SID>Cycle_Signs(resize) "{{{2
1051   if ! has("signs")
1052     return
1053   endif
1054   call Iain_Vars()
1055   let g:marksigns = ! g:marksigns
1056
1057   " Retrofit arrays on to Vim 6.
1058   if ! exists("g:iainsigns")
1059     " Signs are defined in g:iainsigns.  The syntax is as follows:
1060     "
1061     " Sign ::= Name (':' Mark)* Type Symbol
1062     " Type ::= '=' | '-' | '.'
1063     "
1064     " Signs with Type '=' will be highlighted with the MarkSign group.
1065     " Signs with Type '-' will be highlighted with the MarkLine group.
1066     " Signs with Type '.' will be highlighted with the MarkDot group.
1067     " Signs with Type '>' will be highlighted with the MarkArrow group.
1068     " Define the Mark where Symbol is not also the mark name, eg "']".
1069     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"
1070     if Has_Unicode()
1071       let g:iainsigns = g:iainsigns . " Quote:\"=” Dash:'=’ Caret:^.ʌ Dot:..•"
1072       if version < "704"
1073         let g:iainsigns = g:iainsigns ." Cursor:o>▶"
1074       endif
1075     else
1076       let g:iainsigns = g:iainsigns . " Quote=\" Dash=' Caret.^ Dot:..*"
1077       if version < "704"
1078         let g:iainsigns = g:iainsigns ." Cursor>o"
1079       endif
1080     endif
1081   endif
1082
1083   if g:marksigns
1084     " Signs to highlight marks.
1085     " Syntax won't work properly in Vim 6.
1086     let l:signs = g:iainsigns
1087     let l:sign = ""
1088     while strlen(l:signs)
1089       let l:sign = matchstr(l:signs, '^[A-Za-z]\+\(:.\)*[.=>-][^ ]\+')
1090
1091       let l:name = substitute(l:sign, '[:.=>-].*', "", "")
1092       let l:sign = substitute(l:sign, '^[A-Za-z]\+', "", "")
1093       let l:ascii = matchstr(l:sign, '^:.')
1094       let l:mark = substitute(l:sign, '^\(:.\)*[.=>-]', "", "")
1095       if strlen(l:ascii)
1096         let l:ascii = substitute(l:ascii, '^:', "", "")
1097         let l:ascii = matchstr(l:ascii, '^.')
1098       else
1099         let l:ascii = l:mark
1100       endif
1101       let l:ascii = substitute(l:ascii, '"', '\\"', "")
1102       let l:type = substitute(l:sign, '^:.', "", "")
1103       let l:type = matchstr(l:type, '^.')
1104
1105       let l:hl = ""
1106       if l:type == "="
1107         let l:hl = "texthl=MarkSign text="
1108       elseif l:type == "."
1109         let l:hl = "texthl=MarkDot text="
1110       elseif l:type == "-"
1111         let l:hl = "texthl=MarkLine text="
1112       elseif l:type == ">"
1113         let l:hl = "texthl=MarkArrow text="
1114       endif
1115
1116       exe "sign define Mark" . l:name . " " . l:hl . l:mark
1117
1118       let l:signs = substitute(l:signs, '^[^ ]\+ *', "", "")
1119     endwhile
1120
1121     if a:resize
1122       call Resize_Columns("+", 2)
1123     endif
1124     call <SID>Highlight_Signs()
1125   else
1126     let l:i = 0
1127     while l:i < 25
1128       exe "sign unplace " . (g:firstsign + l:i)
1129       let l:i = l:i + 1
1130     endwhile
1131
1132     let l:signs = g:iainsigns
1133     let l:sign = ""
1134     while strlen(l:signs)
1135       let l:sign = matchstr(l:signs, '^[A-Za-z]\+')
1136
1137       exe "sign undefine Mark" . l:sign
1138       call <SID>Prep_Sign(tolower(l:sign))
1139       let l:signs = substitute(l:signs, '^[^ ]\+ *', "", "")
1140     endwhile
1141
1142     if a:resize
1143       call Resize_Columns("-", 2)
1144     endif
1145   endif
1146 endfun "}}}2
1147
1148 " Change list mode.
1149 fun! Cycle_List() "{{{2
1150   " Pretty UTF-8 listchars.
1151   if Has_Unicode()
1152     let basic='tab:»·,trail:…,extends:«,precedes:»'
1153     let eol='eol:¶'
1154     if version >= "700"
1155       let basic=basic . ',nbsp:•'
1156     endif
1157   else
1158     let basic='tab:\\_,trail:_,extends:<,precedes:>'
1159     let eol='eol:$'
1160     if version >= "700"
1161       let basic=basic . ',nbsp:+'
1162     endif
1163   endif
1164   call Iain_Vars()
1165   let w:iainlist = w:iainlist + 1
1166   if w:iainlist > 2
1167     let w:iainlist = 0
1168   endif
1169   if w:iainlist == 0
1170     setlocal nolist
1171   elseif w:iainlist == 1
1172     exec "setlocal lcs=" . basic
1173     setlocal list
1174   else
1175     exec "setlocal lcs=" . basic . "," . eol
1176     setlocal list
1177   endif
1178
1179   call Resize_Columns(Extra_Columns("list", "iainlist", " == 2"), 1)
1180   call Extra_Whitespace_Match()
1181 endfun "}}}2
1182
1183 " Cycle between hex and decimal display of toolbar stuff.
1184 fun! Cycle_HexStatusLine() "{{{2
1185   call Iain_Vars()
1186   let b:iainhex = ! b:iainhex
1187   call Show_StatusLine()
1188 endfun "}}}2
1189
1190 " Cycle verbose display of toolbar stuff.
1191 fun! Cycle_VerboseStatusLine() "{{{2
1192   call Iain_Vars()
1193   let b:iainverbose = ! b:iainverbose
1194   call Show_StatusLine()
1195 endfun "}}}2
1196
1197 " Toggle quickfix window.
1198 fun! Cycle_Quickfix() "{{{2
1199   if ! has("quickfix")
1200     return
1201   endif
1202   if g:quickfixing == 1
1203     cclose
1204     let g:quickfixing=0
1205   else
1206     copen
1207   endif
1208 endfun "}}}2
1209
1210 " Toggle showing alternate buffer information.
1211 fun! Cycle_Alt() "{{{2
1212   call Iain_Vars()
1213   let b:iainalt = ! b:iainalt
1214   call Show_StatusLine()
1215 endfun "{{{2
1216
1217 " To be overridden later if applicable.
1218 fun! Extra_Whitespace_Match() "{{{2
1219   " NOP.
1220 endfun "}}}2
1221
1222 " Swap hex/decimal statusline with \x.
1223 call Mapping("x", ":call Cycle_HexStatusLine()<CR>:<CR>")
1224 " Change statusline verbosity with \v.
1225 call Mapping("V", ":call Cycle_VerboseStatusLine()<CR>:<CR>")
1226 " Cycle list styles with \l.
1227 call Mapping("l", ":call Cycle_List()<CR>:<CR>")
1228 " Toggle tags with \t.
1229 call Mapping("t", ":Tlist<CR>")
1230 " Change foldmethod with \f.
1231 call Mapping("f", ":se foldenable!<CR>:<CR>")
1232 " Toggle quickfix window with \q.
1233 call Mapping("q", ":call Cycle_Quickfix()<CR>:<CR>")
1234 " Rerun filetype detection with \s.  The s is for syntax, as this will be
1235 " updated as a side-effect.
1236 call Mapping("S", ":filetype detect<CR>:<CR>")
1237 " Toggle marks with \m.
1238 call Mapping("m", ":call <SID>Cycle_Signs(1)<CR>:<CR>")
1239
1240 if has("autocmd")
1241   " Show signs by default.
1242   au Display VimEnter * call <SID>Cycle_Signs(0)
1243 endif
1244
1245 " move.
1246 nmap <A-u> <Plug>MoveLineHalfPageUp
1247 nmap <A-d> <Plug>MoveLineHalfPageDown
1248 vmap <A-u> <Plug>MoveBlockHalfPageUp
1249 vmap <A-d> <Plug>MoveBlockHalfPageDown
1250 endif "}}}1
1251
1252 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1253 " Handle options only available in Vim 7 and above.
1254 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1255 if version >= "700" "{{{1
1256 version 7.0
1257
1258 " Helper to show tab name.
1259 fun! <SID>TabName(label, gui) "{{{2
1260   let l:label = a:label
1261   if l:label == ""
1262     let l:label = "No Name"
1263     if a:gui
1264       let l:label = "[" . l:label . "]"
1265     endif
1266   else
1267     let l:label = fnamemodify(l:label, ":t")
1268     if strlen(l:label) >= 18
1269       let l:label = l:label[0:17] . ".."
1270     endif
1271   endif
1272   return l:label
1273 endfun "}}}2
1274
1275 " Find out if any buffer was modified.
1276 fun! <SID>TabModified(buflist) "{{{2
1277   let l:i = 0
1278   while l:i < len(a:buflist)
1279     if getbufvar(a:buflist[l:i], "&modified") == 1
1280       return "+"
1281     endif
1282     let l:i = l:i + 1
1283   endwhile
1284   return ""
1285 endfun "}}}2
1286
1287 " Tab line.
1288 fun! Show_TabLine() "{{{2
1289   let l:s = "%#TabLineFill#Tabs:"
1290
1291   let l:i = 0
1292   while l:i < tabpagenr("$")
1293     let l:i = l:i + 1
1294     " Get the label.
1295     let l:buflist = tabpagebuflist(l:i)
1296     let l:winnr = tabpagewinnr(l:i)
1297     let l:n = tabpagewinnr(l:i, "$")
1298     let l:label = <SID>TabName(bufname(l:buflist[l:winnr - 1]), 0)
1299     let l:modified = <SID>TabModified(l:buflist)
1300
1301     " Choose highlighting.
1302     if l:i == tabpagenr()
1303       let l:s .= "%#TabLineSel#[" . l:n . l:modified . " " . l:label . "]"
1304     else
1305       let l:s .= "%#TabLine# " . l:n . l:modified . " " . l:label . " "
1306     endif
1307   endwhile
1308
1309   " Padding.
1310   let l:s .= "%#TabLine#%T"
1311   return l:s
1312 endfun "}}}2
1313
1314 " Per tab label for the GUI.
1315 fun! Show_GUITabLine() "{{{2
1316   let l:buflist = tabpagebuflist(v:lnum)
1317   let l:winnr = tabpagewinnr(v:lnum)
1318   let l:s = tabpagewinnr(v:lnum, "$")
1319   let l:label = <SID>TabName(bufname(l:buflist[l:winnr - 1]), 1)
1320   let l:modified = <SID>TabModified(l:buflist)
1321
1322   let l:s .= l:modified . " " . l:label
1323   return l:s
1324 endfun "}}}2
1325
1326 " Handle searching in a BufExplorer window.
1327 fun! <SID>BufExplorer_Search(n) "{{{2
1328   if a:n == 0
1329     let l:re = '^  *\d %'
1330   else
1331     let l:re = "^ *" . a:n
1332   endif
1333
1334   " Find matching line.
1335   let l:line = search(l:re, 'w')
1336   if ! l:line
1337     return
1338   endif
1339
1340   if a:n == 0
1341     return
1342   endif
1343
1344   " Peek ahead to the next matching line.
1345   let l:next = search(l:re, 'w')
1346
1347   " Select the buffer if the match is unambiguous.
1348   if l:next == l:line
1349     exe "normal \<CR>"
1350     return
1351   endif
1352
1353   " Go back.
1354   call cursor(l:line, 0)
1355 endfun! "}}}2
1356
1357 " Entering a BufExplorer window.
1358 fun! <SID>BufExplorer_Map() "{{{2
1359   for l:n in [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" ]
1360     exec "nnoremap <buffer> <silent>" . l:n . " :call <SID>BufExplorer_Search(" . l:n . ")<CR>"
1361   endfor
1362 endfun "}}}2
1363
1364 if has("windows")
1365   se tabline=%!Show_TabLine()
1366   se guitablabel=%!Show_GUITabLine()
1367 endif
1368
1369 if has("autocmd")
1370   au StatusLine CursorHoldI * call Highlight_StatusLine("H")
1371   au StatusLine CursorMovedI * call Highlight_StatusLine("h")
1372   au StatusLine FocusGained * call Highlight_StatusLine("F")
1373   au StatusLine FocusLost * call Highlight_StatusLine("f")
1374   au StatusLine InsertEnter * call Highlight_StatusLine("I")
1375   au StatusLine InsertChange * call Highlight_StatusLine("I")
1376   au StatusLine InsertLeave * call Highlight_StatusLine("i")
1377
1378   if has("signs")
1379     au Signs CursorHoldI * call <SID>Highlight_Signs()
1380     au Signs InsertEnter * call <SID>Highlight_Signs()
1381     au Signs InsertLeave * call <SID>Highlight_Signs()
1382   endif
1383
1384   au Mode BufEnter \[BufExplorer\] call <SID>BufExplorer_Map()
1385 endif
1386
1387 " Limit the size of the popup menu when completing.
1388 if has("insert_expand")
1389   se pumheight=20
1390 endif
1391
1392 " Make diffs vertical by default.
1393 if has("diff")
1394   se diffopt+=vertical
1395 endif
1396
1397 " Set size of numbers column.
1398 if has("linebreak")
1399   se numberwidth=5
1400 endif
1401
1402 " Add "previous tab" mapping as gb.
1403 map gb :tabprevious<CR>:<CR>
1404
1405 " Transparency.
1406 if has("gui_macvim")
1407   se transparency=15
1408 endif
1409
1410 " Yet more GUI options.  Add tabs.
1411 if has("gui")
1412   se go+=e
1413 endif
1414
1415 " Perforce.
1416 let g:p4EnableMenu=1
1417 let g:p4Presets='P4CONFIG'
1418
1419 " BufExplorer.
1420 let g:bufExplorerShowRelativePath=1
1421 let g:bufExplorerSplitOutPathName=0
1422
1423 " NERDcommenter.
1424 let g:NERDSpaceDelims=1
1425
1426 " localvimrc.
1427 let g:localvimrc_persistent=1
1428
1429 " Gitv.
1430 let g:Gitv_OpenHorizontal='auto'
1431 let g:Gitv_WipeAllOnClose=1
1432 endif "}}}1
1433
1434 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1435 " Handle options only available in Vim 7.2 and above.
1436 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1437 if version >= "702" "{{{1
1438 if has("autocmd")
1439   " http://vim.wikia.com/wiki/Highlight_unwanted_spaces
1440   augroup WhitespaceMatch
1441   autocmd!
1442   au Display BufWinEnter * call Extra_Whitespace_Match()
1443   au Display Syntax * call Extra_Whitespace_Match()
1444   au Display BufWinLeave * call clearmatches()
1445   augroup END
1446
1447   fun! Extra_Whitespace_Match() "{{{2
1448     " \s\+            <whitespace>
1449     "            $    <before end of line>
1450     "        \@<!     <unless preceded by>
1451     "     \%#         <cursor position, ie when typing>
1452     let l:pattern = '\s\+\%#\@<!$'
1453     " Don't match single space in first column of diff.
1454     if &ft =~# '^diff$\|git'
1455       "         \@!  <unless also matching>
1456       " \(^\s$\)     <a single whitespace>
1457       let l:pattern = '\(^\s$\)\@!' . l:pattern
1458     endif
1459
1460     let l:hl = 'ctermfg=red guifg=red'
1461     if ! &list
1462       " Underline if we aren't using listchars.
1463       let l:hl = l:hl . ' cterm=underline gui=underline'
1464     endif
1465     highlight clear ExtraWhitespace
1466     exe "highlight ExtraWhitespace " . l:hl
1467     if exists('w:whitespace_match_number')
1468       try
1469         call matchdelete(w:whitespace_match_number)
1470       catch
1471       endtry
1472       call matchadd('ExtraWhitespace', l:pattern, 10, w:whitespace_match_number)
1473     else
1474       let w:whitespace_match_number = matchadd('ExtraWhitespace', l:pattern)
1475     endif
1476   endfun "}}}2
1477
1478   call Extra_Whitespace_Match()
1479 endif
1480
1481 endif "}}}1
1482
1483 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1484 " Handle options only available in Vim 7.3 and above.
1485 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1486 if version >= "703" "{{{1
1487 version 7.3
1488
1489 " Toggle persistent undo with \u.
1490 call Mapping("u", ":call <SID>Cycle_Undo()<CR>:<CR>")
1491 " Remove persistent undo file with \U.
1492 call Mapping("U", ":call <SID>Clear_Undo()<CR>:<CR>")
1493
1494 " Toggle gundo window with \g.
1495 call Mapping("g", ":call gundo#GundoToggle()<CR>:<CR>")
1496
1497 " Use a persistent undo file if it exists.
1498 fun! <SID>Check_Undo() "{{{2
1499   if filereadable(undofile(expand("%")))
1500     setlocal undofile
1501   endif
1502 endfun "}}}2
1503
1504 " Toggle persistent undo for this buffer.
1505 fun! <SID>Cycle_Undo() "{{{2
1506   if has("persistent_undo")
1507     let &undofile = ! &undofile
1508   endif
1509 endfun "}}}2
1510
1511 " Remove the persistent undo file for this buffer.
1512 fun! <SID>Clear_Undo() "{{{2
1513   if ! has("persistent_undo")
1514     return
1515   endif
1516
1517   setlocal noundofile
1518
1519   let l:f = expand("%")
1520   if l:f == ""
1521     return
1522   endif
1523
1524   let l:u = undofile(l:f)
1525   if l:u == ""
1526     return
1527   endif
1528
1529   if ! filereadable(l:u) || ! filewritable(l:u)
1530     return
1531   endif
1532
1533   call delete(l:u)
1534 endfun "}}}2
1535
1536 " Toggle ColorColumn at cursor position.
1537 fun! <SID>Cycle_ColorColumn() "{{{2
1538   if ! has("syntax")
1539     return
1540   endif
1541
1542   let l:cc = &colorcolumn
1543   let l:column = col(".")
1544   let l:re = ",*\\<" . l:column . "\\>"
1545   if l:cc =~# l:re
1546     let l:cc = substitute(l:cc, l:re, "", "g")
1547   else
1548     let l:cc = l:cc . "," . l:column
1549   endif
1550   let &colorcolumn = substitute(l:cc, "^,*", "", "")
1551 endfun "}}}2
1552
1553 if has("syntax")
1554   " Enable showing ColorColumn at cursor position with \CC.
1555   call Mapping("CC", ":call <SID>Cycle_ColorColumn()<CR>:<CR>")
1556   " Remove last shown ColorColumn with \Cc.
1557   call Mapping("Cc", ":let &colorcolumn=substitute(&colorcolumn, \",*[0-9]*$\", \"\", \"\")<CR>:<CR>")
1558   " Remove all ColorColumns with \Cx.
1559   call Mapping("Cx", ":se colorcolumn=<CR>:<CR>")
1560 endif
1561
1562 " Use persistent undo if available.
1563 if has("autocmd")
1564   if has("persistent_undo")
1565     au File BufReadPost * call <SID>Check_Undo()
1566   endif
1567
1568   if has("cursorbind")
1569     au Display WinEnter * if &diff | se cursorbind | endif
1570   endif
1571 endif
1572
1573 " Mapping to reload the gundo window.
1574 if has("autocmd")
1575   au Mode BufEnter * if &ft == "gundo" | try | nnoremap <silent> <buffer> <unique> r :call gundo#GundoToggle()<CR>:call gundo#GundoToggle()<CR> | catch | endtry | endif
1576 endif
1577
1578 endif "}}}1
1579 "
1580 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1581 " Handle options only available in Vim 7.4 and above.
1582 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1583 if version >= "704" "{{{1
1584 version 7.4
1585
1586 if has("syntax")
1587   se cursorline
1588 endif
1589
1590 endif "}}}1
1591
1592 " Resize after startup.
1593 if version >= "500" "{{{1
1594 if has("autocmd")
1595   au Display VimEnter * call Startup_Resize()
1596 endif
1597 endif "}}}1