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