changeset 671:83a006f81bac v7.0199

updated for version 7.0199
author vimboss
date Thu, 16 Feb 2006 22:11:02 +0000
parents f892bda292a8
children db58b9066b21
files runtime/doc/syntax.txt runtime/doc/tips.txt runtime/doc/todo.txt runtime/doc/usr_06.txt runtime/doc/version7.txt runtime/ftplugin/vhdl.vim runtime/syntax/colortest.vim runtime/syntax/vim.vim src/auto/configure src/buffer.c src/configure.in src/diff.c src/eval.c src/ex_cmds2.c src/ex_docmd.c src/globals.h src/if_mzsch.c src/if_python.c src/if_ruby.c src/main.c src/mark.c src/misc1.c src/misc2.c src/normal.c src/option.c src/proto/ex_docmd.pro src/proto/window.pro src/screen.c src/structs.h src/version.h src/window.c
diffstat 31 files changed, 623 insertions(+), 215 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/syntax.txt
+++ b/runtime/doc/syntax.txt
@@ -1,4 +1,4 @@
-*syntax.txt*	For Vim version 7.0aa.  Last change: 2006 Jan 23
+*syntax.txt*	For Vim version 7.0aa.  Last change: 2006 Feb 16
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -4257,9 +4257,8 @@ But for using 16 colors in an rxvt these
 <
 							*colortest.vim*
 To test your color setup, a file has been included in the Vim distribution.
-To use it, execute these commands: >
-   :e $VIMRUNTIME/syntax/colortest.vim
-   :so %
+To use it, execute this command: >
+   :runtime syntax/colortest.vim
 
 Some versions of xterm (and other terminals, like the Linux console) can
 output lighter foreground colors, even though the number of colors is defined
--- a/runtime/doc/tips.txt
+++ b/runtime/doc/tips.txt
@@ -1,4 +1,4 @@
-*tips.txt*      For Vim version 7.0aa.  Last change: 2006 Feb 13
+*tips.txt*      For Vim version 7.0aa.  Last change: 2006 Feb 16
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -494,7 +494,7 @@ Note that it doesn't recognize strings o
 	  endif
 	endfunction
 
-	autocmd CursorMoved * call s:Highlight_Matching_Paren()
+	autocmd CursorMoved,CursorMovedI * call s:Highlight_Matching_Paren()
 	autocmd InsertEnter * match none
 <
 
--- a/runtime/doc/todo.txt
+++ b/runtime/doc/todo.txt
@@ -1,4 +1,4 @@
-*todo.txt*      For Vim version 7.0aa.  Last change: 2006 Feb 15
+*todo.txt*      For Vim version 7.0aa.  Last change: 2006 Feb 16
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -32,20 +32,23 @@ be worked on, but only if you sponsor Vi
 
 Support WINDOW TABS.  Works like several pages, each with their own split
 windows.  Let's call them "tab pages".
-    - Mouse click in tab name should select that tab.
-    - line at top of frame with tabs.
-	for the name ignore the help window, unless it's the only one).
-	Add a number for the window count?
-	Add a '+' if one of the windows is modified?
-	Add 'tabtext' option, like 'statusline'.
-        Add an "X" to close the current tab (like firefox).
-    - When deleting a buffer also close windows in other tab pages.
-    - check all places where firstwin and lastwin are used
+    - check all places where lastwin is used
+    - check all places where win_valid() is used
+    - check all places where last_window() is used
+    - ":tabclose N" close tab N
+    - Add ":tabonly" - close all other tabs.
     - check all places wheren only_one_window() is used.
     - Add tabpage(): returns current tab page number.
+    - ":tabsplit" makes a copy of the current tab page.
+    - Add TabLeavePre and TabEnterPost autocommands
+    - line at top of frame with tabs.
+	Add 'tabtext' option, like 'statusline'.
+    - make a diff for each tab page separately.
     - E999
-    - ":tabclose N" close tab N
     - docs:
+	General remark: commands that work on windows only work on the windows
+	    in the current tab page.  Including :windo.
+	Session file only contains the current tab page.
 	:tabedit
 	:tabfind
 	:tab N
@@ -57,6 +60,12 @@ windows.  Let's call them "tab pages".
 	     next one.  Hint in docs: To mess with another buffer, without
 	     changing the window layout, do this in another tab.
 	'tabline' values 0/1/2
+	mouse click in tabline:
+	    select a tab page
+	    X closes current tab page
+	:argall and :ball only opens window for buffers that are not in any
+	      window in any tab page
+	:diffoff only in the current tab page
     - add GUI Tabs for some systems.
       Patch for GTK 1.2 passed on by Christian Michon, 2004 Jan 6.
       Simple patch for GTK by Luis M (nov 7).
@@ -65,11 +74,15 @@ windows.  Let's call them "tab pages".
 
 Crash with X command server (Ciaran McCreesh).
 
-Ctags still hasn't included the patch...
+Ctags still hasn't included the patch.  Darren is looking for someone to do
+maintanance.
 
 "fsutil hardlink" can create a hard link on an NTFS file system. (Daniel
 Einspanjer)  What library function can detect that?
 
+Win32: use GetFileInformationByHandle() to detect hard links on NTFS?
+(George Reilly)
+
 spelling:
 - Also use the spelling dictionary for dictionary completion.
   When 'dictionary' is empty and/or when "kspell" is in 'complete'.
--- a/runtime/doc/usr_06.txt
+++ b/runtime/doc/usr_06.txt
@@ -1,4 +1,4 @@
-*usr_06.txt*	For Vim version 7.0aa.  Last change: 2002 Jul 14
+*usr_06.txt*	For Vim version 7.0aa.  Last change: 2006 Feb 16
 
 		     VIM USER MANUAL - by Bram Moolenaar
 
@@ -179,10 +179,9 @@ 3. Tell Vim to always use your color sch
 	colorscheme mine
 
 If you want to see what the most often used color combinations look like, use
-these commands: >
+this command: >
 
-	:edit $VIMRUNTIME/syntax/colortest.vim
-	:source %
+	:runtime syntax/colortest.vim
 
 You will see text in various color combinations.  You can check which ones are
 readable and look nice.
--- a/runtime/doc/version7.txt
+++ b/runtime/doc/version7.txt
@@ -1,4 +1,4 @@
-*version7.txt*  For Vim version 7.0aa.  Last change: 2006 Feb 14
+*version7.txt*  For Vim version 7.0aa.  Last change: 2006 Feb 16
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1010,6 +1010,9 @@ asdf.c" when it sets the filename for th
 
 Insert mode completion for whole lines now also searches unloaded buffers.
 
+The colortest.vim script can now be invoked directly with ":source" or
+":runtime".
+
 ==============================================================================
 COMPILE TIME CHANGES					*compile-changes-7*
 
@@ -1696,4 +1699,6 @@ event that removed the balloon again.  I
 
 'titleold' was included in ":mkexrc" and ":mksession" files.
 
+":set background&" didn't use the same logic as was used when starting up.
+
  vim:tw=78:ts=8:ft=help:norl:
--- a/runtime/ftplugin/vhdl.vim
+++ b/runtime/ftplugin/vhdl.vim
@@ -1,8 +1,8 @@
-" Vim filetype plugin file
-" Language: VHDL
-" Maintainer:   R.Shankar (shankar at txc.stpn.soft.net)
-" Last Change:  Tue Oct 8
-
+" VHDL filetype plugin
+" Language:    VHDL
+" Maintainer:  R.Shankar <shankar.r?freescale.com>
+" Modified By: Gerald Lai <laigera+vim?gmail.com>
+" Last Change: 2006 Feb 16
 
 " Only do this when not done yet for this buffer
 if exists("b:did_ftplugin")
@@ -20,7 +20,7 @@ let b:did_ftplugin = 1
 "setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,://
 
 " Format comments to be up to 78 characters long
-setlocal tw=75
+"setlocal tw=75
 
 set cpo-=C
 
@@ -34,8 +34,51 @@ set cpo-=C
 if ! exists("b:match_words")  &&  exists("loaded_matchit")
   let b:match_ignorecase=1
   let s:notend = '\%(\<end\s\+\)\@<!'
-  let b:match_words=
-  \ s:notend . '\<if\>:\<elsif\>:\<else\>:\<end\>\s\+\<if\>,' .
-  \ s:notend . '\<case\>:\<when\>:\<end\>\s\+\<case\>,' .
-  \ s:notend . '\<process\>:\<end\>\s\+\<process\>'
+  let b:match_words =
+    \ s:notend.'\<if\>:\<elsif\>:\<else\>:\<end\s\+if\>,'.
+    \ s:notend.'\<case\>:\<when\>:\<end\s\+case\>,'.
+    \ s:notend.'\<loop\>:\<end\s\+loop\>,'.
+    \ s:notend.'\<for\>:\<end\s\+for\>,'.
+    \ s:notend.'\<generate\>:\<end\s\+generate\>,'.
+    \ s:notend.'\<record\>:\<end\s\+record\>,'.
+    \ s:notend.'\<units\>:\<end\s\+units\>,'.
+    \ s:notend.'\<process\>:\<end\s\+process\>,'.
+    \ s:notend.'\<block\>:\<end\s\+block\>,'.
+    \ s:notend.'\<function\>:\<end\s\+function\>,'.
+    \ s:notend.'\<entity\>:\<end\s\+entity\>,'.
+    \ s:notend.'\<component\>:\<end\s\+component\>,'.
+    \ s:notend.'\<architecture\>:\<end\s\+architecture\>,'.
+    \ s:notend.'\<package\>:\<end\s\+package\>,'.
+    \ s:notend.'\<procedure\>:\<end\s\+procedure\>,'.
+    \ s:notend.'\<configuration\>:\<end\s\+configuration\>'
 endif
