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