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