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