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