Index: patches/vim-7.1-branch_update-2.patch
===================================================================
--- patches/vim-7.1-branch_update-2.patch	(revision 867103a20535e8a33175050de8a87ae8b5ddde07)
+++ patches/vim-7.1-branch_update-2.patch	(revision 867103a20535e8a33175050de8a87ae8b5ddde07)
@@ -0,0 +1,9755 @@
+Submitted By: Jim Gifford (jim at linuxfromscratch dot org)
+Date: 12-21-2007
+Initial Package Version: 7.1
+Origin: Upstream
+Upstream Status: Applied
+Description: Contains all upstream patches up to 7.1.175
+             The following patches were skipped
+             003 007 041 065 070 072 080 088 091 092 124 126 128 129 134 146 158 168
+
+diff -Naur vim71.orig/runtime/doc/change.txt vim71/runtime/doc/change.txt
+--- vim71.orig/runtime/doc/change.txt	2007-05-12 06:18:46.000000000 -0400
++++ vim71/runtime/doc/change.txt	2007-12-20 23:57:04.000000000 -0500
+@@ -1571,6 +1571,10 @@
+ 			in their original order, right before the sorted
+ 			lines.
+ 
++			If {pattern} is empty (e.g. // is specified), the
++			last search pattern is used.  This allows trying out
++			a pattern first.
++
+ Note that using ":sort" with ":global" doesn't sort the matching lines, it's
+ quite useless.
+ 
+diff -Naur vim71.orig/runtime/doc/eval.txt vim71/runtime/doc/eval.txt
+--- vim71.orig/runtime/doc/eval.txt	2007-05-12 06:18:46.000000000 -0400
++++ vim71/runtime/doc/eval.txt	2007-12-20 23:58:59.000000000 -0500
+@@ -1,4 +1,4 @@
+-*eval.txt*      For Vim version 7.1.  Last change: 2007 May 11
++*eval.txt*      For Vim version 7.1.  Last change: 2007 Sep 25
+ 
+ 
+ 		  VIM REFERENCE MANUAL    by Bram Moolenaar
+@@ -1557,6 +1557,7 @@
+ changenr()			Number  current change number
+ char2nr( {expr})		Number	ASCII value of first char in {expr}
+ cindent( {lnum})		Number	C indent for line {lnum}
++clearmatches()			None	clear all matches
+ col( {expr})			Number	column nr of cursor or mark
+ complete({startcol}, {matches})	String  set Insert mode completion
+ complete_add( {expr})		Number	add completion match
+@@ -1602,7 +1603,7 @@
+ foldtextresult( {lnum})		String	text for closed fold at {lnum}
+ foreground( )			Number	bring the Vim window to the foreground
+ function( {name})		Funcref reference to function {name}
+-garbagecollect()		none	free memory, breaking cyclic references
++garbagecollect( [at_exit])	none	free memory, breaking cyclic references
+ get( {list}, {idx} [, {def}])	any	get item {idx} from {list} or {def}
+ get( {dict}, {key} [, {def}])	any	get item {key} from {dict} or {def}
+ getbufline( {expr}, {lnum} [, {end}])
+@@ -1622,6 +1623,7 @@
+ getline( {lnum})		String	line {lnum} of current buffer
+ getline( {lnum}, {end})		List	lines {lnum} to {end} of current buffer
+ getloclist({nr})		List	list of location list items
++getmatches()			List	list of current matches
+ getpos( {expr})			List	position of cursor, mark, etc.
+ getqflist()			List	list of quickfix items
+ getreg( [{regname} [, 1]])	String	contents of register
+@@ -1676,7 +1678,10 @@
+ 				String	check for mappings matching {name}
+ match( {expr}, {pat}[, {start}[, {count}]])
+ 				Number	position where {pat} matches in {expr}
++matchadd( {group}, {pattern}[, {priority}[, {id}]])
++				Number	highlight {pattern} with {group}
+ matcharg( {nr})			List	arguments of |:match|
++matchdelete( {id})		Number	delete match identified by {id}
+ matchend( {expr}, {pat}[, {start}[, {count}]])
+ 				Number	position where {pat} ends in {expr}
+ matchlist( {expr}, {pat}[, {start}[, {count}]])
+@@ -1731,6 +1736,7 @@
+ setline( {lnum}, {line})	Number	set line {lnum} to {line}
+ setloclist( {nr}, {list}[, {action}])
+ 				Number	modify location list using {list}
++setmatches( {list})		Number	restore a list of matches
+ setpos( {expr}, {list})		none	set the {expr} position to {list}
+ setqflist( {list}[, {action}])	Number	modify quickfix list using {list}
+ setreg( {n}, {v}[, {opt}])	Number	set register to value and type
+@@ -2012,6 +2018,10 @@
+ 		feature, -1 is returned.
+ 		See |C-indenting|.
+ 
++clearmatches()						*clearmatches()*
++		Clears all matches previously defined by |matchadd()| and the
++		|:match| commands.
++
+ 							*col()*
+ col({expr})	The result is a Number, which is the byte index of the column
+ 		position given with {expr}.  The accepted positions are:
+@@ -2020,6 +2030,10 @@
+ 			    number of characters in the cursor line plus one)
+ 		    'x	    position of mark x (if the mark is not set, 0 is
+ 			    returned)
++		Additionally {expr} can be [lnum, col]: a |List| with the line
++		and column number. Most useful when the column is "$", to get
++		the las column of a specific line.  When "lnum" or "col" is
++		out of range then col() returns zero.
+ 		To get the line number use |line()|.  To get both use
+ 		|getpos()|.
+ 		For the screen column position use |virtcol()|.
+@@ -2659,7 +2673,7 @@
+ 		{name} can be a user defined function or an internal function.
+ 
+ 
+-garbagecollect()					*garbagecollect()*
++garbagecollect([at_exit])				*garbagecollect()*
+ 		Cleanup unused |Lists| and |Dictionaries| that have circular
+ 		references.  There is hardly ever a need to invoke this
+ 		function, as it is automatically done when Vim runs out of
+@@ -2669,6 +2683,9 @@
+ 		This is useful if you have deleted a very big |List| and/or
+ 		|Dictionary| with circular references in a script that runs
+ 		for a long time.
++		When the optional "at_exit" argument is one, garbage
++		collection will also be done when exiting Vim, if it wasn't
++		done before.  This is useful when checking for memory leaks.
+ 
+ get({list}, {idx} [, {default}])			*get()*
+ 		Get item {idx} from |List| {list}.  When this item is not
+@@ -2824,6 +2841,8 @@
+ 		given file {fname}.
+ 		If {fname} is a directory, 0 is returned.
+ 		If the file {fname} can't be found, -1 is returned.
++		If the size of {fname} is too big to fit in a Number then -2
++		is returned.
+ 
+ getfontname([{name}])					*getfontname()*
+ 		Without an argument returns the name of the normal font being
+@@ -2912,6 +2931,28 @@
+ 		returned.  For an invalid window number {nr}, an empty list is
+ 		returned. Otherwise, same as getqflist().
+ 
++getmatches()						*getmatches()*
++		Returns a |List| with all matches previously defined by
++		|matchadd()| and the |:match| commands.  |getmatches()| is
++		useful in combination with |setmatches()|, as |setmatches()|
++		can restore a list of matches saved by |getmatches()|.
++		Example: >
++			:echo getmatches()
++<			[{'group': 'MyGroup1', 'pattern': 'TODO',
++			'priority': 10, 'id': 1}, {'group': 'MyGroup2',
++			'pattern': 'FIXME', 'priority': 10, 'id': 2}] >
++			:let m = getmatches()
++			:call clearmatches()
++			:echo getmatches()
++<			[] >
++			:call setmatches(m)
++			:echo getmatches()
++<			[{'group': 'MyGroup1', 'pattern': 'TODO',
++			'priority': 10, 'id': 1}, {'group': 'MyGroup2',
++			'pattern': 'FIXME', 'priority': 10, 'id': 2}] >
++			:unlet m
++<
++
+ getqflist()						*getqflist()*
+ 		Returns a list with all the current quickfix errors.  Each
+ 		list item is a dictionary with these entries:
+@@ -3616,6 +3657,44 @@
+ 		the pattern.  'smartcase' is NOT used.  The matching is always
+ 		done like 'magic' is set and 'cpoptions' is empty.
+ 
++					*matchadd()* *E798* *E799* *E801*
++matchadd({group}, {pattern}[, {priority}[, {id}]])
++		Defines a pattern to be highlighted in the current window (a
++		"match").  It will be highlighted with {group}.  Returns an
++		identification number (ID), which can be used to delete the
++		match using |matchdelete()|.
++
++		The optional {priority} argument assigns a priority to the
++		match.  A match with a high priority will have its
++		highlighting overrule that of a match with a lower priority.
++		A priority is specified as an integer (negative numbers are no
++		exception).  If the {priority} argument is not specified, the
++		default priority is 10.  The priority of 'hlsearch' is zero,
++		hence all matches with a priority greater than zero will
++		overrule it.  Syntax highlighting (see 'syntax') is a separate
++		mechanism, and regardless of the chosen priority a match will
++		always overrule syntax highlighting.
++
++		The optional {id} argument allows the request for a specific
++		match ID.  If a specified ID is already taken, an error
++		message will appear and the match will not be added.  An ID
++		is specified as a positive integer (zero excluded).  IDs 1, 2
++		and 3 are reserved for |:match|, |:2match| and |:3match|,
++		respectively.  If the {id} argument is not specified,
++		|matchadd()| automatically chooses a free ID.
++
++		The number of matches is not limited, as it is the case with
++		the |:match| commands.
++
++		Example: >
++			:highlight MyGroup ctermbg=green guibg=green
++			:let m = matchadd("MyGroup", "TODO")
++<		Deletion of the pattern: >
++			:call matchdelete(m)
++
++<		A list of matches defined by |matchadd()| and |:match| are
++		available from |getmatches()|.  All matches can be deleted in
++		one operation by |clearmatches()|.
+ 
+ matcharg({nr})							*matcharg()*
+ 		Selects the {nr} match item, as set with a |:match|,
+@@ -3625,8 +3704,15 @@
+ 			The pattern used.
+ 		When {nr} is not 1, 2 or 3 returns an empty |List|.
+ 		When there is no match item set returns ['', ''].
+-		This is usef to save and restore a |:match|.
+-
++		This is useful to save and restore a |:match|.
++		Highlighting matches using the |:match| commands are limited
++		to three matches. |matchadd()| does not have this limitation.
++
++matchdelete({id})			       *matchdelete()* *E802* *E803*
++		Deletes a match with ID {id} previously defined by |matchadd()|
++		or one of the |:match| commands.  Returns 0 if succesfull,
++		otherwise -1.  See example for |matchadd()|.  All matches can
++		be deleted in one operation by |clearmatches()|.
+ 
+ matchend({expr}, {pat}[, {start}[, {count}]])			*matchend()*
+ 		Same as match(), but return the index of first character after
+@@ -4379,7 +4465,13 @@
+ 		When {nr} is zero the current window is used. For a location
+ 		list window, the displayed location list is modified.  For an
+ 		invalid window number {nr}, -1 is returned.
+-		Otherwise, same as setqflist().
++		Otherwise, same as |setqflist()|.
++		Also see |location-list|.
++
++setmatches({list})					*setmatches()*
++		Restores a list of matches saved by |getmatches()|.  Returns 0
++		if succesfull, otherwise -1.  All current matches are cleared
++		before the list is restored.  See example for |getmatches()|.
+ 
+ 							*setpos()*
+ setpos({expr}, {list})
+@@ -5022,14 +5114,12 @@
+ 		position, the returned Number will be the column at the end of
+ 		the <Tab>.  For example, for a <Tab> in column 1, with 'ts'
+ 		set to 8, it returns 8.
+-		For the use of {expr} see |col()|.  Additionally you can use
+-		[lnum, col]: a |List| with the line and column number.  When
+-		"lnum" or "col" is out of range then virtcol() returns zero.
+-		When 'virtualedit' is used it can be [lnum, col, off], where
++		For the byte position use |col()|.
++		For the use of {expr} see |col()|.
++		When 'virtualedit' is used {expr} can be [lnum, col, off], where
+ 		"off" is the offset in screen columns from the start of the
+ 		character.  E.g., a position within a <Tab> or after the last
+ 		character.
+-		For the byte position use |col()|.
+ 		When Virtual editing is active in the current mode, a position
+ 		beyond the end of the line can be returned. |'virtualedit'|
+ 		The accepted positions are:
+diff -Naur vim71.orig/runtime/doc/options.txt vim71/runtime/doc/options.txt
+--- vim71.orig/runtime/doc/options.txt	2007-05-12 06:18:47.000000000 -0400
++++ vim71/runtime/doc/options.txt	2007-12-20 23:57:54.000000000 -0500
+@@ -1,4 +1,4 @@
+-*options.txt*	For Vim version 7.1.  Last change: 2007 May 11
++*options.txt*	For Vim version 7.1.  Last change: 2007 Aug 10
+ 
+ 
+ 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
+@@ -2415,8 +2415,8 @@
+ 	When mixing vertically and horizontally split windows, a minimal size
+ 	is computed and some windows may be larger if there is room.  The
+ 	'eadirection' option tells in which direction the size is affected.
+-	Changing the height of a window can be avoided by setting
+-	'winfixheight'.
++	Changing the height and width of a window can be avoided by setting
++	'winfixheight' and 'winfixwidth', respectively.
+ 
+ 						*'equalprg'* *'ep'*
+ 'equalprg' 'ep'		string	(default "")
+diff -Naur vim71.orig/runtime/doc/pattern.txt vim71/runtime/doc/pattern.txt
+--- vim71.orig/runtime/doc/pattern.txt	2007-05-12 06:18:47.000000000 -0400
++++ vim71/runtime/doc/pattern.txt	2007-12-20 23:57:20.000000000 -0500
+@@ -1212,7 +1212,10 @@
+ 		{group} must exist at the moment this command is executed.
+ 
+ 		The {group} highlighting still applies when a character is
+-		to be highlighted for 'hlsearch'.
++		to be highlighted for 'hlsearch', as the highlighting for
++		matches is given higher priority than that of 'hlsearch'.
++		Syntax highlighting (see 'syntax') is also overruled by
++		matches.
+ 
+ 		Note that highlighting the last used search pattern with
+ 		'hlsearch' is used in all windows, while the pattern defined
+@@ -1226,8 +1229,15 @@
+ 		display you may get unexpected results.  That is because Vim
+ 		looks for a match in the line where redrawing starts.
+ 
+-		Also see |matcharg()|, it returns the highlight group and
+-		pattern of a previous :match command.
++		Also see |matcharg()|and |getmatches()|. The former returns
++		the highlight group and pattern of a previous |:match|
++		command.  The latter returns a list with highlight groups and
++		patterns defined by both |matchadd()| and |:match|.
++
++		Highlighting matches using |:match| are limited to three
++		matches (aside from |:match|, |:2match| and |:3match|are
++		available). |matchadd()| does not have this limitation and in
++		addition makes it possible to prioritize matches.
+ 
+ 		Another example, which highlights all characters in virtual
+ 		column 72 and more: >
+diff -Naur vim71.orig/runtime/doc/pi_paren.txt vim71/runtime/doc/pi_paren.txt
+--- vim71.orig/runtime/doc/pi_paren.txt	2007-05-12 06:18:47.000000000 -0400
++++ vim71/runtime/doc/pi_paren.txt	2007-12-20 23:58:11.000000000 -0500
+@@ -12,8 +12,8 @@
+ You can avoid loading this plugin by setting the "loaded_matchparen" variable: >
+ 	:let loaded_matchparen = 1
+ 
+-The plugin installs CursorMoved autocommands to redefine the match
+-highlighting.
++The plugin installs CursorMoved, CursorMovedI and WinEnter autocommands to
++redefine the match highlighting.
+ 
+ To disable the plugin after it was loaded use this command: >
+ 
+diff -Naur vim71.orig/runtime/doc/usr_41.txt vim71/runtime/doc/usr_41.txt
+--- vim71.orig/runtime/doc/usr_41.txt	2007-05-12 06:18:48.000000000 -0400
++++ vim71/runtime/doc/usr_41.txt	2007-12-20 23:57:20.000000000 -0500
+@@ -763,13 +763,22 @@
+ 	foldtextresult()	get the text displayed for a closed fold
+ 
+ Syntax and highlighting:
++	clearmatches()		clear all matches defined by |matchadd()| and
++				the |:match| commands
++	getmatches()		get all matches defined by |matchadd()| and
++				the |:match| commands
+ 	hlexists()		check if a highlight group exists
+ 	hlID()			get ID of a highlight group
+ 	synID()			get syntax ID at a specific position
+ 	synIDattr()		get a specific attribute of a syntax ID
+ 	synIDtrans()		get translated syntax ID
+ 	diff_hlID()		get highlight ID for diff mode at a position
++	matchadd()		define a pattern to highlight (a "match")
+ 	matcharg()		get info about |:match| arguments
++	matchdelete()		delete a match defined by |matchadd()| or a
++				|:match| command
++	setmatches()		restore a list of matches saved by
++				|getmatches()|
+ 
+ Spelling:
+ 	spellbadword()		locate badly spelled word at or after cursor
+diff -Naur vim71.orig/runtime/doc/windows.txt vim71/runtime/doc/windows.txt
+--- vim71.orig/runtime/doc/windows.txt	2007-05-12 06:18:49.000000000 -0400
++++ vim71/runtime/doc/windows.txt	2007-12-20 23:57:54.000000000 -0500
+@@ -132,7 +132,8 @@
+ 		the same file.  Make new window N high (default is to use half
+ 		the height of the current window).  Reduces the current window
+ 		height to create room (and others, if the 'equalalways' option
+-		is set and 'eadirection' isn't "hor").
++		is set, 'eadirection' isn't "hor", and one of them is higher
++		than the current or the new window).
+ 		Note: CTRL-S does not work on all terminals and might block
+ 		further input, use CTRL-Q to get going again.
+ 		Also see |++opt| and |+cmd|.
+@@ -140,9 +141,13 @@
+ CTRL-W CTRL-V						*CTRL-W_CTRL-V*
+ CTRL-W v						*CTRL-W_v*
+ :[N]vs[plit] [++opt] [+cmd] [file]			*:vs* *:vsplit*
+-		Like |:split|, but split vertically.  If 'equalalways' is set
+-		and 'eadirection' isn't "ver" the windows will be spread out
+-		horizontally, unless a width was specified.
++		Like |:split|, but split vertically.  The windows will be
++		spread out horizontally if
++		1. a width was not specified,
++		2. 'equalalways' is set,
++		3. 'eadirection' isn't "ver", and
++		4. one of the other windows are wider than the current or new
++		   window.
+ 		Note: In other places CTRL-Q does the same as CTRL-V, but here
+ 		it doesn't!
+ 
+diff -Naur vim71.orig/runtime/filetype.vim vim71/runtime/filetype.vim
+--- vim71.orig/runtime/filetype.vim	2007-05-10 11:14:37.000000000 -0400
++++ vim71/runtime/filetype.vim	2007-12-20 23:56:32.000000000 -0500
+@@ -1,7 +1,7 @@
+ " Vim support file to detect file types
+ "
+ " Maintainer:	Bram Moolenaar <Bram@vim.org>
+-" Last Change:	2007 May 10
++" Last Change:	2007 May 15
+ 
+ " Listen very carefully, I will say this only once
+ if exists("did_load_filetypes")
+@@ -1286,7 +1286,7 @@
+ au BufNewFile,BufRead *.it,*.ih			setf ppwiz
+ 
+ " Oracle Pro*C/C++
+-au BufNewFile,BufRead .pc			setf proc
++au BufNewFile,BufRead *.pc			setf proc
+ 
+ " Privoxy actions file
+ au BufNewFile,BufRead *.action			setf privoxy
+diff -Naur vim71.orig/runtime/menu.vim vim71/runtime/menu.vim
+--- vim71.orig/runtime/menu.vim	2007-01-09 08:31:40.000000000 -0500
++++ vim71/runtime/menu.vim	2007-12-20 23:59:53.000000000 -0500
+@@ -2,7 +2,7 @@
+ " You can also use this as a start for your own set of menus.
+ "
+ " Maintainer:	Bram Moolenaar <Bram@vim.org>
+-" Last Change:	2007 Jan 09
++" Last Change:	2007 Nov 19
+ 
+ " Note that ":an" (short for ":anoremenu") is often used to make a menu work
+ " in all modes and avoid side effects from mappings defined by the user.
+@@ -658,7 +658,6 @@
+   let buf = 1
+   while buf <= bufnr('$')
+     if bufexists(buf) && !isdirectory(bufname(buf)) && buflisted(buf)
+-					    \ && !getbufvar(buf, "&bufsecret")
+       let s:bmenu_count = s:bmenu_count + 1
+     endif
+     let buf = buf + 1
+@@ -671,7 +670,6 @@
+   let buf = 1
+   while buf <= bufnr('$')
+     if bufexists(buf) && !isdirectory(bufname(buf)) && buflisted(buf)
+-					    \ && !getbufvar(buf, "&bufsecret")
+       call <SID>BMFilename(bufname(buf), buf)
+     endif
+     let buf = buf + 1
+diff -Naur vim71.orig/runtime/plugin/matchparen.vim vim71/runtime/plugin/matchparen.vim
+--- vim71.orig/runtime/plugin/matchparen.vim	2006-10-12 16:05:05.000000000 -0400
++++ vim71/runtime/plugin/matchparen.vim	2007-12-20 23:58:11.000000000 -0500
+@@ -1,6 +1,6 @@
+ " Vim plugin for showing matching parens
+ " Maintainer:  Bram Moolenaar <Bram@vim.org>
+-" Last Change: 2006 Oct 12
++" Last Change: 2007 Aug 8
+ 
+ " Exit quickly when:
+ " - this plugin was already loaded (or disabled)
+@@ -13,7 +13,7 @@
+ 
+ augroup matchparen
+   " Replace all matchparen autocommands
+-  autocmd! CursorMoved,CursorMovedI * call s:Highlight_Matching_Pair()
++  autocmd! CursorMoved,CursorMovedI,WinEnter * call s:Highlight_Matching_Pair()
+ augroup END
+ 
+ " Skip the rest if it was already done.
+@@ -62,25 +62,37 @@
+   " Figure out the arguments for searchpairpos().
+   " Restrict the search to visible lines with "stopline".
+   " And avoid searching very far (e.g., for closed folds and long lines)
++  " The "viewable" variables give a range in which we can scroll while keeping
++  " the cursor at the same position
++  " adjustedScrolloff accounts for very large numbers of scrolloff
++  let adjustedScrolloff = min([&scrolloff, (line('w$') - line('w0')) / 2])
++  let bottom_viewable = min([line('$'), c_lnum + &lines - adjustedScrolloff - 2])
++  let top_viewable = max([1, c_lnum-&lines+adjustedScrolloff + 2])
++  " one of these stoplines will be adjusted below, but the current values are
++  " minimal boundaries within the current window
++  let stoplinebottom = line('w$')
++  let stoplinetop = line('w0')
+   if i % 2 == 0
+     let s_flags = 'nW'
+     let c2 = plist[i + 1]
+     if has("byte_offset") && has("syntax_items") && &smc > 0
+       let stopbyte = min([line2byte("$"), line2byte(".") + col(".") + &smc * 2])
+-      let stopline = min([line('w$'), byte2line(stopbyte)])
++      let stopline = min([bottom_viewable, byte2line(stopbyte)])
+     else
+-      let stopline = min([line('w$'), c_lnum + 100])
++      let stopline = min([bottom_viewable, c_lnum + 100])
+     endif
++    let stoplinebottom = stopline
+   else
+     let s_flags = 'nbW'
+     let c2 = c
+     let c = plist[i - 1]
+     if has("byte_offset") && has("syntax_items") && &smc > 0
+       let stopbyte = max([1, line2byte(".") + col(".") - &smc * 2])
+-      let stopline = max([line('w0'), byte2line(stopbyte)])
++      let stopline = max([top_viewable, byte2line(stopbyte)])
+     else
+-      let stopline = max([line('w0'), c_lnum - 100])
++      let stopline = max([top_viewable, c_lnum - 100])
+     endif
++    let stoplinetop = stopline
+   endif
+   if c == '['
+     let c = '\['
+@@ -106,7 +118,7 @@
+   endif
+ 
+   " If a match is found setup match highlighting.
+-  if m_lnum > 0 && m_lnum >= line('w0') && m_lnum <= line('w$')
++  if m_lnum > 0 && m_lnum >= stoplinetop && m_lnum <= stoplinebottom 
+     exe '3match MatchParen /\(\%' . c_lnum . 'l\%' . (c_col - before) .
+ 	  \ 'c\)\|\(\%' . m_lnum . 'l\%' . m_col . 'c\)/'
+     let w:paren_hl_on = 1
+@@ -114,7 +126,8 @@
+ endfunction
+ 
+ " Define commands that will disable and enable the plugin.
+-command! NoMatchParen 3match none | unlet! g:loaded_matchparen | au! matchparen
+-command! DoMatchParen runtime plugin/matchparen.vim | doau CursorMoved
++command! NoMatchParen windo 3match none | unlet! g:loaded_matchparen |
++	  \ au! matchparen
++command! DoMatchParen runtime plugin/matchparen.vim | windo doau CursorMoved
+ 
+ let &cpo = cpo_save
+diff -Naur vim71.orig/src/auto/configure vim71/src/auto/configure
+--- vim71.orig/src/auto/configure	2007-05-12 07:49:09.000000000 -0400
++++ vim71/src/auto/configure	2007-12-20 23:59:34.000000000 -0500
+@@ -3843,7 +3843,9 @@
+   fi
+ 
+   if test "X$vi_cv_path_mzscheme_pfx" != "X"; then
+-    if test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"; then
++    if test "x$MACOSX" = "xyes"; then
++      MZSCHEME_LIBS="-framework PLT_MzScheme"
++    elif test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"; then
+       MZSCHEME_LIBS="${vi_cv_path_mzscheme_pfx}/lib/libmzscheme.a ${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"
+     else
+       MZSCHEME_LIBS="-L${vi_cv_path_mzscheme_pfx}/lib -lmzscheme -lmzgc"
+@@ -10263,8 +10265,9 @@
+ 
+ 
+ 
++
+ for ac_header in stdarg.h stdlib.h string.h sys/select.h sys/utsname.h \
+-	termcap.h fcntl.h sgtty.h sys/ioctl.h sys/time.h termio.h \
++	termcap.h fcntl.h sgtty.h sys/ioctl.h sys/time.h sys/types.h termio.h \
+ 	iconv.h langinfo.h unistd.h stropts.h errno.h \
+ 	sys/resource.h sys/systeminfo.h locale.h \
+ 	sys/stream.h sys/ptem.h termios.h libc.h sys/statfs.h \
+diff -Naur vim71.orig/src/buffer.c vim71/src/buffer.c
+--- vim71.orig/src/buffer.c	2007-05-10 11:25:59.000000000 -0400
++++ vim71/src/buffer.c	2007-12-20 23:59:17.000000000 -0500
+@@ -171,6 +171,13 @@
+ 	    /* Put the cursor on the first line. */
+ 	    curwin->w_cursor.lnum = 1;
+ 	    curwin->w_cursor.col = 0;
++
++	    /* Set or reset 'modified' before executing autocommands, so that
++	     * it can be changed there. */
++	    if (!readonlymode && !bufempty())
++		changed();
++	    else if (retval != FAIL)
++		unchanged(curbuf, FALSE);
+ #ifdef FEAT_AUTOCMD
+ # ifdef FEAT_EVAL
+ 	    apply_autocmds_retval(EVENT_STDINREADPOST, NULL, NULL, FALSE,
+@@ -194,16 +201,16 @@
+     /* When reading stdin, the buffer contents always needs writing, so set
+      * the changed flag.  Unless in readonly mode: "ls | gview -".
+      * When interrupted and 'cpoptions' contains 'i' set changed flag. */
+-    if ((read_stdin && !readonlymode && !bufempty())
++    if ((got_int && vim_strchr(p_cpo, CPO_INTMOD) != NULL)
+ #ifdef FEAT_AUTOCMD
+ 		|| modified_was_set	/* ":set modified" used in autocmd */
+ # ifdef FEAT_EVAL
+ 		|| (aborting() && vim_strchr(p_cpo, CPO_INTMOD) != NULL)
+ # endif
+ #endif
+-		|| (got_int && vim_strchr(p_cpo, CPO_INTMOD) != NULL))
++       )
+ 	changed();
+-    else if (retval != FAIL)
++    else if (retval != FAIL && !read_stdin)
+ 	unchanged(curbuf, FALSE);
+     save_file_ff(curbuf);		/* keep this fileformat */
+ 
+@@ -495,6 +502,7 @@
+     buf->b_start_eol = TRUE;
+ #ifdef FEAT_MBYTE
+     buf->b_p_bomb = FALSE;
++    buf->b_start_bomb = FALSE;
+ #endif
+     buf->b_ml.ml_mfp = NULL;
+     buf->b_ml.ml_flags = ML_EMPTY;		/* empty buffer */
+@@ -4167,29 +4175,35 @@
+      * mess up the full path name, even though it starts with a '/'.
+      * Also expand when there is ".." in the file name, try to remove it,
+      * because "c:/src/../README" is equal to "c:/README".
++     * Similarly "c:/src//file" is equal to "c:/src/file".
+      * For MS-Windows also expand names like "longna~1" to "longname".
+      */
+ #ifdef UNIX
+     return FullName_save(fname, TRUE);
+ #else
+-    if (!vim_isAbsName(fname) || strstr((char *)fname, "..") != NULL
+-#if defined(MSWIN) || defined(DJGPP)
++    if (!vim_isAbsName(fname)
++	    || strstr((char *)fname, "..") != NULL
++	    || strstr((char *)fname, "//") != NULL
++# ifdef BACKSLASH_IN_FILENAME
++	    || strstr((char *)fname, "\\\\") != NULL
++# endif
++# if defined(MSWIN) || defined(DJGPP)
+ 	    || vim_strchr(fname, '~') != NULL
+-#endif
++# endif
+ 	    )
+ 	return FullName_save(fname, FALSE);
+ 
+     fname = vim_strsave(fname);
+ 
+-#ifdef USE_FNAME_CASE
+-# ifdef USE_LONG_FNAME
++# ifdef USE_FNAME_CASE
++#  ifdef USE_LONG_FNAME
+     if (USE_LONG_FNAME)
+-# endif
++#  endif
+     {
+ 	if (fname != NULL)
+ 	    fname_case(fname, 0);	/* set correct case for file name */
+     }
+-#endif
++# endif
+ 
+     return fname;
+ #endif
+@@ -4853,7 +4867,7 @@
+ 	     */
+ 	    for (e = s; *e != ':' && *e != NUL; ++e)
+ 		if (e[0] == '\\' && e[1] == ':')
+-		    STRCPY(e, e + 1);
++		    mch_memmove(e, e + 1, STRLEN(e));
+ 	    if (*e == NUL)
+ 		end = TRUE;
+ 
+@@ -5507,11 +5521,11 @@
+ 
+ #ifdef FEAT_AUTOCMD
+     if (!aucmd)		    /* Don't trigger BufDelete autocommands here. */
+-	++autocmd_block;
++	block_autocmds();
+ #endif
+     close_buffer(NULL, buf, DOBUF_WIPE);
+ #ifdef FEAT_AUTOCMD
+     if (!aucmd)
+-	--autocmd_block;
++	unblock_autocmds();
+ #endif
+ }
+diff -Naur vim71.orig/src/charset.c vim71/src/charset.c
+--- vim71.orig/src/charset.c	2007-03-24 16:10:37.000000000 -0400
++++ vim71/src/charset.c	2007-12-20 23:58:12.000000000 -0500
+@@ -207,7 +207,10 @@
+ 	    }
+ 	    while (c <= c2)
+ 	    {
+-		if (!do_isalpha || isalpha(c)
++		/* Use the MB_ functions here, because isalpha() doesn't
++		 * work properly when 'encoding' is "latin1" and the locale is
++		 * "C".  */
++		if (!do_isalpha || MB_ISLOWER(c) || MB_ISUPPER(c)
+ #ifdef FEAT_FKMAP
+ 			|| (p_altkeymap && (F_isalpha(c) || F_isdigit(c)))
+ #endif
+@@ -929,6 +932,23 @@
+ }
+ 
+ /*
++ * return TRUE if 'c' is a valid file-name character or a wildcard character
++ * Assume characters above 0x100 are valid (multi-byte).
++ * Explicitly interpret ']' as a wildcard character as mch_has_wildcard("]")
++ * returns false.
++ */
++    int
++vim_isfilec_or_wc(c)
++    int c;
++{
++    char_u buf[2];
++
++    buf[0] = (char_u)c;
++    buf[1] = NUL;
++    return vim_isfilec(c) || c == ']' || mch_has_wildcard(buf);
++}
++
++/*
+  * return TRUE if 'c' is a printable character
+  * Assume characters above 0x100 are printable (multi-byte), except for
+  * Unicode.
+@@ -1898,7 +1918,7 @@
+ {
+     for ( ; *p; ++p)
+ 	if (rem_backslash(p))
+-	    STRCPY(p, p + 1);
++	    mch_memmove(p, p + 1, STRLEN(p));
+ }
+ 
+ /*
+diff -Naur vim71.orig/src/configure.in vim71/src/configure.in
+--- vim71.orig/src/configure.in	2007-05-12 05:19:27.000000000 -0400
++++ vim71/src/configure.in	2007-12-20 23:59:34.000000000 -0500
+@@ -423,7 +423,9 @@
+   fi
+ 
+   if test "X$vi_cv_path_mzscheme_pfx" != "X"; then
+-    if test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"; then
++    if test "x$MACOSX" = "xyes"; then
++      MZSCHEME_LIBS="-framework PLT_MzScheme"
++    elif test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"; then
+       MZSCHEME_LIBS="${vi_cv_path_mzscheme_pfx}/lib/libmzscheme.a ${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"
+     else
+       MZSCHEME_LIBS="-L${vi_cv_path_mzscheme_pfx}/lib -lmzscheme -lmzgc"
+@@ -2024,7 +2026,7 @@
+ fi
+ 
+ AC_CHECK_HEADERS(stdarg.h stdlib.h string.h sys/select.h sys/utsname.h \
+-	termcap.h fcntl.h sgtty.h sys/ioctl.h sys/time.h termio.h \
++	termcap.h fcntl.h sgtty.h sys/ioctl.h sys/time.h sys/types.h termio.h \
+ 	iconv.h langinfo.h unistd.h stropts.h errno.h \
+ 	sys/resource.h sys/systeminfo.h locale.h \
+ 	sys/stream.h sys/ptem.h termios.h libc.h sys/statfs.h \
+diff -Naur vim71.orig/src/diff.c vim71/src/diff.c
+--- vim71.orig/src/diff.c	2007-02-15 19:18:41.000000000 -0500
++++ vim71/src/diff.c	2007-12-20 23:59:28.000000000 -0500
+@@ -791,6 +791,9 @@
+     }
+     mch_remove(tmp_orig);
+ 
++    /* force updating cursor position on screen */
++    curwin->w_valid_cursor.lnum = 0;
++
+     diff_redraw(TRUE);
+ 
+ theend:
+@@ -840,11 +843,11 @@
+ 		    tmp_orig, tmp_new);
+ 	    append_redir(cmd, p_srr, tmp_diff);
+ #ifdef FEAT_AUTOCMD
+-	    ++autocmd_block;	/* Avoid ShellCmdPost stuff */
++	    block_autocmds();	/* Avoid ShellCmdPost stuff */
+ #endif
+ 	    (void)call_shell(cmd, SHELL_FILTER|SHELL_SILENT|SHELL_DOOUT);
+ #ifdef FEAT_AUTOCMD
+-	    --autocmd_block;
++	    unblock_autocmds();
+ #endif
+ 	    vim_free(cmd);
+ 	}
+@@ -949,11 +952,11 @@
+ # endif
+ 		eap->arg);
+ #ifdef FEAT_AUTOCMD
+-	++autocmd_block;	/* Avoid ShellCmdPost stuff */
++	block_autocmds();	/* Avoid ShellCmdPost stuff */
+ #endif
+ 	(void)call_shell(buf, SHELL_FILTER | SHELL_COOKED);
+ #ifdef FEAT_AUTOCMD
+-	--autocmd_block;
++	unblock_autocmds();
+ #endif
+     }
+ 
+@@ -1310,7 +1313,7 @@
+ 		    dp->df_count[idx_new] += -off;
+ 		off = 0;
+ 	    }
+-	    for (i = idx_orig; i < idx_new + !notset; ++i)
++	    for (i = idx_orig; i < idx_new; ++i)
+ 		if (curtab->tp_diffbuf[i] != NULL)
+ 		    dp->df_count[i] = dpl->df_lnum[i] + dpl->df_count[i]
+ 						       - dp->df_lnum[i] + off;
+diff -Naur vim71.orig/src/digraph.c vim71/src/digraph.c
+--- vim71.orig/src/digraph.c	2006-05-02 14:24:04.000000000 -0400
++++ vim71/src/digraph.c	2007-12-20 23:58:39.000000000 -0500
+@@ -2028,7 +2028,7 @@
+ 
+     ++no_mapping;
+     ++allow_keys;
+-    c = safe_vgetc();
++    c = plain_vgetc();
+     --no_mapping;
+     --allow_keys;
+     if (c != ESC)		/* ESC cancels CTRL-K */
+@@ -2050,7 +2050,7 @@
+ #endif
+ 	++no_mapping;
+ 	++allow_keys;
+-	cc = safe_vgetc();
++	cc = plain_vgetc();
+ 	--no_mapping;
+ 	--allow_keys;
+ 	if (cc != ESC)	    /* ESC cancels CTRL-K */
+@@ -2349,8 +2349,10 @@
+ 
+     if (*curbuf->b_p_keymap == NUL)
+     {
+-	/* Stop any active keymap and clear the table. */
++	/* Stop any active keymap and clear the table.  Also remove
++	 * b:keymap_name, as no keymap is active now. */
+ 	keymap_unload();
++	do_cmdline_cmd((char_u *)"unlet! b:keymap_name");
+     }
+     else
+     {
+@@ -2500,7 +2502,6 @@
+ 
+     ga_clear(&curbuf->b_kmap_ga);
+     curbuf->b_kmap_state &= ~KEYMAP_LOADED;
+-    do_cmdline_cmd((char_u *)"unlet! b:keymap_name");
+ #ifdef FEAT_WINDOWS
+     status_redraw_curbuf();
+ #endif
+diff -Naur vim71.orig/src/edit.c vim71/src/edit.c
+--- vim71.orig/src/edit.c	2007-05-07 15:43:55.000000000 -0400
++++ vim71/src/edit.c	2007-12-21 00:00:07.000000000 -0500
+@@ -129,6 +129,7 @@
+ 
+ static void ins_ctrl_x __ARGS((void));
+ static int  has_compl_option __ARGS((int dict_opt));
++static int  ins_compl_accept_char __ARGS((int c));
+ static int ins_compl_add __ARGS((char_u *str, int len, int icase, char_u *fname, char_u **cptext, int cdir, int flags, int adup));
+ static int  ins_compl_equal __ARGS((compl_T *match, char_u *str, int len));
+ static void ins_compl_longest_match __ARGS((compl_T *match));
+@@ -754,8 +755,9 @@
+ 		    continue;
+ 		}
+ 
+-		/* A printable, non-white character: Add to "compl_leader". */
+-		if (vim_isprintc(c) && !vim_iswhite(c))
++		/* A non-white character that fits in with the current
++		 * completion: Add to "compl_leader". */
++		if (ins_compl_accept_char(c))
+ 		{
+ 		    ins_compl_addleader(c);
+ 		    continue;
+@@ -788,7 +790,7 @@
+ 	    ins_redraw(FALSE);
+ 	    ++no_mapping;
+ 	    ++allow_keys;
+-	    c = safe_vgetc();
++	    c = plain_vgetc();
+ 	    --no_mapping;
+ 	    --allow_keys;
+ 	    if (c != Ctrl_N && c != Ctrl_G && c != Ctrl_O)
+@@ -981,7 +983,7 @@
+ #ifdef FEAT_NETBEANS_INTG
+ 	case K_F21:	/* NetBeans command */
+ 	    ++no_mapping;		/* don't map the next key hits */
+-	    i = safe_vgetc();
++	    i = plain_vgetc();
+ 	    --no_mapping;
+ 	    netbeans_keycommand(i);
+ 	    break;
+@@ -2053,11 +2055,44 @@
+ }
+ 
+ /*
++ * Return TRUE when character "c" is part of the item currently being
++ * completed.  Used to decide whether to abandon complete mode when the menu
++ * is visible.
++ */
++    static int
++ins_compl_accept_char(c)
++    int c;
++{
++    if (ctrl_x_mode & CTRL_X_WANT_IDENT)
++	/* When expanding an identifier only accept identifier chars. */
++	return vim_isIDc(c);
++
++    switch (ctrl_x_mode)
++    {
++	case CTRL_X_FILES:
++	    /* When expanding file name only accept file name chars. But not
++	     * path separators, so that "proto/<Tab>" expands files in
++	     * "proto", not "proto/" as a whole */
++	    return vim_isfilec(c) && !vim_ispathsep(c);
++
++	case CTRL_X_CMDLINE:
++	case CTRL_X_OMNI:
++	    /* Command line and Omni completion can work with just about any
++	     * printable character, but do stop at white space. */
++	    return vim_isprintc(c) && !vim_iswhite(c);
++
++	case CTRL_X_WHOLE_LINE:
++	    /* For while line completion a space can be part of the line. */
++	    return vim_isprintc(c);
++    }
++    return vim_iswordc(c);
++}
++
++/*
+  * This is like ins_compl_add(), but if 'ic' and 'inf' are set, then the
+  * case of the originally typed text is used, and the case of the completed
+  * text is inferred, ie this tries to work out what case you probably wanted
+  * the rest of the word to be in -- webb
+- * TODO: make this work for multi-byte characters.
+  */
+     int
+ ins_compl_add_infercase(str, len, icase, fname, dir, flags)
+@@ -2068,54 +2103,147 @@
+     int		dir;
+     int		flags;
+ {
++    char_u	*p;
++    int		i, c;
++    int		actual_len;		/* Take multi-byte characters */
++    int		actual_compl_length;	/* into account. */
++    int		*wca;		        /* Wide character array. */
+     int		has_lower = FALSE;
+     int		was_letter = FALSE;
+-    int		idx;
+ 
+-    if (p_ic && curbuf->b_p_inf && len < IOSIZE)
++    if (p_ic && curbuf->b_p_inf && len > 0)
+     {
+-	/* Infer case of completed part -- webb */
+-	/* Use IObuff, str would change text in buffer! */
+-	vim_strncpy(IObuff, str, len);
++	/* Infer case of completed part. */
+ 
+-	/* Rule 1: Were any chars converted to lower? */
+-	for (idx = 0; idx < compl_length; ++idx)
++	/* Find actual length of completion. */
++#ifdef FEAT_MBYTE
++	if (has_mbyte)
+ 	{
+-	    if (islower(compl_orig_text[idx]))
++	    p = str;
++	    actual_len = 0;
++	    while (*p != NUL)
+ 	    {
+-		has_lower = TRUE;
+-		if (isupper(IObuff[idx]))
+-		{
+-		    /* Rule 1 is satisfied */
+-		    for (idx = compl_length; idx < len; ++idx)
+-			IObuff[idx] = TOLOWER_LOC(IObuff[idx]);
+-		    break;
+-		}
++		mb_ptr_adv(p);
++		++actual_len;
+ 	    }
+ 	}
++	else
++#endif
++	    actual_len = len;
+ 
+-	/*
+-	 * Rule 2: No lower case, 2nd consecutive letter converted to
+-	 * upper case.
+-	 */
+-	if (!has_lower)
++	/* Find actual length of original text. */
++#ifdef FEAT_MBYTE
++	if (has_mbyte)
++	{
++	    p = compl_orig_text;
++	    actual_compl_length = 0;
++	    while (*p != NUL)
++	    {
++		mb_ptr_adv(p);
++		++actual_compl_length;
++	    }
++	}
++	else
++#endif
++	    actual_compl_length = compl_length;
++
++	/* Allocate wide character array for the completion and fill it. */
++	wca = (int *)alloc(actual_len * sizeof(int));
++	if (wca != NULL)
+ 	{
+-	    for (idx = 0; idx < compl_length; ++idx)
++	    p = str;
++	    for (i = 0; i < actual_len; ++i)
++#ifdef FEAT_MBYTE
++		if (has_mbyte)
++		    wca[i] = mb_ptr2char_adv(&p);
++		else
++#endif
++		    wca[i] = *(p++);
++
++	    /* Rule 1: Were any chars converted to lower? */
++	    p = compl_orig_text;
++	    for (i = 0; i < actual_compl_length; ++i)
+ 	    {
+-		if (was_letter && isupper(compl_orig_text[idx])
+-						      && islower(IObuff[idx]))
++#ifdef FEAT_MBYTE
++		if (has_mbyte)
++		    c = mb_ptr2char_adv(&p);
++		else
++#endif
++		    c = *(p++);
++		if (MB_ISLOWER(c))
+ 		{
+-		    /* Rule 2 is satisfied */
+-		    for (idx = compl_length; idx < len; ++idx)
+-			IObuff[idx] = TOUPPER_LOC(IObuff[idx]);
+-		    break;
++		    has_lower = TRUE;
++		    if (MB_ISUPPER(wca[i]))
++		    {
++			/* Rule 1 is satisfied. */
++			for (i = actual_compl_length; i < actual_len; ++i)
++			    wca[i] = MB_TOLOWER(wca[i]);
++			break;
++		    }
+ 		}
+-		was_letter = isalpha(compl_orig_text[idx]);
+ 	    }
+-	}
+ 
+-	/* Copy the original case of the part we typed */
+-	STRNCPY(IObuff, compl_orig_text, compl_length);
++	    /*
++	     * Rule 2: No lower case, 2nd consecutive letter converted to
++	     * upper case.
++	     */
++	    if (!has_lower)
++	    {
++		p = compl_orig_text;
++		for (i = 0; i < actual_compl_length; ++i)
++		{
++#ifdef FEAT_MBYTE
++		    if (has_mbyte)
++			c = mb_ptr2char_adv(&p);
++		    else
++#endif
++			c = *(p++);
++		    if (was_letter && MB_ISUPPER(c) && MB_ISLOWER(wca[i]))
++		    {
++			/* Rule 2 is satisfied. */
++			for (i = actual_compl_length; i < actual_len; ++i)
++			    wca[i] = MB_TOUPPER(wca[i]);
++			break;
++		    }
++		    was_letter = MB_ISLOWER(c) || MB_ISUPPER(c);
++		}
++	    }
++
++	    /* Copy the original case of the part we typed. */
++	    p = compl_orig_text;
++	    for (i = 0; i < actual_compl_length; ++i)
++	    {
++#ifdef FEAT_MBYTE
++		if (has_mbyte)
++		    c = mb_ptr2char_adv(&p);
++		else
++#endif
++		    c = *(p++);
++		if (MB_ISLOWER(c))
++		    wca[i] = MB_TOLOWER(wca[i]);
++		else if (MB_ISUPPER(c))
++		    wca[i] = MB_TOUPPER(wca[i]);
++	    }
++
++	    /*
++	     * Generate encoding specific output from wide character array.
++	     * Multi-byte characters can occupy up to five bytes more than
++	     * ASCII characters, and we also need one byte for NUL, so stay
++	     * six bytes away from the edge of IObuff.
++	     */
++	    p = IObuff;
++	    i = 0;
++	    while (i < actual_len && (p - IObuff + 6) < IOSIZE)
++#ifdef FEAT_MBYTE
++		if (has_mbyte)
++		    p += (*mb_char2bytes)(wca[i++], p);
++		else
++#endif
++		    *(p++) = wca[i++];
++	    *p = NUL;
++
++	    vim_free(wca);
++	}
+ 
+ 	return ins_compl_add(IObuff, len, icase, fname, NULL, dir,
+ 								flags, FALSE);
+@@ -2842,6 +2970,7 @@
+ 			/*
+ 			 * Add the other matches on the line
+ 			 */
++			ptr = buf;
+ 			while (!got_int)
+ 			{
+ 			    /* Find start of the next word.  Skip white
+@@ -2851,7 +2980,7 @@
+ 				break;
+ 			    wstart = ptr;
+ 
+-			    /* Find end of the word and add it. */
++			    /* Find end of the word. */
+ #ifdef FEAT_MBYTE
+ 			    if (has_mbyte)
+ 				/* Japanese words may have characters in
+@@ -2868,9 +2997,12 @@
+ 			    else
+ #endif
+ 				ptr = find_word_end(ptr);
+-			    add_r = ins_compl_add_infercase(wstart,
+-				    (int)(ptr - wstart),
+-				    p_ic, files[i], *dir, 0);
++
++			    /* Add the word. Skip the regexp match. */
++			    if (wstart != regmatch->startp[0])
++				add_r = ins_compl_add_infercase(wstart,
++					(int)(ptr - wstart),
++					p_ic, files[i], *dir, 0);
+ 			}
+ 		    }
+ 		    if (add_r == OK)
+@@ -3032,8 +3164,11 @@
+     p = line + curwin->w_cursor.col;
+     mb_ptr_back(line, p);
+ 
+-    /* Stop completion when the whole word was deleted. */
+-    if ((int)(p - line) - (int)compl_col <= 0)
++    /* Stop completion when the whole word was deleted.  For Omni completion
++     * allow the word to be deleted, we won't match everything. */
++    if ((int)(p - line) - (int)compl_col < 0
++	    || ((int)(p - line) - (int)compl_col == 0
++		&& (ctrl_x_mode & CTRL_X_OMNI) == 0))
+ 	return K_BS;
+ 
+     /* Deleted more than what was used to find matches or didn't finish
+@@ -3250,8 +3385,8 @@
+     if (c != Ctrl_R && vim_is_ctrl_x_key(c))
+ 	edit_submode_extra = NULL;
+ 
+-    /* Ignore end of Select mode mapping */
+-    if (c == K_SELECT)
++    /* Ignore end of Select mode mapping and mouse scroll buttons. */
++    if (c == K_SELECT || c == K_MOUSEDOWN || c == K_MOUSEUP)
+ 	return retval;
+ 
+     /* Set "compl_get_longest" when finding the first matches. */
+@@ -4495,14 +4630,13 @@
+ 	curs_col = curwin->w_cursor.col;
+ 	compl_pending = 0;
+ 
+-	/* if this same ctrl_x_mode has been interrupted use the text from
++	/* If this same ctrl_x_mode has been interrupted use the text from
+ 	 * "compl_startpos" to the cursor as a pattern to add a new word
+ 	 * instead of expand the one before the cursor, in word-wise if
+-	 * "compl_startpos"
+-	 * is not in the same line as the cursor then fix it (the line has
+-	 * been split because it was longer than 'tw').  if SOL is set then
+-	 * skip the previous pattern, a word at the beginning of the line has
+-	 * been inserted, we'll look for that  -- Acevedo. */
++	 * "compl_startpos" is not in the same line as the cursor then fix it
++	 * (the line has been split because it was longer than 'tw').  if SOL
++	 * is set then skip the previous pattern, a word at the beginning of
++	 * the line has been inserted, we'll look for that  -- Acevedo. */
+ 	if ((compl_cont_status & CONT_INTRPT) == CONT_INTRPT
+ 					    && compl_cont_mode == ctrl_x_mode)
+ 	{
+@@ -5128,10 +5262,7 @@
+     i = 0;
+     for (;;)
+     {
+-	do
+-	    nc = safe_vgetc();
+-	while (nc == K_IGNORE || nc == K_VER_SCROLLBAR
+-						    || nc == K_HOR_SCROLLBAR);
++	nc = plain_vgetc();
+ #ifdef FEAT_CMDL_INFO
+ 	if (!(State & CMDLINE)
+ # ifdef FEAT_MBYTE
+@@ -6313,8 +6444,10 @@
+ {
+     vim_free(last_insert);
+     last_insert = NULL;
++# ifdef FEAT_INS_EXPAND
+     vim_free(compl_orig_text);
+     compl_orig_text = NULL;
++# endif
+ }
+ #endif
+ 
+@@ -7215,6 +7348,8 @@
+ 		p = ml_get_curline();
+ 		if (cin_iscase(p) || cin_isscopedecl(p) || cin_islabel(30))
+ 		    return TRUE;
++		/* Need to get the line again after cin_islabel(). */
++		p = ml_get_curline();
+ 		if (curwin->w_cursor.col > 2
+ 			&& p[curwin->w_cursor.col - 1] == ':'
+ 			&& p[curwin->w_cursor.col - 2] == ':')
+@@ -7477,7 +7612,7 @@
+      * deleted when ESC is hit.
+      */
+     ++no_mapping;
+-    regname = safe_vgetc();
++    regname = plain_vgetc();
+ #ifdef FEAT_LANGMAP
+     LANGMAP_ADJUST(regname, TRUE);
+ #endif
+@@ -7488,7 +7623,7 @@
+ #ifdef FEAT_CMDL_INFO
+ 	add_to_showcmd_c(literally);
+ #endif
+-	regname = safe_vgetc();
++	regname = plain_vgetc();
+ #ifdef FEAT_LANGMAP
+ 	LANGMAP_ADJUST(regname, TRUE);
+ #endif
+@@ -7579,7 +7714,7 @@
+      * deleted when ESC is hit.
+      */
+     ++no_mapping;
+-    c = safe_vgetc();
++    c = plain_vgetc();
+     --no_mapping;
+     switch (c)
+     {
+@@ -7998,7 +8133,8 @@
+     /*
+      * 0^D and ^^D: remove all indent.
+      */
+-    if ((lastc == '0' || lastc == '^') && curwin->w_cursor.col)
++    if (c == Ctrl_D && (lastc == '0' || lastc == '^')
++						  && curwin->w_cursor.col > 0)
+     {
+ 	--curwin->w_cursor.col;
+ 	(void)del_char(FALSE);		/* delete the '^' or '0' */
+@@ -8053,6 +8189,29 @@
+     AppendCharToRedobuff(K_DEL);
+ }
+ 
++static void ins_bs_one __ARGS((colnr_T *vcolp));
++
++/*
++ * Delete one character for ins_bs().
++ */
++    static void
++ins_bs_one(vcolp)
++    colnr_T	*vcolp;
++{
++    dec_cursor();
++    getvcol(curwin, &curwin->w_cursor, vcolp, NULL, NULL);
++    if (State & REPLACE_FLAG)
++    {
++	/* Don't delete characters before the insert point when in
++	 * Replace mode */
++	if (curwin->w_cursor.lnum != Insstart.lnum
++		|| curwin->w_cursor.col >= Insstart.col)
++	    replace_do_bs();
++    }
++    else
++	(void)del_char(FALSE);
++}
++
+ /*
+  * Handle Backspace, delete-word and delete-line in Insert mode.
+  * Return TRUE when backspace was actually used.
+@@ -8282,9 +8441,7 @@
+ 	    int		ts;
+ 	    colnr_T	vcol;
+ 	    colnr_T	want_vcol;
+-#if 0
+-	    int		extra = 0;
+-#endif
++	    colnr_T	start_vcol;
+ 
+ 	    *inserted_space_p = FALSE;
+ 	    if (p_sta && in_indent)
+@@ -8295,6 +8452,7 @@
+ 	     * 'showbreak' may get in the way, need to get the last column of
+ 	     * the previous character. */
+ 	    getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
++	    start_vcol = vcol;
+ 	    dec_cursor();
+ 	    getvcol(curwin, &curwin->w_cursor, NULL, NULL, &want_vcol);
+ 	    inc_cursor();
+@@ -8303,30 +8461,7 @@
+ 	    /* delete characters until we are at or before want_vcol */
+ 	    while (vcol > want_vcol
+ 		    && (cc = *(ml_get_cursor() - 1), vim_iswhite(cc)))
+-	    {
+-		dec_cursor();
+-		getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
+-		if (State & REPLACE_FLAG)
+-		{
+-		    /* Don't delete characters before the insert point when in
+-		     * Replace mode */
+-		    if (curwin->w_cursor.lnum != Insstart.lnum
+-			    || curwin->w_cursor.col >= Insstart.col)
+-		    {
+-#if 0	/* what was this for?  It causes problems when sw != ts. */
+-			if (State == REPLACE && (int)vcol < want_vcol)
+-			{
+-			    (void)del_char(FALSE);
+-			    extra = 2;	/* don't pop too much */
+-			}
+-			else
+-#endif
+-			    replace_do_bs();
+-		    }
+-		}
+-		else
+-		    (void)del_char(FALSE);
+-	    }
++		ins_bs_one(&vcol);
+ 
+ 	    /* insert extra spaces until we are at want_vcol */
+ 	    while (vcol < want_vcol)
+@@ -8343,22 +8478,16 @@
+ #endif
+ 		{
+ 		    ins_str((char_u *)" ");
+-		    if ((State & REPLACE_FLAG) /* && extra <= 1 */)
+-		    {
+-#if 0
+-			if (extra)
+-			    replace_push_off(NUL);
+-			else
+-#endif
+-			    replace_push(NUL);
+-		    }
+-#if 0
+-		    if (extra == 2)
+-			extra = 1;
+-#endif
++		    if ((State & REPLACE_FLAG))
++			replace_push(NUL);
+ 		}
+ 		getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
+ 	    }
++
++	    /* If we are now back where we started delete one character.  Can
++	     * happen when using 'sts' and 'linebreak'. */
++	    if (vcol >= start_vcol)
++		ins_bs_one(&vcol);
+ 	}
+ 
+ 	/*
+@@ -8518,15 +8647,16 @@
+     int		up;
+ {
+     pos_T	tpos;
+-# if defined(FEAT_GUI) && defined(FEAT_WINDOWS)
+-    win_T	*old_curwin;
++# if defined(FEAT_WINDOWS)
++    win_T	*old_curwin = curwin;
++# endif
++# ifdef FEAT_INS_EXPAND
++    int		did_scroll = FALSE;
+ # endif
+ 
+     tpos = curwin->w_cursor;
+ 
+ # if defined(FEAT_GUI) && defined(FEAT_WINDOWS)
+-    old_curwin = curwin;
+-
+     /* Currently the mouse coordinates are only known in the GUI. */
+     if (gui.in_use && mouse_row >= 0 && mouse_col >= 0)
+     {
+@@ -8543,10 +8673,23 @@
+ # endif
+ 	undisplay_dollar();
+ 
+-    if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))
+-	scroll_redraw(up, (long)(curwin->w_botline - curwin->w_topline));
+-    else
+-	scroll_redraw(up, 3L);
++# ifdef FEAT_INS_EXPAND
++    /* Don't scroll the window in which completion is being done. */
++    if (!pum_visible()
++#  if defined(FEAT_WINDOWS)
++	    || curwin != old_curwin
++#  endif
++	    )
++# endif
++    {
++	if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))
++	    scroll_redraw(up, (long)(curwin->w_botline - curwin->w_topline));
++	else
++	    scroll_redraw(up, 3L);
++# ifdef FEAT_INS_EXPAND
++	did_scroll = TRUE;
++# endif
++    }
+ 
+ # if defined(FEAT_GUI) && defined(FEAT_WINDOWS)
+     curwin->w_redr_status = TRUE;
+@@ -8555,6 +8698,17 @@
+     curbuf = curwin->w_buffer;
+ # endif
+ 
++# ifdef FEAT_INS_EXPAND
++    /* The popup menu may overlay the window, need to redraw it.
++     * TODO: Would be more efficient to only redraw the windows that are
++     * overlapped by the popup menu. */
++    if (pum_visible() && did_scroll)
++    {
++	redraw_all_later(NOT_VALID);
++	ins_compl_show_pum();
++    }
++# endif
++
+     if (!equalpos(curwin->w_cursor, tpos))
+     {
+ 	start_arrow(&tpos);
+@@ -9257,7 +9411,7 @@
+      * mode message to be deleted when ESC is hit */
+     ++no_mapping;
+     ++allow_keys;
+-    c = safe_vgetc();
++    c = plain_vgetc();
+     --no_mapping;
+     --allow_keys;
+     if (IS_SPECIAL(c) || mod_mask)	    /* special key */
+@@ -9289,7 +9443,7 @@
+ 	}
+ 	++no_mapping;
+ 	++allow_keys;
+-	cc = safe_vgetc();
++	cc = plain_vgetc();
+ 	--no_mapping;
+ 	--allow_keys;
+ 	if (cc != ESC)
+diff -Naur vim71.orig/src/eval.c vim71/src/eval.c
+--- vim71.orig/src/eval.c	2007-05-07 15:47:32.000000000 -0400
++++ vim71/src/eval.c	2007-12-21 00:00:00.000000000 -0500
+@@ -369,17 +369,17 @@
+ static int ex_let_vars __ARGS((char_u *arg, typval_T *tv, int copy, int semicolon, int var_count, char_u *nextchars));
+ static char_u *skip_var_list __ARGS((char_u *arg, int *var_count, int *semicolon));
+ static char_u *skip_var_one __ARGS((char_u *arg));
+-static void list_hashtable_vars __ARGS((hashtab_T *ht, char_u *prefix, int empty));
+-static void list_glob_vars __ARGS((void));
+-static void list_buf_vars __ARGS((void));
+-static void list_win_vars __ARGS((void));
++static void list_hashtable_vars __ARGS((hashtab_T *ht, char_u *prefix, int empty, int *first));
++static void list_glob_vars __ARGS((int *first));
++static void list_buf_vars __ARGS((int *first));
++static void list_win_vars __ARGS((int *first));
+ #ifdef FEAT_WINDOWS
+-static void list_tab_vars __ARGS((void));
++static void list_tab_vars __ARGS((int *first));
+ #endif
+-static void list_vim_vars __ARGS((void));
+-static void list_script_vars __ARGS((void));
+-static void list_func_vars __ARGS((void));
+-static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg));
++static void list_vim_vars __ARGS((int *first));
++static void list_script_vars __ARGS((int *first));
++static void list_func_vars __ARGS((int *first));
++static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg, int *first));
+ static char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op));
+ static int check_changedtick __ARGS((char_u *arg));
+ static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int quiet, int fne_flags));
+@@ -475,6 +475,7 @@
+ static void f_changenr __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_char2nr __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_cindent __ARGS((typval_T *argvars, typval_T *rettv));
++static void f_clearmatches __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_col __ARGS((typval_T *argvars, typval_T *rettv));
+ #if defined(FEAT_INS_EXPAND)
+ static void f_complete __ARGS((typval_T *argvars, typval_T *rettv));
+@@ -529,6 +530,7 @@
+ static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_getline __ARGS((typval_T *argvars, typval_T *rettv));
++static void f_getmatches __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_getpos __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv));
+@@ -577,7 +579,9 @@
+ static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_match __ARGS((typval_T *argvars, typval_T *rettv));
++static void f_matchadd __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_matcharg __ARGS((typval_T *argvars, typval_T *rettv));
++static void f_matchdelete __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv));
+@@ -618,6 +622,7 @@
+ static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_setline __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_setloclist __ARGS((typval_T *argvars, typval_T *rettv));
++static void f_setmatches __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_setpos __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv));
+@@ -672,7 +677,7 @@
+ static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv));
+ 
+ static int list2fpos __ARGS((typval_T *arg, pos_T *posp, int *fnump));
+-static pos_T *var2fpos __ARGS((typval_T *varp, int lnum, int *fnum));
++static pos_T *var2fpos __ARGS((typval_T *varp, int dollar_lnum, int *fnum));
+ static int get_env_len __ARGS((char_u **arg));
+ static int get_id_len __ARGS((char_u **arg));
+ static int get_name_len __ARGS((char_u **arg, char_u **alias, int evaluate, int verbose));
+@@ -699,8 +704,8 @@
+ static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname));
+ static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val));
+ static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi));
+-static void list_one_var __ARGS((dictitem_T *v, char_u *prefix));
+-static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string));
++static void list_one_var __ARGS((dictitem_T *v, char_u *prefix, int *first));
++static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string, int *first));
+ static void set_var __ARGS((char_u *name, typval_T *varp, int copy));
+ static int var_check_ro __ARGS((int flags, char_u *name));
+ static int var_check_fixed __ARGS((int flags, char_u *name));
+@@ -992,20 +997,20 @@
+     char_u	*value;
+     int		value_len;
+ {
+-    size_t	len;
++    int		len;
+ 
+     if (redir_lval == NULL)
+ 	return;
+ 
+     if (value_len == -1)
+-	len = STRLEN(value);	/* Append the entire string */
++	len = (int)STRLEN(value);	/* Append the entire string */
+     else
+-	len = value_len;	/* Append only "value_len" characters */
++	len = value_len;		/* Append only "value_len" characters */
+ 
+-    if (ga_grow(&redir_ga, (int)len) == OK)
++    if (ga_grow(&redir_ga, len) == OK)
+     {
+ 	mch_memmove((char *)redir_ga.ga_data + redir_ga.ga_len, value, len);
+-	redir_ga.ga_len += (int)len;
++	redir_ga.ga_len += len;
+     }
+     else
+ 	var_redir_stop();
+@@ -1313,7 +1318,6 @@
+ {
+     hashitem_T	*hi;
+ 
+-    clear_tv(&vimvars[idx].vv_tv);
+     vimvars[idx].vv_tv = *save_tv;
+     if (vimvars[idx].vv_type == VAR_UNKNOWN)
+     {
+@@ -1357,7 +1361,6 @@
+ 
+     if (p_verbose == 0)
+ 	--emsg_off;
+-    vimvars[VV_VAL].vv_str = NULL;
+     restore_vimvar(VV_VAL, &save_val);
+ 
+     return list;
+@@ -1411,7 +1414,8 @@
+ }
+ 
+ 
+-#if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO)
++#if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) \
++	|| defined(FEAT_COMPL_FUNC) || defined(PROTO)
+ /*
+  * Call some vimL function and return the result in "*rettv".
+  * Uses argv[argc] for the function arguments.
+@@ -1484,6 +1488,7 @@
+     return ret;
+ }
+ 
++# if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO)
+ /*
+  * Call vimL function "func" and return the result as a string.
+  * Returns NULL when calling the function fails.
+@@ -1506,8 +1511,9 @@
+     clear_tv(&rettv);
+     return retval;
+ }
++# endif
+ 
+-#if defined(FEAT_COMPL_FUNC) || defined(PROTO)
++# if defined(FEAT_COMPL_FUNC) || defined(PROTO)
+ /*
+  * Call vimL function "func" and return the result as a number.
+  * Returns -1 when calling the function fails.
+@@ -1530,7 +1536,7 @@
+     clear_tv(&rettv);
+     return retval;
+ }
+-#endif
++# endif
+ 
+ /*
+  * Call vimL function "func" and return the result as a list
+@@ -1556,9 +1562,9 @@
+ 
+     return rettv.vval.v_list;
+ }
+-
+ #endif
+ 
++
+ /*
+  * Save the current function call pointer, and set it to NULL.
+  * Used when executing autocommands and for ":source".
+@@ -1691,6 +1697,7 @@
+     int		semicolon = 0;
+     char_u	op[2];
+     char_u	*argend;
++    int		first = TRUE;
+ 
+     argend = skip_var_list(arg, &var_count, &semicolon);
+     if (argend == NULL)
+@@ -1707,19 +1714,19 @@
+ 	    EMSG(_(e_invarg));
+ 	else if (!ends_excmd(*arg))
+ 	    /* ":let var1 var2" */
+-	    arg = list_arg_vars(eap, arg);
++	    arg = list_arg_vars(eap, arg, &first);
+ 	else if (!eap->skip)
+ 	{
+ 	    /* ":let" */
+-	    list_glob_vars();
+-	    list_buf_vars();
+-	    list_win_vars();
++	    list_glob_vars(&first);
++	    list_buf_vars(&first);
++	    list_win_vars(&first);
+ #ifdef FEAT_WINDOWS
+-	    list_tab_vars();
++	    list_tab_vars(&first);
+ #endif
+-	    list_script_vars();
+-	    list_func_vars();
+-	    list_vim_vars();
++	    list_script_vars(&first);
++	    list_func_vars(&first);
++	    list_vim_vars(&first);
+ 	}
+ 	eap->nextcmd = check_nextcmd(arg);
+     }
+@@ -1924,10 +1931,11 @@
+  * If "empty" is TRUE also list NULL strings as empty strings.
+  */
+     static void
+-list_hashtable_vars(ht, prefix, empty)
++list_hashtable_vars(ht, prefix, empty, first)
+     hashtab_T	*ht;
+     char_u	*prefix;
+     int		empty;
++    int		*first;
+ {
+     hashitem_T	*hi;
+     dictitem_T	*di;
+@@ -1942,7 +1950,7 @@
+ 	    di = HI2DI(hi);
+ 	    if (empty || di->di_tv.v_type != VAR_STRING
+ 					   || di->di_tv.vval.v_string != NULL)
+-		list_one_var(di, prefix);
++		list_one_var(di, prefix, first);
+ 	}
+     }
+ }
+@@ -1951,32 +1959,38 @@
+  * List global variables.
+  */
+     static void
+-list_glob_vars()
++list_glob_vars(first)
++    int *first;
+ {
+-    list_hashtable_vars(&globvarht, (char_u *)"", TRUE);
++    list_hashtable_vars(&globvarht, (char_u *)"", TRUE, first);
+ }
+ 
+ /*
+  * List buffer variables.
+  */
+     static void
+-list_buf_vars()
++list_buf_vars(first)
++    int *first;
+ {
+     char_u	numbuf[NUMBUFLEN];
+ 
+-    list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:", TRUE);
++    list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:",
++								 TRUE, first);
+ 
+     sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick);
+-    list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, numbuf);
++    list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER,
++							       numbuf, first);
+ }
+ 
+ /*
+  * List window variables.
+  */
+     static void
+-list_win_vars()
++list_win_vars(first)
++    int *first;
+ {
+-    list_hashtable_vars(&curwin->w_vars.dv_hashtab, (char_u *)"w:", TRUE);
++    list_hashtable_vars(&curwin->w_vars.dv_hashtab,
++						 (char_u *)"w:", TRUE, first);
+ }
+ 
+ #ifdef FEAT_WINDOWS
+@@ -1984,9 +1998,11 @@
+  * List tab page variables.
+  */
+     static void
+-list_tab_vars()
++list_tab_vars(first)
++    int *first;
+ {
+-    list_hashtable_vars(&curtab->tp_vars.dv_hashtab, (char_u *)"t:", TRUE);
++    list_hashtable_vars(&curtab->tp_vars.dv_hashtab,
++						 (char_u *)"t:", TRUE, first);
+ }
+ #endif
+ 
+@@ -1994,39 +2010,44 @@
+  * List Vim variables.
+  */
+     static void
+-list_vim_vars()
++list_vim_vars(first)
++    int *first;
+ {
+-    list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE);
++    list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE, first);
+ }
+ 
+ /*
+  * List script-local variables, if there is a script.
+  */
+     static void
+-list_script_vars()
++list_script_vars(first)
++    int *first;
+ {
+     if (current_SID > 0 && current_SID <= ga_scripts.ga_len)
+-	list_hashtable_vars(&SCRIPT_VARS(current_SID), (char_u *)"s:", FALSE);
++	list_hashtable_vars(&SCRIPT_VARS(current_SID),
++						(char_u *)"s:", FALSE, first);
+ }
+ 
+ /*
+  * List function variables, if there is a function.
+  */
+     static void
+-list_func_vars()
++list_func_vars(first)
++    int *first;
+ {
+     if (current_funccal != NULL)
+ 	list_hashtable_vars(&current_funccal->l_vars.dv_hashtab,
+-						       (char_u *)"l:", FALSE);
++						(char_u *)"l:", FALSE, first);
+ }
+ 
+ /*
+  * List variables in "arg".
+  */
+     static char_u *
+-list_arg_vars(eap, arg)
++list_arg_vars(eap, arg, first)
+     exarg_T	*eap;
+     char_u	*arg;
++    int		*first;
+ {
+     int		error = FALSE;
+     int		len;
+@@ -2083,15 +2104,15 @@
+ 			{
+ 			    switch (*name)
+ 			    {
+-				case 'g': list_glob_vars(); break;
+-				case 'b': list_buf_vars(); break;
+-				case 'w': list_win_vars(); break;
++				case 'g': list_glob_vars(first); break;
++				case 'b': list_buf_vars(first); break;
++				case 'w': list_win_vars(first); break;
+ #ifdef FEAT_WINDOWS
+-				case 't': list_tab_vars(); break;
++				case 't': list_tab_vars(first); break;
+ #endif
+-				case 'v': list_vim_vars(); break;
+-				case 's': list_script_vars(); break;
+-				case 'l': list_func_vars(); break;
++				case 'v': list_vim_vars(first); break;
++				case 's': list_script_vars(first); break;
++				case 'l': list_func_vars(first); break;
+ 				default:
+ 					  EMSG2(_("E738: Can't list variables for %s"), name);
+ 			    }
+@@ -2108,7 +2129,9 @@
+ 			    *arg = NUL;
+ 			    list_one_var_a((char_u *)"",
+ 				    arg == arg_subsc ? name : name_start,
+-				    tv.v_type, s == NULL ? (char_u *)"" : s);
++				    tv.v_type,
++				    s == NULL ? (char_u *)"" : s,
++				    first);
+ 			    *arg = c;
+ 			    vim_free(tf);
+ 			}
+@@ -6105,6 +6128,7 @@
+     /* Only do this once. */
+     want_garbage_collect = FALSE;
+     may_garbage_collect = FALSE;
++    garbage_collect_at_exit = FALSE;
+ 
+     /*
+      * 1. Go through all accessible variables and mark all lists and dicts
+@@ -6681,7 +6705,7 @@
+     dict_T	*d = NULL;
+     typval_T	tvkey;
+     typval_T	tv;
+-    char_u	*key;
++    char_u	*key = NULL;
+     dictitem_T	*item;
+     char_u	*start = skipwhite(*arg + 1);
+     char_u	buf[NUMBUFLEN];
+@@ -6721,20 +6745,24 @@
+ 	    clear_tv(&tvkey);
+ 	    goto failret;
+ 	}
+-	key = get_tv_string_buf_chk(&tvkey, buf);
+-	if (key == NULL || *key == NUL)
++	if (evaluate)
+ 	{
+-	    /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */
+-	    if (key != NULL)
+-		EMSG(_(e_emptykey));
+-	    clear_tv(&tvkey);
+-	    goto failret;
++	    key = get_tv_string_buf_chk(&tvkey, buf);
++	    if (key == NULL || *key == NUL)
++	    {
++		/* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */
++		if (key != NULL)
++		    EMSG(_(e_emptykey));
++		clear_tv(&tvkey);
++		goto failret;
++	    }
+ 	}
+ 
+ 	*arg = skipwhite(*arg + 1);
+ 	if (eval1(arg, &tv, evaluate) == FAIL)	/* recursive! */
+ 	{
+-	    clear_tv(&tvkey);
++	    if (evaluate)
++		clear_tv(&tvkey);
+ 	    goto failret;
+ 	}
+ 	if (evaluate)
+@@ -6794,7 +6822,7 @@
+  * "numbuf" is used for a number.
+  * Does not put quotes around strings, as ":echo" displays values.
+  * When "copyID" is not NULL replace recursive lists and dicts with "...".
+- * May return NULL;
++ * May return NULL.
+  */
+     static char_u *
+ echo_string(tv, tofree, numbuf, copyID)
+@@ -6879,7 +6907,7 @@
+  * If the memory is allocated "tofree" is set to it, otherwise NULL.
+  * "numbuf" is used for a number.
+  * Puts quotes around strings, so that they can be parsed back by eval().
+- * May return NULL;
++ * May return NULL.
+  */
+     static char_u *
+ tv2string(tv, tofree, numbuf, copyID)
+@@ -7043,6 +7071,7 @@
+     {"changenr",	0, 0, f_changenr},
+     {"char2nr",		1, 1, f_char2nr},
+     {"cindent",		1, 1, f_cindent},
++    {"clearmatches",	0, 0, f_clearmatches},
+     {"col",		1, 1, f_col},
+ #if defined(FEAT_INS_EXPAND)
+     {"complete",	2, 2, f_complete},
+@@ -7082,7 +7111,7 @@
+     {"foldtextresult",	1, 1, f_foldtextresult},
+     {"foreground",	0, 0, f_foreground},
+     {"function",	1, 1, f_function},
+-    {"garbagecollect",	0, 0, f_garbagecollect},
++    {"garbagecollect",	0, 1, f_garbagecollect},
+     {"get",		2, 3, f_get},
+     {"getbufline",	2, 3, f_getbufline},
+     {"getbufvar",	2, 2, f_getbufvar},
+@@ -7099,6 +7128,7 @@
+     {"getftype",	1, 1, f_getftype},
+     {"getline",		1, 2, f_getline},
+     {"getloclist",	1, 1, f_getqflist},
++    {"getmatches",	0, 0, f_getmatches},
+     {"getpos",		1, 1, f_getpos},
+     {"getqflist",	0, 0, f_getqflist},
+     {"getreg",		0, 2, f_getreg},
+@@ -7149,7 +7179,9 @@
+     {"maparg",		1, 3, f_maparg},
+     {"mapcheck",	1, 3, f_mapcheck},
+     {"match",		2, 4, f_match},
++    {"matchadd",	2, 4, f_matchadd},
+     {"matcharg",	1, 1, f_matcharg},
++    {"matchdelete",	1, 1, f_matchdelete},
+     {"matchend",	2, 4, f_matchend},
+     {"matchlist",	2, 4, f_matchlist},
+     {"matchstr",	2, 4, f_matchstr},
+@@ -7190,6 +7222,7 @@
+     {"setcmdpos",	1, 1, f_setcmdpos},
+     {"setline",		2, 2, f_setline},
+     {"setloclist",	2, 3, f_setloclist},
++    {"setmatches",	1, 1, f_setmatches},
+     {"setpos",		2, 2, f_setpos},
+     {"setqflist",	1, 2, f_setqflist},
+     {"setreg",		2, 3, f_setreg},
+@@ -8240,6 +8273,20 @@
+ }
+ 
+ /*
++ * "clearmatches()" function
++ */
++/*ARGSUSED*/
++    static void
++f_clearmatches(argvars, rettv)
++    typval_T	*argvars;
++    typval_T	*rettv;
++{
++#ifdef FEAT_SEARCH_EXTRA
++    clear_matches(curwin);
++#endif
++}
++
++/*
+  * "col(string)" function
+  */
+     static void
+@@ -8682,7 +8729,7 @@
+     static int		fnum = 0;
+     static int		change_start = 0;
+     static int		change_end = 0;
+-    static hlf_T	hlID = 0;
++    static hlf_T	hlID = (hlf_T)0;
+     int			filler_lines;
+     int			col;
+ 
+@@ -9339,15 +9386,16 @@
+ {
+     typval_T	rettv;
+     char_u	*s;
++    int		retval = FAIL;
+ 
+     copy_tv(tv, &vimvars[VV_VAL].vv_tv);
+     s = expr;
+     if (eval1(&s, &rettv, TRUE) == FAIL)
+-	return FAIL;
++	goto theend;
+     if (*s != NUL)  /* check for trailing chars after expr */
+     {
+ 	EMSG2(_(e_invexpr2), s);
+-	return FAIL;
++	goto theend;
+     }
+     if (map)
+     {
+@@ -9366,10 +9414,12 @@
+ 	/* On type error, nothing has been removed; return FAIL to stop the
+ 	 * loop.  The error message was given by get_tv_number_chk(). */
+ 	if (error)
+-	    return FAIL;
++	    goto theend;
+     }
++    retval = OK;
++theend:
+     clear_tv(&vimvars[VV_VAL].vv_tv);
+-    return OK;
++    return retval;
+ }
+ 
+ /*
+@@ -9670,6 +9720,9 @@
+     /* This is postponed until we are back at the toplevel, because we may be
+      * using Lists and Dicts internally.  E.g.: ":echo [garbagecollect()]". */
+     want_garbage_collect = TRUE;
++
++    if (argvars[0].v_type != VAR_UNKNOWN && get_tv_number(&argvars[0]) == 1)
++	garbage_collect_at_exit = TRUE;
+ }
+ 
+ /*
+@@ -9868,18 +9921,24 @@
+ 
+     ++no_mapping;
+     ++allow_keys;
+-    if (argvars[0].v_type == VAR_UNKNOWN)
+-	/* getchar(): blocking wait. */
+-	n = safe_vgetc();
+-    else if (get_tv_number_chk(&argvars[0], &error) == 1)
+-	/* getchar(1): only check if char avail */
+-	n = vpeekc();
+-    else if (error || vpeekc() == NUL)
+-	/* illegal argument or getchar(0) and no char avail: return zero */
+-	n = 0;
+-    else
+-	/* getchar(0) and char avail: return char */
+-	n = safe_vgetc();
++    for (;;)
++    {
++	if (argvars[0].v_type == VAR_UNKNOWN)
++	    /* getchar(): blocking wait. */
++	    n = safe_vgetc();
++	else if (get_tv_number_chk(&argvars[0], &error) == 1)
++	    /* getchar(1): only check if char avail */
++	    n = vpeekc();
++	else if (error || vpeekc() == NUL)
++	    /* illegal argument or getchar(0) and no char avail: return zero */
++	    n = 0;
++	else
++	    /* getchar(0) and char avail: return char */
++	    n = safe_vgetc();
++	if (n == K_IGNORE)
++	    continue;
++	break;
++    }
+     --no_mapping;
+     --allow_keys;
+ 
+@@ -10136,7 +10195,13 @@
+ 	if (mch_isdir(fname))
+ 	    rettv->vval.v_number = 0;
+ 	else
++	{
+ 	    rettv->vval.v_number = (varnumber_T)st.st_size;
++
++	    /* non-perfect check for overflow */
++	    if ((off_t)rettv->vval.v_number != (off_t)st.st_size)
++		rettv->vval.v_number = -2;
++	}
+     }
+     else
+ 	  rettv->vval.v_number = -1;
+@@ -10269,6 +10334,39 @@
+ }
+ 
+ /*
++ * "getmatches()" function
++ */
++/*ARGSUSED*/
++    static void
++f_getmatches(argvars, rettv)
++    typval_T	*argvars;
++    typval_T	*rettv;
++{
++#ifdef FEAT_SEARCH_EXTRA
++    dict_T	*dict;
++    matchitem_T	*cur = curwin->w_match_head;
++
++    rettv->vval.v_number = 0;
++
++    if (rettv_list_alloc(rettv) == OK)
++    {
++	while (cur != NULL)
++	{
++	    dict = dict_alloc();
++	    if (dict == NULL)
++		return;
++	    dict_add_nr_str(dict, "group", 0L, syn_id2name(cur->hlg_id));
++	    dict_add_nr_str(dict, "pattern", 0L, cur->pattern);
++	    dict_add_nr_str(dict, "priority", (long)cur->priority, NULL);
++	    dict_add_nr_str(dict, "id", (long)cur->id, NULL);
++	    list_append_dict(rettv->vval.v_list, dict);
++	    cur = cur->next;
++	}
++    }
++#endif
++}
++
++/*
+  * "getpos(string)" function
+  */
+     static void
+@@ -10290,7 +10388,8 @@
+ 	    list_append_number(l, (varnumber_T)0);
+ 	list_append_number(l, (fp != NULL) ? (varnumber_T)fp->lnum
+ 							    : (varnumber_T)0);
+-	list_append_number(l, (fp != NULL) ? (varnumber_T)fp->col + 1
++	list_append_number(l, (fp != NULL)
++		     ? (varnumber_T)(fp->col == MAXCOL ? MAXCOL : fp->col + 1)
+ 							    : (varnumber_T)0);
+ 	list_append_number(l,
+ #ifdef FEAT_VIRTUALEDIT
+@@ -10785,6 +10884,9 @@
+ 	"gui_gtk2",
+ # endif
+ #endif
++#ifdef FEAT_GUI_GNOME
++	"gui_gnome",
++#endif
+ #ifdef FEAT_GUI_MAC
+ 	"gui_mac",
+ #endif
+@@ -11471,14 +11573,12 @@
+     char_u	*xp_arg = NULL;
+ 
+     rettv->v_type = VAR_STRING;
++    rettv->vval.v_string = NULL;
+ 
+ #ifdef NO_CONSOLE_INPUT
+     /* While starting up, there is no place to enter text. */
+     if (no_console_input())
+-    {
+-	rettv->vval.v_string = NULL;
+ 	return;
+-    }
+ #endif
+ 
+     cmd_silent = FALSE;		/* Want to see the prompt. */
+@@ -12439,6 +12539,44 @@
+ }
+ 
+ /*
++ * "matchadd()" function
++ */
++    static void
++f_matchadd(argvars, rettv)
++    typval_T	*argvars;
++    typval_T	*rettv;
++{
++#ifdef FEAT_SEARCH_EXTRA
++    char_u	buf[NUMBUFLEN];
++    char_u	*grp = get_tv_string_buf_chk(&argvars[0], buf);	/* group */
++    char_u	*pat = get_tv_string_buf_chk(&argvars[1], buf);	/* pattern */
++    int		prio = 10;	/* default priority */
++    int		id = -1;
++    int		error = FALSE;
++
++    rettv->vval.v_number = -1;
++
++    if (grp == NULL || pat == NULL)
++	return;
++    if (argvars[2].v_type != VAR_UNKNOWN)
++    {
++	prio = get_tv_number_chk(&argvars[2], &error);
++	if (argvars[3].v_type != VAR_UNKNOWN)
++	    id = get_tv_number_chk(&argvars[3], &error);
++    }
++    if (error == TRUE)
++	return;
++    if (id >= 1 && id <= 3)
++    {
++	EMSGN("E798: ID is reserved for \":match\": %ld", id);
++	return;
++    }
++
++    rettv->vval.v_number = match_add(curwin, grp, pat, prio, id);
++#endif
++}
++
++/*
+  * "matcharg()" function
+  */
+     static void
+@@ -12449,20 +12587,42 @@
+     if (rettv_list_alloc(rettv) == OK)
+     {
+ #ifdef FEAT_SEARCH_EXTRA
+-	int	mi = get_tv_number(&argvars[0]);
++	int	    id = get_tv_number(&argvars[0]);
++	matchitem_T *m;
+ 
+-	if (mi >= 1 && mi <= 3)
++	if (id >= 1 && id <= 3)
+ 	{
+-	    list_append_string(rettv->vval.v_list,
+-				 syn_id2name(curwin->w_match_id[mi - 1]), -1);
+-	    list_append_string(rettv->vval.v_list,
+-					     curwin->w_match_pat[mi - 1], -1);
++	    if ((m = (matchitem_T *)get_match(curwin, id)) != NULL)
++	    {
++		list_append_string(rettv->vval.v_list,
++						syn_id2name(m->hlg_id), -1);
++		list_append_string(rettv->vval.v_list, m->pattern, -1);
++	    }
++	    else
++	    {
++		list_append_string(rettv->vval.v_list, NUL, -1);
++		list_append_string(rettv->vval.v_list, NUL, -1);
++	    }
+ 	}
+ #endif
+     }
+ }
+ 
+ /*
++ * "matchdelete()" function
++ */
++    static void
++f_matchdelete(argvars, rettv)
++    typval_T	*argvars;
++    typval_T	*rettv;
++{
++#ifdef FEAT_SEARCH_EXTRA
++    rettv->vval.v_number = match_delete(curwin,
++				       (int)get_tv_number(&argvars[0]), TRUE);
++#endif
++}
++
++/*
+  * "matchend()" function
+  */
+     static void
+@@ -13680,7 +13840,7 @@
+ 	    }
+ 	    /* Shorten "remain". */
+ 	    if (*q != NUL)
+-		STRCPY(remain, q - 1);
++		mch_memmove(remain, q - 1, STRLEN(q - 1) + 1);
+ 	    else
+ 	    {
+ 		vim_free(remain);
+@@ -13919,6 +14079,8 @@
+     /* If 'n' flag is used: restore cursor position. */
+     if (flags & SP_NOMOVE)
+ 	curwin->w_cursor = save_cursor;
++    else
++	curwin->w_set_curswant = TRUE;
+ theend:
+     p_ws = save_p_ws;
+ 
+@@ -14498,6 +14660,66 @@
+ }
+ 
+ /*
++ * "setmatches()" function
++ */
++    static void
++f_setmatches(argvars, rettv)
++    typval_T	*argvars;
++    typval_T	*rettv;
++{
++#ifdef FEAT_SEARCH_EXTRA
++    list_T	*l;
++    listitem_T	*li;
++    dict_T	*d;
++
++    rettv->vval.v_number = -1;
++    if (argvars[0].v_type != VAR_LIST)
++    {
++	EMSG(_(e_listreq));
++	return;
++    }
++    if ((l = argvars[0].vval.v_list) != NULL)
++    {
++
++	/* To some extent make sure that we are dealing with a list from
++	 * "getmatches()". */
++	li = l->lv_first;
++	while (li != NULL)
++	{
++	    if (li->li_tv.v_type != VAR_DICT
++		    || (d = li->li_tv.vval.v_dict) == NULL)
++	    {
++		EMSG(_(e_invarg));
++		return;
++	    }
++	    if (!(dict_find(d, (char_u *)"group", -1) != NULL
++			&& dict_find(d, (char_u *)"pattern", -1) != NULL
++			&& dict_find(d, (char_u *)"priority", -1) != NULL
++			&& dict_find(d, (char_u *)"id", -1) != NULL))
++	    {
++		EMSG(_(e_invarg));
++		return;
++	    }
++	    li = li->li_next;
++	}
++
++	clear_matches(curwin);
++	li = l->lv_first;
++	while (li != NULL)
++	{
++	    d = li->li_tv.vval.v_dict;
++	    match_add(curwin, get_dict_string(d, (char_u *)"group", FALSE),
++		    get_dict_string(d, (char_u *)"pattern", FALSE),
++		    (int)get_dict_number(d, (char_u *)"priority"),
++		    (int)get_dict_number(d, (char_u *)"id"));
++	    li = li->li_next;
++	}
++	rettv->vval.v_number = 0;
++    }
++#endif
++}
++
++/*
+  * "setpos()" function
+  */
+ /*ARGSUSED*/
+@@ -14785,6 +15007,10 @@
+ 
+     p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1, 0);
+     p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2, 0);
++    if (p1 == NULL)
++	p1 = (char_u *)"";
++    if (p2 == NULL)
++	p2 = (char_u *)"";
+     if (item_compare_ic)
+ 	res = STRICMP(p1, p2);
+     else
+@@ -15274,7 +15500,8 @@
+ 
+     rettv->v_type = VAR_STRING;
+     rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf, 0);
+-    if (tofree == NULL)
++    /* Make a copy if we have a value but it's not in allocate memory. */
++    if (rettv->vval.v_string != NULL && tofree == NULL)
+ 	rettv->vval.v_string = vim_strsave(rettv->vval.v_string);
+ }
+ 
+@@ -15599,7 +15826,7 @@
+     FILE	*fd;
+ 
+     if (check_restricted() || check_secure())
+-	return;
++	goto done;
+ 
+     if (argvars[1].v_type != VAR_UNKNOWN)
+     {
+@@ -15610,7 +15837,7 @@
+ 	if ((infile = vim_tempname('i')) == NULL)
+ 	{
+ 	    EMSG(_(e_notmp));
+-	    return;
++	    goto done;
+ 	}
+ 
+ 	fd = mch_fopen((char *)infile, WRITEBIN);
+@@ -16497,9 +16724,9 @@
+  * Returns NULL when there is an error.
+  */
+     static pos_T *
+-var2fpos(varp, lnum, fnum)
++var2fpos(varp, dollar_lnum, fnum)
+     typval_T	*varp;
+-    int		lnum;		/* TRUE when $ is last line */
++    int		dollar_lnum;	/* TRUE when $ is last line */
+     int		*fnum;		/* set to fnum for '0, 'A, etc. */
+ {
+     char_u		*name;
+@@ -16512,6 +16739,7 @@
+ 	list_T		*l;
+ 	int		len;
+ 	int		error = FALSE;
++	listitem_T	*li;
+ 
+ 	l = varp->vval.v_list;
+ 	if (l == NULL)
+@@ -16527,6 +16755,14 @@
+ 	if (error)
+ 	    return NULL;
+ 	len = (long)STRLEN(ml_get(pos.lnum));
++
++	/* We accept "$" for the column number: last column. */
++	li = list_find(l, 1L);
++	if (li != NULL && li->li_tv.v_type == VAR_STRING
++		&& li->li_tv.vval.v_string != NULL
++		&& STRCMP(li->li_tv.vval.v_string, "$") == 0)
++	    pos.col = len + 1;
++
+ 	/* Accept a position up to the NUL after the line. */
+ 	if (pos.col == 0 || (int)pos.col > len + 1)
+ 	    return NULL;	/* invalid column number */
+@@ -16559,7 +16795,7 @@
+     pos.coladd = 0;
+ #endif
+ 
+-    if (name[0] == 'w' && lnum)
++    if (name[0] == 'w' && dollar_lnum)
+     {
+ 	pos.col = 0;
+ 	if (name[1] == '0')		/* "w0": first visible line */
+@@ -16577,7 +16813,7 @@
+     }
+     else if (name[0] == '$')		/* last column or line */
+     {
+-	if (lnum)
++	if (dollar_lnum)
+ 	{
+ 	    pos.lnum = curbuf->b_ml.ml_line_count;
+ 	    pos.col = 0;
+@@ -17798,9 +18034,10 @@
+  * List the value of one internal variable.
+  */
+     static void
+-list_one_var(v, prefix)
++list_one_var(v, prefix, first)
+     dictitem_T	*v;
+     char_u	*prefix;
++    int		*first;
+ {
+     char_u	*tofree;
+     char_u	*s;
+@@ -17808,18 +18045,21 @@
+ 
+     s = echo_string(&v->di_tv, &tofree, numbuf, ++current_copyID);
+     list_one_var_a(prefix, v->di_key, v->di_tv.v_type,
+-						s == NULL ? (char_u *)"" : s);
++					 s == NULL ? (char_u *)"" : s, first);
+     vim_free(tofree);
+ }
+ 
+     static void
+-list_one_var_a(prefix, name, type, string)
++list_one_var_a(prefix, name, type, string, first)
+     char_u	*prefix;
+     char_u	*name;
+     int		type;
+     char_u	*string;
++    int		*first;  /* when TRUE clear rest of screen and set to FALSE */
+ {
+-    msg_attr(prefix, 0);    /* don't use msg(), it overwrites "v:statusmsg" */
++    /* don't use msg() or msg_attr() to avoid overwriting "v:statusmsg" */
++    msg_start();
++    msg_puts(prefix);
+     if (name != NULL)	/* "a:" vars don't have a name stored */
+ 	msg_puts(name);
+     msg_putchar(' ');
+@@ -17847,6 +18087,11 @@
+ 
+     if (type == VAR_FUNC)
+ 	msg_puts((char_u *)"()");
++    if (*first)
++    {
++	msg_clr_eos();
++	*first = FALSE;
++    }
+ }
+ 
+ /*
+@@ -19136,6 +19381,28 @@
+ 	goto theend;
+     }
+ 
++    /* Check if the name is a Funcref.  If so, use the value. */
++    if (lv.ll_exp_name != NULL)
++    {
++	len = (int)STRLEN(lv.ll_exp_name);
++	name = deref_func_name(lv.ll_exp_name, &len);
++	if (name == lv.ll_exp_name)
++	    name = NULL;
++    }
++    else
++    {
++	len = (int)(end - *pp);
++	name = deref_func_name(*pp, &len);
++	if (name == *pp)
++	    name = NULL;
++    }
++    if (name != NULL)
++    {
++	name = vim_strsave(name);
++	*pp = end;
++	goto theend;
++    }
++
+     if (lv.ll_exp_name != NULL)
+     {
+ 	len = (int)STRLEN(lv.ll_exp_name);
+@@ -19969,6 +20236,7 @@
+ 		char_u	buf[MSG_BUF_LEN];
+ 		char_u	numbuf2[NUMBUFLEN];
+ 		char_u	*tofree;
++		char_u	*s;
+ 
+ 		msg_puts((char_u *)"(");
+ 		for (i = 0; i < argcount; ++i)
+@@ -19979,10 +20247,13 @@
+ 			msg_outnum((long)argvars[i].vval.v_number);
+ 		    else
+ 		    {
+-			trunc_string(tv2string(&argvars[i], &tofree,
+-					      numbuf2, 0), buf, MSG_BUF_CLEN);
+-			msg_puts(buf);
+-			vim_free(tofree);
++			s = tv2string(&argvars[i], &tofree, numbuf2, 0);
++			if (s != NULL)
++			{
++			    trunc_string(s, buf, MSG_BUF_CLEN);
++			    msg_puts(buf);
++			    vim_free(tofree);
++			}
+ 		    }
+ 		}
+ 		msg_puts((char_u *)")");
+@@ -20060,14 +20331,18 @@
+ 	    char_u	buf[MSG_BUF_LEN];
+ 	    char_u	numbuf2[NUMBUFLEN];
+ 	    char_u	*tofree;
++	    char_u	*s;
+ 
+ 	    /* The value may be very long.  Skip the middle part, so that we
+ 	     * have some idea how it starts and ends. smsg() would always
+ 	     * truncate it at the end. */
+-	    trunc_string(tv2string(fc.rettv, &tofree, numbuf2, 0),
+-							   buf, MSG_BUF_CLEN);
+-	    smsg((char_u *)_("%s returning %s"), sourcing_name, buf);
+-	    vim_free(tofree);
++	    s = tv2string(fc.rettv, &tofree, numbuf2, 0);
++	    if (s != NULL)
++	    {
++		trunc_string(s, buf, MSG_BUF_CLEN);
++		smsg((char_u *)_("%s returning %s"), sourcing_name, buf);
++		vim_free(tofree);
++	    }
+ 	}
+ 	msg_puts((char_u *)"\n");   /* don't overwrite this either */
+ 
+@@ -21034,14 +21309,27 @@
+ 	*usedlen += 2;
+ 	s = get_past_head(*fnamep);
+ 	while (tail > s && after_pathsep(s, tail))
+-	    --tail;
++	    mb_ptr_back(*fnamep, tail);
+ 	*fnamelen = (int)(tail - *fnamep);
+ #ifdef VMS
+ 	if (*fnamelen > 0)
+ 	    *fnamelen += 1; /* the path separator is part of the path */
+ #endif
+-	while (tail > s && !after_pathsep(s, tail))
+-	    mb_ptr_back(*fnamep, tail);
++	if (*fnamelen == 0)
++	{
++	    /* Result is empty.  Turn it into "." to make ":cd %:h" work. */
++	    p = vim_strsave((char_u *)".");
++	    if (p == NULL)
++		return -1;
++	    vim_free(*bufp);
++	    *bufp = *fnamep = tail = p;
++	    *fnamelen = 1;
++	}
++	else
++	{
++	    while (tail > s && !after_pathsep(s, tail))
++		mb_ptr_back(*fnamep, tail);
++	}
+     }
+ 
+     /* ":8" - shortname  */
+diff -Naur vim71.orig/src/ex_cmds.c vim71/src/ex_cmds.c
+--- vim71.orig/src/ex_cmds.c	2007-05-07 15:41:01.000000000 -0400
++++ vim71/src/ex_cmds.c	2007-12-21 00:00:05.000000000 -0500
+@@ -408,7 +408,11 @@
+ 		goto sortend;
+ 	    }
+ 	    *s = NUL;
+-	    regmatch.regprog = vim_regcomp(p + 1, RE_MAGIC);
++	    /* Use last search pattern if sort pattern is empty. */
++	    if (s == p + 1 && last_search_pat() != NULL)
++		regmatch.regprog = vim_regcomp(last_search_pat(), RE_MAGIC);
++	    else
++		regmatch.regprog = vim_regcomp(p + 1, RE_MAGIC);
+ 	    if (regmatch.regprog == NULL)
+ 		goto sortend;
+ 	    p = s;		/* continue after the regexp */
+@@ -1646,7 +1650,7 @@
+ {
+     vim_snprintf((char *)IObuff, IOSIZE, _("%sviminfo: %s in line: "),
+ 							     errnum, message);
+-    STRNCAT(IObuff, line, IOSIZE - STRLEN(IObuff));
++    STRNCAT(IObuff, line, IOSIZE - STRLEN(IObuff) - 1);
+     if (IObuff[STRLEN(IObuff) - 1] == '\n')
+ 	IObuff[STRLEN(IObuff) - 1] = NUL;
+     emsg(IObuff);
+@@ -1770,7 +1774,8 @@
+ 	 * overwrite a user's viminfo file after a "su root", with a
+ 	 * viminfo file that the user can't read.
+ 	 */
+-	st_old.st_dev = st_old.st_ino = 0;
++	st_old.st_dev = 0;
++	st_old.st_ino = 0;
+ 	st_old.st_mode = 0600;
+ 	if (mch_stat((char *)fname, &st_old) == 0
+ 		&& getuid() != ROOT_UID
+@@ -2727,6 +2732,9 @@
+ 		    && vim_strchr(p_cpo, CPO_OVERNEW) == NULL)
+ 		|| (buf->b_flags & BF_READERR))
+ 	    && !p_wa
++#ifdef FEAT_QUICKFIX
++	    && !bt_nofile(buf)
++#endif
+ 	    && vim_fexists(ffname))
+     {
+ 	if (!eap->forceit && !eap->append)
+@@ -2912,22 +2920,35 @@
+ }
+ 
+ /*
+- * Check if a buffer is read-only.  Ask for overruling in a dialog.
+- * Return TRUE and give an error message when the buffer is readonly.
++ * Check if a buffer is read-only (either 'readonly' option is set or file is
++ * read-only). Ask for overruling in a dialog. Return TRUE and give an error
++ * message when the buffer is readonly.
+  */
+     static int
+ check_readonly(forceit, buf)
+     int		*forceit;
+     buf_T	*buf;
+ {
+-    if (!*forceit && buf->b_p_ro)
++    struct stat	st;
++
++    /* Handle a file being readonly when the 'readonly' option is set or when
++     * the file exists and permissions are read-only.
++     * We will send 0777 to check_file_readonly(), as the "perm" variable is
++     * important for device checks but not here. */
++    if (!*forceit && (buf->b_p_ro
++		|| (mch_stat((char *)buf->b_ffname, &st) >= 0
++		    && check_file_readonly(buf->b_ffname, 0777))))
+     {
+ #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
+ 	if ((p_confirm || cmdmod.confirm) && buf->b_fname != NULL)
+ 	{
+ 	    char_u	buff[IOSIZE];
+ 
+-	    dialog_msg(buff, _("'readonly' option is set for \"%s\".\nDo you wish to write anyway?"),
++	    if (buf->b_p_ro)
++		dialog_msg(buff, _("'readonly' option is set for \"%s\".\nDo you wish to write anyway?"),
++		    buf->b_fname);
++	    else
++		dialog_msg(buff, _("File permissions of \"%s\" are read-only.\nIt may still be possible to write it.\nDo you wish to try?"),
+ 		    buf->b_fname);
+ 
+ 	    if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2) == VIM_YES)
+@@ -2941,9 +2962,14 @@
+ 	}
+ 	else
+ #endif
++	if (buf->b_p_ro)
+ 	    EMSG(_(e_readonly));
++	else
++	    EMSG2(_("E505: \"%s\" is read-only (add ! to override)"),
++		    buf->b_fname);
+ 	return TRUE;
+     }
++
+     return FALSE;
+ }
+ 
+@@ -2952,7 +2978,7 @@
+  * 'fnum' is the number of the file, if zero use ffname/sfname.
+  *
+  * Return 1 for "normal" error, 2 for "not written" error, 0 for success
+- * -1 for succesfully opening another file.
++ * -1 for successfully opening another file.
+  * 'lnum' is the line number for the cursor in the new file (if non-zero).
+  */
+     int
+@@ -3367,7 +3393,7 @@
+ 		 * was in this window (or another window).  If not used
+ 		 * before, reset the local window options to the global
+ 		 * values.  Also restores old folding stuff. */
+-		get_winopts(buf);
++		get_winopts(curbuf);
+ #ifdef FEAT_SPELL
+ 		did_get_winopts = TRUE;
+ #endif
+@@ -3562,9 +3588,20 @@
+ 	curwin_init();
+ 
+ #ifdef FEAT_FOLDING
+-	/* It's like all lines in the buffer changed.  Need to update
+-	 * automatic folding. */
++	/* It's possible that all lines in the buffer changed.  Need to update
++	 * automatic folding for all windows where it's used. */
++# ifdef FEAT_WINDOWS
++	{
++	    win_T	    *win;
++	    tabpage_T	    *tp;
++
++	    FOR_ALL_TAB_WINDOWS(tp, win)
++		if (win->w_buffer == curbuf)
++		    foldUpdateAll(win);
++	}
++# else
+ 	foldUpdateAll(curwin);
++# endif
+ #endif
+ 
+ 	/* Change directories when the 'acd' option is set. */
+@@ -3649,8 +3686,8 @@
+ #ifdef FEAT_SPELL
+     /* If the window options were changed may need to set the spell language.
+      * Can only do this after the buffer has been properly setup. */
+-    if (did_get_winopts && curwin->w_p_spell && *buf->b_p_spl != NUL)
+-	did_set_spelllang(buf);
++    if (did_get_winopts && curwin->w_p_spell && *curbuf->b_p_spl != NUL)
++	did_set_spelllang(curbuf);
+ #endif
+ 
+     if (command == NULL)
+@@ -3754,7 +3791,7 @@
+ 	    workshop_file_opened((char *)curbuf->b_ffname, curbuf->b_p_ro);
+ # endif
+ # ifdef FEAT_NETBEANS_INTG
+-	if (usingNetbeans & ((flags & ECMD_SET_HELP) != ECMD_SET_HELP))
++	if (usingNetbeans && ((flags & ECMD_SET_HELP) != ECMD_SET_HELP))
+ 	    netbeans_file_opened(curbuf);
+ # endif
+     }
+@@ -4294,6 +4331,7 @@
+ 	do_error = TRUE;
+ 	do_print = FALSE;
+ 	do_count = FALSE;
++	do_number = FALSE;
+ 	do_ic = 0;
+     }
+     while (*cmd)
+@@ -4464,7 +4502,7 @@
+ 	     *
+ 	     * The new text is built up in new_start[].  It has some extra
+ 	     * room to avoid using alloc()/free() too often.  new_start_len is
+-	     * the lenght of the allocated memory at new_start.
++	     * the length of the allocated memory at new_start.
+ 	     *
+ 	     * Make a copy of the old line, so it won't be taken away when
+ 	     * updating the screen or handling a multi-line match.  The "old_"
+@@ -4635,7 +4673,7 @@
+ #endif
+ 			    ++no_mapping;	/* don't map this key */
+ 			    ++allow_keys;	/* allow special keys */
+-			    i = safe_vgetc();
++			    i = plain_vgetc();
+ 			    --allow_keys;
+ 			    --no_mapping;
+ 
+@@ -4850,7 +4888,8 @@
+ 			    ++line2;
+ 			    /* move the cursor to the new line, like Vi */
+ 			    ++curwin->w_cursor.lnum;
+-			    STRCPY(new_start, p1 + 1);	/* copy the rest */
++			    /* copy the rest */
++			    mch_memmove(new_start, p1 + 1, STRLEN(p1 + 1) + 1);
+ 			    p1 = new_start - 1;
+ 			}
+ 		    }
+@@ -6351,9 +6390,9 @@
+ 	for (i = 0; i < ga.ga_len; ++i)
+ 	{
+ 	    s = ((char_u **)ga.ga_data)[i];
+-	    if (STRNCMP(s, "help-tags", 9) == 0)
++	    if (STRNCMP(s, "help-tags\t", 10) == 0)
+ 		/* help-tags entry was added in formatted form */
+-		fprintf(fd_tags, (char *)s);
++		fputs((char *)s, fd_tags);
+ 	    else
+ 	    {
+ 		fprintf(fd_tags, "%s\t/*", s);
+diff -Naur vim71.orig/src/ex_docmd.c vim71/src/ex_docmd.c
+--- vim71.orig/src/ex_docmd.c	2007-05-07 15:49:38.000000000 -0400
++++ vim71/src/ex_docmd.c	2007-12-21 00:00:05.000000000 -0500
+@@ -133,6 +133,7 @@
+ static void	get_flags __ARGS((exarg_T *eap));
+ #if !defined(FEAT_PERL) || !defined(FEAT_PYTHON) || !defined(FEAT_TCL) \
+ 	|| !defined(FEAT_RUBY) || !defined(FEAT_MZSCHEME)
++# define HAVE_EX_SCRIPT_NI
+ static void	ex_script_ni __ARGS((exarg_T *eap));
+ #endif
+ static char_u	*invalid_range __ARGS((exarg_T *eap));
+@@ -666,7 +667,7 @@
+ 		if (ex_pressedreturn)
+ 		{
+ 		    /* go up one line, to overwrite the ":<CR>" line, so the
+-		     * output doensn't contain empty lines. */
++		     * output doesn't contain empty lines. */
+ 		    msg_row = prev_msg_row;
+ 		    if (prev_msg_row == Rows - 1)
+ 			msg_row--;
+@@ -1741,7 +1742,9 @@
+ 	}
+ 
+ 	/* ignore comment and empty lines */
+-	if (*ea.cmd == '"' || *ea.cmd == NUL)
++	if (*ea.cmd == '"')
++	    goto doend;
++	if (*ea.cmd == NUL)
+ 	{
+ 	    ex_pressedreturn = TRUE;
+ 	    goto doend;
+@@ -2118,7 +2121,11 @@
+ #ifdef FEAT_USR_CMDS
+ 	    !USER_CMDIDX(ea.cmdidx) &&
+ #endif
+-	    cmdnames[ea.cmdidx].cmd_func == ex_ni);
++	    (cmdnames[ea.cmdidx].cmd_func == ex_ni
++#ifdef HAVE_EX_SCRIPT_NI
++	     || cmdnames[ea.cmdidx].cmd_func == ex_script_ni
++#endif
++	     ));
+ 
+ #ifndef FEAT_EVAL
+     /*
+@@ -2654,7 +2661,7 @@
+ 		errormsg = IObuff;
+ 	    }
+ 	    STRCAT(errormsg, ": ");
+-	    STRNCAT(errormsg, *cmdlinep, IOSIZE - STRLEN(IObuff));
++	    STRNCAT(errormsg, *cmdlinep, IOSIZE - STRLEN(IObuff) - 1);
+ 	}
+ 	emsg(errormsg);
+     }
+@@ -2756,7 +2763,7 @@
+ 
+     /*
+      * Isolate the command and search for it in the command table.
+-     * Exeptions:
++     * Exceptions:
+      * - the 'k' command can directly be followed by any character.
+      * - the 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r'
+      *	    but :sre[wind] is another command, as are :scrip[tnames],
+@@ -2957,6 +2964,57 @@
+ #endif
+ 
+ #if defined(FEAT_EVAL) || defined(PROTO)
++static struct cmdmod
++{
++    char	*name;
++    int		minlen;
++    int		has_count;  /* :123verbose  :3tab */
++} cmdmods[] = {
++    {"aboveleft", 3, FALSE},
++    {"belowright", 3, FALSE},
++    {"botright", 2, FALSE},
++    {"browse", 3, FALSE},
++    {"confirm", 4, FALSE},
++    {"hide", 3, FALSE},
++    {"keepalt", 5, FALSE},
++    {"keepjumps", 5, FALSE},
++    {"keepmarks", 3, FALSE},
++    {"leftabove", 5, FALSE},
++    {"lockmarks", 3, FALSE},
++    {"rightbelow", 6, FALSE},
++    {"sandbox", 3, FALSE},
++    {"silent", 3, FALSE},
++    {"tab", 3, TRUE},
++    {"topleft", 2, FALSE},
++    {"verbose", 4, TRUE},
++    {"vertical", 4, FALSE},
++};
++
++/*
++ * Return length of a command modifier (including optional count).
++ * Return zero when it's not a modifier.
++ */
++    int
++modifier_len(cmd)
++    char_u	*cmd;
++{
++    int		i, j;
++    char_u	*p = cmd;
++
++    if (VIM_ISDIGIT(*cmd))
++	p = skipwhite(skipdigits(cmd));
++    for (i = 0; i < sizeof(cmdmods) / sizeof(struct cmdmod); ++i)
++    {
++	for (j = 0; p[j] != NUL; ++j)
++	    if (p[j] != cmdmods[i].name[j])
++		break;
++	if (!isalpha(p[j]) && j >= cmdmods[i].minlen
++					&& (p == cmd || cmdmods[i].has_count))
++	    return j + (p - cmd);
++    }
++    return 0;
++}
++
+ /*
+  * Return > 0 if an Ex command "name" exists.
+  * Return 2 if there is an exact match.
+@@ -2971,30 +3029,6 @@
+     int		i;
+     int		j;
+     char_u	*p;
+-    static struct cmdmod
+-    {
+-	char	*name;
+-	int	minlen;
+-    } cmdmods[] = {
+-	{"aboveleft", 3},
+-	{"belowright", 3},
+-	{"botright", 2},
+-	{"browse", 3},
+-	{"confirm", 4},
+-	{"hide", 3},
+-	{"keepalt", 5},
+-	{"keepjumps", 5},
+-	{"keepmarks", 3},
+-	{"leftabove", 5},
+-	{"lockmarks", 3},
+-	{"rightbelow", 6},
+-	{"sandbox", 3},
+-	{"silent", 3},
+-	{"tab", 3},
+-	{"topleft", 2},
+-	{"verbose", 4},
+-	{"vertical", 4},
+-    };
+ 
+     /* Check command modifiers. */
+     for (i = 0; i < sizeof(cmdmods) / sizeof(struct cmdmod); ++i)
+@@ -3276,39 +3310,65 @@
+ 
+     if (ea.argt & XFILE)
+     {
+-	int in_quote = FALSE;
+-	char_u *bow = NULL;	/* Beginning of word */
++	int	c;
++	int	in_quote = FALSE;
++	char_u	*bow = NULL;	/* Beginning of word */
+ 
+ 	/*
+ 	 * Allow spaces within back-quotes to count as part of the argument
+ 	 * being expanded.
+ 	 */
+ 	xp->xp_pattern = skipwhite(arg);
+-	for (p = xp->xp_pattern; *p; )
++	p = xp->xp_pattern;
++	while (*p != NUL)
+ 	{
+-	    if (*p == '\\' && p[1] != NUL)
++#ifdef FEAT_MBYTE
++	    if (has_mbyte)
++		c = mb_ptr2char(p);
++	    else
++#endif
++		c = *p;
++	    if (c == '\\' && p[1] != NUL)
+ 		++p;
++	    else if (c == '`')
++	    {
++		if (!in_quote)
++		{
++		    xp->xp_pattern = p;
++		    bow = p + 1;
++		}
++		in_quote = !in_quote;
++	    }
+ #ifdef SPACE_IN_FILENAME
+-	    else if (vim_iswhite(*p) && (!(ea.argt & NOSPC) || usefilter))
++	    else if (!vim_isfilec_or_wc(c)
++					 && (!(ea.argt & NOSPC) || usefilter))
+ #else
+-	    else if (vim_iswhite(*p))
++	    else if (!vim_isfilec_or_wc(c))
+ #endif
+ 	    {
+-		p = skipwhite(p);
++		while (*p != NUL)
++		{
++#ifdef FEAT_MBYTE
++		    if (has_mbyte)
++			c = mb_ptr2char(p);
++		    else
++#endif
++			c = *p;
++		    if (c == '`' || vim_isfilec_or_wc(c))
++			break;
++#ifdef FEAT_MBYTE
++		    if (has_mbyte)
++			len = (*mb_ptr2len)(p);
++		    else
++#endif
++			len = 1;
++		    mb_ptr_adv(p);
++		}
+ 		if (in_quote)
+ 		    bow = p;
+ 		else
+ 		    xp->xp_pattern = p;
+-		--p;
+-	    }
+-	    else if (*p == '`')
+-	    {
+-		if (!in_quote)
+-		{
+-		    xp->xp_pattern = p;
+-		    bow = p + 1;
+-		}
+-		in_quote = !in_quote;
++		p -= len;
+ 	    }
+ 	    mb_ptr_adv(p);
+ 	}
+@@ -3401,14 +3461,13 @@
+ 	case CMD_windo:
+ 	    return arg;
+ 
+-#ifdef FEAT_SEARCH_EXTRA
++#ifdef FEAT_CMDL_COMPL
++# ifdef FEAT_SEARCH_EXTRA
+ 	case CMD_match:
+ 	    if (*arg == NUL || !ends_excmd(*arg))
+ 	    {
+-		/* Dummy call to clear variables. */
+-		set_context_in_highlight_cmd(xp, (char_u *)"link n");
+-		xp->xp_context = EXPAND_HIGHLIGHT;
+-		xp->xp_pattern = arg;
++		/* also complete "None" */
++		set_context_in_echohl_cmd(xp, arg);
+ 		arg = skipwhite(skiptowhite(arg));
+ 		if (*arg != NUL)
+ 		{
+@@ -3417,9 +3476,8 @@
+ 		}
+ 	    }
+ 	    return find_nextcmd(arg);
+-#endif
++# endif
+ 
+-#ifdef FEAT_CMDL_COMPL
+ /*
+  * All completion for the +cmdline_compl feature goes here.
+  */
+@@ -3617,8 +3675,7 @@
+ 	    break;
+ 
+ 	case CMD_echohl:
+-	    xp->xp_context = EXPAND_HIGHLIGHT;
+-	    xp->xp_pattern = arg;
++	    set_context_in_echohl_cmd(xp, arg);
+ 	    break;
+ #endif
+ 	case CMD_highlight:
+@@ -3997,8 +4054,7 @@
+ 	eap->errmsg = (char_u *)N_("E319: Sorry, the command is not available in this version");
+ }
+ 
+-#if !defined(FEAT_PERL) || !defined(FEAT_PYTHON) || !defined(FEAT_TCL) \
+-	|| !defined(FEAT_RUBY) || !defined(FEAT_MZSCHEME)
++#ifdef HAVE_EX_SCRIPT_NI
+ /*
+  * Function called for script command which is Not Implemented.  NI!
+  * Skips over ":perl <<EOF" constructs.
+@@ -4376,7 +4432,7 @@
+ 			    || vim_strchr(eap->arg, '~') != NULL)
+ 		    {
+ 			expand_env_esc(eap->arg, NameBuff, MAXPATHL,
+-								 TRUE, NULL);
++							    TRUE, TRUE, NULL);
+ 			has_wildcards = mch_has_wildcard(NameBuff);
+ 			p = NameBuff;
+ 		    }
+@@ -4492,7 +4548,8 @@
+ 	    if (eap->argt & (USECTRLV | XFILE))
+ 		++p;		/* skip CTRL-V and next char */
+ 	    else
+-		STRCPY(p, p + 1);	/* remove CTRL-V and skip next char */
++				/* remove CTRL-V and skip next char */
++		mch_memmove(p, p + 1, STRLEN(p));
+ 	    if (*p == NUL)		/* stop at NUL after CTRL-V */
+ 		break;
+ 	}
+@@ -6650,7 +6707,7 @@
+  * The list should be allocated using alloc(), as should each item in the
+  * list. This function takes over responsibility for freeing the list.
+  *
+- * XXX The list is made into the arggument list. This is freed using
++ * XXX The list is made into the argument list. This is freed using
+  * FreeWild(), which does a series of vim_free() calls, unless the two defines
+  * __EMX__ and __ALWAYS_HAS_TRAILING_NUL_POINTER are set. In this case, a
+  * routine _fnexplodefree() is used. This may cause problems, but as the drop
+@@ -7768,7 +7825,7 @@
+ 	if (vim_strchr(p_cpo, CPO_CHDIR) != NULL && curbufIsChanged()
+ 							     && !eap->forceit)
+ 	{
+-	    EMSG(_("E747: Cannot change directory, buffer is modifed (add ! to override)"));
++	    EMSG(_("E747: Cannot change directory, buffer is modified (add ! to override)"));
+ 	    return;
+ 	}
+ 
+@@ -8399,21 +8456,17 @@
+ 		    || *arg == '"')
+ 	    {
+ 		redir_reg = *arg++;
+-		if (*arg == '>' && arg[1] == '>')
++		if (*arg == '>' && arg[1] == '>')  /* append */
+ 		    arg += 2;
+-		else if ((*arg == NUL || (*arg == '>' && arg[1] == NUL)) &&
+-			 (islower(redir_reg)
+-# ifdef FEAT_CLIPBOARD
+-			    || redir_reg == '*'
+-			    || redir_reg == '+'
+-# endif
+-			    || redir_reg == '"'))
++		else
+ 		{
++		    /* Can use both "@a" and "@a>". */
+ 		    if (*arg == '>')
+ 			arg++;
+-
+-		    /* make register empty */
+-		    write_reg_contents(redir_reg, (char_u *)"", -1, FALSE);
++		    /* Make register empty when not using @A-@Z and the
++		     * command is valid. */
++		    if (*arg == NUL && !isupper(redir_reg))
++			write_reg_contents(redir_reg, (char_u *)"", -1, FALSE);
+ 		}
+ 	    }
+ 	    if (*arg != NUL)
+@@ -9368,7 +9421,7 @@
+     if (src > srcstart && src[-1] == '\\')
+     {
+ 	*usedlen = 0;
+-	STRCPY(src - 1, src);		/* remove backslash */
++	mch_memmove(src - 1, src, STRLEN(src) + 1);	/* remove backslash */
+ 	return NULL;
+     }
+ 
+@@ -10816,12 +10869,13 @@
+     exarg_T	*eap;
+ {
+     char_u	*p;
++    char_u	*g = NULL;
+     char_u	*end;
+     int		c;
+-    int		mi;
++    int		id;
+ 
+     if (eap->line2 <= 3)
+-	mi = eap->line2 - 1;
++	id = eap->line2;
+     else
+     {
+ 	EMSG(e_invcmd);
+@@ -10830,13 +10884,7 @@
+ 
+     /* First clear any old pattern. */
+     if (!eap->skip)
+-    {
+-	vim_free(curwin->w_match[mi].regprog);
+-	curwin->w_match[mi].regprog = NULL;
+-	vim_free(curwin->w_match_pat[mi]);
+-	curwin->w_match_pat[mi] = NULL;
+-	redraw_later(SOME_VALID);	/* always need a redraw */
+-    }
++	match_delete(curwin, id, FALSE);
+ 
+     if (ends_excmd(*eap->arg))
+ 	end = eap->arg;
+@@ -10847,15 +10895,7 @@
+     {
+ 	p = skiptowhite(eap->arg);
+ 	if (!eap->skip)
+-	{
+-	    curwin->w_match_id[mi] = syn_namen2id(eap->arg,
+-							 (int)(p - eap->arg));
+-	    if (curwin->w_match_id[mi] == 0)
+-	    {
+-		EMSG2(_(e_nogroup), eap->arg);
+-		return;
+-	    }
+-	}
++	    g = vim_strnsave(eap->arg, (int)(p - eap->arg));
+ 	p = skipwhite(p);
+ 	if (*p == NUL)
+ 	{
+@@ -10879,14 +10919,8 @@
+ 
+ 	    c = *end;
+ 	    *end = NUL;
+-	    curwin->w_match[mi].regprog = vim_regcomp(p + 1, RE_MAGIC);
+-	    if (curwin->w_match[mi].regprog == NULL)
+-	    {
+-		EMSG2(_(e_invarg2), p);
+-		*end = c;
+-		return;
+-	    }
+-	    curwin->w_match_pat[mi] = vim_strsave(p + 1);
++	    match_add(curwin, g, p + 1, 10, id);
++	    vim_free(g);
+ 	    *end = c;
+ 	}
+     }
+diff -Naur vim71.orig/src/ex_eval.c vim71/src/ex_eval.c
+--- vim71.orig/src/ex_eval.c	2007-05-07 15:47:50.000000000 -0400
++++ vim71/src/ex_eval.c	2007-12-20 23:59:51.000000000 -0500
+@@ -1551,7 +1551,7 @@
+ 		}
+ 		save_cpo  = p_cpo;
+ 		p_cpo = (char_u *)"";
+-		regmatch.regprog = vim_regcomp(pat, TRUE);
++		regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
+ 		regmatch.rm_ic = FALSE;
+ 		if (end != NULL)
+ 		    *end = save_char;
+@@ -2269,9 +2269,18 @@
+ has_loop_cmd(p)
+     char_u	*p;
+ {
+-    p = skipwhite(p);
+-    while (*p == ':')
+-	p = skipwhite(p + 1);
++    int		len;
++
++    /* skip modifiers, white space and ':' */
++    for (;;)
++    {
++	while (*p == ' ' || *p == '\t' || *p == ':')
++	    ++p;
++	len = modifier_len(p);
++	if (len == 0)
++	    break;
++	p += len;
++    }
+     if ((p[0] == 'w' && p[1] == 'h')
+ 	    || (p[0] == 'f' && p[1] == 'o' && p[2] == 'r'))
+ 	return TRUE;
+diff -Naur vim71.orig/src/ex_getln.c vim71/src/ex_getln.c
+--- vim71.orig/src/ex_getln.c	2007-05-07 15:47:23.000000000 -0400
++++ vim71/src/ex_getln.c	2007-12-21 00:00:02.000000000 -0500
+@@ -268,7 +268,9 @@
+     {
+ 	xpc.xp_context = ccline.xp_context;
+ 	xpc.xp_pattern = ccline.cmdbuff;
++# if defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)
+ 	xpc.xp_arg = ccline.xp_arg;
++# endif
+     }
+ #endif
+ 
+@@ -484,7 +486,8 @@
+ 	if (xpc.xp_context == EXPAND_MENUNAMES && p_wmnu)
+ 	{
+ 	    /* Hitting <Down> after "emenu Name.": complete submenu */
+-	    if (ccline.cmdbuff[ccline.cmdpos - 1] == '.' && c == K_DOWN)
++	    if (c == K_DOWN && ccline.cmdpos > 0
++				  && ccline.cmdbuff[ccline.cmdpos - 1] == '.')
+ 		c = p_wc;
+ 	    else if (c == K_UP)
+ 	    {
+@@ -533,9 +536,11 @@
+ 	    upseg[3] = PATHSEP;
+ 	    upseg[4] = NUL;
+ 
+-	    if (ccline.cmdbuff[ccline.cmdpos - 1] == PATHSEP
+-		    && c == K_DOWN
+-		    && (ccline.cmdbuff[ccline.cmdpos - 2] != '.'
++	    if (c == K_DOWN
++		    && ccline.cmdpos > 0
++		    && ccline.cmdbuff[ccline.cmdpos - 1] == PATHSEP
++		    && (ccline.cmdpos < 3
++			|| ccline.cmdbuff[ccline.cmdpos - 2] != '.'
+ 			|| ccline.cmdbuff[ccline.cmdpos - 3] != '.'))
+ 	    {
+ 		/* go down a directory */
+@@ -636,7 +641,7 @@
+ 	{
+ 	    ++no_mapping;
+ 	    ++allow_keys;
+-	    c = safe_vgetc();
++	    c = plain_vgetc();
+ 	    --no_mapping;
+ 	    --allow_keys;
+ 	    /* CTRL-\ e doesn't work when obtaining an expression. */
+@@ -730,8 +735,8 @@
+ 	    /* In Ex mode a backslash escapes a newline. */
+ 	    if (exmode_active
+ 		    && c != ESC
+-		    && ccline.cmdpos > 0
+ 		    && ccline.cmdpos == ccline.cmdlen
++		    && ccline.cmdpos > 0
+ 		    && ccline.cmdbuff[ccline.cmdpos - 1] == '\\')
+ 	    {
+ 		if (c == K_KENTER)
+@@ -1086,11 +1091,11 @@
+ #endif
+ 		putcmdline('"', TRUE);
+ 		++no_mapping;
+-		i = c = safe_vgetc();	/* CTRL-R <char> */
++		i = c = plain_vgetc();	/* CTRL-R <char> */
+ 		if (i == Ctrl_O)
+ 		    i = Ctrl_R;		/* CTRL-R CTRL-O == CTRL-R CTRL-R */
+ 		if (i == Ctrl_R)
+-		    c = safe_vgetc();	/* CTRL-R CTRL-R <char> */
++		    c = plain_vgetc();	/* CTRL-R CTRL-R <char> */
+ 		--no_mapping;
+ #ifdef FEAT_EVAL
+ 		/*
+@@ -1181,10 +1186,10 @@
+ 	case K_LEFT:
+ 	case K_S_LEFT:
+ 	case K_C_LEFT:
++		if (ccline.cmdpos == 0)
++		    goto cmdline_not_changed;
+ 		do
+ 		{
+-		    if (ccline.cmdpos == 0)
+-			break;
+ 		    --ccline.cmdpos;
+ #ifdef FEAT_MBYTE
+ 		    if (has_mbyte)	/* move to first byte of char */
+@@ -1193,7 +1198,8 @@
+ #endif
+ 		    ccline.cmdspos -= cmdline_charsize(ccline.cmdpos);
+ 		}
+-		while ((c == K_S_LEFT || c == K_C_LEFT
++		while (ccline.cmdpos > 0
++			&& (c == K_S_LEFT || c == K_C_LEFT
+ 			       || (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)))
+ 			&& ccline.cmdbuff[ccline.cmdpos - 1] != ' ');
+ #ifdef FEAT_MBYTE
+@@ -2090,11 +2096,11 @@
+     garray_T	line_ga;
+     char_u	*pend;
+     int		startcol = 0;
+-    int		c1;
++    int		c1 = 0;
+     int		escaped = FALSE;	/* CTRL-V typed */
+     int		vcol = 0;
+     char_u	*p;
+-    int		prev_char = 0;
++    int		prev_char;
+ 
+     /* Switch cursor on now.  This avoids that it happens after the "\n", which
+      * confuses the system function that computes tabstops. */
+@@ -2147,6 +2153,7 @@
+ 
+ 	/* Get one character at a time.  Don't use inchar(), it can't handle
+ 	 * special characters. */
++	prev_char = c1;
+ 	c1 = vgetc();
+ 
+ 	/*
+@@ -2204,7 +2211,6 @@
+ redraw:
+ 		/* redraw the line */
+ 		msg_col = startcol;
+-		windgoto(msg_row, msg_col);
+ 		vcol = 0;
+ 		for (p = (char_u *)line_ga.ga_data;
+ 			  p < (char_u *)line_ga.ga_data + line_ga.ga_len; ++p)
+@@ -2223,6 +2229,7 @@
+ 		    }
+ 		}
+ 		msg_clr_eos();
++		windgoto(msg_row, msg_col);
+ 		continue;
+ 	    }
+ 
+@@ -2268,7 +2275,6 @@
+ 	if (IS_SPECIAL(c1))
+ 	    c1 = '?';
+ 	((char_u *)line_ga.ga_data)[line_ga.ga_len] = c1;
+-	prev_char = c1;
+ 	if (c1 == '\n')
+ 	    msg_putchar('\n');
+ 	else if (c1 == TAB)
+@@ -3311,6 +3317,10 @@
+  * Return a pointer to alloced memory containing the new string.
+  * Return NULL for failure.
+  *
++ * "orig" is the originally expanded string, copied to allocated memory.  It
++ * should either be kept in orig_save or freed.  When "mode" is WILD_NEXT or
++ * WILD_PREV "orig" should be NULL.
++ *
+  * Results are cached in xp->xp_files and xp->xp_numfiles, except when "mode"
+  * is WILD_EXPAND_FREE or WILD_ALL.
+  *
+@@ -3344,6 +3354,7 @@
+     char_u	*ss = NULL;
+     static int	findex;
+     static char_u *orig_save = NULL;	/* kept value of orig */
++    int		orig_saved = FALSE;
+     int		i;
+     long_u	len;
+     int		non_suf_match;		/* number without matching suffix */
+@@ -3395,7 +3406,7 @@
+ 	    return NULL;
+     }
+ 
+-/* free old names */
++    /* free old names */
+     if (xp->xp_numfiles != -1 && mode != WILD_ALL && mode != WILD_LONGEST)
+     {
+ 	FreeWild(xp->xp_numfiles, xp->xp_files);
+@@ -3412,6 +3423,7 @@
+     {
+ 	vim_free(orig_save);
+ 	orig_save = orig;
++	orig_saved = TRUE;
+ 
+ 	/*
+ 	 * Do the expansion.
+@@ -3536,6 +3548,10 @@
+     if (mode == WILD_EXPAND_FREE || mode == WILD_ALL)
+ 	ExpandCleanup(xp);
+ 
++    /* Free "orig" if it wasn't stored in "orig_save". */
++    if (!orig_saved)
++	vim_free(orig);
++
+     return ss;
+ }
+ 
+@@ -4148,13 +4164,19 @@
+ 
+ #ifdef FEAT_EVAL
+     if (ccline.cmdfirstc == '=')
++    {
++# ifdef FEAT_CMDL_COMPL
+ 	/* pass CMD_SIZE because there is no real command */
+ 	set_context_for_expression(xp, str, CMD_SIZE);
++# endif
++    }
+     else if (ccline.input_fn)
+     {
+ 	xp->xp_context = ccline.xp_context;
+ 	xp->xp_pattern = ccline.cmdbuff;
++# if defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)
+ 	xp->xp_arg = ccline.xp_arg;
++# endif
+     }
+     else
+ #endif
+@@ -4295,10 +4317,11 @@
+ 			    && pat[i + 1] == '\\'
+ 			    && pat[i + 2] == '\\'
+ 			    && pat[i + 3] == ' ')
+-			STRCPY(pat + i, pat + i + 3);
++			mch_memmove(pat + i, pat + i + 3,
++						     STRLEN(pat + i + 3) + 1);
+ 		    if (xp->xp_backslash == XP_BS_ONE
+ 			    && pat[i + 1] == ' ')
+-			STRCPY(pat + i, pat + i + 1);
++			mch_memmove(pat + i, pat + i + 1, STRLEN(pat + i));
+ 		}
+ 	}
+ 
+@@ -4502,6 +4525,12 @@
+     if (xp->xp_context != EXPAND_MENUNAMES && xp->xp_context != EXPAND_MENUS)
+ 	sort_strings(*file, *num_file);
+ 
++#ifdef FEAT_CMDL_COMPL
++    /* Reset the variables used for special highlight names expansion, so that
++     * they don't show up when getting normal highlight names by ID. */
++    reset_expand_highlight();
++#endif
++
+     return OK;
+ }
+ 
+@@ -4535,7 +4564,7 @@
+     pat = vim_strsave(filepat);
+     for (i = 0; pat[i]; ++i)
+ 	if (pat[i] == '\\' && pat[i + 1] == ' ')
+-	    STRCPY(pat + i, pat + i + 1);
++	    mch_memmove(pat + i, pat + i + 1, STRLEN(pat + i));
+ 
+     flags |= EW_FILE | EW_EXEC;
+ 
+@@ -5907,7 +5936,7 @@
+ 
+ # ifdef FEAT_AUTOCMD
+     /* Don't execute autocommands while creating the window. */
+-    ++autocmd_block;
++    block_autocmds();
+ # endif
+     /* don't use a new tab page */
+     cmdmod.tab = 0;
+@@ -5916,6 +5945,9 @@
+     if (win_split((int)p_cwh, WSP_BOT) == FAIL)
+     {
+ 	beep_flush();
++# ifdef FEAT_AUTOCMD
++	unblock_autocmds();
++# endif
+ 	return K_IGNORE;
+     }
+     cmdwin_type = ccline.cmdfirstc;
+@@ -5938,7 +5970,7 @@
+ 
+ # ifdef FEAT_AUTOCMD
+     /* Do execute autocommands for setting the filetype (load syntax). */
+-    --autocmd_block;
++    unblock_autocmds();
+ # endif
+ 
+     /* Showing the prompt may have set need_wait_return, reset it. */
+@@ -6092,7 +6124,7 @@
+ 
+ # ifdef FEAT_AUTOCMD
+ 	/* Don't execute autocommands while deleting the window. */
+-	++autocmd_block;
++	block_autocmds();
+ # endif
+ 	wp = curwin;
+ 	bp = curbuf;
+@@ -6104,7 +6136,7 @@
+ 	win_size_restore(&winsizes);
+ 
+ # ifdef FEAT_AUTOCMD
+-	--autocmd_block;
++	unblock_autocmds();
+ # endif
+     }
+ 
+diff -Naur vim71.orig/src/feature.h vim71/src/feature.h
+--- vim71.orig/src/feature.h	2007-05-07 15:33:19.000000000 -0400
++++ vim71/src/feature.h	2007-12-20 23:57:30.000000000 -0500
+@@ -673,7 +673,7 @@
+ # define ESC_CHG_TO_ENG_MODE		/* if defined, when ESC pressed,
+ 					 * turn to english mode
+ 					 */
+-# if !defined(FEAT_XFONTSET) && defined(HAVE_X11)
++# if !defined(FEAT_XFONTSET) && defined(HAVE_X11) && !defined(HAVE_GTK2)
+ #  define FEAT_XFONTSET			/* Hangul input requires xfontset */
+ # endif
+ # if defined(FEAT_XIM) && !defined(LINT)
+diff -Naur vim71.orig/src/fileio.c vim71/src/fileio.c
+--- vim71.orig/src/fileio.c	2007-05-10 07:29:44.000000000 -0400
++++ vim71/src/fileio.c	2007-12-20 23:59:40.000000000 -0500
+@@ -44,6 +44,10 @@
+ /* Is there any system that doesn't have access()? */
+ #define USE_MCH_ACCESS
+ 
++#if defined(sun) && defined(S_ISCHR)
++# define OPEN_CHR_FILES
++static int is_dev_fd_file(char_u *fname);
++#endif
+ #ifdef FEAT_MBYTE
+ static char_u *next_fenc __ARGS((char_u **pp));
+ # ifdef FEAT_EVAL
+@@ -406,6 +410,10 @@
+ # ifdef S_ISSOCK
+ 		      && !S_ISSOCK(perm)	    /* ... or socket */
+ # endif
++# ifdef OPEN_CHR_FILES
++		      && !(S_ISCHR(perm) && is_dev_fd_file(fname))
++			/* ... or a character special file named /dev/fd/<n> */
++# endif
+ 						)
+ 	{
+ 	    if (S_ISDIR(perm))
+@@ -424,7 +432,7 @@
+ 	 */
+ 	if (!p_odev && mch_nodetype(fname) == NODE_WRITABLE)
+ 	{
+-	    filemess(curbuf, fname, (char_u *)_("is a device (disabled with 'opendevice' option"), 0);
++	    filemess(curbuf, fname, (char_u *)_("is a device (disabled with 'opendevice' option)"), 0);
+ 	    msg_end();
+ 	    msg_scroll = msg_save;
+ 	    return FAIL;
+@@ -646,6 +654,7 @@
+ 	curbuf->b_start_eol = TRUE;
+ #ifdef FEAT_MBYTE
+ 	curbuf->b_p_bomb = FALSE;
++	curbuf->b_start_bomb = FALSE;
+ #endif
+     }
+ 
+@@ -904,7 +913,10 @@
+ 	file_rewind = FALSE;
+ #ifdef FEAT_MBYTE
+ 	if (set_options)
++	{
+ 	    curbuf->b_p_bomb = FALSE;
++	    curbuf->b_start_bomb = FALSE;
++	}
+ 	conv_error = 0;
+ #endif
+     }
+@@ -1353,7 +1365,10 @@
+ 		    size -= blen;
+ 		    mch_memmove(ptr, ptr + blen, (size_t)size);
+ 		    if (set_options)
++		    {
+ 			curbuf->b_p_bomb = TRUE;
++			curbuf->b_start_bomb = TRUE;
++		    }
+ 		}
+ 
+ 		if (fio_flags == FIO_UCSBOM)
+@@ -2265,6 +2280,13 @@
+ 	    }
+ #  endif
+ # endif
++# ifdef OPEN_CHR_FILES
++	    if (S_ISCHR(perm))			    /* or character special */
++	    {
++		STRCAT(IObuff, _("[character special]"));
++		c = TRUE;
++	    }
++# endif
+ #endif
+ 	    if (curbuf->b_p_ro)
+ 	    {
+@@ -2464,6 +2486,25 @@
+     return OK;
+ }
+ 
++#ifdef OPEN_CHR_FILES
++/*
++ * Returns TRUE if the file name argument is of the form "/dev/fd/\d\+",
++ * which is the name of files used for process substitution output by
++ * some shells on some operating systems, e.g., bash on SunOS.
++ * Do not accept "/dev/fd/[012]", opening these may hang Vim.
++ */
++    static int
++is_dev_fd_file(fname)
++    char_u	*fname;
++{
++    return (STRNCMP(fname, "/dev/fd/", 8) == 0
++	    && VIM_ISDIGIT(fname[8])
++	    && *skipdigits(fname + 9) == NUL
++	    && (fname[9] != NUL
++		|| (fname[8] != '0' && fname[8] != '1' && fname[8] != '2')));
++}
++#endif
++
+ #ifdef FEAT_MBYTE
+ 
+ /*
+@@ -2734,6 +2775,32 @@
+ #endif
+ 
+ /*
++ * Return TRUE if a file appears to be read-only from the file permissions.
++ */
++    int
++check_file_readonly(fname, perm)
++    char_u	*fname;		/* full path to file */
++    int		perm;		/* known permissions on file */
++{
++#ifndef USE_MCH_ACCESS
++    int	    fd = 0;
++#endif
++
++    return (
++#ifdef USE_MCH_ACCESS
++# ifdef UNIX
++	(perm & 0222) == 0 ||
++# endif
++	mch_access((char *)fname, W_OK)
++#else
++	(fd = mch_open((char *)fname, O_RDWR | O_EXTRA, 0)) < 0
++					? TRUE : (close(fd), FALSE)
++#endif
++	);
++}
++
++
++/*
+  * buf_write() - write to file "fname" lines "start" through "end"
+  *
+  * We do our own buffering here because fwrite() is so slow.
+@@ -3142,7 +3209,8 @@
+      * Get information about original file (if there is one).
+      */
+ #if defined(UNIX) && !defined(ARCHIE)
+-    st_old.st_dev = st_old.st_ino = 0;
++    st_old.st_dev = 0;
++    st_old.st_ino = 0;
+     perm = -1;
+     if (mch_stat((char *)fname, &st_old) < 0)
+ 	newfile = TRUE;
+@@ -3219,17 +3287,8 @@
+ 	 * Check if the file is really writable (when renaming the file to
+ 	 * make a backup we won't discover it later).
+ 	 */
+-	file_readonly = (
+-# ifdef USE_MCH_ACCESS
+-#  ifdef UNIX
+-		    (perm & 0222) == 0 ||
+-#  endif
+-		    mch_access((char *)fname, W_OK)
+-# else
+-		    (fd = mch_open((char *)fname, O_RDWR | O_EXTRA, 0)) < 0
+-						   ? TRUE : (close(fd), FALSE)
+-# endif
+-		    );
++	file_readonly = check_file_readonly(fname, (int)perm);
++
+ 	if (!forceit && file_readonly)
+ 	{
+ 	    if (vim_strchr(p_cpo, CPO_FWRITE) != NULL)
+@@ -5495,6 +5554,8 @@
+ }
+ #endif
+ 
++#if defined(FEAT_VIMINFO) || defined(FEAT_BROWSE) || \
++    defined(FEAT_QUICKFIX) || defined(PROTO)
+ /*
+  * Try to find a shortname by comparing the fullname with the current
+  * directory.
+@@ -5548,6 +5609,7 @@
+ 	p = NULL;
+     return p;
+ }
++#endif
+ 
+ /*
+  * Shorten filenames for all buffers.
+@@ -7107,6 +7169,7 @@
+ 
+ static event_T	last_event;
+ static int	last_group;
++static int	autocmd_blocked = 0;	/* block all autocmds */
+ 
+ /*
+  * Show the autocommands for one AutoPat.
+@@ -8396,7 +8459,7 @@
+      * Quickly return if there are no autocommands for this event or
+      * autocommands are blocked.
+      */
+-    if (first_autopat[(int)event] == NULL || autocmd_block > 0)
++    if (first_autopat[(int)event] == NULL || autocmd_blocked > 0)
+ 	goto BYPASS_AU;
+ 
+     /*
+@@ -8710,6 +8773,40 @@
+     return retval;
+ }
+ 
++# ifdef FEAT_EVAL
++static char_u	*old_termresponse = NULL;
++# endif
++
++/*
++ * Block triggering autocommands until unblock_autocmd() is called.
++ * Can be used recursively, so long as it's symmetric.
++ */
++    void
++block_autocmds()
++{
++# ifdef FEAT_EVAL
++    /* Remember the value of v:termresponse. */
++    if (autocmd_blocked == 0)
++	old_termresponse = get_vim_var_str(VV_TERMRESPONSE);
++# endif
++    ++autocmd_blocked;
++}
++
++    void
++unblock_autocmds()
++{
++    --autocmd_blocked;
++
++# ifdef FEAT_EVAL
++    /* When v:termresponse was set while autocommands were blocked, trigger
++     * the autocommands now.  Esp. useful when executing a shell command
++     * during startup (vimdiff). */
++    if (autocmd_blocked == 0
++		      && get_vim_var_str(VV_TERMRESPONSE) != old_termresponse)
++	apply_autocmds(EVENT_TERMRESPONSE, NULL, NULL, FALSE, curbuf);
++# endif
++}
++
+ /*
+  * Find next autocommand pattern that matches.
+  */
+diff -Naur vim71.orig/src/fold.c vim71/src/fold.c
+--- vim71.orig/src/fold.c	2007-05-07 15:46:32.000000000 -0400
++++ vim71/src/fold.c	2007-12-20 23:59:22.000000000 -0500
+@@ -858,7 +858,14 @@
+ 	    || foldmethodIsDiff(wp)
+ #endif
+ 	    || foldmethodIsSyntax(wp))
++    {
++	int save_got_int = got_int;
++
++	/* reset got_int here, otherwise it won't work */
++	got_int = FALSE;
+ 	foldUpdateIEMS(wp, top, bot);
++	got_int |= save_got_int;
++    }
+ }
+ 
+ /* foldUpdateAll() {{{2 */
+diff -Naur vim71.orig/src/getchar.c vim71/src/getchar.c
+--- vim71.orig/src/getchar.c	2007-05-07 15:18:20.000000000 -0400
++++ vim71/src/getchar.c	2007-12-21 00:00:01.000000000 -0500
+@@ -253,8 +253,9 @@
+ 	return;
+     }
+     else if (buf->bh_index != 0)
+-	STRCPY(buf->bh_first.b_next->b_str,
+-				 buf->bh_first.b_next->b_str + buf->bh_index);
++	mch_memmove(buf->bh_first.b_next->b_str,
++		    buf->bh_first.b_next->b_str + buf->bh_index,
++		    STRLEN(buf->bh_first.b_next->b_str + buf->bh_index) + 1);
+     buf->bh_index = 0;
+ 
+     if (buf->bh_space >= (int)slen)
+@@ -1596,8 +1597,16 @@
+ 		continue;
+ 	    }
+ #endif
+-
+ #ifdef FEAT_GUI
++	    /* Handle focus event here, so that the caller doesn't need to
++	     * know about it.  Return K_IGNORE so that we loop once (needed if
++	     * 'lazyredraw' is set). */
++	    if (c == K_FOCUSGAINED || c == K_FOCUSLOST)
++	    {
++		ui_focus_change(c == K_FOCUSGAINED);
++		c = K_IGNORE;
++	    }
++
+ 	    /* Translate K_CSI to CSI.  The special key is only used to avoid
+ 	     * it being recognized as the start of a special key. */
+ 	    if (c == K_CSI)
+@@ -1741,6 +1750,22 @@
+ }
+ 
+ /*
++ * Like safe_vgetc(), but loop to handle K_IGNORE.
++ * Also ignore scrollbar events.
++ */
++    int
++plain_vgetc()
++{
++    int c;
++
++    do
++    {
++	c = safe_vgetc();
++    } while (c == K_IGNORE || c == K_VER_SCROLLBAR || c == K_HOR_SCROLLBAR);
++    return c;
++}
++
++/*
+  * Check if a character is available, such that vgetc() will not block.
+  * If the next character is a special character or multi-byte, the returned
+  * character is not valid!.
+diff -Naur vim71.orig/src/globals.h vim71/src/globals.h
+--- vim71.orig/src/globals.h	2007-05-07 15:44:26.000000000 -0400
++++ vim71/src/globals.h	2007-12-20 23:59:05.000000000 -0500
+@@ -301,13 +301,17 @@
+ #endif
+ 
+ #ifdef FEAT_EVAL
+-/* Garbage collection can only take place when we are sure there are no Lists
++/*
++ * Garbage collection can only take place when we are sure there are no Lists
+  * or Dictionaries being used internally.  This is flagged with
+  * "may_garbage_collect" when we are at the toplevel.
+  * "want_garbage_collect" is set by the garbagecollect() function, which means
+- * we do garbage collection before waiting for a char at the toplevel. */
++ * we do garbage collection before waiting for a char at the toplevel.
++ * "garbage_collect_at_exit" indicates garbagecollect(1) was called.
++ */
+ EXTERN int	may_garbage_collect INIT(= FALSE);
+ EXTERN int	want_garbage_collect INIT(= FALSE);
++EXTERN int	garbage_collect_at_exit INIT(= FALSE);
+ 
+ /* ID of script being sourced or was sourced to define the current function. */
+ EXTERN scid_T	current_SID INIT(= 0);
+@@ -362,7 +366,6 @@
+ EXTERN int	autocmd_busy INIT(= FALSE);	/* Is apply_autocmds() busy? */
+ EXTERN int	autocmd_no_enter INIT(= FALSE); /* *Enter autocmds disabled */
+ EXTERN int	autocmd_no_leave INIT(= FALSE); /* *Leave autocmds disabled */
+-EXTERN int	autocmd_block INIT(= 0);	/* block all autocmds */
+ EXTERN int	modified_was_set;		/* did ":set modified" */
+ EXTERN int	did_filetype INIT(= FALSE);	/* FileType event found */
+ EXTERN int	keep_filetype INIT(= FALSE);	/* value for did_filetype when
+@@ -801,7 +804,7 @@
+ EXTERN int (*mb_char2bytes) __ARGS((int c, char_u *buf)) INIT(= latin_char2bytes);
+ EXTERN int (*mb_ptr2cells) __ARGS((char_u *p)) INIT(= latin_ptr2cells);
+ EXTERN int (*mb_char2cells) __ARGS((int c)) INIT(= latin_char2cells);
+-EXTERN int (*mb_off2cells) __ARGS((unsigned off)) INIT(= latin_off2cells);
++EXTERN int (*mb_off2cells) __ARGS((unsigned off, unsigned max_off)) INIT(= latin_off2cells);
+ EXTERN int (*mb_ptr2char) __ARGS((char_u *p)) INIT(= latin_ptr2char);
+ EXTERN int (*mb_head_off) __ARGS((char_u *base, char_u *p)) INIT(= latin_head_off);
+ 
+diff -Naur vim71.orig/src/gui.c vim71/src/gui.c
+--- vim71.orig/src/gui.c	2007-05-07 15:50:55.000000000 -0400
++++ vim71/src/gui.c	2007-12-20 23:59:35.000000000 -0500
+@@ -1080,7 +1080,8 @@
+ 		cur_width = gui.char_width;
+ 	    }
+ #ifdef FEAT_MBYTE
+-	    if (has_mbyte && (*mb_off2cells)(LineOffset[gui.row] + gui.col) > 1)
++	    if (has_mbyte && (*mb_off2cells)(LineOffset[gui.row] + gui.col,
++				    LineOffset[gui.row] + screen_Columns) > 1)
+ 	    {
+ 		/* Double wide character. */
+ 		if (shape_table[idx].shape != SHAPE_VER)
+@@ -1159,7 +1160,7 @@
+ #endif
+ 
+ # if defined(FEAT_GUI_TABLINE) && (defined(FEAT_GUI_MSWIN) \
+- 	|| defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_MAC))
++	|| defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_MAC))
+     if (gui_has_tabline())
+ 	text_area_y += gui.tabline_height;
+ #endif
+@@ -4213,7 +4214,19 @@
+ #endif
+ 	    )
+     {
+-	redraw_win_later(wp, VALID);
++	int type = VALID;
++
++#ifdef FEAT_INS_EXPAND
++	if (pum_visible())
++	{
++	    type = NOT_VALID;
++	    wp->w_lines_valid = 0;
++	}
++#endif
++	/* Don't set must_redraw here, it may cause the popup menu to
++	 * disappear when losing focus after a scrollbar drag. */
++	if (wp->w_redr_type < type)
++	    wp->w_redr_type = type;
+ 	updateWindow(wp);   /* update window, status line, and cmdline */
+     }
+ 
+@@ -4518,7 +4531,18 @@
+     xim_set_focus(in_focus);
+ # endif
+ 
+-    ui_focus_change(in_focus);
++    /* Put events in the input queue only when allowed.
++     * ui_focus_change() isn't called directly, because it invokes
++     * autocommands and that must not happen asynchronously. */
++    if (!hold_gui_events)
++    {
++	char_u  bytes[3];
++
++	bytes[0] = CSI;
++	bytes[1] = KS_EXTRA;
++	bytes[2] = in_focus ? (int)KE_FOCUSGAINED : (int)KE_FOCUSLOST;
++	add_to_input_buf(bytes, 3);
++    }
+ #endif
+ }
+ 
+@@ -5117,7 +5141,7 @@
+ 		p = vim_strsave_escaped(fnames[i], (char_u *)"\\ \t\"|");
+ # endif
+ 		if (p != NULL)
+-		    add_to_input_buf(p, (int)STRLEN(p));
++		    add_to_input_buf_csi(p, (int)STRLEN(p));
+ 		vim_free(p);
+ 		vim_free(fnames[i]);
+ 	    }
+diff -Naur vim71.orig/src/gui_gtk.c vim71/src/gui_gtk.c
+--- vim71.orig/src/gui_gtk.c	2007-05-10 04:37:37.000000000 -0400
++++ vim71/src/gui_gtk.c	2007-12-20 23:57:55.000000000 -0500
+@@ -53,8 +53,8 @@
+ # ifdef bindtextdomain
+ #  undef bindtextdomain
+ # endif
+-# ifdef bindtextdomain_codeset
+-#  undef bindtextdomain_codeset
++# ifdef bind_textdomain_codeset
++#  undef bind_textdomain_codeset
+ # endif
+ # if defined(FEAT_GETTEXT) && !defined(ENABLE_NLS)
+ #  define ENABLE_NLS	/* so the texts in the dialog boxes are translated */
+@@ -1630,11 +1630,14 @@
+  */
+ /*ARGSUSED*/
+     static int
+-dlg_key_press_event(GtkWidget * widget, GdkEventKey * event, CancelData *data)
++dlg_key_press_event(GtkWidget *widget, GdkEventKey *event, CancelData *data)
+ {
+-    /* Ignore hitting Enter when there is no default button. */
+-    if (data->ignore_enter && event->keyval == GDK_Return)
++    /* Ignore hitting Enter (or Space) when there is no default button. */
++    if (data->ignore_enter && (event->keyval == GDK_Return
++						     || event->keyval == ' '))
+ 	return TRUE;
++    else    /* A different key was pressed, return to normal behavior */
++	data->ignore_enter = FALSE;
+ 
+     if (event->keyval != GDK_Escape && event->keyval != GDK_Return)
+ 	return FALSE;
+@@ -2224,6 +2227,13 @@
+ {
+     DialogInfo *di = (DialogInfo *)data;
+ 
++    /* Ignore hitting Enter (or Space) when there is no default button. */
++    if (di->ignore_enter && (event->keyval == GDK_Return
++						     || event->keyval == ' '))
++	return TRUE;
++    else    /* A different key was pressed, return to normal behavior */
++	di->ignore_enter = FALSE;
++
+     /* Close the dialog when hitting "Esc". */
+     if (event->keyval == GDK_Escape)
+     {
+diff -Naur vim71.orig/src/gui_gtk_x11.c vim71/src/gui_gtk_x11.c
+--- vim71.orig/src/gui_gtk_x11.c	2007-05-10 04:37:49.000000000 -0400
++++ vim71/src/gui_gtk_x11.c	2007-12-20 23:59:24.000000000 -0500
+@@ -36,8 +36,8 @@
+ # ifdef bindtextdomain
+ #  undef bindtextdomain
+ # endif
+-# ifdef bindtextdomain_codeset
+-#  undef bindtextdomain_codeset
++# ifdef bind_textdomain_codeset
++#  undef bind_textdomain_codeset
+ # endif
+ # if defined(FEAT_GETTEXT) && !defined(ENABLE_NLS)
+ #  define ENABLE_NLS	/* so the texts in the dialog boxes are translated */
+@@ -813,10 +813,15 @@
+     if (blink_state == BLINK_NONE)
+ 	gui_mch_start_blink();
+ 
+-    /* make sure keyboard input goes to the draw area (if this is focus for a window) */
++    /* make sure keyboard input goes to the draw area (if this is focus for a
++     * window) */
+     if (widget != gui.drawarea)
+ 	gtk_widget_grab_focus(gui.drawarea);
+ 
++    /* make sure the input buffer is read */
++    if (gtk_main_level() > 0)
++	gtk_main_quit();
++
+     return TRUE;
+ }
+ 
+@@ -829,6 +834,10 @@
+     if (blink_state != BLINK_NONE)
+ 	gui_mch_stop_blink();
+ 
++    /* make sure the input buffer is read */
++    if (gtk_main_level() > 0)
++	gtk_main_quit();
++
+     return TRUE;
+ }
+ 
+@@ -2188,8 +2197,10 @@
+     escaped_filename = vim_strsave_escaped(filename, escape_chars);
+     if (escaped_filename == NULL)
+ 	return FALSE;
+-    mksession_cmdline = g_strconcat("mksession ", (char *)escaped_filename, NULL);
++    mksession_cmdline = g_strconcat("mksession ", (char *)escaped_filename,
++									NULL);
+     vim_free(escaped_filename);
++
+     /*
+      * Use a reasonable hardcoded set of 'sessionoptions' flags to avoid
+      * unpredictable effects when the session is saved automatically.  Also,
+@@ -2199,7 +2210,7 @@
+      */
+     save_ssop_flags = ssop_flags;
+     ssop_flags = (SSOP_BLANK|SSOP_CURDIR|SSOP_FOLDS|SSOP_GLOBALS
+-		  |SSOP_HELP|SSOP_OPTIONS|SSOP_WINSIZE);
++		  |SSOP_HELP|SSOP_OPTIONS|SSOP_WINSIZE|SSOP_TABPAGES);
+ 
+     do_cmdline_cmd((char_u *)"let Save_VV_this_session = v:this_session");
+     failed = (do_cmdline_cmd((char_u *)mksession_cmdline) == FAIL);
+@@ -3212,8 +3223,9 @@
+ 	{
+ 	    if (clicked_page == 0)
+ 	    {
+-		/* Click after all tabs moves to next tab page. */
+-		if (send_tabline_event(0) && gtk_main_level() > 0)
++		/* Click after all tabs moves to next tab page.  When "x" is
++		 * small guess it's the left button. */
++		if (send_tabline_event(x < 50 ? -1 : 0) && gtk_main_level() > 0)
+ 		    gtk_main_quit();
+ 	    }
+ #ifndef HAVE_GTK2
+@@ -4032,6 +4044,8 @@
+ 	unsigned int	w, h;
+ 	int		x = 0;
+ 	int		y = 0;
++	guint		pixel_width;
++	guint		pixel_height;
+ 
+ 	mask = XParseGeometry((char *)gui.geom, &x, &y, &w, &h);
+ 
+@@ -4043,12 +4057,31 @@
+ 		p_window = h - 1;
+ 	    Rows = h;
+ 	}
++
++	pixel_width = (guint)(gui_get_base_width() + Columns * gui.char_width);
++	pixel_height = (guint)(gui_get_base_height() + Rows * gui.char_height);
++
++#ifdef HAVE_GTK2
++	pixel_width  += get_menu_tool_width();
++	pixel_height += get_menu_tool_height();
++#endif
++
+ 	if (mask & (XValue | YValue))
++	{
++	    int w, h;
++	    gui_mch_get_screen_dimensions(&w, &h);
++	    h += p_ghr + get_menu_tool_height();
++	    w += get_menu_tool_width();
++	    if (mask & XNegative)
++		x += w - pixel_width;
++	    if (mask & YNegative)
++		y += h - pixel_height;
+ #ifdef HAVE_GTK2
+ 	    gtk_window_move(GTK_WINDOW(gui.mainwin), x, y);
+ #else
+ 	    gtk_widget_set_uposition(gui.mainwin, x, y);
+ #endif
++	}
+ 	vim_free(gui.geom);
+ 	gui.geom = NULL;
+ 
+@@ -4059,14 +4092,6 @@
+ 	 */
+ 	if (gtk_socket_id != 0  &&  (mask & WidthValue || mask & HeightValue))
+ 	{
+-	    guint pixel_width = (guint)(gui_get_base_width() + Columns * gui.char_width);
+-	    guint pixel_height = (guint)(gui_get_base_height() + Rows * gui.char_height);
+-
+-#ifdef HAVE_GTK2
+-	    pixel_width  += get_menu_tool_width();
+-	    pixel_height += get_menu_tool_height();
+-#endif
+-
+ 	    update_window_manager_hints(pixel_width, pixel_height);
+ 	    init_window_hints_state = 1;
+ 	    g_timeout_add(1000, check_startup_plug_hints, NULL);
+diff -Naur vim71.orig/src/gui_xmebw.c vim71/src/gui_xmebw.c
+--- vim71.orig/src/gui_xmebw.c	2007-05-07 15:30:49.000000000 -0400
++++ vim71/src/gui_xmebw.c	2007-12-20 23:59:40.000000000 -0500
+@@ -395,11 +395,15 @@
+ 
+     /* Create the "highlight" pixmap. */
+     color[4].pixel = eb->primitive.bottom_shadow_color;
++#ifdef XpmAllocColor /* SGI doesn't have it */
+     attr.valuemask = XpmColorSymbols | XpmCloseness | XpmAllocColor;
++    attr.alloc_color = alloc_color;
++#else
++    attr.valuemask = XpmColorSymbols | XpmCloseness;
++#endif
+     attr.closeness = 65535;	/* accuracy isn't crucial */
+     attr.colorsymbols = color;
+     attr.numsymbols = XtNumber(color);
+-    attr.alloc_color = alloc_color;
+ 
+     status = XpmCreatePixmapFromData(dpy, root, data, &pix, NULL, &attr);
+     XpmFreeAttributes(&attr);
+diff -Naur vim71.orig/src/if_cscope.c vim71/src/if_cscope.c
+--- vim71.orig/src/if_cscope.c	2007-03-11 10:29:57.000000000 -0400
++++ vim71/src/if_cscope.c	2007-12-20 23:58:44.000000000 -0500
+@@ -24,11 +24,6 @@
+     /* not UNIX, must be WIN32 */
+ # include "vimio.h"
+ # include <fcntl.h>
+-# include <process.h>
+-# define STDIN_FILENO    0
+-# define STDOUT_FILENO   1
+-# define STDERR_FILENO   2
+-# define pipe(fds) _pipe(fds, 256, O_TEXT|O_NOINHERIT)
+ #endif
+ #include "if_cscope.h"
+ 
+@@ -65,7 +60,7 @@
+ static char *	    cs_parse_results __ARGS((int cnumber, char *buf, int bufsize, char **context, char **linenumber, char **search));
+ static char *	    cs_pathcomponents __ARGS((char *path));
+ static void	    cs_print_tags_priv __ARGS((char **, char **, int));
+-static int	    cs_read_prompt __ARGS((int ));
++static int	    cs_read_prompt __ARGS((int));
+ static void	    cs_release_csp __ARGS((int, int freefnpp));
+ static int	    cs_reset __ARGS((exarg_T *eap));
+ static char *	    cs_resolve_file __ARGS((int, char *));
+@@ -73,6 +68,8 @@
+ 
+ 
+ static csinfo_T	    csinfo[CSCOPE_MAX_CONNECTIONS];
++static int	    eap_arg_len;    /* length of eap->arg, set in
++				       cs_lookup_cmd() */
+ static cscmd_T	    cs_cmds[] =
+ {
+     { "add",	cs_add,
+@@ -260,14 +257,7 @@
+ 
+     if ((p = cs_manage_matches(NULL, NULL, -1, Get)) == NULL)
+ 	return TRUE;
+-
+-    if ((int)strlen(p) > size)
+-    {
+-	strncpy((char *)buf, p, size - 1);
+-	buf[size] = '\0';
+-    }
+-    else
+-	(void)strcpy((char *)buf, p);
++    vim_strncpy(buf, (char_u *)p, size - 1);
+ 
+     return FALSE;
+ } /* cs_fgets */
+@@ -386,7 +376,7 @@
+  * PRIVATE: cs_add
+  *
+  * add cscope database or a directory name (to look for cscope.out)
+- * the the cscope connection list
++ * to the cscope connection list
+  *
+  * MAXPATHL 256
+  */
+@@ -509,7 +499,7 @@
+ #if defined(UNIX)
+     else if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode))
+ #else
+-	/* substitute define S_ISREG from os_unix.h */
++	/* WIN32 - substitute define S_ISREG from os_unix.h */
+     else if (((statbuf.st_mode) & S_IFMT) == S_IFREG)
+ #endif
+     {
+@@ -722,17 +712,32 @@
+ cs_create_connection(i)
+     int i;
+ {
+-    int to_cs[2], from_cs[2], len;
+-    char *prog, *cmd, *ppath = NULL;
+-#ifndef UNIX
+-    int in_save, out_save, err_save;
+-    long_i ph;
+-# ifdef FEAT_GUI
+-    HWND activewnd = NULL;
+-    HWND consolewnd = NULL;
++#ifdef UNIX
++    int		to_cs[2], from_cs[2];
++#endif
++    int		len;
++    char	*prog, *cmd, *ppath = NULL;
++#ifdef WIN32
++    int		fd;
++    SECURITY_ATTRIBUTES sa;
++    PROCESS_INFORMATION pi;
++    STARTUPINFO si;
++    BOOL	pipe_stdin = FALSE, pipe_stdout = FALSE;
++    HANDLE	stdin_rd, stdout_rd;
++    HANDLE	stdout_wr, stdin_wr;
++    BOOL	created;
++# ifdef __BORLANDC__
++#  define OPEN_OH_ARGTYPE long
++# else
++#  if (_MSC_VER >= 1300)
++#   define OPEN_OH_ARGTYPE intptr_t
++#  else
++#   define OPEN_OH_ARGTYPE long
++#  endif
+ # endif
+ #endif
+ 
++#if defined(UNIX)
+     /*
+      * Cscope reads from to_cs[0] and writes to from_cs[1]; vi reads from
+      * from_cs[0] and writes to to_cs[1].
+@@ -753,18 +758,12 @@
+ 	return CSCOPE_FAILURE;
+     }
+ 
+-#if defined(UNIX)
+     switch (csinfo[i].pid = fork())
+     {
+     case -1:
+ 	(void)EMSG(_("E622: Could not fork for cscope"));
+ 	goto err_closing;
+     case 0:				/* child: run cscope. */
+-#else
+-	in_save = dup(STDIN_FILENO);
+-	out_save = dup(STDOUT_FILENO);
+-	err_save = dup(STDERR_FILENO);
+-#endif
+ 	if (dup2(to_cs[0], STDIN_FILENO) == -1)
+ 	    PERROR("cs_create_connection 1");
+ 	if (dup2(from_cs[1], STDOUT_FILENO) == -1)
+@@ -773,15 +772,32 @@
+ 	    PERROR("cs_create_connection 3");
+ 
+ 	/* close unused */
+-#if defined(UNIX)
+ 	(void)close(to_cs[1]);
+ 	(void)close(from_cs[0]);
+ #else
+-	/* On win32 we must close opposite ends because we are the parent */
+-	(void)close(to_cs[0]);
+-	to_cs[0] = -1;
+-	(void)close(from_cs[1]);
+-	from_cs[1] = -1;
++	/* WIN32 */
++	/* Create pipes to communicate with cscope */
++	sa.nLength = sizeof(SECURITY_ATTRIBUTES);
++	sa.bInheritHandle = TRUE;
++	sa.lpSecurityDescriptor = NULL;
++
++	if (!(pipe_stdin = CreatePipe(&stdin_rd, &stdin_wr, &sa, 0))
++		|| !(pipe_stdout = CreatePipe(&stdout_rd, &stdout_wr, &sa, 0)))
++	{
++	    (void)EMSG(_("E566: Could not create cscope pipes"));
++err_closing:
++	    if (pipe_stdin)
++	    {
++		CloseHandle(stdin_rd);
++		CloseHandle(stdin_wr);
++	    }
++	    if (pipe_stdout)
++	    {
++		CloseHandle(stdout_rd);
++		CloseHandle(stdout_wr);
++	    }
++	    return CSCOPE_FAILURE;
++	}
+ #endif
+ 	/* expand the cscope exec for env var's */
+ 	if ((prog = (char *)alloc(MAXPATHL + 1)) == NULL)
+@@ -789,6 +805,7 @@
+ #ifdef UNIX
+ 	    return CSCOPE_FAILURE;
+ #else
++	    /* WIN32 */
+ 	    goto err_closing;
+ #endif
+ 	}
+@@ -805,6 +822,7 @@
+ #ifdef UNIX
+ 		return CSCOPE_FAILURE;
+ #else
++		/* WIN32 */
+ 		goto err_closing;
+ #endif
+ 	    }
+@@ -823,6 +841,7 @@
+ #ifdef UNIX
+ 	    return CSCOPE_FAILURE;
+ #else
++	    /* WIN32 */
+ 	    goto err_closing;
+ #endif
+ 	}
+@@ -831,6 +850,7 @@
+ #if defined(UNIX)
+ 	(void)sprintf(cmd, "exec %s -dl -f %s", prog, csinfo[i].fname);
+ #else
++	/* WIN32 */
+ 	(void)sprintf(cmd, "%s -dl -f %s", prog, csinfo[i].fname);
+ #endif
+ 	if (csinfo[i].ppath != NULL)
+@@ -856,60 +876,6 @@
+ 	exit(127);
+ 	/* NOTREACHED */
+     default:	/* parent. */
+-#else
+-# ifdef FEAT_GUI
+-	activewnd = GetForegroundWindow(); /* on win9x cscope steals focus */
+-	/* Dirty hack to hide annoying console window */
+-	if (AllocConsole())
+-	{
+-	    char *title;
+-	    title = (char *)alloc(1024);
+-	    if (title == NULL)
+-		FreeConsole();
+-	    else
+-	    {
+-		GetConsoleTitle(title, 1024); /* save for future restore */
+-		SetConsoleTitle(
+-		    "GVIMCS{5499421B-CBEF-45b0-85EF-38167FDEA5C5}GVIMCS");
+-		Sleep(40); /* as stated in MS KB we must wait 40 ms */
+-		consolewnd = FindWindow(NULL,
+-			"GVIMCS{5499421B-CBEF-45b0-85EF-38167FDEA5C5}GVIMCS");
+-		if (consolewnd != NULL)
+-		    ShowWindow(consolewnd, SW_HIDE);
+-		SetConsoleTitle(title);
+-		vim_free(title);
+-	    }
+-	}
+-# endif
+-	/* May be use &shell, &shellquote etc */
+-# ifdef __BORLANDC__
+-	/* BCC 5.5 uses a different function name for spawnlp */
+-	ph = (long_i)spawnlp(P_NOWAIT, prog, cmd, NULL);
+-# else
+-	ph = (long_i)_spawnlp(_P_NOWAIT, prog, cmd, NULL);
+-# endif
+-	vim_free(prog);
+-	vim_free(cmd);
+-# ifdef FEAT_GUI
+-	/* Dirty hack part two */
+-	if (activewnd != NULL)
+-	    /* restoring focus */
+-	    SetForegroundWindow(activewnd);
+-	if (consolewnd != NULL)
+-	    FreeConsole();
+-
+-# endif
+-	if (ph == -1)
+-	{
+-	    PERROR(_("cs_create_connection exec failed"));
+-	    (void)EMSG(_("E623: Could not spawn cscope process"));
+-	    goto err_closing;
+-	}
+-	/* else */
+-	csinfo[i].pid = 0;
+-	csinfo[i].hProc = (HANDLE)ph;
+-
+-#endif /* !UNIX */
+ 	/*
+ 	 * Save the file descriptors for later duplication, and
+ 	 * reopen as streams.
+@@ -919,22 +885,54 @@
+ 	if ((csinfo[i].fr_fp = fdopen(from_cs[0], "r")) == NULL)
+ 	    PERROR(_("cs_create_connection: fdopen for fr_fp failed"));
+ 
+-#if defined(UNIX)
+ 	/* close unused */
+ 	(void)close(to_cs[0]);
+ 	(void)close(from_cs[1]);
+ 
+ 	break;
+     }
++
+ #else
+-	/* restore stdhandles */
+-    dup2(in_save, STDIN_FILENO);
+-    dup2(out_save, STDOUT_FILENO);
+-    dup2(err_save, STDERR_FILENO);
+-    close(in_save);
+-    close(out_save);
+-    close(err_save);
+-#endif
++    /* WIN32 */
++    /* Create a new process to run cscope and use pipes to talk with it */
++    GetStartupInfo(&si);
++    si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
++    si.wShowWindow = SW_HIDE;  /* Hide child application window */
++    si.hStdOutput = stdout_wr;
++    si.hStdError  = stdout_wr;
++    si.hStdInput  = stdin_rd;
++    created = CreateProcess(NULL, cmd, NULL, NULL, TRUE, CREATE_NEW_CONSOLE,
++							NULL, NULL, &si, &pi);
++    vim_free(prog);
++    vim_free(cmd);
++
++    if (!created)
++    {
++	PERROR(_("cs_create_connection exec failed"));
++	(void)EMSG(_("E623: Could not spawn cscope process"));
++	goto err_closing;
++    }
++    /* else */
++    csinfo[i].pid = pi.dwProcessId;
++    csinfo[i].hProc = pi.hProcess;
++    CloseHandle(pi.hThread);
++
++    /* TODO - tidy up after failure to create files on pipe handles. */
++    if (((fd = _open_osfhandle((OPEN_OH_ARGTYPE)stdin_wr,
++						      _O_TEXT|_O_APPEND)) < 0)
++	    || ((csinfo[i].to_fp = _fdopen(fd, "w")) == NULL))
++	PERROR(_("cs_create_connection: fdopen for to_fp failed"));
++    if (((fd = _open_osfhandle((OPEN_OH_ARGTYPE)stdout_rd,
++						      _O_TEXT|_O_RDONLY)) < 0)
++	    || ((csinfo[i].fr_fp = _fdopen(fd, "r")) == NULL))
++	PERROR(_("cs_create_connection: fdopen for fr_fp failed"));
++
++    /* Close handles for file descriptors inherited by the cscope process */
++    CloseHandle(stdin_rd);
++    CloseHandle(stdout_wr);
++
++#endif /* !UNIX */
++
+     return CSCOPE_SUCCESS;
+ } /* cs_create_connection */
+ 
+@@ -966,7 +964,7 @@
+     }
+ 
+     pat = opt + strlen(opt) + 1;
+-    if (pat == NULL || (pat != NULL && pat[0] == '\0'))
++    if (pat >= (char *)eap->arg + eap_arg_len)
+     {
+ 	cs_usage_msg(Find);
+ 	return FALSE;
+@@ -1317,7 +1315,7 @@
+ #else
+ 	    /* compare pathnames first */
+ 	    && ((fullpathcmp(csinfo[j].fname, fname, FALSE) & FPC_SAME)
+-		/* if not Windows 9x, test index file atributes too */
++		/* if not Windows 9x, test index file attributes too */
+ 		|| (!mch_windows95()
+ 		    && csinfo[j].nVolume == bhfi.dwVolumeSerialNumber
+ 		    && csinfo[j].nIndexHigh == bhfi.nFileIndexHigh
+@@ -1401,6 +1399,9 @@
+     if (eap->arg == NULL)
+ 	return NULL;
+ 
++    /* Store length of eap->arg before it gets modified by strtok(). */
++    eap_arg_len = STRLEN(eap->arg);
++
+     if ((stok = strtok((char *)(eap->arg), (const char *)" ")) == NULL)
+ 	return NULL;
+ 
+@@ -2099,8 +2100,8 @@
+ /*
+  * PRIVATE: cs_release_csp
+  *
+- * does the actual free'ing for the cs ptr with an optional flag of whether
+- * or not to free the filename.  called by cs_kill and cs_reset.
++ * Does the actual free'ing for the cs ptr with an optional flag of whether
++ * or not to free the filename.  Called by cs_kill and cs_reset.
+  */
+     static void
+ cs_release_csp(i, freefnpp)
+@@ -2118,10 +2119,13 @@
+ 	(void)fputs("q\n", csinfo[i].to_fp);
+ 	(void)fflush(csinfo[i].to_fp);
+     }
+-    /* give cscope chance to exit normally */
+-    if (csinfo[i].hProc != NULL
+-	    && WaitForSingleObject(csinfo[i].hProc, 1000) == WAIT_TIMEOUT)
+-	TerminateProcess(csinfo[i].hProc, 0);
++    if (csinfo[i].hProc != NULL)
++    {
++	/* Give cscope a chance to exit normally */
++	if (WaitForSingleObject(csinfo[i].hProc, 1000) == WAIT_TIMEOUT)
++	    TerminateProcess(csinfo[i].hProc, 0);
++	CloseHandle(csinfo[i].hProc);
++    }
+ #endif
+ 
+     if (csinfo[i].fr_fp != NULL)
+@@ -2195,7 +2199,7 @@
+ 	    cs_add_common(dblist[i], pplist[i], fllist[i]);
+ 	    if (p_csverbose)
+ 	    {
+-		/* dont' use smsg_attr because want to display
++		/* don't use smsg_attr() because we want to display the
+ 		 * connection number in the same line as
+ 		 * "Added cscope database..."
+ 		 */
+@@ -2304,6 +2308,21 @@
+     return CSCOPE_SUCCESS;
+ } /* cs_show */
+ 
++
++/*
++ * PUBLIC: cs_end
++ *
++ * Only called when VIM exits to quit any cscope sessions.
++ */
++    void
++cs_end()
++{
++    int i;
++
++    for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++)
++	cs_release_csp(i, TRUE);
++}
++
+ #endif	/* FEAT_CSCOPE */
+ 
+ /* the end */
+diff -Naur vim71.orig/src/if_cscope.h vim71/src/if_cscope.h
+--- vim71.orig/src/if_cscope.h	2005-06-30 13:14:22.000000000 -0400
++++ vim71/src/if_cscope.h	2007-12-20 23:58:34.000000000 -0500
+@@ -72,7 +72,7 @@
+     ino_t	    st_ino;	/* inode number of cscope db */
+ #else
+ # if defined(WIN32)
+-    int	    pid;	/* Can't get pid so set it to 0 ;) */
++    DWORD	    pid;	/* PID of the connected cscope process. */
+     HANDLE	    hProc;	/* cscope process handle */
+     DWORD	    nVolume;	/* Volume serial number, instead of st_dev */
+     DWORD	    nIndexHigh;	/* st_ino has no meaning in the Windows */
+diff -Naur vim71.orig/src/if_mzsch.c vim71/src/if_mzsch.c
+--- vim71.orig/src/if_mzsch.c	2007-05-12 07:13:47.000000000 -0400
++++ vim71/src/if_mzsch.c	2007-12-20 23:56:55.000000000 -0500
+@@ -308,6 +308,8 @@
+ static Scheme_Config *(*dll_scheme_current_config)(void);
+ static Scheme_Object *(*dll_scheme_char_string_to_byte_string)
+     (Scheme_Object *s);
++static Scheme_Object *(*dll_scheme_char_string_to_path)
++    (Scheme_Object *s);
+ # endif
+ 
+ /* arrays are imported directly */
+@@ -398,6 +400,8 @@
+ #  define scheme_current_config dll_scheme_current_config
+ #  define scheme_char_string_to_byte_string \
+     dll_scheme_char_string_to_byte_string
++#  define scheme_char_string_to_path \
++    dll_scheme_char_string_to_path
+ # endif
+ 
+ typedef struct
+@@ -498,6 +502,8 @@
+     {"scheme_current_config", (void **)&dll_scheme_current_config},
+     {"scheme_char_string_to_byte_string",
+ 	(void **)&dll_scheme_char_string_to_byte_string},
++    {"scheme_char_string_to_path",
++	(void **)&dll_scheme_char_string_to_path},
+ # endif
+     {NULL, NULL}};
+ 
+@@ -773,7 +779,14 @@
+ #ifdef MZSCHEME_COLLECTS
+     /* setup 'current-library-collection-paths' parameter */
+     scheme_set_param(scheme_config, MZCONFIG_COLLECTION_PATHS,
+-	    scheme_make_pair(scheme_make_string(MZSCHEME_COLLECTS),
++	    scheme_make_pair(
++# if MZSCHEME_VERSION_MAJOR >= 299
++		scheme_char_string_to_path(
++		    scheme_byte_string_to_char_string(
++			scheme_make_byte_string(MZSCHEME_COLLECTS))),
++# else
++		scheme_make_string(MZSCHEME_COLLECTS),
++# endif
+ 		scheme_null));
+ #endif
+ #ifdef HAVE_SANDBOX
+diff -Naur vim71.orig/src/if_perl.xs vim71/src/if_perl.xs
+--- vim71.orig/src/if_perl.xs	2006-08-16 08:45:15.000000000 -0400
++++ vim71/src/if_perl.xs	2007-12-20 23:59:21.000000000 -0500
+@@ -40,6 +40,28 @@
+ #    define PERL_SUBVERSION SUBVERSION
+ #endif
+ 
++/*
++ * Quoting Jan Dubois of Active State:
++ *    ActivePerl build 822 still identifies itself as 5.8.8 but already
++ *    contains many of the changes from the upcoming Perl 5.8.9 release.
++ *
++ * The changes include addition of two symbols (Perl_sv_2iv_flags,
++ * Perl_newXS_flags) not present in earlier releases.
++ *
++ * Jan Dubois suggested the following guarding scheme.
++ *
++ * Active State defined ACTIVEPERL_VERSION as a string in versions before
++ * 5.8.8; and so the comparison to 822 below needs to be guarded.
++ */
++#if (PERL_REVISION == 5) && (PERL_VERSION == 8) && (PERL_SUBVERSION >= 8)
++# if (ACTIVEPERL_VERSION >= 822) || (PERL_SUBVERSION >= 9)
++#  define PERL589_OR_LATER
++# endif
++#endif
++#if (PERL_REVISION == 5) && (PERL_VERSION >= 9)
++# define PERL589_OR_LATER
++#endif
++
+ #ifndef pTHX
+ #    define pTHX void
+ #    define pTHX_
+@@ -109,6 +131,10 @@
+ # else
+ #  define Perl_sv_catpvn dll_Perl_sv_catpvn
+ # endif
++#ifdef PERL589_OR_LATER
++#  define Perl_sv_2iv_flags dll_Perl_sv_2iv_flags
++#  define Perl_newXS_flags dll_Perl_newXS_flags
++#endif
+ # define Perl_sv_free dll_Perl_sv_free
+ # define Perl_sv_isa dll_Perl_sv_isa
+ # define Perl_sv_magic dll_Perl_sv_magic
+@@ -192,6 +218,10 @@
+ #else
+ static void (*Perl_sv_catpvn)(pTHX_ SV*, const char*, STRLEN);
+ #endif
++#ifdef PERL589_OR_LATER
++static IV (*Perl_sv_2iv_flags)(pTHX_ SV* sv, I32 flags);
++static CV * (*Perl_newXS_flags)(pTHX_ const char *name, XSUBADDR_t subaddr, const char *const filename, const char *const proto, U32 flags);
++#endif
+ static void (*Perl_sv_free)(pTHX_ SV*);
+ static int (*Perl_sv_isa)(pTHX_ SV*, const char*);
+ static void (*Perl_sv_magic)(pTHX_ SV*, SV*, int, const char*, I32);
+@@ -267,6 +297,10 @@
+ #else
+     {"Perl_sv_2pv", (PERL_PROC*)&Perl_sv_2pv},
+ #endif
++#ifdef PERL589_OR_LATER
++    {"Perl_sv_2iv_flags", (PERL_PROC*)&Perl_sv_2iv_flags},
++    {"Perl_newXS_flags", (PERL_PROC*)&Perl_newXS_flags},
++#endif
+     {"Perl_sv_bless", (PERL_PROC*)&Perl_sv_bless},
+ #if (PERL_REVISION == 5) && (PERL_VERSION >= 8)
+     {"Perl_sv_catpvn_flags", (PERL_PROC*)&Perl_sv_catpvn_flags},
+@@ -411,13 +445,13 @@
+     char *next;
+     char *token = (char *)s;
+ 
+-    while ((next = strchr(token, '\n')))
++    while ((next = strchr(token, '\n')) && !got_int)
+     {
+ 	*next++ = '\0';			/* replace \n with \0 */
+ 	msg_attr((char_u *)token, attr);
+ 	token = next;
+     }
+-    if (*token)
++    if (*token && !got_int)
+ 	msg_attr((char_u *)token, attr);
+ }
+ 
+diff -Naur vim71.orig/src/if_ruby.c vim71/src/if_ruby.c
+--- vim71.orig/src/if_ruby.c	2007-05-12 05:54:12.000000000 -0400
++++ vim71/src/if_ruby.c	2007-12-20 23:58:35.000000000 -0500
+@@ -789,7 +789,7 @@
+     return get_buffer_line(curbuf, curwin->w_cursor.lnum);
+ }
+ 
+-static VALUE set_current_line(VALUE str)
++static VALUE set_current_line(VALUE self, VALUE str)
+ {
+     return set_buffer_line(curbuf, curwin->w_cursor.lnum, str);
+ }
+diff -Naur vim71.orig/src/keymap.h vim71/src/keymap.h
+--- vim71.orig/src/keymap.h	2006-08-22 07:38:38.000000000 -0400
++++ vim71/src/keymap.h	2007-12-20 23:58:27.000000000 -0500
+@@ -254,6 +254,8 @@
+     , KE_DROP		/* DnD data is available */
+     , KE_CURSORHOLD	/* CursorHold event */
+     , KE_NOP		/* doesn't do something */
++    , KE_FOCUSGAINED	/* focus gained */
++    , KE_FOCUSLOST	/* focus lost */
+ };
+ 
+ /*
+@@ -445,6 +447,8 @@
+ #define K_CMDWIN	TERMCAP2KEY(KS_EXTRA, KE_CMDWIN)
+ 
+ #define K_DROP		TERMCAP2KEY(KS_EXTRA, KE_DROP)
++#define K_FOCUSGAINED	TERMCAP2KEY(KS_EXTRA, KE_FOCUSGAINED)
++#define K_FOCUSLOST	TERMCAP2KEY(KS_EXTRA, KE_FOCUSLOST)
+ 
+ #define K_CURSORHOLD	TERMCAP2KEY(KS_EXTRA, KE_CURSORHOLD)
+ 
+diff -Naur vim71.orig/src/macros.h vim71/src/macros.h
+--- vim71.orig/src/macros.h	2007-05-07 15:38:22.000000000 -0400
++++ vim71/src/macros.h	2007-12-20 23:58:07.000000000 -0500
+@@ -54,10 +54,12 @@
+ 
+ /*
+  * toupper() and tolower() that use the current locale.
+- * On some systems toupper()/tolower() only work on lower/uppercase characters
++ * On some systems toupper()/tolower() only work on lower/uppercase
++ * characters, first use islower() or isupper() then.
+  * Careful: Only call TOUPPER_LOC() and TOLOWER_LOC() with a character in the
+  * range 0 - 255.  toupper()/tolower() on some systems can't handle others.
+- * Note: for UTF-8 use utf_toupper() and utf_tolower().
++ * Note: It is often better to use MB_TOLOWER() and MB_TOUPPER(), because many
++ * toupper() and tolower() implementations only work for ASCII.
+  */
+ #ifdef MSWIN
+ #  define TOUPPER_LOC(c)	toupper_tab[(c) & 255]
+diff -Naur vim71.orig/src/main.aap vim71/src/main.aap
+--- vim71.orig/src/main.aap	2007-05-07 15:46:43.000000000 -0400
++++ vim71/src/main.aap	2007-12-20 23:59:01.000000000 -0500
+@@ -56,9 +56,16 @@
+     config {virtual} auto/config.h auto/config.aap :
+                          auto/configure.aap configure.aap
+                          config.arg config.h.in config.aap.in
++        # Use "uname -a" to detect the architecture of the system.
++        @ok, uname = redir_system('uname -a', 0)
++        @if string.find(uname, "i386") >= 0:
++        @   arch = "i386"
++        @else:
++        @   arch = "ppc"
++        :print Building for $arch system
+         :sys CONFIG_STATUS=auto/config.status
+                 ./configure.aap `file2string("config.arg")`
+-                    --with-mac-arch=ppc
++                    --with-mac-arch=$arch
+                     --cache-file=auto/config.cache
+ 
+     # Configure arguments: create an empty "config.arg" file when its missing
+@@ -1167,7 +1174,7 @@
+         :symlink `os.getcwd()`/../runtime $RESDIR/vim/runtime
+ # TODO: Create the vimtutor application.
+ 
+-gui_bundle {virtual}: $(RESDIR) bundle-dir bundle-executable bundle-info
++gui_bundle {virtual}: $(RESDIR) bundle-dir bundle-executable bundle-info \
+                         bundle-resource bundle-language
+ 
+ bundle-dir {virtual}: $(APPDIR)/Contents $(VIMTARGET)
+@@ -1187,7 +1194,7 @@
+         :sys m4 $(M4FLAGSX) infplist.xml > $(APPDIR)/Contents/Info.plist
+ 
+ bundle-resource {virtual}: bundle-dir bundle-rsrc
+-    :copy {force} $(RSRC_DIR)/*.icns $(RESDIR)
++        :copy {force} $(RSRC_DIR)/*.icns $(RESDIR)
+ 
+ ### Classic resources
+ # Resource fork (in the form of a .rsrc file) for Classic Vim (Mac OS 9)
+diff -Naur vim71.orig/src/main.c vim71/src/main.c
+--- vim71.orig/src/main.c	2007-05-07 15:38:44.000000000 -0400
++++ vim71/src/main.c	2007-12-20 23:58:59.000000000 -0500
+@@ -954,7 +954,8 @@
+     int		cmdwin;	    /* TRUE when working in the command-line window */
+     int		noexmode;   /* TRUE when return on entering Ex mode */
+ {
+-    oparg_T	oa;	/* operator arguments */
++    oparg_T	oa;				/* operator arguments */
++    int		previous_got_int = FALSE;	/* "got_int" was TRUE */
+ 
+ #if defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)
+     /* Setup to catch a terminating error from the X server.  Just ignore
+@@ -1015,12 +1016,32 @@
+ 		need_fileinfo = FALSE;
+ 	    }
+ 	}
+-	if (got_int && !global_busy)
++
++	/* Reset "got_int" now that we got back to the main loop.  Except when
++	 * inside a ":g/pat/cmd" command, then the "got_int" needs to abort
++	 * the ":g" command.
++	 * For ":g/pat/vi" we reset "got_int" when used once.  When used
++	 * a second time we go back to Ex mode and abort the ":g" command. */
++	if (got_int)
+ 	{
+-	    if (!quit_more)
+-		(void)vgetc();		/* flush all buffers */
+-	    got_int = FALSE;
++	    if (noexmode && global_busy && !exmode_active && previous_got_int)
++	    {
++		/* Typed two CTRL-C in a row: go back to ex mode as if "Q" was
++		 * used and keep "got_int" set, so that it aborts ":g". */
++		exmode_active = EXMODE_NORMAL;
++		State = NORMAL;
++	    }
++	    else if (!global_busy || !exmode_active)
++	    {
++		if (!quit_more)
++		    (void)vgetc();		/* flush all buffers */
++		got_int = FALSE;
++	    }
++	    previous_got_int = TRUE;
+ 	}
++	else
++	    previous_got_int = FALSE;
++
+ 	if (!exmode_active)
+ 	    msg_scroll = FALSE;
+ 	quit_more = FALSE;
+@@ -1309,6 +1330,13 @@
+ #ifdef FEAT_NETBEANS_INTG
+     netbeans_end();
+ #endif
++#ifdef FEAT_CSCOPE
++    cs_end();
++#endif
++#ifdef FEAT_EVAL
++    if (garbage_collect_at_exit)
++	garbage_collect();
++#endif
+ 
+     mch_exit(exitval);
+ }
+@@ -1360,8 +1388,7 @@
+ 	p = vim_getenv((char_u *)"VIMRUNTIME", &mustfree);
+ 	if (p != NULL && *p != NUL)
+ 	{
+-	    STRCPY(NameBuff, p);
+-	    STRCAT(NameBuff, "/lang");
++	    vim_snprintf((char *)NameBuff, MAXPATHL, "%s/lang", p);
+ 	    bindtextdomain(VIMPACKAGE, (char *)NameBuff);
+ 	}
+ 	if (mustfree)
+@@ -3632,7 +3659,13 @@
+ 	mainerr_arg_missing((char_u *)filev[-1]);
+     if (mch_dirname(cwd, MAXPATHL) != OK)
+ 	return NULL;
+-    if ((p = vim_strsave_escaped_ext(cwd, PATH_ESC_CHARS, '\\', TRUE)) == NULL)
++    if ((p = vim_strsave_escaped_ext(cwd,
++#ifdef BACKSLASH_IN_FILENAME
++		    "",  /* rem_backslash() will tell what chars to escape */
++#else
++		    PATH_ESC_CHARS,
++#endif
++		    '\\', TRUE)) == NULL)
+ 	return NULL;
+     ga_init2(&ga, 1, 100);
+     ga_concat(&ga, (char_u *)"<C-\\><C-N>:cd ");
+diff -Naur vim71.orig/src/mbyte.c vim71/src/mbyte.c
+--- vim71.orig/src/mbyte.c	2007-05-07 15:47:09.000000000 -0400
++++ vim71/src/mbyte.c	2007-12-20 23:58:25.000000000 -0500
+@@ -1310,20 +1310,26 @@
+ /*
+  * mb_off2cells() function pointer.
+  * Return number of display cells for char at ScreenLines[off].
+- * Caller must make sure "off" and "off + 1" are valid!
++ * We make sure that the offset used is less than "max_off".
+  */
+ /*ARGSUSED*/
+     int
+-latin_off2cells(off)
++latin_off2cells(off, max_off)
+     unsigned	off;
++    unsigned	max_off;
+ {
+     return 1;
+ }
+ 
+     int
+-dbcs_off2cells(off)
++dbcs_off2cells(off, max_off)
+     unsigned	off;
++    unsigned	max_off;
+ {
++    /* never check beyond end of the line */
++    if (off >= max_off)
++	return 1;
++
+     /* Number of cells is equal to number of bytes, except for euc-jp when
+      * the first byte is 0x8e. */
+     if (enc_dbcs == DBCS_JPNU && ScreenLines[off] == 0x8e)
+@@ -1332,10 +1338,11 @@
+ }
+ 
+     int
+-utf_off2cells(off)
++utf_off2cells(off, max_off)
+     unsigned	off;
++    unsigned	max_off;
+ {
+-    return ScreenLines[off + 1] == 0 ? 2 : 1;
++    return (off + 1 < max_off && ScreenLines[off + 1] == 0) ? 2 : 1;
+ }
+ 
+ /*
+@@ -2320,7 +2327,7 @@
+ 		/* Single byte: first check normally, then with ignore case. */
+ 		if (s1[i] != s2[i])
+ 		{
+-		    cdiff = TOLOWER_LOC(s1[i]) - TOLOWER_LOC(s2[i]);
++		    cdiff = MB_TOLOWER(s1[i]) - MB_TOLOWER(s2[i]);
+ 		    if (cdiff != 0)
+ 			return cdiff;
+ 		}
+@@ -2899,12 +2906,8 @@
+     if (composing_hangul)
+ 	return TRUE;
+ #endif
+-    if (enc_dbcs != 0)
+-	return dbcs_off2cells(LineOffset[row] + col) > 1;
+-    if (enc_utf8)
+-	return (col + 1 < Columns
+-		&& ScreenLines[LineOffset[row] + col + 1] == 0);
+-    return FALSE;
++    return (*mb_off2cells)(LineOffset[row] + col,
++					LineOffset[row] + screen_Columns) > 1;
+ }
+ 
+ # if defined(FEAT_CLIPBOARD) || defined(FEAT_GUI) || defined(FEAT_RIGHTLEFT) \
+diff -Naur vim71.orig/src/message.c vim71/src/message.c
+--- vim71.orig/src/message.c	2007-05-07 15:31:59.000000000 -0400
++++ vim71/src/message.c	2007-12-20 23:59:49.000000000 -0500
+@@ -828,7 +828,7 @@
+ 		_("Messages maintainer: Bram Moolenaar <Bram@vim.org>"),
+ 		hl_attr(HLF_T));
+ 
+-    for (p = first_msg_hist; p != NULL; p = p->next)
++    for (p = first_msg_hist; p != NULL && !got_int; p = p->next)
+ 	if (p->msg != NULL)
+ 	    msg_attr(p->msg, p->attr);
+ 
+@@ -944,6 +944,7 @@
+ 		c = K_IGNORE;
+ 	    }
+ #endif
++
+ 	    /*
+ 	     * Allow scrolling back in the messages.
+ 	     * Also accept scroll-down commands when messages fill the screen,
+@@ -1840,9 +1841,10 @@
+     char_u	*sb_str = str;
+     int		sb_col = msg_col;
+     int		wrap;
++    int		did_last_char;
+ 
+     did_wait_return = FALSE;
+-    while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen))
++    while ((maxlen < 0 || (int)(s - str) < maxlen) && *s != NUL)
+     {
+ 	/*
+ 	 * We are at the end of the screen line when:
+@@ -1878,7 +1880,7 @@
+ 		/* output postponed text */
+ 		t_puts(&t_col, t_s, s, attr);
+ 
+-	    /* When no more prompt an no more room, truncate here */
++	    /* When no more prompt and no more room, truncate here */
+ 	    if (msg_no_more && lines_left == 0)
+ 		break;
+ 
+@@ -1909,7 +1911,10 @@
+ 		else
+ #endif
+ 		    msg_screen_putchar(*s++, attr);
++		did_last_char = TRUE;
+ 	    }
++	    else
++		did_last_char = FALSE;
+ 
+ 	    if (p_more)
+ 		/* store text for scrolling back */
+@@ -1927,7 +1932,8 @@
+ 	     * If screen is completely filled and 'more' is set then wait
+ 	     * for a character.
+ 	     */
+-	    --lines_left;
++	    if (lines_left > 0)
++		--lines_left;
+ 	    if (p_more && lines_left == 0 && State != HITRETURN
+ 					    && !msg_no_more && !exmode_active)
+ 	    {
+@@ -1943,11 +1949,7 @@
+ 
+ 	    /* When we displayed a char in last column need to check if there
+ 	     * is still more. */
+-	    if (*s >= ' '
+-#ifdef FEAT_RIGHTLEFT
+-		    && !cmdmsg_rl
+-#endif
+-	       )
++	    if (did_last_char)
+ 		continue;
+ 	}
+ 
+@@ -2234,7 +2236,7 @@
+ {
+     msgchunk_T	*mp;
+ 
+-    /* Only show somethign if there is more than one line, otherwise it looks
++    /* Only show something if there is more than one line, otherwise it looks
+      * weird, typing a command without output results in one line. */
+     mp = msg_sb_start(last_msgchunk);
+     if (mp == NULL || mp->sb_prev == NULL)
+@@ -2622,7 +2624,7 @@
+ 		}
+ 	    }
+ 
+-	    if (scroll < 0 || (scroll == 0 && mp_last != NULL))
++	    if (scroll <= 0)
+ 	    {
+ 		/* displayed the requested text, more prompt again */
+ 		screen_fill((int)Rows - 1, (int)Rows, 0,
+@@ -2848,6 +2850,15 @@
+     }
+     else if (State == HITRETURN || State == SETWSIZE)
+     {
++	if (msg_row == Rows - 1)
++	{
++	    /* Avoid drawing the "hit-enter" prompt below the previous one,
++	     * overwrite it.  Esp. useful when regaining focus and a
++	     * FocusGained autocmd exists but didn't draw anything. */
++	    msg_didout = FALSE;
++	    msg_col = 0;
++	    msg_clr_eos();
++	}
+ 	hit_return_msg();
+ 	msg_row = Rows - 1;
+     }
+@@ -3456,11 +3467,11 @@
+ 		    /* advance to next hotkey and set default hotkey */
+ #ifdef FEAT_MBYTE
+ 		    if (has_mbyte)
+-			hotkp += (*mb_ptr2len)(hotkp);
++			hotkp += STRLEN(hotkp);
+ 		    else
+ #endif
+ 			++hotkp;
+-		    (void)copy_char(r + 1, hotkp, TRUE);
++		    hotkp[copy_char(r + 1, hotkp, TRUE)] = NUL;
+ 		    if (dfltbutton)
+ 			--dfltbutton;
+ 
+@@ -3493,7 +3504,7 @@
+ 			*msgp++ = (dfltbutton == 1) ? ']' : ')';
+ 
+ 			/* redefine hotkey */
+-			(void)copy_char(r, hotkp, TRUE);
++			hotkp[copy_char(r, hotkp, TRUE)] = NUL;
+ 		    }
+ 		}
+ 		else
+@@ -3519,8 +3530,6 @@
+ 	    *msgp++ = ':';
+ 	    *msgp++ = ' ';
+ 	    *msgp = NUL;
+-	    mb_ptr_adv(hotkp);
+-	    *hotkp = NUL;
+ 	}
+ 	else
+ 	{
+@@ -3555,8 +3564,9 @@
+ 	    msgp = confirm_msg + 1 + STRLEN(message);
+ 	    hotkp = hotk;
+ 
+-	    /* define first default hotkey */
+-	    (void)copy_char(buttons, hotkp, TRUE);
++	    /* Define first default hotkey.  Keep the hotkey string NUL
++	     * terminated to avoid reading past the end. */
++	    hotkp[copy_char(buttons, hotkp, TRUE)] = NUL;
+ 
+ 	    /* Remember where the choices start, displaying starts here when
+ 	     * "hotkp" typed at the more prompt. */
+diff -Naur vim71.orig/src/misc1.c vim71/src/misc1.c
+--- vim71.orig/src/misc1.c	2007-05-07 15:49:03.000000000 -0400
++++ vim71/src/misc1.c	2007-12-20 23:59:02.000000000 -0500
+@@ -90,7 +90,7 @@
+  */
+     int
+ set_indent(size, flags)
+-    int		size;
++    int		size;		    /* measured in spaces */
+     int		flags;
+ {
+     char_u	*p;
+@@ -98,12 +98,14 @@
+     char_u	*oldline;
+     char_u	*s;
+     int		todo;
+-    int		ind_len;
++    int		ind_len;	    /* measured in characters */
+     int		line_len;
+     int		doit = FALSE;
+-    int		ind_done;
++    int		ind_done = 0;	    /* measured in spaces */
+     int		tab_pad;
+     int		retval = FALSE;
++    int		orig_char_len = -1; /* number of initial whitespace chars when
++				       'et' and 'pi' are both set */
+ 
+     /*
+      * First check if there is anything to do and compute the number of
+@@ -116,8 +118,10 @@
+     /* Calculate the buffer size for the new indent, and check to see if it
+      * isn't already set */
+ 
+-    /* if 'expandtab' isn't set: use TABs */
+-    if (!curbuf->b_p_et)
++    /* if 'expandtab' isn't set: use TABs; if both 'expandtab' and
++     * 'preserveindent' are set count the number of characters at the
++     * beginning of the line to be copied */
++    if (!curbuf->b_p_et || (!(flags & SIN_INSERT) && curbuf->b_p_pi))
+     {
+ 	/* If 'preserveindent' is set then reuse as much as possible of
+ 	 * the existing indent structure for the new indent */
+@@ -148,9 +152,14 @@
+ 		++p;
+ 	    }
+ 
++	    /* Set initial number of whitespace chars to copy if we are
++	     * preserving indent but expandtab is set */
++	    if (curbuf->b_p_et)
++		orig_char_len = ind_len;
++
+ 	    /* Fill to next tabstop with a tab, if possible */
+ 	    tab_pad = (int)curbuf->b_p_ts - (ind_done % (int)curbuf->b_p_ts);
+-	    if (todo >= tab_pad)
++	    if (todo >= tab_pad && orig_char_len == -1)
+ 	    {
+ 		doit = TRUE;
+ 		todo -= tab_pad;
+@@ -193,13 +202,42 @@
+     else
+ 	p = skipwhite(p);
+     line_len = (int)STRLEN(p) + 1;
+-    newline = alloc(ind_len + line_len);
+-    if (newline == NULL)
+-	return FALSE;
++
++    /* If 'preserveindent' and 'expandtab' are both set keep the original
++     * characters and allocate accordingly.  We will fill the rest with spaces
++     * after the if (!curbuf->b_p_et) below. */
++    if (orig_char_len != -1)
++    {
++	newline = alloc(orig_char_len + size - ind_done + line_len);
++	if (newline == NULL)
++	    return FALSE;
++	todo = size - ind_done;
++	ind_len = orig_char_len + todo;    /* Set total length of indent in
++					    * characters, which may have been
++					    * undercounted until now  */
++	p = oldline;
++	s = newline;
++	while (orig_char_len > 0)
++	{
++	    *s++ = *p++;
++	    orig_char_len--;
++	}
++	/* Skip over any additional white space (useful when newindent is less
++	 * than old) */
++	while (vim_iswhite(*p))
++	    (void)*p++;
++
++    }
++    else
++    {
++	todo = size;
++	newline = alloc(ind_len + line_len);
++	if (newline == NULL)
++	    return FALSE;
++	s = newline;
++    }
+ 
+     /* Put the characters in the new line. */
+-    s = newline;
+-    todo = size;
+     /* if 'expandtab' isn't set: use TABs */
+     if (!curbuf->b_p_et)
+     {
+@@ -1320,8 +1358,8 @@
+ 	    newindent += (int)curbuf->b_p_sw;
+ 	}
+ #endif
+-	/* Copy the indent only if expand tab is disabled */
+-	if (curbuf->b_p_ci && !curbuf->b_p_et)
++	/* Copy the indent */
++	if (curbuf->b_p_ci)
+ 	{
+ 	    (void)copy_indent(newindent, saved_line);
+ 
+@@ -3468,9 +3506,38 @@
+ #endif
+ 
+ /*
++ * Call expand_env() and store the result in an allocated string.
++ * This is not very memory efficient, this expects the result to be freed
++ * again soon.
++ */
++    char_u *
++expand_env_save(src)
++    char_u	*src;
++{
++    return expand_env_save_opt(src, FALSE);
++}
++
++/*
++ * Idem, but when "one" is TRUE handle the string as one file name, only
++ * expand "~" at the start.
++ */
++    char_u *
++expand_env_save_opt(src, one)
++    char_u	*src;
++    int		one;
++{
++    char_u	*p;
++
++    p = alloc(MAXPATHL);
++    if (p != NULL)
++	expand_env_esc(src, p, MAXPATHL, FALSE, one, NULL);
++    return p;
++}
++
++/*
+  * Expand environment variable with path name.
+  * "~/" is also expanded, using $HOME.	For Unix "~user/" is expanded.
+- * Skips over "\ ", "\~" and "\$".
++ * Skips over "\ ", "\~" and "\$" (not for Win32 though).
+  * If anything fails no expansion is done and dst equals src.
+  */
+     void
+@@ -3479,15 +3546,16 @@
+     char_u	*dst;		/* where to put the result */
+     int		dstlen;		/* maximum length of the result */
+ {
+-    expand_env_esc(src, dst, dstlen, FALSE, NULL);
++    expand_env_esc(src, dst, dstlen, FALSE, FALSE, NULL);
+ }
+ 
+     void
+-expand_env_esc(srcp, dst, dstlen, esc, startstr)
++expand_env_esc(srcp, dst, dstlen, esc, one, startstr)
+     char_u	*srcp;		/* input string e.g. "$HOME/vim.hlp" */
+     char_u	*dst;		/* where to put the result */
+     int		dstlen;		/* maximum length of the result */
+     int		esc;		/* escape spaces in expanded variables */
++    int		one;		/* "srcp" is one file name */
+     char_u	*startstr;	/* start again after this (can be NULL) */
+ {
+     char_u	*src;
+@@ -3728,6 +3796,8 @@
+ 	{
+ 	    /*
+ 	     * Recognize the start of a new name, for '~'.
++	     * Don't do this when "one" is TRUE, to avoid expanding "~" in
++	     * ":edit foo ~ foo".
+ 	     */
+ 	    at_start = FALSE;
+ 	    if (src[0] == '\\' && src[1] != NUL)
+@@ -3735,7 +3805,7 @@
+ 		*dst++ = *src++;
+ 		--dstlen;
+ 	    }
+-	    else if (src[0] == ' ' || src[0] == ',')
++	    else if ((src[0] == ' ' || src[0] == ',') && !one)
+ 		at_start = TRUE;
+ 	    *dst++ = *src++;
+ 	    --dstlen;
+@@ -4032,23 +4102,6 @@
+ }
+ 
+ /*
+- * Call expand_env() and store the result in an allocated string.
+- * This is not very memory efficient, this expects the result to be freed
+- * again soon.
+- */
+-    char_u *
+-expand_env_save(src)
+-    char_u	*src;
+-{
+-    char_u	*p;
+-
+-    p = alloc(MAXPATHL);
+-    if (p != NULL)
+-	expand_env(src, p, MAXPATHL);
+-    return p;
+-}
+-
+-/*
+  * Our portable version of setenv.
+  */
+     void
+@@ -4786,7 +4839,7 @@
+ static int	cin_iswhileofdo __ARGS((char_u *, linenr_T, int));
+ static int	cin_iswhileofdo_end __ARGS((int terminated, int	ind_maxparen, int ind_maxcomment));
+ static int	cin_isbreak __ARGS((char_u *));
+-static int	cin_is_cpp_baseclass __ARGS((char_u *line, colnr_T *col));
++static int	cin_is_cpp_baseclass __ARGS((colnr_T *col));
+ static int	get_baseclass_amount __ARGS((int col, int ind_maxparen, int ind_maxcomment, int ind_cpp_baseclass));
+ static int	cin_ends_in __ARGS((char_u *, char_u *, char_u *));
+ static int	cin_skip2pos __ARGS((pos_T *trypos));
+@@ -5551,13 +5604,13 @@
+  * This is a lot of guessing.  Watch out for "cond ? func() : foo".
+  */
+     static int
+-cin_is_cpp_baseclass(line, col)
+-    char_u	*line;
++cin_is_cpp_baseclass(col)
+     colnr_T	*col;	    /* return: column to align with */
+ {
+     char_u	*s;
+     int		class_or_struct, lookfor_ctor_init, cpp_base_class;
+     linenr_T	lnum = curwin->w_cursor.lnum;
++    char_u	*line = ml_get_curline();
+ 
+     *col = 0;
+ 
+@@ -5585,7 +5638,8 @@
+      */
+     while (lnum > 1)
+     {
+-	s = skipwhite(ml_get(lnum - 1));
++	line = ml_get(lnum - 1);
++	s = skipwhite(line);
+ 	if (*s == '#' || *s == NUL)
+ 	    break;
+ 	while (*s != NUL)
+@@ -5602,7 +5656,8 @@
+ 	--lnum;
+     }
+ 
+-    s = cin_skipcomment(ml_get(lnum));
++    line = ml_get(lnum);
++    s = cin_skipcomment(line);
+     for (;;)
+     {
+ 	if (*s == NUL)
+@@ -5610,7 +5665,10 @@
+ 	    if (lnum == curwin->w_cursor.lnum)
+ 		break;
+ 	    /* Continue in the cursor line. */
+-	    s = cin_skipcomment(ml_get(++lnum));
++	    line = ml_get(++lnum);
++	    s = cin_skipcomment(line);
++	    if (*s == NUL)
++		continue;
+ 	}
+ 
+ 	if (s[0] == ':')
+@@ -7079,7 +7137,7 @@
+ 		n = FALSE;
+ 		if (lookfor != LOOKFOR_TERM && ind_cpp_baseclass > 0)
+ 		{
+-		    n = cin_is_cpp_baseclass(l, &col);
++		    n = cin_is_cpp_baseclass(&col);
+ 		    l = ml_get_curline();
+ 		}
+ 		if (n)
+@@ -7670,7 +7728,7 @@
+ 		n = FALSE;
+ 		if (ind_cpp_baseclass != 0 && theline[0] != '{')
+ 		{
+-		    n = cin_is_cpp_baseclass(l, &col);
++		    n = cin_is_cpp_baseclass(&col);
+ 		    l = ml_get_curline();
+ 		}
+ 		if (n)
+@@ -8596,7 +8654,7 @@
+     for (p = buf + wildoff; p < s; ++p)
+ 	if (rem_backslash(p))
+ 	{
+-	    STRCPY(p, p + 1);
++	    mch_memmove(p, p + 1, STRLEN(p));
+ 	    --e;
+ 	    --s;
+ 	}
+@@ -8897,7 +8955,7 @@
+     for (p = buf + wildoff; p < s; ++p)
+ 	if (rem_backslash(p))
+ 	{
+-	    STRCPY(p, p + 1);
++	    mch_memmove(p, p + 1, STRLEN(p));
+ 	    --e;
+ 	    --s;
+ 	}
+@@ -9096,7 +9154,7 @@
+ 	     */
+ 	    if (vim_strpbrk(p, (char_u *)"$~") != NULL)
+ 	    {
+-		p = expand_env_save(p);
++		p = expand_env_save_opt(p, TRUE);
+ 		if (p == NULL)
+ 		    p = pat[i];
+ #ifdef UNIX
+diff -Naur vim71.orig/src/misc2.c vim71/src/misc2.c
+--- vim71.orig/src/misc2.c	2007-05-07 15:49:26.000000000 -0400
++++ vim71/src/misc2.c	2007-12-20 23:59:50.000000000 -0500
+@@ -964,7 +964,6 @@
+ {
+     buf_T	*buf, *nextbuf;
+     static int	entered = FALSE;
+-    win_T	*win;
+ 
+     /* When we cause a crash here it is caught and Vim tries to exit cleanly.
+      * Don't try freeing everything again. */
+@@ -972,15 +971,17 @@
+ 	return;
+     entered = TRUE;
+ 
+-    ++autocmd_block;	    /* don't want to trigger autocommands here */
++# ifdef FEAT_AUTOCMD
++    block_autocmds();	    /* don't want to trigger autocommands here */
++# endif
+ 
+-#ifdef FEAT_WINDOWS
++# ifdef FEAT_WINDOWS
+     /* close all tabs and windows */
+     if (first_tabpage->tp_next != NULL)
+ 	do_cmdline_cmd((char_u *)"tabonly!");
+     if (firstwin != lastwin)
+ 	do_cmdline_cmd((char_u *)"only!");
+-#endif
++# endif
+ 
+ # if defined(FEAT_SPELL)
+     /* Free all spell info. */
+@@ -1031,27 +1032,41 @@
+     free_regexp_stuff();
+     free_tag_stuff();
+     free_cd_dir();
++# ifdef FEAT_EVAL
+     set_expr_line(NULL);
++# endif
++# ifdef FEAT_DIFF
+     diff_clear(curtab);
++# endif
+     clear_sb_text();	      /* free any scrollback text */
+ 
+     /* Free some global vars. */
+     vim_free(username);
++# ifdef FEAT_CLIPBOARD
+     vim_free(clip_exclude_prog);
++# endif
+     vim_free(last_cmdline);
++# ifdef FEAT_CMDHIST
+     vim_free(new_last_cmdline);
++# endif
+     set_keep_msg(NULL, 0);
+     vim_free(ff_expand_buffer);
+ 
+     /* Clear cmdline history. */
+     p_hi = 0;
++# ifdef FEAT_CMDHIST
+     init_history();
++# endif
+ 
+ #ifdef FEAT_QUICKFIX
+-    qf_free_all(NULL);
+-    /* Free all location lists */
+-    FOR_ALL_WINDOWS(win)
+-	qf_free_all(win);
++    {
++	win_T	*win;
++
++	qf_free_all(NULL);
++	/* Free all location lists */
++	FOR_ALL_WINDOWS(win)
++	    qf_free_all(win);
++    }
+ #endif
+ 
+     /* Close all script inputs. */
+@@ -5922,7 +5937,11 @@
+ {
+     if (emsg_not_now())
+ 	return TRUE;		/* no error messages at the moment */
++#ifdef HAVE_STDARG_H
++    vim_snprintf((char *)IObuff, IOSIZE, (char *)s, a1, a2);
++#else
+     vim_snprintf((char *)IObuff, IOSIZE, (char *)s, (long_u)a1, (long_u)a2);
++#endif
+     return emsg(IObuff);
+ }
+ 
+diff -Naur vim71.orig/src/normal.c vim71/src/normal.c
+--- vim71.orig/src/normal.c	2007-05-07 15:34:39.000000000 -0400
++++ vim71/src/normal.c	2007-12-20 23:59:23.000000000 -0500
+@@ -690,13 +690,20 @@
+ 		ca.count0 = ca.count0 * 10 + (c - '0');
+ 	    if (ca.count0 < 0)	    /* got too large! */
+ 		ca.count0 = 999999999L;
++#ifdef FEAT_EVAL
++	    /* Set v:count here, when called from main() and not a stuffed
++	     * command, so that v:count can be used in an expression mapping
++	     * right after the count. */
++	    if (toplevel && stuff_empty())
++		set_vcount(ca.count0, ca.count0 == 0 ? 1 : ca.count0);
++#endif
+ 	    if (ctrl_w)
+ 	    {
+ 		++no_mapping;
+ 		++allow_keys;		/* no mapping for nchar, but keys */
+ 	    }
+ 	    ++no_zero_mapping;		/* don't map zero here */
+-	    c = safe_vgetc();
++	    c = plain_vgetc();
+ #ifdef FEAT_LANGMAP
+ 	    LANGMAP_ADJUST(c, TRUE);
+ #endif
+@@ -721,7 +728,7 @@
+ 	    ca.count0 = 0;
+ 	    ++no_mapping;
+ 	    ++allow_keys;		/* no mapping for nchar, but keys */
+-	    c = safe_vgetc();		/* get next character */
++	    c = plain_vgetc();		/* get next character */
+ #ifdef FEAT_LANGMAP
+ 	    LANGMAP_ADJUST(c, TRUE);
+ #endif
+@@ -889,13 +896,18 @@
+ 
+ 	++no_mapping;
+ 	++allow_keys;		/* no mapping for nchar, but allow key codes */
++#ifdef FEAT_AUTOCMD
++	/* Don't generate a CursorHold event here, most commands can't handle
++	 * it, e.g., nv_replace(), nv_csearch(). */
++	did_cursorhold = TRUE;
++#endif
+ 	if (ca.cmdchar == 'g')
+ 	{
+ 	    /*
+ 	     * For 'g' get the next character now, so that we can check for
+ 	     * "gr", "g'" and "g`".
+ 	     */
+-	    ca.nchar = safe_vgetc();
++	    ca.nchar = plain_vgetc();
+ #ifdef FEAT_LANGMAP
+ 	    LANGMAP_ADJUST(ca.nchar, TRUE);
+ #endif
+@@ -952,7 +964,7 @@
+ 		im_set_active(TRUE);
+ #endif
+ 
+-	    *cp = safe_vgetc();
++	    *cp = plain_vgetc();
+ 
+ 	    if (langmap_active)
+ 	    {
+@@ -1040,7 +1052,7 @@
+ 		}
+ 		if (c > 0)
+ 		{
+-		    c = safe_vgetc();
++		    c = plain_vgetc();
+ 		    if (c != Ctrl_N && c != Ctrl_G)
+ 			vungetc(c);
+ 		    else
+@@ -1059,7 +1071,7 @@
+ 	    while (enc_utf8 && lang && (c = vpeekc()) > 0
+ 				 && (c >= 0x100 || MB_BYTE2LEN(vpeekc()) > 1))
+ 	    {
+-		c = safe_vgetc();
++		c = plain_vgetc();
+ 		if (!utf_iscomposing(c))
+ 		{
+ 		    vungetc(c);		/* it wasn't, put it back */
+@@ -3755,7 +3767,8 @@
+     extra_len = (int)STRLEN(p);
+     overflow = old_len + extra_len - SHOWCMD_COLS;
+     if (overflow > 0)
+-	STRCPY(showcmd_buf, showcmd_buf + overflow);
++	mch_memmove(showcmd_buf, showcmd_buf + overflow,
++						      old_len - overflow + 1);
+     STRCAT(showcmd_buf, p);
+ 
+     if (char_avail())
+@@ -4558,7 +4571,7 @@
+ #endif
+ 	    ++no_mapping;
+ 	    ++allow_keys;   /* no mapping for nchar, but allow key codes */
+-	    nchar = safe_vgetc();
++	    nchar = plain_vgetc();
+ #ifdef FEAT_LANGMAP
+ 	    LANGMAP_ADJUST(nchar, TRUE);
+ #endif
+@@ -4916,7 +4929,7 @@
+     case 'u':	/* "zug" and "zuw": undo "zg" and "zw" */
+ 		++no_mapping;
+ 		++allow_keys;   /* no mapping for nchar, but allow key codes */
+-		nchar = safe_vgetc();
++		nchar = plain_vgetc();
+ #ifdef FEAT_LANGMAP
+ 		LANGMAP_ADJUST(nchar, TRUE);
+ #endif
+@@ -6379,7 +6392,7 @@
+      */
+     else if (cap->nchar == 'p' || cap->nchar == 'P')
+     {
+-	if (!checkclearopq(cap->oap))
++	if (!checkclearop(cap->oap))
+ 	{
+ 	    prep_redo_cmd(cap);
+ 	    do_put(cap->oap->regname,
+@@ -6662,6 +6675,13 @@
+     else
+ 	had_ctrl_v = NUL;
+ 
++    /* Abort if the character is a special key. */
++    if (IS_SPECIAL(cap->nchar))
++    {
++	clearopbeep(cap->oap);
++	return;
++    }
++
+ #ifdef FEAT_VISUAL
+     /* Visual mode "r" */
+     if (VIsual_active)
+@@ -6688,11 +6708,9 @@
+     }
+ #endif
+ 
+-    /*
+-     * Check for a special key or not enough characters to replace.
+-     */
++    /* Abort if not enough characters to replace. */
+     ptr = ml_get_cursor();
+-    if (IS_SPECIAL(cap->nchar) || STRLEN(ptr) < (unsigned)cap->count1
++    if (STRLEN(ptr) < (unsigned)cap->count1
+ #ifdef FEAT_MBYTE
+ 	    || (has_mbyte && mb_charlen(ptr) < cap->count1)
+ #endif
+@@ -8353,7 +8371,7 @@
+ 	n = fwd_word(cap->count1, cap->arg, cap->oap->op_type != OP_NOP);
+ 
+     /* Don't leave the cursor on the NUL past a line */
+-    if (curwin->w_cursor.col && gchar_cursor() == NUL)
++    if (n != FAIL && curwin->w_cursor.col > 0 && gchar_cursor() == NUL)
+     {
+ 	--curwin->w_cursor.col;
+ 	cap->oap->inclusive = TRUE;
+diff -Naur vim71.orig/src/ops.c vim71/src/ops.c
+--- vim71.orig/src/ops.c	2007-05-07 15:33:47.000000000 -0400
++++ vim71/src/ops.c	2007-12-20 23:59:56.000000000 -0500
+@@ -927,15 +927,16 @@
+     int		name;
+     int		copy;	/* make a copy, if FALSE make register empty. */
+ {
+-    static struct yankreg	*reg;
+-    int				i;
++    struct yankreg	*reg;
++    int			i;
+ 
+ #ifdef FEAT_CLIPBOARD
+     /* When Visual area changed, may have to update selection.  Obtain the
+      * selection too. */
+-    if (name == '*' && clip_star.available && clip_isautosel())
++    if (name == '*' && clip_star.available)
+     {
+-	clip_update_selection();
++	if (clip_isautosel())
++	    clip_update_selection();
+ 	may_get_selection(name);
+     }
+ #endif
+@@ -966,7 +967,7 @@
+ }
+ 
+ /*
+- * Put "reg" into register "name".  Free any previous contents.
++ * Put "reg" into register "name".  Free any previous contents and "reg".
+  */
+     void
+ put_register(name, reg)
+@@ -976,6 +977,7 @@
+     get_yank_register(name, 0);
+     free_yank_all();
+     *y_current = *(struct yankreg *)reg;
++    vim_free(reg);
+ 
+ # ifdef FEAT_CLIPBOARD
+     /* Send text written to clipboard register to the clipboard. */
+@@ -2477,7 +2479,7 @@
+ 
+ 	/*
+ 	 * Spaces and tabs in the indent may have changed to other spaces and
+-	 * tabs.  Get the starting column again and correct the lenght.
++	 * tabs.  Get the starting column again and correct the length.
+ 	 * Don't do this when "$" used, end-of-line will have changed.
+ 	 */
+ 	block_prep(oap, &bd2, oap->start.lnum, TRUE);
+@@ -2534,7 +2536,9 @@
+ #ifdef FEAT_VISUALEXTRA
+     long		offset;
+     linenr_T		linenr;
+-    long		ins_len, pre_textlen = 0;
++    long		ins_len;
++    long		pre_textlen = 0;
++    long		pre_indent = 0;
+     char_u		*firstline;
+     char_u		*ins_text, *newp, *oldp;
+     struct block_def	bd;
+@@ -2579,7 +2583,9 @@
+ 						    || gchar_cursor() == NUL))
+ 	    coladvance_force(getviscol());
+ # endif
+-	pre_textlen = (long)STRLEN(ml_get(oap->start.lnum));
++	firstline = ml_get(oap->start.lnum);
++	pre_textlen = (long)STRLEN(firstline);
++	pre_indent = (long)(skipwhite(firstline) - firstline);
+ 	bd.textcol = curwin->w_cursor.col;
+     }
+ #endif
+@@ -2598,13 +2604,22 @@
+      */
+     if (oap->block_mode && oap->start.lnum != oap->end.lnum)
+     {
++	/* Auto-indenting may have changed the indent.  If the cursor was past
++	 * the indent, exclude that indent change from the inserted text. */
+ 	firstline = ml_get(oap->start.lnum);
+-	/*
+-	 * Subsequent calls to ml_get() flush the firstline data - take a
+-	 * copy of the required bit.
+-	 */
+-	if ((ins_len = (long)STRLEN(firstline) - pre_textlen) > 0)
++	if (bd.textcol > (colnr_T)pre_indent)
++	{
++	    long new_indent = (long)(skipwhite(firstline) - firstline);
++
++	    pre_textlen += new_indent - pre_indent;
++	    bd.textcol += new_indent - pre_indent;
++	}
++
++	ins_len = (long)STRLEN(firstline) - pre_textlen;
++	if (ins_len > 0)
+ 	{
++	    /* Subsequent calls to ml_get() flush the firstline data - take a
++	     * copy of the inserted text.  */
+ 	    if ((ins_text = alloc_check((unsigned)(ins_len + 1))) != NULL)
+ 	    {
+ 		vim_strncpy(ins_text, firstline + bd.textcol, (size_t)ins_len);
+@@ -3404,7 +3419,9 @@
+ 
+ #ifdef FEAT_VIRTUALEDIT
+ 	col += curwin->w_cursor.coladd;
+-	if (ve_flags == VE_ALL && curwin->w_cursor.coladd > 0)
++	if (ve_flags == VE_ALL
++		&& (curwin->w_cursor.coladd > 0
++		    || endcol2 == curwin->w_cursor.col))
+ 	{
+ 	    if (dir == FORWARD && c == NUL)
+ 		++col;
+diff -Naur vim71.orig/src/option.c vim71/src/option.c
+--- vim71.orig/src/option.c	2007-05-01 07:26:10.000000000 -0400
++++ vim71/src/option.c	2007-12-20 23:59:12.000000000 -0500
+@@ -427,6 +427,8 @@
+ #define P_NOGLOB       0x100000L/* do not use local value for global vimrc */
+ #define P_NFNAME       0x200000L/* only normal file name chars allowed */
+ #define P_INSECURE     0x400000L/* option was set from a modeline */
++#define P_PRI_MKRC     0x800000L/* priority for :mkvimrc (setting option has
++				   side effects) */
+ 
+ #define ISK_LATIN1  (char_u *)"@,48-57,_,192-255"
+ 
+@@ -773,6 +775,8 @@
+ 			    {(char_u *)0L, (char_u *)0L}
+ #endif
+ 			    },
++			    /* P_PRI_MKRC isn't needed here, optval_default()
++			     * always returns TRUE for 'compatible' */
+     {"compatible",  "cp",   P_BOOL|P_RALL,
+ 			    (char_u *)&p_cp, PV_NONE,
+ 			    {(char_u *)TRUE, (char_u *)FALSE}},
+@@ -1515,7 +1519,7 @@
+ 			    {(char_u *)0L, (char_u *)0L}
+ #endif
+ 			    },
+-    {"keymap",	    "kmp",  P_STRING|P_ALLOCED|P_VI_DEF|P_RBUF|P_RSTAT|P_NFNAME,
++    {"keymap",	    "kmp",  P_STRING|P_ALLOCED|P_VI_DEF|P_RBUF|P_RSTAT|P_NFNAME|P_PRI_MKRC,
+ #ifdef FEAT_KEYMAP
+ 			    (char_u *)&p_keymap, PV_KMAP,
+ 			    {(char_u *)"", (char_u *)0L}
+@@ -1836,7 +1840,7 @@
+     {"paragraphs",  "para", P_STRING|P_VI_DEF,
+ 			    (char_u *)&p_para, PV_NONE,
+ 			    {(char_u *)"IPLPPPQPP LIpplpipbp", (char_u *)0L}},
+-    {"paste",	    NULL,   P_BOOL|P_VI_DEF,
++    {"paste",	    NULL,   P_BOOL|P_VI_DEF|P_PRI_MKRC,
+ 			    (char_u *)&p_paste, PV_NONE,
+ 			    {(char_u *)FALSE, (char_u *)0L}},
+     {"pastetoggle", "pt",   P_STRING|P_VI_DEF,
+@@ -4628,7 +4632,7 @@
+ 				    if ((!(flags & P_COMMA) || *s != ',')
+ 					    && vim_strchr(s + 1, *s) != NULL)
+ 				    {
+-					STRCPY(s, s + 1);
++					mch_memmove(s, s + 1, STRLEN(s));
+ 					--s;
+ 				    }
+ 			    }
+@@ -4992,7 +4996,7 @@
+      * For 'spellsuggest' expand after "file:".
+      */
+     expand_env_esc(val, NameBuff, MAXPATHL,
+-	    (char_u **)options[opt_idx].var == &p_tags,
++	    (char_u **)options[opt_idx].var == &p_tags, FALSE,
+ #ifdef FEAT_SPELL
+ 	    (char_u **)options[opt_idx].var == &p_sps ? (char_u *)"file:" :
+ #endif
+@@ -6348,7 +6352,7 @@
+ 		errmsg = check_stl_option(p_ruf);
+ 	}
+ 	/* check 'statusline' only if it doesn't start with "%!" */
+-	else if (varp != &p_stl || s[0] != '%' || s[1] != '!')
++	else if (varp == &p_ruf || s[0] != '%' || s[1] != '!')
+ 	    errmsg = check_stl_option(s);
+ 	if (varp == &p_ruf && errmsg == NULL)
+ 	    comp_col();
+@@ -7118,6 +7122,11 @@
+     /* when 'endofline' is changed, redraw the window title */
+     else if ((int *)varp == &curbuf->b_p_eol)
+ 	need_maketitle = TRUE;
++#ifdef FEAT_MBYTE
++    /* when 'bomb' is changed, redraw the window title */
++    else if ((int *)varp == &curbuf->b_p_bomb)
++	need_maketitle = TRUE;
++#endif
+ #endif
+ 
+     /* when 'bin' is set also set some other options */
+@@ -7815,6 +7824,8 @@
+ 	    errmsg = e_positive;
+ 	    p_ch = 1;
+ 	}
++	if (p_ch > Rows - min_rows() + 1)
++	    p_ch = Rows - min_rows() + 1;
+ 
+ 	/* Only compute the new window layout when startup has been
+ 	 * completed. Otherwise the frame sizes may be wrong. */
+@@ -8219,6 +8230,25 @@
+ 	    varp = get_varp(&options[opt_idx]);
+ 	    if (varp != NULL)	/* hidden option is not changed */
+ 	    {
++		if (number == 0 && string != NULL)
++		{
++		    int index;
++
++		    /* Either we are given a string or we are setting option
++		     * to zero. */
++		    for (index = 0; string[index] == '0'; ++index)
++			;
++		    if (string[index] != NUL || index == 0)
++		    {
++			/* There's another character after zeros or the string
++			 * is empty.  In both cases, we are trying to set a
++			 * num option using a string. */
++			EMSG3(_("E521: Number required: &%s = '%s'"),
++								name, string);
++			return;     /* do nothing as we hit an error */
++
++		    }
++		}
+ 		if (flags & P_NUM)
+ 		    (void)set_num_option(opt_idx, varp, number,
+ 							  NULL, 0, opt_flags);
+@@ -8511,13 +8541,20 @@
+     char_u		*varp_local = NULL;	/* fresh value */
+     char		*cmd;
+     int			round;
++    int			pri;
+ 
+     /*
+      * The options that don't have a default (terminal name, columns, lines)
+      * are never written.  Terminal options are also not written.
++     * Do the loop over "options[]" twice: once for options with the
++     * P_PRI_MKRC flag and once without.
+      */
+-    for (p = &options[0]; !istermoption(p); p++)
+-	if (!(p->flags & P_NO_MKRC) && !istermoption(p))
++    for (pri = 1; pri >= 0; --pri)
++    {
++      for (p = &options[0]; !istermoption(p); p++)
++	if (!(p->flags & P_NO_MKRC)
++		&& !istermoption(p)
++		&& ((pri == 1) == ((p->flags & P_PRI_MKRC) != 0)))
+ 	{
+ 	    /* skip global option when only doing locals */
+ 	    if (p->indir == PV_NONE && !(opt_flags & OPT_GLOBAL))
+@@ -8613,6 +8650,7 @@
+ 		}
+ 	    }
+ 	}
++    }
+     return OK;
+ }
+ 
+@@ -8715,6 +8753,8 @@
+     char	*name;
+     int		value;
+ {
++    if (value < 0)	/* global/local option using global value */
++	return OK;
+     if (fprintf(fd, "%s %s%s", cmd, value ? "" : "no", name) < 0
+ 	    || put_eol(fd) < 0)
+ 	return FAIL;
+@@ -10585,6 +10625,8 @@
+     buf->b_start_ffc = *buf->b_p_ff;
+     buf->b_start_eol = buf->b_p_eol;
+ #ifdef FEAT_MBYTE
++    buf->b_start_bomb = buf->b_p_bomb;
++
+     /* Only use free/alloc when necessary, they take time. */
+     if (buf->b_start_fenc == NULL
+ 			     || STRCMP(buf->b_start_fenc, buf->b_p_fenc) != 0)
+@@ -10598,13 +10640,17 @@
+ /*
+  * Return TRUE if 'fileformat' and/or 'fileencoding' has a different value
+  * from when editing started (save_file_ff() called).
+- * Also when 'endofline' was changed and 'binary' is set.
++ * Also when 'endofline' was changed and 'binary' is set, or when 'bomb' was
++ * changed and 'binary' is not set.
+  * Don't consider a new, empty buffer to be changed.
+  */
+     int
+ file_ff_differs(buf)
+     buf_T	*buf;
+ {
++    /* In a buffer that was never loaded the options are not valid. */
++    if (buf->b_flags & BF_NEVERLOADED)
++	return FALSE;
+     if ((buf->b_flags & BF_NEW)
+ 	    && buf->b_ml.ml_line_count == 1
+ 	    && *ml_get_buf(buf, (linenr_T)1, FALSE) == NUL)
+@@ -10614,6 +10660,8 @@
+     if (buf->b_p_bin && buf->b_start_eol != buf->b_p_eol)
+ 	return TRUE;
+ #ifdef FEAT_MBYTE
++    if (!buf->b_p_bin && buf->b_start_bomb != buf->b_p_bomb)
++	return TRUE;
+     if (buf->b_start_fenc == NULL)
+ 	return (*buf->b_p_fenc != NUL);
+     return (STRCMP(buf->b_start_fenc, buf->b_p_fenc) != 0);
+diff -Naur vim71.orig/src/os_unix.c vim71/src/os_unix.c
+--- vim71.orig/src/os_unix.c	2007-05-09 15:41:58.000000000 -0400
++++ vim71/src/os_unix.c	2007-12-20 23:59:55.000000000 -0500
+@@ -310,7 +310,7 @@
+ }
+ 
+ /*
+- * mch_inchar(): low level input funcion.
++ * mch_inchar(): low level input function.
+  * Get a characters from the keyboard.
+  * Return the number of characters that are available.
+  * If wtime == 0 do not wait for characters.
+@@ -753,7 +753,8 @@
+     if (signal_stack != NULL)
+     {
+ # ifdef HAVE_SIGALTSTACK
+-#  ifdef __APPLE__
++#  if defined(__APPLE__) && (!defined(MAC_OS_X_VERSION_MAX_ALLOWED) \
++		|| MAC_OS_X_VERSION_MAX_ALLOWED <= 1040)
+ 	/* missing prototype.  Adding it to osdef?.h.in doesn't work, because
+ 	 * "struct sigaltstack" needs to be declared. */
+ 	extern int sigaltstack __ARGS((const struct sigaltstack *ss, struct sigaltstack *oss));
+@@ -1566,18 +1567,19 @@
+ #ifdef FEAT_XCLIPBOARD
+     if (xterm_dpy != NULL && x11_window != 0)
+     {
+-	/* Checked it already. */
+-	if (x11_display_from == XD_XTERM)
+-	    return OK;
+-
+-	/*
+-	 * If the X11 display was opened here before, for the window where Vim
+-	 * was started, close that one now to avoid a memory leak.
+-	 */
+-	if (x11_display_from == XD_HERE && x11_display != NULL)
+-	    XCloseDisplay(x11_display);
+-	x11_display = xterm_dpy;
+-	x11_display_from = XD_XTERM;
++	/* We may have checked it already, but Gnome terminal can move us to
++	 * another window, so we need to check every time. */
++	if (x11_display_from != XD_XTERM)
++	{
++	    /*
++	     * If the X11 display was opened here before, for the window where
++	     * Vim was started, close that one now to avoid a memory leak.
++	     */
++	    if (x11_display_from == XD_HERE && x11_display != NULL)
++		XCloseDisplay(x11_display);
++	    x11_display = xterm_dpy;
++	    x11_display_from = XD_XTERM;
++	}
+ 	if (test_x11_window(x11_display) == FAIL)
+ 	{
+ 	    /* probably bad $WINDOWID */
+@@ -2420,7 +2422,7 @@
+ /*
+  * Set the case of the file name, if it already exists.  This will cause the
+  * file name to remain exactly the same.
+- * Only required for file systems where case is ingored and preserved.
++ * Only required for file systems where case is ignored and preserved.
+  */
+ /*ARGSUSED*/
+     void
+@@ -2499,7 +2501,13 @@
+     if (stat((char *)name, &statb))
+ #endif
+ 	return -1;
++#ifdef __INTERIX
++    /* The top bit makes the value negative, which means the file doesn't
++     * exist.  Remove the bit, we don't use it. */
++    return statb.st_mode & ~S_ADDACE;
++#else
+     return statb.st_mode;
++#endif
+ }
+ 
+ /*
+@@ -4646,7 +4654,7 @@
+ 	ret = poll(fds, nfd, towait);
+ # ifdef FEAT_MZSCHEME
+ 	if (ret == 0 && mzquantum_used)
+-	    /* MzThreads scheduling is required and timeout occured */
++	    /* MzThreads scheduling is required and timeout occurred */
+ 	    finished = FALSE;
+ # endif
+ 
+@@ -4794,7 +4802,7 @@
+ #endif
+ # ifdef FEAT_MZSCHEME
+ 	if (ret == 0 && mzquantum_used)
+-	    /* loop if MzThreads must be scheduled and timeout occured */
++	    /* loop if MzThreads must be scheduled and timeout occurred */
+ 	    finished = FALSE;
+ # endif
+ 
+@@ -5184,7 +5192,7 @@
+ 	{
+ 	    /* When using system() always add extra quotes, because the shell
+ 	     * is started twice.  Otherwise put a backslash before special
+-	     * characters, except insice ``. */
++	     * characters, except inside ``. */
+ #ifdef USE_SYSTEM
+ 	    STRCAT(command, " \"");
+ 	    STRCAT(command, pat[i]);
+@@ -5668,7 +5676,7 @@
+ 	    /* gpm library tries to handling TSTP causes
+ 	     * problems. Anyways, we close connection to Gpm whenever
+ 	     * we are going to suspend or starting an external process
+-	     * so we should'nt  have problem with this
++	     * so we shouldn't  have problem with this
+ 	     */
+ 	    signal(SIGTSTP, restricted ? SIG_IGN : SIG_DFL);
+ 	    return 1; /* succeed */
+@@ -5682,7 +5690,7 @@
+ 
+ /*
+  * Closes connection to gpm
+- * returns non-zero if connection succesfully closed
++ * returns non-zero if connection successfully closed
+  */
+     static void
+ gpm_close()
+diff -Naur vim71.orig/src/os_unix.h vim71/src/os_unix.h
+--- vim71.orig/src/os_unix.h	2007-05-07 15:35:05.000000000 -0400
++++ vim71/src/os_unix.h	2007-12-20 23:57:02.000000000 -0500
+@@ -508,6 +508,9 @@
+ #if !defined(S_ISFIFO) && defined(S_IFIFO)
+ # define	S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
+ #endif
++#if !defined(S_ISCHR) && defined(S_IFCHR)
++# define	S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
++#endif
+ 
+ /* Note: Some systems need both string.h and strings.h (Savage).  However,
+  * some systems can't handle both, only use string.h in that case. */
+diff -Naur vim71.orig/src/popupmnu.c vim71/src/popupmnu.c
+--- vim71.orig/src/popupmnu.c	2007-03-24 16:07:39.000000000 -0400
++++ vim71/src/popupmnu.c	2007-12-20 23:57:41.000000000 -0500
+@@ -75,7 +75,6 @@
+ 
+     row = curwin->w_cline_row + W_WINROW(curwin);
+     height = curwin->w_cline_height;
+-    col = curwin->w_wcol + W_WINCOL(curwin) - curwin->w_leftcol;
+ 
+     if (firstwin->w_p_pvw)
+ 	top_clear = firstwin->w_height;
+@@ -167,6 +166,15 @@
+     pum_base_width = max_width;
+     pum_kind_width = kind_width;
+ 
++    /* Calculate column */
++#ifdef FEAT_RIGHTLEFT
++    if (curwin->w_p_rl)
++	col = W_WINCOL(curwin) + W_WIDTH(curwin) - curwin->w_wcol -
++							curwin->w_leftcol - 1;
++    else
++#endif
++	col = W_WINCOL(curwin) + curwin->w_wcol - curwin->w_leftcol;
++
+     /* if there are more items than room we need a scrollbar */
+     if (pum_height < size)
+     {
+@@ -179,11 +187,23 @@
+     if (def_width < max_width)
+ 	def_width = max_width;
+ 
+-    if (col < Columns - PUM_DEF_WIDTH || col < Columns - max_width)
++    if (((col < Columns - PUM_DEF_WIDTH || col < Columns - max_width)
++#ifdef FEAT_RIGHTLEFT
++		&& !curwin->w_p_rl)
++	    || (curwin->w_p_rl && (col > PUM_DEF_WIDTH || col > max_width)
++#endif
++       ))
+     {
+ 	/* align pum column with "col" */
+ 	pum_col = col;
+-	pum_width = Columns - pum_col - pum_scrollbar;
++
++#ifdef FEAT_RIGHTLEFT
++	if (curwin->w_p_rl)
++	    pum_width = pum_col - pum_scrollbar + 1;
++	else
++#endif
++	    pum_width = Columns - pum_col - pum_scrollbar;
++
+ 	if (pum_width > max_width + kind_width + extra_width + 1
+ 						 && pum_width > PUM_DEF_WIDTH)
+ 	{
+@@ -195,14 +215,24 @@
+     else if (Columns < def_width)
+     {
+ 	/* not enough room, will use what we have */
+-	pum_col = 0;
++#ifdef FEAT_RIGHTLEFT
++	if (curwin->w_p_rl)
++	    pum_col = Columns - 1;
++	else
++#endif
++	    pum_col = 0;
+ 	pum_width = Columns - 1;
+     }
+     else
+     {
+ 	if (max_width > PUM_DEF_WIDTH)
+ 	    max_width = PUM_DEF_WIDTH;	/* truncate */
+-	pum_col = Columns - max_width;
++#ifdef FEAT_RIGHTLEFT
++	if (curwin->w_p_rl)
++	    pum_col = max_width - 1;
++	else
++#endif
++	    pum_col = Columns - max_width;
+ 	pum_width = max_width - pum_scrollbar;
+     }
+ 
+@@ -255,8 +285,16 @@
+ 	attr = (idx == pum_selected) ? attr_select : attr_norm;
+ 
+ 	/* prepend a space if there is room */
+-	if (pum_col > 0)
+-	    screen_putchar(' ', row, pum_col - 1, attr);
++#ifdef FEAT_RIGHTLEFT
++	if (curwin->w_p_rl)
++	{
++	    if (pum_col < W_WINCOL(curwin) + W_WIDTH(curwin) - 1)
++		screen_putchar(' ', row, pum_col + 1, attr);
++	}
++	else
++#endif
++	    if (pum_col > 0)
++		screen_putchar(' ', row, pum_col - 1, attr);
+ 
+ 	/* Display each entry, use two spaces for a Tab.
+ 	 * Do this 3 times: For the main text, kind and extra info */
+@@ -282,26 +320,67 @@
+ 		    {
+ 			/* Display the text that fits or comes before a Tab.
+ 			 * First convert it to printable characters. */
+-			char_u *st;
+-			int  saved = *p;
++			char_u	*st;
++			int	saved = *p;
+ 
+ 			*p = NUL;
+ 			st = transstr(s);
+ 			*p = saved;
+-			if (st != NULL)
++#ifdef FEAT_RIGHTLEFT
++			if (curwin->w_p_rl)
+ 			{
+-			    screen_puts_len(st, (int)STRLEN(st), row, col,
++			    if (st != NULL)
++			    {
++				char_u	*rt = reverse_text(st);
++				char_u	*rt_saved = rt;
++				int	len, j;
++
++				if (rt != NULL)
++				{
++				    len = STRLEN(rt);
++				    if (len > pum_width)
++				    {
++					for (j = pum_width; j < len; ++j)
++					    mb_ptr_adv(rt);
++					len = pum_width;
++				    }
++				    screen_puts_len(rt, len, row,
++							col - len + 1, attr);
++				    vim_free(rt_saved);
++				}
++				vim_free(st);
++			    }
++			    col -= width;
++			}
++			else
++#endif
++			{
++			    if (st != NULL)
++			    {
++				screen_puts_len(st, (int)STRLEN(st), row, col,
+ 									attr);
+-			    vim_free(st);
++				vim_free(st);
++			    }
++			    col += width;
+ 			}
+-			col += width;
+ 
+ 			if (*p != TAB)
+ 			    break;
+ 
+ 			/* Display two spaces for a Tab. */
+-			screen_puts_len((char_u *)"  ", 2, row, col, attr);
+-			col += 2;
++#ifdef FEAT_RIGHTLEFT
++			if (curwin->w_p_rl)
++			{
++			    screen_puts_len((char_u *)"  ", 2, row, col - 1,
++									attr);
++			    col -= 2;
++			}
++			else
++#endif
++			{
++			    screen_puts_len((char_u *)"  ", 2, row, col, attr);
++			    col += 2;
++			}
+ 			totwidth += 2;
+ 			s = NULL;	    /* start text at next char */
+ 			width = 0;
+@@ -322,17 +401,44 @@
+ 					  && pum_array[idx].pum_extra == NULL)
+ 		    || pum_base_width + n >= pum_width)
+ 		break;
+-	    screen_fill(row, row + 1, col, pum_col + pum_base_width + n,
++#ifdef FEAT_RIGHTLEFT
++	    if (curwin->w_p_rl)
++	    {
++		screen_fill(row, row + 1, pum_col - pum_base_width - n + 1,
++						    col + 1, ' ', ' ', attr);
++		col = pum_col - pum_base_width - n + 1;
++	    }
++	    else
++#endif
++	    {
++		screen_fill(row, row + 1, col, pum_col + pum_base_width + n,
+ 							      ' ', ' ', attr);
+-	    col = pum_col + pum_base_width + n;
++		col = pum_col + pum_base_width + n;
++	    }
+ 	    totwidth = pum_base_width + n;
+ 	}
+ 
+-	screen_fill(row, row + 1, col, pum_col + pum_width, ' ', ' ', attr);
++#ifdef FEAT_RIGHTLEFT
++	if (curwin->w_p_rl)
++	    screen_fill(row, row + 1, pum_col - pum_width + 1, col + 1, ' ',
++								    ' ', attr);
++	else
++#endif
++	    screen_fill(row, row + 1, col, pum_col + pum_width, ' ', ' ',
++									attr);
+ 	if (pum_scrollbar > 0)
+-	    screen_putchar(' ', row, pum_col + pum_width,
+-		    i >= thumb_pos && i < thumb_pos + thumb_heigth
++	{
++#ifdef FEAT_RIGHTLEFT
++	    if (curwin->w_p_rl)
++		screen_putchar(' ', row, pum_col - pum_width,
++			i >= thumb_pos && i < thumb_pos + thumb_heigth
+ 						  ? attr_thumb : attr_scroll);
++	    else
++#endif
++		screen_putchar(' ', row, pum_col + pum_width,
++			i >= thumb_pos && i < thumb_pos + thumb_heigth
++						  ? attr_thumb : attr_scroll);
++	}
+ 
+ 	++row;
+     }
+@@ -466,7 +572,7 @@
+ 			set_option_value((char_u *)"bh", 0L,
+ 						 (char_u *)"wipe", OPT_LOCAL);
+ 			set_option_value((char_u *)"diff", 0L,
+-						     (char_u *)"", OPT_LOCAL);
++							     NULL, OPT_LOCAL);
+ 		    }
+ 		}
+ 		if (res == OK)
+diff -Naur vim71.orig/src/proto/charset.pro vim71/src/proto/charset.pro
+--- vim71.orig/src/proto/charset.pro	2007-05-12 06:39:01.000000000 -0400
++++ vim71/src/proto/charset.pro	2007-12-20 23:58:12.000000000 -0500
+@@ -21,6 +21,7 @@
+ int vim_iswordp __ARGS((char_u *p));
+ int vim_iswordc_buf __ARGS((char_u *p, buf_T *buf));
+ int vim_isfilec __ARGS((int c));
++int vim_isfilec_or_wc __ARGS((int c));
+ int vim_isprintc __ARGS((int c));
+ int vim_isprintc_strict __ARGS((int c));
+ int lbr_chartabsize __ARGS((unsigned char *s, colnr_T col));
+diff -Naur vim71.orig/src/proto/ex_docmd.pro vim71/src/proto/ex_docmd.pro
+--- vim71.orig/src/proto/ex_docmd.pro	2007-05-12 06:39:10.000000000 -0400
++++ vim71/src/proto/ex_docmd.pro	2007-12-20 23:59:51.000000000 -0500
+@@ -5,6 +5,7 @@
+ int getline_equal __ARGS((char_u *(*fgetline)(int, void *, int), void *cookie, char_u *(*func)(int, void *, int)));
+ void *getline_cookie __ARGS((char_u *(*fgetline)(int, void *, int), void *cookie));
+ int checkforcmd __ARGS((char_u **pp, char *cmd, int len));
++int modifier_len __ARGS((char_u *cmd));
+ int cmd_exists __ARGS((char_u *name));
+ char_u *set_one_cmd_context __ARGS((expand_T *xp, char_u *buff));
+ char_u *skip_range __ARGS((char_u *cmd, int *ctx));
+diff -Naur vim71.orig/src/proto/fileio.pro vim71/src/proto/fileio.pro
+--- vim71.orig/src/proto/fileio.pro	2007-05-12 06:39:14.000000000 -0400
++++ vim71/src/proto/fileio.pro	2007-12-20 23:59:05.000000000 -0500
+@@ -2,6 +2,7 @@
+ void filemess __ARGS((buf_T *buf, char_u *name, char_u *s, int attr));
+ int readfile __ARGS((char_u *fname, char_u *sfname, linenr_T from, linenr_T lines_to_skip, linenr_T lines_to_read, exarg_T *eap, int flags));
+ int prep_exarg __ARGS((exarg_T *eap, buf_T *buf));
++int check_file_readonly __ARGS((char_u *fname, int perm));
+ int buf_write __ARGS((buf_T *buf, char_u *fname, char_u *sfname, linenr_T start, linenr_T end, exarg_T *eap, int append, int forceit, int reset_changed, int filtering));
+ void msg_add_fname __ARGS((buf_T *buf, char_u *fname));
+ void msg_add_lines __ARGS((int insert_space, long lnum, long nchars));
+@@ -39,6 +40,8 @@
+ int trigger_cursorhold __ARGS((void));
+ int has_cursormoved __ARGS((void));
+ int has_cursormovedI __ARGS((void));
++void block_autocmds __ARGS((void));
++void unblock_autocmds __ARGS((void));
+ int has_autocmd __ARGS((event_T event, char_u *sfname, buf_T *buf));
+ char_u *get_augroup_name __ARGS((expand_T *xp, int idx));
+ char_u *set_context_in_autocmd __ARGS((expand_T *xp, char_u *arg, int doautocmd));
+diff -Naur vim71.orig/src/proto/getchar.pro vim71/src/proto/getchar.pro
+--- vim71.orig/src/proto/getchar.pro	2007-05-12 06:39:16.000000000 -0400
++++ vim71/src/proto/getchar.pro	2007-12-20 23:58:39.000000000 -0500
+@@ -38,6 +38,7 @@
+ void updatescript __ARGS((int c));
+ int vgetc __ARGS((void));
+ int safe_vgetc __ARGS((void));
++int plain_vgetc __ARGS((void));
+ int vpeekc __ARGS((void));
+ int vpeekc_nomap __ARGS((void));
+ int vpeekc_any __ARGS((void));
+diff -Naur vim71.orig/src/proto/if_cscope.pro vim71/src/proto/if_cscope.pro
+--- vim71.orig/src/proto/if_cscope.pro	2007-05-12 06:39:21.000000000 -0400
++++ vim71/src/proto/if_cscope.pro	2007-12-20 23:58:34.000000000 -0500
+@@ -6,4 +6,5 @@
+ void cs_free_tags __ARGS((void));
+ void cs_print_tags __ARGS((void));
+ int cs_connection __ARGS((int num, char_u *dbpath, char_u *ppath));
++void cs_end __ARGS((void));
+ /* vim: set ft=c : */
+diff -Naur vim71.orig/src/proto/mbyte.pro vim71/src/proto/mbyte.pro
+--- vim71.orig/src/proto/mbyte.pro	2007-05-12 06:39:38.000000000 -0400
++++ vim71/src/proto/mbyte.pro	2007-12-20 23:58:25.000000000 -0500
+@@ -12,9 +12,9 @@
+ int utf_ptr2cells __ARGS((char_u *p));
+ int dbcs_ptr2cells __ARGS((char_u *p));
+ int latin_char2cells __ARGS((int c));
+-int latin_off2cells __ARGS((unsigned off));
+-int dbcs_off2cells __ARGS((unsigned off));
+-int utf_off2cells __ARGS((unsigned off));
++int latin_off2cells __ARGS((unsigned off, unsigned max_off));
++int dbcs_off2cells __ARGS((unsigned off, unsigned max_off));
++int utf_off2cells __ARGS((unsigned off, unsigned max_off));
+ int latin_ptr2char __ARGS((char_u *p));
+ int utf_ptr2char __ARGS((char_u *p));
+ int mb_ptr2char_adv __ARGS((char_u **pp));
+diff -Naur vim71.orig/src/proto/misc1.pro vim71/src/proto/misc1.pro
+--- vim71.orig/src/proto/misc1.pro	2007-05-12 06:39:34.000000000 -0400
++++ vim71/src/proto/misc1.pro	2007-12-20 23:59:02.000000000 -0500
+@@ -48,10 +48,11 @@
+ void vim_beep __ARGS((void));
+ void init_homedir __ARGS((void));
+ void free_homedir __ARGS((void));
++char_u *expand_env_save __ARGS((char_u *src));
++char_u *expand_env_save_opt __ARGS((char_u *src, int one));
+ void expand_env __ARGS((char_u *src, char_u *dst, int dstlen));
+-void expand_env_esc __ARGS((char_u *srcp, char_u *dst, int dstlen, int esc, char_u *startstr));
++void expand_env_esc __ARGS((char_u *srcp, char_u *dst, int dstlen, int esc, int one, char_u *startstr));
+ char_u *vim_getenv __ARGS((char_u *name, int *mustfree));
+-char_u *expand_env_save __ARGS((char_u *src));
+ void vim_setenv __ARGS((char_u *name, char_u *val));
+ char_u *get_env_name __ARGS((expand_T *xp, int idx));
+ void home_replace __ARGS((buf_T *buf, char_u *src, char_u *dst, int dstlen, int one));
+diff -Naur vim71.orig/src/proto/search.pro vim71/src/proto/search.pro
+--- vim71.orig/src/proto/search.pro	2007-05-12 06:39:50.000000000 -0400
++++ vim71/src/proto/search.pro	2007-12-20 23:57:41.000000000 -0500
+@@ -1,6 +1,7 @@
+ /* search.c */
+ int search_regcomp __ARGS((char_u *pat, int pat_save, int pat_use, int options, regmmatch_T *regmatch));
+ char_u *get_search_pat __ARGS((void));
++char_u *reverse_text __ARGS((char_u *s));
+ void save_search_patterns __ARGS((void));
+ void restore_search_patterns __ARGS((void));
+ void free_search_patterns __ARGS((void));
+diff -Naur vim71.orig/src/proto/syntax.pro vim71/src/proto/syntax.pro
+--- vim71.orig/src/proto/syntax.pro	2007-05-12 06:39:52.000000000 -0400
++++ vim71/src/proto/syntax.pro	2007-12-20 23:57:14.000000000 -0500
+@@ -8,6 +8,8 @@
+ void syntax_clear __ARGS((buf_T *buf));
+ void ex_syntax __ARGS((exarg_T *eap));
+ int syntax_present __ARGS((buf_T *buf));
++void reset_expand_highlight __ARGS((void));
++void set_context_in_echohl_cmd __ARGS((expand_T *xp, char_u *arg));
+ void set_context_in_syntax_cmd __ARGS((expand_T *xp, char_u *arg));
+ char_u *get_syntax_name __ARGS((expand_T *xp, int idx));
+ int syn_get_id __ARGS((win_T *wp, long lnum, colnr_T col, int trans, int *spellp));
+diff -Naur vim71.orig/src/proto/window.pro vim71/src/proto/window.pro
+--- vim71.orig/src/proto/window.pro	2007-05-12 06:40:00.000000000 -0400
++++ vim71/src/proto/window.pro	2007-12-20 23:57:20.000000000 -0500
+@@ -59,4 +59,8 @@
+ int only_one_window __ARGS((void));
+ void check_lnums __ARGS((int do_curwin));
+ int win_hasvertsplit __ARGS((void));
++int match_add __ARGS((win_T *wp, char_u *grp, char_u *pat, int prio, int id));
++int match_delete __ARGS((win_T *wp, int id, int perr));
++void clear_matches __ARGS((win_T *wp));
++matchitem_T *get_match __ARGS((win_T *wp, int id));
+ /* vim: set ft=c : */
+diff -Naur vim71.orig/src/quickfix.c vim71/src/quickfix.c
+--- vim71.orig/src/quickfix.c	2007-02-03 19:50:17.000000000 -0500
++++ vim71/src/quickfix.c	2007-12-20 23:58:47.000000000 -0500
+@@ -1612,8 +1612,8 @@
+ 	}
+ 
+ 	/*
+-	 * If there is only one window and is the quickfix window, create a new
+-	 * one above the quickfix window.
++	 * If there is only one window and it is the quickfix window, create a
++	 * new one above the quickfix window.
+ 	 */
+ 	if (((firstwin == lastwin) && bt_quickfix(curbuf)) || !usable_win)
+ 	{
+@@ -2331,7 +2331,7 @@
+ 	    set_option_value((char_u *)"bt", 0L, (char_u *)"quickfix",
+ 								   OPT_LOCAL);
+ 	    set_option_value((char_u *)"bh", 0L, (char_u *)"wipe", OPT_LOCAL);
+-	    set_option_value((char_u *)"diff", 0L, (char_u *)"", OPT_LOCAL);
++	    set_option_value((char_u *)"diff", 0L, NULL, OPT_LOCAL);
+ 	}
+ 
+ 	/* Only set the height when still in the same tab page and there is no
+@@ -2981,6 +2981,7 @@
+     buf_T	*buf;
+     int		duplicate_name = FALSE;
+     int		using_dummy;
++    int		redraw_for_dummy = FALSE;
+     int		found_match;
+     buf_T	*first_match_buf = NULL;
+     time_t	seconds = 0;
+@@ -3097,6 +3098,7 @@
+ 	    /* Remember that a buffer with this name already exists. */
+ 	    duplicate_name = (buf != NULL);
+ 	    using_dummy = TRUE;
++	    redraw_for_dummy = TRUE;
+ 
+ #if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
+ 	    /* Don't do Filetype autocommands to avoid loading syntax and
+@@ -3243,11 +3245,29 @@
+     if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
+     {
+ 	if ((flags & VGR_NOJUMP) == 0)
++	{
++	    buf = curbuf;
+ 	    qf_jump(qi, 0, 0, eap->forceit);
++	    if (buf != curbuf)
++		/* If we jumped to another buffer redrawing will already be
++		 * taken care of. */
++		redraw_for_dummy = FALSE;
++	}
+     }
+     else
+ 	EMSG2(_(e_nomatch2), s);
+ 
++    /* If we loaded a dummy buffer into the current window, the autocommands
++     * may have messed up things, need to redraw and recompute folds. */
++    if (redraw_for_dummy)
++    {
++#ifdef FEAT_FOLDING
++	foldUpdateAll(curwin);
++#else
++	redraw_later(NOT_VALID);
++#endif
++    }
++
+ theend:
+     vim_free(regmatch.regprog);
+ }
+diff -Naur vim71.orig/src/regexp.c vim71/src/regexp.c
+--- vim71.orig/src/regexp.c	2007-05-07 15:50:03.000000000 -0400
++++ vim71/src/regexp.c	2007-12-21 00:00:04.000000000 -0500
+@@ -2220,7 +2220,7 @@
+ 				break;
+ 			    case CLASS_LOWER:
+ 				for (cu = 1; cu <= 255; cu++)
+-				    if (islower(cu))
++				    if (MB_ISLOWER(cu))
+ 					regc(cu);
+ 				break;
+ 			    case CLASS_PRINT:
+@@ -2240,7 +2240,7 @@
+ 				break;
+ 			    case CLASS_UPPER:
+ 				for (cu = 1; cu <= 255; cu++)
+-				    if (isupper(cu))
++				    if (MB_ISUPPER(cu))
+ 					regc(cu);
+ 				break;
+ 			    case CLASS_XDIGIT:
+@@ -2770,7 +2770,8 @@
+     {
+ #ifdef FEAT_MBYTE
+ 	if (enc_utf8)
+-	    prevchr_len += utf_char2len(mb_ptr2char(regparse + prevchr_len));
++	    /* exclude composing chars that mb_ptr2len does include */
++	    prevchr_len += utf_ptr2len(regparse + prevchr_len);
+ 	else if (has_mbyte)
+ 	    prevchr_len += (*mb_ptr2len)(regparse + prevchr_len);
+ 	else
+@@ -3465,7 +3466,7 @@
+ 			(enc_utf8 && utf_fold(prog->regstart) == utf_fold(c)))
+ 			|| (c < 255 && prog->regstart < 255 &&
+ #endif
+-			    TOLOWER_LOC(prog->regstart) == TOLOWER_LOC(c)))))
++			    MB_TOLOWER(prog->regstart) == MB_TOLOWER(c)))))
+ 	    retval = regtry(prog, col);
+ 	else
+ 	    retval = 0;
+@@ -3809,11 +3810,11 @@
+ 	    break;
+ 
+ 	  case RE_BOF:
+-	    /* Passing -1 to the getline() function provided for the search
+-	     * should always return NULL if the current line is the first
+-	     * line of the file. */
++	    /* We're not at the beginning of the file when below the first
++	     * line where we started, not at the start of the line or we
++	     * didn't start at the first line of the buffer. */
+ 	    if (reglnum != 0 || reginput != regline
+-			|| (REG_MULTI && reg_getline((linenr_T)-1) != NULL))
++					  || (REG_MULTI && reg_firstlnum > 1))
+ 		status = RA_NOMATCH;
+ 	    break;
+ 
+@@ -4200,7 +4201,7 @@
+ #ifdef FEAT_MBYTE
+ 			    !enc_utf8 &&
+ #endif
+-			    TOLOWER_LOC(*opnd) != TOLOWER_LOC(*reginput))))
++			    MB_TOLOWER(*opnd) != MB_TOLOWER(*reginput))))
+ 		    status = RA_NOMATCH;
+ 		else if (*opnd == NUL)
+ 		{
+@@ -4733,10 +4734,10 @@
+ 		    rst.nextb = *OPERAND(next);
+ 		    if (ireg_ic)
+ 		    {
+-			if (isupper(rst.nextb))
+-			    rst.nextb_ic = TOLOWER_LOC(rst.nextb);
++			if (MB_ISUPPER(rst.nextb))
++			    rst.nextb_ic = MB_TOLOWER(rst.nextb);
+ 			else
+-			    rst.nextb_ic = TOUPPER_LOC(rst.nextb);
++			    rst.nextb_ic = MB_TOUPPER(rst.nextb);
+ 		    }
+ 		    else
+ 			rst.nextb_ic = rst.nextb;
+@@ -5558,11 +5559,12 @@
+ 	    int	    cu, cl;
+ 
+ 	    /* This doesn't do a multi-byte character, because a MULTIBYTECODE
+-	     * would have been used for it. */
++	     * would have been used for it.  It does handle single-byte
++	     * characters, such as latin1. */
+ 	    if (ireg_ic)
+ 	    {
+-		cu = TOUPPER_LOC(*opnd);
+-		cl = TOLOWER_LOC(*opnd);
++		cu = MB_TOUPPER(*opnd);
++		cl = MB_TOLOWER(*opnd);
+ 		while (count < maxcount && (*scan == cu || *scan == cl))
+ 		{
+ 		    count++;
+@@ -6490,10 +6492,10 @@
+ 	cc = utf_fold(c);
+     else
+ #endif
+-	 if (isupper(c))
+-	cc = TOLOWER_LOC(c);
+-    else if (islower(c))
+-	cc = TOUPPER_LOC(c);
++	 if (MB_ISUPPER(c))
++	cc = MB_TOLOWER(c);
++    else if (MB_ISLOWER(c))
++	cc = MB_TOUPPER(c);
+     else
+ 	return vim_strchr(s, c);
+ 
+@@ -6637,9 +6639,9 @@
+ 		}
+ 	    }
+ 	    else if (magic)
+-		STRCPY(p, p + 1);		/* remove '~' */
++		mch_memmove(p, p + 1, STRLEN(p));	/* remove '~' */
+ 	    else
+-		STRCPY(p, p + 2);		/* remove '\~' */
++		mch_memmove(p, p + 2, STRLEN(p) - 1);	/* remove '\~' */
+ 	    --p;
+ 	}
+ 	else
+@@ -7014,7 +7016,14 @@
+ #ifdef FEAT_MBYTE
+ 			    if (has_mbyte)
+ 			    {
+-				int l = mb_ptr2len(s) - 1;
++				int l;
++
++				/* Copy composing characters separately, one
++				 * at a time. */
++				if (enc_utf8)
++				    l = utf_ptr2len(s) - 1;
++				else
++				    l = mb_ptr2len(s) - 1;
+ 
+ 				s += l;
+ 				len -= l;
+diff -Naur vim71.orig/src/screen.c vim71/src/screen.c
+--- vim71.orig/src/screen.c	2007-05-07 15:27:53.000000000 -0400
++++ vim71/src/screen.c	2007-12-20 23:59:41.000000000 -0500
+@@ -100,27 +100,7 @@
+ static int	screen_cur_row, screen_cur_col;	/* last known cursor position */
+ 
+ #ifdef FEAT_SEARCH_EXTRA
+-/*
+- * Struct used for highlighting 'hlsearch' matches for the last use search
+- * pattern or a ":match" item.
+- * For 'hlsearch' there is one pattern for all windows.  For ":match" there is
+- * a different pattern for each window.
+- */
+-typedef struct
+-{
+-    regmmatch_T	rm;	/* points to the regexp program; contains last found
+-			   match (may continue in next line) */
+-    buf_T	*buf;	/* the buffer to search for a match */
+-    linenr_T	lnum;	/* the line to search for a match */
+-    int		attr;	/* attributes to be used for a match */
+-    int		attr_cur; /* attributes currently active in win_line() */
+-    linenr_T	first_lnum;	/* first lnum to search for multi-line pat */
+-    colnr_T	startcol; /* in win_line() points to char where HL starts */
+-    colnr_T	endcol;	 /* in win_line() points to char where HL ends */
+-} match_T;
+-
+ static match_T search_hl;	/* used for 'hlsearch' highlight matching */
+-static match_T match_hl[3];	/* used for ":match" highlight matching */
+ #endif
+ 
+ #ifdef FEAT_FOLDING
+@@ -155,6 +135,7 @@
+ static void redraw_custum_statusline __ARGS((win_T *wp));
+ #endif
+ #ifdef FEAT_SEARCH_EXTRA
++#define SEARCH_HL_PRIORITY 0
+ static void start_search_hl __ARGS((void));
+ static void end_search_hl __ARGS((void));
+ static void prepare_search_hl __ARGS((win_T *wp, linenr_T lnum));
+@@ -350,6 +331,11 @@
+     {
+ 	if (type < must_redraw)	    /* use maximal type */
+ 	    type = must_redraw;
++
++	/* must_redraw is reset here, so that when we run into some weird
++	 * reason to redraw while busy redrawing (e.g., asynchronous
++	 * scrolling), or update_topline() in win_update() will cause a
++	 * scroll, the screen will be redrawn later or in win_update(). */
+ 	must_redraw = 0;
+     }
+ 
+@@ -787,6 +773,7 @@
+ 					   w_topline got smaller a bit */
+ #endif
+ #ifdef FEAT_SEARCH_EXTRA
++    matchitem_T *cur;		/* points to the match list */
+     int		top_to_mod = FALSE;    /* redraw above mod_top */
+ #endif
+ 
+@@ -848,18 +835,20 @@
+ #endif
+ 
+ #ifdef FEAT_SEARCH_EXTRA
+-    /* Setup for ":match" and 'hlsearch' highlighting.  Disable any previous
++    /* Setup for match and 'hlsearch' highlighting.  Disable any previous
+      * match */
+-    for (i = 0; i < 3; ++i)
++    cur = wp->w_match_head;
++    while (cur != NULL)
+     {
+-	match_hl[i].rm = wp->w_match[i];
+-	if (wp->w_match_id[i] == 0)
+-	    match_hl[i].attr = 0;
+-	else
+-	    match_hl[i].attr = syn_id2attr(wp->w_match_id[i]);
+-	match_hl[i].buf = buf;
+-	match_hl[i].lnum = 0;
+-	match_hl[i].first_lnum = 0;
++	cur->hl.rm = cur->match;
++	if (cur->hlg_id == 0)
++	    cur->hl.attr = 0;
++	else
++	    cur->hl.attr = syn_id2attr(cur->hlg_id);
++	cur->hl.buf = buf;
++	cur->hl.lnum = 0;
++	cur->hl.first_lnum = 0;
++	cur = cur->next;
+     }
+     search_hl.buf = buf;
+     search_hl.lnum = 0;
+@@ -923,19 +912,25 @@
+ 	     * change in one line may make the Search highlighting in a
+ 	     * previous line invalid.  Simple solution: redraw all visible
+ 	     * lines above the change.
+-	     * Same for a ":match" pattern.
++	     * Same for a match pattern.
+ 	     */
+ 	    if (search_hl.rm.regprog != NULL
+ 					&& re_multiline(search_hl.rm.regprog))
+ 		top_to_mod = TRUE;
+ 	    else
+-		for (i = 0; i < 3; ++i)
+-		    if (match_hl[i].rm.regprog != NULL
+-				      && re_multiline(match_hl[i].rm.regprog))
++	    {
++		cur = wp->w_match_head;
++		while (cur != NULL)
++		{
++		    if (cur->match.regprog != NULL
++					   && re_multiline(cur->match.regprog))
+ 		    {
+ 			top_to_mod = TRUE;
+ 			break;
+ 		    }
++		    cur = cur->next;
++		}
++	    }
+ #endif
+ 	}
+ #ifdef FEAT_FOLDING
+@@ -1029,6 +1024,13 @@
+ 	    type = VALID;
+     }
+ 
++    /* Trick: we want to avoid clearing the screen twice.  screenclear() will
++     * set "screen_cleared" to TRUE.  The special value MAYBE (which is still
++     * non-zero and thus not FALSE) will indicate that screenclear() was not
++     * called. */
++    if (screen_cleared)
++	screen_cleared = MAYBE;
++
+     /*
+      * If there are no changes on the screen that require a complete redraw,
+      * handle three cases:
+@@ -1230,7 +1232,11 @@
+ 	    mid_end = wp->w_height;
+ 	    if (lastwin == firstwin)
+ 	    {
+-		screenclear();
++		/* Clear the screen when it was not done by win_del_lines() or
++		 * win_ins_lines() above, "screen_cleared" is FALSE or MAYBE
++		 * then. */
++		if (screen_cleared != TRUE)
++		    screenclear();
+ #ifdef FEAT_WINDOWS
+ 		/* The screen was cleared, redraw the tab pages line. */
+ 		if (redraw_tabline)
+@@ -1238,6 +1244,13 @@
+ #endif
+ 	    }
+ 	}
++
++	/* When win_del_lines() or win_ins_lines() caused the screen to be
++	 * cleared (only happens for the first window) or when screenclear()
++	 * was called directly above, "must_redraw" will have been set to
++	 * NOT_VALID, need to reset it here to avoid redrawing twice. */
++	if (screen_cleared == TRUE)
++	    must_redraw = 0;
+     }
+     else
+     {
+@@ -2292,9 +2305,11 @@
+ 			prev_c = u8c;
+ #endif
+ 		    /* Non-BMP character: display as ? or fullwidth ?. */
++#ifdef UNICODE16
+ 		    if (u8c >= 0x10000)
+ 			ScreenLinesUC[idx] = (cells == 2) ? 0xff1f : (int)'?';
+ 		    else
++#endif
+ 			ScreenLinesUC[idx] = u8c;
+ 		    for (i = 0; i < Screen_mco; ++i)
+ 		    {
+@@ -2542,7 +2557,7 @@
+ 
+     char_u	extra[18];		/* "%ld" and 'fdc' must fit in here */
+     int		n_extra = 0;		/* number of extra chars */
+-    char_u	*p_extra = NULL;	/* string of extra chars */
++    char_u	*p_extra = NULL;	/* string of extra chars, plus NUL */
+     int		c_extra = NUL;		/* extra chars, all the same */
+     int		extra_attr = 0;		/* attributes when n_extra != 0 */
+     static char_u *at_end_str = (char_u *)""; /* used for p_extra when
+@@ -2584,6 +2599,7 @@
+     int		syntax_attr = 0;	/* attributes desired by syntax */
+     int		has_syntax = FALSE;	/* this buffer has syntax highl. */
+     int		save_did_emsg;
++    int		eol_hl_off = 0;		/* 1 if highlighted char after EOL */
+ #endif
+ #ifdef FEAT_SPELL
+     int		has_spell = FALSE;	/* this buffer has spell checking */
+@@ -2626,10 +2642,13 @@
+     int		line_attr = 0;		/* atrribute for the whole line */
+ #endif
+ #ifdef FEAT_SEARCH_EXTRA
+-    match_T	*shl;			/* points to search_hl or match_hl */
+-#endif
+-#if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_MBYTE)
+-    int		i;
++    matchitem_T *cur;			/* points to the match list */
++    match_T	*shl;			/* points to search_hl or a match */
++    int		shl_flag;		/* flag to indicate whether search_hl
++					   has been processed or not */
++    int		prevcol_hl_flag;	/* flag to indicate whether prevcol
++					   equals startcol of search_hl or one
++					   of the matches */
+ #endif
+ #ifdef FEAT_ARABIC
+     int		prev_c = 0;		/* previous Arabic character */
+@@ -3074,12 +3093,20 @@
+ 
+ #ifdef FEAT_SEARCH_EXTRA
+     /*
+-     * Handle highlighting the last used search pattern and ":match".
+-     * Do this for both search_hl and match_hl[3].
++     * Handle highlighting the last used search pattern and matches.
++     * Do this for both search_hl and the match list.
+      */
+-    for (i = 3; i >= 0; --i)
++    cur = wp->w_match_head;
++    shl_flag = FALSE;
++    while (cur != NULL || shl_flag == FALSE)
+     {
+-	shl = (i == 3) ? &search_hl : &match_hl[i];
++	if (shl_flag == FALSE)
++	{
++	    shl = &search_hl;
++	    shl_flag = TRUE;
++	}
++	else
++	    shl = &cur->hl;
+ 	shl->startcol = MAXCOL;
+ 	shl->endcol = MAXCOL;
+ 	shl->attr_cur = 0;
+@@ -3122,6 +3149,8 @@
+ 		area_highlighting = TRUE;
+ 	    }
+ 	}
++	if (shl != &search_hl && cur != NULL)
++	    cur = cur->next;
+     }
+ #endif
+ 
+@@ -3163,10 +3192,8 @@
+ 		if (cmdwin_type != 0 && wp == curwin)
+ 		{
+ 		    /* Draw the cmdline character. */
+-		    *extra = cmdwin_type;
+ 		    n_extra = 1;
+-		    p_extra = extra;
+-		    c_extra = NUL;
++		    c_extra = cmdwin_type;
+ 		    char_attr = hl_attr(HLF_AT);
+ 		}
+ 	    }
+@@ -3182,6 +3209,7 @@
+ 		    fill_foldcolumn(extra, wp, FALSE, lnum);
+ 		    n_extra = wp->w_p_fdc;
+ 		    p_extra = extra;
++		    p_extra[n_extra] = NUL;
+ 		    c_extra = NUL;
+ 		    char_attr = hl_attr(HLF_FC);
+ 		}
+@@ -3388,13 +3416,24 @@
+ 		 * After end, check for start/end of next match.
+ 		 * When another match, have to check for start again.
+ 		 * Watch out for matching an empty string!
+-		 * Do this first for search_hl, then for match_hl, so that
+-		 * ":match" overrules 'hlsearch'.
++		 * Do this for 'search_hl' and the match list (ordered by
++		 * priority).
+ 		 */
+ 		v = (long)(ptr - line);
+-		for (i = 3; i >= 0; --i)
+-		{
+-		    shl = (i == 3) ? &search_hl : &match_hl[i];
++		cur = wp->w_match_head;
++		shl_flag = FALSE;
++		while (cur != NULL || shl_flag == FALSE)
++		{
++		    if (shl_flag == FALSE
++			    && ((cur != NULL
++				    && cur->priority > SEARCH_HL_PRIORITY)
++				|| cur == NULL))
++		    {
++			shl = &search_hl;
++			shl_flag = TRUE;
++		    }
++		    else
++			shl = &cur->hl;
+ 		    while (shl->rm.regprog != NULL)
+ 		    {
+ 			if (shl->startcol != MAXCOL
+@@ -3442,26 +3481,43 @@
+ 			}
+ 			break;
+ 		    }
++		    if (shl != &search_hl && cur != NULL)
++			cur = cur->next;
+ 		}
+ 
+-		/* ":match" highlighting overrules 'hlsearch' */
+-		for (i = 0; i <= 3; ++i)
+-		    if (i == 3)
+-			search_attr = search_hl.attr_cur;
+-		    else if (match_hl[i].attr_cur != 0)
++		/* Use attributes from match with highest priority among
++		 * 'search_hl' and the match list. */
++		search_attr = search_hl.attr_cur;
++		cur = wp->w_match_head;
++		shl_flag = FALSE;
++		while (cur != NULL || shl_flag == FALSE)
++		{
++		    if (shl_flag == FALSE
++			    && ((cur != NULL
++				    && cur->priority > SEARCH_HL_PRIORITY)
++				|| cur == NULL))
+ 		    {
+-			search_attr = match_hl[i].attr_cur;
+-			break;
++			shl = &search_hl;
++			shl_flag = TRUE;
+ 		    }
++		    else
++			shl = &cur->hl;
++		    if (shl->attr_cur != 0)
++			search_attr = shl->attr_cur;
++		    if (shl != &search_hl && cur != NULL)
++			cur = cur->next;
++		}
+ 	    }
+ #endif
+ 
+ #ifdef FEAT_DIFF
+ 	    if (diff_hlf != (hlf_T)0)
+ 	    {
+-		if (diff_hlf == HLF_CHD && ptr - line >= change_start)
++		if (diff_hlf == HLF_CHD && ptr - line >= change_start
++							      && n_extra == 0)
+ 		    diff_hlf = HLF_TXD;		/* changed text */
+-		if (diff_hlf == HLF_TXD && ptr - line > change_end)
++		if (diff_hlf == HLF_TXD && ptr - line > change_end
++							      && n_extra == 0)
+ 		    diff_hlf = HLF_CHD;		/* changed line */
+ 		line_attr = hl_attr(diff_hlf);
+ 	    }
+@@ -3496,9 +3552,11 @@
+ 	 * Get the next character to put on the screen.
+ 	 */
+ 	/*
+-	 * The 'extra' array contains the extra stuff that is inserted to
+-	 * represent special characters (non-printable stuff).  When all
+-	 * characters are the same, c_extra is used.
++	 * The "p_extra" points to the extra stuff that is inserted to
++	 * represent special characters (non-printable stuff) and other
++	 * things.  When all characters are the same, c_extra is used.
++	 * "p_extra" must end in a NUL to avoid mb_ptr2len() reads past
++	 * "p_extra[n_extra]".
+ 	 * For the '$' of the 'list' option, n_extra == 1, p_extra == "".
+ 	 */
+ 	if (n_extra > 0)
+@@ -3611,6 +3669,8 @@
+ 			 * Draw it as a space with a composing char. */
+ 			if (utf_iscomposing(mb_c))
+ 			{
++			    int i;
++
+ 			    for (i = Screen_mco - 1; i > 0; --i)
+ 				u8cc[i] = u8cc[i - 1];
+ 			    u8cc[0] = mb_c;
+@@ -3621,13 +3681,18 @@
+ 		    if ((mb_l == 1 && c >= 0x80)
+ 			    || (mb_l >= 1 && mb_c == 0)
+ 			    || (mb_l > 1 && (!vim_isprintc(mb_c)
+-							 || mb_c >= 0x10000)))
++# ifdef UNICODE16
++							 || mb_c >= 0x10000
++# endif
++							 )))
+ 		    {
+ 			/*
+ 			 * Illegal UTF-8 byte: display as <xx>.
+ 			 * Non-BMP character : display as ? or fullwidth ?.
+ 			 */
++# ifdef UNICODE16
+ 			if (mb_c < 0x10000)
++# endif
+ 			{
+ 			    transchar_hex(extra, mb_c);
+ # ifdef FEAT_RIGHTLEFT
+@@ -3635,11 +3700,13 @@
+ 				rl_mirror(extra);
+ # endif
+ 			}
++# ifdef UNICODE16
+ 			else if (utf_char2cells(mb_c) != 2)
+ 			    STRCPY(extra, "?");
+ 			else
+ 			    /* 0xff1f in UTF-8: full-width '?' */
+ 			    STRCPY(extra, "\357\274\237");
++# endif
+ 
+ 			p_extra = extra;
+ 			c = *p_extra;
+@@ -3752,10 +3819,8 @@
+ 		 * a '<' in the first column. */
+ 		if (n_skip > 0 && mb_l > 1)
+ 		{
+-		    extra[0] = '<';
+-		    p_extra = extra;
+ 		    n_extra = 1;
+-		    c_extra = NUL;
++		    c_extra = '<';
+ 		    c = ' ';
+ 		    if (area_attr == 0 && search_attr == 0)
+ 		    {
+@@ -4248,20 +4313,39 @@
+ 	{
+ #ifdef FEAT_SEARCH_EXTRA
+ 	    long prevcol = (long)(ptr - line) - (c == NUL);
++
++	    /* we're not really at that column when skipping some text */
++	    if ((long)(wp->w_p_wrap ? wp->w_skipcol : wp->w_leftcol) > prevcol)
++		++prevcol;
+ #endif
+ 
+ 	    /* invert at least one char, used for Visual and empty line or
+ 	     * highlight match at end of line. If it's beyond the last
+ 	     * char on the screen, just overwrite that one (tricky!)  Not
+ 	     * needed when a '$' was displayed for 'list'. */
++#ifdef FEAT_SEARCH_EXTRA
++	    prevcol_hl_flag = FALSE;
++	    if (prevcol == (long)search_hl.startcol)
++		prevcol_hl_flag = TRUE;
++	    else
++	    {
++		cur = wp->w_match_head;
++		while (cur != NULL)
++		{
++		    if (prevcol == (long)cur->hl.startcol)
++		    {
++			prevcol_hl_flag = TRUE;
++			break;
++		    }
++		    cur = cur->next;
++		}
++	    }
++#endif
+ 	    if (lcs_eol == lcs_eol_one
+ 		    && ((area_attr != 0 && vcol == fromcol && c == NUL)
+ #ifdef FEAT_SEARCH_EXTRA
+ 			/* highlight 'hlsearch' match at end of line */
+-			|| ((prevcol == (long)search_hl.startcol
+-				|| prevcol == (long)match_hl[0].startcol
+-				|| prevcol == (long)match_hl[1].startcol
+-				|| prevcol == (long)match_hl[2].startcol)
++			|| (prevcol_hl_flag == TRUE
+ # if defined(LINE_ATTR)
+ 			    && did_line_attr <= 1
+ # endif
+@@ -4302,26 +4386,47 @@
+ #ifdef FEAT_SEARCH_EXTRA
+ 		if (area_attr == 0)
+ 		{
+-		    for (i = 0; i <= 3; ++i)
+-		    {
+-			if (i == 3)
+-			    char_attr = search_hl.attr;
+-			else if ((ptr - line) - 1 == (long)match_hl[i].startcol)
++		    /* Use attributes from match with highest priority among
++		     * 'search_hl' and the match list. */
++		    char_attr = search_hl.attr;
++		    cur = wp->w_match_head;
++		    shl_flag = FALSE;
++		    while (cur != NULL || shl_flag == FALSE)
++		    {
++			if (shl_flag == FALSE
++				&& ((cur != NULL
++					&& cur->priority > SEARCH_HL_PRIORITY)
++				    || cur == NULL))
+ 			{
+-			    char_attr = match_hl[i].attr;
+-			    break;
++			    shl = &search_hl;
++			    shl_flag = TRUE;
+ 			}
++			else
++			    shl = &cur->hl;
++			if ((ptr - line) - 1 == (long)shl->startcol)
++			    char_attr = shl->attr;
++			if (shl != &search_hl && cur != NULL)
++			    cur = cur->next;
+ 		    }
+ 		}
+ #endif
+ 		ScreenAttrs[off] = char_attr;
+ #ifdef FEAT_RIGHTLEFT
+ 		if (wp->w_p_rl)
++		{
+ 		    --col;
++		    --off;
++		}
+ 		else
+ #endif
++		{
+ 		    ++col;
++		    ++off;
++		}
+ 		++vcol;
++#ifdef FEAT_SYN_HL
++		eol_hl_off = 1;
++#endif
+ 	    }
+ 	}
+ 
+@@ -4331,6 +4436,14 @@
+ 	if (c == NUL)
+ 	{
+ #ifdef FEAT_SYN_HL
++	    if (eol_hl_off > 0 && vcol - eol_hl_off == (long)wp->w_virtcol)
++	    {
++		/* highlight last char after line */
++		--col;
++		--off;
++		--vcol;
++	    }
++
+ 	    /* Highlight 'cursorcolumn' past end of the line. */
+ 	    if (wp->w_p_wrap)
+ 		v = wp->w_skipcol;
+@@ -4341,7 +4454,7 @@
+ 
+ 		vcol = v + col - win_col_off(wp);
+ 	    if (wp->w_p_cuc
+-		    && (int)wp->w_virtcol >= vcol
++		    && (int)wp->w_virtcol >= vcol - eol_hl_off
+ 		    && (int)wp->w_virtcol < W_WIDTH(wp) * (row - startrow + 1)
+ 									   + v
+ 		    && lnum != wp->w_cursor.lnum
+@@ -4460,6 +4573,8 @@
+ 	    {
+ 		if (mb_utf8)
+ 		{
++		    int i;
++
+ 		    ScreenLinesUC[off] = mb_c;
+ 		    if ((c & 0xff) == 0)
+ 			ScreenLines[off] = 0x80;   /* avoid storing zero */
+@@ -4548,7 +4663,7 @@
+ 
+ 	/*
+ 	 * At end of screen line and there is more to come: Display the line
+-	 * so far.  If there is no more to display it is catched above.
++	 * so far.  If there is no more to display it is caught above.
+ 	 */
+ 	if ((
+ #ifdef FEAT_RIGHTLEFT
+@@ -4625,9 +4740,13 @@
+ #endif
+ #ifdef FEAT_MBYTE
+ 			 && !(has_mbyte
+-			     && ((*mb_off2cells)(LineOffset[screen_row]) == 2
++			     && ((*mb_off2cells)(LineOffset[screen_row],
++				     LineOffset[screen_row] + screen_Columns)
++									  == 2
+ 				 || (*mb_off2cells)(LineOffset[screen_row - 1]
+-							+ (int)Columns - 2) == 2))
++							+ (int)Columns - 2,
++				     LineOffset[screen_row] + screen_Columns)
++									== 2))
+ #endif
+ 		   )
+ 		{
+@@ -4787,6 +4906,10 @@
+ {
+     unsigned	    off_from;
+     unsigned	    off_to;
++#ifdef FEAT_MBYTE
++    unsigned	    max_off_from;
++    unsigned	    max_off_to;
++#endif
+     int		    col = 0;
+ #if defined(FEAT_GUI) || defined(UNIX) || defined(FEAT_VERTSPLIT)
+     int		    hl;
+@@ -4813,6 +4936,10 @@
+ 
+     off_from = (unsigned)(current_ScreenLine - ScreenLines);
+     off_to = LineOffset[row] + coloff;
++#ifdef FEAT_MBYTE
++    max_off_from = off_from + screen_Columns;
++    max_off_to = LineOffset[row] + screen_Columns;
++#endif
+ 
+ #ifdef FEAT_RIGHTLEFT
+     if (rlflag)
+@@ -4847,7 +4974,7 @@
+     {
+ #ifdef FEAT_MBYTE
+ 	if (has_mbyte && (col + 1 < endcol))
+-	    char_cells = (*mb_off2cells)(off_from);
++	    char_cells = (*mb_off2cells)(off_from, max_off_from);
+ 	else
+ 	    char_cells = 1;
+ #endif
+@@ -4924,7 +5051,7 @@
+ 		 * ScreenLinesUC[] is sufficient. */
+ 		if (char_cells == 1
+ 			&& col + 1 < endcol
+-			&& (*mb_off2cells)(off_to) > 1)
++			&& (*mb_off2cells)(off_to, max_off_to) > 1)
+ 		{
+ 		    /* Writing a single-cell character over a double-cell
+ 		     * character: need to redraw the next cell. */
+@@ -4933,8 +5060,8 @@
+ 		}
+ 		else if (char_cells == 2
+ 			&& col + 2 < endcol
+-			&& (*mb_off2cells)(off_to) == 1
+-			&& (*mb_off2cells)(off_to + 1) > 1)
++			&& (*mb_off2cells)(off_to, max_off_to) == 1
++			&& (*mb_off2cells)(off_to + 1, max_off_to) > 1)
+ 		{
+ 		    /* Writing the second half of a double-cell character over
+ 		     * a double-cell character: need to redraw the second
+@@ -4953,10 +5080,10 @@
+ 	     * char over the left halve of an existing one. */
+ 	    if (has_mbyte && col + char_cells == endcol
+ 		    && ((char_cells == 1
+-			    && (*mb_off2cells)(off_to) > 1)
++			    && (*mb_off2cells)(off_to, max_off_to) > 1)
+ 			|| (char_cells == 2
+-			    && (*mb_off2cells)(off_to) == 1
+-			    && (*mb_off2cells)(off_to + 1) > 1)))
++			    && (*mb_off2cells)(off_to, max_off_to) == 1
++			    && (*mb_off2cells)(off_to + 1, max_off_to) > 1)))
+ 		clear_next = TRUE;
+ #endif
+ 
+@@ -5096,10 +5223,11 @@
+ 			/* find previous character by counting from first
+ 			 * column and get its width. */
+ 			unsigned off = LineOffset[row];
++			unsigned max_off = LineOffset[row] + screen_Columns;
+ 
+ 			while (off < off_to)
+ 			{
+-			    prev_cells = (*mb_off2cells)(off);
++			    prev_cells = (*mb_off2cells)(off, max_off);
+ 			    off += prev_cells;
+ 			}
+ 		    }
+@@ -5285,7 +5413,7 @@
+ static int skip_status_match_char __ARGS((expand_T *xp, char_u *s));
+ 
+ /*
+- * Get the lenght of an item as it will be shown in the status line.
++ * Get the length of an item as it will be shown in the status line.
+  */
+     static int
+ status_match_len(xp, s)
+@@ -5351,7 +5479,7 @@
+     int		row;
+     char_u	*buf;
+     int		len;
+-    int		clen;		/* lenght in screen cells */
++    int		clen;		/* length in screen cells */
+     int		fillchar;
+     int		attr;
+     int		i;
+@@ -6103,6 +6231,7 @@
+     char_u	*ptr = text;
+     int		c;
+ #ifdef FEAT_MBYTE
++    unsigned	max_off;
+     int		mbyte_blen = 1;
+     int		mbyte_cells = 1;
+     int		u8c = 0;
+@@ -6119,8 +6248,12 @@
+ 	return;
+ 
+     off = LineOffset[row] + col;
+-    while (*ptr != NUL && col < screen_Columns
+-				      && (len < 0 || (int)(ptr - text) < len))
++#ifdef FEAT_MBYTE
++    max_off = LineOffset[row] + screen_Columns;
++#endif
++    while (col < screen_Columns
++	    && (len < 0 || (int)(ptr - text) < len)
++	    && *ptr != NUL)
+     {
+ 	c = *ptr;
+ #ifdef FEAT_MBYTE
+@@ -6143,6 +6276,7 @@
+ 		else
+ 		    u8c = utfc_ptr2char(ptr, u8cc);
+ 		mbyte_cells = utf_char2cells(u8c);
++# ifdef UNICODE16
+ 		/* Non-BMP character: display as ? or fullwidth ?. */
+ 		if (u8c >= 0x10000)
+ 		{
+@@ -6150,6 +6284,7 @@
+ 		    if (attr == 0)
+ 			attr = hl_attr(HLF_8);
+ 		}
++# endif
+ # ifdef FEAT_ARABIC
+ 		if (p_arshape && !p_tbidi && ARABIC_CHAR(u8c))
+ 		{
+@@ -6241,19 +6376,19 @@
+ 	    else if (has_mbyte
+ 		    && (len < 0 ? ptr[mbyte_blen] == NUL
+ 					     : ptr + mbyte_blen >= text + len)
+-		    && ((mbyte_cells == 1 && (*mb_off2cells)(off) > 1)
++		    && ((mbyte_cells == 1 && (*mb_off2cells)(off, max_off) > 1)
+ 			|| (mbyte_cells == 2
+-			    && (*mb_off2cells)(off) == 1
+-			    && (*mb_off2cells)(off + 1) > 1)))
++			    && (*mb_off2cells)(off, max_off) == 1
++			    && (*mb_off2cells)(off + 1, max_off) > 1)))
+ 		clear_next_cell = TRUE;
+ 
+ 	    /* Make sure we never leave a second byte of a double-byte behind,
+ 	     * it confuses mb_off2cells(). */
+ 	    if (enc_dbcs
+-		    && ((mbyte_cells == 1 && (*mb_off2cells)(off) > 1)
++		    && ((mbyte_cells == 1 && (*mb_off2cells)(off, max_off) > 1)
+ 			|| (mbyte_cells == 2
+-			    && (*mb_off2cells)(off) == 1
+-			    && (*mb_off2cells)(off + 1) > 1)))
++			    && (*mb_off2cells)(off, max_off) == 1
++			    && (*mb_off2cells)(off + 1, max_off) > 1)))
+ 		ScreenLines[off + mbyte_blen] = 0;
+ #endif
+ 	    ScreenLines[off] = c;
+@@ -6318,7 +6453,7 @@
+ 
+ #ifdef FEAT_SEARCH_EXTRA
+ /*
+- * Prepare for 'searchhl' highlighting.
++ * Prepare for 'hlsearch' highlighting.
+  */
+     static void
+ start_search_hl()
+@@ -6331,7 +6466,7 @@
+ }
+ 
+ /*
+- * Clean up for 'searchhl' highlighting.
++ * Clean up for 'hlsearch' highlighting.
+  */
+     static void
+ end_search_hl()
+@@ -6351,18 +6486,28 @@
+     win_T	*wp;
+     linenr_T	lnum;
+ {
+-    match_T	*shl;		/* points to search_hl or match_hl */
++    matchitem_T *cur;		/* points to the match list */
++    match_T	*shl;		/* points to search_hl or a match */
++    int		shl_flag;	/* flag to indicate whether search_hl
++				   has been processed or not */
+     int		n;
+-    int		i;
+ 
+     /*
+      * When using a multi-line pattern, start searching at the top
+      * of the window or just after a closed fold.
+-     * Do this both for search_hl and match_hl[3].
++     * Do this both for search_hl and the match list.
+      */
+-    for (i = 3; i >= 0; --i)
++    cur = wp->w_match_head;
++    shl_flag = FALSE;
++    while (cur != NULL || shl_flag == FALSE)
+     {
+-	shl = (i == 3) ? &search_hl : &match_hl[i];
++	if (shl_flag == FALSE)
++	{
++	    shl = &search_hl;
++	    shl_flag = TRUE;
++	}
++	else
++	    shl = &cur->hl;
+ 	if (shl->rm.regprog != NULL
+ 		&& shl->lnum == 0
+ 		&& re_multiline(shl->rm.regprog))
+@@ -6397,11 +6542,13 @@
+ 		}
+ 	    }
+ 	}
++	if (shl != &search_hl && cur != NULL)
++	    cur = cur->next;
+     }
+ }
+ 
+ /*
+- * Search for a next 'searchl' or ":match" match.
++ * Search for a next 'hlsearch' or match.
+  * Uses shl->buf.
+  * Sets shl->lnum and shl->rm contents.
+  * Note: Assumes a previous match is always before "lnum", unless
+@@ -6411,7 +6558,7 @@
+     static void
+ next_search_hl(win, shl, lnum, mincol)
+     win_T	*win;
+-    match_T	*shl;		/* points to search_hl or match_hl */
++    match_T	*shl;		/* points to search_hl or a match */
+     linenr_T	lnum;
+     colnr_T	mincol;		/* minimal column for a match */
+ {
+@@ -6479,7 +6626,7 @@
+ 	    /* Error while handling regexp: stop using this regexp. */
+ 	    if (shl == &search_hl)
+ 	    {
+-		/* don't free the regprog in match_hl[], it's a copy */
++		/* don't free regprog in the match list, it's a copy */
+ 		vim_free(shl->rm.regprog);
+ 		no_hlsearch = TRUE;
+ 	    }
+@@ -6827,6 +6974,9 @@
+ {
+     int		r, c;
+     int		off;
++#ifdef FEAT_MBYTE
++    int		max_off;
++#endif
+ 
+     /* Can't use ScreenLines unless initialized */
+     if (ScreenLines == NULL)
+@@ -6837,10 +6987,13 @@
+     for (r = row; r < row + height; ++r)
+     {
+ 	off = LineOffset[r];
++#ifdef FEAT_MBYTE
++	max_off = off + screen_Columns;
++#endif
+ 	for (c = col; c < col + width; ++c)
+ 	{
+ #ifdef FEAT_MBYTE
+-	    if (enc_dbcs != 0 && dbcs_off2cells(off + c) > 1)
++	    if (enc_dbcs != 0 && dbcs_off2cells(off + c, max_off) > 1)
+ 	    {
+ 		screen_char_2(off + c, r, c);
+ 		++c;
+@@ -6850,7 +7003,7 @@
+ 	    {
+ 		screen_char(off + c, r, c);
+ #ifdef FEAT_MBYTE
+-		if (utf_off2cells(off + c) > 1)
++		if (utf_off2cells(off + c, max_off) > 1)
+ 		    ++c;
+ #endif
+ 	    }
+diff -Naur vim71.orig/src/search.c vim71/src/search.c
+--- vim71.orig/src/search.c	2007-05-07 15:42:02.000000000 -0400
++++ vim71/src/search.c	2007-12-20 23:57:41.000000000 -0500
+@@ -101,7 +101,6 @@
+ static char_u	    *mr_pattern = NULL;	/* pattern used by search_regcomp() */
+ #ifdef FEAT_RIGHTLEFT
+ static int	    mr_pattern_alloced = FALSE; /* mr_pattern was allocated */
+-static char_u	    *reverse_text __ARGS((char_u *s));
+ #endif
+ 
+ #ifdef FEAT_FIND_ID
+@@ -228,12 +227,12 @@
+     return mr_pattern;
+ }
+ 
+-#ifdef FEAT_RIGHTLEFT
++#if defined(FEAT_RIGHTLEFT) || defined(PROTO)
+ /*
+  * Reverse text into allocated memory.
+  * Returns the allocated string, NULL when out of memory.
+  */
+-    static char_u *
++    char_u *
+ reverse_text(s)
+     char_u *s;
+ {
+@@ -573,8 +572,12 @@
+ 	/*
+ 	 * Start searching in current line, unless searching backwards and
+ 	 * we're in column 0.
++	 * If we are searching backwards, in column 0, and not including the
++	 * current position, gain some efficiency by skipping back a line.
++	 * Otherwise begin the search in the current line.
+ 	 */
+-	if (dir == BACKWARD && start_pos.col == 0)
++	if (dir == BACKWARD && start_pos.col == 0
++					     && (options & SEARCH_START) == 0)
+ 	{
+ 	    lnum = pos->lnum - 1;
+ 	    at_first_line = FALSE;
+@@ -1894,7 +1897,7 @@
+     }
+ 
+ #ifdef FEAT_RIGHTLEFT
+-    /* This is just guessing: when 'rightleft' is set, search for a maching
++    /* This is just guessing: when 'rightleft' is set, search for a matching
+      * paren/brace in the other direction. */
+     if (curwin->w_p_rl && vim_strchr((char_u *)"()[]{}<>", initc) != NULL)
+ 	backwards = !backwards;
+@@ -2124,6 +2127,9 @@
+ 			else if (!backwards)
+ 			    inquote = TRUE;
+ 		    }
++
++		    /* ml_get() only keeps one line, need to get linep again */
++		    linep = ml_get(pos.lnum);
+ 		}
+ 	    }
+ 	}
+@@ -2795,7 +2801,7 @@
+ 	i = inc_cursor();
+ 	if (i == -1 || (i >= 1 && last_line)) /* started at last char in file */
+ 	    return FAIL;
+-	if (i == 1 && eol && count == 0)      /* started at last char in line */
++	if (i >= 1 && eol && count == 0)      /* started at last char in line */
+ 	    return OK;
+ 
+ 	/*
+@@ -3600,13 +3606,16 @@
+     {
+ 	oap->start = start_pos;
+ 	oap->motion_type = MCHAR;
++	oap->inclusive = FALSE;
+ 	if (sol)
+-	{
+ 	    incl(&curwin->w_cursor);
+-	    oap->inclusive = FALSE;
+-	}
+-	else
++	else if (lt(start_pos, curwin->w_cursor))
++	    /* Include the character under the cursor. */
+ 	    oap->inclusive = TRUE;
++	else
++	    /* End is before the start (no text in between <>, [], etc.): don't
++	     * operate on any text. */
++	    curwin->w_cursor = start_pos;
+     }
+ 
+     return OK;
+@@ -3734,7 +3743,7 @@
+ 
+ 	if (in_html_tag(FALSE))
+ 	{
+-	    /* cursor on start tag, move to just after it */
++	    /* cursor on start tag, move to its '>' */
+ 	    while (*ml_get_cursor() != '>')
+ 		if (inc_cursor() < 0)
+ 		    break;
+@@ -3838,7 +3847,7 @@
+ 	/* Exclude the start tag. */
+ 	curwin->w_cursor = start_pos;
+ 	while (inc_cursor() >= 0)
+-	    if (*ml_get_cursor() == '>' && lt(curwin->w_cursor, end_pos))
++	    if (*ml_get_cursor() == '>')
+ 	    {
+ 		inc_cursor();
+ 		start_pos = curwin->w_cursor;
+@@ -3860,7 +3869,11 @@
+ #ifdef FEAT_VISUAL
+     if (VIsual_active)
+     {
+-	if (*p_sel == 'e')
++	/* If the end is before the start there is no text between tags, select
++	 * the char under the cursor. */
++	if (lt(end_pos, start_pos))
++	    curwin->w_cursor = start_pos;
++	else if (*p_sel == 'e')
+ 	    ++curwin->w_cursor.col;
+ 	VIsual = start_pos;
+ 	VIsual_mode = 'v';
+@@ -3872,7 +3885,15 @@
+     {
+ 	oap->start = start_pos;
+ 	oap->motion_type = MCHAR;
+-	oap->inclusive = TRUE;
++	if (lt(end_pos, start_pos))
++	{
++	    /* End is before the start: there is no text between tags; operate
++	     * on an empty area. */
++	    curwin->w_cursor = start_pos;
++	    oap->inclusive = FALSE;
++	}
++	else
++	    oap->inclusive = TRUE;
+     }
+     retval = OK;
+ 
+diff -Naur vim71.orig/src/spell.c vim71/src/spell.c
+--- vim71.orig/src/spell.c	2007-05-07 15:48:38.000000000 -0400
++++ vim71/src/spell.c	2007-12-20 23:57:33.000000000 -0500
+@@ -7829,7 +7829,7 @@
+ # if (_MSC_VER <= 1200)
+ /* This line is required for VC6 without the service pack.  Also see the
+  * matching #pragma below. */
+-/* # pragma optimize("", off) */
++ #  pragma optimize("", off)
+ # endif
+ #endif
+ 
+@@ -7859,7 +7859,7 @@
+ 
+ #ifdef _MSC_VER
+ # if (_MSC_VER <= 1200)
+-/* # pragma optimize("", on) */
++ #  pragma optimize("", on)
+ # endif
+ #endif
+ 
+@@ -12182,7 +12182,9 @@
+ 	    {
+ 		n = mb_cptr2len(p);
+ 		c = mb_ptr2char(p);
+-		if (!soundfold && !spell_iswordp(p + n, curbuf))
++		if (p[n] == NUL)
++		    c2 = NUL;
++		else if (!soundfold && !spell_iswordp(p + n, curbuf))
+ 		    c2 = c; /* don't swap non-word char */
+ 		else
+ 		    c2 = mb_ptr2char(p + n);
+@@ -12190,12 +12192,21 @@
+ 	    else
+ #endif
+ 	    {
+-		if (!soundfold && !spell_iswordp(p + 1, curbuf))
++		if (p[1] == NUL)
++		    c2 = NUL;
++		else if (!soundfold && !spell_iswordp(p + 1, curbuf))
+ 		    c2 = c; /* don't swap non-word char */
+ 		else
+ 		    c2 = p[1];
+ 	    }
+ 
++	    /* When the second character is NUL we can't swap. */
++	    if (c2 == NUL)
++	    {
++		sp->ts_state = STATE_REP_INI;
++		break;
++	    }
++
+ 	    /* When characters are identical, swap won't do anything.
+ 	     * Also get here if the second char is not a word character. */
+ 	    if (c == c2)
+diff -Naur vim71.orig/src/structs.h vim71/src/structs.h
+--- vim71.orig/src/structs.h	2007-05-07 15:50:49.000000000 -0400
++++ vim71/src/structs.h	2007-12-20 23:59:11.000000000 -0500
+@@ -278,6 +278,9 @@
+     linenr_T	ue_lcount;	/* linecount when u_save called */
+     char_u	**ue_array;	/* array of lines in undo block */
+     long	ue_size;	/* number of lines in ue_array */
++#ifdef U_DEBUG
++    int		ue_magic;	/* magic number to check allocation */
++#endif
+ };
+ 
+ struct u_header
+@@ -300,6 +303,9 @@
+     visualinfo_T uh_visual;	/* Visual areas before undo/after redo */
+ #endif
+     time_t	uh_time;	/* timestamp when the change was made */
++#ifdef U_DEBUG
++    int		uh_magic;	/* magic number to check allocation */
++#endif
+ };
+ 
+ /* values for uh_flags */
+@@ -1453,6 +1459,7 @@
+ #ifdef FEAT_MBYTE
+     char_u	*b_start_fenc;	/* 'fileencoding' when edit started or NULL */
+     int		b_bad_char;	/* "++bad=" argument when edit started or 0 */
++    int		b_start_bomb;	/* 'bomb' when it was read */
+ #endif
+ 
+ #ifdef FEAT_EVAL
+@@ -1694,6 +1701,41 @@
+ #define FR_COL	2	/* frame with a column of windows */
+ 
+ /*
++ * Struct used for highlighting 'hlsearch' matches, matches defined by
++ * ":match" and matches defined by match functions.
++ * For 'hlsearch' there is one pattern for all windows.  For ":match" and the
++ * match functions there is a different pattern for each window.
++ */
++typedef struct
++{
++    regmmatch_T	rm;	/* points to the regexp program; contains last found
++			   match (may continue in next line) */
++    buf_T	*buf;	/* the buffer to search for a match */
++    linenr_T	lnum;	/* the line to search for a match */
++    int		attr;	/* attributes to be used for a match */
++    int		attr_cur; /* attributes currently active in win_line() */
++    linenr_T	first_lnum;	/* first lnum to search for multi-line pat */
++    colnr_T	startcol; /* in win_line() points to char where HL starts */
++    colnr_T	endcol;	 /* in win_line() points to char where HL ends */
++} match_T;
++
++/*
++ * matchitem_T provides a linked list for storing match items for ":match" and
++ * the match functions.
++ */
++typedef struct matchitem matchitem_T;
++struct matchitem
++{
++    matchitem_T	*next;
++    int		id;	    /* match ID */
++    int		priority;   /* match priority */
++    char_u	*pattern;   /* pattern to highlight */
++    int		hlg_id;	    /* highlight group ID */
++    regmmatch_T	match;	    /* regexp program for pattern */
++    match_T	hl;	    /* struct for doing the actual highlighting */
++};
++
++/*
+  * Structure which contains all information that belongs to a window
+  *
+  * All row numbers are relative to the start of the window, except w_winrow.
+@@ -1934,9 +1976,8 @@
+ #endif
+ 
+ #ifdef FEAT_SEARCH_EXTRA
+-    regmmatch_T	w_match[3];	    /* regexp programs for ":match" */
+-    char_u	*(w_match_pat[3]);  /* patterns for ":match" */
+-    int		w_match_id[3];	    /* highlight IDs for ":match" */
++    matchitem_T	*w_match_head;		/* head of match list */
++    int		w_next_match_id;	/* next match ID */
+ #endif
+ 
+     /*
+diff -Naur vim71.orig/src/syntax.c vim71/src/syntax.c
+--- vim71.orig/src/syntax.c	2007-05-07 15:42:55.000000000 -0400
++++ vim71/src/syntax.c	2007-12-20 23:59:18.000000000 -0500
+@@ -66,8 +66,10 @@
+ #define HL_TABLE() ((struct hl_group *)((highlight_ga.ga_data)))
+ 
+ #ifdef FEAT_CMDL_COMPL
+-static int include_default = FALSE;	/* include "default" for expansion */
+-static int include_link = FALSE;	/* include "link" for expansion */
++/* Flags to indicate an additional string for highlight name completion. */
++static int include_none = 0;	/* when 1 include "None" */
++static int include_default = 0;	/* when 1 include "default" */
++static int include_link = 0;	/* when 2 include "link" and "clear" */
+ #endif
+ 
+ /*
+@@ -277,7 +279,8 @@
+  */
+ typedef struct state_item
+ {
+-    int		si_idx;			/* index of syntax pattern */
++    int		si_idx;			/* index of syntax pattern or
++					   KEYWORD_IDX */
+     int		si_id;			/* highlight group ID for keywords */
+     int		si_trans_id;		/* idem, transparancy removed */
+     int		si_m_lnum;		/* lnum of the match */
+@@ -835,9 +838,18 @@
+ 			    current_lnum = end_lnum;
+ 			    break;
+ 			}
+-			spp = &(SYN_ITEMS(syn_buf)[cur_si->si_idx]);
+-			found_flags = spp->sp_flags;
+-			found_match_idx = spp->sp_sync_idx;
++			if (cur_si->si_idx < 0)
++			{
++			    /* Cannot happen? */
++			    found_flags = 0;
++			    found_match_idx = KEYWORD_IDX;
++			}
++			else
++			{
++			    spp = &(SYN_ITEMS(syn_buf)[cur_si->si_idx]);
++			    found_flags = spp->sp_flags;
++			    found_match_idx = spp->sp_sync_idx;
++			}
+ 			found_current_lnum = current_lnum;
+ 			found_current_col = current_col;
+ 			found_m_endpos = cur_si->si_m_endpos;
+@@ -1725,6 +1737,13 @@
+ {
+     int	    attr = 0;
+ 
++    if (can_spell != NULL)
++	/* Default: Only do spelling when there is no @Spell cluster or when
++	 * ":syn spell toplevel" was used. */
++	*can_spell = syn_buf->b_syn_spell == SYNSPL_DEFAULT
++		    ? (syn_buf->b_spell_cluster_id == 0)
++		    : (syn_buf->b_syn_spell == SYNSPL_TOP);
++
+     /* check for out of memory situation */
+     if (syn_buf->b_sst_array == NULL)
+ 	return 0;
+@@ -2524,6 +2543,10 @@
+     stateitem_T	*sip = &CUR_STATE(idx);
+     synpat_T	*spp;
+ 
++    /* This should not happen... */
++    if (sip->si_idx < 0)
++	return;
++
+     spp = &(SYN_ITEMS(syn_buf)[sip->si_idx]);
+     if (sip->si_flags & HL_MATCH)
+ 	sip->si_id = spp->sp_syn_match_id;
+@@ -2639,6 +2662,10 @@
+     lpos_T	end_endpos;
+     int		end_idx;
+ 
++    /* return quickly for a keyword */
++    if (sip->si_idx < 0)
++	return;
++
+     /* Don't update when it's already done.  Can be a match of an end pattern
+      * that started in a previous line.  Watch out: can also be a "keepend"
+      * from a containing item. */
+@@ -2751,6 +2778,10 @@
+     char_u	*line;
+     int		had_match = FALSE;
+ 
++    /* just in case we are invoked for a keyword */
++    if (idx < 0)
++	return;
++
+     /*
+      * Check for being called with a START pattern.
+      * Can happen with a match that continues to the next line, because it
+@@ -3323,6 +3354,7 @@
+     {
+ 	vim_free(SYN_ITEMS(buf)[i].sp_cont_list);
+ 	vim_free(SYN_ITEMS(buf)[i].sp_next_list);
++	vim_free(SYN_ITEMS(buf)[i].sp_syn.cont_in_list);
+     }
+ }
+ 
+@@ -4460,8 +4492,8 @@
+     current_syn_inc_tag = ++running_syn_inc_tag;
+     prev_toplvl_grp = curbuf->b_syn_topgrp;
+     curbuf->b_syn_topgrp = sgl_id;
+-    if (source ? do_source(eap->arg, FALSE, FALSE) == FAIL
+-				: source_runtime(eap->arg, DOSO_NONE) == FAIL)
++    if (source ? do_source(eap->arg, FALSE, DOSO_NONE) == FAIL
++				: source_runtime(eap->arg, TRUE) == FAIL)
+ 	EMSG2(_(e_notopen), eap->arg);
+     curbuf->b_syn_topgrp = prev_toplvl_grp;
+     current_syn_inc_tag = prev_syn_inc_tag;
+@@ -5956,8 +5988,8 @@
+ {
+     return (buf->b_syn_patterns.ga_len != 0
+ 	    || buf->b_syn_clusters.ga_len != 0
+-	    || curbuf->b_keywtab.ht_used > 0
+-	    || curbuf->b_keywtab_ic.ht_used > 0);
++	    || buf->b_keywtab.ht_used > 0
++	    || buf->b_keywtab_ic.ht_used > 0);
+ }
+ 
+ #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
+@@ -5968,6 +6000,29 @@
+     EXP_CASE	    /* expand ":syn case" arguments */
+ } expand_what;
+ 
++/*
++ * Reset include_link, include_default, include_none to 0.
++ * Called when we are done expanding.
++ */
++    void
++reset_expand_highlight()
++{
++    include_link = include_default = include_none = 0;
++}
++
++/*
++ * Handle command line completion for :match and :echohl command: Add "None"
++ * as highlight group.
++ */
++    void
++set_context_in_echohl_cmd(xp, arg)
++    expand_T	*xp;
++    char_u	*arg;
++{
++    xp->xp_context = EXPAND_HIGHLIGHT;
++    xp->xp_pattern = arg;
++    include_none = 1;
++}
+ 
+ /*
+  * Handle command line completion for :syntax command.
+@@ -5983,8 +6038,8 @@
+     xp->xp_context = EXPAND_SYNTAX;
+     expand_what = EXP_SUBCMD;
+     xp->xp_pattern = arg;
+-    include_link = FALSE;
+-    include_default = FALSE;
++    include_link = 0;
++    include_default = 0;
+ 
+     /* (part of) subcommand already typed */
+     if (*arg != NUL)
+@@ -8479,7 +8534,7 @@
+ syn_id2name(id)
+     int		id;
+ {
+-    if (id <= 0 || id >= highlight_ga.ga_len)
++    if (id <= 0 || id > highlight_ga.ga_len)
+ 	return (char_u *)"";
+     return HL_TABLE()[id - 1].sg_name;
+ }
+@@ -8949,7 +9004,7 @@
+     return OK;
+ }
+ 
+-#ifdef FEAT_CMDL_COMPL
++#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
+ 
+ static void highlight_list __ARGS((void));
+ static void highlight_list_two __ARGS((int cnt, int attr));
+@@ -8967,8 +9022,8 @@
+     /* Default: expand group names */
+     xp->xp_context = EXPAND_HIGHLIGHT;
+     xp->xp_pattern = arg;
+-    include_link = TRUE;
+-    include_default = TRUE;
++    include_link = 2;
++    include_default = 1;
+ 
+     /* (part of) subcommand already typed */
+     if (*arg != NUL)
+@@ -8976,7 +9031,7 @@
+ 	p = skiptowhite(arg);
+ 	if (*p != NUL)			/* past "default" or group name */
+ 	{
+-	    include_default = FALSE;
++	    include_default = 0;
+ 	    if (STRNCMP("default", arg, p - arg) == 0)
+ 	    {
+ 		arg = skipwhite(p);
+@@ -8985,7 +9040,7 @@
+ 	    }
+ 	    if (*p != NUL)			/* past group name */
+ 	    {
+-		include_link = FALSE;
++		include_link = 0;
+ 		if (arg[1] == 'i' && arg[0] == 'N')
+ 		    highlight_list();
+ 		if (STRNCMP("link", arg, p - arg) == 0
+@@ -9045,31 +9100,25 @@
+     expand_T	*xp;
+     int		idx;
+ {
+-    if (idx == highlight_ga.ga_len
+ #ifdef FEAT_CMDL_COMPL
+-	    && include_link
+-#endif
+-	    )
++    if (idx == highlight_ga.ga_len && include_none != 0)
++	return (char_u *)"none";
++    if (idx == highlight_ga.ga_len + include_none && include_default != 0)
++	return (char_u *)"default";
++    if (idx == highlight_ga.ga_len + include_none + include_default
++							 && include_link != 0)
+ 	return (char_u *)"link";
+-    if (idx == highlight_ga.ga_len + 1
+-#ifdef FEAT_CMDL_COMPL
+-	    && include_link
+-#endif
+-	    )
++    if (idx == highlight_ga.ga_len + include_none + include_default + 1
++							 && include_link != 0)
+ 	return (char_u *)"clear";
+-    if (idx == highlight_ga.ga_len + 2
+-#ifdef FEAT_CMDL_COMPL
+-	    && include_default
+ #endif
+-	    )
+-	return (char_u *)"default";
+     if (idx < 0 || idx >= highlight_ga.ga_len)
+ 	return NULL;
+     return HL_TABLE()[idx].sg_name;
+ }
+ #endif
+ 
+-#ifdef FEAT_GUI
++#if defined(FEAT_GUI) || defined(PROTO)
+ /*
+  * Free all the highlight group fonts.
+  * Used when quitting for systems which need it.
+diff -Naur vim71.orig/src/term.c vim71/src/term.c
+--- vim71.orig/src/term.c	2007-05-07 15:39:11.000000000 -0400
++++ vim71/src/term.c	2007-12-20 23:58:45.000000000 -0500
+@@ -4809,6 +4809,8 @@
+ 	    if (num_bytes == -1)
+ 		return -1;
+ 	    current_tab = (int)bytes[0];
++	    if (current_tab == 255)	/* -1 in a byte gives 255 */
++		current_tab = -1;
+ 	    slen += num_bytes;
+ 	}
+ 	else if (key_name[0] == (int)KS_TABMENU)
+diff -Naur vim71.orig/src/termlib.c vim71/src/termlib.c
+--- vim71.orig/src/termlib.c	2007-05-07 15:39:49.000000000 -0400
++++ vim71/src/termlib.c	2007-12-20 23:57:38.000000000 -0500
+@@ -191,7 +191,7 @@
+ 	    lbuf[0] == '\t' &&
+ 	    lbuf[1] == ':')
+ 	{
+-	    strcpy(lbuf, lbuf+2);
++	    mch_memmove(lbuf, lbuf + 2, strlen(lbuf + 2) + 1);
+ 	    llen -= 2;
+ 	}
+ 	if (lbuf[llen-2] == '\\')		/* and continuations */
+diff -Naur vim71.orig/src/testdir/Makefile vim71/src/testdir/Makefile
+--- vim71.orig/src/testdir/Makefile	2006-04-30 07:08:01.000000000 -0400
++++ vim71/src/testdir/Makefile	2007-12-20 23:58:59.000000000 -0500
+@@ -1,9 +1,13 @@
+ #
+-# Makefile to run al tests for Vim
++# Makefile to run all tests for Vim
+ #
+ 
+ VIMPROG = ../vim
+ 
++# Uncomment this line for using valgrind.
++# The output goes into a file "valgrind.$PID" (sorry, no test number).
++# VALGRIND = valgrind --tool=memcheck --leak-check=yes --num-callers=15 --logfile=valgrind
++
+ SCRIPTS = test1.out test2.out test3.out test4.out test5.out test6.out \
+ 		test7.out test8.out test9.out test10.out test11.out \
+ 		test12.out  test13.out test14.out test15.out test17.out \
+@@ -15,7 +19,8 @@
+ 		test43.out test44.out test45.out test46.out test47.out \
+ 		test48.out test49.out test51.out test52.out test53.out \
+ 		test54.out test55.out test56.out test57.out test58.out \
+-		test59.out test60.out test61.out test62.out
++		test59.out test60.out test61.out test62.out test63.out \
++		test64.out
+ 
+ SCRIPTS_GUI = test16.out
+ 
+@@ -34,11 +39,11 @@
+ $(SCRIPTS) $(SCRIPTS_GUI): $(VIMPROG)
+ 
+ clean:
+-	-rm -rf *.out *.failed *.rej *.orig test.log tiny.vim small.vim mbyte.vim test.ok X* viminfo
++	-rm -rf *.out *.failed *.rej *.orig test.log tiny.vim small.vim mbyte.vim test.ok X* valgrind.pid* viminfo
+ 
+ test1.out: test1.in
+ 	-rm -f $*.failed tiny.vim small.vim mbyte.vim test.ok X* viminfo
+-	$(VIMPROG) -u unix.vim -U NONE --noplugin -s dotest.in $*.in
++	$(VALGRIND) $(VIMPROG) -u unix.vim -U NONE --noplugin -s dotest.in $*.in
+ 	@/bin/sh -c "if diff test.out $*.ok; \
+ 		then mv -f test.out $*.out; \
+ 		else echo; \
+@@ -51,7 +56,7 @@
+ 	cp $*.ok test.ok
+ 	# Sleep a moment to avoid that the xterm title is messed up
+ 	@-sleep .2
+-	-$(VIMPROG) -u unix.vim -U NONE --noplugin -s dotest.in $*.in
++	-$(VALGRIND) $(VIMPROG) -u unix.vim -U NONE --noplugin -s dotest.in $*.in
+ 	@/bin/sh -c "if test -f test.out; then\
+ 		  if diff test.out $*.ok; \
+ 		  then mv -f test.out $*.out; \
+@@ -61,5 +66,9 @@
+ 		fi"
+ 	-rm -rf X* test.ok viminfo
+ 
++test49.out: test49.vim
++
++test60.out: test60.vim
++
+ nolog:
+ 	-echo Test results: >test.log
+diff -Naur vim71.orig/src/testdir/test14.in vim71/src/testdir/test14.in
+--- vim71.orig/src/testdir/test14.in	2004-06-07 10:32:05.000000000 -0400
++++ vim71/src/testdir/test14.in	2007-12-20 23:58:59.000000000 -0500
+@@ -18,6 +18,7 @@
+ : let tt = "o\<C-V>65\<C-V>x42\<C-V>o103 \<C-V>33a\<C-V>xfg\<C-V>o78\<Esc>"
+ :endif
+ :exe "normal " . tt
++:unlet tt
+ :.w >>test.out
+ :set vb
+ /^Piece
+diff -Naur vim71.orig/src/testdir/test26.in vim71/src/testdir/test26.in
+--- vim71.orig/src/testdir/test26.in	2004-06-07 10:32:05.000000000 -0400
++++ vim71/src/testdir/test26.in	2007-12-20 23:58:59.000000000 -0500
+@@ -37,6 +37,7 @@
+ :    endif
+ :  endif
+ :endwhile
++:unlet i j
+ :'t,$w! test.out
+ :qa!
+ ENDTEST
+diff -Naur vim71.orig/src/testdir/test34.in vim71/src/testdir/test34.in
+--- vim71.orig/src/testdir/test34.in	2006-04-30 09:33:24.000000000 -0400
++++ vim71/src/testdir/test34.in	2007-12-20 23:58:59.000000000 -0500
+@@ -52,7 +52,15 @@
+ ---*---
+ (one
+ (two
+-[(one again:$-5,$wq! test.out
++[(one again:$-5,$w! test.out
++:delfunc Table
++:delfunc Compute
++:delfunc Expr1
++:delfunc Expr2
++:delfunc ListItem
++:delfunc ListReset
++:unlet retval counter
++:q!
+ ENDTEST
+ 
+ here
+diff -Naur vim71.orig/src/testdir/test45.in vim71/src/testdir/test45.in
+--- vim71.orig/src/testdir/test45.in	2004-06-07 10:32:05.000000000 -0400
++++ vim71/src/testdir/test45.in	2007-12-20 23:58:59.000000000 -0500
+@@ -55,6 +55,7 @@
+ /kk$
+ :call append("$", foldlevel("."))
+ :/^last/+1,$w! test.out
++:delfun Flvl
+ :qa!
+ ENDTEST
+ 
+diff -Naur vim71.orig/src/testdir/test47.in vim71/src/testdir/test47.in
+--- vim71.orig/src/testdir/test47.in	2004-06-07 10:32:05.000000000 -0400
++++ vim71/src/testdir/test47.in	2007-12-20 23:58:59.000000000 -0500
+@@ -34,6 +34,7 @@
+ :call append("$", two)
+ :call append("$", three)
+ :$-2,$w! test.out
++:unlet one two three
+ :qa!
+ ENDTEST
+ 
+diff -Naur vim71.orig/src/testdir/test49.in vim71/src/testdir/test49.in
+--- vim71.orig/src/testdir/test49.in	2006-04-28 05:29:54.000000000 -0400
++++ vim71/src/testdir/test49.in	2007-12-20 23:58:59.000000000 -0500
+@@ -1,13 +1,29 @@
+ This is a test of the script language.
+ 
+ If after adding a new test, the test output doesn't appear properly in
+-test49.failed, try to add one ore more "G"s at the line before ENDTEST.
++test49.failed, try to add one ore more "G"s at the line ending in "test.out"
+ 
+ STARTTEST
+ :so small.vim
+ :se nocp nomore viminfo+=nviminfo
+ :so test49.vim
+-GGGGGGGGGG"rp:.-,$wq! test.out
++GGGGGGGGGGGGGG"rp:.-,$w! test.out
++:"
++:" make valgrind happy
++:redir => funclist
++:silent func
++:redir END
++:for line in split(funclist, "\n")
++:  let name = matchstr(line, 'function \zs[A-Z]\w*\ze(')
++:  if name != ''
++:    exe "delfunc " . name
++:  endif
++:endfor
++:for v in keys(g:)
++:  silent! exe "unlet " . v
++:endfor
++:unlet v
++:qa!
+ ENDTEST
+ 
+ Results of test49.vim:
+diff -Naur vim71.orig/src/testdir/test55.in vim71/src/testdir/test55.in
+--- vim71.orig/src/testdir/test55.in	2006-10-15 10:07:05.000000000 -0400
++++ vim71/src/testdir/test55.in	2007-12-20 23:58:59.000000000 -0500
+@@ -345,6 +345,10 @@
+ :endfun
+ :call Test(1, 2, [3, 4], {5: 6})  " This may take a while
+ :"
++:delfunc Test
++:unlet dict
++:call garbagecollect(1)
++:"
+ :/^start:/,$wq! test.out
+ ENDTEST
+ 
+diff -Naur vim71.orig/src/testdir/test56.in vim71/src/testdir/test56.in
+--- vim71.orig/src/testdir/test56.in	2006-09-03 10:28:41.000000000 -0400
++++ vim71/src/testdir/test56.in	2007-12-20 23:58:59.000000000 -0500
+@@ -17,5 +17,5 @@
+ fun s:DoNothing()
+   call append(line('$'), "nothing line")
+ endfun
+-nnoremap <buffer> _x	:call <SID>DoNothing()<bar>call <SID>DoLast()<cr>
++nnoremap <buffer> _x	:call <SID>DoNothing()<bar>call <SID>DoLast()<bar>delfunc <SID>DoNothing<bar>delfunc <SID>DoLast<cr>
+ end:
+diff -Naur vim71.orig/src/testdir/test58.in vim71/src/testdir/test58.in
+--- vim71.orig/src/testdir/test58.in	2006-04-03 14:24:04.000000000 -0400
++++ vim71/src/testdir/test58.in	2007-12-20 23:58:59.000000000 -0500
+@@ -86,6 +86,7 @@
+ :$put =str
+ `m]s:let [str, a] = spellbadword()
+ :$put =str
++:unlet str a
+ :"
+ :" Postponed prefixes
+ :call TestOne('2', '1')
+@@ -100,6 +101,10 @@
+ :" NOSLITSUGS
+ :call TestOne('8', '8')
+ :"
++:" clean up for valgrind
++:delfunc TestOne
++:set spl= enc=latin1
++:"
+ gg:/^test output:/,$wq! test.out
+ ENDTEST
+ 
+diff -Naur vim71.orig/src/testdir/test59.in vim71/src/testdir/test59.in
+--- vim71.orig/src/testdir/test59.in	2006-04-03 14:29:24.000000000 -0400
++++ vim71/src/testdir/test59.in	2007-12-20 23:58:59.000000000 -0500
+@@ -90,6 +90,7 @@
+ :$put =str
+ `m]s:let [str, a] = spellbadword()
+ :$put =str
++:unlet str a
+ :"
+ :" Postponed prefixes
+ :call TestOne('2', '1')
+@@ -101,6 +102,10 @@
+ :call TestOne('6', '6')
+ :call TestOne('7', '7')
+ :"
++:" clean up for valgrind
++:delfunc TestOne
++:set spl= enc=latin1
++:"
+ gg:/^test output:/,$wq! test.out
+ ENDTEST
+ 
+diff -Naur vim71.orig/src/testdir/test60.in vim71/src/testdir/test60.in
+--- vim71.orig/src/testdir/test60.in	2006-05-05 14:41:18.000000000 -0400
++++ vim71/src/testdir/test60.in	2007-12-20 23:58:59.000000000 -0500
+@@ -569,6 +569,9 @@
+     redir END
+ endfunction
+ :call TestExists()
++:delfunc TestExists
++:delfunc RunTest
++:delfunc TestFuncArg
+ :edit! test.out
+ :set ff=unix
+ :w
+diff -Naur vim71.orig/src/testdir/test60.vim vim71/src/testdir/test60.vim
+--- vim71.orig/src/testdir/test60.vim	2006-01-12 14:45:59.000000000 -0500
++++ vim71/src/testdir/test60.vim	2007-12-20 23:58:59.000000000 -0500
+@@ -94,4 +94,5 @@
+ else
+     echo "FAILED"
+ endif
++unlet str
+ 
+diff -Naur vim71.orig/src/testdir/test62.in vim71/src/testdir/test62.in
+--- vim71.orig/src/testdir/test62.in	2006-04-30 07:29:15.000000000 -0400
++++ vim71/src/testdir/test62.in	2007-12-20 23:58:59.000000000 -0500
+@@ -7,6 +7,7 @@
+ :let nr = tabpagenr()
+ :q
+ :call append(line('$'), 'tab page ' . nr)
++:unlet nr
+ :"
+ :" Open three tab pages and use ":tabdo"
+ :0tabnew
+@@ -23,6 +24,7 @@
+ :q!
+ :call append(line('$'), line1)
+ :call append(line('$'), line2)
++:unlet line1 line2
+ :"
+ :"
+ :/^Results/,$w! test.out
+diff -Naur vim71.orig/src/testdir/test63.in vim71/src/testdir/test63.in
+--- vim71.orig/src/testdir/test63.in	1969-12-31 19:00:00.000000000 -0500
++++ vim71/src/testdir/test63.in	2007-12-20 23:58:59.000000000 -0500
+@@ -0,0 +1,157 @@
++Test for ":match", ":2match", ":3match", "clearmatches()", "getmatches()",
++"matchadd()", "matcharg()", "matchdelete()", and "setmatches()".
++
++STARTTEST
++:so small.vim
++:" --- Check that "matcharg()" returns the correct group and pattern if a match
++:" --- is defined.
++:let @r = "*** Test 1: "
++:highlight MyGroup1 ctermbg=red
++:highlight MyGroup2 ctermbg=green
++:highlight MyGroup3 ctermbg=blue
++:match MyGroup1 /TODO/
++:2match MyGroup2 /FIXME/
++:3match MyGroup3 /XXX/
++:if matcharg(1) == ['MyGroup1', 'TODO'] && matcharg(2) == ['MyGroup2', 'FIXME'] && matcharg(3) == ['MyGroup3', 'XXX']
++:  let @r .= "OK\n"
++:else
++:  let @r .= "FAILED\n"
++:endif
++:" --- Check that "matcharg()" returns an empty list if the argument is not 1,
++:" --- 2 or 3 (only 0 and 4 are tested).
++:let @r .= "*** Test 2: "
++:if matcharg(0) == [] && matcharg(4) == []
++:  let @r .= "OK\n"
++:else
++:  let @r .= "FAILED\n"
++:endif
++:" --- Check that "matcharg()" returns ['', ''] if a match is not defined.
++:let @r .= "*** Test 3: "
++:match
++:2match
++:3match
++:if matcharg(1) == ['', ''] && matcharg(2) == ['', ''] && matcharg(3) == ['', '']
++:  let @r .= "OK\n"
++:else
++:  let @r .= "FAILED\n"
++:endif
++:" --- Check that "matchadd()" and "getmatches()" agree on added matches and
++:" --- that default values apply.
++:let @r .= "*** Test 4: "
++:let m1 = matchadd("MyGroup1", "TODO")
++:let m2 = matchadd("MyGroup2", "FIXME", 42)
++:let m3 = matchadd("MyGroup3", "XXX", 60, 17)
++:if getmatches() == [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 4}, {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 42, 'id': 5}, {'group': 'MyGroup3', 'pattern': 'XXX', 'priority': 60, 'id': 17}]
++:  let @r .= "OK\n"
++:else
++:  let @r .= "FAILED\n"
++:endif
++:" --- Check that "matchdelete()" deletes the matches defined in the previous
++:" --- test correctly.
++:let @r .= "*** Test 5: "
++:call matchdelete(m1)
++:call matchdelete(m2)
++:call matchdelete(m3)
++:unlet m1
++:unlet m2
++:unlet m3
++:if getmatches() == []
++:  let @r .= "OK\n"
++:else
++:  let @r .= "FAILED\n"
++:endif
++:" --- Check that "matchdelete()" returns 0 if successful and otherwise -1.
++:let @r .= "*** Test 6: "
++:let m = matchadd("MyGroup1", "TODO")
++:let r1 = matchdelete(m)
++:let r2 = matchdelete(42)
++:if r1 == 0 && r2 == -1
++:  let @r .= "OK\n"
++:else
++:  let @r .= "FAILED\n"
++:endif
++:unlet m
++:unlet r1
++:unlet r2
++:" --- Check that "clearmatches()" clears all matches defined by ":match" and
++:" --- "matchadd()".
++:let @r .= "*** Test 7: "
++:let m1 = matchadd("MyGroup1", "TODO")
++:let m2 = matchadd("MyGroup2", "FIXME", 42)
++:let m3 = matchadd("MyGroup3", "XXX", 60, 17)
++:match MyGroup1 /COFFEE/
++:2match MyGroup2 /HUMPPA/
++:3match MyGroup3 /VIM/
++:call clearmatches()
++:if getmatches() == []
++:  let @r .= "OK\n"
++:else
++:  let @r .= "FAILED\n"
++:endif
++:unlet m1
++:unlet m2
++:unlet m3
++:" --- Check that "setmatches()" restores a list of matches saved by
++:" --- "getmatches()" without changes. (Matches with equal priority must also
++:" --- remain in the same order.)
++:let @r .= "*** Test 8: "
++:let m1 = matchadd("MyGroup1", "TODO")
++:let m2 = matchadd("MyGroup2", "FIXME", 42)
++:let m3 = matchadd("MyGroup3", "XXX", 60, 17)
++:match MyGroup1 /COFFEE/
++:2match MyGroup2 /HUMPPA/
++:3match MyGroup3 /VIM/
++:let ml = getmatches()
++:call clearmatches()
++:call setmatches(ml)
++:if getmatches() == ml
++:  let @r .= "OK\n"
++:else
++:  let @r .= "FAILED\n"
++:endif
++:call clearmatches()
++:unlet m1
++:unlet m2
++:unlet m3
++:unlet ml
++:" --- Check that "setmatches()" will not add two matches with the same ID. The
++:" --- expected behaviour (for now) is to add the first match but not the
++:" --- second and to return 0 (even though it is a matter of debate whether
++:" --- this can be considered successful behaviour).
++:let @r .= "*** Test 9: "
++:let r1 = setmatches([{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}, {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 10, 'id': 1}])
++:if getmatches() == [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}] && r1 == 0
++:  let @r .= "OK\n"
++:else
++:  let @r .= "FAILED\n"
++:endif
++:call clearmatches()
++:unlet r1
++:" --- Check that "setmatches()" returns 0 if successful and otherwise -1.
++:" --- (A range of valid and invalid input values are tried out to generate the
++:" --- return values.)
++:let @r .= "*** Test 10: "
++:let rs1 = setmatches([])
++:let rs2 = setmatches([{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}])
++:call clearmatches()
++:let rf1 = setmatches(0)
++:let rf2 = setmatches([0])
++:let rf3 = setmatches([{'wrong key': 'wrong value'}])
++:if rs1 == 0 && rs2 == 0 && rf1 == -1 && rf2 == -1 && rf3 == -1
++:  let @r .= "OK\n"
++:else
++:  let @r .= "FAILED\n"
++:endif
++:unlet rs1
++:unlet rs2
++:unlet rf1
++:unlet rf2
++:unlet rf3
++:highlight clear MyGroup1
++:highlight clear MyGroup2
++:highlight clear MyGroup3
++G"rp
++:/^Results/,$wq! test.out
++ENDTEST
++
++Results of test63:
+diff -Naur vim71.orig/src/testdir/test63.ok vim71/src/testdir/test63.ok
+--- vim71.orig/src/testdir/test63.ok	1969-12-31 19:00:00.000000000 -0500
++++ vim71/src/testdir/test63.ok	2007-12-20 23:57:20.000000000 -0500
+@@ -0,0 +1,11 @@
++Results of test63:
++*** Test 1: OK
++*** Test 2: OK
++*** Test 3: OK
++*** Test 4: OK
++*** Test 5: OK
++*** Test 6: OK
++*** Test 7: OK
++*** Test 8: OK
++*** Test 9: OK
++*** Test 10: OK
+diff -Naur vim71.orig/src/testdir/test64.in vim71/src/testdir/test64.in
+--- vim71.orig/src/testdir/test64.in	1969-12-31 19:00:00.000000000 -0500
++++ vim71/src/testdir/test64.in	2007-12-20 23:58:59.000000000 -0500
+@@ -0,0 +1,54 @@
++Test for regexp patterns.
++
++A pattern that gives the expected result produces OK, so that we know it was
++actually tried.
++
++STARTTEST
++:so small.vim
++:" tl is a List of Lists with:
++:"    regexp pattern
++:"    text to test the pattern on
++:"    expected match (optional)
++:"    expected submatch 1 (optional)
++:"    expected submatch 2 (optional)
++:"    etc.
++:"  When there is no match use only the first two items.
++:let tl = []
++:call add(tl, ['b', 'abcdef', 'b'])
++:call add(tl, ['bc*', 'abccccdef', 'bcccc'])
++:call add(tl, ['bc\{-}', 'abccccdef', 'b'])
++:call add(tl, ['bc\{-}\(d\)', 'abccccdef', 'bccccd', 'd'])
++:call add(tl, ['x', 'abcdef'])
++:"
++:for t in tl
++:  let l = matchlist(t[1], t[0])
++:" check the match itself
++:  if len(l) == 0 && len(t) > 2
++:    $put ='ERROR: pat: \"' . t[0] . '\", text: \"' . t[1] . '\", did not match, expected: \"' . t[2] . '\"'
++:  elseif len(l) > 0 && len(t) == 2
++:    $put ='ERROR: pat: \"' . t[0] . '\", text: \"' . t[1] . '\", match: \"' . l[0] . '\", expected no match'
++:  elseif len(t) > 2 && l[0] != t[2]
++:    $put ='ERROR: pat: \"' . t[0] . '\", text: \"' . t[1] . '\", match: \"' . l[0] . '\", expected: \"' . t[2] . '\"'
++:  else
++:    $put ='OK'
++:  endif
++:  if len(l) > 0
++:"   check all the nine submatches
++:    for i in range(1, 9)
++:      if len(t) <= i + 2
++:        let e = ''
++:      else
++:        let e = t[i + 2]
++:      endif
++:      if l[i] != e
++:        $put ='ERROR: pat: \"' . t[0] . '\", text: \"' . t[1] . '\", submatch ' . i . ': \"' . l[i] . '\", expected: \"' . e . '\"'
++:      endif
++:    endfor
++:    unlet i
++:  endif
++:endfor
++:unlet t tl e l
++:/^Results/,$wq! test.out
++ENDTEST
++
++Results of test64:
+diff -Naur vim71.orig/src/testdir/test64.ok vim71/src/testdir/test64.ok
+--- vim71.orig/src/testdir/test64.ok	1969-12-31 19:00:00.000000000 -0500
++++ vim71/src/testdir/test64.ok	2007-12-20 23:57:57.000000000 -0500
+@@ -0,0 +1,6 @@
++Results of test64:
++OK
++OK
++OK
++OK
++OK
+diff -Naur vim71.orig/src/ui.c vim71/src/ui.c
+--- vim71.orig/src/ui.c	2007-05-07 15:49:09.000000000 -0400
++++ vim71/src/ui.c	2007-12-20 23:58:05.000000000 -0500
+@@ -1603,8 +1603,6 @@
+ #if defined(FEAT_GUI) || defined(FEAT_MOUSE_GPM) \
+ 	|| defined(FEAT_XCLIPBOARD) || defined(VMS) \
+ 	|| defined(FEAT_SNIFF) || defined(FEAT_CLIENTSERVER) \
+-	|| (defined(FEAT_GUI) && (!defined(USE_ON_FLY_SCROLL) \
+-		|| defined(FEAT_MENU))) \
+ 	|| defined(PROTO)
+ /*
+  * Add the given bytes to the input buffer
+@@ -1630,7 +1628,9 @@
+ }
+ #endif
+ 
+-#if (defined(FEAT_XIM) && defined(FEAT_GUI_GTK)) \
++#if ((defined(FEAT_XIM) || defined(FEAT_DND)) && defined(FEAT_GUI_GTK)) \
++	|| defined(FEAT_GUI_MSWIN) \
++	|| defined(FEAT_GUI_MAC) \
+ 	|| (defined(FEAT_MBYTE) && defined(FEAT_MBYTE_IME)) \
+ 	|| (defined(FEAT_GUI) && (!defined(USE_ON_FLY_SCROLL) \
+ 		|| defined(FEAT_MENU))) \
+diff -Naur vim71.orig/src/undo.c vim71/src/undo.c
+--- vim71.orig/src/undo.c	2007-05-07 15:21:14.000000000 -0400
++++ vim71/src/undo.c	2007-12-20 23:59:42.000000000 -0500
+@@ -76,6 +76,12 @@
+  * buffer is unloaded.
+  */
+ 
++/* Uncomment the next line for including the u_check() function.  This warns
++ * for errors in the debug information. */
++/* #define U_DEBUG 1 */
++#define UH_MAGIC 0x18dade	/* value for uh_magic when in use */
++#define UE_MAGIC 0xabc123	/* value for ue_magic when in use */
++
+ #include "vim.h"
+ 
+ /* See below: use malloc()/free() for memory management. */
+@@ -113,6 +119,95 @@
+  */
+ static int	undo_undoes = FALSE;
+ 
++#ifdef U_DEBUG
++/*
++ * Check the undo structures for being valid.  Print a warning when something
++ * looks wrong.
++ */
++static int seen_b_u_curhead;
++static int seen_b_u_newhead;
++static int header_count;
++
++    static void
++u_check_tree(u_header_T *uhp,
++	u_header_T *exp_uh_next,
++	u_header_T *exp_uh_alt_prev)
++{
++    u_entry_T *uep;
++
++    if (uhp == NULL)
++	return;
++    ++header_count;
++    if (uhp == curbuf->b_u_curhead && ++seen_b_u_curhead > 1)
++    {
++	EMSG("b_u_curhead found twice (looping?)");
++	return;
++    }
++    if (uhp == curbuf->b_u_newhead && ++seen_b_u_newhead > 1)
++    {
++	EMSG("b_u_newhead found twice (looping?)");
++	return;
++    }
++
++    if (uhp->uh_magic != UH_MAGIC)
++	EMSG("uh_magic wrong (may be using freed memory)");
++    else
++    {
++	/* Check pointers back are correct. */
++	if (uhp->uh_next != exp_uh_next)
++	{
++	    EMSG("uh_next wrong");
++	    smsg((char_u *)"expected: 0x%x, actual: 0x%x",
++						   exp_uh_next, uhp->uh_next);
++	}
++	if (uhp->uh_alt_prev != exp_uh_alt_prev)
++	{
++	    EMSG("uh_alt_prev wrong");
++	    smsg((char_u *)"expected: 0x%x, actual: 0x%x",
++					   exp_uh_alt_prev, uhp->uh_alt_prev);
++	}
++
++	/* Check the undo tree at this header. */
++	for (uep = uhp->uh_entry; uep != NULL; uep = uep->ue_next)
++	{
++	    if (uep->ue_magic != UE_MAGIC)
++	    {
++		EMSG("ue_magic wrong (may be using freed memory)");
++		break;
++	    }
++	}
++
++	/* Check the next alt tree. */
++	u_check_tree(uhp->uh_alt_next, uhp->uh_next, uhp);
++
++	/* Check the next header in this branch. */
++	u_check_tree(uhp->uh_prev, uhp, NULL);
++    }
++}
++
++    void
++u_check(int newhead_may_be_NULL)
++{
++    seen_b_u_newhead = 0;
++    seen_b_u_curhead = 0;
++    header_count = 0;
++
++    u_check_tree(curbuf->b_u_oldhead, NULL, NULL);
++
++    if (seen_b_u_newhead == 0 && curbuf->b_u_oldhead != NULL
++	    && !(newhead_may_be_NULL && curbuf->b_u_newhead == NULL))
++	EMSGN("b_u_newhead invalid: 0x%x", curbuf->b_u_newhead);
++    if (curbuf->b_u_curhead != NULL && seen_b_u_curhead == 0)
++	EMSGN("b_u_curhead invalid: 0x%x", curbuf->b_u_curhead);
++    if (header_count != curbuf->b_u_numhead)
++    {
++	EMSG("b_u_numhead invalid");
++	smsg((char_u *)"expected: %ld, actual: %ld",
++			       (long)header_count, (long)curbuf->b_u_numhead);
++    }
++}
++#endif
++
+ /*
+  * Save the current line for both the "u" and "U" command.
+  * Returns OK or FAIL.
+@@ -243,6 +338,9 @@
+     if (!undo_allowed())
+ 	return FAIL;
+ 
++#ifdef U_DEBUG
++    u_check(FALSE);
++#endif
+ #ifdef FEAT_NETBEANS_INTG
+     /*
+      * Netbeans defines areas that cannot be modified.  Bail out here when
+@@ -294,6 +392,9 @@
+ 	    uhp = (u_header_T *)U_ALLOC_LINE((unsigned)sizeof(u_header_T));
+ 	    if (uhp == NULL)
+ 		goto nomem;
++#ifdef U_DEBUG
++	    uhp->uh_magic = UH_MAGIC;
++#endif
+ 	}
+ 	else
+ 	    uhp = NULL;
+@@ -316,8 +417,11 @@
+ 	{
+ 	    u_header_T	    *uhfree = curbuf->b_u_oldhead;
+ 
+-	    /* If there is no branch only free one header. */
+-	    if (uhfree->uh_alt_next == NULL)
++	    if (uhfree == old_curhead)
++		/* Can't reconnect the branch, delete all of it. */
++		u_freebranch(curbuf, uhfree, &old_curhead);
++	    else if (uhfree->uh_alt_next == NULL)
++		/* There is no branch, only free one header. */
+ 		u_freeheader(curbuf, uhfree, &old_curhead);
+ 	    else
+ 	    {
+@@ -326,6 +430,9 @@
+ 		    uhfree = uhfree->uh_alt_next;
+ 		u_freebranch(curbuf, uhfree, &old_curhead);
+ 	    }
++#ifdef U_DEBUG
++	    u_check(TRUE);
++#endif
+ 	}
+ 
+ 	if (uhp == NULL)		/* no undo at all */
+@@ -478,6 +585,9 @@
+     uep = (u_entry_T *)U_ALLOC_LINE((unsigned)sizeof(u_entry_T));
+     if (uep == NULL)
+ 	goto nomem;
++#ifdef U_DEBUG
++    uep->ue_magic = UE_MAGIC;
++#endif
+ 
+     uep->ue_size = size;
+     uep->ue_top = top;
+@@ -525,6 +635,9 @@
+     curbuf->b_u_synced = FALSE;
+     undo_undoes = FALSE;
+ 
++#ifdef U_DEBUG
++    u_check(FALSE);
++#endif
+     return OK;
+ 
+ nomem:
+@@ -955,6 +1068,9 @@
+     int		empty_buffer;		    /* buffer became empty */
+     u_header_T	*curhead = curbuf->b_u_curhead;
+ 
++#ifdef U_DEBUG
++    u_check(FALSE);
++#endif
+     old_flags = curhead->uh_flags;
+     new_flags = (curbuf->b_changed ? UH_CHANGED : 0) +
+ 	       ((curbuf->b_ml.ml_flags & ML_EMPTY) ? UH_EMPTYBUF : 0);
+@@ -1186,6 +1302,9 @@
+     /* The timestamp can be the same for multiple changes, just use the one of
+      * the undone/redone change. */
+     curbuf->b_u_seq_time = curhead->uh_time;
++#ifdef U_DEBUG
++    u_check(FALSE);
++#endif
+ }
+ 
+ /*
+@@ -1515,7 +1634,7 @@
+ }
+ 
+ /*
+- * Free one header and its entry list and adjust the pointers.
++ * Free one header "uhp" and its entry list and adjust the pointers.
+  */
+     static void
+ u_freeheader(buf, uhp, uhpp)
+@@ -1523,6 +1642,8 @@
+     u_header_T	    *uhp;
+     u_header_T	    **uhpp;	/* if not NULL reset when freeing this header */
+ {
++    u_header_T	    *uhap;
++
+     /* When there is an alternate redo list free that branch completely,
+      * because we can never go there. */
+     if (uhp->uh_alt_next != NULL)
+@@ -1540,7 +1661,8 @@
+     if (uhp->uh_prev == NULL)
+ 	buf->b_u_newhead = uhp->uh_next;
+     else
+-	uhp->uh_prev->uh_next = uhp->uh_next;
++	for (uhap = uhp->uh_prev; uhap != NULL; uhap = uhap->uh_alt_next)
++	    uhap->uh_next = uhp->uh_next;
+ 
+     u_freeentries(buf, uhp, uhpp);
+ }
+@@ -1556,6 +1678,14 @@
+ {
+     u_header_T	    *tofree, *next;
+ 
++    /* If this is the top branch we may need to use u_freeheader() to update
++     * all the pointers. */
++    if (uhp == buf->b_u_oldhead)
++    {
++	u_freeheader(buf, uhp, uhpp);
++	return;
++    }
++
+     if (uhp->uh_alt_prev != NULL)
+ 	uhp->uh_alt_prev->uh_alt_next = NULL;
+ 
+@@ -1585,6 +1715,8 @@
+     /* Check for pointers to the header that become invalid now. */
+     if (buf->b_u_curhead == uhp)
+ 	buf->b_u_curhead = NULL;
++    if (buf->b_u_newhead == uhp)
++	buf->b_u_newhead = NULL;  /* freeing the newest entry */
+     if (uhpp != NULL && uhp == *uhpp)
+ 	*uhpp = NULL;
+ 
+@@ -1594,6 +1726,9 @@
+ 	u_freeentry(uep, uep->ue_size);
+     }
+ 
++#ifdef U_DEBUG
++    uhp->uh_magic = 0;
++#endif
+     U_FREE_LINE((char_u *)uhp);
+     --buf->b_u_numhead;
+ }
+@@ -1609,6 +1744,9 @@
+     while (n > 0)
+ 	U_FREE_LINE(uep->ue_array[--n]);
+     U_FREE_LINE((char_u *)uep->ue_array);
++#ifdef U_DEBUG
++    uep->ue_magic = 0;
++#endif
+     U_FREE_LINE((char_u *)uep);
+ }
+ 
+diff -Naur vim71.orig/src/version.c vim71/src/version.c
+--- vim71.orig/src/version.c	2007-05-12 06:23:44.000000000 -0400
++++ vim71/src/version.c	2007-12-21 00:00:07.000000000 -0500
+@@ -667,6 +667,320 @@
+ static int included_patches[] =
+ {   /* Add new patch number below this line */
+ /**/
++    175,
++/**/
++    174,
++/**/
++    173,
++/**/
++    172,
++/**/
++    171,
++/**/
++    170,
++/**/
++    169,
++/**/
++    167,
++/**/
++    166,
++/**/
++    165,
++/**/
++    164,
++/**/
++    163,
++/**/
++    162,
++/**/
++    161,
++/**/
++    160,
++/**/
++    159,
++/**/
++    157,
++/**/
++    156,
++/**/
++    155,
++/**/
++    154,
++/**/
++    153,
++/**/
++    152,
++/**/
++    151,
++/**/
++    150,
++/**/
++    149,
++/**/
++    148,
++/**/
++    147,
++/**/
++    145,
++/**/
++    144,
++/**/
++    143,
++/**/
++    142,
++/**/
++    141,
++/**/
++    140,
++/**/
++    139,
++/**/
++    138,
++/**/
++    137,
++/**/
++    136,
++/**/
++    135,
++/**/
++    133,
++/**/
++    132,
++/**/
++    131,
++/**/
++    130,
++/**/
++    127,
++/**/
++    125,
++/**/
++    123,
++/**/
++    122,
++/**/
++    121,
++/**/
++    120,
++/**/
++    119,
++/**/
++    118,
++/**/
++    117,
++/**/
++    116,
++/**/
++    115,
++/**/
++    114,
++/**/
++    113,
++/**/
++    112,
++/**/
++    111,
++/**/
++    110,
++/**/
++    109,
++/**/
++    108,
++/**/
++    107,
++/**/
++    106,
++/**/
++    105,
++/**/
++    104,
++/**/
++    103,
++/**/
++    102,
++/**/
++    101,
++/**/
++    100,
++/**/
++    99,
++/**/
++    98,
++/**/
++    97,
++/**/
++    96,
++/**/
++    95,
++/**/
++    94,
++/**/
++    93,
++/**/
++    90,
++/**/
++    89,
++/**/
++    87,
++/**/
++    86,
++/**/
++    85,
++/**/
++    84,
++/**/
++    83,
++/**/
++    82,
++/**/
++    81,
++/**/
++    79,
++/**/
++    78,
++/**/
++    77,
++/**/
++    76,
++/**/
++    75,
++/**/
++    74,
++/**/
++    73,
++/**/
++    71,
++/**/
++    69,
++/**/
++    68,
++/**/
++    67,
++/**/
++    66,
++/**/
++    64,
++/**/
++    63,
++/**/
++    62,
++/**/
++    61,
++/**/
++    60,
++/**/
++    59,
++/**/
++    58,
++/**/
++    57,
++/**/
++    56,
++/**/
++    55,
++/**/
++    54,
++/**/
++    53,
++/**/
++    52,
++/**/
++    51,
++/**/
++    50,
++/**/
++    49,
++/**/
++    48,
++/**/
++    47,
++/**/
++    46,
++/**/
++    45,
++/**/
++    44,
++/**/
++    43,
++/**/
++    42,
++/**/
++    40,
++/**/
++    39,
++/**/
++    38,
++/**/
++    37,
++/**/
++    36,
++/**/
++    35,
++/**/
++    34,
++/**/
++    33,
++/**/
++    32,
++/**/
++    31,
++/**/
++    30,
++/**/
++    29,
++/**/
++    28,
++/**/
++    27,
++/**/
++    26,
++/**/
++    25,
++/**/
++    24,
++/**/
++    23,
++/**/
++    22,
++/**/
++    21,
++/**/
++    20,
++/**/
++    19,
++/**/
++    18,
++/**/
++    17,
++/**/
++    16,
++/**/
++    15,
++/**/
++    14,
++/**/
++    13,
++/**/
++    12,
++/**/
++    11,
++/**/
++    10,
++/**/
++    9,
++/**/
++    8,
++/**/
++    6,
++/**/
++    5,
++/**/
++    4,
++/**/
++    2,
++/**/
++    1,
++/**/
+     0
+ };
+ 
+diff -Naur vim71.orig/src/vim.h vim71/src/vim.h
+--- vim71.orig/src/vim.h	2007-05-12 05:53:29.000000000 -0400
++++ vim71/src/vim.h	2007-12-20 23:57:45.000000000 -0500
+@@ -1380,8 +1380,14 @@
+ #endif
+ 
+ #ifdef FEAT_MBYTE
+-# define MB_STRICMP(d, s)	(has_mbyte ? mb_strnicmp((char_u *)(d), (char_u *)(s), (int)MAXCOL) : STRICMP((d), (s)))
+-# define MB_STRNICMP(d, s, n)	(has_mbyte ? mb_strnicmp((char_u *)(d), (char_u *)(s), (int)(n)) : STRNICMP((d), (s), (n)))
++/* We need to call mb_stricmp() even when we aren't dealing with a multi-byte
++ * encoding because mb_stricmp() takes care of all ascii and non-ascii
++ * encodings, including characters with umluats in latin1, etc., while
++ * STRICMP() only handles the system locale version, which often does not
++ * handle non-ascii properly. */
++
++# define MB_STRICMP(d, s)	mb_strnicmp((char_u *)(d), (char_u *)(s), (int)MAXCOL)
++# define MB_STRNICMP(d, s, n)	mb_strnicmp((char_u *)(d), (char_u *)(s), (int)(n))
+ #else
+ # define MB_STRICMP(d, s)	STRICMP((d), (s))
+ # define MB_STRNICMP(d, s, n)	STRNICMP((d), (s), (n))
+diff -Naur vim71.orig/src/vimtutor vim71/src/vimtutor
+--- vim71.orig/src/vimtutor	2004-06-07 10:32:27.000000000 -0400
++++ vim71/src/vimtutor	2007-12-20 23:57:06.000000000 -0500
+@@ -39,18 +39,22 @@
+ # remove the copy of the tutor on exit
+ trap "rm -rf $TODELETE" 0 1 2 3 9 11 13 15
+ 
+-# Vim could be called "vim" or "vi".  Also check for "vim6", for people who
+-# have Vim 5.x installed as "vim" and Vim 6.0 as "vim6".
+-testvim=`which vim6 2>/dev/null`
+-if test -f "$testvim"; then
+-	VIM=vim6
+-else
+-	testvim=`which vim`
++# Vim could be called "vim" or "vi".  Also check for "vimN", for people who
++# have Vim installed with its version number.
++# We anticipate up to a future Vim 8 version :-).
++seq="vim vim8 vim75 vim74 vim73 vim72 vim71 vim70 vim7 vim6 vi"
++for i in $seq; do
++	testvim=`which $i 2>/dev/null`
+ 	if test -f "$testvim"; then
+-		VIM=vim
+-	else
+-		VIM=vi
++		VIM=$i
++		break
+ 	fi
++done
++
++# When no Vim version was found fall back to "vim", you'll get an error message
++# below.
++if test -z "$VIM"; then
++	VIM=vim
+ fi
+ 
+ # Use Vim to copy the tutor, it knows the value of $VIMRUNTIME
+diff -Naur vim71.orig/src/window.c vim71/src/window.c
+--- vim71.orig/src/window.c	2007-05-07 15:25:30.000000000 -0400
++++ vim71/src/window.c	2007-12-20 23:59:05.000000000 -0500
+@@ -75,6 +75,7 @@
+ static win_T *restore_snapshot_rec __ARGS((frame_T *sn, frame_T *fr));
+ 
+ #endif /* FEAT_WINDOWS */
++
+ static win_T *win_alloc __ARGS((win_T *after));
+ static void win_new_height __ARGS((win_T *, int));
+ 
+@@ -583,7 +584,7 @@
+ 		++no_mapping;
+ 		++allow_keys;   /* no mapping for xchar, but allow key codes */
+ 		if (xchar == NUL)
+-		    xchar = safe_vgetc();
++		    xchar = plain_vgetc();
+ #ifdef FEAT_LANGMAP
+ 		LANGMAP_ADJUST(xchar, TRUE);
+ #endif
+@@ -732,7 +733,6 @@
+     if (flags & WSP_VERT)
+     {
+ 	layout = FR_ROW;
+-	do_equal = (p_ea && new_size == 0 && *p_ead != 'v');
+ 
+ 	/*
+ 	 * Check if we are able to split the current window and compute its
+@@ -769,16 +769,31 @@
+ 	 * instead, if possible. */
+ 	if (oldwin->w_p_wfw)
+ 	    win_setwidth_win(oldwin->w_width + new_size, oldwin);
++
++	/* Only make all windows the same width if one of them (except oldwin)
++	 * is wider than one of the split windows. */
++	if (!do_equal && p_ea && size == 0 && *p_ead != 'v'
++	   && oldwin->w_frame->fr_parent != NULL)
++	{
++	    frp = oldwin->w_frame->fr_parent->fr_child;
++	    while (frp != NULL)
++	    {
++		if (frp->fr_win != oldwin && frp->fr_win != NULL
++			&& (frp->fr_win->w_width > new_size
++			    || frp->fr_win->w_width > oldwin->w_width
++						   - new_size - STATUS_HEIGHT))
++		{
++		    do_equal = TRUE;
++		    break;
++		}
++		frp = frp->fr_next;
++	    }
++	}
+     }
+     else
+ #endif
+     {
+ 	layout = FR_COL;
+-	do_equal = (p_ea && new_size == 0
+-#ifdef FEAT_VERTSPLIT
+-		&& *p_ead != 'h'
+-#endif
+-		);
+ 
+ 	/*
+ 	 * Check if we are able to split the current window and compute its
+@@ -831,6 +846,29 @@
+ 	    if (need_status)
+ 		oldwin_height -= STATUS_HEIGHT;
+ 	}
++
++	/* Only make all windows the same height if one of them (except oldwin)
++	 * is higher than one of the split windows. */
++	if (!do_equal && p_ea && size == 0
++#ifdef FEAT_VERTSPLIT
++		&& *p_ead != 'h'
++#endif
++	   && oldwin->w_frame->fr_parent != NULL)
++	{
++	    frp = oldwin->w_frame->fr_parent->fr_child;
++	    while (frp != NULL)
++	    {
++		if (frp->fr_win != oldwin && frp->fr_win != NULL
++			&& (frp->fr_win->w_height > new_size
++			    || frp->fr_win->w_height > oldwin_height - new_size
++							      - STATUS_HEIGHT))
++		{
++		    do_equal = TRUE;
++		    break;
++		}
++		frp = frp->fr_next;
++	    }
++	}
+     }
+ 
+     /*
+@@ -1253,7 +1291,7 @@
+      * Don't execute autocommands while creating the windows.  Must do that
+      * when putting the buffers in the windows.
+      */
+-    ++autocmd_block;
++    block_autocmds();
+ #endif
+ 
+     /* todo is number of windows left to create */
+@@ -1275,7 +1313,7 @@
+ 	}
+ 
+ #ifdef FEAT_AUTOCMD
+-    --autocmd_block;
++    unblock_autocmds();
+ #endif
+ 
+     /* return actual number of windows */
+@@ -2120,7 +2158,7 @@
+ 	if (wp->w_p_pvw || bt_quickfix(wp->w_buffer))
+ 	{
+ 	    /*
+-	     * The cursor goes to the preview or the quickfix window, try
++	     * If the cursor goes to the preview or the quickfix window, try
+ 	     * finding another window to go to.
+ 	     */
+ 	    for (;;)
+@@ -2307,7 +2345,6 @@
+     frame_T	*frp, *frp2, *frp3;
+     frame_T	*frp_close = win->w_frame;
+     win_T	*wp;
+-    int		old_size = 0;
+ 
+     /*
+      * If there is only one window there is nothing to remove.
+@@ -2328,33 +2365,77 @@
+     if (frp_close->fr_parent->fr_layout == FR_COL)
+     {
+ #endif
+-	/* When 'winfixheight' is set, remember its old size and restore
+-	 * it later (it's a simplistic solution...).  Don't do this if the
+-	 * window will occupy the full height of the screen. */
+-	if (frp2->fr_win != NULL
+-		&& (frp2->fr_next != NULL || frp2->fr_prev != NULL)
+-		&& frp2->fr_win->w_p_wfh)
+-	    old_size = frp2->fr_win->w_height;
++	/* When 'winfixheight' is set, try to find another frame in the column
++	 * (as close to the closed frame as possible) to distribute the height
++	 * to. */
++	if (frp2->fr_win != NULL && frp2->fr_win->w_p_wfh)
++	{
++	    frp = frp_close->fr_prev;
++	    frp3 = frp_close->fr_next;
++	    while (frp != NULL || frp3 != NULL)
++	    {
++		if (frp != NULL)
++		{
++		    if (frp->fr_win != NULL && !frp->fr_win->w_p_wfh)
++		    {
++			frp2 = frp;
++			wp = frp->fr_win;
++			break;
++		    }
++		    frp = frp->fr_prev;
++		}
++		if (frp3 != NULL)
++		{
++		    if (frp3->fr_win != NULL && !frp3->fr_win->w_p_wfh)
++		    {
++			frp2 = frp3;
++			wp = frp3->fr_win;
++			break;
++		    }
++		    frp3 = frp3->fr_next;
++		}
++	    }
++	}
+ 	frame_new_height(frp2, frp2->fr_height + frp_close->fr_height,
+ 			    frp2 == frp_close->fr_next ? TRUE : FALSE, FALSE);
+-	if (old_size != 0)
+-	    win_setheight_win(old_size, frp2->fr_win);
+ #ifdef FEAT_VERTSPLIT
+ 	*dirp = 'v';
+     }
+     else
+     {
+-	/* When 'winfixwidth' is set, remember its old size and restore
+-	 * it later (it's a simplistic solution...).  Don't do this if the
+-	 * window will occupy the full width of the screen. */
+-	if (frp2->fr_win != NULL
+-		&& (frp2->fr_next != NULL || frp2->fr_prev != NULL)
+-		&& frp2->fr_win->w_p_wfw)
+-	    old_size = frp2->fr_win->w_width;
++	/* When 'winfixwidth' is set, try to find another frame in the column
++	 * (as close to the closed frame as possible) to distribute the width
++	 * to. */
++	if (frp2->fr_win != NULL && frp2->fr_win->w_p_wfw)
++	{
++	    frp = frp_close->fr_prev;
++	    frp3 = frp_close->fr_next;
++	    while (frp != NULL || frp3 != NULL)
++	    {
++		if (frp != NULL)
++		{
++		    if (frp->fr_win != NULL && !frp->fr_win->w_p_wfw)
++		    {
++			frp2 = frp;
++			wp = frp->fr_win;
++			break;
++		    }
++		    frp = frp->fr_prev;
++		}
++		if (frp3 != NULL)
++		{
++		    if (frp3->fr_win != NULL && !frp3->fr_win->w_p_wfw)
++		    {
++			frp2 = frp3;
++			wp = frp3->fr_win;
++			break;
++		    }
++		    frp3 = frp3->fr_next;
++		}
++	    }
++	}
+ 	frame_new_width(frp2, frp2->fr_width + frp_close->fr_width,
+ 			    frp2 == frp_close->fr_next ? TRUE : FALSE, FALSE);
+-	if (old_size != 0)
+-	    win_setwidth_win(old_size, frp2->fr_win);
+ 	*dirp = 'h';
+     }
+ #endif
+@@ -3334,7 +3415,7 @@
+      * Don't execute autocommands while creating the tab pages.  Must do that
+      * when putting the buffers in the windows.
+      */
+-    ++autocmd_block;
++    block_autocmds();
+ #endif
+ 
+     for (todo = count - 1; todo > 0; --todo)
+@@ -3342,7 +3423,7 @@
+ 	    break;
+ 
+ #ifdef FEAT_AUTOCMD
+-    --autocmd_block;
++    unblock_autocmds();
+ #endif
+ 
+     /* return actual number of tab pages */
+@@ -4081,7 +4162,7 @@
+ 	/* Don't execute autocommands while the window is not properly
+ 	 * initialized yet.  gui_create_scrollbar() may trigger a FocusGained
+ 	 * event. */
+-	++autocmd_block;
++	block_autocmds();
+ #endif
+ 	/*
+ 	 * link the window in the window list
+@@ -4126,7 +4207,11 @@
+ 	foldInitWin(newwin);
+ #endif
+ #ifdef FEAT_AUTOCMD
+-	--autocmd_block;
++	unblock_autocmds();
++#endif
++#ifdef FEAT_SEARCH_EXTRA
++	newwin->w_match_head = NULL;
++	newwin->w_next_match_id = 4;
+ #endif
+     }
+     return newwin;
+@@ -4147,7 +4232,7 @@
+ #ifdef FEAT_AUTOCMD
+     /* Don't execute autocommands while the window is halfway being deleted.
+      * gui_mch_destroy_scrollbar() may trigger a FocusGained event. */
+-    ++autocmd_block;
++    block_autocmds();
+ #endif
+ 
+ #ifdef FEAT_MZSCHEME
+@@ -4185,11 +4270,11 @@
+ 	vim_free(wp->w_tagstack[i].tagname);
+ 
+     vim_free(wp->w_localdir);
++
+ #ifdef FEAT_SEARCH_EXTRA
+-    vim_free(wp->w_match[0].regprog);
+-    vim_free(wp->w_match[1].regprog);
+-    vim_free(wp->w_match[2].regprog);
++    clear_matches(wp);
+ #endif
++
+ #ifdef FEAT_JUMPLIST
+     free_jumplist(wp);
+ #endif
+@@ -4210,7 +4295,7 @@
+     vim_free(wp);
+ 
+ #ifdef FEAT_AUTOCMD
+-    --autocmd_block;
++    unblock_autocmds();
+ #endif
+ }
+ 
+@@ -5438,6 +5523,7 @@
+ 		{
+ 		    EMSG(_(e_noroom));
+ 		    p_ch = old_p_ch;
++		    curtab->tp_ch_used = p_ch;
+ 		    cmdline_row = Rows - p_ch;
+ 		    break;
+ 		}
+@@ -6174,3 +6260,175 @@
+     return FALSE;
+ }
+ #endif
++
++#if defined(FEAT_SEARCH_EXTRA) || defined(PROTO)
++/*
++ * Add match to the match list of window 'wp'.  The pattern 'pat' will be
++ * highligted with the group 'grp' with priority 'prio'.
++ * Optionally, a desired ID 'id' can be specified (greater than or equal to 1).
++ * If no particular ID is desired, -1 must be specified for 'id'.
++ * Return ID of added match, -1 on failure.
++ */
++    int
++match_add(wp, grp, pat, prio, id)
++    win_T	*wp;
++    char_u	*grp;
++    char_u	*pat;
++    int		prio;
++    int		id;
++{
++    matchitem_T *cur;
++    matchitem_T *prev;
++    matchitem_T *m;
++    int		hlg_id;
++    regprog_T	*regprog;
++
++    if (*grp == NUL || *pat == NUL)
++	return -1;
++    if (id < -1 || id == 0)
++    {
++	EMSGN("E799: Invalid ID: %ld (must be greater than or equal to 1)", id);
++	return -1;
++    }
++    if (id != -1)
++    {
++	cur = wp->w_match_head;
++	while (cur != NULL)
++	{
++	    if (cur->id == id)
++	    {
++		EMSGN("E801: ID already taken: %ld", id);
++		return -1;
++	    }
++	    cur = cur->next;
++	}
++    }
++    if ((hlg_id = syn_namen2id(grp, STRLEN(grp))) == 0)
++    {
++	EMSG2(_(e_nogroup), grp);
++	return -1;
++    }
++    if ((regprog = vim_regcomp(pat, RE_MAGIC)) == NULL)
++    {
++	EMSG2(_(e_invarg2), pat);
++	return -1;
++    }
++
++    /* Find available match ID. */
++    while (id == -1)
++    {
++	cur = wp->w_match_head;
++	while (cur != NULL && cur->id != wp->w_next_match_id)
++	    cur = cur->next;
++	if (cur == NULL)
++	    id = wp->w_next_match_id;
++	wp->w_next_match_id++;
++    }
++
++    /* Build new match. */
++    m = (matchitem_T *)alloc(sizeof(matchitem_T));
++    m->id = id;
++    m->priority = prio;
++    m->pattern = vim_strsave(pat);
++    m->hlg_id = hlg_id;
++    m->match.regprog = regprog;
++    m->match.rmm_ic = FALSE;
++    m->match.rmm_maxcol = 0;
++
++    /* Insert new match.  The match list is in ascending order with regard to
++     * the match priorities. */
++    cur = wp->w_match_head;
++    prev = cur;
++    while (cur != NULL && prio >= cur->priority)
++    {
++	prev = cur;
++	cur = cur->next;
++    }
++    if (cur == prev)
++	wp->w_match_head = m;
++    else
++	prev->next = m;
++    m->next = cur;
++
++    redraw_later(SOME_VALID);
++    return id;
++}
++
++/*
++ * Delete match with ID 'id' in the match list of window 'wp'.
++ * Print error messages if 'perr' is TRUE.
++ */
++    int
++match_delete(wp, id, perr)
++    win_T	*wp;
++    int		id;
++    int		perr;
++{
++    matchitem_T *cur = wp->w_match_head;
++    matchitem_T *prev = cur;
++
++    if (id < 1)
++    {
++	if (perr == TRUE)
++	    EMSGN("E802: Invalid ID: %ld (must be greater than or equal to 1)",
++									  id);
++	return -1;
++    }
++    while (cur != NULL && cur->id != id)
++    {
++	prev = cur;
++	cur = cur->next;
++    }
++    if (cur == NULL)
++    {
++	if (perr == TRUE)
++	    EMSGN("E803: ID not found: %ld", id);
++	return -1;
++    }
++    if (cur == prev)
++	wp->w_match_head = cur->next;
++    else
++	prev->next = cur->next;
++    vim_free(cur->match.regprog);
++    vim_free(cur->pattern);
++    vim_free(cur);
++    redraw_later(SOME_VALID);
++    return 0;
++}
++
++/*
++ * Delete all matches in the match list of window 'wp'.
++ */
++    void
++clear_matches(wp)
++    win_T	*wp;
++{
++    matchitem_T *m;
++
++    while (wp->w_match_head != NULL)
++    {
++	m = wp->w_match_head->next;
++	vim_free(wp->w_match_head->match.regprog);
++	vim_free(wp->w_match_head->pattern);
++	vim_free(wp->w_match_head);
++	wp->w_match_head = m;
++    }
++    redraw_later(SOME_VALID);
++}
++
++/*
++ * Get match from ID 'id' in window 'wp'.
++ * Return NULL if match not found.
++ */
++    matchitem_T *
++get_match(wp, id)
++    win_T	*wp;
++    int		id;
++{
++    matchitem_T *cur = wp->w_match_head;
++
++    while (cur != NULL && cur->id != id)
++	cur = cur->next;
++    return cur;
++}
++#endif
+diff -Naur vim71.orig/src/xxd/xxd.c vim71/src/xxd/xxd.c
+--- vim71.orig/src/xxd/xxd.c	2007-05-07 15:41:57.000000000 -0400
++++ vim71/src/xxd/xxd.c	2007-12-20 23:59:57.000000000 -0500
+@@ -212,7 +212,7 @@
+ 
+ #define TRY_SEEK	/* attempt to use lseek, or skip forward by reading */
+ #define COLS 256	/* change here, if you ever need more columns */
+-#define LLEN (9 + (5*COLS-1)/2 + 2 + COLS)
++#define LLEN (11 + (9*COLS-1)/1 + COLS + 2)
+ 
+ char hexxa[] = "0123456789abcdef0123456789ABCDEF", *hexx = hexxa;
+ 
+@@ -590,7 +590,8 @@
+       default:			octspergrp = 0; break;
+       }
+ 
+-  if (cols < 1 || (!hextype && (cols > COLS)))
++  if (cols < 1 || ((hextype == HEX_NORMAL || hextype == HEX_BITS)
++							    && (cols > COLS)))
+     {
+       fprintf(stderr, "%s: invalid number of columns (max. %d).\n", pname, COLS);
+       exit(1);
+@@ -750,6 +751,7 @@
+ 	}
+       if (ebcdic)
+ 	e = (e < 64) ? '.' : etoa64[e-64];
++      /* When changing this update definition of LLEN above. */
+       l[11 + (grplen * cols - 1)/octspergrp + p] =
+ #ifdef __MVS__
+ 	  (e >= 64)
Index: patches/vim-7.1-branch_update-3.patch
===================================================================
--- patches/vim-7.1-branch_update-3.patch	(revision 37882632fe426710ff21d4b4b1882f9487f5e3fb)
+++ 	(revision )
@@ -1,18261 +1,0 @@
-Submitted By: Jim Gifford (jim at linuxfromscratch dot org)
-Date: 06-18-2008
-Initial Package Version: 7.1
-Origin: Upstream
-Upstream Status: Applied
-Description: Contains all upstream patches up to 7.1.315
-             The following patches were skipped
-             003 007 041 065 070 072 080 088 091 092 124 126 128 129 134 146 158 168 196 204 275 278 280 282 283 285 312
-
-diff -Naur vim71.orig/Filelist vim71/Filelist
---- vim71.orig/Filelist	2007-05-06 11:00:23.000000000 -0400
-+++ vim71/Filelist	2008-06-18 06:56:41.000000000 -0400
-@@ -193,6 +193,7 @@
- 		src/vim_icon.xbm \
- 		src/vim_mask.xbm \
- 		src/vimtutor \
-+		src/gvimtutor \
- 		src/which.sh \
- 		src/workshop.c \
- 		src/workshop.h \
-diff -Naur vim71.orig/runtime/autoload/gzip.vim vim71/runtime/autoload/gzip.vim
---- vim71.orig/runtime/autoload/gzip.vim	2007-05-10 07:40:14.000000000 -0400
-+++ vim71/runtime/autoload/gzip.vim	2008-06-18 06:56:50.000000000 -0400
-@@ -1,6 +1,6 @@
- " Vim autoload file for editing compressed files.
- " Maintainer: Bram Moolenaar <Bram@vim.org>
--" Last Change: 2007 May 10
-+" Last Change: 2008 May 29
- 
- " These functions are used by the gzip plugin.
- 
-@@ -73,8 +73,15 @@
-   let empty = line("'[") == 1 && line("']") == line("$")
-   let tmp = tempname()
-   let tmpe = tmp . "." . expand("<afile>:e")
-+  if exists('*fnameescape')
-+    let tmp_esc = fnameescape(tmp)
-+    let tmpe_esc = fnameescape(tmpe)
-+  else
-+    let tmp_esc = escape(tmp, ' ')
-+    let tmpe_esc = escape(tmpe, ' ')
-+  endif
-   " write the just read lines to a temp file "'[,']w tmp.gz"
--  execute "silent '[,']w " . escape(tmpe, ' ')
-+  execute "silent '[,']w " . tmpe_esc
-   " uncompress the temp file: call system("gzip -dn tmp.gz")
-   call system(a:cmd . " " . s:escape(tmpe))
-   if !filereadable(tmp)
-@@ -95,12 +102,12 @@
-     setlocal nobin
-     if exists(":lockmarks")
-       if empty
--	execute "silent lockmarks " . l . "r ++edit " . tmp
-+	execute "silent lockmarks " . l . "r ++edit " . tmp_esc
-       else
--	execute "silent lockmarks " . l . "r " . tmp
-+	execute "silent lockmarks " . l . "r " . tmp_esc
-       endif
-     else
--      execute "silent " . l . "r " . tmp
-+      execute "silent " . l . "r " . tmp_esc
-     endif
- 
-     " if buffer became empty, delete trailing blank line
-@@ -110,8 +117,8 @@
-     endif
-     " delete the temp file and the used buffers
-     call delete(tmp)
--    silent! exe "bwipe " . tmp
--    silent! exe "bwipe " . tmpe
-+    silent! exe "bwipe " . tmp_esc
-+    silent! exe "bwipe " . tmpe_esc
-   endif
- 
-   " Restore saved option values.
-@@ -124,10 +131,15 @@
- 
-   " When uncompressed the whole buffer, do autocommands
-   if ok && empty
-+    if exists('*fnameescape')
-+      let fname = fnameescape(expand("%:r"))
-+    else
-+      let fname = escape(expand("%:r"), " \t\n*?[{`$\\%#'\"|!<")
-+    endif
-     if &verbose >= 8
--      execute "doau BufReadPost " . expand("%:r")
-+      execute "doau BufReadPost " . fname
-     else
--      execute "silent! doau BufReadPost " . expand("%:r")
-+      execute "silent! doau BufReadPost " . fname
-     endif
-   endif
- endfun
-diff -Naur vim71.orig/runtime/doc/Makefile vim71/runtime/doc/Makefile
---- vim71.orig/runtime/doc/Makefile	2006-11-07 15:59:05.000000000 -0500
-+++ vim71/runtime/doc/Makefile	2008-06-18 06:55:02.000000000 -0400
-@@ -301,7 +301,7 @@
- # Use Vim to generate the tags file.  Can only be used when Vim has been
- # compiled and installed.  Supports multiple languages.
- vimtags: $(DOCS)
--	$(VIMEXE) -u NONE -esX -c "helptags ." -c quit
-+	$(VIMEXE) -u NONE -esX -c "helptags ++t ." -c quit
- 
- # Use "doctags" to generate the tags file.  Only works for English!
- tags: doctags $(DOCS)
-diff -Naur vim71.orig/runtime/doc/change.txt vim71/runtime/doc/change.txt
---- vim71.orig/runtime/doc/change.txt	2007-05-12 06:18:46.000000000 -0400
-+++ vim71/runtime/doc/change.txt	2008-06-18 06:51:08.000000000 -0400
-@@ -1571,6 +1571,10 @@
- 			in their original order, right before the sorted
- 			lines.
- 
-+			If {pattern} is empty (e.g. // is specified), the
-+			last search pattern is used.  This allows trying out
-+			a pattern first.
-+
- Note that using ":sort" with ":global" doesn't sort the matching lines, it's
- quite useless.
- 
-diff -Naur vim71.orig/runtime/doc/cmdline.txt vim71/runtime/doc/cmdline.txt
---- vim71.orig/runtime/doc/cmdline.txt	2007-05-12 06:18:46.000000000 -0400
-+++ vim71/runtime/doc/cmdline.txt	2008-06-18 06:54:39.000000000 -0400
-@@ -1,4 +1,4 @@
--*cmdline.txt*   For Vim version 7.1.  Last change: 2006 Jul 18
-+*cmdline.txt*   For Vim version 7.1.  Last change: 2008 Jan 04
- 
- 
- 		  VIM REFERENCE MANUAL    by Bram Moolenaar
-@@ -316,7 +316,7 @@
- command-line is shown.  (Note: the shifted arrow keys do not work on all
- terminals)
- 
--							*his* *:history*
-+							*:his* *:history*
- :his[tory]	Print the history of last entered commands.
- 		{not in Vi}
- 		{not available when compiled without the |+cmdline_hist|
-@@ -447,6 +447,11 @@
- 
- To completely ignore files with some extension use 'wildignore'.
- 
-+To match only files that end at the end of the typed text append a "$".  For
-+example, to match only files that end in ".c": >
-+	:e *.c$
-+This will not match a file ending in ".cpp".  Without the "$" it does match.
-+
- The old value of an option can be obtained by hitting 'wildchar' just after
- the '='.  For example, typing 'wildchar' after ":set dir=" will insert the
- current value of 'dir'.  This overrules file name completion for the options
-diff -Naur vim71.orig/runtime/doc/eval.txt vim71/runtime/doc/eval.txt
---- vim71.orig/runtime/doc/eval.txt	2007-05-12 06:18:46.000000000 -0400
-+++ vim71/runtime/doc/eval.txt	2008-06-18 06:56:43.000000000 -0400
-@@ -1,4 +1,4 @@
--*eval.txt*      For Vim version 7.1.  Last change: 2007 May 11
-+*eval.txt*      For Vim version 7.1.  Last change: 2008 May 28
- 
- 
- 		  VIM REFERENCE MANUAL    by Bram Moolenaar
-@@ -1401,10 +1401,24 @@
- 		This is the screen column number, like with |virtcol()|.  The
- 		value is zero when there was no mouse button click.
- 
-+					*v:operator* *operator-variable*
-+v:operator	The last operator given in Normal mode.  This is a single
-+		character except for commands starting with <g> or <z>,
-+		in which case it is two characters.  Best used alongside
-+		|v:prevcount| and |v:register|.  Useful if you want to cancel
-+		Operator-pending mode and then use the operator, e.g.: >
-+			:omap O <Esc>:call MyMotion(v:operator)<CR>
-+<		The value remains set until another operator is entered, thus
-+		don't expect it to be empty.
-+		v:operator is not set for |:delete|, |:yank| or other Ex
-+		commands.
-+		Read-only.
-+
- 					*v:prevcount* *prevcount-variable*
- v:prevcount	The count given for the last but one Normal mode command.
- 		This is the v:count value of the previous command.  Useful if
--		you want to cancel Visual mode and then use the count. >
-+		you want to cancel Visual or Operator-pending mode and then
-+		use the count, e.g.: >
- 			:vmap % <Esc>:call MyFilter(v:prevcount)<CR>
- <		Read-only.
- 
-@@ -1557,6 +1571,7 @@
- changenr()			Number  current change number
- char2nr( {expr})		Number	ASCII value of first char in {expr}
- cindent( {lnum})		Number	C indent for line {lnum}
-+clearmatches()			None	clear all matches
- col( {expr})			Number	column nr of cursor or mark
- complete({startcol}, {matches})	String  set Insert mode completion
- complete_add( {expr})		Number	add completion match
-@@ -1594,6 +1609,7 @@
- 				String	find directory {name} in {path}
- findfile( {name}[, {path}[, {count}]])
- 				String	find file {name} in {path}
-+fnameescape( {fname})		String	escape special characters in {fname}
- fnamemodify( {fname}, {mods})	String	modify file name
- foldclosed( {lnum})		Number	first line of fold at {lnum} if closed
- foldclosedend( {lnum})		Number	last line of fold at {lnum} if closed
-@@ -1602,7 +1618,7 @@
- foldtextresult( {lnum})		String	text for closed fold at {lnum}
- foreground( )			Number	bring the Vim window to the foreground
- function( {name})		Funcref reference to function {name}
--garbagecollect()		none	free memory, breaking cyclic references
-+garbagecollect( [at_exit])	none	free memory, breaking cyclic references
- get( {list}, {idx} [, {def}])	any	get item {idx} from {list} or {def}
- get( {dict}, {key} [, {def}])	any	get item {key} from {dict} or {def}
- getbufline( {expr}, {lnum} [, {end}])
-@@ -1622,6 +1638,8 @@
- getline( {lnum})		String	line {lnum} of current buffer
- getline( {lnum}, {end})		List	lines {lnum} to {end} of current buffer
- getloclist({nr})		List	list of location list items
-+getmatches()			List	list of current matches
-+getpid()			Number	process ID of Vim
- getpos( {expr})			List	position of cursor, mark, etc.
- getqflist()			List	list of quickfix items
- getreg( [{regname} [, 1]])	String	contents of register
-@@ -1676,7 +1694,10 @@
- 				String	check for mappings matching {name}
- match( {expr}, {pat}[, {start}[, {count}]])
- 				Number	position where {pat} matches in {expr}
-+matchadd( {group}, {pattern}[, {priority}[, {id}]])
-+				Number	highlight {pattern} with {group}
- matcharg( {nr})			List	arguments of |:match|
-+matchdelete( {id})		Number	delete match identified by {id}
- matchend( {expr}, {pat}[, {start}[, {count}]])
- 				Number	position where {pat} ends in {expr}
- matchlist( {expr}, {pat}[, {start}[, {count}]])
-@@ -1714,14 +1735,15 @@
- repeat( {expr}, {count})	String	repeat {expr} {count} times
- resolve( {filename})		String	get filename a shortcut points to
- reverse( {list})		List	reverse {list} in-place
--search( {pattern} [, {flags}])	Number	search for {pattern}
-+search( {pattern} [, {flags} [, {stopline} [, {timeout}]]])
-+				Number	search for {pattern}
- searchdecl({name} [, {global} [, {thisblock}]])
- 				Number  search for variable declaration
--searchpair( {start}, {middle}, {end} [, {flags} [, {skip} [, {stopline}]]])
-+searchpair( {start}, {middle}, {end} [, {flags} [, {skip} [...]]])
- 				Number	search for other end of start/end pair
--searchpairpos( {start}, {middle}, {end} [, {flags} [, {skip} [, {stopline}]]])
-+searchpairpos( {start}, {middle}, {end} [, {flags} [, {skip} [...]]])
- 				List	search for other end of start/end pair
--searchpos( {pattern} [, {flags} [, {stopline}]])
-+searchpos( {pattern} [, {flags} [, {stopline} [, {timeout}]]])
- 				List	search for {pattern}
- server2client( {clientid}, {string})
- 				Number	send reply string
-@@ -1731,6 +1753,7 @@
- setline( {lnum}, {line})	Number	set line {lnum} to {line}
- setloclist( {nr}, {list}[, {action}])
- 				Number	modify location list using {list}
-+setmatches( {list})		Number	restore a list of matches
- setpos( {expr}, {list})		none	set the {expr} position to {list}
- setqflist( {list}[, {action}])	Number	modify quickfix list using {list}
- setreg( {n}, {v}[, {opt}])	Number	set register to value and type
-@@ -1765,6 +1788,7 @@
- synIDattr( {synID}, {what} [, {mode}])
- 				String	attribute {what} of syntax ID {synID}
- synIDtrans( {synID})		Number	translated syntax ID of {synID}
-+synstack({lnum}, {col})		List    stack of syntax IDs at {lnum} and {col}
- system( {expr} [, {input}])	String	output of shell command/filter {expr}
- tabpagebuflist( [{arg}])	List	list of buffer numbers in tab page
- tabpagenr( [{arg}])		Number	number of current or last tab page
-@@ -2012,6 +2036,10 @@
- 		feature, -1 is returned.
- 		See |C-indenting|.
- 
-+clearmatches()						*clearmatches()*
-+		Clears all matches previously defined by |matchadd()| and the
-+		|:match| commands.
-+
- 							*col()*
- col({expr})	The result is a Number, which is the byte index of the column
- 		position given with {expr}.  The accepted positions are:
-@@ -2020,6 +2048,10 @@
- 			    number of characters in the cursor line plus one)
- 		    'x	    position of mark x (if the mark is not set, 0 is
- 			    returned)
-+		Additionally {expr} can be [lnum, col]: a |List| with the line
-+		and column number. Most useful when the column is "$", to get
-+		the las column of a specific line.  When "lnum" or "col" is
-+		out of range then col() returns zero.
- 		To get the line number use |line()|.  To get both use
- 		|getpos()|.
- 		For the screen column position use |virtcol()|.
-@@ -2589,6 +2621,19 @@
- <		Searches from the directory of the current file upwards until
- 		it finds the file "tags.vim".
- 
-+fnameescape({string})					*fnameescape()*
-+		Escape {string} for use as file name command argument.  All
-+		characters that have a special meaning, such as '%' and '|'
-+		are escaped with a backslash.
-+		For most systems the characters escaped are "".  For systems
-+		where a backslash appears in a filename, it depends on the
-+		value of 'isfname'.
-+		Example: >
-+			:let fname = 'some str%nge|name'
-+			:exe "edit " . fnameescape(fname)
-+<		results in executing: >
-+			edit some\ str\%nge\|name
-+
- fnamemodify({fname}, {mods})				*fnamemodify()*
- 		Modify file name {fname} according to {mods}.  {mods} is a
- 		string of characters like it is used for file names on the
-@@ -2659,7 +2704,7 @@
- 		{name} can be a user defined function or an internal function.
- 
- 
--garbagecollect()					*garbagecollect()*
-+garbagecollect([at_exit])				*garbagecollect()*
- 		Cleanup unused |Lists| and |Dictionaries| that have circular
- 		references.  There is hardly ever a need to invoke this
- 		function, as it is automatically done when Vim runs out of
-@@ -2669,6 +2714,9 @@
- 		This is useful if you have deleted a very big |List| and/or
- 		|Dictionary| with circular references in a script that runs
- 		for a long time.
-+		When the optional "at_exit" argument is one, garbage
-+		collection will also be done when exiting Vim, if it wasn't
-+		done before.  This is useful when checking for memory leaks.
- 
- get({list}, {idx} [, {default}])			*get()*
- 		Get item {idx} from |List| {list}.  When this item is not
-@@ -2824,6 +2872,8 @@
- 		given file {fname}.
- 		If {fname} is a directory, 0 is returned.
- 		If the file {fname} can't be found, -1 is returned.
-+		If the size of {fname} is too big to fit in a Number then -2
-+		is returned.
- 
- getfontname([{name}])					*getfontname()*
- 		Without an argument returns the name of the normal font being
-@@ -2912,6 +2962,28 @@
- 		returned.  For an invalid window number {nr}, an empty list is
- 		returned. Otherwise, same as getqflist().
- 
-+getmatches()						*getmatches()*
-+		Returns a |List| with all matches previously defined by
-+		|matchadd()| and the |:match| commands.  |getmatches()| is
-+		useful in combination with |setmatches()|, as |setmatches()|
-+		can restore a list of matches saved by |getmatches()|.
-+		Example: >
-+			:echo getmatches()
-+<			[{'group': 'MyGroup1', 'pattern': 'TODO',
-+			'priority': 10, 'id': 1}, {'group': 'MyGroup2',
-+			'pattern': 'FIXME', 'priority': 10, 'id': 2}] >
-+			:let m = getmatches()
-+			:call clearmatches()
-+			:echo getmatches()
-+<			[] >
-+			:call setmatches(m)
-+			:echo getmatches()
-+<			[{'group': 'MyGroup1', 'pattern': 'TODO',
-+			'priority': 10, 'id': 1}, {'group': 'MyGroup2',
-+			'pattern': 'FIXME', 'priority': 10, 'id': 2}] >
-+			:unlet m
-+<
-+
- getqflist()						*getqflist()*
- 		Returns a list with all the current quickfix errors.  Each
- 		list item is a dictionary with these entries:
-@@ -3616,6 +3688,44 @@
- 		the pattern.  'smartcase' is NOT used.  The matching is always
- 		done like 'magic' is set and 'cpoptions' is empty.
- 
-+					*matchadd()* *E798* *E799* *E801*
-+matchadd({group}, {pattern}[, {priority}[, {id}]])
-+		Defines a pattern to be highlighted in the current window (a
-+		"match").  It will be highlighted with {group}.  Returns an
-+		identification number (ID), which can be used to delete the
-+		match using |matchdelete()|.
-+
-+		The optional {priority} argument assigns a priority to the
-+		match.  A match with a high priority will have its
-+		highlighting overrule that of a match with a lower priority.
-+		A priority is specified as an integer (negative numbers are no
-+		exception).  If the {priority} argument is not specified, the
-+		default priority is 10.  The priority of 'hlsearch' is zero,
-+		hence all matches with a priority greater than zero will
-+		overrule it.  Syntax highlighting (see 'syntax') is a separate
-+		mechanism, and regardless of the chosen priority a match will
-+		always overrule syntax highlighting.
-+
-+		The optional {id} argument allows the request for a specific
-+		match ID.  If a specified ID is already taken, an error
-+		message will appear and the match will not be added.  An ID
-+		is specified as a positive integer (zero excluded).  IDs 1, 2
-+		and 3 are reserved for |:match|, |:2match| and |:3match|,
-+		respectively.  If the {id} argument is not specified,
-+		|matchadd()| automatically chooses a free ID.
-+
-+		The number of matches is not limited, as it is the case with
-+		the |:match| commands.
-+
-+		Example: >
-+			:highlight MyGroup ctermbg=green guibg=green
-+			:let m = matchadd("MyGroup", "TODO")
-+<		Deletion of the pattern: >
-+			:call matchdelete(m)
-+
-+<		A list of matches defined by |matchadd()| and |:match| are
-+		available from |getmatches()|.  All matches can be deleted in
-+		one operation by |clearmatches()|.
- 
- matcharg({nr})							*matcharg()*
- 		Selects the {nr} match item, as set with a |:match|,
-@@ -3625,8 +3735,15 @@
- 			The pattern used.
- 		When {nr} is not 1, 2 or 3 returns an empty |List|.
- 		When there is no match item set returns ['', ''].
--		This is usef to save and restore a |:match|.
--
-+		This is useful to save and restore a |:match|.
-+		Highlighting matches using the |:match| commands are limited
-+		to three matches. |matchadd()| does not have this limitation.
-+
-+matchdelete({id})			       *matchdelete()* *E802* *E803*
-+		Deletes a match with ID {id} previously defined by |matchadd()|
-+		or one of the |:match| commands.  Returns 0 if succesfull,
-+		otherwise -1.  See example for |matchadd()|.  All matches can
-+		be deleted in one operation by |clearmatches()|.
- 
- matchend({expr}, {pat}[, {start}[, {count}]])			*matchend()*
- 		Same as match(), but return the index of first character after
-@@ -3731,6 +3848,10 @@
- 		characters.  nr2char(0) is a real NUL and terminates the
- 		string, thus results in an empty string.
- 
-+							*getpid()*
-+getpid()	Return a Number which is the process ID of the Vim process.
-+		On Unix this is a unique number.  On MS-DOS it's always zero.
-+
- 							*getpos()*
- getpos({expr})	Get the position for {expr}.  For possible values of {expr}
- 		see |line()|.
-@@ -4112,7 +4233,7 @@
- 		If you want a list to remain unmodified make a copy first: >
- 			:let revlist = reverse(copy(mylist))
- 
--search({pattern} [, {flags} [, {stopline}]])			*search()*
-+search({pattern} [, {flags} [, {stopline} [, {timeout}]]])	*search()*
- 		Search for regexp pattern {pattern}.  The search starts at the
- 		cursor position (you can use |cursor()| to set it).
- 
-@@ -4140,6 +4261,14 @@
- 			let end = search('END', '', line("w$"))
- <		When {stopline} is used and it is not zero this also implies
- 		that the search does not wrap around the end of the file.
-+		A zero value is equal to not giving the argument.
-+
-+		When the {timeout} argument is given the search stops when
-+		more than this many milli seconds have passed.  Thus when
-+		{timeout} is 500 the search stops after half a second.
-+		The value must not be negative.  A zero value is like not
-+		giving the argument.
-+		{only available when compiled with the +reltime feature}
- 
- 		If there is no match a 0 is returned and the cursor doesn't
- 		move.  No error message is given.
-@@ -4202,7 +4331,8 @@
- 			endif
- <
- 							*searchpair()*
--searchpair({start}, {middle}, {end} [, {flags} [, {skip} [, {stopline}]]])
-+searchpair({start}, {middle}, {end} [, {flags} [, {skip}
-+				[, {stopline} [, {timeout}]]]])
- 		Search for the match of a nested start-end pair.  This can be
- 		used to find the "endif" that matches an "if", while other
- 		if/endif pairs in between are ignored.
-@@ -4237,7 +4367,7 @@
- 		When evaluating {skip} causes an error the search is aborted
- 		and -1 returned.
- 
--		For {stopline} see |search()|.
-+		For {stopline} and {timeout} see |search()|.
- 
- 		The value of 'ignorecase' is used.  'magic' is ignored, the
- 		patterns are used like it's on.
-@@ -4283,7 +4413,8 @@
- 	     \ 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string"')
- <
- 							*searchpairpos()*
--searchpairpos({start}, {middle}, {end} [, {flags} [, {skip} [, {stopline}]]])
-+searchpairpos({start}, {middle}, {end} [, {flags} [, {skip}
-+				[, {stopline} [, {timeout}]]]])
- 		Same as searchpair(), but returns a |List| with the line and
- 		column position of the match. The first element of the |List|
- 		is the line number and the second element is the byte index of
-@@ -4294,7 +4425,7 @@
- <
- 		See |match-parens| for a bigger and more useful example.
- 
--searchpos({pattern} [, {flags} [, {stopline}]])		*searchpos()*
-+searchpos({pattern} [, {flags} [, {stopline} [, {timeout}]]])	*searchpos()*
- 		Same as |search()|, but returns a |List| with the line and
- 		column position of the match. The first element of the |List|
- 		is the line number and the second element is the byte index of
-@@ -4379,7 +4510,13 @@
- 		When {nr} is zero the current window is used. For a location
- 		list window, the displayed location list is modified.  For an
- 		invalid window number {nr}, -1 is returned.
--		Otherwise, same as setqflist().
-+		Otherwise, same as |setqflist()|.
-+		Also see |location-list|.
-+
-+setmatches({list})					*setmatches()*
-+		Restores a list of matches saved by |getmatches()|.  Returns 0
-+		if succesfull, otherwise -1.  All current matches are cleared
-+		before the list is restored.  See example for |getmatches()|.
- 
- 							*setpos()*
- setpos({expr}, {list})
-@@ -4405,6 +4542,9 @@
- 		character.  E.g., a position within a <Tab> or after the last
- 		character.
- 
-+		Returns 0 when the position could be set, -1 otherwise.
-+		An error message is given if {expr} is invalid.
-+
- 		Also see |getpos()|
- 
- 		This does not restore the preferred column for moving
-@@ -4845,6 +4985,20 @@
- 		highlight the character.  Highlight links given with
- 		":highlight link" are followed.
- 
-+synstack({lnum}, {col})					*synstack()*
-+		Return a |List|, which is the stack of syntax items at the
-+		position {lnum} and {col} in the current window.  Each item in
-+		the List is an ID like what |synID()| returns.
-+		The first item in the List is the outer region, following are
-+		items contained in that one.  The last one is what |synID()|
-+		returns, unless not the whole item is highlighted or it is a
-+		transparent item.
-+		This function is useful for debugging a syntax file.
-+		Example that shows the syntax stack under the cursor: >
-+			for id in synstack(line("."), col("."))
-+			   echo synIDattr(id, "name")
-+			endfor
-+
- system({expr} [, {input}])				*system()* *E677*
- 		Get the output of the shell command {expr}.
- 		When {input} is given, this string is written to a file and
-@@ -5022,14 +5176,12 @@
- 		position, the returned Number will be the column at the end of
- 		the <Tab>.  For example, for a <Tab> in column 1, with 'ts'
- 		set to 8, it returns 8.
--		For the use of {expr} see |col()|.  Additionally you can use
--		[lnum, col]: a |List| with the line and column number.  When
--		"lnum" or "col" is out of range then virtcol() returns zero.
--		When 'virtualedit' is used it can be [lnum, col, off], where
-+		For the byte position use |col()|.
-+		For the use of {expr} see |col()|.
-+		When 'virtualedit' is used {expr} can be [lnum, col, off], where
- 		"off" is the offset in screen columns from the start of the
- 		character.  E.g., a position within a <Tab> or after the last
- 		character.
--		For the byte position use |col()|.
- 		When Virtual editing is active in the current mode, a position
- 		beyond the end of the line can be returned. |'virtualedit'|
- 		The accepted positions are:
-diff -Naur vim71.orig/runtime/doc/options.txt vim71/runtime/doc/options.txt
---- vim71.orig/runtime/doc/options.txt	2007-05-12 06:18:47.000000000 -0400
-+++ vim71/runtime/doc/options.txt	2008-06-18 06:56:16.000000000 -0400
-@@ -1,4 +1,4 @@
--*options.txt*	For Vim version 7.1.  Last change: 2007 May 11
-+*options.txt*	For Vim version 7.1.  Last change: 2008 Feb 24
- 
- 
- 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
-@@ -2415,8 +2415,8 @@
- 	When mixing vertically and horizontally split windows, a minimal size
- 	is computed and some windows may be larger if there is room.  The
- 	'eadirection' option tells in which direction the size is affected.
--	Changing the height of a window can be avoided by setting
--	'winfixheight'.
-+	Changing the height and width of a window can be avoided by setting
-+	'winfixheight' and 'winfixwidth', respectively.
- 
- 						*'equalprg'* *'ep'*
- 'equalprg' 'ep'		string	(default "")
-@@ -3618,6 +3618,7 @@
- 	When you get bored looking at the highlighted matches, you can turn it
- 	off with |:nohlsearch|.  As soon as you use a search command, the
- 	highlighting comes back.
-+	'redrawtime' specifies the maximum time spend on finding matches.
- 	When the search pattern can match an end-of-line, Vim will try to
- 	highlight all of the matched text.  However, this depends on where the
- 	search starts.  This will be the first line in the window or the first
-@@ -3851,6 +3852,10 @@
- 	original position when no match is found and when pressing <Esc>.  You
- 	still need to finish the search command with <Enter> to move the
- 	cursor to the match.
-+	When compiled with the |+reltime| feature Vim only searches for about
-+	half a second.  With a complicated pattern and/or a lot of text the
-+	match may not be found.  This is to avoid that Vim hangs while you
-+	are typing the pattern.
- 	The highlighting can be set with the 'i' flag in 'highlight'.
- 	See also: 'hlsearch'.
- 	CTRL-L can be used to add one character from after the current match
-@@ -4873,7 +4878,7 @@
- 	|autocmd-osfiletypes|
- 
- 						*'paragraphs'* *'para'*
--'paragraphs' 'para'	string	(default "IPLPPPQPP LIpplpipbp")
-+'paragraphs' 'para'	string	(default "IPLPPPQPP TPHPLIPpLpItpplpipbp")
- 			global
- 	Specifies the nroff macros that separate paragraphs.  These are pairs
- 	of two letters (see |object-motions|).
-@@ -5185,6 +5190,18 @@
- 	{not in Vi:}  When using the ":view" command the 'readonly' option is
- 	set for the newly edited buffer.
- 
-+						*'redrawtime'* *'rdt'*
-+'redrawtime' 'rdt'	number	(default 2000)
-+			global
-+			{not in Vi}
-+			{only available when compiled with the |+reltime|
-+			feature}
-+	The time in milliseconds for redrawing the display.  This applies to
-+	searching for patterns for 'hlsearch' and |:match| highlighting.
-+	When redrawing takes more than this many milliseconds no further
-+	matches will be highlighted.  This is used to avoid that Vim hangs
-+	when using a very complicated pattern.
-+
- 						*'remap'* *'noremap'*
- 'remap'			boolean	(default on)
- 			global
-diff -Naur vim71.orig/runtime/doc/pattern.txt vim71/runtime/doc/pattern.txt
---- vim71.orig/runtime/doc/pattern.txt	2007-05-12 06:18:47.000000000 -0400
-+++ vim71/runtime/doc/pattern.txt	2008-06-18 06:51:23.000000000 -0400
-@@ -1212,7 +1212,10 @@
- 		{group} must exist at the moment this command is executed.
- 
- 		The {group} highlighting still applies when a character is
--		to be highlighted for 'hlsearch'.
-+		to be highlighted for 'hlsearch', as the highlighting for
-+		matches is given higher priority than that of 'hlsearch'.
-+		Syntax highlighting (see 'syntax') is also overruled by
-+		matches.
- 
- 		Note that highlighting the last used search pattern with
- 		'hlsearch' is used in all windows, while the pattern defined
-@@ -1226,8 +1229,15 @@
- 		display you may get unexpected results.  That is because Vim
- 		looks for a match in the line where redrawing starts.
- 
--		Also see |matcharg()|, it returns the highlight group and
--		pattern of a previous :match command.
-+		Also see |matcharg()|and |getmatches()|. The former returns
-+		the highlight group and pattern of a previous |:match|
-+		command.  The latter returns a list with highlight groups and
-+		patterns defined by both |matchadd()| and |:match|.
-+
-+		Highlighting matches using |:match| are limited to three
-+		matches (aside from |:match|, |:2match| and |:3match|are
-+		available). |matchadd()| does not have this limitation and in
-+		addition makes it possible to prioritize matches.
- 
- 		Another example, which highlights all characters in virtual
- 		column 72 and more: >
-diff -Naur vim71.orig/runtime/doc/pi_paren.txt vim71/runtime/doc/pi_paren.txt
---- vim71.orig/runtime/doc/pi_paren.txt	2007-05-12 06:18:47.000000000 -0400
-+++ vim71/runtime/doc/pi_paren.txt	2008-06-18 06:52:15.000000000 -0400
-@@ -12,8 +12,8 @@
- You can avoid loading this plugin by setting the "loaded_matchparen" variable: >
- 	:let loaded_matchparen = 1
- 
--The plugin installs CursorMoved autocommands to redefine the match
--highlighting.
-+The plugin installs CursorMoved, CursorMovedI and WinEnter autocommands to
-+redefine the match highlighting.
- 
- To disable the plugin after it was loaded use this command: >
- 
-diff -Naur vim71.orig/runtime/doc/usr_41.txt vim71/runtime/doc/usr_41.txt
---- vim71.orig/runtime/doc/usr_41.txt	2007-05-12 06:18:48.000000000 -0400
-+++ vim71/runtime/doc/usr_41.txt	2008-06-18 06:51:23.000000000 -0400
-@@ -763,13 +763,22 @@
- 	foldtextresult()	get the text displayed for a closed fold
- 
- Syntax and highlighting:
-+	clearmatches()		clear all matches defined by |matchadd()| and
-+				the |:match| commands
-+	getmatches()		get all matches defined by |matchadd()| and
-+				the |:match| commands
- 	hlexists()		check if a highlight group exists
- 	hlID()			get ID of a highlight group
- 	synID()			get syntax ID at a specific position
- 	synIDattr()		get a specific attribute of a syntax ID
- 	synIDtrans()		get translated syntax ID
- 	diff_hlID()		get highlight ID for diff mode at a position
-+	matchadd()		define a pattern to highlight (a "match")
- 	matcharg()		get info about |:match| arguments
-+	matchdelete()		delete a match defined by |matchadd()| or a
-+				|:match| command
-+	setmatches()		restore a list of matches saved by
-+				|getmatches()|
- 
- Spelling:
- 	spellbadword()		locate badly spelled word at or after cursor
-diff -Naur vim71.orig/runtime/doc/various.txt vim71/runtime/doc/various.txt
---- vim71.orig/runtime/doc/various.txt	2007-05-12 06:18:48.000000000 -0400
-+++ vim71/runtime/doc/various.txt	2008-06-18 06:55:02.000000000 -0400
-@@ -1,4 +1,4 @@
--*various.txt*   For Vim version 7.1.  Last change: 2007 Jan 14
-+*various.txt*   For Vim version 7.1.  Last change: 2008 Jan 11
- 
- 
- 		  VIM REFERENCE MANUAL    by Bram Moolenaar
-@@ -748,7 +748,8 @@
- 
- 					*:helpt* *:helptags*
- 				*E154* *E150* *E151* *E152* *E153* *E670*
--:helpt[ags] {dir}	Generate the help tags file(s) for directory {dir}.
-+:helpt[ags] [++t] {dir}
-+			Generate the help tags file(s) for directory {dir}.
- 			All "*.txt" and "*.??x" files in the directory are
- 			scanned for a help tag definition in between stars.
- 			The "*.??x" files are for translated docs, they
-@@ -756,6 +757,9 @@
- 			The generated tags files are sorted.
- 			When there are duplicates an error message is given.
- 			An existing tags file is silently overwritten.
-+			The optional "++t" argument forces adding the
-+			"help-tags" tag.  This is also done when the {dir} is
-+			equal to $VIMRUNTIME/doc.
- 			To rebuild the help tags in the runtime directory
- 			(requires write permission there): >
- 				:helptags $VIMRUNTIME/doc
-diff -Naur vim71.orig/runtime/doc/vimtutor.1 vim71/runtime/doc/vimtutor.1
---- vim71.orig/runtime/doc/vimtutor.1	2004-06-07 10:32:40.000000000 -0400
-+++ vim71/runtime/doc/vimtutor.1	2008-06-18 06:56:38.000000000 -0400
-@@ -3,7 +3,7 @@
- vimtutor \- the Vim tutor
- .SH SYNOPSIS
- .br
--.B vimtutor [language]
-+.B vimtutor [-g] [language]
- .SH DESCRIPTION
- .B Vimtutor
- starts the
-@@ -18,6 +18,9 @@
- .B Vim
- commands.
- .PP
-+The optional argument -g starts vimtutor with gvim rather than vim, if the
-+GUI version of vim is available, or falls back to Vim if gvim is not found.
-+.PP
- The optional [language] argument is the two-letter name of a language, like
- "it" or "es".
- If the [language] argument is missing, the language of the current locale will
-diff -Naur vim71.orig/runtime/doc/windows.txt vim71/runtime/doc/windows.txt
---- vim71.orig/runtime/doc/windows.txt	2007-05-12 06:18:49.000000000 -0400
-+++ vim71/runtime/doc/windows.txt	2008-06-18 06:51:59.000000000 -0400
-@@ -132,7 +132,8 @@
- 		the same file.  Make new window N high (default is to use half
- 		the height of the current window).  Reduces the current window
- 		height to create room (and others, if the 'equalalways' option
--		is set and 'eadirection' isn't "hor").
-+		is set, 'eadirection' isn't "hor", and one of them is higher
-+		than the current or the new window).
- 		Note: CTRL-S does not work on all terminals and might block
- 		further input, use CTRL-Q to get going again.
- 		Also see |++opt| and |+cmd|.
-@@ -140,9 +141,13 @@
- CTRL-W CTRL-V						*CTRL-W_CTRL-V*
- CTRL-W v						*CTRL-W_v*
- :[N]vs[plit] [++opt] [+cmd] [file]			*:vs* *:vsplit*
--		Like |:split|, but split vertically.  If 'equalalways' is set
--		and 'eadirection' isn't "ver" the windows will be spread out
--		horizontally, unless a width was specified.
-+		Like |:split|, but split vertically.  The windows will be
-+		spread out horizontally if
-+		1. a width was not specified,
-+		2. 'equalalways' is set,
-+		3. 'eadirection' isn't "ver", and
-+		4. one of the other windows are wider than the current or new
-+		   window.
- 		Note: In other places CTRL-Q does the same as CTRL-V, but here
- 		it doesn't!
- 
-diff -Naur vim71.orig/runtime/filetype.vim vim71/runtime/filetype.vim
---- vim71.orig/runtime/filetype.vim	2007-05-10 11:14:37.000000000 -0400
-+++ vim71/runtime/filetype.vim	2008-06-18 06:56:44.000000000 -0400
-@@ -1,7 +1,7 @@
- " Vim support file to detect file types
- "
- " Maintainer:	Bram Moolenaar <Bram@vim.org>
--" Last Change:	2007 May 10
-+" Last Change:	2007 May 15
- 
- " Listen very carefully, I will say this only once
- if exists("did_load_filetypes")
-@@ -16,20 +16,23 @@
- augroup filetypedetect
- 
- " Ignored extensions
-+if exists("*fnameescape")
- au BufNewFile,BufRead ?\+.orig,?\+.bak,?\+.old,?\+.new,?\+.rpmsave,?\+.rpmnew
--	\ exe "doau filetypedetect BufRead " . expand("<afile>:r")
-+	\ exe "doau filetypedetect BufRead " . fnameescape(expand("<afile>:r"))
- au BufNewFile,BufRead *~
- 	\ let s:name = expand("<afile>") |
- 	\ let s:short = substitute(s:name, '\~$', '', '') |
- 	\ if s:name != s:short && s:short != "" |
--	\   exe "doau filetypedetect BufRead " . s:short |
-+	\   exe "doau filetypedetect BufRead " . fnameescape(s:short) |
- 	\ endif |
--	\ unlet s:name |
--	\ unlet s:short
-+	\ unlet s:name s:short
- au BufNewFile,BufRead ?\+.in
- 	\ if expand("<afile>:t") != "configure.in" |
--	\   exe "doau filetypedetect BufRead " . expand("<afile>:r") |
-+	\   exe "doau filetypedetect BufRead " . fnameescape(expand("<afile>:r")) |
- 	\ endif
-+elseif &verbose > 0
-+  echomsg "Warning: some filetypes will not be recognized because this version of Vim does not have fnameescape()"
-+endif
- 
- " Pattern used to match file names which should not be inspected.
- " Currently finds compressed files.
-@@ -187,7 +190,7 @@
-   let head = " ".getline(1)." ".getline(2)." ".getline(3)." ".getline(4).
- 	\" ".getline(5)." "
-   if head =~ '\sasmsyntax=\S\+\s'
--    let b:asmsyntax = substitute(head, '.*\sasmsyntax=\(\S\+\)\s.*','\1', "")
-+    let b:asmsyntax = substitute(head, '.*\sasmsyntax=\([a-zA-Z0-9]\+\)\s.*','\1', "")
-   elseif ((head =~? '\.title') || (head =~? '\.ident') || (head =~? '\.macro') || (head =~? '\.subtitle') || (head =~? '\.library'))
-     let b:asmsyntax = "vmasm"
-   endif
-@@ -1286,7 +1289,7 @@
- au BufNewFile,BufRead *.it,*.ih			setf ppwiz
- 
- " Oracle Pro*C/C++
--au BufNewFile,BufRead .pc			setf proc
-+au BufNewFile,BufRead *.pc			setf proc
- 
- " Privoxy actions file
- au BufNewFile,BufRead *.action			setf privoxy
-diff -Naur vim71.orig/runtime/indent.vim vim71/runtime/indent.vim
---- vim71.orig/runtime/indent.vim	2006-02-01 03:54:35.000000000 -0500
-+++ vim71/runtime/indent.vim	2008-06-18 06:55:58.000000000 -0400
-@@ -1,7 +1,7 @@
- " Vim support file to switch on loading indent files for file types
- "
- " Maintainer:	Bram Moolenaar <Bram@vim.org>
--" Last Change:	2005 Mar 28
-+" Last Change:	2008 Feb 22
- 
- if exists("did_indent_on")
-   finish
-@@ -15,11 +15,17 @@
-       exe b:undo_indent
-       unlet! b:undo_indent b:did_indent
-     endif
--    if expand("<amatch>") != ""
-+    let s = expand("<amatch>")
-+    if s != ""
-       if exists("b:did_indent")
- 	unlet b:did_indent
-       endif
--      runtime! indent/<amatch>.vim
-+
-+      " When there is a dot it is used to separate filetype names.  Thus for
-+      " "aaa.bbb" load "indent/aaa.vim" and then "indent/bbb.vim".
-+      for name in split(s, '\.')
-+	exe 'runtime! indent/' . name . '.vim'
-+      endfor
-     endif
-   endfunc
- augroup END
-diff -Naur vim71.orig/runtime/menu.vim vim71/runtime/menu.vim
---- vim71.orig/runtime/menu.vim	2007-01-09 08:31:40.000000000 -0500
-+++ vim71/runtime/menu.vim	2008-06-18 06:53:55.000000000 -0400
-@@ -2,7 +2,7 @@
- " You can also use this as a start for your own set of menus.
- "
- " Maintainer:	Bram Moolenaar <Bram@vim.org>
--" Last Change:	2007 Jan 09
-+" Last Change:	2007 Nov 19
- 
- " Note that ":an" (short for ":anoremenu") is often used to make a menu work
- " in all modes and avoid side effects from mappings defined by the user.
-@@ -658,7 +658,6 @@
-   let buf = 1
-   while buf <= bufnr('$')
-     if bufexists(buf) && !isdirectory(bufname(buf)) && buflisted(buf)
--					    \ && !getbufvar(buf, "&bufsecret")
-       let s:bmenu_count = s:bmenu_count + 1
-     endif
-     let buf = buf + 1
-@@ -671,7 +670,6 @@
-   let buf = 1
-   while buf <= bufnr('$')
-     if bufexists(buf) && !isdirectory(bufname(buf)) && buflisted(buf)
--					    \ && !getbufvar(buf, "&bufsecret")
-       call <SID>BMFilename(bufname(buf), buf)
-     endif
-     let buf = buf + 1
-diff -Naur vim71.orig/runtime/optwin.vim vim71/runtime/optwin.vim
---- vim71.orig/runtime/optwin.vim	2006-10-10 17:06:34.000000000 -0400
-+++ vim71/runtime/optwin.vim	2008-06-18 06:56:54.000000000 -0400
-@@ -1,7 +1,7 @@
- " These commands create the option window.
- "
- " Maintainer:	Bram Moolenaar <Bram@vim.org>
--" Last Change:	2006 Oct 10
-+" Last Change:	2008 May 12
- 
- " If there already is an option window, jump to that one.
- if bufwinnr("option-window") > 0
-@@ -147,7 +147,7 @@
- 
- " Open the window
- new option-window
--setlocal ts=15 tw=0
-+setlocal ts=15 tw=0 noro
- 
- " Insert help and a "set" command for each option.
- call append(0, '" Each "set" line shows the current value of an option (on the left).')
-@@ -350,6 +350,10 @@
- call append("$", " \tset lines=" . &lines)
- call append("$", "lazyredraw\tdon't redraw while executing macros")
- call <SID>BinOptionG("lz", &lz)
-+if has("reltime")
-+  call append("$", "redrawtime\ttimeout for 'hlsearch' and :match highlighting in msec")
-+  call append("$", " \tset rdt=" . &rdt)
-+endif
- call append("$", "writedelay\tdelay in msec for each char written to the display")
- call append("$", "\t(for debugging)")
- call append("$", " \tset wd=" . &wd)
-diff -Naur vim71.orig/runtime/plugin/matchparen.vim vim71/runtime/plugin/matchparen.vim
---- vim71.orig/runtime/plugin/matchparen.vim	2006-10-12 16:05:05.000000000 -0400
-+++ vim71/runtime/plugin/matchparen.vim	2008-06-18 06:56:05.000000000 -0400
-@@ -1,6 +1,6 @@
- " Vim plugin for showing matching parens
- " Maintainer:  Bram Moolenaar <Bram@vim.org>
--" Last Change: 2006 Oct 12
-+" Last Change: 2008 Feb 27
- 
- " Exit quickly when:
- " - this plugin was already loaded (or disabled)
-@@ -13,7 +13,7 @@
- 
- augroup matchparen
-   " Replace all matchparen autocommands
--  autocmd! CursorMoved,CursorMovedI * call s:Highlight_Matching_Pair()
-+  autocmd! CursorMoved,CursorMovedI,WinEnter * call s:Highlight_Matching_Pair()
- augroup END
- 
- " Skip the rest if it was already done.
-@@ -34,7 +34,8 @@
-   endif
- 
-   " Avoid that we remove the popup menu.
--  if pumvisible()
-+  " Return when there are no colors (looks like the cursor jumps).
-+  if pumvisible() || (&t_Co < 8 && !has("gui_running"))
-     return
-   endif
- 
-@@ -60,27 +61,13 @@
-   endif
- 
-   " Figure out the arguments for searchpairpos().
--  " Restrict the search to visible lines with "stopline".
--  " And avoid searching very far (e.g., for closed folds and long lines)
-   if i % 2 == 0
-     let s_flags = 'nW'
-     let c2 = plist[i + 1]
--    if has("byte_offset") && has("syntax_items") && &smc > 0
--      let stopbyte = min([line2byte("$"), line2byte(".") + col(".") + &smc * 2])
--      let stopline = min([line('w$'), byte2line(stopbyte)])
--    else
--      let stopline = min([line('w$'), c_lnum + 100])
--    endif
-   else
-     let s_flags = 'nbW'
-     let c2 = c
-     let c = plist[i - 1]
--    if has("byte_offset") && has("syntax_items") && &smc > 0
--      let stopbyte = max([1, line2byte(".") + col(".") - &smc * 2])
--      let stopline = max([line('w0'), byte2line(stopbyte)])
--    else
--      let stopline = max([line('w0'), c_lnum - 100])
--    endif
-   endif
-   if c == '['
-     let c = '\['
-@@ -99,14 +86,56 @@
- 	\ '=~?  "string\\|character\\|singlequote\\|comment"'
-   execute 'if' s_skip '| let s_skip = 0 | endif'
- 
--  let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip, stopline)
-+  " Limit the search to lines visible in the window.
-+  let stoplinebottom = line('w$')
-+  let stoplinetop = line('w0')
-+  if i % 2 == 0
-+    let stopline = stoplinebottom
-+  else
-+    let stopline = stoplinetop
-+  endif
-+
-+  try
-+    " Limit the search time to 300 msec to avoid a hang on very long lines.
-+    " This fails when a timeout is not supported.
-+    let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip, stopline, 300)
-+  catch /E118/
-+    " Can't use the timeout, restrict the stopline a bit more to avoid taking
-+    " a long time on closed folds and long lines.
-+    " The "viewable" variables give a range in which we can scroll while
-+    " keeping the cursor at the same position.
-+    " adjustedScrolloff accounts for very large numbers of scrolloff.
-+    let adjustedScrolloff = min([&scrolloff, (line('w$') - line('w0')) / 2])
-+    let bottom_viewable = min([line('$'), c_lnum + &lines - adjustedScrolloff - 2])
-+    let top_viewable = max([1, c_lnum-&lines+adjustedScrolloff + 2])
-+    " one of these stoplines will be adjusted below, but the current values are
-+    " minimal boundaries within the current window
-+    if i % 2 == 0
-+      if has("byte_offset") && has("syntax_items") && &smc > 0
-+	let stopbyte = min([line2byte("$"), line2byte(".") + col(".") + &smc * 2])
-+	let stopline = min([bottom_viewable, byte2line(stopbyte)])
-+      else
-+	let stopline = min([bottom_viewable, c_lnum + 100])
-+      endif
-+      let stoplinebottom = stopline
-+    else
-+      if has("byte_offset") && has("syntax_items") && &smc > 0
-+	let stopbyte = max([1, line2byte(".") + col(".") - &smc * 2])
-+	let stopline = max([top_viewable, byte2line(stopbyte)])
-+      else
-+	let stopline = max([top_viewable, c_lnum - 100])
-+      endif
-+      let stoplinetop = stopline
-+    endif
-+    let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip, stopline)
-+  endtry
- 
-   if before > 0
-     call winrestview(save_cursor)
-   endif
- 
-   " If a match is found setup match highlighting.
--  if m_lnum > 0 && m_lnum >= line('w0') && m_lnum <= line('w$')
-+  if m_lnum > 0 && m_lnum >= stoplinetop && m_lnum <= stoplinebottom 
-     exe '3match MatchParen /\(\%' . c_lnum . 'l\%' . (c_col - before) .
- 	  \ 'c\)\|\(\%' . m_lnum . 'l\%' . m_col . 'c\)/'
-     let w:paren_hl_on = 1
-@@ -114,7 +143,8 @@
- endfunction
- 
- " Define commands that will disable and enable the plugin.
--command! NoMatchParen 3match none | unlet! g:loaded_matchparen | au! matchparen
--command! DoMatchParen runtime plugin/matchparen.vim | doau CursorMoved
-+command! NoMatchParen windo 3match none | unlet! g:loaded_matchparen |
-+	  \ au! matchparen
-+command! DoMatchParen runtime plugin/matchparen.vim | windo doau CursorMoved
- 
- let &cpo = cpo_save
-diff -Naur vim71.orig/src/Makefile vim71/src/Makefile
---- vim71.orig/src/Makefile	2007-05-12 07:57:13.000000000 -0400
-+++ vim71/src/Makefile	2008-06-18 06:56:55.000000000 -0400
-@@ -545,7 +545,7 @@
- # For unknown reasons adding "-lc" fixes a linking problem with GCC.  That's
- # probably a bug in the "-pg" implementation.
- # Need to recompile everything after changing this: "make clean" "make".
--#PROFILE_CFLAGS = -pg -g
-+#PROFILE_CFLAGS = -pg -g -DWE_ARE_PROFILING
- #PROFILE_LIBS = -pg
- #PROFILE_LIBS = -pg -lc
- 
-@@ -780,6 +780,8 @@
- # 1) make config
- # 2) edit auto/config.mk, add -n32 to LDFLAGS
- # 3) make
-+#
-+#Alternatively: use -o32 instead of -n32.
- ###
- 
- ### (C)  On SCO Unix v3.2.5 (and probably other versions) the termcap library,
-@@ -1074,7 +1076,7 @@
- # default vi editor, it will create a link from vi to Vim when doing
- # "make install".  An existing file will be overwritten!
- # When not using it, some make programs can't handle an undefined $(LINKIT).
--#LINKIT = -ln -f -s $(BINDIR)/$(VIMTARGET) /usr/bin/vi
-+#LINKIT = ln -f -s $(DEST_BIN)/$(VIMTARGET) $(DESTDIR)/usr/bin/vi
- LINKIT = @echo >/dev/null
- 
- ###
-@@ -1290,6 +1292,9 @@
- 
- DEPEND_CFLAGS = -DPROTO -DDEPEND -DFEAT_GUI $(LINT_CFLAGS)
- 
-+# If you have problems with flags that cproto doesn't support, and you are
-+# using GNU make, you can try using the other line to filter out arguments.
-+#PFLAGS = $(PROTO_FLAGS) -DPROTO $(filter -D% -I%, $(LINT_CFLAGS))
- PFLAGS = $(PROTO_FLAGS) -DPROTO $(LINT_CFLAGS)
- 
- ALL_LIB_DIRS = $(GUI_LIBS_DIR) $(X_LIBS_DIR)
-@@ -1867,6 +1872,8 @@
- installtutorbin: $(DEST_VIM)
- 	$(INSTALL_DATA) vimtutor $(DEST_BIN)/$(VIMNAME)tutor
- 	chmod $(SCRIPTMOD) $(DEST_BIN)/$(VIMNAME)tutor
-+	$(INSTALL_DATA) gvimtutor $(DEST_BIN)/$(GVIMNAME)tutor
-+	chmod $(SCRIPTMOD) $(DEST_BIN)/$(GVIMNAME)tutor
- 
- installtutor: $(DEST_RT) $(DEST_TUTOR)
- 	-$(INSTALL_DATA) $(TUTORSOURCE)/README* $(TUTORSOURCE)/tutor* $(DEST_TUTOR)
-@@ -2075,6 +2082,7 @@
- uninstall: uninstall_runtime
- 	-rm -f $(DEST_BIN)/$(VIMTARGET)
- 	-rm -f $(DEST_BIN)/vimtutor
-+	-rm -f $(DEST_BIN)/gvimtutor
- 	-rm -f $(DEST_BIN)/$(EXTARGET) $(DEST_BIN)/$(VIEWTARGET)
- 	-rm -f $(DEST_BIN)/$(GVIMTARGET) $(DEST_BIN)/$(GVIEWTARGET)
- 	-rm -f $(DEST_BIN)/$(RVIMTARGET) $(DEST_BIN)/$(RVIEWTARGET)
-@@ -2171,7 +2179,7 @@
- 
- shadow:	runtime pixmaps
- 	mkdir $(SHADOWDIR)
--	cd $(SHADOWDIR); ln -s ../*.[ch] ../*.in ../*.sh ../*.xs ../*.xbm ../toolcheck ../proto ../vimtutor ../mkinstalldirs .
-+	cd $(SHADOWDIR); ln -s ../*.[ch] ../*.in ../*.sh ../*.xs ../*.xbm ../toolcheck ../proto ../po ../vimtutor ../gvimtutor ../mkinstalldirs .
- 	mkdir $(SHADOWDIR)/auto
- 	cd $(SHADOWDIR)/auto; ln -s ../../auto/configure .
- 	cd $(SHADOWDIR); rm -f auto/link.sed
-@@ -2190,7 +2198,7 @@
- 	cd $(SHADOWDIR)/testdir; ln -s ../../testdir/Makefile \
- 				 ../../testdir/vimrc.unix \
- 				 ../../testdir/*.in \
--				 ../../testdir/unix.vim \
-+				 ../../testdir/*.vim \
- 				 ../../testdir/*.ok .
- 
- # Link needed for doing "make install" in a shadow directory.
-@@ -2559,8 +2567,11 @@
- #	-mkdir $(DESTDIR)$(prefix)/$(APPDIR)/bin
- 	srcdir=`pwd`; $(MAKE) -f Makefile installruntime \
- 		VIMEXE=$$srcdir/$(VIMTARGET) \
--		prefix=$(DESTDIR)$(prefix)/$(RESDIR)/vim \
--		VIMRTLOC=$(DESTDIR)$(prefix)/$(RESDIR)/vim/runtime
-+		prefix=$(DESTDIR)$(prefix)/$(RESDIR)$(VIMDIR) \
-+		exec_prefix=$(DESTDIR)$(prefix)/$(APPDIR)/Contents \
-+		BINDIR=$(DESTDIR)$(prefix)/$(APPDIR)/Contents/MacOS \
-+		VIMLOC=$(DESTDIR)$(prefix)/$(RESDIR)$(VIMDIR) \
-+		VIMRTLOC=$(DESTDIR)$(prefix)/$(RESDIR)$(VIMDIR)/runtime
- # Put the link back.
- 	ln -s `pwd`/../runtime $(RESDIR)/vim
- # Copy rgb.txt, Mac doesn't always have X11
-diff -Naur vim71.orig/src/auto/configure vim71/src/auto/configure
---- vim71.orig/src/auto/configure	2007-05-12 07:49:09.000000000 -0400
-+++ vim71/src/auto/configure	2008-06-18 06:56:39.000000000 -0400
-@@ -845,6 +845,7 @@
-   --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
-   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
-   --disable-darwin        Disable Darwin (Mac OS X) support.
-+  --disable-selinux	  Don't check for SELinux support.
-   --disable-xsmp          Disable XSMP session management
-   --disable-xsmp-interact Disable XSMP interaction
-   --enable-mzschemeinterp   Include MzScheme interpreter.
-@@ -3611,6 +3612,94 @@
- esac
- fi
- 
-+echo "$as_me:$LINENO: checking --disable-selinux argument" >&5
-+echo $ECHO_N "checking --disable-selinux argument... $ECHO_C" >&6
-+# Check whether --enable-selinux or --disable-selinux was given.
-+if test "${enable_selinux+set}" = set; then
-+  enableval="$enable_selinux"
-+
-+else
-+  enable_selinux="yes"
-+fi;
-+if test "$enable_selinux" = "yes"; then
-+  echo "$as_me:$LINENO: result: no" >&5
-+echo "${ECHO_T}no" >&6
-+  echo "$as_me:$LINENO: checking for is_selinux_enabled in -lselinux" >&5
-+echo $ECHO_N "checking for is_selinux_enabled in -lselinux... $ECHO_C" >&6
-+if test "${ac_cv_lib_selinux_is_selinux_enabled+set}" = set; then
-+  echo $ECHO_N "(cached) $ECHO_C" >&6
-+else
-+  ac_check_lib_save_LIBS=$LIBS
-+LIBS="-lselinux  $LIBS"
-+cat >conftest.$ac_ext <<_ACEOF
-+/* confdefs.h.  */
-+_ACEOF
-+cat confdefs.h >>conftest.$ac_ext
-+cat >>conftest.$ac_ext <<_ACEOF
-+/* end confdefs.h.  */
-+
-+/* Override any gcc2 internal prototype to avoid an error.  */
-+#ifdef __cplusplus
-+extern "C"
-+#endif
-+/* We use char because int might match the return type of a gcc2
-+   builtin and then its argument prototype would still apply.  */
-+char is_selinux_enabled ();
-+int
-+main ()
-+{
-+is_selinux_enabled ();
-+  ;
-+  return 0;
-+}
-+_ACEOF
-+rm -f conftest.$ac_objext conftest$ac_exeext
-+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-+  (eval $ac_link) 2>conftest.er1
-+  ac_status=$?
-+  grep -v '^ *+' conftest.er1 >conftest.err
-+  rm -f conftest.er1
-+  cat conftest.err >&5
-+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+  (exit $ac_status); } &&
-+	 { ac_try='test -z "$ac_c_werror_flag"
-+			 || test ! -s conftest.err'
-+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-+  (eval $ac_try) 2>&5
-+  ac_status=$?
-+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+  (exit $ac_status); }; } &&
-+	 { ac_try='test -s conftest$ac_exeext'
-+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-+  (eval $ac_try) 2>&5
-+  ac_status=$?
-+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+  (exit $ac_status); }; }; then
-+  ac_cv_lib_selinux_is_selinux_enabled=yes
-+else
-+  echo "$as_me: failed program was:" >&5
-+sed 's/^/| /' conftest.$ac_ext >&5
-+
-+ac_cv_lib_selinux_is_selinux_enabled=no
-+fi
-+rm -f conftest.err conftest.$ac_objext \
-+      conftest$ac_exeext conftest.$ac_ext
-+LIBS=$ac_check_lib_save_LIBS
-+fi
-+echo "$as_me:$LINENO: result: $ac_cv_lib_selinux_is_selinux_enabled" >&5
-+echo "${ECHO_T}$ac_cv_lib_selinux_is_selinux_enabled" >&6
-+if test $ac_cv_lib_selinux_is_selinux_enabled = yes; then
-+  LIBS="$LIBS -lselinux"
-+	   cat >>confdefs.h <<\_ACEOF
-+#define HAVE_SELINUX 1
-+_ACEOF
-+
-+fi
-+
-+else
-+   echo "$as_me:$LINENO: result: yes" >&5
-+echo "${ECHO_T}yes" >&6
-+fi
- 
- 
- echo "$as_me:$LINENO: checking --with-features argument" >&5
-@@ -3843,7 +3932,9 @@
-   fi
- 
-   if test "X$vi_cv_path_mzscheme_pfx" != "X"; then
--    if test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"; then
-+    if test "x$MACOSX" = "xyes"; then
-+      MZSCHEME_LIBS="-framework PLT_MzScheme"
-+    elif test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"; then
-       MZSCHEME_LIBS="${vi_cv_path_mzscheme_pfx}/lib/libmzscheme.a ${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"
-     else
-       MZSCHEME_LIBS="-L${vi_cv_path_mzscheme_pfx}/lib -lmzscheme -lmzgc"
-@@ -4443,7 +4534,7 @@
-   tclsh_name="$withval"; echo "$as_me:$LINENO: result: $tclsh_name" >&5
- echo "${ECHO_T}$tclsh_name" >&6
- else
--  tclsh_name="tclsh8.4"; echo "$as_me:$LINENO: result: no" >&5
-+  tclsh_name="tclsh8.5"; echo "$as_me:$LINENO: result: no" >&5
- echo "${ECHO_T}no" >&6
- fi;
-   # Extract the first word of "$tclsh_name", so it can be a program name with args.
-@@ -4487,7 +4578,49 @@
- 
- 
- 
--    if test "X$vi_cv_path_tcl" = "X" -a $tclsh_name = "tclsh8.4"; then
-+    if test "X$vi_cv_path_tcl" = "X" -a $tclsh_name = "tclsh8.5"; then
-+    tclsh_name="tclsh8.4"
-+    # Extract the first word of "$tclsh_name", so it can be a program name with args.
-+set dummy $tclsh_name; ac_word=$2
-+echo "$as_me:$LINENO: checking for $ac_word" >&5
-+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-+if test "${ac_cv_path_vi_cv_path_tcl+set}" = set; then
-+  echo $ECHO_N "(cached) $ECHO_C" >&6
-+else
-+  case $vi_cv_path_tcl in
-+  [\\/]* | ?:[\\/]*)
-+  ac_cv_path_vi_cv_path_tcl="$vi_cv_path_tcl" # Let the user override the test with a path.
-+  ;;
-+  *)
-+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-+for as_dir in $PATH
-+do
-+  IFS=$as_save_IFS
-+  test -z "$as_dir" && as_dir=.
-+  for ac_exec_ext in '' $ac_executable_extensions; do
-+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-+    ac_cv_path_vi_cv_path_tcl="$as_dir/$ac_word$ac_exec_ext"
-+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-+    break 2
-+  fi
-+done
-+done
-+
-+  ;;
-+esac
-+fi
-+vi_cv_path_tcl=$ac_cv_path_vi_cv_path_tcl
-+
-+if test -n "$vi_cv_path_tcl"; then
-+  echo "$as_me:$LINENO: result: $vi_cv_path_tcl" >&5
-+echo "${ECHO_T}$vi_cv_path_tcl" >&6
-+else
-+  echo "$as_me:$LINENO: result: no" >&5
-+echo "${ECHO_T}no" >&6
-+fi
-+
-+  fi
-+  if test "X$vi_cv_path_tcl" = "X" -a $tclsh_name = "tclsh8.4"; then
-     tclsh_name="tclsh8.2"
-     # Extract the first word of "$tclsh_name", so it can be a program name with args.
- set dummy $tclsh_name; ac_word=$2
-@@ -4625,10 +4758,11 @@
-       echo "$as_me:$LINENO: checking for location of Tcl include" >&5
- echo $ECHO_N "checking for location of Tcl include... $ECHO_C" >&6
-       if test "x$MACOSX" != "xyes"; then
--	tclinc="$tclloc/include $tclloc/include/tcl $tclloc/include/tcl$tclver /usr/local/include /usr/include"
-+	tclinc="$tclloc/include $tclloc/include/tcl $tclloc/include/tcl$tclver /usr/local/include /usr/include /usr/include/tcl$tclver"
-       else
- 		tclinc="/System/Library/Frameworks/Tcl.framework/Headers"
-       fi
-+      TCL_INC=
-       for try in $tclinc; do
- 	if test -f "$try/tcl.h"; then
- 	  echo "$as_me:$LINENO: result: $try/tcl.h" >&5
-@@ -4647,6 +4781,7 @@
- echo $ECHO_N "checking for location of tclConfig.sh script... $ECHO_C" >&6
- 	if test "x$MACOSX" != "xyes"; then
- 	  tclcnf=`echo $tclinc | sed s/include/lib/g`
-+	  tclcnf="$tclcnf `echo $tclinc | sed s/include/lib64/g`"
- 	else
- 	  	  tclcnf="/System/Library/Frameworks/Tcl.framework"
- 	fi
-@@ -4666,6 +4801,7 @@
- 	  echo "$as_me:$LINENO: checking for Tcl library by myself" >&5
- echo $ECHO_N "checking for Tcl library by myself... $ECHO_C" >&6
- 	  tcllib=`echo $tclinc | sed s/include/lib/g`
-+	  tcllib="$tcllib `echo $tclinc | sed s/include/lib64/g`"
- 	  for ext in .so .a ; do
- 	    for ver in "" $tclver ; do
- 	      for try in $tcllib ; do
-@@ -10263,8 +10399,9 @@
- 
- 
- 
-+
- for ac_header in stdarg.h stdlib.h string.h sys/select.h sys/utsname.h \
--	termcap.h fcntl.h sgtty.h sys/ioctl.h sys/time.h termio.h \
-+	termcap.h fcntl.h sgtty.h sys/ioctl.h sys/time.h sys/types.h termio.h \
- 	iconv.h langinfo.h unistd.h stropts.h errno.h \
- 	sys/resource.h sys/systeminfo.h locale.h \
- 	sys/stream.h sys/ptem.h termios.h libc.h sys/statfs.h \
-@@ -14212,7 +14349,7 @@
- echo "$as_me:$LINENO: checking how to run man with a section nr" >&5
- echo $ECHO_N "checking how to run man with a section nr... $ECHO_C" >&6
- MANDEF="man"
--(eval man -s 2 read) < /dev/null > /dev/null 2>&5 && MANDEF="man -s"
-+(eval MANPAGER=cat PAGER=cat man -s 2 read) < /dev/null > /dev/null 2>&5 && MANDEF="man -s"
- echo "$as_me:$LINENO: result: $MANDEF" >&5
- echo "${ECHO_T}$MANDEF" >&6
- if test "$MANDEF" = "man -s"; then
-diff -Naur vim71.orig/src/buffer.c vim71/src/buffer.c
---- vim71.orig/src/buffer.c	2007-05-10 11:25:59.000000000 -0400
-+++ vim71/src/buffer.c	2008-06-18 06:56:11.000000000 -0400
-@@ -171,6 +171,13 @@
- 	    /* Put the cursor on the first line. */
- 	    curwin->w_cursor.lnum = 1;
- 	    curwin->w_cursor.col = 0;
-+
-+	    /* Set or reset 'modified' before executing autocommands, so that
-+	     * it can be changed there. */
-+	    if (!readonlymode && !bufempty())
-+		changed();
-+	    else if (retval != FAIL)
-+		unchanged(curbuf, FALSE);
- #ifdef FEAT_AUTOCMD
- # ifdef FEAT_EVAL
- 	    apply_autocmds_retval(EVENT_STDINREADPOST, NULL, NULL, FALSE,
-@@ -194,16 +201,16 @@
-     /* When reading stdin, the buffer contents always needs writing, so set
-      * the changed flag.  Unless in readonly mode: "ls | gview -".
-      * When interrupted and 'cpoptions' contains 'i' set changed flag. */
--    if ((read_stdin && !readonlymode && !bufempty())
-+    if ((got_int && vim_strchr(p_cpo, CPO_INTMOD) != NULL)
- #ifdef FEAT_AUTOCMD
- 		|| modified_was_set	/* ":set modified" used in autocmd */
- # ifdef FEAT_EVAL
- 		|| (aborting() && vim_strchr(p_cpo, CPO_INTMOD) != NULL)
- # endif
- #endif
--		|| (got_int && vim_strchr(p_cpo, CPO_INTMOD) != NULL))
-+       )
- 	changed();
--    else if (retval != FAIL)
-+    else if (retval != FAIL && !read_stdin)
- 	unchanged(curbuf, FALSE);
-     save_file_ff(curbuf);		/* keep this fileformat */
- 
-@@ -495,6 +502,7 @@
-     buf->b_start_eol = TRUE;
- #ifdef FEAT_MBYTE
-     buf->b_p_bomb = FALSE;
-+    buf->b_start_bomb = FALSE;
- #endif
-     buf->b_ml.ml_mfp = NULL;
-     buf->b_ml.ml_flags = ML_EMPTY;		/* empty buffer */
-@@ -4167,29 +4175,35 @@
-      * mess up the full path name, even though it starts with a '/'.
-      * Also expand when there is ".." in the file name, try to remove it,
-      * because "c:/src/../README" is equal to "c:/README".
-+     * Similarly "c:/src//file" is equal to "c:/src/file".
-      * For MS-Windows also expand names like "longna~1" to "longname".
-      */
- #ifdef UNIX
-     return FullName_save(fname, TRUE);
- #else
--    if (!vim_isAbsName(fname) || strstr((char *)fname, "..") != NULL
--#if defined(MSWIN) || defined(DJGPP)
-+    if (!vim_isAbsName(fname)
-+	    || strstr((char *)fname, "..") != NULL
-+	    || strstr((char *)fname, "//") != NULL
-+# ifdef BACKSLASH_IN_FILENAME
-+	    || strstr((char *)fname, "\\\\") != NULL
-+# endif
-+# if defined(MSWIN) || defined(DJGPP)
- 	    || vim_strchr(fname, '~') != NULL
--#endif
-+# endif
- 	    )
- 	return FullName_save(fname, FALSE);
- 
-     fname = vim_strsave(fname);
- 
--#ifdef USE_FNAME_CASE
--# ifdef USE_LONG_FNAME
-+# ifdef USE_FNAME_CASE
-+#  ifdef USE_LONG_FNAME
-     if (USE_LONG_FNAME)
--# endif
-+#  endif
-     {
- 	if (fname != NULL)
- 	    fname_case(fname, 0);	/* set correct case for file name */
-     }
--#endif
-+# endif
- 
-     return fname;
- #endif
-@@ -4853,7 +4867,7 @@
- 	     */
- 	    for (e = s; *e != ':' && *e != NUL; ++e)
- 		if (e[0] == '\\' && e[1] == ':')
--		    STRCPY(e, e + 1);
-+		    mch_memmove(e, e + 1, STRLEN(e));
- 	    if (*e == NUL)
- 		end = TRUE;
- 
-@@ -4898,7 +4912,7 @@
-     return retval;
- }
- 
--#ifdef FEAT_VIMINFO
-+#if defined(FEAT_VIMINFO) || defined(PROTO)
-     int
- read_viminfo_bufferlist(virp, writing)
-     vir_T	*virp;
-@@ -5022,13 +5036,14 @@
- #if defined(FEAT_QUICKFIX) && defined(FEAT_WINDOWS)
-     if (bt_quickfix(buf))
-     {
--	win_T	*win;
-+	win_T	    *win = NULL;
-+	tabpage_T   *tp;
- 
- 	/*
- 	 * For location list window, w_llist_ref points to the location list.
- 	 * For quickfix window, w_llist_ref is NULL.
- 	 */
--	FOR_ALL_WINDOWS(win)
-+	FOR_ALL_TAB_WINDOWS(tp, win)
- 	    if (win->w_buffer == buf)
- 		break;
- 	if (win != NULL && win->w_llist_ref != NULL)
-@@ -5507,11 +5522,11 @@
- 
- #ifdef FEAT_AUTOCMD
-     if (!aucmd)		    /* Don't trigger BufDelete autocommands here. */
--	++autocmd_block;
-+	block_autocmds();
- #endif
-     close_buffer(NULL, buf, DOBUF_WIPE);
- #ifdef FEAT_AUTOCMD
-     if (!aucmd)
--	--autocmd_block;
-+	unblock_autocmds();
- #endif
- }
-diff -Naur vim71.orig/src/charset.c vim71/src/charset.c
---- vim71.orig/src/charset.c	2007-03-24 16:10:37.000000000 -0400
-+++ vim71/src/charset.c	2008-06-18 06:55:55.000000000 -0400
-@@ -207,7 +207,10 @@
- 	    }
- 	    while (c <= c2)
- 	    {
--		if (!do_isalpha || isalpha(c)
-+		/* Use the MB_ functions here, because isalpha() doesn't
-+		 * work properly when 'encoding' is "latin1" and the locale is
-+		 * "C".  */
-+		if (!do_isalpha || MB_ISLOWER(c) || MB_ISUPPER(c)
- #ifdef FEAT_FKMAP
- 			|| (p_altkeymap && (F_isalpha(c) || F_isdigit(c)))
- #endif
-@@ -929,6 +932,23 @@
- }
- 
- /*
-+ * return TRUE if 'c' is a valid file-name character or a wildcard character
-+ * Assume characters above 0x100 are valid (multi-byte).
-+ * Explicitly interpret ']' as a wildcard character as mch_has_wildcard("]")
-+ * returns false.
-+ */
-+    int
-+vim_isfilec_or_wc(c)
-+    int c;
-+{
-+    char_u buf[2];
-+
-+    buf[0] = (char_u)c;
-+    buf[1] = NUL;
-+    return vim_isfilec(c) || c == ']' || mch_has_wildcard(buf);
-+}
-+
-+/*
-  * return TRUE if 'c' is a printable character
-  * Assume characters above 0x100 are printable (multi-byte), except for
-  * Unicode.
-@@ -1270,7 +1290,8 @@
- 		    /* If a double-cell char doesn't fit at the end of a line
- 		     * it wraps to the next line, it's like this char is three
- 		     * cells wide. */
--		    if (incr == 2 && wp->w_p_wrap && in_win_border(wp, vcol))
-+		    if (incr == 2 && wp->w_p_wrap && MB_BYTE2LEN(*ptr) > 1
-+			    && in_win_border(wp, vcol))
- 		    {
- 			++incr;
- 			head = 1;
-@@ -1898,7 +1919,7 @@
- {
-     for ( ; *p; ++p)
- 	if (rem_backslash(p))
--	    STRCPY(p, p + 1);
-+	    mch_memmove(p, p + 1, STRLEN(p));
- }
- 
- /*
-diff -Naur vim71.orig/src/config.h.in vim71/src/config.h.in
---- vim71.orig/src/config.h.in	2007-04-26 10:40:34.000000000 -0400
-+++ vim71/src/config.h.in	2008-06-18 06:56:39.000000000 -0400
-@@ -155,6 +155,7 @@
- #undef HAVE_READLINK
- #undef HAVE_RENAME
- #undef HAVE_SELECT
-+#undef HAVE_SELINUX
- #undef HAVE_SETENV
- #undef HAVE_SETPGID
- #undef HAVE_SETSID
-diff -Naur vim71.orig/src/configure.in vim71/src/configure.in
---- vim71.orig/src/configure.in	2007-05-12 05:19:27.000000000 -0400
-+++ vim71/src/configure.in	2008-06-18 06:56:39.000000000 -0400
-@@ -299,6 +299,19 @@
- esac
- fi
- 
-+dnl Link with -lselinux for SELinux stuff; if not found
-+AC_MSG_CHECKING(--disable-selinux argument)
-+AC_ARG_ENABLE(selinux,
-+	[  --disable-selinux	  Don't check for SELinux support.],
-+	, enable_selinux="yes")
-+if test "$enable_selinux" = "yes"; then
-+  AC_MSG_RESULT(no)
-+  AC_CHECK_LIB(selinux, is_selinux_enabled,
-+	  [LIBS="$LIBS -lselinux"
-+	   AC_DEFINE(HAVE_SELINUX)])
-+else
-+   AC_MSG_RESULT(yes)
-+fi
- 
- dnl Check user requested features.
- 
-@@ -423,7 +436,9 @@
-   fi
- 
-   if test "X$vi_cv_path_mzscheme_pfx" != "X"; then
--    if test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"; then
-+    if test "x$MACOSX" = "xyes"; then
-+      MZSCHEME_LIBS="-framework PLT_MzScheme"
-+    elif test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"; then
-       MZSCHEME_LIBS="${vi_cv_path_mzscheme_pfx}/lib/libmzscheme.a ${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"
-     else
-       MZSCHEME_LIBS="-L${vi_cv_path_mzscheme_pfx}/lib -lmzscheme -lmzgc"
-@@ -757,15 +772,19 @@
- 
- if test "$enable_tclinterp" = "yes"; then
- 
--  dnl on FreeBSD tclsh is a silly script, look for tclsh8.[420]
-+  dnl on FreeBSD tclsh is a silly script, look for tclsh8.[5420]
-   AC_MSG_CHECKING(--with-tclsh argument)
-   AC_ARG_WITH(tclsh, [  --with-tclsh=PATH       which tclsh to use (default: tclsh8.0)],
- 	tclsh_name="$withval"; AC_MSG_RESULT($tclsh_name),
--	tclsh_name="tclsh8.4"; AC_MSG_RESULT(no))
-+	tclsh_name="tclsh8.5"; AC_MSG_RESULT(no))
-   AC_PATH_PROG(vi_cv_path_tcl, $tclsh_name)
-   AC_SUBST(vi_cv_path_tcl)
- 
--  dnl when no specific version specified, also try 8.2 and 8.0
-+  dnl when no specific version specified, also try 8.4, 8.2 and 8.0
-+  if test "X$vi_cv_path_tcl" = "X" -a $tclsh_name = "tclsh8.5"; then
-+    tclsh_name="tclsh8.4"
-+    AC_PATH_PROG(vi_cv_path_tcl, $tclsh_name)
-+  fi
-   if test "X$vi_cv_path_tcl" = "X" -a $tclsh_name = "tclsh8.4"; then
-     tclsh_name="tclsh8.2"
-     AC_PATH_PROG(vi_cv_path_tcl, $tclsh_name)
-@@ -788,11 +807,12 @@
- 
-       AC_MSG_CHECKING(for location of Tcl include)
-       if test "x$MACOSX" != "xyes"; then
--	tclinc="$tclloc/include $tclloc/include/tcl $tclloc/include/tcl$tclver /usr/local/include /usr/include"
-+	tclinc="$tclloc/include $tclloc/include/tcl $tclloc/include/tcl$tclver /usr/local/include /usr/local/include/tcl$tclver /usr/include /usr/include/tcl$tclver"
-       else
- 	dnl For Mac OS X 10.3, use the OS-provided framework location
- 	tclinc="/System/Library/Frameworks/Tcl.framework/Headers"
-       fi
-+      TCL_INC=
-       for try in $tclinc; do
- 	if test -f "$try/tcl.h"; then
- 	  AC_MSG_RESULT($try/tcl.h)
-@@ -808,6 +828,7 @@
- 	AC_MSG_CHECKING(for location of tclConfig.sh script)
- 	if test "x$MACOSX" != "xyes"; then
- 	  tclcnf=`echo $tclinc | sed s/include/lib/g`
-+	  tclcnf="$tclcnf `echo $tclinc | sed s/include/lib64/g`"
- 	else
- 	  dnl For Mac OS X 10.3, use the OS-provided framework location
- 	  tclcnf="/System/Library/Frameworks/Tcl.framework"
-@@ -828,6 +849,7 @@
- 	  AC_MSG_RESULT(<not found>)
- 	  AC_MSG_CHECKING(for Tcl library by myself)
- 	  tcllib=`echo $tclinc | sed s/include/lib/g`
-+	  tcllib="$tcllib `echo $tclinc | sed s/include/lib64/g`"
- 	  for ext in .so .a ; do
- 	    for ver in "" $tclver ; do
- 	      for try in $tcllib ; do
-@@ -2024,7 +2046,7 @@
- fi
- 
- AC_CHECK_HEADERS(stdarg.h stdlib.h string.h sys/select.h sys/utsname.h \
--	termcap.h fcntl.h sgtty.h sys/ioctl.h sys/time.h termio.h \
-+	termcap.h fcntl.h sgtty.h sys/ioctl.h sys/time.h sys/types.h termio.h \
- 	iconv.h langinfo.h unistd.h stropts.h errno.h \
- 	sys/resource.h sys/systeminfo.h locale.h \
- 	sys/stream.h sys/ptem.h termios.h libc.h sys/statfs.h \
-@@ -2718,7 +2740,7 @@
- dnl Check how we can run man with a section number
- AC_MSG_CHECKING(how to run man with a section nr)
- MANDEF="man"
--(eval man -s 2 read) < /dev/null > /dev/null 2>&AC_FD_CC && MANDEF="man -s"
-+(eval MANPAGER=cat PAGER=cat man -s 2 read) < /dev/null > /dev/null 2>&AC_FD_CC && MANDEF="man -s"
- AC_MSG_RESULT($MANDEF)
- if test "$MANDEF" = "man -s"; then
-   AC_DEFINE(USEMAN_S)
-diff -Naur vim71.orig/src/diff.c vim71/src/diff.c
---- vim71.orig/src/diff.c	2007-02-15 19:18:41.000000000 -0500
-+++ vim71/src/diff.c	2008-06-18 06:55:22.000000000 -0400
-@@ -791,6 +791,9 @@
-     }
-     mch_remove(tmp_orig);
- 
-+    /* force updating cursor position on screen */
-+    curwin->w_valid_cursor.lnum = 0;
-+
-     diff_redraw(TRUE);
- 
- theend:
-@@ -840,11 +843,11 @@
- 		    tmp_orig, tmp_new);
- 	    append_redir(cmd, p_srr, tmp_diff);
- #ifdef FEAT_AUTOCMD
--	    ++autocmd_block;	/* Avoid ShellCmdPost stuff */
-+	    block_autocmds();	/* Avoid ShellCmdPost stuff */
- #endif
- 	    (void)call_shell(cmd, SHELL_FILTER|SHELL_SILENT|SHELL_DOOUT);
- #ifdef FEAT_AUTOCMD
--	    --autocmd_block;
-+	    unblock_autocmds();
- #endif
- 	    vim_free(cmd);
- 	}
-@@ -949,11 +952,11 @@
- # endif
- 		eap->arg);
- #ifdef FEAT_AUTOCMD
--	++autocmd_block;	/* Avoid ShellCmdPost stuff */
-+	block_autocmds();	/* Avoid ShellCmdPost stuff */
- #endif
- 	(void)call_shell(buf, SHELL_FILTER | SHELL_COOKED);
- #ifdef FEAT_AUTOCMD
--	--autocmd_block;
-+	unblock_autocmds();
- #endif
-     }
- 
-@@ -1296,7 +1299,9 @@
- 	    }
- 	    else
- 		/* second overlap of new block with existing block */
--		dp->df_count[idx_new] += count_new - count_orig;
-+		dp->df_count[idx_new] += count_new - count_orig
-+		    + dpl->df_lnum[idx_orig] + dpl->df_count[idx_orig]
-+		    - (dp->df_lnum[idx_orig] + dp->df_count[idx_orig]);
- 
- 	    /* Adjust the size of the block to include all the lines to the
- 	     * end of the existing block or the new diff, whatever ends last. */
-@@ -1310,7 +1315,7 @@
- 		    dp->df_count[idx_new] += -off;
- 		off = 0;
- 	    }
--	    for (i = idx_orig; i < idx_new + !notset; ++i)
-+	    for (i = idx_orig; i < idx_new; ++i)
- 		if (curtab->tp_diffbuf[i] != NULL)
- 		    dp->df_count[i] = dpl->df_lnum[i] + dpl->df_count[i]
- 						       - dp->df_lnum[i] + off;
-@@ -1625,14 +1630,16 @@
-     win_T	*fromwin;
-     win_T	*towin;
- {
--    buf_T	*buf = fromwin->w_buffer;
-+    buf_T	*frombuf = fromwin->w_buffer;
-     linenr_T	lnum = fromwin->w_topline;
--    int		idx;
-+    int		fromidx;
-+    int		toidx;
-     diff_T	*dp;
-+    int		max_count;
-     int		i;
- 
--    idx = diff_buf_idx(buf);
--    if (idx == DB_COUNT)
-+    fromidx = diff_buf_idx(frombuf);
-+    if (fromidx == DB_COUNT)
- 	return;		/* safety check */
- 
-     if (curtab->tp_diff_invalid)
-@@ -1642,42 +1649,72 @@
- 
-     /* search for a change that includes "lnum" in the list of diffblocks. */
-     for (dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next)
--	if (lnum <= dp->df_lnum[idx] + dp->df_count[idx])
-+	if (lnum <= dp->df_lnum[fromidx] + dp->df_count[fromidx])
- 	    break;
-     if (dp == NULL)
-     {
- 	/* After last change, compute topline relative to end of file; no
- 	 * filler lines. */
- 	towin->w_topline = towin->w_buffer->b_ml.ml_line_count
--					   - (buf->b_ml.ml_line_count - lnum);
-+				       - (frombuf->b_ml.ml_line_count - lnum);
-     }
-     else
-     {
- 	/* Find index for "towin". */
--	i = diff_buf_idx(towin->w_buffer);
--	if (i == DB_COUNT)
-+	toidx = diff_buf_idx(towin->w_buffer);
-+	if (toidx == DB_COUNT)
- 	    return;		/* safety check */
- 
--	towin->w_topline = lnum + (dp->df_lnum[i] - dp->df_lnum[idx]);
--	if (lnum >= dp->df_lnum[idx])
-+	towin->w_topline = lnum + (dp->df_lnum[toidx] - dp->df_lnum[fromidx]);
-+	if (lnum >= dp->df_lnum[fromidx])
- 	{
--	    /* Inside a change: compute filler lines. */
--	    if (dp->df_count[i] == dp->df_count[idx])
-+	    /* Inside a change: compute filler lines. With three or more
-+	     * buffers we need to know the largest count. */
-+	    max_count = 0;
-+	    for (i = 0; i < DB_COUNT; ++i)
-+		if (curtab->tp_diffbuf[i] != NULL
-+					       && max_count < dp->df_count[i])
-+		    max_count = dp->df_count[i];
-+
-+	    if (dp->df_count[toidx] == dp->df_count[fromidx])
-+	    {
-+		/* same number of lines: use same filler count */
- 		towin->w_topfill = fromwin->w_topfill;
--	    else if (dp->df_count[i] > dp->df_count[idx])
-+	    }
-+	    else if (dp->df_count[toidx] > dp->df_count[fromidx])
- 	    {
--		if (lnum == dp->df_lnum[idx] + dp->df_count[idx])
--		    towin->w_topline = dp->df_lnum[i] + dp->df_count[i]
--							 - fromwin->w_topfill;
-+		if (lnum == dp->df_lnum[fromidx] + dp->df_count[fromidx])
-+		{
-+		    /* more lines in towin and fromwin doesn't show diff
-+		     * lines, only filler lines */
-+		    if (max_count - fromwin->w_topfill >= dp->df_count[toidx])
-+		    {
-+			/* towin also only shows filler lines */
-+			towin->w_topline = dp->df_lnum[toidx]
-+						       + dp->df_count[toidx];
-+			towin->w_topfill = fromwin->w_topfill;
-+		    }
-+		    else
-+			/* towin still has some diff lines to show */
-+			towin->w_topline = dp->df_lnum[toidx]
-+					     + max_count - fromwin->w_topfill;
-+		}
- 	    }
--	    else
-+	    else if (towin->w_topline >= dp->df_lnum[toidx]
-+							+ dp->df_count[toidx])
- 	    {
--		if (towin->w_topline >= dp->df_lnum[i] + dp->df_count[i])
-+		/* less lines in towin and no diff lines to show: compute
-+		 * filler lines */
-+		towin->w_topline = dp->df_lnum[toidx] + dp->df_count[toidx];
-+		if (diff_flags & DIFF_FILLER)
- 		{
--		    if (diff_flags & DIFF_FILLER)
--			towin->w_topfill = dp->df_lnum[idx]
--						   + dp->df_count[idx] - lnum;
--		    towin->w_topline = dp->df_lnum[i] + dp->df_count[i];
-+		    if (lnum == dp->df_lnum[fromidx] + dp->df_count[fromidx])
-+			/* fromwin is also out of diff lines */
-+			towin->w_topfill = fromwin->w_topfill;
-+		    else
-+			/* fromwin has some diff lines */
-+			towin->w_topfill = dp->df_lnum[fromidx]
-+							   + max_count - lnum;
- 		}
- 	    }
- 	}
-diff -Naur vim71.orig/src/digraph.c vim71/src/digraph.c
---- vim71.orig/src/digraph.c	2006-05-02 14:24:04.000000000 -0400
-+++ vim71/src/digraph.c	2008-06-18 06:54:32.000000000 -0400
-@@ -1978,6 +1978,61 @@
- 	{'f', 't', 0xfb05},
- 	{'s', 't', 0xfb06},
- #      endif /* FEAT_MBYTE */
-+
-+	/* Vim 5.x compatible digraphs that don't conflict with the above */
-+	{'~', '!', 161},	/* ¡ */
-+	{'c', '|', 162},	/* ¢ */
-+	{'$', '$', 163},	/* £ */
-+	{'o', 'x', 164},	/* € - currency symbol in ISO 8859-1 */
-+	{'Y', '-', 165},	/* ¥ */
-+	{'|', '|', 166},	/* Š */
-+	{'c', 'O', 169},	/* © */
-+	{'-', ',', 172},	/* ¬ */
-+	{'-', '=', 175},	/* ¯ */
-+	{'~', 'o', 176},	/* ° */
-+	{'2', '2', 178},	/* ² */
-+	{'3', '3', 179},	/* ³ */
-+	{'p', 'p', 182},	/* ¶ */
-+	{'~', '.', 183},	/* · */
-+	{'1', '1', 185},	/* ¹ */
-+	{'~', '?', 191},	/* ¿ */
-+	{'A', '`', 192},	/* À */
-+	{'A', '^', 194},	/* Â */
-+	{'A', '~', 195},	/* Ã */
-+	{'A', '"', 196},	/* Ä */
-+	{'A', '@', 197},	/* Å */
-+	{'E', '`', 200},	/* È */
-+	{'E', '^', 202},	/* Ê */
-+	{'E', '"', 203},	/* Ë */
-+	{'I', '`', 204},	/* Ì */
-+	{'I', '^', 206},	/* Î */
-+	{'I', '"', 207},	/* Ï */
-+	{'N', '~', 209},	/* Ñ */
-+	{'O', '`', 210},	/* Ò */
-+	{'O', '^', 212},	/* Ô */
-+	{'O', '~', 213},	/* Õ */
-+	{'/', '\\', 215},	/* × - multiplication symbol in ISO 8859-1 */
-+	{'U', '`', 217},	/* Ù */
-+	{'U', '^', 219},	/* Û */
-+	{'I', 'p', 222},	/* Þ */
-+	{'a', '`', 224},	/* à */
-+	{'a', '^', 226},	/* â */
-+	{'a', '~', 227},	/* ã */
-+	{'a', '"', 228},	/* ä */
-+	{'a', '@', 229},	/* å */
-+	{'e', '`', 232},	/* è */
-+	{'e', '^', 234},	/* ê */
-+	{'e', '"', 235},	/* ë */
-+	{'i', '`', 236},	/* ì */
-+	{'i', '^', 238},	/* î */
-+	{'n', '~', 241},	/* ñ */
-+	{'o', '`', 242},	/* ò */
-+	{'o', '^', 244},	/* ô */
-+	{'o', '~', 245},	/* õ */
-+	{'u', '`', 249},	/* ù */
-+	{'u', '^', 251},	/* û */
-+	{'y', '"', 255},	/* x XX */
-+
- 	{NUL, NUL, NUL}
-        };
- 
-@@ -2028,7 +2083,7 @@
- 
-     ++no_mapping;
-     ++allow_keys;
--    c = safe_vgetc();
-+    c = plain_vgetc();
-     --no_mapping;
-     --allow_keys;
-     if (c != ESC)		/* ESC cancels CTRL-K */
-@@ -2050,7 +2105,7 @@
- #endif
- 	++no_mapping;
- 	++allow_keys;
--	cc = safe_vgetc();
-+	cc = plain_vgetc();
- 	--no_mapping;
- 	--allow_keys;
- 	if (cc != ESC)	    /* ESC cancels CTRL-K */
-@@ -2349,8 +2404,10 @@
- 
-     if (*curbuf->b_p_keymap == NUL)
-     {
--	/* Stop any active keymap and clear the table. */
-+	/* Stop any active keymap and clear the table.  Also remove
-+	 * b:keymap_name, as no keymap is active now. */
- 	keymap_unload();
-+	do_cmdline_cmd((char_u *)"unlet! b:keymap_name");
-     }
-     else
-     {
-@@ -2500,7 +2557,6 @@
- 
-     ga_clear(&curbuf->b_kmap_ga);
-     curbuf->b_kmap_state &= ~KEYMAP_LOADED;
--    do_cmdline_cmd((char_u *)"unlet! b:keymap_name");
- #ifdef FEAT_WINDOWS
-     status_redraw_curbuf();
- #endif
-diff -Naur vim71.orig/src/edit.c vim71/src/edit.c
---- vim71.orig/src/edit.c	2007-05-07 15:43:55.000000000 -0400
-+++ vim71/src/edit.c	2008-06-18 06:56:15.000000000 -0400
-@@ -129,6 +129,7 @@
- 
- static void ins_ctrl_x __ARGS((void));
- static int  has_compl_option __ARGS((int dict_opt));
-+static int  ins_compl_accept_char __ARGS((int c));
- static int ins_compl_add __ARGS((char_u *str, int len, int icase, char_u *fname, char_u **cptext, int cdir, int flags, int adup));
- static int  ins_compl_equal __ARGS((compl_T *match, char_u *str, int len));
- static void ins_compl_longest_match __ARGS((compl_T *match));
-@@ -549,7 +550,7 @@
- 	i = showmode();
- 
-     if (!p_im && did_restart_edit == 0)
--	change_warning(i + 1);
-+	change_warning(i == 0 ? 0 : i + 1);
- 
- #ifdef CURSOR_SHAPE
-     ui_cursor_shape();		/* may show different cursor shape */
-@@ -702,10 +703,13 @@
- #endif
- 
- 	/*
--	 * Get a character for Insert mode.
-+	 * Get a character for Insert mode.  Ignore K_IGNORE.
- 	 */
- 	lastc = c;			/* remember previous char for CTRL-D */
--	c = safe_vgetc();
-+	do
-+	{
-+	    c = safe_vgetc();
-+	} while (c == K_IGNORE);
- 
- #ifdef FEAT_AUTOCMD
- 	/* Don't want K_CURSORHOLD for the second key, e.g., after CTRL-V. */
-@@ -754,8 +758,9 @@
- 		    continue;
- 		}
- 
--		/* A printable, non-white character: Add to "compl_leader". */
--		if (vim_isprintc(c) && !vim_iswhite(c))
-+		/* A non-white character that fits in with the current
-+		 * completion: Add to "compl_leader". */
-+		if (ins_compl_accept_char(c))
- 		{
- 		    ins_compl_addleader(c);
- 		    continue;
-@@ -775,7 +780,7 @@
- 	/* Prepare for or stop CTRL-X mode.  This doesn't do completion, but
- 	 * it does fix up the text when finishing completion. */
- 	compl_get_longest = FALSE;
--	if (c != K_IGNORE && ins_compl_prep(c))
-+	if (ins_compl_prep(c))
- 	    continue;
- #endif
- 
-@@ -788,7 +793,7 @@
- 	    ins_redraw(FALSE);
- 	    ++no_mapping;
- 	    ++allow_keys;
--	    c = safe_vgetc();
-+	    c = plain_vgetc();
- 	    --no_mapping;
- 	    --allow_keys;
- 	    if (c != Ctrl_N && c != Ctrl_G && c != Ctrl_O)
-@@ -981,7 +986,7 @@
- #ifdef FEAT_NETBEANS_INTG
- 	case K_F21:	/* NetBeans command */
- 	    ++no_mapping;		/* don't map the next key hits */
--	    i = safe_vgetc();
-+	    i = plain_vgetc();
- 	    --no_mapping;
- 	    netbeans_keycommand(i);
- 	    break;
-@@ -1453,6 +1458,14 @@
- # endif
- 			     )
- 	{
-+# ifdef FEAT_SYN_HL
-+	    /* Need to update the screen first, to make sure syntax
-+	     * highlighting is correct after making a change (e.g., inserting
-+	     * a "(".  The autocommand may also require a redraw, so it's done
-+	     * again below, unfortunately. */
-+	    if (syntax_present(curbuf) && must_redraw)
-+		update_screen(0);
-+# endif
- 	    apply_autocmds(EVENT_CURSORMOVEDI, NULL, NULL, FALSE, curbuf);
- 	    last_cursormoved = curwin->w_cursor;
- 	}
-@@ -1652,11 +1665,12 @@
-  * if round is TRUE, round the indent to 'shiftwidth' (only with _INC and _Dec).
-  */
-     void
--change_indent(type, amount, round, replaced)
-+change_indent(type, amount, round, replaced, call_changed_bytes)
-     int		type;
-     int		amount;
-     int		round;
-     int		replaced;	/* replaced character, put on replace stack */
-+    int		call_changed_bytes;	/* call changed_bytes() */
- {
-     int		vcol;
-     int		last_vcol;
-@@ -1713,7 +1727,7 @@
-      * Set the new indent.  The cursor will be put on the first non-blank.
-      */
-     if (type == INDENT_SET)
--	(void)set_indent(amount, SIN_CHANGED);
-+	(void)set_indent(amount, call_changed_bytes ? SIN_CHANGED : 0);
-     else
-     {
- #ifdef FEAT_VREPLACE
-@@ -1723,7 +1737,7 @@
- 	if (State & VREPLACE_FLAG)
- 	    State = INSERT;
- #endif
--	shift_line(type == INDENT_DEC, round, 1);
-+	shift_line(type == INDENT_DEC, round, 1, call_changed_bytes);
- #ifdef FEAT_VREPLACE
- 	State = save_State;
- #endif
-@@ -2053,11 +2067,44 @@
- }
- 
- /*
-+ * Return TRUE when character "c" is part of the item currently being
-+ * completed.  Used to decide whether to abandon complete mode when the menu
-+ * is visible.
-+ */
-+    static int
-+ins_compl_accept_char(c)
-+    int c;
-+{
-+    if (ctrl_x_mode & CTRL_X_WANT_IDENT)
-+	/* When expanding an identifier only accept identifier chars. */
-+	return vim_isIDc(c);
-+
-+    switch (ctrl_x_mode)
-+    {
-+	case CTRL_X_FILES:
-+	    /* When expanding file name only accept file name chars. But not
-+	     * path separators, so that "proto/<Tab>" expands files in
-+	     * "proto", not "proto/" as a whole */
-+	    return vim_isfilec(c) && !vim_ispathsep(c);
-+
-+	case CTRL_X_CMDLINE:
-+	case CTRL_X_OMNI:
-+	    /* Command line and Omni completion can work with just about any
-+	     * printable character, but do stop at white space. */
-+	    return vim_isprintc(c) && !vim_iswhite(c);
-+
-+	case CTRL_X_WHOLE_LINE:
-+	    /* For while line completion a space can be part of the line. */
-+	    return vim_isprintc(c);
-+    }
-+    return vim_iswordc(c);
-+}
-+
-+/*
-  * This is like ins_compl_add(), but if 'ic' and 'inf' are set, then the
-  * case of the originally typed text is used, and the case of the completed
-  * text is inferred, ie this tries to work out what case you probably wanted
-  * the rest of the word to be in -- webb
-- * TODO: make this work for multi-byte characters.
-  */
-     int
- ins_compl_add_infercase(str, len, icase, fname, dir, flags)
-@@ -2068,54 +2115,147 @@
-     int		dir;
-     int		flags;
- {
-+    char_u	*p;
-+    int		i, c;
-+    int		actual_len;		/* Take multi-byte characters */
-+    int		actual_compl_length;	/* into account. */
-+    int		*wca;		        /* Wide character array. */
-     int		has_lower = FALSE;
-     int		was_letter = FALSE;
--    int		idx;
- 
--    if (p_ic && curbuf->b_p_inf && len < IOSIZE)
-+    if (p_ic && curbuf->b_p_inf && len > 0)
-     {
--	/* Infer case of completed part -- webb */
--	/* Use IObuff, str would change text in buffer! */
--	vim_strncpy(IObuff, str, len);
-+	/* Infer case of completed part. */
- 
--	/* Rule 1: Were any chars converted to lower? */
--	for (idx = 0; idx < compl_length; ++idx)
-+	/* Find actual length of completion. */
-+#ifdef FEAT_MBYTE
-+	if (has_mbyte)
- 	{
--	    if (islower(compl_orig_text[idx]))
-+	    p = str;
-+	    actual_len = 0;
-+	    while (*p != NUL)
- 	    {
--		has_lower = TRUE;
--		if (isupper(IObuff[idx]))
--		{
--		    /* Rule 1 is satisfied */
--		    for (idx = compl_length; idx < len; ++idx)
--			IObuff[idx] = TOLOWER_LOC(IObuff[idx]);
--		    break;
--		}
-+		mb_ptr_adv(p);
-+		++actual_len;
- 	    }
- 	}
-+	else
-+#endif
-+	    actual_len = len;
- 
--	/*
--	 * Rule 2: No lower case, 2nd consecutive letter converted to
--	 * upper case.
--	 */
--	if (!has_lower)
-+	/* Find actual length of original text. */
-+#ifdef FEAT_MBYTE
-+	if (has_mbyte)
-+	{
-+	    p = compl_orig_text;
-+	    actual_compl_length = 0;
-+	    while (*p != NUL)
-+	    {
-+		mb_ptr_adv(p);
-+		++actual_compl_length;
-+	    }
-+	}
-+	else
-+#endif
-+	    actual_compl_length = compl_length;
-+
-+	/* Allocate wide character array for the completion and fill it. */
-+	wca = (int *)alloc(actual_len * sizeof(int));
-+	if (wca != NULL)
- 	{
--	    for (idx = 0; idx < compl_length; ++idx)
-+	    p = str;
-+	    for (i = 0; i < actual_len; ++i)
-+#ifdef FEAT_MBYTE
-+		if (has_mbyte)
-+		    wca[i] = mb_ptr2char_adv(&p);
-+		else
-+#endif
-+		    wca[i] = *(p++);
-+
-+	    /* Rule 1: Were any chars converted to lower? */
-+	    p = compl_orig_text;
-+	    for (i = 0; i < actual_compl_length; ++i)
- 	    {
--		if (was_letter && isupper(compl_orig_text[idx])
--						      && islower(IObuff[idx]))
-+#ifdef FEAT_MBYTE
-+		if (has_mbyte)
-+		    c = mb_ptr2char_adv(&p);
-+		else
-+#endif
-+		    c = *(p++);
-+		if (MB_ISLOWER(c))
- 		{
--		    /* Rule 2 is satisfied */
--		    for (idx = compl_length; idx < len; ++idx)
--			IObuff[idx] = TOUPPER_LOC(IObuff[idx]);
--		    break;
-+		    has_lower = TRUE;
-+		    if (MB_ISUPPER(wca[i]))
-+		    {
-+			/* Rule 1 is satisfied. */
-+			for (i = actual_compl_length; i < actual_len; ++i)
-+			    wca[i] = MB_TOLOWER(wca[i]);
-+			break;
-+		    }
-+		}
-+	    }
-+
-+	    /*
-+	     * Rule 2: No lower case, 2nd consecutive letter converted to
-+	     * upper case.
-+	     */
-+	    if (!has_lower)
-+	    {
-+		p = compl_orig_text;
-+		for (i = 0; i < actual_compl_length; ++i)
-+		{
-+#ifdef FEAT_MBYTE
-+		    if (has_mbyte)
-+			c = mb_ptr2char_adv(&p);
-+		    else
-+#endif
-+			c = *(p++);
-+		    if (was_letter && MB_ISUPPER(c) && MB_ISLOWER(wca[i]))
-+		    {
-+			/* Rule 2 is satisfied. */
-+			for (i = actual_compl_length; i < actual_len; ++i)
-+			    wca[i] = MB_TOUPPER(wca[i]);
-+			break;
-+		    }
-+		    was_letter = MB_ISLOWER(c) || MB_ISUPPER(c);
- 		}
--		was_letter = isalpha(compl_orig_text[idx]);
- 	    }
--	}
- 
--	/* Copy the original case of the part we typed */
--	STRNCPY(IObuff, compl_orig_text, compl_length);
-+	    /* Copy the original case of the part we typed. */
-+	    p = compl_orig_text;
-+	    for (i = 0; i < actual_compl_length; ++i)
-+	    {
-+#ifdef FEAT_MBYTE
-+		if (has_mbyte)
-+		    c = mb_ptr2char_adv(&p);
-+		else
-+#endif
-+		    c = *(p++);
-+		if (MB_ISLOWER(c))
-+		    wca[i] = MB_TOLOWER(wca[i]);
-+		else if (MB_ISUPPER(c))
-+		    wca[i] = MB_TOUPPER(wca[i]);
-+	    }
-+
-+	    /*
-+	     * Generate encoding specific output from wide character array.
-+	     * Multi-byte characters can occupy up to five bytes more than
-+	     * ASCII characters, and we also need one byte for NUL, so stay
-+	     * six bytes away from the edge of IObuff.
-+	     */
-+	    p = IObuff;
-+	    i = 0;
-+	    while (i < actual_len && (p - IObuff + 6) < IOSIZE)
-+#ifdef FEAT_MBYTE
-+		if (has_mbyte)
-+		    p += (*mb_char2bytes)(wca[i++], p);
-+		else
-+#endif
-+		    *(p++) = wca[i++];
-+	    *p = NUL;
-+
-+	    vim_free(wca);
-+	}
- 
- 	return ins_compl_add(IObuff, len, icase, fname, NULL, dir,
- 								flags, FALSE);
-@@ -2842,6 +2982,7 @@
- 			/*
- 			 * Add the other matches on the line
- 			 */
-+			ptr = buf;
- 			while (!got_int)
- 			{
- 			    /* Find start of the next word.  Skip white
-@@ -2851,7 +2992,7 @@
- 				break;
- 			    wstart = ptr;
- 
--			    /* Find end of the word and add it. */
-+			    /* Find end of the word. */
- #ifdef FEAT_MBYTE
- 			    if (has_mbyte)
- 				/* Japanese words may have characters in
-@@ -2868,9 +3009,12 @@
- 			    else
- #endif
- 				ptr = find_word_end(ptr);
--			    add_r = ins_compl_add_infercase(wstart,
--				    (int)(ptr - wstart),
--				    p_ic, files[i], *dir, 0);
-+
-+			    /* Add the word. Skip the regexp match. */
-+			    if (wstart != regmatch->startp[0])
-+				add_r = ins_compl_add_infercase(wstart,
-+					(int)(ptr - wstart),
-+					p_ic, files[i], *dir, 0);
- 			}
- 		    }
- 		    if (add_r == OK)
-@@ -3032,8 +3176,11 @@
-     p = line + curwin->w_cursor.col;
-     mb_ptr_back(line, p);
- 
--    /* Stop completion when the whole word was deleted. */
--    if ((int)(p - line) - (int)compl_col <= 0)
-+    /* Stop completion when the whole word was deleted.  For Omni completion
-+     * allow the word to be deleted, we won't match everything. */
-+    if ((int)(p - line) - (int)compl_col < 0
-+	    || ((int)(p - line) - (int)compl_col == 0
-+		&& (ctrl_x_mode & CTRL_X_OMNI) == 0))
- 	return K_BS;
- 
-     /* Deleted more than what was used to find matches or didn't finish
-@@ -3250,8 +3397,8 @@
-     if (c != Ctrl_R && vim_is_ctrl_x_key(c))
- 	edit_submode_extra = NULL;
- 
--    /* Ignore end of Select mode mapping */
--    if (c == K_SELECT)
-+    /* Ignore end of Select mode mapping and mouse scroll buttons. */
-+    if (c == K_SELECT || c == K_MOUSEDOWN || c == K_MOUSEUP)
- 	return retval;
- 
-     /* Set "compl_get_longest" when finding the first matches. */
-@@ -3927,7 +4074,7 @@
- 		    found_new_match = searchit(NULL, ins_buf, pos,
- 							      compl_direction,
- 				 compl_pattern, 1L, SEARCH_KEEP + SEARCH_NFMSG,
--							RE_LAST, (linenr_T)0);
-+						  RE_LAST, (linenr_T)0, NULL);
- 		--msg_silent;
- 		if (!compl_started)
- 		{
-@@ -4372,15 +4519,17 @@
- 	else
- 	{
- 	    /* Need to get the character to have KeyTyped set.  We'll put it
--	     * back with vungetc() below. */
-+	     * back with vungetc() below.  But skip K_IGNORE. */
- 	    c = safe_vgetc();
-+	    if (c != K_IGNORE)
-+	    {
-+		/* Don't interrupt completion when the character wasn't typed,
-+		 * e.g., when doing @q to replay keys. */
-+		if (c != Ctrl_R && KeyTyped)
-+		    compl_interrupted = TRUE;
- 
--	    /* Don't interrupt completion when the character wasn't typed,
--	     * e.g., when doing @q to replay keys. */
--	    if (c != Ctrl_R && KeyTyped)
--		compl_interrupted = TRUE;
--
--	    vungetc(c);
-+		vungetc(c);
-+	    }
- 	}
-     }
-     if (compl_pending != 0 && !got_int)
-@@ -4495,14 +4644,13 @@
- 	curs_col = curwin->w_cursor.col;
- 	compl_pending = 0;
- 
--	/* if this same ctrl_x_mode has been interrupted use the text from
-+	/* If this same ctrl_x_mode has been interrupted use the text from
- 	 * "compl_startpos" to the cursor as a pattern to add a new word
- 	 * instead of expand the one before the cursor, in word-wise if
--	 * "compl_startpos"
--	 * is not in the same line as the cursor then fix it (the line has
--	 * been split because it was longer than 'tw').  if SOL is set then
--	 * skip the previous pattern, a word at the beginning of the line has
--	 * been inserted, we'll look for that  -- Acevedo. */
-+	 * "compl_startpos" is not in the same line as the cursor then fix it
-+	 * (the line has been split because it was longer than 'tw').  if SOL
-+	 * is set then skip the previous pattern, a word at the beginning of
-+	 * the line has been inserted, we'll look for that  -- Acevedo. */
- 	if ((compl_cont_status & CONT_INTRPT) == CONT_INTRPT
- 					    && compl_cont_mode == ctrl_x_mode)
- 	{
-@@ -5128,10 +5276,7 @@
-     i = 0;
-     for (;;)
-     {
--	do
--	    nc = safe_vgetc();
--	while (nc == K_IGNORE || nc == K_VER_SCROLLBAR
--						    || nc == K_HOR_SCROLLBAR);
-+	nc = plain_vgetc();
- #ifdef FEAT_CMDL_INFO
- 	if (!(State & CMDLINE)
- # ifdef FEAT_MBYTE
-@@ -5346,7 +5491,7 @@
- #if defined(FEAT_EVAL)
- 	int do_internal = TRUE;
- 
--	if (*curbuf->b_p_fex != NUL)
-+	if (*curbuf->b_p_fex != NUL && (flags & INSCHAR_NO_FEX) == 0)
- 	{
- 	    do_internal = (fex_format(curwin->w_cursor.lnum, 1L, c) != 0);
- 	    /* It may be required to save for undo again, e.g. when setline()
-@@ -5782,7 +5927,7 @@
- 	    {
- #ifdef FEAT_VREPLACE
- 		if (State & VREPLACE_FLAG)
--		    change_indent(INDENT_SET, second_indent, FALSE, NUL);
-+		    change_indent(INDENT_SET, second_indent, FALSE, NUL, TRUE);
- 		else
- #endif
- 		    (void)set_indent(second_indent, SIN_CHANGED);
-@@ -5912,7 +6057,7 @@
-      * be adjusted for the text formatting.
-      */
-     saved_cursor = pos;
--    format_lines((linenr_T)-1);
-+    format_lines((linenr_T)-1, FALSE);
-     curwin->w_cursor = saved_cursor;
-     saved_cursor.lnum = 0;
- 
-@@ -6313,8 +6458,10 @@
- {
-     vim_free(last_insert);
-     last_insert = NULL;
-+# ifdef FEAT_INS_EXPAND
-     vim_free(compl_orig_text);
-     compl_orig_text = NULL;
-+# endif
- }
- #endif
- 
-@@ -6806,6 +6953,25 @@
-     ++replace_stack_nr;
- }
- 
-+#if defined(FEAT_MBYTE) || defined(PROTO)
-+/*
-+ * Push a character onto the replace stack.  Handles a multi-byte character in
-+ * reverse byte order, so that the first byte is popped off first.
-+ * Return the number of bytes done (includes composing characters).
-+ */
-+    int
-+replace_push_mb(p)
-+    char_u *p;
-+{
-+    int l = (*mb_ptr2len)(p);
-+    int j;
-+
-+    for (j = l - 1; j >= 0; --j)
-+	replace_push(p[j]);
-+    return l;
-+}
-+#endif
-+
- #if 0
- /*
-  * call replace_push(c) with replace_offset set to the first NUL.
-@@ -7067,7 +7233,7 @@
- fixthisline(get_the_indent)
-     int (*get_the_indent) __ARGS((void));
- {
--    change_indent(INDENT_SET, get_the_indent(), FALSE, 0);
-+    change_indent(INDENT_SET, get_the_indent(), FALSE, 0, TRUE);
-     if (linewhite(curwin->w_cursor.lnum))
- 	did_ai = TRUE;	    /* delete the indent if the line stays empty */
- }
-@@ -7215,6 +7381,8 @@
- 		p = ml_get_curline();
- 		if (cin_iscase(p) || cin_isscopedecl(p) || cin_islabel(30))
- 		    return TRUE;
-+		/* Need to get the line again after cin_islabel(). */
-+		p = ml_get_curline();
- 		if (curwin->w_cursor.col > 2
- 			&& p[curwin->w_cursor.col - 1] == ':'
- 			&& p[curwin->w_cursor.col - 2] == ':')
-@@ -7477,7 +7645,7 @@
-      * deleted when ESC is hit.
-      */
-     ++no_mapping;
--    regname = safe_vgetc();
-+    regname = plain_vgetc();
- #ifdef FEAT_LANGMAP
-     LANGMAP_ADJUST(regname, TRUE);
- #endif
-@@ -7488,7 +7656,7 @@
- #ifdef FEAT_CMDL_INFO
- 	add_to_showcmd_c(literally);
- #endif
--	regname = safe_vgetc();
-+	regname = plain_vgetc();
- #ifdef FEAT_LANGMAP
- 	LANGMAP_ADJUST(regname, TRUE);
- #endif
-@@ -7579,7 +7747,7 @@
-      * deleted when ESC is hit.
-      */
-     ++no_mapping;
--    c = safe_vgetc();
-+    c = plain_vgetc();
-     --no_mapping;
-     switch (c)
-     {
-@@ -7998,7 +8166,8 @@
-     /*
-      * 0^D and ^^D: remove all indent.
-      */
--    if ((lastc == '0' || lastc == '^') && curwin->w_cursor.col)
-+    if (c == Ctrl_D && (lastc == '0' || lastc == '^')
-+						  && curwin->w_cursor.col > 0)
-     {
- 	--curwin->w_cursor.col;
- 	(void)del_char(FALSE);		/* delete the '^' or '0' */
-@@ -8007,10 +8176,10 @@
- 	    replace_pop_ins();
- 	if (lastc == '^')
- 	    old_indent = get_indent();	/* remember curr. indent */
--	change_indent(INDENT_SET, 0, TRUE, 0);
-+	change_indent(INDENT_SET, 0, TRUE, 0, TRUE);
-     }
-     else
--	change_indent(c == Ctrl_D ? INDENT_DEC : INDENT_INC, 0, TRUE, 0);
-+	change_indent(c == Ctrl_D ? INDENT_DEC : INDENT_INC, 0, TRUE, 0, TRUE);
- 
-     if (did_ai && *skipwhite(ml_get_curline()) != NUL)
- 	did_ai = FALSE;
-@@ -8053,6 +8222,29 @@
-     AppendCharToRedobuff(K_DEL);
- }
- 
-+static void ins_bs_one __ARGS((colnr_T *vcolp));
-+
-+/*
-+ * Delete one character for ins_bs().
-+ */
-+    static void
-+ins_bs_one(vcolp)
-+    colnr_T	*vcolp;
-+{
-+    dec_cursor();
-+    getvcol(curwin, &curwin->w_cursor, vcolp, NULL, NULL);
-+    if (State & REPLACE_FLAG)
-+    {
-+	/* Don't delete characters before the insert point when in
-+	 * Replace mode */
-+	if (curwin->w_cursor.lnum != Insstart.lnum
-+		|| curwin->w_cursor.col >= Insstart.col)
-+	    replace_do_bs();
-+    }
-+    else
-+	(void)del_char(FALSE);
-+}
-+
- /*
-  * Handle Backspace, delete-word and delete-line in Insert mode.
-  * Return TRUE when backspace was actually used.
-@@ -8274,6 +8466,7 @@
- 	if (	   mode == BACKSPACE_CHAR
- 		&& ((p_sta && in_indent)
- 		    || (curbuf->b_p_sts != 0
-+			&& curwin->w_cursor.col > 0
- 			&& (*(ml_get_cursor() - 1) == TAB
- 			    || (*(ml_get_cursor() - 1) == ' '
- 				&& (!*inserted_space_p
-@@ -8282,9 +8475,7 @@
- 	    int		ts;
- 	    colnr_T	vcol;
- 	    colnr_T	want_vcol;
--#if 0
--	    int		extra = 0;
--#endif
-+	    colnr_T	start_vcol;
- 
- 	    *inserted_space_p = FALSE;
- 	    if (p_sta && in_indent)
-@@ -8295,6 +8486,7 @@
- 	     * 'showbreak' may get in the way, need to get the last column of
- 	     * the previous character. */
- 	    getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
-+	    start_vcol = vcol;
- 	    dec_cursor();
- 	    getvcol(curwin, &curwin->w_cursor, NULL, NULL, &want_vcol);
- 	    inc_cursor();
-@@ -8303,30 +8495,7 @@
- 	    /* delete characters until we are at or before want_vcol */
- 	    while (vcol > want_vcol
- 		    && (cc = *(ml_get_cursor() - 1), vim_iswhite(cc)))
--	    {
--		dec_cursor();
--		getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
--		if (State & REPLACE_FLAG)
--		{
--		    /* Don't delete characters before the insert point when in
--		     * Replace mode */
--		    if (curwin->w_cursor.lnum != Insstart.lnum
--			    || curwin->w_cursor.col >= Insstart.col)
--		    {
--#if 0	/* what was this for?  It causes problems when sw != ts. */
--			if (State == REPLACE && (int)vcol < want_vcol)
--			{
--			    (void)del_char(FALSE);
--			    extra = 2;	/* don't pop too much */
--			}
--			else
--#endif
--			    replace_do_bs();
--		    }
--		}
--		else
--		    (void)del_char(FALSE);
--	    }
-+		ins_bs_one(&vcol);
- 
- 	    /* insert extra spaces until we are at want_vcol */
- 	    while (vcol < want_vcol)
-@@ -8343,22 +8512,16 @@
- #endif
- 		{
- 		    ins_str((char_u *)" ");
--		    if ((State & REPLACE_FLAG) /* && extra <= 1 */)
--		    {
--#if 0
--			if (extra)
--			    replace_push_off(NUL);
--			else
--#endif
--			    replace_push(NUL);
--		    }
--#if 0
--		    if (extra == 2)
--			extra = 1;
--#endif
-+		    if ((State & REPLACE_FLAG))
-+			replace_push(NUL);
- 		}
- 		getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
- 	    }
-+
-+	    /* If we are now back where we started delete one character.  Can
-+	     * happen when using 'sts' and 'linebreak'. */
-+	    if (vcol >= start_vcol)
-+		ins_bs_one(&vcol);
- 	}
- 
- 	/*
-@@ -8461,6 +8624,14 @@
-     if (vim_strchr(p_cpo, CPO_BACKSPACE) != NULL && dollar_vcol == 0)
- 	dollar_vcol = curwin->w_virtcol;
- 
-+#ifdef FEAT_FOLDING
-+    /* When deleting a char the cursor line must never be in a closed fold.
-+     * E.g., when 'foldmethod' is indent and deleting the first non-white
-+     * char before a Tab. */
-+    if (did_backspace)
-+	foldOpenCursor();
-+#endif
-+
-     return did_backspace;
- }
- 
-@@ -8518,15 +8689,16 @@
-     int		up;
- {
-     pos_T	tpos;
--# if defined(FEAT_GUI) && defined(FEAT_WINDOWS)
--    win_T	*old_curwin;
-+# if defined(FEAT_WINDOWS)
-+    win_T	*old_curwin = curwin;
-+# endif
-+# ifdef FEAT_INS_EXPAND
-+    int		did_scroll = FALSE;
- # endif
- 
-     tpos = curwin->w_cursor;
- 
- # if defined(FEAT_GUI) && defined(FEAT_WINDOWS)
--    old_curwin = curwin;
--
-     /* Currently the mouse coordinates are only known in the GUI. */
-     if (gui.in_use && mouse_row >= 0 && mouse_col >= 0)
-     {
-@@ -8543,10 +8715,23 @@
- # endif
- 	undisplay_dollar();
- 
--    if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))
--	scroll_redraw(up, (long)(curwin->w_botline - curwin->w_topline));
--    else
--	scroll_redraw(up, 3L);
-+# ifdef FEAT_INS_EXPAND
-+    /* Don't scroll the window in which completion is being done. */
-+    if (!pum_visible()
-+#  if defined(FEAT_WINDOWS)
-+	    || curwin != old_curwin
-+#  endif
-+	    )
-+# endif
-+    {
-+	if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))
-+	    scroll_redraw(up, (long)(curwin->w_botline - curwin->w_topline));
-+	else
-+	    scroll_redraw(up, 3L);
-+# ifdef FEAT_INS_EXPAND
-+	did_scroll = TRUE;
-+# endif
-+    }
- 
- # if defined(FEAT_GUI) && defined(FEAT_WINDOWS)
-     curwin->w_redr_status = TRUE;
-@@ -8555,6 +8740,17 @@
-     curbuf = curwin->w_buffer;
- # endif
- 
-+# ifdef FEAT_INS_EXPAND
-+    /* The popup menu may overlay the window, need to redraw it.
-+     * TODO: Would be more efficient to only redraw the windows that are
-+     * overlapped by the popup menu. */
-+    if (pum_visible() && did_scroll)
-+    {
-+	redraw_all_later(NOT_VALID);
-+	ins_compl_show_pum();
-+    }
-+# endif
-+
-     if (!equalpos(curwin->w_cursor, tpos))
-     {
- 	start_arrow(&tpos);
-@@ -9257,7 +9453,7 @@
-      * mode message to be deleted when ESC is hit */
-     ++no_mapping;
-     ++allow_keys;
--    c = safe_vgetc();
-+    c = plain_vgetc();
-     --no_mapping;
-     --allow_keys;
-     if (IS_SPECIAL(c) || mod_mask)	    /* special key */
-@@ -9289,7 +9485,7 @@
- 	}
- 	++no_mapping;
- 	++allow_keys;
--	cc = safe_vgetc();
-+	cc = plain_vgetc();
- 	--no_mapping;
- 	--allow_keys;
- 	if (cc != ESC)
-@@ -9443,7 +9639,7 @@
- 	    curwin->w_cursor = old_pos;
- #ifdef FEAT_VREPLACE
- 	    if (State & VREPLACE_FLAG)
--		change_indent(INDENT_SET, i, FALSE, NUL);
-+		change_indent(INDENT_SET, i, FALSE, NUL, TRUE);
- 	    else
- #endif
- 		(void)set_indent(i, SIN_CHANGED);
-@@ -9472,7 +9668,7 @@
- 		curwin->w_cursor = old_pos;
- 	    }
- 	    if (temp)
--		shift_line(TRUE, FALSE, 1);
-+		shift_line(TRUE, FALSE, 1, TRUE);
- 	}
-     }
- 
-diff -Naur vim71.orig/src/eval.c vim71/src/eval.c
---- vim71.orig/src/eval.c	2007-05-07 15:47:32.000000000 -0400
-+++ vim71/src/eval.c	2008-06-18 06:56:49.000000000 -0400
-@@ -345,6 +345,7 @@
-     {VV_NAME("mouse_win",	 VAR_NUMBER), 0},
-     {VV_NAME("mouse_lnum",	 VAR_NUMBER), 0},
-     {VV_NAME("mouse_col",	 VAR_NUMBER), 0},
-+    {VV_NAME("operator",	 VAR_STRING), VV_RO},
- };
- 
- /* shorthand */
-@@ -369,17 +370,17 @@
- static int ex_let_vars __ARGS((char_u *arg, typval_T *tv, int copy, int semicolon, int var_count, char_u *nextchars));
- static char_u *skip_var_list __ARGS((char_u *arg, int *var_count, int *semicolon));
- static char_u *skip_var_one __ARGS((char_u *arg));
--static void list_hashtable_vars __ARGS((hashtab_T *ht, char_u *prefix, int empty));
--static void list_glob_vars __ARGS((void));
--static void list_buf_vars __ARGS((void));
--static void list_win_vars __ARGS((void));
-+static void list_hashtable_vars __ARGS((hashtab_T *ht, char_u *prefix, int empty, int *first));
-+static void list_glob_vars __ARGS((int *first));
-+static void list_buf_vars __ARGS((int *first));
-+static void list_win_vars __ARGS((int *first));
- #ifdef FEAT_WINDOWS
--static void list_tab_vars __ARGS((void));
-+static void list_tab_vars __ARGS((int *first));
- #endif
--static void list_vim_vars __ARGS((void));
--static void list_script_vars __ARGS((void));
--static void list_func_vars __ARGS((void));
--static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg));
-+static void list_vim_vars __ARGS((int *first));
-+static void list_script_vars __ARGS((int *first));
-+static void list_func_vars __ARGS((int *first));
-+static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg, int *first));
- static char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op));
- static int check_changedtick __ARGS((char_u *arg));
- static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int quiet, int fne_flags));
-@@ -475,6 +476,7 @@
- static void f_changenr __ARGS((typval_T *argvars, typval_T *rettv));
- static void f_char2nr __ARGS((typval_T *argvars, typval_T *rettv));
- static void f_cindent __ARGS((typval_T *argvars, typval_T *rettv));
-+static void f_clearmatches __ARGS((typval_T *argvars, typval_T *rettv));
- static void f_col __ARGS((typval_T *argvars, typval_T *rettv));
- #if defined(FEAT_INS_EXPAND)
- static void f_complete __ARGS((typval_T *argvars, typval_T *rettv));
-@@ -505,6 +507,7 @@
- static void f_filter __ARGS((typval_T *argvars, typval_T *rettv));
- static void f_finddir __ARGS((typval_T *argvars, typval_T *rettv));
- static void f_findfile __ARGS((typval_T *argvars, typval_T *rettv));
-+static void f_fnameescape __ARGS((typval_T *argvars, typval_T *rettv));
- static void f_fnamemodify __ARGS((typval_T *argvars, typval_T *rettv));
- static void f_foldclosed __ARGS((typval_T *argvars, typval_T *rettv));
- static void f_foldclosedend __ARGS((typval_T *argvars, typval_T *rettv));
-@@ -529,6 +532,8 @@
- static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv));
- static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv));
- static void f_getline __ARGS((typval_T *argvars, typval_T *rettv));
-+static void f_getmatches __ARGS((typval_T *argvars, typval_T *rettv));
-+static void f_getpid __ARGS((typval_T *argvars, typval_T *rettv));
- static void f_getpos __ARGS((typval_T *argvars, typval_T *rettv));
- static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv));
- static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv));
-@@ -577,7 +582,9 @@
- static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv));
- static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv));
- static void f_match __ARGS((typval_T *argvars, typval_T *rettv));
-+static void f_matchadd __ARGS((typval_T *argvars, typval_T *rettv));
- static void f_matcharg __ARGS((typval_T *argvars, typval_T *rettv));
-+static void f_matchdelete __ARGS((typval_T *argvars, typval_T *rettv));
- static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv));
- static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv));
- static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv));
-@@ -618,6 +625,7 @@
- static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv));
- static void f_setline __ARGS((typval_T *argvars, typval_T *rettv));
- static void f_setloclist __ARGS((typval_T *argvars, typval_T *rettv));
-+static void f_setmatches __ARGS((typval_T *argvars, typval_T *rettv));
- static void f_setpos __ARGS((typval_T *argvars, typval_T *rettv));
- static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv));
- static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv));
-@@ -645,6 +653,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_synstack __ARGS((typval_T *argvars, typval_T *rettv));
- static void f_system __ARGS((typval_T *argvars, typval_T *rettv));
- static void f_tabpagebuflist __ARGS((typval_T *argvars, typval_T *rettv));
- static void f_tabpagenr __ARGS((typval_T *argvars, typval_T *rettv));
-@@ -672,7 +681,7 @@
- static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv));
- 
- static int list2fpos __ARGS((typval_T *arg, pos_T *posp, int *fnump));
--static pos_T *var2fpos __ARGS((typval_T *varp, int lnum, int *fnum));
-+static pos_T *var2fpos __ARGS((typval_T *varp, int dollar_lnum, int *fnum));
- static int get_env_len __ARGS((char_u **arg));
- static int get_id_len __ARGS((char_u **arg));
- static int get_name_len __ARGS((char_u **arg, char_u **alias, int evaluate, int verbose));
-@@ -699,8 +708,8 @@
- static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname));
- static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val));
- static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi));
--static void list_one_var __ARGS((dictitem_T *v, char_u *prefix));
--static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string));
-+static void list_one_var __ARGS((dictitem_T *v, char_u *prefix, int *first));
-+static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string, int *first));
- static void set_var __ARGS((char_u *name, typval_T *varp, int copy));
- static int var_check_ro __ARGS((int flags, char_u *name));
- static int var_check_fixed __ARGS((int flags, char_u *name));
-@@ -992,20 +1001,20 @@
-     char_u	*value;
-     int		value_len;
- {
--    size_t	len;
-+    int		len;
- 
-     if (redir_lval == NULL)
- 	return;
- 
-     if (value_len == -1)
--	len = STRLEN(value);	/* Append the entire string */
-+	len = (int)STRLEN(value);	/* Append the entire string */
-     else
--	len = value_len;	/* Append only "value_len" characters */
-+	len = value_len;		/* Append only "value_len" characters */
- 
--    if (ga_grow(&redir_ga, (int)len) == OK)
-+    if (ga_grow(&redir_ga, len) == OK)
-     {
- 	mch_memmove((char *)redir_ga.ga_data + redir_ga.ga_len, value, len);
--	redir_ga.ga_len += (int)len;
-+	redir_ga.ga_len += len;
-     }
-     else
- 	var_redir_stop();
-@@ -1313,7 +1322,6 @@
- {
-     hashitem_T	*hi;
- 
--    clear_tv(&vimvars[idx].vv_tv);
-     vimvars[idx].vv_tv = *save_tv;
-     if (vimvars[idx].vv_type == VAR_UNKNOWN)
-     {
-@@ -1357,7 +1365,6 @@
- 
-     if (p_verbose == 0)
- 	--emsg_off;
--    vimvars[VV_VAL].vv_str = NULL;
-     restore_vimvar(VV_VAL, &save_val);
- 
-     return list;
-@@ -1411,7 +1418,8 @@
- }
- 
- 
--#if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO)
-+#if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) \
-+	|| defined(FEAT_COMPL_FUNC) || defined(PROTO)
- /*
-  * Call some vimL function and return the result in "*rettv".
-  * Uses argv[argc] for the function arguments.
-@@ -1484,6 +1492,7 @@
-     return ret;
- }
- 
-+# if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO)
- /*
-  * Call vimL function "func" and return the result as a string.
-  * Returns NULL when calling the function fails.
-@@ -1506,8 +1515,9 @@
-     clear_tv(&rettv);
-     return retval;
- }
-+# endif
- 
--#if defined(FEAT_COMPL_FUNC) || defined(PROTO)
-+# if defined(FEAT_COMPL_FUNC) || defined(PROTO)
- /*
-  * Call vimL function "func" and return the result as a number.
-  * Returns -1 when calling the function fails.
-@@ -1530,7 +1540,7 @@
-     clear_tv(&rettv);
-     return retval;
- }
--#endif
-+# endif
- 
- /*
-  * Call vimL function "func" and return the result as a list
-@@ -1556,9 +1566,9 @@
- 
-     return rettv.vval.v_list;
- }
--
- #endif
- 
-+
- /*
-  * Save the current function call pointer, and set it to NULL.
-  * Used when executing autocommands and for ":source".
-@@ -1691,6 +1701,7 @@
-     int		semicolon = 0;
-     char_u	op[2];
-     char_u	*argend;
-+    int		first = TRUE;
- 
-     argend = skip_var_list(arg, &var_count, &semicolon);
-     if (argend == NULL)
-@@ -1707,19 +1718,19 @@
- 	    EMSG(_(e_invarg));
- 	else if (!ends_excmd(*arg))
- 	    /* ":let var1 var2" */
--	    arg = list_arg_vars(eap, arg);
-+	    arg = list_arg_vars(eap, arg, &first);
- 	else if (!eap->skip)
- 	{
- 	    /* ":let" */
--	    list_glob_vars();
--	    list_buf_vars();
--	    list_win_vars();
-+	    list_glob_vars(&first);
-+	    list_buf_vars(&first);
-+	    list_win_vars(&first);
- #ifdef FEAT_WINDOWS
--	    list_tab_vars();
-+	    list_tab_vars(&first);
- #endif
--	    list_script_vars();
--	    list_func_vars();
--	    list_vim_vars();
-+	    list_script_vars(&first);
-+	    list_func_vars(&first);
-+	    list_vim_vars(&first);
- 	}
- 	eap->nextcmd = check_nextcmd(arg);
-     }
-@@ -1924,10 +1935,11 @@
-  * If "empty" is TRUE also list NULL strings as empty strings.
-  */
-     static void
--list_hashtable_vars(ht, prefix, empty)
-+list_hashtable_vars(ht, prefix, empty, first)
-     hashtab_T	*ht;
-     char_u	*prefix;
-     int		empty;
-+    int		*first;
- {
-     hashitem_T	*hi;
-     dictitem_T	*di;
-@@ -1942,7 +1954,7 @@
- 	    di = HI2DI(hi);
- 	    if (empty || di->di_tv.v_type != VAR_STRING
- 					   || di->di_tv.vval.v_string != NULL)
--		list_one_var(di, prefix);
-+		list_one_var(di, prefix, first);
- 	}
-     }
- }
-@@ -1951,32 +1963,38 @@
-  * List global variables.
-  */
-     static void
--list_glob_vars()
-+list_glob_vars(first)
-+    int *first;
- {
--    list_hashtable_vars(&globvarht, (char_u *)"", TRUE);
-+    list_hashtable_vars(&globvarht, (char_u *)"", TRUE, first);
- }
- 
- /*
-  * List buffer variables.
-  */
-     static void
--list_buf_vars()
-+list_buf_vars(first)
-+    int *first;
- {
-     char_u	numbuf[NUMBUFLEN];
- 
--    list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:", TRUE);
-+    list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:",
-+								 TRUE, first);
- 
-     sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick);
--    list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, numbuf);
-+    list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER,
-+							       numbuf, first);
- }
- 
- /*
-  * List window variables.
-  */
-     static void
--list_win_vars()
-+list_win_vars(first)
-+    int *first;
- {
--    list_hashtable_vars(&curwin->w_vars.dv_hashtab, (char_u *)"w:", TRUE);
-+    list_hashtable_vars(&curwin->w_vars.dv_hashtab,
-+						 (char_u *)"w:", TRUE, first);
- }
- 
- #ifdef FEAT_WINDOWS
-@@ -1984,9 +2002,11 @@
-  * List tab page variables.
-  */
-     static void
--list_tab_vars()
-+list_tab_vars(first)
-+    int *first;
- {
--    list_hashtable_vars(&curtab->tp_vars.dv_hashtab, (char_u *)"t:", TRUE);
-+    list_hashtable_vars(&curtab->tp_vars.dv_hashtab,
-+						 (char_u *)"t:", TRUE, first);
- }
- #endif
- 
-@@ -1994,39 +2014,44 @@
-  * List Vim variables.
-  */
-     static void
--list_vim_vars()
-+list_vim_vars(first)
-+    int *first;
- {
--    list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE);
-+    list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE, first);
- }
- 
- /*
-  * List script-local variables, if there is a script.
-  */
-     static void
--list_script_vars()
-+list_script_vars(first)
-+    int *first;
- {
-     if (current_SID > 0 && current_SID <= ga_scripts.ga_len)
--	list_hashtable_vars(&SCRIPT_VARS(current_SID), (char_u *)"s:", FALSE);
-+	list_hashtable_vars(&SCRIPT_VARS(current_SID),
-+						(char_u *)"s:", FALSE, first);
- }
- 
- /*
-  * List function variables, if there is a function.
-  */
-     static void
--list_func_vars()
-+list_func_vars(first)
-+    int *first;
- {
-     if (current_funccal != NULL)
- 	list_hashtable_vars(&current_funccal->l_vars.dv_hashtab,
--						       (char_u *)"l:", FALSE);
-+						(char_u *)"l:", FALSE, first);
- }
- 
- /*
-  * List variables in "arg".
-  */
-     static char_u *
--list_arg_vars(eap, arg)
-+list_arg_vars(eap, arg, first)
-     exarg_T	*eap;
-     char_u	*arg;
-+    int		*first;
- {
-     int		error = FALSE;
-     int		len;
-@@ -2083,15 +2108,15 @@
- 			{
- 			    switch (*name)
- 			    {
--				case 'g': list_glob_vars(); break;
--				case 'b': list_buf_vars(); break;
--				case 'w': list_win_vars(); break;
-+				case 'g': list_glob_vars(first); break;
-+				case 'b': list_buf_vars(first); break;
-+				case 'w': list_win_vars(first); break;
- #ifdef FEAT_WINDOWS
--				case 't': list_tab_vars(); break;
-+				case 't': list_tab_vars(first); break;
- #endif
--				case 'v': list_vim_vars(); break;
--				case 's': list_script_vars(); break;
--				case 'l': list_func_vars(); break;
-+				case 'v': list_vim_vars(first); break;
-+				case 's': list_script_vars(first); break;
-+				case 'l': list_func_vars(first); break;
- 				default:
- 					  EMSG2(_("E738: Can't list variables for %s"), name);
- 			    }
-@@ -2108,7 +2133,9 @@
- 			    *arg = NUL;
- 			    list_one_var_a((char_u *)"",
- 				    arg == arg_subsc ? name : name_start,
--				    tv.v_type, s == NULL ? (char_u *)"" : s);
-+				    tv.v_type,
-+				    s == NULL ? (char_u *)"" : s,
-+				    first);
- 			    *arg = c;
- 			    vim_free(tf);
- 			}
-@@ -3383,6 +3410,7 @@
-     hashtab_T	*ht;
-     hashitem_T	*hi;
-     char_u	*varname;
-+    dictitem_T	*di;
- 
-     ht = find_var_ht(name, &varname);
-     if (ht != NULL && *varname != NUL)
-@@ -3390,9 +3418,9 @@
- 	hi = hash_find(ht, varname);
- 	if (!HASHITEM_EMPTY(hi))
- 	{
--	    if (var_check_fixed(HI2DI(hi)->di_flags, name))
--		return FAIL;
--	    if (var_check_ro(HI2DI(hi)->di_flags, name))
-+	    di = HI2DI(hi);
-+	    if (var_check_fixed(di->di_flags, name)
-+		    || var_check_ro(di->di_flags, name))
- 		return FAIL;
- 	    delete_var(ht, hi);
- 	    return OK;
-@@ -6105,6 +6133,7 @@
-     /* Only do this once. */
-     want_garbage_collect = FALSE;
-     may_garbage_collect = FALSE;
-+    garbage_collect_at_exit = FALSE;
- 
-     /*
-      * 1. Go through all accessible variables and mark all lists and dicts
-@@ -6681,7 +6710,7 @@
-     dict_T	*d = NULL;
-     typval_T	tvkey;
-     typval_T	tv;
--    char_u	*key;
-+    char_u	*key = NULL;
-     dictitem_T	*item;
-     char_u	*start = skipwhite(*arg + 1);
-     char_u	buf[NUMBUFLEN];
-@@ -6721,20 +6750,24 @@
- 	    clear_tv(&tvkey);
- 	    goto failret;
- 	}
--	key = get_tv_string_buf_chk(&tvkey, buf);
--	if (key == NULL || *key == NUL)
-+	if (evaluate)
- 	{
--	    /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */
--	    if (key != NULL)
--		EMSG(_(e_emptykey));
--	    clear_tv(&tvkey);
--	    goto failret;
-+	    key = get_tv_string_buf_chk(&tvkey, buf);
-+	    if (key == NULL || *key == NUL)
-+	    {
-+		/* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */
-+		if (key != NULL)
-+		    EMSG(_(e_emptykey));
-+		clear_tv(&tvkey);
-+		goto failret;
-+	    }
- 	}
- 
- 	*arg = skipwhite(*arg + 1);
- 	if (eval1(arg, &tv, evaluate) == FAIL)	/* recursive! */
- 	{
--	    clear_tv(&tvkey);
-+	    if (evaluate)
-+		clear_tv(&tvkey);
- 	    goto failret;
- 	}
- 	if (evaluate)
-@@ -6794,7 +6827,7 @@
-  * "numbuf" is used for a number.
-  * Does not put quotes around strings, as ":echo" displays values.
-  * When "copyID" is not NULL replace recursive lists and dicts with "...".
-- * May return NULL;
-+ * May return NULL.
-  */
-     static char_u *
- echo_string(tv, tofree, numbuf, copyID)
-@@ -6879,7 +6912,7 @@
-  * If the memory is allocated "tofree" is set to it, otherwise NULL.
-  * "numbuf" is used for a number.
-  * Puts quotes around strings, so that they can be parsed back by eval().
-- * May return NULL;
-+ * May return NULL.
-  */
-     static char_u *
- tv2string(tv, tofree, numbuf, copyID)
-@@ -7043,6 +7076,7 @@
-     {"changenr",	0, 0, f_changenr},
-     {"char2nr",		1, 1, f_char2nr},
-     {"cindent",		1, 1, f_cindent},
-+    {"clearmatches",	0, 0, f_clearmatches},
-     {"col",		1, 1, f_col},
- #if defined(FEAT_INS_EXPAND)
-     {"complete",	2, 2, f_complete},
-@@ -7074,6 +7108,7 @@
-     {"filter",		2, 2, f_filter},
-     {"finddir",		1, 3, f_finddir},
-     {"findfile",	1, 3, f_findfile},
-+    {"fnameescape",	1, 1, f_fnameescape},
-     {"fnamemodify",	2, 2, f_fnamemodify},
-     {"foldclosed",	1, 1, f_foldclosed},
-     {"foldclosedend",	1, 1, f_foldclosedend},
-@@ -7082,7 +7117,7 @@
-     {"foldtextresult",	1, 1, f_foldtextresult},
-     {"foreground",	0, 0, f_foreground},
-     {"function",	1, 1, f_function},
--    {"garbagecollect",	0, 0, f_garbagecollect},
-+    {"garbagecollect",	0, 1, f_garbagecollect},
-     {"get",		2, 3, f_get},
-     {"getbufline",	2, 3, f_getbufline},
-     {"getbufvar",	2, 2, f_getbufvar},
-@@ -7099,6 +7134,8 @@
-     {"getftype",	1, 1, f_getftype},
-     {"getline",		1, 2, f_getline},
-     {"getloclist",	1, 1, f_getqflist},
-+    {"getmatches",	0, 0, f_getmatches},
-+    {"getpid",		0, 0, f_getpid},
-     {"getpos",		1, 1, f_getpos},
-     {"getqflist",	0, 0, f_getqflist},
-     {"getreg",		0, 2, f_getreg},
-@@ -7149,7 +7186,9 @@
-     {"maparg",		1, 3, f_maparg},
-     {"mapcheck",	1, 3, f_mapcheck},
-     {"match",		2, 4, f_match},
-+    {"matchadd",	2, 4, f_matchadd},
-     {"matcharg",	1, 1, f_matcharg},
-+    {"matchdelete",	1, 1, f_matchdelete},
-     {"matchend",	2, 4, f_matchend},
-     {"matchlist",	2, 4, f_matchlist},
-     {"matchstr",	2, 4, f_matchstr},
-@@ -7179,17 +7218,18 @@
-     {"repeat",		2, 2, f_repeat},
-     {"resolve",		1, 1, f_resolve},
-     {"reverse",		1, 1, f_reverse},
--    {"search",		1, 3, f_search},
-+    {"search",		1, 4, f_search},
-     {"searchdecl",	1, 3, f_searchdecl},
--    {"searchpair",	3, 6, f_searchpair},
--    {"searchpairpos",	3, 6, f_searchpairpos},
--    {"searchpos",	1, 3, f_searchpos},
-+    {"searchpair",	3, 7, f_searchpair},
-+    {"searchpairpos",	3, 7, f_searchpairpos},
-+    {"searchpos",	1, 4, f_searchpos},
-     {"server2client",	2, 2, f_server2client},
-     {"serverlist",	0, 0, f_serverlist},
-     {"setbufvar",	3, 3, f_setbufvar},
-     {"setcmdpos",	1, 1, f_setcmdpos},
-     {"setline",		2, 2, f_setline},
-     {"setloclist",	2, 3, f_setloclist},
-+    {"setmatches",	1, 1, f_setmatches},
-     {"setpos",		2, 2, f_setpos},
-     {"setqflist",	1, 2, f_setqflist},
-     {"setreg",		2, 3, f_setreg},
-@@ -7217,6 +7257,7 @@
-     {"synID",		3, 3, f_synID},
-     {"synIDattr",	2, 3, f_synIDattr},
-     {"synIDtrans",	1, 1, f_synIDtrans},
-+    {"synstack",	2, 2, f_synstack},
-     {"system",		1, 2, f_system},
-     {"tabpagebuflist",	0, 1, f_tabpagebuflist},
-     {"tabpagenr",	0, 1, f_tabpagenr},
-@@ -8240,6 +8281,20 @@
- }
- 
- /*
-+ * "clearmatches()" function
-+ */
-+/*ARGSUSED*/
-+    static void
-+f_clearmatches(argvars, rettv)
-+    typval_T	*argvars;
-+    typval_T	*rettv;
-+{
-+#ifdef FEAT_SEARCH_EXTRA
-+    clear_matches(curwin);
-+#endif
-+}
-+
-+/*
-  * "col(string)" function
-  */
-     static void
-@@ -8682,7 +8737,7 @@
-     static int		fnum = 0;
-     static int		change_start = 0;
-     static int		change_end = 0;
--    static hlf_T	hlID = 0;
-+    static hlf_T	hlID = (hlf_T)0;
-     int			filler_lines;
-     int			col;
- 
-@@ -9152,13 +9207,13 @@
-     rettv->vval.v_number = filewritable(get_tv_string(&argvars[0]));
- }
- 
--static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int dir));
-+static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int find_what));
- 
-     static void
--findfilendir(argvars, rettv, dir)
-+findfilendir(argvars, rettv, find_what)
-     typval_T	*argvars;
-     typval_T	*rettv;
--    int		dir;
-+    int		find_what;
- {
- #ifdef FEAT_SEARCHPATH
-     char_u	*fname;
-@@ -9203,8 +9258,11 @@
- 		vim_free(fresult);
- 	    fresult = find_file_in_path_option(first ? fname : NULL,
- 					       first ? (int)STRLEN(fname) : 0,
--					0, first, path, dir, curbuf->b_ffname,
--					dir ? (char_u *)"" : curbuf->b_p_sua);
-+					0, first, path,
-+					find_what,
-+					curbuf->b_ffname,
-+					find_what == FINDFILE_DIR
-+					    ? (char_u *)"" : curbuf->b_p_sua);
- 	    first = FALSE;
- 
- 	    if (fresult != NULL && rettv->v_type == VAR_LIST)
-@@ -9339,15 +9397,16 @@
- {
-     typval_T	rettv;
-     char_u	*s;
-+    int		retval = FAIL;
- 
-     copy_tv(tv, &vimvars[VV_VAL].vv_tv);
-     s = expr;
-     if (eval1(&s, &rettv, TRUE) == FAIL)
--	return FAIL;
-+	goto theend;
-     if (*s != NUL)  /* check for trailing chars after expr */
-     {
- 	EMSG2(_(e_invexpr2), s);
--	return FAIL;
-+	goto theend;
-     }
-     if (map)
-     {
-@@ -9366,10 +9425,12 @@
- 	/* On type error, nothing has been removed; return FAIL to stop the
- 	 * loop.  The error message was given by get_tv_number_chk(). */
- 	if (error)
--	    return FAIL;
-+	    goto theend;
-     }
-+    retval = OK;
-+theend:
-     clear_tv(&vimvars[VV_VAL].vv_tv);
--    return OK;
-+    return retval;
- }
- 
- /*
-@@ -9391,7 +9452,7 @@
-     typval_T	*argvars;
-     typval_T	*rettv;
- {
--    findfilendir(argvars, rettv, TRUE);
-+    findfilendir(argvars, rettv, FINDFILE_DIR);
- }
- 
- /*
-@@ -9402,7 +9463,20 @@
-     typval_T	*argvars;
-     typval_T	*rettv;
- {
--    findfilendir(argvars, rettv, FALSE);
-+    findfilendir(argvars, rettv, FINDFILE_FILE);
-+}
-+
-+/*
-+ * "fnameescape({string})" function
-+ */
-+    static void
-+f_fnameescape(argvars, rettv)
-+    typval_T	*argvars;
-+    typval_T	*rettv;
-+{
-+    rettv->vval.v_string = vim_strsave_fnameescape(
-+					   get_tv_string(&argvars[0]), FALSE);
-+    rettv->v_type = VAR_STRING;
- }
- 
- /*
-@@ -9670,6 +9744,9 @@
-     /* This is postponed until we are back at the toplevel, because we may be
-      * using Lists and Dicts internally.  E.g.: ":echo [garbagecollect()]". */
-     want_garbage_collect = TRUE;
-+
-+    if (argvars[0].v_type != VAR_UNKNOWN && get_tv_number(&argvars[0]) == 1)
-+	garbage_collect_at_exit = TRUE;
- }
- 
- /*
-@@ -9868,18 +9945,24 @@
- 
-     ++no_mapping;
-     ++allow_keys;
--    if (argvars[0].v_type == VAR_UNKNOWN)
--	/* getchar(): blocking wait. */
--	n = safe_vgetc();
--    else if (get_tv_number_chk(&argvars[0], &error) == 1)
--	/* getchar(1): only check if char avail */
--	n = vpeekc();
--    else if (error || vpeekc() == NUL)
--	/* illegal argument or getchar(0) and no char avail: return zero */
--	n = 0;
--    else
--	/* getchar(0) and char avail: return char */
--	n = safe_vgetc();
-+    for (;;)
-+    {
-+	if (argvars[0].v_type == VAR_UNKNOWN)
-+	    /* getchar(): blocking wait. */
-+	    n = safe_vgetc();
-+	else if (get_tv_number_chk(&argvars[0], &error) == 1)
-+	    /* getchar(1): only check if char avail */
-+	    n = vpeekc();
-+	else if (error || vpeekc() == NUL)
-+	    /* illegal argument or getchar(0) and no char avail: return zero */
-+	    n = 0;
-+	else
-+	    /* getchar(0) and char avail: return char */
-+	    n = safe_vgetc();
-+	if (n == K_IGNORE)
-+	    continue;
-+	break;
-+    }
-     --no_mapping;
-     --allow_keys;
- 
-@@ -10136,7 +10219,13 @@
- 	if (mch_isdir(fname))
- 	    rettv->vval.v_number = 0;
- 	else
-+	{
- 	    rettv->vval.v_number = (varnumber_T)st.st_size;
-+
-+	    /* non-perfect check for overflow */
-+	    if ((off_t)rettv->vval.v_number != (off_t)st.st_size)
-+		rettv->vval.v_number = -2;
-+	}
-     }
-     else
- 	  rettv->vval.v_number = -1;
-@@ -10269,6 +10358,51 @@
- }
- 
- /*
-+ * "getmatches()" function
-+ */
-+/*ARGSUSED*/
-+    static void
-+f_getmatches(argvars, rettv)
-+    typval_T	*argvars;
-+    typval_T	*rettv;
-+{
-+#ifdef FEAT_SEARCH_EXTRA
-+    dict_T	*dict;
-+    matchitem_T	*cur = curwin->w_match_head;
-+
-+    rettv->vval.v_number = 0;
-+
-+    if (rettv_list_alloc(rettv) == OK)
-+    {
-+	while (cur != NULL)
-+	{
-+	    dict = dict_alloc();
-+	    if (dict == NULL)
-+		return;
-+	    dict_add_nr_str(dict, "group", 0L, syn_id2name(cur->hlg_id));
-+	    dict_add_nr_str(dict, "pattern", 0L, cur->pattern);
-+	    dict_add_nr_str(dict, "priority", (long)cur->priority, NULL);
-+	    dict_add_nr_str(dict, "id", (long)cur->id, NULL);
-+	    list_append_dict(rettv->vval.v_list, dict);
-+	    cur = cur->next;
-+	}
-+    }
-+#endif
-+}
-+
-+/*
-+ * "getpid()" function
-+ */
-+/*ARGSUSED*/
-+    static void
-+f_getpid(argvars, rettv)
-+    typval_T	*argvars;
-+    typval_T	*rettv;
-+{
-+    rettv->vval.v_number = mch_get_pid();
-+}
-+
-+/*
-  * "getpos(string)" function
-  */
-     static void
-@@ -10290,7 +10424,8 @@
- 	    list_append_number(l, (varnumber_T)0);
- 	list_append_number(l, (fp != NULL) ? (varnumber_T)fp->lnum
- 							    : (varnumber_T)0);
--	list_append_number(l, (fp != NULL) ? (varnumber_T)fp->col + 1
-+	list_append_number(l, (fp != NULL)
-+		     ? (varnumber_T)(fp->col == MAXCOL ? MAXCOL : fp->col + 1)
- 							    : (varnumber_T)0);
- 	list_append_number(l,
- #ifdef FEAT_VIRTUALEDIT
-@@ -10785,6 +10920,9 @@
- 	"gui_gtk2",
- # endif
- #endif
-+#ifdef FEAT_GUI_GNOME
-+	"gui_gnome",
-+#endif
- #ifdef FEAT_GUI_MAC
- 	"gui_mac",
- #endif
-@@ -11471,14 +11609,12 @@
-     char_u	*xp_arg = NULL;
- 
-     rettv->v_type = VAR_STRING;
-+    rettv->vval.v_string = NULL;
- 
- #ifdef NO_CONSOLE_INPUT
-     /* While starting up, there is no place to enter text. */
-     if (no_console_input())
--    {
--	rettv->vval.v_string = NULL;
- 	return;
--    }
- #endif
- 
-     cmd_silent = FALSE;		/* Want to see the prompt. */
-@@ -12439,6 +12575,44 @@
- }
- 
- /*
-+ * "matchadd()" function
-+ */
-+    static void
-+f_matchadd(argvars, rettv)
-+    typval_T	*argvars;
-+    typval_T	*rettv;
-+{
-+#ifdef FEAT_SEARCH_EXTRA
-+    char_u	buf[NUMBUFLEN];
-+    char_u	*grp = get_tv_string_buf_chk(&argvars[0], buf);	/* group */
-+    char_u	*pat = get_tv_string_buf_chk(&argvars[1], buf);	/* pattern */
-+    int		prio = 10;	/* default priority */
-+    int		id = -1;
-+    int		error = FALSE;
-+
-+    rettv->vval.v_number = -1;
-+
-+    if (grp == NULL || pat == NULL)
-+	return;
-+    if (argvars[2].v_type != VAR_UNKNOWN)
-+    {
-+	prio = get_tv_number_chk(&argvars[2], &error);
-+	if (argvars[3].v_type != VAR_UNKNOWN)
-+	    id = get_tv_number_chk(&argvars[3], &error);
-+    }
-+    if (error == TRUE)
-+	return;
-+    if (id >= 1 && id <= 3)
-+    {
-+	EMSGN("E798: ID is reserved for \":match\": %ld", id);
-+	return;
-+    }
-+
-+    rettv->vval.v_number = match_add(curwin, grp, pat, prio, id);
-+#endif
-+}
-+
-+/*
-  * "matcharg()" function
-  */
-     static void
-@@ -12449,20 +12623,42 @@
-     if (rettv_list_alloc(rettv) == OK)
-     {
- #ifdef FEAT_SEARCH_EXTRA
--	int	mi = get_tv_number(&argvars[0]);
-+	int	    id = get_tv_number(&argvars[0]);
-+	matchitem_T *m;
- 
--	if (mi >= 1 && mi <= 3)
-+	if (id >= 1 && id <= 3)
- 	{
--	    list_append_string(rettv->vval.v_list,
--				 syn_id2name(curwin->w_match_id[mi - 1]), -1);
--	    list_append_string(rettv->vval.v_list,
--					     curwin->w_match_pat[mi - 1], -1);
-+	    if ((m = (matchitem_T *)get_match(curwin, id)) != NULL)
-+	    {
-+		list_append_string(rettv->vval.v_list,
-+						syn_id2name(m->hlg_id), -1);
-+		list_append_string(rettv->vval.v_list, m->pattern, -1);
-+	    }
-+	    else
-+	    {
-+		list_append_string(rettv->vval.v_list, NUL, -1);
-+		list_append_string(rettv->vval.v_list, NUL, -1);
-+	    }
- 	}
- #endif
-     }
- }
- 
- /*
-+ * "matchdelete()" function
-+ */
-+    static void
-+f_matchdelete(argvars, rettv)
-+    typval_T	*argvars;
-+    typval_T	*rettv;
-+{
-+#ifdef FEAT_SEARCH_EXTRA
-+    rettv->vval.v_number = match_delete(curwin,
-+				       (int)get_tv_number(&argvars[0]), TRUE);
-+#endif
-+}
-+
-+/*
-  * "matchend()" function
-  */
-     static void
-@@ -13680,7 +13876,7 @@
- 	    }
- 	    /* Shorten "remain". */
- 	    if (*q != NUL)
--		STRCPY(remain, q - 1);
-+		mch_memmove(remain, q - 1, STRLEN(q - 1) + 1);
- 	    else
- 	    {
- 		vim_free(remain);
-@@ -13773,6 +13969,7 @@
- 	rettv->vval.v_list = l;
- 	rettv->v_type = VAR_LIST;
- 	++l->lv_refcount;
-+	l->lv_idx = l->lv_len - l->lv_idx - 1;
-     }
- }
- 
-@@ -13858,6 +14055,10 @@
-     int		dir;
-     int		retval = 0;	/* default: FAIL */
-     long	lnum_stop = 0;
-+    proftime_T	tm;
-+#ifdef FEAT_RELTIME
-+    long	time_limit = 0;
-+#endif
-     int		options = SEARCH_KEEP;
-     int		subpatnum;
- 
-@@ -13871,15 +14072,27 @@
-     if (flags & SP_END)
- 	options |= SEARCH_END;
- 
--    /* Optional extra argument: line number to stop searching. */
--    if (argvars[1].v_type != VAR_UNKNOWN
--	    && argvars[2].v_type != VAR_UNKNOWN)
-+    /* Optional arguments: line number to stop searching and timeout. */
-+    if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN)
-     {
- 	lnum_stop = get_tv_number_chk(&argvars[2], NULL);
- 	if (lnum_stop < 0)
- 	    goto theend;
-+#ifdef FEAT_RELTIME
-+	if (argvars[3].v_type != VAR_UNKNOWN)
-+	{
-+	    time_limit = get_tv_number_chk(&argvars[3], NULL);
-+	    if (time_limit < 0)
-+		goto theend;
-+	}
-+#endif
-     }
- 
-+#ifdef FEAT_RELTIME
-+    /* Set the time limit, if there is one. */
-+    profile_setlimit(time_limit, &tm);
-+#endif
-+
-     /*
-      * This function does not accept SP_REPEAT and SP_RETCOUNT flags.
-      * Check to make sure only those flags are set.
-@@ -13895,7 +14108,7 @@
- 
-     pos = save_cursor = curwin->w_cursor;
-     subpatnum = searchit(curwin, curbuf, &pos, dir, pat, 1L,
--				     options, RE_SEARCH, (linenr_T)lnum_stop);
-+				options, RE_SEARCH, (linenr_T)lnum_stop, &tm);
-     if (subpatnum != FAIL)
-     {
- 	if (flags & SP_SUBPAT)
-@@ -13919,6 +14132,8 @@
-     /* If 'n' flag is used: restore cursor position. */
-     if (flags & SP_NOMOVE)
- 	curwin->w_cursor = save_cursor;
-+    else
-+	curwin->w_set_curswant = TRUE;
- theend:
-     p_ws = save_p_ws;
- 
-@@ -13983,6 +14198,7 @@
-     char_u	nbuf3[NUMBUFLEN];
-     int		retval = 0;		/* default: FAIL */
-     long	lnum_stop = 0;
-+    long	time_limit = 0;
- 
-     /* Get the three pattern arguments: start, middle, end. */
-     spat = get_tv_string_chk(&argvars[0]);
-@@ -14006,6 +14222,10 @@
- 	goto theend;
-     }
- 
-+    /* Using 'r' implies 'W', otherwise it doesn't work. */
-+    if (flags & SP_REPEAT)
-+	p_ws = FALSE;
-+
-     /* Optional fifth argument: skip expression */
-     if (argvars[3].v_type == VAR_UNKNOWN
- 	    || argvars[4].v_type == VAR_UNKNOWN)
-@@ -14018,13 +14238,21 @@
- 	    lnum_stop = get_tv_number_chk(&argvars[5], NULL);
- 	    if (lnum_stop < 0)
- 		goto theend;
-+#ifdef FEAT_RELTIME
-+	    if (argvars[6].v_type != VAR_UNKNOWN)
-+	    {
-+		time_limit = get_tv_number_chk(&argvars[6], NULL);
-+		if (time_limit < 0)
-+		    goto theend;
-+	    }
-+#endif
- 	}
-     }
-     if (skip == NULL)
- 	goto theend;	    /* type error */
- 
-     retval = do_searchpair(spat, mpat, epat, dir, skip, flags,
--							match_pos, lnum_stop);
-+					    match_pos, lnum_stop, time_limit);
- 
- theend:
-     p_ws = save_p_ws;
-@@ -14076,7 +14304,8 @@
-  * Returns 0 or -1 for no match,
-  */
-     long
--do_searchpair(spat, mpat, epat, dir, skip, flags, match_pos, lnum_stop)
-+do_searchpair(spat, mpat, epat, dir, skip, flags, match_pos,
-+							lnum_stop, time_limit)
-     char_u	*spat;	    /* start pattern */
-     char_u	*mpat;	    /* middle pattern */
-     char_u	*epat;	    /* end pattern */
-@@ -14085,6 +14314,7 @@
-     int		flags;	    /* SP_SETPCMARK and other SP_ values */
-     pos_T	*match_pos;
-     linenr_T	lnum_stop;  /* stop at this line if not zero */
-+    long	time_limit; /* stop after this many msec */
- {
-     char_u	*save_cpo;
-     char_u	*pat, *pat2 = NULL, *pat3 = NULL;
-@@ -14099,11 +14329,17 @@
-     int		nest = 1;
-     int		err;
-     int		options = SEARCH_KEEP;
-+    proftime_T	tm;
- 
-     /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
-     save_cpo = p_cpo;
-     p_cpo = (char_u *)"";
- 
-+#ifdef FEAT_RELTIME
-+    /* Set the time limit, if there is one. */
-+    profile_setlimit(time_limit, &tm);
-+#endif
-+
-     /* Make two search patterns: start/end (pat2, for in nested pairs) and
-      * start/middle/end (pat3, for the top pair). */
-     pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15));
-@@ -14127,7 +14363,7 @@
-     for (;;)
-     {
- 	n = searchit(curwin, curbuf, &pos, dir, pat, 1L,
--					       options, RE_SEARCH, lnum_stop);
-+					   options, RE_SEARCH, lnum_stop, &tm);
- 	if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos)))
- 	    /* didn't find it or found the first match again: FAIL */
- 	    break;
-@@ -14146,6 +14382,9 @@
- 	}
- 	foundpos = pos;
- 
-+	/* clear the start flag to avoid getting stuck here */
-+	options &= ~SEARCH_START;
-+
- 	/* If the skip pattern matches, ignore this match. */
- 	if (*skip != NUL)
- 	{
-@@ -14439,6 +14678,8 @@
- 	appended_lines_mark(lcount, added);
- }
- 
-+static void set_qf_ll_list __ARGS((win_T *wp, typval_T *list_arg, typval_T *action_arg, typval_T *rettv));
-+
- /*
-  * Used by "setqflist()" and "setloclist()" functions
-  */
-@@ -14498,6 +14739,66 @@
- }
- 
- /*
-+ * "setmatches()" function
-+ */
-+    static void
-+f_setmatches(argvars, rettv)
-+    typval_T	*argvars;
-+    typval_T	*rettv;
-+{
-+#ifdef FEAT_SEARCH_EXTRA
-+    list_T	*l;
-+    listitem_T	*li;
-+    dict_T	*d;
-+
-+    rettv->vval.v_number = -1;
-+    if (argvars[0].v_type != VAR_LIST)
-+    {
-+	EMSG(_(e_listreq));
-+	return;
-+    }
-+    if ((l = argvars[0].vval.v_list) != NULL)
-+    {
-+
-+	/* To some extent make sure that we are dealing with a list from
-+	 * "getmatches()". */
-+	li = l->lv_first;
-+	while (li != NULL)
-+	{
-+	    if (li->li_tv.v_type != VAR_DICT
-+		    || (d = li->li_tv.vval.v_dict) == NULL)
-+	    {
-+		EMSG(_(e_invarg));
-+		return;
-+	    }
-+	    if (!(dict_find(d, (char_u *)"group", -1) != NULL
-+			&& dict_find(d, (char_u *)"pattern", -1) != NULL
-+			&& dict_find(d, (char_u *)"priority", -1) != NULL
-+			&& dict_find(d, (char_u *)"id", -1) != NULL))
-+	    {
-+		EMSG(_(e_invarg));
-+		return;
-+	    }
-+	    li = li->li_next;
-+	}
-+
-+	clear_matches(curwin);
-+	li = l->lv_first;
-+	while (li != NULL)
-+	{
-+	    d = li->li_tv.vval.v_dict;
-+	    match_add(curwin, get_dict_string(d, (char_u *)"group", FALSE),
-+		    get_dict_string(d, (char_u *)"pattern", FALSE),
-+		    (int)get_dict_number(d, (char_u *)"priority"),
-+		    (int)get_dict_number(d, (char_u *)"id"));
-+	    li = li->li_next;
-+	}
-+	rettv->vval.v_number = 0;
-+    }
-+#endif
-+}
-+
-+/*
-  * "setpos()" function
-  */
- /*ARGSUSED*/
-@@ -14510,24 +14811,31 @@
-     int		fnum;
-     char_u	*name;
- 
-+    rettv->vval.v_number = -1;
-     name = get_tv_string_chk(argvars);
-     if (name != NULL)
-     {
- 	if (list2fpos(&argvars[1], &pos, &fnum) == OK)
- 	{
- 	    --pos.col;
--	    if (name[0] == '.')		/* cursor */
-+	    if (name[0] == '.' && name[1] == NUL)
- 	    {
-+		/* set cursor */
- 		if (fnum == curbuf->b_fnum)
- 		{
- 		    curwin->w_cursor = pos;
- 		    check_cursor();
-+		    rettv->vval.v_number = 0;
- 		}
- 		else
- 		    EMSG(_(e_invarg));
- 	    }
--	    else if (name[0] == '\'')	/* mark */
--		(void)setmark_pos(name[1], &pos, fnum);
-+	    else if (name[0] == '\'' && name[1] != NUL && name[2] == NUL)
-+	    {
-+		/* set mark */
-+		if (setmark_pos(name[1], &pos, fnum) == OK)
-+		    rettv->vval.v_number = 0;
-+	    }
- 	    else
- 		EMSG(_(e_invarg));
- 	}
-@@ -14785,6 +15093,10 @@
- 
-     p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1, 0);
-     p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2, 0);
-+    if (p1 == NULL)
-+	p1 = (char_u *)"";
-+    if (p2 == NULL)
-+	p2 = (char_u *)"";
-     if (item_compare_ic)
- 	res = STRICMP(p1, p2);
-     else
-@@ -14906,7 +15218,7 @@
- 	    if (!item_compare_func_err)
- 	    {
- 		/* Clear the List and append the items in the sorted order. */
--		l->lv_first = l->lv_last = NULL;
-+		l->lv_first = l->lv_last = l->lv_idx_item = NULL;
- 		l->lv_len = 0;
- 		for (i = 0; i < len; ++i)
- 		    list_append(l, ptrs[i]);
-@@ -15274,7 +15586,8 @@
- 
-     rettv->v_type = VAR_STRING;
-     rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf, 0);
--    if (tofree == NULL)
-+    /* Make a copy if we have a value but it's not in allocate memory. */
-+    if (rettv->vval.v_string != NULL && tofree == NULL)
- 	rettv->vval.v_string = vim_strsave(rettv->vval.v_string);
- }
- 
-@@ -15461,7 +15774,7 @@
- 
-     if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count
- 	    && col >= 0 && col < (long)STRLEN(ml_get(lnum)))
--	id = syn_get_id(curwin, lnum, (colnr_T)col, trans, NULL);
-+	id = syn_get_id(curwin, lnum, (colnr_T)col, trans, NULL, FALSE);
- #endif
- 
-     rettv->vval.v_number = id;
-@@ -15584,6 +15897,46 @@
- }
- 
- /*
-+ * "synstack(lnum, col)" function
-+ */
-+/*ARGSUSED*/
-+    static void
-+f_synstack(argvars, rettv)
-+    typval_T	*argvars;
-+    typval_T	*rettv;
-+{
-+#ifdef FEAT_SYN_HL
-+    long	lnum;
-+    long	col;
-+    int		i;
-+    int		id;
-+#endif
-+
-+    rettv->v_type = VAR_LIST;
-+    rettv->vval.v_list = NULL;
-+
-+#ifdef FEAT_SYN_HL
-+    lnum = get_tv_lnum(argvars);		/* -1 on type error */
-+    col = get_tv_number(&argvars[1]) - 1;	/* -1 on type error */
-+
-+    if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count
-+	    && col >= 0 && col < (long)STRLEN(ml_get(lnum))
-+	    && rettv_list_alloc(rettv) != FAIL)
-+    {
-+	(void)syn_get_id(curwin, lnum, (colnr_T)col, FALSE, NULL, TRUE);
-+	for (i = 0; ; ++i)
-+	{
-+	    id = syn_get_stack_item(i);
-+	    if (id < 0)
-+		break;
-+	    if (list_append_number(rettv->vval.v_list, id) == FAIL)
-+		break;
-+	}
-+    }
-+#endif
-+}
-+
-+/*
-  * "system()" function
-  */
-     static void
-@@ -15599,7 +15952,7 @@
-     FILE	*fd;
- 
-     if (check_restricted() || check_secure())
--	return;
-+	goto done;
- 
-     if (argvars[1].v_type != VAR_UNKNOWN)
-     {
-@@ -15610,7 +15963,7 @@
- 	if ((infile = vim_tempname('i')) == NULL)
- 	{
- 	    EMSG(_(e_notmp));
--	    return;
-+	    goto done;
- 	}
- 
- 	fd = mch_fopen((char *)infile, WRITEBIN);
-@@ -16497,9 +16850,9 @@
-  * Returns NULL when there is an error.
-  */
-     static pos_T *
--var2fpos(varp, lnum, fnum)
-+var2fpos(varp, dollar_lnum, fnum)
-     typval_T	*varp;
--    int		lnum;		/* TRUE when $ is last line */
-+    int		dollar_lnum;	/* TRUE when $ is last line */
-     int		*fnum;		/* set to fnum for '0, 'A, etc. */
- {
-     char_u		*name;
-@@ -16512,6 +16865,7 @@
- 	list_T		*l;
- 	int		len;
- 	int		error = FALSE;
-+	listitem_T	*li;
- 
- 	l = varp->vval.v_list;
- 	if (l == NULL)
-@@ -16527,6 +16881,14 @@
- 	if (error)
- 	    return NULL;
- 	len = (long)STRLEN(ml_get(pos.lnum));
-+
-+	/* We accept "$" for the column number: last column. */
-+	li = list_find(l, 1L);
-+	if (li != NULL && li->li_tv.v_type == VAR_STRING
-+		&& li->li_tv.vval.v_string != NULL
-+		&& STRCMP(li->li_tv.vval.v_string, "$") == 0)
-+	    pos.col = len + 1;
-+
- 	/* Accept a position up to the NUL after the line. */
- 	if (pos.col == 0 || (int)pos.col > len + 1)
- 	    return NULL;	/* invalid column number */
-@@ -16559,7 +16921,7 @@
-     pos.coladd = 0;
- #endif
- 
--    if (name[0] == 'w' && lnum)
-+    if (name[0] == 'w' && dollar_lnum)
-     {
- 	pos.col = 0;
- 	if (name[1] == '0')		/* "w0": first visible line */
-@@ -16577,7 +16939,7 @@
-     }
-     else if (name[0] == '$')		/* last column or line */
-     {
--	if (lnum)
-+	if (dollar_lnum)
- 	{
- 	    pos.lnum = curbuf->b_ml.ml_line_count;
- 	    pos.col = 0;
-@@ -17798,9 +18160,10 @@
-  * List the value of one internal variable.
-  */
-     static void
--list_one_var(v, prefix)
-+list_one_var(v, prefix, first)
-     dictitem_T	*v;
-     char_u	*prefix;
-+    int		*first;
- {
-     char_u	*tofree;
-     char_u	*s;
-@@ -17808,18 +18171,21 @@
- 
-     s = echo_string(&v->di_tv, &tofree, numbuf, ++current_copyID);
-     list_one_var_a(prefix, v->di_key, v->di_tv.v_type,
--						s == NULL ? (char_u *)"" : s);
-+					 s == NULL ? (char_u *)"" : s, first);
-     vim_free(tofree);
- }
- 
-     static void
--list_one_var_a(prefix, name, type, string)
-+list_one_var_a(prefix, name, type, string, first)
-     char_u	*prefix;
-     char_u	*name;
-     int		type;
-     char_u	*string;
-+    int		*first;  /* when TRUE clear rest of screen and set to FALSE */
- {
--    msg_attr(prefix, 0);    /* don't use msg(), it overwrites "v:statusmsg" */
-+    /* don't use msg() or msg_attr() to avoid overwriting "v:statusmsg" */
-+    msg_start();
-+    msg_puts(prefix);
-     if (name != NULL)	/* "a:" vars don't have a name stored */
- 	msg_puts(name);
-     msg_putchar(' ');
-@@ -17847,6 +18213,11 @@
- 
-     if (type == VAR_FUNC)
- 	msg_puts((char_u *)"()");
-+    if (*first)
-+    {
-+	msg_clr_eos();
-+	*first = FALSE;
-+    }
- }
- 
- /*
-@@ -19136,6 +19507,28 @@
- 	goto theend;
-     }
- 
-+    /* Check if the name is a Funcref.  If so, use the value. */
-+    if (lv.ll_exp_name != NULL)
-+    {
-+	len = (int)STRLEN(lv.ll_exp_name);
-+	name = deref_func_name(lv.ll_exp_name, &len);
-+	if (name == lv.ll_exp_name)
-+	    name = NULL;
-+    }
-+    else
-+    {
-+	len = (int)(end - *pp);
-+	name = deref_func_name(*pp, &len);
-+	if (name == *pp)
-+	    name = NULL;
-+    }
-+    if (name != NULL)
-+    {
-+	name = vim_strsave(name);
-+	*pp = end;
-+	goto theend;
-+    }
-+
-     if (lv.ll_exp_name != NULL)
-     {
- 	len = (int)STRLEN(lv.ll_exp_name);
-@@ -19969,6 +20362,7 @@
- 		char_u	buf[MSG_BUF_LEN];
- 		char_u	numbuf2[NUMBUFLEN];
- 		char_u	*tofree;
-+		char_u	*s;
- 
- 		msg_puts((char_u *)"(");
- 		for (i = 0; i < argcount; ++i)
-@@ -19979,10 +20373,13 @@
- 			msg_outnum((long)argvars[i].vval.v_number);
- 		    else
- 		    {
--			trunc_string(tv2string(&argvars[i], &tofree,
--					      numbuf2, 0), buf, MSG_BUF_CLEN);
--			msg_puts(buf);
--			vim_free(tofree);
-+			s = tv2string(&argvars[i], &tofree, numbuf2, 0);
-+			if (s != NULL)
-+			{
-+			    trunc_string(s, buf, MSG_BUF_CLEN);
-+			    msg_puts(buf);
-+			    vim_free(tofree);
-+			}
- 		    }
- 		}
- 		msg_puts((char_u *)")");
-@@ -20060,14 +20457,18 @@
- 	    char_u	buf[MSG_BUF_LEN];
- 	    char_u	numbuf2[NUMBUFLEN];
- 	    char_u	*tofree;
-+	    char_u	*s;
- 
- 	    /* The value may be very long.  Skip the middle part, so that we
- 	     * have some idea how it starts and ends. smsg() would always
- 	     * truncate it at the end. */
--	    trunc_string(tv2string(fc.rettv, &tofree, numbuf2, 0),
--							   buf, MSG_BUF_CLEN);
--	    smsg((char_u *)_("%s returning %s"), sourcing_name, buf);
--	    vim_free(tofree);
-+	    s = tv2string(fc.rettv, &tofree, numbuf2, 0);
-+	    if (s != NULL)
-+	    {
-+		trunc_string(s, buf, MSG_BUF_CLEN);
-+		smsg((char_u *)_("%s returning %s"), sourcing_name, buf);
-+		vim_free(tofree);
-+	    }
- 	}
- 	msg_puts((char_u *)"\n");   /* don't overwrite this either */
- 
-@@ -20667,8 +21068,12 @@
- static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen));
- 
- /*
-- * Get the short pathname of a file.
-- * Returns 1 on success. *fnamelen is 0 for nonexistent path.
-+ * Get the short path (8.3) for the filename in "fnamep".
-+ * Only works for a valid file name.
-+ * When the path gets longer "fnamep" is changed and the allocated buffer
-+ * is put in "bufp".
-+ * *fnamelen is the length of "fnamep" and set to 0 for a nonexistent path.
-+ * Returns OK on success, FAIL on failure.
-  */
-     static int
- get_short_pathname(fnamep, bufp, fnamelen)
-@@ -20676,36 +21081,44 @@
-     char_u	**bufp;
-     int		*fnamelen;
- {
--    int		l,len;
-+    int		l, len;
-     char_u	*newbuf;
- 
-     len = *fnamelen;
--
-     l = GetShortPathName(*fnamep, *fnamep, len);
-     if (l > len - 1)
-     {
- 	/* If that doesn't work (not enough space), then save the string
--	 * and try again with a new buffer big enough
--	 */
-+	 * and try again with a new buffer big enough. */
- 	newbuf = vim_strnsave(*fnamep, l);
- 	if (newbuf == NULL)
--	    return 0;
-+	    return FAIL;
- 
- 	vim_free(*bufp);
- 	*fnamep = *bufp = newbuf;
- 
--	l = GetShortPathName(*fnamep,*fnamep,l+1);
--
--	/* Really should always succeed, as the buffer is big enough */
-+	/* Really should always succeed, as the buffer is big enough. */
-+	l = GetShortPathName(*fnamep, *fnamep, l+1);
-     }
- 
-     *fnamelen = l;
--    return 1;
-+    return OK;
- }
- 
- /*
-- * Create a short path name.  Returns the length of the buffer it needs.
-- * Doesn't copy over the end of the buffer passed in.
-+ * Get the short path (8.3) for the filename in "fname". The converted
-+ * path is returned in "bufp".
-+ *
-+ * Some of the directories specified in "fname" may not exist. This function
-+ * will shorten the existing directories at the beginning of the path and then
-+ * append the remaining non-existing path.
-+ *
-+ * fname - Pointer to the filename to shorten.  On return, contains the
-+ *         pointer to the shortened pathname
-+ * bufp -  Pointer to an allocated buffer for the filename.
-+ * fnamelen - Length of the filename pointed to by fname
-+ *
-+ * Returns OK on success (or nothing done) and FAIL on failure (out of memory).
-  */
-     static int
- shortpath_for_invalid_fname(fname, bufp, fnamelen)
-@@ -20713,85 +21126,106 @@
-     char_u	**bufp;
-     int		*fnamelen;
- {
--    char_u	*s, *p, *pbuf2, *pbuf3;
-+    char_u	*short_fname, *save_fname, *pbuf_unused;
-+    char_u	*endp, *save_endp;
-     char_u	ch;
--    int		len, len2, plen, slen;
-+    int		old_len, len;
-+    int		new_len, sfx_len;
-+    int		retval = OK;
- 
-     /* Make a copy */
--    len2 = *fnamelen;
--    pbuf2 = vim_strnsave(*fname, len2);
--    pbuf3 = NULL;
--
--    s = pbuf2 + len2 - 1; /* Find the end */
--    slen = 1;
--    plen = len2;
--
--    if (after_pathsep(pbuf2, s + 1))
--    {
--	--s;
--	++slen;
--	--plen;
--    }
-+    old_len = *fnamelen;
-+    save_fname = vim_strnsave(*fname, old_len);
-+    pbuf_unused = NULL;
-+    short_fname = NULL;
- 
--    do
-+    endp = save_fname + old_len - 1; /* Find the end of the copy */
-+    save_endp = endp;
-+
-+    /*
-+     * Try shortening the supplied path till it succeeds by removing one
-+     * directory at a time from the tail of the path.
-+     */
-+    len = 0;
-+    for (;;)
-     {
--	/* Go back one path-separator */
--	while (s > pbuf2 && !after_pathsep(pbuf2, s + 1))
--	{
--	    --s;
--	    ++slen;
--	    --plen;
--	}
--	if (s <= pbuf2)
--	    break;
-+	/* go back one path-separator */
-+	while (endp > save_fname && !after_pathsep(save_fname, endp + 1))
-+	    --endp;
-+	if (endp <= save_fname)
-+	    break;		/* processed the complete path */
- 
--	/* Remember the character that is about to be splatted */
--	ch = *s;
--	*s = 0; /* get_short_pathname requires a null-terminated string */
--
--	/* Try it in situ */
--	p = pbuf2;
--	if (!get_short_pathname(&p, &pbuf3, &plen))
-+	/*
-+	 * Replace the path separator with a NUL and try to shorten the
-+	 * resulting path.
-+	 */
-+	ch = *endp;
-+	*endp = 0;
-+	short_fname = save_fname;
-+	len = STRLEN(short_fname) + 1;
-+	if (get_short_pathname(&short_fname, &pbuf_unused, &len) == FAIL)
- 	{
--	    vim_free(pbuf2);
--	    return -1;
-+	    retval = FAIL;
-+	    goto theend;
- 	}
--	*s = ch;    /* Preserve the string */
--    } while (plen == 0);
-+	*endp = ch;	/* preserve the string */
- 
--    if (plen > 0)
-+	if (len > 0)
-+	    break;	/* successfully shortened the path */
-+
-+	/* failed to shorten the path. Skip the path separator */
-+	--endp;
-+    }
-+
-+    if (len > 0)
-     {
--	/* Remember the length of the new string.  */
--	*fnamelen = len = plen + slen;
-+	/*
-+	 * Succeeded in shortening the path. Now concatenate the shortened
-+	 * path with the remaining path at the tail.
-+	 */
-+
-+	/* Compute the length of the new path. */
-+	sfx_len = (int)(save_endp - endp) + 1;
-+	new_len = len + sfx_len;
-+
-+	*fnamelen = new_len;
- 	vim_free(*bufp);
--	if (len > len2)
-+	if (new_len > old_len)
- 	{
--	    /* If there's not enough space in the currently allocated string,
--	     * then copy it to a buffer big enough.
--	     */
--	    *fname= *bufp = vim_strnsave(p, len);
-+	    /* There is not enough space in the currently allocated string,
-+	     * copy it to a buffer big enough. */
-+	    *fname = *bufp = vim_strnsave(short_fname, new_len);
- 	    if (*fname == NULL)
--		return -1;
-+	    {
-+		retval = FAIL;
-+		goto theend;
-+	    }
- 	}
- 	else
- 	{
--	    /* Transfer pbuf2 to being the main buffer  (it's big enough) */
--	    *fname = *bufp = pbuf2;
--	    if (p != pbuf2)
--		strncpy(*fname, p, plen);
--	    pbuf2 = NULL;
--	}
--	/* Concat the next bit */
--	strncpy(*fname + plen, s, slen);
--	(*fname)[len] = '\0';
-+	    /* Transfer short_fname to the main buffer (it's big enough),
-+	     * unless get_short_pathname() did its work in-place. */
-+	    *fname = *bufp = save_fname;
-+	    if (short_fname != save_fname)
-+		vim_strncpy(save_fname, short_fname, len);
-+	    save_fname = NULL;
-+	}
-+
-+	/* concat the not-shortened part of the path */
-+	vim_strncpy(*fname + len, endp, sfx_len);
-+	(*fname)[new_len] = NUL;
-     }
--    vim_free(pbuf3);
--    vim_free(pbuf2);
--    return 0;
-+
-+theend:
-+    vim_free(pbuf_unused);
-+    vim_free(save_fname);
-+
-+    return retval;
- }
- 
- /*
-  * Get a pathname for a partial path.
-+ * Returns OK for success, FAIL for failure.
-  */
-     static int
- shortpath_for_partial(fnamep, bufp, fnamelen)
-@@ -20821,8 +21255,8 @@
- 
-     len = tflen = (int)STRLEN(tfname);
- 
--    if (!get_short_pathname(&tfname, &pbuf, &len))
--	return -1;
-+    if (get_short_pathname(&tfname, &pbuf, &len) == FAIL)
-+	return FAIL;
- 
-     if (len == 0)
-     {
-@@ -20831,8 +21265,8 @@
- 	 * there's not a lot of point in guessing what it might be.
- 	 */
- 	len = tflen;
--	if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == -1)
--	    return -1;
-+	if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == FAIL)
-+	    return FAIL;
-     }
- 
-     /* Count the paths backward to find the beginning of the desired string. */
-@@ -20856,7 +21290,7 @@
- 	if (p >= tfname)
- 	    *p = '~';
- 	else
--	    return -1;
-+	    return FAIL;
-     }
-     else
- 	++p;
-@@ -20867,7 +21301,7 @@
-     *bufp = pbuf;
-     *fnamep = p;
- 
--    return 0;
-+    return OK;
- }
- #endif /* WIN3264 */
- 
-@@ -20875,7 +21309,7 @@
-  * Adjust a filename, according to a string of modifiers.
-  * *fnamep must be NUL terminated when called.  When returning, the length is
-  * determined by *fnamelen.
-- * Returns valid flags.
-+ * Returns VALID_ flags or -1 for failure.
-  * When there is an error, *fnamep is set to NULL.
-  */
-     int
-@@ -21034,14 +21468,27 @@
- 	*usedlen += 2;
- 	s = get_past_head(*fnamep);
- 	while (tail > s && after_pathsep(s, tail))
--	    --tail;
-+	    mb_ptr_back(*fnamep, tail);
- 	*fnamelen = (int)(tail - *fnamep);
- #ifdef VMS
- 	if (*fnamelen > 0)
- 	    *fnamelen += 1; /* the path separator is part of the path */
- #endif
--	while (tail > s && !after_pathsep(s, tail))
--	    mb_ptr_back(*fnamep, tail);
-+	if (*fnamelen == 0)
-+	{
-+	    /* Result is empty.  Turn it into "." to make ":cd %:h" work. */
-+	    p = vim_strsave((char_u *)".");
-+	    if (p == NULL)
-+		return -1;
-+	    vim_free(*bufp);
-+	    *bufp = *fnamep = tail = p;
-+	    *fnamelen = 1;
-+	}
-+	else
-+	{
-+	    while (tail > s && !after_pathsep(s, tail))
-+		mb_ptr_back(*fnamep, tail);
-+	}
-     }
- 
-     /* ":8" - shortname  */
-@@ -21074,7 +21521,7 @@
- 	 */
- 	if (!has_fullname && !vim_isAbsName(*fnamep))
- 	{
--	    if (shortpath_for_partial(fnamep, bufp, fnamelen) == -1)
-+	    if (shortpath_for_partial(fnamep, bufp, fnamelen) == FAIL)
- 		return -1;
- 	}
- 	else
-@@ -21084,7 +21531,7 @@
- 	    /* Simple case, already have the full-name
- 	     * Nearly always shorter, so try first time. */
- 	    l = *fnamelen;
--	    if (!get_short_pathname(fnamep, bufp, &l))
-+	    if (get_short_pathname(fnamep, bufp, &l) == FAIL)
- 		return -1;
- 
- 	    if (l == 0)
-@@ -21092,7 +21539,7 @@
- 		/* Couldn't find the filename.. search the paths.
- 		 */
- 		l = *fnamelen;
--		if (shortpath_for_invalid_fname(fnamep, bufp, &l ) == -1)
-+		if (shortpath_for_invalid_fname(fnamep, bufp, &l) == FAIL)
- 		    return -1;
- 	    }
- 	    *fnamelen = l;
-diff -Naur vim71.orig/src/ex_cmds.c vim71/src/ex_cmds.c
---- vim71.orig/src/ex_cmds.c	2007-05-07 15:41:01.000000000 -0400
-+++ vim71/src/ex_cmds.c	2008-06-18 06:56:36.000000000 -0400
-@@ -365,6 +365,10 @@
-     int		sort_oct;		/* sort on octal number */
-     int		sort_hex;		/* sort on hex number */
- 
-+    /* Sorting one line is really quick! */
-+    if (count <= 1)
-+	return;
-+
-     if (u_save((linenr_T)(eap->line1 - 1), (linenr_T)(eap->line2 + 1)) == FAIL)
- 	return;
-     sortbuf1 = NULL;
-@@ -408,7 +412,11 @@
- 		goto sortend;
- 	    }
- 	    *s = NUL;
--	    regmatch.regprog = vim_regcomp(p + 1, RE_MAGIC);
-+	    /* Use last search pattern if sort pattern is empty. */
-+	    if (s == p + 1 && last_search_pat() != NULL)
-+		regmatch.regprog = vim_regcomp(last_search_pat(), RE_MAGIC);
-+	    else
-+		regmatch.regprog = vim_regcomp(p + 1, RE_MAGIC);
- 	    if (regmatch.regprog == NULL)
- 		goto sortend;
- 	    p = s;		/* continue after the regexp */
-@@ -1152,6 +1160,7 @@
-     if (!do_out)
- 	msg_putchar('\n');
- 
-+    /* Create the shell command in allocated memory. */
-     cmd_buf = make_filter_cmd(cmd, itmp, otmp);
-     if (cmd_buf == NULL)
- 	goto filterend;
-@@ -1172,7 +1181,10 @@
-     if (do_out)
-     {
- 	if (u_save((linenr_T)(line2), (linenr_T)(line2 + 1)) == FAIL)
-+	{
-+	    vim_free(cmd_buf);
- 	    goto error;
-+	}
- 	redraw_curbuf_later(VALID);
-     }
-     read_linecount = curbuf->b_ml.ml_line_count;
-@@ -1646,7 +1658,7 @@
- {
-     vim_snprintf((char *)IObuff, IOSIZE, _("%sviminfo: %s in line: "),
- 							     errnum, message);
--    STRNCAT(IObuff, line, IOSIZE - STRLEN(IObuff));
-+    STRNCAT(IObuff, line, IOSIZE - STRLEN(IObuff) - 1);
-     if (IObuff[STRLEN(IObuff) - 1] == '\n')
- 	IObuff[STRLEN(IObuff) - 1] = NUL;
-     emsg(IObuff);
-@@ -1770,7 +1782,8 @@
- 	 * overwrite a user's viminfo file after a "su root", with a
- 	 * viminfo file that the user can't read.
- 	 */
--	st_old.st_dev = st_old.st_ino = 0;
-+	st_old.st_dev = 0;
-+	st_old.st_ino = 0;
- 	st_old.st_mode = 0600;
- 	if (mch_stat((char *)fname, &st_old) == 0
- 		&& getuid() != ROOT_UID
-@@ -2727,6 +2740,9 @@
- 		    && vim_strchr(p_cpo, CPO_OVERNEW) == NULL)
- 		|| (buf->b_flags & BF_READERR))
- 	    && !p_wa
-+#ifdef FEAT_QUICKFIX
-+	    && !bt_nofile(buf)
-+#endif
- 	    && vim_fexists(ffname))
-     {
- 	if (!eap->forceit && !eap->append)
-@@ -2912,22 +2928,35 @@
- }
- 
- /*
-- * Check if a buffer is read-only.  Ask for overruling in a dialog.
-- * Return TRUE and give an error message when the buffer is readonly.
-+ * Check if a buffer is read-only (either 'readonly' option is set or file is
-+ * read-only). Ask for overruling in a dialog. Return TRUE and give an error
-+ * message when the buffer is readonly.
-  */
-     static int
- check_readonly(forceit, buf)
-     int		*forceit;
-     buf_T	*buf;
- {
--    if (!*forceit && buf->b_p_ro)
-+    struct stat	st;
-+
-+    /* Handle a file being readonly when the 'readonly' option is set or when
-+     * the file exists and permissions are read-only.
-+     * We will send 0777 to check_file_readonly(), as the "perm" variable is
-+     * important for device checks but not here. */
-+    if (!*forceit && (buf->b_p_ro
-+		|| (mch_stat((char *)buf->b_ffname, &st) >= 0
-+		    && check_file_readonly(buf->b_ffname, 0777))))
-     {
- #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
- 	if ((p_confirm || cmdmod.confirm) && buf->b_fname != NULL)
- 	{
- 	    char_u	buff[IOSIZE];
- 
--	    dialog_msg(buff, _("'readonly' option is set for \"%s\".\nDo you wish to write anyway?"),
-+	    if (buf->b_p_ro)
-+		dialog_msg(buff, _("'readonly' option is set for \"%s\".\nDo you wish to write anyway?"),
-+		    buf->b_fname);
-+	    else
-+		dialog_msg(buff, _("File permissions of \"%s\" are read-only.\nIt may still be possible to write it.\nDo you wish to try?"),
- 		    buf->b_fname);
- 
- 	    if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2) == VIM_YES)
-@@ -2941,9 +2970,14 @@
- 	}
- 	else
- #endif
-+	if (buf->b_p_ro)
- 	    EMSG(_(e_readonly));
-+	else
-+	    EMSG2(_("E505: \"%s\" is read-only (add ! to override)"),
-+		    buf->b_fname);
- 	return TRUE;
-     }
-+
-     return FALSE;
- }
- 
-@@ -2952,7 +2986,7 @@
-  * 'fnum' is the number of the file, if zero use ffname/sfname.
-  *
-  * Return 1 for "normal" error, 2 for "not written" error, 0 for success
-- * -1 for succesfully opening another file.
-+ * -1 for successfully opening another file.
-  * 'lnum' is the line number for the cursor in the new file (if non-zero).
-  */
-     int
-@@ -3367,7 +3401,7 @@
- 		 * was in this window (or another window).  If not used
- 		 * before, reset the local window options to the global
- 		 * values.  Also restores old folding stuff. */
--		get_winopts(buf);
-+		get_winopts(curbuf);
- #ifdef FEAT_SPELL
- 		did_get_winopts = TRUE;
- #endif
-@@ -3562,9 +3596,20 @@
- 	curwin_init();
- 
- #ifdef FEAT_FOLDING
--	/* It's like all lines in the buffer changed.  Need to update
--	 * automatic folding. */
-+	/* It's possible that all lines in the buffer changed.  Need to update
-+	 * automatic folding for all windows where it's used. */
-+# ifdef FEAT_WINDOWS
-+	{
-+	    win_T	    *win;
-+	    tabpage_T	    *tp;
-+
-+	    FOR_ALL_TAB_WINDOWS(tp, win)
-+		if (win->w_buffer == curbuf)
-+		    foldUpdateAll(win);
-+	}
-+# else
- 	foldUpdateAll(curwin);
-+# endif
- #endif
- 
- 	/* Change directories when the 'acd' option is set. */
-@@ -3649,8 +3694,8 @@
- #ifdef FEAT_SPELL
-     /* If the window options were changed may need to set the spell language.
-      * Can only do this after the buffer has been properly setup. */
--    if (did_get_winopts && curwin->w_p_spell && *buf->b_p_spl != NUL)
--	did_set_spelllang(buf);
-+    if (did_get_winopts && curwin->w_p_spell && *curbuf->b_p_spl != NUL)
-+	did_set_spelllang(curbuf);
- #endif
- 
-     if (command == NULL)
-@@ -3754,7 +3799,7 @@
- 	    workshop_file_opened((char *)curbuf->b_ffname, curbuf->b_p_ro);
- # endif
- # ifdef FEAT_NETBEANS_INTG
--	if (usingNetbeans & ((flags & ECMD_SET_HELP) != ECMD_SET_HELP))
-+	if (usingNetbeans && ((flags & ECMD_SET_HELP) != ECMD_SET_HELP))
- 	    netbeans_file_opened(curbuf);
- # endif
-     }
-@@ -4163,7 +4208,6 @@
-     linenr_T	old_line_count = curbuf->b_ml.ml_line_count;
-     linenr_T	line2;
-     long	nmatch;			/* number of lines in match */
--    linenr_T	sub_firstlnum;		/* nr of first sub line */
-     char_u	*sub_firstline;		/* allocated copy of first sub line */
-     int		endcolumn = FALSE;	/* cursor in last column when done */
-     pos_T	old_cursor = curwin->w_cursor;
-@@ -4175,11 +4219,6 @@
- 	sub_nlines = 0;
-     }
- 
--#ifdef FEAT_FKMAP	/* reverse the flow of the Farsi characters */
--    if (p_altkeymap && curwin->w_p_rl)
--	lrF_sub(cmd);
--#endif
--
-     if (eap->cmdidx == CMD_tilde)
- 	which_pat = RE_LAST;	/* use last used regexp */
-     else
-@@ -4215,6 +4254,10 @@
- 	}
- 	else		/* find the end of the regexp */
- 	{
-+#ifdef FEAT_FKMAP	/* reverse the flow of the Farsi characters */
-+	    if (p_altkeymap && curwin->w_p_rl)
-+		lrF_sub(cmd);
-+#endif
- 	    which_pat = RE_LAST;	    /* use last used regexp */
- 	    delimiter = *cmd++;		    /* remember delimiter character */
- 	    pat = cmd;			    /* remember start of search pat */
-@@ -4294,6 +4337,7 @@
- 	do_error = TRUE;
- 	do_print = FALSE;
- 	do_count = FALSE;
-+	do_number = FALSE;
- 	do_ic = 0;
-     }
-     while (*cmd)
-@@ -4410,8 +4454,8 @@
- #endif
- 		); ++lnum)
-     {
--	sub_firstlnum = lnum;
--	nmatch = vim_regexec_multi(&regmatch, curwin, curbuf, lnum, (colnr_T)0);
-+	nmatch = vim_regexec_multi(&regmatch, curwin, curbuf, lnum,
-+							    (colnr_T)0, NULL);
- 	if (nmatch)
- 	{
- 	    colnr_T	copycol;
-@@ -4426,11 +4470,12 @@
- 	    long	nmatch_tl = 0;	/* nr of lines matched below lnum */
- 	    int		do_again;	/* do it again after joining lines */
- 	    int		skip_match = FALSE;
-+	    linenr_T	sub_firstlnum;	/* nr of first sub line */
- 
- 	    /*
- 	     * The new text is build up step by step, to avoid too much
- 	     * copying.  There are these pieces:
--	     * sub_firstline	The old text, unmodifed.
-+	     * sub_firstline	The old text, unmodified.
- 	     * copycol		Column in the old text where we started
- 	     *			looking for a match; from here old text still
- 	     *			needs to be copied to the new text.
-@@ -4445,8 +4490,10 @@
- 	     *			far.
- 	     * new_end		The new text, where to append new text.
- 	     *
--	     * lnum		The line number where we were looking for the
--	     *			first match in the old line.
-+	     * lnum		The line number where we found the start of
-+	     *			the match.  Can be below the line we searched
-+	     *			when there is a \n before a \zs in the
-+	     *			pattern.
- 	     * sub_firstlnum	The line number in the buffer where to look
- 	     *			for a match.  Can be different from "lnum"
- 	     *			when the pattern or substitute string contains
-@@ -4464,18 +4511,13 @@
- 	     *
- 	     * The new text is built up in new_start[].  It has some extra
- 	     * room to avoid using alloc()/free() too often.  new_start_len is
--	     * the lenght of the allocated memory at new_start.
-+	     * the length of the allocated memory at new_start.
- 	     *
- 	     * Make a copy of the old line, so it won't be taken away when
- 	     * updating the screen or handling a multi-line match.  The "old_"
- 	     * pointers point into this copy.
- 	     */
--	    sub_firstline = vim_strsave(ml_get(sub_firstlnum));
--	    if (sub_firstline == NULL)
--	    {
--		vim_free(new_start);
--		goto outofmem;
--	    }
-+	    sub_firstlnum = lnum;
- 	    copycol = 0;
- 	    matchcol = 0;
- 
-@@ -4496,6 +4538,28 @@
- 	     */
- 	    for (;;)
- 	    {
-+		/* Advance "lnum" to the line where the match starts.  The
-+		 * match does not start in the first line when there is a line
-+		 * break before \zs. */
-+		if (regmatch.startpos[0].lnum > 0)
-+		{
-+		    lnum += regmatch.startpos[0].lnum;
-+		    sub_firstlnum += regmatch.startpos[0].lnum;
-+		    nmatch -= regmatch.startpos[0].lnum;
-+		    vim_free(sub_firstline);
-+		    sub_firstline = NULL;
-+		}
-+
-+		if (sub_firstline == NULL)
-+		{
-+		    sub_firstline = vim_strsave(ml_get(sub_firstlnum));
-+		    if (sub_firstline == NULL)
-+		    {
-+			vim_free(new_start);
-+			goto outofmem;
-+		    }
-+		}
-+
- 		/* Save the line number of the last change for the final
- 		 * cursor position (just like Vi). */
- 		curwin->w_cursor.lnum = lnum;
-@@ -4538,6 +4602,7 @@
- 		    {
- 			matchcol = (colnr_T)STRLEN(sub_firstline);
- 			nmatch = 1;
-+			skip_match = TRUE;
- 		    }
- 		    sub_nsubs++;
- 		    did_sub = TRUE;
-@@ -4600,7 +4665,8 @@
- 			    temp = RedrawingDisabled;
- 			    RedrawingDisabled = 0;
- 
--			    search_match_lines = regmatch.endpos[0].lnum;
-+			    search_match_lines = regmatch.endpos[0].lnum
-+						  - regmatch.startpos[0].lnum;
- 			    search_match_endcol = regmatch.endpos[0].col;
- 			    highlight_match = TRUE;
- 
-@@ -4635,7 +4701,7 @@
- #endif
- 			    ++no_mapping;	/* don't map this key */
- 			    ++allow_keys;	/* allow special keys */
--			    i = safe_vgetc();
-+			    i = plain_vgetc();
- 			    --allow_keys;
- 			    --no_mapping;
- 
-@@ -4711,7 +4777,8 @@
- 		 * 3. substitute the string.
- 		 */
- 		/* get length of substitution part */
--		sublen = vim_regsub_multi(&regmatch, sub_firstlnum,
-+		sublen = vim_regsub_multi(&regmatch,
-+				    sub_firstlnum - regmatch.startpos[0].lnum,
- 				    sub, sub_firstline, FALSE, p_magic, TRUE);
- 
- 		/* When the match included the "$" of the last line it may
-@@ -4781,7 +4848,8 @@
- 		mch_memmove(new_end, sub_firstline + copycol, (size_t)i);
- 		new_end += i;
- 
--		(void)vim_regsub_multi(&regmatch, sub_firstlnum,
-+		(void)vim_regsub_multi(&regmatch,
-+				    sub_firstlnum - regmatch.startpos[0].lnum,
- 					   sub, new_end, TRUE, p_magic, TRUE);
- 		sub_nsubs++;
- 		did_sub = TRUE;
-@@ -4850,7 +4918,8 @@
- 			    ++line2;
- 			    /* move the cursor to the new line, like Vi */
- 			    ++curwin->w_cursor.lnum;
--			    STRCPY(new_start, p1 + 1);	/* copy the rest */
-+			    /* copy the rest */
-+			    mch_memmove(new_start, p1 + 1, STRLEN(p1 + 1) + 1);
- 			    p1 = new_start - 1;
- 			}
- 		    }
-@@ -4869,10 +4938,13 @@
- skip:
- 		/* We already know that we did the last subst when we are at
- 		 * the end of the line, except that a pattern like
--		 * "bar\|\nfoo" may match at the NUL. */
-+		 * "bar\|\nfoo" may match at the NUL.  "lnum" can be below
-+		 * "line2" when there is a \zs in the pattern after a line
-+		 * break. */
- 		lastone = (skip_match
- 			|| got_int
- 			|| got_quit
-+			|| lnum > line2
- 			|| !(do_all || do_again)
- 			|| (sub_firstline[matchcol] == NUL && nmatch <= 1
- 					 && !re_multiline(regmatch.regprog)));
-@@ -4887,12 +4959,16 @@
- 		 * When asking the user we like to show the already replaced
- 		 * text, but don't do it when "\<@=" or "\<@!" is used, it
- 		 * changes what matches.
-+		 * When the match starts below where we start searching also
-+		 * need to replace the line first (using \zs after \n).
- 		 */
- 		if (lastone
- 			|| (do_ask && !re_lookbehind(regmatch.regprog))
- 			|| nmatch_tl > 0
- 			|| (nmatch = vim_regexec_multi(&regmatch, curwin,
--				       curbuf, sub_firstlnum, matchcol)) == 0)
-+							curbuf, sub_firstlnum,
-+							 matchcol, NULL)) == 0
-+			|| regmatch.startpos[0].lnum > 0)
- 		{
- 		    if (new_start != NULL)
- 		    {
-@@ -4956,13 +5032,20 @@
- 		    }
- 		    if (nmatch == -1 && !lastone)
- 			nmatch = vim_regexec_multi(&regmatch, curwin, curbuf,
--						     sub_firstlnum, matchcol);
-+					       sub_firstlnum, matchcol, NULL);
- 
- 		    /*
- 		     * 5. break if there isn't another match in this line
- 		     */
- 		    if (nmatch <= 0)
-+		    {
-+			/* If the match found didn't start where we were
-+			 * searching, do the next search in the line where we
-+			 * found the match. */
-+			if (nmatch == -1)
-+			    lnum -= regmatch.startpos[0].lnum;
- 			break;
-+		    }
- 		}
- 
- 		line_breakcheck();
-@@ -5179,7 +5262,8 @@
-     for (lnum = eap->line1; lnum <= eap->line2 && !got_int; ++lnum)
-     {
- 	/* a match on this line? */
--	match = vim_regexec_multi(&regmatch, curwin, curbuf, lnum, (colnr_T)0);
-+	match = vim_regexec_multi(&regmatch, curwin, curbuf, lnum,
-+							    (colnr_T)0, NULL);
- 	if ((type == 'g' && match) || (type == 'v' && !match))
- 	{
- 	    ml_setmarked(lnum);
-@@ -6018,7 +6102,7 @@
- }
- 
- #if defined(FEAT_EX_EXTRA) || defined(PROTO)
--static void helptags_one __ARGS((char_u *dir, char_u *ext, char_u *lang));
-+static void helptags_one __ARGS((char_u *dir, char_u *ext, char_u *lang, int add_help_tags));
- 
- /*
-  * ":helptags"
-@@ -6033,12 +6117,26 @@
- #ifdef FEAT_MULTI_LANG
-     char_u	lang[2];
- #endif
-+    expand_T	xpc;
-+    char_u	*dirname;
-     char_u	ext[5];
-     char_u	fname[8];
-     int		filecount;
-     char_u	**files;
-+    int		add_help_tags = FALSE;
-+
-+    /* Check for ":helptags ++t {dir}". */
-+    if (STRNCMP(eap->arg, "++t", 3) == 0 && vim_iswhite(eap->arg[3]))
-+    {
-+	add_help_tags = TRUE;
-+	eap->arg = skipwhite(eap->arg + 3);
-+    }
- 
--    if (!mch_isdir(eap->arg))
-+    ExpandInit(&xpc);
-+    xpc.xp_context = EXPAND_DIRECTORIES;
-+    dirname = ExpandOne(&xpc, eap->arg, NULL,
-+			    WILD_LIST_NOTFOUND|WILD_SILENT, WILD_EXPAND_FREE);
-+    if (dirname == NULL || !mch_isdir(dirname))
-     {
- 	EMSG2(_("E150: Not a directory: %s"), eap->arg);
- 	return;
-@@ -6046,7 +6144,7 @@
- 
- #ifdef FEAT_MULTI_LANG
-     /* Get a list of all files in the directory. */
--    STRCPY(NameBuff, eap->arg);
-+    STRCPY(NameBuff, dirname);
-     add_pathsep(NameBuff);
-     STRCAT(NameBuff, "*");
-     if (gen_expand_wildcards(1, &NameBuff, &filecount, &files,
-@@ -6054,6 +6152,7 @@
- 	    || filecount == 0)
-     {
- 	EMSG2("E151: No match: %s", NameBuff);
-+	vim_free(dirname);
- 	return;
-     }
- 
-@@ -6119,7 +6218,7 @@
- 	    ext[1] = fname[5];
- 	    ext[2] = fname[6];
- 	}
--	helptags_one(eap->arg, ext, fname);
-+	helptags_one(dirname, ext, fname, add_help_tags);
-     }
- 
-     ga_clear(&ga);
-@@ -6127,15 +6226,17 @@
- 
- #else
-     /* No language support, just use "*.txt" and "tags". */
--    helptags_one(eap->arg, (char_u *)".txt", (char_u *)"tags");
-+    helptags_one(dirname, (char_u *)".txt", (char_u *)"tags", add_help_tags);
- #endif
-+    vim_free(dirname);
- }
- 
-     static void
--helptags_one(dir, ext, tagfname)
--    char_u	*dir;	    /* doc directory */
--    char_u	*ext;	    /* suffix, ".txt", ".itx", ".frx", etc. */
--    char_u	*tagfname;    /* "tags" for English, "tags-it" for Italian. */
-+helptags_one(dir, ext, tagfname, add_help_tags)
-+    char_u	*dir;		/* doc directory */
-+    char_u	*ext;		/* suffix, ".txt", ".itx", ".frx", etc. */
-+    char_u	*tagfname;      /* "tags" for English, "tags-fr" for French. */
-+    int		add_help_tags;  /* add "help-tags" tag */
- {
-     FILE	*fd_tags;
-     FILE	*fd;
-@@ -6186,10 +6287,12 @@
-     }
- 
-     /*
--     * If generating tags for "$VIMRUNTIME/doc" add the "help-tags" tag.
-+     * If using the "++t" argument or generating tags for "$VIMRUNTIME/doc"
-+     * add the "help-tags" tag.
-      */
-     ga_init2(&ga, (int)sizeof(char_u *), 100);
--    if (fullpathcmp((char_u *)"$VIMRUNTIME/doc", dir, FALSE) == FPC_SAME)
-+    if (add_help_tags || fullpathcmp((char_u *)"$VIMRUNTIME/doc",
-+						      dir, FALSE) == FPC_SAME)
-     {
- 	if (ga_grow(&ga, 1) == FAIL)
- 	    got_int = TRUE;
-@@ -6351,9 +6454,9 @@
- 	for (i = 0; i < ga.ga_len; ++i)
- 	{
- 	    s = ((char_u **)ga.ga_data)[i];
--	    if (STRNCMP(s, "help-tags", 9) == 0)
-+	    if (STRNCMP(s, "help-tags\t", 10) == 0)
- 		/* help-tags entry was added in formatted form */
--		fprintf(fd_tags, (char *)s);
-+		fputs((char *)s, fd_tags);
- 	    else
- 	    {
- 		fprintf(fd_tags, "%s\t/*", s);
-diff -Naur vim71.orig/src/ex_cmds.h vim71/src/ex_cmds.h
---- vim71.orig/src/ex_cmds.h	2007-03-07 15:53:27.000000000 -0500
-+++ vim71/src/ex_cmds.h	2008-06-18 06:55:02.000000000 -0400
-@@ -422,7 +422,7 @@
- EX(CMD_helpgrep,	"helpgrep",	ex_helpgrep,
- 			EXTRA|NOTRLCOM|NEEDARG),
- EX(CMD_helptags,	"helptags",	ex_helptags,
--			NEEDARG|FILE1|TRLBAR|CMDWIN),
-+			NEEDARG|FILES|TRLBAR|CMDWIN),
- EX(CMD_hardcopy,	"hardcopy",	ex_hardcopy,
- 			RANGE|COUNT|EXTRA|TRLBAR|DFLALL|BANG),
- EX(CMD_highlight,	"highlight",	ex_highlight,
-diff -Naur vim71.orig/src/ex_cmds2.c vim71/src/ex_cmds2.c
---- vim71.orig/src/ex_cmds2.c	2007-05-07 15:25:02.000000000 -0400
-+++ vim71/src/ex_cmds2.c	2008-06-18 06:55:20.000000000 -0400
-@@ -93,6 +93,8 @@
-     int		save_emsg_silent = emsg_silent;
-     int		save_redir_off = redir_off;
-     tasave_T	typeaheadbuf;
-+    int		typeahead_saved = FALSE;
-+    int		save_ignore_script = 0;
- # ifdef FEAT_EX_EXTRA
-     int		save_ex_normal_busy;
- # endif
-@@ -159,18 +161,26 @@
- 	 * This makes sure we get input from the user here and don't interfere
- 	 * with the commands being executed.  Reset "ex_normal_busy" to avoid
- 	 * the side effects of using ":normal". Save the stuff buffer and make
--	 * it empty. */
-+	 * it empty. Set ignore_script to avoid reading from script input. */
- # ifdef FEAT_EX_EXTRA
- 	save_ex_normal_busy = ex_normal_busy;
- 	ex_normal_busy = 0;
- # endif
- 	if (!debug_greedy)
-+	{
- 	    save_typeahead(&typeaheadbuf);
-+	    typeahead_saved = TRUE;
-+	    save_ignore_script = ignore_script;
-+	    ignore_script = TRUE;
-+	}
- 
- 	cmdline = getcmdline_prompt('>', NULL, 0, EXPAND_NOTHING, NULL);
- 
--	if (!debug_greedy)
-+	if (typeahead_saved)
-+	{
- 	    restore_typeahead(&typeaheadbuf);
-+	    ignore_script = save_ignore_script;
-+	}
- # ifdef FEAT_EX_EXTRA
- 	ex_normal_busy = save_ex_normal_busy;
- # endif
-@@ -885,19 +895,61 @@
-     sprintf(buf, "%10.6lf", (double)tm->QuadPart / (double)fr.QuadPart);
- # else
-     sprintf(buf, "%3ld.%06ld", (long)tm->tv_sec, (long)tm->tv_usec);
--#endif
-+# endif
-     return buf;
- }
- 
--# endif  /* FEAT_PROFILE || FEAT_RELTIME */
-+/*
-+ * Put the time "msec" past now in "tm".
-+ */
-+    void
-+profile_setlimit(msec, tm)
-+    long	msec;
-+    proftime_T	*tm;
-+{
-+    if (msec <= 0)   /* no limit */
-+	profile_zero(tm);
-+    else
-+    {
-+# ifdef WIN3264
-+	LARGE_INTEGER   fr;
-+
-+	QueryPerformanceCounter(tm);
-+	QueryPerformanceFrequency(&fr);
-+	tm->QuadPart += (LONGLONG)((double)msec / 1000.0 * (double)fr.QuadPart);
-+# else
-+	long	    usec;
-+
-+	gettimeofday(tm, NULL);
-+	usec = (long)tm->tv_usec + (long)msec * 1000;
-+	tm->tv_usec = usec % 1000000L;
-+	tm->tv_sec += usec / 1000000L;
-+# endif
-+    }
-+}
- 
--# if defined(FEAT_PROFILE) || defined(PROTO)
- /*
-- * Functions for profiling.
-+ * Return TRUE if the current time is past "tm".
-  */
--static void script_do_profile __ARGS((scriptitem_T *si));
--static void script_dump_profile __ARGS((FILE *fd));
--static proftime_T prof_wait_time;
-+    int
-+profile_passed_limit(tm)
-+    proftime_T	*tm;
-+{
-+    proftime_T	now;
-+
-+# ifdef WIN3264
-+    if (tm->QuadPart == 0)  /* timer was not set */
-+	return FALSE;
-+    QueryPerformanceCounter(&now);
-+    return (now.QuadPart > tm->QuadPart);
-+# else
-+    if (tm->tv_sec == 0)    /* timer was not set */
-+	return FALSE;
-+    gettimeofday(&now, NULL);
-+    return (now.tv_sec > tm->tv_sec
-+	    || (now.tv_sec == tm->tv_sec && now.tv_usec > tm->tv_usec));
-+# endif
-+}
- 
- /*
-  * Set the time in "tm" to zero.
-@@ -914,6 +966,16 @@
- # endif
- }
- 
-+# endif  /* FEAT_PROFILE || FEAT_RELTIME */
-+
-+# if defined(FEAT_PROFILE) || defined(PROTO)
-+/*
-+ * Functions for profiling.
-+ */
-+static void script_do_profile __ARGS((scriptitem_T *si));
-+static void script_dump_profile __ARGS((FILE *fd));
-+static proftime_T prof_wait_time;
-+
- /*
-  * Add the time "tm2" to "tm".
-  */
-@@ -2827,11 +2889,14 @@
-     if (has_autocmd(EVENT_SOURCECMD, fname_exp, NULL)
- 	    && apply_autocmds(EVENT_SOURCECMD, fname_exp, fname_exp,
- 							       FALSE, curbuf))
-+    {
- # ifdef FEAT_EVAL
--	return aborting() ? FAIL : OK;
-+	retval = aborting() ? FAIL : OK;
- # else
--	return OK;
-+	retval = OK;
- # endif
-+	goto theend;
-+    }
- 
-     /* Apply SourcePre autocommands, they may get the file. */
-     apply_autocmds(EVENT_SOURCEPRE, fname_exp, fname_exp, FALSE, curbuf);
-diff -Naur vim71.orig/src/ex_docmd.c vim71/src/ex_docmd.c
---- vim71.orig/src/ex_docmd.c	2007-05-07 15:49:38.000000000 -0400
-+++ vim71/src/ex_docmd.c	2008-06-18 06:56:06.000000000 -0400
-@@ -133,6 +133,7 @@
- static void	get_flags __ARGS((exarg_T *eap));
- #if !defined(FEAT_PERL) || !defined(FEAT_PYTHON) || !defined(FEAT_TCL) \
- 	|| !defined(FEAT_RUBY) || !defined(FEAT_MZSCHEME)
-+# define HAVE_EX_SCRIPT_NI
- static void	ex_script_ni __ARGS((exarg_T *eap));
- #endif
- static char_u	*invalid_range __ARGS((exarg_T *eap));
-@@ -372,7 +373,7 @@
- static char_u	*arg_all __ARGS((void));
- #ifdef FEAT_SESSION
- static int	makeopens __ARGS((FILE *fd, char_u *dirnow));
--static int	put_view __ARGS((FILE *fd, win_T *wp, int add_edit, unsigned *flagp));
-+static int	put_view __ARGS((FILE *fd, win_T *wp, int add_edit, unsigned *flagp, int current_arg_idx));
- static void	ex_loadview __ARGS((exarg_T *eap));
- static char_u	*get_view_file __ARGS((int c));
- static int	did_lcd;	/* whether ":lcd" was produced for a session */
-@@ -666,7 +667,7 @@
- 		if (ex_pressedreturn)
- 		{
- 		    /* go up one line, to overwrite the ":<CR>" line, so the
--		     * output doensn't contain empty lines. */
-+		     * output doesn't contain empty lines. */
- 		    msg_row = prev_msg_row;
- 		    if (prev_msg_row == Rows - 1)
- 			msg_row--;
-@@ -1741,7 +1742,9 @@
- 	}
- 
- 	/* ignore comment and empty lines */
--	if (*ea.cmd == '"' || *ea.cmd == NUL)
-+	if (*ea.cmd == '"')
-+	    goto doend;
-+	if (*ea.cmd == NUL)
- 	{
- 	    ex_pressedreturn = TRUE;
- 	    goto doend;
-@@ -2118,7 +2121,11 @@
- #ifdef FEAT_USR_CMDS
- 	    !USER_CMDIDX(ea.cmdidx) &&
- #endif
--	    cmdnames[ea.cmdidx].cmd_func == ex_ni);
-+	    (cmdnames[ea.cmdidx].cmd_func == ex_ni
-+#ifdef HAVE_EX_SCRIPT_NI
-+	     || cmdnames[ea.cmdidx].cmd_func == ex_script_ni
-+#endif
-+	     ));
- 
- #ifndef FEAT_EVAL
-     /*
-@@ -2654,7 +2661,7 @@
- 		errormsg = IObuff;
- 	    }
- 	    STRCAT(errormsg, ": ");
--	    STRNCAT(errormsg, *cmdlinep, IOSIZE - STRLEN(IObuff));
-+	    STRNCAT(errormsg, *cmdlinep, IOSIZE - STRLEN(IObuff) - 1);
- 	}
- 	emsg(errormsg);
-     }
-@@ -2756,7 +2763,7 @@
- 
-     /*
-      * Isolate the command and search for it in the command table.
--     * Exeptions:
-+     * Exceptions:
-      * - the 'k' command can directly be followed by any character.
-      * - the 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r'
-      *	    but :sre[wind] is another command, as are :scrip[tnames],
-@@ -2957,6 +2964,57 @@
- #endif
- 
- #if defined(FEAT_EVAL) || defined(PROTO)
-+static struct cmdmod
-+{
-+    char	*name;
-+    int		minlen;
-+    int		has_count;  /* :123verbose  :3tab */
-+} cmdmods[] = {
-+    {"aboveleft", 3, FALSE},
-+    {"belowright", 3, FALSE},
-+    {"botright", 2, FALSE},
-+    {"browse", 3, FALSE},
-+    {"confirm", 4, FALSE},
-+    {"hide", 3, FALSE},
-+    {"keepalt", 5, FALSE},
-+    {"keepjumps", 5, FALSE},
-+    {"keepmarks", 3, FALSE},
-+    {"leftabove", 5, FALSE},
-+    {"lockmarks", 3, FALSE},
-+    {"rightbelow", 6, FALSE},
-+    {"sandbox", 3, FALSE},
-+    {"silent", 3, FALSE},
-+    {"tab", 3, TRUE},
-+    {"topleft", 2, FALSE},
-+    {"verbose", 4, TRUE},
-+    {"vertical", 4, FALSE},
-+};
-+
-+/*
-+ * Return length of a command modifier (including optional count).
-+ * Return zero when it's not a modifier.
-+ */
-+    int
-+modifier_len(cmd)
-+    char_u	*cmd;
-+{
-+    int		i, j;
-+    char_u	*p = cmd;
-+
-+    if (VIM_ISDIGIT(*cmd))
-+	p = skipwhite(skipdigits(cmd));
-+    for (i = 0; i < sizeof(cmdmods) / sizeof(struct cmdmod); ++i)
-+    {
-+	for (j = 0; p[j] != NUL; ++j)
-+	    if (p[j] != cmdmods[i].name[j])
-+		break;
-+	if (!isalpha(p[j]) && j >= cmdmods[i].minlen
-+					&& (p == cmd || cmdmods[i].has_count))
-+	    return j + (p - cmd);
-+    }
-+    return 0;
-+}
-+
- /*
-  * Return > 0 if an Ex command "name" exists.
-  * Return 2 if there is an exact match.
-@@ -2971,30 +3029,6 @@
-     int		i;
-     int		j;
-     char_u	*p;
--    static struct cmdmod
--    {
--	char	*name;
--	int	minlen;
--    } cmdmods[] = {
--	{"aboveleft", 3},
--	{"belowright", 3},
--	{"botright", 2},
--	{"browse", 3},
--	{"confirm", 4},
--	{"hide", 3},
--	{"keepalt", 5},
--	{"keepjumps", 5},
--	{"keepmarks", 3},
--	{"leftabove", 5},
--	{"lockmarks", 3},
--	{"rightbelow", 6},
--	{"sandbox", 3},
--	{"silent", 3},
--	{"tab", 3},
--	{"topleft", 2},
--	{"verbose", 4},
--	{"vertical", 4},
--    };
- 
-     /* Check command modifiers. */
-     for (i = 0; i < sizeof(cmdmods) / sizeof(struct cmdmod); ++i)
-@@ -3276,32 +3310,27 @@
- 
-     if (ea.argt & XFILE)
-     {
--	int in_quote = FALSE;
--	char_u *bow = NULL;	/* Beginning of word */
-+	int	c;
-+	int	in_quote = FALSE;
-+	char_u	*bow = NULL;	/* Beginning of word */
- 
- 	/*
- 	 * Allow spaces within back-quotes to count as part of the argument
- 	 * being expanded.
- 	 */
- 	xp->xp_pattern = skipwhite(arg);
--	for (p = xp->xp_pattern; *p; )
-+	p = xp->xp_pattern;
-+	while (*p != NUL)
- 	{
--	    if (*p == '\\' && p[1] != NUL)
--		++p;
--#ifdef SPACE_IN_FILENAME
--	    else if (vim_iswhite(*p) && (!(ea.argt & NOSPC) || usefilter))
--#else
--	    else if (vim_iswhite(*p))
-+#ifdef FEAT_MBYTE
-+	    if (has_mbyte)
-+		c = mb_ptr2char(p);
-+	    else
- #endif
--	    {
--		p = skipwhite(p);
--		if (in_quote)
--		    bow = p;
--		else
--		    xp->xp_pattern = p;
--		--p;
--	    }
--	    else if (*p == '`')
-+		c = *p;
-+	    if (c == '\\' && p[1] != NUL)
-+		++p;
-+	    else if (c == '`')
- 	    {
- 		if (!in_quote)
- 		{
-@@ -3310,6 +3339,39 @@
- 		}
- 		in_quote = !in_quote;
- 	    }
-+	    /* An argument can contain just about everything, except
-+	     * characters that end the command and white space. */
-+	    else if (c == '|' || c == '\n' || c == '"' || (vim_iswhite(c)
-+#ifdef SPACE_IN_FILENAME
-+					 && (!(ea.argt & NOSPC) || usefilter)
-+#endif
-+		    ))
-+	    {
-+		len = 0;  /* avoid getting stuck when space is in 'isfname' */
-+		while (*p != NUL)
-+		{
-+#ifdef FEAT_MBYTE
-+		    if (has_mbyte)
-+			c = mb_ptr2char(p);
-+		    else
-+#endif
-+			c = *p;
-+		    if (c == '`' || vim_isfilec_or_wc(c))
-+			break;
-+#ifdef FEAT_MBYTE
-+		    if (has_mbyte)
-+			len = (*mb_ptr2len)(p);
-+		    else
-+#endif
-+			len = 1;
-+		    mb_ptr_adv(p);
-+		}
-+		if (in_quote)
-+		    bow = p;
-+		else
-+		    xp->xp_pattern = p;
-+		p -= len;
-+	    }
- 	    mb_ptr_adv(p);
- 	}
- 
-@@ -3401,14 +3463,13 @@
- 	case CMD_windo:
- 	    return arg;
- 
--#ifdef FEAT_SEARCH_EXTRA
-+#ifdef FEAT_CMDL_COMPL
-+# ifdef FEAT_SEARCH_EXTRA
- 	case CMD_match:
- 	    if (*arg == NUL || !ends_excmd(*arg))
- 	    {
--		/* Dummy call to clear variables. */
--		set_context_in_highlight_cmd(xp, (char_u *)"link n");
--		xp->xp_context = EXPAND_HIGHLIGHT;
--		xp->xp_pattern = arg;
-+		/* also complete "None" */
-+		set_context_in_echohl_cmd(xp, arg);
- 		arg = skipwhite(skiptowhite(arg));
- 		if (*arg != NUL)
- 		{
-@@ -3417,9 +3478,8 @@
- 		}
- 	    }
- 	    return find_nextcmd(arg);
--#endif
-+# endif
- 
--#ifdef FEAT_CMDL_COMPL
- /*
-  * All completion for the +cmdline_compl feature goes here.
-  */
-@@ -3617,8 +3677,7 @@
- 	    break;
- 
- 	case CMD_echohl:
--	    xp->xp_context = EXPAND_HIGHLIGHT;
--	    xp->xp_pattern = arg;
-+	    set_context_in_echohl_cmd(xp, arg);
- 	    break;
- #endif
- 	case CMD_highlight:
-@@ -3874,7 +3933,7 @@
- 				curwin->w_cursor.col = 0;
- 			    searchcmdlen = 0;
- 			    if (!do_search(NULL, c, cmd, 1L,
--				      SEARCH_HIS + SEARCH_MSG + SEARCH_START))
-+					       SEARCH_HIS | SEARCH_MSG, NULL))
- 			    {
- 				curwin->w_cursor = pos;
- 				cmd = NULL;
-@@ -3921,9 +3980,8 @@
- 				pos.col = 0;
- 			    if (searchit(curwin, curbuf, &pos,
- 					*cmd == '?' ? BACKWARD : FORWARD,
--					(char_u *)"", 1L,
--					SEARCH_MSG + SEARCH_START,
--						      i, (linenr_T)0) != FAIL)
-+					(char_u *)"", 1L, SEARCH_MSG,
-+						i, (linenr_T)0, NULL) != FAIL)
- 				lnum = pos.lnum;
- 			    else
- 			    {
-@@ -3997,8 +4055,7 @@
- 	eap->errmsg = (char_u *)N_("E319: Sorry, the command is not available in this version");
- }
- 
--#if !defined(FEAT_PERL) || !defined(FEAT_PYTHON) || !defined(FEAT_TCL) \
--	|| !defined(FEAT_RUBY) || !defined(FEAT_MZSCHEME)
-+#ifdef HAVE_EX_SCRIPT_NI
- /*
-  * Function called for script command which is Not Implemented.  NI!
-  * Skips over ":perl <<EOF" constructs.
-@@ -4376,7 +4433,7 @@
- 			    || vim_strchr(eap->arg, '~') != NULL)
- 		    {
- 			expand_env_esc(eap->arg, NameBuff, MAXPATHL,
--								 TRUE, NULL);
-+							    TRUE, TRUE, NULL);
- 			has_wildcards = mch_has_wildcard(NameBuff);
- 			p = NameBuff;
- 		    }
-@@ -4492,7 +4549,8 @@
- 	    if (eap->argt & (USECTRLV | XFILE))
- 		++p;		/* skip CTRL-V and next char */
- 	    else
--		STRCPY(p, p + 1);	/* remove CTRL-V and skip next char */
-+				/* remove CTRL-V and skip next char */
-+		mch_memmove(p, p + 1, STRLEN(p));
- 	    if (*p == NUL)		/* stop at NUL after CTRL-V */
- 		break;
- 	}
-@@ -6650,7 +6708,7 @@
-  * The list should be allocated using alloc(), as should each item in the
-  * list. This function takes over responsibility for freeing the list.
-  *
-- * XXX The list is made into the arggument list. This is freed using
-+ * XXX The list is made into the argument list. This is freed using
-  * FreeWild(), which does a series of vim_free() calls, unless the two defines
-  * __EMX__ and __ALWAYS_HAS_TRAILING_NUL_POINTER are set. In this case, a
-  * routine _fnexplodefree() is used. This may cause problems, but as the drop
-@@ -7070,7 +7128,7 @@
- 			 : eap->addr_count == 0 ? 0
- 					       : (int)eap->line2 + 1) != FAIL)
- 	{
--	    do_exedit(eap, NULL);
-+	    do_exedit(eap, old_curwin);
- 
- 	    /* set the alternate buffer for the window we came from */
- 	    if (curwin != old_curwin
-@@ -7743,6 +7801,7 @@
- free_cd_dir()
- {
-     vim_free(prev_dir);
-+    prev_dir = NULL;
- }
- #endif
- 
-@@ -7768,7 +7827,7 @@
- 	if (vim_strchr(p_cpo, CPO_CHDIR) != NULL && curbufIsChanged()
- 							     && !eap->forceit)
- 	{
--	    EMSG(_("E747: Cannot change directory, buffer is modifed (add ! to override)"));
-+	    EMSG(_("E747: Cannot change directory, buffer is modified (add ! to override)"));
- 	    return;
- 	}
- 
-@@ -8399,21 +8458,17 @@
- 		    || *arg == '"')
- 	    {
- 		redir_reg = *arg++;
--		if (*arg == '>' && arg[1] == '>')
-+		if (*arg == '>' && arg[1] == '>')  /* append */
- 		    arg += 2;
--		else if ((*arg == NUL || (*arg == '>' && arg[1] == NUL)) &&
--			 (islower(redir_reg)
--# ifdef FEAT_CLIPBOARD
--			    || redir_reg == '*'
--			    || redir_reg == '+'
--# endif
--			    || redir_reg == '"'))
-+		else
- 		{
-+		    /* Can use both "@a" and "@a>". */
- 		    if (*arg == '>')
- 			arg++;
--
--		    /* make register empty */
--		    write_reg_contents(redir_reg, (char_u *)"", -1, FALSE);
-+		    /* Make register empty when not using @A-@Z and the
-+		     * command is valid. */
-+		    if (*arg == NUL && !isupper(redir_reg))
-+			write_reg_contents(redir_reg, (char_u *)"", -1, FALSE);
- 		}
- 	    }
- 	    if (*arg != NUL)
-@@ -8710,7 +8765,8 @@
- 	    }
- 	    else
- 	    {
--		failed |= (put_view(fd, curwin, !using_vdir, flagp) == FAIL);
-+		failed |= (put_view(fd, curwin, !using_vdir, flagp,
-+								 -1) == FAIL);
- 	    }
- 	    if (put_line(fd, "let &so = s:so_save | let &siso = s:siso_save")
- 								      == FAIL)
-@@ -9368,7 +9424,7 @@
-     if (src > srcstart && src[-1] == '\\')
-     {
- 	*usedlen = 0;
--	STRCPY(src - 1, src);		/* remove backslash */
-+	mch_memmove(src - 1, src, STRLEN(src) + 1);	/* remove backslash */
- 	return NULL;
-     }
- 
-@@ -9468,6 +9524,7 @@
- 		    *errormsg = (char_u *)_("E495: no autocommand file name to substitute for \"<afile>\"");
- 		    return NULL;
- 		}
-+		result = shorten_fname1(result);
- 		break;
- 
- 	case SPEC_ABUF:		/* buffer number for autocommand */
-@@ -9709,6 +9766,8 @@
-     int		tabnr;
-     win_T	*tab_firstwin;
-     frame_T	*tab_topframe;
-+    int		cur_arg_idx = 0;
-+    int		next_arg_idx = 0;
- 
-     if (ssop_flags & SSOP_BUFFERS)
- 	only_save_windows = FALSE;		/* Save ALL buffers */
-@@ -9924,12 +9983,19 @@
- 	{
- 	    if (!ses_do_win(wp))
- 		continue;
--	    if (put_view(fd, wp, wp != edited_win, &ssop_flags) == FAIL)
-+	    if (put_view(fd, wp, wp != edited_win, &ssop_flags,
-+							 cur_arg_idx) == FAIL)
- 		return FAIL;
- 	    if (nr > 1 && put_line(fd, "wincmd w") == FAIL)
- 		return FAIL;
-+	    next_arg_idx = wp->w_arg_idx;
- 	}
- 
-+	/* The argument index in the first tab page is zero, need to set it in
-+	 * each window.  For further tab pages it's the window where we do
-+	 * "tabedit". */
-+	cur_arg_idx = next_arg_idx;
-+
- 	/*
- 	 * Restore cursor to the current window if it's not the first one.
- 	 */
-@@ -10138,11 +10204,13 @@
-  * Caller must make sure 'scrolloff' is zero.
-  */
-     static int
--put_view(fd, wp, add_edit, flagp)
-+put_view(fd, wp, add_edit, flagp, current_arg_idx)
-     FILE	*fd;
-     win_T	*wp;
-     int		add_edit;	/* add ":edit" command to view */
-     unsigned	*flagp;		/* vop_flags or ssop_flags */
-+    int		current_arg_idx; /* current argument index of the window, use
-+				  * -1 if unknown */
- {
-     win_T	*save_curwin;
-     int		f;
-@@ -10172,10 +10240,10 @@
- 
-     /* Only when part of a session: restore the argument index.  Some
-      * arguments may have been deleted, check if the index is valid. */
--    if (wp->w_arg_idx != 0 && wp->w_arg_idx <= WARGCOUNT(wp)
-+    if (wp->w_arg_idx != current_arg_idx && wp->w_arg_idx <= WARGCOUNT(wp)
- 						      && flagp == &ssop_flags)
-     {
--	if (fprintf(fd, "%ldnext", (long)wp->w_arg_idx) < 0
-+	if (fprintf(fd, "%ldargu", (long)wp->w_arg_idx + 1) < 0
- 		|| put_eol(fd) == FAIL)
- 	    return FAIL;
- 	did_next = TRUE;
-@@ -10816,12 +10884,13 @@
-     exarg_T	*eap;
- {
-     char_u	*p;
-+    char_u	*g = NULL;
-     char_u	*end;
-     int		c;
--    int		mi;
-+    int		id;
- 
-     if (eap->line2 <= 3)
--	mi = eap->line2 - 1;
-+	id = eap->line2;
-     else
-     {
- 	EMSG(e_invcmd);
-@@ -10830,13 +10899,7 @@
- 
-     /* First clear any old pattern. */
-     if (!eap->skip)
--    {
--	vim_free(curwin->w_match[mi].regprog);
--	curwin->w_match[mi].regprog = NULL;
--	vim_free(curwin->w_match_pat[mi]);
--	curwin->w_match_pat[mi] = NULL;
--	redraw_later(SOME_VALID);	/* always need a redraw */
--    }
-+	match_delete(curwin, id, FALSE);
- 
-     if (ends_excmd(*eap->arg))
- 	end = eap->arg;
-@@ -10847,15 +10910,7 @@
-     {
- 	p = skiptowhite(eap->arg);
- 	if (!eap->skip)
--	{
--	    curwin->w_match_id[mi] = syn_namen2id(eap->arg,
--							 (int)(p - eap->arg));
--	    if (curwin->w_match_id[mi] == 0)
--	    {
--		EMSG2(_(e_nogroup), eap->arg);
--		return;
--	    }
--	}
-+	    g = vim_strnsave(eap->arg, (int)(p - eap->arg));
- 	p = skipwhite(p);
- 	if (*p == NUL)
- 	{
-@@ -10879,14 +10934,8 @@
- 
- 	    c = *end;
- 	    *end = NUL;
--	    curwin->w_match[mi].regprog = vim_regcomp(p + 1, RE_MAGIC);
--	    if (curwin->w_match[mi].regprog == NULL)
--	    {
--		EMSG2(_(e_invarg2), p);
--		*end = c;
--		return;
--	    }
--	    curwin->w_match_pat[mi] = vim_strsave(p + 1);
-+	    match_add(curwin, g, p + 1, 10, id);
-+	    vim_free(g);
- 	    *end = c;
- 	}
-     }
-diff -Naur vim71.orig/src/ex_eval.c vim71/src/ex_eval.c
---- vim71.orig/src/ex_eval.c	2007-05-07 15:47:50.000000000 -0400
-+++ vim71/src/ex_eval.c	2008-06-18 06:53:54.000000000 -0400
-@@ -1551,7 +1551,7 @@
- 		}
- 		save_cpo  = p_cpo;
- 		p_cpo = (char_u *)"";
--		regmatch.regprog = vim_regcomp(pat, TRUE);
-+		regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
- 		regmatch.rm_ic = FALSE;
- 		if (end != NULL)
- 		    *end = save_char;
-@@ -2269,9 +2269,18 @@
- has_loop_cmd(p)
-     char_u	*p;
- {
--    p = skipwhite(p);
--    while (*p == ':')
--	p = skipwhite(p + 1);
-+    int		len;
-+
-+    /* skip modifiers, white space and ':' */
-+    for (;;)
-+    {
-+	while (*p == ' ' || *p == '\t' || *p == ':')
-+	    ++p;
-+	len = modifier_len(p);
-+	if (len == 0)
-+	    break;
-+	p += len;
-+    }
-     if ((p[0] == 'w' && p[1] == 'h')
- 	    || (p[0] == 'f' && p[1] == 'o' && p[2] == 'r'))
- 	return TRUE;
-diff -Naur vim71.orig/src/ex_getln.c vim71/src/ex_getln.c
---- vim71.orig/src/ex_getln.c	2007-05-07 15:47:23.000000000 -0400
-+++ vim71/src/ex_getln.c	2008-06-18 06:56:47.000000000 -0400
-@@ -268,7 +268,9 @@
-     {
- 	xpc.xp_context = ccline.xp_context;
- 	xpc.xp_pattern = ccline.cmdbuff;
-+# if defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)
- 	xpc.xp_arg = ccline.xp_arg;
-+# endif
-     }
- #endif
- 
-@@ -333,7 +335,14 @@
- 	quit_more = FALSE;	/* reset after CTRL-D which had a more-prompt */
- 
- 	cursorcmd();		/* set the cursor on the right spot */
--	c = safe_vgetc();
-+
-+	/* Get a character.  Ignore K_IGNORE, it should not do anything, such
-+	 * as stop completion. */
-+	do
-+	{
-+	    c = safe_vgetc();
-+	} while (c == K_IGNORE);
-+
- 	if (KeyTyped)
- 	{
- 	    some_key_typed = TRUE;
-@@ -484,7 +493,8 @@
- 	if (xpc.xp_context == EXPAND_MENUNAMES && p_wmnu)
- 	{
- 	    /* Hitting <Down> after "emenu Name.": complete submenu */
--	    if (ccline.cmdbuff[ccline.cmdpos - 1] == '.' && c == K_DOWN)
-+	    if (c == K_DOWN && ccline.cmdpos > 0
-+				  && ccline.cmdbuff[ccline.cmdpos - 1] == '.')
- 		c = p_wc;
- 	    else if (c == K_UP)
- 	    {
-@@ -533,9 +543,11 @@
- 	    upseg[3] = PATHSEP;
- 	    upseg[4] = NUL;
- 
--	    if (ccline.cmdbuff[ccline.cmdpos - 1] == PATHSEP
--		    && c == K_DOWN
--		    && (ccline.cmdbuff[ccline.cmdpos - 2] != '.'
-+	    if (c == K_DOWN
-+		    && ccline.cmdpos > 0
-+		    && ccline.cmdbuff[ccline.cmdpos - 1] == PATHSEP
-+		    && (ccline.cmdpos < 3
-+			|| ccline.cmdbuff[ccline.cmdpos - 2] != '.'
- 			|| ccline.cmdbuff[ccline.cmdpos - 3] != '.'))
- 	    {
- 		/* go down a directory */
-@@ -636,7 +648,7 @@
- 	{
- 	    ++no_mapping;
- 	    ++allow_keys;
--	    c = safe_vgetc();
-+	    c = plain_vgetc();
- 	    --no_mapping;
- 	    --allow_keys;
- 	    /* CTRL-\ e doesn't work when obtaining an expression. */
-@@ -730,8 +742,8 @@
- 	    /* In Ex mode a backslash escapes a newline. */
- 	    if (exmode_active
- 		    && c != ESC
--		    && ccline.cmdpos > 0
- 		    && ccline.cmdpos == ccline.cmdlen
-+		    && ccline.cmdpos > 0
- 		    && ccline.cmdbuff[ccline.cmdpos - 1] == '\\')
- 	    {
- 		if (c == K_KENTER)
-@@ -1086,11 +1098,11 @@
- #endif
- 		putcmdline('"', TRUE);
- 		++no_mapping;
--		i = c = safe_vgetc();	/* CTRL-R <char> */
-+		i = c = plain_vgetc();	/* CTRL-R <char> */
- 		if (i == Ctrl_O)
- 		    i = Ctrl_R;		/* CTRL-R CTRL-O == CTRL-R CTRL-R */
- 		if (i == Ctrl_R)
--		    c = safe_vgetc();	/* CTRL-R CTRL-R <char> */
-+		    c = plain_vgetc();	/* CTRL-R CTRL-R <char> */
- 		--no_mapping;
- #ifdef FEAT_EVAL
- 		/*
-@@ -1181,10 +1193,10 @@
- 	case K_LEFT:
- 	case K_S_LEFT:
- 	case K_C_LEFT:
-+		if (ccline.cmdpos == 0)
-+		    goto cmdline_not_changed;
- 		do
- 		{
--		    if (ccline.cmdpos == 0)
--			break;
- 		    --ccline.cmdpos;
- #ifdef FEAT_MBYTE
- 		    if (has_mbyte)	/* move to first byte of char */
-@@ -1193,7 +1205,8 @@
- #endif
- 		    ccline.cmdspos -= cmdline_charsize(ccline.cmdpos);
- 		}
--		while ((c == K_S_LEFT || c == K_C_LEFT
-+		while (ccline.cmdpos > 0
-+			&& (c == K_S_LEFT || c == K_C_LEFT
- 			       || (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)))
- 			&& ccline.cmdbuff[ccline.cmdpos - 1] != ' ');
- #ifdef FEAT_MBYTE
-@@ -1203,7 +1216,8 @@
- 		goto cmdline_not_changed;
- 
- 	case K_IGNORE:
--		goto cmdline_not_changed;	/* Ignore mouse */
-+		/* Ignore mouse event or ex_window() result. */
-+		goto cmdline_not_changed;
- 
- #ifdef FEAT_GUI_W32
- 	    /* On Win32 ignore <M-F4>, we get it when closing the window was
-@@ -1695,6 +1709,9 @@
- 	if (p_is && !cmd_silent && (firstc == '/' || firstc == '?'))
- 	{
- 	    pos_T	end_pos;
-+#ifdef FEAT_RELTIME
-+	    proftime_T	tm;
-+#endif
- 
- 	    /* if there is a character waiting, search and redraw later */
- 	    if (char_avail())
-@@ -1713,8 +1730,18 @@
- 		cursor_off();		/* so the user knows we're busy */
- 		out_flush();
- 		++emsg_off;    /* So it doesn't beep if bad expr */
-+#ifdef FEAT_RELTIME
-+		/* Set the time limit to half a second. */
-+		profile_setlimit(500L, &tm);
-+#endif
- 		i = do_search(NULL, firstc, ccline.cmdbuff, count,
--			SEARCH_KEEP + SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK);
-+			SEARCH_KEEP + SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK,
-+#ifdef FEAT_RELTIME
-+			&tm
-+#else
-+			NULL
-+#endif
-+			);
- 		--emsg_off;
- 		/* if interrupted while searching, behave like it failed */
- 		if (got_int)
-@@ -2090,11 +2117,11 @@
-     garray_T	line_ga;
-     char_u	*pend;
-     int		startcol = 0;
--    int		c1;
-+    int		c1 = 0;
-     int		escaped = FALSE;	/* CTRL-V typed */
-     int		vcol = 0;
-     char_u	*p;
--    int		prev_char = 0;
-+    int		prev_char;
- 
-     /* Switch cursor on now.  This avoids that it happens after the "\n", which
-      * confuses the system function that computes tabstops. */
-@@ -2147,6 +2174,7 @@
- 
- 	/* Get one character at a time.  Don't use inchar(), it can't handle
- 	 * special characters. */
-+	prev_char = c1;
- 	c1 = vgetc();
- 
- 	/*
-@@ -2204,7 +2232,6 @@
- redraw:
- 		/* redraw the line */
- 		msg_col = startcol;
--		windgoto(msg_row, msg_col);
- 		vcol = 0;
- 		for (p = (char_u *)line_ga.ga_data;
- 			  p < (char_u *)line_ga.ga_data + line_ga.ga_len; ++p)
-@@ -2223,6 +2250,7 @@
- 		    }
- 		}
- 		msg_clr_eos();
-+		windgoto(msg_row, msg_col);
- 		continue;
- 	    }
- 
-@@ -2268,7 +2296,6 @@
- 	if (IS_SPECIAL(c1))
- 	    c1 = '?';
- 	((char_u *)line_ga.ga_data)[line_ga.ga_len] = c1;
--	prev_char = c1;
- 	if (c1 == '\n')
- 	    msg_putchar('\n');
- 	else if (c1 == TAB)
-@@ -3311,6 +3338,10 @@
-  * Return a pointer to alloced memory containing the new string.
-  * Return NULL for failure.
-  *
-+ * "orig" is the originally expanded string, copied to allocated memory.  It
-+ * should either be kept in orig_save or freed.  When "mode" is WILD_NEXT or
-+ * WILD_PREV "orig" should be NULL.
-+ *
-  * Results are cached in xp->xp_files and xp->xp_numfiles, except when "mode"
-  * is WILD_EXPAND_FREE or WILD_ALL.
-  *
-@@ -3344,6 +3375,7 @@
-     char_u	*ss = NULL;
-     static int	findex;
-     static char_u *orig_save = NULL;	/* kept value of orig */
-+    int		orig_saved = FALSE;
-     int		i;
-     long_u	len;
-     int		non_suf_match;		/* number without matching suffix */
-@@ -3395,7 +3427,7 @@
- 	    return NULL;
-     }
- 
--/* free old names */
-+    /* free old names */
-     if (xp->xp_numfiles != -1 && mode != WILD_ALL && mode != WILD_LONGEST)
-     {
- 	FreeWild(xp->xp_numfiles, xp->xp_files);
-@@ -3412,6 +3444,7 @@
-     {
- 	vim_free(orig_save);
- 	orig_save = orig;
-+	orig_saved = TRUE;
- 
- 	/*
- 	 * Do the expansion.
-@@ -3536,6 +3569,10 @@
-     if (mode == WILD_EXPAND_FREE || mode == WILD_ALL)
- 	ExpandCleanup(xp);
- 
-+    /* Free "orig" if it wasn't stored in "orig_save". */
-+    if (!orig_saved)
-+	vim_free(orig);
-+
-     return ss;
- }
- 
-@@ -3620,20 +3657,9 @@
- 		    }
- 		}
- #ifdef BACKSLASH_IN_FILENAME
--		{
--		    char_u	buf[20];
--		    int		j = 0;
--
--		    /* Don't escape '[' and '{' if they are in 'isfname'. */
--		    for (p = PATH_ESC_CHARS; *p != NUL; ++p)
--			if ((*p != '[' && *p != '{') || !vim_isfilec(*p))
--			    buf[j++] = *p;
--		    buf[j] = NUL;
--		    p = vim_strsave_escaped(files[i], buf);
--		}
-+		p = vim_strsave_fnameescape(files[i], FALSE);
- #else
--		p = vim_strsave_escaped(files[i],
--			     xp->xp_shell ? SHELL_ESC_CHARS : PATH_ESC_CHARS);
-+		p = vim_strsave_fnameescape(files[i], xp->xp_shell);
- #endif
- 		if (p != NULL)
- 		{
-@@ -3673,6 +3699,32 @@
- }
- 
- /*
-+ * Escape special characters in "fname" for when used as a file name argument
-+ * after a Vim command, or, when "shell" is non-zero, a shell command.
-+ * Returns the result in allocated memory.
-+ */
-+    char_u *
-+vim_strsave_fnameescape(fname, shell)
-+    char_u *fname;
-+    int    shell;
-+{
-+#ifdef BACKSLASH_IN_FILENAME
-+    char_u	buf[20];
-+    int		j = 0;
-+    char_u	*p;
-+
-+    /* Don't escape '[' and '{' if they are in 'isfname'. */
-+    for (p = PATH_ESC_CHARS; *p != NUL; ++p)
-+	if ((*p != '[' && *p != '{') || !vim_isfilec(*p))
-+	    buf[j++] = *p;
-+    buf[j] = NUL;
-+    return vim_strsave_escaped(fname, buf);
-+#else
-+    return vim_strsave_escaped(fname, shell ? SHELL_ESC_CHARS : PATH_ESC_CHARS);
-+#endif
-+}
-+
-+/*
-  * Put a backslash before the file name in "pp", which is in allocated memory.
-  */
-     static void
-@@ -4054,6 +4106,7 @@
- 	     * ~ would be at the start of the file name, but not the tail.
- 	     * $ could be anywhere in the tail.
- 	     * ` could be anywhere in the file name.
-+	     * When the name ends in '$' don't add a star, remove the '$'.
- 	     */
- 	    tail = gettail(retval);
- 	    if ((*retval != '~' || tail != retval)
-@@ -4061,6 +4114,8 @@
- 		    && vim_strchr(tail, '$') == NULL
- 		    && vim_strchr(retval, '`') == NULL)
- 		retval[len++] = '*';
-+	    else if (len > 0 && retval[len - 1] == '$')
-+		--len;
- 	    retval[len] = NUL;
- 	}
-     }
-@@ -4148,13 +4203,19 @@
- 
- #ifdef FEAT_EVAL
-     if (ccline.cmdfirstc == '=')
-+    {
-+# ifdef FEAT_CMDL_COMPL
- 	/* pass CMD_SIZE because there is no real command */
- 	set_context_for_expression(xp, str, CMD_SIZE);
-+# endif
-+    }
-     else if (ccline.input_fn)
-     {
- 	xp->xp_context = ccline.xp_context;
- 	xp->xp_pattern = ccline.cmdbuff;
-+# if defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)
- 	xp->xp_arg = ccline.xp_arg;
-+# endif
-     }
-     else
- #endif
-@@ -4295,10 +4356,11 @@
- 			    && pat[i + 1] == '\\'
- 			    && pat[i + 2] == '\\'
- 			    && pat[i + 3] == ' ')
--			STRCPY(pat + i, pat + i + 3);
-+			mch_memmove(pat + i, pat + i + 3,
-+						     STRLEN(pat + i + 3) + 1);
- 		    if (xp->xp_backslash == XP_BS_ONE
- 			    && pat[i + 1] == ' ')
--			STRCPY(pat + i, pat + i + 1);
-+			mch_memmove(pat + i, pat + i + 1, STRLEN(pat + i));
- 		}
- 	}
- 
-@@ -4502,6 +4564,12 @@
-     if (xp->xp_context != EXPAND_MENUNAMES && xp->xp_context != EXPAND_MENUS)
- 	sort_strings(*file, *num_file);
- 
-+#ifdef FEAT_CMDL_COMPL
-+    /* Reset the variables used for special highlight names expansion, so that
-+     * they don't show up when getting normal highlight names by ID. */
-+    reset_expand_highlight();
-+#endif
-+
-     return OK;
- }
- 
-@@ -4535,7 +4603,7 @@
-     pat = vim_strsave(filepat);
-     for (i = 0; pat[i]; ++i)
- 	if (pat[i] == '\\' && pat[i + 1] == ' ')
--	    STRCPY(pat + i, pat + i + 1);
-+	    mch_memmove(pat + i, pat + i + 1, STRLEN(pat + i));
- 
-     flags |= EW_FILE | EW_EXEC;
- 
-@@ -4615,7 +4683,7 @@
- static void * call_user_expand_func __ARGS((void *(*user_expand_func) __ARGS((char_u *, int, char_u **, int)), expand_T	*xp, int *num_file, char_u ***file));
- 
- /*
-- * call "user_expand_func()" to invoke a user defined VimL function and return
-+ * Call "user_expand_func()" to invoke a user defined VimL function and return
-  * the result (either a string or a List).
-  */
-     static void *
-@@ -4637,11 +4705,22 @@
-     *num_file = 0;
-     *file = NULL;
- 
--    keep = ccline.cmdbuff[ccline.cmdlen];
--    ccline.cmdbuff[ccline.cmdlen] = 0;
--    sprintf((char *)num, "%d", ccline.cmdpos);
-+    if (ccline.cmdbuff == NULL)
-+    {
-+	/* Completion from Insert mode, pass fake arguments. */
-+	keep = 0;
-+	sprintf((char *)num, "%d", (int)STRLEN(xp->xp_pattern));
-+	args[1] = xp->xp_pattern;
-+    }
-+    else
-+    {
-+	/* Completion on the command line, pass real arguments. */
-+	keep = ccline.cmdbuff[ccline.cmdlen];
-+	ccline.cmdbuff[ccline.cmdlen] = 0;
-+	sprintf((char *)num, "%d", ccline.cmdpos);
-+	args[1] = ccline.cmdbuff;
-+    }
-     args[0] = xp->xp_pattern;
--    args[1] = ccline.cmdbuff;
-     args[2] = num;
- 
-     /* Save the cmdline, we don't know what the function may do. */
-@@ -4654,8 +4733,8 @@
- 
-     ccline = save_ccline;
-     current_SID = save_current_SID;
--
--    ccline.cmdbuff[ccline.cmdlen] = keep;
-+    if (ccline.cmdbuff != NULL)
-+	ccline.cmdbuff[ccline.cmdlen] = keep;
- 
-     return ret;
- }
-@@ -5907,7 +5986,7 @@
- 
- # ifdef FEAT_AUTOCMD
-     /* Don't execute autocommands while creating the window. */
--    ++autocmd_block;
-+    block_autocmds();
- # endif
-     /* don't use a new tab page */
-     cmdmod.tab = 0;
-@@ -5916,6 +5995,9 @@
-     if (win_split((int)p_cwh, WSP_BOT) == FAIL)
-     {
- 	beep_flush();
-+# ifdef FEAT_AUTOCMD
-+	unblock_autocmds();
-+# endif
- 	return K_IGNORE;
-     }
-     cmdwin_type = ccline.cmdfirstc;
-@@ -5938,7 +6020,7 @@
- 
- # ifdef FEAT_AUTOCMD
-     /* Do execute autocommands for setting the filetype (load syntax). */
--    --autocmd_block;
-+    unblock_autocmds();
- # endif
- 
-     /* Showing the prompt may have set need_wait_return, reset it. */
-@@ -6092,7 +6174,7 @@
- 
- # ifdef FEAT_AUTOCMD
- 	/* Don't execute autocommands while deleting the window. */
--	++autocmd_block;
-+	block_autocmds();
- # endif
- 	wp = curwin;
- 	bp = curbuf;
-@@ -6104,7 +6186,7 @@
- 	win_size_restore(&winsizes);
- 
- # ifdef FEAT_AUTOCMD
--	--autocmd_block;
-+	unblock_autocmds();
- # endif
-     }
- 
-diff -Naur vim71.orig/src/feature.h vim71/src/feature.h
---- vim71.orig/src/feature.h	2007-05-07 15:33:19.000000000 -0400
-+++ vim71/src/feature.h	2008-06-18 06:51:34.000000000 -0400
-@@ -673,7 +673,7 @@
- # define ESC_CHG_TO_ENG_MODE		/* if defined, when ESC pressed,
- 					 * turn to english mode
- 					 */
--# if !defined(FEAT_XFONTSET) && defined(HAVE_X11)
-+# if !defined(FEAT_XFONTSET) && defined(HAVE_X11) && !defined(HAVE_GTK2)
- #  define FEAT_XFONTSET			/* Hangul input requires xfontset */
- # endif
- # if defined(FEAT_XIM) && !defined(LINT)
-diff -Naur vim71.orig/src/fileio.c vim71/src/fileio.c
---- vim71.orig/src/fileio.c	2007-05-10 07:29:44.000000000 -0400
-+++ vim71/src/fileio.c	2008-06-18 06:56:56.000000000 -0400
-@@ -44,6 +44,10 @@
- /* Is there any system that doesn't have access()? */
- #define USE_MCH_ACCESS
- 
-+#if defined(sun) && defined(S_ISCHR)
-+# define OPEN_CHR_FILES
-+static int is_dev_fd_file(char_u *fname);
-+#endif
- #ifdef FEAT_MBYTE
- static char_u *next_fenc __ARGS((char_u **pp));
- # ifdef FEAT_EVAL
-@@ -217,11 +221,12 @@
- {
-     int		fd = 0;
-     int		newfile = (flags & READ_NEW);
--    int		set_options = newfile || (eap != NULL && eap->read_edit);
-     int		check_readonly;
-     int		filtering = (flags & READ_FILTER);
-     int		read_stdin = (flags & READ_STDIN);
-     int		read_buffer = (flags & READ_BUFFER);
-+    int		set_options = newfile || read_buffer
-+					   || (eap != NULL && eap->read_edit);
-     linenr_T	read_buf_lnum = 1;	/* next line to read from curbuf */
-     colnr_T	read_buf_col = 0;	/* next char to read from this line */
-     char_u	c;
-@@ -406,6 +411,10 @@
- # ifdef S_ISSOCK
- 		      && !S_ISSOCK(perm)	    /* ... or socket */
- # endif
-+# ifdef OPEN_CHR_FILES
-+		      && !(S_ISCHR(perm) && is_dev_fd_file(fname))
-+			/* ... or a character special file named /dev/fd/<n> */
-+# endif
- 						)
- 	{
- 	    if (S_ISDIR(perm))
-@@ -424,7 +433,7 @@
- 	 */
- 	if (!p_odev && mch_nodetype(fname) == NODE_WRITABLE)
- 	{
--	    filemess(curbuf, fname, (char_u *)_("is a device (disabled with 'opendevice' option"), 0);
-+	    filemess(curbuf, fname, (char_u *)_("is a device (disabled with 'opendevice' option)"), 0);
- 	    msg_end();
- 	    msg_scroll = msg_save;
- 	    return FAIL;
-@@ -642,10 +651,16 @@
- 
-     if (set_options)
-     {
--	curbuf->b_p_eol = TRUE;
--	curbuf->b_start_eol = TRUE;
-+	/* Don't change 'eol' if reading from buffer as it will already be
-+	 * correctly set when reading stdin. */
-+	if (!read_buffer)
-+	{
-+	    curbuf->b_p_eol = TRUE;
-+	    curbuf->b_start_eol = TRUE;
-+	}
- #ifdef FEAT_MBYTE
- 	curbuf->b_p_bomb = FALSE;
-+	curbuf->b_start_bomb = FALSE;
- #endif
-     }
- 
-@@ -904,7 +919,10 @@
- 	file_rewind = FALSE;
- #ifdef FEAT_MBYTE
- 	if (set_options)
-+	{
- 	    curbuf->b_p_bomb = FALSE;
-+	    curbuf->b_start_bomb = FALSE;
-+	}
- 	conv_error = 0;
- #endif
-     }
-@@ -1270,12 +1288,49 @@
- #ifdef FEAT_MBYTE
- 		    else if (conv_restlen > 0)
- 		    {
--			/* Reached end-of-file but some trailing bytes could
--			 * not be converted.  Truncated file? */
--			if (conv_error == 0)
--			    conv_error = linecnt;
--			if (bad_char_behavior != BAD_DROP)
-+			/*
-+			 * Reached end-of-file but some trailing bytes could
-+			 * not be converted.  Truncated file?
-+			 */
-+
-+			/* When we did a conversion report an error. */
-+			if (fio_flags != 0
-+# ifdef USE_ICONV
-+				|| iconv_fd != (iconv_t)-1
-+# endif
-+			   )
- 			{
-+			    if (conv_error == 0)
-+				conv_error = curbuf->b_ml.ml_line_count
-+								- linecnt + 1;
-+			}
-+			/* Remember the first linenr with an illegal byte */
-+			else if (illegal_byte == 0)
-+			    illegal_byte = curbuf->b_ml.ml_line_count
-+								- linecnt + 1;
-+			if (bad_char_behavior == BAD_DROP)
-+			{
-+			    *(ptr - conv_restlen) = NUL;
-+			    conv_restlen = 0;
-+			}
-+			else
-+			{
-+			    /* Replace the trailing bytes with the replacement
-+			     * character if we were converting; if we weren't,
-+			     * leave the UTF8 checking code to do it, as it
-+			     * works slightly differently. */
-+			    if (bad_char_behavior != BAD_KEEP && (fio_flags != 0
-+# ifdef USE_ICONV
-+				    || iconv_fd != (iconv_t)-1
-+# endif
-+			       ))
-+			    {
-+				while (conv_restlen > 0)
-+				{
-+				    *(--ptr) = bad_char_behavior;
-+				    --conv_restlen;
-+				}
-+			    }
- 			    fio_flags = 0;	/* don't convert this */
- # ifdef USE_ICONV
- 			    if (iconv_fd != (iconv_t)-1)
-@@ -1284,20 +1339,6 @@
- 				iconv_fd = (iconv_t)-1;
- 			    }
- # endif
--			    if (bad_char_behavior == BAD_KEEP)
--			    {
--				/* Keep the trailing bytes as-is. */
--				size = conv_restlen;
--				ptr -= conv_restlen;
--			    }
--			    else
--			    {
--				/* Replace the trailing bytes with the
--				 * replacement character. */
--				size = 1;
--				*--ptr = bad_char_behavior;
--			    }
--			    conv_restlen = 0;
- 			}
- 		    }
- #endif
-@@ -1353,7 +1394,10 @@
- 		    size -= blen;
- 		    mch_memmove(ptr, ptr + blen, (size_t)size);
- 		    if (set_options)
-+		    {
- 			curbuf->b_p_bomb = TRUE;
-+			curbuf->b_start_bomb = TRUE;
-+		    }
- 		}
- 
- 		if (fio_flags == FIO_UCSBOM)
-@@ -1376,6 +1420,11 @@
- 		    goto retry;
- 		}
- 	    }
-+
-+	    /* Include not converted bytes. */
-+	    ptr -= conv_restlen;
-+	    size += conv_restlen;
-+	    conv_restlen = 0;
- #endif
- 	    /*
- 	     * Break here for a read error or end-of-file.
-@@ -1385,11 +1434,6 @@
- 
- #ifdef FEAT_MBYTE
- 
--	    /* Include not converted bytes. */
--	    ptr -= conv_restlen;
--	    size += conv_restlen;
--	    conv_restlen = 0;
--
- # ifdef USE_ICONV
- 	    if (iconv_fd != (iconv_t)-1)
- 	    {
-@@ -1851,12 +1895,12 @@
- 		size = (long)((ptr + real_size) - dest);
- 		ptr = dest;
- 	    }
--	    else if (enc_utf8 && conv_error == 0 && !curbuf->b_p_bin)
-+	    else if (enc_utf8 && !curbuf->b_p_bin)
- 	    {
--		/* Reading UTF-8: Check if the bytes are valid UTF-8.
--		 * Need to start before "ptr" when part of the character was
--		 * read in the previous read() call. */
--		for (p = ptr - utf_head_off(buffer, ptr); ; ++p)
-+		int  incomplete_tail = FALSE;
-+
-+		/* Reading UTF-8: Check if the bytes are valid UTF-8. */
-+		for (p = ptr; ; ++p)
- 		{
- 		    int	 todo = (int)((ptr + size) - p);
- 		    int	 l;
-@@ -1870,43 +1914,56 @@
- 			 * read() will get the next bytes, we'll check it
- 			 * then. */
- 			l = utf_ptr2len_len(p, todo);
--			if (l > todo)
-+			if (l > todo && !incomplete_tail)
- 			{
--			    /* Incomplete byte sequence, the next read()
--			     * should get them and check the bytes. */
--			    p += todo;
--			    break;
-+			    /* Avoid retrying with a different encoding when
-+			     * a truncated file is more likely, or attempting
-+			     * to read the rest of an incomplete sequence when
-+			     * we have already done so. */
-+			    if (p > ptr || filesize > 0)
-+				incomplete_tail = TRUE;
-+			    /* Incomplete byte sequence, move it to conv_rest[]
-+			     * and try to read the rest of it, unless we've
-+			     * already done so. */
-+			    if (p > ptr)
-+			    {
-+				conv_restlen = todo;
-+				mch_memmove(conv_rest, p, conv_restlen);
-+				size -= conv_restlen;
-+				break;
-+			    }
- 			}
--			if (l == 1)
-+			if (l == 1 || l > todo)
- 			{
- 			    /* Illegal byte.  If we can try another encoding
--			     * do that. */
--			    if (can_retry)
-+			     * do that, unless at EOF where a truncated
-+			     * file is more likely than a conversion error. */
-+			    if (can_retry && !incomplete_tail)
- 				break;
--
--			    /* Remember the first linenr with an illegal byte */
--			    if (illegal_byte == 0)
--				illegal_byte = readfile_linenr(linecnt, ptr, p);
- # ifdef USE_ICONV
- 			    /* When we did a conversion report an error. */
- 			    if (iconv_fd != (iconv_t)-1 && conv_error == 0)
- 				conv_error = readfile_linenr(linecnt, ptr, p);
- # endif
-+			    /* Remember the first linenr with an illegal byte */
-+			    if (conv_error == 0 && illegal_byte == 0)
-+				illegal_byte = readfile_linenr(linecnt, ptr, p);
- 
- 			    /* Drop, keep or replace the bad byte. */
- 			    if (bad_char_behavior == BAD_DROP)
- 			    {
--				mch_memmove(p, p+1, todo - 1);
-+				mch_memmove(p, p + 1, todo - 1);
- 				--p;
- 				--size;
- 			    }
- 			    else if (bad_char_behavior != BAD_KEEP)
- 				*p = bad_char_behavior;
- 			}
--			p += l - 1;
-+			else
-+			    p += l - 1;
- 		    }
- 		}
--		if (p < ptr + size)
-+		if (p < ptr + size && !incomplete_tail)
- 		{
- 		    /* Detected a UTF-8 error. */
- rewind_retry:
-@@ -2265,6 +2322,13 @@
- 	    }
- #  endif
- # endif
-+# ifdef OPEN_CHR_FILES
-+	    if (S_ISCHR(perm))			    /* or character special */
-+	    {
-+		STRCAT(IObuff, _("[character special]"));
-+		c = TRUE;
-+	    }
-+# endif
- #endif
- 	    if (curbuf->b_p_ro)
- 	    {
-@@ -2464,6 +2528,25 @@
-     return OK;
- }
- 
-+#ifdef OPEN_CHR_FILES
-+/*
-+ * Returns TRUE if the file name argument is of the form "/dev/fd/\d\+",
-+ * which is the name of files used for process substitution output by
-+ * some shells on some operating systems, e.g., bash on SunOS.
-+ * Do not accept "/dev/fd/[012]", opening these may hang Vim.
-+ */
-+    static int
-+is_dev_fd_file(fname)
-+    char_u	*fname;
-+{
-+    return (STRNCMP(fname, "/dev/fd/", 8) == 0
-+	    && VIM_ISDIGIT(fname[8])
-+	    && *skipdigits(fname + 9) == NUL
-+	    && (fname[9] != NUL
-+		|| (fname[8] != '0' && fname[8] != '1' && fname[8] != '2')));
-+}
-+#endif
-+
- #ifdef FEAT_MBYTE
- 
- /*
-@@ -2734,6 +2817,32 @@
- #endif
- 
- /*
-+ * Return TRUE if a file appears to be read-only from the file permissions.
-+ */
-+    int
-+check_file_readonly(fname, perm)
-+    char_u	*fname;		/* full path to file */
-+    int		perm;		/* known permissions on file */
-+{
-+#ifndef USE_MCH_ACCESS
-+    int	    fd = 0;
-+#endif
-+
-+    return (
-+#ifdef USE_MCH_ACCESS
-+# ifdef UNIX
-+	(perm & 0222) == 0 ||
-+# endif
-+	mch_access((char *)fname, W_OK)
-+#else
-+	(fd = mch_open((char *)fname, O_RDWR | O_EXTRA, 0)) < 0
-+					? TRUE : (close(fd), FALSE)
-+#endif
-+	);
-+}
-+
-+
-+/*
-  * buf_write() - write to file "fname" lines "start" through "end"
-  *
-  * We do our own buffering here because fwrite() is so slow.
-@@ -3142,7 +3251,8 @@
-      * Get information about original file (if there is one).
-      */
- #if defined(UNIX) && !defined(ARCHIE)
--    st_old.st_dev = st_old.st_ino = 0;
-+    st_old.st_dev = 0;
-+    st_old.st_ino = 0;
-     perm = -1;
-     if (mch_stat((char *)fname, &st_old) < 0)
- 	newfile = TRUE;
-@@ -3219,17 +3329,8 @@
- 	 * Check if the file is really writable (when renaming the file to
- 	 * make a backup we won't discover it later).
- 	 */
--	file_readonly = (
--# ifdef USE_MCH_ACCESS
--#  ifdef UNIX
--		    (perm & 0222) == 0 ||
--#  endif
--		    mch_access((char *)fname, W_OK)
--# else
--		    (fd = mch_open((char *)fname, O_RDWR | O_EXTRA, 0)) < 0
--						   ? TRUE : (close(fd), FALSE)
--# endif
--		    );
-+	file_readonly = check_file_readonly(fname, (int)perm);
-+
- 	if (!forceit && file_readonly)
- 	{
- 	    if (vim_strchr(p_cpo, CPO_FWRITE) != NULL)
-@@ -3586,6 +3687,9 @@
- 						)
- 			    mch_setperm(backup,
- 					  (perm & 0707) | ((perm & 07) << 3));
-+# ifdef HAVE_SELINUX
-+			mch_copy_sec(fname, backup);
-+# endif
- #endif
- 
- 			/*
-@@ -3622,6 +3726,9 @@
- #ifdef HAVE_ACL
- 			mch_set_acl(backup, acl);
- #endif
-+#ifdef HAVE_SELINUX
-+			mch_copy_sec(fname, backup);
-+#endif
- 			break;
- 		    }
- 		}
-@@ -4243,6 +4350,12 @@
-     }
- #endif
- 
-+#ifdef HAVE_SELINUX
-+    /* Probably need to set the security context. */
-+    if (!backup_copy)
-+	mch_copy_sec(backup, wfname);
-+#endif
-+
- #ifdef UNIX
-     /* When creating a new file, set its owner/group to that of the original
-      * file.  Get the new device and inode number. */
-@@ -5448,10 +5561,11 @@
-     else if (p[0] == 0xfe && p[1] == 0xff
- 	    && (flags == FIO_ALL || flags == FIO_UCS2 || flags == FIO_UTF16))
-     {
--	if (flags == FIO_UTF16)
--	    name = "utf-16";	/* FE FF */
--	else
-+	/* Default to utf-16, it works also for ucs-2 text. */
-+	if (flags == FIO_UCS2)
- 	    name = "ucs-2";	/* FE FF */
-+	else
-+	    name = "utf-16";	/* FE FF */
-     }
-     else if (size >= 4 && p[0] == 0 && p[1] == 0 && p[2] == 0xfe
- 	    && p[3] == 0xff && (flags == FIO_ALL || flags == FIO_UCS4))
-@@ -5495,6 +5609,8 @@
- }
- #endif
- 
-+#if defined(FEAT_VIMINFO) || defined(FEAT_BROWSE) || \
-+    defined(FEAT_QUICKFIX) || defined(FEAT_AUTOCMD) || defined(PROTO)
- /*
-  * Try to find a shortname by comparing the fullname with the current
-  * directory.
-@@ -5548,6 +5664,7 @@
- 	p = NULL;
-     return p;
- }
-+#endif
- 
- /*
-  * Shorten filenames for all buffers.
-@@ -7107,6 +7224,7 @@
- 
- static event_T	last_event;
- static int	last_group;
-+static int	autocmd_blocked = 0;	/* block all autocmds */
- 
- /*
-  * Show the autocommands for one AutoPat.
-@@ -8396,7 +8514,7 @@
-      * Quickly return if there are no autocommands for this event or
-      * autocommands are blocked.
-      */
--    if (first_autopat[(int)event] == NULL || autocmd_block > 0)
-+    if (first_autopat[(int)event] == NULL || autocmd_blocked > 0)
- 	goto BYPASS_AU;
- 
-     /*
-@@ -8461,6 +8579,8 @@
- 
-     /*
-      * Set the file name to be used for <afile>.
-+     * Make a copy to avoid that changing a buffer name or directory makes it
-+     * invalid.
-      */
-     if (fname_io == NULL)
-     {
-@@ -8473,6 +8593,8 @@
-     }
-     else
- 	autocmd_fname = fname_io;
-+    if (autocmd_fname != NULL)
-+	autocmd_fname = FullName_save(autocmd_fname, FALSE);
- 
-     /*
-      * Set the buffer number to be used for <abuf>.
-@@ -8655,6 +8777,7 @@
-     vim_free(sourcing_name);
-     sourcing_name = save_sourcing_name;
-     sourcing_lnum = save_sourcing_lnum;
-+    vim_free(autocmd_fname);
-     autocmd_fname = save_autocmd_fname;
-     autocmd_bufnr = save_autocmd_bufnr;
-     autocmd_match = save_autocmd_match;
-@@ -8710,6 +8833,40 @@
-     return retval;
- }
- 
-+# ifdef FEAT_EVAL
-+static char_u	*old_termresponse = NULL;
-+# endif
-+
-+/*
-+ * Block triggering autocommands until unblock_autocmd() is called.
-+ * Can be used recursively, so long as it's symmetric.
-+ */
-+    void
-+block_autocmds()
-+{
-+# ifdef FEAT_EVAL
-+    /* Remember the value of v:termresponse. */
-+    if (autocmd_blocked == 0)
-+	old_termresponse = get_vim_var_str(VV_TERMRESPONSE);
-+# endif
-+    ++autocmd_blocked;
-+}
-+
-+    void
-+unblock_autocmds()
-+{
-+    --autocmd_blocked;
-+
-+# ifdef FEAT_EVAL
-+    /* When v:termresponse was set while autocommands were blocked, trigger
-+     * the autocommands now.  Esp. useful when executing a shell command
-+     * during startup (vimdiff). */
-+    if (autocmd_blocked == 0
-+		      && get_vim_var_str(VV_TERMRESPONSE) != old_termresponse)
-+	apply_autocmds(EVENT_TERMRESPONSE, NULL, NULL, FALSE, curbuf);
-+# endif
-+}
-+
- /*
-  * Find next autocommand pattern that matches.
-  */
-@@ -9108,7 +9265,7 @@
-     aco_save_T	*aco;		/* structure to save values in */
-     buf_T	*buf;		/* new curbuf */
- {
--    aco->save_buf = buf;
-+    aco->save_buf = curbuf;
-     curbuf = buf;
-     curwin->w_buffer = buf;
- }
-diff -Naur vim71.orig/src/fold.c vim71/src/fold.c
---- vim71.orig/src/fold.c	2007-05-07 15:46:32.000000000 -0400
-+++ vim71/src/fold.c	2008-06-18 06:56:03.000000000 -0400
-@@ -858,7 +858,14 @@
- 	    || foldmethodIsDiff(wp)
- #endif
- 	    || foldmethodIsSyntax(wp))
-+    {
-+	int save_got_int = got_int;
-+
-+	/* reset got_int here, otherwise it won't work */
-+	got_int = FALSE;
- 	foldUpdateIEMS(wp, top, bot);
-+	got_int |= save_got_int;
-+    }
- }
- 
- /* foldUpdateAll() {{{2 */
-@@ -2300,7 +2307,7 @@
- 
-     /* If some fold changed, need to redraw and position cursor. */
-     if (fold_changed && wp->w_p_fen)
--	changed_window_setting();
-+	changed_window_setting_win(wp);
- 
-     /* If we updated folds past "bot", need to redraw more lines.  Don't do
-      * this in other situations, the changed lines will be redrawn anyway and
-@@ -2669,6 +2676,7 @@
-     if (fp->fd_len < flp->lnum - fp->fd_top)
-     {
- 	fp->fd_len = flp->lnum - fp->fd_top;
-+	fp->fd_small = MAYBE;
- 	fold_changed = TRUE;
-     }
- 
-diff -Naur vim71.orig/src/getchar.c vim71/src/getchar.c
---- vim71.orig/src/getchar.c	2007-05-07 15:18:20.000000000 -0400
-+++ vim71/src/getchar.c	2008-06-18 06:54:12.000000000 -0400
-@@ -253,8 +253,9 @@
- 	return;
-     }
-     else if (buf->bh_index != 0)
--	STRCPY(buf->bh_first.b_next->b_str,
--				 buf->bh_first.b_next->b_str + buf->bh_index);
-+	mch_memmove(buf->bh_first.b_next->b_str,
-+		    buf->bh_first.b_next->b_str + buf->bh_index,
-+		    STRLEN(buf->bh_first.b_next->b_str + buf->bh_index) + 1);
-     buf->bh_index = 0;
- 
-     if (buf->bh_space >= (int)slen)
-@@ -1278,8 +1279,14 @@
-     void
- free_typebuf()
- {
--    vim_free(typebuf.tb_buf);
--    vim_free(typebuf.tb_noremap);
-+    if (typebuf.tb_buf == typebuf_init)
-+	EMSG2(_(e_intern2), "Free typebuf 1");
-+    else
-+	vim_free(typebuf.tb_buf);
-+    if (typebuf.tb_buf == noremapbuf_init)
-+	EMSG2(_(e_intern2), "Free typebuf 2");
-+    else
-+	vim_free(typebuf.tb_noremap);
- }
- 
- /*
-@@ -1358,6 +1365,11 @@
- 	EMSG(_(e_nesting));
- 	return;
-     }
-+#ifdef FEAT_EVAL
-+    if (ignore_script)
-+	/* Not reading from script, also don't open one.  Warning message? */
-+	return;
-+#endif
- 
-     if (scriptin[curscript] != NULL)	/* already reading script */
- 	++curscript;
-@@ -1596,8 +1608,16 @@
- 		continue;
- 	    }
- #endif
--
- #ifdef FEAT_GUI
-+	    /* Handle focus event here, so that the caller doesn't need to
-+	     * know about it.  Return K_IGNORE so that we loop once (needed if
-+	     * 'lazyredraw' is set). */
-+	    if (c == K_FOCUSGAINED || c == K_FOCUSLOST)
-+	    {
-+		ui_focus_change(c == K_FOCUSGAINED);
-+		c = K_IGNORE;
-+	    }
-+
- 	    /* Translate K_CSI to CSI.  The special key is only used to avoid
- 	     * it being recognized as the start of a special key. */
- 	    if (c == K_CSI)
-@@ -1741,6 +1761,22 @@
- }
- 
- /*
-+ * Like safe_vgetc(), but loop to handle K_IGNORE.
-+ * Also ignore scrollbar events.
-+ */
-+    int
-+plain_vgetc()
-+{
-+    int c;
-+
-+    do
-+    {
-+	c = safe_vgetc();
-+    } while (c == K_IGNORE || c == K_VER_SCROLLBAR || c == K_HOR_SCROLLBAR);
-+    return c;
-+}
-+
-+/*
-  * Check if a character is available, such that vgetc() will not block.
-  * If the next character is a special character or multi-byte, the returned
-  * character is not valid!.
-@@ -2321,7 +2357,7 @@
- 						   current_menu->silent[idx]);
- 				}
- 			    }
--#endif /* FEAT_GUI */
-+#endif /* FEAT_GUI && FEAT_MENU */
- 			    continue;	/* try mapping again */
- 			}
- 
-@@ -2837,11 +2873,15 @@
-     undo_off = FALSE;		    /* restart undo now */
- 
-     /*
--     * first try script file
--     *	If interrupted: Stop reading script files.
-+     * Get a character from a script file if there is one.
-+     * If interrupted: Stop reading script files, close them all.
-      */
-     script_char = -1;
--    while (scriptin[curscript] != NULL && script_char < 0)
-+    while (scriptin[curscript] != NULL && script_char < 0
-+#ifdef FEAT_EVAL
-+	    && !ignore_script
-+#endif
-+	    )
-     {
- 	if (got_int || (script_char = getc(scriptin[curscript])) < 0)
- 	{
-diff -Naur vim71.orig/src/globals.h vim71/src/globals.h
---- vim71.orig/src/globals.h	2007-05-07 15:44:26.000000000 -0400
-+++ vim71/src/globals.h	2008-06-18 06:54:12.000000000 -0400
-@@ -301,13 +301,17 @@
- #endif
- 
- #ifdef FEAT_EVAL
--/* Garbage collection can only take place when we are sure there are no Lists
-+/*
-+ * Garbage collection can only take place when we are sure there are no Lists
-  * or Dictionaries being used internally.  This is flagged with
-  * "may_garbage_collect" when we are at the toplevel.
-  * "want_garbage_collect" is set by the garbagecollect() function, which means
-- * we do garbage collection before waiting for a char at the toplevel. */
-+ * we do garbage collection before waiting for a char at the toplevel.
-+ * "garbage_collect_at_exit" indicates garbagecollect(1) was called.
-+ */
- EXTERN int	may_garbage_collect INIT(= FALSE);
- EXTERN int	want_garbage_collect INIT(= FALSE);
-+EXTERN int	garbage_collect_at_exit INIT(= FALSE);
- 
- /* ID of script being sourced or was sourced to define the current function. */
- EXTERN scid_T	current_SID INIT(= 0);
-@@ -362,7 +366,6 @@
- EXTERN int	autocmd_busy INIT(= FALSE);	/* Is apply_autocmds() busy? */
- EXTERN int	autocmd_no_enter INIT(= FALSE); /* *Enter autocmds disabled */
- EXTERN int	autocmd_no_leave INIT(= FALSE); /* *Leave autocmds disabled */
--EXTERN int	autocmd_block INIT(= 0);	/* block all autocmds */
- EXTERN int	modified_was_set;		/* did ":set modified" */
- EXTERN int	did_filetype INIT(= FALSE);	/* FileType event found */
- EXTERN int	keep_filetype INIT(= FALSE);	/* value for did_filetype when
-@@ -801,7 +804,7 @@
- EXTERN int (*mb_char2bytes) __ARGS((int c, char_u *buf)) INIT(= latin_char2bytes);
- EXTERN int (*mb_ptr2cells) __ARGS((char_u *p)) INIT(= latin_ptr2cells);
- EXTERN int (*mb_char2cells) __ARGS((int c)) INIT(= latin_char2cells);
--EXTERN int (*mb_off2cells) __ARGS((unsigned off)) INIT(= latin_off2cells);
-+EXTERN int (*mb_off2cells) __ARGS((unsigned off, unsigned max_off)) INIT(= latin_off2cells);
- EXTERN int (*mb_ptr2char) __ARGS((char_u *p)) INIT(= latin_ptr2char);
- EXTERN int (*mb_head_off) __ARGS((char_u *base, char_u *p)) INIT(= latin_head_off);
- 
-@@ -951,6 +954,9 @@
- EXTERN int	ex_normal_busy INIT(= 0); /* recursiveness of ex_normal() */
- EXTERN int	ex_normal_lock INIT(= 0); /* forbid use of ex_normal() */
- #endif
-+#ifdef FEAT_EVAL
-+EXTERN int	ignore_script INIT(= FALSE);  /* ignore script input */
-+#endif
- EXTERN int	stop_insert_mode;	/* for ":stopinsert" and 'insertmode' */
- 
- EXTERN int	KeyTyped;		/* TRUE if user typed current char */
-diff -Naur vim71.orig/src/gui.c vim71/src/gui.c
---- vim71.orig/src/gui.c	2007-05-07 15:50:55.000000000 -0400
-+++ vim71/src/gui.c	2008-06-18 06:56:40.000000000 -0400
-@@ -1080,7 +1080,8 @@
- 		cur_width = gui.char_width;
- 	    }
- #ifdef FEAT_MBYTE
--	    if (has_mbyte && (*mb_off2cells)(LineOffset[gui.row] + gui.col) > 1)
-+	    if (has_mbyte && (*mb_off2cells)(LineOffset[gui.row] + gui.col,
-+				    LineOffset[gui.row] + screen_Columns) > 1)
- 	    {
- 		/* Double wide character. */
- 		if (shape_table[idx].shape != SHAPE_VER)
-@@ -1159,7 +1160,7 @@
- #endif
- 
- # if defined(FEAT_GUI_TABLINE) && (defined(FEAT_GUI_MSWIN) \
-- 	|| defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_MAC))
-+	|| defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_MAC))
-     if (gui_has_tabline())
- 	text_area_y += gui.tabline_height;
- #endif
-@@ -1293,11 +1294,7 @@
-     out_flush();
- 
-     gui.num_cols = (pixel_width - gui_get_base_width()) / gui.char_width;
--    gui.num_rows = (pixel_height - gui_get_base_height()
--#if !defined(FEAT_GUI_PHOTON) && !defined(FEAT_GUI_MSWIN)
--				    + (gui.char_height / 2)
--#endif
--					) / gui.char_height;
-+    gui.num_rows = (pixel_height - gui_get_base_height()) / gui.char_height;
- 
-     gui_position_components(pixel_width);
- 
-@@ -3733,8 +3730,10 @@
-     sb->value = value;
- 
- #ifdef USE_ON_FLY_SCROLL
--    /* When not allowed to do the scrolling right now, return. */
--    if (dont_scroll || input_available())
-+    /* When not allowed to do the scrolling right now, return.
-+     * This also checked input_available(), but that causes the first click in
-+     * a scrollbar to be ignored when Vim doesn't have focus. */
-+    if (dont_scroll)
- 	return;
- #endif
- #ifdef FEAT_INS_EXPAND
-@@ -4213,7 +4212,19 @@
- #endif
- 	    )
-     {
--	redraw_win_later(wp, VALID);
-+	int type = VALID;
-+
-+#ifdef FEAT_INS_EXPAND
-+	if (pum_visible())
-+	{
-+	    type = NOT_VALID;
-+	    wp->w_lines_valid = 0;
-+	}
-+#endif
-+	/* Don't set must_redraw here, it may cause the popup menu to
-+	 * disappear when losing focus after a scrollbar drag. */
-+	if (wp->w_redr_type < type)
-+	    wp->w_redr_type = type;
- 	updateWindow(wp);   /* update window, status line, and cmdline */
-     }
- 
-@@ -4518,7 +4529,18 @@
-     xim_set_focus(in_focus);
- # endif
- 
--    ui_focus_change(in_focus);
-+    /* Put events in the input queue only when allowed.
-+     * ui_focus_change() isn't called directly, because it invokes
-+     * autocommands and that must not happen asynchronously. */
-+    if (!hold_gui_events)
-+    {
-+	char_u  bytes[3];
-+
-+	bytes[0] = CSI;
-+	bytes[1] = KS_EXTRA;
-+	bytes[2] = in_focus ? (int)KE_FOCUSGAINED : (int)KE_FOCUSLOST;
-+	add_to_input_buf(bytes, 3);
-+    }
- #endif
- }
- 
-@@ -4833,6 +4855,15 @@
- {
-     update_topline();
-     validate_cursor();
-+#ifdef FEAT_AUTOCMD
-+    /* Trigger CursorMoved if the cursor moved. */
-+    if (!finish_op && has_cursormoved()
-+	    && !equalpos(last_cursormoved, curwin->w_cursor))
-+    {
-+	apply_autocmds(EVENT_CURSORMOVED, NULL, NULL, FALSE, curbuf);
-+	last_cursormoved = curwin->w_cursor;
-+    }
-+#endif
-     update_screen(0);	/* may need to update the screen */
-     setcursor();
-     out_flush();		/* make sure output has been written */
-@@ -5026,7 +5057,7 @@
- 	/* Search for the next match. */
- 	i = msg_scroll;
- 	do_search(NULL, down ? '/' : '?', ga.ga_data, 1L,
--						    SEARCH_MSG + SEARCH_MARK);
-+					      SEARCH_MSG + SEARCH_MARK, NULL);
- 	msg_scroll = i;	    /* don't let an error message set msg_scroll */
-     }
- 
-@@ -5117,7 +5148,7 @@
- 		p = vim_strsave_escaped(fnames[i], (char_u *)"\\ \t\"|");
- # endif
- 		if (p != NULL)
--		    add_to_input_buf(p, (int)STRLEN(p));
-+		    add_to_input_buf_csi(p, (int)STRLEN(p));
- 		vim_free(p);
- 		vim_free(fnames[i]);
- 	    }
-diff -Naur vim71.orig/src/gui_gtk.c vim71/src/gui_gtk.c
---- vim71.orig/src/gui_gtk.c	2007-05-10 04:37:37.000000000 -0400
-+++ vim71/src/gui_gtk.c	2008-06-18 06:52:00.000000000 -0400
-@@ -53,8 +53,8 @@
- # ifdef bindtextdomain
- #  undef bindtextdomain
- # endif
--# ifdef bindtextdomain_codeset
--#  undef bindtextdomain_codeset
-+# ifdef bind_textdomain_codeset
-+#  undef bind_textdomain_codeset
- # endif
- # if defined(FEAT_GETTEXT) && !defined(ENABLE_NLS)
- #  define ENABLE_NLS	/* so the texts in the dialog boxes are translated */
-@@ -1630,11 +1630,14 @@
-  */
- /*ARGSUSED*/
-     static int
--dlg_key_press_event(GtkWidget * widget, GdkEventKey * event, CancelData *data)
-+dlg_key_press_event(GtkWidget *widget, GdkEventKey *event, CancelData *data)
- {
--    /* Ignore hitting Enter when there is no default button. */
--    if (data->ignore_enter && event->keyval == GDK_Return)
-+    /* Ignore hitting Enter (or Space) when there is no default button. */
-+    if (data->ignore_enter && (event->keyval == GDK_Return
-+						     || event->keyval == ' '))
- 	return TRUE;
-+    else    /* A different key was pressed, return to normal behavior */
-+	data->ignore_enter = FALSE;
- 
-     if (event->keyval != GDK_Escape && event->keyval != GDK_Return)
- 	return FALSE;
-@@ -2224,6 +2227,13 @@
- {
-     DialogInfo *di = (DialogInfo *)data;
- 
-+    /* Ignore hitting Enter (or Space) when there is no default button. */
-+    if (di->ignore_enter && (event->keyval == GDK_Return
-+						     || event->keyval == ' '))
-+	return TRUE;
-+    else    /* A different key was pressed, return to normal behavior */
-+	di->ignore_enter = FALSE;
-+
-     /* Close the dialog when hitting "Esc". */
-     if (event->keyval == GDK_Escape)
-     {
-diff -Naur vim71.orig/src/gui_gtk_x11.c vim71/src/gui_gtk_x11.c
---- vim71.orig/src/gui_gtk_x11.c	2007-05-10 04:37:49.000000000 -0400
-+++ vim71/src/gui_gtk_x11.c	2008-06-18 06:54:51.000000000 -0400
-@@ -36,8 +36,8 @@
- # ifdef bindtextdomain
- #  undef bindtextdomain
- # endif
--# ifdef bindtextdomain_codeset
--#  undef bindtextdomain_codeset
-+# ifdef bind_textdomain_codeset
-+#  undef bind_textdomain_codeset
- # endif
- # if defined(FEAT_GETTEXT) && !defined(ENABLE_NLS)
- #  define ENABLE_NLS	/* so the texts in the dialog boxes are translated */
-@@ -813,10 +813,15 @@
-     if (blink_state == BLINK_NONE)
- 	gui_mch_start_blink();
- 
--    /* make sure keyboard input goes to the draw area (if this is focus for a window) */
-+    /* make sure keyboard input goes to the draw area (if this is focus for a
-+     * window) */
-     if (widget != gui.drawarea)
- 	gtk_widget_grab_focus(gui.drawarea);
- 
-+    /* make sure the input buffer is read */
-+    if (gtk_main_level() > 0)
-+	gtk_main_quit();
-+
-     return TRUE;
- }
- 
-@@ -829,6 +834,10 @@
-     if (blink_state != BLINK_NONE)
- 	gui_mch_stop_blink();
- 
-+    /* make sure the input buffer is read */
-+    if (gtk_main_level() > 0)
-+	gtk_main_quit();
-+
-     return TRUE;
- }
- 
-@@ -2188,8 +2197,10 @@
-     escaped_filename = vim_strsave_escaped(filename, escape_chars);
-     if (escaped_filename == NULL)
- 	return FALSE;
--    mksession_cmdline = g_strconcat("mksession ", (char *)escaped_filename, NULL);
-+    mksession_cmdline = g_strconcat("mksession ", (char *)escaped_filename,
-+									NULL);
-     vim_free(escaped_filename);
-+
-     /*
-      * Use a reasonable hardcoded set of 'sessionoptions' flags to avoid
-      * unpredictable effects when the session is saved automatically.  Also,
-@@ -2199,7 +2210,7 @@
-      */
-     save_ssop_flags = ssop_flags;
-     ssop_flags = (SSOP_BLANK|SSOP_CURDIR|SSOP_FOLDS|SSOP_GLOBALS
--		  |SSOP_HELP|SSOP_OPTIONS|SSOP_WINSIZE);
-+		  |SSOP_HELP|SSOP_OPTIONS|SSOP_WINSIZE|SSOP_TABPAGES);
- 
-     do_cmdline_cmd((char_u *)"let Save_VV_this_session = v:this_session");
-     failed = (do_cmdline_cmd((char_u *)mksession_cmdline) == FAIL);
-@@ -3212,8 +3223,9 @@
- 	{
- 	    if (clicked_page == 0)
- 	    {
--		/* Click after all tabs moves to next tab page. */
--		if (send_tabline_event(0) && gtk_main_level() > 0)
-+		/* Click after all tabs moves to next tab page.  When "x" is
-+		 * small guess it's the left button. */
-+		if (send_tabline_event(x < 50 ? -1 : 0) && gtk_main_level() > 0)
- 		    gtk_main_quit();
- 	    }
- #ifndef HAVE_GTK2
-@@ -4032,6 +4044,8 @@
- 	unsigned int	w, h;
- 	int		x = 0;
- 	int		y = 0;
-+	guint		pixel_width;
-+	guint		pixel_height;
- 
- 	mask = XParseGeometry((char *)gui.geom, &x, &y, &w, &h);
- 
-@@ -4043,12 +4057,31 @@
- 		p_window = h - 1;
- 	    Rows = h;
- 	}
-+
-+	pixel_width = (guint)(gui_get_base_width() + Columns * gui.char_width);
-+	pixel_height = (guint)(gui_get_base_height() + Rows * gui.char_height);
-+
-+#ifdef HAVE_GTK2
-+	pixel_width  += get_menu_tool_width();
-+	pixel_height += get_menu_tool_height();
-+#endif
-+
- 	if (mask & (XValue | YValue))
-+	{
-+	    int w, h;
-+	    gui_mch_get_screen_dimensions(&w, &h);
-+	    h += p_ghr + get_menu_tool_height();
-+	    w += get_menu_tool_width();
-+	    if (mask & XNegative)
-+		x += w - pixel_width;
-+	    if (mask & YNegative)
-+		y += h - pixel_height;
- #ifdef HAVE_GTK2
- 	    gtk_window_move(GTK_WINDOW(gui.mainwin), x, y);
- #else
- 	    gtk_widget_set_uposition(gui.mainwin, x, y);
- #endif
-+	}
- 	vim_free(gui.geom);
- 	gui.geom = NULL;
- 
-@@ -4059,14 +4092,6 @@
- 	 */
- 	if (gtk_socket_id != 0  &&  (mask & WidthValue || mask & HeightValue))
- 	{
--	    guint pixel_width = (guint)(gui_get_base_width() + Columns * gui.char_width);
--	    guint pixel_height = (guint)(gui_get_base_height() + Rows * gui.char_height);
--
--#ifdef HAVE_GTK2
--	    pixel_width  += get_menu_tool_width();
--	    pixel_height += get_menu_tool_height();
--#endif
--
- 	    update_window_manager_hints(pixel_width, pixel_height);
- 	    init_window_hints_state = 1;
- 	    g_timeout_add(1000, check_startup_plug_hints, NULL);
-@@ -6635,6 +6660,7 @@
-     unsigned	i;
-     int		nbytes;
-     char_u	*buffer;
-+    time_t	start;
- 
-     for (i = 0; i < N_SELECTION_TARGETS; ++i)
-     {
-@@ -6645,7 +6671,11 @@
- 			      cbd->gtk_sel_atom, target,
- 			      (guint32)GDK_CURRENT_TIME);
- 
--	while (received_selection == RS_NONE)
-+	/* Hack: Wait up to three seconds for the selection.  A hang was
-+	 * noticed here when using the netrw plugin combined with ":gui"
-+	 * during the FocusGained event. */
-+	start = time(NULL);
-+	while (received_selection == RS_NONE && time(NULL) < start + 3)
- 	    gtk_main();	/* wait for selection_received_cb */
- 
- 	if (received_selection != RS_FAIL)
-diff -Naur vim71.orig/src/gui_motif.c vim71/src/gui_motif.c
---- vim71.orig/src/gui_motif.c	2007-05-07 15:20:24.000000000 -0400
-+++ vim71/src/gui_motif.c	2008-06-18 06:55:26.000000000 -0400
-@@ -3813,7 +3813,7 @@
- 
-     XtAddCallback(frdp->find, XmNactivateCallback,
- 	    find_replace_callback,
--	    (XtPointer) (do_replace ? FRD_R_FINDNEXT : FRD_FINDNEXT));
-+	    (do_replace ? (XtPointer)FRD_R_FINDNEXT : (XtPointer)FRD_FINDNEXT));
- 
-     if (do_replace)
-     {
-diff -Naur vim71.orig/src/gui_xmebw.c vim71/src/gui_xmebw.c
---- vim71.orig/src/gui_xmebw.c	2007-05-07 15:30:49.000000000 -0400
-+++ vim71/src/gui_xmebw.c	2008-06-18 06:53:43.000000000 -0400
-@@ -395,11 +395,15 @@
- 
-     /* Create the "highlight" pixmap. */
-     color[4].pixel = eb->primitive.bottom_shadow_color;
-+#ifdef XpmAllocColor /* SGI doesn't have it */
-     attr.valuemask = XpmColorSymbols | XpmCloseness | XpmAllocColor;
-+    attr.alloc_color = alloc_color;
-+#else
-+    attr.valuemask = XpmColorSymbols | XpmCloseness;
-+#endif
-     attr.closeness = 65535;	/* accuracy isn't crucial */
-     attr.colorsymbols = color;
-     attr.numsymbols = XtNumber(color);
--    attr.alloc_color = alloc_color;
- 
-     status = XpmCreatePixmapFromData(dpy, root, data, &pix, NULL, &attr);
-     XpmFreeAttributes(&attr);
-diff -Naur vim71.orig/src/gvimtutor vim71/src/gvimtutor
---- vim71.orig/src/gvimtutor	1969-12-31 19:00:00.000000000 -0500
-+++ vim71/src/gvimtutor	2008-06-18 06:56:38.000000000 -0400
-@@ -0,0 +1,8 @@
-+#!/bin/sh
-+
-+# Start GUI Vim on a copy of the tutor file.
-+
-+# Usage: gvimtutor [xx]
-+# See vimtutor for usage.
-+
-+exec `dirname $0`/vimtutor -g "$@"
-diff -Naur vim71.orig/src/hardcopy.c vim71/src/hardcopy.c
---- vim71.orig/src/hardcopy.c	2007-05-07 15:34:18.000000000 -0400
-+++ vim71/src/hardcopy.c	2008-06-18 06:55:04.000000000 -0400
-@@ -876,7 +876,7 @@
- 	 */
- 	if (psettings->do_syntax)
- 	{
--	    id = syn_get_id(curwin, ppos->file_line, col, 1, NULL);
-+	    id = syn_get_id(curwin, ppos->file_line, col, 1, NULL, FALSE);
- 	    if (id > 0)
- 		id = syn_get_final_id(id);
- 	    else
-diff -Naur vim71.orig/src/if_cscope.c vim71/src/if_cscope.c
---- vim71.orig/src/if_cscope.c	2007-03-11 10:29:57.000000000 -0400
-+++ vim71/src/if_cscope.c	2008-06-18 06:56:33.000000000 -0400
-@@ -24,11 +24,6 @@
-     /* not UNIX, must be WIN32 */
- # include "vimio.h"
- # include <fcntl.h>
--# include <process.h>
--# define STDIN_FILENO    0
--# define STDOUT_FILENO   1
--# define STDERR_FILENO   2
--# define pipe(fds) _pipe(fds, 256, O_TEXT|O_NOINHERIT)
- #endif
- #include "if_cscope.h"
- 
-@@ -65,7 +60,7 @@
- static char *	    cs_parse_results __ARGS((int cnumber, char *buf, int bufsize, char **context, char **linenumber, char **search));
- static char *	    cs_pathcomponents __ARGS((char *path));
- static void	    cs_print_tags_priv __ARGS((char **, char **, int));
--static int	    cs_read_prompt __ARGS((int ));
-+static int	    cs_read_prompt __ARGS((int));
- static void	    cs_release_csp __ARGS((int, int freefnpp));
- static int	    cs_reset __ARGS((exarg_T *eap));
- static char *	    cs_resolve_file __ARGS((int, char *));
-@@ -73,6 +68,8 @@
- 
- 
- static csinfo_T	    csinfo[CSCOPE_MAX_CONNECTIONS];
-+static int	    eap_arg_len;    /* length of eap->arg, set in
-+				       cs_lookup_cmd() */
- static cscmd_T	    cs_cmds[] =
- {
-     { "add",	cs_add,
-@@ -260,14 +257,7 @@
- 
-     if ((p = cs_manage_matches(NULL, NULL, -1, Get)) == NULL)
- 	return TRUE;
--
--    if ((int)strlen(p) > size)
--    {
--	strncpy((char *)buf, p, size - 1);
--	buf[size] = '\0';
--    }
--    else
--	(void)strcpy((char *)buf, p);
-+    vim_strncpy(buf, (char_u *)p, size - 1);
- 
-     return FALSE;
- } /* cs_fgets */
-@@ -386,7 +376,7 @@
-  * PRIVATE: cs_add
-  *
-  * add cscope database or a directory name (to look for cscope.out)
-- * the the cscope connection list
-+ * to the cscope connection list
-  *
-  * MAXPATHL 256
-  */
-@@ -509,7 +499,7 @@
- #if defined(UNIX)
-     else if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode))
- #else
--	/* substitute define S_ISREG from os_unix.h */
-+	/* WIN32 - substitute define S_ISREG from os_unix.h */
-     else if (((statbuf.st_mode) & S_IFMT) == S_IFREG)
- #endif
-     {
-@@ -722,17 +712,32 @@
- cs_create_connection(i)
-     int i;
- {
--    int to_cs[2], from_cs[2], len;
--    char *prog, *cmd, *ppath = NULL;
--#ifndef UNIX
--    int in_save, out_save, err_save;
--    long_i ph;
--# ifdef FEAT_GUI
--    HWND activewnd = NULL;
--    HWND consolewnd = NULL;
-+#ifdef UNIX
-+    int		to_cs[2], from_cs[2];
-+#endif
-+    int		len;
-+    char	*prog, *cmd, *ppath = NULL;
-+#ifdef WIN32
-+    int		fd;
-+    SECURITY_ATTRIBUTES sa;
-+    PROCESS_INFORMATION pi;
-+    STARTUPINFO si;
-+    BOOL	pipe_stdin = FALSE, pipe_stdout = FALSE;
-+    HANDLE	stdin_rd, stdout_rd;
-+    HANDLE	stdout_wr, stdin_wr;
-+    BOOL	created;
-+# ifdef __BORLANDC__
-+#  define OPEN_OH_ARGTYPE long
-+# else
-+#  if (_MSC_VER >= 1300)
-+#   define OPEN_OH_ARGTYPE intptr_t
-+#  else
-+#   define OPEN_OH_ARGTYPE long
-+#  endif
- # endif
- #endif
- 
-+#if defined(UNIX)
-     /*
-      * Cscope reads from to_cs[0] and writes to from_cs[1]; vi reads from
-      * from_cs[0] and writes to to_cs[1].
-@@ -753,18 +758,12 @@
- 	return CSCOPE_FAILURE;
-     }
- 
--#if defined(UNIX)
-     switch (csinfo[i].pid = fork())
-     {
-     case -1:
- 	(void)EMSG(_("E622: Could not fork for cscope"));
- 	goto err_closing;
-     case 0:				/* child: run cscope. */
--#else
--	in_save = dup(STDIN_FILENO);
--	out_save = dup(STDOUT_FILENO);
--	err_save = dup(STDERR_FILENO);
--#endif
- 	if (dup2(to_cs[0], STDIN_FILENO) == -1)
- 	    PERROR("cs_create_connection 1");
- 	if (dup2(from_cs[1], STDOUT_FILENO) == -1)
-@@ -773,15 +772,32 @@
- 	    PERROR("cs_create_connection 3");
- 
- 	/* close unused */
--#if defined(UNIX)
- 	(void)close(to_cs[1]);
- 	(void)close(from_cs[0]);
- #else
--	/* On win32 we must close opposite ends because we are the parent */
--	(void)close(to_cs[0]);
--	to_cs[0] = -1;
--	(void)close(from_cs[1]);
--	from_cs[1] = -1;
-+	/* WIN32 */
-+	/* Create pipes to communicate with cscope */
-+	sa.nLength = sizeof(SECURITY_ATTRIBUTES);
-+	sa.bInheritHandle = TRUE;
-+	sa.lpSecurityDescriptor = NULL;
-+
-+	if (!(pipe_stdin = CreatePipe(&stdin_rd, &stdin_wr, &sa, 0))
-+		|| !(pipe_stdout = CreatePipe(&stdout_rd, &stdout_wr, &sa, 0)))
-+	{
-+	    (void)EMSG(_("E566: Could not create cscope pipes"));
-+err_closing:
-+	    if (pipe_stdin)
-+	    {
-+		CloseHandle(stdin_rd);
-+		CloseHandle(stdin_wr);
-+	    }
-+	    if (pipe_stdout)
-+	    {
-+		CloseHandle(stdout_rd);
-+		CloseHandle(stdout_wr);
-+	    }
-+	    return CSCOPE_FAILURE;
-+	}
- #endif
- 	/* expand the cscope exec for env var's */
- 	if ((prog = (char *)alloc(MAXPATHL + 1)) == NULL)
-@@ -789,6 +805,7 @@
- #ifdef UNIX
- 	    return CSCOPE_FAILURE;
- #else
-+	    /* WIN32 */
- 	    goto err_closing;
- #endif
- 	}
-@@ -805,6 +822,7 @@
- #ifdef UNIX
- 		return CSCOPE_FAILURE;
- #else
-+		/* WIN32 */
- 		goto err_closing;
- #endif
- 	    }
-@@ -823,6 +841,7 @@
- #ifdef UNIX
- 	    return CSCOPE_FAILURE;
- #else
-+	    /* WIN32 */
- 	    goto err_closing;
- #endif
- 	}
-@@ -831,6 +850,7 @@
- #if defined(UNIX)
- 	(void)sprintf(cmd, "exec %s -dl -f %s", prog, csinfo[i].fname);
- #else
-+	/* WIN32 */
- 	(void)sprintf(cmd, "%s -dl -f %s", prog, csinfo[i].fname);
- #endif
- 	if (csinfo[i].ppath != NULL)
-@@ -856,60 +876,6 @@
- 	exit(127);
- 	/* NOTREACHED */
-     default:	/* parent. */
--#else
--# ifdef FEAT_GUI
--	activewnd = GetForegroundWindow(); /* on win9x cscope steals focus */
--	/* Dirty hack to hide annoying console window */
--	if (AllocConsole())
--	{
--	    char *title;
--	    title = (char *)alloc(1024);
--	    if (title == NULL)
--		FreeConsole();
--	    else
--	    {
--		GetConsoleTitle(title, 1024); /* save for future restore */
--		SetConsoleTitle(
--		    "GVIMCS{5499421B-CBEF-45b0-85EF-38167FDEA5C5}GVIMCS");
--		Sleep(40); /* as stated in MS KB we must wait 40 ms */
--		consolewnd = FindWindow(NULL,
--			"GVIMCS{5499421B-CBEF-45b0-85EF-38167FDEA5C5}GVIMCS");
--		if (consolewnd != NULL)
--		    ShowWindow(consolewnd, SW_HIDE);
--		SetConsoleTitle(title);
--		vim_free(title);
--	    }
--	}
--# endif
--	/* May be use &shell, &shellquote etc */
--# ifdef __BORLANDC__
--	/* BCC 5.5 uses a different function name for spawnlp */
--	ph = (long_i)spawnlp(P_NOWAIT, prog, cmd, NULL);
--# else
--	ph = (long_i)_spawnlp(_P_NOWAIT, prog, cmd, NULL);
--# endif
--	vim_free(prog);
--	vim_free(cmd);
--# ifdef FEAT_GUI
--	/* Dirty hack part two */
--	if (activewnd != NULL)
--	    /* restoring focus */
--	    SetForegroundWindow(activewnd);
--	if (consolewnd != NULL)
--	    FreeConsole();
--
--# endif
--	if (ph == -1)
--	{
--	    PERROR(_("cs_create_connection exec failed"));
--	    (void)EMSG(_("E623: Could not spawn cscope process"));
--	    goto err_closing;
--	}
--	/* else */
--	csinfo[i].pid = 0;
--	csinfo[i].hProc = (HANDLE)ph;
--
--#endif /* !UNIX */
- 	/*
- 	 * Save the file descriptors for later duplication, and
- 	 * reopen as streams.
-@@ -919,22 +885,54 @@
- 	if ((csinfo[i].fr_fp = fdopen(from_cs[0], "r")) == NULL)
- 	    PERROR(_("cs_create_connection: fdopen for fr_fp failed"));
- 
--#if defined(UNIX)
- 	/* close unused */
- 	(void)close(to_cs[0]);
- 	(void)close(from_cs[1]);
- 
- 	break;
-     }
-+
- #else
--	/* restore stdhandles */
--    dup2(in_save, STDIN_FILENO);
--    dup2(out_save, STDOUT_FILENO);
--    dup2(err_save, STDERR_FILENO);
--    close(in_save);
--    close(out_save);
--    close(err_save);
--#endif
-+    /* WIN32 */
-+    /* Create a new process to run cscope and use pipes to talk with it */
-+    GetStartupInfo(&si);
-+    si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
-+    si.wShowWindow = SW_HIDE;  /* Hide child application window */
-+    si.hStdOutput = stdout_wr;
-+    si.hStdError  = stdout_wr;
-+    si.hStdInput  = stdin_rd;
-+    created = CreateProcess(NULL, cmd, NULL, NULL, TRUE, CREATE_NEW_CONSOLE,
-+							NULL, NULL, &si, &pi);
-+    vim_free(prog);
-+    vim_free(cmd);
-+
-+    if (!created)
-+    {
-+	PERROR(_("cs_create_connection exec failed"));
-+	(void)EMSG(_("E623: Could not spawn cscope process"));
-+	goto err_closing;
-+    }
-+    /* else */
-+    csinfo[i].pid = pi.dwProcessId;
-+    csinfo[i].hProc = pi.hProcess;
-+    CloseHandle(pi.hThread);
-+
-+    /* TODO - tidy up after failure to create files on pipe handles. */
-+    if (((fd = _open_osfhandle((OPEN_OH_ARGTYPE)stdin_wr,
-+						      _O_TEXT|_O_APPEND)) < 0)
-+	    || ((csinfo[i].to_fp = _fdopen(fd, "w")) == NULL))
-+	PERROR(_("cs_create_connection: fdopen for to_fp failed"));
-+    if (((fd = _open_osfhandle((OPEN_OH_ARGTYPE)stdout_rd,
-+						      _O_TEXT|_O_RDONLY)) < 0)
-+	    || ((csinfo[i].fr_fp = _fdopen(fd, "r")) == NULL))
-+	PERROR(_("cs_create_connection: fdopen for fr_fp failed"));
-+
-+    /* Close handles for file descriptors inherited by the cscope process */
-+    CloseHandle(stdin_rd);
-+    CloseHandle(stdout_wr);
-+
-+#endif /* !UNIX */
-+
-     return CSCOPE_SUCCESS;
- } /* cs_create_connection */
- 
-@@ -966,7 +964,7 @@
-     }
- 
-     pat = opt + strlen(opt) + 1;
--    if (pat == NULL || (pat != NULL && pat[0] == '\0'))
-+    if (pat >= (char *)eap->arg + eap_arg_len)
-     {
- 	cs_usage_msg(Find);
- 	return FALSE;
-@@ -1317,7 +1315,7 @@
- #else
- 	    /* compare pathnames first */
- 	    && ((fullpathcmp(csinfo[j].fname, fname, FALSE) & FPC_SAME)
--		/* if not Windows 9x, test index file atributes too */
-+		/* if not Windows 9x, test index file attributes too */
- 		|| (!mch_windows95()
- 		    && csinfo[j].nVolume == bhfi.dwVolumeSerialNumber
- 		    && csinfo[j].nIndexHigh == bhfi.nFileIndexHigh
-@@ -1401,6 +1399,9 @@
-     if (eap->arg == NULL)
- 	return NULL;
- 
-+    /* Store length of eap->arg before it gets modified by strtok(). */
-+    eap_arg_len = STRLEN(eap->arg);
-+
-     if ((stok = strtok((char *)(eap->arg), (const char *)" ")) == NULL)
- 	return NULL;
- 
-@@ -2095,21 +2096,30 @@
-     return CSCOPE_SUCCESS;
- }
- 
-+#if defined(UNIX) && defined(SIGALRM)
-+/*
-+ * Used to catch and ignore SIGALRM below.
-+ */
-+/* ARGSUSED */
-+    static RETSIGTYPE
-+sig_handler SIGDEFARG(sigarg)
-+{
-+    /* do nothing */
-+    SIGRETURN;
-+}
-+#endif
- 
- /*
-  * PRIVATE: cs_release_csp
-  *
-- * does the actual free'ing for the cs ptr with an optional flag of whether
-- * or not to free the filename.  called by cs_kill and cs_reset.
-+ * Does the actual free'ing for the cs ptr with an optional flag of whether
-+ * or not to free the filename.  Called by cs_kill and cs_reset.
-  */
-     static void
- cs_release_csp(i, freefnpp)
-     int i;
-     int freefnpp;
- {
--#if defined(UNIX)
--    int pstat;
--#else
-     /*
-      * Trying to exit normally (not sure whether it is fit to UNIX cscope
-      */
-@@ -2118,10 +2128,95 @@
- 	(void)fputs("q\n", csinfo[i].to_fp);
- 	(void)fflush(csinfo[i].to_fp);
-     }
--    /* give cscope chance to exit normally */
--    if (csinfo[i].hProc != NULL
--	    && WaitForSingleObject(csinfo[i].hProc, 1000) == WAIT_TIMEOUT)
--	TerminateProcess(csinfo[i].hProc, 0);
-+#if defined(UNIX)
-+    {
-+	int waitpid_errno;
-+	int pstat;
-+	pid_t pid;
-+
-+# if defined(HAVE_SIGACTION)
-+	struct sigaction sa, old;
-+
-+	/* Use sigaction() to limit the waiting time to two seconds. */
-+	sigemptyset(&sa.sa_mask);
-+	sa.sa_handler = sig_handler;
-+	sa.sa_flags = SA_NODEFER;
-+	sigaction(SIGALRM, &sa, &old);
-+	alarm(2); /* 2 sec timeout */
-+
-+	/* Block until cscope exits or until timer expires */
-+	pid = waitpid(csinfo[i].pid, &pstat, 0);
-+	waitpid_errno = errno;
-+
-+	/* cancel pending alarm if still there and restore signal */
-+	alarm(0);
-+	sigaction(SIGALRM, &old, NULL);
-+# else
-+	int waited;
-+
-+	/* Can't use sigaction(), loop for two seconds.  First yield the CPU
-+	 * to give cscope a chance to exit quickly. */
-+	sleep(0);
-+	for (waited = 0; waited < 40; ++waited)
-+	{
-+	    pid = waitpid(csinfo[i].pid, &pstat, WNOHANG);
-+	    waitpid_errno = errno;
-+	    if (pid != 0)
-+		break;  /* break unless the process is still running */
-+	    mch_delay(50L, FALSE); /* sleep 50 ms */
-+	}
-+# endif
-+	/*
-+	 * If the cscope process is still running: kill it.
-+	 * Safety check: If the PID would be zero here, the entire X session
-+	 * would be killed.  -1 and 1 are dangerous as well.
-+	 */
-+	if (pid < 0 && csinfo[i].pid > 1)
-+	{
-+# ifdef ECHILD
-+	    int alive = TRUE;
-+
-+	    if (waitpid_errno == ECHILD)
-+	    {
-+		/*
-+		 * When using 'vim -g', vim is forked and cscope process is
-+		 * no longer a child process but a sibling.  So waitpid()
-+		 * fails with errno being ECHILD (No child processes).
-+		 * Don't send SIGKILL to cscope immediately but wait
-+		 * (polling) for it to exit normally as result of sending
-+		 * the "q" command, hence giving it a chance to clean up
-+		 * its temporary files.
-+		 */
-+		int waited;
-+
-+		sleep(0);
-+		for (waited = 0; waited < 40; ++waited)
-+		{
-+		    /* Check whether cscope process is still alive */
-+		    if (kill(csinfo[i].pid, 0) != 0)
-+		    {
-+			alive = FALSE; /* cscope process no longer exists */
-+			break;
-+		    }
-+		    mch_delay(50L, FALSE); /* sleep 50ms */
-+		}
-+	    }
-+	    if (alive)
-+# endif
-+	    {
-+		kill(csinfo[i].pid, SIGKILL);
-+		(void)waitpid(csinfo[i].pid, &pstat, 0);
-+	    }
-+	}
-+    }
-+#else  /* !UNIX */
-+    if (csinfo[i].hProc != NULL)
-+    {
-+	/* Give cscope a chance to exit normally */
-+	if (WaitForSingleObject(csinfo[i].hProc, 1000) == WAIT_TIMEOUT)
-+	    TerminateProcess(csinfo[i].hProc, 0);
-+	CloseHandle(csinfo[i].hProc);
-+    }
- #endif
- 
-     if (csinfo[i].fr_fp != NULL)
-@@ -2129,18 +2224,6 @@
-     if (csinfo[i].to_fp != NULL)
- 	(void)fclose(csinfo[i].to_fp);
- 
--    /*
--     * Safety check: If the PID would be zero here, the entire X session would
--     * be killed.  -1 and 1 are dangerous as well.
--     */
--#if defined(UNIX)
--    if (csinfo[i].pid > 1)
--    {
--	kill(csinfo[i].pid, SIGTERM);
--	(void)waitpid(csinfo[i].pid, &pstat, 0);
--    }
--#endif
--
-     if (freefnpp)
-     {
- 	vim_free(csinfo[i].fname);
-@@ -2195,7 +2278,7 @@
- 	    cs_add_common(dblist[i], pplist[i], fllist[i]);
- 	    if (p_csverbose)
- 	    {
--		/* dont' use smsg_attr because want to display
-+		/* don't use smsg_attr() because we want to display the
- 		 * connection number in the same line as
- 		 * "Added cscope database..."
- 		 */
-@@ -2304,6 +2387,21 @@
-     return CSCOPE_SUCCESS;
- } /* cs_show */
- 
-+
-+/*
-+ * PUBLIC: cs_end
-+ *
-+ * Only called when VIM exits to quit any cscope sessions.
-+ */
-+    void
-+cs_end()
-+{
-+    int i;
-+
-+    for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++)
-+	cs_release_csp(i, TRUE);
-+}
-+
- #endif	/* FEAT_CSCOPE */
- 
- /* the end */
-diff -Naur vim71.orig/src/if_cscope.h vim71/src/if_cscope.h
---- vim71.orig/src/if_cscope.h	2005-06-30 13:14:22.000000000 -0400
-+++ vim71/src/if_cscope.h	2008-06-18 06:52:38.000000000 -0400
-@@ -72,7 +72,7 @@
-     ino_t	    st_ino;	/* inode number of cscope db */
- #else
- # if defined(WIN32)
--    int	    pid;	/* Can't get pid so set it to 0 ;) */
-+    DWORD	    pid;	/* PID of the connected cscope process. */
-     HANDLE	    hProc;	/* cscope process handle */
-     DWORD	    nVolume;	/* Volume serial number, instead of st_dev */
-     DWORD	    nIndexHigh;	/* st_ino has no meaning in the Windows */
-diff -Naur vim71.orig/src/if_mzsch.c vim71/src/if_mzsch.c
---- vim71.orig/src/if_mzsch.c	2007-05-12 07:13:47.000000000 -0400
-+++ vim71/src/if_mzsch.c	2008-06-18 06:51:00.000000000 -0400
-@@ -308,6 +308,8 @@
- static Scheme_Config *(*dll_scheme_current_config)(void);
- static Scheme_Object *(*dll_scheme_char_string_to_byte_string)
-     (Scheme_Object *s);
-+static Scheme_Object *(*dll_scheme_char_string_to_path)
-+    (Scheme_Object *s);
- # endif
- 
- /* arrays are imported directly */
-@@ -398,6 +400,8 @@
- #  define scheme_current_config dll_scheme_current_config
- #  define scheme_char_string_to_byte_string \
-     dll_scheme_char_string_to_byte_string
-+#  define scheme_char_string_to_path \
-+    dll_scheme_char_string_to_path
- # endif
- 
- typedef struct
-@@ -498,6 +502,8 @@
-     {"scheme_current_config", (void **)&dll_scheme_current_config},
-     {"scheme_char_string_to_byte_string",
- 	(void **)&dll_scheme_char_string_to_byte_string},
-+    {"scheme_char_string_to_path",
-+	(void **)&dll_scheme_char_string_to_path},
- # endif
-     {NULL, NULL}};
- 
-@@ -773,7 +779,14 @@
- #ifdef MZSCHEME_COLLECTS
-     /* setup 'current-library-collection-paths' parameter */
-     scheme_set_param(scheme_config, MZCONFIG_COLLECTION_PATHS,
--	    scheme_make_pair(scheme_make_string(MZSCHEME_COLLECTS),
-+	    scheme_make_pair(
-+# if MZSCHEME_VERSION_MAJOR >= 299
-+		scheme_char_string_to_path(
-+		    scheme_byte_string_to_char_string(
-+			scheme_make_byte_string(MZSCHEME_COLLECTS))),
-+# else
-+		scheme_make_string(MZSCHEME_COLLECTS),
-+# endif
- 		scheme_null));
- #endif
- #ifdef HAVE_SANDBOX
-diff -Naur vim71.orig/src/if_perl.xs vim71/src/if_perl.xs
---- vim71.orig/src/if_perl.xs	2006-08-16 08:45:15.000000000 -0400
-+++ vim71/src/if_perl.xs	2008-06-18 06:53:25.000000000 -0400
-@@ -40,6 +40,28 @@
- #    define PERL_SUBVERSION SUBVERSION
- #endif
- 
-+/*
-+ * Quoting Jan Dubois of Active State:
-+ *    ActivePerl build 822 still identifies itself as 5.8.8 but already
-+ *    contains many of the changes from the upcoming Perl 5.8.9 release.
-+ *
-+ * The changes include addition of two symbols (Perl_sv_2iv_flags,
-+ * Perl_newXS_flags) not present in earlier releases.
-+ *
-+ * Jan Dubois suggested the following guarding scheme.
-+ *
-+ * Active State defined ACTIVEPERL_VERSION as a string in versions before
-+ * 5.8.8; and so the comparison to 822 below needs to be guarded.
-+ */
-+#if (PERL_REVISION == 5) && (PERL_VERSION == 8) && (PERL_SUBVERSION >= 8)
-+# if (ACTIVEPERL_VERSION >= 822) || (PERL_SUBVERSION >= 9)
-+#  define PERL589_OR_LATER
-+# endif
-+#endif
-+#if (PERL_REVISION == 5) && (PERL_VERSION >= 9)
-+# define PERL589_OR_LATER
-+#endif
-+
- #ifndef pTHX
- #    define pTHX void
- #    define pTHX_
-@@ -109,6 +131,10 @@
- # else
- #  define Perl_sv_catpvn dll_Perl_sv_catpvn
- # endif
-+#ifdef PERL589_OR_LATER
-+#  define Perl_sv_2iv_flags dll_Perl_sv_2iv_flags
-+#  define Perl_newXS_flags dll_Perl_newXS_flags
-+#endif
- # define Perl_sv_free dll_Perl_sv_free
- # define Perl_sv_isa dll_Perl_sv_isa
- # define Perl_sv_magic dll_Perl_sv_magic
-@@ -192,6 +218,10 @@
- #else
- static void (*Perl_sv_catpvn)(pTHX_ SV*, const char*, STRLEN);
- #endif
-+#ifdef PERL589_OR_LATER
-+static IV (*Perl_sv_2iv_flags)(pTHX_ SV* sv, I32 flags);
-+static CV * (*Perl_newXS_flags)(pTHX_ const char *name, XSUBADDR_t subaddr, const char *const filename, const char *const proto, U32 flags);
-+#endif
- static void (*Perl_sv_free)(pTHX_ SV*);
- static int (*Perl_sv_isa)(pTHX_ SV*, const char*);
- static void (*Perl_sv_magic)(pTHX_ SV*, SV*, int, const char*, I32);
-@@ -267,6 +297,10 @@
- #else
-     {"Perl_sv_2pv", (PERL_PROC*)&Perl_sv_2pv},
- #endif
-+#ifdef PERL589_OR_LATER
-+    {"Perl_sv_2iv_flags", (PERL_PROC*)&Perl_sv_2iv_flags},
-+    {"Perl_newXS_flags", (PERL_PROC*)&Perl_newXS_flags},
-+#endif
-     {"Perl_sv_bless", (PERL_PROC*)&Perl_sv_bless},
- #if (PERL_REVISION == 5) && (PERL_VERSION >= 8)
-     {"Perl_sv_catpvn_flags", (PERL_PROC*)&Perl_sv_catpvn_flags},
-@@ -411,13 +445,13 @@
-     char *next;
-     char *token = (char *)s;
- 
--    while ((next = strchr(token, '\n')))
-+    while ((next = strchr(token, '\n')) && !got_int)
-     {
- 	*next++ = '\0';			/* replace \n with \0 */
- 	msg_attr((char_u *)token, attr);
- 	token = next;
-     }
--    if (*token)
-+    if (*token && !got_int)
- 	msg_attr((char_u *)token, attr);
- }
- 
-diff -Naur vim71.orig/src/if_python.c vim71/src/if_python.c
---- vim71.orig/src/if_python.c	2007-03-06 17:00:53.000000000 -0500
-+++ vim71/src/if_python.c	2008-06-18 06:56:52.000000000 -0400
-@@ -38,6 +38,8 @@
- # undef HAVE_STDARG_H	/* Python's config.h defines it as well. */
- #endif
- 
-+#define PY_SSIZE_T_CLEAN
-+
- #include <Python.h>
- #if defined(MACOS) && !defined(MACOS_X_UNIX)
- # include "macglue.h"
-@@ -55,6 +57,22 @@
- # define PySequenceMethods int
- #endif
- 
-+#if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02050000
-+# define PyInt Py_ssize_t
-+# define PyInquiry lenfunc
-+# define PyIntArgFunc ssizeargfunc
-+# define PyIntIntArgFunc ssizessizeargfunc
-+# define PyIntObjArgProc ssizeobjargproc
-+# define PyIntIntObjArgProc ssizessizeobjargproc
-+#else
-+# define PyInt int
-+# define PyInquiry inquiry
-+# define PyIntArgFunc intargfunc
-+# define PyIntIntArgFunc intintargfunc
-+# define PyIntObjArgProc intobjargproc
-+# define PyIntIntObjArgProc intintobjargproc
-+#endif
-+
- /* Parser flags */
- #define single_input	256
- #define file_input	257
-@@ -150,11 +168,11 @@
- static long(*dll_PyInt_AsLong)(PyObject *);
- static PyObject*(*dll_PyInt_FromLong)(long);
- static PyTypeObject* dll_PyInt_Type;
--static PyObject*(*dll_PyList_GetItem)(PyObject *, int);
-+static PyObject*(*dll_PyList_GetItem)(PyObject *, PyInt);
- static PyObject*(*dll_PyList_Append)(PyObject *, PyObject *);
--static PyObject*(*dll_PyList_New)(int size);
--static int(*dll_PyList_SetItem)(PyObject *, int, PyObject *);
--static int(*dll_PyList_Size)(PyObject *);
-+static PyObject*(*dll_PyList_New)(PyInt size);
-+static int(*dll_PyList_SetItem)(PyObject *, PyInt, PyObject *);
-+static PyInt(*dll_PyList_Size)(PyObject *);
- static PyTypeObject* dll_PyList_Type;
- static PyObject*(*dll_PyImport_ImportModule)(const char *);
- static PyObject*(*dll_PyDict_New)(void);
-@@ -163,8 +181,8 @@
- static int(*dll_PyRun_SimpleString)(char *);
- static char*(*dll_PyString_AsString)(PyObject *);
- static PyObject*(*dll_PyString_FromString)(const char *);
--static PyObject*(*dll_PyString_FromStringAndSize)(const char *, int);
--static int(*dll_PyString_Size)(PyObject *);
-+static PyObject*(*dll_PyString_FromStringAndSize)(const char *, PyInt);
-+static PyInt(*dll_PyString_Size)(PyObject *);
- static PyTypeObject* dll_PyString_Type;
- static int(*dll_PySys_SetObject)(char *, PyObject *);
- static int(*dll_PySys_SetArgv)(int, char **);
-@@ -367,10 +385,10 @@
-  * ----------------------------------------------
-  */
- static PyObject *GetBufferLine(buf_T *, int);
--static PyObject *GetBufferLineList(buf_T *, int, int);
-+static PyObject *GetBufferLineList(buf_T *, PyInt, PyInt);
- 
- static int SetBufferLine(buf_T *, int, PyObject *, int *);
--static int SetBufferLineList(buf_T *, int, int, PyObject *, int *);
-+static int SetBufferLineList(buf_T *, PyInt, PyInt, PyObject *, int *);
- static int InsertBufferLines(buf_T *, int, PyObject *, int *);
- 
- static PyObject *LineToString(const char *);
-@@ -773,8 +791,8 @@
-     static PyObject *
- OutputWritelines(PyObject *self, PyObject *args)
- {
--    int n;
--    int i;
-+    PyInt n;
-+    PyInt i;
-     PyObject *list;
-     int error = ((OutputObject *)(self))->error;
- 
-@@ -986,11 +1004,11 @@
- static PyObject *BufferGetattr(PyObject *, char *);
- static PyObject *BufferRepr(PyObject *);
- 
--static int BufferLength(PyObject *);
--static PyObject *BufferItem(PyObject *, int);
--static PyObject *BufferSlice(PyObject *, int, int);
--static int BufferAssItem(PyObject *, int, PyObject *);
--static int BufferAssSlice(PyObject *, int, int, PyObject *);
-+static PyInt BufferLength(PyObject *);
-+static PyObject *BufferItem(PyObject *, PyInt);
-+static PyObject *BufferSlice(PyObject *, PyInt, PyInt);
-+static PyInt BufferAssItem(PyObject *, PyInt, PyObject *);
-+static PyInt BufferAssSlice(PyObject *, PyInt, PyInt, PyObject *);
- 
- static PyObject *BufferAppend(PyObject *, PyObject *);
- static PyObject *BufferMark(PyObject *, PyObject *);
-@@ -1017,11 +1035,11 @@
- static PyObject *RangeGetattr(PyObject *, char *);
- static PyObject *RangeRepr(PyObject *);
- 
--static int RangeLength(PyObject *);
--static PyObject *RangeItem(PyObject *, int);
--static PyObject *RangeSlice(PyObject *, int, int);
--static int RangeAssItem(PyObject *, int, PyObject *);
--static int RangeAssSlice(PyObject *, int, int, PyObject *);
-+static PyInt RangeLength(PyObject *);
-+static PyObject *RangeItem(PyObject *, PyInt);
-+static PyObject *RangeSlice(PyObject *, PyInt, PyInt);
-+static PyInt RangeAssItem(PyObject *, PyInt, PyObject *);
-+static PyInt RangeAssSlice(PyObject *, PyInt, PyInt, PyObject *);
- 
- static PyObject *RangeAppend(PyObject *, PyObject *);
- 
-@@ -1029,15 +1047,15 @@
-  * -------------------------------------------
-  */
- 
--static int WinListLength(PyObject *);
--static PyObject *WinListItem(PyObject *, int);
-+static PyInt WinListLength(PyObject *);
-+static PyObject *WinListItem(PyObject *, PyInt);
- 
- /* Buffer list type - Implementation functions
-  * -------------------------------------------
-  */
- 
--static int BufListLength(PyObject *);
--static PyObject *BufListItem(PyObject *, int);
-+static PyInt BufListLength(PyObject *);
-+static PyObject *BufListItem(PyObject *, PyInt);
- 
- /* Current objects type - Implementation functions
-  * -----------------------------------------------
-@@ -1130,6 +1148,16 @@
- 	result = Py_BuildValue("s", buf);
- 	PyDict_SetItemString(lookupDict, ptrBuf, result);
-     }
-+#ifdef FEAT_FLOAT
-+    else if (our_tv->v_type == VAR_FLOAT)
-+    {
-+	char buf[NUMBUFLEN];
-+
-+	sprintf(buf, "%f", our_tv->vval.v_float);
-+	result = Py_BuildValue("s", buf);
-+	PyDict_SetItemString(lookupDict, ptrBuf, result);
-+    }
-+#endif
-     else if (our_tv->v_type == VAR_LIST)
-     {
- 	list_T		*list = our_tv->vval.v_list;
-@@ -1245,7 +1273,7 @@
- }
- 
-     static PyObject *
--RBItem(BufferObject *self, int n, int start, int end)
-+RBItem(BufferObject *self, PyInt n, int start, int end)
- {
-     if (CheckBuffer(self))
- 	return NULL;
-@@ -1260,9 +1288,9 @@
- }
- 
-     static PyObject *
--RBSlice(BufferObject *self, int lo, int hi, int start, int end)
-+RBSlice(BufferObject *self, PyInt lo, PyInt hi, int start, int end)
- {
--    int size;
-+    PyInt size;
- 
-     if (CheckBuffer(self))
- 	return NULL;
-@@ -1283,8 +1311,8 @@
-     return GetBufferLineList(self->buf, lo+start, hi+start);
- }
- 
--    static int
--RBAssItem(BufferObject *self, int n, PyObject *val, int start, int end, int *new_end)
-+    static PyInt
-+RBAssItem(BufferObject *self, PyInt n, PyObject *val, int start, int end, int *new_end)
- {
-     int len_change;
- 
-@@ -1306,8 +1334,8 @@
-     return 0;
- }
- 
--    static int
--RBAssSlice(BufferObject *self, int lo, int hi, PyObject *val, int start, int end, int *new_end)
-+    static PyInt
-+RBAssSlice(BufferObject *self, PyInt lo, PyInt hi, PyObject *val, int start, int end, int *new_end)
- {
-     int size;
-     int len_change;
-@@ -1384,13 +1412,13 @@
- };
- 
- static PySequenceMethods BufferAsSeq = {
--    (inquiry)		BufferLength,	    /* sq_length,    len(x)   */
-+    (PyInquiry)		BufferLength,	    /* sq_length,    len(x)   */
-     (binaryfunc)	0, /* BufferConcat, */	     /* sq_concat,    x+y      */
--    (intargfunc)	0, /* BufferRepeat, */	     /* sq_repeat,    x*n      */
--    (intargfunc)	BufferItem,	    /* sq_item,      x[i]     */
--    (intintargfunc)	BufferSlice,	    /* sq_slice,     x[i:j]   */
--    (intobjargproc)	BufferAssItem,	    /* sq_ass_item,  x[i]=v   */
--    (intintobjargproc)	BufferAssSlice,     /* sq_ass_slice, x[i:j]=v */
-+    (PyIntArgFunc)	0, /* BufferRepeat, */	     /* sq_repeat,    x*n      */
-+    (PyIntArgFunc)	BufferItem,	    /* sq_item,      x[i]     */
-+    (PyIntIntArgFunc)	BufferSlice,	    /* sq_slice,     x[i:j]   */
-+    (PyIntObjArgProc)	BufferAssItem,	    /* sq_ass_item,  x[i]=v   */
-+    (PyIntIntObjArgProc)	BufferAssSlice,     /* sq_ass_slice, x[i:j]=v */
- };
- 
- static PyTypeObject BufferType = {
-@@ -1516,7 +1544,7 @@
- 
- /******************/
- 
--    static int
-+    static PyInt
- BufferLength(PyObject *self)
- {
-     /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
-@@ -1527,29 +1555,29 @@
- }
- 
-     static PyObject *
--BufferItem(PyObject *self, int n)
-+BufferItem(PyObject *self, PyInt n)
- {
-     return RBItem((BufferObject *)(self), n, 1,
- 		  (int)((BufferObject *)(self))->buf->b_ml.ml_line_count);
- }
- 
-     static PyObject *
--BufferSlice(PyObject *self, int lo, int hi)
-+BufferSlice(PyObject *self, PyInt lo, PyInt hi)
- {
-     return RBSlice((BufferObject *)(self), lo, hi, 1,
- 		   (int)((BufferObject *)(self))->buf->b_ml.ml_line_count);
- }
- 
--    static int
--BufferAssItem(PyObject *self, int n, PyObject *val)
-+    static PyInt
-+BufferAssItem(PyObject *self, PyInt n, PyObject *val)
- {
-     return RBAssItem((BufferObject *)(self), n, val, 1,
- 		     (int)((BufferObject *)(self))->buf->b_ml.ml_line_count,
- 		     NULL);
- }
- 
--    static int
--BufferAssSlice(PyObject *self, int lo, int hi, PyObject *val)
-+    static PyInt
-+BufferAssSlice(PyObject *self, PyInt lo, PyInt hi, PyObject *val)
- {
-     return RBAssSlice((BufferObject *)(self), lo, hi, val, 1,
- 		      (int)((BufferObject *)(self))->buf->b_ml.ml_line_count,
-@@ -1627,13 +1655,13 @@
- };
- 
- static PySequenceMethods RangeAsSeq = {
--    (inquiry)		RangeLength,	    /* sq_length,    len(x)   */
-+    (PyInquiry)		RangeLength,	    /* sq_length,    len(x)   */
-     (binaryfunc)	0, /* RangeConcat, */	     /* sq_concat,    x+y      */
--    (intargfunc)	0, /* RangeRepeat, */	     /* sq_repeat,    x*n      */
--    (intargfunc)	RangeItem,	    /* sq_item,      x[i]     */
--    (intintargfunc)	RangeSlice,	    /* sq_slice,     x[i:j]   */
--    (intobjargproc)	RangeAssItem,	    /* sq_ass_item,  x[i]=v   */
--    (intintobjargproc)	RangeAssSlice,	    /* sq_ass_slice, x[i:j]=v */
-+    (PyIntArgFunc)	0, /* RangeRepeat, */	     /* sq_repeat,    x*n      */
-+    (PyIntArgFunc)	RangeItem,	    /* sq_item,      x[i]     */
-+    (PyIntIntArgFunc)	RangeSlice,	    /* sq_slice,     x[i:j]   */
-+    (PyIntObjArgProc)	RangeAssItem,	    /* sq_ass_item,  x[i]=v   */
-+    (PyIntIntObjArgProc)	RangeAssSlice,	    /* sq_ass_slice, x[i:j]=v */
- };
- 
- static PyTypeObject RangeType = {
-@@ -1738,7 +1766,7 @@
- 
- /****************/
- 
--    static int
-+    static PyInt
- RangeLength(PyObject *self)
- {
-     /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
-@@ -1749,7 +1777,7 @@
- }
- 
-     static PyObject *
--RangeItem(PyObject *self, int n)
-+RangeItem(PyObject *self, PyInt n)
- {
-     return RBItem(((RangeObject *)(self))->buf, n,
- 		  ((RangeObject *)(self))->start,
-@@ -1757,15 +1785,15 @@
- }
- 
-     static PyObject *
--RangeSlice(PyObject *self, int lo, int hi)
-+RangeSlice(PyObject *self, PyInt lo, PyInt hi)
- {
-     return RBSlice(((RangeObject *)(self))->buf, lo, hi,
- 		   ((RangeObject *)(self))->start,
- 		   ((RangeObject *)(self))->end);
- }
- 
--    static int
--RangeAssItem(PyObject *self, int n, PyObject *val)
-+    static PyInt
-+RangeAssItem(PyObject *self, PyInt n, PyObject *val)
- {
-     return RBAssItem(((RangeObject *)(self))->buf, n, val,
- 		     ((RangeObject *)(self))->start,
-@@ -1773,8 +1801,8 @@
- 		     &((RangeObject *)(self))->end);
- }
- 
--    static int
--RangeAssSlice(PyObject *self, int lo, int hi, PyObject *val)
-+    static PyInt
-+RangeAssSlice(PyObject *self, PyInt lo, PyInt hi, PyObject *val)
- {
-     return RBAssSlice(((RangeObject *)(self))->buf, lo, hi, val,
- 		      ((RangeObject *)(self))->start,
-@@ -1801,13 +1829,13 @@
- BufListObject;
- 
- static PySequenceMethods BufListAsSeq = {
--    (inquiry)		BufListLength,	    /* sq_length,    len(x)   */
-+    (PyInquiry)		BufListLength,	    /* sq_length,    len(x)   */
-     (binaryfunc)	0,		    /* sq_concat,    x+y      */
--    (intargfunc)	0,		    /* sq_repeat,    x*n      */
--    (intargfunc)	BufListItem,	    /* sq_item,      x[i]     */
--    (intintargfunc)	0,		    /* sq_slice,     x[i:j]   */
--    (intobjargproc)	0,		    /* sq_ass_item,  x[i]=v   */
--    (intintobjargproc)	0,		    /* sq_ass_slice, x[i:j]=v */
-+    (PyIntArgFunc)	0,		    /* sq_repeat,    x*n      */
-+    (PyIntArgFunc)	BufListItem,	    /* sq_item,      x[i]     */
-+    (PyIntIntArgFunc)	0,		    /* sq_slice,     x[i:j]   */
-+    (PyIntObjArgProc)	0,		    /* sq_ass_item,  x[i]=v   */
-+    (PyIntIntObjArgProc)	0,		    /* sq_ass_slice, x[i:j]=v */
- };
- 
- static PyTypeObject BufListType = {
-@@ -1837,7 +1865,7 @@
-  */
- 
- /*ARGSUSED*/
--    static int
-+    static PyInt
- BufListLength(PyObject *self)
- {
-     buf_T	*b = firstbuf;
-@@ -1854,7 +1882,7 @@
- 
- /*ARGSUSED*/
-     static PyObject *
--BufListItem(PyObject *self, int n)
-+BufListItem(PyObject *self, PyInt n)
- {
-     buf_T *b;
- 
-@@ -2119,13 +2147,13 @@
- WinListObject;
- 
- static PySequenceMethods WinListAsSeq = {
--    (inquiry)		WinListLength,	    /* sq_length,    len(x)   */
-+    (PyInquiry)		WinListLength,	    /* sq_length,    len(x)   */
-     (binaryfunc)	0,		    /* sq_concat,    x+y      */
--    (intargfunc)	0,		    /* sq_repeat,    x*n      */
--    (intargfunc)	WinListItem,	    /* sq_item,      x[i]     */
--    (intintargfunc)	0,		    /* sq_slice,     x[i:j]   */
--    (intobjargproc)	0,		    /* sq_ass_item,  x[i]=v   */
--    (intintobjargproc)	0,		    /* sq_ass_slice, x[i:j]=v */
-+    (PyIntArgFunc)	0,		    /* sq_repeat,    x*n      */
-+    (PyIntArgFunc)	WinListItem,	    /* sq_item,      x[i]     */
-+    (PyIntIntArgFunc)	0,		    /* sq_slice,     x[i:j]   */
-+    (PyIntObjArgProc)	0,		    /* sq_ass_item,  x[i]=v   */
-+    (PyIntIntObjArgProc)	0,		    /* sq_ass_slice, x[i:j]=v */
- };
- 
- static PyTypeObject WinListType = {
-@@ -2154,7 +2182,7 @@
- /* Window list object - Implementation
-  */
- /*ARGSUSED*/
--    static int
-+    static PyInt
- WinListLength(PyObject *self)
- {
-     win_T	*w = firstwin;
-@@ -2171,7 +2199,7 @@
- 
- /*ARGSUSED*/
-     static PyObject *
--WinListItem(PyObject *self, int n)
-+WinListItem(PyObject *self, PyInt n)
- {
-     win_T *w;
- 
-@@ -2351,10 +2379,10 @@
-  * including, hi. The list is returned as a Python list of string objects.
-  */
-     static PyObject *
--GetBufferLineList(buf_T *buf, int lo, int hi)
-+GetBufferLineList(buf_T *buf, PyInt lo, PyInt hi)
- {
--    int i;
--    int n = hi - lo;
-+    PyInt i;
-+    PyInt n = hi - lo;
-     PyObject *list = PyList_New(n);
- 
-     if (list == NULL)
-@@ -2517,7 +2545,7 @@
-  * is set to the change in the buffer length.
-  */
-     static int
--SetBufferLineList(buf_T *buf, int lo, int hi, PyObject *list, int *len_change)
-+SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, int *len_change)
- {
-     /* First of all, we check the thpe of the supplied Python object.
-      * There are three cases:
-@@ -2527,8 +2555,8 @@
-      */
-     if (list == Py_None || list == NULL)
-     {
--	int	i;
--	int	n = hi - lo;
-+	PyInt	i;
-+	PyInt	n = hi - lo;
- 	buf_T	*savebuf = curbuf;
- 
- 	PyErr_Clear();
-@@ -2564,9 +2592,9 @@
-     }
-     else if (PyList_Check(list))
-     {
--	int	i;
--	int	new_len = PyList_Size(list);
--	int	old_len = hi - lo;
-+	PyInt	i;
-+	PyInt	new_len = PyList_Size(list);
-+	PyInt	old_len = hi - lo;
- 	int	extra = 0;	/* lines added to text, can be negative */
- 	char	**array;
- 	buf_T	*savebuf;
-@@ -2745,8 +2773,8 @@
-     }
-     else if (PyList_Check(lines))
-     {
--	int	i;
--	int	size = PyList_Size(lines);
-+	PyInt	i;
-+	PyInt	size = PyList_Size(lines);
- 	char	**array;
- 	buf_T	*savebuf;
- 
-@@ -2831,7 +2859,7 @@
- LineToString(const char *str)
- {
-     PyObject *result;
--    int len = strlen(str);
-+    PyInt len = strlen(str);
-     char *p;
- 
-     /* Allocate an Python string object, with uninitialised contents. We
-@@ -2871,8 +2899,8 @@
- {
-     const char *str;
-     char *save;
--    int len;
--    int i;
-+    PyInt len;
-+    PyInt i;
-     char *p;
- 
-     if (obj == NULL || !PyString_Check(obj))
-diff -Naur vim71.orig/src/if_ruby.c vim71/src/if_ruby.c
---- vim71.orig/src/if_ruby.c	2007-05-12 05:54:12.000000000 -0400
-+++ vim71/src/if_ruby.c	2008-06-18 06:52:39.000000000 -0400
-@@ -789,7 +789,7 @@
-     return get_buffer_line(curbuf, curwin->w_cursor.lnum);
- }
- 
--static VALUE set_current_line(VALUE str)
-+static VALUE set_current_line(VALUE self, VALUE str)
- {
-     return set_buffer_line(curbuf, curwin->w_cursor.lnum, str);
- }
-diff -Naur vim71.orig/src/keymap.h vim71/src/keymap.h
---- vim71.orig/src/keymap.h	2006-08-22 07:38:38.000000000 -0400
-+++ vim71/src/keymap.h	2008-06-18 06:52:31.000000000 -0400
-@@ -254,6 +254,8 @@
-     , KE_DROP		/* DnD data is available */
-     , KE_CURSORHOLD	/* CursorHold event */
-     , KE_NOP		/* doesn't do something */
-+    , KE_FOCUSGAINED	/* focus gained */
-+    , KE_FOCUSLOST	/* focus lost */
- };
- 
- /*
-@@ -445,6 +447,8 @@
- #define K_CMDWIN	TERMCAP2KEY(KS_EXTRA, KE_CMDWIN)
- 
- #define K_DROP		TERMCAP2KEY(KS_EXTRA, KE_DROP)
-+#define K_FOCUSGAINED	TERMCAP2KEY(KS_EXTRA, KE_FOCUSGAINED)
-+#define K_FOCUSLOST	TERMCAP2KEY(KS_EXTRA, KE_FOCUSLOST)
- 
- #define K_CURSORHOLD	TERMCAP2KEY(KS_EXTRA, KE_CURSORHOLD)
- 
-diff -Naur vim71.orig/src/macros.h vim71/src/macros.h
---- vim71.orig/src/macros.h	2007-05-07 15:38:22.000000000 -0400
-+++ vim71/src/macros.h	2008-06-18 06:52:12.000000000 -0400
-@@ -54,10 +54,12 @@
- 
- /*
-  * toupper() and tolower() that use the current locale.
-- * On some systems toupper()/tolower() only work on lower/uppercase characters
-+ * On some systems toupper()/tolower() only work on lower/uppercase
-+ * characters, first use islower() or isupper() then.
-  * Careful: Only call TOUPPER_LOC() and TOLOWER_LOC() with a character in the
-  * range 0 - 255.  toupper()/tolower() on some systems can't handle others.
-- * Note: for UTF-8 use utf_toupper() and utf_tolower().
-+ * Note: It is often better to use MB_TOLOWER() and MB_TOUPPER(), because many
-+ * toupper() and tolower() implementations only work for ASCII.
-  */
- #ifdef MSWIN
- #  define TOUPPER_LOC(c)	toupper_tab[(c) & 255]
-diff -Naur vim71.orig/src/main.aap vim71/src/main.aap
---- vim71.orig/src/main.aap	2007-05-07 15:46:43.000000000 -0400
-+++ vim71/src/main.aap	2008-06-18 06:54:11.000000000 -0400
-@@ -56,9 +56,17 @@
-     config {virtual} auto/config.h auto/config.aap :
-                          auto/configure.aap configure.aap
-                          config.arg config.h.in config.aap.in
-+        # Use "uname -a" to detect the architecture of the system.
-+        @ok, uname = redir_system('uname -a', 0)
-+        @if string.find(uname, "i386") >= 0:
-+        @   arch = "i386"
-+        @else:
-+        @   arch = "ppc"
-+        :print Building for $arch system
-+        config_args = `file2string("config.arg")`
-         :sys CONFIG_STATUS=auto/config.status
--                ./configure.aap `file2string("config.arg")`
--                    --with-mac-arch=ppc
-+                ./configure.aap $config_args
-+                    --with-mac-arch=$arch
-                     --cache-file=auto/config.cache
- 
-     # Configure arguments: create an empty "config.arg" file when its missing
-@@ -433,11 +441,13 @@
-         :print >> $target char_u *all_lflags = (char_u *)"$linkcmd";
-         @if _no.get("COMPILEDBY"):
-             who = $COMPILEDBY
--            where = ''
-+            where =
-         @else:
-             :syseval whoami | :eval re.sub("\n", "", stdin) | :assign who
- 
-             :syseval hostname | :eval re.sub("\n", "", stdin) | :assign where
-+        @who = string.replace(who, '"', '\\"')
-+        @where = string.replace(where, '"', '\\"')
-         :print >> $target char_u *compiled_user = (char_u *)"$who";
-         :print >> $target char_u *compiled_sys = (char_u *)"$where";
- 
-@@ -1167,7 +1177,7 @@
-         :symlink `os.getcwd()`/../runtime $RESDIR/vim/runtime
- # TODO: Create the vimtutor application.
- 
--gui_bundle {virtual}: $(RESDIR) bundle-dir bundle-executable bundle-info
-+gui_bundle {virtual}: $(RESDIR) bundle-dir bundle-executable bundle-info \
-                         bundle-resource bundle-language
- 
- bundle-dir {virtual}: $(APPDIR)/Contents $(VIMTARGET)
-@@ -1187,7 +1197,7 @@
-         :sys m4 $(M4FLAGSX) infplist.xml > $(APPDIR)/Contents/Info.plist
- 
- bundle-resource {virtual}: bundle-dir bundle-rsrc
--    :copy {force} $(RSRC_DIR)/*.icns $(RESDIR)
-+        :copy {force} $(RSRC_DIR)/*.icns $(RESDIR)
- 
- ### Classic resources
- # Resource fork (in the form of a .rsrc file) for Classic Vim (Mac OS 9)
-diff -Naur vim71.orig/src/main.c vim71/src/main.c
---- vim71.orig/src/main.c	2007-05-07 15:38:44.000000000 -0400
-+++ vim71/src/main.c	2008-06-18 06:55:10.000000000 -0400
-@@ -954,7 +954,8 @@
-     int		cmdwin;	    /* TRUE when working in the command-line window */
-     int		noexmode;   /* TRUE when return on entering Ex mode */
- {
--    oparg_T	oa;	/* operator arguments */
-+    oparg_T	oa;				/* operator arguments */
-+    int		previous_got_int = FALSE;	/* "got_int" was TRUE */
- 
- #if defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)
-     /* Setup to catch a terminating error from the X server.  Just ignore
-@@ -1015,12 +1016,32 @@
- 		need_fileinfo = FALSE;
- 	    }
- 	}
--	if (got_int && !global_busy)
-+
-+	/* Reset "got_int" now that we got back to the main loop.  Except when
-+	 * inside a ":g/pat/cmd" command, then the "got_int" needs to abort
-+	 * the ":g" command.
-+	 * For ":g/pat/vi" we reset "got_int" when used once.  When used
-+	 * a second time we go back to Ex mode and abort the ":g" command. */
-+	if (got_int)
- 	{
--	    if (!quit_more)
--		(void)vgetc();		/* flush all buffers */
--	    got_int = FALSE;
-+	    if (noexmode && global_busy && !exmode_active && previous_got_int)
-+	    {
-+		/* Typed two CTRL-C in a row: go back to ex mode as if "Q" was
-+		 * used and keep "got_int" set, so that it aborts ":g". */
-+		exmode_active = EXMODE_NORMAL;
-+		State = NORMAL;
-+	    }
-+	    else if (!global_busy || !exmode_active)
-+	    {
-+		if (!quit_more)
-+		    (void)vgetc();		/* flush all buffers */
-+		got_int = FALSE;
-+	    }
-+	    previous_got_int = TRUE;
- 	}
-+	else
-+	    previous_got_int = FALSE;
-+
- 	if (!exmode_active)
- 	    msg_scroll = FALSE;
- 	quit_more = FALSE;
-@@ -1309,6 +1330,13 @@
- #ifdef FEAT_NETBEANS_INTG
-     netbeans_end();
- #endif
-+#ifdef FEAT_CSCOPE
-+    cs_end();
-+#endif
-+#ifdef FEAT_EVAL
-+    if (garbage_collect_at_exit)
-+	garbage_collect();
-+#endif
- 
-     mch_exit(exitval);
- }
-@@ -1360,8 +1388,7 @@
- 	p = vim_getenv((char_u *)"VIMRUNTIME", &mustfree);
- 	if (p != NULL && *p != NUL)
- 	{
--	    STRCPY(NameBuff, p);
--	    STRCAT(NameBuff, "/lang");
-+	    vim_snprintf((char *)NameBuff, MAXPATHL, "%s/lang", p);
- 	    bindtextdomain(VIMPACKAGE, (char *)NameBuff);
- 	}
- 	if (mustfree)
-@@ -1730,7 +1757,8 @@
- 
- 	    case 'F':		/* "-F" start in Farsi mode: rl + fkmap set */
- #ifdef FEAT_FKMAP
--		curwin->w_p_rl = p_fkmap = TRUE;
-+		p_fkmap = TRUE;
-+		set_option_value((char_u *)"rl", 1L, NULL, 0);
- #else
- 		mch_errmsg(_(e_nofarsi));
- 		mch_exit(2);
-@@ -1747,7 +1775,8 @@
- 
- 	    case 'H':		/* "-H" start in Hebrew mode: rl + hkmap set */
- #ifdef FEAT_RIGHTLEFT
--		curwin->w_p_rl = p_hkmap = TRUE;
-+		p_hkmap = TRUE;
-+		set_option_value((char_u *)"rl", 1L, NULL, 0);
- #else
- 		mch_errmsg(_(e_nohebrew));
- 		mch_exit(2);
-@@ -3036,7 +3065,7 @@
-     main_msg(_("--remote-wait <files>  As --remote but wait for files to have been edited"));
-     main_msg(_("--remote-wait-silent <files>  Same, don't complain if there is no server"));
- # ifdef FEAT_WINDOWS
--    main_msg(_("--remote-tab <files>  As --remote but open tab page for each file"));
-+    main_msg(_("--remote-tab[-wait][-silent] <files>  As --remote but use tab page per file"));
- # endif
-     main_msg(_("--remote-send <keys>\tSend <keys> to a Vim server and exit"));
-     main_msg(_("--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"));
-@@ -3632,7 +3661,13 @@
- 	mainerr_arg_missing((char_u *)filev[-1]);
-     if (mch_dirname(cwd, MAXPATHL) != OK)
- 	return NULL;
--    if ((p = vim_strsave_escaped_ext(cwd, PATH_ESC_CHARS, '\\', TRUE)) == NULL)
-+    if ((p = vim_strsave_escaped_ext(cwd,
-+#ifdef BACKSLASH_IN_FILENAME
-+		    "",  /* rem_backslash() will tell what chars to escape */
-+#else
-+		    PATH_ESC_CHARS,
-+#endif
-+		    '\\', TRUE)) == NULL)
- 	return NULL;
-     ga_init2(&ga, 1, 100);
-     ga_concat(&ga, (char_u *)"<C-\\><C-N>:cd ");
-diff -Naur vim71.orig/src/mark.c vim71/src/mark.c
---- vim71.orig/src/mark.c	2007-05-07 15:28:01.000000000 -0400
-+++ vim71/src/mark.c	2008-06-18 06:55:40.000000000 -0400
-@@ -79,6 +79,12 @@
- 	return OK;
-     }
- 
-+    if (c == '"')
-+    {
-+	curbuf->b_last_cursor = *pos;
-+	return OK;
-+    }
-+
-     /* Allow setting '[ and '] for an autocommand that simulates reading a
-      * file. */
-     if (c == '[')
-@@ -505,9 +511,24 @@
-     {
- 	/*
- 	 * First expand "~/" in the file name to the home directory.
--	 * Try to shorten the file name.
-+	 * Don't expand the whole name, it may contain other '~' chars.
- 	 */
--	expand_env(fm->fname, NameBuff, MAXPATHL);
-+	if (fm->fname[0] == '~' && (fm->fname[1] == '/'
-+#ifdef BACKSLASH_IN_FILENAME
-+		    || fm->fname[1] == '\\'
-+#endif
-+		    ))
-+	{
-+	    int len;
-+
-+	    expand_env((char_u *)"~/", NameBuff, MAXPATHL);
-+	    len = STRLEN(NameBuff);
-+	    vim_strncpy(NameBuff + len, fm->fname + 2, MAXPATHL - len - 1);
-+	}
-+	else
-+	    vim_strncpy(NameBuff, fm->fname, MAXPATHL - 1);
-+
-+	/* Try to shorten the file name. */
- 	mch_dirname(IObuff, IOSIZE);
- 	p = shorten_fname(NameBuff, IObuff);
- 
-diff -Naur vim71.orig/src/mbyte.c vim71/src/mbyte.c
---- vim71.orig/src/mbyte.c	2007-05-07 15:47:09.000000000 -0400
-+++ vim71/src/mbyte.c	2008-06-18 06:56:57.000000000 -0400
-@@ -360,6 +360,12 @@
-     {"ucs4be",		IDX_UCS4},
-     {"ucs-4be",		IDX_UCS4},
-     {"ucs4le",		IDX_UCS4LE},
-+    {"utf32",		IDX_UCS4},
-+    {"utf-32",		IDX_UCS4},
-+    {"utf32be",		IDX_UCS4},
-+    {"utf-32be",	IDX_UCS4},
-+    {"utf32le",		IDX_UCS4LE},
-+    {"utf-32le",	IDX_UCS4LE},
-     {"932",		IDX_CP932},
-     {"949",		IDX_CP949},
-     {"936",		IDX_CP936},
-@@ -1310,20 +1316,26 @@
- /*
-  * mb_off2cells() function pointer.
-  * Return number of display cells for char at ScreenLines[off].
-- * Caller must make sure "off" and "off + 1" are valid!
-+ * We make sure that the offset used is less than "max_off".
-  */
- /*ARGSUSED*/
-     int
--latin_off2cells(off)
-+latin_off2cells(off, max_off)
-     unsigned	off;
-+    unsigned	max_off;
- {
-     return 1;
- }
- 
-     int
--dbcs_off2cells(off)
-+dbcs_off2cells(off, max_off)
-     unsigned	off;
-+    unsigned	max_off;
- {
-+    /* never check beyond end of the line */
-+    if (off >= max_off)
-+	return 1;
-+
-     /* Number of cells is equal to number of bytes, except for euc-jp when
-      * the first byte is 0x8e. */
-     if (enc_dbcs == DBCS_JPNU && ScreenLines[off] == 0x8e)
-@@ -1332,10 +1344,11 @@
- }
- 
-     int
--utf_off2cells(off)
-+utf_off2cells(off, max_off)
-     unsigned	off;
-+    unsigned	max_off;
- {
--    return ScreenLines[off + 1] == 0 ? 2 : 1;
-+    return (off + 1 < max_off && ScreenLines[off + 1] == 0) ? 2 : 1;
- }
- 
- /*
-@@ -1635,7 +1648,7 @@
-  * Get the length of UTF-8 byte sequence "p[size]".  Does not include any
-  * following composing characters.
-  * Returns 1 for "".
-- * Returns 1 for an illegal byte sequence.
-+ * Returns 1 for an illegal byte sequence (also in incomplete byte seq.).
-  * Returns number > "size" for an incomplete byte sequence.
-  */
-     int
-@@ -1645,13 +1658,14 @@
- {
-     int		len;
-     int		i;
-+    int		m;
- 
-     if (*p == NUL)
- 	return 1;
--    len = utf8len_tab[*p];
-+    m = len = utf8len_tab[*p];
-     if (len > size)
--	return len;	/* incomplete byte sequence. */
--    for (i = 1; i < len; ++i)
-+	m = size;	/* incomplete byte sequence. */
-+    for (i = 1; i < m; ++i)
- 	if ((p[i] & 0xc0) != 0x80)
- 	    return 1;
-     return len;
-@@ -1959,8 +1973,10 @@
- 	{0x205f, 0x205f, 0},
- 	{0x2060, 0x27ff, 1},		/* punctuation and symbols */
- 	{0x2070, 0x207f, 0x2070},	/* superscript */
--	{0x2080, 0x208f, 0x2080},	/* subscript */
--	{0x2983, 0x2998, 1},
-+	{0x2080, 0x2094, 0x2080},	/* subscript */
-+	{0x20a0, 0x27ff, 1},		/* all kinds of symbols */
-+	{0x2800, 0x28ff, 0x2800},	/* braille */
-+	{0x2900, 0x2998, 1},		/* arrows, brackets, etc. */
- 	{0x29d8, 0x29db, 1},
- 	{0x29fc, 0x29fd, 1},
- 	{0x3000, 0x3000, 0},		/* ideographic space */
-@@ -2320,7 +2336,7 @@
- 		/* Single byte: first check normally, then with ignore case. */
- 		if (s1[i] != s2[i])
- 		{
--		    cdiff = TOLOWER_LOC(s1[i]) - TOLOWER_LOC(s2[i]);
-+		    cdiff = MB_TOLOWER(s1[i]) - MB_TOLOWER(s2[i]);
- 		    if (cdiff != 0)
- 			return cdiff;
- 		}
-@@ -2855,15 +2871,17 @@
- 	    buf[m++] = K_SPECIAL;
- 	    n += 2;
- 	}
-+	else if ((str[n] == K_SPECIAL
- # ifdef FEAT_GUI
--	else if (str[n] == CSI
-+		    || str[n] == CSI
-+# endif
-+		 )
- 		&& str[n + 1] == KS_EXTRA
- 		&& str[n + 2] == (int)KE_CSI)
- 	{
- 	    buf[m++] = CSI;
- 	    n += 2;
- 	}
--# endif
- 	else if (str[n] == K_SPECIAL
- # ifdef FEAT_GUI
- 		|| str[n] == CSI
-@@ -2899,12 +2917,8 @@
-     if (composing_hangul)
- 	return TRUE;
- #endif
--    if (enc_dbcs != 0)
--	return dbcs_off2cells(LineOffset[row] + col) > 1;
--    if (enc_utf8)
--	return (col + 1 < Columns
--		&& ScreenLines[LineOffset[row] + col + 1] == 0);
--    return FALSE;
-+    return (*mb_off2cells)(LineOffset[row] + col,
-+					LineOffset[row] + screen_Columns) > 1;
- }
- 
- # if defined(FEAT_CLIPBOARD) || defined(FEAT_GUI) || defined(FEAT_RIGHTLEFT) \
-@@ -5506,13 +5520,13 @@
-     preedit_caret_cb.callback = (XIMProc)preedit_caret_cbproc;
-     preedit_done_cb.callback = (XIMProc)preedit_done_cbproc;
-     preedit_attr
--	= XVaCreateNestedList (0,
-+	 = XVaCreateNestedList(0,
- 			       XNPreeditStartCallback, &preedit_start_cb,
- 			       XNPreeditDrawCallback, &preedit_draw_cb,
- 			       XNPreeditCaretCallback, &preedit_caret_cb,
- 			       XNPreeditDoneCallback, &preedit_done_cb,
--			       0);
--    XSetICValues (xxic, XNPreeditAttributes, preedit_attr, 0);
-+			       NULL);
-+    XSetICValues(xxic, XNPreeditAttributes, preedit_attr, NULL);
-     XFree(preedit_attr);
- }
- 
-@@ -5522,7 +5536,8 @@
- {
- #ifdef USE_X11R6_XIM
-     /* don't change the input context when we call reset */
--    XSetICValues(((GdkICPrivate*)ic)->xic, XNResetState, XIMPreserveState, 0);
-+    XSetICValues(((GdkICPrivate *)ic)->xic, XNResetState, XIMPreserveState,
-+									NULL);
- #endif
- }
- 
-diff -Naur vim71.orig/src/memfile.c vim71/src/memfile.c
---- vim71.orig/src/memfile.c	2007-05-11 13:50:12.000000000 -0400
-+++ vim71/src/memfile.c	2008-06-18 06:56:39.000000000 -0400
-@@ -1346,5 +1346,10 @@
- 	mfp->mf_ffname = NULL;
-     }
-     else
-+    {
-+#ifdef HAVE_SELINUX
-+	mch_copy_sec(fname, mfp->mf_fname);
-+#endif
- 	mch_hide(mfp->mf_fname);    /* try setting the 'hidden' flag */
-+    }
- }
-diff -Naur vim71.orig/src/message.c vim71/src/message.c
---- vim71.orig/src/message.c	2007-05-07 15:31:59.000000000 -0400
-+++ vim71/src/message.c	2008-06-18 06:53:52.000000000 -0400
-@@ -828,7 +828,7 @@
- 		_("Messages maintainer: Bram Moolenaar <Bram@vim.org>"),
- 		hl_attr(HLF_T));
- 
--    for (p = first_msg_hist; p != NULL; p = p->next)
-+    for (p = first_msg_hist; p != NULL && !got_int; p = p->next)
- 	if (p->msg != NULL)
- 	    msg_attr(p->msg, p->attr);
- 
-@@ -944,6 +944,7 @@
- 		c = K_IGNORE;
- 	    }
- #endif
-+
- 	    /*
- 	     * Allow scrolling back in the messages.
- 	     * Also accept scroll-down commands when messages fill the screen,
-@@ -1840,9 +1841,10 @@
-     char_u	*sb_str = str;
-     int		sb_col = msg_col;
-     int		wrap;
-+    int		did_last_char;
- 
-     did_wait_return = FALSE;
--    while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen))
-+    while ((maxlen < 0 || (int)(s - str) < maxlen) && *s != NUL)
-     {
- 	/*
- 	 * We are at the end of the screen line when:
-@@ -1878,7 +1880,7 @@
- 		/* output postponed text */
- 		t_puts(&t_col, t_s, s, attr);
- 
--	    /* When no more prompt an no more room, truncate here */
-+	    /* When no more prompt and no more room, truncate here */
- 	    if (msg_no_more && lines_left == 0)
- 		break;
- 
-@@ -1909,7 +1911,10 @@
- 		else
- #endif
- 		    msg_screen_putchar(*s++, attr);
-+		did_last_char = TRUE;
- 	    }
-+	    else
-+		did_last_char = FALSE;
- 
- 	    if (p_more)
- 		/* store text for scrolling back */
-@@ -1927,7 +1932,8 @@
- 	     * If screen is completely filled and 'more' is set then wait
- 	     * for a character.
- 	     */
--	    --lines_left;
-+	    if (lines_left > 0)
-+		--lines_left;
- 	    if (p_more && lines_left == 0 && State != HITRETURN
- 					    && !msg_no_more && !exmode_active)
- 	    {
-@@ -1943,11 +1949,7 @@
- 
- 	    /* When we displayed a char in last column need to check if there
- 	     * is still more. */
--	    if (*s >= ' '
--#ifdef FEAT_RIGHTLEFT
--		    && !cmdmsg_rl
--#endif
--	       )
-+	    if (did_last_char)
- 		continue;
- 	}
- 
-@@ -2234,7 +2236,7 @@
- {
-     msgchunk_T	*mp;
- 
--    /* Only show somethign if there is more than one line, otherwise it looks
-+    /* Only show something if there is more than one line, otherwise it looks
-      * weird, typing a command without output results in one line. */
-     mp = msg_sb_start(last_msgchunk);
-     if (mp == NULL || mp->sb_prev == NULL)
-@@ -2622,7 +2624,7 @@
- 		}
- 	    }
- 
--	    if (scroll < 0 || (scroll == 0 && mp_last != NULL))
-+	    if (scroll <= 0)
- 	    {
- 		/* displayed the requested text, more prompt again */
- 		screen_fill((int)Rows - 1, (int)Rows, 0,
-@@ -2848,6 +2850,15 @@
-     }
-     else if (State == HITRETURN || State == SETWSIZE)
-     {
-+	if (msg_row == Rows - 1)
-+	{
-+	    /* Avoid drawing the "hit-enter" prompt below the previous one,
-+	     * overwrite it.  Esp. useful when regaining focus and a
-+	     * FocusGained autocmd exists but didn't draw anything. */
-+	    msg_didout = FALSE;
-+	    msg_col = 0;
-+	    msg_clr_eos();
-+	}
- 	hit_return_msg();
- 	msg_row = Rows - 1;
-     }
-@@ -3456,11 +3467,11 @@
- 		    /* advance to next hotkey and set default hotkey */
- #ifdef FEAT_MBYTE
- 		    if (has_mbyte)
--			hotkp += (*mb_ptr2len)(hotkp);
-+			hotkp += STRLEN(hotkp);
- 		    else
- #endif
- 			++hotkp;
--		    (void)copy_char(r + 1, hotkp, TRUE);
-+		    hotkp[copy_char(r + 1, hotkp, TRUE)] = NUL;
- 		    if (dfltbutton)
- 			--dfltbutton;
- 
-@@ -3493,7 +3504,7 @@
- 			*msgp++ = (dfltbutton == 1) ? ']' : ')';
- 
- 			/* redefine hotkey */
--			(void)copy_char(r, hotkp, TRUE);
-+			hotkp[copy_char(r, hotkp, TRUE)] = NUL;
- 		    }
- 		}
- 		else
-@@ -3519,8 +3530,6 @@
- 	    *msgp++ = ':';
- 	    *msgp++ = ' ';
- 	    *msgp = NUL;
--	    mb_ptr_adv(hotkp);
--	    *hotkp = NUL;
- 	}
- 	else
- 	{
-@@ -3555,8 +3564,9 @@
- 	    msgp = confirm_msg + 1 + STRLEN(message);
- 	    hotkp = hotk;
- 
--	    /* define first default hotkey */
--	    (void)copy_char(buttons, hotkp, TRUE);
-+	    /* Define first default hotkey.  Keep the hotkey string NUL
-+	     * terminated to avoid reading past the end. */
-+	    hotkp[copy_char(buttons, hotkp, TRUE)] = NUL;
- 
- 	    /* Remember where the choices start, displaying starts here when
- 	     * "hotkp" typed at the more prompt. */
-diff -Naur vim71.orig/src/misc1.c vim71/src/misc1.c
---- vim71.orig/src/misc1.c	2007-05-07 15:49:03.000000000 -0400
-+++ vim71/src/misc1.c	2008-06-18 06:55:59.000000000 -0400
-@@ -90,7 +90,7 @@
-  */
-     int
- set_indent(size, flags)
--    int		size;
-+    int		size;		    /* measured in spaces */
-     int		flags;
- {
-     char_u	*p;
-@@ -98,12 +98,14 @@
-     char_u	*oldline;
-     char_u	*s;
-     int		todo;
--    int		ind_len;
-+    int		ind_len;	    /* measured in characters */
-     int		line_len;
-     int		doit = FALSE;
--    int		ind_done;
-+    int		ind_done = 0;	    /* measured in spaces */
-     int		tab_pad;
-     int		retval = FALSE;
-+    int		orig_char_len = -1; /* number of initial whitespace chars when
-+				       'et' and 'pi' are both set */
- 
-     /*
-      * First check if there is anything to do and compute the number of
-@@ -116,8 +118,10 @@
-     /* Calculate the buffer size for the new indent, and check to see if it
-      * isn't already set */
- 
--    /* if 'expandtab' isn't set: use TABs */
--    if (!curbuf->b_p_et)
-+    /* if 'expandtab' isn't set: use TABs; if both 'expandtab' and
-+     * 'preserveindent' are set count the number of characters at the
-+     * beginning of the line to be copied */
-+    if (!curbuf->b_p_et || (!(flags & SIN_INSERT) && curbuf->b_p_pi))
-     {
- 	/* If 'preserveindent' is set then reuse as much as possible of
- 	 * the existing indent structure for the new indent */
-@@ -148,9 +152,14 @@
- 		++p;
- 	    }
- 
-+	    /* Set initial number of whitespace chars to copy if we are
-+	     * preserving indent but expandtab is set */
-+	    if (curbuf->b_p_et)
-+		orig_char_len = ind_len;
-+
- 	    /* Fill to next tabstop with a tab, if possible */
- 	    tab_pad = (int)curbuf->b_p_ts - (ind_done % (int)curbuf->b_p_ts);
--	    if (todo >= tab_pad)
-+	    if (todo >= tab_pad && orig_char_len == -1)
- 	    {
- 		doit = TRUE;
- 		todo -= tab_pad;
-@@ -193,13 +202,43 @@
-     else
- 	p = skipwhite(p);
-     line_len = (int)STRLEN(p) + 1;
--    newline = alloc(ind_len + line_len);
--    if (newline == NULL)
--	return FALSE;
-+
-+    /* If 'preserveindent' and 'expandtab' are both set keep the original
-+     * characters and allocate accordingly.  We will fill the rest with spaces
-+     * after the if (!curbuf->b_p_et) below. */
-+    if (orig_char_len != -1)
-+    {
-+	newline = alloc(orig_char_len + size - ind_done + line_len);
-+	if (newline == NULL)
-+	    return FALSE;
-+	todo = size - ind_done;
-+	ind_len = orig_char_len + todo;    /* Set total length of indent in
-+					    * characters, which may have been
-+					    * undercounted until now  */
-+	p = oldline;
-+	s = newline;
-+	while (orig_char_len > 0)
-+	{
-+	    *s++ = *p++;
-+	    orig_char_len--;
-+	}
-+
-+	/* Skip over any additional white space (useful when newindent is less
-+	 * than old) */
-+	while (vim_iswhite(*p))
-+	    ++p;
-+
-+    }
-+    else
-+    {
-+	todo = size;
-+	newline = alloc(ind_len + line_len);
-+	if (newline == NULL)
-+	    return FALSE;
-+	s = newline;
-+    }
- 
-     /* Put the characters in the new line. */
--    s = newline;
--    todo = size;
-     /* if 'expandtab' isn't set: use TABs */
-     if (!curbuf->b_p_et)
-     {
-@@ -398,7 +437,8 @@
-     {
- 	regmatch.rmm_ic = FALSE;
- 	regmatch.rmm_maxcol = 0;
--	if (vim_regexec_multi(&regmatch, curwin, curbuf, lnum, (colnr_T)0))
-+	if (vim_regexec_multi(&regmatch, curwin, curbuf, lnum,
-+							    (colnr_T)0, NULL))
- 	{
- 	    pos.lnum = regmatch.endpos[0].lnum + lnum;
- 	    pos.col = regmatch.endpos[0].col;
-@@ -553,7 +593,14 @@
- 	replace_push(NUL);
- 	p = saved_line + curwin->w_cursor.col;
- 	while (*p != NUL)
--	    replace_push(*p++);
-+	{
-+#ifdef FEAT_MBYTE
-+	    if (has_mbyte)
-+		p += replace_push_mb(p);
-+	    else
-+#endif
-+		replace_push(*p++);
-+	}
- 	saved_line[curwin->w_cursor.col] = NUL;
-     }
- #endif
-@@ -1320,8 +1367,8 @@
- 	    newindent += (int)curbuf->b_p_sw;
- 	}
- #endif
--	/* Copy the indent only if expand tab is disabled */
--	if (curbuf->b_p_ci && !curbuf->b_p_et)
-+	/* Copy the indent */
-+	if (curbuf->b_p_ci)
- 	{
- 	    (void)copy_indent(newindent, saved_line);
- 
-@@ -1876,7 +1923,6 @@
-     int		charlen;
- {
-     int		c = buf[0];
--    int		l, j;
- #endif
-     int		newlen;		/* nr of bytes inserted */
-     int		oldlen;		/* nr of bytes deleted (0 when not replacing) */
-@@ -1978,13 +2024,11 @@
- 	for (i = 0; i < oldlen; ++i)
- 	{
- #ifdef FEAT_MBYTE
--	    l = (*mb_ptr2len)(oldp + col + i) - 1;
--	    for (j = l; j >= 0; --j)
--		replace_push(oldp[col + i + j]);
--	    i += l;
--#else
--	    replace_push(oldp[col + i]);
-+	    if (has_mbyte)
-+		i += replace_push_mb(oldp + col + i) - 1;
-+	    else
- #endif
-+		replace_push(oldp[col + i]);
- 	}
-     }
- 
-@@ -2226,13 +2270,16 @@
-     /*
-      * If the old line has been allocated the deletion can be done in the
-      * existing line. Otherwise a new line has to be allocated
-+     * Can't do this when using Netbeans, because we would need to invoke
-+     * netbeans_removed(), which deallocates the line.  Let ml_replace() take
-+     * care of notifiying Netbeans.
-      */
--    was_alloced = ml_line_alloced();	    /* check if oldp was allocated */
- #ifdef FEAT_NETBEANS_INTG
--    if (was_alloced && usingNetbeans)
--	netbeans_removed(curbuf, lnum, col, count);
--    /* else is handled by ml_replace() */
-+    if (usingNetbeans)
-+	was_alloced = FALSE;
-+    else
- #endif
-+	was_alloced = ml_line_alloced();    /* check if oldp was allocated */
-     if (was_alloced)
- 	newp = oldp;			    /* use same allocated memory */
-     else
-@@ -2982,7 +3029,7 @@
- 	if (direct)
- 	    r = get_keystroke();
- 	else
--	    r = safe_vgetc();
-+	    r = plain_vgetc();
- 	if (r == Ctrl_C || r == ESC)
- 	    r = 'n';
- 	msg_putchar(r);	    /* show what you typed */
-@@ -3468,9 +3515,38 @@
- #endif
- 
- /*
-+ * Call expand_env() and store the result in an allocated string.
-+ * This is not very memory efficient, this expects the result to be freed
-+ * again soon.
-+ */
-+    char_u *
-+expand_env_save(src)
-+    char_u	*src;
-+{
-+    return expand_env_save_opt(src, FALSE);
-+}
-+
-+/*
-+ * Idem, but when "one" is TRUE handle the string as one file name, only
-+ * expand "~" at the start.
-+ */
-+    char_u *
-+expand_env_save_opt(src, one)
-+    char_u	*src;
-+    int		one;
-+{
-+    char_u	*p;
-+
-+    p = alloc(MAXPATHL);
-+    if (p != NULL)
-+	expand_env_esc(src, p, MAXPATHL, FALSE, one, NULL);
-+    return p;
-+}
-+
-+/*
-  * Expand environment variable with path name.
-  * "~/" is also expanded, using $HOME.	For Unix "~user/" is expanded.
-- * Skips over "\ ", "\~" and "\$".
-+ * Skips over "\ ", "\~" and "\$" (not for Win32 though).
-  * If anything fails no expansion is done and dst equals src.
-  */
-     void
-@@ -3479,15 +3555,16 @@
-     char_u	*dst;		/* where to put the result */
-     int		dstlen;		/* maximum length of the result */
- {
--    expand_env_esc(src, dst, dstlen, FALSE, NULL);
-+    expand_env_esc(src, dst, dstlen, FALSE, FALSE, NULL);
- }
- 
-     void
--expand_env_esc(srcp, dst, dstlen, esc, startstr)
-+expand_env_esc(srcp, dst, dstlen, esc, one, startstr)
-     char_u	*srcp;		/* input string e.g. "$HOME/vim.hlp" */
-     char_u	*dst;		/* where to put the result */
-     int		dstlen;		/* maximum length of the result */
-     int		esc;		/* escape spaces in expanded variables */
-+    int		one;		/* "srcp" is one file name */
-     char_u	*startstr;	/* start again after this (can be NULL) */
- {
-     char_u	*src;
-@@ -3728,6 +3805,8 @@
- 	{
- 	    /*
- 	     * Recognize the start of a new name, for '~'.
-+	     * Don't do this when "one" is TRUE, to avoid expanding "~" in
-+	     * ":edit foo ~ foo".
- 	     */
- 	    at_start = FALSE;
- 	    if (src[0] == '\\' && src[1] != NUL)
-@@ -3735,7 +3814,7 @@
- 		*dst++ = *src++;
- 		--dstlen;
- 	    }
--	    else if (src[0] == ' ' || src[0] == ',')
-+	    else if ((src[0] == ' ' || src[0] == ',') && !one)
- 		at_start = TRUE;
- 	    *dst++ = *src++;
- 	    --dstlen;
-@@ -3902,7 +3981,7 @@
- 	    /* remove trailing path separator */
- #ifndef MACOS_CLASSIC
- 	    /* With MacOS path (with  colons) the final colon is required */
--	    /* to avoid confusion between absoulute and relative path */
-+	    /* to avoid confusion between absolute and relative path */
- 	    if (pend > p && after_pathsep(p, pend))
- 		--pend;
- #endif
-@@ -4032,23 +4111,6 @@
- }
- 
- /*
-- * Call expand_env() and store the result in an allocated string.
-- * This is not very memory efficient, this expects the result to be freed
-- * again soon.
-- */
--    char_u *
--expand_env_save(src)
--    char_u	*src;
--{
--    char_u	*p;
--
--    p = alloc(MAXPATHL);
--    if (p != NULL)
--	expand_env(src, p, MAXPATHL);
--    return p;
--}
--
--/*
-  * Our portable version of setenv.
-  */
-     void
-@@ -4786,7 +4848,7 @@
- static int	cin_iswhileofdo __ARGS((char_u *, linenr_T, int));
- static int	cin_iswhileofdo_end __ARGS((int terminated, int	ind_maxparen, int ind_maxcomment));
- static int	cin_isbreak __ARGS((char_u *));
--static int	cin_is_cpp_baseclass __ARGS((char_u *line, colnr_T *col));
-+static int	cin_is_cpp_baseclass __ARGS((colnr_T *col));
- static int	get_baseclass_amount __ARGS((int col, int ind_maxparen, int ind_maxcomment, int ind_cpp_baseclass));
- static int	cin_ends_in __ARGS((char_u *, char_u *, char_u *));
- static int	cin_skip2pos __ARGS((pos_T *trypos));
-@@ -5551,13 +5613,13 @@
-  * This is a lot of guessing.  Watch out for "cond ? func() : foo".
-  */
-     static int
--cin_is_cpp_baseclass(line, col)
--    char_u	*line;
-+cin_is_cpp_baseclass(col)
-     colnr_T	*col;	    /* return: column to align with */
- {
-     char_u	*s;
-     int		class_or_struct, lookfor_ctor_init, cpp_base_class;
-     linenr_T	lnum = curwin->w_cursor.lnum;
-+    char_u	*line = ml_get_curline();
- 
-     *col = 0;
- 
-@@ -5585,7 +5647,8 @@
-      */
-     while (lnum > 1)
-     {
--	s = skipwhite(ml_get(lnum - 1));
-+	line = ml_get(lnum - 1);
-+	s = skipwhite(line);
- 	if (*s == '#' || *s == NUL)
- 	    break;
- 	while (*s != NUL)
-@@ -5602,7 +5665,8 @@
- 	--lnum;
-     }
- 
--    s = cin_skipcomment(ml_get(lnum));
-+    line = ml_get(lnum);
-+    s = cin_skipcomment(line);
-     for (;;)
-     {
- 	if (*s == NUL)
-@@ -5610,7 +5674,10 @@
- 	    if (lnum == curwin->w_cursor.lnum)
- 		break;
- 	    /* Continue in the cursor line. */
--	    s = cin_skipcomment(ml_get(++lnum));
-+	    line = ml_get(++lnum);
-+	    s = cin_skipcomment(line);
-+	    if (*s == NUL)
-+		continue;
- 	}
- 
- 	if (s[0] == ':')
-@@ -5625,7 +5692,7 @@
- 	    else if (lookfor_ctor_init || class_or_struct)
- 	    {
- 		/* we have something found, that looks like the start of
--		 * cpp-base-class-declaration or contructor-initialization */
-+		 * cpp-base-class-declaration or constructor-initialization */
- 		cpp_base_class = TRUE;
- 		lookfor_ctor_init = class_or_struct = FALSE;
- 		*col = 0;
-@@ -6082,7 +6149,7 @@
-     pos_T	our_paren_pos;
-     char_u	*start;
-     int		start_brace;
--#define BRACE_IN_COL0		1	    /* '{' is in comumn 0 */
-+#define BRACE_IN_COL0		1	    /* '{' is in column 0 */
- #define BRACE_AT_START		2	    /* '{' is at start of line */
- #define BRACE_AT_END		3	    /* '{' is at end of line */
-     linenr_T	ourscope;
-@@ -6305,7 +6372,7 @@
- 		    if (curwin->w_cursor.lnum > 1)
- 		    {
- 			/* If the start comment string matches in the previous
--			 * line, use the indent of that line pluss offset.  If
-+			 * line, use the indent of that line plus offset.  If
- 			 * the middle comment string matches in the previous
- 			 * line, use the indent of that line.  XXX */
- 			look = skipwhite(ml_get(curwin->w_cursor.lnum - 1));
-@@ -6827,6 +6894,7 @@
- 			if (trypos != NULL)
- 			{
- 			    curwin->w_cursor.lnum = trypos->lnum + 1;
-+			    curwin->w_cursor.col = 0;
- 			    continue;
- 			}
- 
-@@ -6887,6 +6955,7 @@
- 			    if (trypos != NULL)
- 			    {
- 				curwin->w_cursor.lnum = trypos->lnum + 1;
-+				curwin->w_cursor.col = 0;
- 				continue;
- 			    }
- 			}
-@@ -6924,6 +6993,7 @@
- 		if ((trypos = find_start_comment(ind_maxcomment)) != NULL)
- 		{
- 		    curwin->w_cursor.lnum = trypos->lnum + 1;
-+		    curwin->w_cursor.col = 0;
- 		    continue;
- 		}
- 
-@@ -7047,7 +7117,10 @@
- 		{
- 		    if (find_last_paren(l, '{', '}') && (trypos =
- 				    find_start_brace(ind_maxcomment)) != NULL)
-+		    {
- 			curwin->w_cursor.lnum = trypos->lnum + 1;
-+			curwin->w_cursor.col = 0;
-+		    }
- 		    continue;
- 		}
- 
-@@ -7079,7 +7152,7 @@
- 		n = FALSE;
- 		if (lookfor != LOOKFOR_TERM && ind_cpp_baseclass > 0)
- 		{
--		    n = cin_is_cpp_baseclass(l, &col);
-+		    n = cin_is_cpp_baseclass(&col);
- 		    l = ml_get_curline();
- 		}
- 		if (n)
-@@ -7163,11 +7236,12 @@
- 			 *     case xx:  if ( asdf &&
- 			 *			asdf)
- 			 */
--			curwin->w_cursor.lnum = trypos->lnum;
-+			curwin->w_cursor = *trypos;
- 			l = ml_get_curline();
- 			if (cin_iscase(l) || cin_isscopedecl(l))
- 			{
- 			    ++curwin->w_cursor.lnum;
-+			    curwin->w_cursor.col = 0;
- 			    continue;
- 			}
- 		    }
-@@ -7187,6 +7261,7 @@
- 			    if (*l == NUL || l[STRLEN(l) - 1] != '\\')
- 				break;
- 			    --curwin->w_cursor.lnum;
-+			    curwin->w_cursor.col = 0;
- 			}
- 		    }
- 
-@@ -7520,11 +7595,12 @@
- 			     *	   case xx:  if ( asdf &&
- 			     *			    asdf)
- 			     */
--			    curwin->w_cursor.lnum = trypos->lnum;
-+			    curwin->w_cursor = *trypos;
- 			    l = ml_get_curline();
- 			    if (cin_iscase(l) || cin_isscopedecl(l))
- 			    {
- 				++curwin->w_cursor.lnum;
-+				curwin->w_cursor.col = 0;
- 				continue;
- 			    }
- 			}
-@@ -7585,13 +7661,14 @@
- 				&& (trypos = find_start_brace(ind_maxcomment))
- 							    != NULL) /* XXX */
- 			{
--			    curwin->w_cursor.lnum = trypos->lnum;
-+			    curwin->w_cursor = *trypos;
- 			    /* if not "else {" check for terminated again */
- 			    /* but skip block for "} else {" */
- 			    l = cin_skipcomment(ml_get_curline());
- 			    if (*l == '}' || !cin_iselse(l))
- 				goto term_again;
- 			    ++curwin->w_cursor.lnum;
-+			    curwin->w_cursor.col = 0;
- 			}
- 		    }
- 		}
-@@ -7660,6 +7737,7 @@
- 		if ((trypos = find_start_comment(ind_maxcomment)) != NULL)
- 		{
- 		    curwin->w_cursor.lnum = trypos->lnum + 1;
-+		    curwin->w_cursor.col = 0;
- 		    continue;
- 		}
- 
-@@ -7670,7 +7748,7 @@
- 		n = FALSE;
- 		if (ind_cpp_baseclass != 0 && theline[0] != '{')
- 		{
--		    n = cin_is_cpp_baseclass(l, &col);
-+		    n = cin_is_cpp_baseclass(&col);
- 		    l = ml_get_curline();
- 		}
- 		if (n)
-@@ -7710,7 +7788,7 @@
- 		    if (find_last_paren(l, '(', ')')
- 			    && (trypos = find_match_paren(ind_maxparen,
- 						     ind_maxcomment)) != NULL)
--			curwin->w_cursor.lnum = trypos->lnum;
-+			curwin->w_cursor = *trypos;
- 
- 		    /* For a line ending in ',' that is a continuation line go
- 		     * back to the first line with a backslash:
-@@ -7724,6 +7802,7 @@
- 			if (*l == NUL || l[STRLEN(l) - 1] != '\\')
- 			    break;
- 			--curwin->w_cursor.lnum;
-+			curwin->w_cursor.col = 0;
- 		    }
- 
- 		    amount = get_indent();	    /* XXX */
-@@ -7797,7 +7876,7 @@
- 
- 		if ((trypos = find_match_paren(ind_maxparen,
- 						     ind_maxcomment)) != NULL)
--		    curwin->w_cursor.lnum = trypos->lnum;
-+		    curwin->w_cursor = *trypos;
- 		amount = get_indent();	    /* XXX */
- 		break;
- 	    }
-@@ -8158,7 +8237,7 @@
- 
- 		    if (*that && *that != ';') /* not a comment line */
- 		    {
--			/* test *that != '(' to accomodate first let/do
-+			/* test *that != '(' to accommodate first let/do
- 			 * argument if it is more than one line */
- 			if (!vi_lisp && *that != '(' && *that != '[')
- 			    firsttry++;
-@@ -8596,7 +8675,7 @@
-     for (p = buf + wildoff; p < s; ++p)
- 	if (rem_backslash(p))
- 	{
--	    STRCPY(p, p + 1);
-+	    mch_memmove(p, p + 1, STRLEN(p));
- 	    --e;
- 	    --s;
- 	}
-@@ -8897,7 +8976,7 @@
-     for (p = buf + wildoff; p < s; ++p)
- 	if (rem_backslash(p))
- 	{
--	    STRCPY(p, p + 1);
-+	    mch_memmove(p, p + 1, STRLEN(p));
- 	    --e;
- 	    --s;
- 	}
-@@ -9096,7 +9175,7 @@
- 	     */
- 	    if (vim_strpbrk(p, (char_u *)"$~") != NULL)
- 	    {
--		p = expand_env_save(p);
-+		p = expand_env_save_opt(p, TRUE);
- 		if (p == NULL)
- 		    p = pat[i];
- #ifdef UNIX
-diff -Naur vim71.orig/src/misc2.c vim71/src/misc2.c
---- vim71.orig/src/misc2.c	2007-05-07 15:49:26.000000000 -0400
-+++ vim71/src/misc2.c	2008-06-18 06:56:31.000000000 -0400
-@@ -507,12 +507,17 @@
- 	curwin->w_cursor.col = 0;
-     else if (curwin->w_cursor.col >= len)
-     {
--	/* Allow cursor past end-of-line in Insert mode, restarting Insert
--	 * mode or when in Visual mode and 'selection' isn't "old" */
-+	/* Allow cursor past end-of-line when:
-+	 * - in Insert mode or restarting Insert mode
-+	 * - in Visual mode and 'selection' isn't "old"
-+	 * - 'virtualedit' is set */
- 	if ((State & INSERT) || restart_edit
- #ifdef FEAT_VISUAL
- 		|| (VIsual_active && *p_sel != 'o')
- #endif
-+#ifdef FEAT_VIRTUALEDIT
-+		|| (ve_flags & VE_ONEMORE)
-+#endif
- 		|| virtual_active())
- 	    curwin->w_cursor.col = len;
- 	else
-@@ -746,7 +751,7 @@
- #endif
- 
- /*
-- * Note: if unsinged is 16 bits we can only allocate up to 64K with alloc().
-+ * Note: if unsigned is 16 bits we can only allocate up to 64K with alloc().
-  * Use lalloc for larger blocks.
-  */
-     char_u *
-@@ -964,7 +969,6 @@
- {
-     buf_T	*buf, *nextbuf;
-     static int	entered = FALSE;
--    win_T	*win;
- 
-     /* When we cause a crash here it is caught and Vim tries to exit cleanly.
-      * Don't try freeing everything again. */
-@@ -972,15 +976,17 @@
- 	return;
-     entered = TRUE;
- 
--    ++autocmd_block;	    /* don't want to trigger autocommands here */
-+# ifdef FEAT_AUTOCMD
-+    block_autocmds();	    /* don't want to trigger autocommands here */
-+# endif
- 
--#ifdef FEAT_WINDOWS
-+# ifdef FEAT_WINDOWS
-     /* close all tabs and windows */
-     if (first_tabpage->tp_next != NULL)
- 	do_cmdline_cmd((char_u *)"tabonly!");
-     if (firstwin != lastwin)
- 	do_cmdline_cmd((char_u *)"only!");
--#endif
-+# endif
- 
- # if defined(FEAT_SPELL)
-     /* Free all spell info. */
-@@ -1031,27 +1037,41 @@
-     free_regexp_stuff();
-     free_tag_stuff();
-     free_cd_dir();
-+# ifdef FEAT_EVAL
-     set_expr_line(NULL);
-+# endif
-+# ifdef FEAT_DIFF
-     diff_clear(curtab);
-+# endif
-     clear_sb_text();	      /* free any scrollback text */
- 
-     /* Free some global vars. */
-     vim_free(username);
-+# ifdef FEAT_CLIPBOARD
-     vim_free(clip_exclude_prog);
-+# endif
-     vim_free(last_cmdline);
-+# ifdef FEAT_CMDHIST
-     vim_free(new_last_cmdline);
-+# endif
-     set_keep_msg(NULL, 0);
-     vim_free(ff_expand_buffer);
- 
-     /* Clear cmdline history. */
-     p_hi = 0;
-+# ifdef FEAT_CMDHIST
-     init_history();
-+# endif
- 
- #ifdef FEAT_QUICKFIX
--    qf_free_all(NULL);
--    /* Free all location lists */
--    FOR_ALL_WINDOWS(win)
--	qf_free_all(win);
-+    {
-+	win_T	*win;
-+
-+	qf_free_all(NULL);
-+	/* Free all location lists */
-+	FOR_ALL_WINDOWS(win)
-+	    qf_free_all(win);
-+    }
- #endif
- 
-     /* Close all script inputs. */
-@@ -1062,7 +1082,11 @@
-     win_free_all();
- #endif
- 
--    /* Free all buffers. */
-+    /* Free all buffers.  Reset 'autochdir' to avoid accessing things that
-+     * were freed already. */
-+#ifdef FEAT_AUTOCHDIR
-+    p_acd = FALSE;
-+#endif
-     for (buf = firstbuf; buf != NULL; )
-     {
- 	nextbuf = buf->b_next;
-@@ -3757,9 +3781,9 @@
-     char_u		ffs_filearray_cur;   /* needed for partly handled dirs */
- 
-     /* to store status of partly handled directories
--     * 0: we work the on this directory for the first time
-+     * 0: we work on this directory for the first time
-      * 1: this directory was partly searched in an earlier step
--    */
-+     */
-     int			ffs_stage;
- 
-     /* How deep are we in the directory tree?
-@@ -3828,6 +3852,7 @@
-  * Set the default maximum depth.
-  */
- #define FF_MAX_STAR_STAR_EXPAND ((char_u)30)
-+
- /*
-  * The search context:
-  *   ffsc_stack_ptr:	the stack for the dirs to search
-@@ -3842,7 +3867,7 @@
-  *   ffsc_wc_path:	the part of the given path containing wildcards
-  *   ffsc_level:	how many levels of dirs to search downwards
-  *   ffsc_stopdirs_v:	array of stop directories for upward search
-- *   ffsc_need_dir:	TRUE if we search for a directory
-+ *   ffsc_find_what:	FINDFILE_BOTH, FINDFILE_DIR or FINDFILE_FILE
-  */
- typedef struct ff_search_ctx_T
- {
-@@ -3859,11 +3884,9 @@
-      int			ffsc_level;
-      char_u			**ffsc_stopdirs_v;
- #endif
--     int			ffsc_need_dir;
-+     int			ffsc_find_what;
- } ff_search_ctx_T;
- 
--static ff_search_ctx_T *ff_search_ctx = NULL;
--
- /* locally needed functions */
- #ifdef FEAT_PATH_EXTRA
- static int ff_check_visited __ARGS((ff_visited_T **, char_u *, char_u *));
-@@ -3877,10 +3900,10 @@
- static int ff_wc_equal __ARGS((char_u *s1, char_u *s2));
- #endif
- 
--static void ff_push __ARGS((ff_stack_T *));
--static ff_stack_T * ff_pop __ARGS((void));
--static void ff_clear __ARGS((void));
--static void ff_free_stack_element __ARGS((ff_stack_T *));
-+static void ff_push __ARGS((ff_search_ctx_T *search_ctx, ff_stack_T *stack_ptr));
-+static ff_stack_T *ff_pop __ARGS((ff_search_ctx_T *search_ctx));
-+static void ff_clear __ARGS((ff_search_ctx_T *search_ctx));
-+static void ff_free_stack_element __ARGS((ff_stack_T *stack_ptr));
- #ifdef FEAT_PATH_EXTRA
- static ff_stack_T *ff_create_stack_element __ARGS((char_u *, char_u *, int, int));
- #else
-@@ -3941,6 +3964,9 @@
-  * not related to restricts given to the '**' wildcard. If 'level' is 100
-  * and you use '**200' vim_findfile() will stop after 100 levels.
-  *
-+ * 'filename' cannot contain wildcards!  It is used as-is, no backslashes to
-+ * escape special characters.
-+ *
-  * If 'stopdirs' is not NULL and nothing is found downward, the search is
-  * restarted on the next higher directory level. This is repeated until the
-  * start-directory of a search is contained in 'stopdirs'. 'stopdirs' has the
-@@ -3960,74 +3986,74 @@
-  * The list of visited files/dirs can also be cleared with the function
-  * vim_findfile_free_visited().
-  *
-- * Set the parameter 'need_dir' to TRUE if you want to search for a directory
-- * instead of a file.
-+ * Set the parameter 'find_what' to FINDFILE_DIR if you want to search for
-+ * directories only, FINDFILE_FILE for files only, FINDFILE_BOTH for both.
-  *
-  * A search context returned by a previous call to vim_findfile_init() can be
-- * passed in the parameter 'search_ctx'. This context is than reused and
-- * reinitialized with the new parameters. The list of already viseted
-+ * passed in the parameter "search_ctx_arg".  This context is reused and
-+ * reinitialized with the new parameters.  The list of already visited
-  * directories from this context is only deleted if the parameter
-- * 'free_visited' is true. Be aware that the passed search_context is freed if
-- * the reinitialization fails.
-+ * "free_visited" is true.  Be aware that the passed "search_ctx_arg" is freed
-+ * if the reinitialization fails.
-  *
-- * If you don't have a search context from a previous call 'search_ctx' must be
-- * NULL.
-+ * If you don't have a search context from a previous call "search_ctx_arg"
-+ * must be NULL.
-  *
-  * This function silently ignores a few errors, vim_findfile() will have
-  * limited functionality then.
-  */
- /*ARGSUSED*/
-     void *
--vim_findfile_init(path, filename, stopdirs, level, free_visited, need_dir,
--						search_ctx, tagfile, rel_fname)
-+vim_findfile_init(path, filename, stopdirs, level, free_visited, find_what,
-+					   search_ctx_arg, tagfile, rel_fname)
-     char_u	*path;
-     char_u	*filename;
-     char_u	*stopdirs;
-     int		level;
-     int		free_visited;
--    int		need_dir;
--    void	*search_ctx;
-+    int		find_what;
-+    void	*search_ctx_arg;
-     int		tagfile;
-     char_u	*rel_fname;	/* file name to use for "." */
- {
- #ifdef FEAT_PATH_EXTRA
--    char_u	*wc_part;
-+    char_u		*wc_part;
- #endif
--    ff_stack_T	*sptr;
-+    ff_stack_T		*sptr;
-+    ff_search_ctx_T	*search_ctx;
- 
-     /* If a search context is given by the caller, reuse it, else allocate a
-      * new one.
-      */
--    if (search_ctx != NULL)
--	ff_search_ctx = search_ctx;
-+    if (search_ctx_arg != NULL)
-+	search_ctx = search_ctx_arg;
-     else
-     {
--	ff_search_ctx = (ff_search_ctx_T*)alloc(
--					   (unsigned)sizeof(ff_search_ctx_T));
--	if (ff_search_ctx == NULL)
-+	search_ctx = (ff_search_ctx_T*)alloc((unsigned)sizeof(ff_search_ctx_T));
-+	if (search_ctx == NULL)
- 	    goto error_return;
--	memset(ff_search_ctx, 0, sizeof(ff_search_ctx_T));
-+	memset(search_ctx, 0, sizeof(ff_search_ctx_T));
-     }
-+    search_ctx->ffsc_find_what = find_what;
- 
-     /* clear the search context, but NOT the visited lists */
--    ff_clear();
-+    ff_clear(search_ctx);
- 
-     /* clear visited list if wanted */
-     if (free_visited == TRUE)
--	vim_findfile_free_visited(ff_search_ctx);
-+	vim_findfile_free_visited(search_ctx);
-     else
-     {
- 	/* Reuse old visited lists. Get the visited list for the given
- 	 * filename. If no list for the current filename exists, creates a new
--	 * one.
--	 */
--	ff_search_ctx->ffsc_visited_list = ff_get_visited_list(filename,
--				     &ff_search_ctx->ffsc_visited_lists_list);
--	if (ff_search_ctx->ffsc_visited_list == NULL)
-+	 * one. */
-+	search_ctx->ffsc_visited_list = ff_get_visited_list(filename,
-+					&search_ctx->ffsc_visited_lists_list);
-+	if (search_ctx->ffsc_visited_list == NULL)
- 	    goto error_return;
--	ff_search_ctx->ffsc_dir_visited_list = ff_get_visited_list(filename,
--				 &ff_search_ctx->ffsc_dir_visited_lists_list);
--	if (ff_search_ctx->ffsc_dir_visited_list == NULL)
-+	search_ctx->ffsc_dir_visited_list = ff_get_visited_list(filename,
-+				    &search_ctx->ffsc_dir_visited_lists_list);
-+	if (search_ctx->ffsc_dir_visited_list == NULL)
- 	    goto error_return;
-     }
- 
-@@ -4051,12 +4077,11 @@
- 	{
- 	    /* Make the start dir an absolute path name. */
- 	    vim_strncpy(ff_expand_buffer, rel_fname, len);
--	    ff_search_ctx->ffsc_start_dir = FullName_save(ff_expand_buffer,
--								       FALSE);
-+	    search_ctx->ffsc_start_dir = FullName_save(ff_expand_buffer, FALSE);
- 	}
- 	else
--	    ff_search_ctx->ffsc_start_dir = vim_strnsave(rel_fname, len);
--	if (ff_search_ctx->ffsc_start_dir == NULL)
-+	    search_ctx->ffsc_start_dir = vim_strnsave(rel_fname, len);
-+	if (search_ctx->ffsc_start_dir == NULL)
- 	    goto error_return;
- 	if (*++path != NUL)
- 	    ++path;
-@@ -4081,8 +4106,8 @@
- 	if (mch_dirname(ff_expand_buffer, MAXPATHL) == FAIL)
- 	    goto error_return;
- 
--	ff_search_ctx->ffsc_start_dir = vim_strsave(ff_expand_buffer);
--	if (ff_search_ctx->ffsc_start_dir == NULL)
-+	search_ctx->ffsc_start_dir = vim_strsave(ff_expand_buffer);
-+	if (search_ctx->ffsc_start_dir == NULL)
- 	    goto error_return;
- 
- #ifdef BACKSLASH_IN_FILENAME
-@@ -4090,8 +4115,8 @@
- 	 * directory (but not for "//machine/dir").  Only use the drive name. */
- 	if ((*path == '/' || *path == '\\')
- 		&& path[1] != path[0]
--		&& ff_search_ctx->ffsc_start_dir[1] == ':')
--	    ff_search_ctx->ffsc_start_dir[2] = NUL;
-+		&& search_ctx->ffsc_start_dir[1] == ':')
-+	    search_ctx->ffsc_start_dir[2] = NUL;
- #endif
-     }
- 
-@@ -4101,7 +4126,7 @@
-      * If this fails (mem allocation), there is no upward search at all or a
-      * stop directory is not recognized -> continue silently.
-      * If stopdirs just contains a ";" or is empty,
--     * ff_search_ctx->ffsc_stopdirs_v will only contain a  NULL pointer. This
-+     * search_ctx->ffsc_stopdirs_v will only contain a  NULL pointer. This
-      * is handled as unlimited upward search.  See function
-      * ff_path_in_stoplist() for details.
-      */
-@@ -4114,10 +4139,10 @@
- 	    walker++;
- 
- 	dircount = 1;
--	ff_search_ctx->ffsc_stopdirs_v =
--	    (char_u **)alloc((unsigned)sizeof(char_u *));
-+	search_ctx->ffsc_stopdirs_v =
-+				 (char_u **)alloc((unsigned)sizeof(char_u *));
- 
--	if (ff_search_ctx->ffsc_stopdirs_v != NULL)
-+	if (search_ctx->ffsc_stopdirs_v != NULL)
- 	{
- 	    do
- 	    {
-@@ -4125,37 +4150,37 @@
- 		void	*ptr;
- 
- 		helper = walker;
--		ptr = vim_realloc(ff_search_ctx->ffsc_stopdirs_v,
-+		ptr = vim_realloc(search_ctx->ffsc_stopdirs_v,
- 					   (dircount + 1) * sizeof(char_u *));
- 		if (ptr)
--		    ff_search_ctx->ffsc_stopdirs_v = ptr;
-+		    search_ctx->ffsc_stopdirs_v = ptr;
- 		else
- 		    /* ignore, keep what we have and continue */
- 		    break;
- 		walker = vim_strchr(walker, ';');
- 		if (walker)
- 		{
--		    ff_search_ctx->ffsc_stopdirs_v[dircount-1] =
--			vim_strnsave(helper, (int)(walker - helper));
-+		    search_ctx->ffsc_stopdirs_v[dircount-1] =
-+				 vim_strnsave(helper, (int)(walker - helper));
- 		    walker++;
- 		}
- 		else
- 		    /* this might be "", which means ascent till top
- 		     * of directory tree.
- 		     */
--		    ff_search_ctx->ffsc_stopdirs_v[dircount-1] =
--			vim_strsave(helper);
-+		    search_ctx->ffsc_stopdirs_v[dircount-1] =
-+							  vim_strsave(helper);
- 
- 		dircount++;
- 
- 	    } while (walker != NULL);
--	    ff_search_ctx->ffsc_stopdirs_v[dircount-1] = NULL;
-+	    search_ctx->ffsc_stopdirs_v[dircount-1] = NULL;
- 	}
-     }
- #endif
- 
- #ifdef FEAT_PATH_EXTRA
--    ff_search_ctx->ffsc_level = level;
-+    search_ctx->ffsc_level = level;
- 
-     /* split into:
-      *  -fix path
-@@ -4169,8 +4194,7 @@
- 	char	*errpt;
- 
- 	/* save the fix part of the path */
--	ff_search_ctx->ffsc_fix_path = vim_strnsave(path,
--						       (int)(wc_part - path));
-+	search_ctx->ffsc_fix_path = vim_strnsave(path, (int)(wc_part - path));
- 
- 	/*
- 	 * copy wc_path and add restricts to the '**' wildcard.
-@@ -4209,47 +4233,47 @@
- 		ff_expand_buffer[len++] = *wc_part++;
- 	}
- 	ff_expand_buffer[len] = NUL;
--	ff_search_ctx->ffsc_wc_path = vim_strsave(ff_expand_buffer);
-+	search_ctx->ffsc_wc_path = vim_strsave(ff_expand_buffer);
- 
--	if (ff_search_ctx->ffsc_wc_path == NULL)
-+	if (search_ctx->ffsc_wc_path == NULL)
- 	    goto error_return;
-     }
-     else
- #endif
--	ff_search_ctx->ffsc_fix_path = vim_strsave(path);
-+	search_ctx->ffsc_fix_path = vim_strsave(path);
- 
--    if (ff_search_ctx->ffsc_start_dir == NULL)
-+    if (search_ctx->ffsc_start_dir == NULL)
-     {
- 	/* store the fix part as startdir.
- 	 * This is needed if the parameter path is fully qualified.
- 	 */
--	ff_search_ctx->ffsc_start_dir = vim_strsave(ff_search_ctx->ffsc_fix_path);
--	if (ff_search_ctx->ffsc_start_dir)
--	    ff_search_ctx->ffsc_fix_path[0] = NUL;
-+	search_ctx->ffsc_start_dir = vim_strsave(search_ctx->ffsc_fix_path);
-+	if (search_ctx->ffsc_start_dir)
-+	    search_ctx->ffsc_fix_path[0] = NUL;
-     }
- 
-     /* create an absolute path */
--    STRCPY(ff_expand_buffer, ff_search_ctx->ffsc_start_dir);
-+    STRCPY(ff_expand_buffer, search_ctx->ffsc_start_dir);
-     add_pathsep(ff_expand_buffer);
--    STRCAT(ff_expand_buffer, ff_search_ctx->ffsc_fix_path);
-+    STRCAT(ff_expand_buffer, search_ctx->ffsc_fix_path);
-     add_pathsep(ff_expand_buffer);
- 
-     sptr = ff_create_stack_element(ff_expand_buffer,
- #ifdef FEAT_PATH_EXTRA
--	    ff_search_ctx->ffsc_wc_path,
-+	    search_ctx->ffsc_wc_path,
- #endif
- 	    level, 0);
- 
-     if (sptr == NULL)
- 	goto error_return;
- 
--    ff_push(sptr);
-+    ff_push(search_ctx, sptr);
- 
--    ff_search_ctx->ffsc_file_to_search = vim_strsave(filename);
--    if (ff_search_ctx->ffsc_file_to_search == NULL)
-+    search_ctx->ffsc_file_to_search = vim_strsave(filename);
-+    if (search_ctx->ffsc_file_to_search == NULL)
- 	goto error_return;
- 
--    return ff_search_ctx;
-+    return search_ctx;
- 
- error_return:
-     /*
-@@ -4257,7 +4281,7 @@
-      * Even when the caller gave us a (perhaps valid) context we free it here,
-      * as we might have already destroyed it.
-      */
--    vim_findfile_cleanup(ff_search_ctx);
-+    vim_findfile_cleanup(search_ctx);
-     return NULL;
- }
- 
-@@ -4294,7 +4318,9 @@
- }
- #endif
- 
--/* Clean up the given search context. Can handle a NULL pointer */
-+/*
-+ * Clean up the given search context. Can handle a NULL pointer.
-+ */
-     void
- vim_findfile_cleanup(ctx)
-     void	*ctx;
-@@ -4302,12 +4328,9 @@
-     if (ctx == NULL)
- 	return;
- 
--    ff_search_ctx = ctx;
--
-     vim_findfile_free_visited(ctx);
--    ff_clear();
-+    ff_clear(ctx);
-     vim_free(ctx);
--    ff_search_ctx = NULL;
- }
- 
- /*
-@@ -4323,15 +4346,15 @@
-  * top of the list).
-  */
-     char_u *
--vim_findfile(search_ctx)
--    void	*search_ctx;
-+vim_findfile(search_ctx_arg)
-+    void	*search_ctx_arg;
- {
-     char_u	*file_path;
- #ifdef FEAT_PATH_EXTRA
-     char_u	*rest_of_wildcards;
-     char_u	*path_end = NULL;
- #endif
--    ff_stack_T	*ctx;
-+    ff_stack_T	*stackp;
- #if defined(FEAT_SEARCHPATH) || defined(FEAT_PATH_EXTRA)
-     int		len;
- #endif
-@@ -4340,11 +4363,12 @@
- #ifdef FEAT_SEARCHPATH
-     char_u	*suf;
- #endif
-+    ff_search_ctx_T *search_ctx;
- 
--    if (search_ctx == NULL)
-+    if (search_ctx_arg == NULL)
- 	return NULL;
- 
--    ff_search_ctx = (ff_search_ctx_T*)search_ctx;
-+    search_ctx = (ff_search_ctx_T *)search_ctx_arg;
- 
-     /*
-      * filepath is used as buffer for various actions and as the storage to
-@@ -4355,8 +4379,9 @@
- 
- #ifdef FEAT_PATH_EXTRA
-     /* store the end of the start dir -- needed for upward search */
--    if (ff_search_ctx->ffsc_start_dir != NULL)
--	path_end = &ff_search_ctx->ffsc_start_dir[STRLEN(ff_search_ctx->ffsc_start_dir)];
-+    if (search_ctx->ffsc_start_dir != NULL)
-+	path_end = &search_ctx->ffsc_start_dir[
-+					  STRLEN(search_ctx->ffsc_start_dir)];
- #endif
- 
- #ifdef FEAT_PATH_EXTRA
-@@ -4373,8 +4398,8 @@
- 		break;
- 
- 	    /* get directory to work on from stack */
--	    ctx = ff_pop();
--	    if (ctx == NULL)
-+	    stackp = ff_pop(search_ctx);
-+	    if (stackp == NULL)
- 		break;
- 
- 	    /*
-@@ -4394,14 +4419,14 @@
- 	     *  /etc/rc.d/init.d is linked to /etc/rc.d -> endless loop)
- 	     *
- 	     * This check is only needed for directories we work on for the
--	     * first time (hence ctx->ff_filearray == NULL)
-+	     * first time (hence stackp->ff_filearray == NULL)
- 	     */
--	    if (ctx->ffs_filearray == NULL
--		    && ff_check_visited(&ff_search_ctx->ffsc_dir_visited_list
-+	    if (stackp->ffs_filearray == NULL
-+		    && ff_check_visited(&search_ctx->ffsc_dir_visited_list
- 							  ->ffvl_visited_list,
--			ctx->ffs_fix_path
-+			stackp->ffs_fix_path
- #ifdef FEAT_PATH_EXTRA
--			, ctx->ffs_wc_path
-+			, stackp->ffs_wc_path
- #endif
- 			) == FAIL)
- 	    {
-@@ -4410,13 +4435,13 @@
- 		{
- 		    verbose_enter_scroll();
- 		    smsg((char_u *)"Already Searched: %s (%s)",
--					   ctx->ffs_fix_path, ctx->ffs_wc_path);
-+				   stackp->ffs_fix_path, stackp->ffs_wc_path);
- 		    /* don't overwrite this either */
- 		    msg_puts((char_u *)"\n");
- 		    verbose_leave_scroll();
- 		}
- #endif
--		ff_free_stack_element(ctx);
-+		ff_free_stack_element(stackp);
- 		continue;
- 	    }
- #ifdef FF_VERBOSE
-@@ -4424,7 +4449,7 @@
- 	    {
- 		verbose_enter_scroll();
- 		smsg((char_u *)"Searching: %s (%s)",
--					 ctx->ffs_fix_path, ctx->ffs_wc_path);
-+				   stackp->ffs_fix_path, stackp->ffs_wc_path);
- 		/* don't overwrite this either */
- 		msg_puts((char_u *)"\n");
- 		verbose_leave_scroll();
-@@ -4432,9 +4457,9 @@
- #endif
- 
- 	    /* check depth */
--	    if (ctx->ffs_level <= 0)
-+	    if (stackp->ffs_level <= 0)
- 	    {
--		ff_free_stack_element(ctx);
-+		ff_free_stack_element(stackp);
- 		continue;
- 	    }
- 
-@@ -4446,7 +4471,7 @@
- 	     * and all possible expands are returned in one array. We use this
- 	     * to handle the expansion of '**' into an empty string.
- 	     */
--	    if (ctx->ffs_filearray == NULL)
-+	    if (stackp->ffs_filearray == NULL)
- 	    {
- 		char_u *dirptrs[2];
- 
-@@ -4457,19 +4482,19 @@
- 		dirptrs[1] = NULL;
- 
- 		/* if we have a start dir copy it in */
--		if (!vim_isAbsName(ctx->ffs_fix_path)
--			&& ff_search_ctx->ffsc_start_dir)
-+		if (!vim_isAbsName(stackp->ffs_fix_path)
-+						&& search_ctx->ffsc_start_dir)
- 		{
--		    STRCPY(file_path, ff_search_ctx->ffsc_start_dir);
-+		    STRCPY(file_path, search_ctx->ffsc_start_dir);
- 		    add_pathsep(file_path);
- 		}
- 
- 		/* append the fix part of the search path */
--		STRCAT(file_path, ctx->ffs_fix_path);
-+		STRCAT(file_path, stackp->ffs_fix_path);
- 		add_pathsep(file_path);
- 
- #ifdef FEAT_PATH_EXTRA
--		rest_of_wildcards = ctx->ffs_wc_path;
-+		rest_of_wildcards = stackp->ffs_wc_path;
- 		if (*rest_of_wildcards != NUL)
- 		{
- 		    len = (int)STRLEN(file_path);
-@@ -4496,11 +4521,11 @@
- 			else
- 			    rest_of_wildcards += 3;
- 
--			if (ctx->ffs_star_star_empty == 0)
-+			if (stackp->ffs_star_star_empty == 0)
- 			{
- 			    /* if not done before, expand '**' to empty */
--			    ctx->ffs_star_star_empty = 1;
--			    dirptrs[1] = ctx->ffs_fix_path;
-+			    stackp->ffs_star_star_empty = 1;
-+			    dirptrs[1] = stackp->ffs_fix_path;
- 			}
- 		    }
- 
-@@ -4527,30 +4552,31 @@
- 		 */
- 		if (path_with_url(dirptrs[0]))
- 		{
--		    ctx->ffs_filearray = (char_u **)
-+		    stackp->ffs_filearray = (char_u **)
- 					      alloc((unsigned)sizeof(char *));
--		    if (ctx->ffs_filearray != NULL
--			    && (ctx->ffs_filearray[0]
-+		    if (stackp->ffs_filearray != NULL
-+			    && (stackp->ffs_filearray[0]
- 				= vim_strsave(dirptrs[0])) != NULL)
--			ctx->ffs_filearray_size = 1;
-+			stackp->ffs_filearray_size = 1;
- 		    else
--			ctx->ffs_filearray_size = 0;
-+			stackp->ffs_filearray_size = 0;
- 		}
- 		else
- 		    expand_wildcards((dirptrs[1] == NULL) ? 1 : 2, dirptrs,
--			    &ctx->ffs_filearray_size,
--			    &ctx->ffs_filearray,
-+			    &stackp->ffs_filearray_size,
-+			    &stackp->ffs_filearray,
- 			    EW_DIR|EW_ADDSLASH|EW_SILENT);
- 
--		ctx->ffs_filearray_cur = 0;
--		ctx->ffs_stage = 0;
-+		stackp->ffs_filearray_cur = 0;
-+		stackp->ffs_stage = 0;
- 	    }
- #ifdef FEAT_PATH_EXTRA
- 	    else
--		rest_of_wildcards = &ctx->ffs_wc_path[STRLEN(ctx->ffs_wc_path)];
-+		rest_of_wildcards = &stackp->ffs_wc_path[
-+						 STRLEN(stackp->ffs_wc_path)];
- #endif
- 
--	    if (ctx->ffs_stage == 0)
-+	    if (stackp->ffs_stage == 0)
- 	    {
- 		/* this is the first time we work on this directory */
- #ifdef FEAT_PATH_EXTRA
-@@ -4561,18 +4587,18 @@
- 		     * we don't have further wildcards to expand, so we have to
- 		     * check for the final file now
- 		     */
--		    for (i = ctx->ffs_filearray_cur;
--					     i < ctx->ffs_filearray_size; ++i)
-+		    for (i = stackp->ffs_filearray_cur;
-+					  i < stackp->ffs_filearray_size; ++i)
- 		    {
--			if (!path_with_url(ctx->ffs_filearray[i])
--					 && !mch_isdir(ctx->ffs_filearray[i]))
-+			if (!path_with_url(stackp->ffs_filearray[i])
-+				      && !mch_isdir(stackp->ffs_filearray[i]))
- 			    continue;   /* not a directory */
- 
- 			/* prepare the filename to be checked for existance
- 			 * below */
--			STRCPY(file_path, ctx->ffs_filearray[i]);
-+			STRCPY(file_path, stackp->ffs_filearray[i]);
- 			add_pathsep(file_path);
--			STRCAT(file_path, ff_search_ctx->ffsc_file_to_search);
-+			STRCAT(file_path, search_ctx->ffsc_file_to_search);
- 
- 			/*
- 			 * Try without extra suffix and then with suffixes
-@@ -4586,12 +4612,15 @@
- 			{
- 			    /* if file exists and we didn't already find it */
- 			    if ((path_with_url(file_path)
--					|| (mch_getperm(file_path) >= 0
--					    && (!ff_search_ctx->ffsc_need_dir
--						|| mch_isdir(file_path))))
-+				  || (mch_getperm(file_path) >= 0
-+				      && (search_ctx->ffsc_find_what
-+							      == FINDFILE_BOTH
-+					  || ((search_ctx->ffsc_find_what
-+							      == FINDFILE_DIR)
-+						   == mch_isdir(file_path)))))
- #ifndef FF_VERBOSE
- 				    && (ff_check_visited(
--					    &ff_search_ctx->ffsc_visited_list->ffvl_visited_list,
-+					    &search_ctx->ffsc_visited_list->ffvl_visited_list,
- 					    file_path
- #ifdef FEAT_PATH_EXTRA
- 					    , (char_u *)""
-@@ -4602,7 +4631,7 @@
- 			    {
- #ifdef FF_VERBOSE
- 				if (ff_check_visited(
--					    &ff_search_ctx->ffsc_visited_list->ffvl_visited_list,
-+					    &search_ctx->ffsc_visited_list->ffvl_visited_list,
- 					    file_path
- #ifdef FEAT_PATH_EXTRA
- 					    , (char_u *)""
-@@ -4623,8 +4652,8 @@
- #endif
- 
- 				/* push dir to examine rest of subdirs later */
--				ctx->ffs_filearray_cur = i + 1;
--				ff_push(ctx);
-+				stackp->ffs_filearray_cur = i + 1;
-+				ff_push(search_ctx, stackp);
- 
- 				simplify_filename(file_path);
- 				if (mch_dirname(ff_expand_buffer, MAXPATHL)
-@@ -4666,19 +4695,22 @@
- 		     * still wildcards left, push the directories for further
- 		     * search
- 		     */
--		    for (i = ctx->ffs_filearray_cur;
--					     i < ctx->ffs_filearray_size; ++i)
-+		    for (i = stackp->ffs_filearray_cur;
-+					  i < stackp->ffs_filearray_size; ++i)
- 		    {
--			if (!mch_isdir(ctx->ffs_filearray[i]))
-+			if (!mch_isdir(stackp->ffs_filearray[i]))
- 			    continue;	/* not a directory */
- 
--			ff_push(ff_create_stack_element(ctx->ffs_filearray[i],
--				      rest_of_wildcards, ctx->ffs_level - 1, 0));
-+			ff_push(search_ctx,
-+				ff_create_stack_element(
-+						     stackp->ffs_filearray[i],
-+						     rest_of_wildcards,
-+						     stackp->ffs_level - 1, 0));
- 		    }
- 		}
- #endif
--		ctx->ffs_filearray_cur = 0;
--		ctx->ffs_stage = 1;
-+		stackp->ffs_filearray_cur = 0;
-+		stackp->ffs_stage = 1;
- 	    }
- 
- #ifdef FEAT_PATH_EXTRA
-@@ -4686,23 +4718,25 @@
- 	     * if wildcards contains '**' we have to descent till we reach the
- 	     * leaves of the directory tree.
- 	     */
--	    if (STRNCMP(ctx->ffs_wc_path, "**", 2) == 0)
-+	    if (STRNCMP(stackp->ffs_wc_path, "**", 2) == 0)
- 	    {
--		for (i = ctx->ffs_filearray_cur;
--					     i < ctx->ffs_filearray_size; ++i)
-+		for (i = stackp->ffs_filearray_cur;
-+					  i < stackp->ffs_filearray_size; ++i)
- 		{
--		    if (fnamecmp(ctx->ffs_filearray[i], ctx->ffs_fix_path) == 0)
-+		    if (fnamecmp(stackp->ffs_filearray[i],
-+						   stackp->ffs_fix_path) == 0)
- 			continue; /* don't repush same directory */
--		    if (!mch_isdir(ctx->ffs_filearray[i]))
-+		    if (!mch_isdir(stackp->ffs_filearray[i]))
- 			continue;   /* not a directory */
--		    ff_push(ff_create_stack_element(ctx->ffs_filearray[i],
--				ctx->ffs_wc_path, ctx->ffs_level - 1, 1));
-+		    ff_push(search_ctx,
-+			    ff_create_stack_element(stackp->ffs_filearray[i],
-+				stackp->ffs_wc_path, stackp->ffs_level - 1, 1));
- 		}
- 	    }
- #endif
- 
- 	    /* we are done with the current directory */
--	    ff_free_stack_element(ctx);
-+	    ff_free_stack_element(stackp);
- 
- 	}
- 
-@@ -4710,40 +4744,40 @@
- 	/* If we reached this, we didn't find anything downwards.
- 	 * Let's check if we should do an upward search.
- 	 */
--	if (ff_search_ctx->ffsc_start_dir
--		&& ff_search_ctx->ffsc_stopdirs_v != NULL && !got_int)
-+	if (search_ctx->ffsc_start_dir
-+		&& search_ctx->ffsc_stopdirs_v != NULL && !got_int)
- 	{
- 	    ff_stack_T  *sptr;
- 
- 	    /* is the last starting directory in the stop list? */
--	    if (ff_path_in_stoplist(ff_search_ctx->ffsc_start_dir,
--		       (int)(path_end - ff_search_ctx->ffsc_start_dir),
--		       ff_search_ctx->ffsc_stopdirs_v) == TRUE)
-+	    if (ff_path_in_stoplist(search_ctx->ffsc_start_dir,
-+		       (int)(path_end - search_ctx->ffsc_start_dir),
-+		       search_ctx->ffsc_stopdirs_v) == TRUE)
- 		break;
- 
- 	    /* cut of last dir */
--	    while (path_end > ff_search_ctx->ffsc_start_dir
--		    && vim_ispathsep(*path_end))
-+	    while (path_end > search_ctx->ffsc_start_dir
-+						  && vim_ispathsep(*path_end))
- 		path_end--;
--	    while (path_end > ff_search_ctx->ffsc_start_dir
--		    && !vim_ispathsep(path_end[-1]))
-+	    while (path_end > search_ctx->ffsc_start_dir
-+					      && !vim_ispathsep(path_end[-1]))
- 		path_end--;
- 	    *path_end = 0;
- 	    path_end--;
- 
--	    if (*ff_search_ctx->ffsc_start_dir == 0)
-+	    if (*search_ctx->ffsc_start_dir == 0)
- 		break;
- 
--	    STRCPY(file_path, ff_search_ctx->ffsc_start_dir);
-+	    STRCPY(file_path, search_ctx->ffsc_start_dir);
- 	    add_pathsep(file_path);
--	    STRCAT(file_path, ff_search_ctx->ffsc_fix_path);
-+	    STRCAT(file_path, search_ctx->ffsc_fix_path);
- 
- 	    /* create a new stack entry */
- 	    sptr = ff_create_stack_element(file_path,
--		    ff_search_ctx->ffsc_wc_path, ff_search_ctx->ffsc_level, 0);
-+		    search_ctx->ffsc_wc_path, search_ctx->ffsc_level, 0);
- 	    if (sptr == NULL)
- 		break;
--	    ff_push(sptr);
-+	    ff_push(search_ctx, sptr);
- 	}
- 	else
- 	    break;
-@@ -4759,16 +4793,17 @@
-  * Can handle it if the passed search_context is NULL;
-  */
-     void
--vim_findfile_free_visited(search_ctx)
--    void	*search_ctx;
-+vim_findfile_free_visited(search_ctx_arg)
-+    void	*search_ctx_arg;
- {
--    if (search_ctx == NULL)
--	return;
-+    ff_search_ctx_T *search_ctx;
- 
--    ff_search_ctx = (ff_search_ctx_T *)search_ctx;
-+    if (search_ctx_arg == NULL)
-+	return;
- 
--    vim_findfile_free_visited_list(&ff_search_ctx->ffsc_visited_lists_list);
--    vim_findfile_free_visited_list(&ff_search_ctx->ffsc_dir_visited_lists_list);
-+    search_ctx = (ff_search_ctx_T *)search_ctx_arg;
-+    vim_findfile_free_visited_list(&search_ctx->ffsc_visited_lists_list);
-+    vim_findfile_free_visited_list(&search_ctx->ffsc_dir_visited_lists_list);
- }
- 
-     static void
-@@ -5083,33 +5118,35 @@
- }
- 
- /*
-- * push a dir on the directory stack
-+ * Push a dir on the directory stack.
-  */
-     static void
--ff_push(ctx)
--    ff_stack_T *ctx;
-+ff_push(search_ctx, stack_ptr)
-+    ff_search_ctx_T *search_ctx;
-+    ff_stack_T	    *stack_ptr;
- {
-     /* check for NULL pointer, not to return an error to the user, but
-      * to prevent a crash */
--    if (ctx != NULL)
-+    if (stack_ptr != NULL)
-     {
--	ctx->ffs_prev   = ff_search_ctx->ffsc_stack_ptr;
--	ff_search_ctx->ffsc_stack_ptr = ctx;
-+	stack_ptr->ffs_prev = search_ctx->ffsc_stack_ptr;
-+	search_ctx->ffsc_stack_ptr = stack_ptr;
-     }
- }
- 
- /*
-- * pop a dir from the directory stack
-- * returns NULL if stack is empty
-+ * Pop a dir from the directory stack.
-+ * Returns NULL if stack is empty.
-  */
-     static ff_stack_T *
--ff_pop()
-+ff_pop(search_ctx)
-+    ff_search_ctx_T *search_ctx;
- {
-     ff_stack_T  *sptr;
- 
--    sptr = ff_search_ctx->ffsc_stack_ptr;
--    if (ff_search_ctx->ffsc_stack_ptr != NULL)
--	ff_search_ctx->ffsc_stack_ptr = ff_search_ctx->ffsc_stack_ptr->ffs_prev;
-+    sptr = search_ctx->ffsc_stack_ptr;
-+    if (search_ctx->ffsc_stack_ptr != NULL)
-+	search_ctx->ffsc_stack_ptr = search_ctx->ffsc_stack_ptr->ffs_prev;
- 
-     return sptr;
- }
-@@ -5118,62 +5155,63 @@
-  * free the given stack element
-  */
-     static void
--ff_free_stack_element(ctx)
--    ff_stack_T  *ctx;
-+ff_free_stack_element(stack_ptr)
-+    ff_stack_T  *stack_ptr;
- {
-     /* vim_free handles possible NULL pointers */
--    vim_free(ctx->ffs_fix_path);
-+    vim_free(stack_ptr->ffs_fix_path);
- #ifdef FEAT_PATH_EXTRA
--    vim_free(ctx->ffs_wc_path);
-+    vim_free(stack_ptr->ffs_wc_path);
- #endif
- 
--    if (ctx->ffs_filearray != NULL)
--	FreeWild(ctx->ffs_filearray_size, ctx->ffs_filearray);
-+    if (stack_ptr->ffs_filearray != NULL)
-+	FreeWild(stack_ptr->ffs_filearray_size, stack_ptr->ffs_filearray);
- 
--    vim_free(ctx);
-+    vim_free(stack_ptr);
- }
- 
- /*
-- * clear the search context
-+ * Clear the search context, but NOT the visited list.
-  */
-     static void
--ff_clear()
-+ff_clear(search_ctx)
-+    ff_search_ctx_T *search_ctx;
- {
-     ff_stack_T   *sptr;
- 
-     /* clear up stack */
--    while ((sptr = ff_pop()) != NULL)
-+    while ((sptr = ff_pop(search_ctx)) != NULL)
- 	ff_free_stack_element(sptr);
- 
--    vim_free(ff_search_ctx->ffsc_file_to_search);
--    vim_free(ff_search_ctx->ffsc_start_dir);
--    vim_free(ff_search_ctx->ffsc_fix_path);
-+    vim_free(search_ctx->ffsc_file_to_search);
-+    vim_free(search_ctx->ffsc_start_dir);
-+    vim_free(search_ctx->ffsc_fix_path);
- #ifdef FEAT_PATH_EXTRA
--    vim_free(ff_search_ctx->ffsc_wc_path);
-+    vim_free(search_ctx->ffsc_wc_path);
- #endif
- 
- #ifdef FEAT_PATH_EXTRA
--    if (ff_search_ctx->ffsc_stopdirs_v != NULL)
-+    if (search_ctx->ffsc_stopdirs_v != NULL)
-     {
- 	int  i = 0;
- 
--	while (ff_search_ctx->ffsc_stopdirs_v[i] != NULL)
-+	while (search_ctx->ffsc_stopdirs_v[i] != NULL)
- 	{
--	    vim_free(ff_search_ctx->ffsc_stopdirs_v[i]);
-+	    vim_free(search_ctx->ffsc_stopdirs_v[i]);
- 	    i++;
- 	}
--	vim_free(ff_search_ctx->ffsc_stopdirs_v);
-+	vim_free(search_ctx->ffsc_stopdirs_v);
-     }
--    ff_search_ctx->ffsc_stopdirs_v = NULL;
-+    search_ctx->ffsc_stopdirs_v = NULL;
- #endif
- 
-     /* reset everything */
--    ff_search_ctx->ffsc_file_to_search	= NULL;
--    ff_search_ctx->ffsc_start_dir	= NULL;
--    ff_search_ctx->ffsc_fix_path	= NULL;
-+    search_ctx->ffsc_file_to_search = NULL;
-+    search_ctx->ffsc_start_dir = NULL;
-+    search_ctx->ffsc_fix_path = NULL;
- #ifdef FEAT_PATH_EXTRA
--    ff_search_ctx->ffsc_wc_path		= NULL;
--    ff_search_ctx->ffsc_level		= 0;
-+    search_ctx->ffsc_wc_path = NULL;
-+    search_ctx->ffsc_level = 0;
- #endif
- }
- 
-@@ -5222,7 +5260,7 @@
- 
- #if defined(FEAT_SEARCHPATH) || defined(PROTO)
- /*
-- * Find the file name "ptr[len]" in the path.
-+ * Find the file name "ptr[len]" in the path.  Also finds directory names.
-  *
-  * On the first call set the parameter 'first' to TRUE to initialize
-  * the search.  For repeating calls to FALSE.
-@@ -5256,7 +5294,7 @@
- {
-     return find_file_in_path_option(ptr, len, options, first,
- 	    *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path,
--	    FALSE, rel_fname, curbuf->b_p_sua);
-+	    FINDFILE_BOTH, rel_fname, curbuf->b_p_sua);
- }
- 
- static char_u	*ff_file_to_find = NULL;
-@@ -5289,17 +5327,17 @@
-     char_u	*rel_fname;	/* file name searching relative to */
- {
-     return find_file_in_path_option(ptr, len, options, TRUE, p_cdpath,
--					       TRUE, rel_fname, (char_u *)"");
-+				       FINDFILE_DIR, rel_fname, (char_u *)"");
- }
- 
-     char_u *
--find_file_in_path_option(ptr, len, options, first, path_option, need_dir, rel_fname, suffixes)
-+find_file_in_path_option(ptr, len, options, first, path_option, find_what, rel_fname, suffixes)
-     char_u	*ptr;		/* file name */
-     int		len;		/* length of file name */
-     int		options;
-     int		first;		/* use count'th matching file name */
-     char_u	*path_option;	/* p_path or p_cdpath */
--    int		need_dir;	/* looking for directory name */
-+    int		find_what;	/* FINDFILE_FILE, _DIR or _BOTH */
-     char_u	*rel_fname;	/* file name we are looking relative to. */
-     char_u	*suffixes;	/* list of suffixes, 'suffixesadd' option */
- {
-@@ -5401,12 +5439,14 @@
- #ifdef DJGPP
- 			    /* "C:" by itself will fail for mch_getperm(),
- 			     * assume it's always valid. */
--			    (need_dir && NameBuff[0] != NUL
-+			    (find_what != FINDFILE_FILE && NameBuff[0] != NUL
- 				  && NameBuff[1] == ':'
- 				  && NameBuff[2] == NUL) ||
- #endif
- 			    (mch_getperm(NameBuff) >= 0
--				       && (!need_dir || mch_isdir(NameBuff))))
-+			     && (find_what == FINDFILE_BOTH
-+				 || ((find_what == FINDFILE_DIR)
-+						    == mch_isdir(NameBuff)))))
- 		    {
- 			file_name = vim_strsave(NameBuff);
- 			goto theend;
-@@ -5437,9 +5477,7 @@
- 	{
- 	    if (did_findfile_init)
- 	    {
--		ff_search_ctx->ffsc_need_dir = need_dir;
- 		file_name = vim_findfile(fdip_search_ctx);
--		ff_search_ctx->ffsc_need_dir = FALSE;
- 		if (file_name != NULL)
- 		    break;
- 
-@@ -5472,7 +5510,7 @@
- 		r_ptr = NULL;
- #endif
- 		fdip_search_ctx = vim_findfile_init(buf, ff_file_to_find,
--					    r_ptr, 100, FALSE, TRUE,
-+					    r_ptr, 100, FALSE, find_what,
- 					   fdip_search_ctx, FALSE, rel_fname);
- 		if (fdip_search_ctx != NULL)
- 		    did_findfile_init = TRUE;
-@@ -5484,7 +5522,7 @@
-     {
- 	if (first == TRUE)
- 	{
--	    if (need_dir)
-+	    if (find_what == FINDFILE_DIR)
- 		EMSG2(_("E344: Can't find directory \"%s\" in cdpath"),
- 			ff_file_to_find);
- 	    else
-@@ -5493,7 +5531,7 @@
- 	}
- 	else
- 	{
--	    if (need_dir)
-+	    if (find_what == FINDFILE_DIR)
- 		EMSG2(_("E346: No more directory \"%s\" found in cdpath"),
- 			ff_file_to_find);
- 	    else
-@@ -5922,7 +5960,11 @@
- {
-     if (emsg_not_now())
- 	return TRUE;		/* no error messages at the moment */
-+#ifdef HAVE_STDARG_H
-+    vim_snprintf((char *)IObuff, IOSIZE, (char *)s, a1, a2);
-+#else
-     vim_snprintf((char *)IObuff, IOSIZE, (char *)s, (long_u)a1, (long_u)a2);
-+#endif
-     return emsg(IObuff);
- }
- 
-diff -Naur vim71.orig/src/netbeans.c vim71/src/netbeans.c
---- vim71.orig/src/netbeans.c	2007-05-07 15:51:36.000000000 -0400
-+++ vim71/src/netbeans.c	2008-06-18 06:57:00.000000000 -0400
-@@ -16,6 +16,10 @@
-  * See ":help netbeans-protocol" for explanation.
-  */
- 
-+#if defined(MSDOS) || defined(MSWIN)
-+# include "vimio.h"	/* for mch_open(), must be before vim.h */
-+#endif
-+
- #include "vim.h"
- 
- #if defined(FEAT_NETBEANS_INTG) || defined(PROTO)
-@@ -1204,6 +1208,54 @@
-     return result;
- }
- 
-+/*
-+ * Remove from "first" byte to "last" byte (inclusive), at line "lnum" of the
-+ * current buffer.  Remove to end of line when "last" is MAXCOL.
-+ */
-+    static void
-+nb_partialremove(linenr_T lnum, colnr_T first, colnr_T last)
-+{
-+    char_u *oldtext, *newtext;
-+    int oldlen;
-+    int lastbyte = last;
-+
-+    oldtext = ml_get(lnum);
-+    oldlen = STRLEN(oldtext);
-+    if (first >= (colnr_T)oldlen || oldlen == 0)  /* just in case */
-+	return;
-+    if (lastbyte >= oldlen)
-+	lastbyte = oldlen - 1;
-+    newtext = alloc(oldlen - (int)(lastbyte - first));
-+    if (newtext != NULL)
-+    {
-+	mch_memmove(newtext, oldtext, first);
-+	mch_memmove(newtext + first, oldtext + lastbyte + 1, STRLEN(oldtext + lastbyte + 1) + 1);
-+	nbdebug(("    NEW LINE %d: %s\n", lnum, newtext));
-+	ml_replace(lnum, newtext, FALSE);
-+    }
-+}
-+
-+/*
-+ * Replace the "first" line with the concatenation of the "first" and
-+ * the "other" line. The "other" line is not removed.
-+ */
-+    static void
-+nb_joinlines(linenr_T first, linenr_T other)
-+{
-+    int len_first, len_other;
-+    char_u *p;
-+
-+    len_first = STRLEN(ml_get(first));
-+    len_other = STRLEN(ml_get(other));
-+    p = alloc((unsigned)(len_first + len_other + 1));
-+    if (p != NULL)
-+    {
-+      mch_memmove(p, ml_get(first), len_first);
-+      mch_memmove(p + len_first, ml_get(other), len_other + 1);
-+      ml_replace(first, p, FALSE);
-+    }
-+}
-+
- #define SKIP_STOP 2
- #define streq(a,b) (strcmp(a,b) == 0)
- static int needupdate = 0;
-@@ -1371,6 +1423,8 @@
- 	    long count;
- 	    pos_T first, last;
- 	    pos_T *pos;
-+	    pos_T *next;
-+	    linenr_T del_from_lnum, del_to_lnum;  /* lines to be deleted as a whole */
- 	    int oldFire = netbeansFireChanges;
- 	    int oldSuppress = netbeansSuppressNoLines;
- 	    int wasChanged;
-@@ -1420,25 +1474,75 @@
- 		}
- 		last = *pos;
- 		nbdebug(("    LAST POS: line %d, col %d\n", last.lnum, last.col));
--		curwin->w_cursor = first;
-+		del_from_lnum = first.lnum;
-+		del_to_lnum = last.lnum;
- 		doupdate = 1;
- 
--		/* keep part of first line */
--		if (first.lnum == last.lnum && first.col != last.col)
-+		/* Get the position of the first byte after the deleted
-+		 * section.  "next" is NULL when deleting to the end of the
-+		 * file. */
-+		next = off2pos(buf->bufp, off + count);
-+
-+		/* Remove part of the first line. */
-+		if (first.col != 0 || (next != NULL && first.lnum == next->lnum))
- 		{
--		    /* deletion is within one line */
--		    char_u *p = ml_get(first.lnum);
--		    mch_memmove(p + first.col, p + last.col + 1, STRLEN(p + last.col) + 1);
--		    nbdebug(("    NEW LINE %d: %s\n", first.lnum, p));
--		    ml_replace(first.lnum, p, TRUE);
-+		    if (first.lnum != last.lnum
-+			    || (next != NULL && first.lnum != next->lnum))
-+		    {
-+			/* remove to the end of the first line */
-+			nb_partialremove(first.lnum, first.col,
-+							     (colnr_T)MAXCOL);
-+			if (first.lnum == last.lnum)
-+			{
-+			    /* Partial line to remove includes the end of
-+			     * line.  Join the line with the next one, have
-+			     * the next line deleted below. */
-+			    nb_joinlines(first.lnum, next->lnum);
-+			    del_to_lnum = next->lnum;
-+			}
-+		    }
-+		    else
-+		    {
-+			/* remove within one line */
-+			nb_partialremove(first.lnum, first.col, last.col);
-+		    }
-+		    ++del_from_lnum;  /* don't delete the first line */
- 		}
- 
--		if (first.lnum < last.lnum)
-+		/* Remove part of the last line. */
-+		if (first.lnum != last.lnum && next != NULL
-+			&& next->col != 0 && last.lnum == next->lnum)
-+		{
-+		    nb_partialremove(last.lnum, 0, last.col);
-+		    if (del_from_lnum > first.lnum)
-+		    {
-+			/* Join end of last line to start of first line; last
-+			 * line is deleted below. */
-+			nb_joinlines(first.lnum, last.lnum);
-+		    }
-+		    else
-+			/* First line is deleted as a whole, keep the last
-+			 * line. */
-+			--del_to_lnum;
-+		}
-+
-+		/* First is partial line; last line to remove includes
-+		 * the end of line; join first line to line following last
-+		 * line; line following last line is deleted below. */
-+		if (first.lnum != last.lnum && del_from_lnum > first.lnum
-+			&& next != NULL && last.lnum != next->lnum)
-+		{
-+		    nb_joinlines(first.lnum, next->lnum);
-+		    del_to_lnum = next->lnum;
-+		}
-+
-+		/* Delete whole lines if there are any. */
-+		if (del_to_lnum >= del_from_lnum)
- 		{
- 		    int i;
- 
- 		    /* delete signs from the lines being deleted */
--		    for (i = first.lnum; i <= last.lnum; i++)
-+		    for (i = del_from_lnum; i <= del_to_lnum; i++)
- 		    {
- 			int id = buf_findsign_id(buf->bufp, (linenr_T)i);
- 			if (id > 0)
-@@ -1450,10 +1554,15 @@
- 			    nbdebug(("    No sign on line %d\n", i));
- 		    }
- 
--		    /* delete whole lines */
--		    nbdebug(("    Deleting lines %d through %d\n", first.lnum, last.lnum));
--		    del_lines(last.lnum - first.lnum + 1, FALSE);
-+		    nbdebug(("    Deleting lines %d through %d\n", del_from_lnum, del_to_lnum));
-+		    curwin->w_cursor.lnum = del_from_lnum;
-+		    curwin->w_cursor.col = 0;
-+		    del_lines(del_to_lnum - del_from_lnum + 1, FALSE);
- 		}
-+
-+		/* Leave cursor at first deleted byte. */
-+		curwin->w_cursor = first;
-+		check_cursor_lnum();
- 		buf->bufp->b_changed = wasChanged; /* logically unchanged */
- 		netbeansFireChanges = oldFire;
- 		netbeansSuppressNoLines = oldSuppress;
-@@ -1869,13 +1978,16 @@
- 	}
- 	else if (streq((char *)cmd, "setModified"))
- 	{
-+	    int prev_b_changed;
-+
- 	    if (buf == NULL || buf->bufp == NULL)
- 	    {
- /*		EMSG("E646: null bufp in setModified"); */
- 		return FAIL;
- 	    }
-+	    prev_b_changed = buf->bufp->b_changed;
- 	    if (streq((char *)args, "T"))
--		buf->bufp->b_changed = 1;
-+		buf->bufp->b_changed = TRUE;
- 	    else
- 	    {
- 		struct stat	st;
-@@ -1885,9 +1997,20 @@
- 		if (buf->bufp->b_ffname != NULL
- 			&& mch_stat((char *)buf->bufp->b_ffname, &st) >= 0)
- 		    buf_store_time(buf->bufp, &st, buf->bufp->b_ffname);
--		buf->bufp->b_changed = 0;
-+		buf->bufp->b_changed = FALSE;
- 	    }
- 	    buf->modified = buf->bufp->b_changed;
-+	    if (prev_b_changed != buf->bufp->b_changed)
-+	    {
-+#ifdef FEAT_WINDOWS
-+		check_status(buf->bufp);
-+		redraw_tabline = TRUE;
-+#endif
-+#ifdef FEAT_TITLE
-+		maketitle();
-+#endif
-+		update_screen(0);
-+	    }
- /* =====================================================================*/
- 	}
- 	else if (streq((char *)cmd, "setModtime"))
-@@ -2374,8 +2497,7 @@
-  * the current buffer as "buf".
-  */
-     static void
--nb_set_curbuf(buf)
--    buf_T *buf;
-+nb_set_curbuf(buf_T *buf)
- {
-     if (curbuf != buf && buf_jump_open_win(buf) == NULL)
- 	set_curbuf(buf, DOBUF_GOTO);
-diff -Naur vim71.orig/src/normal.c vim71/src/normal.c
---- vim71.orig/src/normal.c	2007-05-07 15:34:39.000000000 -0400
-+++ vim71/src/normal.c	2008-06-18 06:56:27.000000000 -0400
-@@ -141,12 +141,16 @@
- static void	nv_Undo __ARGS((cmdarg_T *cap));
- static void	nv_tilde __ARGS((cmdarg_T *cap));
- static void	nv_operator __ARGS((cmdarg_T *cap));
-+#ifdef FEAT_EVAL
-+static void	set_op_var __ARGS((int optype));
-+#endif
- static void	nv_lineop __ARGS((cmdarg_T *cap));
- static void	nv_home __ARGS((cmdarg_T *cap));
- static void	nv_pipe __ARGS((cmdarg_T *cap));
- static void	nv_bck_word __ARGS((cmdarg_T *cap));
- static void	nv_wordcmd __ARGS((cmdarg_T *cap));
- static void	nv_beginline __ARGS((cmdarg_T *cap));
-+static void	adjust_cursor __ARGS((oparg_T *oap));
- #ifdef FEAT_VISUAL
- static void	adjust_for_sel __ARGS((cmdarg_T *cap));
- static int	unadjust_for_sel __ARGS((void));
-@@ -690,13 +694,20 @@
- 		ca.count0 = ca.count0 * 10 + (c - '0');
- 	    if (ca.count0 < 0)	    /* got too large! */
- 		ca.count0 = 999999999L;
-+#ifdef FEAT_EVAL
-+	    /* Set v:count here, when called from main() and not a stuffed
-+	     * command, so that v:count can be used in an expression mapping
-+	     * right after the count. */
-+	    if (toplevel && stuff_empty())
-+		set_vcount(ca.count0, ca.count0 == 0 ? 1 : ca.count0);
-+#endif
- 	    if (ctrl_w)
- 	    {
- 		++no_mapping;
- 		++allow_keys;		/* no mapping for nchar, but keys */
- 	    }
- 	    ++no_zero_mapping;		/* don't map zero here */
--	    c = safe_vgetc();
-+	    c = plain_vgetc();
- #ifdef FEAT_LANGMAP
- 	    LANGMAP_ADJUST(c, TRUE);
- #endif
-@@ -721,7 +732,7 @@
- 	    ca.count0 = 0;
- 	    ++no_mapping;
- 	    ++allow_keys;		/* no mapping for nchar, but keys */
--	    c = safe_vgetc();		/* get next character */
-+	    c = plain_vgetc();		/* get next character */
- #ifdef FEAT_LANGMAP
- 	    LANGMAP_ADJUST(c, TRUE);
- #endif
-@@ -889,13 +900,18 @@
- 
- 	++no_mapping;
- 	++allow_keys;		/* no mapping for nchar, but allow key codes */
-+#ifdef FEAT_AUTOCMD
-+	/* Don't generate a CursorHold event here, most commands can't handle
-+	 * it, e.g., nv_replace(), nv_csearch(). */
-+	did_cursorhold = TRUE;
-+#endif
- 	if (ca.cmdchar == 'g')
- 	{
- 	    /*
- 	     * For 'g' get the next character now, so that we can check for
- 	     * "gr", "g'" and "g`".
- 	     */
--	    ca.nchar = safe_vgetc();
-+	    ca.nchar = plain_vgetc();
- #ifdef FEAT_LANGMAP
- 	    LANGMAP_ADJUST(ca.nchar, TRUE);
- #endif
-@@ -952,7 +968,7 @@
- 		im_set_active(TRUE);
- #endif
- 
--	    *cp = safe_vgetc();
-+	    *cp = plain_vgetc();
- 
- 	    if (langmap_active)
- 	    {
-@@ -1040,7 +1056,7 @@
- 		}
- 		if (c > 0)
- 		{
--		    c = safe_vgetc();
-+		    c = plain_vgetc();
- 		    if (c != Ctrl_N && c != Ctrl_G)
- 			vungetc(c);
- 		    else
-@@ -1059,7 +1075,7 @@
- 	    while (enc_utf8 && lang && (c = vpeekc()) > 0
- 				 && (c >= 0x100 || MB_BYTE2LEN(vpeekc()) > 1))
- 	    {
--		c = safe_vgetc();
-+		c = plain_vgetc();
- 		if (!utf_iscomposing(c))
- 		{
- 		    vungetc(c);		/* it wasn't, put it back */
-@@ -3755,7 +3771,8 @@
-     extra_len = (int)STRLEN(p);
-     overflow = old_len + extra_len - SHOWCMD_COLS;
-     if (overflow > 0)
--	STRCPY(showcmd_buf, showcmd_buf + overflow);
-+	mch_memmove(showcmd_buf, showcmd_buf + overflow,
-+						      old_len - overflow + 1);
-     STRCAT(showcmd_buf, p);
- 
-     if (char_avail())
-@@ -4178,7 +4195,7 @@
-     for (;;)
-     {
- 	t = searchit(curwin, curbuf, &curwin->w_cursor, FORWARD,
--				  pat, 1L, searchflags, RE_LAST, (linenr_T)0);
-+			    pat, 1L, searchflags, RE_LAST, (linenr_T)0, NULL);
- 	if (curwin->w_cursor.lnum >= old_pos.lnum)
- 	    t = FAIL;	/* match after start is failure too */
- 
-@@ -4558,7 +4575,7 @@
- #endif
- 	    ++no_mapping;
- 	    ++allow_keys;   /* no mapping for nchar, but allow key codes */
--	    nchar = safe_vgetc();
-+	    nchar = plain_vgetc();
- #ifdef FEAT_LANGMAP
- 	    LANGMAP_ADJUST(nchar, TRUE);
- #endif
-@@ -4916,7 +4933,7 @@
-     case 'u':	/* "zug" and "zuw": undo "zg" and "zw" */
- 		++no_mapping;
- 		++allow_keys;   /* no mapping for nchar, but allow key codes */
--		nchar = safe_vgetc();
-+		nchar = plain_vgetc();
- #ifdef FEAT_LANGMAP
- 		LANGMAP_ADJUST(nchar, TRUE);
- #endif
-@@ -5836,12 +5853,13 @@
- 		/* When the NL before the first char has to be deleted we
- 		 * put the cursor on the NUL after the previous line.
- 		 * This is a very special case, be careful!
--		 * don't adjust op_end now, otherwise it won't work */
-+		 * Don't adjust op_end now, otherwise it won't work. */
- 		if (	   (cap->oap->op_type == OP_DELETE
- 			    || cap->oap->op_type == OP_CHANGE)
- 			&& !lineempty(curwin->w_cursor.lnum))
- 		{
--		    ++curwin->w_cursor.col;
-+		    if (*ml_get_cursor() != NUL)
-+			++curwin->w_cursor.col;
- 		    cap->retval |= CA_NO_ADJ_OP_END;
- 		}
- 		continue;
-@@ -6075,7 +6093,7 @@
-     curwin->w_set_curswant = TRUE;
- 
-     i = do_search(cap->oap, dir, pat, cap->count1,
--				 opt | SEARCH_OPT | SEARCH_ECHO | SEARCH_MSG);
-+			   opt | SEARCH_OPT | SEARCH_ECHO | SEARCH_MSG, NULL);
-     if (i == 0)
- 	clearop(cap->oap);
-     else
-@@ -6379,7 +6397,7 @@
-      */
-     else if (cap->nchar == 'p' || cap->nchar == 'P')
-     {
--	if (!checkclearopq(cap->oap))
-+	if (!checkclearop(cap->oap))
- 	{
- 	    prep_redo_cmd(cap);
- 	    do_put(cap->oap->regname,
-@@ -6550,6 +6568,8 @@
- 	clearopbeep(cap->oap);
-     else
-     {
-+	/* Don't leave the cursor on the NUL past end of line. */
-+	adjust_cursor(cap->oap);
- #ifdef FEAT_VIRTUALEDIT
- 	curwin->w_cursor.coladd = 0;
- #endif
-@@ -6662,6 +6682,13 @@
-     else
- 	had_ctrl_v = NUL;
- 
-+    /* Abort if the character is a special key. */
-+    if (IS_SPECIAL(cap->nchar))
-+    {
-+	clearopbeep(cap->oap);
-+	return;
-+    }
-+
- #ifdef FEAT_VISUAL
-     /* Visual mode "r" */
-     if (VIsual_active)
-@@ -6688,11 +6715,9 @@
-     }
- #endif
- 
--    /*
--     * Check for a special key or not enough characters to replace.
--     */
-+    /* Abort if not enough characters to replace. */
-     ptr = ml_get_cursor();
--    if (IS_SPECIAL(cap->nchar) || STRLEN(ptr) < (unsigned)cap->count1
-+    if (STRLEN(ptr) < (unsigned)cap->count1
- #ifdef FEAT_MBYTE
- 	    || (has_mbyte && mb_charlen(ptr) < cap->count1)
- #endif
-@@ -7155,6 +7180,9 @@
- 	{
- 	    cap->oap->start = curwin->w_cursor;
- 	    cap->oap->op_type = OP_DELETE;
-+#ifdef FEAT_EVAL
-+	    set_op_var(OP_DELETE);
-+#endif
- 	    cap->count1 = 1;
- 	    nv_dollar(cap);
- 	    finish_op = TRUE;
-@@ -8194,9 +8222,34 @@
-     {
- 	cap->oap->start = curwin->w_cursor;
- 	cap->oap->op_type = op_type;
-+#ifdef FEAT_EVAL
-+	set_op_var(op_type);
-+#endif
-     }
- }
- 
-+#ifdef FEAT_EVAL
-+/*
-+ * Set v:operator to the characters for "optype".
-+ */
-+    static void
-+set_op_var(optype)
-+    int optype;
-+{
-+    char_u	opchars[3];
-+
-+    if (optype == OP_NOP)
-+	set_vim_var_string(VV_OP, NULL, 0);
-+    else
-+    {
-+	opchars[0] = get_op_char(optype);
-+	opchars[1] = get_extra_op_char(optype);
-+	opchars[2] = NUL;
-+	set_vim_var_string(VV_OP, opchars, -1);
-+    }
-+}
-+#endif
-+
- /*
-  * Handle linewise operator "dd", "yy", etc.
-  *
-@@ -8292,6 +8345,7 @@
-     int		n;
-     int		word_end;
-     int		flag = FALSE;
-+    pos_T	startpos = curwin->w_cursor;
- 
-     /*
-      * Set inclusive for the "E" and "e" command.
-@@ -8352,12 +8406,10 @@
-     else
- 	n = fwd_word(cap->count1, cap->arg, cap->oap->op_type != OP_NOP);
- 
--    /* Don't leave the cursor on the NUL past a line */
--    if (curwin->w_cursor.col && gchar_cursor() == NUL)
--    {
--	--curwin->w_cursor.col;
--	cap->oap->inclusive = TRUE;
--    }
-+    /* Don't leave the cursor on the NUL past the end of line. Unless we
-+     * didn't move it forward. */
-+    if (lt(startpos, curwin->w_cursor))
-+	adjust_cursor(cap->oap);
- 
-     if (n == FAIL && cap->oap->op_type == OP_NOP)
- 	clearopbeep(cap->oap);
-@@ -8374,6 +8426,39 @@
- }
- 
- /*
-+ * Used after a movement command: If the cursor ends up on the NUL after the
-+ * end of the line, may move it back to the last character and make the motion
-+ * inclusive.
-+ */
-+    static void
-+adjust_cursor(oap)
-+    oparg_T *oap;
-+{
-+    /* The cursor cannot remain on the NUL when:
-+     * - the column is > 0
-+     * - not in Visual mode or 'selection' is "o"
-+     * - 'virtualedit' is not "all" and not "onemore".
-+     */
-+    if (curwin->w_cursor.col > 0 && gchar_cursor() == NUL
-+#ifdef FEAT_VISUAL
-+		&& (!VIsual_active || *p_sel == 'o')
-+#endif
-+#ifdef FEAT_VIRTUALEDIT
-+		&& !virtual_active() && (ve_flags & VE_ONEMORE) == 0
-+#endif
-+		)
-+    {
-+	--curwin->w_cursor.col;
-+#ifdef FEAT_MBYTE
-+	/* prevent cursor from moving on the trail byte */
-+	if (has_mbyte)
-+	    mb_adjust_cursor();
-+#endif
-+	oap->inclusive = TRUE;
-+    }
-+}
-+
-+/*
-  * "0" and "^" commands.
-  * cap->arg is the argument for beginline().
-  */
-diff -Naur vim71.orig/src/ops.c vim71/src/ops.c
---- vim71.orig/src/ops.c	2007-05-07 15:33:47.000000000 -0400
-+++ vim71/src/ops.c	2008-06-18 06:56:15.000000000 -0400
-@@ -258,7 +258,7 @@
- 	    if (first_char != '#' || !preprocs_left())
- #endif
- 	{
--	    shift_line(oap->op_type == OP_LSHIFT, p_sr, amount);
-+	    shift_line(oap->op_type == OP_LSHIFT, p_sr, amount, FALSE);
- 	}
- 	++curwin->w_cursor.lnum;
-     }
-@@ -321,10 +321,11 @@
-  * leaves cursor on first blank in the line
-  */
-     void
--shift_line(left, round, amount)
-+shift_line(left, round, amount, call_changed_bytes)
-     int	left;
-     int	round;
-     int	amount;
-+    int call_changed_bytes;	/* call changed_bytes() */
- {
-     int		count;
-     int		i, j;
-@@ -363,10 +364,10 @@
-     /* Set new indent */
- #ifdef FEAT_VREPLACE
-     if (State & VREPLACE_FLAG)
--	change_indent(INDENT_SET, count, FALSE, NUL);
-+	change_indent(INDENT_SET, count, FALSE, NUL, call_changed_bytes);
-     else
- #endif
--	(void)set_indent(count, SIN_CHANGED);
-+	(void)set_indent(count, call_changed_bytes ? SIN_CHANGED : 0);
- }
- 
- #if defined(FEAT_VISUALEXTRA) || defined(PROTO)
-@@ -691,6 +692,7 @@
- 	    }
- 	}
- 	++curwin->w_cursor.lnum;
-+	curwin->w_cursor.col = 0;  /* make sure it's valid */
-     }
- 
-     /* put cursor on first non-blank of indented line */
-@@ -927,15 +929,16 @@
-     int		name;
-     int		copy;	/* make a copy, if FALSE make register empty. */
- {
--    static struct yankreg	*reg;
--    int				i;
-+    struct yankreg	*reg;
-+    int			i;
- 
- #ifdef FEAT_CLIPBOARD
-     /* When Visual area changed, may have to update selection.  Obtain the
-      * selection too. */
--    if (name == '*' && clip_star.available && clip_isautosel())
-+    if (name == '*' && clip_star.available)
-     {
--	clip_update_selection();
-+	if (clip_isautosel())
-+	    clip_update_selection();
- 	may_get_selection(name);
-     }
- #endif
-@@ -966,7 +969,7 @@
- }
- 
- /*
-- * Put "reg" into register "name".  Free any previous contents.
-+ * Put "reg" into register "name".  Free any previous contents and "reg".
-  */
-     void
- put_register(name, reg)
-@@ -976,6 +979,7 @@
-     get_yank_register(name, 0);
-     free_yank_all();
-     *y_current = *(struct yankreg *)reg;
-+    vim_free(reg);
- 
- # ifdef FEAT_CLIPBOARD
-     /* Send text written to clipboard register to the clipboard. */
-@@ -2181,6 +2185,8 @@
- }
- #endif
- 
-+static int swapchars __ARGS((int op_type, pos_T *pos, int length));
-+
- /*
-  * Handle the (non-standard vi) tilde operator.  Also for "gu", "gU" and "g?".
-  */
-@@ -2191,9 +2197,8 @@
-     pos_T		pos;
- #ifdef FEAT_VISUAL
-     struct block_def	bd;
--    int			todo;
- #endif
--    int			did_change = 0;
-+    int			did_change = FALSE;
- 
-     if (u_save((linenr_T)(oap->start.lnum - 1),
- 				       (linenr_T)(oap->end.lnum + 1)) == FAIL)
-@@ -2207,16 +2212,8 @@
- 	{
- 	    block_prep(oap, &bd, pos.lnum, FALSE);
- 	    pos.col = bd.textcol;
--	    for (todo = bd.textlen; todo > 0; --todo)
--	    {
--# ifdef FEAT_MBYTE
--		if (has_mbyte)
--		    todo -= (*mb_ptr2len)(ml_get_pos(&pos)) - 1;
--# endif
--		did_change |= swapchar(oap->op_type, &pos);
--		if (inc(&pos) == -1)	    /* at end of file */
--		    break;
--	    }
-+	    did_change = swapchars(oap->op_type, &pos, bd.textlen);
-+
- # ifdef FEAT_NETBEANS_INTG
- 	    if (usingNetbeans && did_change)
- 	    {
-@@ -2246,13 +2243,18 @@
- 	else if (!oap->inclusive)
- 	    dec(&(oap->end));
- 
--	while (ltoreq(pos, oap->end))
--	{
--	    did_change |= swapchar(oap->op_type, &pos);
--	    if (inc(&pos) == -1)    /* at end of file */
--		break;
--	}
--
-+	if (pos.lnum == oap->end.lnum)
-+	    did_change = swapchars(oap->op_type, &pos,
-+						  oap->end.col - pos.col + 1);
-+	else
-+	    for (;;)
-+	    {
-+		did_change |= swapchars(oap->op_type, &pos,
-+				pos.lnum == oap->end.lnum ? oap->end.col + 1:
-+					   (int)STRLEN(ml_get_pos(&pos)));
-+		if (ltoreq(oap->end, pos) || inc(&pos) == -1)
-+		    break;
-+	    }
- 	if (did_change)
- 	{
- 	    changed_lines(oap->start.lnum, oap->start.col, oap->end.lnum + 1,
-@@ -2306,6 +2308,36 @@
- }
- 
- /*
-+ * Invoke swapchar() on "length" bytes at position "pos".
-+ * "pos" is advanced to just after the changed characters.
-+ * "length" is rounded up to include the whole last multi-byte character.
-+ * Also works correctly when the number of bytes changes.
-+ * Returns TRUE if some character was changed.
-+ */
-+    static int
-+swapchars(op_type, pos, length)
-+    int		op_type;
-+    pos_T	*pos;
-+    int		length;
-+{
-+    int todo;
-+    int	did_change = 0;
-+
-+    for (todo = length; todo > 0; --todo)
-+    {
-+# ifdef FEAT_MBYTE
-+	if (has_mbyte)
-+	    /* we're counting bytes, not characters */
-+	    todo -= (*mb_ptr2len)(ml_get_pos(pos)) - 1;
-+# endif
-+	did_change |= swapchar(op_type, pos);
-+	if (inc(pos) == -1)    /* at end of file */
-+	    break;
-+    }
-+    return did_change;
-+}
-+
-+/*
-  * If op_type == OP_UPPER: make uppercase,
-  * if op_type == OP_LOWER: make lowercase,
-  * if op_type == OP_ROT13: do rot13 encoding,
-@@ -2327,7 +2359,8 @@
- 	return FALSE;
- 
- #ifdef FEAT_MBYTE
--    if (op_type == OP_UPPER && enc_latin1like && c == 0xdf)
-+    if (op_type == OP_UPPER && c == 0xdf
-+		      && (enc_latin1like || STRCMP(p_enc, "iso-8859-2") == 0))
-     {
- 	pos_T   sp = curwin->w_cursor;
- 
-@@ -2466,9 +2499,10 @@
- 
-     edit(NUL, FALSE, (linenr_T)count1);
- 
--    /* if user has moved off this line, we don't know what to do, so do
--     * nothing */
--    if (curwin->w_cursor.lnum != oap->start.lnum)
-+    /* If user has moved off this line, we don't know what to do, so do
-+     * nothing.
-+     * Also don't repeat the insert when Insert mode ended with CTRL-C. */
-+    if (curwin->w_cursor.lnum != oap->start.lnum || got_int)
- 	return;
- 
-     if (oap->block_mode)
-@@ -2477,7 +2511,7 @@
- 
- 	/*
- 	 * Spaces and tabs in the indent may have changed to other spaces and
--	 * tabs.  Get the starting column again and correct the lenght.
-+	 * tabs.  Get the starting column again and correct the length.
- 	 * Don't do this when "$" used, end-of-line will have changed.
- 	 */
- 	block_prep(oap, &bd2, oap->start.lnum, TRUE);
-@@ -2534,7 +2568,9 @@
- #ifdef FEAT_VISUALEXTRA
-     long		offset;
-     linenr_T		linenr;
--    long		ins_len, pre_textlen = 0;
-+    long		ins_len;
-+    long		pre_textlen = 0;
-+    long		pre_indent = 0;
-     char_u		*firstline;
-     char_u		*ins_text, *newp, *oldp;
-     struct block_def	bd;
-@@ -2579,7 +2615,9 @@
- 						    || gchar_cursor() == NUL))
- 	    coladvance_force(getviscol());
- # endif
--	pre_textlen = (long)STRLEN(ml_get(oap->start.lnum));
-+	firstline = ml_get(oap->start.lnum);
-+	pre_textlen = (long)STRLEN(firstline);
-+	pre_indent = (long)(skipwhite(firstline) - firstline);
- 	bd.textcol = curwin->w_cursor.col;
-     }
- #endif
-@@ -2595,16 +2633,26 @@
-     /*
-      * In Visual block mode, handle copying the new text to all lines of the
-      * block.
-+     * Don't repeat the insert when Insert mode ended with CTRL-C.
-      */
--    if (oap->block_mode && oap->start.lnum != oap->end.lnum)
-+    if (oap->block_mode && oap->start.lnum != oap->end.lnum && !got_int)
-     {
-+	/* Auto-indenting may have changed the indent.  If the cursor was past
-+	 * the indent, exclude that indent change from the inserted text. */
- 	firstline = ml_get(oap->start.lnum);
--	/*
--	 * Subsequent calls to ml_get() flush the firstline data - take a
--	 * copy of the required bit.
--	 */
--	if ((ins_len = (long)STRLEN(firstline) - pre_textlen) > 0)
-+	if (bd.textcol > (colnr_T)pre_indent)
-+	{
-+	    long new_indent = (long)(skipwhite(firstline) - firstline);
-+
-+	    pre_textlen += new_indent - pre_indent;
-+	    bd.textcol += new_indent - pre_indent;
-+	}
-+
-+	ins_len = (long)STRLEN(firstline) - pre_textlen;
-+	if (ins_len > 0)
- 	{
-+	    /* Subsequent calls to ml_get() flush the firstline data - take a
-+	     * copy of the inserted text.  */
- 	    if ((ins_text = alloc_check((unsigned)(ins_len + 1))) != NULL)
- 	    {
- 		vim_strncpy(ins_text, firstline + bd.textcol, (size_t)ins_len);
-@@ -3404,7 +3452,9 @@
- 
- #ifdef FEAT_VIRTUALEDIT
- 	col += curwin->w_cursor.coladd;
--	if (ve_flags == VE_ALL && curwin->w_cursor.coladd > 0)
-+	if (ve_flags == VE_ALL
-+		&& (curwin->w_cursor.coladd > 0
-+		    || endcol2 == curwin->w_cursor.col))
- 	{
- 	    if (dir == FORWARD && c == NUL)
- 		++col;
-@@ -4330,7 +4380,7 @@
-     if (keep_cursor)
- 	saved_cursor = oap->cursor_start;
- 
--    format_lines(oap->line_count);
-+    format_lines(oap->line_count, keep_cursor);
- 
-     /*
-      * Leave the cursor at the first non-blank of the last formatted line.
-@@ -4445,8 +4495,9 @@
-  * first line.
-  */
-     void
--format_lines(line_count)
-+format_lines(line_count, avoid_fex)
-     linenr_T	line_count;
-+    int		avoid_fex;		/* don't use 'formatexpr' */
- {
-     int		max_len;
-     int		is_not_par;		/* current line not part of parag. */
-@@ -4616,7 +4667,7 @@
- #ifdef FEAT_COMMENTS
- 			+ (do_comments ? INSCHAR_DO_COM : 0)
- #endif
--			, second_indent);
-+			+ (avoid_fex ? INSCHAR_NO_FEX : 0), second_indent);
- 		State = old_State;
- 		p_smd = smd_save;
- 		second_indent = -1;
-diff -Naur vim71.orig/src/option.c vim71/src/option.c
---- vim71.orig/src/option.c	2007-05-01 07:26:10.000000000 -0400
-+++ vim71/src/option.c	2008-06-18 06:57:01.000000000 -0400
-@@ -243,7 +243,8 @@
- /* WV_ and BV_ values get typecasted to this for the "indir" field */
- typedef enum
- {
--    PV_NONE = 0
-+    PV_NONE = 0,
-+    PV_MAXVAL = 0xffff    /* to avoid warnings for value out of range */
- } idopt_T;
- 
- /*
-@@ -427,6 +428,8 @@
- #define P_NOGLOB       0x100000L/* do not use local value for global vimrc */
- #define P_NFNAME       0x200000L/* only normal file name chars allowed */
- #define P_INSECURE     0x400000L/* option was set from a modeline */
-+#define P_PRI_MKRC     0x800000L/* priority for :mkvimrc (setting option has
-+				   side effects) */
- 
- #define ISK_LATIN1  (char_u *)"@,48-57,_,192-255"
- 
-@@ -773,6 +776,8 @@
- 			    {(char_u *)0L, (char_u *)0L}
- #endif
- 			    },
-+			    /* P_PRI_MKRC isn't needed here, optval_default()
-+			     * always returns TRUE for 'compatible' */
-     {"compatible",  "cp",   P_BOOL|P_RALL,
- 			    (char_u *)&p_cp, PV_NONE,
- 			    {(char_u *)TRUE, (char_u *)FALSE}},
-@@ -1515,7 +1520,7 @@
- 			    {(char_u *)0L, (char_u *)0L}
- #endif
- 			    },
--    {"keymap",	    "kmp",  P_STRING|P_ALLOCED|P_VI_DEF|P_RBUF|P_RSTAT|P_NFNAME,
-+    {"keymap",	    "kmp",  P_STRING|P_ALLOCED|P_VI_DEF|P_RBUF|P_RSTAT|P_NFNAME|P_PRI_MKRC,
- #ifdef FEAT_KEYMAP
- 			    (char_u *)&p_keymap, PV_KMAP,
- 			    {(char_u *)"", (char_u *)0L}
-@@ -1835,8 +1840,9 @@
- 			    },
-     {"paragraphs",  "para", P_STRING|P_VI_DEF,
- 			    (char_u *)&p_para, PV_NONE,
--			    {(char_u *)"IPLPPPQPP LIpplpipbp", (char_u *)0L}},
--    {"paste",	    NULL,   P_BOOL|P_VI_DEF,
-+			    {(char_u *)"IPLPPPQPP TPHPLIPpLpItpplpipbp",
-+				(char_u *)0L}},
-+    {"paste",	    NULL,   P_BOOL|P_VI_DEF|P_PRI_MKRC,
- 			    (char_u *)&p_paste, PV_NONE,
- 			    {(char_u *)FALSE, (char_u *)0L}},
-     {"pastetoggle", "pt",   P_STRING|P_VI_DEF,
-@@ -1987,6 +1993,13 @@
-     {"redraw",	    NULL,   P_BOOL|P_VI_DEF,
- 			    (char_u *)NULL, PV_NONE,
- 			    {(char_u *)FALSE, (char_u *)0L}},
-+    {"redrawtime",  "rdt",  P_NUM|P_VI_DEF,
-+#ifdef FEAT_RELTIME
-+			    (char_u *)&p_rdt, PV_NONE,
-+#else
-+			    (char_u *)NULL, PV_NONE,
-+#endif
-+			    {(char_u *)2000L, (char_u *)0L}},
-     {"remap",	    NULL,   P_BOOL|P_VI_DEF,
- 			    (char_u *)&p_remap, PV_NONE,
- 			    {(char_u *)TRUE, (char_u *)0L}},
-@@ -4628,7 +4641,7 @@
- 				    if ((!(flags & P_COMMA) || *s != ',')
- 					    && vim_strchr(s + 1, *s) != NULL)
- 				    {
--					STRCPY(s, s + 1);
-+					mch_memmove(s, s + 1, STRLEN(s));
- 					--s;
- 				    }
- 			    }
-@@ -4992,7 +5005,7 @@
-      * For 'spellsuggest' expand after "file:".
-      */
-     expand_env_esc(val, NameBuff, MAXPATHL,
--	    (char_u **)options[opt_idx].var == &p_tags,
-+	    (char_u **)options[opt_idx].var == &p_tags, FALSE,
- #ifdef FEAT_SPELL
- 	    (char_u **)options[opt_idx].var == &p_sps ? (char_u *)"file:" :
- #endif
-@@ -5660,7 +5673,7 @@
-     {
- 	if (gvarp == &p_fenc)
- 	{
--	    if (!curbuf->b_p_ma)
-+	    if (!curbuf->b_p_ma && opt_flags != OPT_GLOBAL)
- 		errmsg = e_modifiable;
- 	    else if (vim_strchr(*varp, ',') != NULL)
- 		/* No comma allowed in 'fileencoding'; catches confusing it
-@@ -6348,7 +6361,7 @@
- 		errmsg = check_stl_option(p_ruf);
- 	}
- 	/* check 'statusline' only if it doesn't start with "%!" */
--	else if (varp != &p_stl || s[0] != '%' || s[1] != '!')
-+	else if (varp == &p_ruf || s[0] != '%' || s[1] != '!')
- 	    errmsg = check_stl_option(s);
- 	if (varp == &p_ruf && errmsg == NULL)
- 	    comp_col();
-@@ -7118,6 +7131,11 @@
-     /* when 'endofline' is changed, redraw the window title */
-     else if ((int *)varp == &curbuf->b_p_eol)
- 	need_maketitle = TRUE;
-+#ifdef FEAT_MBYTE
-+    /* when 'bomb' is changed, redraw the window title */
-+    else if ((int *)varp == &curbuf->b_p_bomb)
-+	need_maketitle = TRUE;
-+#endif
- #endif
- 
-     /* when 'bin' is set also set some other options */
-@@ -7815,6 +7833,8 @@
- 	    errmsg = e_positive;
- 	    p_ch = 1;
- 	}
-+	if (p_ch > Rows - min_rows() + 1)
-+	    p_ch = Rows - min_rows() + 1;
- 
- 	/* Only compute the new window layout when startup has been
- 	 * completed. Otherwise the frame sizes may be wrong. */
-@@ -8219,6 +8239,25 @@
- 	    varp = get_varp(&options[opt_idx]);
- 	    if (varp != NULL)	/* hidden option is not changed */
- 	    {
-+		if (number == 0 && string != NULL)
-+		{
-+		    int index;
-+
-+		    /* Either we are given a string or we are setting option
-+		     * to zero. */
-+		    for (index = 0; string[index] == '0'; ++index)
-+			;
-+		    if (string[index] != NUL || index == 0)
-+		    {
-+			/* There's another character after zeros or the string
-+			 * is empty.  In both cases, we are trying to set a
-+			 * num option using a string. */
-+			EMSG3(_("E521: Number required: &%s = '%s'"),
-+								name, string);
-+			return;     /* do nothing as we hit an error */
-+
-+		    }
-+		}
- 		if (flags & P_NUM)
- 		    (void)set_num_option(opt_idx, varp, number,
- 							  NULL, 0, opt_flags);
-@@ -8511,13 +8550,20 @@
-     char_u		*varp_local = NULL;	/* fresh value */
-     char		*cmd;
-     int			round;
-+    int			pri;
- 
-     /*
-      * The options that don't have a default (terminal name, columns, lines)
-      * are never written.  Terminal options are also not written.
-+     * Do the loop over "options[]" twice: once for options with the
-+     * P_PRI_MKRC flag and once without.
-      */
--    for (p = &options[0]; !istermoption(p); p++)
--	if (!(p->flags & P_NO_MKRC) && !istermoption(p))
-+    for (pri = 1; pri >= 0; --pri)
-+    {
-+      for (p = &options[0]; !istermoption(p); p++)
-+	if (!(p->flags & P_NO_MKRC)
-+		&& !istermoption(p)
-+		&& ((pri == 1) == ((p->flags & P_PRI_MKRC) != 0)))
- 	{
- 	    /* skip global option when only doing locals */
- 	    if (p->indir == PV_NONE && !(opt_flags & OPT_GLOBAL))
-@@ -8613,6 +8659,7 @@
- 		}
- 	    }
- 	}
-+    }
-     return OK;
- }
- 
-@@ -8667,7 +8714,7 @@
- 	{
- 	    s = *valuep;
- 	    while (*s != NUL)
--		if (fputs((char *)str2special(&s, FALSE), fd) < 0)
-+		if (put_escstr(fd, str2special(&s, FALSE), 2) == FAIL)
- 		    return FAIL;
- 	}
- 	else if (expand)
-@@ -8715,6 +8762,8 @@
-     char	*name;
-     int		value;
- {
-+    if (value < 0)	/* global/local option using global value */
-+	return OK;
-     if (fprintf(fd, "%s %s%s", cmd, value ? "" : "no", name) < 0
- 	    || put_eol(fd) < 0)
- 	return FAIL;
-@@ -10585,6 +10634,8 @@
-     buf->b_start_ffc = *buf->b_p_ff;
-     buf->b_start_eol = buf->b_p_eol;
- #ifdef FEAT_MBYTE
-+    buf->b_start_bomb = buf->b_p_bomb;
-+
-     /* Only use free/alloc when necessary, they take time. */
-     if (buf->b_start_fenc == NULL
- 			     || STRCMP(buf->b_start_fenc, buf->b_p_fenc) != 0)
-@@ -10598,13 +10649,17 @@
- /*
-  * Return TRUE if 'fileformat' and/or 'fileencoding' has a different value
-  * from when editing started (save_file_ff() called).
-- * Also when 'endofline' was changed and 'binary' is set.
-+ * Also when 'endofline' was changed and 'binary' is set, or when 'bomb' was
-+ * changed and 'binary' is not set.
-  * Don't consider a new, empty buffer to be changed.
-  */
-     int
- file_ff_differs(buf)
-     buf_T	*buf;
- {
-+    /* In a buffer that was never loaded the options are not valid. */
-+    if (buf->b_flags & BF_NEVERLOADED)
-+	return FALSE;
-     if ((buf->b_flags & BF_NEW)
- 	    && buf->b_ml.ml_line_count == 1
- 	    && *ml_get_buf(buf, (linenr_T)1, FALSE) == NUL)
-@@ -10614,6 +10669,8 @@
-     if (buf->b_p_bin && buf->b_start_eol != buf->b_p_eol)
- 	return TRUE;
- #ifdef FEAT_MBYTE
-+    if (!buf->b_p_bin && buf->b_start_bomb != buf->b_p_bomb)
-+	return TRUE;
-     if (buf->b_start_fenc == NULL)
- 	return (*buf->b_p_fenc != NUL);
-     return (STRCMP(buf->b_start_fenc, buf->b_p_fenc) != 0);
-diff -Naur vim71.orig/src/option.h vim71/src/option.h
---- vim71.orig/src/option.h	2007-05-07 15:23:03.000000000 -0400
-+++ vim71/src/option.h	2008-06-18 06:55:25.000000000 -0400
-@@ -633,6 +633,9 @@
- #ifdef FEAT_SEARCHPATH
- EXTERN char_u	*p_cdpath;	/* 'cdpath' */
- #endif
-+#ifdef FEAT_RELTIME
-+EXTERN long	p_rdt;		/* 'redrawtime' */
-+#endif
- EXTERN int	p_remap;	/* 'remap' */
- EXTERN long	p_report;	/* 'report' */
- #if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
-diff -Naur vim71.orig/src/os_unix.c vim71/src/os_unix.c
---- vim71.orig/src/os_unix.c	2007-05-09 15:41:58.000000000 -0400
-+++ vim71/src/os_unix.c	2008-06-18 06:56:39.000000000 -0400
-@@ -45,6 +45,11 @@
- # include <X11/SM/SMlib.h>
- #endif
- 
-+#ifdef HAVE_SELINUX
-+# include <selinux/selinux.h>
-+static int selinux_enabled = -1;
-+#endif
-+
- /*
-  * Use this prototype for select, some include files have a wrong prototype
-  */
-@@ -195,6 +200,7 @@
- static int	show_shell_mess = TRUE;
- #endif
- static int	deadly_signal = 0;	    /* The signal we caught */
-+static int	in_mch_delay = FALSE;	    /* sleeping in mch_delay() */
- 
- static int curr_tmode = TMODE_COOK;	/* contains current terminal mode */
- 
-@@ -268,8 +274,9 @@
- #ifdef SIGVTALRM
-     {SIGVTALRM,	    "VTALRM",	TRUE},
- #endif
--#if defined(SIGPROF) && !defined(FEAT_MZSCHEME)
--    /* MzScheme uses SIGPROF for its own needs */
-+#if defined(SIGPROF) && !defined(FEAT_MZSCHEME) && !defined(WE_ARE_PROFILING)
-+    /* MzScheme uses SIGPROF for its own needs; On Linux with profiling
-+     * this makes Vim exit.  WE_ARE_PROFILING is defined in Makefile.  */
-     {SIGPROF,	    "PROF",	TRUE},
- #endif
- #ifdef SIGXCPU
-@@ -310,7 +317,7 @@
- }
- 
- /*
-- * mch_inchar(): low level input funcion.
-+ * mch_inchar(): low level input function.
-  * Get a characters from the keyboard.
-  * Return the number of characters that are available.
-  * If wtime == 0 do not wait for characters.
-@@ -538,7 +545,9 @@
-     if (ignoreinput)
-     {
- 	/* Go to cooked mode without echo, to allow SIGINT interrupting us
--	 * here */
-+	 * here.  But we don't want QUIT to kill us (CTRL-\ used in a
-+	 * shell may produce SIGQUIT). */
-+	in_mch_delay = TRUE;
- 	old_tmode = curr_tmode;
- 	if (curr_tmode == TMODE_RAW)
- 	    settmode(TMODE_SLEEP);
-@@ -602,6 +611,7 @@
- #endif
- 
- 	settmode(old_tmode);
-+	in_mch_delay = FALSE;
-     }
-     else
- 	WaitForChar(msec);
-@@ -753,7 +763,8 @@
-     if (signal_stack != NULL)
-     {
- # ifdef HAVE_SIGALTSTACK
--#  ifdef __APPLE__
-+#  if defined(__APPLE__) && (!defined(MAC_OS_X_VERSION_MAX_ALLOWED) \
-+		|| MAC_OS_X_VERSION_MAX_ALLOWED <= 1040)
- 	/* missing prototype.  Adding it to osdef?.h.in doesn't work, because
- 	 * "struct sigaltstack" needs to be declared. */
- 	extern int sigaltstack __ARGS((const struct sigaltstack *ss, struct sigaltstack *oss));
-@@ -921,6 +932,14 @@
- #endif
- 
- #ifdef SIGHASARG
-+# ifdef SIGQUIT
-+    /* While in mch_delay() we go to cooked mode to allow a CTRL-C to
-+     * interrupt us.  But in cooked mode we may also get SIGQUIT, e.g., when
-+     * pressing CTRL-\, but we don't want Vim to exit then. */
-+    if (in_mch_delay && sigarg == SIGQUIT)
-+	SIGRETURN;
-+# endif
-+
-     /* When SIGHUP, SIGQUIT, etc. are blocked: postpone the effect and return
-      * here.  This avoids that a non-reentrant function is interrupted, e.g.,
-      * free().  Calling free() again may then cause a crash. */
-@@ -1566,18 +1585,19 @@
- #ifdef FEAT_XCLIPBOARD
-     if (xterm_dpy != NULL && x11_window != 0)
-     {
--	/* Checked it already. */
--	if (x11_display_from == XD_XTERM)
--	    return OK;
--
--	/*
--	 * If the X11 display was opened here before, for the window where Vim
--	 * was started, close that one now to avoid a memory leak.
--	 */
--	if (x11_display_from == XD_HERE && x11_display != NULL)
--	    XCloseDisplay(x11_display);
--	x11_display = xterm_dpy;
--	x11_display_from = XD_XTERM;
-+	/* We may have checked it already, but Gnome terminal can move us to
-+	 * another window, so we need to check every time. */
-+	if (x11_display_from != XD_XTERM)
-+	{
-+	    /*
-+	     * If the X11 display was opened here before, for the window where
-+	     * Vim was started, close that one now to avoid a memory leak.
-+	     */
-+	    if (x11_display_from == XD_HERE && x11_display != NULL)
-+		XCloseDisplay(x11_display);
-+	    x11_display = xterm_dpy;
-+	    x11_display_from = XD_XTERM;
-+	}
- 	if (test_x11_window(x11_display) == FAIL)
- 	{
- 	    /* probably bad $WINDOWID */
-@@ -2420,7 +2440,7 @@
- /*
-  * Set the case of the file name, if it already exists.  This will cause the
-  * file name to remain exactly the same.
-- * Only required for file systems where case is ingored and preserved.
-+ * Only required for file systems where case is ignored and preserved.
-  */
- /*ARGSUSED*/
-     void
-@@ -2499,7 +2519,13 @@
-     if (stat((char *)name, &statb))
- #endif
- 	return -1;
-+#ifdef __INTERIX
-+    /* The top bit makes the value negative, which means the file doesn't
-+     * exist.  Remove the bit, we don't use it. */
-+    return statb.st_mode & ~S_ADDACE;
-+#else
-     return statb.st_mode;
-+#endif
- }
- 
- /*
-@@ -2536,6 +2562,62 @@
- } vim_acl_solaris_T;
- # endif
- 
-+#if defined(HAVE_SELINUX) || defined(PROTO)
-+/*
-+ * Copy security info from "from_file" to "to_file".
-+ */
-+    void
-+mch_copy_sec(from_file, to_file)
-+    char_u	*from_file;
-+    char_u	*to_file;
-+{
-+    if (from_file == NULL)
-+	return;
-+
-+    if (selinux_enabled == -1)
-+	selinux_enabled = is_selinux_enabled();
-+
-+    if (selinux_enabled > 0)
-+    {
-+	security_context_t from_context = NULL;
-+	security_context_t to_context = NULL;
-+
-+	if (getfilecon((char *)from_file, &from_context) < 0)
-+	{
-+	    /* If the filesystem doesn't support extended attributes,
-+	       the original had no special security context and the
-+	       target cannot have one either.  */
-+	    if (errno == EOPNOTSUPP)
-+		return;
-+
-+	    MSG_PUTS(_("\nCould not get security context for "));
-+	    msg_outtrans(from_file);
-+	    msg_putchar('\n');
-+	    return;
-+	}
-+	if (getfilecon((char *)to_file, &to_context) < 0)
-+	{
-+	    MSG_PUTS(_("\nCould not get security context for "));
-+	    msg_outtrans(to_file);
-+	    msg_putchar('\n');
-+	    freecon (from_context);
-+	    return ;
-+	}
-+	if (strcmp(from_context, to_context) != 0)
-+	{
-+	    if (setfilecon((char *)to_file, from_context) < 0)
-+	    {
-+		MSG_PUTS(_("\nCould not set security context for "));
-+		msg_outtrans(to_file);
-+		msg_putchar('\n');
-+	    }
-+	}
-+	freecon(to_context);
-+	freecon(from_context);
-+    }
-+}
-+#endif /* HAVE_SELINUX */
-+
- /*
-  * Return a pointer to the ACL of file "fname" in allocated memory.
-  * Return NULL if the ACL is not available for whatever reason.
-@@ -4646,7 +4728,7 @@
- 	ret = poll(fds, nfd, towait);
- # ifdef FEAT_MZSCHEME
- 	if (ret == 0 && mzquantum_used)
--	    /* MzThreads scheduling is required and timeout occured */
-+	    /* MzThreads scheduling is required and timeout occurred */
- 	    finished = FALSE;
- # endif
- 
-@@ -4794,7 +4876,7 @@
- #endif
- # ifdef FEAT_MZSCHEME
- 	if (ret == 0 && mzquantum_used)
--	    /* loop if MzThreads must be scheduled and timeout occured */
-+	    /* loop if MzThreads must be scheduled and timeout occurred */
- 	    finished = FALSE;
- # endif
- 
-@@ -4938,6 +5020,9 @@
-     char_u	*p;
-     int		dir;
- #ifdef __EMX__
-+    /*
-+     * This is the OS/2 implementation.
-+     */
- # define EXPL_ALLOC_INC	16
-     char_u	**expl_files;
-     size_t	files_alloced, files_free;
-@@ -5048,20 +5133,26 @@
-     return OK;
- 
- #else /* __EMX__ */
--
-+    /*
-+     * This is the non-OS/2 implementation (really Unix).
-+     */
-     int		j;
-     char_u	*tempname;
-     char_u	*command;
-     FILE	*fd;
-     char_u	*buffer;
--#define STYLE_ECHO  0	    /* use "echo" to expand */
--#define STYLE_GLOB  1	    /* use "glob" to expand, for csh */
--#define STYLE_PRINT 2	    /* use "print -N" to expand, for zsh */
--#define STYLE_BT    3	    /* `cmd` expansion, execute the pattern directly */
-+#define STYLE_ECHO	0	/* use "echo", the default */
-+#define STYLE_GLOB	1	/* use "glob", for csh */
-+#define STYLE_VIMGLOB	2	/* use "vimglob", for Posix sh */
-+#define STYLE_PRINT	3	/* use "print -N", for zsh */
-+#define STYLE_BT	4	/* `cmd` expansion, execute the pattern
-+				 * directly */
-     int		shell_style = STYLE_ECHO;
-     int		check_spaces;
-     static int	did_find_nul = FALSE;
-     int		ampersent = FALSE;
-+		/* vimglob() function to define for Posix shell */
-+    static char *sh_vimglob_func = "vimglob() { while [ $# -ge 1 ]; do echo -n \"$1\"; echo; shift; done }; vimglob >";
- 
-     *num_file = 0;	/* default: no files found */
-     *file = NULL;
-@@ -5099,9 +5190,17 @@
- 
-     /*
-      * Let the shell expand the patterns and write the result into the temp
--     * file.  if expanding `cmd` execute it directly.
--     * If we use csh, glob will work better than echo.
--     * If we use zsh, print -N will work better than glob.
-+     * file.
-+     * STYLE_BT:	NL separated
-+     *	    If expanding `cmd` execute it directly.
-+     * STYLE_GLOB:	NUL separated
-+     *	    If we use *csh, "glob" will work better than "echo".
-+     * STYLE_PRINT:	NL or NUL separated
-+     *	    If we use *zsh, "print -N" will work better than "glob".
-+     * STYLE_VIMGLOB:	NL separated
-+     *	    If we use *sh*, we define "vimglob()".
-+     * STYLE_ECHO:	space separated.
-+     *	    A shell we don't know, stay safe and use "echo".
-      */
-     if (num_pat == 1 && *pat[0] == '`'
- 	    && (len = STRLEN(pat[0])) > 2
-@@ -5114,9 +5213,17 @@
- 	else if (STRCMP(p_sh + len - 3, "zsh") == 0)
- 	    shell_style = STYLE_PRINT;
-     }
--
--    /* "unset nonomatch; print -N >" plus two is 29 */
-+    if (shell_style == STYLE_ECHO && strstr((char *)gettail(p_sh),
-+								"sh") != NULL)
-+	shell_style = STYLE_VIMGLOB;
-+
-+    /* Compute the length of the command.  We need 2 extra bytes: for the
-+     * optional '&' and for the NUL.
-+     * Worst case: "unset nonomatch; print -N >" plus two is 29 */
-     len = STRLEN(tempname) + 29;
-+    if (shell_style == STYLE_VIMGLOB)
-+	len += STRLEN(sh_vimglob_func);
-+
-     for (i = 0; i < num_pat; ++i)
-     {
- 	/* Count the length of the patterns in the same way as they are put in
-@@ -5175,16 +5282,20 @@
- 	    STRCAT(command, "glob >");
- 	else if (shell_style == STYLE_PRINT)
- 	    STRCAT(command, "print -N >");
-+	else if (shell_style == STYLE_VIMGLOB)
-+	    STRCAT(command, sh_vimglob_func);
- 	else
- 	    STRCAT(command, "echo >");
-     }
-+
-     STRCAT(command, tempname);
-+
-     if (shell_style != STYLE_BT)
- 	for (i = 0; i < num_pat; ++i)
- 	{
- 	    /* When using system() always add extra quotes, because the shell
- 	     * is started twice.  Otherwise put a backslash before special
--	     * characters, except insice ``. */
-+	     * characters, except inside ``. */
- #ifdef USE_SYSTEM
- 	    STRCAT(command, " \"");
- 	    STRCAT(command, pat[i]);
-@@ -5224,8 +5335,7 @@
-     if (flags & EW_SILENT)
- 	show_shell_mess = FALSE;
-     if (ampersent)
--	STRCAT(command, "&");		/* put the '&' back after the
--					   redirection */
-+	STRCAT(command, "&");		/* put the '&' after the redirection */
- 
-     /*
-      * Using zsh -G: If a pattern has no matches, it is just deleted from
-@@ -5257,7 +5367,7 @@
-     show_shell_mess = TRUE;
-     vim_free(command);
- 
--    if (i)				/* mch_call_shell() failed */
-+    if (i != 0)				/* mch_call_shell() failed */
-     {
- 	mch_remove(tempname);
- 	vim_free(tempname);
-@@ -5328,7 +5438,7 @@
-     }
-     vim_free(tempname);
- 
--#if defined(__CYGWIN__) || defined(__CYGWIN32__)
-+# if defined(__CYGWIN__) || defined(__CYGWIN32__)
-     /* Translate <CR><NL> into <NL>.  Caution, buffer may contain NUL. */
-     p = buffer;
-     for (i = 0; i < len; ++i)
-@@ -5351,7 +5461,7 @@
- 	}
-     }
-     /* file names are separated with NL */
--    else if (shell_style == STYLE_BT)
-+    else if (shell_style == STYLE_BT || shell_style == STYLE_VIMGLOB)
-     {
- 	buffer[len] = NUL;		/* make sure the buffer ends in NUL */
- 	p = buffer;
-@@ -5430,7 +5540,8 @@
-     {
- 	(*file)[i] = p;
- 	/* Space or NL separates */
--	if (shell_style == STYLE_ECHO || shell_style == STYLE_BT)
-+	if (shell_style == STYLE_ECHO || shell_style == STYLE_BT
-+					      || shell_style == STYLE_VIMGLOB)
- 	{
- 	    while (!(shell_style == STYLE_ECHO && *p == ' ')
- 						   && *p != '\n' && *p != NUL)
-@@ -5474,7 +5585,7 @@
- 	{
- 	    STRCPY(p, (*file)[i]);
- 	    if (dir)
--		STRCAT(p, "/");	    /* add '/' to a directory name */
-+		add_pathsep(p);	    /* add '/' to a directory name */
- 	    (*file)[j++] = p;
- 	}
-     }
-@@ -5668,7 +5779,7 @@
- 	    /* gpm library tries to handling TSTP causes
- 	     * problems. Anyways, we close connection to Gpm whenever
- 	     * we are going to suspend or starting an external process
--	     * so we should'nt  have problem with this
-+	     * so we shouldn't  have problem with this
- 	     */
- 	    signal(SIGTSTP, restricted ? SIG_IGN : SIG_DFL);
- 	    return 1; /* succeed */
-@@ -5682,7 +5793,7 @@
- 
- /*
-  * Closes connection to gpm
-- * returns non-zero if connection succesfully closed
-+ * returns non-zero if connection successfully closed
-  */
-     static void
- gpm_close()
-@@ -6108,9 +6219,9 @@
-     if (xterm_trace == 1)
-     {
- 	/* Get the hints just before tracking starts.  The font size might
--	 * have changed recently */
--	XGetWMNormalHints(xterm_dpy, x11_window, &xterm_hints, &got_hints);
--	if (!(got_hints & PResizeInc)
-+	 * have changed recently. */
-+	if (!XGetWMNormalHints(xterm_dpy, x11_window, &xterm_hints, &got_hints)
-+		|| !(got_hints & PResizeInc)
- 		|| xterm_hints.width_inc <= 1
- 		|| xterm_hints.height_inc <= 1)
- 	{
-diff -Naur vim71.orig/src/os_unix.h vim71/src/os_unix.h
---- vim71.orig/src/os_unix.h	2007-05-07 15:35:05.000000000 -0400
-+++ vim71/src/os_unix.h	2008-06-18 06:51:07.000000000 -0400
-@@ -508,6 +508,9 @@
- #if !defined(S_ISFIFO) && defined(S_IFIFO)
- # define	S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
- #endif
-+#if !defined(S_ISCHR) && defined(S_IFCHR)
-+# define	S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
-+#endif
- 
- /* Note: Some systems need both string.h and strings.h (Savage).  However,
-  * some systems can't handle both, only use string.h in that case. */
-diff -Naur vim71.orig/src/popupmnu.c vim71/src/popupmnu.c
---- vim71.orig/src/popupmnu.c	2007-03-24 16:07:39.000000000 -0400
-+++ vim71/src/popupmnu.c	2008-06-18 06:51:46.000000000 -0400
-@@ -75,7 +75,6 @@
- 
-     row = curwin->w_cline_row + W_WINROW(curwin);
-     height = curwin->w_cline_height;
--    col = curwin->w_wcol + W_WINCOL(curwin) - curwin->w_leftcol;
- 
-     if (firstwin->w_p_pvw)
- 	top_clear = firstwin->w_height;
-@@ -167,6 +166,15 @@
-     pum_base_width = max_width;
-     pum_kind_width = kind_width;
- 
-+    /* Calculate column */
-+#ifdef FEAT_RIGHTLEFT
-+    if (curwin->w_p_rl)
-+	col = W_WINCOL(curwin) + W_WIDTH(curwin) - curwin->w_wcol -
-+							curwin->w_leftcol - 1;
-+    else
-+#endif
-+	col = W_WINCOL(curwin) + curwin->w_wcol - curwin->w_leftcol;
-+
-     /* if there are more items than room we need a scrollbar */
-     if (pum_height < size)
-     {
-@@ -179,11 +187,23 @@
-     if (def_width < max_width)
- 	def_width = max_width;
- 
--    if (col < Columns - PUM_DEF_WIDTH || col < Columns - max_width)
-+    if (((col < Columns - PUM_DEF_WIDTH || col < Columns - max_width)
-+#ifdef FEAT_RIGHTLEFT
-+		&& !curwin->w_p_rl)
-+	    || (curwin->w_p_rl && (col > PUM_DEF_WIDTH || col > max_width)
-+#endif
-+       ))
-     {
- 	/* align pum column with "col" */
- 	pum_col = col;
--	pum_width = Columns - pum_col - pum_scrollbar;
-+
-+#ifdef FEAT_RIGHTLEFT
-+	if (curwin->w_p_rl)
-+	    pum_width = pum_col - pum_scrollbar + 1;
-+	else
-+#endif
-+	    pum_width = Columns - pum_col - pum_scrollbar;
-+
- 	if (pum_width > max_width + kind_width + extra_width + 1
- 						 && pum_width > PUM_DEF_WIDTH)
- 	{
-@@ -195,14 +215,24 @@
-     else if (Columns < def_width)
-     {
- 	/* not enough room, will use what we have */
--	pum_col = 0;
-+#ifdef FEAT_RIGHTLEFT
-+	if (curwin->w_p_rl)
-+	    pum_col = Columns - 1;
-+	else
-+#endif
-+	    pum_col = 0;
- 	pum_width = Columns - 1;
-     }
-     else
-     {
- 	if (max_width > PUM_DEF_WIDTH)
- 	    max_width = PUM_DEF_WIDTH;	/* truncate */
--	pum_col = Columns - max_width;
-+#ifdef FEAT_RIGHTLEFT
-+	if (curwin->w_p_rl)
-+	    pum_col = max_width - 1;
-+	else
-+#endif
-+	    pum_col = Columns - max_width;
- 	pum_width = max_width - pum_scrollbar;
-     }
- 
-@@ -255,8 +285,16 @@
- 	attr = (idx == pum_selected) ? attr_select : attr_norm;
- 
- 	/* prepend a space if there is room */
--	if (pum_col > 0)
--	    screen_putchar(' ', row, pum_col - 1, attr);
-+#ifdef FEAT_RIGHTLEFT
-+	if (curwin->w_p_rl)
-+	{
-+	    if (pum_col < W_WINCOL(curwin) + W_WIDTH(curwin) - 1)
-+		screen_putchar(' ', row, pum_col + 1, attr);
-+	}
-+	else
-+#endif
-+	    if (pum_col > 0)
-+		screen_putchar(' ', row, pum_col - 1, attr);
- 
- 	/* Display each entry, use two spaces for a Tab.
- 	 * Do this 3 times: For the main text, kind and extra info */
-@@ -282,26 +320,67 @@
- 		    {
- 			/* Display the text that fits or comes before a Tab.
- 			 * First convert it to printable characters. */
--			char_u *st;
--			int  saved = *p;
-+			char_u	*st;
-+			int	saved = *p;
- 
- 			*p = NUL;
- 			st = transstr(s);
- 			*p = saved;
--			if (st != NULL)
-+#ifdef FEAT_RIGHTLEFT
-+			if (curwin->w_p_rl)
- 			{
--			    screen_puts_len(st, (int)STRLEN(st), row, col,
-+			    if (st != NULL)
-+			    {
-+				char_u	*rt = reverse_text(st);
-+				char_u	*rt_saved = rt;
-+				int	len, j;
-+
-+				if (rt != NULL)
-+				{
-+				    len = STRLEN(rt);
-+				    if (len > pum_width)
-+				    {
-+					for (j = pum_width; j < len; ++j)
-+					    mb_ptr_adv(rt);
-+					len = pum_width;
-+				    }
-+				    screen_puts_len(rt, len, row,
-+							col - len + 1, attr);
-+				    vim_free(rt_saved);
-+				}
-+				vim_free(st);
-+			    }
-+			    col -= width;
-+			}
-+			else
-+#endif
-+			{
-+			    if (st != NULL)
-+			    {
-+				screen_puts_len(st, (int)STRLEN(st), row, col,
- 									attr);
--			    vim_free(st);
-+				vim_free(st);
-+			    }
-+			    col += width;
- 			}
--			col += width;
- 
- 			if (*p != TAB)
- 			    break;
- 
- 			/* Display two spaces for a Tab. */
--			screen_puts_len((char_u *)"  ", 2, row, col, attr);
--			col += 2;
-+#ifdef FEAT_RIGHTLEFT
-+			if (curwin->w_p_rl)
-+			{
-+			    screen_puts_len((char_u *)"  ", 2, row, col - 1,
-+									attr);
-+			    col -= 2;
-+			}
-+			else
-+#endif
-+			{
-+			    screen_puts_len((char_u *)"  ", 2, row, col, attr);
-+			    col += 2;
-+			}
- 			totwidth += 2;
- 			s = NULL;	    /* start text at next char */
- 			width = 0;
-@@ -322,17 +401,44 @@
- 					  && pum_array[idx].pum_extra == NULL)
- 		    || pum_base_width + n >= pum_width)
- 		break;
--	    screen_fill(row, row + 1, col, pum_col + pum_base_width + n,
-+#ifdef FEAT_RIGHTLEFT
-+	    if (curwin->w_p_rl)
-+	    {
-+		screen_fill(row, row + 1, pum_col - pum_base_width - n + 1,
-+						    col + 1, ' ', ' ', attr);
-+		col = pum_col - pum_base_width - n + 1;
-+	    }
-+	    else
-+#endif
-+	    {
-+		screen_fill(row, row + 1, col, pum_col + pum_base_width + n,
- 							      ' ', ' ', attr);
--	    col = pum_col + pum_base_width + n;
-+		col = pum_col + pum_base_width + n;
-+	    }
- 	    totwidth = pum_base_width + n;
- 	}
- 
--	screen_fill(row, row + 1, col, pum_col + pum_width, ' ', ' ', attr);
-+#ifdef FEAT_RIGHTLEFT
-+	if (curwin->w_p_rl)
-+	    screen_fill(row, row + 1, pum_col - pum_width + 1, col + 1, ' ',
-+								    ' ', attr);
-+	else
-+#endif
-+	    screen_fill(row, row + 1, col, pum_col + pum_width, ' ', ' ',
-+									attr);
- 	if (pum_scrollbar > 0)
--	    screen_putchar(' ', row, pum_col + pum_width,
--		    i >= thumb_pos && i < thumb_pos + thumb_heigth
-+	{
-+#ifdef FEAT_RIGHTLEFT
-+	    if (curwin->w_p_rl)
-+		screen_putchar(' ', row, pum_col - pum_width,
-+			i >= thumb_pos && i < thumb_pos + thumb_heigth
- 						  ? attr_thumb : attr_scroll);
-+	    else
-+#endif
-+		screen_putchar(' ', row, pum_col + pum_width,
-+			i >= thumb_pos && i < thumb_pos + thumb_heigth
-+						  ? attr_thumb : attr_scroll);
-+	}
- 
- 	++row;
-     }
-@@ -466,7 +572,7 @@
- 			set_option_value((char_u *)"bh", 0L,
- 						 (char_u *)"wipe", OPT_LOCAL);
- 			set_option_value((char_u *)"diff", 0L,
--						     (char_u *)"", OPT_LOCAL);
-+							     NULL, OPT_LOCAL);
- 		    }
- 		}
- 		if (res == OK)
-diff -Naur vim71.orig/src/proto/charset.pro vim71/src/proto/charset.pro
---- vim71.orig/src/proto/charset.pro	2007-05-12 06:39:01.000000000 -0400
-+++ vim71/src/proto/charset.pro	2008-06-18 06:52:16.000000000 -0400
-@@ -21,6 +21,7 @@
- int vim_iswordp __ARGS((char_u *p));
- int vim_iswordc_buf __ARGS((char_u *p, buf_T *buf));
- int vim_isfilec __ARGS((int c));
-+int vim_isfilec_or_wc __ARGS((int c));
- int vim_isprintc __ARGS((int c));
- int vim_isprintc_strict __ARGS((int c));
- int lbr_chartabsize __ARGS((unsigned char *s, colnr_T col));
-diff -Naur vim71.orig/src/proto/edit.pro vim71/src/proto/edit.pro
---- vim71.orig/src/proto/edit.pro	2007-05-12 06:39:05.000000000 -0400
-+++ vim71/src/proto/edit.pro	2008-06-18 06:55:19.000000000 -0400
-@@ -3,7 +3,7 @@
- void edit_putchar __ARGS((int c, int highlight));
- void edit_unputchar __ARGS((void));
- void display_dollar __ARGS((colnr_T col));
--void change_indent __ARGS((int type, int amount, int round, int replaced));
-+void change_indent __ARGS((int type, int amount, int round, int replaced, int call_changed_bytes));
- void truncate_spaces __ARGS((char_u *line));
- void backspace_until_column __ARGS((int col));
- int vim_is_ctrl_x_key __ARGS((int c));
-@@ -32,6 +32,7 @@
- char_u *get_last_insert __ARGS((void));
- char_u *get_last_insert_save __ARGS((void));
- void replace_push __ARGS((int c));
-+int replace_push_mb __ARGS((char_u *p));
- void fixthisline __ARGS((int (*get_the_indent)(void)));
- void fix_indent __ARGS((void));
- int in_cinkeys __ARGS((int keytyped, int when, int line_is_empty));
-diff -Naur vim71.orig/src/proto/eval.pro vim71/src/proto/eval.pro
---- vim71.orig/src/proto/eval.pro	2007-05-12 06:39:06.000000000 -0400
-+++ vim71/src/proto/eval.pro	2008-06-18 06:54:54.000000000 -0400
-@@ -54,7 +54,7 @@
- long get_dict_number __ARGS((dict_T *d, char_u *key));
- char_u *get_function_name __ARGS((expand_T *xp, int idx));
- char_u *get_expr_name __ARGS((expand_T *xp, int idx));
--long do_searchpair __ARGS((char_u *spat, char_u *mpat, char_u *epat, int dir, char_u *skip, int flags, pos_T *match_pos, linenr_T lnum_stop));
-+long do_searchpair __ARGS((char_u *spat, char_u *mpat, char_u *epat, int dir, char_u *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long time_limit));
- void set_vim_var_nr __ARGS((int idx, long val));
- long get_vim_var_nr __ARGS((int idx));
- char_u *get_vim_var_str __ARGS((int idx));
-diff -Naur vim71.orig/src/proto/ex_cmds2.pro vim71/src/proto/ex_cmds2.pro
---- vim71.orig/src/proto/ex_cmds2.pro	2007-05-12 06:39:09.000000000 -0400
-+++ vim71/src/proto/ex_cmds2.pro	2008-06-18 06:54:54.000000000 -0400
-@@ -14,6 +14,8 @@
- void profile_end __ARGS((proftime_T *tm));
- void profile_sub __ARGS((proftime_T *tm, proftime_T *tm2));
- char *profile_msg __ARGS((proftime_T *tm));
-+void profile_setlimit __ARGS((long msec, proftime_T *tm));
-+int profile_passed_limit __ARGS((proftime_T *tm));
- void profile_zero __ARGS((proftime_T *tm));
- void profile_add __ARGS((proftime_T *tm, proftime_T *tm2));
- void profile_self __ARGS((proftime_T *self, proftime_T *total, proftime_T *children));
-diff -Naur vim71.orig/src/proto/ex_docmd.pro vim71/src/proto/ex_docmd.pro
---- vim71.orig/src/proto/ex_docmd.pro	2007-05-12 06:39:10.000000000 -0400
-+++ vim71/src/proto/ex_docmd.pro	2008-06-18 06:53:54.000000000 -0400
-@@ -5,6 +5,7 @@
- int getline_equal __ARGS((char_u *(*fgetline)(int, void *, int), void *cookie, char_u *(*func)(int, void *, int)));
- void *getline_cookie __ARGS((char_u *(*fgetline)(int, void *, int), void *cookie));
- int checkforcmd __ARGS((char_u **pp, char *cmd, int len));
-+int modifier_len __ARGS((char_u *cmd));
- int cmd_exists __ARGS((char_u *name));
- char_u *set_one_cmd_context __ARGS((expand_T *xp, char_u *buff));
- char_u *skip_range __ARGS((char_u *cmd, int *ctx));
-diff -Naur vim71.orig/src/proto/ex_getln.pro vim71/src/proto/ex_getln.pro
---- vim71.orig/src/proto/ex_getln.pro	2007-05-12 06:39:13.000000000 -0400
-+++ vim71/src/proto/ex_getln.pro	2008-06-18 06:56:43.000000000 -0400
-@@ -24,6 +24,7 @@
- void ExpandInit __ARGS((expand_T *xp));
- void ExpandCleanup __ARGS((expand_T *xp));
- void ExpandEscape __ARGS((expand_T *xp, char_u *str, int numfiles, char_u **files, int options));
-+char_u *vim_strsave_fnameescape __ARGS((char_u *fname, int shell));
- void tilde_replace __ARGS((char_u *orig_pat, int num_files, char_u **files));
- char_u *sm_gettail __ARGS((char_u *s));
- char_u *addstar __ARGS((char_u *fname, int len, int context));
-diff -Naur vim71.orig/src/proto/fileio.pro vim71/src/proto/fileio.pro
---- vim71.orig/src/proto/fileio.pro	2007-05-12 06:39:14.000000000 -0400
-+++ vim71/src/proto/fileio.pro	2008-06-18 06:53:09.000000000 -0400
-@@ -2,6 +2,7 @@
- void filemess __ARGS((buf_T *buf, char_u *name, char_u *s, int attr));
- int readfile __ARGS((char_u *fname, char_u *sfname, linenr_T from, linenr_T lines_to_skip, linenr_T lines_to_read, exarg_T *eap, int flags));
- int prep_exarg __ARGS((exarg_T *eap, buf_T *buf));
-+int check_file_readonly __ARGS((char_u *fname, int perm));
- int buf_write __ARGS((buf_T *buf, char_u *fname, char_u *sfname, linenr_T start, linenr_T end, exarg_T *eap, int append, int forceit, int reset_changed, int filtering));
- void msg_add_fname __ARGS((buf_T *buf, char_u *fname));
- void msg_add_lines __ARGS((int insert_space, long lnum, long nchars));
-@@ -39,6 +40,8 @@
- int trigger_cursorhold __ARGS((void));
- int has_cursormoved __ARGS((void));
- int has_cursormovedI __ARGS((void));
-+void block_autocmds __ARGS((void));
-+void unblock_autocmds __ARGS((void));
- int has_autocmd __ARGS((event_T event, char_u *sfname, buf_T *buf));
- char_u *get_augroup_name __ARGS((expand_T *xp, int idx));
- char_u *set_context_in_autocmd __ARGS((expand_T *xp, char_u *arg, int doautocmd));
-diff -Naur vim71.orig/src/proto/getchar.pro vim71/src/proto/getchar.pro
---- vim71.orig/src/proto/getchar.pro	2007-05-12 06:39:16.000000000 -0400
-+++ vim71/src/proto/getchar.pro	2008-06-18 06:52:43.000000000 -0400
-@@ -38,6 +38,7 @@
- void updatescript __ARGS((int c));
- int vgetc __ARGS((void));
- int safe_vgetc __ARGS((void));
-+int plain_vgetc __ARGS((void));
- int vpeekc __ARGS((void));
- int vpeekc_nomap __ARGS((void));
- int vpeekc_any __ARGS((void));
-diff -Naur vim71.orig/src/proto/if_cscope.pro vim71/src/proto/if_cscope.pro
---- vim71.orig/src/proto/if_cscope.pro	2007-05-12 06:39:21.000000000 -0400
-+++ vim71/src/proto/if_cscope.pro	2008-06-18 06:52:38.000000000 -0400
-@@ -6,4 +6,5 @@
- void cs_free_tags __ARGS((void));
- void cs_print_tags __ARGS((void));
- int cs_connection __ARGS((int num, char_u *dbpath, char_u *ppath));
-+void cs_end __ARGS((void));
- /* vim: set ft=c : */
-diff -Naur vim71.orig/src/proto/mbyte.pro vim71/src/proto/mbyte.pro
---- vim71.orig/src/proto/mbyte.pro	2007-05-12 06:39:38.000000000 -0400
-+++ vim71/src/proto/mbyte.pro	2008-06-18 06:52:29.000000000 -0400
-@@ -12,9 +12,9 @@
- int utf_ptr2cells __ARGS((char_u *p));
- int dbcs_ptr2cells __ARGS((char_u *p));
- int latin_char2cells __ARGS((int c));
--int latin_off2cells __ARGS((unsigned off));
--int dbcs_off2cells __ARGS((unsigned off));
--int utf_off2cells __ARGS((unsigned off));
-+int latin_off2cells __ARGS((unsigned off, unsigned max_off));
-+int dbcs_off2cells __ARGS((unsigned off, unsigned max_off));
-+int utf_off2cells __ARGS((unsigned off, unsigned max_off));
- int latin_ptr2char __ARGS((char_u *p));
- int utf_ptr2char __ARGS((char_u *p));
- int mb_ptr2char_adv __ARGS((char_u **pp));
-diff -Naur vim71.orig/src/proto/misc1.pro vim71/src/proto/misc1.pro
---- vim71.orig/src/proto/misc1.pro	2007-05-12 06:39:34.000000000 -0400
-+++ vim71/src/proto/misc1.pro	2008-06-18 06:53:06.000000000 -0400
-@@ -48,10 +48,11 @@
- void vim_beep __ARGS((void));
- void init_homedir __ARGS((void));
- void free_homedir __ARGS((void));
-+char_u *expand_env_save __ARGS((char_u *src));
-+char_u *expand_env_save_opt __ARGS((char_u *src, int one));
- void expand_env __ARGS((char_u *src, char_u *dst, int dstlen));
--void expand_env_esc __ARGS((char_u *srcp, char_u *dst, int dstlen, int esc, char_u *startstr));
-+void expand_env_esc __ARGS((char_u *srcp, char_u *dst, int dstlen, int esc, int one, char_u *startstr));
- char_u *vim_getenv __ARGS((char_u *name, int *mustfree));
--char_u *expand_env_save __ARGS((char_u *src));
- void vim_setenv __ARGS((char_u *name, char_u *val));
- char_u *get_env_name __ARGS((expand_T *xp, int idx));
- void home_replace __ARGS((buf_T *buf, char_u *src, char_u *dst, int dstlen, int one));
-diff -Naur vim71.orig/src/proto/ops.pro vim71/src/proto/ops.pro
---- vim71.orig/src/proto/ops.pro	2007-05-12 06:39:40.000000000 -0400
-+++ vim71/src/proto/ops.pro	2008-06-18 06:56:15.000000000 -0400
-@@ -4,7 +4,7 @@
- int get_op_char __ARGS((int optype));
- int get_extra_op_char __ARGS((int optype));
- void op_shift __ARGS((oparg_T *oap, int curs_top, int amount));
--void shift_line __ARGS((int left, int round, int amount));
-+void shift_line __ARGS((int left, int round, int amount, int call_changed_bytes));
- void op_reindent __ARGS((oparg_T *oap, int (*how)(void)));
- int get_expr_register __ARGS((void));
- void set_expr_line __ARGS((char_u *new_line));
-@@ -41,7 +41,7 @@
- void op_format __ARGS((oparg_T *oap, int keep_cursor));
- void op_formatexpr __ARGS((oparg_T *oap));
- int fex_format __ARGS((linenr_T lnum, long count, int c));
--void format_lines __ARGS((linenr_T line_count));
-+void format_lines __ARGS((linenr_T line_count, int avoid_fex));
- int paragraph_start __ARGS((linenr_T lnum));
- int do_addsub __ARGS((int command, linenr_T Prenum1));
- int read_viminfo_register __ARGS((vir_T *virp, int force));
-diff -Naur vim71.orig/src/proto/os_unix.pro vim71/src/proto/os_unix.pro
---- vim71.orig/src/proto/os_unix.pro	2007-05-12 06:39:43.000000000 -0400
-+++ vim71/src/proto/os_unix.pro	2008-06-18 06:56:39.000000000 -0400
-@@ -34,6 +34,7 @@
- void fname_case __ARGS((char_u *name, int len));
- long mch_getperm __ARGS((char_u *name));
- int mch_setperm __ARGS((char_u *name, long perm));
-+void mch_copy_sec __ARGS((char_u *from_file, char_u *to_file));
- vim_acl_T mch_get_acl __ARGS((char_u *fname));
- void mch_set_acl __ARGS((char_u *fname, vim_acl_T aclent));
- void mch_free_acl __ARGS((vim_acl_T aclent));
-diff -Naur vim71.orig/src/proto/regexp.pro vim71/src/proto/regexp.pro
---- vim71.orig/src/proto/regexp.pro	2007-05-12 06:39:48.000000000 -0400
-+++ vim71/src/proto/regexp.pro	2008-06-18 06:55:25.000000000 -0400
-@@ -1,13 +1,13 @@
- /* regexp.c */
--void free_regexp_stuff __ARGS((void));
- int re_multiline __ARGS((regprog_T *prog));
- int re_lookbehind __ARGS((regprog_T *prog));
- char_u *skip_regexp __ARGS((char_u *startp, int dirc, int magic, char_u **newp));
- regprog_T *vim_regcomp __ARGS((char_u *expr, int re_flags));
- int vim_regcomp_had_eol __ARGS((void));
-+void free_regexp_stuff __ARGS((void));
- int vim_regexec __ARGS((regmatch_T *rmp, char_u *line, colnr_T col));
- int vim_regexec_nl __ARGS((regmatch_T *rmp, char_u *line, colnr_T col));
--long vim_regexec_multi __ARGS((regmmatch_T *rmp, win_T *win, buf_T *buf, linenr_T lnum, colnr_T col));
-+long vim_regexec_multi __ARGS((regmmatch_T *rmp, win_T *win, buf_T *buf, linenr_T lnum, colnr_T col, proftime_T *tm));
- reg_extmatch_T *ref_extmatch __ARGS((reg_extmatch_T *em));
- void unref_extmatch __ARGS((reg_extmatch_T *em));
- char_u *regtilde __ARGS((char_u *source, int magic));
-diff -Naur vim71.orig/src/proto/search.pro vim71/src/proto/search.pro
---- vim71.orig/src/proto/search.pro	2007-05-12 06:39:50.000000000 -0400
-+++ vim71/src/proto/search.pro	2008-06-18 06:55:25.000000000 -0400
-@@ -1,6 +1,7 @@
- /* search.c */
- int search_regcomp __ARGS((char_u *pat, int pat_save, int pat_use, int options, regmmatch_T *regmatch));
- char_u *get_search_pat __ARGS((void));
-+char_u *reverse_text __ARGS((char_u *s));
- void save_search_patterns __ARGS((void));
- void restore_search_patterns __ARGS((void));
- void free_search_patterns __ARGS((void));
-@@ -9,8 +10,8 @@
- void reset_search_dir __ARGS((void));
- void set_last_search_pat __ARGS((char_u *s, int idx, int magic, int setlast));
- void last_pat_prog __ARGS((regmmatch_T *regmatch));
--int searchit __ARGS((win_T *win, buf_T *buf, pos_T *pos, int dir, char_u *pat, long count, int options, int pat_use, linenr_T stop_lnum));
--int do_search __ARGS((oparg_T *oap, int dirc, char_u *pat, long count, int options));
-+int searchit __ARGS((win_T *win, buf_T *buf, pos_T *pos, int dir, char_u *pat, long count, int options, int pat_use, linenr_T stop_lnum, proftime_T *tm));
-+int do_search __ARGS((oparg_T *oap, int dirc, char_u *pat, long count, int options, proftime_T *tm));
- int search_for_exact_line __ARGS((buf_T *buf, pos_T *pos, int dir, char_u *pat));
- int searchc __ARGS((cmdarg_T *cap, int t_cmd));
- pos_T *findmatch __ARGS((oparg_T *oap, int initc));
-diff -Naur vim71.orig/src/proto/syntax.pro vim71/src/proto/syntax.pro
---- vim71.orig/src/proto/syntax.pro	2007-05-12 06:39:52.000000000 -0400
-+++ vim71/src/proto/syntax.pro	2008-06-18 06:55:04.000000000 -0400
-@@ -4,13 +4,16 @@
- void syn_stack_apply_changes __ARGS((buf_T *buf));
- void syntax_end_parsing __ARGS((linenr_T lnum));
- int syntax_check_changed __ARGS((linenr_T lnum));
--int get_syntax_attr __ARGS((colnr_T col, int *can_spell));
-+int get_syntax_attr __ARGS((colnr_T col, int *can_spell, int keep_state));
- void syntax_clear __ARGS((buf_T *buf));
- void ex_syntax __ARGS((exarg_T *eap));
- int syntax_present __ARGS((buf_T *buf));
-+void reset_expand_highlight __ARGS((void));
-+void set_context_in_echohl_cmd __ARGS((expand_T *xp, char_u *arg));
- void set_context_in_syntax_cmd __ARGS((expand_T *xp, char_u *arg));
- char_u *get_syntax_name __ARGS((expand_T *xp, int idx));
--int syn_get_id __ARGS((win_T *wp, long lnum, colnr_T col, int trans, int *spellp));
-+int syn_get_id __ARGS((win_T *wp, long lnum, colnr_T col, int trans, int *spellp, int keep_state));
-+int syn_get_stack_item __ARGS((int i));
- int syn_get_foldlevel __ARGS((win_T *wp, long lnum));
- void init_highlight __ARGS((int both, int reset));
- int load_colors __ARGS((char_u *name));
-diff -Naur vim71.orig/src/proto/window.pro vim71/src/proto/window.pro
---- vim71.orig/src/proto/window.pro	2007-05-12 06:40:00.000000000 -0400
-+++ vim71/src/proto/window.pro	2008-06-18 06:51:23.000000000 -0400
-@@ -59,4 +59,8 @@
- int only_one_window __ARGS((void));
- void check_lnums __ARGS((int do_curwin));
- int win_hasvertsplit __ARGS((void));
-+int match_add __ARGS((win_T *wp, char_u *grp, char_u *pat, int prio, int id));
-+int match_delete __ARGS((win_T *wp, int id, int perr));
-+void clear_matches __ARGS((win_T *wp));
-+matchitem_T *get_match __ARGS((win_T *wp, int id));
- /* vim: set ft=c : */
-diff -Naur vim71.orig/src/quickfix.c vim71/src/quickfix.c
---- vim71.orig/src/quickfix.c	2007-02-03 19:50:17.000000000 -0500
-+++ vim71/src/quickfix.c	2008-06-18 06:56:25.000000000 -0400
-@@ -106,7 +106,9 @@
- 
- static int	qf_init_ext __ARGS((qf_info_T *qi, char_u *efile, buf_T *buf, typval_T *tv, char_u *errorformat, int newlist, linenr_T lnumfirst, linenr_T lnumlast));
- static void	qf_new_list __ARGS((qf_info_T *qi));
-+static void	ll_free_all __ARGS((qf_info_T **pqi));
- static int	qf_add_entry __ARGS((qf_info_T *qi, qfline_T **prevp, char_u *dir, char_u *fname, int bufnum, char_u *mesg, long lnum, int col, int vis_col, char_u *pattern, int nr, int type, int valid));
-+static qf_info_T *ll_new_list __ARGS((void));
- static void	qf_msg __ARGS((qf_info_T *qi));
- static void	qf_free __ARGS((qf_info_T *qi, int idx));
- static char_u	*qf_types __ARGS((int, int));
-@@ -1612,8 +1614,8 @@
- 	}
- 
- 	/*
--	 * If there is only one window and is the quickfix window, create a new
--	 * one above the quickfix window.
-+	 * If there is only one window and it is the quickfix window, create a
-+	 * new one above the quickfix window.
- 	 */
- 	if (((firstwin == lastwin) && bt_quickfix(curbuf)) || !usable_win)
- 	{
-@@ -1803,7 +1805,8 @@
- 	    /* Move the cursor to the first line in the buffer */
- 	    save_cursor = curwin->w_cursor;
- 	    curwin->w_cursor.lnum = 0;
--	    if (!do_search(NULL, '/', qf_ptr->qf_pattern, (long)1, SEARCH_KEEP))
-+	    if (!do_search(NULL, '/', qf_ptr->qf_pattern, (long)1,
-+							   SEARCH_KEEP, NULL))
- 		curwin->w_cursor = save_cursor;
- 	}
- 
-@@ -2331,7 +2334,7 @@
- 	    set_option_value((char_u *)"bt", 0L, (char_u *)"quickfix",
- 								   OPT_LOCAL);
- 	    set_option_value((char_u *)"bh", 0L, (char_u *)"wipe", OPT_LOCAL);
--	    set_option_value((char_u *)"diff", 0L, (char_u *)"", OPT_LOCAL);
-+	    set_option_value((char_u *)"diff", 0L, NULL, OPT_LOCAL);
- 	}
- 
- 	/* Only set the height when still in the same tab page and there is no
-@@ -2981,6 +2984,7 @@
-     buf_T	*buf;
-     int		duplicate_name = FALSE;
-     int		using_dummy;
-+    int		redraw_for_dummy = FALSE;
-     int		found_match;
-     buf_T	*first_match_buf = NULL;
-     time_t	seconds = 0;
-@@ -3097,6 +3101,7 @@
- 	    /* Remember that a buffer with this name already exists. */
- 	    duplicate_name = (buf != NULL);
- 	    using_dummy = TRUE;
-+	    redraw_for_dummy = TRUE;
- 
- #if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
- 	    /* Don't do Filetype autocommands to avoid loading syntax and
-@@ -3135,7 +3140,7 @@
- 	    {
- 		col = 0;
- 		while (vim_regexec_multi(&regmatch, curwin, buf, lnum,
--								     col) > 0)
-+							       col, NULL) > 0)
- 		{
- 		    if (qf_add_entry(qi, &prevp,
- 				NULL,       /* dir */
-@@ -3243,11 +3248,29 @@
-     if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
-     {
- 	if ((flags & VGR_NOJUMP) == 0)
-+	{
-+	    buf = curbuf;
- 	    qf_jump(qi, 0, 0, eap->forceit);
-+	    if (buf != curbuf)
-+		/* If we jumped to another buffer redrawing will already be
-+		 * taken care of. */
-+		redraw_for_dummy = FALSE;
-+	}
-     }
-     else
- 	EMSG2(_(e_nomatch2), s);
- 
-+    /* If we loaded a dummy buffer into the current window, the autocommands
-+     * may have messed up things, need to redraw and recompute folds. */
-+    if (redraw_for_dummy)
-+    {
-+#ifdef FEAT_FOLDING
-+	foldUpdateAll(curwin);
-+#else
-+	redraw_later(NOT_VALID);
-+#endif
-+    }
-+
- theend:
-     vim_free(regmatch.regprog);
- }
-diff -Naur vim71.orig/src/regexp.c vim71/src/regexp.c
---- vim71.orig/src/regexp.c	2007-05-07 15:50:03.000000000 -0400
-+++ vim71/src/regexp.c	2008-06-18 06:57:02.000000000 -0400
-@@ -378,14 +378,6 @@
- 
- static char_u		*reg_prev_sub = NULL;
- 
--#if defined(EXITFREE) || defined(PROTO)
--    void
--free_regexp_stuff()
--{
--    vim_free(reg_prev_sub);
--}
--#endif
--
- /*
-  * REGEXP_INRANGE contains all characters which are always special in a []
-  * range after '\'.
-@@ -1288,8 +1280,7 @@
- }
- 
- /*
-- * regbranch - one alternative of an | operator
-- *
-+ * Handle one alternative of an | operator.
-  * Implements the & operator.
-  */
-     static char_u *
-@@ -1330,8 +1321,7 @@
- }
- 
- /*
-- * regbranch - one alternative of an | or & operator
-- *
-+ * Handle one alternative of an | or & operator.
-  * Implements the concatenation operator.
-  */
-     static char_u *
-@@ -1708,6 +1698,8 @@
-       case Magic('|'):
-       case Magic('&'):
-       case Magic(')'):
-+	if (one_exactly)
-+	    EMSG_ONE_RET_NULL;
- 	EMSG_RET_NULL(_(e_internal));	/* Supposed to be caught earlier. */
- 	/* NOTREACHED */
- 
-@@ -2220,7 +2212,7 @@
- 				break;
- 			    case CLASS_LOWER:
- 				for (cu = 1; cu <= 255; cu++)
--				    if (islower(cu))
-+				    if (MB_ISLOWER(cu))
- 					regc(cu);
- 				break;
- 			    case CLASS_PRINT:
-@@ -2240,7 +2232,7 @@
- 				break;
- 			    case CLASS_UPPER:
- 				for (cu = 1; cu <= 255; cu++)
--				    if (isupper(cu))
-+				    if (MB_ISUPPER(cu))
- 					regc(cu);
- 				break;
- 			    case CLASS_XDIGIT:
-@@ -2770,7 +2762,8 @@
-     {
- #ifdef FEAT_MBYTE
- 	if (enc_utf8)
--	    prevchr_len += utf_char2len(mb_ptr2char(regparse + prevchr_len));
-+	    /* exclude composing chars that mb_ptr2len does include */
-+	    prevchr_len += utf_ptr2len(regparse + prevchr_len);
- 	else if (has_mbyte)
- 	    prevchr_len += (*mb_ptr2len)(regparse + prevchr_len);
- 	else
-@@ -3046,13 +3039,25 @@
-     } se_u;
- } save_se_T;
- 
-+/* used for BEHIND and NOBEHIND matching */
-+typedef struct regbehind_S
-+{
-+    regsave_T	save_after;
-+    regsave_T	save_behind;
-+    int		save_need_clear_subexpr;
-+    save_se_T   save_start[NSUBEXP];
-+    save_se_T   save_end[NSUBEXP];
-+} regbehind_T;
-+
- static char_u	*reg_getline __ARGS((linenr_T lnum));
--static long	vim_regexec_both __ARGS((char_u *line, colnr_T col));
-+static long	vim_regexec_both __ARGS((char_u *line, colnr_T col, proftime_T *tm));
- static long	regtry __ARGS((regprog_T *prog, colnr_T col));
- static void	cleanup_subexpr __ARGS((void));
- #ifdef FEAT_SYN_HL
- static void	cleanup_zsubexpr __ARGS((void));
- #endif
-+static void	save_subexpr __ARGS((regbehind_T *bp));
-+static void	restore_subexpr __ARGS((regbehind_T *bp));
- static void	reg_nextline __ARGS((void));
- static void	reg_save __ARGS((regsave_T *save, garray_T *gap));
- static void	reg_restore __ARGS((regsave_T *save, garray_T *gap));
-@@ -3105,7 +3110,7 @@
-  * slow, we keep one allocated piece of memory and only re-allocate it when
-  * it's too small.  It's freed in vim_regexec_both() when finished.
-  */
--static char_u	*reg_tofree;
-+static char_u	*reg_tofree = NULL;
- static unsigned	reg_tofreelen;
- 
- /*
-@@ -3173,19 +3178,12 @@
- 	save_se_T  sesave;
- 	regsave_T  regsave;
-     } rs_un;			/* room for saving reginput */
--    short	rs_no;		/* submatch nr */
-+    short	rs_no;		/* submatch nr or BEHIND/NOBEHIND */
- } regitem_T;
- 
- static regitem_T *regstack_push __ARGS((regstate_T state, char_u *scan));
- static void regstack_pop __ARGS((char_u **scan));
- 
--/* used for BEHIND and NOBEHIND matching */
--typedef struct regbehind_S
--{
--    regsave_T	save_after;
--    regsave_T	save_behind;
--} regbehind_T;
--
- /* used for STAR, PLUS and BRACE_SIMPLE matching */
- typedef struct regstar_S
- {
-@@ -3205,12 +3203,39 @@
- } backpos_T;
- 
- /*
-- * regstack and backpos are used by regmatch().  They are kept over calls to
-- * avoid invoking malloc() and free() often.
-+ * "regstack" and "backpos" are used by regmatch().  They are kept over calls
-+ * to avoid invoking malloc() and free() often.
-+ * "regstack" is a stack with regitem_T items, sometimes preceded by regstar_T
-+ * or regbehind_T.
-+ * "backpos_T" is a table with backpos_T for BACK
-+ */
-+static garray_T	regstack = {0, 0, 0, 0, NULL};
-+static garray_T	backpos = {0, 0, 0, 0, NULL};
-+
-+/*
-+ * Both for regstack and backpos tables we use the following strategy of
-+ * allocation (to reduce malloc/free calls):
-+ * - Initial size is fairly small.
-+ * - When needed, the tables are grown bigger (8 times at first, double after
-+ *   that).
-+ * - After executing the match we free the memory only if the array has grown.
-+ *   Thus the memory is kept allocated when it's at the initial size.
-+ * This makes it fast while not keeping a lot of memory allocated.
-+ * A three times speed increase was observed when using many simple patterns.
-  */
--static garray_T	regstack;	/* stack with regitem_T items, sometimes
--				   preceded by regstar_T or regbehind_T. */
--static garray_T	backpos;	/* table with backpos_T for BACK */
-+#define REGSTACK_INITIAL	2048
-+#define BACKPOS_INITIAL		64
-+
-+#if defined(EXITFREE) || defined(PROTO)
-+    void
-+free_regexp_stuff()
-+{
-+    ga_clear(&regstack);
-+    ga_clear(&backpos);
-+    vim_free(reg_tofree);
-+    vim_free(reg_prev_sub);
-+}
-+#endif
- 
- /*
-  * Get pointer to the line "lnum", which is relative to "reg_firstlnum".
-@@ -3264,7 +3289,7 @@
-     ireg_icombine = FALSE;
- #endif
-     ireg_maxcol = 0;
--    return (vim_regexec_both(line, col) != 0);
-+    return (vim_regexec_both(line, col, NULL) != 0);
- }
- 
- #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) \
-@@ -3288,7 +3313,7 @@
-     ireg_icombine = FALSE;
- #endif
-     ireg_maxcol = 0;
--    return (vim_regexec_both(line, col) != 0);
-+    return (vim_regexec_both(line, col, NULL) != 0);
- }
- #endif
- 
-@@ -3301,12 +3326,13 @@
-  * match otherwise.
-  */
-     long
--vim_regexec_multi(rmp, win, buf, lnum, col)
-+vim_regexec_multi(rmp, win, buf, lnum, col, tm)
-     regmmatch_T	*rmp;
-     win_T	*win;		/* window in which to search or NULL */
-     buf_T	*buf;		/* buffer in which to search */
-     linenr_T	lnum;		/* nr of line to start looking for match */
-     colnr_T	col;		/* column to start looking for match */
-+    proftime_T	*tm;		/* timeout limit or NULL */
- {
-     long	r;
-     buf_T	*save_curbuf = curbuf;
-@@ -3326,7 +3352,7 @@
- 
-     /* Need to switch to buffer "buf" to make vim_iswordc() work. */
-     curbuf = buf;
--    r = vim_regexec_both(NULL, col);
-+    r = vim_regexec_both(NULL, col, tm);
-     curbuf = save_curbuf;
- 
-     return r;
-@@ -3336,24 +3362,36 @@
-  * Match a regexp against a string ("line" points to the string) or multiple
-  * lines ("line" is NULL, use reg_getline()).
-  */
-+/*ARGSUSED*/
-     static long
--vim_regexec_both(line, col)
-+vim_regexec_both(line, col, tm)
-     char_u	*line;
-     colnr_T	col;		/* column to start looking for match */
-+    proftime_T	*tm;		/* timeout limit or NULL */
- {
-     regprog_T	*prog;
-     char_u	*s;
-     long	retval = 0L;
- 
--    reg_tofree = NULL;
--
--    /* Init the regstack empty.  Use an item size of 1 byte, since we push
--     * different things onto it.  Use a large grow size to avoid reallocating
--     * it too often. */
--    ga_init2(&regstack, 1, 10000);
--
--    /* Init the backpos table empty. */
--    ga_init2(&backpos, sizeof(backpos_T), 10);
-+    /* Create "regstack" and "backpos" if they are not allocated yet.
-+     * We allocate *_INITIAL amount of bytes first and then set the grow size
-+     * to much bigger value to avoid many malloc calls in case of deep regular
-+     * expressions.  */
-+    if (regstack.ga_data == NULL)
-+    {
-+	/* Use an item size of 1 byte, since we push different things
-+	 * onto the regstack. */
-+	ga_init2(&regstack, 1, REGSTACK_INITIAL);
-+	ga_grow(&regstack, REGSTACK_INITIAL);
-+	regstack.ga_growsize = REGSTACK_INITIAL * 8;
-+    }
-+
-+    if (backpos.ga_data == NULL)
-+    {
-+	ga_init2(&backpos, sizeof(backpos_T), BACKPOS_INITIAL);
-+	ga_grow(&backpos, BACKPOS_INITIAL);
-+	backpos.ga_growsize = BACKPOS_INITIAL * 8;
-+    }
- 
-     if (REG_MULTI)
-     {
-@@ -3465,13 +3503,16 @@
- 			(enc_utf8 && utf_fold(prog->regstart) == utf_fold(c)))
- 			|| (c < 255 && prog->regstart < 255 &&
- #endif
--			    TOLOWER_LOC(prog->regstart) == TOLOWER_LOC(c)))))
-+			    MB_TOLOWER(prog->regstart) == MB_TOLOWER(c)))))
- 	    retval = regtry(prog, col);
- 	else
- 	    retval = 0;
-     }
-     else
-     {
-+#ifdef FEAT_RELTIME
-+	int tm_count = 0;
-+#endif
- 	/* Messy cases:  unanchored match. */
- 	while (!got_int)
- 	{
-@@ -3520,13 +3561,30 @@
- 	    else
- #endif
- 		++col;
-+#ifdef FEAT_RELTIME
-+	    /* Check for timeout once in a twenty times to avoid overhead. */
-+	    if (tm != NULL && ++tm_count == 20)
-+	    {
-+		tm_count = 0;
-+		if (profile_passed_limit(tm))
-+		    break;
-+	    }
-+#endif
- 	}
-     }
- 
- theend:
--    vim_free(reg_tofree);
--    ga_clear(&regstack);
--    ga_clear(&backpos);
-+    /* Free "reg_tofree" when it's a bit big.
-+     * Free regstack and backpos if they are bigger than their initial size. */
-+    if (reg_tofreelen > 400)
-+    {
-+	vim_free(reg_tofree);
-+	reg_tofree = NULL;
-+    }
-+    if (regstack.ga_maxlen > REGSTACK_INITIAL)
-+	ga_clear(&regstack);
-+    if (backpos.ga_maxlen > BACKPOS_INITIAL)
-+	ga_clear(&backpos);
- 
-     return retval;
- }
-@@ -3716,8 +3774,8 @@
- #define RA_MATCH	4	/* successful match */
- #define RA_NOMATCH	5	/* didn't match */
- 
--  /* Init the regstack and backpos table empty.  They are initialized and
--   * freed in vim_regexec_both() to reduce malloc()/free() calls. */
-+  /* Make "regstack" and "backpos" empty.  They are allocated and freed in
-+   * vim_regexec_both() to reduce malloc()/free() calls. */
-   regstack.ga_len = 0;
-   backpos.ga_len = 0;
- 
-@@ -3809,11 +3867,11 @@
- 	    break;
- 
- 	  case RE_BOF:
--	    /* Passing -1 to the getline() function provided for the search
--	     * should always return NULL if the current line is the first
--	     * line of the file. */
-+	    /* We're not at the beginning of the file when below the first
-+	     * line where we started, not at the start of the line or we
-+	     * didn't start at the first line of the buffer. */
- 	    if (reglnum != 0 || reginput != regline
--			|| (REG_MULTI && reg_getline((linenr_T)-1) != NULL))
-+					  || (REG_MULTI && reg_firstlnum > 1))
- 		status = RA_NOMATCH;
- 	    break;
- 
-@@ -4200,7 +4258,7 @@
- #ifdef FEAT_MBYTE
- 			    !enc_utf8 &&
- #endif
--			    TOLOWER_LOC(*opnd) != TOLOWER_LOC(*reginput))))
-+			    MB_TOLOWER(*opnd) != MB_TOLOWER(*reginput))))
- 		    status = RA_NOMATCH;
- 		else if (*opnd == NUL)
- 		{
-@@ -4733,10 +4791,10 @@
- 		    rst.nextb = *OPERAND(next);
- 		    if (ireg_ic)
- 		    {
--			if (isupper(rst.nextb))
--			    rst.nextb_ic = TOLOWER_LOC(rst.nextb);
-+			if (MB_ISUPPER(rst.nextb))
-+			    rst.nextb_ic = MB_TOLOWER(rst.nextb);
- 			else
--			    rst.nextb_ic = TOUPPER_LOC(rst.nextb);
-+			    rst.nextb_ic = MB_TOUPPER(rst.nextb);
- 		    }
- 		    else
- 			rst.nextb_ic = rst.nextb;
-@@ -4835,6 +4893,10 @@
- 		    status = RA_FAIL;
- 		else
- 		{
-+		    /* Need to save the subexpr to be able to restore them
-+		     * when there is a match but we don't use it. */
-+		    save_subexpr(((regbehind_T *)rp) - 1);
-+
- 		    rp->rs_no = op;
- 		    reg_save(&rp->rs_un.regsave, &backpos);
- 		    /* First try if what follows matches.  If it does then we
-@@ -5065,15 +5127,20 @@
- 		    reg_restore(&(((regbehind_T *)rp) - 1)->save_after,
- 								    &backpos);
- 		else
--		    /* But we didn't want a match. */
-+		{
-+		    /* But we didn't want a match.  Need to restore the
-+		     * subexpr, because what follows matched, so they have
-+		     * been set. */
- 		    status = RA_NOMATCH;
-+		    restore_subexpr(((regbehind_T *)rp) - 1);
-+		}
- 		regstack_pop(&scan);
- 		regstack.ga_len -= sizeof(regbehind_T);
- 	    }
- 	    else
- 	    {
--		/* No match: Go back one character.  May go to previous
--		 * line once. */
-+		/* No match or a match that doesn't end where we want it: Go
-+		 * back one character.  May go to previous line once. */
- 		no = OK;
- 		if (REG_MULTI)
- 		{
-@@ -5107,6 +5174,13 @@
- 		    /* Advanced, prepare for finding match again. */
- 		    reg_restore(&rp->rs_un.regsave, &backpos);
- 		    scan = OPERAND(rp->rs_scan);
-+		    if (status == RA_MATCH)
-+		    {
-+			/* We did match, so subexpr may have been changed,
-+			 * need to restore them for the next try. */
-+			status = RA_NOMATCH;
-+			restore_subexpr(((regbehind_T *)rp) - 1);
-+		    }
- 		}
- 		else
- 		{
-@@ -5119,7 +5193,16 @@
- 			status = RA_MATCH;
- 		    }
- 		    else
--			status = RA_NOMATCH;
-+		    {
-+			/* We do want a proper match.  Need to restore the
-+			 * subexpr if we had a match, because they may have
-+			 * been set. */
-+			if (status == RA_MATCH)
-+			{
-+			    status = RA_NOMATCH;
-+			    restore_subexpr(((regbehind_T *)rp) - 1);
-+			}
-+		    }
- 		    regstack_pop(&scan);
- 		    regstack.ga_len -= sizeof(regbehind_T);
- 		}
-@@ -5558,11 +5641,12 @@
- 	    int	    cu, cl;
- 
- 	    /* This doesn't do a multi-byte character, because a MULTIBYTECODE
--	     * would have been used for it. */
-+	     * would have been used for it.  It does handle single-byte
-+	     * characters, such as latin1. */
- 	    if (ireg_ic)
- 	    {
--		cu = TOUPPER_LOC(*opnd);
--		cl = TOLOWER_LOC(*opnd);
-+		cu = MB_TOUPPER(*opnd);
-+		cl = MB_TOLOWER(*opnd);
- 		while (count < maxcount && (*scan == cu || *scan == cl))
- 		{
- 		    count++;
-@@ -5766,6 +5850,66 @@
- #endif
- 
- /*
-+ * Save the current subexpr to "bp", so that they can be restored
-+ * later by restore_subexpr().
-+ */
-+    static void
-+save_subexpr(bp)
-+    regbehind_T *bp;
-+{
-+    int i;
-+
-+    /* When "need_clear_subexpr" is set we don't need to save the values, only
-+     * remember that this flag needs to be set again when restoring. */
-+    bp->save_need_clear_subexpr = need_clear_subexpr;
-+    if (!need_clear_subexpr)
-+    {
-+	for (i = 0; i < NSUBEXP; ++i)
-+	{
-+	    if (REG_MULTI)
-+	    {
-+		bp->save_start[i].se_u.pos = reg_startpos[i];
-+		bp->save_end[i].se_u.pos = reg_endpos[i];
-+	    }
-+	    else
-+	    {
-+		bp->save_start[i].se_u.ptr = reg_startp[i];
-+		bp->save_end[i].se_u.ptr = reg_endp[i];
-+	    }
-+	}
-+    }
-+}
-+
-+/*
-+ * Restore the subexpr from "bp".
-+ */
-+    static void
-+restore_subexpr(bp)
-+    regbehind_T *bp;
-+{
-+    int i;
-+
-+    /* Only need to restore saved values when they are not to be cleared. */
-+    need_clear_subexpr = bp->save_need_clear_subexpr;
-+    if (!need_clear_subexpr)
-+    {
-+	for (i = 0; i < NSUBEXP; ++i)
-+	{
-+	    if (REG_MULTI)
-+	    {
-+		reg_startpos[i] = bp->save_start[i].se_u.pos;
-+		reg_endpos[i] = bp->save_end[i].se_u.pos;
-+	    }
-+	    else
-+	    {
-+		reg_startp[i] = bp->save_start[i].se_u.ptr;
-+		reg_endp[i] = bp->save_end[i].se_u.ptr;
-+	    }
-+	}
-+    }
-+}
-+
-+/*
-  * Advance reglnum, regline and reginput to the next line.
-  */
-     static void
-@@ -6490,10 +6634,10 @@
- 	cc = utf_fold(c);
-     else
- #endif
--	 if (isupper(c))
--	cc = TOLOWER_LOC(c);
--    else if (islower(c))
--	cc = TOUPPER_LOC(c);
-+	 if (MB_ISUPPER(c))
-+	cc = MB_TOLOWER(c);
-+    else if (MB_ISLOWER(c))
-+	cc = MB_TOUPPER(c);
-     else
- 	return vim_strchr(s, c);
- 
-@@ -6637,9 +6781,9 @@
- 		}
- 	    }
- 	    else if (magic)
--		STRCPY(p, p + 1);		/* remove '~' */
-+		mch_memmove(p, p + 1, STRLEN(p));	/* remove '~' */
- 	    else
--		STRCPY(p, p + 2);		/* remove '\~' */
-+		mch_memmove(p, p + 2, STRLEN(p) - 1);	/* remove '\~' */
- 	    --p;
- 	}
- 	else
-@@ -7014,7 +7158,14 @@
- #ifdef FEAT_MBYTE
- 			    if (has_mbyte)
- 			    {
--				int l = mb_ptr2len(s) - 1;
-+				int l;
-+
-+				/* Copy composing characters separately, one
-+				 * at a time. */
-+				if (enc_utf8)
-+				    l = utf_ptr2len(s) - 1;
-+				else
-+				    l = mb_ptr2len(s) - 1;
- 
- 				s += l;
- 				len -= l;
-diff -Naur vim71.orig/src/screen.c vim71/src/screen.c
---- vim71.orig/src/screen.c	2007-05-07 15:27:53.000000000 -0400
-+++ vim71/src/screen.c	2008-06-18 06:56:45.000000000 -0400
-@@ -100,27 +100,7 @@
- static int	screen_cur_row, screen_cur_col;	/* last known cursor position */
- 
- #ifdef FEAT_SEARCH_EXTRA
--/*
-- * Struct used for highlighting 'hlsearch' matches for the last use search
-- * pattern or a ":match" item.
-- * For 'hlsearch' there is one pattern for all windows.  For ":match" there is
-- * a different pattern for each window.
-- */
--typedef struct
--{
--    regmmatch_T	rm;	/* points to the regexp program; contains last found
--			   match (may continue in next line) */
--    buf_T	*buf;	/* the buffer to search for a match */
--    linenr_T	lnum;	/* the line to search for a match */
--    int		attr;	/* attributes to be used for a match */
--    int		attr_cur; /* attributes currently active in win_line() */
--    linenr_T	first_lnum;	/* first lnum to search for multi-line pat */
--    colnr_T	startcol; /* in win_line() points to char where HL starts */
--    colnr_T	endcol;	 /* in win_line() points to char where HL ends */
--} match_T;
--
- static match_T search_hl;	/* used for 'hlsearch' highlight matching */
--static match_T match_hl[3];	/* used for ":match" highlight matching */
- #endif
- 
- #ifdef FEAT_FOLDING
-@@ -155,6 +135,7 @@
- static void redraw_custum_statusline __ARGS((win_T *wp));
- #endif
- #ifdef FEAT_SEARCH_EXTRA
-+#define SEARCH_HL_PRIORITY 0
- static void start_search_hl __ARGS((void));
- static void end_search_hl __ARGS((void));
- static void prepare_search_hl __ARGS((win_T *wp, linenr_T lnum));
-@@ -350,6 +331,11 @@
-     {
- 	if (type < must_redraw)	    /* use maximal type */
- 	    type = must_redraw;
-+
-+	/* must_redraw is reset here, so that when we run into some weird
-+	 * reason to redraw while busy redrawing (e.g., asynchronous
-+	 * scrolling), or update_topline() in win_update() will cause a
-+	 * scroll, the screen will be redrawn later or in win_update(). */
- 	must_redraw = 0;
-     }
- 
-@@ -787,6 +773,7 @@
- 					   w_topline got smaller a bit */
- #endif
- #ifdef FEAT_SEARCH_EXTRA
-+    matchitem_T *cur;		/* points to the match list */
-     int		top_to_mod = FALSE;    /* redraw above mod_top */
- #endif
- 
-@@ -848,22 +835,29 @@
- #endif
- 
- #ifdef FEAT_SEARCH_EXTRA
--    /* Setup for ":match" and 'hlsearch' highlighting.  Disable any previous
-+    /* Setup for match and 'hlsearch' highlighting.  Disable any previous
-      * match */
--    for (i = 0; i < 3; ++i)
-+    cur = wp->w_match_head;
-+    while (cur != NULL)
-     {
--	match_hl[i].rm = wp->w_match[i];
--	if (wp->w_match_id[i] == 0)
--	    match_hl[i].attr = 0;
--	else
--	    match_hl[i].attr = syn_id2attr(wp->w_match_id[i]);
--	match_hl[i].buf = buf;
--	match_hl[i].lnum = 0;
--	match_hl[i].first_lnum = 0;
-+	cur->hl.rm = cur->match;
-+	if (cur->hlg_id == 0)
-+	    cur->hl.attr = 0;
-+	else
-+	    cur->hl.attr = syn_id2attr(cur->hlg_id);
-+	cur->hl.buf = buf;
-+	cur->hl.lnum = 0;
-+	cur->hl.first_lnum = 0;
-+# ifdef FEAT_RELTIME
-+	/* Set the time limit to 'redrawtime'. */
-+	profile_setlimit(p_rdt, &(cur->hl.tm));
-+# endif
-+	cur = cur->next;
-     }
-     search_hl.buf = buf;
-     search_hl.lnum = 0;
-     search_hl.first_lnum = 0;
-+    /* time limit is set at the toplevel, for all windows */
- #endif
- 
- #ifdef FEAT_LINEBREAK
-@@ -923,19 +917,25 @@
- 	     * change in one line may make the Search highlighting in a
- 	     * previous line invalid.  Simple solution: redraw all visible
- 	     * lines above the change.
--	     * Same for a ":match" pattern.
-+	     * Same for a match pattern.
- 	     */
- 	    if (search_hl.rm.regprog != NULL
- 					&& re_multiline(search_hl.rm.regprog))
- 		top_to_mod = TRUE;
- 	    else
--		for (i = 0; i < 3; ++i)
--		    if (match_hl[i].rm.regprog != NULL
--				      && re_multiline(match_hl[i].rm.regprog))
-+	    {
-+		cur = wp->w_match_head;
-+		while (cur != NULL)
-+		{
-+		    if (cur->match.regprog != NULL
-+					   && re_multiline(cur->match.regprog))
- 		    {
- 			top_to_mod = TRUE;
- 			break;
- 		    }
-+		    cur = cur->next;
-+		}
-+	    }
- #endif
- 	}
- #ifdef FEAT_FOLDING
-@@ -1029,6 +1029,13 @@
- 	    type = VALID;
-     }
- 
-+    /* Trick: we want to avoid clearing the screen twice.  screenclear() will
-+     * set "screen_cleared" to TRUE.  The special value MAYBE (which is still
-+     * non-zero and thus not FALSE) will indicate that screenclear() was not
-+     * called. */
-+    if (screen_cleared)
-+	screen_cleared = MAYBE;
-+
-     /*
-      * If there are no changes on the screen that require a complete redraw,
-      * handle three cases:
-@@ -1230,7 +1237,11 @@
- 	    mid_end = wp->w_height;
- 	    if (lastwin == firstwin)
- 	    {
--		screenclear();
-+		/* Clear the screen when it was not done by win_del_lines() or
-+		 * win_ins_lines() above, "screen_cleared" is FALSE or MAYBE
-+		 * then. */
-+		if (screen_cleared != TRUE)
-+		    screenclear();
- #ifdef FEAT_WINDOWS
- 		/* The screen was cleared, redraw the tab pages line. */
- 		if (redraw_tabline)
-@@ -1238,6 +1249,13 @@
- #endif
- 	    }
- 	}
-+
-+	/* When win_del_lines() or win_ins_lines() caused the screen to be
-+	 * cleared (only happens for the first window) or when screenclear()
-+	 * was called directly above, "must_redraw" will have been set to
-+	 * NOT_VALID, need to reset it here to avoid redrawing twice. */
-+	if (screen_cleared == TRUE)
-+	    must_redraw = 0;
-     }
-     else
-     {
-@@ -2292,9 +2310,11 @@
- 			prev_c = u8c;
- #endif
- 		    /* Non-BMP character: display as ? or fullwidth ?. */
-+#ifdef UNICODE16
- 		    if (u8c >= 0x10000)
- 			ScreenLinesUC[idx] = (cells == 2) ? 0xff1f : (int)'?';
- 		    else
-+#endif
- 			ScreenLinesUC[idx] = u8c;
- 		    for (i = 0; i < Screen_mco; ++i)
- 		    {
-@@ -2542,7 +2562,7 @@
- 
-     char_u	extra[18];		/* "%ld" and 'fdc' must fit in here */
-     int		n_extra = 0;		/* number of extra chars */
--    char_u	*p_extra = NULL;	/* string of extra chars */
-+    char_u	*p_extra = NULL;	/* string of extra chars, plus NUL */
-     int		c_extra = NUL;		/* extra chars, all the same */
-     int		extra_attr = 0;		/* attributes when n_extra != 0 */
-     static char_u *at_end_str = (char_u *)""; /* used for p_extra when
-@@ -2584,6 +2604,7 @@
-     int		syntax_attr = 0;	/* attributes desired by syntax */
-     int		has_syntax = FALSE;	/* this buffer has syntax highl. */
-     int		save_did_emsg;
-+    int		eol_hl_off = 0;		/* 1 if highlighted char after EOL */
- #endif
- #ifdef FEAT_SPELL
-     int		has_spell = FALSE;	/* this buffer has spell checking */
-@@ -2623,13 +2644,16 @@
- #if defined(FEAT_SIGNS) || (defined(FEAT_QUICKFIX) && defined(FEAT_WINDOWS)) \
- 	|| defined(FEAT_SYN_HL) || defined(FEAT_DIFF)
- # define LINE_ATTR
--    int		line_attr = 0;		/* atrribute for the whole line */
-+    int		line_attr = 0;		/* attribute for the whole line */
- #endif
- #ifdef FEAT_SEARCH_EXTRA
--    match_T	*shl;			/* points to search_hl or match_hl */
--#endif
--#if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_MBYTE)
--    int		i;
-+    matchitem_T *cur;			/* points to the match list */
-+    match_T	*shl;			/* points to search_hl or a match */
-+    int		shl_flag;		/* flag to indicate whether search_hl
-+					   has been processed or not */
-+    int		prevcol_hl_flag;	/* flag to indicate whether prevcol
-+					   equals startcol of search_hl or one
-+					   of the matches */
- #endif
- #ifdef FEAT_ARABIC
-     int		prev_c = 0;		/* previous Arabic character */
-@@ -3016,18 +3040,25 @@
- 	if (has_spell)
- 	{
- 	    int		len;
-+	    colnr_T	linecol = (colnr_T)(ptr - line);
- 	    hlf_T	spell_hlf = HLF_COUNT;
- 
- 	    pos = wp->w_cursor;
- 	    wp->w_cursor.lnum = lnum;
--	    wp->w_cursor.col = (colnr_T)(ptr - line);
-+	    wp->w_cursor.col = linecol;
- 	    len = spell_move_to(wp, FORWARD, TRUE, TRUE, &spell_hlf);
-+
-+	    /* spell_move_to() may call ml_get() and make "line" invalid */
-+	    line = ml_get_buf(wp->w_buffer, lnum, FALSE);
-+	    ptr = line + linecol;
-+
- 	    if (len == 0 || (int)wp->w_cursor.col > ptr - line)
- 	    {
- 		/* no bad word found at line start, don't check until end of a
- 		 * word */
- 		spell_hlf = HLF_COUNT;
--		word_end = (int)(spell_to_word_end(ptr, wp->w_buffer) - line + 1);
-+		word_end = (int)(spell_to_word_end(ptr, wp->w_buffer)
-+								  - line + 1);
- 	    }
- 	    else
- 	    {
-@@ -3074,12 +3105,20 @@
- 
- #ifdef FEAT_SEARCH_EXTRA
-     /*
--     * Handle highlighting the last used search pattern and ":match".
--     * Do this for both search_hl and match_hl[3].
-+     * Handle highlighting the last used search pattern and matches.
-+     * Do this for both search_hl and the match list.
-      */
--    for (i = 3; i >= 0; --i)
-+    cur = wp->w_match_head;
-+    shl_flag = FALSE;
-+    while (cur != NULL || shl_flag == FALSE)
-     {
--	shl = (i == 3) ? &search_hl : &match_hl[i];
-+	if (shl_flag == FALSE)
-+	{
-+	    shl = &search_hl;
-+	    shl_flag = TRUE;
-+	}
-+	else
-+	    shl = &cur->hl;
- 	shl->startcol = MAXCOL;
- 	shl->endcol = MAXCOL;
- 	shl->attr_cur = 0;
-@@ -3122,6 +3161,8 @@
- 		area_highlighting = TRUE;
- 	    }
- 	}
-+	if (shl != &search_hl && cur != NULL)
-+	    cur = cur->next;
-     }
- #endif
- 
-@@ -3163,10 +3204,8 @@
- 		if (cmdwin_type != 0 && wp == curwin)
- 		{
- 		    /* Draw the cmdline character. */
--		    *extra = cmdwin_type;
- 		    n_extra = 1;
--		    p_extra = extra;
--		    c_extra = NUL;
-+		    c_extra = cmdwin_type;
- 		    char_attr = hl_attr(HLF_AT);
- 		}
- 	    }
-@@ -3182,6 +3221,7 @@
- 		    fill_foldcolumn(extra, wp, FALSE, lnum);
- 		    n_extra = wp->w_p_fdc;
- 		    p_extra = extra;
-+		    p_extra[n_extra] = NUL;
- 		    c_extra = NUL;
- 		    char_attr = hl_attr(HLF_FC);
- 		}
-@@ -3388,13 +3428,24 @@
- 		 * After end, check for start/end of next match.
- 		 * When another match, have to check for start again.
- 		 * Watch out for matching an empty string!
--		 * Do this first for search_hl, then for match_hl, so that
--		 * ":match" overrules 'hlsearch'.
-+		 * Do this for 'search_hl' and the match list (ordered by
-+		 * priority).
- 		 */
- 		v = (long)(ptr - line);
--		for (i = 3; i >= 0; --i)
--		{
--		    shl = (i == 3) ? &search_hl : &match_hl[i];
-+		cur = wp->w_match_head;
-+		shl_flag = FALSE;
-+		while (cur != NULL || shl_flag == FALSE)
-+		{
-+		    if (shl_flag == FALSE
-+			    && ((cur != NULL
-+				    && cur->priority > SEARCH_HL_PRIORITY)
-+				|| cur == NULL))
-+		    {
-+			shl = &search_hl;
-+			shl_flag = TRUE;
-+		    }
-+		    else
-+			shl = &cur->hl;
- 		    while (shl->rm.regprog != NULL)
- 		    {
- 			if (shl->startcol != MAXCOL
-@@ -3442,26 +3493,43 @@
- 			}
- 			break;
- 		    }
-+		    if (shl != &search_hl && cur != NULL)
-+			cur = cur->next;
- 		}
- 
--		/* ":match" highlighting overrules 'hlsearch' */
--		for (i = 0; i <= 3; ++i)
--		    if (i == 3)
--			search_attr = search_hl.attr_cur;
--		    else if (match_hl[i].attr_cur != 0)
-+		/* Use attributes from match with highest priority among
-+		 * 'search_hl' and the match list. */
-+		search_attr = search_hl.attr_cur;
-+		cur = wp->w_match_head;
-+		shl_flag = FALSE;
-+		while (cur != NULL || shl_flag == FALSE)
-+		{
-+		    if (shl_flag == FALSE
-+			    && ((cur != NULL
-+				    && cur->priority > SEARCH_HL_PRIORITY)
-+				|| cur == NULL))
- 		    {
--			search_attr = match_hl[i].attr_cur;
--			break;
-+			shl = &search_hl;
-+			shl_flag = TRUE;
- 		    }
-+		    else
-+			shl = &cur->hl;
-+		    if (shl->attr_cur != 0)
-+			search_attr = shl->attr_cur;
-+		    if (shl != &search_hl && cur != NULL)
-+			cur = cur->next;
-+		}
- 	    }
- #endif
- 
- #ifdef FEAT_DIFF
- 	    if (diff_hlf != (hlf_T)0)
- 	    {
--		if (diff_hlf == HLF_CHD && ptr - line >= change_start)
-+		if (diff_hlf == HLF_CHD && ptr - line >= change_start
-+							      && n_extra == 0)
- 		    diff_hlf = HLF_TXD;		/* changed text */
--		if (diff_hlf == HLF_TXD && ptr - line > change_end)
-+		if (diff_hlf == HLF_TXD && ptr - line > change_end
-+							      && n_extra == 0)
- 		    diff_hlf = HLF_CHD;		/* changed line */
- 		line_attr = hl_attr(diff_hlf);
- 	    }
-@@ -3496,9 +3564,11 @@
- 	 * Get the next character to put on the screen.
- 	 */
- 	/*
--	 * The 'extra' array contains the extra stuff that is inserted to
--	 * represent special characters (non-printable stuff).  When all
--	 * characters are the same, c_extra is used.
-+	 * The "p_extra" points to the extra stuff that is inserted to
-+	 * represent special characters (non-printable stuff) and other
-+	 * things.  When all characters are the same, c_extra is used.
-+	 * "p_extra" must end in a NUL to avoid mb_ptr2len() reads past
-+	 * "p_extra[n_extra]".
- 	 * For the '$' of the 'list' option, n_extra == 1, p_extra == "".
- 	 */
- 	if (n_extra > 0)
-@@ -3611,6 +3681,8 @@
- 			 * Draw it as a space with a composing char. */
- 			if (utf_iscomposing(mb_c))
- 			{
-+			    int i;
-+
- 			    for (i = Screen_mco - 1; i > 0; --i)
- 				u8cc[i] = u8cc[i - 1];
- 			    u8cc[0] = mb_c;
-@@ -3621,13 +3693,18 @@
- 		    if ((mb_l == 1 && c >= 0x80)
- 			    || (mb_l >= 1 && mb_c == 0)
- 			    || (mb_l > 1 && (!vim_isprintc(mb_c)
--							 || mb_c >= 0x10000)))
-+# ifdef UNICODE16
-+							 || mb_c >= 0x10000
-+# endif
-+							 )))
- 		    {
- 			/*
- 			 * Illegal UTF-8 byte: display as <xx>.
- 			 * Non-BMP character : display as ? or fullwidth ?.
- 			 */
-+# ifdef UNICODE16
- 			if (mb_c < 0x10000)
-+# endif
- 			{
- 			    transchar_hex(extra, mb_c);
- # ifdef FEAT_RIGHTLEFT
-@@ -3635,11 +3712,13 @@
- 				rl_mirror(extra);
- # endif
- 			}
-+# ifdef UNICODE16
- 			else if (utf_char2cells(mb_c) != 2)
- 			    STRCPY(extra, "?");
- 			else
- 			    /* 0xff1f in UTF-8: full-width '?' */
- 			    STRCPY(extra, "\357\274\237");
-+# endif
- 
- 			p_extra = extra;
- 			c = *p_extra;
-@@ -3752,10 +3831,8 @@
- 		 * a '<' in the first column. */
- 		if (n_skip > 0 && mb_l > 1)
- 		{
--		    extra[0] = '<';
--		    p_extra = extra;
- 		    n_extra = 1;
--		    c_extra = NUL;
-+		    c_extra = '<';
- 		    c = ' ';
- 		    if (area_attr == 0 && search_attr == 0)
- 		    {
-@@ -3820,7 +3897,7 @@
- # ifdef FEAT_SPELL
- 					       has_spell ? &can_spell :
- # endif
--					       NULL);
-+					       NULL, FALSE);
- 
- 		    if (did_emsg)
- 		    {
-@@ -4248,20 +4325,39 @@
- 	{
- #ifdef FEAT_SEARCH_EXTRA
- 	    long prevcol = (long)(ptr - line) - (c == NUL);
-+
-+	    /* we're not really at that column when skipping some text */
-+	    if ((long)(wp->w_p_wrap ? wp->w_skipcol : wp->w_leftcol) > prevcol)
-+		++prevcol;
- #endif
- 
- 	    /* invert at least one char, used for Visual and empty line or
- 	     * highlight match at end of line. If it's beyond the last
- 	     * char on the screen, just overwrite that one (tricky!)  Not
- 	     * needed when a '$' was displayed for 'list'. */
-+#ifdef FEAT_SEARCH_EXTRA
-+	    prevcol_hl_flag = FALSE;
-+	    if (prevcol == (long)search_hl.startcol)
-+		prevcol_hl_flag = TRUE;
-+	    else
-+	    {
-+		cur = wp->w_match_head;
-+		while (cur != NULL)
-+		{
-+		    if (prevcol == (long)cur->hl.startcol)
-+		    {
-+			prevcol_hl_flag = TRUE;
-+			break;
-+		    }
-+		    cur = cur->next;
-+		}
-+	    }
-+#endif
- 	    if (lcs_eol == lcs_eol_one
- 		    && ((area_attr != 0 && vcol == fromcol && c == NUL)
- #ifdef FEAT_SEARCH_EXTRA
- 			/* highlight 'hlsearch' match at end of line */
--			|| ((prevcol == (long)search_hl.startcol
--				|| prevcol == (long)match_hl[0].startcol
--				|| prevcol == (long)match_hl[1].startcol
--				|| prevcol == (long)match_hl[2].startcol)
-+			|| (prevcol_hl_flag == TRUE
- # if defined(LINE_ATTR)
- 			    && did_line_attr <= 1
- # endif
-@@ -4302,26 +4398,47 @@
- #ifdef FEAT_SEARCH_EXTRA
- 		if (area_attr == 0)
- 		{
--		    for (i = 0; i <= 3; ++i)
--		    {
--			if (i == 3)
--			    char_attr = search_hl.attr;
--			else if ((ptr - line) - 1 == (long)match_hl[i].startcol)
-+		    /* Use attributes from match with highest priority among
-+		     * 'search_hl' and the match list. */
-+		    char_attr = search_hl.attr;
-+		    cur = wp->w_match_head;
-+		    shl_flag = FALSE;
-+		    while (cur != NULL || shl_flag == FALSE)
-+		    {
-+			if (shl_flag == FALSE
-+				&& ((cur != NULL
-+					&& cur->priority > SEARCH_HL_PRIORITY)
-+				    || cur == NULL))
- 			{
--			    char_attr = match_hl[i].attr;
--			    break;
-+			    shl = &search_hl;
-+			    shl_flag = TRUE;
- 			}
-+			else
-+			    shl = &cur->hl;
-+			if ((ptr - line) - 1 == (long)shl->startcol)
-+			    char_attr = shl->attr;
-+			if (shl != &search_hl && cur != NULL)
-+			    cur = cur->next;
- 		    }
- 		}
- #endif
- 		ScreenAttrs[off] = char_attr;
- #ifdef FEAT_RIGHTLEFT
- 		if (wp->w_p_rl)
-+		{
- 		    --col;
-+		    --off;
-+		}
- 		else
- #endif
-+		{
- 		    ++col;
-+		    ++off;
-+		}
- 		++vcol;
-+#ifdef FEAT_SYN_HL
-+		eol_hl_off = 1;
-+#endif
- 	    }
- 	}
- 
-@@ -4331,6 +4448,14 @@
- 	if (c == NUL)
- 	{
- #ifdef FEAT_SYN_HL
-+	    if (eol_hl_off > 0 && vcol - eol_hl_off == (long)wp->w_virtcol)
-+	    {
-+		/* highlight last char after line */
-+		--col;
-+		--off;
-+		--vcol;
-+	    }
-+
- 	    /* Highlight 'cursorcolumn' past end of the line. */
- 	    if (wp->w_p_wrap)
- 		v = wp->w_skipcol;
-@@ -4341,7 +4466,7 @@
- 
- 		vcol = v + col - win_col_off(wp);
- 	    if (wp->w_p_cuc
--		    && (int)wp->w_virtcol >= vcol
-+		    && (int)wp->w_virtcol >= vcol - eol_hl_off
- 		    && (int)wp->w_virtcol < W_WIDTH(wp) * (row - startrow + 1)
- 									   + v
- 		    && lnum != wp->w_cursor.lnum
-@@ -4402,7 +4527,7 @@
- #endif
- 		    col == W_WIDTH(wp) - 1)
- 		&& (*ptr != NUL
--		    || (wp->w_p_list && lcs_eol != NUL && p_extra != at_end_str)
-+		    || (wp->w_p_list && lcs_eol_one > 0)
- 		    || (n_extra && (c_extra != NUL || *p_extra != NUL))))
- 	{
- 	    c = lcs_ext;
-@@ -4460,6 +4585,8 @@
- 	    {
- 		if (mb_utf8)
- 		{
-+		    int i;
-+
- 		    ScreenLinesUC[off] = mb_c;
- 		    if ((c & 0xff) == 0)
- 			ScreenLines[off] = 0x80;   /* avoid storing zero */
-@@ -4548,7 +4675,7 @@
- 
- 	/*
- 	 * At end of screen line and there is more to come: Display the line
--	 * so far.  If there is no more to display it is catched above.
-+	 * so far.  If there is no more to display it is caught above.
- 	 */
- 	if ((
- #ifdef FEAT_RIGHTLEFT
-@@ -4625,9 +4752,13 @@
- #endif
- #ifdef FEAT_MBYTE
- 			 && !(has_mbyte
--			     && ((*mb_off2cells)(LineOffset[screen_row]) == 2
-+			     && ((*mb_off2cells)(LineOffset[screen_row],
-+				     LineOffset[screen_row] + screen_Columns)
-+									  == 2
- 				 || (*mb_off2cells)(LineOffset[screen_row - 1]
--							+ (int)Columns - 2) == 2))
-+							+ (int)Columns - 2,
-+				     LineOffset[screen_row] + screen_Columns)
-+									== 2))
- #endif
- 		   )
- 		{
-@@ -4787,6 +4918,10 @@
- {
-     unsigned	    off_from;
-     unsigned	    off_to;
-+#ifdef FEAT_MBYTE
-+    unsigned	    max_off_from;
-+    unsigned	    max_off_to;
-+#endif
-     int		    col = 0;
- #if defined(FEAT_GUI) || defined(UNIX) || defined(FEAT_VERTSPLIT)
-     int		    hl;
-@@ -4813,6 +4948,10 @@
- 
-     off_from = (unsigned)(current_ScreenLine - ScreenLines);
-     off_to = LineOffset[row] + coloff;
-+#ifdef FEAT_MBYTE
-+    max_off_from = off_from + screen_Columns;
-+    max_off_to = LineOffset[row] + screen_Columns;
-+#endif
- 
- #ifdef FEAT_RIGHTLEFT
-     if (rlflag)
-@@ -4847,7 +4986,7 @@
-     {
- #ifdef FEAT_MBYTE
- 	if (has_mbyte && (col + 1 < endcol))
--	    char_cells = (*mb_off2cells)(off_from);
-+	    char_cells = (*mb_off2cells)(off_from, max_off_from);
- 	else
- 	    char_cells = 1;
- #endif
-@@ -4924,7 +5063,7 @@
- 		 * ScreenLinesUC[] is sufficient. */
- 		if (char_cells == 1
- 			&& col + 1 < endcol
--			&& (*mb_off2cells)(off_to) > 1)
-+			&& (*mb_off2cells)(off_to, max_off_to) > 1)
- 		{
- 		    /* Writing a single-cell character over a double-cell
- 		     * character: need to redraw the next cell. */
-@@ -4933,8 +5072,8 @@
- 		}
- 		else if (char_cells == 2
- 			&& col + 2 < endcol
--			&& (*mb_off2cells)(off_to) == 1
--			&& (*mb_off2cells)(off_to + 1) > 1)
-+			&& (*mb_off2cells)(off_to, max_off_to) == 1
-+			&& (*mb_off2cells)(off_to + 1, max_off_to) > 1)
- 		{
- 		    /* Writing the second half of a double-cell character over
- 		     * a double-cell character: need to redraw the second
-@@ -4953,10 +5092,10 @@
- 	     * char over the left halve of an existing one. */
- 	    if (has_mbyte && col + char_cells == endcol
- 		    && ((char_cells == 1
--			    && (*mb_off2cells)(off_to) > 1)
-+			    && (*mb_off2cells)(off_to, max_off_to) > 1)
- 			|| (char_cells == 2
--			    && (*mb_off2cells)(off_to) == 1
--			    && (*mb_off2cells)(off_to + 1) > 1)))
-+			    && (*mb_off2cells)(off_to, max_off_to) == 1
-+			    && (*mb_off2cells)(off_to + 1, max_off_to) > 1)))
- 		clear_next = TRUE;
- #endif
- 
-@@ -5096,10 +5235,11 @@
- 			/* find previous character by counting from first
- 			 * column and get its width. */
- 			unsigned off = LineOffset[row];
-+			unsigned max_off = LineOffset[row] + screen_Columns;
- 
- 			while (off < off_to)
- 			{
--			    prev_cells = (*mb_off2cells)(off);
-+			    prev_cells = (*mb_off2cells)(off, max_off);
- 			    off += prev_cells;
- 			}
- 		    }
-@@ -5285,7 +5425,7 @@
- static int skip_status_match_char __ARGS((expand_T *xp, char_u *s));
- 
- /*
-- * Get the lenght of an item as it will be shown in the status line.
-+ * Get the length of an item as it will be shown in the status line.
-  */
-     static int
- status_match_len(xp, s)
-@@ -5351,7 +5491,7 @@
-     int		row;
-     char_u	*buf;
-     int		len;
--    int		clen;		/* lenght in screen cells */
-+    int		clen;		/* length in screen cells */
-     int		fillchar;
-     int		attr;
-     int		i;
-@@ -6103,6 +6243,7 @@
-     char_u	*ptr = text;
-     int		c;
- #ifdef FEAT_MBYTE
-+    unsigned	max_off;
-     int		mbyte_blen = 1;
-     int		mbyte_cells = 1;
-     int		u8c = 0;
-@@ -6119,8 +6260,12 @@
- 	return;
- 
-     off = LineOffset[row] + col;
--    while (*ptr != NUL && col < screen_Columns
--				      && (len < 0 || (int)(ptr - text) < len))
-+#ifdef FEAT_MBYTE
-+    max_off = LineOffset[row] + screen_Columns;
-+#endif
-+    while (col < screen_Columns
-+	    && (len < 0 || (int)(ptr - text) < len)
-+	    && *ptr != NUL)
-     {
- 	c = *ptr;
- #ifdef FEAT_MBYTE
-@@ -6143,6 +6288,7 @@
- 		else
- 		    u8c = utfc_ptr2char(ptr, u8cc);
- 		mbyte_cells = utf_char2cells(u8c);
-+# ifdef UNICODE16
- 		/* Non-BMP character: display as ? or fullwidth ?. */
- 		if (u8c >= 0x10000)
- 		{
-@@ -6150,6 +6296,7 @@
- 		    if (attr == 0)
- 			attr = hl_attr(HLF_8);
- 		}
-+# endif
- # ifdef FEAT_ARABIC
- 		if (p_arshape && !p_tbidi && ARABIC_CHAR(u8c))
- 		{
-@@ -6241,19 +6388,19 @@
- 	    else if (has_mbyte
- 		    && (len < 0 ? ptr[mbyte_blen] == NUL
- 					     : ptr + mbyte_blen >= text + len)
--		    && ((mbyte_cells == 1 && (*mb_off2cells)(off) > 1)
-+		    && ((mbyte_cells == 1 && (*mb_off2cells)(off, max_off) > 1)
- 			|| (mbyte_cells == 2
--			    && (*mb_off2cells)(off) == 1
--			    && (*mb_off2cells)(off + 1) > 1)))
-+			    && (*mb_off2cells)(off, max_off) == 1
-+			    && (*mb_off2cells)(off + 1, max_off) > 1)))
- 		clear_next_cell = TRUE;
- 
- 	    /* Make sure we never leave a second byte of a double-byte behind,
- 	     * it confuses mb_off2cells(). */
- 	    if (enc_dbcs
--		    && ((mbyte_cells == 1 && (*mb_off2cells)(off) > 1)
-+		    && ((mbyte_cells == 1 && (*mb_off2cells)(off, max_off) > 1)
- 			|| (mbyte_cells == 2
--			    && (*mb_off2cells)(off) == 1
--			    && (*mb_off2cells)(off + 1) > 1)))
-+			    && (*mb_off2cells)(off, max_off) == 1
-+			    && (*mb_off2cells)(off + 1, max_off) > 1)))
- 		ScreenLines[off + mbyte_blen] = 0;
- #endif
- 	    ScreenLines[off] = c;
-@@ -6318,7 +6465,7 @@
- 
- #ifdef FEAT_SEARCH_EXTRA
- /*
-- * Prepare for 'searchhl' highlighting.
-+ * Prepare for 'hlsearch' highlighting.
-  */
-     static void
- start_search_hl()
-@@ -6327,11 +6474,15 @@
-     {
- 	last_pat_prog(&search_hl.rm);
- 	search_hl.attr = hl_attr(HLF_L);
-+# ifdef FEAT_RELTIME
-+	/* Set the time limit to 'redrawtime'. */
-+	profile_setlimit(p_rdt, &search_hl.tm);
-+# endif
-     }
- }
- 
- /*
-- * Clean up for 'searchhl' highlighting.
-+ * Clean up for 'hlsearch' highlighting.
-  */
-     static void
- end_search_hl()
-@@ -6351,18 +6502,28 @@
-     win_T	*wp;
-     linenr_T	lnum;
- {
--    match_T	*shl;		/* points to search_hl or match_hl */
-+    matchitem_T *cur;		/* points to the match list */
-+    match_T	*shl;		/* points to search_hl or a match */
-+    int		shl_flag;	/* flag to indicate whether search_hl
-+				   has been processed or not */
-     int		n;
--    int		i;
- 
-     /*
-      * When using a multi-line pattern, start searching at the top
-      * of the window or just after a closed fold.
--     * Do this both for search_hl and match_hl[3].
-+     * Do this both for search_hl and the match list.
-      */
--    for (i = 3; i >= 0; --i)
-+    cur = wp->w_match_head;
-+    shl_flag = FALSE;
-+    while (cur != NULL || shl_flag == FALSE)
-     {
--	shl = (i == 3) ? &search_hl : &match_hl[i];
-+	if (shl_flag == FALSE)
-+	{
-+	    shl = &search_hl;
-+	    shl_flag = TRUE;
-+	}
-+	else
-+	    shl = &cur->hl;
- 	if (shl->rm.regprog != NULL
- 		&& shl->lnum == 0
- 		&& re_multiline(shl->rm.regprog))
-@@ -6397,11 +6558,13 @@
- 		}
- 	    }
- 	}
-+	if (shl != &search_hl && cur != NULL)
-+	    cur = cur->next;
-     }
- }
- 
- /*
-- * Search for a next 'searchl' or ":match" match.
-+ * Search for a next 'hlsearch' or match.
-  * Uses shl->buf.
-  * Sets shl->lnum and shl->rm contents.
-  * Note: Assumes a previous match is always before "lnum", unless
-@@ -6411,7 +6574,7 @@
-     static void
- next_search_hl(win, shl, lnum, mincol)
-     win_T	*win;
--    match_T	*shl;		/* points to search_hl or match_hl */
-+    match_T	*shl;		/* points to search_hl or a match */
-     linenr_T	lnum;
-     colnr_T	mincol;		/* minimal column for a match */
- {
-@@ -6440,6 +6603,14 @@
-     called_emsg = FALSE;
-     for (;;)
-     {
-+#ifdef FEAT_RELTIME
-+	/* Stop searching after passing the time limit. */
-+	if (profile_passed_limit(&(shl->tm)))
-+	{
-+	    shl->lnum = 0;		/* no match found in time */
-+	    break;
-+	}
-+#endif
- 	/* Three situations:
- 	 * 1. No useful previous match: search from start of line.
- 	 * 2. Not Vi compatible or empty match: continue at next character.
-@@ -6473,13 +6644,19 @@
- 	    matchcol = shl->rm.endpos[0].col;
- 
- 	shl->lnum = lnum;
--	nmatched = vim_regexec_multi(&shl->rm, win, shl->buf, lnum, matchcol);
-+	nmatched = vim_regexec_multi(&shl->rm, win, shl->buf, lnum, matchcol,
-+#ifdef FEAT_RELTIME
-+		&(shl->tm)
-+#else
-+		NULL
-+#endif
-+		);
- 	if (called_emsg)
- 	{
- 	    /* Error while handling regexp: stop using this regexp. */
- 	    if (shl == &search_hl)
- 	    {
--		/* don't free the regprog in match_hl[], it's a copy */
-+		/* don't free regprog in the match list, it's a copy */
- 		vim_free(shl->rm.regprog);
- 		no_hlsearch = TRUE;
- 	    }
-@@ -6827,6 +7004,9 @@
- {
-     int		r, c;
-     int		off;
-+#ifdef FEAT_MBYTE
-+    int		max_off;
-+#endif
- 
-     /* Can't use ScreenLines unless initialized */
-     if (ScreenLines == NULL)
-@@ -6837,10 +7017,13 @@
-     for (r = row; r < row + height; ++r)
-     {
- 	off = LineOffset[r];
-+#ifdef FEAT_MBYTE
-+	max_off = off + screen_Columns;
-+#endif
- 	for (c = col; c < col + width; ++c)
- 	{
- #ifdef FEAT_MBYTE
--	    if (enc_dbcs != 0 && dbcs_off2cells(off + c) > 1)
-+	    if (enc_dbcs != 0 && dbcs_off2cells(off + c, max_off) > 1)
- 	    {
- 		screen_char_2(off + c, r, c);
- 		++c;
-@@ -6850,7 +7033,7 @@
- 	    {
- 		screen_char(off + c, r, c);
- #ifdef FEAT_MBYTE
--		if (utf_off2cells(off + c) > 1)
-+		if (utf_off2cells(off + c, max_off) > 1)
- 		    ++c;
- #endif
- 	    }
-@@ -7862,9 +8045,13 @@
- 	windgoto(W_WINROW(curwin) + curwin->w_wrow,
- 		W_WINCOL(curwin) + (
- #ifdef FEAT_RIGHTLEFT
-+		/* With 'rightleft' set and the cursor on a double-wide
-+		 * character, position it on the leftmost column. */
- 		curwin->w_p_rl ? ((int)W_WIDTH(curwin) - curwin->w_wcol - (
- # ifdef FEAT_MBYTE
--			has_mbyte ? (*mb_ptr2cells)(ml_get_cursor()) :
-+			(has_mbyte
-+			   && (*mb_ptr2cells)(ml_get_cursor()) == 2
-+			   && vim_isprintc(gchar_cursor())) ? 2 :
- # endif
- 			1)) :
- #endif
-@@ -9170,6 +9357,11 @@
-        )
- 	maketitle();
- #endif
-+#ifdef FEAT_WINDOWS
-+    /* Redraw the tab pages line if needed. */
-+    if (redraw_tabline)
-+	draw_tabline();
-+#endif
- }
- 
- #ifdef FEAT_CMDL_INFO
-diff -Naur vim71.orig/src/search.c vim71/src/search.c
---- vim71.orig/src/search.c	2007-05-07 15:42:02.000000000 -0400
-+++ vim71/src/search.c	2008-06-18 06:56:06.000000000 -0400
-@@ -101,7 +101,6 @@
- static char_u	    *mr_pattern = NULL;	/* pattern used by search_regcomp() */
- #ifdef FEAT_RIGHTLEFT
- static int	    mr_pattern_alloced = FALSE; /* mr_pattern was allocated */
--static char_u	    *reverse_text __ARGS((char_u *s));
- #endif
- 
- #ifdef FEAT_FIND_ID
-@@ -228,12 +227,12 @@
-     return mr_pattern;
- }
- 
--#ifdef FEAT_RIGHTLEFT
-+#if defined(FEAT_RIGHTLEFT) || defined(PROTO)
- /*
-  * Reverse text into allocated memory.
-  * Returns the allocated string, NULL when out of memory.
-  */
--    static char_u *
-+    char_u *
- reverse_text(s)
-     char_u *s;
- {
-@@ -495,8 +494,9 @@
-  * When FEAT_EVAL is defined, returns the index of the first matching
-  * subpattern plus one; one if there was none.
-  */
-+/*ARGSUSED*/
-     int
--searchit(win, buf, pos, dir, pat, count, options, pat_use, stop_lnum)
-+searchit(win, buf, pos, dir, pat, count, options, pat_use, stop_lnum, tm)
-     win_T	*win;		/* window to search in; can be NULL for a
- 				   buffer without a window! */
-     buf_T	*buf;
-@@ -507,6 +507,7 @@
-     int		options;
-     int		pat_use;	/* which pattern to use when "pat" is empty */
-     linenr_T	stop_lnum;	/* stop after this line number when != 0 */
-+    proftime_T	*tm;		/* timeout limit or NULL */
- {
-     int		found;
-     linenr_T	lnum;		/* no init to shut up Apollo cc */
-@@ -537,7 +538,10 @@
- 	return FAIL;
-     }
- 
--    if (options & SEARCH_START)
-+    /* When not accepting a match at the start position set "extra_col" to a
-+     * non-zero value.  Don't do that when starting at MAXCOL, since MAXCOL +
-+     * 1 is zero. */
-+    if ((options & SEARCH_START) || pos->col == MAXCOL)
- 	extra_col = 0;
- #ifdef FEAT_MBYTE
-     /* Watch out for the "col" being MAXCOL - 2, used in a closed fold. */
-@@ -573,8 +577,12 @@
- 	/*
- 	 * Start searching in current line, unless searching backwards and
- 	 * we're in column 0.
-+	 * If we are searching backwards, in column 0, and not including the
-+	 * current position, gain some efficiency by skipping back a line.
-+	 * Otherwise begin the search in the current line.
- 	 */
--	if (dir == BACKWARD && start_pos.col == 0)
-+	if (dir == BACKWARD && start_pos.col == 0
-+					     && (options & SEARCH_START) == 0)
- 	{
- 	    lnum = pos->lnum - 1;
- 	    at_first_line = FALSE;
-@@ -591,12 +599,23 @@
- 		if (stop_lnum != 0 && (dir == FORWARD
- 				       ? lnum > stop_lnum : lnum < stop_lnum))
- 		    break;
-+#ifdef FEAT_RELTIME
-+		/* Stop after passing the "tm" time limit. */
-+		if (tm != NULL && profile_passed_limit(tm))
-+		    break;
-+#endif
- 
- 		/*
- 		 * Look for a match somewhere in line "lnum".
- 		 */
- 		nmatched = vim_regexec_multi(&regmatch, win, buf,
--							    lnum, (colnr_T)0);
-+						      lnum, (colnr_T)0,
-+#ifdef FEAT_RELTIME
-+						      tm
-+#else
-+						      NULL
-+#endif
-+						      );
- 		/* Abort searching on an error (e.g., out of stack). */
- 		if (called_emsg)
- 		    break;
-@@ -605,10 +624,10 @@
- 		    /* match may actually be in another line when using \zs */
- 		    matchpos = regmatch.startpos[0];
- 		    endpos = regmatch.endpos[0];
--# ifdef FEAT_EVAL
-+#ifdef FEAT_EVAL
- 		    submatch = first_submatch(&regmatch);
--# endif
--		    /* Line me be past end of buffer for "\n\zs". */
-+#endif
-+		    /* "lnum" may be past end of buffer for "\n\zs". */
- 		    if (lnum + matchpos.lnum > buf->b_ml.ml_line_count)
- 			ptr = (char_u *)"";
- 		    else
-@@ -683,7 +702,13 @@
- 			    if (ptr[matchcol] == NUL
- 				    || (nmatched = vim_regexec_multi(&regmatch,
- 					      win, buf, lnum + matchpos.lnum,
--					      matchcol)) == 0)
-+					      matchcol,
-+#ifdef FEAT_RELTIME
-+					      tm
-+#else
-+					      NULL
-+#endif
-+					      )) == 0)
- 			    {
- 				match_ok = FALSE;
- 				break;
-@@ -789,7 +814,13 @@
- 			    if (ptr[matchcol] == NUL
- 				    || (nmatched = vim_regexec_multi(&regmatch,
- 					      win, buf, lnum + matchpos.lnum,
--							      matchcol)) == 0)
-+					      matchcol,
-+#ifdef FEAT_RELTIME
-+					      tm
-+#else
-+					      NULL
-+#endif
-+					    )) == 0)
- 				break;
- 
- 			    /* Need to get the line pointer again, a
-@@ -805,21 +836,38 @@
- 			    continue;
- 		    }
- 
--		    if (options & SEARCH_END && !(options & SEARCH_NOOF))
-+		    /* With the SEARCH_END option move to the last character
-+		     * of the match.  Don't do it for an empty match, end
-+		     * should be same as start then. */
-+		    if (options & SEARCH_END && !(options & SEARCH_NOOF)
-+			    && !(matchpos.lnum == endpos.lnum
-+				&& matchpos.col == endpos.col))
- 		    {
-+			/* For a match in the first column, set the position
-+			 * on the NUL in the previous line. */
- 			pos->lnum = lnum + endpos.lnum;
--			pos->col = endpos.col - 1;
--#ifdef FEAT_MBYTE
--			if (has_mbyte)
-+			pos->col = endpos.col;
-+			if (endpos.col == 0)
- 			{
--			    /* 'e' offset may put us just below the last line */
--			    if (pos->lnum > buf->b_ml.ml_line_count)
--				ptr = (char_u *)"";
--			    else
--				ptr = ml_get_buf(buf, pos->lnum, FALSE);
--			    pos->col -= (*mb_head_off)(ptr, ptr + pos->col);
-+			    if (pos->lnum > 1)  /* just in case */
-+			    {
-+				--pos->lnum;
-+				pos->col = (colnr_T)STRLEN(ml_get_buf(buf,
-+							   pos->lnum, FALSE));
-+			    }
- 			}
-+			else
-+			{
-+			    --pos->col;
-+#ifdef FEAT_MBYTE
-+			    if (has_mbyte
-+				    && pos->lnum <= buf->b_ml.ml_line_count)
-+			    {
-+				ptr = ml_get_buf(buf, pos->lnum, FALSE);
-+				pos->col -= (*mb_head_off)(ptr, ptr + pos->col);
-+			    }
- #endif
-+			}
- 		    }
- 		    else
- 		    {
-@@ -967,12 +1015,13 @@
-  * return 0 for failure, 1 for found, 2 for found and line offset added
-  */
-     int
--do_search(oap, dirc, pat, count, options)
-+do_search(oap, dirc, pat, count, options, tm)
-     oparg_T	    *oap;	/* can be NULL */
-     int		    dirc;	/* '/' or '?' */
-     char_u	   *pat;
-     long	    count;
-     int		    options;
-+    proftime_T	    *tm;	/* timeout limit or NULL */
- {
-     pos_T	    pos;	/* position of the last match */
-     char_u	    *searchstr;
-@@ -1246,7 +1295,7 @@
- 		       (SEARCH_KEEP + SEARCH_PEEK + SEARCH_HIS
- 			+ SEARCH_MSG + SEARCH_START
- 			+ ((pat != NULL && *pat == ';') ? 0 : SEARCH_NOOF))),
--		RE_LAST, (linenr_T)0);
-+		RE_LAST, (linenr_T)0, tm);
- 
- 	if (dircp != NULL)
- 	    *dircp = dirc;	/* restore second '/' or '?' for normal_cmd() */
-@@ -1894,7 +1943,7 @@
-     }
- 
- #ifdef FEAT_RIGHTLEFT
--    /* This is just guessing: when 'rightleft' is set, search for a maching
-+    /* This is just guessing: when 'rightleft' is set, search for a matching
-      * paren/brace in the other direction. */
-     if (curwin->w_p_rl && vim_strchr((char_u *)"()[]{}<>", initc) != NULL)
- 	backwards = !backwards;
-@@ -2124,6 +2173,9 @@
- 			else if (!backwards)
- 			    inquote = TRUE;
- 		    }
-+
-+		    /* ml_get() only keeps one line, need to get linep again */
-+		    linep = ml_get(pos.lnum);
- 		}
- 	    }
- 	}
-@@ -2313,7 +2365,9 @@
- #endif
-     while ((p = vim_strchr(p, '/')) != NULL)
-     {
--	if (p[1] == '/')
-+	/* accept a double /, unless it's preceded with * and followed by *,
-+	 * because * / / * is an end and start of a C comment */
-+	if (p[1] == '/' && (p == line || p[-1] != '*' || p[2] != '*'))
- 	    break;
- 	++p;
-     }
-@@ -2795,7 +2849,7 @@
- 	i = inc_cursor();
- 	if (i == -1 || (i >= 1 && last_line)) /* started at last char in file */
- 	    return FAIL;
--	if (i == 1 && eol && count == 0)      /* started at last char in line */
-+	if (i >= 1 && eol && count == 0)      /* started at last char in line */
- 	    return OK;
- 
- 	/*
-@@ -3600,13 +3654,16 @@
-     {
- 	oap->start = start_pos;
- 	oap->motion_type = MCHAR;
-+	oap->inclusive = FALSE;
- 	if (sol)
--	{
- 	    incl(&curwin->w_cursor);
--	    oap->inclusive = FALSE;
--	}
--	else
-+	else if (ltoreq(start_pos, curwin->w_cursor))
-+	    /* Include the character under the cursor. */
- 	    oap->inclusive = TRUE;
-+	else
-+	    /* End is before the start (no text in between <>, [], etc.): don't
-+	     * operate on any text. */
-+	    curwin->w_cursor = start_pos;
-     }
- 
-     return OK;
-@@ -3717,6 +3774,10 @@
-     old_pos = curwin->w_cursor;
-     old_end = curwin->w_cursor;		    /* remember where we started */
-     old_start = old_end;
-+#ifdef FEAT_VISUAL
-+    if (!VIsual_active || *p_sel == 'e')
-+#endif
-+	decl(&old_end);			    /* old_end is inclusive */
- 
-     /*
-      * If we start on "<aaa>" select that block.
-@@ -3734,7 +3795,7 @@
- 
- 	if (in_html_tag(FALSE))
- 	{
--	    /* cursor on start tag, move to just after it */
-+	    /* cursor on start tag, move to its '>' */
- 	    while (*ml_get_cursor() != '>')
- 		if (inc_cursor() < 0)
- 		    break;
-@@ -3769,7 +3830,7 @@
- 	if (do_searchpair((char_u *)"<[^ \t>/!]\\+\\%(\\_s\\_[^>]\\{-}[^/]>\\|$\\|\\_s\\=>\\)",
- 		    (char_u *)"",
- 		    (char_u *)"</[^>]*>", BACKWARD, (char_u *)"", 0,
--						      NULL, (linenr_T)0) <= 0)
-+						  NULL, (linenr_T)0, 0L) <= 0)
- 	{
- 	    curwin->w_cursor = old_pos;
- 	    goto theend;
-@@ -3803,7 +3864,7 @@
-     sprintf((char *)epat, "</%.*s>\\c", len, p);
- 
-     r = do_searchpair(spat, (char_u *)"", epat, FORWARD, (char_u *)"",
--						       0, NULL, (linenr_T)0);
-+						    0, NULL, (linenr_T)0, 0L);
- 
-     vim_free(spat);
-     vim_free(epat);
-@@ -3838,7 +3899,7 @@
- 	/* Exclude the start tag. */
- 	curwin->w_cursor = start_pos;
- 	while (inc_cursor() >= 0)
--	    if (*ml_get_cursor() == '>' && lt(curwin->w_cursor, end_pos))
-+	    if (*ml_get_cursor() == '>')
- 	    {
- 		inc_cursor();
- 		start_pos = curwin->w_cursor;
-@@ -3860,7 +3921,11 @@
- #ifdef FEAT_VISUAL
-     if (VIsual_active)
-     {
--	if (*p_sel == 'e')
-+	/* If the end is before the start there is no text between tags, select
-+	 * the char under the cursor. */
-+	if (lt(end_pos, start_pos))
-+	    curwin->w_cursor = start_pos;
-+	else if (*p_sel == 'e')
- 	    ++curwin->w_cursor.col;
- 	VIsual = start_pos;
- 	VIsual_mode = 'v';
-@@ -3872,7 +3937,15 @@
-     {
- 	oap->start = start_pos;
- 	oap->motion_type = MCHAR;
--	oap->inclusive = TRUE;
-+	if (lt(end_pos, start_pos))
-+	{
-+	    /* End is before the start: there is no text between tags; operate
-+	     * on an empty area. */
-+	    curwin->w_cursor = start_pos;
-+	    oap->inclusive = FALSE;
-+	}
-+	else
-+	    oap->inclusive = TRUE;
-     }
-     retval = OK;
- 
-diff -Naur vim71.orig/src/spell.c vim71/src/spell.c
---- vim71.orig/src/spell.c	2007-05-07 15:48:38.000000000 -0400
-+++ vim71/src/spell.c	2008-06-18 06:56:35.000000000 -0400
-@@ -753,6 +753,7 @@
- static int spell_iswordp __ARGS((char_u *p, buf_T *buf));
- static int spell_iswordp_nmw __ARGS((char_u *p));
- #ifdef FEAT_MBYTE
-+static int spell_mb_isword_class __ARGS((int cl));
- static int spell_iswordp_w __ARGS((int *p, buf_T *buf));
- #endif
- static int write_spell_prefcond __ARGS((FILE *fd, garray_T *gap));
-@@ -2146,7 +2147,7 @@
- 			{
- 			    col = (int)(p - buf);
- 			    (void)syn_get_id(wp, lnum, (colnr_T)col,
--						       FALSE, &can_spell);
-+						    FALSE, &can_spell, FALSE);
- 			    if (!can_spell)
- 				attr = HLF_COUNT;
- 			}
-@@ -2268,6 +2269,8 @@
- /*
-  * For spell checking: concatenate the start of the following line "line" into
-  * "buf", blanking-out special characters.  Copy less then "maxlen" bytes.
-+ * Keep the blanks at the start of the next line, this is used in win_line()
-+ * to skip those bytes if the word was OK.
-  */
-     void
- spell_cat_line(buf, line, maxlen)
-@@ -2284,12 +2287,14 @@
- 
-     if (*p != NUL)
-     {
--	*buf = ' ';
--	vim_strncpy(buf + 1, line, maxlen - 2);
--	n = (int)(p - line);
--	if (n >= maxlen)
--	    n = maxlen - 1;
--	vim_memset(buf + 1, ' ', n);
-+	/* Only worth concatenating if there is something else than spaces to
-+	 * concatenate. */
-+	n = (int)(p - line) + 1;
-+	if (n < maxlen - 1)
-+	{
-+	    vim_memset(buf, ' ', n);
-+	    vim_strncpy(buf +  n, p, maxlen - 1 - n);
-+	}
-     }
- }
- 
-@@ -7829,7 +7834,7 @@
- # if (_MSC_VER <= 1200)
- /* This line is required for VC6 without the service pack.  Also see the
-  * matching #pragma below. */
--/* # pragma optimize("", off) */
-+ #  pragma optimize("", off)
- # endif
- #endif
- 
-@@ -7859,7 +7864,7 @@
- 
- #ifdef _MSC_VER
- # if (_MSC_VER <= 1200)
--/* # pragma optimize("", on) */
-+ #  pragma optimize("", on)
- # endif
- #endif
- 
-@@ -9785,7 +9790,7 @@
- 
- 	c = mb_ptr2char(s);
- 	if (c > 255)
--	    return mb_get_class(s) >= 2;
-+	    return spell_mb_isword_class(mb_get_class(s));
- 	return spelltab.st_isw[c];
-     }
- #endif
-@@ -9808,7 +9813,7 @@
-     {
- 	c = mb_ptr2char(p);
- 	if (c > 255)
--	    return mb_get_class(p) >= 2;
-+	    return spell_mb_isword_class(mb_get_class(p));
- 	return spelltab.st_isw[c];
-     }
- #endif
-@@ -9817,6 +9822,18 @@
- 
- #ifdef FEAT_MBYTE
- /*
-+ * Return TRUE if word class indicates a word character.
-+ * Only for characters above 255.
-+ * Unicode subscript and superscript are not considered word characters.
-+ */
-+    static int
-+spell_mb_isword_class(cl)
-+    int cl;
-+{
-+    return cl >= 2 && cl != 0x2070 && cl != 0x2080;
-+}
-+
-+/*
-  * Return TRUE if "p" points to a word character.
-  * Wide version of spell_iswordp().
-  */
-@@ -9837,7 +9854,7 @@
-     if (*s > 255)
-     {
- 	if (enc_utf8)
--	    return utf_class(*s) >= 2;
-+	    return spell_mb_isword_class(utf_class(*s));
- 	if (enc_dbcs)
- 	    return dbcs_class((unsigned)*s >> 8, *s & 0xff) >= 2;
- 	return 0;
-@@ -10343,7 +10360,7 @@
-     curwin->w_cursor.lnum = 0;
-     while (!got_int)
-     {
--	if (do_search(NULL, '/', frompat, 1L, SEARCH_KEEP) == 0
-+	if (do_search(NULL, '/', frompat, 1L, SEARCH_KEEP, NULL) == 0
- 						   || u_save_cursor() == FAIL)
- 	    break;
- 
-@@ -12182,7 +12199,9 @@
- 	    {
- 		n = mb_cptr2len(p);
- 		c = mb_ptr2char(p);
--		if (!soundfold && !spell_iswordp(p + n, curbuf))
-+		if (p[n] == NUL)
-+		    c2 = NUL;
-+		else if (!soundfold && !spell_iswordp(p + n, curbuf))
- 		    c2 = c; /* don't swap non-word char */
- 		else
- 		    c2 = mb_ptr2char(p + n);
-@@ -12190,12 +12209,21 @@
- 	    else
- #endif
- 	    {
--		if (!soundfold && !spell_iswordp(p + 1, curbuf))
-+		if (p[1] == NUL)
-+		    c2 = NUL;
-+		else if (!soundfold && !spell_iswordp(p + 1, curbuf))
- 		    c2 = c; /* don't swap non-word char */
- 		else
- 		    c2 = p[1];
- 	    }
- 
-+	    /* When the second character is NUL we can't swap. */
-+	    if (c2 == NUL)
-+	    {
-+		sp->ts_state = STATE_REP_INI;
-+		break;
-+	    }
-+
- 	    /* When characters are identical, swap won't do anything.
- 	     * Also get here if the second char is not a word character. */
- 	    if (c == c2)
-diff -Naur vim71.orig/src/structs.h vim71/src/structs.h
---- vim71.orig/src/structs.h	2007-05-07 15:50:49.000000000 -0400
-+++ vim71/src/structs.h	2008-06-18 06:55:25.000000000 -0400
-@@ -278,6 +278,9 @@
-     linenr_T	ue_lcount;	/* linecount when u_save called */
-     char_u	**ue_array;	/* array of lines in undo block */
-     long	ue_size;	/* number of lines in ue_array */
-+#ifdef U_DEBUG
-+    int		ue_magic;	/* magic number to check allocation */
-+#endif
- };
- 
- struct u_header
-@@ -300,6 +303,9 @@
-     visualinfo_T uh_visual;	/* Visual areas before undo/after redo */
- #endif
-     time_t	uh_time;	/* timestamp when the change was made */
-+#ifdef U_DEBUG
-+    int		uh_magic;	/* magic number to check allocation */
-+#endif
- };
- 
- /* values for uh_flags */
-@@ -1453,6 +1459,7 @@
- #ifdef FEAT_MBYTE
-     char_u	*b_start_fenc;	/* 'fileencoding' when edit started or NULL */
-     int		b_bad_char;	/* "++bad=" argument when edit started or 0 */
-+    int		b_start_bomb;	/* 'bomb' when it was read */
- #endif
- 
- #ifdef FEAT_EVAL
-@@ -1694,6 +1701,44 @@
- #define FR_COL	2	/* frame with a column of windows */
- 
- /*
-+ * Struct used for highlighting 'hlsearch' matches, matches defined by
-+ * ":match" and matches defined by match functions.
-+ * For 'hlsearch' there is one pattern for all windows.  For ":match" and the
-+ * match functions there is a different pattern for each window.
-+ */
-+typedef struct
-+{
-+    regmmatch_T	rm;	/* points to the regexp program; contains last found
-+			   match (may continue in next line) */
-+    buf_T	*buf;	/* the buffer to search for a match */
-+    linenr_T	lnum;	/* the line to search for a match */
-+    int		attr;	/* attributes to be used for a match */
-+    int		attr_cur; /* attributes currently active in win_line() */
-+    linenr_T	first_lnum;	/* first lnum to search for multi-line pat */
-+    colnr_T	startcol; /* in win_line() points to char where HL starts */
-+    colnr_T	endcol;	 /* in win_line() points to char where HL ends */
-+#ifdef FEAT_RELTIME
-+    proftime_T	tm;	/* for a time limit */
-+#endif
-+} match_T;
-+
-+/*
-+ * matchitem_T provides a linked list for storing match items for ":match" and
-+ * the match functions.
-+ */
-+typedef struct matchitem matchitem_T;
-+struct matchitem
-+{
-+    matchitem_T	*next;
-+    int		id;	    /* match ID */
-+    int		priority;   /* match priority */
-+    char_u	*pattern;   /* pattern to highlight */
-+    int		hlg_id;	    /* highlight group ID */
-+    regmmatch_T	match;	    /* regexp program for pattern */
-+    match_T	hl;	    /* struct for doing the actual highlighting */
-+};
-+
-+/*
-  * Structure which contains all information that belongs to a window
-  *
-  * All row numbers are relative to the start of the window, except w_winrow.
-@@ -1934,9 +1979,8 @@
- #endif
- 
- #ifdef FEAT_SEARCH_EXTRA
--    regmmatch_T	w_match[3];	    /* regexp programs for ":match" */
--    char_u	*(w_match_pat[3]);  /* patterns for ":match" */
--    int		w_match_id[3];	    /* highlight IDs for ":match" */
-+    matchitem_T	*w_match_head;		/* head of match list */
-+    int		w_next_match_id;	/* next match ID */
- #endif
- 
-     /*
-diff -Naur vim71.orig/src/syntax.c vim71/src/syntax.c
---- vim71.orig/src/syntax.c	2007-05-07 15:42:55.000000000 -0400
-+++ vim71/src/syntax.c	2008-06-18 06:55:25.000000000 -0400
-@@ -66,8 +66,10 @@
- #define HL_TABLE() ((struct hl_group *)((highlight_ga.ga_data)))
- 
- #ifdef FEAT_CMDL_COMPL
--static int include_default = FALSE;	/* include "default" for expansion */
--static int include_link = FALSE;	/* include "link" for expansion */
-+/* Flags to indicate an additional string for highlight name completion. */
-+static int include_none = 0;	/* when 1 include "None" */
-+static int include_default = 0;	/* when 1 include "default" */
-+static int include_link = 0;	/* when 2 include "link" and "clear" */
- #endif
- 
- /*
-@@ -277,7 +279,8 @@
-  */
- typedef struct state_item
- {
--    int		si_idx;			/* index of syntax pattern */
-+    int		si_idx;			/* index of syntax pattern or
-+					   KEYWORD_IDX */
-     int		si_id;			/* highlight group ID for keywords */
-     int		si_trans_id;		/* idem, transparancy removed */
-     int		si_m_lnum;		/* lnum of the match */
-@@ -369,13 +372,13 @@
- static int syn_stack_cleanup __ARGS((void));
- static void syn_stack_free_entry __ARGS((buf_T *buf, synstate_T *p));
- static synstate_T *syn_stack_find_entry __ARGS((linenr_T lnum));
--static synstate_T *store_current_state __ARGS((synstate_T *sp));
-+static synstate_T *store_current_state __ARGS((void));
- static void load_current_state __ARGS((synstate_T *from));
- static void invalidate_current_state __ARGS((void));
- static int syn_stack_equal __ARGS((synstate_T *sp));
- static void validate_current_state __ARGS((void));
- static int syn_finish_line __ARGS((int syncing));
--static int syn_current_attr __ARGS((int syncing, int displaying, int *can_spell));
-+static int syn_current_attr __ARGS((int syncing, int displaying, int *can_spell, int keep_state));
- static int did_match_already __ARGS((int idx, garray_T *gap));
- static stateitem_T *push_next_match __ARGS((stateitem_T *cur_si));
- static void check_state_ends __ARGS((void));
-@@ -461,7 +464,7 @@
-     synstate_T	*p;
-     synstate_T	*last_valid = NULL;
-     synstate_T	*last_min_valid = NULL;
--    synstate_T	*sp, *prev;
-+    synstate_T	*sp, *prev = NULL;
-     linenr_T	parsed_lnum;
-     linenr_T	first_stored;
-     int		dist;
-@@ -499,7 +502,7 @@
- 	if (!current_state_stored)
- 	{
- 	    ++current_lnum;
--	    (void)store_current_state(NULL);
-+	    (void)store_current_state();
- 	}
- 
- 	/*
-@@ -555,7 +558,6 @@
- 	dist = 999999;
-     else
- 	dist = syn_buf->b_ml.ml_line_count / (syn_buf->b_sst_len - Rows) + 1;
--    prev = syn_stack_find_entry(current_lnum);
-     while (current_lnum < lnum)
-     {
- 	syn_start_line();
-@@ -570,9 +572,13 @@
- 	     * equal to the current state.  If so, then validate all saved
- 	     * states that depended on a change before the parsed line. */
- 	    if (prev == NULL)
-+		prev = syn_stack_find_entry(current_lnum - 1);
-+	    if (prev == NULL)
- 		sp = syn_buf->b_sst_first;
- 	    else
--		sp = prev->sst_next;
-+		sp = prev;
-+	    while (sp != NULL && sp->sst_lnum < current_lnum)
-+		sp = sp->sst_next;
- 	    if (sp != NULL
- 		    && sp->sst_lnum == current_lnum
- 		    && syn_stack_equal(sp))
-@@ -598,7 +604,7 @@
- 	    else if (prev == NULL
- 			|| current_lnum == lnum
- 			|| current_lnum >= prev->sst_lnum + dist)
--		prev = store_current_state(prev);
-+		prev = store_current_state();
- 	}
- 
- 	/* This can take a long time: break when CTRL-C pressed.  The current
-@@ -835,9 +841,18 @@
- 			    current_lnum = end_lnum;
- 			    break;
- 			}
--			spp = &(SYN_ITEMS(syn_buf)[cur_si->si_idx]);
--			found_flags = spp->sp_flags;
--			found_match_idx = spp->sp_sync_idx;
-+			if (cur_si->si_idx < 0)
-+			{
-+			    /* Cannot happen? */
-+			    found_flags = 0;
-+			    found_match_idx = KEYWORD_IDX;
-+			}
-+			else
-+			{
-+			    spp = &(SYN_ITEMS(syn_buf)[cur_si->si_idx]);
-+			    found_flags = spp->sp_flags;
-+			    found_match_idx = spp->sp_sync_idx;
-+			}
- 			found_current_lnum = current_lnum;
- 			found_current_col = current_col;
- 			found_m_endpos = cur_si->si_m_endpos;
-@@ -1341,17 +1356,13 @@
-  * The current state must be valid for the start of the current_lnum line!
-  */
-     static synstate_T *
--store_current_state(sp)
--    synstate_T	*sp;	/* at or before where state is to be saved or
--				   NULL */
-+store_current_state()
- {
-     int		i;
-     synstate_T	*p;
-     bufstate_T	*bp;
-     stateitem_T	*cur_si;
--
--    if (sp == NULL)
--	sp = syn_stack_find_entry(current_lnum);
-+    synstate_T	*sp = syn_stack_find_entry(current_lnum);
- 
-     /*
-      * If the current state contains a start or end pattern that continues
-@@ -1655,7 +1666,7 @@
- 	     * Store the current state in b_sst_array[] for later use.
- 	     */
- 	    ++current_lnum;
--	    (void)store_current_state(NULL);
-+	    (void)store_current_state();
- 	}
-     }
- 
-@@ -1679,7 +1690,7 @@
-     {
- 	while (!current_finished)
- 	{
--	    (void)syn_current_attr(syncing, FALSE, NULL);
-+	    (void)syn_current_attr(syncing, FALSE, NULL, FALSE);
- 	    /*
- 	     * When syncing, and found some item, need to check the item.
- 	     */
-@@ -1719,12 +1730,20 @@
-  * done.
-  */
-     int
--get_syntax_attr(col, can_spell)
-+get_syntax_attr(col, can_spell, keep_state)
-     colnr_T	col;
-     int		*can_spell;
-+    int		keep_state;	/* keep state of char at "col" */
- {
-     int	    attr = 0;
- 
-+    if (can_spell != NULL)
-+	/* Default: Only do spelling when there is no @Spell cluster or when
-+	 * ":syn spell toplevel" was used. */
-+	*can_spell = syn_buf->b_syn_spell == SYNSPL_DEFAULT
-+		    ? (syn_buf->b_spell_cluster_id == 0)
-+		    : (syn_buf->b_syn_spell == SYNSPL_TOP);
-+
-     /* check for out of memory situation */
-     if (syn_buf->b_sst_array == NULL)
- 	return 0;
-@@ -1749,7 +1768,8 @@
-      */
-     while (current_col <= col)
-     {
--	attr = syn_current_attr(FALSE, TRUE, can_spell);
-+	attr = syn_current_attr(FALSE, TRUE, can_spell,
-+				     current_col == col ? keep_state : FALSE);
- 	++current_col;
-     }
- 
-@@ -1760,10 +1780,11 @@
-  * Get syntax attributes for current_lnum, current_col.
-  */
-     static int
--syn_current_attr(syncing, displaying, can_spell)
-+syn_current_attr(syncing, displaying, can_spell, keep_state)
-     int		syncing;		/* When 1: called for syncing */
-     int		displaying;		/* result will be displayed */
-     int		*can_spell;		/* return: do spell checking */
-+    int		keep_state;		/* keep syntax stack afterwards */
- {
-     int		syn_id;
-     lpos_T	endpos;		/* was: char_u *endp; */
-@@ -2279,7 +2300,7 @@
- 	 * may be for an empty match and a containing item might end in the
- 	 * current column.
- 	 */
--	if (!syncing)
-+	if (!syncing && !keep_state)
- 	{
- 	    check_state_ends();
- 	    if (current_state.ga_len > 0
-@@ -2476,7 +2497,7 @@
- 		if (current_state.ga_len == 0)
- 		    break;
- 
--		if (had_extend)
-+		if (had_extend && keepend_level >= 0)
- 		{
- 		    syn_update_ends(FALSE);
- 		    if (current_state.ga_len == 0)
-@@ -2524,6 +2545,10 @@
-     stateitem_T	*sip = &CUR_STATE(idx);
-     synpat_T	*spp;
- 
-+    /* This should not happen... */
-+    if (sip->si_idx < 0)
-+	return;
-+
-     spp = &(SYN_ITEMS(syn_buf)[sip->si_idx]);
-     if (sip->si_flags & HL_MATCH)
- 	sip->si_id = spp->sp_syn_match_id;
-@@ -2639,6 +2664,10 @@
-     lpos_T	end_endpos;
-     int		end_idx;
- 
-+    /* return quickly for a keyword */
-+    if (sip->si_idx < 0)
-+	return;
-+
-     /* Don't update when it's already done.  Can be a match of an end pattern
-      * that started in a previous line.  Watch out: can also be a "keepend"
-      * from a containing item. */
-@@ -2751,6 +2780,10 @@
-     char_u	*line;
-     int		had_match = FALSE;
- 
-+    /* just in case we are invoked for a keyword */
-+    if (idx < 0)
-+	return;
-+
-     /*
-      * Check for being called with a START pattern.
-      * Can happen with a match that continues to the next line, because it
-@@ -3064,7 +3097,7 @@
-     colnr_T	col;
- {
-     rmp->rmm_maxcol = syn_buf->b_p_smc;
--    if (vim_regexec_multi(rmp, syn_win, syn_buf, lnum, col) > 0)
-+    if (vim_regexec_multi(rmp, syn_win, syn_buf, lnum, col, NULL) > 0)
-     {
- 	rmp->startpos[0].lnum += lnum;
- 	rmp->endpos[0].lnum += lnum;
-@@ -3323,6 +3356,7 @@
-     {
- 	vim_free(SYN_ITEMS(buf)[i].sp_cont_list);
- 	vim_free(SYN_ITEMS(buf)[i].sp_next_list);
-+	vim_free(SYN_ITEMS(buf)[i].sp_syn.cont_in_list);
-     }
- }
- 
-@@ -4460,8 +4494,8 @@
-     current_syn_inc_tag = ++running_syn_inc_tag;
-     prev_toplvl_grp = curbuf->b_syn_topgrp;
-     curbuf->b_syn_topgrp = sgl_id;
--    if (source ? do_source(eap->arg, FALSE, FALSE) == FAIL
--				: source_runtime(eap->arg, DOSO_NONE) == FAIL)
-+    if (source ? do_source(eap->arg, FALSE, DOSO_NONE) == FAIL
-+				: source_runtime(eap->arg, TRUE) == FAIL)
- 	EMSG2(_(e_notopen), eap->arg);
-     curbuf->b_syn_topgrp = prev_toplvl_grp;
-     current_syn_inc_tag = prev_syn_inc_tag;
-@@ -5956,8 +5990,8 @@
- {
-     return (buf->b_syn_patterns.ga_len != 0
- 	    || buf->b_syn_clusters.ga_len != 0
--	    || curbuf->b_keywtab.ht_used > 0
--	    || curbuf->b_keywtab_ic.ht_used > 0);
-+	    || buf->b_keywtab.ht_used > 0
-+	    || buf->b_keywtab_ic.ht_used > 0);
- }
- 
- #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
-@@ -5968,6 +6002,29 @@
-     EXP_CASE	    /* expand ":syn case" arguments */
- } expand_what;
- 
-+/*
-+ * Reset include_link, include_default, include_none to 0.
-+ * Called when we are done expanding.
-+ */
-+    void
-+reset_expand_highlight()
-+{
-+    include_link = include_default = include_none = 0;
-+}
-+
-+/*
-+ * Handle command line completion for :match and :echohl command: Add "None"
-+ * as highlight group.
-+ */
-+    void
-+set_context_in_echohl_cmd(xp, arg)
-+    expand_T	*xp;
-+    char_u	*arg;
-+{
-+    xp->xp_context = EXPAND_HIGHLIGHT;
-+    xp->xp_pattern = arg;
-+    include_none = 1;
-+}
- 
- /*
-  * Handle command line completion for :syntax command.
-@@ -5983,8 +6040,8 @@
-     xp->xp_context = EXPAND_SYNTAX;
-     expand_what = EXP_SUBCMD;
-     xp->xp_pattern = arg;
--    include_link = FALSE;
--    include_default = FALSE;
-+    include_link = 0;
-+    include_default = 0;
- 
-     /* (part of) subcommand already typed */
-     if (*arg != NUL)
-@@ -6031,12 +6088,13 @@
-  * Function called for expression evaluation: get syntax ID at file position.
-  */
-     int
--syn_get_id(wp, lnum, col, trans, spellp)
-+syn_get_id(wp, lnum, col, trans, spellp, keep_state)
-     win_T	*wp;
-     long	lnum;
-     colnr_T	col;
--    int		trans;	    /* remove transparancy */
--    int		*spellp;    /* return: can do spell checking */
-+    int		trans;	     /* remove transparancy */
-+    int		*spellp;     /* return: can do spell checking */
-+    int		keep_state;  /* keep state of char at "col" */
- {
-     /* When the position is not after the current position and in the same
-      * line of the same buffer, need to restart parsing. */
-@@ -6045,11 +6103,33 @@
- 	    || col < current_col)
- 	syntax_start(wp, lnum);
- 
--    (void)get_syntax_attr(col, spellp);
-+    (void)get_syntax_attr(col, spellp, keep_state);
- 
-     return (trans ? current_trans_id : current_id);
- }
- 
-+#if defined(FEAT_EVAL) || defined(PROTO)
-+/*
-+ * Return the syntax ID at position "i" in the current stack.
-+ * The caller must have called syn_get_id() before to fill the stack.
-+ * Returns -1 when "i" is out of range.
-+ */
-+    int
-+syn_get_stack_item(i)
-+    int i;
-+{
-+    if (i >= current_state.ga_len)
-+    {
-+	/* Need to invalidate the state, because we didn't properly finish it
-+	 * for the last character, "keep_state" was TRUE. */
-+	invalidate_current_state();
-+	current_col = MAXCOL;
-+	return -1;
-+    }
-+    return CUR_STATE(i).si_id;
-+}
-+#endif
-+
- #if defined(FEAT_FOLDING) || defined(PROTO)
- /*
-  * Function called to get folding level for line "lnum" in window "wp".
-@@ -8479,7 +8559,7 @@
- syn_id2name(id)
-     int		id;
- {
--    if (id <= 0 || id >= highlight_ga.ga_len)
-+    if (id <= 0 || id > highlight_ga.ga_len)
- 	return (char_u *)"";
-     return HL_TABLE()[id - 1].sg_name;
- }
-@@ -8949,7 +9029,7 @@
-     return OK;
- }
- 
--#ifdef FEAT_CMDL_COMPL
-+#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
- 
- static void highlight_list __ARGS((void));
- static void highlight_list_two __ARGS((int cnt, int attr));
-@@ -8967,8 +9047,8 @@
-     /* Default: expand group names */
-     xp->xp_context = EXPAND_HIGHLIGHT;
-     xp->xp_pattern = arg;
--    include_link = TRUE;
--    include_default = TRUE;
-+    include_link = 2;
-+    include_default = 1;
- 
-     /* (part of) subcommand already typed */
-     if (*arg != NUL)
-@@ -8976,7 +9056,7 @@
- 	p = skiptowhite(arg);
- 	if (*p != NUL)			/* past "default" or group name */
- 	{
--	    include_default = FALSE;
-+	    include_default = 0;
- 	    if (STRNCMP("default", arg, p - arg) == 0)
- 	    {
- 		arg = skipwhite(p);
-@@ -8985,7 +9065,7 @@
- 	    }
- 	    if (*p != NUL)			/* past group name */
- 	    {
--		include_link = FALSE;
-+		include_link = 0;
- 		if (arg[1] == 'i' && arg[0] == 'N')
- 		    highlight_list();
- 		if (STRNCMP("link", arg, p - arg) == 0
-@@ -9045,31 +9125,25 @@
-     expand_T	*xp;
-     int		idx;
- {
--    if (idx == highlight_ga.ga_len
- #ifdef FEAT_CMDL_COMPL
--	    && include_link
--#endif
--	    )
-+    if (idx == highlight_ga.ga_len && include_none != 0)
-+	return (char_u *)"none";
-+    if (idx == highlight_ga.ga_len + include_none && include_default != 0)
-+	return (char_u *)"default";
-+    if (idx == highlight_ga.ga_len + include_none + include_default
-+							 && include_link != 0)
- 	return (char_u *)"link";
--    if (idx == highlight_ga.ga_len + 1
--#ifdef FEAT_CMDL_COMPL
--	    && include_link
--#endif
--	    )
-+    if (idx == highlight_ga.ga_len + include_none + include_default + 1
-+							 && include_link != 0)
- 	return (char_u *)"clear";
--    if (idx == highlight_ga.ga_len + 2
--#ifdef FEAT_CMDL_COMPL
--	    && include_default
- #endif
--	    )
--	return (char_u *)"default";
-     if (idx < 0 || idx >= highlight_ga.ga_len)
- 	return NULL;
-     return HL_TABLE()[idx].sg_name;
- }
- #endif
- 
--#ifdef FEAT_GUI
-+#if defined(FEAT_GUI) || defined(PROTO)
- /*
-  * Free all the highlight group fonts.
-  * Used when quitting for systems which need it.
-diff -Naur vim71.orig/src/tag.c vim71/src/tag.c
---- vim71.orig/src/tag.c	2007-05-07 15:36:40.000000000 -0400
-+++ vim71/src/tag.c	2008-06-18 06:55:50.000000000 -0400
-@@ -2669,8 +2669,8 @@
- 
- 	    tnp->tn_search_ctx = vim_findfile_init(buf, filename,
- 		    r_ptr, 100,
--		    FALSE, /* don't free visited list */
--		    FALSE, /* we search for a file */
-+		    FALSE,         /* don't free visited list */
-+		    FINDFILE_FILE, /* we search for a file */
- 		    tnp->tn_search_ctx, TRUE, curbuf->b_ffname);
- 	    if (tnp->tn_search_ctx != NULL)
- 		tnp->tn_did_filefind_init = TRUE;
-@@ -2691,6 +2691,7 @@
- {
-     vim_free(tnp->tn_tags);
-     vim_findfile_cleanup(tnp->tn_search_ctx);
-+    tnp->tn_search_ctx = NULL;
-     ga_clear_strings(&tag_fnames);
- }
- 
-@@ -3191,7 +3192,8 @@
- #endif
- 	    save_lnum = curwin->w_cursor.lnum;
- 	    curwin->w_cursor.lnum = 0;	/* start search before first line */
--	    if (do_search(NULL, pbuf[0], pbuf + 1, (long)1, search_options))
-+	    if (do_search(NULL, pbuf[0], pbuf + 1, (long)1,
-+							search_options, NULL))
- 		retval = OK;
- 	    else
- 	    {
-@@ -3203,7 +3205,7 @@
- 		 */
- 		p_ic = TRUE;
- 		if (!do_search(NULL, pbuf[0], pbuf + 1, (long)1,
--							      search_options))
-+							search_options, NULL))
- 		{
- 		    /*
- 		     * Failed to find pattern, take a guess: "^func  ("
-@@ -3213,13 +3215,14 @@
- 		    cc = *tagp.tagname_end;
- 		    *tagp.tagname_end = NUL;
- 		    sprintf((char *)pbuf, "^%s\\s\\*(", tagp.tagname);
--		    if (!do_search(NULL, '/', pbuf, (long)1, search_options))
-+		    if (!do_search(NULL, '/', pbuf, (long)1,
-+							search_options, NULL))
- 		    {
- 			/* Guess again: "^char * \<func  (" */
- 			sprintf((char *)pbuf, "^\\[#a-zA-Z_]\\.\\*\\<%s\\s\\*(",
- 								tagp.tagname);
- 			if (!do_search(NULL, '/', pbuf, (long)1,
--							      search_options))
-+							search_options, NULL))
- 			    found = 0;
- 		    }
- 		    *tagp.tagname_end = cc;
-diff -Naur vim71.orig/src/term.c vim71/src/term.c
---- vim71.orig/src/term.c	2007-05-07 15:39:11.000000000 -0400
-+++ vim71/src/term.c	2008-06-18 06:56:02.000000000 -0400
-@@ -4050,15 +4050,17 @@
- 	{
- 	    /* Check for xterm version string: "<Esc>[>{x};{vers};{y}c".  Also
- 	     * eat other possible responses to t_RV, rxvt returns
--	     * "<Esc>[?1;2c".  Also accept CSI instead of <Esc>[. */
-+	     * "<Esc>[?1;2c".  Also accept CSI instead of <Esc>[.
-+	     * mrxvt has been reported to have "+" in the version. Assume
-+	     * the escape sequence ends with a letter or one of "{|}~". */
- 	    if (*T_CRV != NUL && ((tp[0] == ESC && tp[1] == '[' && len >= 3)
- 					       || (tp[0] == CSI && len >= 2)))
- 	    {
- 		j = 0;
- 		extra = 0;
--		for (i = 2 + (tp[0] != CSI);
--			i < len && (VIM_ISDIGIT(tp[i])
--			    || tp[i] == ';' || tp[i] == '.'); ++i)
-+		for (i = 2 + (tp[0] != CSI); i < len
-+				&& !(tp[i] >= '{' && tp[i] <= '~')
-+				&& !ASCII_ISALPHA(tp[i]); ++i)
- 		    if (tp[i] == ';' && ++j == 1)
- 			extra = atoi((char *)tp + i + 1);
- 		if (i == len)
-@@ -4809,6 +4811,8 @@
- 	    if (num_bytes == -1)
- 		return -1;
- 	    current_tab = (int)bytes[0];
-+	    if (current_tab == 255)	/* -1 in a byte gives 255 */
-+		current_tab = -1;
- 	    slen += num_bytes;
- 	}
- 	else if (key_name[0] == (int)KS_TABMENU)
-diff -Naur vim71.orig/src/termlib.c vim71/src/termlib.c
---- vim71.orig/src/termlib.c	2007-05-07 15:39:49.000000000 -0400
-+++ vim71/src/termlib.c	2008-06-18 06:51:42.000000000 -0400
-@@ -191,7 +191,7 @@
- 	    lbuf[0] == '\t' &&
- 	    lbuf[1] == ':')
- 	{
--	    strcpy(lbuf, lbuf+2);
-+	    mch_memmove(lbuf, lbuf + 2, strlen(lbuf + 2) + 1);
- 	    llen -= 2;
- 	}
- 	if (lbuf[llen-2] == '\\')		/* and continuations */
-diff -Naur vim71.orig/src/testdir/Makefile vim71/src/testdir/Makefile
---- vim71.orig/src/testdir/Makefile	2006-04-30 07:08:01.000000000 -0400
-+++ vim71/src/testdir/Makefile	2008-06-18 06:53:02.000000000 -0400
-@@ -1,9 +1,13 @@
- #
--# Makefile to run al tests for Vim
-+# Makefile to run all tests for Vim
- #
- 
- VIMPROG = ../vim
- 
-+# Uncomment this line for using valgrind.
-+# The output goes into a file "valgrind.$PID" (sorry, no test number).
-+# VALGRIND = valgrind --tool=memcheck --leak-check=yes --num-callers=15 --logfile=valgrind
-+
- SCRIPTS = test1.out test2.out test3.out test4.out test5.out test6.out \
- 		test7.out test8.out test9.out test10.out test11.out \
- 		test12.out  test13.out test14.out test15.out test17.out \
-@@ -15,7 +19,8 @@
- 		test43.out test44.out test45.out test46.out test47.out \
- 		test48.out test49.out test51.out test52.out test53.out \
- 		test54.out test55.out test56.out test57.out test58.out \
--		test59.out test60.out test61.out test62.out
-+		test59.out test60.out test61.out test62.out test63.out \
-+		test64.out
- 
- SCRIPTS_GUI = test16.out
- 
-@@ -34,11 +39,11 @@
- $(SCRIPTS) $(SCRIPTS_GUI): $(VIMPROG)
- 
- clean:
--	-rm -rf *.out *.failed *.rej *.orig test.log tiny.vim small.vim mbyte.vim test.ok X* viminfo
-+	-rm -rf *.out *.failed *.rej *.orig test.log tiny.vim small.vim mbyte.vim test.ok X* valgrind.pid* viminfo
- 
- test1.out: test1.in
- 	-rm -f $*.failed tiny.vim small.vim mbyte.vim test.ok X* viminfo
--	$(VIMPROG) -u unix.vim -U NONE --noplugin -s dotest.in $*.in
-+	$(VALGRIND) $(VIMPROG) -u unix.vim -U NONE --noplugin -s dotest.in $*.in
- 	@/bin/sh -c "if diff test.out $*.ok; \
- 		then mv -f test.out $*.out; \
- 		else echo; \
-@@ -51,7 +56,7 @@
- 	cp $*.ok test.ok
- 	# Sleep a moment to avoid that the xterm title is messed up
- 	@-sleep .2
--	-$(VIMPROG) -u unix.vim -U NONE --noplugin -s dotest.in $*.in
-+	-$(VALGRIND) $(VIMPROG) -u unix.vim -U NONE --noplugin -s dotest.in $*.in
- 	@/bin/sh -c "if test -f test.out; then\
- 		  if diff test.out $*.ok; \
- 		  then mv -f test.out $*.out; \
-@@ -61,5 +66,9 @@
- 		fi"
- 	-rm -rf X* test.ok viminfo
- 
-+test49.out: test49.vim
-+
-+test60.out: test60.vim
-+
- nolog:
- 	-echo Test results: >test.log
-diff -Naur vim71.orig/src/testdir/test14.in vim71/src/testdir/test14.in
---- vim71.orig/src/testdir/test14.in	2004-06-07 10:32:05.000000000 -0400
-+++ vim71/src/testdir/test14.in	2008-06-18 06:53:02.000000000 -0400
-@@ -18,6 +18,7 @@
- : let tt = "o\<C-V>65\<C-V>x42\<C-V>o103 \<C-V>33a\<C-V>xfg\<C-V>o78\<Esc>"
- :endif
- :exe "normal " . tt
-+:unlet tt
- :.w >>test.out
- :set vb
- /^Piece
-diff -Naur vim71.orig/src/testdir/test26.in vim71/src/testdir/test26.in
---- vim71.orig/src/testdir/test26.in	2004-06-07 10:32:05.000000000 -0400
-+++ vim71/src/testdir/test26.in	2008-06-18 06:53:02.000000000 -0400
-@@ -37,6 +37,7 @@
- :    endif
- :  endif
- :endwhile
-+:unlet i j
- :'t,$w! test.out
- :qa!
- ENDTEST
-diff -Naur vim71.orig/src/testdir/test34.in vim71/src/testdir/test34.in
---- vim71.orig/src/testdir/test34.in	2006-04-30 09:33:24.000000000 -0400
-+++ vim71/src/testdir/test34.in	2008-06-18 06:53:02.000000000 -0400
-@@ -52,7 +52,15 @@
- ---*---
- (one
- (two
--[(one again:$-5,$wq! test.out
-+[(one again:$-5,$w! test.out
-+:delfunc Table
-+:delfunc Compute
-+:delfunc Expr1
-+:delfunc Expr2
-+:delfunc ListItem
-+:delfunc ListReset
-+:unlet retval counter
-+:q!
- ENDTEST
- 
- here
-diff -Naur vim71.orig/src/testdir/test39.in vim71/src/testdir/test39.in
---- vim71.orig/src/testdir/test39.in	2004-06-07 10:32:05.000000000 -0400
-+++ vim71/src/testdir/test39.in	2008-06-18 06:55:45.000000000 -0400
-@@ -1,8 +1,12 @@
- 
- Test Visual block mode commands
-+And test "U" in Visual mode, also on German sharp S.
- 
- STARTTEST
- :so small.vim
-+:so mbyte.vim
-+:" This only works when 'encoding' is "latin1", don't depend on the environment
-+:set enc=latin1
- /^abcde
- :" Test shift-right of a block
- jlllljj>wlljlll>
-@@ -14,7 +18,22 @@
- Gllllkkklllrq
- :" Test block-change
- G$khhhhhkkcmno
--:$-4,$wq! test.out
-+:$-4,$w! test.out
-+:" gUe must uppercase a whole word, also when ß changes to SS
-+Gothe youtußeuu endYpk0wgUe
-+:" gUfx must uppercase until x, inclusive.
-+O- youßtußexu -0fogUfx
-+:" VU must uppercase a whole line
-+YpkVU
-+:" same, when it's the last line in the buffer
-+YPGi111VUddP
-+:" Uppercase two lines
-+Oblah di
-+doh dutVkUj
-+:" Uppercase part of two lines
-+ddppi333k0i222fyllvjfuUk
-+:/^the/,$w >> test.out
-+:qa!
- ENDTEST
- 
- abcdefghijklm
-diff -Naur vim71.orig/src/testdir/test39.ok vim71/src/testdir/test39.ok
---- vim71.orig/src/testdir/test39.ok	2004-06-07 10:32:05.000000000 -0400
-+++ vim71/src/testdir/test39.ok	2008-06-18 06:55:34.000000000 -0400
-@@ -3,3 +3,11 @@
- axyzqqqqef mno        ghijklm
- axyzqqqqefgmnoklm
- abcdqqqqijklm
-+the YOUTUSSEUU end
-+- yOUSSTUSSEXu -
-+THE YOUTUSSEUU END
-+111THE YOUTUSSEUU END
-+BLAH DI
-+DOH DUT
-+222the yoUTUSSEUU END
-+333THE YOUTUßeuu end
-diff -Naur vim71.orig/src/testdir/test42.ok vim71/src/testdir/test42.ok
---- vim71.orig/src/testdir/test42.ok	2004-06-07 10:32:05.000000000 -0400
-+++ vim71/src/testdir/test42.ok	2008-06-18 06:55:56.000000000 -0400
-@@ -15,7 +15,7 @@
- ï»¿utf-8err
- 
- 
--  fileencoding=ucs-2
-+  fileencoding=utf-16
-   bomb
- ucs-2
- 
-diff -Naur vim71.orig/src/testdir/test45.in vim71/src/testdir/test45.in
---- vim71.orig/src/testdir/test45.in	2004-06-07 10:32:05.000000000 -0400
-+++ vim71/src/testdir/test45.in	2008-06-18 06:53:02.000000000 -0400
-@@ -55,6 +55,7 @@
- /kk$
- :call append("$", foldlevel("."))
- :/^last/+1,$w! test.out
-+:delfun Flvl
- :qa!
- ENDTEST
- 
-diff -Naur vim71.orig/src/testdir/test47.in vim71/src/testdir/test47.in
---- vim71.orig/src/testdir/test47.in	2004-06-07 10:32:05.000000000 -0400
-+++ vim71/src/testdir/test47.in	2008-06-18 06:53:02.000000000 -0400
-@@ -34,6 +34,7 @@
- :call append("$", two)
- :call append("$", three)
- :$-2,$w! test.out
-+:unlet one two three
- :qa!
- ENDTEST
- 
-diff -Naur vim71.orig/src/testdir/test49.in vim71/src/testdir/test49.in
---- vim71.orig/src/testdir/test49.in	2006-04-28 05:29:54.000000000 -0400
-+++ vim71/src/testdir/test49.in	2008-06-18 06:55:47.000000000 -0400
-@@ -1,13 +1,30 @@
- This is a test of the script language.
- 
- If after adding a new test, the test output doesn't appear properly in
--test49.failed, try to add one ore more "G"s at the line before ENDTEST.
-+test49.failed, try to add one ore more "G"s at the line ending in "test.out"
- 
- STARTTEST
- :so small.vim
- :se nocp nomore viminfo+=nviminfo
-+:lang mess C
- :so test49.vim
--GGGGGGGGGG"rp:.-,$wq! test.out
-+GGGGGGGGGGGGGG"rp:.-,$w! test.out
-+:"
-+:" make valgrind happy
-+:redir => funclist
-+:silent func
-+:redir END
-+:for line in split(funclist, "\n")
-+:  let name = matchstr(line, 'function \zs[A-Z]\w*\ze(')
-+:  if name != ''
-+:    exe "delfunc " . name
-+:  endif
-+:endfor
-+:for v in keys(g:)
-+:  silent! exe "unlet " . v
-+:endfor
-+:unlet v
-+:qa!
- ENDTEST
- 
- Results of test49.vim:
-diff -Naur vim71.orig/src/testdir/test55.in vim71/src/testdir/test55.in
---- vim71.orig/src/testdir/test55.in	2006-10-15 10:07:05.000000000 -0400
-+++ vim71/src/testdir/test55.in	2008-06-18 06:55:47.000000000 -0400
-@@ -146,7 +146,7 @@
- :try
- :  let n = d[1500]
- :catch
--:  $put =v:exception[:14] . v:exception[-4:-1]
-+:  $put =substitute(v:exception, '\v(.{14}).*( \d{4}).*', '\1\2', '')
- :endtry
- :" lookup each items
- :for i in range(1500)
-@@ -345,6 +345,10 @@
- :endfun
- :call Test(1, 2, [3, 4], {5: 6})  " This may take a while
- :"
-+:delfunc Test
-+:unlet dict
-+:call garbagecollect(1)
-+:"
- :/^start:/,$wq! test.out
- ENDTEST
- 
-diff -Naur vim71.orig/src/testdir/test56.in vim71/src/testdir/test56.in
---- vim71.orig/src/testdir/test56.in	2006-09-03 10:28:41.000000000 -0400
-+++ vim71/src/testdir/test56.in	2008-06-18 06:53:02.000000000 -0400
-@@ -17,5 +17,5 @@
- fun s:DoNothing()
-   call append(line('$'), "nothing line")
- endfun
--nnoremap <buffer> _x	:call <SID>DoNothing()<bar>call <SID>DoLast()<cr>
-+nnoremap <buffer> _x	:call <SID>DoNothing()<bar>call <SID>DoLast()<bar>delfunc <SID>DoNothing<bar>delfunc <SID>DoLast<cr>
- end:
-diff -Naur vim71.orig/src/testdir/test58.in vim71/src/testdir/test58.in
---- vim71.orig/src/testdir/test58.in	2006-04-03 14:24:04.000000000 -0400
-+++ vim71/src/testdir/test58.in	2008-06-18 06:53:02.000000000 -0400
-@@ -86,6 +86,7 @@
- :$put =str
- `m]s:let [str, a] = spellbadword()
- :$put =str
-+:unlet str a
- :"
- :" Postponed prefixes
- :call TestOne('2', '1')
-@@ -100,6 +101,10 @@
- :" NOSLITSUGS
- :call TestOne('8', '8')
- :"
-+:" clean up for valgrind
-+:delfunc TestOne
-+:set spl= enc=latin1
-+:"
- gg:/^test output:/,$wq! test.out
- ENDTEST
- 
-diff -Naur vim71.orig/src/testdir/test59.in vim71/src/testdir/test59.in
---- vim71.orig/src/testdir/test59.in	2006-04-03 14:29:24.000000000 -0400
-+++ vim71/src/testdir/test59.in	2008-06-18 06:53:02.000000000 -0400
-@@ -90,6 +90,7 @@
- :$put =str
- `m]s:let [str, a] = spellbadword()
- :$put =str
-+:unlet str a
- :"
- :" Postponed prefixes
- :call TestOne('2', '1')
-@@ -101,6 +102,10 @@
- :call TestOne('6', '6')
- :call TestOne('7', '7')
- :"
-+:" clean up for valgrind
-+:delfunc TestOne
-+:set spl= enc=latin1
-+:"
- gg:/^test output:/,$wq! test.out
- ENDTEST
- 
-diff -Naur vim71.orig/src/testdir/test60.in vim71/src/testdir/test60.in
---- vim71.orig/src/testdir/test60.in	2006-05-05 14:41:18.000000000 -0400
-+++ vim71/src/testdir/test60.in	2008-06-18 06:53:02.000000000 -0400
-@@ -569,6 +569,9 @@
-     redir END
- endfunction
- :call TestExists()
-+:delfunc TestExists
-+:delfunc RunTest
-+:delfunc TestFuncArg
- :edit! test.out
- :set ff=unix
- :w
-diff -Naur vim71.orig/src/testdir/test60.vim vim71/src/testdir/test60.vim
---- vim71.orig/src/testdir/test60.vim	2006-01-12 14:45:59.000000000 -0500
-+++ vim71/src/testdir/test60.vim	2008-06-18 06:53:02.000000000 -0400
-@@ -94,4 +94,5 @@
- else
-     echo "FAILED"
- endif
-+unlet str
- 
-diff -Naur vim71.orig/src/testdir/test62.in vim71/src/testdir/test62.in
---- vim71.orig/src/testdir/test62.in	2006-04-30 07:29:15.000000000 -0400
-+++ vim71/src/testdir/test62.in	2008-06-18 06:53:02.000000000 -0400
-@@ -7,6 +7,7 @@
- :let nr = tabpagenr()
- :q
- :call append(line('$'), 'tab page ' . nr)
-+:unlet nr
- :"
- :" Open three tab pages and use ":tabdo"
- :0tabnew
-@@ -23,6 +24,7 @@
- :q!
- :call append(line('$'), line1)
- :call append(line('$'), line2)
-+:unlet line1 line2
- :"
- :"
- :/^Results/,$w! test.out
-diff -Naur vim71.orig/src/testdir/test63.in vim71/src/testdir/test63.in
---- vim71.orig/src/testdir/test63.in	1969-12-31 19:00:00.000000000 -0500
-+++ vim71/src/testdir/test63.in	2008-06-18 06:53:02.000000000 -0400
-@@ -0,0 +1,157 @@
-+Test for ":match", ":2match", ":3match", "clearmatches()", "getmatches()",
-+"matchadd()", "matcharg()", "matchdelete()", and "setmatches()".
-+
-+STARTTEST
-+:so small.vim
-+:" --- Check that "matcharg()" returns the correct group and pattern if a match
-+:" --- is defined.
-+:let @r = "*** Test 1: "
-+:highlight MyGroup1 ctermbg=red
-+:highlight MyGroup2 ctermbg=green
-+:highlight MyGroup3 ctermbg=blue
-+:match MyGroup1 /TODO/
-+:2match MyGroup2 /FIXME/
-+:3match MyGroup3 /XXX/
-+:if matcharg(1) == ['MyGroup1', 'TODO'] && matcharg(2) == ['MyGroup2', 'FIXME'] && matcharg(3) == ['MyGroup3', 'XXX']
-+:  let @r .= "OK\n"
-+:else
-+:  let @r .= "FAILED\n"
-+:endif
-+:" --- Check that "matcharg()" returns an empty list if the argument is not 1,
-+:" --- 2 or 3 (only 0 and 4 are tested).
-+:let @r .= "*** Test 2: "
-+:if matcharg(0) == [] && matcharg(4) == []
-+:  let @r .= "OK\n"
-+:else
-+:  let @r .= "FAILED\n"
-+:endif
-+:" --- Check that "matcharg()" returns ['', ''] if a match is not defined.
-+:let @r .= "*** Test 3: "
-+:match
-+:2match
-+:3match
-+:if matcharg(1) == ['', ''] && matcharg(2) == ['', ''] && matcharg(3) == ['', '']
-+:  let @r .= "OK\n"
-+:else
-+:  let @r .= "FAILED\n"
-+:endif
-+:" --- Check that "matchadd()" and "getmatches()" agree on added matches and
-+:" --- that default values apply.
-+:let @r .= "*** Test 4: "
-+:let m1 = matchadd("MyGroup1", "TODO")
-+:let m2 = matchadd("MyGroup2", "FIXME", 42)
-+:let m3 = matchadd("MyGroup3", "XXX", 60, 17)
-+:if getmatches() == [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 4}, {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 42, 'id': 5}, {'group': 'MyGroup3', 'pattern': 'XXX', 'priority': 60, 'id': 17}]
-+:  let @r .= "OK\n"
-+:else
-+:  let @r .= "FAILED\n"
-+:endif
-+:" --- Check that "matchdelete()" deletes the matches defined in the previous
-+:" --- test correctly.
-+:let @r .= "*** Test 5: "
-+:call matchdelete(m1)
-+:call matchdelete(m2)
-+:call matchdelete(m3)
-+:unlet m1
-+:unlet m2
-+:unlet m3
-+:if getmatches() == []
-+:  let @r .= "OK\n"
-+:else
-+:  let @r .= "FAILED\n"
-+:endif
-+:" --- Check that "matchdelete()" returns 0 if successful and otherwise -1.
-+:let @r .= "*** Test 6: "
-+:let m = matchadd("MyGroup1", "TODO")
-+:let r1 = matchdelete(m)
-+:let r2 = matchdelete(42)
-+:if r1 == 0 && r2 == -1
-+:  let @r .= "OK\n"
-+:else
-+:  let @r .= "FAILED\n"
-+:endif
-+:unlet m
-+:unlet r1
-+:unlet r2
-+:" --- Check that "clearmatches()" clears all matches defined by ":match" and
-+:" --- "matchadd()".
-+:let @r .= "*** Test 7: "
-+:let m1 = matchadd("MyGroup1", "TODO")
-+:let m2 = matchadd("MyGroup2", "FIXME", 42)
-+:let m3 = matchadd("MyGroup3", "XXX", 60, 17)
-+:match MyGroup1 /COFFEE/
-+:2match MyGroup2 /HUMPPA/
-+:3match MyGroup3 /VIM/
-+:call clearmatches()
-+:if getmatches() == []
-+:  let @r .= "OK\n"
-+:else
-+:  let @r .= "FAILED\n"
-+:endif
-+:unlet m1
-+:unlet m2
-+:unlet m3
-+:" --- Check that "setmatches()" restores a list of matches saved by
-+:" --- "getmatches()" without changes. (Matches with equal priority must also
-+:" --- remain in the same order.)
-+:let @r .= "*** Test 8: "
-+:let m1 = matchadd("MyGroup1", "TODO")
-+:let m2 = matchadd("MyGroup2", "FIXME", 42)
-+:let m3 = matchadd("MyGroup3", "XXX", 60, 17)
-+:match MyGroup1 /COFFEE/
-+:2match MyGroup2 /HUMPPA/
-+:3match MyGroup3 /VIM/
-+:let ml = getmatches()
-+:call clearmatches()
-+:call setmatches(ml)
-+:if getmatches() == ml
-+:  let @r .= "OK\n"
-+:else
-+:  let @r .= "FAILED\n"
-+:endif
-+:call clearmatches()
-+:unlet m1
-+:unlet m2
-+:unlet m3
-+:unlet ml
-+:" --- Check that "setmatches()" will not add two matches with the same ID. The
-+:" --- expected behaviour (for now) is to add the first match but not the
-+:" --- second and to return 0 (even though it is a matter of debate whether
-+:" --- this can be considered successful behaviour).
-+:let @r .= "*** Test 9: "
-+:let r1 = setmatches([{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}, {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 10, 'id': 1}])
-+:if getmatches() == [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}] && r1 == 0
-+:  let @r .= "OK\n"
-+:else
-+:  let @r .= "FAILED\n"
-+:endif
-+:call clearmatches()
-+:unlet r1
-+:" --- Check that "setmatches()" returns 0 if successful and otherwise -1.
-+:" --- (A range of valid and invalid input values are tried out to generate the
-+:" --- return values.)
-+:let @r .= "*** Test 10: "
-+:let rs1 = setmatches([])
-+:let rs2 = setmatches([{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}])
-+:call clearmatches()
-+:let rf1 = setmatches(0)
-+:let rf2 = setmatches([0])
-+:let rf3 = setmatches([{'wrong key': 'wrong value'}])
-+:if rs1 == 0 && rs2 == 0 && rf1 == -1 && rf2 == -1 && rf3 == -1
-+:  let @r .= "OK\n"
-+:else
-+:  let @r .= "FAILED\n"
-+:endif
-+:unlet rs1
-+:unlet rs2
-+:unlet rf1
-+:unlet rf2
-+:unlet rf3
-+:highlight clear MyGroup1
-+:highlight clear MyGroup2
-+:highlight clear MyGroup3
-+G"rp
-+:/^Results/,$wq! test.out
-+ENDTEST
-+
-+Results of test63:
-diff -Naur vim71.orig/src/testdir/test63.ok vim71/src/testdir/test63.ok
---- vim71.orig/src/testdir/test63.ok	1969-12-31 19:00:00.000000000 -0500
-+++ vim71/src/testdir/test63.ok	2008-06-18 06:51:23.000000000 -0400
-@@ -0,0 +1,11 @@
-+Results of test63:
-+*** Test 1: OK
-+*** Test 2: OK
-+*** Test 3: OK
-+*** Test 4: OK
-+*** Test 5: OK
-+*** Test 6: OK
-+*** Test 7: OK
-+*** Test 8: OK
-+*** Test 9: OK
-+*** Test 10: OK
-diff -Naur vim71.orig/src/testdir/test64.in vim71/src/testdir/test64.in
---- vim71.orig/src/testdir/test64.in	1969-12-31 19:00:00.000000000 -0500
-+++ vim71/src/testdir/test64.in	2008-06-18 06:54:16.000000000 -0400
-@@ -0,0 +1,167 @@
-+Test for regexp patterns.
-+
-+A pattern that gives the expected result produces OK, so that we know it was
-+actually tried.
-+
-+STARTTEST
-+:so small.vim
-+:" tl is a List of Lists with:
-+:"    regexp pattern
-+:"    text to test the pattern on
-+:"    expected match (optional)
-+:"    expected submatch 1 (optional)
-+:"    expected submatch 2 (optional)
-+:"    etc.
-+:"  When there is no match use only the first two items.
-+:let tl = []
-+:call add(tl, ['ab', 'aab', 'ab'])
-+:call add(tl, ['b', 'abcdef', 'b'])
-+:call add(tl, ['bc*', 'abccccdef', 'bcccc'])
-+:call add(tl, ['bc\{-}', 'abccccdef', 'b'])
-+:call add(tl, ['bc\{-}\(d\)', 'abccccdef', 'bccccd', 'd'])
-+:call add(tl, ['bc*', 'abbdef', 'b'])
-+:call add(tl, ['c*', 'ccc', 'ccc'])
-+:call add(tl, ['bc*', 'abdef', 'b'])
-+:call add(tl, ['c*', 'abdef', ''])
-+:call add(tl, ['bc\+', 'abccccdef', 'bcccc'])
-+:call add(tl, ['bc\+', 'abdef']) "no match
-+:"
-+:"operator \|
-+:call add(tl, ['a\|ab', 'cabd', 'a']) "alternation is ordered
-+:"
-+:call add(tl, ['c\?', 'ccb', 'c'])
-+:call add(tl, ['bc\?', 'abd', 'b'])
-+:call add(tl, ['bc\?', 'abccd', 'bc'])
-+:"
-+:call add(tl, ['\va{1}', 'ab', 'a'])
-+:"
-+:call add(tl, ['\va{2}', 'aa', 'aa'])
-+:call add(tl, ['\va{2}', 'caad', 'aa'])
-+:call add(tl, ['\va{2}', 'aba'])
-+:call add(tl, ['\va{2}', 'ab'])
-+:call add(tl, ['\va{2}', 'abaa', 'aa'])
-+:call add(tl, ['\va{2}', 'aaa', 'aa'])
-+:"
-+:call add(tl, ['\vb{1}', 'abca', 'b'])
-+:call add(tl, ['\vba{2}', 'abaa', 'baa'])
-+:call add(tl, ['\vba{3}', 'aabaac'])
-+:"
-+:call add(tl, ['\v(ab){1}', 'ab', 'ab', 'ab'])
-+:call add(tl, ['\v(ab){1}', 'dabc', 'ab', 'ab'])
-+:call add(tl, ['\v(ab){1}', 'acb'])
-+:"
-+:call add(tl, ['\v(ab){0,2}', 'acb', "", ""])
-+:call add(tl, ['\v(ab){0,2}', 'ab', 'ab', 'ab'])
-+:call add(tl, ['\v(ab){1,2}', 'ab', 'ab', 'ab'])
-+:call add(tl, ['\v(ab){1,2}', 'ababc', 'abab', 'ab'])
-+:call add(tl, ['\v(ab){2,4}', 'ababcab', 'abab', 'ab'])
-+:call add(tl, ['\v(ab){2,4}', 'abcababa', 'abab', 'ab'])
-+:"
-+:call add(tl, ['\v(ab){2}', 'abab', 'abab', 'ab'])
-+:call add(tl, ['\v(ab){2}', 'cdababe', 'abab', 'ab'])
-+:call add(tl, ['\v(ab){2}', 'abac'])
-+:call add(tl, ['\v(ab){2}', 'abacabab', 'abab', 'ab'])
-+:call add(tl, ['\v((ab){2}){2}', 'abababab', 'abababab', 'abab', 'ab'])
-+:call add(tl, ['\v((ab){2}){2}', 'abacabababab', 'abababab', 'abab', 'ab'])
-+:"
-+:call add(tl, ['\v(a{1}){1}', 'a', 'a', 'a'])
-+:call add(tl, ['\v(a{2}){1}', 'aa', 'aa', 'aa'])
-+:call add(tl, ['\v(a{2}){1}', 'aaac', 'aa', 'aa'])
-+:call add(tl, ['\v(a{2}){1}', 'daaac', 'aa', 'aa'])
-+:call add(tl, ['\v(a{1}){2}', 'daaac', 'aa', 'a'])
-+:call add(tl, ['\v(a{1}){2}', 'aaa', 'aa', 'a'])
-+:call add(tl, ['\v(a{2})+', 'adaac', 'aa', 'aa'])
-+:call add(tl, ['\v(a{2})+', 'aa', 'aa', 'aa'])
-+:call add(tl, ['\v(a{2}){1}', 'aa', 'aa', 'aa'])
-+:call add(tl, ['\v(a{1}){2}', 'aa', 'aa', 'a'])
-+:call add(tl, ['\v(a{1}){1}', 'a', 'a', 'a'])
-+:call add(tl, ['\v(a{2}){2}', 'aaaa', 'aaaa', 'aa'])
-+:call add(tl, ['\v(a{2}){2}', 'aaabaaaa', 'aaaa', 'aa'])
-+:"
-+:call add(tl, ['\v(a+){2}', 'dadaac', 'aa', 'a'])
-+:call add(tl, ['\v(a{3}){2}', 'aaaaaaa', 'aaaaaa', 'aaa'])
-+:"
-+:call add(tl, ['\v(a{1,2}){2}', 'daaac', 'aaa', 'a'])
-+:call add(tl, ['\v(a{1,3}){2}', 'daaaac', 'aaaa', 'a'])
-+:call add(tl, ['\v(a{1,3}){2}', 'daaaaac', 'aaaaa', 'aa'])
-+:call add(tl, ['\v(a{1,3}){3}', 'daac'])
-+:call add(tl, ['\v(a{1,2}){2}', 'dac'])
-+:call add(tl, ['\v(a+)+', 'daac', 'aa', 'aa'])
-+:call add(tl, ['\v(a+)+', 'aaa', 'aaa', 'aaa'])
-+:call add(tl, ['\v(a+){1,2}', 'aaa', 'aaa', 'aaa'])
-+:call add(tl, ['\v(a+)(a+)', 'aaa', 'aaa', 'aa', 'a'])
-+:call add(tl, ['\v(a{3})+', 'daaaac', 'aaa', 'aaa'])
-+:call add(tl, ['\v(a|b|c)+', 'aacb', 'aacb', 'b'])
-+:call add(tl, ['\v(a|b|c){2}', 'abcb', 'ab', 'b'])
-+:call add(tl, ['\v(abc){2}', 'abcabd', ])
-+:call add(tl, ['\v(abc){2}', 'abdabcabc','abcabc', 'abc'])
-+:"
-+:call add(tl, ['a*', 'cc', ''])
-+:call add(tl, ['\v(a*)+', 'cc', ''])
-+:call add(tl, ['\v((ab)+)+', 'ab', 'ab', 'ab', 'ab'])
-+:call add(tl, ['\v(((ab)+)+)+', 'ab', 'ab', 'ab', 'ab', 'ab'])
-+:call add(tl, ['\v(((ab)+)+)+', 'dababc', 'abab', 'abab', 'abab', 'ab'])
-+:call add(tl, ['\v(a{0,2})+', 'cc', ''])
-+:call add(tl, ['\v(a*)+', '', ''])
-+:call add(tl, ['\v((a*)+)+', '', ''])
-+:call add(tl, ['\v((ab)*)+', '', ''])
-+:call add(tl, ['\va{1,3}', 'aab', 'aa'])
-+:call add(tl, ['\va{2,3}', 'abaa', 'aa'])
-+:"
-+:call add(tl, ['\v((ab)+|c*)+', 'abcccaba', 'abcccab', '', 'ab'])
-+:call add(tl, ['\v(a{2})|(b{3})', 'bbabbbb', 'bbb', '', 'bbb'])
-+:call add(tl, ['\va{2}|b{2}', 'abab'])
-+:call add(tl, ['\v(a)+|(c)+', 'bbacbaacbbb', 'a', 'a'])
-+:call add(tl, ['\vab{2,3}c', 'aabbccccccccccccc', 'abbc'])
-+:call add(tl, ['\vab{2,3}c', 'aabbbccccccccccccc', 'abbbc'])
-+:call add(tl, ['\vab{2,3}cd{2,3}e', 'aabbbcddee', 'abbbcdde'])
-+:call add(tl, ['\va(bc){2}d', 'aabcbfbc' ])
-+:call add(tl, ['\va*a{2}', 'a', ])
-+:call add(tl, ['\va*a{2}', 'aa', 'aa' ])
-+:call add(tl, ['\va*a{2}', 'aaa', 'aaa' ])
-+:call add(tl, ['\va*a{2}', 'bbbabcc', ])
-+:call add(tl, ['\va*b*|a*c*', 'a', 'a'])
-+:call add(tl, ['\va{1}b{1}|a{1}b{1}', ''])
-+:"
-+:"submatches
-+:call add(tl, ['\v(a)', 'ab', 'a', 'a'])
-+:call add(tl, ['\v(a)(b)', 'ab', 'ab', 'a', 'b'])
-+:call add(tl, ['\v(ab)(b)(c)', 'abbc', 'abbc', 'ab', 'b', 'c'])
-+:call add(tl, ['\v((a)(b))', 'ab', 'ab', 'ab', 'a', 'b'])
-+:call add(tl, ['\v(a)|(b)', 'ab', 'a', 'a'])
-+:"
-+:call add(tl, ['\v(a*)+', 'aaaa', 'aaaa', ''])
-+:call add(tl, ['x', 'abcdef'])
-+:"
-+:for t in tl
-+:  let l = matchlist(t[1], t[0])
-+:" check the match itself
-+:  if len(l) == 0 && len(t) > 2
-+:    $put ='ERROR: pat: \"' . t[0] . '\", text: \"' . t[1] . '\", did not match, expected: \"' . t[2] . '\"'
-+:  elseif len(l) > 0 && len(t) == 2
-+:    $put ='ERROR: pat: \"' . t[0] . '\", text: \"' . t[1] . '\", match: \"' . l[0] . '\", expected no match'
-+:  elseif len(t) > 2 && l[0] != t[2]
-+:    $put ='ERROR: pat: \"' . t[0] . '\", text: \"' . t[1] . '\", match: \"' . l[0] . '\", expected: \"' . t[2] . '\"'
-+:  else
-+:    $put ='OK'
-+:  endif
-+:  if len(l) > 0
-+:"   check all the nine submatches
-+:    for i in range(1, 9)
-+:      if len(t) <= i + 2
-+:        let e = ''
-+:      else
-+:        let e = t[i + 2]
-+:      endif
-+:      if l[i] != e
-+:        $put ='ERROR: pat: \"' . t[0] . '\", text: \"' . t[1] . '\", submatch ' . i . ': \"' . l[i] . '\", expected: \"' . e . '\"'
-+:      endif
-+:    endfor
-+:    unlet i
-+:  endif
-+:endfor
-+:unlet t tl e l
-+:/^Results/,$wq! test.out
-+ENDTEST
-+
-+Results of test64:
-diff -Naur vim71.orig/src/testdir/test64.ok vim71/src/testdir/test64.ok
---- vim71.orig/src/testdir/test64.ok	1969-12-31 19:00:00.000000000 -0500
-+++ vim71/src/testdir/test64.ok	2008-06-18 06:54:16.000000000 -0400
-@@ -0,0 +1,102 @@
-+Results of test64:
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-+OK
-diff -Naur vim71.orig/src/ui.c vim71/src/ui.c
---- vim71.orig/src/ui.c	2007-05-07 15:49:09.000000000 -0400
-+++ vim71/src/ui.c	2008-06-18 06:52:10.000000000 -0400
-@@ -1603,8 +1603,6 @@
- #if defined(FEAT_GUI) || defined(FEAT_MOUSE_GPM) \
- 	|| defined(FEAT_XCLIPBOARD) || defined(VMS) \
- 	|| defined(FEAT_SNIFF) || defined(FEAT_CLIENTSERVER) \
--	|| (defined(FEAT_GUI) && (!defined(USE_ON_FLY_SCROLL) \
--		|| defined(FEAT_MENU))) \
- 	|| defined(PROTO)
- /*
-  * Add the given bytes to the input buffer
-@@ -1630,7 +1628,9 @@
- }
- #endif
- 
--#if (defined(FEAT_XIM) && defined(FEAT_GUI_GTK)) \
-+#if ((defined(FEAT_XIM) || defined(FEAT_DND)) && defined(FEAT_GUI_GTK)) \
-+	|| defined(FEAT_GUI_MSWIN) \
-+	|| defined(FEAT_GUI_MAC) \
- 	|| (defined(FEAT_MBYTE) && defined(FEAT_MBYTE_IME)) \
- 	|| (defined(FEAT_GUI) && (!defined(USE_ON_FLY_SCROLL) \
- 		|| defined(FEAT_MENU))) \
-diff -Naur vim71.orig/src/undo.c vim71/src/undo.c
---- vim71.orig/src/undo.c	2007-05-07 15:21:14.000000000 -0400
-+++ vim71/src/undo.c	2008-06-18 06:55:41.000000000 -0400
-@@ -76,6 +76,12 @@
-  * buffer is unloaded.
-  */
- 
-+/* Uncomment the next line for including the u_check() function.  This warns
-+ * for errors in the debug information. */
-+/* #define U_DEBUG 1 */
-+#define UH_MAGIC 0x18dade	/* value for uh_magic when in use */
-+#define UE_MAGIC 0xabc123	/* value for ue_magic when in use */
-+
- #include "vim.h"
- 
- /* See below: use malloc()/free() for memory management. */
-@@ -113,6 +119,95 @@
-  */
- static int	undo_undoes = FALSE;
- 
-+#ifdef U_DEBUG
-+/*
-+ * Check the undo structures for being valid.  Print a warning when something
-+ * looks wrong.
-+ */
-+static int seen_b_u_curhead;
-+static int seen_b_u_newhead;
-+static int header_count;
-+
-+    static void
-+u_check_tree(u_header_T *uhp,
-+	u_header_T *exp_uh_next,
-+	u_header_T *exp_uh_alt_prev)
-+{
-+    u_entry_T *uep;
-+
-+    if (uhp == NULL)
-+	return;
-+    ++header_count;
-+    if (uhp == curbuf->b_u_curhead && ++seen_b_u_curhead > 1)
-+    {
-+	EMSG("b_u_curhead found twice (looping?)");
-+	return;
-+    }
-+    if (uhp == curbuf->b_u_newhead && ++seen_b_u_newhead > 1)
-+    {
-+	EMSG("b_u_newhead found twice (looping?)");
-+	return;
-+    }
-+
-+    if (uhp->uh_magic != UH_MAGIC)
-+	EMSG("uh_magic wrong (may be using freed memory)");
-+    else
-+    {
-+	/* Check pointers back are correct. */
-+	if (uhp->uh_next != exp_uh_next)
-+	{
-+	    EMSG("uh_next wrong");
-+	    smsg((char_u *)"expected: 0x%x, actual: 0x%x",
-+						   exp_uh_next, uhp->uh_next);
-+	}
-+	if (uhp->uh_alt_prev != exp_uh_alt_prev)
-+	{
-+	    EMSG("uh_alt_prev wrong");
-+	    smsg((char_u *)"expected: 0x%x, actual: 0x%x",
-+					   exp_uh_alt_prev, uhp->uh_alt_prev);
-+	}
-+
-+	/* Check the undo tree at this header. */
-+	for (uep = uhp->uh_entry; uep != NULL; uep = uep->ue_next)
-+	{
-+	    if (uep->ue_magic != UE_MAGIC)
-+	    {
-+		EMSG("ue_magic wrong (may be using freed memory)");
-+		break;
-+	    }
-+	}
-+
-+	/* Check the next alt tree. */
-+	u_check_tree(uhp->uh_alt_next, uhp->uh_next, uhp);
-+
-+	/* Check the next header in this branch. */
-+	u_check_tree(uhp->uh_prev, uhp, NULL);
-+    }
-+}
-+
-+    void
-+u_check(int newhead_may_be_NULL)
-+{
-+    seen_b_u_newhead = 0;
-+    seen_b_u_curhead = 0;
-+    header_count = 0;
-+
-+    u_check_tree(curbuf->b_u_oldhead, NULL, NULL);
-+
-+    if (seen_b_u_newhead == 0 && curbuf->b_u_oldhead != NULL
-+	    && !(newhead_may_be_NULL && curbuf->b_u_newhead == NULL))
-+	EMSGN("b_u_newhead invalid: 0x%x", curbuf->b_u_newhead);
-+    if (curbuf->b_u_curhead != NULL && seen_b_u_curhead == 0)
-+	EMSGN("b_u_curhead invalid: 0x%x", curbuf->b_u_curhead);
-+    if (header_count != curbuf->b_u_numhead)
-+    {
-+	EMSG("b_u_numhead invalid");
-+	smsg((char_u *)"expected: %ld, actual: %ld",
-+			       (long)header_count, (long)curbuf->b_u_numhead);
-+    }
-+}
-+#endif
-+
- /*
-  * Save the current line for both the "u" and "U" command.
-  * Returns OK or FAIL.
-@@ -243,6 +338,9 @@
-     if (!undo_allowed())
- 	return FAIL;
- 
-+#ifdef U_DEBUG
-+    u_check(FALSE);
-+#endif
- #ifdef FEAT_NETBEANS_INTG
-     /*
-      * Netbeans defines areas that cannot be modified.  Bail out here when
-@@ -294,6 +392,9 @@
- 	    uhp = (u_header_T *)U_ALLOC_LINE((unsigned)sizeof(u_header_T));
- 	    if (uhp == NULL)
- 		goto nomem;
-+#ifdef U_DEBUG
-+	    uhp->uh_magic = UH_MAGIC;
-+#endif
- 	}
- 	else
- 	    uhp = NULL;
-@@ -316,8 +417,11 @@
- 	{
- 	    u_header_T	    *uhfree = curbuf->b_u_oldhead;
- 
--	    /* If there is no branch only free one header. */
--	    if (uhfree->uh_alt_next == NULL)
-+	    if (uhfree == old_curhead)
-+		/* Can't reconnect the branch, delete all of it. */
-+		u_freebranch(curbuf, uhfree, &old_curhead);
-+	    else if (uhfree->uh_alt_next == NULL)
-+		/* There is no branch, only free one header. */
- 		u_freeheader(curbuf, uhfree, &old_curhead);
- 	    else
- 	    {
-@@ -326,6 +430,9 @@
- 		    uhfree = uhfree->uh_alt_next;
- 		u_freebranch(curbuf, uhfree, &old_curhead);
- 	    }
-+#ifdef U_DEBUG
-+	    u_check(TRUE);
-+#endif
- 	}
- 
- 	if (uhp == NULL)		/* no undo at all */
-@@ -478,6 +585,9 @@
-     uep = (u_entry_T *)U_ALLOC_LINE((unsigned)sizeof(u_entry_T));
-     if (uep == NULL)
- 	goto nomem;
-+#ifdef U_DEBUG
-+    uep->ue_magic = UE_MAGIC;
-+#endif
- 
-     uep->ue_size = size;
-     uep->ue_top = top;
-@@ -525,6 +635,9 @@
-     curbuf->b_u_synced = FALSE;
-     undo_undoes = FALSE;
- 
-+#ifdef U_DEBUG
-+    u_check(FALSE);
-+#endif
-     return OK;
- 
- nomem:
-@@ -955,6 +1068,9 @@
-     int		empty_buffer;		    /* buffer became empty */
-     u_header_T	*curhead = curbuf->b_u_curhead;
- 
-+#ifdef U_DEBUG
-+    u_check(FALSE);
-+#endif
-     old_flags = curhead->uh_flags;
-     new_flags = (curbuf->b_changed ? UH_CHANGED : 0) +
- 	       ((curbuf->b_ml.ml_flags & ML_EMPTY) ? UH_EMPTYBUF : 0);
-@@ -1186,6 +1302,9 @@
-     /* The timestamp can be the same for multiple changes, just use the one of
-      * the undone/redone change. */
-     curbuf->b_u_seq_time = curhead->uh_time;
-+#ifdef U_DEBUG
-+    u_check(FALSE);
-+#endif
- }
- 
- /*
-@@ -1515,7 +1634,7 @@
- }
- 
- /*
-- * Free one header and its entry list and adjust the pointers.
-+ * Free one header "uhp" and its entry list and adjust the pointers.
-  */
-     static void
- u_freeheader(buf, uhp, uhpp)
-@@ -1523,6 +1642,8 @@
-     u_header_T	    *uhp;
-     u_header_T	    **uhpp;	/* if not NULL reset when freeing this header */
- {
-+    u_header_T	    *uhap;
-+
-     /* When there is an alternate redo list free that branch completely,
-      * because we can never go there. */
-     if (uhp->uh_alt_next != NULL)
-@@ -1540,7 +1661,8 @@
-     if (uhp->uh_prev == NULL)
- 	buf->b_u_newhead = uhp->uh_next;
-     else
--	uhp->uh_prev->uh_next = uhp->uh_next;
-+	for (uhap = uhp->uh_prev; uhap != NULL; uhap = uhap->uh_alt_next)
-+	    uhap->uh_next = uhp->uh_next;
- 
-     u_freeentries(buf, uhp, uhpp);
- }
-@@ -1556,6 +1678,14 @@
- {
-     u_header_T	    *tofree, *next;
- 
-+    /* If this is the top branch we may need to use u_freeheader() to update
-+     * all the pointers. */
-+    if (uhp == buf->b_u_oldhead)
-+    {
-+	u_freeheader(buf, uhp, uhpp);
-+	return;
-+    }
-+
-     if (uhp->uh_alt_prev != NULL)
- 	uhp->uh_alt_prev->uh_alt_next = NULL;
- 
-@@ -1585,6 +1715,8 @@
-     /* Check for pointers to the header that become invalid now. */
-     if (buf->b_u_curhead == uhp)
- 	buf->b_u_curhead = NULL;
-+    if (buf->b_u_newhead == uhp)
-+	buf->b_u_newhead = NULL;  /* freeing the newest entry */
-     if (uhpp != NULL && uhp == *uhpp)
- 	*uhpp = NULL;
- 
-@@ -1594,6 +1726,9 @@
- 	u_freeentry(uep, uep->ue_size);
-     }
- 
-+#ifdef U_DEBUG
-+    uhp->uh_magic = 0;
-+#endif
-     U_FREE_LINE((char_u *)uhp);
-     --buf->b_u_numhead;
- }
-@@ -1609,6 +1744,9 @@
-     while (n > 0)
- 	U_FREE_LINE(uep->ue_array[--n]);
-     U_FREE_LINE((char_u *)uep->ue_array);
-+#ifdef U_DEBUG
-+    uep->ue_magic = 0;
-+#endif
-     U_FREE_LINE((char_u *)uep);
- }
- 
-@@ -1676,13 +1814,14 @@
-     if (undo_off)
- 	return;
- 
--    if (curbuf->b_u_line_ptr == NULL ||
--			curbuf->b_u_line_lnum > curbuf->b_ml.ml_line_count)
-+    if (curbuf->b_u_line_ptr == NULL
-+			|| curbuf->b_u_line_lnum > curbuf->b_ml.ml_line_count)
-     {
- 	beep_flush();
- 	return;
-     }
--	/* first save the line for the 'u' command */
-+
-+    /* first save the line for the 'u' command */
-     if (u_savecommon(curbuf->b_u_line_lnum - 1,
- 				curbuf->b_u_line_lnum + 1, (linenr_T)0) == FAIL)
- 	return;
-@@ -1702,6 +1841,7 @@
- 	curbuf->b_u_line_colnr = curwin->w_cursor.col;
-     curwin->w_cursor.col = t;
-     curwin->w_cursor.lnum = curbuf->b_u_line_lnum;
-+    check_cursor_col();
- }
- 
- /*
-diff -Naur vim71.orig/src/version.c vim71/src/version.c
---- vim71.orig/src/version.c	2007-05-12 06:23:44.000000000 -0400
-+++ vim71/src/version.c	2008-06-18 06:57:02.000000000 -0400
-@@ -667,6 +667,582 @@
- static int included_patches[] =
- {   /* Add new patch number below this line */
- /**/
-+    315,
-+/**/
-+    314,
-+/**/
-+    313,
-+/**/
-+    311,
-+/**/
-+    310,
-+/**/
-+    309,
-+/**/
-+    308,
-+/**/
-+    307,
-+/**/
-+    306,
-+/**/
-+    305,
-+/**/
-+    304,
-+/**/
-+    303,
-+/**/
-+    302,
-+/**/
-+    301,
-+/**/
-+    300,
-+/**/
-+    299,
-+/**/
-+    298,
-+/**/
-+    297,
-+/**/
-+    296,
-+/**/
-+    295,
-+/**/
-+    294,
-+/**/
-+    293,
-+/**/
-+    292,
-+/**/
-+    291,
-+/**/
-+    290,
-+/**/
-+    289,
-+/**/
-+    288,
-+/**/
-+    287,
-+/**/
-+    286,
-+/**/
-+    284,
-+/**/
-+    281,
-+/**/
-+    279,
-+/**/
-+    277,
-+/**/
-+    276,
-+/**/
-+    274,
-+/**/
-+    273,
-+/**/
-+    272,
-+/**/
-+    271,
-+/**/
-+    270,
-+/**/
-+    269,
-+/**/
-+    268,
-+/**/
-+    267,
-+/**/
-+    266,
-+/**/
-+    265,
-+/**/
-+    264,
-+/**/
-+    263,
-+/**/
-+    262,
-+/**/
-+    261,
-+/**/
-+    260,
-+/**/
-+    259,
-+/**/
-+    258,
-+/**/
-+    257,
-+/**/
-+    256,
-+/**/
-+    255,
-+/**/
-+    254,
-+/**/
-+    253,
-+/**/
-+    252,
-+/**/
-+    251,
-+/**/
-+    250,
-+/**/
-+    249,
-+/**/
-+    248,
-+/**/
-+    247,
-+/**/
-+    246,
-+/**/
-+    245,
-+/**/
-+    244,
-+/**/
-+    243,
-+/**/
-+    242,
-+/**/
-+    241,
-+/**/
-+    240,
-+/**/
-+    239,
-+/**/
-+    238,
-+/**/
-+    237,
-+/**/
-+    236,
-+/**/
-+    235,
-+/**/
-+    234,
-+/**/
-+    233,
-+/**/
-+    232,
-+/**/
-+    231,
-+/**/
-+    230,
-+/**/
-+    229,
-+/**/
-+    228,
-+/**/
-+    227,
-+/**/
-+    226,
-+/**/
-+    225,
-+/**/
-+    224,
-+/**/
-+    223,
-+/**/
-+    222,
-+/**/
-+    221,
-+/**/
-+    220,
-+/**/
-+    219,
-+/**/
-+    218,
-+/**/
-+    217,
-+/**/
-+    216,
-+/**/
-+    215,
-+/**/
-+    214,
-+/**/
-+    213,
-+/**/
-+    212,
-+/**/
-+    211,
-+/**/
-+    210,
-+/**/
-+    209,
-+/**/
-+    208,
-+/**/
-+    207,
-+/**/
-+    206,
-+/**/
-+    205,
-+/**/
-+    203,
-+/**/
-+    202,
-+/**/
-+    201,
-+/**/
-+    200,
-+/**/
-+    199,
-+/**/
-+    198,
-+/**/
-+    197,
-+/**/
-+    195,
-+/**/
-+    194,
-+/**/
-+    193,
-+/**/
-+    192,
-+/**/
-+    191,
-+/**/
-+    190,
-+/**/
-+    189,
-+/**/
-+    188,
-+/**/
-+    187,
-+/**/
-+    186,
-+/**/
-+    185,
-+/**/
-+    184,
-+/**/
-+    183,
-+/**/
-+    182,
-+/**/
-+    181,
-+/**/
-+    180,
-+/**/
-+    179,
-+/**/
-+    178,
-+/**/
-+    177,
-+/**/
-+    176,
-+/**/
-+    175,
-+/**/
-+    174,
-+/**/
-+    173,
-+/**/
-+    172,
-+/**/
-+    171,
-+/**/
-+    170,
-+/**/
-+    169,
-+/**/
-+    167,
-+/**/
-+    166,
-+/**/
-+    165,
-+/**/
-+    164,
-+/**/
-+    163,
-+/**/
-+    162,
-+/**/
-+    161,
-+/**/
-+    160,
-+/**/
-+    159,
-+/**/
-+    157,
-+/**/
-+    156,
-+/**/
-+    155,
-+/**/
-+    154,
-+/**/
-+    153,
-+/**/
-+    152,
-+/**/
-+    151,
-+/**/
-+    150,
-+/**/
-+    149,
-+/**/
-+    148,
-+/**/
-+    147,
-+/**/
-+    145,
-+/**/
-+    144,
-+/**/
-+    143,
-+/**/
-+    142,
-+/**/
-+    141,
-+/**/
-+    140,
-+/**/
-+    139,
-+/**/
-+    138,
-+/**/
-+    137,
-+/**/
-+    136,
-+/**/
-+    135,
-+/**/
-+    133,
-+/**/
-+    132,
-+/**/
-+    131,
-+/**/
-+    130,
-+/**/
-+    127,
-+/**/
-+    125,
-+/**/
-+    123,
-+/**/
-+    122,
-+/**/
-+    121,
-+/**/
-+    120,
-+/**/
-+    119,
-+/**/
-+    118,
-+/**/
-+    117,
-+/**/
-+    116,
-+/**/
-+    115,
-+/**/
-+    114,
-+/**/
-+    113,
-+/**/
-+    112,
-+/**/
-+    111,
-+/**/
-+    110,
-+/**/
-+    109,
-+/**/
-+    108,
-+/**/
-+    107,
-+/**/
-+    106,
-+/**/
-+    105,
-+/**/
-+    104,
-+/**/
-+    103,
-+/**/
-+    102,
-+/**/
-+    101,
-+/**/
-+    100,
-+/**/
-+    99,
-+/**/
-+    98,
-+/**/
-+    97,
-+/**/
-+    96,
-+/**/
-+    95,
-+/**/
-+    94,
-+/**/
-+    93,
-+/**/
-+    90,
-+/**/
-+    89,
-+/**/
-+    87,
-+/**/
-+    86,
-+/**/
-+    85,
-+/**/
-+    84,
-+/**/
-+    83,
-+/**/
-+    82,
-+/**/
-+    81,
-+/**/
-+    79,
-+/**/
-+    78,
-+/**/
-+    77,
-+/**/
-+    76,
-+/**/
-+    75,
-+/**/
-+    74,
-+/**/
-+    73,
-+/**/
-+    71,
-+/**/
-+    69,
-+/**/
-+    68,
-+/**/
-+    67,
-+/**/
-+    66,
-+/**/
-+    64,
-+/**/
-+    63,
-+/**/
-+    62,
-+/**/
-+    61,
-+/**/
-+    60,
-+/**/
-+    59,
-+/**/
-+    58,
-+/**/
-+    57,
-+/**/
-+    56,
-+/**/
-+    55,
-+/**/
-+    54,
-+/**/
-+    53,
-+/**/
-+    52,
-+/**/
-+    51,
-+/**/
-+    50,
-+/**/
-+    49,
-+/**/
-+    48,
-+/**/
-+    47,
-+/**/
-+    46,
-+/**/
-+    45,
-+/**/
-+    44,
-+/**/
-+    43,
-+/**/
-+    42,
-+/**/
-+    40,
-+/**/
-+    39,
-+/**/
-+    38,
-+/**/
-+    37,
-+/**/
-+    36,
-+/**/
-+    35,
-+/**/
-+    34,
-+/**/
-+    33,
-+/**/
-+    32,
-+/**/
-+    31,
-+/**/
-+    30,
-+/**/
-+    29,
-+/**/
-+    28,
-+/**/
-+    27,
-+/**/
-+    26,
-+/**/
-+    25,
-+/**/
-+    24,
-+/**/
-+    23,
-+/**/
-+    22,
-+/**/
-+    21,
-+/**/
-+    20,
-+/**/
-+    19,
-+/**/
-+    18,
-+/**/
-+    17,
-+/**/
-+    16,
-+/**/
-+    15,
-+/**/
-+    14,
-+/**/
-+    13,
-+/**/
-+    12,
-+/**/
-+    11,
-+/**/
-+    10,
-+/**/
-+    9,
-+/**/
-+    8,
-+/**/
-+    6,
-+/**/
-+    5,
-+/**/
-+    4,
-+/**/
-+    2,
-+/**/
-+    1,
-+/**/
-     0
- };
- 
-@@ -1177,9 +1753,9 @@
- 
-     if (*mesg == ' ')
-     {
--	vim_strncpy(modby, _("Modified by "), MODBY_LEN - 1);
-+	vim_strncpy(modby, (char_u *)_("Modified by "), MODBY_LEN - 1);
- 	l = STRLEN(modby);
--	vim_strncpy(modby + l, MODIFIED_BY, MODBY_LEN - l - 1);
-+	vim_strncpy(modby + l, (char_u *)MODIFIED_BY, MODBY_LEN - l - 1);
- 	mesg = modby;
-     }
- #endif
-diff -Naur vim71.orig/src/vim.h vim71/src/vim.h
---- vim71.orig/src/vim.h	2007-05-12 05:53:29.000000000 -0400
-+++ vim71/src/vim.h	2008-06-18 06:56:43.000000000 -0400
-@@ -336,10 +336,10 @@
- # endif
- #endif
- #ifdef BACKSLASH_IN_FILENAME
--# define PATH_ESC_CHARS ((char_u *)" \t*?[{`%#")
-+# define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`%#'\"|!<")
- #else
--# define PATH_ESC_CHARS ((char_u *)" \t*?[{`$\\%#'\"|")
--# define SHELL_ESC_CHARS ((char_u *)" \t*?[{`$\\%#'\"|<>();&!")
-+# define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<")
-+# define SHELL_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<>();&")
- #endif
- 
- #define NUMBUFLEN 30	    /* length of a buffer to store a number in ASCII */
-@@ -721,6 +721,11 @@
- /* Note: mostly EW_NOTFOUND and EW_SILENT are mutually exclusive: EW_NOTFOUND
-  * is used when executing commands and EW_SILENT for interactive expanding. */
- 
-+/* Flags for find_file_*() functions. */
-+#define FINDFILE_FILE	0	/* only files */
-+#define FINDFILE_DIR	1	/* only directories */
-+#define FINDFILE_BOTH	2	/* files and directories */
-+
- #ifdef FEAT_VERTSPLIT
- # define W_WINCOL(wp)	(wp->w_wincol)
- # define W_WIDTH(wp)	(wp->w_width)
-@@ -943,6 +948,7 @@
- #define INSCHAR_FORMAT	1	/* force formatting */
- #define INSCHAR_DO_COM	2	/* format comments */
- #define INSCHAR_CTRLV	4	/* char typed just after CTRL-V */
-+#define INSCHAR_NO_FEX	8	/* don't use 'formatexpr' */
- 
- /* flags for open_line() */
- #define OPENLINE_DELSPACES  1	/* delete spaces after cursor */
-@@ -1380,8 +1386,14 @@
- #endif
- 
- #ifdef FEAT_MBYTE
--# define MB_STRICMP(d, s)	(has_mbyte ? mb_strnicmp((char_u *)(d), (char_u *)(s), (int)MAXCOL) : STRICMP((d), (s)))
--# define MB_STRNICMP(d, s, n)	(has_mbyte ? mb_strnicmp((char_u *)(d), (char_u *)(s), (int)(n)) : STRNICMP((d), (s), (n)))
-+/* We need to call mb_stricmp() even when we aren't dealing with a multi-byte
-+ * encoding because mb_stricmp() takes care of all ascii and non-ascii
-+ * encodings, including characters with umluats in latin1, etc., while
-+ * STRICMP() only handles the system locale version, which often does not
-+ * handle non-ascii properly. */
-+
-+# define MB_STRICMP(d, s)	mb_strnicmp((char_u *)(d), (char_u *)(s), (int)MAXCOL)
-+# define MB_STRNICMP(d, s, n)	mb_strnicmp((char_u *)(d), (char_u *)(s), (int)(n))
- #else
- # define MB_STRICMP(d, s)	STRICMP((d), (s))
- # define MB_STRNICMP(d, s, n)	STRNICMP((d), (s), (n))
-@@ -1544,6 +1556,16 @@
- # define MB_MAXBYTES	21
- #endif
- 
-+#if (defined(FEAT_PROFILE) || defined(FEAT_RELTIME)) && !defined(PROTO)
-+# ifdef WIN3264
-+typedef LARGE_INTEGER proftime_T;
-+# else
-+typedef struct timeval proftime_T;
-+# endif
-+#else
-+typedef int proftime_T;	    /* dummy for function prototypes */
-+#endif
-+
- /* Include option.h before structs.h, because the number of window-local and
-  * buffer-local options is used there. */
- #include "option.h"	    /* options and default values */
-@@ -1682,7 +1704,8 @@
- #define VV_MOUSE_WIN	49
- #define VV_MOUSE_LNUM   50
- #define VV_MOUSE_COL	51
--#define VV_LEN		52	/* number of v: vars */
-+#define VV_OP		52
-+#define VV_LEN		53	/* number of v: vars */
- 
- #ifdef FEAT_CLIPBOARD
- 
-@@ -1755,16 +1778,6 @@
- # define stat(a,b) (access(a,0) ? -1 : stat(a,b))
- #endif
- 
--#if (defined(FEAT_PROFILE) || defined(FEAT_RELTIME)) && !defined(PROTO)
--# ifdef WIN3264
--typedef LARGE_INTEGER proftime_T;
--# else
--typedef struct timeval proftime_T;
--# endif
--#else
--typedef int proftime_T;	    /* dummy for function prototypes */
--#endif
--
- #include "ex_cmds.h"	    /* Ex command defines */
- #include "proto.h"	    /* function prototypes */
- 
-diff -Naur vim71.orig/src/vimtutor vim71/src/vimtutor
---- vim71.orig/src/vimtutor	2004-06-07 10:32:27.000000000 -0400
-+++ vim71/src/vimtutor	2008-06-18 06:56:38.000000000 -0400
-@@ -2,11 +2,24 @@
- 
- # Start Vim on a copy of the tutor file.
- 
--# Usage: vimtutor [xx], where xx is a language code like "es" or "nl".
-+# Usage: vimtutor [-g] [xx]
-+# Where optional argument -g starts vimtutor in gvim (GUI) instead of vim.
-+# and xx is a language code like "es" or "nl".
- # When an argument is given, it tries loading that tutor.
- # When this fails or no argument was given, it tries using 'v:lang'
- # When that also fails, it uses the English version.
- 
-+# Vim could be called "vim" or "vi".  Also check for "vimN", for people who
-+# have Vim installed with its version number.
-+# We anticipate up to a future Vim 8 version :-).
-+seq="vim vim8 vim75 vim74 vim73 vim72 vim71 vim70 vim7 vim6 vi"
-+if test "$1" = "-g"; then 
-+  # Try to use the GUI version of Vim if possible, it will fall back
-+  # on Vim if Gvim is not installed.
-+  seq="gvim gvim8 gvim75 gvim74 gvim73 gvim72 gvim71 gvim70 gvim7 gvim6 $seq"
-+  shift
-+fi
-+
- xx=$1
- export xx
- 
-@@ -39,23 +52,23 @@
- # remove the copy of the tutor on exit
- trap "rm -rf $TODELETE" 0 1 2 3 9 11 13 15
- 
--# Vim could be called "vim" or "vi".  Also check for "vim6", for people who
--# have Vim 5.x installed as "vim" and Vim 6.0 as "vim6".
--testvim=`which vim6 2>/dev/null`
--if test -f "$testvim"; then
--	VIM=vim6
--else
--	testvim=`which vim`
-+for i in $seq; do
-+	testvim=`which $i 2>/dev/null`
- 	if test -f "$testvim"; then
--		VIM=vim
--	else
--		VIM=vi
-+		VIM=$i
-+		break
- 	fi
-+done
-+
-+# When no Vim version was found fall back to "vim", you'll get an error message
-+# below.
-+if test -z "$VIM"; then
-+	VIM=vim
- fi
- 
- # Use Vim to copy the tutor, it knows the value of $VIMRUNTIME
- # The script tutor.vim tells Vim which file to copy
--$VIM -u NONE -c 'so $VIMRUNTIME/tutor/tutor.vim'
-+$VIM -f -u NONE -c 'so $VIMRUNTIME/tutor/tutor.vim'
- 
- # Start vim without any .vimrc, set 'nocompatible'
--$VIM -u NONE -c "set nocp" $TUTORCOPY
-+$VIM -f -u NONE -c "set nocp" $TUTORCOPY
-diff -Naur vim71.orig/src/window.c vim71/src/window.c
---- vim71.orig/src/window.c	2007-05-07 15:25:30.000000000 -0400
-+++ vim71/src/window.c	2008-06-18 06:53:09.000000000 -0400
-@@ -75,6 +75,7 @@
- static win_T *restore_snapshot_rec __ARGS((frame_T *sn, frame_T *fr));
- 
- #endif /* FEAT_WINDOWS */
-+
- static win_T *win_alloc __ARGS((win_T *after));
- static void win_new_height __ARGS((win_T *, int));
- 
-@@ -583,7 +584,7 @@
- 		++no_mapping;
- 		++allow_keys;   /* no mapping for xchar, but allow key codes */
- 		if (xchar == NUL)
--		    xchar = safe_vgetc();
-+		    xchar = plain_vgetc();
- #ifdef FEAT_LANGMAP
- 		LANGMAP_ADJUST(xchar, TRUE);
- #endif
-@@ -732,7 +733,6 @@
-     if (flags & WSP_VERT)
-     {
- 	layout = FR_ROW;
--	do_equal = (p_ea && new_size == 0 && *p_ead != 'v');
- 
- 	/*
- 	 * Check if we are able to split the current window and compute its
-@@ -769,16 +769,31 @@
- 	 * instead, if possible. */
- 	if (oldwin->w_p_wfw)
- 	    win_setwidth_win(oldwin->w_width + new_size, oldwin);
-+
-+	/* Only make all windows the same width if one of them (except oldwin)
-+	 * is wider than one of the split windows. */
-+	if (!do_equal && p_ea && size == 0 && *p_ead != 'v'
-+	   && oldwin->w_frame->fr_parent != NULL)
-+	{
-+	    frp = oldwin->w_frame->fr_parent->fr_child;
-+	    while (frp != NULL)
-+	    {
-+		if (frp->fr_win != oldwin && frp->fr_win != NULL
-+			&& (frp->fr_win->w_width > new_size
-+			    || frp->fr_win->w_width > oldwin->w_width
-+						   - new_size - STATUS_HEIGHT))
-+		{
-+		    do_equal = TRUE;
-+		    break;
-+		}
-+		frp = frp->fr_next;
-+	    }
-+	}
-     }
-     else
- #endif
-     {
- 	layout = FR_COL;
--	do_equal = (p_ea && new_size == 0
--#ifdef FEAT_VERTSPLIT
--		&& *p_ead != 'h'
--#endif
--		);
- 
- 	/*
- 	 * Check if we are able to split the current window and compute its
-@@ -831,6 +846,29 @@
- 	    if (need_status)
- 		oldwin_height -= STATUS_HEIGHT;
- 	}
-+
-+	/* Only make all windows the same height if one of them (except oldwin)
-+	 * is higher than one of the split windows. */
-+	if (!do_equal && p_ea && size == 0
-+#ifdef FEAT_VERTSPLIT
-+		&& *p_ead != 'h'
-+#endif
-+	   && oldwin->w_frame->fr_parent != NULL)
-+	{
-+	    frp = oldwin->w_frame->fr_parent->fr_child;
-+	    while (frp != NULL)
-+	    {
-+		if (frp->fr_win != oldwin && frp->fr_win != NULL
-+			&& (frp->fr_win->w_height > new_size
-+			    || frp->fr_win->w_height > oldwin_height - new_size
-+							      - STATUS_HEIGHT))
-+		{
-+		    do_equal = TRUE;
-+		    break;
-+		}
-+		frp = frp->fr_next;
-+	    }
-+	}
-     }
- 
-     /*
-@@ -1253,7 +1291,7 @@
-      * Don't execute autocommands while creating the windows.  Must do that
-      * when putting the buffers in the windows.
-      */
--    ++autocmd_block;
-+    block_autocmds();
- #endif
- 
-     /* todo is number of windows left to create */
-@@ -1275,7 +1313,7 @@
- 	}
- 
- #ifdef FEAT_AUTOCMD
--    --autocmd_block;
-+    unblock_autocmds();
- #endif
- 
-     /* return actual number of windows */
-@@ -2120,7 +2158,7 @@
- 	if (wp->w_p_pvw || bt_quickfix(wp->w_buffer))
- 	{
- 	    /*
--	     * The cursor goes to the preview or the quickfix window, try
-+	     * If the cursor goes to the preview or the quickfix window, try
- 	     * finding another window to go to.
- 	     */
- 	    for (;;)
-@@ -2307,7 +2345,6 @@
-     frame_T	*frp, *frp2, *frp3;
-     frame_T	*frp_close = win->w_frame;
-     win_T	*wp;
--    int		old_size = 0;
- 
-     /*
-      * If there is only one window there is nothing to remove.
-@@ -2328,33 +2365,77 @@
-     if (frp_close->fr_parent->fr_layout == FR_COL)
-     {
- #endif
--	/* When 'winfixheight' is set, remember its old size and restore
--	 * it later (it's a simplistic solution...).  Don't do this if the
--	 * window will occupy the full height of the screen. */
--	if (frp2->fr_win != NULL
--		&& (frp2->fr_next != NULL || frp2->fr_prev != NULL)
--		&& frp2->fr_win->w_p_wfh)
--	    old_size = frp2->fr_win->w_height;
-+	/* When 'winfixheight' is set, try to find another frame in the column
-+	 * (as close to the closed frame as possible) to distribute the height
-+	 * to. */
-+	if (frp2->fr_win != NULL && frp2->fr_win->w_p_wfh)
-+	{
-+	    frp = frp_close->fr_prev;
-+	    frp3 = frp_close->fr_next;
-+	    while (frp != NULL || frp3 != NULL)
-+	    {
-+		if (frp != NULL)
-+		{
-+		    if (frp->fr_win != NULL && !frp->fr_win->w_p_wfh)
-+		    {
-+			frp2 = frp;
-+			wp = frp->fr_win;
-+			break;
-+		    }
-+		    frp = frp->fr_prev;
-+		}
-+		if (frp3 != NULL)
-+		{
-+		    if (frp3->fr_win != NULL && !frp3->fr_win->w_p_wfh)
-+		    {
-+			frp2 = frp3;
-+			wp = frp3->fr_win;
-+			break;
-+		    }
-+		    frp3 = frp3->fr_next;
-+		}
-+	    }
-+	}
- 	frame_new_height(frp2, frp2->fr_height + frp_close->fr_height,
- 			    frp2 == frp_close->fr_next ? TRUE : FALSE, FALSE);
--	if (old_size != 0)
--	    win_setheight_win(old_size, frp2->fr_win);
- #ifdef FEAT_VERTSPLIT
- 	*dirp = 'v';
-     }
-     else
-     {
--	/* When 'winfixwidth' is set, remember its old size and restore
--	 * it later (it's a simplistic solution...).  Don't do this if the
--	 * window will occupy the full width of the screen. */
--	if (frp2->fr_win != NULL
--		&& (frp2->fr_next != NULL || frp2->fr_prev != NULL)
--		&& frp2->fr_win->w_p_wfw)
--	    old_size = frp2->fr_win->w_width;
-+	/* When 'winfixwidth' is set, try to find another frame in the column
-+	 * (as close to the closed frame as possible) to distribute the width
-+	 * to. */
-+	if (frp2->fr_win != NULL && frp2->fr_win->w_p_wfw)
-+	{
-+	    frp = frp_close->fr_prev;
-+	    frp3 = frp_close->fr_next;
-+	    while (frp != NULL || frp3 != NULL)
-+	    {
-+		if (frp != NULL)
-+		{
-+		    if (frp->fr_win != NULL && !frp->fr_win->w_p_wfw)
-+		    {
-+			frp2 = frp;
-+			wp = frp->fr_win;
-+			break;
-+		    }
-+		    frp = frp->fr_prev;
-+		}
-+		if (frp3 != NULL)
-+		{
-+		    if (frp3->fr_win != NULL && !frp3->fr_win->w_p_wfw)
-+		    {
-+			frp2 = frp3;
-+			wp = frp3->fr_win;
-+			break;
-+		    }
-+		    frp3 = frp3->fr_next;
-+		}
-+	    }
-+	}
- 	frame_new_width(frp2, frp2->fr_width + frp_close->fr_width,
- 			    frp2 == frp_close->fr_next ? TRUE : FALSE, FALSE);
--	if (old_size != 0)
--	    win_setwidth_win(old_size, frp2->fr_win);
- 	*dirp = 'h';
-     }
- #endif
-@@ -3334,7 +3415,7 @@
-      * Don't execute autocommands while creating the tab pages.  Must do that
-      * when putting the buffers in the windows.
-      */
--    ++autocmd_block;
-+    block_autocmds();
- #endif
- 
-     for (todo = count - 1; todo > 0; --todo)
-@@ -3342,7 +3423,7 @@
- 	    break;
- 
- #ifdef FEAT_AUTOCMD
--    --autocmd_block;
-+    unblock_autocmds();
- #endif
- 
-     /* return actual number of tab pages */
-@@ -4081,7 +4162,7 @@
- 	/* Don't execute autocommands while the window is not properly
- 	 * initialized yet.  gui_create_scrollbar() may trigger a FocusGained
- 	 * event. */
--	++autocmd_block;
-+	block_autocmds();
- #endif
- 	/*
- 	 * link the window in the window list
-@@ -4126,7 +4207,11 @@
- 	foldInitWin(newwin);
- #endif
- #ifdef FEAT_AUTOCMD
--	--autocmd_block;
-+	unblock_autocmds();
-+#endif
-+#ifdef FEAT_SEARCH_EXTRA
-+	newwin->w_match_head = NULL;
-+	newwin->w_next_match_id = 4;
- #endif
-     }
-     return newwin;
-@@ -4147,7 +4232,7 @@
- #ifdef FEAT_AUTOCMD
-     /* Don't execute autocommands while the window is halfway being deleted.
-      * gui_mch_destroy_scrollbar() may trigger a FocusGained event. */
--    ++autocmd_block;
-+    block_autocmds();
- #endif
- 
- #ifdef FEAT_MZSCHEME
-@@ -4185,11 +4270,11 @@
- 	vim_free(wp->w_tagstack[i].tagname);
- 
-     vim_free(wp->w_localdir);
-+
- #ifdef FEAT_SEARCH_EXTRA
--    vim_free(wp->w_match[0].regprog);
--    vim_free(wp->w_match[1].regprog);
--    vim_free(wp->w_match[2].regprog);
-+    clear_matches(wp);
- #endif
-+
- #ifdef FEAT_JUMPLIST
-     free_jumplist(wp);
- #endif
-@@ -4210,7 +4295,7 @@
-     vim_free(wp);
- 
- #ifdef FEAT_AUTOCMD
--    --autocmd_block;
-+    unblock_autocmds();
- #endif
- }
- 
-@@ -5438,6 +5523,7 @@
- 		{
- 		    EMSG(_(e_noroom));
- 		    p_ch = old_p_ch;
-+		    curtab->tp_ch_used = p_ch;
- 		    cmdline_row = Rows - p_ch;
- 		    break;
- 		}
-@@ -6174,3 +6260,175 @@
-     return FALSE;
- }
- #endif
-+
-+#if defined(FEAT_SEARCH_EXTRA) || defined(PROTO)
-+/*
-+ * Add match to the match list of window 'wp'.  The pattern 'pat' will be
-+ * highligted with the group 'grp' with priority 'prio'.
-+ * Optionally, a desired ID 'id' can be specified (greater than or equal to 1).
-+ * If no particular ID is desired, -1 must be specified for 'id'.
-+ * Return ID of added match, -1 on failure.
-+ */
-+    int
-+match_add(wp, grp, pat, prio, id)
-+    win_T	*wp;
-+    char_u	*grp;
-+    char_u	*pat;
-+    int		prio;
-+    int		id;
-+{
-+    matchitem_T *cur;
-+    matchitem_T *prev;
-+    matchitem_T *m;
-+    int		hlg_id;
-+    regprog_T	*regprog;
-+
-+    if (*grp == NUL || *pat == NUL)
-+	return -1;
-+    if (id < -1 || id == 0)
-+    {
-+	EMSGN("E799: Invalid ID: %ld (must be greater than or equal to 1)", id);
-+	return -1;
-+    }
-+    if (id != -1)
-+    {
-+	cur = wp->w_match_head;
-+	while (cur != NULL)
-+	{
-+	    if (cur->id == id)
-+	    {
-+		EMSGN("E801: ID already taken: %ld", id);
-+		return -1;
-+	    }
-+	    cur = cur->next;
-+	}
-+    }
-+    if ((hlg_id = syn_namen2id(grp, STRLEN(grp))) == 0)
-+    {
-+	EMSG2(_(e_nogroup), grp);
-+	return -1;
-+    }
-+    if ((regprog = vim_regcomp(pat, RE_MAGIC)) == NULL)
-+    {
-+	EMSG2(_(e_invarg2), pat);
-+	return -1;
-+    }
-+
-+    /* Find available match ID. */
-+    while (id == -1)
-+    {
-+	cur = wp->w_match_head;
-+	while (cur != NULL && cur->id != wp->w_next_match_id)
-+	    cur = cur->next;
-+	if (cur == NULL)
-+	    id = wp->w_next_match_id;
-+	wp->w_next_match_id++;
-+    }
-+
-+    /* Build new match. */
-+    m = (matchitem_T *)alloc(sizeof(matchitem_T));
-+    m->id = id;
-+    m->priority = prio;
-+    m->pattern = vim_strsave(pat);
-+    m->hlg_id = hlg_id;
-+    m->match.regprog = regprog;
-+    m->match.rmm_ic = FALSE;
-+    m->match.rmm_maxcol = 0;
-+
-+    /* Insert new match.  The match list is in ascending order with regard to
-+     * the match priorities. */
-+    cur = wp->w_match_head;
-+    prev = cur;
-+    while (cur != NULL && prio >= cur->priority)
-+    {
-+	prev = cur;
-+	cur = cur->next;
-+    }
-+    if (cur == prev)
-+	wp->w_match_head = m;
-+    else
-+	prev->next = m;
-+    m->next = cur;
-+
-+    redraw_later(SOME_VALID);
-+    return id;
-+}
-+
-+/*
-+ * Delete match with ID 'id' in the match list of window 'wp'.
-+ * Print error messages if 'perr' is TRUE.
-+ */
-+    int
-+match_delete(wp, id, perr)
-+    win_T	*wp;
-+    int		id;
-+    int		perr;
-+{
-+    matchitem_T *cur = wp->w_match_head;
-+    matchitem_T *prev = cur;
-+
-+    if (id < 1)
-+    {
-+	if (perr == TRUE)
-+	    EMSGN("E802: Invalid ID: %ld (must be greater than or equal to 1)",
-+									  id);
-+	return -1;
-+    }
-+    while (cur != NULL && cur->id != id)
-+    {
-+	prev = cur;
-+	cur = cur->next;
-+    }
-+    if (cur == NULL)
-+    {
-+	if (perr == TRUE)
-+	    EMSGN("E803: ID not found: %ld", id);
-+	return -1;
-+    }
-+    if (cur == prev)
-+	wp->w_match_head = cur->next;
-+    else
-+	prev->next = cur->next;
-+    vim_free(cur->match.regprog);
-+    vim_free(cur->pattern);
-+    vim_free(cur);
-+    redraw_later(SOME_VALID);
-+    return 0;
-+}
-+
-+/*
-+ * Delete all matches in the match list of window 'wp'.
-+ */
-+    void
-+clear_matches(wp)
-+    win_T	*wp;
-+{
-+    matchitem_T *m;
-+
-+    while (wp->w_match_head != NULL)
-+    {
-+	m = wp->w_match_head->next;
-+	vim_free(wp->w_match_head->match.regprog);
-+	vim_free(wp->w_match_head->pattern);
-+	vim_free(wp->w_match_head);
-+	wp->w_match_head = m;
-+    }
-+    redraw_later(SOME_VALID);
-+}
-+
-+/*
-+ * Get match from ID 'id' in window 'wp'.
-+ * Return NULL if match not found.
-+ */
-+    matchitem_T *
-+get_match(wp, id)
-+    win_T	*wp;
-+    int		id;
-+{
-+    matchitem_T *cur = wp->w_match_head;
-+
-+    while (cur != NULL && cur->id != id)
-+	cur = cur->next;
-+    return cur;
-+}
-+#endif
-diff -Naur vim71.orig/src/xxd/xxd.c vim71/src/xxd/xxd.c
---- vim71.orig/src/xxd/xxd.c	2007-05-07 15:41:57.000000000 -0400
-+++ vim71/src/xxd/xxd.c	2008-06-18 06:54:00.000000000 -0400
-@@ -212,7 +212,7 @@
- 
- #define TRY_SEEK	/* attempt to use lseek, or skip forward by reading */
- #define COLS 256	/* change here, if you ever need more columns */
--#define LLEN (9 + (5*COLS-1)/2 + 2 + COLS)
-+#define LLEN (11 + (9*COLS-1)/1 + COLS + 2)
- 
- char hexxa[] = "0123456789abcdef0123456789ABCDEF", *hexx = hexxa;
- 
-@@ -590,7 +590,8 @@
-       default:			octspergrp = 0; break;
-       }
- 
--  if (cols < 1 || (!hextype && (cols > COLS)))
-+  if (cols < 1 || ((hextype == HEX_NORMAL || hextype == HEX_BITS)
-+							    && (cols > COLS)))
-     {
-       fprintf(stderr, "%s: invalid number of columns (max. %d).\n", pname, COLS);
-       exit(1);
-@@ -750,6 +751,7 @@
- 	}
-       if (ebcdic)
- 	e = (e < 64) ? '.' : etoa64[e-64];
-+      /* When changing this update definition of LLEN above. */
-       l[11 + (grplen * cols - 1)/octspergrp + p] =
- #ifdef __MVS__
- 	  (e >= 64)
