From 7e8fd63682801d6cdd7f31972540c21f148b289e Mon Sep 17 00:00:00 2001
From: Bram Moolenaar <Bram@vim.org>
Date: Sat, 18 Feb 2006 22:14:51 +0000
Subject: [PATCH] updated for version 7.0201

---
 runtime/autoload/htmlcomplete.vim |  22 +++---
 runtime/autoload/xmlcomplete.vim  |   9 ++-
 runtime/doc/Makefile              |   2 +
 runtime/doc/autocmd.txt           |  12 ++-
 runtime/doc/diff.txt              |   8 +-
 runtime/doc/editing.txt           |   5 +-
 runtime/doc/eval.txt              |  15 +++-
 runtime/doc/help.txt              |   3 +-
 runtime/doc/index.txt             |  11 ++-
 runtime/doc/options.txt           |  17 +++-
 runtime/doc/starting.txt          |  14 +++-
 runtime/doc/tabpage.txt           | 125 ++++++++++++++++++++++++++++++
 runtime/doc/tags                  |  23 ++++++
 runtime/doc/tips.txt              |  11 ++-
 runtime/doc/todo.txt              |  55 ++++---------
 runtime/doc/version7.txt          |   5 +-
 runtime/doc/windows.txt           |  15 +++-
 src/INSTALLmac.txt                |   5 +-
 src/Makefile                      |   7 +-
 src/edit.c                        |  17 ++--
 src/eval.c                        |  36 +++++++++
 src/ex_cmds.h                     |   2 +
 src/ex_docmd.c                    |  16 ++--
 src/fileio.c                      |   4 +-
 src/gui.c                         |  23 +++---
 src/main.c                        |  20 ++---
 src/misc1.c                       |   3 +
 src/proto/edit.pro                |   1 +
 src/screen.c                      |  73 +++++++++--------
 src/version.h                     |   4 +-
 src/vim.h                         |   4 +-
 src/window.c                      |  76 +++++++++++-------
 32 files changed, 469 insertions(+), 174 deletions(-)
 create mode 100644 runtime/doc/tabpage.txt

diff --git a/runtime/autoload/htmlcomplete.vim b/runtime/autoload/htmlcomplete.vim
index 0b4bc5fd88..c28e3d3fc0 100644
--- a/runtime/autoload/htmlcomplete.vim
+++ b/runtime/autoload/htmlcomplete.vim
@@ -1,7 +1,7 @@
 " Vim completion script
 " Language:	XHTML 1.0 Strict
 " Maintainer:	Mikolaj Machowski ( mikmach AT wp DOT pl )
-" Last Change:	2006 Feb 6
+" Last Change:	2006 Feb 18
 
 function! htmlcomplete#CompleteTags(findstart, base)
   if a:findstart
@@ -540,24 +540,26 @@ function! htmlcomplete#CompleteTags(findstart, base)
 		let opentag = xmlcomplete#GetLastOpenTag("b:unaryTagsStack")
 		return [opentag.">"]
 	endif
+	" Load data {{{
+	if !exists("g:xmldata_xhtml10s")
+		runtime! autoload/xml/xhtml10s.vim
+	endif
+	" }}}
+	" Tag completion {{{
 	" Deal with tag completion.
 	let opentag = xmlcomplete#GetLastOpenTag("b:unaryTagsStack")
 	if opentag == ''
 		" Hack for sometimes failing GetLastOpenTag.
 		" As far as I tested fail isn't GLOT fault but problem
 		" of invalid document - not properly closed tags and other mish-mash.
-		" If returns empty string assume <body>. Safe bet.
-		let opentag = 'body'
-	endif
-	" }}}
-	" Load data {{{
-	if !exists("g:xmldata_xhtml10s")
-		runtime! autoload/xml/xhtml10s.vim
+		" Also when document is empty. Return list of *all* tags.
+	    let tags = keys(g:xmldata_xhtml10s)
+		call filter(tags, 'v:val !~ "^vimxml"')
+	else
+		let tags = g:xmldata_xhtml10s[opentag][0]
 	endif
 	" }}}
-	" Tag completion {{{
 
-	let tags = g:xmldata_xhtml10s[opentag][0]
 
 	for m in sort(tags)
 		if m =~ '^'.context
diff --git a/runtime/autoload/xmlcomplete.vim b/runtime/autoload/xmlcomplete.vim
index 22e81a4d93..6b7b804e36 100644
--- a/runtime/autoload/xmlcomplete.vim
+++ b/runtime/autoload/xmlcomplete.vim
@@ -1,7 +1,7 @@
 " Vim completion script
 " Language:	XML
 " Maintainer:	Mikolaj Machowski ( mikmach AT wp DOT pl )
-" Last Change:	2006 Feb 6
+" Last Change:	2006 Feb 18
 
 " This function will create Dictionary with users namespace strings and values
 " canonical (system) names of data files.  Names should be lowercase,
@@ -319,10 +319,13 @@ function! xmlcomplete#CompleteTags(findstart, base)
 	let opentag = xmlcomplete#GetLastOpenTag("b:unaryTagsStack")
 	let opentag = substitute(opentag, '^\k*:', '', '')
 	if opentag == ''
-		return []
+		"return []
+	    let tags = keys(g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]})
+		call filter(tags, 'v:val !~ "^vimxml"')
+	else
+		let tags = g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}[opentag][0]
 	endif
 
-	let tags = g:xmldata{'_'.g:xmldata_connection[b:xml_namespace]}[opentag][0]
 	let context = substitute(context, '^\k*:', '', '')
 
 	for m in tags
diff --git a/runtime/doc/Makefile b/runtime/doc/Makefile
index c63d09b00b..1cf3241b65 100644
--- a/runtime/doc/Makefile
+++ b/runtime/doc/Makefile
@@ -89,6 +89,7 @@ DOCS = \
 	starting.txt \
 	spell.txt \
 	syntax.txt \
+	tabpage.txt \
 	tagsrch.txt \
 	term.txt \
 	tips.txt \
@@ -211,6 +212,7 @@ HTMLS = \
 	starting.html \
 	spell.html \
 	syntax.html \
+	tabpage.html \
 	tagsrch.html \
 	tags.html \
 	term.html \
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
index 3688cdae37..2ca301ba32 100644
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -1,4 +1,4 @@
-*autocmd.txt*   For Vim version 7.0aa.  Last change: 2006 Feb 13
+*autocmd.txt*   For Vim version 7.0aa.  Last change: 2006 Feb 18
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -284,6 +284,8 @@ Name			triggered by ~
 
 |WinEnter|		after entering another window
 |WinLeave|		before leaving a window
+|TabEnterPost|		after entering another tab page
+|TabLeavePre|		before leaving a tab page
 |CmdwinEnter|		after entering the command-line window
 |CmdwinLeave|		before leaving the command-line window
 
@@ -704,6 +706,14 @@ Syntax				When the 'syntax' option has been set.
 				where this option was set, and <amatch> for
 				the new value of 'syntax'.
 				See |:syn-on|.
+							*TabEnterPost*
+TabEnterPost			Just after entering a tab page. |tab-page|
+				Before triggering the WinEnter and BufEnter
+				events.
+							*TabLeavePre*
+TabLeavePre			Just before leaving a tab page. |tab-page|
+				BufLeave and WinLeave events will have been
+				triggered first.
 							*TermChanged*
 TermChanged			After the value of 'term' has changed.  Useful
 				for re-loading the syntax file to update the
diff --git a/runtime/doc/diff.txt b/runtime/doc/diff.txt
index b39e721c12..aaf21b0f34 100644
--- a/runtime/doc/diff.txt
+++ b/runtime/doc/diff.txt
@@ -1,4 +1,4 @@
-*diff.txt*      For Vim version 7.0aa.  Last change: 2006 Jan 22
+*diff.txt*      For Vim version 7.0aa.  Last change: 2006 Feb 18
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -41,6 +41,10 @@ the file.
 
 This only works when a standard "diff" command is available.  See 'diffexpr'.
 
