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