812f103499a27ec93dcdfd8888f98f9de9434a63
[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 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
17 "{{{1
18 " No compatibility mode.
19 se nocp
20
21 " Find stuff.
22 if has("win32")
23   se rtp=~/.vim,$VIMRUNTIME
24 endif
25
26 " Tabstop 2.
27 se ts=2
28 " And use spaces not tabs.
29 se expandtab
30 " And << and >> indent by 2.
31 se sw=2
32 " Backspace deletes full tab width at the start of a line.
33 se smarttab
34
35 " Allow backspace to delete before start of line.
36 se bs=2
37
38 " Don't jump to the start of the line when using H, L etc.
39 se nosol
40
41 " Show the ruler.
42 se ruler
43 " Show partial commands in the ruler.
44 se showcmd
45 " And always show the status line.
46 se laststatus=2
47
48 " Use C indent style.
49 se cindent
50 se cinkeys=0{,0},0),:,!^F,o,O,e
51 se cinoptions=b1,c2
52
53 " GUI options.
54 se go=aglmr
55
56 " Don't be bugged by messages at the bottom of the screen.
57 se shm=aot
58
59 " Find as you type.
60 se incsearch
61
62 " Case-insensitive search.
63 se ignorecase
64 " But override by typing capitals.
65 se smartcase
66
67 " Look for ctags in home directory first.
68 se tags=~/.tags,./tags,tags
69
70 " Don't timeout waiting to interpet, eg, <ESC>OA as an escape code.
71 se ttimeoutlen=100
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 noremap ' `
80 noremap ` '
81 "}}}1
82
83 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
84 " Handle options only available in Vim 5 and above.
85 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
86 if version >= "500" "{{{1
87 version 5.0
88
89 " Tell Vim we use dark backgrounds in our terminals.
90 if ! has("gui_running")
91   se bg=dark
92 endif
93
94 " Allow mouse use in a terminal but only if it can work.
95 if has("xterm_clipboard")
96   se mouse=nvir
97 endif
98
99 " Update more quickly.  For use with sign highlighting as polling for
100 " CursorMove makes redrawing slow.
101 if has("signs")
102   se updatetime=500
103 endif
104
105 " Enable tab-completion prompting for commands.
106 se wildmenu
107 " Don't list object files when globbing files to load.
108 se wildignore+=*.o,*.obj
109 " So there's no need to assign them low priority.
110 se suffixes-=*.o,*.obj
111
112 " Save sessions in UNIX format with / as file separator.  This is
113 " cross-platform.
114 se ssop+=unix,slash
115
116 " How often do we need to use ^A/^X on octals?
117 se nf=hex
118
119 " Nuke any pre-existing autocommands.
120 augroup Display
121 autocmd!
122 augroup Mode
123 autocmd!
124 if has("signs")
125   augroup Signs
126   autocmd!
127 endif
128 augroup StatusLine
129 autocmd!
130 augroup END
131
132 " Save the current window width so we can restore it when we quit.
133 if ! exists("g:oldcols")
134   let g:oldcols=&columns
135 endif
136
137 " More GUI options.  Add icon and tearoffs.
138 se go+=i
139 se go+=t
140
141 " Allow dynamic window resize even if we aren't in an xterm.
142 se t_WS=\e[8;%p1%d;%p2%dt
143
144 " Highlight search results.
145 se hlsearch
146
147 " Set graphical window title.
148 se titlestring=%{Show_TitleString()}
149
150 " Syntax highlighting.  New versions will use syn enable instead.
151 if version < "600"
152   syn on
153 endif
154
155 " Catch typos.
156 command! W :w
157 command! Wq :wq
158 command! Wqa :wqa
159
160 " Helper to initialise a variable.
161 fun! Prep_Var(var, value) "{{{2
162   if exists(a:var)
163     return
164   endif
165   exe "let " . a:var . "=" . a:value
166 endfun "}}}2
167
168 " Set up our variables.
169 fun! Iain_Vars() "{{{2
170   call Prep_Var("w:iainlist", 0)
171   call Prep_Var("b:iainhex", 0)
172   call Prep_Var("b:iainverbose", 0)
173   " Window Flags: (F)ocused, (I)nsert mode, Cursor (H)old.
174   call Prep_Var("b:iainstatus", "'Fih'")
175   call Prep_Var("g:iainextracolumnsnumber", "''")
176   call Prep_Var("g:iainextracolumnslist", "''")
177   if has("signs")
178     call Prep_Var("g:marksigns", 0)
179     call Prep_Var("g:firstsign", 100)
180   endif
181 endfun "}}}2
182
183 " Helper for status line.
184 " Show space, underscore or dollar sign depending on list mode.
185 fun! Show_List() "{{{2
186   call Iain_Vars()
187   if w:iainlist == 0
188     " No list.
189     return " "
190   elseif <SID>Has_Unicode()
191     if w:iainlist == 1
192       " Just tabs.
193       return "»"
194     else
195       " Full list.
196       return "¶"
197     endif
198   else
199     if w:iainlist == 1
200       return "_"
201     else
202       return "\$"
203     endif
204   endif
205 endfun "}}}2
206
207 " Helper for status line.
208 " Show c or C to denote case-sensitivity.
209 fun! Show_Case() "{{{2
210   if &ic
211     return "c"
212   else
213     return "C"
214   endif
215 endfun "}}}2
216
217 " Helper for status line.
218 " Show the size of the tabstop.
219 fun! Show_Tabstop() "{{{2
220   return &ts
221 endfun "}}}2
222
223 " Helper for status line.
224 " Show p when paste mode is on.
225 fun! Show_Paste() "{{{2
226   if &paste
227     return "p"
228   else
229     return ""
230   endif
231 endfun "}}}2
232
233 " Show the window title.
234 fun! Show_TitleString() "{{{2
235   if bufname("") == ""
236     let l:ts1='Vim'
237   else
238     " Vim 5 doesn't have printf.
239     let l:ts1=bufnr("")
240     if l:ts1 < 10
241       let l:ts1=" " . l:ts1
242     endif
243     let l:ts1=l:ts1 . ": " . expand('%t')
244   endif
245   let l:ts1=l:ts1 . " (" .  getcwd() . ")"
246   if has("clientserver")
247     let l:ts1=l:ts1 . " " . v:servername
248   endif
249   return l:ts1
250 endfun "}}}2
251
252 " Show the status line.
253 fun! Show_StatusLine() "{{{2
254   call Iain_Vars()
255   let l:sl1='%2n\:\ %<%1*%f%0*\ [%{Show_List()}%{Show_Case()}%{Show_Tabstop()}%{Show_Paste()}%Y%M%R]\ '
256   let l:sl3='L:%1*%4.6l%0*/%-4.6L\ C:%1*%3.6c%0*\ \|\ %P'
257   let l:hexformat='%b'
258   if b:iainhex
259     let l:hexformat='0\x%02B'
260   endif
261   if b:iainverbose
262     let l:sl1=l:sl1 . v:version . '\ %='
263     let l:sl2=l:hexformat . '\ \|\ P:%4.6o\ '
264   else
265     let l:sl1=l:sl1 . '%='
266     let l:sl2=''
267   endif
268   exec "set statusline=" . l:sl1 . l:sl2 . l:sl3
269 endfun "}}}2
270
271 " Toggle case-sensitivity.
272 fun! Invert_Case() "{{{2
273   let &ic = ! &ic
274 endfun "}}}2
275
276 " Grow or shrink the window size.
277 fun! Resize_Columns(op, ...) "{{{2
278   if a:op == ""
279     return
280   endif
281
282   if a:0 == 0
283     " Vim 5 hardcodes the size of numbers column to 8.
284     if version >= "700"
285       let l:columns = &numberwidth
286     else
287       let l:columns = 8
288     endif
289   else
290     let l:columns = a:1
291   endif
292
293   exe "let l:resize=" . &columns . a:op . l:columns
294   let l:resize = "se columns=" . l:resize
295
296   " HACK: Inside screen there is an extra line for the status bar.  Vim
297   " manages the resize by sending an escape sequence to set the number of
298   " lines and number of columns in one action.  To do this it will first query
299   " the number of lines and then set <same number of lines> by <new number of
300   " columns>.  Because of the extra line for the status bar this results in
301   " the real terminal being shrunk by a line.  We ask for the terminal to grow
302   " by a line so it ends up actually being the same.
303   if &term =~ '^screen'
304     let l:resize = l:resize . " lines=" . (&lines + 1)
305   endif
306
307   exe l:resize
308 endfun "}}}2
309
310 " Set extra columns depending on window status.
311 fun! Extra_Columns(extra, var, ...) "{{{2
312   " Vim 6 doesn't have winnr("$").  Determine which windows are open
313   " ourselves by using :windo to incremement a counter.  As Vim 5 
314   " doesn't have :windo we require Vim 6 for this.
315   if v:version < "600"
316     return ""
317   endif
318
319   " Remember which window we're in.
320   let l:winnr = winnr()
321   let l:num_windows = 0
322   windo let l:num_windows = l:num_windows + 1
323   " Switch back to the window we were in.
324   exe l:winnr . "wincmd w"
325
326   call Iain_Vars()
327
328   if a:0 == 0
329     let l:condition = ""
330   else
331     let l:condition = a:1
332   endif
333
334   let l:n = 0
335   let l:i = 1
336   let l:windows = ""
337   while l:n < l:num_windows
338     " If window w exists then getwinvar(w, "&modified") will be 0 or 1.
339     if getwinvar(l:i, "&modified") =~ '^\d'
340       let l:n = l:n + 1
341
342     let l:val = 0
343     exe "if getwinvar(" . l:i . ", '" . a:var . "') " . l:condition . " | let l:val = 1 | endif"
344     if l:val
345         exe "let l:windows = '" . l:windows . ":" . l:i . "'"
346       endif
347     endif
348     let l:i = l:i + 1
349   endwhile
350
351   let l:extra = "g:iainextracolumns" . a:extra
352   exe "let l:val = " . l:extra
353   exe "let " . l:extra . " = '" . l:windows . "'"
354
355   if l:windows == l:val
356     return ""
357   endif
358
359   if l:windows == ""
360     return "-"
361   elseif l:val == ""
362     return "+"
363   endif
364 endfun "}}}2
365
366 " Toggle number display.
367 fun! Number(resize) "{{{2
368   call Iain_Vars()
369   let &number = ! &number
370
371   " Ensure we keep track of any extra columns even if we aren't resizing.
372   " This prevents confusion when number is set at startup.
373   let l:extra = Extra_Columns("number", "&number")
374
375   if a:resize
376     call Resize_Columns(l:extra)
377   endif
378 endfun "}}}2
379
380 " Restore window size.
381 au Display VimLeave * if exists("g:oldcols") | call Resize_Columns("-", (&columns - g:oldcols)) | endif
382
383 " Map Makefile mode.
384 au Mode BufEnter * if &ft == "make" | call MakeMode_map() | endif
385 au Mode BufLeave * if &ft == "make" | call MakeMode_unmap() | endif
386
387 " Entering Make mode.
388 fun! MakeMode_map() "{{{2
389   call Iain_Vars()
390   let w:iainlist=1
391   call Cycle_List()
392   set ts=8
393   set noexpandtab
394 endfun "}}}2
395
396 " Leaving Make mode.
397 fun! MakeMode_unmap() "{{{2
398   call Cycle_List()
399   set ts=2
400   set expandtab
401 endfun "}}}2
402
403 " Show the status line for the first time.
404 call Show_StatusLine()
405
406 " Function to create mappings with either a hardcoded \ or <Leader>.
407 fun! Mapping(keysequence,mapping) "{{{2
408   if version < "600"
409     exec "map \\" . a:keysequence . " " . a:mapping
410   else
411     exec "map <Leader>" . a:keysequence . " " . a:mapping
412   endif
413 endfun "}}}2
414
415 " Use - and = to create underlines.
416 call Mapping("-", "yyp:s/./-/g<RETURN>:let @/=''<RETURN>:<RETURN>")
417 call Mapping("=", "yyp:s/./=/g<RETURN>:let @/=''<RETURN>:<RETURN>")
418
419 " Change to ts=2 with \2.
420 call Mapping("2", ":se ts=2<CR>:<CR>")
421 " Change to ts=4 with \4.
422 call Mapping("4", ":se ts=4<CR>:<CR>")
423 " Change to ts=8 with \8.
424 call Mapping("8", ":se ts=8<CR>:<CR>")
425 " Change to ts=16 with \6.
426 call Mapping("6", ":se ts=16<CR>:<CR>")
427 " Change to ts=32 with \3.
428 call Mapping("3", ":se ts=32<CR>:<CR>")
429 " Toggle paste mode with \p.
430 call Mapping("p", ":se paste!<CR>:<CR>")
431 " Swap case-sensitivity with \c.
432 call Mapping("C", ":call Invert_Case()<CR>:<CR>")
433 " Change number mode with \n.
434 call Mapping("n", ":call Number(1)<CR>:<CR>")
435 " Expand or shrink window size with \> and \<.
436 call Mapping(">", ":call Resize_Columns('+')<CR>:<CR>")
437 call Mapping("<", ":call Resize_Columns('-')<CR>:<CR>")
438 " Clear search pattern with \/.
439 call Mapping("/", ":let @/=\"\"<CR>:<CR>")
440
441 " Forget the Ex mode mapping.
442 map Q <NOP>
443
444 " Vim tip 99: What's the highlighting group under the cursor?
445 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>")
446
447 fun! Uncluttered_Buffer() "{{{2
448   if exists("uncluttered_buffer")
449     if uncluttered_buffer == 1
450       return 1
451     endif
452   endif
453
454   if version >= "600"
455     if &buftype != ''
456       return 1
457     endif
458   endif
459
460   if &ft == 'perforce'
461     return 1
462   endif
463
464   if &ft == 'svn'
465     return 1
466   endif
467
468   if &ft == 'gitcommit'
469     return 1
470   endif
471
472   return 0
473 endfun "}}}2
474
475 fun! Startup_Resize() "{{{2
476   let l:columns = 0
477
478   " Resize for numbers.
479   if &number
480     if version >= "700"
481       let l:columns = &numberwidth
482     else
483       let l:columns = 8
484     endif
485   endif
486
487   " Resize for signs.
488   if has("signs")
489     if g:marksigns
490       if version >= "600"
491         let l:columns = l:columns + 2
492       endif
493     endif
494   endif
495
496   if g:oldcols < (80 + l:columns)
497     call Resize_Columns("+", l:columns)
498   endif
499 endfun "}}}2
500
501 " Change status bar colour when various things happen.
502 " Flags: H/h: Cursor held/moved.
503 "        F/f: Focus gained/lost.
504 "        I/i: Insert mode entered/left.
505 fun! Highlight_StatusLine(flag) "{{{2
506   " Get current status.
507   call Iain_Vars()
508
509   " Change the status based on the flag.  XXX: Does Vim let us to do flags?
510   let l:ic = &ic
511   set ic
512   let b:iainstatus = substitute(b:iainstatus, a:flag, a:flag, "")
513   let &ic = l:ic
514
515   let l:normalcolour = "darkblue"
516   let l:editingcolour = "darkmagenta"
517   let l:warningcolour = "darkred"
518   let l:readonlycolour = "red"
519
520   " Default colour.
521   let l:colour = l:normalcolour
522   " Maybe override depending on status.
523   if b:iainstatus =~# "H"
524     if b:iainstatus =~# "I"
525       " Held in insert mode.  Add extra highlight if we don't have focus.
526       if b:iainstatus =~# "f"
527         let l:colour = l:warningcolour
528       else
529         let l:colour = l:editingcolour
530       endif
531     endif
532   else
533     if b:iainstatus =~# "I"
534       " Regular insert mode.
535       let l:colour = l:editingcolour
536     endif
537   endif
538
539   " Override again if readonly.
540   if l:colour != l:normalcolour
541     if getbufvar("", "&ro")
542       let l:colour = l:readonlycolour
543     endif
544   endif
545
546   let l:termcolour = Iain_Colour(l:colour)
547
548   exec "highlight StatusLine gui=none term=none cterm=none guifg=white guibg=" . l:colour . " ctermfg=white ctermbg=" . l:termcolour
549   exec "highlight User1 gui=bold term=bold cterm=bold guifg=white guibg=" . l:colour . " ctermfg=white ctermbg=" . l:termcolour
550 endfun "}}}2
551
552 fun! Iain_Colour(colour) "{{{2
553   if &t_Co == 88
554     if a:colour == "darkblue"
555       return 17
556     elseif a:colour == "darkmagenta"
557       return 33
558     elseif a:colour == "darkred"
559       return 32
560     elseif a:colour == "red"
561       return 64
562     endif
563   elseif &t_Co == 256
564     if a:colour == "darkblue"
565       return 17
566     elseif a:colour == "darkmagenta"
567       return 90
568     elseif a:colour == "darkred"
569       return 88
570     elseif a:colour == "red"
571       return 196
572     endif
573   else
574     return a:colour
575   endif
576 endfun "}}}2
577
578 au StatusLine VimEnter * call Highlight_StatusLine("")
579
580 " Show numbers by default.
581 au Display VimEnter * if ! Uncluttered_Buffer() | call Number(0) | endif
582
583 " Position the compview plugin window.
584 au Display BufEnter -SearchResults- set buftype=nowrite | set nonumber | wincmd J
585 endif "}}}1
586
587 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
588 " Handle options only available in Vim 6 and above.
589 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
590 if version >= "600" "{{{1
591 version 6.0
592
593 if has("win32")
594   se encoding=utf-8
595 endif
596
597 " Remember quickfix state.
598 let g:quickfixing=0
599
600 " Set indenting by filetype.
601 filetype indent on
602
603 " Less intrusive syntax highlighting.
604 syn enable
605
606 " Set colours.
607 if has("gui_running")
608   try
609     if has("win32")
610       se guifont=DejaVu_Sans_Mono:h10:cANSI
611     else
612       se guifont=DejaVu\ Sans\ Mono\ 10
613     endif
614   catch
615   endtry
616 endif
617 if has("gui_running") || &t_Co > 16
618   try
619     colo iain
620   catch
621   endtry
622 endif
623
624 " Ignore whitespace when diffing.
625 se diffopt=filler,iwhite
626
627 " Expand window when doing a vertical diff.
628 if &diff
629   if &columns < 161
630     let &columns = &columns * 2
631   endif
632 endif
633
634 " Remember that we are opening the quickfix window.
635 au Mode BufWinEnter quickfix let g:quickfixing=1
636 au Mode BufUnload * if &ft == "qf" | let g:quickfixing=0 | endif
637
638 " Allow in-place editing of crontabs.
639 au Mode FileType crontab set backupcopy=yes
640
641 " Make * and # work the way you expect in visual mode.
642 vnoremap * y/\V<C-R>=substitute(escape(@@,"/\\"),"\n","\\\\n","ge")<CR><CR>
643 vnoremap # y?\V<C-R>=substitute(escape(@@,"?\\"),"\n","\\\\n","ge")<CR><CR>
644
645 " Set mark and update highlighting.
646 if has("signs")
647   au Signs BufReadPost * call <SID>Highlight_Signs()
648   au Signs CursorHold * call <SID>Highlight_Signs()
649 endif
650
651 " Helper to set buffer variable for a given sign.
652 fun! <SID>Prep_Sign(sign) "{{{2
653   if ! exists("b:sign" . a:sign) || ! g:marksigns
654     exe "let b:sign" . a:sign . "=0"
655    endif
656 endfun "}}}2
657
658 fun! <SID>Prep_Signs() "{{{2
659   call <SID>Prep_Sign("dot")
660   call <SID>Prep_Sign("dash")
661   call <SID>Prep_Sign("quote")
662   call <SID>Prep_Sign("caret")
663   call <SID>Prep_Sign("less")
664   call <SID>Prep_Sign("greater")
665   call <SID>Prep_Sign("left")
666   call <SID>Prep_Sign("right")
667   call <SID>Prep_Sign("squareleft")
668   call <SID>Prep_Sign("squareright")
669   call <SID>Prep_Sign("braceleft")
670   call <SID>Prep_Sign("braceright")
671   call <SID>Prep_Sign("a")
672   call <SID>Prep_Sign("b")
673   call <SID>Prep_Sign("c")
674   call <SID>Prep_Sign("d")
675   call <SID>Prep_Sign("e")
676   call <SID>Prep_Sign("f")
677   call <SID>Prep_Sign("A")
678   call <SID>Prep_Sign("B")
679   call <SID>Prep_Sign("C")
680   call <SID>Prep_Sign("D")
681   call <SID>Prep_Sign("E")
682   call <SID>Prep_Sign("F")
683 endfun! "}}}2
684
685 fun! <SID>Place_Sign(number, line, old, name) "{{{2
686   if a:line == a:old
687     return a:old
688   endif
689
690   exe "sign unplace " . (g:firstsign + a:number) . " buffer=" . bufnr("")
691   " Don't place the sign if it would conflict with the last change sign.
692   exe "sign place " . (g:firstsign + a:number) . " line=" . a:line . " name=" . a:name . " buffer=" . bufnr("")
693   return a:line
694 endfun "}}}2
695
696 fun! <SID>Highlight_Signs(...) "{{{2
697   if ! has("signs") || ! g:marksigns || Uncluttered_Buffer()
698     return
699   endif
700
701   call <SID>Prep_Signs()
702
703   let b:signdot = <SID>Place_Sign(0, line("'."), b:signdot, "MarkDot")
704   let b:signdash = <SID>Place_Sign(1, line("''"), b:signdash, "MarkDash")
705   let b:signquote = <SID>Place_Sign(2, line("'\""), b:signquote, "MarkQuote")
706   let b:signcaret = <SID>Place_Sign(3, line("'^"), b:signcaret, "MarkCaret")
707   let b:signless = <SID>Place_Sign(4, line("'<"), b:signless, "MarkLess")
708   let b:signgreater = <SID>Place_Sign(5, line("'>"), b:signgreater, "MarkGreater")
709   let b:signleft = <SID>Place_Sign(6, line("'("), b:signleft, "MarkLeft")
710   let b:signright = <SID>Place_Sign(7, line("')"), b:signright, "MarkRight")
711   let b:signsquareleft = <SID>Place_Sign(8, line("'["), b:signsquareleft, "MarkSquareLeft")
712   let b:signsquareright = <SID>Place_Sign(9, line("']"), b:signsquareright, "MarkSquareRight")
713   let b:signbraceleft = <SID>Place_Sign(10, line("'{"), b:signbraceleft, "MarkBraceLeft")
714   let b:signbraceright = <SID>Place_Sign(11, line("'}"), b:signbraceright, "MarkBraceRight")
715
716   let b:signa = <SID>Place_Sign(12, line("'a"), b:signa, "Marka")
717   let b:signb = <SID>Place_Sign(13, line("'b"), b:signb, "Markb")
718   let b:signc = <SID>Place_Sign(15, line("'c"), b:signc, "Markc")
719   let b:signd = <SID>Place_Sign(16, line("'d"), b:signd, "Markd")
720   let b:signe = <SID>Place_Sign(17, line("'e"), b:signe, "Marke")
721   let b:signf = <SID>Place_Sign(18, line("'f"), b:signf, "Markf")
722   let b:signA = <SID>Place_Sign(19, line("'A"), b:signA, "MarkA")
723   let b:signB = <SID>Place_Sign(20, line("'B"), b:signB, "MarkB")
724   let b:signC = <SID>Place_Sign(21, line("'C"), b:signC, "MarkC")
725   let b:signD = <SID>Place_Sign(22, line("'D"), b:signD, "MarkD")
726   let b:signE = <SID>Place_Sign(23, line("'E"), b:signE, "MarkE")
727   let b:signF = <SID>Place_Sign(24, line("'F"), b:signF, "MarkF")
728 endfun "}}}2
729
730 " Toggle signs.
731 fun! <SID>Cycle_Signs(resize) "{{{2
732   if ! has("signs")
733     return
734   endif
735   call Iain_Vars()
736   let g:marksigns = ! g:marksigns
737
738   if g:marksigns
739     " Signs to highlight marks.
740     " Syntax won't work properly in Vim 6.
741     if <SID>Has_Unicode()
742       sign define MarkDash text=’ texthl=MarkSign
743       sign define MarkDot text=• texthl=MarkDot
744       sign define MarkQuote text=” texthl=MarkSign
745       sign define MarkCaret text=ʌ texthl=MarkDot
746     else
747       sign define MarkDash text=' texthl=MarkSign
748       sign define MarkDot text=* texthl=MarkDot
749       sign define MarkQuote text=" texthl=MarkSign
750       sign define MarkCaret text=^ texthl=MarkDot
751     endif
752     sign define MarkLess text=< texthl=MarkSign
753     sign define MarkGreater text=> texthl=MarkSign
754     sign define MarkLeft text=( texthl=MarkSign
755     sign define MarkRight text=) texthl=MarkSign
756     sign define MarkSquareLeft text=[ texthl=MarkSign
757     sign define MarkSquareRight text=] texthl=MarkSign
758     sign define MarkBraceLeft text={ texthl=MarkSign
759     sign define MarkBraceRight text=} texthl=MarkSign
760     sign define Marka text=a texthl=MarkSign linehl=MarkLine
761     sign define Markb text=b texthl=MarkSign linehl=MarkLine
762     sign define Markc text=c texthl=MarkSign linehl=MarkLine
763     sign define Markd text=d texthl=MarkSign linehl=MarkLine
764     sign define Marke text=e texthl=MarkSign linehl=MarkLine
765     sign define Markf text=f texthl=MarkSign linehl=MarkLine
766     sign define MarkA text=A texthl=MarkSign linehl=MarkLine
767     sign define MarkB text=B texthl=MarkSign linehl=MarkLine
768     sign define MarkC text=C texthl=MarkSign linehl=MarkLine
769     sign define MarkD text=D texthl=MarkSign linehl=MarkLine
770     sign define MarkE text=E texthl=MarkSign linehl=MarkLine
771     sign define MarkF text=F texthl=MarkSign linehl=MarkLine
772
773     if a:resize
774       call Resize_Columns("+", 2)
775     endif
776     call <SID>Highlight_Signs()
777   else
778     exe "sign unplace " . (g:firstsign + 0)
779     exe "sign unplace " . (g:firstsign + 1)
780     exe "sign unplace " . (g:firstsign + 2)
781     exe "sign unplace " . (g:firstsign + 3)
782     exe "sign unplace " . (g:firstsign + 4)
783     exe "sign unplace " . (g:firstsign + 5)
784     exe "sign unplace " . (g:firstsign + 6)
785     exe "sign unplace " . (g:firstsign + 7)
786     exe "sign unplace " . (g:firstsign + 8)
787     exe "sign unplace " . (g:firstsign + 9)
788     exe "sign unplace " . (g:firstsign + 10)
789     exe "sign unplace " . (g:firstsign + 11)
790     exe "sign unplace " . (g:firstsign + 12)
791     exe "sign unplace " . (g:firstsign + 13)
792     exe "sign unplace " . (g:firstsign + 14)
793     exe "sign unplace " . (g:firstsign + 15)
794     exe "sign unplace " . (g:firstsign + 16)
795     exe "sign unplace " . (g:firstsign + 17)
796     exe "sign unplace " . (g:firstsign + 18)
797     exe "sign unplace " . (g:firstsign + 19)
798     exe "sign unplace " . (g:firstsign + 20)
799     exe "sign unplace " . (g:firstsign + 21)
800     exe "sign unplace " . (g:firstsign + 22)
801     exe "sign unplace " . (g:firstsign + 23)
802     exe "sign unplace " . (g:firstsign + 24)
803
804     sign undefine MarkDash
805     sign undefine MarkDot
806     sign undefine MarkQuote
807     sign undefine MarkCaret
808     sign undefine MarkLess
809     sign undefine MarkGreater
810     sign undefine MarkLeft
811     sign undefine MarkRight
812     sign undefine MarkSquareLeft
813     sign undefine MarkSquareRight
814     sign undefine MarkBraceLeft
815     sign undefine MarkBraceRight
816     sign undefine Marka
817     sign undefine Markb
818     sign undefine Markc
819     sign undefine Markd
820     sign undefine Marke
821     sign undefine Markf
822     sign undefine MarkA
823     sign undefine MarkB
824     sign undefine MarkC
825     sign undefine MarkD
826     sign undefine MarkE
827     sign undefine MarkF
828
829     call <SID>Prep_Signs()
830     if a:resize
831       call Resize_Columns("-", 2)
832     endif
833   endif
834 endfun "}}}2
835
836 " Do we have Unicode?
837 fun! <SID>Has_Unicode() "{{{2
838   if ! has('multi_byte')
839     return 0
840   endif
841
842   if version < "602"
843     return 0
844   endif
845
846   if &tenc =~? '^u\(tf\|cs\)'
847     return 1
848   endif
849
850   if ! strlen(&tenc) && &enc =~? '^u\(tf\|cs\)'
851     return 1
852   endif
853
854   return 0
855 endfun "}}}2
856
857 " Change list mode.
858 fun! Cycle_List() "{{{2
859   " Pretty UTF-8 listchars.
860   if <SID>Has_Unicode()
861     let basic='tab:»·,trail:…,extends:«,precedes:»'
862     let eol='eol:¶'
863     if version >= "700"
864       let basic=basic . ',nbsp:•'
865     endif
866   else
867     let basic='tab:\\_,trail:_,extends:<,precedes:>'
868     let eol='eol:$'
869     if version >= "700"
870       let basic=basic . ',nbsp:+'
871     endif
872   endif
873   call Iain_Vars()
874   let w:iainlist = w:iainlist + 1
875   if w:iainlist > 2
876     let w:iainlist = 0
877   endif
878   if w:iainlist == 0
879     setlocal nolist
880   elseif w:iainlist == 1
881     exec "setlocal lcs=" . basic
882     setlocal list
883   else
884     exec "setlocal lcs=" . basic . "," . eol
885     setlocal list
886   endif
887
888   call Resize_Columns(Extra_Columns("list", "iainlist", " == 2"), 1)
889 endfun "}}}2
890
891 " Cycle between hex and decimal display of toolbar stuff.
892 fun! Cycle_HexStatusLine() "{{{2
893   call Iain_Vars()
894   let b:iainhex = ! b:iainhex
895   call Show_StatusLine()
896 endfun "}}}2
897
898 " Cycle verbose display of toolbar stuff.
899 fun! Cycle_VerboseStatusLine() "{{{2
900   call Iain_Vars()
901   let b:iainverbose = ! b:iainverbose
902   call Show_StatusLine()
903 endfun "}}}2
904
905 " Toggle quickfix window.
906 fun! Cycle_Quickfix() "{{{2
907   if g:quickfixing == 1
908     cclose
909     let g:quickfixing=0
910   else
911     copen
912   endif
913 endfun "}}}2
914
915 " Swap hex/decimal statusline with \x.
916 call Mapping("x", ":call Cycle_HexStatusLine()<CR>:<CR>")
917 " Change statusline verbosity with \v.
918 call Mapping("V", ":call Cycle_VerboseStatusLine()<CR>:<CR>")
919 " Cycle list styles with \l.
920 call Mapping("l", ":call Cycle_List()<CR>:<CR>")
921 " Toggle tags with \t.
922 call Mapping("t", ":Tlist<CR>")
923 " Change foldmethod with \f.
924 call Mapping("f", ":se foldenable!<CR>:<CR>")
925 " Toggle quickfix window with \q.
926 call Mapping("q", ":call Cycle_Quickfix()<CR>:<CR>")
927 " Rerun filetype detection with \s.  The s is for syntax, as this will be
928 " updated as a side-effect.
929 call Mapping("S", ":filetype detect<CR>:<CR>")
930 " Toggle marks with \m.
931 call Mapping("m", ":call <SID>Cycle_Signs(1)<CR>:<CR>")
932
933 " Show signs by default.
934 au Display VimEnter * call <SID>Cycle_Signs(0)
935 endif "}}}1
936
937 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
938 " Handle options only available in Vim 7 and above.
939 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
940 if version >= "700" "{{{1
941 version 7.0
942
943 " Helper to show tab name.
944 fun! <SID>TabName(label, gui) "{{{2
945   let l:label = a:label
946   if l:label == ""
947     let l:label = "No Name"
948     if a:gui
949       let l:label = "[" . l:label . "]"
950     endif
951   else
952     let l:label = fnamemodify(l:label, ":t")
953     if strlen(l:label) >= 18
954       let l:label = l:label[0:17] . ".."
955     endif
956   endif
957   return l:label
958 endfun "}}}2
959
960 " Find out if any buffer was modified.
961 fun! <SID>TabModified(buflist) "{{{2
962   let l:i = 0
963   while l:i < len(a:buflist)
964     if getbufvar(a:buflist[l:i], "&modified") == 1
965       return "+"
966     endif
967     let l:i = l:i + 1
968   endwhile
969   return ""
970 endfun "}}}2
971
972 " Tab line.
973 fun! Show_TabLine() "{{{2
974   let l:s = "%#TabLineFill#Tabs:"
975
976   let l:i = 0
977   while l:i < tabpagenr("$")
978     let l:i = l:i + 1
979     " Get the label.
980     let l:buflist = tabpagebuflist(l:i)
981     let l:winnr = tabpagewinnr(l:i)
982     let l:n = tabpagewinnr(l:i, "$")
983     let l:label = <SID>TabName(bufname(l:buflist[l:winnr - 1]), 0)
984     let l:modified = <SID>TabModified(l:buflist)
985
986     " Choose highlighting.
987     if l:i == tabpagenr()
988       let l:s .= "%#TabLineSel#[" . l:n . l:modified . " " . l:label . "]"
989     else
990       let l:s .= "%#TabLine# " . l:n . l:modified . " " . l:label . " "
991     endif
992   endwhile
993
994   " Padding.
995   let l:s .= "%#TabLine#%T"
996   return l:s
997 endfun "}}}2
998
999 " Per tab label for the GUI.
1000 fun! Show_GUITabLine() "{{{2
1001   let l:buflist = tabpagebuflist(v:lnum)
1002   let l:winnr = tabpagewinnr(v:lnum)
1003   let l:s = tabpagewinnr(v:lnum, "$")
1004   let l:label = <SID>TabName(bufname(l:buflist[l:winnr - 1]), 1)
1005   let l:modified = <SID>TabModified(l:buflist)
1006
1007   let l:s .= l:modified . " " . l:label
1008   return l:s
1009 endfun "}}}2
1010
1011 se tabline=%!Show_TabLine()
1012 se guitablabel=%!Show_GUITabLine()
1013
1014 au StatusLine CursorHoldI * call Highlight_StatusLine("H")
1015 au StatusLine CursorMovedI * call Highlight_StatusLine("h")
1016 au StatusLine FocusGained * call Highlight_StatusLine("F")
1017 au StatusLine FocusLost * call Highlight_StatusLine("f")
1018 au StatusLine InsertEnter * call Highlight_StatusLine("I")
1019 au StatusLine InsertLeave * call Highlight_StatusLine("i")
1020
1021 if has("signs")
1022   au Signs InsertEnter * call <SID>Highlight_Signs()
1023   au Signs InsertLeave * call <SID>Highlight_Signs()
1024 endif
1025
1026 " Limit the size of the popup menu when completing.
1027 se pumheight=20
1028
1029 " Make diffs vertical by default.
1030 se diffopt+=vertical
1031
1032 " Set size of numbers column.
1033 se numberwidth=5
1034
1035 " Add "previous tab" mapping as gb.
1036 map gb :tabprevious<CR>:<CR>
1037
1038 " Transparency.
1039 if has("gui_macvim")
1040   se transparency=15
1041 endif 
1042
1043 " Yet more GUI options.  Add tabs.
1044 se go+=e
1045
1046 " Perforce.
1047 let g:p4EnableMenu=1
1048 let g:p4Presets='P4CONFIG'
1049 endif "}}}1
1050
1051 " Resize after startup.
1052 if version >= "500" "{{{1
1053 au Display VimEnter * call Startup_Resize()
1054 endif "}}}1