+Diffs are local to the current tab page |tab-page|.  You can't see diffs with
+a window in another tab page.  This does make it possible to have several
+diffs at the same time, each in their own tab page.
+
 What happens is that Vim opens a window for each of the files.  This is like
 using the |-O| argument.  This uses vertical splits.  If you prefer horizontal
 splits add the |-o| argument: >
@@ -113,7 +117,7 @@ file for a moment and come back to the same file and be in diff mode again.
 							*:diffo* *:diffoff*
 :diffoff	Switch off diff mode for the current window.
 
-:diffoff!	Switch off diff mode for all windows.
+:diffoff!	Switch off diff mode for all windows in the current tab page.
 
 The ":diffoff" command resets the relevant options to their default value.
 This may be different from what the values were before diff mode was started,
diff --git a/runtime/doc/editing.txt b/runtime/doc/editing.txt
index 25dc1a674e..b29504ced2 100644
--- a/runtime/doc/editing.txt
+++ b/runtime/doc/editing.txt
@@ -1,4 +1,4 @@
-*editing.txt*   For Vim version 7.0aa.  Last change: 2006 Jan 20
+*editing.txt*   For Vim version 7.0aa.  Last change: 2006 Feb 18
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1014,6 +1014,9 @@ The names can be in upper- or lowercase.
 			Vim refuses to |abandon| the current buffer, and when
 			the last file in the argument list has not been
 			edited.
+			If there are other tab pages and quitting the last
+			window in the current tab page the current tab page is
+			closed |tab-page|.
 
 :conf[irm] q[uit]	Quit, but give prompt when changes have been made, or
 			the last file in the argument list has not been
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 0f339e1119..9bad529eb6 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1,4 +1,4 @@
-*eval.txt*      For Vim version 7.0aa.  Last change: 2006 Feb 14
+*eval.txt*      For Vim version 7.0aa.  Last change: 2006 Feb 18
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1690,6 +1690,7 @@ synIDattr( {synID}, {what} [, {mode}])
 				String	attribute {what} of syntax ID {synID}
 synIDtrans( {synID})		Number	translated syntax ID of {synID}
 system( {expr} [, {input}])	String	output of shell command/filter {expr}
+tabpage( [{expr}])		Number	number of current tab page
 taglist( {expr})			List	list of tags matching {expr}
 tagfiles()			List    tags files used
 tempname()			String	name for a temporary file
@@ -1705,7 +1706,7 @@ winbufnr( {nr})			Number	buffer number of window {nr}
 wincol()			Number	window column of the cursor
 winheight( {nr})		Number	height of window {nr}
 winline()			Number	window line of the cursor
-winnr()				Number	number of current window
+winnr( [{expr}])		Number	number of current window
 winrestcmd()			String	returns command to restore window sizes
 winwidth( {nr})			Number	width of window {nr}
 writefile({list}, {fname} [, {binary}])
@@ -4447,6 +4448,14 @@ system({expr} [, {input}])				*system()* *E677*
 		Use |:checktime| to force a check.
 
 
+tabpagenr([{arg}])						*tabpagenr()*
+		The result is a Number, which is the number of the current
+		tab page.  The first tab page has number 1.
+		When the optional argument is "$", the number of the last tab
+		page is returned (the tab page count).
+		The number can be used with the |:tab| command.
+
+
 taglist({expr})							*taglist()*
 		Returns a list of tags matching the regular expression {expr}.
 		Each list item is a dictionary with at least the following
@@ -4618,7 +4627,7 @@ winline()	The result is a Number, which is the screen line of the cursor
 winnr([{arg}])	The result is a Number, which is the number of the current
 		window.  The top window has number 1.
 		When the optional argument is "$", the number of the
-		last window is returnd (the window count).
+		last window is returned (the window count).
 		When the optional argument is "#", the number of the last
 		accessed window is returned (where |CTRL-W_p| goes to).
 		If there is no previous window 0 is returned.
diff --git a/runtime/doc/help.txt b/runtime/doc/help.txt
index 999a50772d..42f0eb1e4d 100644
--- a/runtime/doc/help.txt
+++ b/runtime/doc/help.txt
@@ -1,4 +1,4 @@
-*help.txt*	For Vim version 7.0aa.  Last change: 2005 Nov 30
+*help.txt*	For Vim version 7.0aa.  Last change: 2006 Feb 18
 
 			VIM - main help file
 									 k
@@ -122,6 +122,7 @@ Advanced editing ~
 |tagsrch.txt|	tags and special searches
 |quickfix.txt|	commands for a quick edit-compile-fix cycle
 |windows.txt|	commands for using multiple windows and buffers
+|tabpage.txt|	commands for using multiple tab pages
 |syntax.txt|	syntax highlighting
 |spell.txt|	spell checking
 |diff.txt|	working with two or three versions of the same file
diff --git a/runtime/doc/index.txt b/runtime/doc/index.txt
index e1788b0a93..b265ee61ae 100644
--- a/runtime/doc/index.txt
+++ b/runtime/doc/index.txt
@@ -1,4 +1,4 @@
-*index.txt*     For Vim version 7.0aa.  Last change: 2006 Jan 26
+*index.txt*     For Vim version 7.0aa.  Last change: 2006 Feb 18
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1305,7 +1305,7 @@ The commands are sorted on the non-optional part of their name.
 |:omap|		:om[ap]		like ":map" but for Operator-pending mode
 |:omapclear|	:omapc[lear]	remove all mappings for Operator-pending mode
 |:omenu|	:ome[nu]	add menu for Operator-pending mode
-|:only|		:on[ly]		close all windows except current one
+|:only|		:on[ly]		close all windows except the current one
 |:onoremap|	:ono[remap]	like ":noremap" but for Operator-pending mode
 |:onoremenu|	:onoreme[nu]	like ":noremenu" but for Operator-pending mode
 |:options|	:opt[ions]	open the options-window
@@ -1436,6 +1436,13 @@ The commands are sorted on the non-optional part of their name.
 |:syncbind|	:sync[bind]	sync scroll binding
 |:t|		:t		same as ":copy"
 |:tNext|	:tN[ext]	jump to previous matching tag
+|:tabclose|	:tabc[lose]	close current tab page
+|:tabedit|	:tabe[dit]	edit a file in a new tab page
+|:tabfind|	:tabf[ind]	find file in 'path', edit it in a new tab page
+|:tabnew|	:tabn[ew]	edit a file in a new tab page
+|:tabonly|	:tabo[nly]	close all tab pages except the current one
+|:tabs|		:tabs		list the tab pages and what they contain
+|:tab|		:tab		jump to another tab page
 |:tag|		:ta[g]		jump to tag
 |:tags|		:tags		show the contents of the tag stack
 |:tcl|		:tc[l]		execute Tcl command
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index c9aa452f48..c17074c2d5 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1,4 +1,4 @@
-*options.txt*	For Vim version 7.0aa.  Last change: 2006 Feb 14
+*options.txt*	For Vim version 7.0aa.  Last change: 2006 Feb 18
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -5336,6 +5336,8 @@ A jump table for the options with a short description can be found at |Q_op|.
 	   winsize	window sizes
 
 	Don't include both "curdir" and "sesdir".
+	There is no option to include tab pages yet, only the current tab page
+	is stored in the session. |tab-page|
 	When "curdir" nor "sesdir" is included, file names are stored with
 	absolute paths.
 	"slash" and "unix" are useful on Windows when sharing session files
@@ -6232,6 +6234,19 @@ A jump table for the options with a short description can be found at |Q_op|.
 	'S' flag in 'cpoptions'.
 	Only normal file name characters can be used, "/\*?[|<>" are illegal.
 
