Back compatibility.
authorIain Patterson <me@iain.cx>
Thu, 8 Jul 2010 12:47:22 +0000 (13:47 +0100)
committerIain Patterson <me@iain.cx>
Mon, 19 Jul 2010 12:50:43 +0000 (13:50 +0100)
Make sure more things which rely on particular features are wrapped in
has("feature") conditionals and wrap more stuff in version checks.
User functions were introduced in Vim 5.2.
VIMRUNTIME was introduced in Vim 5.4
The system() command was introduced in Vim 5.4.
The statusline option could not be modified before Vim 5.4.

.vimrc

diff --git a/.vimrc b/.vimrc
index 85b1595..a589ea0 100644 (file)
--- a/.vimrc
+++ b/.vimrc
@@ -13,16 +13,13 @@ version 4.0
 " Handle options safe to use in version 4.  Vim 4 parses but ignores the 
 " "if version" syntax used later in this file so we don't use it.  No attempt 
 " is made to make this configuration compatible with Vim 3.
+" Some of these settings should strictly be wrapped inside "if has()" blocks
+" but that would cause them not to be ignored by Vim 4.
 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 "{{{1
 " No compatibility mode.
 se nocp
 
-" Find stuff.
-if has("win32") || has("win64")
-  se rtp=~/.vim,$VIMRUNTIME
-endif
-
 " Tabstop 2.
 se ts=2
 " And use spaces not tabs.
