1d7d9d70fde6bde61472fb02b9af7d57caae528c
[profile.git] / .vimrc
1 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
2 " $Id$
3 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
4 " Multi-version vimrc compatible with version 4 and above.
5 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
6
7 " Note that "if <condition> | call Something() | endif" syntax is unsupported 
8 " in Vim 4 so we write all our functions out the long way.  It does work in 
9 " autocommand definitions, however.
10
11 " Vim 4 complains if version isn't set in the configuration file.
12 version 4.0
13
14 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
15 " Handle options safe to use in version 4.  Vim 4 parses but ignores the 
16 " "if version" syntax used later in this file so we don't use it.  No attempt 
17 " is made to make this configuration compatible with Vim 3.
18 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
19 " No compatibility mode.
20 se nocp
21
22 " Tabstop 2.
23 se ts=2
24 " And use spaces not tabs.
25 se expandtab
26 " And << and >> indent by 2.
27 se sw=2
28
29 " Allow backspace to delete before start of line.
30 se bs=2
31
32 " Show the ruler.
33 se ruler
34 " Show partial commands in the ruler.
35 se showcmd
36 " And always show the status line.
37 se laststatus=2
38
39 " Use C indent style.
40 se cindent
41 se cinkeys=0{,0},0),:,!^F,o,O,e
42 se cinoptions=b1,c2
43
44 " GUI options.
45 se go=aglmr
46
47 " Don't be bugged by messages at the bottom of the screen.
48 se shm=aot
49
50 " Find as you type.
51 se incsearch
52
53 " Case-insensitive search.
54 se ignorecase
55 " But override by typing capitals.
56 se smartcase
57
58 " Look for ctags in home directory first.
59 se tags=~/.tags,./tags,tags
60
61 " Use - and = to create underlines.
62 map - yyp:s/./-/g<RETURN>:let @/=''<RETURN>:<RETURN>
63 map = yyp:s/./=/g<RETURN>:let @/=''<RETURN>:<RETURN>
64
65 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
66 " Handle options only available in Vim 5 and above.
67 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
68 if version >= "500"
69 version 5.0
70
71 " Nuke any pre-existing autocommands.
72 autocmd!
73
74 " Save the current window width so we can restore it when we quit.
75 let oldcols=&columns
76
77 " More GUI options.  Add icon, tearoffs and toolbar.
78 se go=agilmrtT
79
80 " Allow dynamic window resize even if we aren't in an xterm.
81 se t_WS=\e[8;%p1%d;%p2%dt
82
83 " Highlight search results.
84 se hlsearch
85
86 " Syntax highlighting.
87 syn on
88
89 " Catch typos.
90 command! W :w
91 command! Wq :wq
92 command! Wqa :wqa
93
94 " Set up our variables.
95 fun! Iain_Vars()
96   if ! exists("b:iainlist")
97     let b:iainlist = 0
98   endif
99   if ! exists("b:iainhex")
100     let b:iainhex = 0
101   endif
102   if ! exists("b:iainverbose")
103     let b:iainverbose = 0
104   endif
105 endfun
106
107 " Helper for status line.
108 " Show space, underscore or dollar sign depending on list mode.
109 fun! Show_List()
110   call Iain_Vars()
111   if b:iainlist == 0
112     " No list.
113     return " "
114   elseif b:iainlist == 1
115     " Just tabs.
116     return "_"
117   else
118     " Full list.
119     return "\$"
120   endif
121 endfun
122
123 " Helper for status line.
124 " Show c or C to denote case-sensitivity.
125 fun! Show_Case()
126   if &ic
127     return "c"
128   else
129     return "C"
130   endif
131 endfun
132
133 " Helper for status line.
134 " Show the size of the tabstop.
135 fun! Show_Tabstop()
136   return &ts
137 endfun
138
139 " Helper for status line.
140 " Show p when paste mode is on.
141 fun! Show_Paste()
142   if &paste
143     return "p"
144   else
145     return ""
146   endif
147 endfun
148
149 " Show the status line.
150 fun! Show_StatusLine()
151   call Iain_Vars()
152   let sl1='%2n\:\ %<%f\ [%{Show_List()}%{Show_Case()}%{Show_Tabstop()}%{Show_Paste()}%Y%M%R]\ %='
153   let sl3='L:%4.6l/%-4.6L\ C:%3.6c\ \|\ %P'
154   let hexformat='%b'
155   if b:iainhex
156     let hexformat='0\x%02B'
157   endif
158   if b:iainverbose
159     let sl2=hexformat . '\ \|\ P:%4.6o\ '
160   else
161     let sl2=''
162   endif
163   exec "set statusline=" . sl1 . sl2 . sl3
164 endfun
165
166 " Restore window size.
167 au VimLeave * if exists("oldcols") | let &columns=oldcols | endif
168
169 " Map C mode.
170 au BufEnter * if &ft == "c" || &ft == "cpp" | call CMode_map() | endif
171 au BufLeave * if &ft == "c" || &ft == "cpp" | call CMode_unmap() | endif
172
173 " Map Perl mode.
174 au BufEnter * if &ft == "perl" | call PerlMode_map() | endif
175 au BufLeave * if &ft == "perl" | call PerlMode_unmap() | endif
176
177 " Map Makefile mode.
178 au BufEnter * if &ft == "make" | call MakeMode_map() | endif
179 au BufLeave * if &ft == "make" | call MakeMode_unmap() | endif
180
181 " Entering C mode.
182 fun! CMode_map()
183   let oldcinkeys=&cinkeys
184   let oldcinwords=&cinwords
185   set cinkeys=0{,0},:,0#,!^F,o,O,e
186   set cinwords=if,else,while,do,for,switch
187 endfun
188
189 " Leaving C mode.
190 fun! CMode_unmap()
191   set cinkeys=oldcinkeys
192   set cinwords=oldcinwords
193 endfun
194
195 " Entering Perl mode.
196 fun! PerlMode_map()
197   let oldcinkeys=&cinkeys
198   let oldcinwords=&cinwords
199   set cinkeys=0{,0},:,!^F,o,O,e
200   set cinwords=if,else,while,do,for,eval
201 endfun
202
203 " Leaving Perl mode.
204 fun! PerlMode_unmap()
205   set cinkeys=oldcinkeys
206   set cinwords=oldcinwords
207 endfun
208
209 " Entering Make mode.
210 fun! MakeMode_map()
211   set list
212   set noexpandtab
213 endfun
214
215 " Leaving Make mode.
216 fun! MakeMode_unmap()
217   set nolist
218   set expandtab
219 endfun
220
221 " Show the status line for the first time.
222 call Show_StatusLine()
223 endif
224
225 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
226 " Handle options only available in Vim 6 and above.
227 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
228 if version >= "600"
229 version 6.0
230
231 " Track changing number mode.
232 let g:numbercols=&columns
233 let g:numberchanges=0
234
235 " Less intrusive syntax highlighting.
236 syn enable
237
238 " Nice GUI colour.
239 if has("gui_running")
240   se guifont=Bitstream\ Vera\ Sans\ Mono\ 12
241   colo darkblue
242 endif
243 if has("win32")
244   se guifont=Bitstream_Vera_Sans_Mono:h10:cANSI
245 endif
246
247 " Ignore whitespace when diffing.
248 se diffopt=filler,iwhite
249
250 " Expand window when doing a vertical diff.
251 if &diff
252   let &columns = 164
253 endif
254
255 " Status bar matches the colour.
256 highlight StatusLine guifg=white guibg=blue ctermbg=white ctermfg=blue
257
258 " Numbers in blue.
259 highlight LineNr term=underline cterm=bold guifg=blue ctermfg=blue
260
261 " Make * and # work the way you expect in visual mode.
262 vnoremap * y/\V<C-R>=substitute(escape(@@,"/\\"),"\n","\\\\n","ge")<CR><CR>
263 vnoremap # y?\V<C-R>=substitute(escape(@@,"?\\"),"\n","\\\\n","ge")<CR><CR>
264
265 " Change list mode.
266 fun! Cycle_List()
267   let basic='tab:\\_,trail:_,extends:<,precedes:>'
268   call Iain_Vars()
269   let b:iainlist = b:iainlist + 1
270   if b:iainlist > 2
271     let b:iainlist = 0
272   endif
273   if b:iainlist == 0
274     set nolist
275   elseif b:iainlist == 1
276     exec "set lcs=" . basic
277     set list
278   else
279     exec "set lcs=" . basic . ",eol:$"
280     set list
281   endif
282 endfun
283
284 " Cycle between hex and decimal display of toolbar stuff.
285 fun! Cycle_HexStatusLine()
286   call Iain_Vars()
287   let b:iainhex = ! b:iainhex
288   call Show_StatusLine()
289 endfun
290
291 " Cycle verbose display of toolbar stuff.
292 fun! Cycle_VerboseStatusLine()
293   call Iain_Vars()
294   let b:iainverbose = ! b:iainverbose
295   call Show_StatusLine()
296 endfun
297
298 " Cycle between number mode.
299 " FIXME: Toggling in a split window doesn't work properly.  We need to track 
300 " the number of windows and number modes.  Something for later...
301 " Perhaps have a redraw callback that checks width and original column number.
302 fun! Cycle_Number()
303   if &number
304     " Restore width.
305     if &t_WS =~ '^\e.'
306       " Track changes.
307       let g:numberchanges=g:numberchanges-1
308       if g:numberchanges<0
309         g:numberchanges=0
310       endif
311
312       " Change size back if this was the last window.
313       if g:numberchanges == 0
314         let &columns=g:numbercols
315       endif
316     endif
317     set nonumber
318   else
319     " Save width between number toggling.
320     if &t_WS =~ '^\e'
321       " Expand if this was the first change.
322       if g:numberchanges == 0
323         let g:numbercols=&columns
324         if version >= 700
325           " Expand column by our preferred width.
326           let &columns=&columns+&numberwidth
327         else
328           " Vim 6 hardcodes width to 8.
329           let &columns=&columns+8
330         endif
331       endif
332
333       " Track changes.
334       let g:numberchanges=g:numberchanges+1
335     endif
336     set number
337   endif
338 endfun
339
340 " Toggle case-sensitivity.
341 fun! Invert_Case()
342   let &ic = ! &ic
343 endfun
344
345 " We'll use Q for various commands.  Unmap it.
346 map Q <Nop>
347
348 " Change to ts=2 with Q2.
349 map Q2 :se ts=2<CR>:<CR>
350 " Change to ts=4 with Q4.
351 map Q4 :se ts=4<CR>:<CR>
352 " Change to ts=8 with Q8.
353 map Q8 :se ts=8<CR>:<CR>
354 " Change to ts=16 with Q6.
355 map Q6 :se ts=16<CR>:<CR>
356 " Change to ts=32 with Q3.
357 map Q3 :se ts=32<CR>:<CR>
358 " Change foldmethod with Qf.
359 map Qf :se foldenable!<CR>:<CR>
360 " Toggle paste mode with Qp.
361 map Qp :se paste!<CR>:<CR>
362 " Swap hex/decimal statusline with Qx
363 map Qx :call Cycle_HexStatusLine()<CR>:<CR>
364 " Change statusline verbosity with Qv
365 map Qv :call Cycle_VerboseStatusLine()<CR>:<CR>
366 " Swap case-sensitivity with Qc.
367 map Qc :call Invert_Case()<CR>:<CR>
368 " Cycle list styles with Ql.
369 map Ql :call Cycle_List()<CR>:<CR>
370 " Change number mode with Qn.
371 map Qn :call Cycle_Number()<CR>:<CR>
372 " Toggle tags with Qt.
373 map Qt :Tlist<CR>
374 " Clear search pattern with Q/.
375 map Q/ :let @/=""<CR>:<CR>
376
377 " Leaving Perl mode.
378 fun! PerlMode_unmap()
379   set cinkeys=oldcinkeys
380   set cinwords=oldcinwords
381   set foldmethod=manual
382 endfun
383 endif
384
385 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
386 " Handle options only available in Vim 7 and above.
387 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
388 if version >= "700"
389 version 7.0
390
391 " Make diffs vertical by default.
392 se diffopt+=vertical
393
394 " Set size of numbers column.
395 se numberwidth=5
396
397 " Add "previous tab" mapping as gb.
398 map gb :tabPrev<CR>
399 endif