+					*'tabline'* *'tal'*
+'tabline' 'tal'		number	(default 1)
+			global
+			{not in Vi}
+			{not available when compiled without the +windows
+			feature}
+	The value of this option specifies when the line with tab page labels
+	will be displayed:
+		0: never
+		1: only if there are at least two tab pages
+		2: always
+	|tab-page|
+
 					*'tabstop'* *'ts'*
 'tabstop' 'ts'		number	(default 8)
 			local to buffer
diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt
index d21a52dc2a..0b64ca3a19 100644
--- a/runtime/doc/starting.txt
+++ b/runtime/doc/starting.txt
@@ -1,4 +1,4 @@
-*starting.txt*  For Vim version 7.0aa.  Last change: 2006 Feb 14
+*starting.txt*  For Vim version 7.0aa.  Last change: 2006 Feb 18
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -372,6 +372,13 @@ a slash.  Thus "-R" means recovery and "-/R" readonly.
 -O[N]		Open N windows, split vertically.  Otherwise it's like -o.
 		If both the -o and the -O option are given, the last one on
 		the command line determines how the windows will be split.
+		{not in Vi}
+
+							*-p*
+-p[N]		Open N tab pages.  If [N] is not given, one tab page is opened
+		for every file given as argument.  The maximum is 10 tab
+		pages.  If there are more tab pages than arguments, the last
+		few tab pages will be editing an empty file.
 		{not in Vi}
 
 							*-T*
@@ -831,6 +838,8 @@ accordingly.  Vim proceeds in this order:
 11. Open all windows
 	When the |-o| flag was given, windows will be opened (but not
 	displayed yet).
+	When the |-p| flag was given, tab pages will be created (but not
+	displayed yet).
 	When switching screens, it happens now.  Redrawing starts.
 	If the "-q" flag was given to Vim, the first error is jumped to.
 	Buffers for all windows will be loaded.
@@ -1203,6 +1212,9 @@ An example mapping: >
   :nmap <F2> :wa<Bar>exe "mksession! " . v:this_session<CR>:so ~/sessions/
 This saves the current Session, and starts off the command to load another.
 
+A session only includes the current tab page.  There currently is no option to
+store all tab pages. |tab-page|
+
 The |SessionLoadPost| autocmd event is triggered after a session file is
 loaded/sourced.
 						*SessionLoad-variable*
