Don't bother resizing a GUI window before exit.
[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 if ! has("gui_running")
415   au Display VimLeave * if exists("g:oldcols") | call Resize_Columns("-", (&columns - g:oldcols)) | endif
416 endif
417
418 " Map Makefile mode.
419 au Mode BufEnter * if &ft == "make" | call MakeMode_map() | endif
420 au Mode BufLeave * if &ft == "make" | call MakeMode_unmap() | endif
421
422 " Entering Make mode.
423 fun! MakeMode_map() "{{{2
424   call Iain_Vars()
425   let w:iainlist=1
426   call Cycle_List()
427   set ts=8
428   set noexpandtab
429 endfun "}}}2
430
431 " Leaving Make mode.
432 fun! MakeMode_unmap() "{{{2
433   call Cycle_List()
434   set ts=2
435   set expandtab
436 endfun "}}}2
437
438 " Show the status line for the first time.
439 call Show_StatusLine()
440
441 " Function to create mappings with either a hardcoded \ or <Leader>.
442 fun! Mapping(keysequence,mapping) "{{{2
443   if version < "600"
444     exec "map \\" . a:keysequence . " " . a:mapping
445   else
446     exec "map <Leader>" . a:keysequence . " " . a:mapping
447   endif
448 endfun "}}}2
449
450 " Use - and = to create underlines.
451 call Mapping("-", "yyp:s/./-/g<RETURN>:let @/=''<RETURN>:<RETURN>")
452 call Mapping("=", "yyp:s/./=/g<RETURN>:let @/=''<RETURN>:<RETURN>")
453
454 " Change to ts=2 with \2.
455 call Mapping("2", ":se ts=2<CR>:<CR>")
456 " Change to ts=4 with \4.
457 call Mapping("4", ":se ts=4<CR>:<CR>")
458 " Change to ts=8 with \8.
459 call Mapping("8", ":se ts=8<CR>:<CR>")
460 " Change to ts=16 with \6.
461 call Mapping("6", ":se ts=16<CR>:<CR>")
462 " Change to ts=32 with \3.
463 call Mapping("3", ":se ts=32<CR>:<CR>")
464 " Toggle paste mode with \p.
465 call Mapping("p", ":se paste!<CR>:<CR>")
466 " Swap case-sensitivity with \c.
467 call Mapping("C", ":call Invert_Case()<CR>:<CR>")
468 " Change number mode with \n.
469 call Mapping("n", ":call Number(1)<CR>:<CR>")
470 " Expand or shrink window size with \> and \<.
471 call Mapping(">", ":call Resize_Columns('+')<CR>:<CR>")
472 call Mapping("<", ":call Resize_Columns('-')<CR>:<CR>")
473 " Clear search pattern with \/.
474 call Mapping("/", ":let @/=\"\"<CR>:<CR>")
475
476 " Forget the Ex mode mapping.
477 map Q <NOP>
478
479 " Vim tip 99: What's the highlighting group under the cursor?
480 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>")
481
482 fun! Uncluttered_Buffer() "{{{2
483   if exists("uncluttered_buffer")
484     if uncluttered_buffer == 1
485       return 1
486     endif
487   endif
488
489   if version >= "600"
490     if &buftype != ''
491       return 1
492     endif
493   endif
494
495   if &ft == 'perforce'
496     return 1
497   endif
498
499   if &ft == 'svn'
500     return 1
501   endif
502
503   if &ft == 'gitcommit'
504     return 1
505   endif
506
507   return 0
508 endfun "}}}2
509
510 fun! Startup_Resize() "{{{2
511   let l:columns = 0
512
513   " Resize for numbers.
514   if &number
515     if version >= "700"
516       let l:columns = &numberwidth
517     else
518       let l:columns = 8
519     endif
520   endif
521
522   " Resize for signs.
523   if has("signs")
524     if g:marksigns
525       if version >= "600"
526         let l:columns = l:columns + 2
527       endif
528     endif
529   endif
530
531   if g:oldcols < (80 + l:columns)
532     call Resize_Columns("+", l:columns)
533   endif
534 endfun "}}}2
535
536 " Change status bar colour when various things happen.
537 " Flags: H/h: Cursor held/moved.
538 "        F/f: Focus gained/lost.
539 "        I/i: Insert mode entered/left.
540 fun! Highlight_StatusLine(flag) "{{{2
541   " Get current status.
542   call Iain_Vars()
543
544   " Change the status based on the flag.  XXX: Does Vim let us to do flags?
545   let l:ic = &ic
546   set ic
547   let b:iainstatus = substitute(b:iainstatus, a:flag, a:flag, "")
548   let &ic = l:ic
549
550   let l:normalcolour = "darkblue"
551   let l:editingcolour = "darkmagenta"
552   let l:warningcolour = "darkred"
553   let l:readonlycolour = "red"
554
555   " Default colour.
556   let l:colour = l:normalcolour
557   " Maybe override depending on status.
558   if b:iainstatus =~# "H"
559     if b:iainstatus =~# "I"
560       " Held in insert mode.  Add extra highlight if we don't have focus.
561       if b:iainstatus =~# "f"
562         let l:colour = l:warningcolour
563       else
564         let l:colour = l:editingcolour
565       endif
566     endif
567   else
568     if b:iainstatus =~# "I"
569       " Regular insert mode.
570       let l:colour = l:editingcolour
571     endif
572   endif
573
574   " Override again if readonly.
575   if l:colour != l:normalcolour
576     if getbufvar("", "&ro")
577       let l:colour = l:readonlycolour
578     endif
579   endif
580
581   let l:termcolour = Iain_Colour(l:colour)
582
583   exec "highlight StatusLine gui=none term=none cterm=none guifg=white guibg=" . l:colour . " ctermfg=white ctermbg=" . l:termcolour
584   exec "highlight User1 gui=bold term=bold cterm=bold guifg=white guibg=" . l:colour . " ctermfg=white ctermbg=" . l:termcolour
585 endfun "}}}2
586
587 fun! Iain_Colour(colour) "{{{2
588   if &t_Co == 88
589     if a:colour == "darkblue"
590       return 17
591     elseif a:colour == "darkmagenta"
592       return 33
593     elseif a:colour == "darkred"
594       return 32
595     elseif a:colour == "red"
596       return 64
597     endif
598   elseif &t_Co == 256
599     if a:colour == "darkblue"
600       return 17
601     elseif a:colour == "darkmagenta"
602       return 90
603     elseif a:colour == "darkred"
604       return 88
605     elseif a:colour == "red"
606       return 196
607     endif
608   else
609     return a:colour
610   endif
611 endfun "}}}2
612
613 au StatusLine VimEnter * call Highlight_StatusLine("")
614
615 " Show numbers by default.
616 au Display VimEnter * if ! Uncluttered_Buffer() | call Number(0) | endif
617
618 " Position the compview plugin window.
619 au Display BufEnter -SearchResults- set buftype=nowrite | set nonumber | wincmd J
620 endif "}}}1
621
622 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
623 " Handle options only available in Vim 6 and above.
624 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
625 if version >= "600" "{{{1
626 version 6.0
627
628 if has("gui_win32")
629   se encoding=utf-8
630 endif
631
632 " Remember quickfix state.
633 let g:quickfixing=0
634
635 " Set indenting by filetype.
636 filetype indent on
637
638 " Less intrusive syntax highlighting.
639 syn enable
640
641 " Set colours.
642 if has("gui_running")
643   if has("win32") || has("win64")
644     exe "silent se guifont=DejaVu_Sans_Mono:h10:cANSI"
645   else
646     exe "silent se guifont=DejaVu\\ Sans\\ Mono\\ 10"
647   endif
648 endif
649 if has("gui_running") || &t_Co > 16
650   exe "silent colo iain"
651 endif
652
653 " Ignore whitespace when diffing.
654 se diffopt=filler,iwhite
655
656 " Expand window when doing a vertical diff.
657 if &diff
658   if &columns < 161
659     let &columns = &columns * 2
660   endif
661 endif
662
663 " Remember that we are opening the quickfix window.
664 au Mode BufWinEnter quickfix let g:quickfixing=1
665 au Mode BufUnload * if &ft == "qf" | let g:quickfixing=0 | endif
666
667 " Allow in-place editing of crontabs.
668 au Mode FileType crontab set backupcopy=yes
669
670 " Make * and # work the way you expect in visual mode.
671 vnoremap * y/\V<C-R>=substitute(escape(@@,"/\\"),"\n","\\\\n","ge")<CR><CR>
672 vnoremap # y?\V<C-R>=substitute(escape(@@,"?\\"),"\n","\\\\n","ge")<CR><CR>
673
674 " Set mark and update highlighting.
675 if has("signs")
676   au Signs BufReadPost * call <SID>Highlight_Signs()
677   au Signs CursorHold * call <SID>Highlight_Signs()
678 endif
679
680 " Helper to set buffer variable for a given sign.
681 fun! <SID>Prep_Sign(sign) "{{{2
682   if ! exists("b:sign" . a:sign) || ! g:marksigns
683     exe "let b:sign" . a:sign . "=0"
684    endif
685 endfun "}}}2
686
687 fun! <SID>Place_Sign(number, line, old, name) "{{{2
688   if a:line == a:old
689     return a:old
690   endif
691
692   exe "sign unplace " . (g:firstsign + a:number) . " buffer=" . bufnr("")
693   " Don't place the sign if it would conflict with the last change sign.
694   exe "sign place " . (g:firstsign + a:number) . " line=" . a:line . " name=" . a:name . " buffer=" . bufnr("")
695   return a:line
696 endfun "}}}2
697
698 fun! <SID>Highlight_Signs(...) "{{{2
699   if ! has("signs") || ! g:marksigns || Uncluttered_Buffer()
700     return
701   endif
702
703   let l:signs = g:iainsigns
704   let l:sign = ""
705   let l:i = 0
706   while strlen(l:signs)
707     let l:sign = matchstr(l:signs, '^[A-Za-z]\+\(:.\)*[.=-][^ ]\+')
708
709     let l:name = substitute(l:sign, '[:.=-].*', "", "")
710     let l:var = tolower(l:name)
711     let l:sign = substitute(l:sign, '^[A-Za-z]\+', "", "")
712     let l:ascii = matchstr(l:sign, '^:.')
713     let l:mark = substitute(l:sign, '^\(:.\)*[.-=]', "", "")
714     if strlen(l:ascii)
715       let l:ascii = substitute(l:ascii, '^:', "", "")
716     else
717       let l:ascii = l:mark
718     endif
719     let l:ascii = substitute(l:ascii, '"', '\\"', "")
720
721     call <SID>Prep_Sign(l:var)
722     exe "let " . l:var . " = <SID>Place_Sign(" . l:i . ", line(\"'" . l:ascii . "\"), b:sign" . l:var . ", \"Mark" . l:name . "\")"
723     let l:i = l:i + 1
724
725     let l:signs = substitute(l:signs, '^[^ ]\+ *', "", "")
726   endwhile
727 endfun "}}}2
728
729 " Toggle signs.
730 fun! <SID>Cycle_Signs(resize) "{{{2
731   if ! has("signs")
732     return
733   endif
734   call Iain_Vars()
735   let g:marksigns = ! g:marksigns
736
737   " Retrofit arrays on to Vim 6.
738   if ! exists("g:iainsigns")
739     " Signs are defined in g:iainsigns.  The syntax is as follows:
740     "
741     " Sign ::= Name (':' Mark)* Type Symbol
742     " Type ::= '=' | '-' | '.'
743     "
744     " Signs with Type '=' will be highlighted with the MarkSign group.
745     " Signs with Type '-' will be highlighted with the MarkLine group.
746     " Signs with Type '.' will be highlighted with the MarkDot group.
747     " Define the Mark where Symbol is not also the mark name, eg "']".
748     if <SID>Has_Unicode()
749       let g:iainsigns = "Dash:'=’ Dot:..• Quote:\"=” Caret:^.ʌ"
750     else
751       let g:iainsigns = "Dash=' Dot:..* Quote=\" Caret.^"
752     endif
753     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"
754   endif
755
756   if g:marksigns
757     " Signs to highlight marks.
758     " Syntax won't work properly in Vim 6.
759     let l:signs = g:iainsigns
760     let l:sign = ""
761     while strlen(l:signs)
762       let l:sign = matchstr(l:signs, '^[A-Za-z]\+\(:.\)*[.=-][^ ]\+')
763
764       let l:sign = substitute(l:sign, ':.', "", "")
765       let l:sign = substitute(l:sign, '=', " texthl=MarkSign text=", "")
766       let l:sign = substitute(l:sign, '\.', " texthl=MarkDot text=", "")
767       let l:sign = substitute(l:sign, '-', " texthl=MarkLine text=", "")
768
769       exe "sign define Mark" . l:sign
770
771       let l:signs = substitute(l:signs, '^[^ ]\+ *', "", "")
772     endwhile
773
774     if a:resize
775       call Resize_Columns("+", 2)
776     endif
777     call <SID>Highlight_Signs()
778   else
779     let l:i = 0
780     while l:i < 25
781       exe "sign unplace " . (g:firstsign + l:i)
782       let l:i = l:i + 1
783     endwhile
784
785     let l:signs = g:iainsigns
786     let l:sign = ""
787     while strlen(l:signs)
788       let l:sign = matchstr(l:signs, '^[A-Za-z]\+')
789
790       exe "sign undefine Mark" . l:sign
791       call <SID>Prep_Sign(tolower(l:sign))
792       let l:signs = substitute(l:signs, '^[^ ]\+ *', "", "")
793     endwhile
794
795     if a:resize
796       call Resize_Columns("-", 2)
797     endif
798   endif
799 endfun "}}}2
800
801 " Do we have Unicode?
802 fun! <SID>Has_Unicode() "{{{2
803   if ! has('multi_byte')
804     return 0
805   endif
806
807   if version < "602"
808     return 0
809   endif
810
811   if &tenc =~? '^u\(tf\|cs\)'
812     return 1
813   endif
814
815   if ! strlen(&tenc) && &enc =~? '^u\(tf\|cs\)'
816     return 1
817   endif
818
819   return 0
820 endfun "}}}2
821
822 " Change list mode.
823 fun! Cycle_List() "{{{2
824   " Pretty UTF-8 listchars.
825   if <SID>Has_Unicode()
826     let basic='tab:»·,trail:…,extends:«,precedes:»'
827     let eol='eol:¶'
828     if version >= "700"
829       let basic=basic . ',nbsp:•'
830     endif
831   else
832     let basic='tab:\\_,trail:_,extends:<,precedes:>'
833     let eol='eol:$'
834     if version >= "700"
835       let basic=basic . ',nbsp:+'
836     endif
837   endif
838   call Iain_Vars()
839   let w:iainlist = w:iainlist + 1
840   if w:iainlist > 2
841     let w:iainlist = 0
842   endif
843   if w:iainlist == 0
844     setlocal nolist
845   elseif w:iainlist == 1
846     exec "setlocal lcs=" . basic
847     setlocal list
848   else
849     exec "setlocal lcs=" . basic . "," . eol
850     setlocal list
851   endif
852
853   call Resize_Columns(Extra_Columns("list", "iainlist", " == 2"), 1)
854 endfun "}}}2
855
856 " Cycle between hex and decimal display of toolbar stuff.
857 fun! Cycle_HexStatusLine() "{{{2
858   call Iain_Vars()
859   let b:iainhex = ! b:iainhex
860   call Show_StatusLine()
861 endfun "}}}2
862
863 " Cycle verbose display of toolbar stuff.
864 fun! Cycle_VerboseStatusLine() "{{{2
865   call Iain_Vars()
866   let b:iainverbose = ! b:iainverbose
867   call Show_StatusLine()
868 endfun "}}}2
869
870 " Toggle quickfix window.
871 fun! Cycle_Quickfix() "{{{2
872   if g:quickfixing == 1
873     cclose
874     let g:quickfixing=0
875   else
876     copen
877   endif
878 endfun "}}}2
879
880 " Swap hex/decimal statusline with \x.
881 call Mapping("x", ":call Cycle_HexStatusLine()<CR>:<CR>")
882 " Change statusline verbosity with \v.
883 call Mapping("V", ":call Cycle_VerboseStatusLine()<CR>:<CR>")
884 " Cycle list styles with \l.
885 call Mapping("l", ":call Cycle_List()<CR>:<CR>")
886 " Toggle tags with \t.
887 call Mapping("t", ":Tlist<CR>")
888 " Change foldmethod with \f.
889 call Mapping("f", ":se foldenable!<CR>:<CR>")
890 " Toggle quickfix window with \q.
891 call Mapping("q", ":call Cycle_Quickfix()<CR>:<CR>")
892 " Rerun filetype detection with \s.  The s is for syntax, as this will be
893 " updated as a side-effect.
894 call Mapping("S", ":filetype detect<CR>:<CR>")
895 " Toggle marks with \m.
896 call Mapping("m", ":call <SID>Cycle_Signs(1)<CR>:<CR>")
897
898 " Show signs by default.
899 au Display VimEnter * call <SID>Cycle_Signs(0)
900 endif "}}}1
901
902 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
903 " Handle options only available in Vim 7 and above.
904 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
905 if version >= "700" "{{{1
906 version 7.0
907
908 " Helper to show tab name.
909 fun! <SID>TabName(label, gui) "{{{2
910   let l:label = a:label
911   if l:label == ""
912     let l:label = "No Name"
913     if a:gui
914       let l:label = "[" . l:label . "]"
915     endif
916   else
917     let l:label = fnamemodify(l:label, ":t")
918     if strlen(l:label) >= 18
919       let l:label = l:label[0:17] . ".."
920     endif
921   endif
922   return l:label
923 endfun "}}}2
924
925 " Find out if any buffer was modified.
926 fun! <SID>TabModified(buflist) "{{{2
927   let l:i = 0
928   while l:i < len(a:buflist)
929     if getbufvar(a:buflist[l:i], "&modified") == 1
930       return "+"
931     endif
932     let l:i = l:i + 1
933   endwhile
934   return ""
935 endfun "}}}2
936
937 " Tab line.
938 fun! Show_TabLine() "{{{2
939   let l:s = "%#TabLineFill#Tabs:"
940
941   let l:i = 0
942   while l:i < tabpagenr("$")
943     let l:i = l:i + 1
944     " Get the label.
945     let l:buflist = tabpagebuflist(l:i)
946     let l:winnr = tabpagewinnr(l:i)
947     let l:n = tabpagewinnr(l:i, "$")
948     let l:label = <SID>TabName(bufname(l:buflist[l:winnr - 1]), 0)
949     let l:modified = <SID>TabModified(l:buflist)
950
951     " Choose highlighting.
952     if l:i == tabpagenr()
953       let l:s .= "%#TabLineSel#[" . l:n . l:modified . " " . l:label . "]"
954     else
955       let l:s .= "%#TabLine# " . l:n . l:modified . " " . l:label . " "
956     endif
957   endwhile
958
959   " Padding.
960   let l:s .= "%#TabLine#%T"
961   return l:s
962 endfun "}}}2
963
964 " Per tab label for the GUI.
965 fun! Show_GUITabLine() "{{{2
966   let l:buflist = tabpagebuflist(v:lnum)
967   let l:winnr = tabpagewinnr(v:lnum)
968   let l:s = tabpagewinnr(v:lnum, "$")
969   let l:label = <SID>TabName(bufname(l:buflist[l:winnr - 1]), 1)
970   let l:modified = <SID>TabModified(l:buflist)
971
972   let l:s .= l:modified . " " . l:label
973   return l:s
974 endfun "}}}2
975
976 " Toggle highlighting cursor line when focus changes.
977 fun! <SID>ToggleCursorLine() "{{{2
978   call Iain_Vars()
979
980   if b:iainstatus =~# "f" && b:iainstatus =~# "H" && b:iainstatus =~# "I"
981     " Focus lost while held in insert mode.
982     let b:iaincul = getbufvar("", "&cursorline")
983     setlocal cursorline
984   elseif ! b:iaincul
985     setlocal nocursorline
986   endif
987 endfun "}}}2
988
989 se tabline=%!Show_TabLine()
990 se guitablabel=%!Show_GUITabLine()
991
992 au StatusLine CursorHoldI * call Highlight_StatusLine("H")
993 au StatusLine CursorMovedI * call Highlight_StatusLine("h")
994 au StatusLine FocusGained * call Highlight_StatusLine("F")
995 au StatusLine FocusLost * call Highlight_StatusLine("f")
996 au StatusLine InsertEnter * call Highlight_StatusLine("I")
997 au StatusLine InsertLeave * call Highlight_StatusLine("i")
998
999 au Display FocusGained,FocusLost * call <SID>ToggleCursorLine()
1000
1001 if has("signs")
1002   au Signs InsertEnter * call <SID>Highlight_Signs()
1003   au Signs InsertLeave * call <SID>Highlight_Signs()
1004 endif
1005
1006 " Limit the size of the popup menu when completing.
1007 se pumheight=20
1008
1009 " Make diffs vertical by default.
1010 se diffopt+=vertical
1011
1012 " Set size of numbers column.
1013 se numberwidth=5
1014
1015 " Add "previous tab" mapping as gb.
1016 map gb :tabprevious<CR>:<CR>
1017
1018 " Transparency.
1019 if has("gui_macvim")
1020   se transparency=15
1021 endif 
1022
1023 " Yet more GUI options.  Add tabs.
1024 se go+=e
1025
1026 " Perforce.
1027 let g:p4EnableMenu=1
1028 let g:p4Presets='P4CONFIG'
1029
1030 " BufExplorer.
1031 let g:bufExplorerShowRelativePath=1
1032 let g:bufExplorerSplitOutPathName=0
1033 endif "}}}1
1034
1035 " Resize after startup.
1036 if version >= "500" "{{{1
1037 au Display VimEnter * call Startup_Resize()
1038 endif "}}}1