+
+" count repeat
+function! <SID>CountWrapper(cmd)
+  let i = v:count1
+  if a:cmd[0] == ":"
+    while i > 0
+      execute a:cmd
+      let i = i - 1
+    endwhile
+  else
+    execute "normal! gv\<Esc>"
+    execute "normal ".i.a:cmd
+    let curcol = col(".")
+    let curline = line(".")
+    normal! gv
+    call cursor(curline, curcol)
+  endif
+endfunction
+
+" explore motion
+" keywords: "architecture", "block", "configuration", "component", "entity", "function", "package", "procedure", "process", "record", "units"
+let b:vhdl_explore = '\%(architecture\|block\|configuration\|component\|entity\|function\|package\|procedure\|process\|record\|units\)'
+noremap  <buffer><silent>[[ :<C-u>cal <SID>CountWrapper(':cal search("\\%(--.*\\)\\@<!\\%(\\<end\\s\\+\\)\\@<!\\<".b:vhdl_explore."\\>\\c\\<Bar>\\%^","bW")')<CR>
+noremap  <buffer><silent>]] :<C-u>cal <SID>CountWrapper(':cal search("\\%(--.*\\)\\@<!\\%(\\<end\\s\\+\\)\\@<!\\<".b:vhdl_explore."\\>\\c\\<Bar>\\%$","W")')<CR>
+noremap  <buffer><silent>[] :<C-u>cal <SID>CountWrapper(':cal search("\\%(--.*\\)\\@<!\\<end\\s\\+".b:vhdl_explore."\\>\\c\\<Bar>\\%^","bW")')<CR>
+noremap  <buffer><silent>][ :<C-u>cal <SID>CountWrapper(':cal search("\\%(--.*\\)\\@<!\\<end\\s\\+".b:vhdl_explore."\\>\\c\\<Bar>\\%$","W")')<CR>
+vnoremap <buffer><silent>[[ :<C-u>cal <SID>CountWrapper('[[')<CR>
+vnoremap <buffer><silent>]] :<C-u>cal <SID>CountWrapper(']]')<CR>
+vnoremap <buffer><silent>[] :<C-u>cal <SID>CountWrapper('[]')<CR>
+vnoremap <buffer><silent>][ :<C-u>cal <SID>CountWrapper('][')<CR>
--- a/runtime/syntax/colortest.vim
+++ b/runtime/syntax/colortest.vim
@@ -1,7 +1,7 @@
 " Vim script for testing colors
 " Maintainer:	Bram Moolenaar <Bram@vim.org>
 " Contributors:	Rafael Garcia-Suarez, Charles Campbell
-" Last Change:	2001 Jul 28
+" Last Change:	2006 Feb 16
 
 " edit this file, then do ":source %", and check if the colors match
 
@@ -52,6 +52,15 @@
 " lightcyan	lightcyan_on_white			white_on_lightcyan
 "				lightcyan_on_black	black_on_lightcyan
 
+" Open this file in a window if it isn't edited yet.
+" Use the current window if it's empty.
+if &mod || line('$') != 1 || getline(1) != ''
+  new
+endif
+if expand('%:p') != expand('<sfile>:p')
+  exe "edit " . expand('<sfile>')
+endif
+
 syn clear
 8
 while search("_on_", "W") < 55
@@ -60,6 +69,5 @@ while search("_on_", "W") < 55
   exec 'hi col_'.col1.'_'.col2.' ctermfg='.col1.' guifg='.col1.' ctermbg='.col2.' guibg='.col2
   exec 'syn keyword col_'.col1.'_'.col2.' '.col1.'_on_'.col2
 endwhile
-8,55g/^" \a/exec 'hi col_'.expand("<cword>").' ctermfg='.expand("<cword>").' guifg='.expand("<cword>")|
-	\ exec 'syn keyword col_'.expand("<cword>")." ".expand("<cword>")
+8,54g/^" \a/exec 'hi col_'.expand("<cword>").' ctermfg='.expand("<cword>").' guifg='.expand("<cword>")| exec 'syn keyword col_'.expand("<cword>")." ".expand("<cword>")
 nohlsearch
--- a/runtime/syntax/vim.vim
+++ b/runtime/syntax/vim.vim
@@ -1,8 +1,8 @@
 " Vim syntax file
 " Language:	Vim 7.0 script
 " Maintainer:	Dr. Charles E. Campbell, Jr. <NdrOchipS@PcampbellAfamily.Mbiz>
-" Last Change:	February 07, 2006
-" Version:	7.0-25
+" Last Change:	February 15, 2006
+" Version:	7.0-26
 " Automatically generated keyword lists: {{{1
 
 " Quit when a syntax file was already loaded {{{2
@@ -16,11 +16,11 @@ syn keyword vimTodo contained	COMBAK	NOT
 syn cluster vimCommentGroup	contains=vimTodo,@Spell
 
 " regular vim commands {{{2
-syn keyword vimCommand contained	ab[breviate] abc[lear] abo[veleft] al[l] arga[dd] argd[elete] argdo arge[dit] argg[lobal] argl[ocal] ar[gs] argu[ment] as[cii] bad[d] ba[ll] bd[elete] be bel[owright] bf[irst] bl[ast] bm[odified] bn[ext] bN[ext] bo[tright] bp[revious] brea[k] breaka[dd] breakd[el] breakl[ist] br[ewind] bro[wse] bufdo b[uffer] buffers bun[load] bw[ipeout] ca[bbrev] cabc[lear] caddb[uffer] cad[dexpr] caddf[ile] cal[l] cat[ch] cb[uffer] cc ccl[ose] cd ce[nter] cex[pr] cf[ile] cfir[st] cg[etfile] c[hange] changes chd[ir] che[ckpath] checkt[ime] cla[st] cl[ist] clo[se] cmapc[lear] cnew[er] cn[ext] cN[ext] cnf[ile] cNf[ile] cnorea[bbrev] col[der] colo[rscheme] comc[lear] comp[iler] conf[irm] con[tinue] cope[n] co[py] cpf[ile] cp[revious] cq[uit] cr[ewind] cuna[bbrev] cu[nmap] cw[indow] debugg[reedy] delc[ommand] d[elete] DeleteFirst delf[unction] delm[arks] diffg[et] diffoff diffpatch diffpu[t] diffsplit diffthis diffu[pdate] dig[raphs] di[splay] dj[ump] dl[ist] dr[op] ds[earch] dsp[lit] echoe[rr] echom[sg] echon e[dit] el[se] elsei[f] em[enu] emenu* endfo[r] endf[unction] en[dif] endt[ry] endw[hile] ene[w] ex exi[t] Explore exu[sage] f[ile] files filetype fina[lly] fin[d] fini[sh] fir[st] fix[del] fo[ld] foldc[lose] folddoc[losed] foldd[oopen] foldo[pen] for fu[nction] g[lobal] go[to] gr[ep] grepa[dd] ha[rdcopy] h[elp] helpf[ind] helpg[rep] helpt[ags] Hexplore hid[e] his[tory] I ia[bbrev] iabc[lear] if ij[ump] il[ist] imapc[lear] inorea[bbrev] is[earch] isp[lit] iuna[bbrev] iu[nmap] j[oin] ju[mps] k keepalt keepj[umps] kee[pmarks] laddb[uffer] lad[dexpr] laddf[ile] lan[guage] la[st] lb[uffer] lc[d] lch[dir] lcl[ose] le[ft] lefta[bove] lex[pr] lf[ile] lfir[st] lg[etfile] lgr[ep] lgrepa[dd] l[ist] ll lla[st] lli[st] lmak[e] lm[ap] lmapc[lear] lnew[er] lne[xt] lN[ext] lnf[ile] lNf[ile] ln[oremap] lo[adview] loc[kmarks] lockv[ar] lol[der] lop[en] lpf[ile] lp[revious] lr[ewind] ls lt[ag] lu[nmap] lv[imgrep] lvimgrepa[dd] lw[indow] mak[e] ma[rk] marks mat[ch] menut[ranslate] mk[exrc] mks[ession] mksp[ell] mkvie[w] mkv[imrc] mod[e] m[ove] mzf[ile] mz[scheme] nbkey NetrwSettings new n[ext] N[ext] nmapc[lear] noh[lsearch] norea[bbrev] Nread nu[mber] nun[map] Nw omapc[lear] on[ly] o[pen] opt[ions] ou[nmap] pc[lose] ped[it] pe[rl] perld[o] po[p] popu popu[p] pp[op] pre[serve] prev[ious] p[rint] P[rint] profd[el] prof[ile] prompt promptf[ind] promptr[epl] ps[earch] pta[g] ptf[irst] ptj[ump] ptl[ast] ptn[ext] ptN[ext] ptp[revious] ptr[ewind] pts[elect] pu[t] pw[d] pyf[ile] py[thon] qa[ll] q[uit] quita[ll] r[ead] rec[over] redi[r] red[o] redr[aw] redraws[tatus] reg[isters] res[ize] ret[ab] retu[rn] rew[ind] ri[ght] rightb[elow] rub[y] rubyd[o] rubyf[ile] ru[ntime] rv[iminfo] sal[l] san[dbox] sa[rgument] sav[eas] sba[ll] sbf[irst] sbl[ast] sbm[odified] sbn[ext] sbN[ext] sbp[revious] sbr[ewind] sb[uffer] scripte[ncoding] scrip[tnames] se[t] setf[iletype] setg[lobal] setl[ocal] Sexplore sf[ind] sfir[st] sh[ell] sign sil[ent] sim[alt] sla[st] sl[eep] sm[agic] sn[ext] sN[ext] sni[ff] sno[magic] sor[t] so[urce] spelld[ump] spe[llgood] spellr[epall] spellw[rong] sp[lit] spr[evious] sre[wind] sta[g] startg[replace] star[tinsert] startr[eplace] stj[ump] st[op] stopi[nsert] sts[elect] sun[hide] sus[pend] sv[iew] syncbind t ta[g] tags tc[l] tcld[o] tclf[ile] te[aroff] tf[irst] the th[row] tj[ump] tl[ast] tm tm[enu] tn[ext] tN[ext] to[pleft] tp[revious] tr[ewind] try ts[elect] tu tu[nmenu] una[bbreviate] u[ndo] unh[ide] unlo[ckvar] unm[ap] up[date] verb[ose] ve[rsion] vert[ical] Vexplore v[global] vie[w] vim[grep] vimgrepa[dd] vi[sual] viu[sage] vmapc[lear] vne[w] vs[plit] vu[nmap] wa[ll] wh[ile] winc[md] windo winp[os] win[size] wn[ext] wN[ext] wp[revious] wq wqa[ll] w[rite] ws[verb] wv[iminfo] X xa[ll] x[it] XMLent XMLns y[ank] 
+syn keyword vimCommand contained	ab[breviate] abc[lear] abo[veleft] al[l] arga[dd] argd[elete] argdo arge[dit] argg[lobal] argl[ocal] ar[gs] argu[ment] as[cii] bad[d] ba[ll] bd[elete] be bel[owright] bf[irst] bl[ast] bm[odified] bn[ext] bN[ext] bo[tright] bp[revious] brea[k] breaka[dd] breakd[el] breakl[ist] br[ewind] bro[wse] bufdo b[uffer] buffers bun[load] bw[ipeout] ca[bbrev] cabc[lear] caddb[uffer] cad[dexpr] caddf[ile] cal[l] cat[ch] cb[uffer] cc ccl[ose] cd ce[nter] cex[pr] cf[ile] cfir[st] cg[etfile] c[hange] changes chd[ir] che[ckpath] checkt[ime] cla[st] cl[ist] clo[se] cmapc[lear] cnew[er] cn[ext] cN[ext] cnf[ile] cNf[ile] cnorea[bbrev] col[der] colo[rscheme] comc[lear] comp[iler] conf[irm] con[tinue] cope[n] co[py] cpf[ile] cp[revious] cq[uit] cr[ewind] cuna[bbrev] cu[nmap] cw[indow] debugg[reedy] delc[ommand] d[elete] DeleteFirst delf[unction] delm[arks] diffg[et] diffoff diffpatch diffpu[t] diffsplit diffthis diffu[pdate] dig[raphs] di[splay] dj[ump] dl[ist] dr[op] ds[earch] dsp[lit] echoe[rr] echom[sg] echon e[dit] el[se] elsei[f] em[enu] emenu* endfo[r] endf[unction] en[dif] endt[ry] endw[hile] ene[w] ex exi[t] Explore exu[sage] f[ile] files filetype fina[lly] fin[d] fini[sh] fir[st] fix[del] fo[ld] foldc[lose] folddoc[losed] foldd[oopen] foldo[pen] for fu[nction] g[lobal] go[to] gr[ep] grepa[dd] ha[rdcopy] h[elp] helpf[ind] helpg[rep] helpt[ags] Hexplore hid[e] his[tory] I ia[bbrev] iabc[lear] if ij[ump] il[ist] imapc[lear] inorea[bbrev] is[earch] isp[lit] iuna[bbrev] iu[nmap] j[oin] ju[mps] k keepalt keepj[umps] kee[pmarks] laddb[uffer] lad[dexpr] laddf[ile] lan[guage] la[st] lb[uffer] lc[d] lch[dir] lcl[ose] le[ft] lefta[bove] lex[pr] lf[ile] lfir[st] lg[etfile] lgr[ep] lgrepa[dd] lh[elpgrep] l[ist] ll lla[st] lli[st] lmak[e] lm[ap] lmapc[lear] lnew[er] lne[xt] lN[ext] lnf[ile] lNf[ile] ln[oremap] lo[adview] loc[kmarks] lockv[ar] lol[der] lop[en] lpf[ile] lp[revious] lr[ewind] ls lt[ag] lu[nmap] lv[imgrep] lvimgrepa[dd] lw[indow] mak[e] ma[rk] marks mat[ch] menut[ranslate] mk[exrc] mks[ession] mksp[ell] mkvie[w] mkv[imrc] mod[e] m[ove] mzf[ile] mz[scheme] nbkey NetrwSettings new n[ext] N[ext] nmapc[lear] noh[lsearch] norea[bbrev] Nread nu[mber] nun[map] Nw omapc[lear] on[ly] o[pen] opt[ions] ou[nmap] pc[lose] ped[it] pe[rl] perld[o] po[p] popu popu[p] pp[op] pre[serve] prev[ious] p[rint] P[rint] profd[el] prof[ile] prompt promptf[ind] promptr[epl] ps[earch] pta[g] ptf[irst] ptj[ump] ptl[ast] ptn[ext] ptN[ext] ptp[revious] ptr[ewind] pts[elect] pu[t] pw[d] pyf[ile] py[thon] qa[ll] q[uit] quita[ll] r[ead] rec[over] redi[r] red[o] redr[aw] redraws[tatus] reg[isters] res[ize] ret[ab] retu[rn] rew[ind] ri[ght] rightb[elow] rub[y] rubyd[o] rubyf[ile] ru[ntime] rv[iminfo] sal[l] san[dbox] sa[rgument] sav[eas] sba[ll] sbf[irst] sbl[ast] sbm[odified] sbn[ext] sbN[ext] sbp[revious] sbr[ewind] sb[uffer] scripte[ncoding] scrip[tnames] se[t] setf[iletype] setg[lobal] setl[ocal] Sexplore sf[ind] sfir[st] sh[ell] sign sil[ent] sim[alt] sla[st] sl[eep] sm[agic] sn[ext] sN[ext] sni[ff] sno[magic] sor[t] so[urce] spelld[ump] spe[llgood] spellr[epall] spellw[rong] sp[lit] spr[evious] sre[wind] sta[g] startg[replace] star[tinsert] startr[eplace] stj[ump] st[op] stopi[nsert] sts[elect] sun[hide] sus[pend] sv[iew] syncbind t ta[g] tags tc[l] tcld[o] tclf[ile] te[aroff] tf[irst] the th[row] tj[ump] tl[ast] tm tm[enu] tn[ext] tN[ext] to[pleft] tp[revious] tr[ewind] try ts[elect] tu tu[nmenu] una[bbreviate] u[ndo] unh[ide] unlo[ckvar] unm[ap] up[date] verb[ose] ve[rsion] vert[ical] Vexplore v[global] vie[w] vim[grep] vimgrepa[dd] vi[sual] viu[sage] vmapc[lear] vne[w] vs[plit] vu[nmap] wa[ll] wh[ile] winc[md] windo winp[os] win[size] wn[ext] wN[ext] wp[revious] wq wqa[ll] w[rite] ws[verb] wv[iminfo] X xa[ll] x[it] XMLent XMLns y[ank] 
 syn match   vimCommand contained	"\<z[-+^.=]"
 
 " vimOptions are caught only when contained in a vimSet {{{2
-syn keyword vimOption contained	: acd ai akm al aleph allowrevins altkeymap ambiwidth ambw anti antialias ar arab arabic arabicshape ari arshape autochdir autoindent autoread autowrite autowriteall aw awa background backspace backup backupcopy backupdir backupext backupskip balloondelay ballooneval balloonexpr bdir bdlay beval bex bexpr bg bh bin binary biosk bioskey bk bkc bl bomb breakat brk browsedir bs bsdir bsk bt bufhidden buflisted buftype casemap cb ccv cd cdpath cedit cf cfu ch charconvert ci cin cindent cink cinkeys cino cinoptions cinw cinwords clipboard cmdheight cmdwinheight cmp cms co columns com comments commentstring compatible complete completefunc completeopt confirm consk conskey copyindent cot cp cpo cpoptions cpt cscopepathcomp cscopeprg cscopequickfix cscopetag cscopetagorder cscopeverbose cspc csprg csqf cst csto csverb cwh debug deco def define delcombine dex dg dict dictionary diff diffexpr diffopt digraph dip dir directory display dy ea ead eadirection eb ed edcompatible ef efm ei ek enc encoding endofline eol ep equalalways equalprg errorbells errorfile errorformat esckeys et eventignore ex expandtab exrc fcl fcs fdc fde fdi fdl fdls fdm fdn fdo fdt fen fenc fencs ff ffs fileencoding fileencodings fileformat fileformats filetype fillchars fk fkmap flp fml fmr fo foldclose foldcolumn foldenable foldexpr foldignore foldlevel foldlevelstart foldmarker foldmethod foldminlines foldnestmax foldopen foldtext formatlistpat formatoptions formatprg fp fs fsync ft gcr gd gdefault gfm gfn gfs gfw ghr go gp grepformat grepprg guicursor guifont guifontset guifontwide guiheadroom guioptions guipty helpfile helpheight helplang hf hh hi hid hidden highlight history hk hkmap hkmapp hkp hl hlg hls hlsearch ic icon iconstring ignorecase im imactivatekey imak imc imcmdline imd imdisable imi iminsert ims imsearch inc include includeexpr incsearch inde indentexpr indentkeys indk inex inf infercase insertmode is isf isfname isi isident isk iskeyword isp isprint joinspaces js key keymap keymodel keywordprg km kmp kp langmap langmenu laststatus lazyredraw lbr lcs linebreak lines linespace lisp lispwords list listchars lm lmap loadplugins lpl ls lsp lw lz ma magic makeef makeprg mat matchpairs matchtime maxfuncdepth maxmapdepth maxmem maxmempattern maxmemtot mef menuitems mfd mh mis mkspellmem ml mls mm mmd mmp mmt mod modeline modelines modifiable modified more mouse mousef mousefocus mousehide mousem mousemodel mouses mouseshape mouset mousetime mp mps msm mzq mzquantum nf nrformats nu number numberwidth nuw oft ofu omnifunc operatorfunc opfunc osfiletype pa para paragraphs paste pastetoggle patchexpr patchmode path pdev penc pex pexpr pfn pheader pi pm pmbcs pmbfn popt preserveindent previewheight previewwindow printdevice printencoding printexpr printfont printheader printmbcharset printmbfont printoptions prompt pt pvh pvw qe quoteescape readonly remap report restorescreen revins ri rightleft rightleftcmd rl rlc ro rs rtp ru ruf ruler rulerformat runtimepath sb sbo sbr sc scb scr scroll scrollbind scrolljump scrolloff scrollopt scs sect sections secure sel selection selectmode sessionoptions sft sh shcf shell shellcmdflag shellpipe shellquote shellredir shellslash shelltemp shelltype shellxquote shiftround shiftwidth shm shortmess shortname showbreak showcmd showfulltag showmatch showmode shq si sidescroll sidescrolloff siso sj slm sm smartcase smartindent smarttab smc smd sn so softtabstop sol sp spc spell spellcapcheck spellfile spelllang spellsuggest spf spl splitbelow splitright spr sps sr srr ss ssl ssop st sta startofline statusline stl stmp sts su sua suffixes suffixesadd sw swapfile swapsync swb swf switchbuf sws sxq syn synmaxcol syntax ta tabstop tag tagbsearch taglength tagrelative tags tagstack tb tbi tbidi tbis tbs tenc term termbidi termencoding terse textauto textmode textwidth tf tgst thesaurus tildeop timeout timeoutlen title titlelen titleold titlestring tl tm to toolbar toolbariconsize top tr ts tsl tsr ttimeout ttimeoutlen ttm tty ttybuiltin ttyfast ttym ttymouse ttyscroll ttytype tw tx uc ul undolevels updatecount updatetime ut vb vbs vdir ve verbose verbosefile vfile vi viewdir viewoptions viminfo virtualedit visualbell vop wa wak warn wb wc wcm wd weirdinvert wfh wh whichwrap wi wig wildchar wildcharm wildignore wildmenu wildmode wildoptions wim winaltkeys window winfixheight winheight winminheight winminwidth winwidth wiv wiw wm wmh wmnu wmw wop wrap wrapmargin wrapscan write writeany writebackup writedelay ws ww 
+syn keyword vimOption contained	: acd ai akm al aleph allowrevins altkeymap ambiwidth ambw anti antialias ar arab arabic arabicshape ari arshape autochdir autoindent autoread autowrite autowriteall aw awa background backspace backup backupcopy backupdir backupext backupskip balloondelay ballooneval balloonexpr bdir bdlay beval bex bexpr bg bh bin binary biosk bioskey bk bkc bl bomb breakat brk browsedir bs bsdir bsk bt bufhidden buflisted buftype casemap cb ccv cd cdpath cedit cf cfu ch charconvert ci cin cindent cink cinkeys cino cinoptions cinw cinwords clipboard cmdheight cmdwinheight cmp cms co columns com comments commentstring compatible complete completefunc completeopt confirm consk conskey copyindent cot cp cpo cpoptions cpt cscopepathcomp cscopeprg cscopequickfix cscopetag cscopetagorder cscopeverbose cspc csprg csqf cst csto csverb cwh debug deco def define delcombine dex dg dict dictionary diff diffexpr diffopt digraph dip dir directory display dy ea ead eadirection eb ed edcompatible ef efm ei ek enc encoding endofline eol ep equalalways equalprg errorbells errorfile errorformat esckeys et eventignore ex expandtab exrc fcl fcs fdc fde fdi fdl fdls fdm fdn fdo fdt fen fenc fencs fex ff ffs fileencoding fileencodings fileformat fileformats filetype fillchars fk fkmap flp fml fmr fo foldclose foldcolumn foldenable foldexpr foldignore foldlevel foldlevelstart foldmarker foldmethod foldminlines foldnestmax foldopen foldtext formatexpr formatlistpat formatoptions formatprg fp fs fsync ft gcr gd gdefault gfm gfn gfs gfw ghr go gp grepformat grepprg guicursor guifont guifontset guifontwide guiheadroom guioptions guipty helpfile helpheight helplang hf hh hi hid hidden highlight history hk hkmap hkmapp hkp hl hlg hls hlsearch ic icon iconstring ignorecase im imactivatekey imak imc imcmdline imd imdisable imi iminsert ims imsearch inc include includeexpr incsearch inde indentexpr indentkeys indk inex inf infercase insertmode is isf isfname isi isident isk iskeyword isp isprint joinspaces js key keymap keymodel keywordprg km kmp kp langmap langmenu laststatus lazyredraw lbr lcs linebreak lines linespace lisp lispwords list listchars lm lmap loadplugins lpl ls lsp lw lz ma magic makeef makeprg mat matchpairs matchtime maxfuncdepth maxmapdepth maxmem maxmempattern maxmemtot mef menuitems mfd mh mis mkspellmem ml mls mm mmd mmp mmt mod modeline modelines modifiable modified more mouse mousef mousefocus mousehide mousem mousemodel mouses mouseshape mouset mousetime mp mps msm mzq mzquantum nf nrformats nu number numberwidth nuw oft ofu omnifunc operatorfunc opfunc osfiletype pa para paragraphs paste pastetoggle patchexpr patchmode path pdev penc pex pexpr pfn pheader pi pm pmbcs pmbfn popt preserveindent previewheight previewwindow printdevice printencoding printexpr printfont printheader printmbcharset printmbfont printoptions prompt pt pvh pvw qe quoteescape readonly remap report restorescreen revins ri rightleft rightleftcmd rl rlc ro rs rtp ru ruf ruler rulerformat runtimepath sb sbo sbr sc scb scr scroll scrollbind scrolljump scrolloff scrollopt scs sect sections secure sel selection selectmode sessionoptions sft sh shcf shell shellcmdflag shellpipe shellquote shellredir shellslash shelltemp shelltype shellxquote shiftround shiftwidth shm shortmess shortname showbreak showcmd showfulltag showmatch showmode shq si sidescroll sidescrolloff siso sj slm sm smartcase smartindent smarttab smc smd sn so softtabstop sol sp spc spell spellcapcheck spellfile spelllang spellsuggest spf spl splitbelow splitright spr sps sr srr ss ssl ssop st sta startofline statusline stl stmp sts su sua suffixes suffixesadd sw swapfile swapsync swb swf switchbuf sws sxq syn synmaxcol syntax ta tabstop tag tagbsearch taglength tagrelative tags tagstack tb tbi tbidi tbis tbs tenc term termbidi termencoding terse textauto textmode textwidth tf tgst thesaurus tildeop timeout timeoutlen title titlelen titleold titlestring tl tm to toolbar toolbariconsize top tr ts tsl tsr ttimeout ttimeoutlen ttm tty ttybuiltin ttyfast ttym ttymouse ttyscroll ttytype tw tx uc ul undolevels updatecount updatetime ut vb vbs vdir ve verbose verbosefile vfile vi viewdir viewoptions viminfo virtualedit visualbell vop wa wak warn wb wc wcm wd weirdinvert wfh wh whichwrap wi wig wildchar wildcharm wildignore wildmenu wildmode wildoptions wim winaltkeys window winfixheight winheight winminheight winminwidth winwidth wiv wiw wm wmh wmnu wmw wop wrap wrapmargin wrapscan write writeany writebackup writedelay ws ww 
 
 " vimOptions: These are the turn-off setting variants {{{2
 syn keyword vimOption contained	noacd noai noakm noallowrevins noaltkeymap noanti noantialias noar noarab noarabic noarabicshape noari noarshape noautochdir noautoindent noautoread noautowrite noautowriteall noaw noawa nobackup noballooneval nobeval nobin nobinary nobiosk nobioskey nobk nobl nobomb nobuflisted nocf noci nocin nocindent nocompatible noconfirm noconsk noconskey nocopyindent nocp nocscopetag nocscopeverbose nocst nocsverb nodeco nodelcombine nodg nodiff nodigraph nodisable noea noeb noed noedcompatible noek noendofline noeol noequalalways noerrorbells noesckeys noet noex noexpandtab noexrc nofen nofk nofkmap nofoldenable nogd nogdefault noguipty nohid nohidden nohk nohkmap nohkmapp nohkp nohls nohlsearch noic noicon noignorecase noim noimc noimcmdline noimd noincsearch noinf noinfercase noinsertmode nois nojoinspaces nojs nolazyredraw nolbr nolinebreak nolisp nolist noloadplugins nolpl nolz noma nomagic nomh noml nomod nomodeline nomodifiable nomodified nomore nomousef nomousefocus nomousehide nonu nonumber nopaste nopi nopreserveindent nopreviewwindow noprompt nopvw noreadonly noremap norestorescreen norevins nori norightleft norightleftcmd norl norlc noro nors noru noruler nosb nosc noscb noscrollbind noscs nosecure nosft noshellslash noshelltemp noshiftround noshortname noshowcmd noshowfulltag noshowmatch noshowmode nosi nosm nosmartcase nosmartindent nosmarttab nosmd nosn nosol nospell nosplitbelow nosplitright nospr nosr nossl nosta nostartofline nostmp noswapfile noswf nota notagbsearch notagrelative notagstack notbi notbidi notbs notermbidi noterse notextauto notextmode notf notgst notildeop notimeout notitle noto notop notr nottimeout nottybuiltin nottyfast notx novb novisualbell nowa nowarn nowb noweirdinvert nowfh nowildmenu nowinfixheight nowiv nowmnu nowrap nowrapscan nowrite nowriteany nowritebackup nows 
@@ -44,7 +44,7 @@ syn keyword vimErrSetting contained	hard
 
 " AutoBuf Events {{{2
 syn case ignore
-syn keyword vimAutoEvent contained	BufAdd BufCreate BufDelete BufEnter BufFilePost BufFilePre BufHidden BufLeave BufNew BufNewFile BufRead BufReadCmd BufReadPost BufReadPre BufUnload BufWinEnter BufWinLeave BufWipeout BufWrite BufWriteCmd BufWritePost BufWritePre Cmd-event CmdwinEnter CmdwinLeave ColorScheme CursorHold E135 E143 E200 E201 E203 E204 EncodingChanged FileAppendCmd FileAppendPost FileAppendPre FileChangedRO FileChangedShell FileEncoding FileReadCmd FileReadPost FileReadPre FileType FileWriteCmd FileWritePost FileWritePre FilterReadPost FilterReadPre FilterWritePost FilterWritePre FocusGained FocusLost FuncUndefined GUIEnter InsertChange InsertEnter InsertLeave MenuPopup QuickFixCmdPost QuickFixCmdPre RemoteReply SessionLoadPost SpellFileMissing StdinReadPost StdinReadPre SwapExists Syntax TermChanged TermResponse User UserGettingBored VimEnter VimLeave VimLeavePre WinEnter WinLeave 
+syn keyword vimAutoEvent contained	BufAdd BufCreate BufDelete BufEnter BufFilePost BufFilePre BufHidden BufLeave BufNew BufNewFile BufRead BufReadCmd BufReadPost BufReadPre BufUnload BufWinEnter BufWinLeave BufWipeout BufWrite BufWriteCmd BufWritePost BufWritePre Cmd-event CmdwinEnter CmdwinLeave ColorScheme CursorHold CursorHoldI CursorMoved CursorMovedI E135 E143 E200 E201 E203 E204 EncodingChanged FileAppendCmd FileAppendPost FileAppendPre FileChangedRO FileChangedShell FileEncoding FileReadCmd FileReadPost FileReadPre FileType FileWriteCmd FileWritePost FileWritePre FilterReadPost FilterReadPre FilterWritePost FilterWritePre FocusGained FocusLost FuncUndefined GUIEnter InsertChange InsertEnter InsertLeave MenuPopup QuickFixCmdPost QuickFixCmdPre RemoteReply SessionLoadPost SpellFileMissing StdinReadPost StdinReadPre SwapExists Syntax TermChanged TermResponse User UserGettingBored VimEnter VimLeave VimLeavePre WinEnter WinLeave 
 
 " Highlight commonly used Groupnames {{{2
 syn keyword vimGroup contained	Comment Constant String Character Number Boolean Float Identifier Function Statement Conditional Repeat Label Operator Keyword Exception PreProc Include Define Macro PreCondit Type StorageClass Structure Typedef Special SpecialChar Tag Delimiter SpecialComment Debug Underlined Ignore Error Todo 
@@ -55,7 +55,7 @@ syn match vimHLGroup contained	"Conceal"
 syn case match
 
 " Function Names {{{2
-syn keyword vimFuncName contained	add append argc argidx argv browse browsedir bufexists buflisted bufloaded bufname bufnr bufwinnr byte2line byteidx call char2nr cindent col complete_add complete_check confirm copy count cscope_connection cursor deepcopy delete did_filetype diff_filler diff_hlID empty escape eval eventhandler executable exists expand expr8 extend filereadable filewritable filter finddir findfile fnamemodify foldclosed foldclosedend foldlevel foldtext foldtextresult foreground function garbagecollect get getbufline getbufvar getchar getcharmod getcmdline getcmdpos getcmdtype getcwd getfontname getfperm getfsize getftime getftype getline getloclist getqflist getreg getregtype getwinposx getwinposy getwinvar glob globpath has has_key hasmapto histadd histdel histget histnr hlexists hlID hostname iconv indent index input inputdialog inputlist inputrestore inputsave inputsecret insert isdirectory islocked items join keys len libcall libcallnr line line2byte lispindent localtime map maparg mapcheck match matchend matchlist matchstr max min mkdir mode nextnonblank nr2char prevnonblank printf range readfile remote_expr remote_foreground remote_peek remote_read remote_send remove rename repeat resolve reverse search searchdecl searchpair server2client serverlist setbufvar setcmdpos setline setloclist setqflist setreg setwinvar simplify sort soundfold spellbadword spellsuggest split strftime stridx string strlen strpart strridx strtrans submatch substitute synID synIDattr synIDtrans system tagfiles taglist tempname tolower toupper tr type values virtcol visualmode winbufnr wincol winheight winline winnr winrestcmd winwidth writefile 
+syn keyword vimFuncName contained	add append argc argidx argv browse browsedir bufexists buflisted bufloaded bufname bufnr bufwinnr byte2line byteidx call char2nr cindent col complete_add complete_check confirm copy count cscope_connection cursor deepcopy delete did_filetype diff_filler diff_hlID empty escape eval eventhandler executable exists expand expr8 extend filereadable filewritable filter finddir findfile fnamemodify foldclosed foldclosedend foldlevel foldtext foldtextresult foreground function garbagecollect get getbufline getbufvar getchar getcharmod getcmdline getcmdpos getcmdtype getcwd getfontname getfperm getfsize getftime getftype getline getloclist getqflist getreg getregtype getwinposx getwinposy getwinvar glob globpath has has_key hasmapto histadd histdel histget histnr hlexists hlID hostname iconv indent index input inputdialog inputlist inputrestore inputsave inputsecret insert isdirectory islocked items join keys len libcall libcallnr line line2byte lispindent localtime map maparg mapcheck match matchend matchlist matchstr max min mkdir mode nextnonblank nr2char prevnonblank printf pumvisible range readfile remote_expr remote_foreground remote_peek remote_read remote_send remove rename repeat resolve reverse search searchdecl searchpair searchpairpos searchpos server2client serverlist setbufvar setcmdpos setline setloclist setqflist setreg setwinvar simplify sort soundfold spellbadword spellsuggest split strftime stridx string strlen strpart strridx strtrans submatch substitute synID synIDattr synIDtrans system tagfiles taglist tempname tolower toupper tr type values virtcol visualmode winbufnr wincol winheight winline winnr winrestcmd winwidth writefile 
 
 "--- syntax above generated by mkvimvim ---
 " Special Vim Highlighting (not automatic) {{{1
--- a/src/auto/configure
+++ b/src/auto/configure
@@ -15088,7 +15088,7 @@ echo $ECHO_N "checking for GCC 3 or late
 DEPEND_CFLAGS_FILTER=
 if test "$GCC" = yes; then
   gccmajor=`"$CC" --version | sed -e '2,$d;s/^[^0-9]*\([1-9]\)\.[0-9.]*.*$/\1/g'`
-  if test "$gccmajor" > "2"; then
+  if test "$gccmajor" -gt "2"; then
     DEPEND_CFLAGS_FILTER="| sed 's+-I */+-isystem /+g'"
   fi
 fi
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1062,21 +1062,7 @@ do_buffer(action, start, dir, count, for
 
 	    /* Close any other windows on this buffer, then make it empty. */
 #ifdef FEAT_WINDOWS
-	    {
-		win_T	*wp, *nextwp;
-
-		for (wp = firstwin; wp != NULL; wp = nextwp)
-		{
-		    nextwp = wp->w_next;
-		    if (wp != curwin && wp->w_buffer == buf)
-		    {
-			/* Start all over, autocommands may change the window
-			 * layout. */
-			nextwp = firstwin;
-			win_close(wp, FALSE);
-		    }
-		}
-	    }
+	    close_windows(buf, TRUE);
 #endif
 	    setpcmark();
 	    retval = do_ecmd(0, NULL, NULL, NULL, ECMD_ONE,
@@ -1095,9 +1081,11 @@ do_buffer(action, start, dir, count, for
 #ifdef FEAT_WINDOWS
 	/*
 	 * If the deleted buffer is the current one, close the current window
-	 * (unless it's the only window).
+	 * (unless it's the only window).  Repeat this so long as we end up in
+	 * a window with this buffer.
 	 */
-	while (buf == curbuf && firstwin != lastwin)
+	while (buf == curbuf
+		   && (firstwin != lastwin || first_tabpage->tp_next != NULL))
 	    win_close(curwin, FALSE);
 #endif
 
@@ -1107,7 +1095,7 @@ do_buffer(action, start, dir, count, for
 	if (buf != curbuf)
 	{
 #ifdef FEAT_WINDOWS
-	    close_windows(buf);
+	    close_windows(buf, FALSE);
 #endif
 	    if (buf != curbuf && buf_valid(buf) && buf->b_nwindows <= 0)
 		close_buffer(NULL, buf, action);
@@ -1317,7 +1305,7 @@ set_curbuf(buf, action)
     {
 #ifdef FEAT_WINDOWS
 	if (unload)
-	    close_windows(prevbuf);
+	    close_windows(prevbuf, FALSE);
 #endif
 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
 	if (buf_valid(prevbuf) && !aborting())
@@ -4707,6 +4695,7 @@ write_viminfo_bufferlist(fp)
     buf_T	*buf;
 #ifdef FEAT_WINDOWS
     win_T	*win;
+    tabpage_T	*tp;
 #endif
     char_u	*line;
     int		max_buffers;
@@ -4723,7 +4712,7 @@ write_viminfo_bufferlist(fp)
 	return;
 
 #ifdef FEAT_WINDOWS
-    for (win = firstwin; win != NULL; win = win->w_next)
+    FOR_ALL_TAB_WINDOWS(tp, win)
 	set_last_cursor(win);
 #else
     set_last_cursor(curwin);
--- a/src/configure.in
+++ b/src/configure.in
@@ -2761,7 +2761,7 @@ AC_MSG_CHECKING(for GCC 3 or later)
 DEPEND_CFLAGS_FILTER=
 if test "$GCC" = yes; then
   gccmajor=`"$CC" --version | sed -e '2,$d;s/^[[^0-9]]*\([[1-9]]\)\.[[0-9.]]*.*$/\1/g'`
-  if test "$gccmajor" > "2"; then
+  if test "$gccmajor" -gt "2"; then
     DEPEND_CFLAGS_FILTER="| sed 's+-I */+-isystem /+g'"
   fi
 fi
--- a/src/diff.c
+++ b/src/diff.c
@@ -1075,6 +1075,7 @@ diff_win_options(wp, addbuf)
 
 /*
  * Set options not to show diffs.  For the current window or all windows.
+ * Only in the current tab page.
  */
     void
 ex_diffoff(eap)
--- a/src/eval.c
+++ b/src/eval.c
@@ -15509,11 +15509,13 @@ var2fpos(varp, lnum)
 	pos.col = 0;
 	if (name[1] == '0')		/* "w0": first visible line */
 	{
+	    update_topline();
 	    pos.lnum = curwin->w_topline;
 	    return &pos;
 	}
 	else if (name[1] == '$')	/* "w$": last visible line */
 	{
+	    validate_botline();
 	    pos.lnum = curwin->w_botline - 1;
 	    return &pos;
 	}
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -1761,8 +1761,9 @@ alist_check_arg_idx()
 {
 #ifdef FEAT_WINDOWS
     win_T	*win;
-
-    for (win = firstwin; win != NULL; win = win->w_next)
+    tabpage_T	*tp;
+
+    FOR_ALL_TAB_WINDOWS(tp, win)
 	if (win->w_alist == curwin->w_alist)
 	    check_arg_idx(win);
 #else
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -148,7 +148,7 @@ static void	ex_cquit __ARGS((exarg_T *ea
 static void	ex_quit_all __ARGS((exarg_T *eap));
 #ifdef FEAT_WINDOWS
 static void	ex_close __ARGS((exarg_T *eap));
-static void	ex_win_close __ARGS((int forceit, win_T *win));
+static void	ex_win_close __ARGS((int forceit, win_T *win, tabpage_T *tp));
 static void	ex_only __ARGS((exarg_T *eap));
 static void	ex_all __ARGS((exarg_T *eap));
 static void	ex_resize __ARGS((exarg_T *eap));
@@ -6144,7 +6144,7 @@ ex_close(eap)
     else
 # endif
 	if (!text_locked())
-	    ex_win_close(eap->forceit, curwin);
+	    ex_win_close(eap->forceit, curwin, NULL);
 }
 
 #ifdef FEAT_QUICKFIX
@@ -6160,16 +6160,21 @@ ex_pclose(eap)
     for (win = firstwin; win != NULL; win = win->w_next)
 	if (win->w_p_pvw)
 	{
-	    ex_win_close(eap->forceit, win);
+	    ex_win_close(eap->forceit, win, NULL);
 	    break;
 	}
 }
 #endif
 
-    static void
-ex_win_close(forceit, win)
+/*
+ * Close window "win" and take care of handling closing the last window for a
+ * modified buffer.
+ */
+    static void
+ex_win_close(forceit, win, tp)
     int		forceit;
     win_T	*win;
+    tabpage_T	*tp;		/* NULL or the tab page "win" is in */
 {
     int		need_hide;
     buf_T	*buf = win->w_buffer;
@@ -6196,36 +6201,90 @@ ex_win_close(forceit, win)
 #ifdef FEAT_GUI
     need_mouse_correct = TRUE;
 #endif
+
     /* free buffer when not hiding it or when it's a scratch buffer */
-    win_close(win, !need_hide && !P_HID(buf));
-}
-
-/*
- * ":tabclose": close current tab page, unless it is the last one
+    if (tp == NULL)
+	win_close(win, !need_hide && !P_HID(buf));
+    else
+	win_close_othertab(win, !need_hide && !P_HID(buf), tp);
+}
+
+/*
+ * ":tabclose": close current tab page, unless it is the last one.
+ * ":tabclose N": close tab page N.
  */
     static void
 ex_tabclose(eap)
     exarg_T	*eap;
 {
+    tabpage_T	*tp;
+
 # ifdef FEAT_CMDWIN
     if (cmdwin_type != 0)
 	cmdwin_result = K_IGNORE;
     else
 # endif
-	if (!text_locked())
-	{
-	    if (first_tabpage->tp_next == NULL)
-		EMSG(_("E999: Cannot close last tab page"));
-	    else
-	    {
-		/* First close all the windows but the current one.  If that
-		 * worked then close the last window in this tab, that will
-		 * close it. */
-		ex_only(eap);
-		if (lastwin == firstwin)
-		    ex_win_close(eap->forceit, curwin);
-	    }
-	}
+	if (first_tabpage->tp_next == NULL)
+	    EMSG(_("E999: Cannot close last tab page"));
+	else
+	{
+	    if (eap->addr_count > 0)
+	    {
+		tp = find_tabpage((int)eap->line2);
+		if (tp == NULL)
+		{
+		    beep_flush();
+		    return;
+		}
+		if (tp->tp_topframe != topframe)
+		{
+		    tabpage_close_other(tp, eap->forceit);
+		    return;
+		}
+	    }
+	    if (!text_locked())
+		tabpage_close(eap->forceit);
+	}
+}
+
+/*
+ * Close the current tab page.
+ */
+    void
+tabpage_close(forceit)
+    int	    forceit;
+{
+    /* First close all the windows but the current one.  If that worked then
+     * close the last window in this tab, that will close it. */
+    close_others(TRUE, forceit);
+    if (lastwin == firstwin)
+	ex_win_close(forceit, curwin, NULL);
+# ifdef FEAT_GUI
+    need_mouse_correct = TRUE;
+# endif
+}
+
+/*
+ * Close tab page "tp", which is not the current tab page.
+ * Note that autocommands may make "tp" invalid.
+ */
+    void
+tabpage_close_other(tp, forceit)
+    tabpage_T	*tp;
+    int		forceit;
+{
+    int		done = 0;
+
+    /* Limit to 1000 windows, autocommands may add a window while we close
+     * one.  OK, so I'm paranoid... */
+    while (++done < 1000)
+    {
+	ex_win_close(forceit, tp->tp_firstwin, tp);
+
+	/* Autocommands may delete the tab page under our fingers. */
+	if (!valid_tabpage(tp))
+	    break;
+    }
 }
 
 /*
@@ -6689,13 +6748,14 @@ alist_slash_adjust()
     int		i;
 # ifdef FEAT_WINDOWS
     win_T	*wp;
+    tabpage_T	*tp;
 # endif
 
     for (i = 0; i < GARGCOUNT; ++i)
 	if (GARGLIST[i].ae_fname != NULL)
 	    slash_adjust(GARGLIST[i].ae_fname);
 # ifdef FEAT_WINDOWS
-    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+    FOR_ALL_TAB_WINDOWS(tp, wp)
 	if (wp->w_alist != &global_alist)
 	    for (i = 0; i < WARGCOUNT(wp); ++i)
 		if (WARGLIST(wp)[i].ae_fname != NULL)
@@ -6925,7 +6985,8 @@ ex_tabedit(eap)
 # ifdef FEAT_SCROLLBIND
 	curwin->w_p_scb = FALSE;
 # endif
-	do_exedit(eap, NULL);
+	if (*eap->arg != NUL)
+	    do_exedit(eap, NULL);
     }
 
 # ifdef FEAT_BROWSE
--- a/src/globals.h
+++ b/src/globals.h
@@ -42,7 +42,7 @@ EXTERN long	Columns INIT(= 80);	/* nr of
 EXTERN schar_T	*ScreenLines INIT(= NULL);
 EXTERN sattr_T	*ScreenAttrs INIT(= NULL);
 EXTERN unsigned	*LineOffset INIT(= NULL);
-EXTERN char_u	*LineWraps INIT(= NULL);
+EXTERN char_u	*LineWraps INIT(= NULL);	/* line wraps to next line */
 
 #ifdef FEAT_MBYTE
 /*
@@ -61,6 +61,10 @@ EXTERN u8char_T	*ScreenLinesC2 INIT(= NU
 EXTERN schar_T	*ScreenLines2 INIT(= NULL);
 #endif
 
+#ifdef FEAT_WINDOWS
+EXTERN char_u	*TabPageIdxs INIT(= NULL);	/* indexes for tab page line */
+#endif
+
 EXTERN int	screen_Rows INIT(= 0);	    /* actual size of ScreenLines[] */
 EXTERN int	screen_Columns INIT(= 0);   /* actual size of ScreenLines[] */
 
@@ -482,6 +486,10 @@ EXTERN win_T	*lastwin;		/* last window *
 EXTERN win_T	*prevwin INIT(= NULL);	/* previous window */
 # define W_NEXT(wp) ((wp)->w_next)
 # define FOR_ALL_WINDOWS(wp) for (wp = firstwin; wp != NULL; wp = wp->w_next)
+#define FOR_ALL_TAB_WINDOWS(tp, wp) \
+    for ((tp) = first_tabpage; (tp) != NULL; (tp) = (tp)->tp_next) \
+	for ((wp) = ((tp)->tp_topframe == topframe) \
+		? firstwin : (tp)->tp_firstwin; (wp); (wp) = (wp)->w_next)
 #else
 # define firstwin curwin
 # define lastwin curwin
--- a/src/if_mzsch.c
+++ b/src/if_mzsch.c
@@ -1423,7 +1423,8 @@ get_window_count(void *data, int argc, S
     win_T   *w;
     int	    n = 0;
 
-    for (w = firstwin; w; w = w->w_next) ++n;
+    for (w = firstwin; w != NULL; w = w->w_next)
+	++n;
     return scheme_make_integer(n);
 }
 
@@ -1439,7 +1440,7 @@ get_window_list(void *data, int argc, Sc
     buf = get_buffer_arg(prim->name, 0, argc, argv);
     list = scheme_null;
 
-    for (w = firstwin; w; w = w->w_next)
+    for (w = firstwin; w != NULL; w = w->w_next)
         if (w->w_buffer == buf->buf)
 	    list = scheme_make_pair(window_new(w), list);
 
@@ -1500,7 +1501,7 @@ get_window_by_num(void *data, int argc, 
     if (fnum < 1)
 	scheme_signal_error(_("window index is out of range"));
 
-    for (win = firstwin; win; win = win->w_next, --fnum)
+    for (win = firstwin; win != NULL; win = win->w_next, --fnum)
         if (fnum == 1)	    /* to be 1-based */
 	    return window_new(win);
 
--- a/src/if_python.c
+++ b/src/if_python.c
@@ -2160,7 +2160,7 @@ WinListLength(PyObject *self)
     win_T	*w = firstwin;
     int		n = 0;
 
-    while (w)
+    while (w != NULL)
     {
 	++n;
 	w = W_NEXT(w);
@@ -2175,7 +2175,7 @@ WinListItem(PyObject *self, int n)
 {
     win_T *w;
 
-    for (w = firstwin; w; w = W_NEXT(w), --n)
+    for (w = firstwin; w != NULL; w = W_NEXT(w), --n)
 	if (n == 0)
 	    return WindowNew(w);
 
--- a/src/if_ruby.c
+++ b/src/if_ruby.c
@@ -726,7 +726,7 @@ static VALUE window_s_count()
     win_T	*w;
     int n = 0;
 
-    for (w = firstwin; w; w = w->w_next)
+    for (w = firstwin; w != NULL; w = w->w_next)
 	n++;
     return INT2NUM(n);
 #else
--- a/src/main.c
+++ b/src/main.c
@@ -1133,6 +1133,7 @@ getout(exitval)
 #ifdef FEAT_AUTOCMD
     buf_T	*buf;
     win_T	*wp;
+    tabpage_T	*tp, *next_tp;
 #endif
 
     exiting = TRUE;
@@ -1160,23 +1161,28 @@ getout(exitval)
 
 #ifdef FEAT_AUTOCMD
     /* Trigger BufWinLeave for all windows, but only once per buffer. */
-    for (wp = firstwin; wp != NULL; )
+# if defined FEAT_WINDOWS
+    for (tp = first_tabpage; tp != NULL; tp = next_tp)
     {
-	buf = wp->w_buffer;
-	if (buf->b_changedtick != -1)
+	next_tp = tp->tp_next;
+	for (wp = (tp->tp_topframe == topframe)
+		    ? firstwin : tp->tp_firstwin; wp != NULL; wp = wp->w_next)
 	{
-	    apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname,
+	    buf = wp->w_buffer;
+	    if (buf->b_changedtick != -1)
+	    {
+		apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname,
 								  FALSE, buf);
-	    buf->b_changedtick = -1;	/* note that we did it already */
-	    wp = firstwin;		/* restart, window may be closed */
+		buf->b_changedtick = -1;    /* note that we did it already */
+		/* start all over, autocommands may mess up the lists */
+		next_tp = first_tabpage;
+		break;
+	    }
 	}
-# ifdef FEAT_WINDOWS
-	else
-	    wp = wp->w_next;
+    }
 # else
-	break;
+    apply_autocmds(EVENT_BUFWINLEAVE, curbuf, curbuf->b_fname, FALSE, curbuf);
 # endif
-    }
 
     /* Trigger BufUnload for buffers that are loaded */
     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
--- a/src/mark.c
+++ b/src/mark.c
@@ -1500,11 +1500,12 @@ write_viminfo_marks(fp_out)
     int		i;
 #ifdef FEAT_WINDOWS
     win_T	*win;
+    tabpage_T	*tp;
 
     /*
      * Set b_last_cursor for the all buffers that have a window.
      */
-    for (win = firstwin; win != NULL; win = win->w_next)
+    FOR_ALL_TAB_WINDOWS(tp, win)
 	set_last_cursor(win);
 #else
 	set_last_cursor(curwin);
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -2458,6 +2458,7 @@ changed()
 	ml_setflags(curbuf);
 #ifdef FEAT_WINDOWS
 	check_status(curbuf);
+	redraw_tabpage = TRUE;
 #endif
 #ifdef FEAT_TITLE
 	need_maketitle = TRUE;	    /* set window title later */
@@ -2847,6 +2848,7 @@ unchanged(buf, ff)
 	    save_file_ff(buf);
 #ifdef FEAT_WINDOWS
 	check_status(buf);
+	redraw_tabpage = TRUE;
 #endif
 #ifdef FEAT_TITLE
 	need_maketitle = TRUE;	    /* set window title later */
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -2790,7 +2790,9 @@ set_fileformat(t, opt_flags)
 	set_string_option_direct((char_u *)"ff", -1, (char_u *)p,
 							OPT_FREE | opt_flags);
 #ifdef FEAT_WINDOWS
+    /* This may cause the buffer to become (un)modified. */
     check_status(curbuf);
+    redraw_tabpage = TRUE;
 #endif
 #ifdef FEAT_TITLE
     need_maketitle = TRUE;	    /* set window title later */
--- a/src/normal.c
+++ b/src/normal.c
@@ -2421,6 +2421,37 @@ do_mouse(oap, c, dir, count, fixindent)
 
     start_visual.lnum = 0;
 
+#ifdef FEAT_WINDOWS
+    /* Check for clicking in the tab page line. */
+    if (mouse_row == 0 && firstwin->w_winrow > 0)
+    {
+	got_click = FALSE;	/* ignore mouse-up and drag events */
+
+	/* click in last column closes the current tab page. */
+	if (mouse_col == Columns - 1 && first_tabpage->tp_next != NULL)
+	{
+	    tabpage_close(FALSE);
+	    return TRUE;
+	}
+
+	/* click in a tab selects that tab page */
+	if (is_click
+# ifdef FEAT_CMDWIN
+		&& cmdwin_type == 0
+# endif
+		&& mouse_col < Columns && TabPageIdxs[mouse_col] != 0xff)
+	{
+	    goto_tabpage(TabPageIdxs[mouse_col]);
+
+	    /* It's like clicking on the status line of a window. */
+	    if (curwin != old_curwin)
+		end_visual_mode();
+	    return TRUE;
+	}
+	return FALSE;
+    }
+#endif
+
     /*
      * When 'mousemodel' is "popup" or "popup_setpos", translate mouse events:
      * right button up   -> pop-up menu
--- a/src/option.c
+++ b/src/option.c
@@ -2653,6 +2653,7 @@ static char *(p_cot_values[]) = {"menu",
 
 static void set_option_default __ARGS((int, int opt_flags, int compatible));
 static void set_options_default __ARGS((int opt_flags));
+static char_u *term_bg_default __ARGS((void));
 static void did_set_option __ARGS((int opt_idx, int opt_flags, int new_value));
 static char_u *illegal_char __ARGS((char_u *, int));
 static int string_to_key __ARGS((char_u *arg));
@@ -3200,6 +3201,7 @@ set_options_default(opt_flags)
     int		i;
 #ifdef FEAT_WINDOWS
     win_T	*wp;
+    tabpage_T	*tp;
 #endif
 
     for (i = 0; !istermoption(&options[i]); i++)
@@ -3208,7 +3210,7 @@ set_options_default(opt_flags)
 
 #ifdef FEAT_WINDOWS
     /* The 'scroll' option must be computed for all windows. */
-    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+    FOR_ALL_TAB_WINDOWS(tp, wp)
 	win_comp_scroll(wp);
 #else
 	win_comp_scroll(curwin);
@@ -3306,39 +3308,20 @@ set_init_2()
 	p_window = Rows - 1;
     set_number_default("window", Rows - 1);
 
+    /* For DOS console the default is always black. */
 #if !((defined(MSDOS) || defined(OS2) || defined(WIN3264)) && !defined(FEAT_GUI))
-    {
-	char_u	*p;
-
-	/*
-	 * If 'background' wasn't set by the user, try guessing the value,
-	 * depending on the terminal name.  Only need to check for terminals
-	 * with a dark background, that can handle color.  Recognized are:
-	 * "linux"	    Linux console
-	 * "screen.linux"   Linux console with screen
-	 * "cygwin"	    Cygwin shell
-	 * "putty"	    Putty program
-	 * We also check the COLORFGBG environment variable, which is set by
-	 * rxvt and derivatives. This variable contains either two or three
-	 * values separated by semicolons; we want the last value in either
-	 * case. If this value is 0-6 or 8, our background is dark.
-	 */
-	idx = findoption((char_u *)"bg");
-	if (!(options[idx].flags & P_WAS_SET)
-		&& (STRCMP(T_NAME, "linux") == 0
-		    || STRCMP(T_NAME, "screen.linux") == 0
-		    || STRCMP(T_NAME, "cygwin") == 0
-		    || STRCMP(T_NAME, "putty") == 0
-		    || ((p = mch_getenv((char_u *)"COLORFGBG")) != NULL
-			&& (p = vim_strrchr(p, ';')) != NULL
-			&& ((p[1] >= '0' && p[1] <= '6') || p[1] == '8')
-			&& p[2] == NUL)))
-	{
-	    set_string_option_direct(NULL, idx, (char_u *)"dark", OPT_FREE);
-	    /* don't mark it as set, when starting the GUI it may be
-	     * changed again */
-	    options[idx].flags &= ~P_WAS_SET;
-	}
+    /*
+     * If 'background' wasn't set by the user, try guessing the value,
+     * depending on the terminal name.  Only need to check for terminals
+     * with a dark background, that can handle color.
+     */
+    idx = findoption((char_u *)"bg");
+    if (!(options[idx].flags & P_WAS_SET) && *term_bg_default() == 'd')
+    {
+	set_string_option_direct(NULL, idx, (char_u *)"dark", OPT_FREE);
+	/* don't mark it as set, when starting the GUI it may be
+	 * changed again */
+	options[idx].flags &= ~P_WAS_SET;
     }
 #endif
 
@@ -3354,6 +3337,40 @@ set_init_2()
 }
 
 /*
+ * Return "dark" or "light" depending on the kind of terminal.
+ * This is just guessing!  Recognized are:
+ * "linux"	    Linux console
+ * "screen.linux"   Linux console with screen
+ * "cygwin"	    Cygwin shell
+ * "putty"	    Putty program
+ * We also check the COLORFGBG environment variable, which is set by
+ * rxvt and derivatives. This variable contains either two or three
+ * values separated by semicolons; we want the last value in either
+ * case. If this value is 0-6 or 8, our background is dark.
+ */
+    static char_u *
+term_bg_default()
+{
+    char_u	*p;
+
+#if defined(MSDOS) || defined(OS2) || defined(WIN3264)
+    /* DOS console nearly always black */
+    return (char_u *)"dark";
+#else
+    if (STRCMP(T_NAME, "linux") == 0
+	    || STRCMP(T_NAME, "screen.linux") == 0
+	    || STRCMP(T_NAME, "cygwin") == 0
+	    || STRCMP(T_NAME, "putty") == 0
+	    || ((p = mch_getenv((char_u *)"COLORFGBG")) != NULL
+		&& (p = vim_strrchr(p, ';')) != NULL
+		&& ((p[1] >= '0' && p[1] <= '6') || p[1] == '8')
+		&& p[2] == NUL))
+	return (char_u *)"dark";
+    return (char_u *)"light";
+#endif
+}
+
+/*
  * Initialize the options, part three: After reading the .vimrc
  */
     void
@@ -4071,8 +4088,7 @@ do_set(arg, opt_flags)
 				    newval = gui_bg_default();
 				else
 #endif
-				    if (STRCMP(T_NAME, "linux") == 0)
-					newval = (char_u *)"dark";
+				    newval = term_bg_default();
 			    }
 
 			    /* expand environment variables and ~ (since the
--- a/src/proto/ex_docmd.pro
+++ b/src/proto/ex_docmd.pro
@@ -23,6 +23,8 @@ char_u *get_user_cmd_nargs __ARGS((expan
 char_u *get_user_cmd_complete __ARGS((expand_T *xp, int idx));
 int parse_compl_arg __ARGS((char_u *value, int vallen, int *complp, long *argt, char_u **compl_arg));
 void not_exiting __ARGS((void));
+void tabpage_close __ARGS((int forceit));
+void tabpage_close_other __ARGS((tabpage_T *tp, int forceit));
 void handle_drop __ARGS((int filec, char_u **filev, int split));
 void alist_clear __ARGS((alist_T *al));
 void alist_init __ARGS((alist_T *al));
--- a/src/proto/window.pro
+++ b/src/proto/window.pro
@@ -6,15 +6,18 @@ int win_count __ARGS((void));
 int make_windows __ARGS((int count, int vertical));
 void win_move_after __ARGS((win_T *win1, win_T *win2));
 void win_equal __ARGS((win_T *next_curwin, int current, int dir));
-void close_windows __ARGS((buf_T *buf));
+void close_windows __ARGS((buf_T *buf, int keep_curwin));
 int last_window __ARGS((void));
 void win_close __ARGS((win_T *win, int free_buf));
+void win_close_othertab __ARGS((win_T *win, int free_buf, tabpage_T *tp));
 void win_free_all __ARGS((void));
 void close_others __ARGS((int message, int forceit));
 void win_init __ARGS((win_T *wp));
 int win_alloc_first __ARGS((void));
 void win_init_size __ARGS((void));
 int win_new_tabpage __ARGS((void));
+int valid_tabpage __ARGS((tabpage_T *tpc));
+tabpage_T *find_tabpage __ARGS((int n));
 void goto_tabpage __ARGS((int n));
 void win_goto __ARGS((win_T *wp));
 win_T *win_find_nr __ARGS((int winnr));
--- a/src/screen.c
+++ b/src/screen.c
@@ -6742,6 +6742,10 @@ screenalloc(clear)
     sattr_T	    *new_ScreenAttrs;
     unsigned	    *new_LineOffset;
     char_u	    *new_LineWraps;
+#ifdef FEAT_WINDOWS
+    char_u	    *new_TabPageIdxs;
+    tabpage_T	    *tp;
+#endif
     static int	    entered = FALSE;		/* avoid recursiveness */
     static int	    did_outofmem_msg = FALSE;	/* did outofmem message */
 
@@ -6788,10 +6792,10 @@ screenalloc(clear)
      * size is wrong.
      */
 #ifdef FEAT_WINDOWS
-    for (wp = firstwin; wp; wp = wp->w_next)
+    FOR_ALL_TAB_WINDOWS(tp, wp)
 	win_free_lsize(wp);
 #else
-	win_free_lsize(curwin);
+    win_free_lsize(curwin);
 #endif
 
     new_ScreenLines = (schar_T *)lalloc((long_u)(
@@ -6815,6 +6819,9 @@ screenalloc(clear)
     new_LineOffset = (unsigned *)lalloc((long_u)(
 					 Rows * sizeof(unsigned)), FALSE);
     new_LineWraps = (char_u *)lalloc((long_u)(Rows * sizeof(char_u)), FALSE);
+#ifdef FEAT_WINDOWS
+    new_TabPageIdxs = (char_u *)lalloc((long_u)(Columns * sizeof(char_u)), FALSE);
+#endif
 
     FOR_ALL_WINDOWS(wp)
     {
@@ -6836,6 +6843,9 @@ screenalloc(clear)
 	    || new_ScreenAttrs == NULL
 	    || new_LineOffset == NULL
 	    || new_LineWraps == NULL
+#ifdef FEAT_WINDOWS
+	    || new_TabPageIdxs == NULL
+#endif
 	    || outofmem)
     {
 	if (ScreenLines != NULL || !did_outofmem_msg)
@@ -6865,6 +6875,10 @@ screenalloc(clear)
 	new_LineOffset = NULL;
 	vim_free(new_LineWraps);
 	new_LineWraps = NULL;
+#ifdef FEAT_WINDOWS
+	vim_free(new_TabPageIdxs);
+	new_TabPageIdxs = NULL;
+#endif
     }
     else
     {
@@ -6956,6 +6970,9 @@ screenalloc(clear)
     ScreenAttrs = new_ScreenAttrs;
     LineOffset = new_LineOffset;
     LineWraps = new_LineWraps;
+#ifdef FEAT_WINDOWS
+    TabPageIdxs = new_TabPageIdxs;
+#endif
 
     /* It's important that screen_Rows and screen_Columns reflect the actual
      * size of ScreenLines[].  Set them before calling anything. */
@@ -7005,6 +7022,9 @@ free_screenlines()
     vim_free(ScreenAttrs);
     vim_free(LineOffset);
     vim_free(LineWraps);
+#ifdef FEAT_WINDOWS
+    vim_free(TabPageIdxs);
+#endif
 }
 
     void
@@ -8443,9 +8463,13 @@ draw_tabpage()
     tabpage_T	*tp;
     int		tabwidth;
     int		col = 0;
+    int		scol;
     int		had_current = FALSE;
     int		attr;
     win_T	*wp;
+    win_T	*cwp;
+    int		wincount;
+    int		modified;
     int		c;
     int		len;
     int		attr_sel = hl_attr(HLF_TPS);
@@ -8460,13 +8484,16 @@ draw_tabpage()
     for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
 	++tabcount;
 
-    tabwidth = Columns / tabcount;
+    tabwidth = (Columns - 1 + tabcount / 2) / tabcount;
     if (tabwidth < 6)
 	tabwidth = 6;
 
     attr = attr_nosel;
-    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
-    {
+    tabcount = 0;
+    for (tp = first_tabpage; tp != NULL && col < Columns; tp = tp->tp_next)
+    {
+	scol = col;
+
 	if (tp->tp_topframe == topframe)
 	{
 	    c = '/';
@@ -8486,21 +8513,55 @@ draw_tabpage()
 	screen_putchar(' ', 0, col++, attr);
 
 	if (tp->tp_topframe == topframe)
-	    wp = curwin;
+	{
+	    cwp = curwin;
+	    wp = firstwin;
+	}
 	else
-	    wp = tp->tp_curwin;
-	if (buf_spname(wp->w_buffer) != NULL)
-	    STRCPY(NameBuff, buf_spname(wp->w_buffer));
+	{
+	    cwp = tp->tp_curwin;
+	    wp = tp->tp_firstwin;
+	}
+
+	modified = FALSE;
+	for (wincount = 0; wp != NULL; wp = wp->w_next, ++wincount)
+	    if (bufIsChanged(wp->w_buffer))
+		modified = TRUE;
+	if (modified || wincount > 1)
+	{
+	    if (wincount > 1)
+	    {
+		vim_snprintf((char *)NameBuff, MAXPATHL, "#%d", wincount);
+		len = STRLEN(NameBuff);
+		screen_puts_len(NameBuff, len, 0, col, attr);
+		col += len;
+	    }
+	    if (modified)
+		screen_puts_len((char_u *)"+", 2, 0, col++, attr);
+	    screen_putchar(' ', 0, col++, attr);
+	}
+
+	if (buf_spname(cwp->w_buffer) != NULL)
+	    STRCPY(NameBuff, buf_spname(cwp->w_buffer));
 	else
-	    home_replace(wp->w_buffer, wp->w_buffer->b_fname, NameBuff,
+	    home_replace(cwp->w_buffer, cwp->w_buffer->b_fname, NameBuff,
 							      MAXPATHL, TRUE);
 	trans_characters(NameBuff, MAXPATHL);
 	len = STRLEN(NameBuff);
-	if (len > tabwidth) /* TODO: multi-byte chars */
-	    len = tabwidth;
-	screen_puts_len(NameBuff, len, 0, col, attr);
-	col += len;
+	if (len > scol - col + tabwidth - 1) /* TODO: multi-byte chars */
+	    len = scol - col + tabwidth - 1;
+	if (len > 0)
+	{
+	    screen_puts_len(NameBuff, len, 0, col, attr);
+	    col += len;
+	}
 	screen_putchar(' ', 0, col++, attr);
+
+	/* Store the tab page number in TabPageIdxs[], so that jump_to_mouse()
+	 * knows where each one is. */
+	++tabcount;
+	while (scol < col)
+	    TabPageIdxs[scol++] = tabcount;
     }
 
     if (t_colors < 8)
@@ -8511,6 +8572,14 @@ draw_tabpage()
     else
 	c = ' ';
     screen_fill(0, 1, col, (int)Columns, c, c, attr_fill);
+
+    /* Put an "X" for closing the current tab if there are several. */
+    if (first_tabpage->tp_next != NULL)
+	screen_putchar('X', 0, (int)Columns - 1, attr_nosel);
+
+    /* Clicking outside of tabs has no effect. */
+    while (scol < Columns)
+	TabPageIdxs[scol++] = 0xff;
 }
 #endif
 
--- a/src/structs.h
+++ b/src/structs.h
@@ -1558,6 +1558,7 @@ struct tabpage_S
     tabpage_T	    *tp_next;	    /* next tabpage or NULL */
     frame_T	    *tp_topframe;   /* topframe for the windows */
     win_T	    *tp_curwin;	    /* current window in this Tab page */
+    win_T	    *tp_prevwin;    /* previous window in this Tab page */
     win_T	    *tp_firstwin;   /* first window in this Tab page */
     win_T	    *tp_lastwin;    /* last window in this Tab page */
     long	    tp_old_Rows;    /* Rows when Tab page was left */
--- a/src/version.h
+++ b/src/version.h
@@ -36,5 +36,5 @@
 #define VIM_VERSION_NODOT	"vim70aa"
 #define VIM_VERSION_SHORT	"7.0aa"
 #define VIM_VERSION_MEDIUM	"7.0aa ALPHA"
-#define VIM_VERSION_LONG	"VIM - Vi IMproved 7.0aa ALPHA (2006 Feb 15)"
-#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0aa ALPHA (2006 Feb 15, compiled "
+#define VIM_VERSION_LONG	"VIM - Vi IMproved 7.0aa ALPHA (2006 Feb 16)"
+#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0aa ALPHA (2006 Feb 16, compiled "
--- a/src/window.c
+++ b/src/window.c
@@ -25,9 +25,9 @@ static void win_exchange __ARGS((long));
 static void win_rotate __ARGS((int, int));
 static void win_totop __ARGS((int size, int flags));
 static void win_equal_rec __ARGS((win_T *next_curwin, int current, frame_T *topfr, int dir, int col, int row, int width, int height));
-static win_T *win_free_mem __ARGS((win_T *win, int *dirp));
-static win_T *winframe_remove __ARGS((win_T *win, int *dirp));
-static frame_T *win_altframe __ARGS((win_T *win));
+static win_T *win_free_mem __ARGS((win_T *win, int *dirp, tabpage_T *tp));
+static win_T *winframe_remove __ARGS((win_T *win, int *dirp, tabpage_T *tp));
+static frame_T *win_altframe __ARGS((win_T *win, tabpage_T *tp));
 static tabpage_T *alt_tabpage __ARGS((void));
 static win_T *frame2win __ARGS((frame_T *frp));
 static int frame_has_win __ARGS((frame_T *frp, win_T *wp));
@@ -49,9 +49,9 @@ static void enter_tabpage __ARGS((tabpag
 static void frame_fix_height __ARGS((win_T *wp));
 static int frame_minheight __ARGS((frame_T *topfrp, win_T *next_curwin));
 static void win_enter_ext __ARGS((win_T *wp, int undo_sync, int no_curwin));
-static void win_free __ARGS((win_T *wp));
+static void win_free __ARGS((win_T *wp, tabpage_T *tp));
 static void win_append __ARGS((win_T *, win_T *));
-static void win_remove __ARGS((win_T *));
+static void win_remove __ARGS((win_T *, tabpage_T *tp));
 static void frame_append __ARGS((frame_T *after, frame_T *frp));
 static void frame_insert __ARGS((frame_T *before, frame_T *frp));
 static void frame_remove __ARGS((frame_T *frp));
@@ -1262,14 +1262,14 @@ win_exchange(Prenum)
     frp2 = curwin->w_frame->fr_prev;
     if (wp->w_prev != curwin)
     {
-	win_remove(curwin);
+	win_remove(curwin, NULL);
 	frame_remove(curwin->w_frame);
 	win_append(wp->w_prev, curwin);
 	frame_insert(frp, curwin->w_frame);
     }
     if (wp != wp2)
     {
-	win_remove(wp);
+	win_remove(wp, NULL);
 	frame_remove(wp->w_frame);
 	win_append(wp2, wp);
 	if (frp2 == NULL)
@@ -1353,7 +1353,7 @@ win_rotate(upwards, count)
 	    /* remove first window/frame from the list */
 	    frp = curwin->w_frame->fr_parent->fr_child;
 	    wp1 = frp->fr_win;
-	    win_remove(wp1);
+	    win_remove(wp1, NULL);
 	    frame_remove(frp);
 
 	    /* find last frame and append removed window/frame after it */
@@ -1372,7 +1372,7 @@ win_rotate(upwards, count)
 		;
 	    wp1 = frp->fr_win;
 	    wp2 = wp1->w_prev;		    /* will become last window */
-	    win_remove(wp1);
+	    win_remove(wp1, NULL);
 	    frame_remove(frp);
 
 	    /* append the removed window/frame before the first in the list */
@@ -1419,8 +1419,8 @@ win_totop(size, flags)
     }
 
     /* Remove the window and frame from the tree of frames. */
-    (void)winframe_remove(curwin, &dir);
-    win_remove(curwin);
+    (void)winframe_remove(curwin, &dir, NULL);
+    win_remove(curwin, NULL);
     last_status(FALSE);	    /* may need to remove last status line */
     (void)win_comp_pos();   /* recompute window positions */
 
@@ -1486,7 +1486,7 @@ win_move_after(win1, win2)
 	    win1->w_vsep_width = 0;
 #endif
 	}
-	win_remove(win1);
+	win_remove(win1, NULL);
 	frame_remove(win1->w_frame);
 	win_append(win2, win1);
 	frame_append(win2->w_frame, win1->w_frame);
@@ -1797,23 +1797,50 @@ win_equal_rec(next_curwin, current, topf
  * close all windows for buffer 'buf'
  */
     void
-close_windows(buf)
+close_windows(buf, keep_curwin)
     buf_T	*buf;
+    int		keep_curwin;	    /* don't close "curwin" */
 {
-    win_T	*win;
+    win_T	*wp;
+    tabpage_T   *tp, *nexttp;
+    int		h = tabpageline_height();
 
     ++RedrawingDisabled;
-    for (win = firstwin; win != NULL && lastwin != firstwin; )
+
+    for (wp = firstwin; wp != NULL && lastwin != firstwin; )
     {
-	if (win->w_buffer == buf)
+	if (wp->w_buffer == buf && (!keep_curwin || wp != curwin))
 	{
-	    win_close(win, FALSE);
-	    win = firstwin;	    /* go back to the start */
+	    win_close(wp, FALSE);
+
+	    /* Start all over, autocommands may change the window layout. */
+	    wp = firstwin;
 	}
 	else
-	    win = win->w_next;
+	    wp = wp->w_next;
     }
+
+    /* Also check windows in other tab pages. */
+    for (tp = first_tabpage; tp != NULL; tp = nexttp)
+    {
+	nexttp = tp->tp_next;
+	if (tp->tp_topframe != topframe)
+	    for (wp = tp->tp_firstwin; wp != NULL; wp = wp->w_next)
+		if (wp->w_buffer == buf)
+		{
+		    win_close_othertab(wp, FALSE, tp);
+
+		    /* Start all over, the tab page may be closed and
+		     * autocommands may change the window layout. */
+		    nexttp = first_tabpage;
+		    break;
+		}
+    }
+
     --RedrawingDisabled;
+
+    if (h != tabpageline_height())
+	shell_new_rows();
 }
 
 /*
@@ -1827,7 +1854,7 @@ last_window()
 }
 
 /*
- * close window "win"
+ * Close window "win".
  * If "free_buf" is TRUE related buffer may be unloaded.
  *
  * called by :quit, :close, :xit, :wq and findtag()
@@ -1866,7 +1893,7 @@ win_close(win, free_buf)
 	 * Guess which window is going to be the new current window.
 	 * This may change because of the autocommands (sigh).
 	 */
-	wp = frame2win(win_altframe(win));
+	wp = frame2win(win_altframe(win, NULL));
 
 	/*
 	 * Be careful: If autocommands delete the window, return now.
@@ -1899,7 +1926,7 @@ win_close(win, free_buf)
 	return;
 
     /* Free the memory used for the window. */
-    wp = win_free_mem(win, &dir);
+    wp = win_free_mem(win, &dir, NULL);
 
     /* When closing the last window in a tab page go to another tab page. */
     if (wp == NULL)
@@ -2004,13 +2031,70 @@ win_close(win, free_buf)
 }
 
 /*
+ * Close window "win" in tab page "tp", which is not the current tab page.
+ * This may be the last window ih that tab page and result in closing the tab,
+ * thus "tp" may become invalid!
+ * Called must check if buffer is hidden.
+ */
+    void
+win_close_othertab(win, free_buf, tp)
+    win_T	*win;
+    int		free_buf;
+    tabpage_T	*tp;
+{
+    win_T	*wp;
+    int		dir;
+    tabpage_T   *ptp = NULL;
+
+    /* Close the link to the buffer. */
+    close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0);
+
+    /* Careful: Autocommands may have closed the tab page or made it the
+     * current tab page.  */
+    for (ptp = first_tabpage; ptp != NULL && ptp != tp; ptp = ptp->tp_next)
+	;
+    if (ptp == NULL || tp->tp_topframe == topframe)
+	return;
+
+    /* Autocommands may have closed the window already. */
+    for (wp = tp->tp_firstwin; wp != NULL && wp != win; wp = wp->w_next)
+	;
+    if (wp == NULL)
+	return;
+
+    /* Free the memory used for the window. */
+    wp = win_free_mem(win, &dir, tp);
+
+    /* When closing the last window in a tab page remove the tab page. */
+    if (wp == NULL)
+    {
+	if (tp == first_tabpage)
+	    first_tabpage = tp->tp_next;
+	else
+	{
+	    for (ptp = first_tabpage; ptp != NULL && ptp->tp_next != tp;
+							   ptp = ptp->tp_next)
+		;
+	    if (ptp == NULL)
+	    {
+		EMSG2(_(e_intern2), "win_close_othertab()");
+		return;
+	    }
+	    ptp->tp_next = tp->tp_next;
+	}
+	vim_free(tp);
+    }
+}
+
+/*
  * Free the memory used for a window.
  * Returns a pointer to the window that got the freed up space.
  */
     static win_T *
-win_free_mem(win, dirp)
+win_free_mem(win, dirp, tp)
     win_T	*win;
     int		*dirp;		/* set to 'v' or 'h' for direction if 'ea' */
+    tabpage_T	*tp;		/* tab page "win" is in, NULL for current */
 {
     frame_T	*frp;
     win_T	*wp;
@@ -2024,13 +2108,9 @@ win_free_mem(win, dirp)
 
     /* Remove the window and its frame from the tree of frames. */
     frp = win->w_frame;
-    if (firstwin == lastwin)
-	/* Last window in a tab page. */
-	wp = NULL;
-    else
-	wp = winframe_remove(win, dirp);
+    wp = winframe_remove(win, dirp, tp);
     vim_free(frp);
-    win_free(win);
+    win_free(win, tp);
 
     return wp;
 }
@@ -2041,8 +2121,13 @@ win_free_all()
 {
     int		dummy;
 
+# ifdef FEAT_WINDOWS
+    while (first_tabpage->tp_next != NULL)
+	tabpage_close(TRUE);
+# endif
+
     while (firstwin != NULL)
-	(void)win_free_mem(firstwin, &dummy);
+	(void)win_free_mem(firstwin, &dummy, NULL);
 }
 #endif
 
@@ -2052,9 +2137,10 @@ win_free_all()
  */
 /*ARGSUSED*/
     static win_T *
-winframe_remove(win, dirp)
+winframe_remove(win, dirp, tp)
     win_T	*win;
     int		*dirp;		/* set to 'v' or 'h' for direction if 'ea' */
+    tabpage_T	*tp;		/* tab page "win" is in, NULL for current */
 {
     frame_T	*frp, *frp2, *frp3;
     frame_T	*frp_close = win->w_frame;
@@ -2062,12 +2148,15 @@ winframe_remove(win, dirp)
     int		old_height = 0;
 
     /*
+     * If there is only one window there is nothing to remove.
+     */
+    if (tp == NULL ? firstwin == lastwin : tp->tp_firstwin == tp->tp_lastwin)
+	return NULL;
+
+    /*
      * Remove the window from its frame.
      */
-    frp2 = win_altframe(win);
-    if (frp2 == NULL)
-	return NULL;	    /* deleted the last frame */
-
+    frp2 = win_altframe(win, tp);
     wp = frame2win(frp2);
 
     /* Remove this frame from the list of frames. */
@@ -2160,13 +2249,14 @@ winframe_remove(win, dirp)
  * layout.
  */
     static frame_T *
-win_altframe(win)
+win_altframe(win, tp)
     win_T	*win;
+    tabpage_T	*tp;		/* tab page "win" is in, NULL for current */
 {
     frame_T	*frp;
     int		b;
 
-    if (firstwin == lastwin)
+    if (tp == NULL ? firstwin == lastwin : tp->tp_firstwin == tp->tp_lastwin)
 	/* Last window in this tab page, will go to next tab page. */
 	return alt_tabpage()->tp_curwin->w_frame;
 
@@ -2861,6 +2951,7 @@ win_new_tabpage()
 	firstwin->w_winrow = tabpageline_height();
 
 	newtp->tp_topframe = topframe;
+	last_status(FALSE);
 	redraw_all_later(CLEAR);
 	return OK;
     }
@@ -2868,6 +2959,7 @@ win_new_tabpage()
     /* Failed, get back the previous Tab page */
     topframe = tp->tp_topframe;
     curwin = tp->tp_curwin;
+    prevwin = tp->tp_prevwin;
     firstwin = tp->tp_firstwin;
     lastwin = tp->tp_lastwin;
     return FAIL;
@@ -2890,6 +2982,36 @@ current_tabpage()
 }
 
 /*
+ * Return TRUE when "tpc" points to a valid tab page.
+ */
+    int
+valid_tabpage(tpc)
+    tabpage_T	*tpc;
+{
+    tabpage_T	*tp;
+
+    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+	if (tp == tpc)
+	    return TRUE;
+    return FALSE;
+}
+
+/*
+ * Find tab page "n" (first one is 1).  Returns NULL when not found.
+ */
+    tabpage_T *
+find_tabpage(n)
+    int		n;
+{
+    tabpage_T	*tp;
+    int		i = 1;
+
+    for (tp = first_tabpage; tp != NULL && i != n; tp = tp->tp_next)
+	++i;
+    return tp;
+}
+
+/*
  * Prepare for leaving the current tab page "tp".
  */
     static void
@@ -2902,6 +3024,7 @@ leave_tabpage(tp)
 	gui_remove_scrollbars();
 #endif
     tp->tp_curwin = curwin;
+    tp->tp_prevwin = prevwin;
     tp->tp_firstwin = firstwin;
     tp->tp_lastwin = lastwin;
     tp->tp_old_Rows = Rows;
@@ -2925,6 +3048,7 @@ enter_tabpage(tp, old_curbuf)
     lastwin = tp->tp_lastwin;
     topframe = tp->tp_topframe;
     win_enter_ext(tp->tp_curwin, FALSE, TRUE);
+    prevwin = tp->tp_prevwin;
 
 #ifdef FEAT_AUTOCMD
     if (old_curbuf != curbuf)
@@ -2985,12 +3109,13 @@ goto_tabpage(n)
     {
 	/* Go to tab page "n". */
 	i = 0;
-	for (tp = first_tabpage; ++i != n; tp = tp->tp_next)
-	    if (tp == NULL)
-	    {
-		beep_flush();
-		return;
-	    }
+	for (tp = first_tabpage; ++i != n && tp != NULL; tp = tp->tp_next)
+	    ;
+	if (tp == NULL)
+	{
+	    beep_flush();
+	    return;
+	}
     }
 
     leave_tabpage(otp);
@@ -3418,8 +3543,9 @@ win_alloc(after)
  * remove window 'wp' from the window list and free the structure
  */
     static void
-win_free(wp)
+win_free(wp, tp)
     win_T	*wp;
+    tabpage_T	*tp;		/* tab page "win" is in, NULL for current */
 {
     int		i;
 
@@ -3478,7 +3604,7 @@ win_free(wp)
     }
 #endif /* FEAT_GUI */
 
-    win_remove(wp);
+    win_remove(wp, tp);
     vim_free(wp);
 }
 
@@ -3512,17 +3638,22 @@ win_append(after, wp)
  * Remove a window from the window list.
  */
     static void
-win_remove(wp)
+win_remove(wp, tp)
     win_T	*wp;
+    tabpage_T	*tp;		/* tab page "win" is in, NULL for current */
 {
     if (wp->w_prev != NULL)
 	wp->w_prev->w_next = wp->w_next;
+    else if (tp == NULL)
+	firstwin = wp->w_next;
     else
-	firstwin = wp->w_next;
+	tp->tp_firstwin = wp->w_next;
     if (wp->w_next != NULL)
 	wp->w_next->w_prev = wp->w_prev;
+    else if (tp == NULL)
+	lastwin = wp->w_prev;
     else
-	lastwin = wp->w_prev;
+	tp->tp_lastwin = wp->w_prev;
 }
 
 /*
@@ -3600,6 +3731,7 @@ win_free_lsize(wp)
 
 /*
  * Called from win_new_shellsize() after Rows changed.
+ * This only does the current tab page, others must be done when made active.
  */
     void
 shell_new_rows()
@@ -5115,16 +5247,27 @@ vim_FullName(fname, buf, len, force)
 min_rows()
 {
     int		total;
+#ifdef FEAT_WINDOWS
+    tabpage_T	*tp;
+    int		n;
+#endif
 
     if (firstwin == NULL)	/* not initialized yet */
 	return MIN_LINES;
 
-    total = 1;		/* count the room for the command line */
 #ifdef FEAT_WINDOWS
-    total += frame_minheight(topframe, NULL);
+    total = 0;
+    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+    {
+	n = frame_minheight(tp->tp_topframe, NULL);
+	if (total < n)
+	    total = n;
+    }
+    total += tabpageline_height();
 #else
-    total += 1;		/* at least one window should have a line! */
+    total = 1;		/* at least one window should have a line! */
 #endif
+    total += 1;		/* count the room for the command line */
     return total;
 }
 
@@ -5169,7 +5312,9 @@ check_lnums(do_curwin)
     win_T	*wp;
 
 #ifdef FEAT_WINDOWS
-    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+    tabpage_T	*tp;
+
+    FOR_ALL_TAB_WINDOWS(tp, wp)
 	if ((do_curwin || wp != curwin) && wp->w_buffer == curbuf)
 #else
     wp = curwin;