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