diff --git a/runtime/doc/tabpage.txt b/runtime/doc/tabpage.txt
new file mode 100644
index 0000000000..cf95ca2176
--- /dev/null
+++ b/runtime/doc/tabpage.txt
@@ -0,0 +1,125 @@
+*tabpage.txt*   For Vim version 7.0aa.  Last change: 2006 Feb 18
+
+
+		  VIM REFERENCE MANUAL    by Bram Moolenaar
+
+
+Editing with windows in multuple tab pages.		*tab-page* *tabpage*
+
+The commands which have been added to use multiple tab pages are explained
+here.  Additionally, there are explanations for commands that work differently
+when used in combination with more than one tab page.
+
+1.  Introduction			|tab-page-intro|
+2.  Commands				|tab-page-commands|
+3.  Other items				|tab-page-other|
+
+{Vi does not have any of these commands}
+{not able to use multiple tab pages when the |+windows| feature was disabled
+at compile time}
+
+==============================================================================
+1. Introduction						*tab-page-intro*
+
+A tab page holds one or more windows.  You can easily switch between tab
+pages, so that you have several collections of windows to work on different
+things.
+
+Usually you will see a list of labels at the top of the Vim window, one for
+each tab page.  With the mouse you can click on the label to jump to that tab
+page.  There are other ways to move between tab pages, see below.
+
+Most commands work only in the current tab page.  That includes the |CTRL-W|
+commands, |:windo|, |:all| and |:ball|.  The commands that are aware of
+other tab pages than the current one are mentioned below.
+
+Tabs are also a nice way to edit a buffer temporarily without changing the
+current window layout.  Open a new tab page, do whatever you want to do and
+close the tab page.
+
+==============================================================================
+2. Commands						*tab-page-commands*
+
+OPENING A NEW TAB PAGE:
+
+When starting Vim "vim -p filename ..." opens each file argument in a separate
+tab page (up to 10). |-p|
+
+:tabe[dit]						*:tabe* *:tabedit*
+:tabn[ew]	Open a new tab page with an empty window.
+
+:tabe[dit] [++opt] [+cmd] {file}
+:tabn[ew] [++opt] [+cmd] {file}
+		Open a new tab page and edit {file}, like with |:edit|.
+
+:tabf[ind] [++opt] [+cmd] {file}
+		Open a new tab page and edit {file} in 'path', like with
+		|:find|.
+		{not available when the |+file_in_path| feature was disabled
+		at compile time}
+
+
+CLOSING A TAB PAGE:
+
+Using |:close| in the last window of a tab page closes it.
+
+Using the mouse: If the tab page line is displayed you can click in the "X" at
+the top right to close the current tab page. |'tabline'|
+
+							*:tabc* *:tabclose*
+:tabc[lose][!]	Close current tab page.
+		This command fails when:
+		- There is only one tab page on the screen.		*E784*
+		- When 'hidden' is not set, [!] is not used, a buffer has
+		  changes, and there is no other window on this buffer.
+		Changes to the buffer are not written and won't get lost, so
+		this is a "safe" command.
+
+:tabc[lose][!] {count}
+		Close tab page {count}.  Fails in the same way as ':tabclose"
+		above.
+
+							*:tabo* *:tabonly*
+:tabo[nly][!]	Close all other tab pages.
+		When the 'hidden' option is set, all buffers in closed windows
+		become hidden.
+		When 'hidden' is not set, and the 'autowrite' option is set,
+		modified buffers are written.  Otherwise, windows that have
+		buffers that are modified are not removed, unless the [!] is
+		given, then they become hidden.  But modified buffers are
+		never abandoned, so changes cannot get lost.
+
+
+SWITCHING TO ANOTHER TAB PAGE:
+
+Using the mouse: If the tab page line is displayed you can click in a tab page
+label to switch to that tab page. |'tabline'|
+
+:tab							*:tab* *gt*
+gt		Go to the next tab page.  Wraps around from the last to the
+		first one.
+
+:tab {count}
+{count}gt	Go to tab page {count}.  The first tab page has number one.
+
+
+Other commands:
+							*:tabs*
+:tabs		List the tab pages and the windows they contain.  Shows a "+"
+		for modified buffers.
+
+==============================================================================
+3. Other items						*tab-page-other*
+
+You can use the 'tabline' option to specify when you want the line with tab
+page labels to appear: never, when there is more than one tab page or always.
+
+Diff mode works per tab page.  You can see the diffs between several files
+within one tab page.  Other tab pages can show differences between other
+files.
+
+The TabLeavePre and TabEnterPost autocommand events can be used to do
+something when switching from one tab page to another.
+
+
+ vim:tw=78:ts=8:ft=help:norl:
diff --git a/runtime/doc/tags b/runtime/doc/tags
index fdaa136f4e..514ca293d2 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -892,6 +892,7 @@ $VIMRUNTIME	starting.txt	/*$VIMRUNTIME*
 't_vs'	term.txt	/*'t_vs'*
 't_xs'	term.txt	/*'t_xs'*
 'ta'	options.txt	/*'ta'*
+'tabline'	options.txt	/*'tabline'*
 'tabstop'	options.txt	/*'tabstop'*
 'tag'	options.txt	/*'tag'*
 'tagbsearch'	options.txt	/*'tagbsearch'*
@@ -899,6 +900,7 @@ $VIMRUNTIME	starting.txt	/*$VIMRUNTIME*
 'tagrelative'	options.txt	/*'tagrelative'*
 'tags'	options.txt	/*'tags'*
 'tagstack'	options.txt	/*'tagstack'*
+'tal'	options.txt	/*'tal'*
 'tb'	options.txt	/*'tb'*
 'tbi'	options.txt	/*'tbi'*
 'tbidi'	options.txt	/*'tbidi'*
@@ -1224,6 +1226,7 @@ $VIMRUNTIME	starting.txt	/*$VIMRUNTIME*
 -n	starting.txt	/*-n*
 -nb	starting.txt	/*-nb*
 -o	starting.txt	/*-o*
+-p	starting.txt	/*-p*
 -q	starting.txt	/*-q*
 -qf	starting.txt	/*-qf*
 -r	starting.txt	/*-r*
@@ -2638,6 +2641,14 @@ $VIMRUNTIME	starting.txt	/*$VIMRUNTIME*
 :tN	tagsrch.txt	/*:tN*
 :tNext	tagsrch.txt	/*:tNext*
 :ta	tagsrch.txt	/*:ta*
+:tab	tabpage.txt	/*:tab*
+:tabc	tabpage.txt	/*:tabc*
+:tabclose	tabpage.txt	/*:tabclose*
+:tabe	tabpage.txt	/*:tabe*
+:tabedit	tabpage.txt	/*:tabedit*
+:tabo	tabpage.txt	/*:tabo*
+:tabonly	tabpage.txt	/*:tabonly*
+:tabs	tabpage.txt	/*:tabs*
 :tag	tagsrch.txt	/*:tag*
 :tags	tagsrch.txt	/*:tags*
 :tc	if_tcl.txt	/*:tc*
@@ -3875,6 +3886,7 @@ E780	spell.txt	/*E780*
 E781	spell.txt	/*E781*
 E782	spell.txt	/*E782*
 E783	spell.txt	/*E783*
+E784	tabpage.txt	/*E784*
 E79	message.txt	/*E79*
 E80	message.txt	/*E80*
 E800	arabic.txt	/*E800*
@@ -4086,6 +4098,8 @@ TCL	if_tcl.txt	/*TCL*
 TERM	starting.txt	/*TERM*
 TTpro-telnet	syntax.txt	/*TTpro-telnet*
 Tab	intro.txt	/*Tab*
+TabEnterPost	autocmd.txt	/*TabEnterPost*
+TabLeavePre	autocmd.txt	/*TabLeavePre*
 Tcl	if_tcl.txt	/*Tcl*
 TermChanged	autocmd.txt	/*TermChanged*
 TermResponse	autocmd.txt	/*TermResponse*
@@ -5340,6 +5354,7 @@ group-name	syntax.txt	/*group-name*
 gs	various.txt	/*gs*
 gsp.vim	syntax.txt	/*gsp.vim*
 gstar	pattern.txt	/*gstar*
+gt	tabpage.txt	/*gt*
 gtk-tooltip-colors	gui_x11.txt	/*gtk-tooltip-colors*
 gu	change.txt	/*gu*
 gugu	change.txt	/*gugu*
@@ -5429,6 +5444,7 @@ hebrew	hebrew.txt	/*hebrew*
 hebrew.txt	hebrew.txt	/*hebrew.txt*
 help	various.txt	/*help*
 help-context	help.txt	/*help-context*
+help-tags	tags	1
 help-translated	various.txt	/*help-translated*
 help-xterm-window	various.txt	/*help-xterm-window*
 help.txt	help.txt	/*help.txt*
@@ -6927,6 +6943,13 @@ t_vi	term.txt	/*t_vi*
 t_vs	term.txt	/*t_vs*
 t_xs	term.txt	/*t_xs*
 tab	intro.txt	/*tab*
+tab-page	tabpage.txt	/*tab-page*
+tab-page-commands	tabpage.txt	/*tab-page-commands*
+tab-page-intro	tabpage.txt	/*tab-page-intro*
+tab-page-other	tabpage.txt	/*tab-page-other*
+tabpage	tabpage.txt	/*tabpage*
+tabpage.txt	tabpage.txt	/*tabpage.txt*
+tabpagenr()	eval.txt	/*tabpagenr()*
 tag	tagsrch.txt	/*tag*
 tag-!	tagsrch.txt	/*tag-!*
 tag-any-white	tagsrch.txt	/*tag-any-white*
diff --git a/runtime/doc/tips.txt b/runtime/doc/tips.txt
index 2fc1bee0c7..30c548d61d 100644
--- 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 16
+*tips.txt*      For Vim version 7.0aa.  Last change: 2006 Feb 18
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -450,11 +450,13 @@ Highlighting matching parens					*match-parens*
 This example shows the use of a few advanced tricks:
 - using the |CursorMoved| autocommand event
 - using |searchpairpos()| to find a matching paren
+- using |synID()| to detect whether the cursor is in a string or comment
 - using |:match| to highlight something
 - using a |pattern| to match a specific position in the file.
 
 This should be put in a Vim script file, since it uses script-local variables.
-Note that it doesn't recognize strings or comments in the text.
+It skips matches in strings or comments, unless the cursor started in string
+or comment.  This requires syntax highlighting.
 >
 	let s:paren_hl_on = 0
 	function s:Highlight_Matching_Paren()
@@ -484,8 +486,11 @@ Note that it doesn't recognize strings or comments in the text.
 	    let c = '\['
 	    let c2 = '\]'
 	  endif
+	  let s_skip ='synIDattr(synID(line("."), col("."), 0), "name") ' .
+ 	  	\ '=~?  "string\\|comment"'
+ 	  execute 'if' s_skip '| let s_skip = 0 | endif'
 
-	  let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags)
+	  let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip)
 
 	  if m_lnum > 0 && m_lnum >= line('w0') && m_lnum <= line('w$')
 	    exe 'match Search /\(\%' . c_lnum . 'l\%' . c_col .
diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt
index 2912a5884f..4c65d1df99 100644
--- 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 17
+*todo.txt*      For Vim version 7.0aa.  Last change: 2006 Feb 18
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -32,52 +32,15 @@ be worked on, but only if you sponsor Vim development.  See |sponsor|.
 
 Support WINDOW TABS.  Works like several pages, each with their own split
 windows.  Let's call them "tab pages".
-    - 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'.
-    - check for E999
-    - 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
-	:tabs
-	{count}gt
-	:close may close current tab page if there is one window.
-	:tabclose
-	:tabclose N - close tab N
-	:tabonly - close all other tabs.
-	:close and :quit (last window in tab)
-	"gt": Use "1gt" - "99gt" to switch to another tab.  "gt" goes to the
-	     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 works in the current tab page
-	diff works per tab page
-        "vim -p *" opens each file in a separate tab page (up to 10).
-    - 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).
     - Need to be able to search the windows in inactive tabs, e.g. for the
-      quickfix window.
-Future enhancements:
-    tab page local variables?
-    tab page local options?  'diffopt' could differ between tab pages.
-    tab page local colors?
+      quickfix window?
+    - docs:
+	Add info to the user manual somewhere.
 
 Crash with X command server (Ciaran McCreesh).
 
-Motif: in diff mode dragging one scrollbar doesn't update the other one.
-
 Ctags still hasn't included the patch.  Darren is looking for someone to do
 maintanance.
 
@@ -494,6 +457,16 @@ Patch for "paranoid mode" by Kevin Collins, March 7.  Needs much more work.
 Check if file explorer can handle directory names and links with a single
 quote. (Nieko Maatjes, 2005 Jan 4)
 
+Future enhancements for tab pages:
+    - Add GUI Tabs for all systems.
+      Patch for GTK 1.2 passed on by Christian Michon, 2004 Jan 6.
+      Simple patch for GTK by Luis M (nov 7).
+    - ":tabsplit" makes a copy of the current tab page.
+    - Add local variables for each tab page?
+    - Add local options for each tab page?  E.g., 'diffopt' could differ
+      between tab pages.
+    - Add local highlighting for a tab page?
+
 
 Vi incompatibility:
 8   With undo/redo only marks in the changed lines should be changed.  Other
diff --git a/runtime/doc/version7.txt b/runtime/doc/version7.txt
index 7f7c092c35..7f93bcfba2 100644
--- 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 17
+*version7.txt*  For Vim version 7.0aa.  Last change: 2006 Feb 18
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1707,4 +1707,7 @@ event that removed the balloon again.  Ignore the key release event.
 When "umask" is set such that nothing is writable then the viminfo file would
 be written without write permission. (Julian Bridle)
 
+Motif: In diff mode dragging one scrollbar didn't update the scrollbar of the
+other diff'ed window.
+
  vim:tw=78:ts=8:ft=help:norl:
diff --git a/runtime/doc/windows.txt b/runtime/doc/windows.txt
index 8e38965101..a83bdd2968 100644
--- a/runtime/doc/windows.txt
+++ b/runtime/doc/windows.txt
@@ -1,4 +1,4 @@
-*windows.txt*   For Vim version 7.0aa.  Last change: 2006 Jan 27
+*windows.txt*   For Vim version 7.0aa.  Last change: 2006 Feb 18
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -68,6 +68,9 @@ inactive	  no		 no		  ' '
 Note: All CTRL-W commands can also be executed with |:wincmd|, for those
 places where a Normal mode command can't be used or is inconvenient.
 
+The main Vim window can hold several split windows.  There are also tab pages
+|tab-page|, each of which can hold multiple windows.
+
 ==============================================================================
 2. Starting Vim						*windows-starting*
 
@@ -255,6 +258,9 @@ CTRL-W c					*CTRL-W_c* *:clo* *:close*
 :clo[se][!]	Close current window.  When the 'hidden' option is set, or
 		when the buffer was changed and the [!] is used, the buffer
 		becomes hidden (unless there is another window editing it).
+		When there is only one window in the current tab page and
+		there is another tab page, this closes the current tab page.
+		|tab-page|.
 		This command fails when:			*E444*
 		- There is only one window on the screen.
 		- When 'hidden' is not set, [!] is not used, the buffer has
@@ -271,6 +277,8 @@ CTRL-W CTRL-C						*CTRL-W_CTRL-C*
 :hid[e]		Quit current window, unless it is the last window on the
 		screen.  The buffer becomes hidden (unless there is another
 		window editing it or 'bufhidden' is "unload" or "delete").
+		If the window is the last one in the current tab page the tab
+		page is closed. |tab-page|
 		The value of 'hidden' is irrelevant for this command.
 		Changes to the buffer are not written and won't get lost, so
 		this is a "safe" command.
@@ -551,6 +559,7 @@ can also get to them with the buffer list commands, like ":bnext".
 		Rearrange the screen to open one window for each argument.
 		All other windows are closed.  When a count is given, this is
 		the maximum number of windows to open.
+		Only uses the current tab page |tab-page|.
 		When the 'hidden' option is set, all buffers in closed windows
 		become hidden.
 		When 'hidden' is not set, and the 'autowrite' option is set,
@@ -620,7 +629,8 @@ can also get to them with the buffer list commands, like ":bnext".
 				CTRL-W w
 				:{cmd}
 				etc.
-<			When an error is detected on one window, further
+<			This only works in the current tab page.
+			When an error is detected on one window, further
 			windows will not be visited.
 			The last window (or where an error occurred) becomes
 			the current window.
@@ -1073,6 +1083,7 @@ list of buffers. |unlisted-buffer|
 		of windows opened ('winwidth' if |:vertical| was prepended).
 		Buf/Win Enter/Leave autocommands are not executed for the new
 		windows here, that's only done when they are really entered.
+		Only uses the current tab page |tab-page|.
 
 Note: All the commands above that start editing another buffer, keep the
 'readonly' flag as it was.  This differs from the ":edit" command, which sets
diff --git a/src/INSTALLmac.txt b/src/INSTALLmac.txt
index adb1ca1638..1c4d7732a4 100644
--- a/src/INSTALLmac.txt
+++ b/src/INSTALLmac.txt
@@ -36,13 +36,16 @@ MacOS Classic is no longer supported.  If you really want it use Vim 6.4.
  directory.  You can move this bundle (the Vim.app directory) anywhere
  you want, for example, /Applications.
 
+ You need at least Xcode 1.5 to compile Vim 7.0.
+
+
 1.2 X-Windows or Plain Text
 
  If you do not want the Carbon interface, you must explicitly tell
  configure to use a different GUI.
 
   cd ..
-  ./configure --enable-gui=gtk2
+  ./configure --disable-darwin --enable-gui=gtk2
   make; make install
 
  NOTE: The following GUI options are supported:
diff --git a/src/Makefile b/src/Makefile
index 2da7860835..a4b7d207c0 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1510,6 +1510,8 @@ PRO_AUTO = \
 	$(ALL_GUI_PRO) \
 	$(TCL_PRO)
 
+ICON_APP = gui_mac.icns
+
 PRO_MANUAL = os_amiga.pro os_msdos.pro os_win16.pro os_win32.pro \
 	os_mswin.pro os_beos.pro os_vms.pro os_riscos.pro $(PERL_PRO)
 
@@ -2131,6 +2133,10 @@ shadow:	runtime pixmaps
 	cp config.mk.dist $(SHADOWDIR)
 	mkdir $(SHADOWDIR)/xxd
 	cd $(SHADOWDIR)/xxd; ln -s ../../xxd/*.[ch] ../../xxd/Make* .
+	if test -f $(ICON_APP); then \
+		cd $(SHADOWDIR); \
+		ln -s ../$(ICON_APP) ../os_mac.rsr.hqx ../dehqx.py .; \
+	fi
 	mkdir $(SHADOWDIR)/testdir
 	cd $(SHADOWDIR)/testdir; ln -s ../../testdir/Makefile \
 				 ../../testdir/vimrc.unix \
@@ -2494,7 +2500,6 @@ M4FLAGSX = $(M4FLAGS) -DAPP_EXE=$(VIMNAME) -DAPP_NAME=$(VIMNAME) \
 		-DAPP_VER=$(VERSION) -DICON_APP=$(ICON_APP)
 
 ### Icons
-ICON_APP = gui_mac.icns
 ICONS = $(RESDIR)/$(ICON_APP)
 
 # If you uncomment the following lines the *.icns in the src directory will be
diff --git a/src/edit.c b/src/edit.c
index 9224c58970..cb78cd62d9 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -114,7 +114,6 @@ static int	  compl_pending = FALSE;
 static pos_T	  compl_startpos;
 static colnr_T	  compl_col = 0;	    /* column where the text starts
 					     * that is being completed */
