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