@@ -80,6 +77,11 @@ noremap ' `
 noremap ` '
 "}}}1
 
+" Find stuff.
+if (has("win32") || has("win64")) && version >= "504"
+  se rtp=~/.vim,$VIMRUNTIME
+endif
+
 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 " Handle options only available in Vim 5 and above.
 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
@@ -103,31 +105,37 @@ if has("signs")
 endif
 
 " Enable tab-completion prompting for commands.
-se wildmenu
-" Don't list object files when globbing files to load.
-se wildignore+=*.o,*.obj
-" So there's no need to assign them low priority.
-se suffixes-=*.o,*.obj
+if has("wildmenu")
+  se wildmenu
+  " Don't list object files when globbing files to load.
+  se wildignore+=*.o,*.obj
+  " So there's no need to assign them low priority.
+  se suffixes-=*.o,*.obj
+endif
 
 " Save sessions in UNIX format with / as file separator.  This is
 " cross-platform.
-se ssop+=unix,slash
+if has("mksession")
+  se ssop+=unix,slash
+endif
 
 " How often do we need to use ^A/^X on octals?
 se nf=hex
 
 " Nuke any pre-existing autocommands.
-augroup Display
-autocmd!
-augroup Mode
-autocmd!
-if has("signs")
-  augroup Signs
+if has("autocmd")
+  augroup Display
+  autocmd!
+  augroup Mode
+  autocmd!
+  if has("signs")
+    augroup Signs
+    autocmd!
+  endif
+  augroup StatusLine
   autocmd!
+  augroup END
 endif
-augroup StatusLine
-autocmd!
-augroup END
 
 " Save the current window dimensions so we can restore them when we quit.
 if ! exists("g:oldcols")
@@ -138,21 +146,17 @@ if ! exists("g:oldlines")
 endif
 
 " More GUI options.  Add icon and tearoffs.
-se go+=i
-se go+=t
+if has("gui")
+  se go+=i
+  se go+=t
+endif
 
 " Allow dynamic window resize even if we aren't in an xterm.
 se t_WS=\e[8;%p1%d;%p2%dt
 
 " Highlight search results.
-se hlsearch
-
-" Set graphical window title.
-if has("win32") || has("win64")
-  " Windows taskbar entries are probably too small to show full titles.
-  se titlestring=%t
-else
-  se titlestring=%{Show_TitleString()}
+if has("extra_search")
+  se hlsearch
 endif
 
 " Syntax highlighting.  New versions will use syn enable instead.
@@ -160,10 +164,27 @@ if version < "600"
   syn on
 endif
 
-" Catch typos.
-command! W :w
-command! Wq :wq
-command! Wqa :wqa
+if has("user_commands")
+  " Catch typos.
+  command! W :w
+  command! Wq :wq
+  command! Wqa :wqa
+endif
+
+" Forget the Ex mode mapping.
+map Q <NOP>
+
+if has("autocmd")
+  " Position the compview plugin window.
+  au Display BufEnter -SearchResults- set buftype=nowrite | set nonumber | wincmd J
+endif
+endif "}}}1
+
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+" Handle options only available in Vim 5.2 and above.
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+if version >= "502" "{{{1
+version 5.2
 
 " Helper to initialise a variable.
 fun! Prep_Var(var, value) "{{{2
@@ -190,56 +211,6 @@ fun! Iain_Vars() "{{{2
   call Prep_Var("g:resizable", "''")
 endfun "}}}2
 
-" Helper for status line.
-" Show space, underscore or dollar sign depending on list mode.
-fun! Show_List() "{{{2
-  call Iain_Vars()
-  if w:iainlist == 0
-    " No list.
-    return " "
-  elseif <SID>Has_Unicode()
-    if w:iainlist == 1
-      " Just tabs.
-      return "»"
-    else
-      " Full list.
-      return "¶"
-    endif
-  else
-    if w:iainlist == 1
-      return "_"
-    else
-      return "\$"
-    endif
-  endif
-endfun "}}}2
-
-" Helper for status line.
-" Show c or C to denote case-sensitivity.
-fun! Show_Case() "{{{2
-  if &ic
-    return "c"
-  else
-    return "C"
-  endif
-endfun "}}}2
-
-" Helper for status line.
-" Show the size of the tabstop.
-fun! Show_Tabstop() "{{{2
-  return &ts
-endfun "}}}2
-
-" Helper for status line.
-" Show p when paste mode is on.
-fun! Show_Paste() "{{{2
-  if &paste
-    return "p"
-  else
-    return ""
-  endif
-endfun "}}}2
-
 " Show the window title.
 fun! Show_TitleString() "{{{2
   if bufname("") == ""
@@ -259,25 +230,6 @@ fun! Show_TitleString() "{{{2
   return l:ts1
 endfun "}}}2
 
-" Show the status line.
-fun! Show_StatusLine() "{{{2
-  call Iain_Vars()
-  let l:sl1='%2n\:\ %<%1*%f%0*\ [%{Show_List()}%{Show_Case()}%{Show_Tabstop()}%{Show_Paste()}%Y%M%R]\ '
-  let l:sl3='L:%1*%4.6l%0*/%-4.6L\ C:%1*%3.6c%0*\ \|\ %P'
-  let l:hexformat='%b'
-  if b:iainhex
-    let l:hexformat='0\x%02B'
-  endif
-  if b:iainverbose
-    let l:sl1=l:sl1 . v:version . '\ %='
-    let l:sl2=l:hexformat . '\ \|\ P:%4.6o\ '
-  else
-    let l:sl1=l:sl1 . '%='
-    let l:sl2=''
-  endif
-  exec "set statusline=" . l:sl1 . l:sl2 . l:sl3
-endfun "}}}2
-
 " Toggle case-sensitivity.
 fun! Invert_Case() "{{{2
   let &ic = ! &ic
@@ -317,7 +269,7 @@ fun! Resize_Columns(op, ...) "{{{2
 
   if a:0 == 0
     " Vim 5 hardcodes the size of numbers column to 8.
-    if version >= "700"
+    if version >= "700" && has("linebreak")
       let l:columns = &numberwidth
     else
       let l:columns = 8
@@ -370,6 +322,9 @@ fun! Extra_Columns(extra, var, ...) "{{{2
   if v:version < "600"
     return ""
   endif
+  if ! has("windows")
+    return ""
+  endif
 
   " Remember which window we're in.
   let l:winnr = winnr()
@@ -433,14 +388,16 @@ fun! Number(resize) "{{{2
 endfun "}}}2
 
 " Restore window size.
-if ! has("gui_running")
+if has("autocmd") && ! has("gui_running")
   au Display VimLeave * if exists("g:oldcols") | call Resize_Columns("-", (&columns - g:oldcols)) | endif
   au Display VimLeave * if exists("g:oldlines") | call Resize_Lines("-", (&lines - g:oldlines)) | endif
 endif
 
 " Map Makefile mode.
-au Mode BufEnter * if &ft == "make" | call MakeMode_map() | endif
-au Mode BufLeave * if &ft == "make" | call MakeMode_unmap() | endif
+if has("autocmd")
+  au Mode BufEnter * if &ft == "make" | call MakeMode_map() | endif
+  au Mode BufLeave * if &ft == "make" | call MakeMode_unmap() | endif
+endif
 
 " Entering Make mode.
 fun! MakeMode_map() "{{{2
@@ -458,9 +415,6 @@ fun! MakeMode_unmap() "{{{2
   set expandtab
 endfun "}}}2
 
-" Show the status line for the first time.
-call Show_StatusLine()
-
 " Function to create mappings with either a hardcoded \ or <Leader>.
 fun! Mapping(keysequence,mapping) "{{{2
   if version < "600"
@@ -496,8 +450,13 @@ call Mapping("<", ":call Resize_Columns('-')<CR>:<CR>")
 " Clear search pattern with \/.
 call Mapping("/", ":let @/=\"\"<CR>:<CR>")
 
-" Forget the Ex mode mapping.
-map Q <NOP>
+" Set graphical window title.
+if has("win32") || has("win64")
+  " Windows taskbar entries are probably too small to show full titles.
+  se titlestring=%t
+else
+  se titlestring=%{Show_TitleString()}
+endif
 
 " Vim tip 99: What's the highlighting group under the cursor?
 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>")
@@ -535,7 +494,7 @@ fun! Startup_Resize() "{{{2
 
   " Resize for numbers.
   if &number
-    if version >= "700"
+    if version >= "700" && has("linebreak")
       let l:columns = &numberwidth
     else
       let l:columns = 8
@@ -561,6 +520,9 @@ endfun "}}}2
 "        F/f: Focus gained/lost.
 "        I/i: Insert mode entered/left.
 fun! Highlight_StatusLine(flag) "{{{2
+  if ! has("statusline")
+    return
+  endif
   " Get current status.
   call Iain_Vars()
 
@@ -633,13 +595,94 @@ fun! Iain_Colour(colour) "{{{2
   endif
 endfun "}}}2
 
-au StatusLine VimEnter * call Highlight_StatusLine("")
+if has("autocmd")
+  au StatusLine VimEnter * call Highlight_StatusLine("")
+
+  " Show numbers by default.
+  au Display VimEnter * if ! Uncluttered_Buffer() | call Number(0) | endif
+endif
+endif "}}}1
+
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+" Handle options only available in Vim 5.4 and above.
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+if version >= "504" "{{{1
+version 5.4
+
+" Helper for status line.
+" Show space, underscore or dollar sign depending on list mode.
+fun! Show_List() "{{{2
+  call Iain_Vars()
+  if w:iainlist == 0
+    " No list.
+    return " "
+  elseif <SID>Has_Unicode()
+    if w:iainlist == 1
+      " Just tabs.
+      return "»"
+    else
+      " Full list.
+      return "¶"
+    endif
+  else
+    if w:iainlist == 1
+      return "_"
+    else
+      return "\$"
+    endif
+  endif
+endfun "}}}2
+
+" Helper for status line.
+" Show c or C to denote case-sensitivity.
+fun! Show_Case() "{{{2
+  if &ic
+    return "c"
+  else
+    return "C"
+  endif
+endfun "}}}2
+
+" Helper for status line.
+" Show the size of the tabstop.
+fun! Show_Tabstop() "{{{2
+  return &ts
+endfun "}}}2
+
+" Helper for status line.
+" Show p when paste mode is on.
+fun! Show_Paste() "{{{2
+  if &paste
+    return "p"
+  else
+    return ""
+  endif
+endfun "}}}2
 
-" Show numbers by default.
-au Display VimEnter * if ! Uncluttered_Buffer() | call Number(0) | endif
+" Show the status line.
+fun! Show_StatusLine() "{{{2
+  if ! has("statusline")
+    return
+  endif
+  call Iain_Vars()
+  let l:sl1='%2n\:\ %<%1*%f%0*\ [%{Show_List()}%{Show_Case()}%{Show_Tabstop()}%{Show_Paste()}%Y%M%R]\ '
+  let l:sl3='L:%1*%4.6l%0*/%-4.6L\ C:%1*%3.6c%0*\ \|\ %P'
+  let l:hexformat='%b'
+  if b:iainhex
+    let l:hexformat='0\x%02B'
+  endif
+  if b:iainverbose
+    let l:sl1=l:sl1 . v:version . '\ %='
+    let l:sl2=l:hexformat . '\ \|\ P:%4.6o\ '
+  else
+    let l:sl1=l:sl1 . '%='
+    let l:sl2=''
+  endif
+  exec "set statusline=" . l:sl1 . l:sl2 . l:sl3
+endfun "}}}2
 
-" Position the compview plugin window.
-au Display BufEnter -SearchResults- set buftype=nowrite | set nonumber | wincmd J
+" Show the status line for the first time.
+call Show_StatusLine()
 endif "}}}1
 
 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
@@ -653,13 +696,17 @@ if has("gui_win32")
 endif
 
 " Remember quickfix state.
-let g:quickfixing=0
+if has("quickfix")
+  let g:quickfixing=0
+endif
 
 " Set indenting by filetype.
 filetype indent on
 
 " Less intrusive syntax highlighting.
-syn enable
+if has("syntax")
+  syn enable
+endif
 
 " Set colours.
 if has("gui_running")
@@ -674,21 +721,20 @@ if has("gui_running") || &t_Co > 16
 endif
 
 " Ignore whitespace when diffing.
-se diffopt=filler,iwhite
-
-" Expand window when doing a vertical diff.
-if &diff
-  if &columns < 161
-    let &columns = &columns * 2
-  endif
+if has("diff")
+  se diffopt=filler,iwhite
 endif
 
-" Remember that we are opening the quickfix window.
-au Mode BufWinEnter quickfix let g:quickfixing=1
-au Mode BufUnload * if &ft == "qf" | let g:quickfixing=0 | endif
+if has("autocmd")
+  if has("quickfix")
+    " Remember that we are opening the quickfix window.
+    au Mode BufWinEnter quickfix let g:quickfixing=1
+    au Mode BufUnload * if &ft == "qf" | let g:quickfixing=0 | endif
+  endif
 
-" Allow in-place editing of crontabs.
-au Mode FileType crontab set backupcopy=yes
+  " Allow in-place editing of crontabs.
+  au Mode FileType crontab set backupcopy=yes
+endif
 
 " Make * and # work the way you expect in visual mode.
 vnoremap * y/\V<C-R>=substitute(escape(@@,"/\\"),"\n","\\\\n","ge")<CR><CR>
@@ -892,6 +938,9 @@ endfun "}}}2
 
 " Toggle quickfix window.
 fun! Cycle_Quickfix() "{{{2
+  if ! has("quickfix")
+    return
+  endif
   if g:quickfixing == 1
     cclose
     let g:quickfixing=0
@@ -918,8 +967,10 @@ call Mapping("S", ":filetype detect<CR>:<CR>")
 " Toggle marks with \m.
 call Mapping("m", ":call <SID>Cycle_Signs(1)<CR>:<CR>")
 
-" Show signs by default.
-au Display VimEnter * call <SID>Cycle_Signs(0)
+if has("autocmd")
+  " Show signs by default.
+  au Display VimEnter * call <SID>Cycle_Signs(0)
+endif
 endif "}}}1
 
 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
@@ -1009,31 +1060,43 @@ fun! <SID>ToggleCursorLine() "{{{2
   endif
 endfun "}}}2
 
-se tabline=%!Show_TabLine()
-se guitablabel=%!Show_GUITabLine()
+if has("windows")
+  se tabline=%!Show_TabLine()
+  se guitablabel=%!Show_GUITabLine()
+endif
 
-au StatusLine CursorHoldI * call Highlight_StatusLine("H")
-au StatusLine CursorMovedI * call Highlight_StatusLine("h")
-au StatusLine FocusGained * call Highlight_StatusLine("F")
-au StatusLine FocusLost * call Highlight_StatusLine("f")
-au StatusLine InsertEnter * call Highlight_StatusLine("I")
-au StatusLine InsertLeave * call Highlight_StatusLine("i")
+if has("autocmd")
+  au StatusLine CursorHoldI * call Highlight_StatusLine("H")
+  au StatusLine CursorMovedI * call Highlight_StatusLine("h")
+  au StatusLine FocusGained * call Highlight_StatusLine("F")
+  au StatusLine FocusLost * call Highlight_StatusLine("f")
+  au StatusLine InsertEnter * call Highlight_StatusLine("I")
+  au StatusLine InsertLeave * call Highlight_StatusLine("i")
 
-au Display FocusGained,FocusLost * call <SID>ToggleCursorLine()
+  if has("syntax")
+    au Display FocusGained,FocusLost * call <SID>ToggleCursorLine()
+  endif
 
-if has("signs")
-  au Signs InsertEnter * call <SID>Highlight_Signs()
-  au Signs InsertLeave * call <SID>Highlight_Signs()
+  if has("signs")
+    au Signs InsertEnter * call <SID>Highlight_Signs()
+    au Signs InsertLeave * call <SID>Highlight_Signs()
+  endif
 endif
 
 " Limit the size of the popup menu when completing.
-se pumheight=20
+if has("insert_expand")
+  se pumheight=20
+endif
 
 " Make diffs vertical by default.
-se diffopt+=vertical
+if has("diff")
+  se diffopt+=vertical
+endif
 
 " Set size of numbers column.
-se numberwidth=5
+if has("linebreak")
+  se numberwidth=5
+endif
 
 " Add "previous tab" mapping as gb.
 map gb :tabprevious<CR>:<CR>
@@ -1044,7 +1107,9 @@ if has("gui_macvim")
 endif 
 
 " Yet more GUI options.  Add tabs.
-se go+=e
+if has("gui")
+  se go+=e
+endif
 
 " Perforce.
 let g:p4EnableMenu=1
@@ -1057,5 +1122,7 @@ endif "}}}1
 
 " Resize after startup.
 if version >= "500" "{{{1
-au Display VimEnter * call Startup_Resize()
+if has("autocmd")
+  au Display VimEnter * call Startup_Resize()
+endif
 endif "}}}1