Space plugin.
[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 " Mark DOS buffers.
749 fun! Show_DOS() "{{{2
750   if &ff == "unix"
751     return ""
752   endif
753   return &ff . ","
754 endfun "}}}2
755
756 " Helper for status line.
757 " Show the size of the tabstop.
758 fun! Show_Tabstop() "{{{2
759   return &ts
760 endfun "}}}2
761
762 " Helper for status line.
763 " Show p when paste mode is on.
764 fun! Show_Paste() "{{{2
765   if &paste
766     return "p"
767   else
768     return ""
769   endif
770 endfun "}}}2
771
772 " Helper for status line.
773 " Show v when virtualedit mode is block, insert or onemore.
774 " Show V when virtualedit mode is all.
775 fun! Show_VirtualEdit() "{{{2
776   if ! has("virtualedit")
777     return ""
778   endif
779
780   if &ve == "all"
781     return "V"
782   elseif &ve != ''
783     return "v"
784   else
785     return ""
786   endif
787 endfun "}}}2
788
789 " Helper for status line.
790 " Show U when persistent undo is on.
791 " Show u when persistent undo is off but an undofile exists.
792 fun! Show_Undo() "{{{2
793   if ! exists("&undofile")
794     return ""
795   endif
796
797   if &undofile
798     return "U"
799   elseif filereadable(undofile(expand("%")))
800     return "u"
801   else
802     return ""
803   endif
804 endfun "}}}2
805
806 " Helper for status line.
807 " Show alternate buffer number and name.
808 fun! Show_Alt() "{{{2
809   let l:alt = bufnr("#")
810   if l:alt < 0 || l:alt == bufnr("") || ! b:iainalt
811     return ""
812   endif
813
814   return " " . l:alt . ": " . expand("#:t")
815 endfun "}}}2
816
817 " Helper for status line.
818 " Show scrollbind or cursorbind.
819 fun! Show_Bind() "{{{2
820   if has("cursorbind")
821     if &cursorbind
822       if Has_Unicode()
823         return "⇄"
824       else
825         return ">"
826       endif
827     elseif &scrollbind
828       if Has_Unicode()
829         return "⇅"
830       else
831         return "^"
832       endif
833     endif
834   endif
835   return ""
836 endfun "}}}2
837
838 " Helper for status line.
839 " Show marker if searchforward is unset.
840 fun! Show_SearchForward() "{{{2
841   if version >= "702"
842     if ! v:searchforward
843       if Has_Unicode()
844         return "∆"
845       else
846         return "^"
847       endif
848     endif
849   endif
850   return ""
851 endfun "}}}2
852
853 " Helper for status line.
854 " Show marks set in cursor line.
855 fun! Show_Marks() "{{{2
856   if ! exists("g:iainsigns")
857     return ""
858   endif
859
860   let l:marks = ""
861
862   let l:signs = g:iainsigns
863   let l:sign = ""
864   let l:cursorline = line(".")
865   while strlen(l:signs)
866     let l:sign = matchstr(l:signs, '^[A-Za-z]\+\(:.\)*[.=>-][^ ]\+')
867     let l:sign = substitute(l:sign, '^[A-Za-z]\+', "", "")
868     let l:ascii = matchstr(l:sign, '^:.')
869     let l:mark = substitute(l:sign, '^\(:.\)*[.=>-]', "", "")
870     if strlen(l:ascii)
871       let l:ascii = substitute(l:ascii, '^:', "", "")
872     else
873       let l:ascii = l:mark
874     endif
875     let l:ascii = substitute(l:ascii, '"', '\\"', "")
876
877     if l:ascii == "o"
878       let l:line = "."
879     else
880       let l:line = "'" . l:ascii
881     endif
882
883     " Ignore cursor line which will always match.
884     if l:line != "."
885       if l:cursorline == line(l:line)
886         let l:marks = l:marks . l:mark
887       endif
888     endif
889
890     let l:signs = substitute(l:signs, '^[^ ]\+ *', "", "")
891   endwhile
892
893   if l:marks == ""
894     return ""
895   else
896     return "M:" . l:marks . " "
897   endif
898 endfun "}}}2
899
900 " Show the status line.
901 fun! Show_StatusLine() "{{{2
902   if ! has("statusline")
903     return
904   endif
905   call Iain_Vars()
906
907   " User{N} highlights %{N}*.
908   " Named highlight groups %#group% aren't available until Vim 7.
909   let l:normal = '%0*'
910   let l:bold = '%1*'
911
912   " sl1 contains left-aligned stuff.
913   " sl2 contains stuff shown only when verbose mode is enabled.
914   " sl3 contains right-aligned stuff.
915   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()}\ '
916   let l:sl3='%{Show_Marks()}L:' . l:bold . '%4.6l' . l:normal . '/%-4.6L\ C:' . l:bold . '%3.6c%V' . l:normal . '\ \|\ %P'
917   let l:hexformat='%b'
918   if b:iainhex
919     let l:hexformat='0\x%02B'
920   endif
921   if b:iainverbose
922     let l:sl1=l:sl1 . v:version . '\ %='
923     let l:sl2=l:hexformat . '\ \|\ P:%4.6o\ '
924   else
925     let l:sl1=l:sl1 . '%='
926     let l:sl2=''
927   endif
928   exec "set statusline=" . l:sl1 . l:sl2 . l:sl3
929 endfun "}}}2
930
931 " Show the status line for the first time.
932 call Show_StatusLine()
933 endif "}}}1
934
935 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
936 " Handle options only available in Vim 6 and above.
937 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
938 if version >= "600" "{{{1
939 version 6.0
940
941 if has("win32") || has("win64")
942   se encoding=utf-8
943 endif
944
945 " Remember quickfix state.
946 if has("quickfix")
947   let g:quickfixing=0
948 endif
949
950 " Set indenting by filetype.
951 filetype indent on
952
953 " Less intrusive syntax highlighting.
954 if has("syntax")
955   " The :syntax enable command tries to source the syntax.vim runtime script.
956   " Parsing this .vimrc will fail if for some reason the runtime doesn't
957   " exist, as could be the case if the binary was installed with no support
958   " files.  GNU On Windows is one example of an incomplete installation.
959   try
960     syn enable
961   catch
962   endtry
963 endif
964
965 " Set colours.
966 if has("gui_running")
967   if has("win32") || has("win64")
968     exe "silent se guifont=DejaVu_Sans_Mono:h10:cANSI"
969   else
970     exe "silent se guifont=DejaVu\\ Sans\\ Mono\\ 10"
971   endif
972 endif
973 if has("gui_running") || &t_Co > 16
974   exe "silent colo iain"
975 endif
976
977 " Ignore whitespace when diffing.
978 if has("diff")
979   se diffopt=filler,iwhite
980 endif
981
982 if has("autocmd")
983   if has("quickfix")
984     " Remember that we are opening the quickfix window.
985     au Mode BufWinEnter quickfix let g:quickfixing=1
986     au Mode BufUnload * if &ft == "qf" | let g:quickfixing=0 | endif
987   endif
988
989   " Allow in-place editing of crontabs.
990   au Mode FileType crontab set backupcopy=yes
991 endif
992
993 " Make * and # work the way you expect in visual mode.
994 vnoremap * y/\V<C-R>=substitute(escape(@@,"/\\"),"\n","\\\\n","ge")<CR><CR>
995 vnoremap # y?\V<C-R>=substitute(escape(@@,"?\\"),"\n","\\\\n","ge")<CR><CR>
996
997 " Set mark and update highlighting.
998 if has("signs")
999   au Signs BufReadPost * call <SID>Highlight_Signs()
1000   au Signs CursorHold * call <SID>Highlight_Signs()
1001 endif
1002
1003 " Helper to set buffer variable for a given sign.
1004 fun! <SID>Prep_Sign(sign) "{{{2
1005   if ! exists("b:sign" . a:sign) || ! g:marksigns
1006     exe "let b:sign" . a:sign . "=0"
1007    endif
1008 endfun "}}}2
1009
1010 fun! <SID>Place_Sign(number, line, old, name) "{{{2
1011   if a:line == a:old
1012     return a:old
1013   endif
1014
1015   exe "sign unplace " . (g:firstsign + a:number) . " buffer=" . bufnr("")
1016   " Don't place the sign if it would conflict with the last change sign.
1017   exe "sign place " . (g:firstsign + a:number) . " line=" . a:line . " name=" . a:name . " buffer=" . bufnr("")
1018   return a:line
1019 endfun "}}}2
1020
1021 fun! <SID>Highlight_Signs(...) "{{{2
1022   if ! has("signs") || ! g:marksigns || Uncluttered_Buffer()
1023     return
1024   endif
1025
1026   let l:signs = g:iainsigns
1027   let l:sign = ""
1028   let l:i = 0
1029   while strlen(l:signs)
1030     let l:sign = matchstr(l:signs, '^[A-Za-z]\+\(:.\)*[.=>-][^ ]\+')
1031
1032     let l:name = substitute(l:sign, '[:.=>-].*', "", "")
1033     let l:var = tolower(l:name)
1034     let l:sign = substitute(l:sign, '^[A-Za-z]\+', "", "")
1035     let l:ascii = matchstr(l:sign, '^:.')
1036     let l:mark = substitute(l:sign, '^\(:.\)*[.=>-]', "", "")
1037     if strlen(l:ascii)
1038       let l:ascii = substitute(l:ascii, '^:', "", "")
1039     else
1040       let l:ascii = l:mark
1041     endif
1042     let l:ascii = substitute(l:ascii, '"', '\\"', "")
1043
1044     if l:ascii == "o"
1045       let l:line = "."
1046     else
1047       let l:line = "'" . l:ascii
1048     endif
1049
1050     call <SID>Prep_Sign(l:var)
1051     exe "let " . l:var . " = <SID>Place_Sign(" . l:i . ", line(\"" . l:line . "\"), b:sign" . l:var . ", \"Mark" . l:name . "\")"
1052     let l:i = l:i + 1
1053
1054     let l:signs = substitute(l:signs, '^[^ ]\+ *', "", "")
1055   endwhile
1056 endfun "}}}2
1057
1058 " Toggle signs.
1059 fun! <SID>Cycle_Signs(resize) "{{{2
1060   if ! has("signs")
1061     return
1062   endif
1063   call Iain_Vars()
1064   let g:marksigns = ! g:marksigns
1065
1066   " Retrofit arrays on to Vim 6.
1067   if ! exists("g:iainsigns")
1068     " Signs are defined in g:iainsigns.  The syntax is as follows:
1069     "
1070     " Sign ::= Name (':' Mark)* Type Symbol
1071     " Type ::= '=' | '-' | '.'
1072     "
1073     " Signs with Type '=' will be highlighted with the MarkSign group.
1074     " Signs with Type '-' will be highlighted with the MarkLine group.
1075     " Signs with Type '.' will be highlighted with the MarkDot group.
1076     " Signs with Type '>' will be highlighted with the MarkArrow group.
1077     " Define the Mark where Symbol is not also the mark name, eg "']".
1078     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"
1079     if Has_Unicode()
1080       let g:iainsigns = g:iainsigns . " Quote:\"=” Dash:'=’ Caret:^.ʌ Dot:..•"
1081       if version < "704"
1082         let g:iainsigns = g:iainsigns ." Cursor:o>▶"
1083       endif
1084     else
1085       let g:iainsigns = g:iainsigns . " Quote=\" Dash=' Caret.^ Dot:..*"
1086       if version < "704"
1087         let g:iainsigns = g:iainsigns ." Cursor>o"
1088       endif
1089     endif
1090   endif
1091
1092   if g:marksigns
1093     " Signs to highlight marks.
1094     " Syntax won't work properly in Vim 6.
1095     let l:signs = g:iainsigns
1096     let l:sign = ""
1097     while strlen(l:signs)
1098       let l:sign = matchstr(l:signs, '^[A-Za-z]\+\(:.\)*[.=>-][^ ]\+')
1099
1100       let l:name = substitute(l:sign, '[:.=>-].*', "", "")
1101       let l:sign = substitute(l:sign, '^[A-Za-z]\+', "", "")
1102       let l:ascii = matchstr(l:sign, '^:.')
1103       let l:mark = substitute(l:sign, '^\(:.\)*[.=>-]', "", "")
1104       if strlen(l:ascii)
1105         let l:ascii = substitute(l:ascii, '^:', "", "")
1106         let l:ascii = matchstr(l:ascii, '^.')
1107       else
1108         let l:ascii = l:mark
1109       endif
1110       let l:ascii = substitute(l:ascii, '"', '\\"', "")
1111       let l:type = substitute(l:sign, '^:.', "", "")
1112       let l:type = matchstr(l:type, '^.')
1113
1114       let l:hl = ""
1115       if l:type == "="
1116         let l:hl = "texthl=MarkSign text="
1117       elseif l:type == "."
1118         let l:hl = "texthl=MarkDot text="
1119       elseif l:type == "-"
1120         let l:hl = "texthl=MarkLine text="
1121       elseif l:type == ">"
1122         let l:hl = "texthl=MarkArrow text="
1123       endif
1124
1125       exe "sign define Mark" . l:name . " " . l:hl . l:mark
1126
1127       let l:signs = substitute(l:signs, '^[^ ]\+ *', "", "")
1128     endwhile
1129
1130     if a:resize
1131       call Resize_Columns("+", 2)
1132     endif
1133     call <SID>Highlight_Signs()
1134   else
1135     let l:i = 0
1136     while l:i < 25
1137       exe "sign unplace " . (g:firstsign + l:i)
1138       let l:i = l:i + 1
1139     endwhile
1140
1141     let l:signs = g:iainsigns
1142     let l:sign = ""
1143     while strlen(l:signs)
1144       let l:sign = matchstr(l:signs, '^[A-Za-z]\+')
1145
1146       exe "sign undefine Mark" . l:sign
1147       call <SID>Prep_Sign(tolower(l:sign))
1148       let l:signs = substitute(l:signs, '^[^ ]\+ *', "", "")
1149     endwhile
1150
1151     if a:resize
1152       call Resize_Columns("-", 2)
1153     endif
1154   endif
1155 endfun "}}}2
1156
1157 " Change list mode.
1158 fun! Cycle_List() "{{{2
1159   " Pretty UTF-8 listchars.
1160   if Has_Unicode()
1161     let basic='tab:»·,trail:…,extends:«,precedes:»'
1162     let eol='eol:¶'
1163     if version >= "700"
1164       let basic=basic . ',nbsp:•'
1165     endif
1166   else
1167     let basic='tab:\\_,trail:_,extends:<,precedes:>'
1168     let eol='eol:$'
1169     if version >= "700"
1170       let basic=basic . ',nbsp:+'
1171     endif
1172   endif
1173   call Iain_Vars()
1174   let w:iainlist = w:iainlist + 1
1175   if w:iainlist > 2
1176     let w:iainlist = 0
1177   endif
1178   if w:iainlist == 0
1179     setlocal nolist
1180   elseif w:iainlist == 1
1181     exec "setlocal lcs=" . basic
1182     setlocal list
1183   else
1184     exec "setlocal lcs=" . basic . "," . eol
1185     setlocal list
1186   endif
1187
1188   call Resize_Columns(Extra_Columns("list", "iainlist", " == 2"), 1)
1189   call Extra_Whitespace_Match()
1190 endfun "}}}2
1191
1192 " Cycle between hex and decimal display of toolbar stuff.
1193 fun! Cycle_HexStatusLine() "{{{2
1194   call Iain_Vars()
1195   let b:iainhex = ! b:iainhex
1196   call Show_StatusLine()
1197 endfun "}}}2
1198
1199 " Cycle verbose display of toolbar stuff.
1200 fun! Cycle_VerboseStatusLine() "{{{2
1201   call Iain_Vars()
1202   let b:iainverbose = ! b:iainverbose
1203   call Show_StatusLine()
1204 endfun "}}}2
1205
1206 " Toggle quickfix window.
1207 fun! Cycle_Quickfix() "{{{2
1208   if ! has("quickfix")
1209     return
1210   endif
1211   if g:quickfixing == 1
1212     cclose
1213     let g:quickfixing=0
1214   else
1215     copen
1216   endif
1217 endfun "}}}2
1218
1219 " Toggle showing alternate buffer information.
1220 fun! Cycle_Alt() "{{{2
1221   call Iain_Vars()
1222   let b:iainalt = ! b:iainalt
1223   call Show_StatusLine()
1224 endfun "{{{2
1225
1226 " To be overridden later if applicable.
1227 fun! Extra_Whitespace_Match() "{{{2
1228   " NOP.
1229 endfun "}}}2
1230
1231 " Swap hex/decimal statusline with \x.
1232 call Mapping("x", ":call Cycle_HexStatusLine()<CR>:<CR>")
1233 " Change statusline verbosity with \v.
1234 call Mapping("V", ":call Cycle_VerboseStatusLine()<CR>:<CR>")
1235 " Cycle list styles with \l.
1236 call Mapping("l", ":call Cycle_List()<CR>:<CR>")
1237 " Toggle tags with \t.
1238 call Mapping("t", ":Tlist<CR>")
1239 " Change foldmethod with \f.
1240 call Mapping("f", ":se foldenable!<CR>:<CR>")
1241 " Toggle quickfix window with \q.
1242 call Mapping("q", ":call Cycle_Quickfix()<CR>:<CR>")
1243 " Rerun filetype detection with \s.  The s is for syntax, as this will be
1244 " updated as a side-effect.
1245 call Mapping("S", ":filetype detect<CR>:<CR>")
1246 " Toggle marks with \m.
1247 call Mapping("m", ":call <SID>Cycle_Signs(1)<CR>:<CR>")
1248
1249 if has("autocmd")
1250   " Show signs by default.
1251   au Display VimEnter * call <SID>Cycle_Signs(0)
1252 endif
1253
1254 " move.
1255 nmap <A-u> <Plug>MoveLineHalfPageUp
1256 nmap <A-d> <Plug>MoveLineHalfPageDown
1257 vmap <A-u> <Plug>MoveBlockHalfPageUp
1258 vmap <A-d> <Plug>MoveBlockHalfPageDown
1259 endif "}}}1
1260
1261 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1262 " Handle options only available in Vim 7 and above.
1263 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1264 if version >= "700" "{{{1
1265 version 7.0
1266
1267 " Narrow buffer with \w.
1268 call Mapping("w", ":NarrowRegion<CR>:<CR>")
1269 " Narrow window with \W.
1270 call Mapping("W", ":NarrowWindow<CR>:<CR>")
1271
1272 " Helper to show tab name.
1273 fun! <SID>TabName(label, gui) "{{{2
1274   let l:label = a:label
1275   if l:label == ""
1276     let l:label = "No Name"
1277     if a:gui
1278       let l:label = "[" . l:label . "]"
1279     endif
1280   else
1281     let l:label = fnamemodify(l:label, ":t")
1282     if strlen(l:label) >= 18
1283       let l:label = l:label[0:17] . ".."
1284     endif
1285   endif
1286   return l:label
1287 endfun "}}}2
1288
1289 " Find out if any buffer was modified.
1290 fun! <SID>TabModified(buflist) "{{{2
1291   let l:i = 0
1292   while l:i < len(a:buflist)
1293     if getbufvar(a:buflist[l:i], "&modified") == 1
1294       return "+"
1295     endif
1296     let l:i = l:i + 1
1297   endwhile
1298   return ""
1299 endfun "}}}2
1300
1301 " Tab line.
1302 fun! Show_TabLine() "{{{2
1303   let l:s = "%#TabLineFill#Tabs:"
1304
1305   let l:i = 0
1306   while l:i < tabpagenr("$")
1307     let l:i = l:i + 1
1308     " Get the label.
1309     let l:buflist = tabpagebuflist(l:i)
1310     let l:winnr = tabpagewinnr(l:i)
1311     let l:n = tabpagewinnr(l:i, "$")
1312     let l:label = <SID>TabName(bufname(l:buflist[l:winnr - 1]), 0)
1313     let l:modified = <SID>TabModified(l:buflist)
1314
1315     " Choose highlighting.
1316     if l:i == tabpagenr()
1317       let l:s .= "%#TabLineSel#[" . l:n . l:modified . " " . l:label . "]"
1318     else
1319       let l:s .= "%#TabLine# " . l:n . l:modified . " " . l:label . " "
1320     endif
1321   endwhile
1322
1323   " Padding.
1324   let l:s .= "%#TabLine#%T"
1325   return l:s
1326 endfun "}}}2
1327
1328 " Per tab label for the GUI.
1329 fun! Show_GUITabLine() "{{{2
1330   let l:buflist = tabpagebuflist(v:lnum)
1331   let l:winnr = tabpagewinnr(v:lnum)
1332   let l:s = tabpagewinnr(v:lnum, "$")
1333   let l:label = <SID>TabName(bufname(l:buflist[l:winnr - 1]), 1)
1334   let l:modified = <SID>TabModified(l:buflist)
1335
1336   let l:s .= l:modified . " " . l:label
1337   return l:s
1338 endfun "}}}2
1339
1340 " Handle searching in a BufExplorer window.
1341 fun! <SID>BufExplorer_Search(n) "{{{2
1342   if a:n == 0
1343     let l:re = '^  *\d %'
1344   else
1345     let l:re = "^ *" . a:n
1346   endif
1347
1348   " Find matching line.
1349   let l:line = search(l:re, 'w')
1350   if ! l:line
1351     return
1352   endif
1353
1354   if a:n == 0
1355     return
1356   endif
1357
1358   " Peek ahead to the next matching line.
1359   let l:next = search(l:re, 'w')
1360
1361   " Select the buffer if the match is unambiguous.
1362   if l:next == l:line
1363     exe "normal \<CR>"
1364     return
1365   endif
1366
1367   " Go back.
1368   call cursor(l:line, 0)
1369 endfun! "}}}2
1370
1371 " Entering a BufExplorer window.
1372 fun! <SID>BufExplorer_Map() "{{{2
1373   for l:n in [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" ]
1374     exec "nnoremap <buffer> <silent>" . l:n . " :call <SID>BufExplorer_Search(" . l:n . ")<CR>"
1375   endfor
1376 endfun "}}}2
1377
1378 if has("windows")
1379   se tabline=%!Show_TabLine()
1380   se guitablabel=%!Show_GUITabLine()
1381 endif
1382
1383 if has("autocmd")
1384   au StatusLine CursorHoldI * call Highlight_StatusLine("H")
1385   au StatusLine CursorMovedI * call Highlight_StatusLine("h")
1386   au StatusLine FocusGained * call Highlight_StatusLine("F")
1387   au StatusLine FocusLost * call Highlight_StatusLine("f")
1388   au StatusLine InsertEnter * call Highlight_StatusLine("I")
1389   au StatusLine InsertChange * call Highlight_StatusLine("I")
1390   au StatusLine InsertLeave * call Highlight_StatusLine("i")
1391
1392   if has("signs")
1393     au Signs CursorHoldI * call <SID>Highlight_Signs()
1394     au Signs InsertEnter * call <SID>Highlight_Signs()
1395     au Signs InsertLeave * call <SID>Highlight_Signs()
1396   endif
1397
1398   au Mode BufEnter \[BufExplorer\] call <SID>BufExplorer_Map()
1399 endif
1400
1401 " Limit the size of the popup menu when completing.
1402 if has("insert_expand")
1403   se pumheight=20
1404 endif
1405
1406 " Make diffs vertical by default.
1407 if has("diff")
1408   se diffopt+=vertical
1409 endif
1410
1411 " Set size of numbers column.
1412 if has("linebreak")
1413   se numberwidth=5
1414 endif
1415
1416 " Add "previous tab" mapping as gb.
1417 map gb :tabprevious<CR>:<CR>
1418
1419 " Transparency.
1420 if has("gui_macvim")
1421   se transparency=15
1422 endif
1423
1424 " Yet more GUI options.  Add tabs.
1425 if has("gui")
1426   se go+=e
1427 endif
1428
1429 " Perforce.
1430 let g:p4EnableMenu=1
1431 let g:p4Presets='P4CONFIG'
1432
1433 " BufExplorer.
1434 let g:bufExplorerShowRelativePath=1
1435 let g:bufExplorerSplitOutPathName=0
1436
1437 " NERDcommenter.
1438 let g:NERDSpaceDelims=1
1439
1440 " localvimrc.
1441 let g:localvimrc_persistent=1
1442
1443 " Gitv.
1444 let g:Gitv_OpenHorizontal='auto'
1445 let g:Gitv_WipeAllOnClose=1
1446 endif "}}}1
1447
1448 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1449 " Handle options only available in Vim 7.2 and above.
1450 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1451 if version >= "702" "{{{1
1452 if has("autocmd")
1453   " http://vim.wikia.com/wiki/Highlight_unwanted_spaces
1454   augroup WhitespaceMatch
1455   autocmd!
1456   au Display BufWinEnter * call Extra_Whitespace_Match()
1457   au Display Syntax * call Extra_Whitespace_Match()
1458   au Display BufWinLeave * call clearmatches()
1459   augroup END
1460
1461   fun! Extra_Whitespace_Match() "{{{2
1462     " \s\+            <whitespace>
1463     "            $    <before end of line>
1464     "        \@<!     <unless preceded by>
1465     "     \%#         <cursor position, ie when typing>
1466     let l:pattern = '\s\+\%#\@<!$'
1467     " Don't match single space in first column of diff.
1468     if &ft =~# '^diff$\|git'
1469       "         \@!  <unless also matching>
1470       " \(^\s$\)     <a single whitespace>
1471       let l:pattern = '\(^\s$\)\@!' . l:pattern
1472     endif
1473
1474     let l:hl = 'ctermfg=red guifg=red'
1475     if ! &list
1476       " Underline if we aren't using listchars.
1477       let l:hl = l:hl . ' cterm=underline gui=underline'
1478     endif
1479     highlight clear ExtraWhitespace
1480     exe "highlight ExtraWhitespace " . l:hl
1481     if exists('w:whitespace_match_number')
1482       try
1483         call matchdelete(w:whitespace_match_number)
1484       catch
1485       endtry
1486       call matchadd('ExtraWhitespace', l:pattern, 10, w:whitespace_match_number)
1487     else
1488       let w:whitespace_match_number = matchadd('ExtraWhitespace', l:pattern)
1489     endif
1490   endfun "}}}2
1491
1492   call Extra_Whitespace_Match()
1493 endif
1494
1495 endif "}}}1
1496
1497 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1498 " Handle options only available in Vim 7.3 and above.
1499 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1500 if version >= "703" "{{{1
1501 version 7.3
1502
1503 " Toggle persistent undo with \u.
1504 call Mapping("u", ":call <SID>Cycle_Undo()<CR>:<CR>")
1505 " Remove persistent undo file with \U.
1506 call Mapping("U", ":call <SID>Clear_Undo()<CR>:<CR>")
1507
1508 " Toggle gundo window with \g.
1509 call Mapping("g", ":call gundo#GundoToggle()<CR>:<CR>")
1510
1511 " Use a persistent undo file if it exists.
1512 fun! <SID>Check_Undo() "{{{2
1513   if filereadable(undofile(expand("%")))
1514     setlocal undofile
1515   endif
1516 endfun "}}}2
1517
1518 " Toggle persistent undo for this buffer.
1519 fun! <SID>Cycle_Undo() "{{{2
1520   if has("persistent_undo")
1521     let &undofile = ! &undofile
1522   endif
1523 endfun "}}}2
1524
1525 " Remove the persistent undo file for this buffer.
1526 fun! <SID>Clear_Undo() "{{{2
1527   if ! has("persistent_undo")
1528     return
1529   endif
1530
1531   setlocal noundofile
1532
1533   let l:f = expand("%")
1534   if l:f == ""
1535     return
1536   endif
1537
1538   let l:u = undofile(l:f)
1539   if l:u == ""
1540     return
1541   endif
1542
1543   if ! filereadable(l:u) || ! filewritable(l:u)
1544     return
1545   endif
1546
1547   call delete(l:u)
1548 endfun "}}}2
1549
1550 " Toggle ColorColumn at cursor position.
1551 fun! <SID>Cycle_ColorColumn() "{{{2
1552   if ! has("syntax")
1553     return
1554   endif
1555
1556   let l:cc = &colorcolumn
1557   let l:column = col(".")
1558   let l:re = ",*\\<" . l:column . "\\>"
1559   if l:cc =~# l:re
1560     let l:cc = substitute(l:cc, l:re, "", "g")
1561   else
1562     let l:cc = l:cc . "," . l:column
1563   endif
1564   let &colorcolumn = substitute(l:cc, "^,*", "", "")
1565 endfun "}}}2
1566
1567 if has("syntax")
1568   " Enable showing ColorColumn at cursor position with \CC.
1569   call Mapping("CC", ":call <SID>Cycle_ColorColumn()<CR>:<CR>")
1570   " Remove last shown ColorColumn with \Cc.
1571   call Mapping("Cc", ":let &colorcolumn=substitute(&colorcolumn, \",*[0-9]*$\", \"\", \"\")<CR>:<CR>")
1572   " Remove all ColorColumns with \Cx.
1573   call Mapping("Cx", ":se colorcolumn=<CR>:<CR>")
1574 endif
1575
1576 " Use persistent undo if available.
1577 if has("autocmd")
1578   if has("persistent_undo")
1579     au File BufReadPost * call <SID>Check_Undo()
1580   endif
1581
1582   if has("cursorbind")
1583     au Display WinEnter * if &diff | se cursorbind | endif
1584   endif
1585 endif
1586
1587 " Mapping to reload the gundo window.
1588 if has("autocmd")
1589   au Mode BufEnter * if &ft == "gundo" | try | nnoremap <silent> <buffer> <unique> r :call gundo#GundoToggle()<CR>:call gundo#GundoToggle()<CR> | catch | endtry | endif
1590 endif
1591
1592 endif "}}}1
1593 "
1594 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1595 " Handle options only available in Vim 7.4 and above.
1596 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1597 if version >= "704" "{{{1
1598 version 7.4
1599
1600 if has("syntax")
1601   se cursorline
1602 endif
1603
1604 endif "}}}1
1605
1606 " Resize after startup.
1607 if version >= "500" "{{{1
1608 if has("autocmd")
1609   au Display VimEnter * call Startup_Resize()
1610 endif
1611 endif "}}}1