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