-static int	  save_sm = -1;
 static char_u	  *compl_orig_text = NULL;  /* text as it was before
 					     * completion started */
 static int	  compl_cont_mode = 0;
@@ -2733,10 +2732,18 @@ ins_compl_clear()
     compl_pattern = NULL;
     vim_free(compl_leader);
     compl_leader = NULL;
-    save_sm = -1;
     edit_submode_extra = NULL;
 }
 
+/*
+ * Return TRUE when Insert completion is active.
+ */
+    int
+ins_compl_active()
+{
+    return compl_started;
+}
+
 /*
  * Delete one character before the cursor and show the subset of the matches
  * that match the word that is now before the cursor.
@@ -3071,8 +3078,6 @@ ins_compl_prep(c)
 	    compl_matches = 0;
 	    msg_clr_cmdline();		/* necessary for "noshowmode" */
 	    ctrl_x_mode = 0;
-	    if (save_sm >= 0)
-		p_sm = save_sm;
 	    if (edit_submode != NULL)
 	    {
 		edit_submode = NULL;
@@ -3904,10 +3909,6 @@ ins_complete(c)
     {
 	/* First time we hit ^N or ^P (in a row, I mean) */
 
-	/* Turn off 'sm' so we don't show matches with ^X^L */
-	save_sm = p_sm;
-	p_sm = FALSE;
-
 	did_ai = FALSE;
 #ifdef FEAT_SMARTINDENT
 	did_si = FALSE;
diff --git a/src/eval.c b/src/eval.c
index 8c7049be30..b0202cdb32 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -621,6 +621,7 @@ static void f_synID __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_synIDattr __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_synIDtrans __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_system __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_tabpagenr __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_taglist __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_tagfiles __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_tempname __ARGS((typval_T *argvars, typval_T *rettv));
@@ -6983,6 +6984,7 @@ static struct fst
     {"synIDattr",	2, 3, f_synIDattr},
     {"synIDtrans",	1, 1, f_synIDtrans},
     {"system",		1, 2, f_system},
+    {"tabpagenr",	0, 1, f_tabpagenr},
     {"tagfiles",	0, 0, f_tagfiles},
     {"taglist",		1, 1, f_taglist},
     {"tempname",	0, 0, f_tempname},
@@ -14867,6 +14869,40 @@ done:
     rettv->vval.v_string = res;
 }
 
+/*
+ * "tabpagenr()" function
+ */
+/* ARGSUSED */
+    static void
+f_tabpagenr(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    int		nr = 1;
+#ifdef FEAT_WINDOWS
+    tabpage_T	*tp;
+    char_u	*arg;
+
+    if (argvars[0].v_type != VAR_UNKNOWN)
+    {
+	arg = get_tv_string_chk(&argvars[0]);
+	nr = 0;
+	if (arg != NULL)
+	{
+	    if (STRCMP(arg, "$") == 0)
+		for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+		    ++nr;
+	    else
+		EMSG2(_(e_invexpr2), arg);
+	}
+    }
+    else
+	for (tp = first_tabpage; tp != curtab; tp = tp->tp_next)
+	    ++nr;
+#endif
+    rettv->vval.v_number = nr;
+}
+
 /*
  * "tagfiles()" function
  */
diff --git a/src/ex_cmds.h b/src/ex_cmds.h
index d505bff37f..9ab8b885ad 100644
--- a/src/ex_cmds.h
+++ b/src/ex_cmds.h
@@ -884,6 +884,8 @@ EX(CMD_tabclose,	"tabclose",	ex_tabclose,
 EX(CMD_tabedit,		"tabedit",	ex_tabedit,
 			BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
 EX(CMD_tabfind,		"tabfind",	ex_tabedit,
+			BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|NEEDARG|TRLBAR),
+EX(CMD_tabnew,		"tabnew",	ex_tabedit,
 			BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
 EX(CMD_tabonly,		"tabonly",	ex_tabonly,
 			TRLBAR|CMDWIN),
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 495d7397b3..1a8788684f 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -6228,7 +6228,7 @@ ex_tabclose(eap)
     else
 # endif
 	if (first_tabpage->tp_next == NULL)
-	    EMSG(_("E999: Cannot close last tab page"));
+	    EMSG(_("E784: Cannot close last tab page"));
 	else
 	{
 	    if (eap->addr_count > 0)
@@ -6239,7 +6239,7 @@ ex_tabclose(eap)
 		    beep_flush();
 		    return;
 		}
-		if (tp->tp_topframe != topframe)
+		if (tp != curtab)
 		{
 		    tabpage_close_other(tp, eap->forceit);
 		    return;
@@ -6975,9 +6975,10 @@ theend:
 }
 
 /*
- * :tabedit [[+command] file]	open new Tab page with empty window
- * :tabedit [[+command] file]	open new Tab page and edit "file"
- * :tabfind [[+command] file]	open new Tab page and find "file"
+ * :tabedit			open new Tab page with empty window
+ * :tabedit [+command] file	open new Tab page and edit "file"
+ * :tabnew [[+command] file]	just like :tabedit
+ * :tabfind [+command] file	open new Tab page and find "file"
  */
     void
 ex_tabedit(eap)
@@ -10626,6 +10627,11 @@ ex_match(eap)
 		eap->errmsg = e_trailing;
 		return;
 	    }
+	    if (*end != *p)
+	    {
+		EMSG2(_(e_invarg2), p);
+		return;
+	    }
 
 	    c = *end;
 	    *end = NUL;
diff --git a/src/fileio.c b/src/fileio.c
index 437a4b670d..de101c8f32 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -6960,8 +6960,10 @@ static struct event_name
     {"SpellFileMissing",EVENT_SPELLFILEMISSING},
     {"StdinReadPost",	EVENT_STDINREADPOST},
     {"StdinReadPre",	EVENT_STDINREADPRE},
-    {"Syntax",		EVENT_SYNTAX},
     {"SwapExists",	EVENT_SWAPEXISTS},
+    {"Syntax",		EVENT_SYNTAX},
+    {"TabEnterPost",	EVENT_TABENTERPOST},
+    {"TabLeavePre",	EVENT_TABLEAVEPRE},
     {"TermChanged",	EVENT_TERMCHANGED},
     {"TermResponse",	EVENT_TERMRESPONSE},
     {"User",		EVENT_USER},
diff --git a/src/gui.c b/src/gui.c
index 4f18988caa..0047a26a32 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -3598,14 +3598,9 @@ gui_update_scrollbars(force)
      * have both a left and right scrollbar, and we drag one of them, we still
      * need to update the other one.
      */
-    if (       (gui.dragged_sb == SBAR_LEFT
-		|| gui.dragged_sb == SBAR_RIGHT)
-	    && (!gui.which_scrollbars[SBAR_LEFT]
-		|| !gui.which_scrollbars[SBAR_RIGHT])
-	    && !force)
-	return;
-
-    if (!force && (gui.dragged_sb == SBAR_LEFT || gui.dragged_sb == SBAR_RIGHT))
+    if (!force && (gui.dragged_sb == SBAR_LEFT || gui.dragged_sb == SBAR_RIGHT)
+	    && gui.which_scrollbars[SBAR_LEFT]
+	    && gui.which_scrollbars[SBAR_RIGHT])
     {
 	/*
 	 * If we have two scrollbars and one of them is being dragged, just
@@ -3618,7 +3613,6 @@ gui_update_scrollbars(force)
 		    gui.dragged_wp->w_scrollbars[0].value,
 		    gui.dragged_wp->w_scrollbars[0].size,
 		    gui.dragged_wp->w_scrollbars[0].max);
-	return;
     }
 
     /* avoid that moving components around generates events */
@@ -3628,6 +3622,12 @@ gui_update_scrollbars(force)
     {
 	if (wp->w_buffer == NULL)	/* just in case */
 	    continue;
+	/* Skip a scrollbar that is being dragged. */
+	if (!force && (gui.dragged_sb == SBAR_LEFT
+					     || gui.dragged_sb == SBAR_RIGHT)
+		&& gui.dragged_wp == wp)
+	    continue;
+
 #ifdef SCROLL_PAST_END
 	max = wp->w_buffer->b_ml.ml_line_count - 1;
 #else
@@ -3759,11 +3759,12 @@ gui_update_scrollbars(force)
 #endif
 	    sb->size = size;
 	    sb->max = max;
-	    if (gui.which_scrollbars[SBAR_LEFT] && gui.dragged_sb != SBAR_LEFT)
+	    if (gui.which_scrollbars[SBAR_LEFT]
+		    && (gui.dragged_sb != SBAR_LEFT || gui.dragged_wp != wp))
 		gui_mch_set_scrollbar_thumb(&wp->w_scrollbars[SBAR_LEFT],
 					    val, size, max);
 	    if (gui.which_scrollbars[SBAR_RIGHT]
-					&& gui.dragged_sb != SBAR_RIGHT)
+		    && (gui.dragged_sb != SBAR_RIGHT || gui.dragged_wp != wp))
 		gui_mch_set_scrollbar_thumb(&wp->w_scrollbars[SBAR_RIGHT],
 					    val, size, max);
 	}
diff --git a/src/main.c b/src/main.c
index 31c6f6fbab..3dc72e15da 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1710,15 +1710,6 @@ command_line_scan(parmp)
 #endif
 		break;
 
-#ifdef TARGET_API_MAC_OSX
-		/* For some reason on MacOS X, an argument like:
-		   -psn_0_10223617 is passed in when invoke from Finder
-		   or with the 'open' command */
-	    case 'p':
-		argv_idx = -1; /* bypass full -psn */
-		main_start_gui();
-		break;
-#endif
 	    case 'M':		/* "-M"  no changes or writing of files */
 		reset_modifiable();
 		/* FALLTHROUGH */
@@ -1743,6 +1734,17 @@ command_line_scan(parmp)
 		break;
 
 	    case 'p':		/* "-p[N]" open N tab pages */
+#ifdef TARGET_API_MAC_OSX
+		/* For some reason on MacOS X, an argument like:
+		   -psn_0_10223617 is passed in when invoke from Finder
+		   or with the 'open' command */
+		if (argv[0][argv_idx] == 's')
+		{
+		    argv_idx = -1; /* bypass full -psn */
+		    main_start_gui();
+		    break;
+		}
+#endif
 #ifdef FEAT_WINDOWS
 		/* default is 0: open window for each file */
 		parmp->window_count = get_number_arg((char_u *)argv[0],
diff --git a/src/misc1.c b/src/misc1.c
index bcc43dafbf..97e41964f2 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -2033,6 +2033,9 @@ ins_char_bytes(buf, charlen)
 	    && msg_silent == 0
 #ifdef FEAT_MBYTE
 	    && charlen == 1
+#endif
+#ifdef FEAT_INS_EXPAND
+	    && !ins_compl_active()
 #endif
        )
 	showmatch(c);
diff --git a/src/proto/edit.pro b/src/proto/edit.pro
index 3939efc371..5434b1c1b3 100644
--- a/src/proto/edit.pro
+++ b/src/proto/edit.pro
@@ -12,6 +12,7 @@ int ins_compl_add __ARGS((char_u *str, int len, char_u *fname, char_u *extra, in
 void ins_compl_show_pum __ARGS((void));
 char_u *find_word_start __ARGS((char_u *ptr));
 char_u *find_word_end __ARGS((char_u *ptr));
+int ins_compl_active __ARGS((void));
 void ins_compl_check_keys __ARGS((int frequency));
 int get_literal __ARGS((void));
 void insertchar __ARGS((int c, int flags, int second_indent));
diff --git a/src/screen.c b/src/screen.c
index 928b1b01bf..f36ac81a45 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -2516,6 +2516,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
     long	v;
 
     int		char_attr = 0;		/* attributes for next character */
+    int		attr_pri = FALSE;	/* char_attr has priority */
     int		area_highlighting = FALSE; /* Visual or incsearch highlighting
 					      in this line */
     int		attr = 0;		/* attributes for area highlighting */
@@ -2764,7 +2765,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
     }
 
     /*
-     * handle 'insearch' and ":s///c" highlighting
+     * handle 'incsearch' and ":s///c" highlighting
      */
     else
 #endif /* FEAT_VISUAL */
@@ -3287,14 +3288,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
 	    else if (area_attr != 0
 		    && (vcol == tocol
 			|| (noinvcur && (colnr_T)vcol == wp->w_virtcol)))
-#ifdef LINE_ATTR
-		area_attr = line_attr;		/* stop highlighting */
-	    else if (line_attr && ((fromcol == -10 && tocol == MAXCOL)
-					 || (vcol < fromcol || vcol > tocol)))
-		area_attr = line_attr;
-#else
 		area_attr = 0;			/* stop highlighting */
-#endif
 
 #ifdef FEAT_SEARCH_EXTRA
 	    if (!n_extra)
@@ -3370,33 +3364,40 @@ win_line(wp, lnum, startrow, endrow, nochange)
 	    }
 #endif
 
-	    if (area_attr != 0)
-		char_attr = area_attr;
-#ifdef FEAT_SYN_HL
-	    else if (search_attr == 0 && has_syntax)
-		char_attr = syntax_attr;
-#endif
-	    else
-		char_attr = search_attr;
-
 #ifdef FEAT_DIFF
-	    if (diff_hlf != (hlf_T)0 && n_extra == 0)
+	    if (diff_hlf != (hlf_T)0)
 	    {
 		if (diff_hlf == HLF_CHD && ptr - line >= change_start)
 		    diff_hlf = HLF_TXD;		/* changed text */
 		if (diff_hlf == HLF_TXD && ptr - line > change_end)
 		    diff_hlf = HLF_CHD;		/* changed line */
-		if (attr == 0 || area_attr != attr)
-		    area_attr = hl_attr(diff_hlf);
-		if (attr == 0 || char_attr != attr)
-		{
-		    if (search_attr != 0)
-			char_attr = search_attr;
-		    else
-			char_attr = hl_attr(diff_hlf);
-		}
+		line_attr = hl_attr(diff_hlf);
 	    }
 #endif
+
+	    /* Decide which of the highlight attributes to use. */
+	    attr_pri = TRUE;
+	    if (area_attr != 0)
+		char_attr = area_attr;
+	    else if (search_attr != 0)
+		char_attr = search_attr;
+#ifdef LINE_ATTR
+		/* Use line_attr when not in the Visual or 'incsearch' area
+		 * (area_attr may be 0 when "noinvcur" is set). */
+	    else if (line_attr != 0 && ((fromcol == -10 && tocol == MAXCOL)
+					|| (vcol < fromcol || vcol >= tocol)))
+		char_attr = line_attr;
+#endif
+	    else
+	    {
+		attr_pri = FALSE;
+#ifdef FEAT_SYN_HL
+		if (has_syntax)
+		    char_attr = syntax_attr;
+		else
+#endif
+		    char_attr = 0;
+	    }
 	}
 
 	/*
@@ -3727,7 +3728,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
 		    line = ml_get_buf(wp->w_buffer, lnum, FALSE);
 		    ptr = line + v;
 
-		    if (area_attr == 0 && search_attr == 0)
+		    if (!attr_pri)
 			char_attr = syntax_attr;
 		    else
 			char_attr = hl_combine_attr(syntax_attr, char_attr);
@@ -3740,7 +3741,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
 		if (has_spell && v >= word_end && v > cur_checked_col)
 		{
 		    spell_attr = 0;
-		    if (area_attr == 0 && search_attr == 0)
+		    if (!attr_pri)
 			char_attr = syntax_attr;
 		    if (c != 0 && (!has_syntax || can_spell))
 		    {
@@ -3813,7 +3814,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
 		}
 		if (spell_attr != 0)
 		{
-		    if (area_attr == 0 && search_attr == 0)
+		    if (!attr_pri)
 			char_attr = hl_combine_attr(char_attr, spell_attr);
 		    else
 			char_attr = hl_combine_attr(spell_attr, char_attr);
@@ -3840,7 +3841,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
 		if (trailcol != MAXCOL && ptr > line + trailcol && c == ' ')
 		{
 		    c = lcs_trail;
-		    if (area_attr == 0 && search_attr == 0)
+		    if (!attr_pri)
 		    {
 			n_attr = 1;
 			extra_attr = hl_attr(HLF_8);
@@ -3953,7 +3954,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
 			c = ' ';
 		    lcs_eol_one = -1;
 		    --ptr;	    /* put it back at the NUL */
-		    if (area_attr == 0 && search_attr == 0)
+		    if (!attr_pri)
 		    {
 			extra_attr = hl_attr(HLF_AT);
 			n_attr = 1;
@@ -3979,7 +3980,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
 		    n_extra = byte2cells(c) - 1;
 		    c_extra = NUL;
 		    c = *p_extra++;
-		    if (area_attr == 0 && search_attr == 0)
+		    if (!attr_pri)
 		    {
 			n_attr = n_extra + 1;
 			extra_attr = hl_attr(HLF_8);
@@ -4042,8 +4043,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
 	/* Don't override visual selection highlighting. */
 	if (n_attr > 0
 		&& draw_state == WL_LINE
-		&& (area_attr == 0 || char_attr != area_attr)
-		&& (search_attr == 0 || char_attr != search_attr))
+		&& !attr_pri)
 	    char_attr = extra_attr;
 
 #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
@@ -4108,8 +4108,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
 	    else
 		mb_utf8 = FALSE;	/* don't draw as UTF-8 */
 #endif
-	    if ((area_attr == 0 || char_attr != area_attr)
-		    && (search_attr == 0 || char_attr != search_attr))
+	    if (!attr_pri)
 	    {
 		saved_attr3 = char_attr; /* save current attr */
 		char_attr = hl_attr(HLF_AT); /* later copied to char_attr */
diff --git a/src/version.h b/src/version.h
index 80a3f61a4f..e09294a0bd 100644
--- 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 17)"
-#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0aa ALPHA (2006 Feb 17, compiled "
+#define VIM_VERSION_LONG	"VIM - Vi IMproved 7.0aa ALPHA (2006 Feb 18)"
+#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0aa ALPHA (2006 Feb 18, compiled "
diff --git a/src/vim.h b/src/vim.h
index 9af9514045..ef86e81bb9 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -347,7 +347,7 @@ typedef unsigned long	long_u;
 /*
  * The characters and attributes cached for the screen.
  */
-#define schar_T	char_u
+typedef char_u schar_T;
 #ifdef FEAT_SYN_HL
 typedef unsigned short sattr_T;
 # define MAX_TYPENR 65535
@@ -1109,6 +1109,8 @@ enum auto_event
     EVENT_SPELLFILEMISSING,	/* spell file missing */
     EVENT_CURSORMOVED,		/* cursor was moved */
     EVENT_CURSORMOVEDI,		/* cursor was moved in Insert mode */
+    EVENT_TABLEAVEPRE,		/* before leaving a tab page */
+    EVENT_TABENTERPOST,		/* after entering a tab page */
     NUM_EVENTS			/* MUST be the last one */
 };
 
diff --git a/src/window.c b/src/window.c
index 03cc56c7ec..b117fe32c1 100644
--- a/src/window.c
+++ b/src/window.c
@@ -46,7 +46,7 @@ static int win_alloc_firstwin __ARGS((void));
 #if defined(FEAT_WINDOWS) || defined(PROTO)
 static tabpage_T *alloc_tabpage __ARGS((void));
 static void free_tabpage __ARGS((tabpage_T *tp));
-static void leave_tabpage __ARGS((tabpage_T *tp));
+static int leave_tabpage __ARGS((buf_T *new_curbuf));
 static void enter_tabpage __ARGS((tabpage_T *tp, buf_T *old_curbuf));
 static void frame_fix_height __ARGS((win_T *wp));
 static int frame_minheight __ARGS((frame_T *topfrp, win_T *next_curwin));
@@ -2282,15 +2282,15 @@ alt_tabpage()
 {
     tabpage_T	*tp;
 
-    /* Use the next tab page if it exists. */
-    if (curtab->tp_next != NULL)
+    /* Use the next tab page if we are currently at the first one. */
+    if (curtab == first_tabpage)
 	return curtab->tp_next;
 
     /* Find the previous tab page. */
     for (tp = first_tabpage; tp->tp_next != NULL; tp = tp->tp_next)
 	if (tp->tp_next == curtab)
-	    return tp;
-    return first_tabpage;
+	    break;
+    return tp;
 }
 
 /*
@@ -2963,7 +2963,11 @@ win_new_tabpage()
 	return FAIL;
 
     /* Remember the current windows in this Tab page. */
-    leave_tabpage(curtab);
+    if (leave_tabpage(NULL) == FAIL)
+    {
+	vim_free(newtp);
+	return FAIL;
+    }
     curtab = newtp;
 
     /* Create a new empty window. */
@@ -2985,12 +2989,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;
-    curtab = tp;
+    enter_tabpage(curtab, curbuf);
     return FAIL;
 }
 
@@ -3060,12 +3059,33 @@ find_tabpage(n)
 }
 
 /*
- * Prepare for leaving the current tab page "tp".
+ * Prepare for leaving the current tab page.
+ * When autocomands change "curtab" we don't leave the tab page and return
+ * FAIL.
+ * Careful: When OK is returned need to get a new tab page very very soon!
  */
