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