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