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