Set GUI options more elegantly.
[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+=itT
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 Makefile mode.
174 au BufEnter * if &ft == "make" | call MakeMode_map() | endif
175 au BufLeave * if &ft == "make" | call MakeMode_unmap() | endif
176
177 " Entering Make mode.
178 fun! MakeMode_map()
179   set list
180   set noexpandtab
181 endfun
182
183 " Leaving Make mode.
184 fun! MakeMode_unmap()
185   set nolist
186   set expandtab
187 endfun
188
189 " Show the status line for the first time.
190 call Show_StatusLine()
191 endif
192
193 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
194 " Handle options only available in Vim 6 and above.
195 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
196 if version >= "600"
197 version 6.0
198
199 " Set indenting by filetype.
200 filetype indent on
201
202 " Track changing number mode.
203 let g:numbercols=&columns
204 let g:numberchanges=0
205
206 " Less intrusive syntax highlighting.
207 syn enable
208
209 " Nice GUI colour.
210 if has("gui_running")
211   se guifont=Bitstream\ Vera\ Sans\ Mono\ 10
212   colo darkblue
213 endif
214 if has("win32")
215   se guifont=Bitstream_Vera_Sans_Mono:h10:cANSI
216 endif
217
218 " Ignore whitespace when diffing.
219 se diffopt=filler,iwhite
220
221 " Expand window when doing a vertical diff.
222 if &diff
223   let &columns = 164
224 endif
225
226 " Status bar matches the colour.
227 highlight StatusLine guifg=white guibg=blue ctermbg=white ctermfg=blue
228
229 " Numbers in blue.
230 highlight LineNr term=underline cterm=bold guifg=blue ctermfg=blue
231
232 " Make * and # work the way you expect in visual mode.
233 vnoremap * y/\V<C-R>=substitute(escape(@@,"/\\"),"\n","\\\\n","ge")<CR><CR>
234 vnoremap # y?\V<C-R>=substitute(escape(@@,"?\\"),"\n","\\\\n","ge")<CR><CR>
235
236 " Change list mode.
237 fun! Cycle_List()
238   let basic='tab:\\_,trail:_,extends:<,precedes:>'
239   call Iain_Vars()
240   let b:iainlist = b:iainlist + 1
241   if b:iainlist > 2
242     let b:iainlist = 0
243   endif
244   if b:iainlist == 0
245     set nolist
246   elseif b:iainlist == 1
247     exec "set lcs=" . basic
248     set list
249   else
250     exec "set lcs=" . basic . ",eol:$"
251     set list
252   endif
253 endfun
254
255 " Cycle between hex and decimal display of toolbar stuff.
256 fun! Cycle_HexStatusLine()
257   call Iain_Vars()
258   let b:iainhex = ! b:iainhex
259   call Show_StatusLine()
260 endfun
261
262 " Cycle verbose display of toolbar stuff.
263 fun! Cycle_VerboseStatusLine()
264   call Iain_Vars()
265   let b:iainverbose = ! b:iainverbose
266   call Show_StatusLine()
267 endfun
268
269 " Cycle between number mode.
270 " FIXME: Toggling in a split window doesn't work properly.  We need to track 
271 " the number of windows and number modes.  Something for later...
272 " Perhaps have a redraw callback that checks width and original column number.
273 fun! Cycle_Number()
274   if &number
275     " Restore width.
276     if &t_WS =~ '^\e.'
277       " Track changes.
278       let g:numberchanges=g:numberchanges-1
279       if g:numberchanges<0
280         g:numberchanges=0
281       endif
282
283       " Change size back if this was the last window.
284       if g:numberchanges == 0
285         let &columns=g:numbercols
286       endif
287     endif
288     set nonumber
289   else
290     " Save width between number toggling.
291     if &t_WS =~ '^\e'
292       " Expand if this was the first change.
293       if g:numberchanges == 0
294         let g:numbercols=&columns
295         if version >= 700
296           " Expand column by our preferred width.
297           let &columns=&columns+&numberwidth
298         else
299           " Vim 6 hardcodes width to 8.
300           let &columns=&columns+8
301         endif
302       endif
303
304       " Track changes.
305       let g:numberchanges=g:numberchanges+1
306     endif
307     set number
308   endif
309 endfun
310
311 " Toggle case-sensitivity.
312 fun! Invert_Case()
313   let &ic = ! &ic
314 endfun
315
316 " We'll use Q for various commands.  Unmap it.
317 map Q <Nop>
318
319 " Change to ts=2 with Q2.
320 map Q2 :se ts=2<CR>:<CR>
321 " Change to ts=4 with Q4.
322 map Q4 :se ts=4<CR>:<CR>
323 " Change to ts=8 with Q8.
324 map Q8 :se ts=8<CR>:<CR>
325 " Change to ts=16 with Q6.
326 map Q6 :se ts=16<CR>:<CR>
327 " Change to ts=32 with Q3.
328 map Q3 :se ts=32<CR>:<CR>
329 " Change foldmethod with Qf.
330 map Qf :se foldenable!<CR>:<CR>
331 " Toggle paste mode with Qp.
332 map Qp :se paste!<CR>:<CR>
333 " Swap hex/decimal statusline with Qx
334 map Qx :call Cycle_HexStatusLine()<CR>:<CR>
335 " Change statusline verbosity with Qv
336 map Qv :call Cycle_VerboseStatusLine()<CR>:<CR>
337 " Swap case-sensitivity with Qc.
338 map Qc :call Invert_Case()<CR>:<CR>
339 " Cycle list styles with Ql.
340 map Ql :call Cycle_List()<CR>:<CR>
341 " Change number mode with Qn.
342 map Qn :call Cycle_Number()<CR>:<CR>
343 " Toggle tags with Qt.
344 map Qt :Tlist<CR>
345 " Clear search pattern with Q/.
346 map Q/ :let @/=""<CR>:<CR>
347
348 endif
349
350 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
351 " Handle options only available in Vim 7 and above.
352 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
353 if version >= "700"
354 version 7.0
355
356 " Make diffs vertical by default.
357 se diffopt+=vertical
358
359 " Set size of numbers column.
360 se numberwidth=5
361
362 " Add "previous tab" mapping as gb.
363 map gb :tabPrev<CR>
364 endif