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