-    static void
-leave_tabpage(tp)
-    tabpage_T	*tp;
+/*ARGSUSED*/
+    static int
+leave_tabpage(new_curbuf)
+    buf_T	*new_curbuf;	    /* what is going to be the new curbuf,
+				       NULL if unknown */
 {
+    tabpage_T	*tp = curtab;
+
+#ifdef FEAT_AUTOCMD
+    if (new_curbuf != curbuf)
+    {
+	apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
+	if (curtab != tp)
+	    return FAIL;
+    }
+    apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf);
+    if (curtab != tp)
+	return FAIL;
+    apply_autocmds(EVENT_TABLEAVEPRE, NULL, NULL, FALSE, curbuf);
+    if (curtab != tp)
+	return FAIL;
+#endif
 #if defined(FEAT_GUI)
     /* Remove the scrollbars.  They may be added back later. */
     if (gui.in_use)
@@ -3079,6 +3099,7 @@ leave_tabpage(tp)
     tp->tp_old_Columns = Columns;
     firstwin = NULL;
     lastwin = NULL;
+    return OK;
 }
 
 /*
@@ -3100,6 +3121,8 @@ enter_tabpage(tp, old_curbuf)
     prevwin = tp->tp_prevwin;
 
 #ifdef FEAT_AUTOCMD
+    apply_autocmds(EVENT_TABENTERPOST, NULL, NULL, FALSE, curbuf);
+    apply_autocmds(EVENT_WINENTER, NULL, NULL, FALSE, curbuf);
     if (old_curbuf != curbuf)
 	apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
 #endif
@@ -3114,10 +3137,10 @@ enter_tabpage(tp, old_curbuf)
     /* The tabpage line may have appeared or disappeared, may need to resize
      * the frames for that.  When the Vim window was resized need to update
      * frame sizes too. */
