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