-    if (tp->tp_old_Rows != Rows || old_off != firstwin->w_winrow)
+    if (curtab->tp_old_Rows != Rows || old_off != firstwin->w_winrow)
 	shell_new_rows();
 #ifdef FEAT_VERTSPLIT
-    if (tp->tp_old_Columns != Columns && starting == 0)
+    if (curtab->tp_old_Columns != Columns && starting == 0)
 	shell_new_columns();	/* update window widths */
 #endif
 
@@ -3143,20 +3166,16 @@ enter_tabpage(tp, old_curbuf)
 goto_tabpage(n)
     int	    n;
 {
-    tabpage_T	*otp = curtab;
     tabpage_T	*tp;
     int		i;
 
-    if (otp == NULL)
-	return;
-
     if (n == 0)
     {
 	/* No count, go to next tab page, wrap around end. */
-	if (otp->tp_next == NULL)
+	if (curtab->tp_next == NULL)
 	    tp = first_tabpage;
 	else
-	    tp = otp->tp_next;
+	    tp = curtab->tp_next;
     }
     else
     {
@@ -3171,8 +3190,13 @@ goto_tabpage(n)
 	}
     }
 
-    leave_tabpage(otp);
-    enter_tabpage(tp, curbuf);
+    if (leave_tabpage(tp->tp_curwin->w_buffer) == OK)
+    {
+	if (valid_tabpage(tp))
+	    enter_tabpage(tp, curbuf);
+	else
+	    enter_tabpage(curtab, curbuf);
+    }
 }
 
 /*
-- 
GitLab