Submitted By: Jim Gifford (jim at cross-lfs dot org)
Date: 03-12-2009
Initial Package Version: 7.2
Origin: Upstream
Upstream Status: Applied
Description: Contains all upstream patches up to 7.2.141
             The following patches were skipped
             007 036 041 049 071 072 074 088 089 093 101 138

diff -Naur vim72.orig/Filelist vim72/Filelist
--- vim72.orig/Filelist	2008-07-06 11:02:23.000000000 -0700
+++ vim72/Filelist	2009-03-12 11:54:40.397486521 -0700
@@ -285,6 +285,7 @@
 		src/proto/os_win32.pro \
 		src/proto/os_mswin.pro \
 		src/testdir/Make_dos.mak \
+		src/testdir/Make_ming.mak \
 		src/testdir/dos.vim \
 		src/uninstal.c \
 		src/vim.def \
diff -Naur vim72.orig/runtime/doc/cmdline.txt vim72/runtime/doc/cmdline.txt
--- vim72.orig/runtime/doc/cmdline.txt	2008-08-09 07:22:59.000000000 -0700
+++ vim72/runtime/doc/cmdline.txt	2009-03-12 11:54:40.529493784 -0700
@@ -1,4 +1,4 @@
-*cmdline.txt*   For Vim version 7.2.  Last change: 2008 Jul 29
+*cmdline.txt*   For Vim version 7.2.  Last change: 2008 Sep 18
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -157,6 +157,11 @@
 				(doesn't work at the expression prompt; some
 				things such as changing the buffer or current
 				window are not allowed to avoid side effects)
+				When the result is a |List| the items are used
+				as lines.  They can have line breaks inside
+				too.
+				When the result is a Float it's automatically
+				converted to a String.
 		See |registers| about registers.  {not in Vi}
 		Implementation detail: When using the |expression| register
 		and invoking setcmdpos(), this sets the position before
@@ -730,19 +735,29 @@
 In Ex commands, at places where a file name can be used, the following
 characters have a special meaning.  These can also be used in the expression
 function expand() |expand()|.
-	%	is replaced with the current file name			*:_%*
-	#	is replaced with the alternate file name		*:_#*
+	%	Is replaced with the current file name.		  *:_%* *c_%*
+	#	Is replaced with the alternate file name.	  *:_#* *c_#*
 	#n	(where n is a number) is replaced with the file name of
-		buffer n.  "#0" is the same as "#"
-	##	is replaced with all names in the argument list		*:_##*
+		buffer n.  "#0" is the same as "#".
+	##	Is replaced with all names in the argument list	  *:_##* *c_##*
 		concatenated, separated by spaces.  Each space in a name
 		is preceded with a backslash.
-Note that these give the file name as it was typed.  If an absolute path is
-needed (when using the file name from a different directory), you need to add
-":p".  See |filename-modifiers|.
+	#<n	(where n is a number > 0) is replaced with old	  *:_#<* *c_#<*
+		file name n.  See |:oldfiles| or |v:oldfiles| to get the
+		number.							*E809*
+		{only when compiled with the +eval and +viminfo features}
+
+Note that these, except "#<n", give the file name as it was typed.  If an
+absolute path is needed (when using the file name from a different directory),
+you need to add ":p".  See |filename-modifiers|.
+
+The "#<n" item returns an absolute path, but it will start with "~/" for files
+below your home directory.
+
 Note that backslashes are inserted before spaces, so that the command will
 correctly interpret the file name.  But this doesn't happen for shell
-commands.  For those you probably have to use quotes: >
+commands.  For those you probably have to use quotes (this fails for files
+that contain a quote and wildcards): >
 	:!ls "%"
 	:r !spell "%"
 
diff -Naur vim72.orig/runtime/doc/eval.txt vim72/runtime/doc/eval.txt
--- vim72.orig/runtime/doc/eval.txt	2008-08-09 07:22:59.000000000 -0700
+++ vim72/runtime/doc/eval.txt	2009-03-12 11:54:50.318122364 -0700
@@ -1,4 +1,4 @@
-*eval.txt*	For Vim version 7.2.  Last change: 2008 Aug 09
+*eval.txt*	For Vim version 7.2.  Last change: 2008 Nov 27
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -1484,6 +1484,17 @@
 		This is the screen column number, like with |virtcol()|.  The
 		value is zero when there was no mouse button click.
 
+					*v:oldfiles* *oldfiles-variable*
+v:oldfiles	List of file names that is loaded from the |viminfo| file on
+		startup.  These are the files that Vim remembers marks for.
+		The length of the List is limited by the ' argument of the
+		'viminfo' option (default is 100).
+		Also see |:oldfiles| and |c_#<|.
+		The List can be modified, but this has no effect on what is
+		stored in the |viminfo| file later.  If you use values other
+		than String this will cause trouble.
+		{only when compiled with the +viminfo feature}
+
 					*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>,
@@ -1695,7 +1706,7 @@
 exists( {expr})			Number	TRUE if {expr} exists
 extend({expr1}, {expr2} [, {expr3}])
 				List/Dict insert items of {expr2} into {expr1}
-expand( {expr})			String	expand special keywords in {expr}
+expand( {expr} [, {flag}])	String	expand special keywords in {expr}
 feedkeys( {string} [, {mode}])	Number	add key sequence to typeahead buffer
 filereadable( {file})		Number	TRUE if {file} is a readable file
 filewritable( {file})		Number	TRUE if {file} is a writable file
@@ -1747,8 +1758,9 @@
 getwinposx()			Number	X coord in pixels of GUI Vim window
 getwinposy()			Number	Y coord in pixels of GUI Vim window
 getwinvar( {nr}, {varname})	any	variable {varname} in window {nr}
-glob( {expr})			String	expand file wildcards in {expr}
-globpath( {path}, {expr})	String	do glob({expr}) for all dirs in {path}
+glob( {expr} [, {flag}])	String	expand file wildcards in {expr}
+globpath( {path}, {expr} [, {flag}])
+				String	do glob({expr}) for all dirs in {path}
 has( {feature})			Number	TRUE if feature {feature} supported
 has_key( {dict}, {key})		Number	TRUE if {dict} has entry {key}
 haslocaldir()			Number	TRUE if current window executed |:lcd|
@@ -3275,14 +3287,16 @@
 			:let list_is_on = getwinvar(2, '&list')
 			:echo "myvar = " . getwinvar(1, 'myvar')
 <
-							*glob()*
-glob({expr})	Expand the file wildcards in {expr}.  See |wildcards| for the
+glob({expr} [, {flag}])					*glob()*
+		Expand the file wildcards in {expr}.  See |wildcards| for the
 		use of special characters.
 		The result is a String.
 		When there are several matches, they are separated by <NL>
 		characters.
-		The 'wildignore' option applies: Names matching one of the
-		patterns in 'wildignore' will be skipped.
+		Unless the optional {flag} argument is given and is non-zero,
+		the 'suffixes' and 'wildignore' options apply: Names matching
+		one of the patterns in 'wildignore' will be skipped and
+		'suffixes' affect the ordering of matches.
 		If the expansion fails, the result is an empty string.
 		A name for a non-existing file is not included.
 
@@ -3296,20 +3310,22 @@
 		See |expand()| for expanding special Vim variables.  See
 		|system()| for getting the raw output of an external command.
 
-globpath({path}, {expr})				*globpath()*
+globpath({path}, {expr} [, {flag}])			*globpath()*
 		Perform glob() on all directories in {path} and concatenate
 		the results.  Example: >
 			:echo globpath(&rtp, "syntax/c.vim")
 <		{path} is a comma-separated list of directory names.  Each
 		directory name is prepended to {expr} and expanded like with
-		glob().  A path separator is inserted when needed.
+		|glob()|.  A path separator is inserted when needed.
 		To add a comma inside a directory name escape it with a
 		backslash.  Note that on MS-Windows a directory may have a
 		trailing backslash, remove it if you put a comma after it.
 		If the expansion fails for one of the directories, there is no
 		error message.
-		The 'wildignore' option applies: Names matching one of the
-		patterns in 'wildignore' will be skipped.
+		Unless the optional {flag} argument is given and is non-zero,
+		the 'suffixes' and 'wildignore' options apply: Names matching
+		one of the patterns in 'wildignore' will be skipped and
+		'suffixes' affect the ordering of matches.
 
 		The "**" item can be used to search in a directory tree.
 		For example, to find all "README.txt" files in the directories
@@ -5332,10 +5348,12 @@
 		"fg"		foreground color (GUI: color name used to set
 				the color, cterm: color number as a string,
 				term: empty string)
-		"bg"		background color (like "fg")
+		"bg"		background color (as with "fg")
+		"sp"		special color (as with "fg") |highlight-guisp|
 		"fg#"		like "fg", but for the GUI and the GUI is
 				running the name in "#RRGGBB" form
 		"bg#"		like "fg#" for "bg"
+		"sp#"		like "fg#" for "sp"
 		"bold"		"1" if bold
 		"italic"	"1" if italic
 		"reverse"	"1" if reverse
@@ -5823,7 +5841,8 @@
 mouse_pterm		Compiled with support for qnx pterm mouse.
 mouse_sysmouse		Compiled with support for sysmouse (*BSD console mouse)
 mouse_xterm		Compiled with support for xterm mouse.
-multi_byte		Compiled with support for editing Korean et al.
+multi_byte		Compiled with support for 'encoding'
+multi_byte_encoding	'encoding' is set to a multi-byte encoding.
 multi_byte_ime		Compiled with support for IME input method.
 multi_lang		Compiled with support for multiple languages.
 mzscheme		Compiled with MzScheme interface |mzscheme|.
diff -Naur vim72.orig/runtime/doc/netbeans.txt vim72/runtime/doc/netbeans.txt
--- vim72.orig/runtime/doc/netbeans.txt	2008-08-09 07:22:59.000000000 -0700
+++ vim72/runtime/doc/netbeans.txt	2009-03-12 11:54:59.850731108 -0700
@@ -1,4 +1,4 @@
-*netbeans.txt*  For Vim version 7.2.  Last change: 2008 Jun 28
+*netbeans.txt*  For Vim version 7.2.  Last change: 2009 Jan 06
 
 
 		  VIM REFERENCE MANUAL    by Gordon Prieur et al.
@@ -722,8 +722,10 @@
 		of the cursor.
 		New in version 2.1.
 
-killed		A file was closed by the user.  Only for files that have been
-		assigned a number by the IDE.
+killed		A file was deleted or wiped out by the user and the buffer
+		annotations have been removed.  The bufID number for this
+		buffer has become invalid.  Only for files that have been
+		assigned a bufID number by the IDE.
 
 newDotAndMark off off
 		Reports the position of the cursor being at "off" bytes into
diff -Naur vim72.orig/runtime/doc/options.txt vim72/runtime/doc/options.txt
--- vim72.orig/runtime/doc/options.txt	2008-08-09 07:22:59.000000000 -0700
+++ vim72/runtime/doc/options.txt	2009-03-12 11:55:13.407601900 -0700
@@ -1,4 +1,4 @@
-*options.txt*	For Vim version 7.2.  Last change: 2008 Aug 06
+*options.txt*	For Vim version 7.2.  Last change: 2008 Nov 25
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -4175,9 +4175,6 @@
 	be able to execute Normal mode commands.
 	This is the opposite of the 'keymap' option, where characters are
 	mapped in Insert mode.
-	This only works for 8-bit characters.  The value of 'langmap' may be
-	specified with multi-byte characters (e.g., UTF-8), but only the lower
-	8 bits of each character will be used.
 
 	Example (for Greek, in UTF-8):				*greek*  >
 	    :set langmap=ΑA,ΒB,ΨC,ΔD,ΕE,ΦF,ΓG,ΗH,ΙI,ΞJ,ΚK,ΛL,ΜM,ΝN,ΟO,ΠP,QQ,ΡR,ΣS,ΤT,ΘU,ΩV,WW,ΧX,ΥY,ΖZ,αa,βb,ψc,δd,εe,φf,γg,ηh,ιi,ξj,κk,λl,μm,νn,οo,πp,qq,ρr,σs,τt,θu,ωv,ςw,χx,υy,ζz
@@ -7472,7 +7469,9 @@
 			{not available when compiled without the |+wildignore|
 			feature}
 	A list of file patterns.  A file that matches with one of these
-	patterns is ignored when completing file or directory names.
+	patterns is ignored when completing file or directory names, and
+	influences the result of |expand()|, |glob()| and |globpath()| unless
+	a flag is passed to disable this.
 	The pattern is used like with |:autocmd|, see |autocmd-patterns|.
 	Also see 'suffixes'.
 	Example: >
diff -Naur vim72.orig/runtime/doc/spell.txt vim72/runtime/doc/spell.txt
--- vim72.orig/runtime/doc/spell.txt	2008-08-09 07:23:00.000000000 -0700
+++ vim72/runtime/doc/spell.txt	2009-03-12 11:54:50.218113983 -0700
@@ -1,4 +1,4 @@
-*spell.txt*	For Vim version 7.2.  Last change: 2008 Jun 21
+*spell.txt*	For Vim version 7.2.  Last change: 2008 Nov 30
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -831,8 +831,11 @@
 
 	# comment line ~
 
-With some items it's also possible to put a comment after it, but this isn't
-supported in general.
+Items with a fixed number of arguments can be followed by a comment.  But only
+if none of the arguments can contain white space.  The comment must start with
+a "#" character.  Example:
+
+	KEEPCASE =  # fix case for words with this flag ~
 
 
 ENCODING							*spell-SET*
@@ -965,6 +968,9 @@
 
 Note: When using utf-8 only characters up to 65000 may be used for flags.
 
+Note: even when using "num" or "long" the number of flags available to
+compounding and prefixes is limited to about 250.
+
 
 AFFIXES
 					    *spell-PFX* *spell-SFX*
@@ -1178,6 +1184,9 @@
 The flag also applies to the word with affixes, thus this can be used to mark
 a whole bunch of related words as bad.
 
+							*spell-FORBIDDENWORD*
+FORBIDDENWORD can be used just like BAD.  For compatibility with Hunspell.
+
 							*spell-NEEDAFFIX*
 The NEEDAFFIX flag is used to require that a word is used with an affix.  The
 word itself is not a good word (unless there is an empty affix).  Example:
@@ -1268,6 +1277,10 @@
 
 	NEEDCOMPOUND & ~
 
+							*spell-ONLYINCOMPOUND*
+The ONLYINCOMPOUND does exactly the same as NEEDCOMPOUND.  Supported for
+compatiblity with Hunspell.
+
 							*spell-COMPOUNDMIN*
 The minimal character length of a word used for compounding is specified with
 COMPOUNDMIN.  Example:
@@ -1328,6 +1341,20 @@
 rules.  Can also be used for an affix to count the affix as a compounding
 word.
 
+						*spell-CHECKCOMPOUNDPATTERN*
+CHECKCOMPOUNDPATTERN is used to define patterns that, when matching at the
+position where two words are compounded together forbids the compound.
+For example:
+	CHECKCOMPOUNDPATTERN o e ~
+
+This forbids compounding if the first word ends in "o" and the second word
+starts with "e".
+
+The arguments must be plain text, no patterns are actually supported, despite
+the item name.  Case is always ignored.
+
+The Hunspell feature to use three arguments and flags is not supported.
+
 							*spell-SYLLABLE*
 The SYLLABLE item defines characters or character sequences that are used to
 count the number of syllables in a word.  Example:
@@ -1496,6 +1523,10 @@
 ACCENT		(Hunspell)				*spell-ACCENT*
 		Use MAP instead. |spell-MAP|
 
+BREAK		(Hunspell)				*spell-BREAK*
+		Define break points.  Unclear how it works exactly.
+		Not supported.
+
 CHECKCOMPOUNDCASE  (Hunspell)			*spell-CHECKCOMPOUNDCASE*
 		Disallow uppercase letters at compound word boundaries.
 		Not supported.
@@ -1512,9 +1543,6 @@
 		Forbid three identical characters when compounding.  Not
 		supported.
 
-CHECKCOMPOUNDPATTERN  (Hunspell)		*spell-CHECKCOMPOUNDPATTERN*
-		Forbid compounding when patterns match.  Not supported.
-
 COMPLEXPREFIXES  (Hunspell)				*spell-COMPLEXPREFIXES*
 		Enables using two prefixes.  Not supported.
 
@@ -1536,13 +1564,18 @@
 COMPOUNDMIDDLE	(Hunspell)				*spell-COMPOUNDMIDDLE*
 		Use COMPOUNDRULE instead. |spell-COMPOUNDRULE|
 
+COMPOUNDRULES	(Hunspell)				*spell-COMPOUNDRULES*
+		Number of COMPOUNDRULE lines following.  Ignored, but the
+		argument must be a number.
+
 COMPOUNDSYLLABLE  (Hunspell)			*spell-COMPOUNDSYLLABLE*
 		Use SYLLABLE and COMPOUNDSYLMAX instead. |spell-SYLLABLE|
 		|spell-COMPOUNDSYLMAX|
 
-FORBIDDENWORD	(Hunspell)				*spell-FORBIDDENWORD*
-		Use BAD instead. |spell-BAD|
-
+KEY		(Hunspell)				*spell-KEY*
+		Define characters that are close together on the keyboard.
+		Used to give better suggestions.  Not supported.
+		
 LANG		(Hunspell)				*spell-LANG*
 		This specifies language-specific behavior.  This actually
 		moves part of the language knowledge into the program,
@@ -1553,10 +1586,7 @@
 		Only needed for morphological analysis.
 
 MAXNGRAMSUGS	(Hunspell)				*spell-MAXNGRAMSUGS*
-		Not supported.
-
-ONLYINCOMPOUND	(Hunspell)				*spell-ONLYINCOMPOUND*
-		Use NEEDCOMPOUND instead. |spell-NEEDCOMPOUND|
+		Set number of n-gram suggestions.  Not supported.
 
 PSEUDOROOT	(Hunspell)				*spell-PSEUDOROOT*
 		Use NEEDAFFIX instead. |spell-NEEDAFFIX|
diff -Naur vim72.orig/runtime/doc/starting.txt vim72/runtime/doc/starting.txt
--- vim72.orig/runtime/doc/starting.txt	2008-08-09 07:23:00.000000000 -0700
+++ vim72/runtime/doc/starting.txt	2009-03-12 11:54:40.533495740 -0700
@@ -1,4 +1,4 @@
-*starting.txt*  For Vim version 7.2.  Last change: 2008 Jun 21
+*starting.txt*  For Vim version 7.2.  Last change: 2008 Nov 09
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1337,8 +1337,9 @@
 							*viminfo-read*
 When Vim is started and the 'viminfo' option is non-empty, the contents of
 the viminfo file are read and the info can be used in the appropriate places.
-The marks are not read in at startup (but file marks are).  See
-|initialization| for how to set the 'viminfo' option upon startup.
+The |v:oldfiles| variable is filled.  The marks are not read in at startup
+(but file marks are).  See |initialization| for how to set the 'viminfo'
+option upon startup.
 
 							*viminfo-write*
 When Vim exits and 'viminfo' is non-empty, the info is stored in the viminfo
@@ -1372,6 +1373,8 @@
 that start with any string given with the "r" flag in 'viminfo'.  This can be
 used to avoid saving marks for files on removable media (for MS-DOS you would
 use "ra:,rb:", for Amiga "rdf0:,rdf1:,rdf2:").
+The |v:oldfiles| variable is filled with the file names that the viminfo file
+has marks for.
 
 							*viminfo-file-marks*
 Uppercase marks ('A to 'Z) are stored when writing the viminfo file.  The
@@ -1463,8 +1466,8 @@
 						   *:rv* *:rviminfo* *E195*
 :rv[iminfo][!] [file]	Read from viminfo file [file] (default: see above).
 			If [!] is given, then any information that is
-			already set (registers, marks, etc.) will be
-			overwritten.  {not in Vi}
+			already set (registers, marks, |v:oldfiles|, etc.)
+			will be overwritten   {not in Vi}
 
 					*:wv* *:wviminfo* *E137* *E138* *E574*
 :wv[iminfo][!] [file]	Write to viminfo file [file] (default: see above).
@@ -1479,4 +1482,20 @@
 			the .viminfo file.
 			{not in Vi}
 
+						*:ol* *:oldfiles*
+:ol[dfiles]		List the files that have marks stored in the viminfo
+			file.  This list is read on startup and only changes
+			afterwards with ":rviminfo!".  Also see |v:oldfiles|.
+			The number can be used with |c_#<|.
+			{not in Vi, only when compiled with the +eval feature}
+
+:bro[wse] ol[dfiles][!]
+			List file names as with |:oldfiles|, and then prompt
+			for a number.  When the number is valid that file from
+			the list is edited.
+			If you get the |press-enter| prompt you can press "q"
+			and still get the prompt to enter a file number.
+			Use ! to abondon a modified buffer. |abandon|
+			{not when compiled with tiny or small features}
+
  vim:tw=78:ts=8:ft=help:norl:
diff -Naur vim72.orig/runtime/doc/usr_21.txt vim72/runtime/doc/usr_21.txt
--- vim72.orig/runtime/doc/usr_21.txt	2008-08-09 07:23:01.000000000 -0700
+++ vim72/runtime/doc/usr_21.txt	2009-03-12 11:54:40.533495740 -0700
@@ -1,4 +1,4 @@
-*usr_21.txt*	For Vim version 7.2.  Last change: 2007 May 01
+*usr_21.txt*	For Vim version 7.2.  Last change: 2008 Nov 09
 
 		     VIM USER MANUAL - by Bram Moolenaar
 
@@ -153,7 +153,7 @@
 to be lost.  Each item can be remembered only once.
 
 
-GETTING BACK TO WHERE YOU WERE
+GETTING BACK TO WHERE YOU STOPPED VIM
 
 You are halfway editing a file and it's time to leave for holidays.  You exit
 Vim and go enjoy yourselves, forgetting all about your work.  After a couple
@@ -168,6 +168,48 @@
    The |:marks| command is useful to find out where '0 to '9 will take you.
 
 
+GETTING BACK TO SOME FILE
+
+If you want to go back to a file that you edited recently, but not when
+exiting Vim, there is a slightly more complicated way.  You can see a list of
+files by typing the command: >
+
+	:oldfiles
+<	1: ~/.viminfo ~
+	2: ~/text/resume.txt ~
+	3: /tmp/draft ~
+
+Now you would like to edit the second file, which is in the list preceded by
+"2:".  You type: >
+
+	:e #<2
+
+Instead of ":e" you can use any command that has a file name argument, the
+"#<2" item works in the same place as "%" (current file name) and "#"
+(alternate file name).  So you can also split the window to edit the third
+file: >
+
+	:split #<3
+
+That #<123 thing is a bit complicated when you just want to edit a file.
+Fortunately there is a simpler way: >
+
+	:browse oldfiles
+<	1: ~/.viminfo ~
+	2: ~/text/resume.txt ~
+	3: /tmp/draft ~
+	-- More --
+
+You get the same list of files as with |:oldfiles|.  If you want to edit
+"resume.txt" first press "q" to stop the listing.  You will get a prompt:
+
+	Type number and <Enter> (empty cancels): ~
+
+Type "2" and press <Enter> to edit the second file.
+
+More info at |:oldfiles|, |v:oldfiles| and |c_#<|.
+
+
 MOVE INFO FROM ONE VIM TO ANOTHER
 
 You can use the ":wviminfo" and ":rviminfo" commands to save and restore the
diff -Naur vim72.orig/runtime/scripts.vim vim72/runtime/scripts.vim
--- vim72.orig/runtime/scripts.vim	2008-08-08 15:27:21.000000000 -0700
+++ vim72/runtime/scripts.vim	2009-03-12 11:54:28.900750105 -0700
@@ -234,6 +234,10 @@
   elseif s:line1 =~ '\<DTD\s\+XHTML\s'
     set ft=xhtml
 
+    " HTML (e.g.: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN")
+  elseif s:line1 =~? '\<DOCTYPE\s\+html\>'
+    set ft=html
+
     " PDF
   elseif s:line1 =~ '^%PDF-'
     set ft=pdf
diff -Naur vim72.orig/src/auto/configure vim72/src/auto/configure
--- vim72.orig/src/auto/configure	2008-07-24 05:40:36.000000000 -0700
+++ vim72/src/auto/configure	2009-03-12 11:55:13.667618383 -0700
@@ -11565,6 +11565,67 @@
 
 fi
 
+{ $as_echo "$as_me:$LINENO: checking for working volatile" >&5
+$as_echo_n "checking for working volatile... " >&6; }
+if test "${ac_cv_c_volatile+set}" = set; then
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+volatile int x;
+int * volatile y = (int *) 0;
+return !x && !y;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_c_volatile=yes
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_c_volatile=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_volatile" >&5
+$as_echo "$ac_cv_c_volatile" >&6; }
+if test $ac_cv_c_volatile = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define volatile /**/
+_ACEOF
+
+fi
+
 { $as_echo "$as_me:$LINENO: checking for mode_t" >&5
 $as_echo_n "checking for mode_t... " >&6; }
 if test "${ac_cv_type_mode_t+set}" = set; then
@@ -16819,21 +16880,29 @@
   LDFLAGS="$LDFLAGS -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -arch ppc"
 fi
 
-{ $as_echo "$as_me:$LINENO: checking for GCC 3 or later" >&5
-$as_echo_n "checking for GCC 3 or later... " >&6; }
 DEPEND_CFLAGS_FILTER=
 if test "$GCC" = yes; then
+  { $as_echo "$as_me:$LINENO: checking for GCC 3 or later" >&5
+$as_echo_n "checking for GCC 3 or later... " >&6; }
   gccmajor=`echo "$gccversion" | sed -e 's/^\([1-9]\)\..*$/\1/g'`
   if test "$gccmajor" -gt "2"; then
     DEPEND_CFLAGS_FILTER="| sed 's+-I */+-isystem /+g'"
-  fi
-fi
-if test "$DEPEND_CFLAGS_FILTER" = ""; then
-  { $as_echo "$as_me:$LINENO: result: no" >&5
+    { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+  else
+    { $as_echo "$as_me:$LINENO: result: no" >&5
 $as_echo "no" >&6; }
-else
-  { $as_echo "$as_me:$LINENO: result: yes" >&5
+  fi
+      { $as_echo "$as_me:$LINENO: checking whether we need -D_FORTIFY_SOURCE=1" >&5
+$as_echo_n "checking whether we need -D_FORTIFY_SOURCE=1... " >&6; }
+  if test "$gccmajor" -gt "3"; then
+    CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=1"
+    { $as_echo "$as_me:$LINENO: result: yes" >&5
 $as_echo "yes" >&6; }
+  else
+    { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+  fi
 fi
 
 
diff -Naur vim72.orig/src/buffer.c vim72/src/buffer.c
--- vim72.orig/src/buffer.c	2008-08-06 04:00:48.000000000 -0700
+++ vim72/src/buffer.c	2009-03-12 11:55:13.507605811 -0700
@@ -437,10 +437,6 @@
 	return;
 #endif
 
-#ifdef FEAT_NETBEANS_INTG
-    if (usingNetbeans)
-	netbeans_file_closed(buf);
-#endif
     /* Change directories when the 'acd' option is set. */
     DO_AUTOCHDIR
 
@@ -639,6 +635,10 @@
 #ifdef FEAT_SIGNS
     buf_delete_signs(buf);		/* delete any signs */
 #endif
+#ifdef FEAT_NETBEANS_INTG
+    if (usingNetbeans)
+        netbeans_file_killed(buf);
+#endif
 #ifdef FEAT_LOCALMAP
     map_clear_int(buf, MAP_ALL_MODES, TRUE, FALSE);  /* clear local mappings */
     map_clear_int(buf, MAP_ALL_MODES, TRUE, TRUE);   /* clear local abbrevs */
@@ -647,6 +647,9 @@
     vim_free(buf->b_start_fenc);
     buf->b_start_fenc = NULL;
 #endif
+#ifdef FEAT_SPELL
+    ga_clear(&buf->b_langp);
+#endif
 }
 
 /*
@@ -812,9 +815,6 @@
     int		bnr;		/* buffer number */
     char_u	*p;
 
-#ifdef FEAT_NETBEANS_INTG
-    netbeansCloseFile = 1;
-#endif
     if (addr_count == 0)
     {
 	(void)do_buffer(command, DOBUF_CURRENT, FORWARD, 0, forceit);
@@ -909,9 +909,6 @@
 	}
     }
 
-#ifdef FEAT_NETBEANS_INTG
-    netbeansCloseFile = 0;
-#endif
 
     return errormsg;
 }
@@ -1237,7 +1234,7 @@
 	 * "buf" if one exists */
 	if ((swb_flags & SWB_USEOPEN) && buf_jump_open_win(buf))
 	    return OK;
-	/* If 'switchbuf' contians "usetab": jump to first window in any tab
+	/* If 'switchbuf' contains "usetab": jump to first window in any tab
 	 * page containing "buf" if one exists */
 	if ((swb_flags & SWB_USETAB) && buf_jump_open_tab(buf))
 	    return OK;
@@ -1351,11 +1348,12 @@
 	}
     }
 #ifdef FEAT_AUTOCMD
+    /* An autocommand may have deleted "buf", already entered it (e.g., when
+     * it did ":bunload") or aborted the script processing! */
 # ifdef FEAT_EVAL
-    /* An autocommand may have deleted buf or aborted the script processing! */
-    if (buf_valid(buf) && !aborting())
+    if (buf_valid(buf) && buf != curbuf && !aborting())
 # else
-    if (buf_valid(buf))	    /* an autocommand may have deleted buf! */
+    if (buf_valid(buf) && buf != curbuf)
 # endif
 #endif
 	enter_buffer(buf);
@@ -1397,6 +1395,9 @@
     curwin->w_cursor.coladd = 0;
 #endif
     curwin->w_set_curswant = TRUE;
+#ifdef FEAT_AUTOCMD
+    curwin->w_topline_was_set = FALSE;
+#endif
 
     /* Make sure the buffer is loaded. */
     if (curbuf->b_ml.ml_mfp == NULL)	/* need to load the file */
@@ -1436,7 +1437,8 @@
     maketitle();
 #endif
 #ifdef FEAT_AUTOCMD
-    if (curwin->w_topline == 1)		/* when autocmds didn't change it */
+	/* when autocmds didn't change it */
+    if (curwin->w_topline == 1 && !curwin->w_topline_was_set)
 #endif
 	scroll_cursor_halfway(FALSE);	/* redisplay at correct position */
 
@@ -3963,7 +3965,7 @@
     width = vim_strsize(out);
     if (maxwidth > 0 && width > maxwidth)
     {
-	/* Result is too long, must trunctate somewhere. */
+	/* Result is too long, must truncate somewhere. */
 	l = 0;
 	if (itemcnt == 0)
 	    s = out;
@@ -5048,7 +5050,8 @@
 	 */
 	FOR_ALL_TAB_WINDOWS(tp, win)
 	    if (win->w_buffer == buf)
-		break;
+		goto win_found;
+win_found:
 	if (win != NULL && win->w_llist_ref != NULL)
 	    return _("[Location List]");
 	else
@@ -5062,7 +5065,7 @@
     {
 	if (buf->b_sfname != NULL)
 	    return (char *)buf->b_sfname;
-	return "[Scratch]";
+	return _("[Scratch]");
     }
 #endif
     if (buf->b_fname == NULL)
diff -Naur vim72.orig/src/config.h.in vim72/src/config.h.in
--- vim72.orig/src/config.h.in	2008-06-21 08:01:41.000000000 -0700
+++ vim72/src/config.h.in	2009-03-12 11:55:13.667618383 -0700
@@ -50,6 +50,9 @@
 /* Define to empty if the keyword does not work.  */
 #undef const
 
+/* Define to empty if the keyword does not work.  */
+#undef volatile
+
 /* Define to `int' if <sys/types.h> doesn't define.  */
 #undef mode_t
 
diff -Naur vim72.orig/src/configure.in vim72/src/configure.in
--- vim72.orig/src/configure.in	2008-07-24 05:40:26.000000000 -0700
+++ vim72/src/configure.in	2009-03-12 11:55:13.667618383 -0700
@@ -2148,6 +2148,7 @@
 dnl Checks for typedefs, structures, and compiler characteristics.
 AC_PROG_GCC_TRADITIONAL
 AC_C_CONST
+AC_C_VOLATILE
 AC_TYPE_MODE_T
 AC_TYPE_OFF_T
 AC_TYPE_PID_T
@@ -3152,18 +3153,25 @@
 dnl But only when making dependencies, cproto and lint don't take "-isystem".
 dnl Mac gcc returns "powerpc-apple-darwin8-gcc-4.0.1 (GCC)...", need to allow
 dnl the number before the version number.
-AC_MSG_CHECKING(for GCC 3 or later)
 DEPEND_CFLAGS_FILTER=
 if test "$GCC" = yes; then
+  AC_MSG_CHECKING(for GCC 3 or later)
   gccmajor=`echo "$gccversion" | sed -e 's/^\([[1-9]]\)\..*$/\1/g'`
   if test "$gccmajor" -gt "2"; then
     DEPEND_CFLAGS_FILTER="| sed 's+-I */+-isystem /+g'"
+    AC_MSG_RESULT(yes)
+  else
+    AC_MSG_RESULT(no)
+  fi
+  dnl -D_FORTIFY_SOURCE=2 crashes Vim on strcpy(buf, "000") when buf is
+  dnl declared as char x[1] but actually longer.  Introduced in gcc 4.0.
+  AC_MSG_CHECKING(whether we need -D_FORTIFY_SOURCE=1)
+  if test "$gccmajor" -gt "3"; then
+    CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=1"
+    AC_MSG_RESULT(yes)
+  else
+    AC_MSG_RESULT(no)
   fi
-fi
-if test "$DEPEND_CFLAGS_FILTER" = ""; then
-  AC_MSG_RESULT(no)
-else
-  AC_MSG_RESULT(yes)
 fi
 AC_SUBST(DEPEND_CFLAGS_FILTER)
 
diff -Naur vim72.orig/src/diff.c vim72/src/diff.c
--- vim72.orig/src/diff.c	2008-03-05 03:16:56.000000000 -0800
+++ vim72/src/diff.c	2009-03-12 11:55:16.155775667 -0700
@@ -8,7 +8,7 @@
  */
 
 /*
- * diff.c: code for diff'ing two or three buffers.
+ * diff.c: code for diff'ing two, three or four buffers.
  */
 
 #include "vim.h"
@@ -73,6 +73,8 @@
 	{
 	    tp->tp_diffbuf[i] = NULL;
 	    tp->tp_diff_invalid = TRUE;
+	    if (tp == curtab)
+		diff_redraw(TRUE);
 	}
     }
 }
@@ -102,6 +104,7 @@
 	    {
 		curtab->tp_diffbuf[i] = NULL;
 		curtab->tp_diff_invalid = TRUE;
+		diff_redraw(TRUE);
 	    }
 	}
     }
@@ -113,7 +116,7 @@
  * Add a buffer to make diffs for.
  * Call this when a new buffer is being edited in the current window where
  * 'diff' is set.
- * Marks the current buffer as being part of the diff and requireing updating.
+ * Marks the current buffer as being part of the diff and requiring updating.
  * This must be done before any autocmd, because a command may use info
  * about the screen contents.
  */
@@ -131,6 +134,7 @@
 	{
 	    curtab->tp_diffbuf[i] = buf;
 	    curtab->tp_diff_invalid = TRUE;
+	    diff_redraw(TRUE);
 	    return;
 	}
 
@@ -661,6 +665,7 @@
     char_u	*tmp_diff;
     FILE	*fd;
     int		ok;
+    int		io_error = FALSE;
 
     /* Delete all diffblocks. */
     diff_clear(curtab);
@@ -697,18 +702,26 @@
     {
 	ok = FALSE;
 	fd = mch_fopen((char *)tmp_orig, "w");
-	if (fd != NULL)
+	if (fd == NULL)
+	    io_error = TRUE;
+	else
 	{
-	    fwrite("line1\n", (size_t)6, (size_t)1, fd);
+	    if (fwrite("line1\n", (size_t)6, (size_t)1, fd) != 1)
+		io_error = TRUE;
 	    fclose(fd);
 	    fd = mch_fopen((char *)tmp_new, "w");
-	    if (fd != NULL)
+	    if (fd == NULL)
+		io_error = TRUE;
+	    else
 	    {
-		fwrite("line2\n", (size_t)6, (size_t)1, fd);
+		if (fwrite("line2\n", (size_t)6, (size_t)1, fd) != 1)
+		    io_error = TRUE;
 		fclose(fd);
 		diff_file(tmp_orig, tmp_new, tmp_diff);
 		fd = mch_fopen((char *)tmp_diff, "r");
-		if (fd != NULL)
+		if (fd == NULL)
+		    io_error = TRUE;
+		else
 		{
 		    char_u	linebuf[LBUFLEN];
 
@@ -761,6 +774,8 @@
     }
     if (!ok)
     {
+	if (io_error)
+	    EMSG(_("E810: Cannot read or write temp files"));
 	EMSG(_("E97: Cannot create diffs"));
 	diff_a_works = MAYBE;
 #if defined(MSWIN) || defined(MSDOS)
@@ -914,7 +929,7 @@
 	goto theend;
 
 #ifdef UNIX
-    /* Temporaraly chdir to /tmp, to avoid patching files in the current
+    /* Temporarily chdir to /tmp, to avoid patching files in the current
      * directory when the patch file contains more than one patch.  When we
      * have our own temp dir use that instead, it will be cleaned up when we
      * exit (any .rej files created).  Don't change directory if we can't
@@ -925,10 +940,10 @@
     {
 # ifdef TEMPDIRNAMES
 	if (vim_tempdir != NULL)
-	    mch_chdir((char *)vim_tempdir);
+	    ignored = mch_chdir((char *)vim_tempdir);
 	else
 # endif
-	    mch_chdir("/tmp");
+	    ignored = mch_chdir("/tmp");
 	shorten_fnames(TRUE);
     }
 #endif
@@ -1138,7 +1153,7 @@
 
     for (wp = firstwin; wp != NULL; wp = wp->w_next)
     {
-	if (wp == curwin || eap->forceit)
+	if (wp == curwin || (eap->forceit && wp->w_p_diff))
 	{
 	    /* Set 'diff', 'scrollbind' off and 'wrap' on. */
 	    wp->w_p_diff = FALSE;
@@ -2114,6 +2129,8 @@
 	    EMSG2(_("E102: Can't find buffer \"%s\""), eap->arg);
 	    return;
 	}
+	if (buf == curbuf)
+	    return;		/* nothing to do */
 	idx_other = diff_buf_idx(buf);
 	if (idx_other == DB_COUNT)
 	{
diff -Naur vim72.orig/src/edit.c vim72/src/edit.c
--- vim72.orig/src/edit.c	2008-08-06 05:51:17.000000000 -0700
+++ vim72/src/edit.c	2009-03-12 11:55:13.411601900 -0700
@@ -147,6 +147,7 @@
 static int  ins_compl_bs __ARGS((void));
 static void ins_compl_new_leader __ARGS((void));
 static void ins_compl_addleader __ARGS((int c));
+static int ins_compl_len __ARGS((void));
 static void ins_compl_restart __ARGS((void));
 static void ins_compl_set_original_text __ARGS((char_u *str));
 static void ins_compl_addfrommatch __ARGS((void));
@@ -197,7 +198,8 @@
 static void mb_replace_pop_ins __ARGS((int cc));
 #endif
 static void replace_flush __ARGS((void));
-static void replace_do_bs __ARGS((void));
+static void replace_do_bs __ARGS((int limit_col));
+static int del_char_after_col __ARGS((int limit_col));
 #ifdef FEAT_CINDENT
 static int cindent_on __ARGS((void));
 #endif
@@ -1933,6 +1935,8 @@
 /*
  * Backspace the cursor until the given column.  Handles REPLACE and VREPLACE
  * modes correctly.  May also be used when not in insert mode at all.
+ * Will attempt not to go before "col" even when there is a composing
+ * character.
  */
     void
 backspace_until_column(col)
@@ -1942,13 +1946,50 @@
     {
 	curwin->w_cursor.col--;
 	if (State & REPLACE_FLAG)
-	    replace_do_bs();
-	else
-	    (void)del_char(FALSE);
+	    replace_do_bs(col);
+	else if (!del_char_after_col(col))
+	    break;
     }
 }
 #endif
 
+/*
+ * Like del_char(), but make sure not to go before column "limit_col".
+ * Only matters when there are composing characters.
+ * Return TRUE when something was deleted.
+ */
+/*ARGSUSED*/
+   static int
+del_char_after_col(limit_col)
+    int limit_col;
+{
+#ifdef FEAT_MBYTE
+    if (enc_utf8 && limit_col >= 0)
+    {
+	int ecol = curwin->w_cursor.col + 1;
+
+	/* Make sure the cursor is at the start of a character, but
+	 * skip forward again when going too far back because of a
+	 * composing character. */
+	mb_adjust_cursor();
+	while (curwin->w_cursor.col < (colnr_T)limit_col)
+	{
+	    int l = utf_ptr2len(ml_get_cursor());
+
+	    if (l == 0)  /* end of line */
+		break;
+	    curwin->w_cursor.col += l;
+	}
+	if (*ml_get_cursor() == NUL || curwin->w_cursor.col == ecol)
+	    return FALSE;
+	del_bytes((long)(ecol - curwin->w_cursor.col), FALSE, TRUE);
+    }
+    else
+#endif
+	(void)del_char(FALSE);
+    return TRUE;
+}
+
 #if defined(FEAT_INS_EXPAND) || defined(PROTO)
 /*
  * CTRL-X pressed in Insert mode.
@@ -2418,7 +2459,7 @@
 	{
 	    had_match = (curwin->w_cursor.col > compl_col);
 	    ins_compl_delete();
-	    ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
+	    ins_bytes(compl_leader + ins_compl_len());
 	    ins_redraw(FALSE);
 
 	    /* When the match isn't there (to avoid matching itself) remove it
@@ -2470,7 +2511,7 @@
 	    *p = NUL;
 	    had_match = (curwin->w_cursor.col > compl_col);
 	    ins_compl_delete();
-	    ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
+	    ins_bytes(compl_leader + ins_compl_len());
 	    ins_redraw(FALSE);
 
 	    /* When the match isn't there (to avoid matching itself) remove it
@@ -3209,7 +3250,7 @@
 {
     ins_compl_del_pum();
     ins_compl_delete();
-    ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
+    ins_bytes(compl_leader + ins_compl_len());
     compl_used_match = FALSE;
 
     if (compl_started)
@@ -3264,6 +3305,20 @@
 }
 
 /*
+ * Return the length of the completion, from the completion start column to
+ * the cursor column.  Making sure it never goes below zero.
+ */
+    static int
+ins_compl_len()
+{
+    int off = curwin->w_cursor.col - compl_col;
+
+    if (off < 0)
+	return 0;
+    return off;
+}
+
+/*
  * Append one character to the match leader.  May reduce the number of
  * matches.
  */
@@ -3621,10 +3676,9 @@
 	    {
 		ins_compl_delete();
 		if (compl_leader != NULL)
-		    ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
+		    ins_bytes(compl_leader + ins_compl_len());
 		else if (compl_first_match != NULL)
-		    ins_bytes(compl_orig_text
-					  + curwin->w_cursor.col - compl_col);
+		    ins_bytes(compl_orig_text + ins_compl_len());
 		retval = TRUE;
 	    }
 
@@ -4187,7 +4241,7 @@
 	}
 
 	/* check if compl_curr_match has changed, (e.g. other type of
-	 * expansion added somenthing) */
+	 * expansion added something) */
 	if (type != 0 && compl_curr_match != old_match)
 	    found_new_match = OK;
 
@@ -4256,7 +4310,7 @@
     static void
 ins_compl_insert()
 {
-    ins_bytes(compl_shown_match->cp_str + curwin->w_cursor.col - compl_col);
+    ins_bytes(compl_shown_match->cp_str + ins_compl_len());
     if (compl_shown_match->cp_flags & ORIGINAL_TEXT)
 	compl_used_match = FALSE;
     else
@@ -4425,7 +4479,7 @@
 	if (!compl_get_longest || compl_used_match)
 	    ins_compl_insert();
 	else
-	    ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
+	    ins_bytes(compl_leader + ins_compl_len());
     }
     else
 	compl_used_match = FALSE;
@@ -4688,7 +4742,7 @@
 		}
 		compl_length = curwin->w_cursor.col - (int)compl_col;
 		/* IObuff is used to add a "word from the next line" would we
-		 * have enough space?  just being paranoic */
+		 * have enough space?  just being paranoid */
 #define	MIN_SPACE 75
 		if (compl_length > (IOSIZE - MIN_SPACE))
 		{
@@ -7123,9 +7177,12 @@
  * cc == 0: character was inserted, delete it
  * cc > 0: character was replaced, put cc (first byte of original char) back
  * and check for more characters to be put back
+ * When "limit_col" is >= 0, don't delete before this column.  Matters when
+ * using composing characters, use del_char_after_col() instead of del_char().
  */
     static void
-replace_do_bs()
+replace_do_bs(limit_col)
+    int		limit_col;
 {
     int		cc;
 #ifdef FEAT_VREPLACE
@@ -7153,7 +7210,7 @@
 #ifdef FEAT_MBYTE
 	if (has_mbyte)
 	{
-	    del_char(FALSE);
+	    (void)del_char_after_col(limit_col);
 # ifdef FEAT_VREPLACE
 	    if (State & VREPLACE_FLAG)
 		orig_len = (int)STRLEN(ml_get_cursor());
@@ -7203,7 +7260,7 @@
 	changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col);
     }
     else if (cc == 0)
-	(void)del_char(FALSE);
+	(void)del_char_after_col(limit_col);
 }
 
 #ifdef FEAT_CINDENT
@@ -7646,9 +7703,7 @@
      */
     ++no_mapping;
     regname = plain_vgetc();
-#ifdef FEAT_LANGMAP
     LANGMAP_ADJUST(regname, TRUE);
-#endif
     if (regname == Ctrl_R || regname == Ctrl_O || regname == Ctrl_P)
     {
 	/* Get a third key for literal register insertion */
@@ -7657,9 +7712,7 @@
 	add_to_showcmd_c(literally);
 #endif
 	regname = plain_vgetc();
-#ifdef FEAT_LANGMAP
 	LANGMAP_ADJUST(regname, TRUE);
-#endif
     }
     --no_mapping;
 
@@ -8150,7 +8203,7 @@
 /*
  * If the cursor is on an indent, ^T/^D insert/delete one
  * shiftwidth.	Otherwise ^T/^D behave like a "<<" or ">>".
- * Always round the indent to 'shiftwith', this is compatible
+ * Always round the indent to 'shiftwidth', this is compatible
  * with vi.  But vi only supports ^T and ^D after an
  * autoindent, we support it everywhere.
  */
@@ -8239,7 +8292,7 @@
 	 * Replace mode */
 	if (curwin->w_cursor.lnum != Insstart.lnum
 		|| curwin->w_cursor.col >= Insstart.col)
-	    replace_do_bs();
+	    replace_do_bs(-1);
     }
     else
 	(void)del_char(FALSE);
@@ -8556,7 +8609,7 @@
 		break;
 	    }
 	    if (State & REPLACE_FLAG)
-		replace_do_bs();
+		replace_do_bs(-1);
 	    else
 	    {
 #ifdef FEAT_MBYTE
diff -Naur vim72.orig/src/eval.c vim72/src/eval.c
--- vim72.orig/src/eval.c	2008-08-07 12:37:22.000000000 -0700
+++ vim72/src/eval.c	2009-03-12 11:55:08.231269731 -0700
@@ -32,6 +32,9 @@
 
 #define DICT_MAXNEST 100	/* maximum nesting of lists and dicts */
 
+#define DO_NOT_FREE_CNT 99999	/* refcount for dict or list that should not
+				   be freed. */
+
 /*
  * In a hashtab item "hi_key" points to "di_key" in a dictitem.
  * This avoids adding a pointer to the hashtab item.
@@ -348,6 +351,7 @@
     {VV_NAME("mouse_col",	 VAR_NUMBER), 0},
     {VV_NAME("operator",	 VAR_STRING), VV_RO},
     {VV_NAME("searchforward",	 VAR_NUMBER), 0},
+    {VV_NAME("oldfiles",	 VAR_LIST), 0},
 };
 
 /* shorthand */
@@ -355,6 +359,7 @@
 #define vv_nr		vv_di.di_tv.vval.v_number
 #define vv_float	vv_di.di_tv.vval.v_float
 #define vv_str		vv_di.di_tv.vval.v_string
+#define vv_list		vv_di.di_tv.vval.v_list
 #define vv_tv		vv_di.di_tv
 
 /*
@@ -426,7 +431,6 @@
 static long list_idx_of_item __ARGS((list_T *l, listitem_T *item));
 static void list_append __ARGS((list_T *l, listitem_T *item));
 static int list_append_tv __ARGS((list_T *l, typval_T *tv));
-static int list_append_string __ARGS((list_T *l, char_u *str, int len));
 static int list_append_number __ARGS((list_T *l, varnumber_T n));
 static int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item));
 static int list_extend __ARGS((list_T	*l1, list_T *l2, listitem_T *bef));
@@ -788,6 +792,8 @@
 static void func_unref __ARGS((char_u *name));
 static void func_ref __ARGS((char_u *name));
 static void call_user_func __ARGS((ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rettv, linenr_T firstline, linenr_T lastline, dict_T *selfdict));
+static int can_free_funccal __ARGS((funccall_T *fc, int copyID)) ;
+static void free_funccal __ARGS((funccall_T *fc, int free_val));
 static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name, varnumber_T nr));
 static win_T *find_win_by_nr __ARGS((typval_T *vp, tabpage_T *tp));
 static void getwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off));
@@ -845,11 +851,17 @@
 	p = &vimvars[i];
 	if (p->vv_di.di_tv.v_type == VAR_STRING)
 	{
-	    vim_free(p->vv_di.di_tv.vval.v_string);
-	    p->vv_di.di_tv.vval.v_string = NULL;
+	    vim_free(p->vv_str);
+	    p->vv_str = NULL;
+	}
+	else if (p->vv_di.di_tv.v_type == VAR_LIST)
+	{
+	    list_unref(p->vv_list);
+	    p->vv_list = NULL;
 	}
     }
     hash_clear(&vimvarht);
+    hash_init(&vimvarht);  /* garbage_collect() will access it */
     hash_clear(&compat_hashtab);
 
     /* script-local variables */
@@ -916,6 +928,10 @@
 /* pointer to funccal for currently active function */
 funccall_T *current_funccal = NULL;
 
+/* pointer to list of previously used funccal, still around because some
+ * item in it is still being used. */
+funccall_T *previous_funccal = NULL;
+
 /*
  * Return TRUE when a function was ended by a ":return" command.
  */
@@ -1256,23 +1272,26 @@
 
 /*
  * Top level evaluation function, returning a string.
+ * When "convert" is TRUE convert a List into a sequence of lines and convert
+ * a Float to a String.
  * Return pointer to allocated memory, or NULL for failure.
  */
     char_u *
-eval_to_string(arg, nextcmd, dolist)
+eval_to_string(arg, nextcmd, convert)
     char_u	*arg;
     char_u	**nextcmd;
-    int		dolist;		/* turn List into sequence of lines */
+    int		convert;
 {
     typval_T	tv;
     char_u	*retval;
     garray_T	ga;
+    char_u	numbuf[NUMBUFLEN];
 
     if (eval0(arg, &tv, nextcmd, TRUE) == FAIL)
 	retval = NULL;
     else
     {
-	if (dolist && tv.v_type == VAR_LIST)
+	if (convert && tv.v_type == VAR_LIST)
 	{
 	    ga_init2(&ga, (int)sizeof(char), 80);
 	    if (tv.vval.v_list != NULL)
@@ -1280,6 +1299,13 @@
 	    ga_append(&ga, NUL);
 	    retval = (char_u *)ga.ga_data;
 	}
+#ifdef FEAT_FLOAT
+	else if (convert && tv.v_type == VAR_FLOAT)
+	{
+	    vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv.vval.v_float);
+	    retval = vim_strsave(numbuf);
+	}
+#endif
 	else
 	    retval = vim_strsave(get_tv_string(&tv));
 	clear_tv(&tv);
@@ -3277,7 +3303,7 @@
 
     if (*startarg != '(')
     {
-	EMSG2(_("E107: Missing braces: %s"), eap->arg);
+	EMSG2(_("E107: Missing parentheses: %s"), eap->arg);
 	goto end;
     }
 
@@ -3657,8 +3683,8 @@
 }
 
 /*
- * Return TRUE if typeval "tv" is locked: Either tha value is locked itself or
- * it refers to a List or Dictionary that is locked.
+ * Return TRUE if typeval "tv" is locked: Either that value is locked itself
+ * or it refers to a List or Dictionary that is locked.
  */
     static int
 tv_islocked(tv)
@@ -3902,7 +3928,7 @@
 
 /*
  * Handle top level expression:
- *	expr1 ? expr0 : expr0
+ *	expr2 ? expr1 : expr1
  *
  * "arg" must point to the first non-white of the expression.
  * "arg" is advanced to the next non-white after the recognized expression.
@@ -6047,6 +6073,25 @@
 }
 
 /*
+ * Get list item "l[idx - 1]" as a string.  Returns NULL for failure.
+ */
+    char_u *
+list_find_str(l, idx)
+    list_T	*l;
+    long	idx;
+{
+    listitem_T	*li;
+
+    li = list_find(l, idx - 1);
+    if (li == NULL)
+    {
+	EMSGN(_(e_listidx), idx);
+	return NULL;
+    }
+    return get_tv_string(&li->li_tv);
+}
+
+/*
  * Locate "item" list "l" and return its index.
  * Returns -1 when "item" is not in the list.
  */
@@ -6137,7 +6182,7 @@
  * When "len" >= 0 use "str[len]".
  * Returns FAIL when out of memory.
  */
-    static int
+    int
 list_append_string(l, str, len)
     list_T	*l;
     char_u	*str;
@@ -6454,7 +6499,7 @@
     buf_T	*buf;
     win_T	*wp;
     int		i;
-    funccall_T	*fc;
+    funccall_T	*fc, **pfc;
     int		did_free = FALSE;
 #ifdef FEAT_WINDOWS
     tabpage_T	*tp;
@@ -6497,6 +6542,9 @@
 	set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID);
     }
 
+    /* v: vars */
+    set_ref_in_ht(&vimvarht, copyID);
+
     /*
      * 2. Go through the list of dicts and free items without the copyID.
      */
@@ -6535,6 +6583,20 @@
 	else
 	    ll = ll->lv_used_next;
 
+    /* check if any funccal can be freed now */
+    for (pfc = &previous_funccal; *pfc != NULL; )
+    {
+	if (can_free_funccal(*pfc, copyID))
+	{
+	    fc = *pfc;
+	    *pfc = fc->caller;
+	    free_funccal(fc, TRUE);
+	    did_free = TRUE;
+	}
+	else
+	    pfc = &(*pfc)->caller;
+    }
+
     return did_free;
 }
 
@@ -6587,7 +6649,7 @@
     {
 	case VAR_DICT:
 	    dd = tv->vval.v_dict;
-	    if (dd->dv_copyID != copyID)
+	    if (dd != NULL && dd->dv_copyID != copyID)
 	    {
 		/* Didn't see this dict yet. */
 		dd->dv_copyID = copyID;
@@ -6597,7 +6659,7 @@
 
 	case VAR_LIST:
 	    ll = tv->vval.v_list;
-	    if (ll->lv_copyID != copyID)
+	    if (ll != NULL && ll->lv_copyID != copyID)
 	    {
 		/* Didn't see this list yet. */
 		ll->lv_copyID = copyID;
@@ -7525,8 +7587,8 @@
     {"getwinposx",	0, 0, f_getwinposx},
     {"getwinposy",	0, 0, f_getwinposy},
     {"getwinvar",	2, 2, f_getwinvar},
-    {"glob",		1, 1, f_glob},
-    {"globpath",	2, 2, f_globpath},
+    {"glob",		1, 2, f_glob},
+    {"globpath",	2, 3, f_globpath},
     {"has",		1, 1, f_has},
     {"has_key",		2, 2, f_has_key},
     {"haslocaldir",	0, 0, f_haslocaldir},
@@ -7856,9 +7918,9 @@
     else if (!aborting())
     {
 	if (argcount == MAX_FUNC_ARGS)
-	    emsg_funcname("E740: Too many arguments for function %s", name);
+	    emsg_funcname(N_("E740: Too many arguments for function %s"), name);
 	else
-	    emsg_funcname("E116: Invalid arguments for function %s", name);
+	    emsg_funcname(N_("E116: Invalid arguments for function %s"), name);
     }
 
     while (--argcount >= 0)
@@ -8091,6 +8153,7 @@
 
 /*
  * Give an error message with a function name.  Handle <SNR> things.
+ * "ermsg" is to be passed without translation, use N_() instead of _().
  */
     static void
 emsg_funcname(ermsg, name)
@@ -9518,7 +9581,7 @@
     else
     {
 	/* When the optional second argument is non-zero, don't remove matches
-	 * for 'suffixes' and 'wildignore' */
+	 * for 'wildignore' and don't put matches for 'suffixes' at the end. */
 	if (argvars[1].v_type != VAR_UNKNOWN
 				    && get_tv_number_chk(&argvars[1], &error))
 	    flags |= WILD_KEEP_ALL;
@@ -10300,7 +10363,8 @@
     s = get_tv_string(&argvars[0]);
     if (s == NULL || *s == NUL || VIM_ISDIGIT(*s))
 	EMSG2(_(e_invarg2), s);
-    else if (!function_exists(s))
+    /* Don't check an autoload name for existence here. */
+    else if (vim_strchr(s, AUTOLOAD_CHAR) == NULL && !function_exists(s))
 	EMSG2(_("E700: Unknown function: %s"), s);
     else
     {
@@ -10602,7 +10666,7 @@
 # ifdef FEAT_WINDOWS
 	    win_T	*wp;
 # endif
-	    int		n = 1;
+	    int		winnr = 1;
 
 	    if (row >= 0 && col >= 0)
 	    {
@@ -10612,9 +10676,9 @@
 		(void)mouse_comp_pos(win, &row, &col, &lnum);
 # ifdef FEAT_WINDOWS
 		for (wp = firstwin; wp != win; wp = wp->w_next)
-		    ++n;
+		    ++winnr;
 # endif
-		vimvars[VV_MOUSE_WIN].vv_nr = n;
+		vimvars[VV_MOUSE_WIN].vv_nr = winnr;
 		vimvars[VV_MOUSE_LNUM].vv_nr = lnum;
 		vimvars[VV_MOUSE_COL].vv_nr = col + 1;
 	    }
@@ -11284,13 +11348,25 @@
     typval_T	*argvars;
     typval_T	*rettv;
 {
+    int		flags = WILD_SILENT|WILD_USE_NL;
     expand_T	xpc;
+    int		error = FALSE;
 
-    ExpandInit(&xpc);
-    xpc.xp_context = EXPAND_FILES;
+    /* When the optional second argument is non-zero, don't remove matches
+    * for 'wildignore' and don't put matches for 'suffixes' at the end. */
+    if (argvars[1].v_type != VAR_UNKNOWN
+				&& get_tv_number_chk(&argvars[1], &error))
+	flags |= WILD_KEEP_ALL;
     rettv->v_type = VAR_STRING;
-    rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]),
-				     NULL, WILD_USE_NL|WILD_SILENT, WILD_ALL);
+    if (!error)
+    {
+	ExpandInit(&xpc);
+	xpc.xp_context = EXPAND_FILES;
+	rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]),
+						       NULL, flags, WILD_ALL);
+    }
+    else
+	rettv->vval.v_string = NULL;
 }
 
 /*
@@ -11301,14 +11377,22 @@
     typval_T	*argvars;
     typval_T	*rettv;
 {
+    int		flags = 0;
     char_u	buf1[NUMBUFLEN];
     char_u	*file = get_tv_string_buf_chk(&argvars[1], buf1);
+    int		error = FALSE;
 
+    /* When the optional second argument is non-zero, don't remove matches
+    * for 'wildignore' and don't put matches for 'suffixes' at the end. */
+    if (argvars[2].v_type != VAR_UNKNOWN
+				&& get_tv_number_chk(&argvars[2], &error))
+	flags |= WILD_KEEP_ALL;
     rettv->v_type = VAR_STRING;
-    if (file == NULL)
+    if (file == NULL || error)
 	rettv->vval.v_string = NULL;
     else
-	rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file);
+	rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file,
+								       flags);
 }
 
 /*
@@ -11782,6 +11866,10 @@
 	    n = has_patch(atoi((char *)name + 5));
 	else if (STRICMP(name, "vim_starting") == 0)
 	    n = (starting != 0);
+#ifdef FEAT_MBYTE
+	else if (STRICMP(name, "multi_byte_encoding") == 0)
+	    n = has_mbyte;
+#endif
 #if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32)
 	else if (STRICMP(name, "balloon_multiline") == 0)
 	    n = multiline_balloon_available();
@@ -15838,10 +15926,9 @@
     if (res == FAIL)
 	res = ITEM_COMPARE_FAIL;
     else
-	/* return value has wrong type */
 	res = get_tv_number_chk(&rettv, &item_compare_func_err);
     if (item_compare_func_err)
-	res = ITEM_COMPARE_FAIL;
+	res = ITEM_COMPARE_FAIL;  /* return value has wrong type */
     clear_tv(&rettv);
     return res;
 }
@@ -16590,8 +16677,11 @@
 		p = highlight_has_attr(id, HL_INVERSE, modec);
 		break;
 
-	case 's':					/* standout */
-		p = highlight_has_attr(id, HL_STANDOUT, modec);
+	case 's':
+		if (TOLOWER_ASC(what[1]) == 'p')	/* sp[#] */
+		    p = highlight_color(id, what, modec);
+		else					/* standout */
+		    p = highlight_has_attr(id, HL_STANDOUT, modec);
 		break;
 
 	case 'u':
@@ -16658,7 +16748,7 @@
     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))
+	    && col >= 0 && (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);
@@ -18097,14 +18187,28 @@
 }
 
 /*
- * Set v:count, v:count1 and v:prevcount.
+ * Get List v: variable value.  Caller must take care of reference count when
+ * needed.
+ */
+    list_T *
+get_vim_var_list(idx)
+    int		idx;
+{
+    return vimvars[idx].vv_list;
+}
+
+/*
+ * Set v:count to "count" and v:count1 to "count1".
+ * When "set_prevcount" is TRUE first set v:prevcount from v:count.
  */
     void
-set_vcount(count, count1)
+set_vcount(count, count1, set_prevcount)
     long	count;
     long	count1;
+    int		set_prevcount;
 {
-    vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr;
+    if (set_prevcount)
+	vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr;
     vimvars[VV_COUNT].vv_nr = count;
     vimvars[VV_COUNT1].vv_nr = count1;
 }
@@ -18132,6 +18236,20 @@
 }
 
 /*
+ * Set List v: variable to "val".
+ */
+    void
+set_vim_var_list(idx, val)
+    int		idx;
+    list_T	*val;
+{
+    list_unref(vimvars[idx].vv_list);
+    vimvars[idx].vv_list = val;
+    if (val != NULL)
+	++val->lv_refcount;
+}
+
+/*
  * Set v:register if needed.
  */
     void
@@ -18868,7 +18986,7 @@
     dictitem_T	*dict_var;
 {
     hash_init(&dict->dv_hashtab);
-    dict->dv_refcount = 99999;
+    dict->dv_refcount = DO_NOT_FREE_CNT;
     dict_var->di_tv.vval.v_dict = dict;
     dict_var->di_tv.v_type = VAR_DICT;
     dict_var->di_tv.v_lock = VAR_FIXED;
@@ -19205,6 +19323,8 @@
  * Copy the values from typval_T "from" to typval_T "to".
  * When needed allocates string or increases reference count.
  * Does not make a copy of a list or dict but copies the reference!
+ * It is OK for "from" and "to" to point to the same item.  This is used to
+ * make a copy later.
  */
     static void
 copy_tv(from, to)
@@ -19748,7 +19868,7 @@
 		}
 	    }
 	    else
-		emsg_funcname("E123: Undefined function: %s", name);
+		emsg_funcname(N_("E123: Undefined function: %s"), name);
 	}
 	goto ret_free;
     }
@@ -19792,7 +19912,7 @@
 						      : eval_isnamec(arg[j])))
 		++j;
 	    if (arg[j] != NUL)
-		emsg_funcname(_(e_invarg2), arg);
+		emsg_funcname((char *)e_invarg2, arg);
 	}
     }
 
@@ -20064,7 +20184,7 @@
 	v = find_var(name, &ht);
 	if (v != NULL && v->di_tv.v_type == VAR_FUNC)
 	{
-	    emsg_funcname("E707: Function name conflicts with variable: %s",
+	    emsg_funcname(N_("E707: Function name conflicts with variable: %s"),
 									name);
 	    goto erret;
 	}
@@ -20079,7 +20199,7 @@
 	    }
 	    if (fp->uf_calls > 0)
 	    {
-		emsg_funcname("E127: Cannot redefine function %s: It is in use",
+		emsg_funcname(N_("E127: Cannot redefine function %s: It is in use"),
 									name);
 		goto erret;
 	    }
@@ -20590,6 +20710,9 @@
     int		st_len = 0;
 
     todo = (int)func_hashtab.ht_used;
+    if (todo == 0)
+	return;     /* nothing to dump */
+
     sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T) * todo));
 
     for (hi = func_hashtab.ht_array; todo > 0; ++hi)
@@ -20638,6 +20761,8 @@
 							      prof_self_cmp);
 	prof_sort_list(fd, sorttab, st_len, "SELF", TRUE);
     }
+
+    vim_free(sorttab);
 }
 
     static void
@@ -21012,7 +21137,7 @@
     char_u	*save_sourcing_name;
     linenr_T	save_sourcing_lnum;
     scid_T	save_current_SID;
-    funccall_T	fc;
+    funccall_T	*fc;
     int		save_did_emsg;
     static int	depth = 0;
     dictitem_T	*v;
@@ -21038,36 +21163,37 @@
 
     line_breakcheck();		/* check for CTRL-C hit */
 
-    fc.caller = current_funccal;
-    current_funccal = &fc;
-    fc.func = fp;
-    fc.rettv = rettv;
+    fc = (funccall_T *)alloc(sizeof(funccall_T));
+    fc->caller = current_funccal;
+    current_funccal = fc;
+    fc->func = fp;
+    fc->rettv = rettv;
     rettv->vval.v_number = 0;
-    fc.linenr = 0;
-    fc.returned = FALSE;
-    fc.level = ex_nesting_level;
+    fc->linenr = 0;
+    fc->returned = FALSE;
+    fc->level = ex_nesting_level;
     /* Check if this function has a breakpoint. */
-    fc.breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0);
-    fc.dbg_tick = debug_tick;
+    fc->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0);
+    fc->dbg_tick = debug_tick;
 
     /*
-     * Note about using fc.fixvar[]: This is an array of FIXVAR_CNT variables
+     * Note about using fc->fixvar[]: This is an array of FIXVAR_CNT variables
      * with names up to VAR_SHORT_LEN long.  This avoids having to alloc/free
      * each argument variable and saves a lot of time.
      */
     /*
      * Init l: variables.
      */
-    init_var_dict(&fc.l_vars, &fc.l_vars_var);
+    init_var_dict(&fc->l_vars, &fc->l_vars_var);
     if (selfdict != NULL)
     {
 	/* Set l:self to "selfdict".  Use "name" to avoid a warning from
 	 * some compiler that checks the destination size. */
-	v = &fc.fixvar[fixvar_idx++].var;
+	v = &fc->fixvar[fixvar_idx++].var;
 	name = v->di_key;
 	STRCPY(name, "self");
 	v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX;
-	hash_add(&fc.l_vars.dv_hashtab, DI2HIKEY(v));
+	hash_add(&fc->l_vars.dv_hashtab, DI2HIKEY(v));
 	v->di_tv.v_type = VAR_DICT;
 	v->di_tv.v_lock = 0;
 	v->di_tv.vval.v_dict = selfdict;
@@ -21079,28 +21205,31 @@
      * Set a:0 to "argcount".
      * Set a:000 to a list with room for the "..." arguments.
      */
-    init_var_dict(&fc.l_avars, &fc.l_avars_var);
-    add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "0",
+    init_var_dict(&fc->l_avars, &fc->l_avars_var);
+    add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "0",
 				(varnumber_T)(argcount - fp->uf_args.ga_len));
-    v = &fc.fixvar[fixvar_idx++].var;
-    STRCPY(v->di_key, "000");
+    /* Use "name" to avoid a warning from some compiler that checks the
+     * destination size. */
+    v = &fc->fixvar[fixvar_idx++].var;
+    name = v->di_key;
+    STRCPY(name, "000");
     v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
-    hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v));
+    hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v));
     v->di_tv.v_type = VAR_LIST;
     v->di_tv.v_lock = VAR_FIXED;
-    v->di_tv.vval.v_list = &fc.l_varlist;
-    vim_memset(&fc.l_varlist, 0, sizeof(list_T));
-    fc.l_varlist.lv_refcount = 99999;
-    fc.l_varlist.lv_lock = VAR_FIXED;
+    v->di_tv.vval.v_list = &fc->l_varlist;
+    vim_memset(&fc->l_varlist, 0, sizeof(list_T));
+    fc->l_varlist.lv_refcount = DO_NOT_FREE_CNT;
+    fc->l_varlist.lv_lock = VAR_FIXED;
 
     /*
      * Set a:firstline to "firstline" and a:lastline to "lastline".
      * Set a:name to named arguments.
      * Set a:N to the "..." arguments.
      */
-    add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "firstline",
+    add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "firstline",
 						      (varnumber_T)firstline);
-    add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "lastline",
+    add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "lastline",
 						       (varnumber_T)lastline);
     for (i = 0; i < argcount; ++i)
     {
@@ -21116,7 +21245,7 @@
 	}
 	if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN)
 	{
-	    v = &fc.fixvar[fixvar_idx++].var;
+	    v = &fc->fixvar[fixvar_idx++].var;
 	    v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
 	}
 	else
@@ -21128,7 +21257,7 @@
 	    v->di_flags = DI_FLAGS_RO;
 	}
 	STRCPY(v->di_key, name);
-	hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v));
+	hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v));
 
 	/* Note: the values are copied directly to avoid alloc/free.
 	 * "argvars" must have VAR_FIXED for v_lock. */
@@ -21137,9 +21266,9 @@
 
 	if (ai >= 0 && ai < MAX_FUNC_ARGS)
 	{
-	    list_append(&fc.l_varlist, &fc.l_listitems[ai]);
-	    fc.l_listitems[ai].li_tv = argvars[i];
-	    fc.l_listitems[ai].li_tv.v_lock = VAR_FIXED;
+	    list_append(&fc->l_varlist, &fc->l_listitems[ai]);
+	    fc->l_listitems[ai].li_tv = argvars[i];
+	    fc->l_listitems[ai].li_tv.v_lock = VAR_FIXED;
 	}
     }
 
@@ -21204,7 +21333,7 @@
 	if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL))
 	    func_do_profile(fp);
 	if (fp->uf_profiling
-		       || (fc.caller != NULL && &fc.caller->func->uf_profiling))
+		    || (fc->caller != NULL && fc->caller->func->uf_profiling))
 	{
 	    ++fp->uf_tm_count;
 	    profile_start(&call_start);
@@ -21220,7 +21349,7 @@
     did_emsg = FALSE;
 
     /* call do_cmdline() to execute the lines */
-    do_cmdline(NULL, get_func_line, (void *)&fc,
+    do_cmdline(NULL, get_func_line, (void *)fc,
 				     DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT);
 
     --RedrawingDisabled;
@@ -21235,16 +21364,16 @@
 
 #ifdef FEAT_PROFILE
     if (do_profiling == PROF_YES && (fp->uf_profiling
-		    || (fc.caller != NULL && &fc.caller->func->uf_profiling)))
+		    || (fc->caller != NULL && fc->caller->func->uf_profiling)))
     {
 	profile_end(&call_start);
 	profile_sub_wait(&wait_start, &call_start);
 	profile_add(&fp->uf_tm_total, &call_start);
 	profile_self(&fp->uf_tm_self, &call_start, &fp->uf_tm_children);
-	if (fc.caller != NULL && &fc.caller->func->uf_profiling)
+	if (fc->caller != NULL && fc->caller->func->uf_profiling)
 	{
-	    profile_add(&fc.caller->func->uf_tm_children, &call_start);
-	    profile_add(&fc.caller->func->uf_tml_children, &call_start);
+	    profile_add(&fc->caller->func->uf_tm_children, &call_start);
+	    profile_add(&fc->caller->func->uf_tml_children, &call_start);
 	}
     }
 #endif
@@ -21257,9 +21386,9 @@
 
 	if (aborting())
 	    smsg((char_u *)_("%s aborted"), sourcing_name);
-	else if (fc.rettv->v_type == VAR_NUMBER)
+	else if (fc->rettv->v_type == VAR_NUMBER)
 	    smsg((char_u *)_("%s returning #%ld"), sourcing_name,
-					       (long)fc.rettv->vval.v_number);
+					       (long)fc->rettv->vval.v_number);
 	else
 	{
 	    char_u	buf[MSG_BUF_LEN];
@@ -21270,7 +21399,7 @@
 	    /* 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. */
-	    s = tv2string(fc.rettv, &tofree, numbuf2, 0);
+	    s = tv2string(fc->rettv, &tofree, numbuf2, 0);
 	    if (s != NULL)
 	    {
 		trunc_string(s, buf, MSG_BUF_CLEN);
@@ -21306,14 +21435,84 @@
     }
 
     did_emsg |= save_did_emsg;
-    current_funccal = fc.caller;
+    current_funccal = fc->caller;
+    --depth;
 
-    /* The a: variables typevals were not allocated, only free the allocated
-     * variables. */
-    vars_clear_ext(&fc.l_avars.dv_hashtab, FALSE);
+    /* if the a:000 list and the a: dict are not referenced we can free the
+     * funccall_T and what's in it. */
+    if (fc->l_varlist.lv_refcount == DO_NOT_FREE_CNT
+	    && fc->l_vars.dv_refcount == DO_NOT_FREE_CNT
+	    && fc->l_avars.dv_refcount == DO_NOT_FREE_CNT)
+    {
+	free_funccal(fc, FALSE);
+    }
+    else
+    {
+	hashitem_T	*hi;
+	listitem_T	*li;
+	int		todo;
 
-    vars_clear(&fc.l_vars.dv_hashtab);		/* free all l: variables */
-    --depth;
+	/* "fc" is still in use.  This can happen when returning "a:000" or
+	 * assigning "l:" to a global variable.
+	 * Link "fc" in the list for garbage collection later. */
+	fc->caller = previous_funccal;
+	previous_funccal = fc;
+
+	/* Make a copy of the a: variables, since we didn't do that above. */
+	todo = (int)fc->l_avars.dv_hashtab.ht_used;
+	for (hi = fc->l_avars.dv_hashtab.ht_array; todo > 0; ++hi)
+	{
+	    if (!HASHITEM_EMPTY(hi))
+	    {
+		--todo;
+		v = HI2DI(hi);
+		copy_tv(&v->di_tv, &v->di_tv);
+	    }
+	}
+
+	/* Make a copy of the a:000 items, since we didn't do that above. */
+	for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next)
+	    copy_tv(&li->li_tv, &li->li_tv);
+    }
+}
+
+/*
+ * Return TRUE if items in "fc" do not have "copyID".  That means they are not
+ * referenced from anywhere.
+ */
+    static int
+can_free_funccal(fc, copyID)
+    funccall_T	*fc;
+    int		copyID;
+{
+    return (fc->l_varlist.lv_copyID != copyID
+	    && fc->l_vars.dv_copyID != copyID
+	    && fc->l_avars.dv_copyID != copyID);
+}
+
+/*
+ * Free "fc" and what it contains.
+ */
+   static void
+free_funccal(fc, free_val)
+    funccall_T	*fc;
+    int		free_val;  /* a: vars were allocated */
+{
+    listitem_T	*li;
+
+    /* The a: variables typevals may not have been allocated, only free the
+     * allocated variables. */
+    vars_clear_ext(&fc->l_avars.dv_hashtab, free_val);
+
+    /* free all l: variables */
+    vars_clear(&fc->l_vars.dv_hashtab);
+
+    /* Free the a:000 variables if they were allocated. */
+    if (free_val)
+	for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next)
+	    clear_tv(&li->li_tv);
+
+    vim_free(fc);
 }
 
 /*
@@ -21886,6 +22085,62 @@
     }
 }
 
+/*
+ * List v:oldfiles in a nice way.
+ */
+/*ARGSUSED*/
+    void
+ex_oldfiles(eap)
+    exarg_T	*eap;
+{
+    list_T	*l = vimvars[VV_OLDFILES].vv_list;
+    listitem_T	*li;
+    int		nr = 0;
+
+    if (l == NULL)
+	msg((char_u *)_("No old files"));
+    else
+    {
+	msg_start();
+	msg_scroll = TRUE;
+	for (li = l->lv_first; li != NULL && !got_int; li = li->li_next)
+	{
+	    msg_outnum((long)++nr);
+	    MSG_PUTS(": ");
+	    msg_outtrans(get_tv_string(&li->li_tv));
+	    msg_putchar('\n');
+	    out_flush();	    /* output one line at a time */
+	    ui_breakcheck();
+	}
+	/* Assume "got_int" was set to truncate the listing. */
+	got_int = FALSE;
+
+#ifdef FEAT_BROWSE_CMD
+	if (cmdmod.browse)
+	{
+	    quit_more = FALSE;
+	    nr = prompt_for_number(FALSE);
+	    msg_starthere();
+	    if (nr > 0)
+	    {
+		char_u *p = list_find_str(get_vim_var_list(VV_OLDFILES),
+								    (long)nr);
+
+		if (p != NULL)
+		{
+		    p = expand_env_save(p);
+		    eap->arg = p;
+		    eap->cmdidx = CMD_edit;
+		    cmdmod.browse = FALSE;
+		    do_exedit(eap, NULL);
+		    vim_free(p);
+		}
+	    }
+	}
+#endif
+    }
+}
+
 #endif /* FEAT_EVAL */
 
 
diff -Naur vim72.orig/src/ex_cmds2.c vim72/src/ex_cmds2.c
--- vim72.orig/src/ex_cmds2.c	2008-07-13 09:18:22.000000000 -0700
+++ vim72/src/ex_cmds2.c	2009-03-12 11:55:13.311593519 -0700
@@ -2842,6 +2842,7 @@
     linenr_T		    save_sourcing_lnum;
     char_u		    *p;
     char_u		    *fname_exp;
+    char_u		    *firstline = NULL;
     int			    retval = FAIL;
 #ifdef FEAT_EVAL
     scid_T		    save_current_SID;
@@ -2992,23 +2993,6 @@
 
     cookie.level = ex_nesting_level;
 #endif
-#ifdef FEAT_MBYTE
-    cookie.conv.vc_type = CONV_NONE;		/* no conversion */
-
-    /* Try reading the first few bytes to check for a UTF-8 BOM. */
-    {
-	char_u	    buf[3];
-
-	if (fread((char *)buf, sizeof(char_u), (size_t)3, cookie.fp)
-								  == (size_t)3
-		&& buf[0] == 0xef && buf[1] == 0xbb && buf[2] == 0xbf)
-	    /* Found BOM, setup conversion and skip over it. */
-	    convert_setup(&cookie.conv, (char_u *)"utf-8", p_enc);
-	else
-	    /* No BOM found, rewind. */
-	    fseek(cookie.fp, 0L, SEEK_SET);
-    }
-#endif
 
     /*
      * Keep the sourcing name/lnum, for recursive calls.
@@ -3018,6 +3002,27 @@
     save_sourcing_lnum = sourcing_lnum;
     sourcing_lnum = 0;
 
+#ifdef FEAT_MBYTE
+    cookie.conv.vc_type = CONV_NONE;		/* no conversion */
+
+    /* Read the first line so we can check for a UTF-8 BOM. */
+    firstline = getsourceline(0, (void *)&cookie, 0);
+    if (firstline != NULL && STRLEN(firstline) >= 3 && firstline[0] == 0xef
+			      && firstline[1] == 0xbb && firstline[2] == 0xbf)
+    {
+	/* Found BOM; setup conversion, skip over BOM and recode the line. */
+	convert_setup(&cookie.conv, (char_u *)"utf-8", p_enc);
+	p = string_convert(&cookie.conv, firstline + 3, NULL);
+	if (p == NULL)
+	    p = vim_strsave(firstline + 3);
+	if (p != NULL)
+	{
+	    vim_free(firstline);
+	    firstline = p;
+	}
+    }
+#endif
+
 #ifdef STARTUPTIME
     time_push(&tv_rel, &tv_start);
 #endif
@@ -3111,9 +3116,8 @@
     /*
      * Call do_cmdline, which will call getsourceline() to get the lines.
      */
-    do_cmdline(NULL, getsourceline, (void *)&cookie,
+    do_cmdline(firstline, getsourceline, (void *)&cookie,
 				     DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_REPEAT);
-
     retval = OK;
 
 #ifdef FEAT_PROFILE
@@ -3145,8 +3149,8 @@
 	verbose_leave();
     }
 #ifdef STARTUPTIME
-    vim_snprintf(IObuff, IOSIZE, "sourcing %s", fname);
-    time_msg(IObuff, &tv_start);
+    vim_snprintf((char *)IObuff, IOSIZE, "sourcing %s", fname);
+    time_msg((char *)IObuff, &tv_start);
     time_pop(&tv_rel);
 #endif
 
@@ -3171,6 +3175,7 @@
 #endif
     fclose(cookie.fp);
     vim_free(cookie.nextline);
+    vim_free(firstline);
 #ifdef FEAT_MBYTE
     convert_setup(&cookie.conv, NULL, NULL);
 #endif
diff -Naur vim72.orig/src/ex_cmds.c vim72/src/ex_cmds.c
--- vim72.orig/src/ex_cmds.c	2008-08-04 12:15:00.000000000 -0700
+++ vim72/src/ex_cmds.c	2009-03-12 11:55:13.611614471 -0700
@@ -24,7 +24,7 @@
 static void do_filter __ARGS((linenr_T line1, linenr_T line2, exarg_T *eap, char_u *cmd, int do_in, int do_out));
 #ifdef FEAT_VIMINFO
 static char_u *viminfo_filename __ARGS((char_u	*));
-static void do_viminfo __ARGS((FILE *fp_in, FILE *fp_out, int want_info, int want_marks, int force_read));
+static void do_viminfo __ARGS((FILE *fp_in, FILE *fp_out, int flags));
 static int viminfo_encoding __ARGS((vir_T *virp));
 static int read_viminfo_up_to_marks __ARGS((vir_T *virp, int forceit, int writing));
 #endif
@@ -49,6 +49,7 @@
     exarg_T	*eap;
 {
     int		c;
+    int		cval;
     char	buf1[20];
     char	buf2[20];
     char_u	buf3[7];
@@ -75,6 +76,10 @@
     {
 	if (c == NL)	    /* NUL is stored as NL */
 	    c = NUL;
+	if (c == CAR && get_fileformat(curbuf) == EOL_MAC)
+	    cval = NL;	    /* NL is stored as CR */
+	else
+	    cval = c;
 	if (vim_isprintc_strict(c) && (c < ' '
 #ifndef EBCDIC
 		    || c > '~'
@@ -94,7 +99,7 @@
 	    buf2[0] = NUL;
 	vim_snprintf((char *)IObuff, IOSIZE,
 		_("<%s>%s%s  %d,  Hex %02x,  Octal %03o"),
-					   transchar(c), buf1, buf2, c, c, c);
+				  transchar(c), buf1, buf2, cval, cval, cval);
 #ifdef FEAT_MBYTE
 	if (enc_utf8)
 	    c = cc[ci++];
@@ -1676,14 +1681,12 @@
 
 /*
  * read_viminfo() -- Read the viminfo file.  Registers etc. which are already
- * set are not over-written unless force is TRUE. -- webb
+ * set are not over-written unless "flags" includes VIF_FORCEIT. -- webb
  */
     int
-read_viminfo(file, want_info, want_marks, forceit)
-    char_u	*file;
-    int		want_info;
-    int		want_marks;
-    int		forceit;
+read_viminfo(file, flags)
+    char_u	*file;	    /* file name or NULL to use default name */
+    int		flags;	    /* VIF_WANT_INFO et al. */
 {
     FILE	*fp;
     char_u	*fname;
@@ -1691,7 +1694,7 @@
     if (no_viminfo())
 	return FAIL;
 
-    fname = viminfo_filename(file);	    /* may set to default if NULL */
+    fname = viminfo_filename(file);	/* get file name in allocated buffer */
     if (fname == NULL)
 	return FAIL;
     fp = mch_fopen((char *)fname, READBIN);
@@ -1701,8 +1704,9 @@
 	verbose_enter();
 	smsg((char_u *)_("Reading viminfo file \"%s\"%s%s%s"),
 		fname,
-		want_info ? _(" info") : "",
-		want_marks ? _(" marks") : "",
+		(flags & VIF_WANT_INFO) ? _(" info") : "",
+		(flags & VIF_WANT_MARKS) ? _(" marks") : "",
+		(flags & VIF_GET_OLDFILES) ? _(" oldfiles") : "",
 		fp == NULL ? _(" FAILED") : "");
 	verbose_leave();
     }
@@ -1712,10 +1716,9 @@
 	return FAIL;
 
     viminfo_errcnt = 0;
-    do_viminfo(fp, NULL, want_info, want_marks, forceit);
+    do_viminfo(fp, NULL, flags);
 
     fclose(fp);
-
     return OK;
 }
 
@@ -1943,7 +1946,7 @@
 	     * root.
 	     */
 	    if (fp_out != NULL)
-		(void)fchown(fileno(fp_out), st_old.st_uid, st_old.st_gid);
+		ignored = fchown(fileno(fp_out), st_old.st_uid, st_old.st_gid);
 #endif
 	}
     }
@@ -1968,7 +1971,7 @@
     }
 
     viminfo_errcnt = 0;
-    do_viminfo(fp_in, fp_out, !forceit, !forceit, FALSE);
+    do_viminfo(fp_in, fp_out, forceit ? 0 : (VIF_WANT_INFO | VIF_WANT_MARKS));
 
     fclose(fp_out);	    /* errors are ignored !? */
     if (fp_in != NULL)
@@ -2041,12 +2044,10 @@
  * do_viminfo() -- Should only be called from read_viminfo() & write_viminfo().
  */
     static void
-do_viminfo(fp_in, fp_out, want_info, want_marks, force_read)
+do_viminfo(fp_in, fp_out, flags)
     FILE	*fp_in;
     FILE	*fp_out;
-    int		want_info;
-    int		want_marks;
-    int		force_read;
+    int		flags;
 {
     int		count = 0;
     int		eof = FALSE;
@@ -2061,8 +2062,9 @@
 
     if (fp_in != NULL)
     {
-	if (want_info)
-	    eof = read_viminfo_up_to_marks(&vir, force_read, fp_out != NULL);
+	if (flags & VIF_WANT_INFO)
+	    eof = read_viminfo_up_to_marks(&vir,
+					 flags & VIF_FORCEIT, fp_out != NULL);
 	else
 	    /* Skip info, find start of marks */
 	    while (!(eof = viminfo_readline(&vir))
@@ -2092,8 +2094,9 @@
 	write_viminfo_bufferlist(fp_out);
 	count = write_viminfo_marks(fp_out);
     }
-    if (fp_in != NULL && want_marks)
-	copy_viminfo_marks(&vir, fp_out, count, eof);
+    if (fp_in != NULL
+	    && (flags & (VIF_WANT_MARKS | VIF_GET_OLDFILES | VIF_FORCEIT)))
+	copy_viminfo_marks(&vir, fp_out, count, eof, flags);
 
     vim_free(vir.vir_line);
 #ifdef FEAT_MBYTE
@@ -2414,8 +2417,8 @@
 	cursor_on();		/* msg_start() switches it off */
 	out_flush();
 	silent_mode = save_silent;
-	info_message = FALSE;
     }
+    info_message = FALSE;
 }
 
 /*
@@ -2704,7 +2707,12 @@
 	if (eap->cmdidx == CMD_saveas)
 	{
 	    if (retval == OK)
+	    {
 		curbuf->b_p_ro = FALSE;
+#ifdef FEAT_WINDOWS
+		redraw_tabline = TRUE;
+#endif
+	    }
 	    /* Change directories when the 'acd' option is set. */
 	    DO_AUTOCHDIR
 	}
@@ -5059,6 +5067,7 @@
 
 	    if (did_sub)
 		++sub_nlines;
+	    vim_free(new_start);	/* for when substitute was cancelled */
 	    vim_free(sub_firstline);	/* free the copy of the original line */
 	    sub_firstline = NULL;
 	}
@@ -6520,6 +6529,7 @@
 static int	last_sign_typenr = MAX_TYPENR;	/* is decremented */
 
 static void sign_list_defined __ARGS((sign_T *sp));
+static void sign_undefine __ARGS((sign_T *sp, sign_T *sp_prev));
 
 /*
  * ":sign" command
@@ -6728,24 +6738,8 @@
 		/* ":sign list {name}" */
 		sign_list_defined(sp);
 	    else
-	    {
 		/* ":sign undefine {name}" */
-		vim_free(sp->sn_name);
-		vim_free(sp->sn_icon);
-#ifdef FEAT_SIGN_ICONS
-		if (sp->sn_image != NULL)
-		{
-		    out_flush();
-		    gui_mch_destroy_sign(sp->sn_image);
-		}
-#endif
-		vim_free(sp->sn_text);
-		if (sp_prev == NULL)
-		    first_sign = sp->sn_next;
-		else
-		    sp_prev->sn_next = sp->sn_next;
-		vim_free(sp);
-	    }
+		sign_undefine(sp, sp_prev);
 	}
     }
     else
@@ -6994,6 +6988,31 @@
 }
 
 /*
+ * Undefine a sign and free its memory.
+ */
+    static void
+sign_undefine(sp, sp_prev)
+    sign_T	*sp;
+    sign_T	*sp_prev;
+{
+    vim_free(sp->sn_name);
+    vim_free(sp->sn_icon);
+#ifdef FEAT_SIGN_ICONS
+    if (sp->sn_image != NULL)
+    {
+	out_flush();
+	gui_mch_destroy_sign(sp->sn_image);
+    }
+#endif
+    vim_free(sp->sn_text);
+    if (sp_prev == NULL)
+	first_sign = sp->sn_next;
+    else
+	sp_prev->sn_next = sp->sn_next;
+    vim_free(sp);
+}
+
+/*
  * Get highlighting attribute for sign "typenr".
  * If "line" is TRUE: line highl, if FALSE: text highl.
  */
@@ -7067,6 +7086,18 @@
     return (char_u *)_("[Deleted]");
 }
 
+#if defined(EXITFREE) || defined(PROTO)
+/*
+ * Undefine/free all signs.
+ */
+    void
+free_signs()
+{
+    while (first_sign != NULL)
+	sign_undefine(first_sign, NULL);
+}
+#endif
+
 #endif
 
 #if defined(FEAT_GUI) || defined(FEAT_CLIENTSERVER) || defined(PROTO)
diff -Naur vim72.orig/src/ex_cmds.h vim72/src/ex_cmds.h
--- vim72.orig/src/ex_cmds.h	2008-06-21 11:47:57.000000000 -0700
+++ vim72/src/ex_cmds.h	2009-03-12 11:54:40.541495740 -0700
@@ -278,7 +278,7 @@
 EX(CMD_crewind,		"crewind",	ex_cc,
 			RANGE|NOTADR|COUNT|TRLBAR|BANG),
 EX(CMD_cscope,		"cscope",	do_cscope,
-			EXTRA|NOTRLCOM|SBOXOK|XFILE),
+			EXTRA|NOTRLCOM|XFILE),
 EX(CMD_cstag,		"cstag",	do_cstag,
 			BANG|TRLBAR|WORD1),
 EX(CMD_cunmap,		"cunmap",	ex_unmap,
@@ -506,7 +506,7 @@
 EX(CMD_lclose,		"lclose",	ex_cclose,
 			RANGE|NOTADR|COUNT|TRLBAR),
 EX(CMD_lcscope,		"lcscope",	do_cscope,
-			EXTRA|NOTRLCOM|SBOXOK|XFILE),
+			EXTRA|NOTRLCOM|XFILE),
 EX(CMD_left,		"left",		ex_align,
 			TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
 EX(CMD_leftabove,	"leftabove",	ex_wrongmodifier,
@@ -635,6 +635,8 @@
 			RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
 EX(CMD_noremap,		"noremap",	ex_map,
 			BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+EX(CMD_noautocmd,	"noautocmd",	ex_wrongmodifier,
+			NEEDARG|EXTRA|NOTRLCOM),
 EX(CMD_nohlsearch,	"nohlsearch",	ex_nohlsearch,
 			TRLBAR|SBOXOK|CMDWIN),
 EX(CMD_noreabbrev,	"noreabbrev",	ex_abbreviate,
@@ -651,6 +653,8 @@
 			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
 EX(CMD_open,		"open",		ex_open,
 			RANGE|EXTRA),
+EX(CMD_oldfiles,	"oldfiles",	ex_oldfiles,
+			BANG|TRLBAR|SBOXOK|CMDWIN),
 EX(CMD_omap,		"omap",		ex_map,
 			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
 EX(CMD_omapclear,	"omapclear",	ex_mapclear,
@@ -802,7 +806,7 @@
 EX(CMD_scriptencoding,	"scriptencoding", ex_scriptencoding,
 			WORD1|TRLBAR|CMDWIN),
 EX(CMD_scscope,		"scscope",	do_scscope,
-			EXTRA|NOTRLCOM|SBOXOK),
+			EXTRA|NOTRLCOM),
 EX(CMD_set,		"set",		ex_set,
 			TRLBAR|EXTRA|CMDWIN|SBOXOK),
 EX(CMD_setfiletype,	"setfiletype",	ex_setfiletype,
diff -Naur vim72.orig/src/ex_docmd.c vim72/src/ex_docmd.c
--- vim72.orig/src/ex_docmd.c	2008-07-26 04:51:05.000000000 -0700
+++ vim72/src/ex_docmd.c	2009-03-12 11:55:24.900337757 -0700
@@ -364,6 +364,7 @@
 # define ex_function		ex_ni
 # define ex_delfunction		ex_ni
 # define ex_return		ex_ni
+# define ex_oldfiles		ex_ni
 #endif
 static char_u	*arg_all __ARGS((void));
 #ifdef FEAT_SESSION
@@ -1770,7 +1771,7 @@
 			}
 			if (checkforcmd(&ea.cmd, "browse", 3))
 			{
-#ifdef FEAT_BROWSE
+#ifdef FEAT_BROWSE_CMD
 			    cmdmod.browse = TRUE;
 #endif
 			    continue;
@@ -2978,6 +2979,7 @@
     {"keepmarks", 3, FALSE},
     {"leftabove", 5, FALSE},
     {"lockmarks", 3, FALSE},
+    {"noautocmd", 3, FALSE},
     {"rightbelow", 6, FALSE},
     {"sandbox", 3, FALSE},
     {"silent", 3, FALSE},
@@ -3608,6 +3610,7 @@
 	    return set_context_in_autocmd(xp, arg, FALSE);
 
 	case CMD_doautocmd:
+	case CMD_doautoall:
 	    return set_context_in_autocmd(xp, arg, TRUE);
 #endif
 	case CMD_set:
@@ -5121,7 +5124,11 @@
 	    }
 
 	    vim_free(cmd->uc_rep);
-	    cmd->uc_rep = 0;
+	    cmd->uc_rep = NULL;
+#if defined(FEAT_EVAL) && defined(FEAT_CMDL_COMPL)
+	    vim_free(cmd->uc_compl_arg);
+	    cmd->uc_compl_arg = NULL;
+#endif
 	    break;
 	}
 
@@ -5479,6 +5486,9 @@
     return OK;
 }
 
+/*
+ * ":command ..."
+ */
     static void
 ex_command(eap)
     exarg_T   *eap;
@@ -5910,7 +5920,8 @@
     char_u	*q;
 
     char_u	*start;
-    char_u	*end;
+    char_u	*end = NULL;
+    char_u	*ksp;
     size_t	len, totlen;
 
     size_t	split_len = 0;
@@ -5927,16 +5938,51 @@
 
     /*
      * Replace <> in the command by the arguments.
+     * First round: "buf" is NULL, compute length, allocate "buf".
+     * Second round: copy result into "buf".
      */
     buf = NULL;
     for (;;)
     {
-	p = cmd->uc_rep;
-	q = buf;
+	p = cmd->uc_rep;    /* source */
+	q = buf;	    /* destination */
 	totlen = 0;
-	while ((start = vim_strchr(p, '<')) != NULL
-	       && (end = vim_strchr(start + 1, '>')) != NULL)
+
+	for (;;)
 	{
+	    start = vim_strchr(p, '<');
+	    if (start != NULL)
+		end = vim_strchr(start + 1, '>');
+	    if (buf != NULL)
+	    {
+		ksp = vim_strchr(p, K_SPECIAL);
+		if (ksp != NULL && (start == NULL || ksp < start || end == NULL)
+			&& ((ksp[1] == KS_SPECIAL && ksp[2] == KE_FILLER)
+# ifdef FEAT_GUI
+			    || (ksp[1] == KS_EXTRA && ksp[2] == (int)KE_CSI)
+# endif
+			    ))
+		{
+		    /* K_SPECIAL han been put in the buffer as K_SPECIAL
+		     * KS_SPECIAL KE_FILLER, like for mappings, but
+		     * do_cmdline() doesn't handle that, so convert it back.
+		     * Also change K_SPECIAL KS_EXTRA KE_CSI into CSI. */
+		    len = ksp - p;
+		    if (len > 0)
+		    {
+			mch_memmove(q, p, len);
+			q += len;
+		    }
+		    *q++ = ksp[1] == KS_SPECIAL ? K_SPECIAL : CSI;
+		    p = ksp + 3;
+		    continue;
+		}
+	    }
+
+	    /* break if there no <item> is found */
+	    if (start == NULL || end == NULL)
+		break;
+
 	    /* Include the '>' */
 	    ++end;
 
@@ -7803,6 +7849,9 @@
 {
     vim_free(prev_dir);
     prev_dir = NULL;
+
+    vim_free(globaldir);
+    globaldir = NULL;
 }
 #endif
 
@@ -7825,6 +7874,10 @@
     else
 #endif
     {
+#ifdef FEAT_AUTOCMD
+	if (allbuf_locked())
+	    return;
+#endif
 	if (vim_strchr(p_cpo, CPO_CHDIR) != NULL && curbufIsChanged()
 							     && !eap->forceit)
 	{
@@ -8749,8 +8802,8 @@
 		else if (*dirnow != NUL
 			&& (ssop_flags & SSOP_CURDIR) && globaldir != NULL)
 		{
-		    (void)mch_chdir((char *)globaldir);
-		    shorten_fnames(TRUE);
+		    if (mch_chdir((char *)globaldir) == 0)
+			shorten_fnames(TRUE);
 		}
 
 		failed |= (makeopens(fd, dirnow) == FAIL);
@@ -9506,24 +9559,50 @@
 		    break;
 		}
 		s = src + 1;
+		if (*s == '<')		/* "#<99" uses v:oldfiles */
+		    ++s;
 		i = (int)getdigits(&s);
 		*usedlen = (int)(s - src); /* length of what we expand */
 
-		buf = buflist_findnr(i);
-		if (buf == NULL)
+		if (src[1] == '<')
 		{
-		    *errormsg = (char_u *)_("E194: No alternate file name to substitute for '#'");
+		    if (*usedlen < 2)
+		    {
+			/* Should we give an error message for #<text? */
+			*usedlen = 1;
+			return NULL;
+		    }
+#ifdef FEAT_EVAL
+		    result = list_find_str(get_vim_var_list(VV_OLDFILES),
+								     (long)i);
+		    if (result == NULL)
+		    {
+			*errormsg = (char_u *)"";
+			return NULL;
+		    }
+#else
+		    *errormsg = (char_u *)_("E809: #< is not available without the +eval feature");
 		    return NULL;
+#endif
 		}
-		if (lnump != NULL)
-		    *lnump = ECMD_LAST;
-		if (buf->b_fname == NULL)
+		else
 		{
-		    result = (char_u *)"";
-		    valid = 0;	    /* Must have ":p:h" to be valid */
+		    buf = buflist_findnr(i);
+		    if (buf == NULL)
+		    {
+			*errormsg = (char_u *)_("E194: No alternate file name to substitute for '#'");
+			return NULL;
+		    }
+		    if (lnump != NULL)
+			*lnump = ECMD_LAST;
+		    if (buf->b_fname == NULL)
+		    {
+			result = (char_u *)"";
+			valid = 0;	    /* Must have ":p:h" to be valid */
+		    }
+		    else
+			result = buf->b_fname;
 		}
-		else
-		    result = buf->b_fname;
 		break;
 
 #ifdef FEAT_SEARCHPATH
@@ -9541,6 +9620,15 @@
 #ifdef FEAT_AUTOCMD
 	case SPEC_AFILE:	/* file name for autocommand */
 		result = autocmd_fname;
+		if (result != NULL && !autocmd_fname_full)
+		{
+		    /* Still need to turn the fname into a full path.  It is
+		     * postponed to avoid a delay when <afile> is not used. */
+		    autocmd_fname_full = TRUE;
+		    result = FullName_save(autocmd_fname, FALSE);
+		    vim_free(autocmd_fname);
+		    autocmd_fname = result;
+		}
 		if (result == NULL)
 		{
 		    *errormsg = (char_u *)_("E495: no autocommand file name to substitute for \"<afile>\"");
@@ -10067,7 +10155,7 @@
      */
     if (put_line(fd, "let s:sx = expand(\"<sfile>:p:r\").\"x.vim\"") == FAIL
 	    || put_line(fd, "if file_readable(s:sx)") == FAIL
-	    || put_line(fd, "  exe \"source \" . s:sx") == FAIL
+	    || put_line(fd, "  exe \"source \" . fnameescape(s:sx)") == FAIL
 	    || put_line(fd, "endif") == FAIL)
 	return FAIL;
 
@@ -10689,7 +10777,8 @@
 	p_viminfo = (char_u *)"'100";
     if (eap->cmdidx == CMD_rviminfo)
     {
-	if (read_viminfo(eap->arg, TRUE, TRUE, eap->forceit) == FAIL)
+	if (read_viminfo(eap->arg, VIF_WANT_INFO | VIF_WANT_MARKS
+				  | (eap->forceit ? VIF_FORCEIT : 0)) == FAIL)
 	    EMSG(_("E195: Cannot open viminfo file for reading"));
     }
     else
diff -Naur vim72.orig/src/ex_getln.c vim72/src/ex_getln.c
--- vim72.orig/src/ex_getln.c	2008-08-08 02:31:33.000000000 -0700
+++ vim72/src/ex_getln.c	2009-03-12 11:55:13.699620338 -0700
@@ -31,6 +31,8 @@
     int		cmdattr;	/* attributes for prompt */
     int		overstrike;	/* Typing mode on the command line.  Shared by
 				   getcmdline() and put_on_cmdline(). */
+    expand_T	*xpc;		/* struct being used for expansion, xp_pattern
+				   may point into cmdbuff */
     int		xp_context;	/* type of expansion */
 # ifdef FEAT_EVAL
     char_u	*xp_arg;	/* user-defined expansion arg */
@@ -38,7 +40,11 @@
 # endif
 };
 
-static struct cmdline_info ccline;	/* current cmdline_info */
+/* The current cmdline_info.  It is initialized in getcmdline() and after that
+ * used by other functions.  When invoking getcmdline() recursively it needs
+ * to be saved with save_cmdline() and restored with restore_cmdline().
+ * TODO: make it local to getcmdline() and pass it around. */
+static struct cmdline_info ccline;
 
 static int	cmd_showtail;		/* Only show path tail in lists ? */
 
@@ -238,6 +244,7 @@
     }
 
     ExpandInit(&xpc);
+    ccline.xpc = &xpc;
 
 #ifdef FEAT_RIGHTLEFT
     if (curwin->w_p_rl && *curwin->w_p_rlc == 's'
@@ -408,9 +415,10 @@
 #endif
 
 	/*
-	 * <S-Tab> works like CTRL-P (unless 'wc' is <S-Tab>).
+	 * When there are matching completions to select <S-Tab> works like
+	 * CTRL-P (unless 'wc' is <S-Tab>).
 	 */
-	if (c != p_wc && c == K_S_TAB && xpc.xp_numfiles != -1)
+	if (c != p_wc && c == K_S_TAB && xpc.xp_numfiles > 0)
 	    c = Ctrl_P;
 
 #ifdef FEAT_WILDMENU
@@ -1513,6 +1521,7 @@
 		    int		old_firstc;
 
 		    vim_free(ccline.cmdbuff);
+		    xpc.xp_context = EXPAND_NOTHING;
 		    if (hiscnt == hislen)
 			p = lookfor;	/* back to the old one */
 		    else
@@ -1839,6 +1848,7 @@
 #endif
 
     ExpandCleanup(&xpc);
+    ccline.xpc = NULL;
 
 #ifdef FEAT_SEARCH_EXTRA
     if (did_incsearch)
@@ -1990,8 +2000,8 @@
 
 #if defined(FEAT_AUTOCMD) || defined(PROTO)
 /*
- * Check if "curbuf_lock" is set and return TRUE when it is and give an error
- * message.
+ * Check if "curbuf_lock" or "allbuf_lock" is set and return TRUE when it is
+ * and give an error message.
  */
     int
 curbuf_locked()
@@ -2001,6 +2011,21 @@
 	EMSG(_("E788: Not allowed to edit another buffer now"));
 	return TRUE;
     }
+    return allbuf_locked();
+}
+
+/*
+ * Check if "allbuf_lock" is set and return TRUE when it is and give an error
+ * message.
+ */
+    int
+allbuf_locked()
+{
+    if (allbuf_lock > 0)
+    {
+	EMSG(_("E811: Not allowed to change buffer information now"));
+	return TRUE;
+    }
     return FALSE;
 }
 #endif
@@ -2508,6 +2533,20 @@
     }
     mch_memmove(ccline.cmdbuff, p, (size_t)ccline.cmdlen + 1);
     vim_free(p);
+
+    if (ccline.xpc != NULL
+	    && ccline.xpc->xp_pattern != NULL
+	    && ccline.xpc->xp_context != EXPAND_NOTHING
+	    && ccline.xpc->xp_context != EXPAND_UNSUCCESSFUL)
+    {
+	int i = (int)(ccline.xpc->xp_pattern - p);
+
+	/* If xp_pattern points inside the old cmdbuff it needs to be adjusted
+	 * to point into the newly allocated memory. */
+	if (i >= 0 && i <= ccline.cmdlen)
+	    ccline.xpc->xp_pattern = ccline.cmdbuff + i;
+    }
+
     return OK;
 }
 
@@ -2875,6 +2914,7 @@
     prev_ccline = ccline;
     ccline.cmdbuff = NULL;
     ccline.cmdprompt = NULL;
+    ccline.xpc = NULL;
 }
 
 /*
@@ -3582,6 +3622,7 @@
 ExpandInit(xp)
     expand_T	*xp;
 {
+    xp->xp_pattern = NULL;
     xp->xp_backslash = XP_BS_NONE;
 #ifndef BACKSLASH_IN_FILENAME
     xp->xp_shell = FALSE;
@@ -4871,7 +4912,7 @@
     if (s == NULL)
 	return FAIL;
     sprintf((char *)s, "%s/%s*.vim", dirname, pat);
-    all = globpath(p_rtp, s);
+    all = globpath(p_rtp, s, 0);
     vim_free(s);
     if (all == NULL)
 	return FAIL;
@@ -4912,9 +4953,10 @@
  * newlines.  Returns NULL for an error or no matches.
  */
     char_u *
-globpath(path, file)
+globpath(path, file, expand_options)
     char_u	*path;
     char_u	*file;
+    int		expand_options;
 {
     expand_T	xpc;
     char_u	*buf;
@@ -4943,10 +4985,10 @@
 	{
 	    add_pathsep(buf);
 	    STRCAT(buf, file);
-	    if (ExpandFromContext(&xpc, buf, &num_p, &p, WILD_SILENT) != FAIL
-								 && num_p > 0)
+	    if (ExpandFromContext(&xpc, buf, &num_p, &p,
+			     WILD_SILENT|expand_options) != FAIL && num_p > 0)
 	    {
-		ExpandEscape(&xpc, buf, num_p, p, WILD_SILENT);
+		ExpandEscape(&xpc, buf, num_p, p, WILD_SILENT|expand_options);
 		for (len = 0, i = 0; i < num_p; ++i)
 		    len += (int)STRLEN(p[i]) + 1;
 
@@ -6020,9 +6062,7 @@
 # endif
 	return K_IGNORE;
     }
-    cmdwin_type = ccline.cmdfirstc;
-    if (cmdwin_type == NUL)
-	cmdwin_type = '-';
+    cmdwin_type = get_cmdline_type();
 
     /* Create the command-line buffer empty. */
     (void)do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE);
@@ -6046,7 +6086,7 @@
     /* Showing the prompt may have set need_wait_return, reset it. */
     need_wait_return = FALSE;
 
-    histtype = hist_char2type(ccline.cmdfirstc);
+    histtype = hist_char2type(cmdwin_type);
     if (histtype == HIST_CMD || histtype == HIST_DEBUG)
     {
 	if (p_wc == TAB)
diff -Naur vim72.orig/src/feature.h vim72/src/feature.h
--- vim72.orig/src/feature.h	2008-08-06 04:00:39.000000000 -0700
+++ vim72/src/feature.h	2009-03-12 11:54:40.545495740 -0700
@@ -767,9 +767,13 @@
 
 /*
  * +browse		":browse" command.
+ *			or just the ":browse" command modifier
  */
-#if defined(FEAT_NORMAL) && (defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC))
-# define FEAT_BROWSE
+#if defined(FEAT_NORMAL)
+# define FEAT_BROWSE_CMD
+# if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC)
+#  define FEAT_BROWSE
+# endif
 #endif
 
 /*
diff -Naur vim72.orig/src/fileio.c vim72/src/fileio.c
--- vim72.orig/src/fileio.c	2008-08-06 04:01:03.000000000 -0700
+++ vim72/src/fileio.c	2009-03-12 11:55:18.711941333 -0700
@@ -69,7 +69,7 @@
 static int au_find_group __ARGS((char_u *name));
 
 # define AUGROUP_DEFAULT    -1	    /* default autocmd group */
-# define AUGROUP_ERROR	    -2	    /* errornouse autocmd group */
+# define AUGROUP_ERROR	    -2	    /* erroneous autocmd group */
 # define AUGROUP_ALL	    -3	    /* all autocmd groups */
 #endif
 
@@ -144,7 +144,9 @@
 # endif
 #endif
 static int move_lines __ARGS((buf_T *frombuf, buf_T *tobuf));
-
+#ifdef FEAT_AUTOCMD
+static char *e_auchangedbuf = N_("E812: Autocommands changed buffer or buffer name");
+#endif
 
     void
 filemess(buf, name, s, attr)
@@ -295,6 +297,19 @@
     int		conv_restlen = 0;	/* nr of bytes in conv_rest[] */
 #endif
 
+#ifdef FEAT_AUTOCMD
+    /* Remember the initial values of curbuf, curbuf->b_ffname and
+     * curbuf->b_fname to detect whether they are altered as a result of
+     * executing nasty autocommands.  Also check if "fname" and "sfname"
+     * point to one of these values. */
+    buf_T   *old_curbuf = curbuf;
+    char_u  *old_b_ffname = curbuf->b_ffname;
+    char_u  *old_b_fname = curbuf->b_fname;
+    int     using_b_ffname = (fname == curbuf->b_ffname)
+					      || (sfname == curbuf->b_ffname);
+    int     using_b_fname = (fname == curbuf->b_fname)
+					       || (sfname == curbuf->b_fname);
+#endif
     write_no_eol_lnum = 0;	/* in case it was set by the previous read */
 
     /*
@@ -589,7 +604,21 @@
 #ifdef FEAT_QUICKFIX
 		    if (!bt_dontwrite(curbuf))
 #endif
+		    {
 			check_need_swap(newfile);
+#ifdef FEAT_AUTOCMD
+			/* SwapExists autocommand may mess things up */
+			if (curbuf != old_curbuf
+				|| (using_b_ffname
+					&& (old_b_ffname != curbuf->b_ffname))
+				|| (using_b_fname
+					 && (old_b_fname != curbuf->b_fname)))
+			{
+			    EMSG(_(e_auchangedbuf));
+			    return FAIL;
+			}
+#endif
+		    }
 		    if (dir_of_file_exists(fname))
 			filemess(curbuf, sfname, (char_u *)_("[New File]"), 0);
 		    else
@@ -668,6 +697,17 @@
 #endif
     {
 	check_need_swap(newfile);
+#ifdef FEAT_AUTOCMD
+	if (!read_stdin && (curbuf != old_curbuf
+		|| (using_b_ffname && (old_b_ffname != curbuf->b_ffname))
+		|| (using_b_fname && (old_b_fname != curbuf->b_fname))))
+	{
+	    EMSG(_(e_auchangedbuf));
+	    if (!read_buffer)
+		close(fd);
+	    return FAIL;
+	}
+#endif
 #ifdef UNIX
 	/* Set swap file protection bits after creating it. */
 	if (swap_mode > 0 && curbuf->b_ml.ml_mfp->mf_fname != NULL)
@@ -698,7 +738,6 @@
     {
 	int	m = msg_scroll;
 	int	n = msg_scrolled;
-	buf_T	*old_curbuf = curbuf;
 
 	/*
 	 * The file must be closed again, the autocommands may want to change
@@ -740,8 +779,13 @@
 	/*
 	 * Don't allow the autocommands to change the current buffer.
 	 * Try to re-open the file.
+	 *
+	 * Don't allow the autocommands to change the buffer name either
+	 * (cd for example) if it invalidates fname or sfname.
 	 */
 	if (!read_stdin && (curbuf != old_curbuf
+		|| (using_b_ffname && (old_b_ffname != curbuf->b_ffname))
+		|| (using_b_fname && (old_b_fname != curbuf->b_fname))
 		|| (fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0)) < 0))
 	{
 	    --no_wait_return;
@@ -932,7 +976,10 @@
     else
     {
 	if (eap != NULL && eap->force_ff != 0)
+	{
 	    fileformat = get_fileformat_force(curbuf, eap);
+	    try_unix = try_dos = try_mac = FALSE;
+	}
 	else if (curbuf->b_p_bin)
 	    fileformat = EOL_UNIX;		/* binary: use Unix format */
 	else if (*p_ffs == NUL)
@@ -2211,7 +2258,7 @@
     {
 	/* Use stderr for stdin, makes shell commands work. */
 	close(0);
-	dup(2);
+	ignored = dup(2);
     }
 #endif
 
@@ -2341,11 +2388,6 @@
 		STRCAT(IObuff, _("[CR missing]"));
 		c = TRUE;
 	    }
-	    if (ff_error == EOL_MAC)
-	    {
-		STRCAT(IObuff, _("[NL found]"));
-		c = TRUE;
-	    }
 	    if (split)
 	    {
 		STRCAT(IObuff, _("[long lines split]"));
@@ -2711,7 +2753,7 @@
 {
     if (!curbuf->b_marks_read && get_viminfo_parameter('\'') > 0
 						  && curbuf->b_ffname != NULL)
-	read_viminfo(NULL, FALSE, TRUE, FALSE);
+	read_viminfo(NULL, VIF_WANT_MARKS);
 
     /* Always set b_marks_read; needed when 'viminfo' is changed to include
      * the ' parameter after opening a buffer. */
@@ -3451,7 +3493,7 @@
 		{
 # ifdef UNIX
 #  ifdef HAVE_FCHOWN
-		    fchown(fd, st_old.st_uid, st_old.st_gid);
+		    ignored = fchown(fd, st_old.st_uid, st_old.st_gid);
 #  endif
 		    if (mch_stat((char *)IObuff, &st) < 0
 			    || st.st_uid != st_old.st_uid
@@ -4367,7 +4409,7 @@
 		|| st.st_uid != st_old.st_uid
 		|| st.st_gid != st_old.st_gid)
 	{
-	    fchown(fd, st_old.st_uid, st_old.st_gid);
+	    ignored = fchown(fd, st_old.st_uid, st_old.st_gid);
 	    if (perm >= 0)	/* set permission again, may have changed */
 		(void)mch_setperm(wfname, perm);
 	}
@@ -5246,13 +5288,16 @@
 	    /* Convert with iconv(). */
 	    if (ip->bw_restlen > 0)
 	    {
+		char *fp;
+
 		/* Need to concatenate the remainder of the previous call and
 		 * the bytes of the current call.  Use the end of the
 		 * conversion buffer for this. */
 		fromlen = len + ip->bw_restlen;
-		from = (char *)ip->bw_conv_buf + ip->bw_conv_buflen - fromlen;
-		mch_memmove((void *)from, ip->bw_rest, (size_t)ip->bw_restlen);
-		mch_memmove((void *)(from + ip->bw_restlen), buf, (size_t)len);
+		fp = (char *)ip->bw_conv_buf + ip->bw_conv_buflen - fromlen;
+		mch_memmove(fp, ip->bw_rest, (size_t)ip->bw_restlen);
+		mch_memmove(fp + ip->bw_restlen, buf, (size_t)len);
+		from = fp;
 		tolen = ip->bw_conv_buflen - fromlen;
 	    }
 	    else
@@ -5550,9 +5595,10 @@
 	    name = "ucs-4le";	/* FF FE 00 00 */
 	    len = 4;
 	}
-	else if (flags == FIO_ALL || flags == (FIO_UCS2 | FIO_ENDIAN_L))
+	else if (flags == (FIO_UCS2 | FIO_ENDIAN_L))
 	    name = "ucs-2le";	/* FF FE */
-	else if (flags == (FIO_UTF16 | FIO_ENDIAN_L))
+	else if (flags == FIO_ALL || flags == (FIO_UTF16 | FIO_ENDIAN_L))
+	    /* utf-16le is preferred, it also works for ucs-2le text */
 	    name = "utf-16le";	/* FF FE */
     }
     else if (p[0] == 0xfe && p[1] == 0xff
@@ -6031,9 +6077,9 @@
 	{
 	    tbuf[FGETS_SIZE - 2] = NUL;
 #ifdef USE_CR
-	    fgets_cr((char *)tbuf, FGETS_SIZE, fp);
+	    ignoredp = fgets_cr((char *)tbuf, FGETS_SIZE, fp);
 #else
-	    fgets((char *)tbuf, FGETS_SIZE, fp);
+	    ignoredp = fgets((char *)tbuf, FGETS_SIZE, fp);
 #endif
 	} while (tbuf[FGETS_SIZE - 2] != NUL && tbuf[FGETS_SIZE - 2] != '\n');
     }
@@ -6107,12 +6153,24 @@
 #ifdef HAVE_ACL
     vim_acl_T	acl;		/* ACL from original file */
 #endif
+#if defined(UNIX) || defined(CASE_INSENSITIVE_FILENAME)
+    int		use_tmp_file = FALSE;
+#endif
 
     /*
-     * When the names are identical, there is nothing to do.
+     * When the names are identical, there is nothing to do.  When they refer
+     * to the same file (ignoring case and slash/backslash differences) but
+     * the file name differs we need to go through a temp file.
      */
     if (fnamecmp(from, to) == 0)
-	return 0;
+    {
+#ifdef CASE_INSENSITIVE_FILENAME
+	if (STRCMP(gettail(from), gettail(to)) != 0)
+	    use_tmp_file = TRUE;
+	else
+#endif
+	    return 0;
+    }
 
     /*
      * Fail if the "from" file doesn't exist.  Avoids that "to" is deleted.
@@ -6120,6 +6178,55 @@
     if (mch_stat((char *)from, &st) < 0)
 	return -1;
 
+#ifdef UNIX
+    {
+	struct stat	st_to;
+
+	/* It's possible for the source and destination to be the same file.
+	 * This happens when "from" and "to" differ in case and are on a FAT32
+	 * filesystem.  In that case go through a temp file name. */
+	if (mch_stat((char *)to, &st_to) >= 0
+		&& st.st_dev == st_to.st_dev
+		&& st.st_ino == st_to.st_ino)
+	    use_tmp_file = TRUE;
+    }
+#endif
+
+#if defined(UNIX) || defined(CASE_INSENSITIVE_FILENAME)
+    if (use_tmp_file)
+    {
+	char	tempname[MAXPATHL + 1];
+
+	/*
+	 * Find a name that doesn't exist and is in the same directory.
+	 * Rename "from" to "tempname" and then rename "tempname" to "to".
+	 */
+	if (STRLEN(from) >= MAXPATHL - 5)
+	    return -1;
+	STRCPY(tempname, from);
+	for (n = 123; n < 99999; ++n)
+	{
+	    sprintf((char *)gettail((char_u *)tempname), "%d", n);
+	    if (mch_stat(tempname, &st) < 0)
+	    {
+		if (mch_rename((char *)from, tempname) == 0)
+		{
+		    if (mch_rename(tempname, (char *)to) == 0)
+			return 0;
+		    /* Strange, the second step failed.  Try moving the
+		     * file back and return failure. */
+		    mch_rename(tempname, (char *)from);
+		    return -1;
+		}
+		/* If it fails for one temp name it will most likely fail
+		 * for any temp name, give up. */
+		return -1;
+	    }
+	}
+	return -1;
+    }
+#endif
+
     /*
      * Delete the "to" file, this is required on some systems to make the
      * mch_rename() work, on other systems it makes sure that we don't have
@@ -6260,7 +6367,7 @@
 
     if (!stuff_empty() || global_busy || !typebuf_typed()
 #ifdef FEAT_AUTOCMD
-			|| autocmd_busy || curbuf_lock > 0
+			|| autocmd_busy || curbuf_lock > 0 || allbuf_lock > 0
 #endif
 					)
 	need_check_timestamps = TRUE;		/* check later */
@@ -6462,8 +6569,10 @@
 	    set_vim_var_string(VV_FCS_REASON, (char_u *)reason, -1);
 	    set_vim_var_string(VV_FCS_CHOICE, (char_u *)"", -1);
 # endif
+	    ++allbuf_lock;
 	    n = apply_autocmds(EVENT_FILECHANGEDSHELL,
 				      buf->b_fname, buf->b_fname, FALSE, buf);
+	    --allbuf_lock;
 	    busy = FALSE;
 	    if (n)
 	    {
@@ -8523,6 +8632,7 @@
     char_u	*save_sourcing_name;
     linenr_T	save_sourcing_lnum;
     char_u	*save_autocmd_fname;
+    int		save_autocmd_fname_full;
     int		save_autocmd_bufnr;
     char_u	*save_autocmd_match;
     int		save_autocmd_busy;
@@ -8601,6 +8711,7 @@
      * Save the autocmd_* variables and info about the current buffer.
      */
     save_autocmd_fname = autocmd_fname;
+    save_autocmd_fname_full = autocmd_fname_full;
     save_autocmd_bufnr = autocmd_bufnr;
     save_autocmd_match = autocmd_match;
     save_autocmd_busy = autocmd_busy;
@@ -8618,14 +8729,15 @@
 	if (fname != NULL && *fname != NUL)
 	    autocmd_fname = fname;
 	else if (buf != NULL)
-	    autocmd_fname = buf->b_fname;
+	    autocmd_fname = buf->b_ffname;
 	else
 	    autocmd_fname = NULL;
     }
     else
 	autocmd_fname = fname_io;
     if (autocmd_fname != NULL)
-	autocmd_fname = FullName_save(autocmd_fname, FALSE);
+	autocmd_fname = vim_strsave(autocmd_fname);
+    autocmd_fname_full = FALSE; /* call FullName_save() later */
 
     /*
      * Set the buffer number to be used for <abuf>.
@@ -8810,6 +8922,7 @@
     sourcing_lnum = save_sourcing_lnum;
     vim_free(autocmd_fname);
     autocmd_fname = save_autocmd_fname;
+    autocmd_fname_full = save_autocmd_fname_full;
     autocmd_bufnr = save_autocmd_bufnr;
     autocmd_match = save_autocmd_match;
 #ifdef FEAT_EVAL
@@ -8918,7 +9031,7 @@
     {
 	apc->curpat = NULL;
 
-	/* only use a pattern when it has not been removed, has commands and
+	/* Only use a pattern when it has not been removed, has commands and
 	 * the group matches. For buffer-local autocommands only check the
 	 * buffer number. */
 	if (ap->pat != NULL && ap->cmds != NULL
@@ -9104,7 +9217,7 @@
 set_context_in_autocmd(xp, arg, doautocmd)
     expand_T	*xp;
     char_u	*arg;
-    int		doautocmd;	/* TRUE for :doautocmd, FALSE for :autocmd */
+    int		doautocmd;	/* TRUE for :doauto*, FALSE for :autocmd */
 {
     char_u	*p;
     int		group;
diff -Naur vim72.orig/src/fold.c vim72/src/fold.c
--- vim72.orig/src/fold.c	2008-08-06 04:01:12.000000000 -0700
+++ vim72/src/fold.c	2009-03-12 11:54:59.842732505 -0700
@@ -48,7 +48,7 @@
 static int foldFind __ARGS((garray_T *gap, linenr_T lnum, fold_T **fpp));
 static int foldLevelWin __ARGS((win_T *wp, linenr_T lnum));
 static void checkupdate __ARGS((win_T *wp));
-static void setFoldRepeat __ARGS((linenr_T lnum, long count, int open));
+static void setFoldRepeat __ARGS((linenr_T lnum, long count, int do_open));
 static linenr_T setManualFold __ARGS((linenr_T lnum, int opening, int recurse, int *donep));
 static linenr_T setManualFoldWin __ARGS((win_T *wp, linenr_T lnum, int opening, int recurse, int *donep));
 static void foldOpenNested __ARGS((fold_T *fpr));
@@ -740,7 +740,7 @@
     garray_T	*found_ga;
     fold_T	*found_fp = NULL;
     linenr_T	found_off = 0;
-    int		use_level = FALSE;
+    int		use_level;
     int		maybe_small = FALSE;
     int		level = 0;
     linenr_T	lnum = start;
@@ -757,6 +757,7 @@
 	gap = &curwin->w_folds;
 	found_ga = NULL;
 	lnum_off = 0;
+	use_level = FALSE;
 	for (;;)
 	{
 	    if (!foldFind(gap, lnum - lnum_off, &fp))
@@ -783,20 +784,21 @@
 	else
 	{
 	    lnum = found_fp->fd_top + found_fp->fd_len + found_off;
-	    did_one = TRUE;
 
 	    if (foldmethodIsManual(curwin))
 		deleteFoldEntry(found_ga,
 		    (int)(found_fp - (fold_T *)found_ga->ga_data), recursive);
 	    else
 	    {
-		if (found_fp->fd_top + found_off < first_lnum)
-		    first_lnum = found_fp->fd_top;
-		if (lnum > last_lnum)
+		if (first_lnum > found_fp->fd_top + found_off)
+		    first_lnum = found_fp->fd_top + found_off;
+		if (last_lnum < lnum)
 		    last_lnum = lnum;
-		parseMarker(curwin);
+		if (!did_one)
+		    parseMarker(curwin);
 		deleteFoldMarkers(found_fp, recursive, found_off);
 	    }
+	    did_one = TRUE;
 
 	    /* redraw window */
 	    changed_window_setting();
@@ -811,6 +813,10 @@
 	    redraw_curbuf_later(INVERTED);
 #endif
     }
+    else
+	/* Deleting markers may make cursor column invalid. */
+	check_cursor_col();
+
     if (last_lnum > 0)
 	changed_lines(first_lnum, (colnr_T)0, last_lnum, 0L);
 }
@@ -1241,10 +1247,10 @@
  * Repeat "count" times.
  */
     static void
-setFoldRepeat(lnum, count, open)
+setFoldRepeat(lnum, count, do_open)
     linenr_T	lnum;
     long	count;
-    int		open;
+    int		do_open;
 {
     int		done;
     long	n;
@@ -1252,7 +1258,7 @@
     for (n = 0; n < count; ++n)
     {
 	done = DONE_NOTHING;
-	(void)setManualFold(lnum, open, FALSE, &done);
+	(void)setManualFold(lnum, do_open, FALSE, &done);
 	if (!(done & DONE_ACTION))
 	{
 	    /* Only give an error message when no fold could be opened. */
diff -Naur vim72.orig/src/getchar.c vim72/src/getchar.c
--- vim72.orig/src/getchar.c	2008-07-22 09:57:48.000000000 -0700
+++ vim72/src/getchar.c	2009-03-12 11:55:13.579612236 -0700
@@ -3816,7 +3816,11 @@
     int len = 1;
 
     if (msg_didout || msg_silent != 0)
+    {
 	msg_putchar('\n');
+	if (got_int)	    /* 'q' typed at MORE prompt */
+	    return;
+    }
     if ((mp->m_mode & (INSERT + CMDLINE)) == INSERT + CMDLINE)
 	msg_putchar('!');			/* :map! */
     else if (mp->m_mode & INSERT)
@@ -4702,7 +4706,7 @@
 			return FAIL;
 		    if (mp->m_noremap != REMAP_YES && fprintf(fd, "nore") < 0)
 			return FAIL;
-		    if (fprintf(fd, cmd) < 0)
+		    if (fputs(cmd, fd) < 0)
 			return FAIL;
 		    if (buf != NULL && fputs(" <buffer>", fd) < 0)
 			return FAIL;
@@ -4801,7 +4805,7 @@
 	    }
 	    if (IS_SPECIAL(c) || modifiers)	/* special key */
 	    {
-		if (fprintf(fd, (char *)get_special_key_name(c, modifiers)) < 0)
+		if (fputs((char *)get_special_key_name(c, modifiers), fd) < 0)
 		    return FAIL;
 		continue;
 	    }
diff -Naur vim72.orig/src/globals.h vim72/src/globals.h
--- vim72.orig/src/globals.h	2008-07-26 04:53:29.000000000 -0700
+++ vim72/src/globals.h	2009-03-12 11:55:13.699620338 -0700
@@ -482,8 +482,10 @@
 /*
  * While executing external commands or in Ex mode, should not insert GUI
  * events in the input buffer: Set hold_gui_events to non-zero.
+ *
+ * volatile because it is used in signal handler sig_sysmouse().
  */
-EXTERN int	hold_gui_events INIT(= 0);
+EXTERN volatile int hold_gui_events INIT(= 0);
 
 /*
  * When resizing the shell is postponed, remember the new size, and call
@@ -597,7 +599,8 @@
 EXTERN int	really_exiting INIT(= FALSE);
 				/* TRUE when we are sure to exit, e.g., after
 				 * a deadly signal */
-EXTERN int	full_screen INIT(= FALSE);
+/* volatile because it is used in signal handler deathtrap(). */
+EXTERN volatile int full_screen INIT(= FALSE);
 				/* TRUE when doing full-screen output
 				 * otherwise only writing some messages */
 
@@ -616,6 +619,11 @@
 EXTERN int	curbuf_lock INIT(= 0);
 				/* non-zero when the current buffer can't be
 				 * changed.  Used for FileChangedRO. */
+EXTERN int	allbuf_lock INIT(= 0);
+				/* non-zero when no buffer name can be
+				 * changed, no buffer can be deleted and
+				 * current directory can't be changed.
+				 * Used for SwapExists et al. */
 #endif
 #ifdef FEAT_EVAL
 # define HAVE_SANDBOX
@@ -739,10 +747,12 @@
  */
 EXTERN JMP_BUF lc_jump_env;	/* argument to SETJMP() */
 # ifdef SIGHASARG
-EXTERN int lc_signal;		/* catched signal number, 0 when no was signal
-				   catched; used for mch_libcall() */
+/* volatile because it is used in signal handlers. */
+EXTERN volatile int lc_signal;	/* caught signal number, 0 when no was signal
+				   caught; used for mch_libcall() */
 # endif
-EXTERN int lc_active INIT(= FALSE); /* TRUE when lc_jump_env is valid. */
+/* volatile because it is used in signal handler deathtrap(). */
+EXTERN volatile int lc_active INIT(= FALSE); /* TRUE when lc_jump_env is valid. */
 #endif
 
 #if defined(FEAT_MBYTE) || defined(FEAT_POSTSCRIPT)
@@ -986,7 +996,8 @@
 EXTERN FILE	*scriptout  INIT(= NULL);   /* stream to write script to */
 EXTERN int	read_cmd_fd INIT(= 0);	    /* fd to read commands from */
 
-EXTERN int	got_int INIT(= FALSE);	    /* set to TRUE when interrupt
+/* volatile because it is used in signal handler catch_sigint(). */
+EXTERN volatile int got_int INIT(= FALSE);    /* set to TRUE when interrupt
 						signal occurred */
 #ifdef USE_TERM_CONSOLE
 EXTERN int	term_console INIT(= FALSE); /* set to TRUE when console used */
@@ -1022,6 +1033,7 @@
 #endif
 #ifdef FEAT_AUTOCMD
 EXTERN char_u	*autocmd_fname INIT(= NULL); /* fname for <afile> on cmdline */
+EXTERN int	autocmd_fname_full;	     /* autocmd_fname is full path */
 EXTERN int	autocmd_bufnr INIT(= 0);     /* fnum for <abuf> on cmdline */
 EXTERN char_u	*autocmd_match INIT(= NULL); /* name for <amatch> on cmdline */
 EXTERN int	did_cursorhold INIT(= FALSE); /* set when CursorHold t'gerd */
@@ -1339,7 +1351,6 @@
 
 #ifdef FEAT_NETBEANS_INTG
 EXTERN char *netbeansArg INIT(= NULL);	/* the -nb[:host:port:passwd] arg */
-EXTERN int netbeansCloseFile INIT(= 0);	/* send killed if != 0 */
 EXTERN int netbeansFireChanges INIT(= 1); /* send buffer changes if != 0 */
 EXTERN int netbeansForcedQuit INIT(= 0);/* don't write modified files */
 EXTERN int netbeansReadFile INIT(= 1);	/* OK to read from disk if != 0 */
@@ -1548,6 +1559,14 @@
 EXTERN time_t starttime;
 
 /*
+ * Some compilers warn for not using a return value, but in some situations we
+ * can't do anything useful with the value.  Assign to this variable to avoid
+ * the warning.
+ */
+EXTERN int ignored;
+EXTERN char *ignoredp;
+
+/*
  * Optional Farsi support.  Include it here, so EXTERN and INIT are defined.
  */
 #ifdef FEAT_FKMAP
diff -Naur vim72.orig/src/gui_at_sb.c vim72/src/gui_at_sb.c
--- vim72.orig/src/gui_at_sb.c	2004-06-07 07:32:25.000000000 -0700
+++ vim72/src/gui_at_sb.c	2009-03-12 11:54:50.138110630 -0700
@@ -1078,6 +1078,12 @@
     Cardinal	*num_params;	/* unused */
 {
     ScrollbarWidget sbw = (ScrollbarWidget)w;
+    /* Use a union to avoid a warning for the weird conversion from float to
+     * XtPointer.  Comes from Xaw/Scrollbar.c. */
+    union {
+	XtPointer xtp;
+	float xtf;
+    } xtpf;
 
     if (LookAhead(w, event))
 	return;
@@ -1085,7 +1091,8 @@
     /* thumbProc is not pretty, but is necessary for backwards
        compatibility on those architectures for which it work{s,ed};
        the intent is to pass a (truncated) float by value. */
-    XtCallCallbacks(w, XtNthumbProc, *(XtPointer*)&sbw->scrollbar.top);
+    xtpf.xtf = sbw->scrollbar.top;
+    XtCallCallbacks(w, XtNthumbProc, xtpf.xtp);
     XtCallCallbacks(w, XtNjumpProc, (XtPointer)&sbw->scrollbar.top);
 }
 
diff -Naur vim72.orig/src/gui.c vim72/src/gui.c
--- vim72.orig/src/gui.c	2008-07-27 12:32:14.000000000 -0700
+++ vim72/src/gui.c	2009-03-12 11:54:50.298121805 -0700
@@ -139,7 +139,7 @@
 		/* The read returns when the child closes the pipe (or when
 		 * the child dies for some reason). */
 		close(pipefd[1]);
-		(void)read(pipefd[0], &dummy, (size_t)1);
+		ignored = (int)read(pipefd[0], &dummy, (size_t)1);
 		close(pipefd[0]);
 	    }
 
@@ -3241,7 +3241,7 @@
 	    i = Rows;
 	    gui_update_tabline();
 	    Rows = i;
-	    need_set_size = RESIZE_VERT;
+	    need_set_size |= RESIZE_VERT;
 	    if (using_tabline)
 		fix_size = TRUE;
 	    if (!gui_use_tabline())
@@ -3275,9 +3275,9 @@
 		if (gui.which_scrollbars[i] != prev_which_scrollbars[i])
 		{
 		    if (i == SBAR_BOTTOM)
-			need_set_size = RESIZE_VERT;
+			need_set_size |= RESIZE_VERT;
 		    else
-			need_set_size = RESIZE_HOR;
+			need_set_size |= RESIZE_HOR;
 		    if (gui.which_scrollbars[i])
 			fix_size = TRUE;
 		}
@@ -3297,7 +3297,7 @@
 	    gui_mch_enable_menu(gui.menu_is_active);
 	    Rows = i;
 	    prev_menu_is_active = gui.menu_is_active;
-	    need_set_size = RESIZE_VERT;
+	    need_set_size |= RESIZE_VERT;
 	    if (gui.menu_is_active)
 		fix_size = TRUE;
 	}
@@ -3308,7 +3308,7 @@
 	{
 	    gui_mch_show_toolbar(using_toolbar);
 	    prev_toolbar = using_toolbar;
-	    need_set_size = RESIZE_VERT;
+	    need_set_size |= RESIZE_VERT;
 	    if (using_toolbar)
 		fix_size = TRUE;
 	}
@@ -3318,7 +3318,7 @@
 	{
 	    gui_mch_enable_footer(using_footer);
 	    prev_footer = using_footer;
-	    need_set_size = RESIZE_VERT;
+	    need_set_size |= RESIZE_VERT;
 	    if (using_footer)
 		fix_size = TRUE;
 	}
@@ -3330,10 +3330,11 @@
 	    prev_tearoff = using_tearoff;
 	}
 #endif
-	if (need_set_size)
+	if (need_set_size != 0)
 	{
 #ifdef FEAT_GUI_GTK
-	    long    c = Columns;
+	    long    prev_Columns = Columns;
+	    long    prev_Rows = Rows;
 #endif
 	    /* Adjust the size of the window to make the text area keep the
 	     * same size and to avoid that part of our window is off-screen
@@ -3349,11 +3350,14 @@
 	     * If you remove this, please test this command for resizing
 	     * effects (with optional left scrollbar): ":vsp|q|vsp|q|vsp|q".
 	     * Don't do this while starting up though.
-	     * And don't change Rows, it may have be reduced intentionally
-	     * when adding menu/toolbar/tabline. */
-	    if (!gui.starting)
+	     * Don't change Rows when adding menu/toolbar/tabline.
+	     * Don't change Columns when adding vertical toolbar. */
+	    if (!gui.starting && need_set_size != (RESIZE_VERT | RESIZE_HOR))
 		(void)char_avail();
-	    Columns = c;
+	    if ((need_set_size & RESIZE_VERT) == 0)
+		Rows = prev_Rows;
+	    if ((need_set_size & RESIZE_HOR) == 0)
+		Columns = prev_Columns;
 #endif
 	}
 #ifdef FEAT_WINDOWS
diff -Naur vim72.orig/src/gui_gtk_x11.c vim72/src/gui_gtk_x11.c
--- vim72.orig/src/gui_gtk_x11.c	2008-07-04 03:46:24.000000000 -0700
+++ vim72/src/gui_gtk_x11.c	2009-03-12 11:54:50.138110630 -0700
@@ -4070,14 +4070,14 @@
 
 	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();
+	    int ww, hh;
+	    gui_mch_get_screen_dimensions(&ww, &hh);
+	    hh += p_ghr + get_menu_tool_height();
+	    ww += get_menu_tool_width();
 	    if (mask & XNegative)
-		x += w - pixel_width;
+		x += ww - pixel_width;
 	    if (mask & YNegative)
-		y += h - pixel_height;
+		y += hh - pixel_height;
 #ifdef HAVE_GTK2
 	    gtk_window_move(GTK_WINDOW(gui.mainwin), x, y);
 #else
diff -Naur vim72.orig/src/gui_x11.c vim72/src/gui_x11.c
--- vim72.orig/src/gui_x11.c	2008-06-08 08:13:45.000000000 -0700
+++ vim72/src/gui_x11.c	2009-03-12 11:55:13.599613075 -0700
@@ -1587,6 +1587,8 @@
     XtCloseDisplay(gui.dpy);
     gui.dpy = NULL;
     vimShell = (Widget)0;
+    vim_free(gui_argv);
+    gui_argv = NULL;
 }
 
 /*
@@ -1761,6 +1763,8 @@
      * says that this isn't needed when exiting, so just skip it. */
     XtCloseDisplay(gui.dpy);
 #endif
+    vim_free(gui_argv);
+    gui_argv = NULL;
 }
 
 /*
@@ -2450,7 +2454,7 @@
 	*colorPtr = colortable[closest];
     }
 
-    free(colortable);
+    vim_free(colortable);
     return OK;
 }
 
@@ -3439,47 +3443,37 @@
     char_u	    *signfile;
 {
     XpmAttributes   attrs;
-    XImage	    *sign;
+    XImage	    *sign = NULL;
     int		    status;
 
     /*
      * Setup the color substitution table.
      */
-    sign = NULL;
     if (signfile[0] != NUL && signfile[0] != '-')
     {
-	sign = (XImage *)alloc(sizeof(XImage));
-	if (sign != NULL)
+	XpmColorSymbol color[5] =
 	{
-	    XpmColorSymbol color[5] =
-	    {
-		{"none", NULL, 0},
-		{"iconColor1", NULL, 0},
-		{"bottomShadowColor", NULL, 0},
-		{"topShadowColor", NULL, 0},
-		{"selectColor", NULL, 0}
-	    };
-	    attrs.valuemask = XpmColorSymbols;
-	    attrs.numsymbols = 2;
-	    attrs.colorsymbols = color;
-	    attrs.colorsymbols[0].pixel = gui.back_pixel;
-	    attrs.colorsymbols[1].pixel = gui.norm_pixel;
-	    status = XpmReadFileToImage(gui.dpy, (char *)signfile,
+	    {"none", NULL, 0},
+	    {"iconColor1", NULL, 0},
+	    {"bottomShadowColor", NULL, 0},
+	    {"topShadowColor", NULL, 0},
+	    {"selectColor", NULL, 0}
+	};
+	attrs.valuemask = XpmColorSymbols;
+	attrs.numsymbols = 2;
+	attrs.colorsymbols = color;
+	attrs.colorsymbols[0].pixel = gui.back_pixel;
+	attrs.colorsymbols[1].pixel = gui.norm_pixel;
+	status = XpmReadFileToImage(gui.dpy, (char *)signfile,
 							 &sign, NULL, &attrs);
-
-	    if (status == 0)
-	    {
-		/* Sign width is fixed at two columns now.
-		if (sign->width > gui.sign_width)
-		    gui.sign_width = sign->width + 8; */
-	    }
-	    else
-	    {
-		vim_free(sign);
-		sign = NULL;
-		EMSG(_(e_signdata));
-	    }
+	if (status == 0)
+	{
+	    /* Sign width is fixed at two columns now.
+	    if (sign->width > gui.sign_width)
+	        gui.sign_width = sign->width + 8; */
 	}
+	else
+	    EMSG(_(e_signdata));
     }
 
     return (void *)sign;
@@ -3489,8 +3483,7 @@
 gui_mch_destroy_sign(sign)
     void *sign;
 {
-    XFree(((XImage *)sign)->data);
-    vim_free(sign);
+    XDestroyImage((XImage*)sign);
 }
 #endif
 
diff -Naur vim72.orig/src/gui_xmdlg.c vim72/src/gui_xmdlg.c
--- vim72.orig/src/gui_xmdlg.c	2008-06-21 09:05:32.000000000 -0700
+++ vim72/src/gui_xmdlg.c	2009-03-12 11:54:50.142110910 -0700
@@ -369,10 +369,10 @@
     char	buf[TEMP_BUF_SIZE];
     XmString	items[MAX_ENTRIES_IN_LIST];
     int		i;
-    int		index;
+    int		idx;
 
-    for (index = (int)ENCODING; index < (int)NONE; ++index)
-	count[index] = 0;
+    for (idx = (int)ENCODING; idx < (int)NONE; ++idx)
+	count[idx] = 0;
 
     /* First we insert the wild char into every single list. */
     if (fix != ENCODING)
@@ -503,14 +503,14 @@
     /*
      * Now loop trough the remaining lists and set them up.
      */
-    for (index = (int)NAME; index < (int)NONE; ++index)
+    for (idx = (int)NAME; idx < (int)NONE; ++idx)
     {
 	Widget w;
 
-	if (fix == (enum ListSpecifier)index)
+	if (fix == (enum ListSpecifier)idx)
 	    continue;
 
-	switch ((enum ListSpecifier)index)
+	switch ((enum ListSpecifier)idx)
 	{
 	    case NAME:
 		w = data->list[NAME];
@@ -525,21 +525,21 @@
 		w = (Widget)0;	/* for lint */
 	}
 
-	for (i = 0; i < count[index]; ++i)
+	for (i = 0; i < count[idx]; ++i)
 	{
-	    items[i] = XmStringCreateLocalized(list[index][i]);
-	    XtFree(list[index][i]);
+	    items[i] = XmStringCreateLocalized(list[idx][i]);
+	    XtFree(list[idx][i]);
 	}
 	XmListDeleteAllItems(w);
-	XmListAddItems(w, items, count[index], 1);
-	if (data->sel[index])
+	XmListAddItems(w, items, count[idx], 1);
+	if (data->sel[idx])
 	{
 	    XmStringFree(items[0]);
-	    items[0] = XmStringCreateLocalized(data->sel[index]);
+	    items[0] = XmStringCreateLocalized(data->sel[idx]);
 	    XmListSelectItem(w, items[0], False);
 	    XmListSetBottomItem(w, items[0]);
 	}
-	for (i = 0; i < count[index]; ++i)
+	for (i = 0; i < count[idx]; ++i)
 	    XmStringFree(items[i]);
     }
 }
@@ -695,14 +695,14 @@
 	int	    n;
 	XmString    str;
 	Arg	    args[4];
-	char	    *msg = _("no specific match");
+	char	    *nomatch_msg = _("no specific match");
 
 	n = 0;
-	str = XmStringCreateLocalized(msg);
+	str = XmStringCreateLocalized(nomatch_msg);
 	XtSetArg(args[n], XmNlabelString, str); ++n;
 	XtSetValues(data->sample, args, n);
 	apply_fontlist(data->sample);
-	XmTextSetString(data->name, msg);
+	XmTextSetString(data->name, nomatch_msg);
 	XmStringFree(str);
 
 	return False;
@@ -886,21 +886,21 @@
     {
 	int	i;
 	int	max;
-	int	index = 0;
+	int	idx = 0;
 	int	size;
-	char	str[128];
+	char	buf[128];
 
 	for (i = 0, max = 0; i < data->num; i++)
 	{
-	    get_part(fn(data, i), 7, str);
-	    size = atoi(str);
+	    get_part(fn(data, i), 7, buf);
+	    size = atoi(buf);
 	    if ((size > max) && (size < MAX_DISPLAY_SIZE))
 	    {
-		index = i;
+		idx = i;
 		max = size;
 	    }
 	}
-	strcpy(big_font, fn(data, index));
+	strcpy(big_font, fn(data, idx));
     }
     data->old = XLoadQueryFont(XtDisplay(parent), big_font);
     data->old_list = gui_motif_create_fontlist(data->old);
@@ -1217,28 +1217,28 @@
 
 	if (i != 0)
 	{
-	    char name[TEMP_BUF_SIZE];
-	    char style[TEMP_BUF_SIZE];
-	    char size[TEMP_BUF_SIZE];
-	    char encoding[TEMP_BUF_SIZE];
+	    char namebuf[TEMP_BUF_SIZE];
+	    char stylebuf[TEMP_BUF_SIZE];
+	    char sizebuf[TEMP_BUF_SIZE];
+	    char encodingbuf[TEMP_BUF_SIZE];
 	    char *found;
 
 	    found = names[0];
 
-	    name_part(found, name);
-	    style_part(found, style);
-	    size_part(found, size, data->in_pixels);
-	    encoding_part(found, encoding);
-
-	    if (strlen(name) > 0
-		    && strlen(style) > 0
-		    && strlen(size) > 0
-		    && strlen(encoding) > 0)
+	    name_part(found, namebuf);
+	    style_part(found, stylebuf);
+	    size_part(found, sizebuf, data->in_pixels);
+	    encoding_part(found, encodingbuf);
+
+	    if (strlen(namebuf) > 0
+		    && strlen(stylebuf) > 0
+		    && strlen(sizebuf) > 0
+		    && strlen(encodingbuf) > 0)
 	    {
-		data->sel[NAME] = XtNewString(name);
-		data->sel[STYLE] = XtNewString(style);
-		data->sel[SIZE] = XtNewString(size);
-		data->sel[ENCODING] = XtNewString(encoding);
+		data->sel[NAME] = XtNewString(namebuf);
+		data->sel[STYLE] = XtNewString(stylebuf);
+		data->sel[SIZE] = XtNewString(sizebuf);
+		data->sel[ENCODING] = XtNewString(encodingbuf);
 		data->font_name = XtNewString(names[0]);
 		display_sample(data);
 		XmTextSetString(data->name, data->font_name);
diff -Naur vim72.orig/src/gui_xmebw.c vim72/src/gui_xmebw.c
--- vim72.orig/src/gui_xmebw.c	2007-09-06 03:57:51.000000000 -0700
+++ vim72/src/gui_xmebw.c	2009-03-12 11:54:50.142110910 -0700
@@ -1256,7 +1256,7 @@
     }
     else
     {
-	int adjust = 0;
+	adjust = 0;
 
 #if !defined(LESSTIF_VERSION) && (XmVersion > 1002)
 	/*
@@ -1268,12 +1268,11 @@
 	{
 	    case XmEXTERNAL_HIGHLIGHT:
 		adjust = (eb->primitive.highlight_thickness -
-			(eb->pushbutton.default_button_shadow_thickness ?
-			 Xm3D_ENHANCE_PIXEL : 0));
+			 (eb->pushbutton.default_button_shadow_thickness
+			  ?  Xm3D_ENHANCE_PIXEL : 0));
 		break;
 
 	    case XmINTERNAL_HIGHLIGHT:
-		adjust = 0;
 		break;
 
 	    default:
diff -Naur vim72.orig/src/if_cscope.c vim72/src/if_cscope.c
--- vim72.orig/src/if_cscope.c	2008-06-24 09:32:34.000000000 -0700
+++ vim72/src/if_cscope.c	2009-03-12 11:55:05.383086185 -0700
@@ -74,7 +74,7 @@
     { "add",	cs_add,
 		N_("Add a new database"),     "add file|dir [pre-path] [flags]", 0 },
     { "find",	cs_find,
-		N_("Query for a pattern"),    FIND_USAGE, 1 },
+		N_("Query for a pattern"),    "find c|d|e|f|g|i|s|t name", 1 },
     { "help",	cs_help,
 		N_("Show this message"),      "help", 0 },
     { "kill",	cs_kill,
@@ -1177,10 +1177,27 @@
     (void)MSG_PUTS(_("cscope commands:\n"));
     while (cmdp->name != NULL)
     {
-	(void)smsg((char_u *)_("%-5s: %-30s (Usage: %s)"),
-				      cmdp->name, _(cmdp->help), cmdp->usage);
+	char *help = _(cmdp->help);
+	int  space_cnt = 30 - vim_strsize((char_u *)help);
+
+	/* Use %*s rather than %30s to ensure proper alignment in utf-8 */
+	if (space_cnt < 0)
+	    space_cnt = 0;
+	(void)smsg((char_u *)_("%-5s: %s%*s (Usage: %s)"),
+				      cmdp->name,
+				      help, space_cnt, " ",
+				      cmdp->usage);
 	if (strcmp(cmdp->name, "find") == 0)
-	    MSG_PUTS(FIND_HELP);
+	    MSG_PUTS(_("\n"
+		       "       c: Find functions calling this function\n"
+		       "       d: Find functions called by this function\n"
+		       "       e: Find this egrep pattern\n"
+		       "       f: Find this file\n"
+		       "       g: Find this definition\n"
+		       "       i: Find files #including this file\n"
+		       "       s: Find this C symbol\n"
+		       "       t: Find assignments to\n"));
+
 	cmdp++;
     }
 
diff -Naur vim72.orig/src/if_cscope.h vim72/src/if_cscope.h
--- vim72.orig/src/if_cscope.h	2007-09-02 07:51:08.000000000 -0700
+++ vim72/src/if_cscope.h	2009-03-12 11:54:28.876748429 -0700
@@ -42,17 +42,6 @@
  * f 7name	Find this file
  * i 8name	Find files #including this file
  */
-#define	FIND_USAGE "find c|d|e|f|g|i|s|t name"
-#define FIND_HELP "\n\
-       c: Find functions calling this function\n\
-       d: Find functions called by this function\n\
-       e: Find this egrep pattern\n\
-       f: Find this file\n\
-       g: Find this definition\n\
-       i: Find files #including this file\n\
-       s: Find this C symbol\n\
-       t: Find assignments to\n"
-
 
 typedef struct {
     char *  name;
diff -Naur vim72.orig/src/if_perl.xs vim72/src/if_perl.xs
--- vim72.orig/src/if_perl.xs	2008-07-17 13:55:09.000000000 -0700
+++ vim72/src/if_perl.xs	2009-03-12 11:54:50.278119291 -0700
@@ -136,6 +136,9 @@
 #  define Perl_newXS_flags dll_Perl_newXS_flags
 #endif
 # define Perl_sv_free dll_Perl_sv_free
+# if (PERL_REVISION == 5) && (PERL_VERSION >= 10)
+#  define Perl_sv_free2 dll_Perl_sv_free2
+# endif
 # define Perl_sv_isa dll_Perl_sv_isa
 # define Perl_sv_magic dll_Perl_sv_magic
 # define Perl_sv_setiv dll_Perl_sv_setiv
@@ -163,7 +166,7 @@
 # define Perl_Isv_yes_ptr dll_Perl_Isv_yes_ptr
 # define boot_DynaLoader dll_boot_DynaLoader
 
-# define Perl_sys_init3 dll_Perl_sys_init3
+# define Perl_sys_init dll_Perl_sys_init
 # define Perl_sys_term dll_Perl_sys_term
 # define Perl_ISv_ptr dll_Perl_ISv_ptr
 # define Perl_Istack_max_ptr dll_Perl_Istack_max_ptr
@@ -268,7 +271,8 @@
 static void (*boot_DynaLoader)_((pTHX_ CV*));
 
 #if (PERL_REVISION == 5) && (PERL_VERSION >= 10)
-static void (*Perl_sys_init3)(int* argc, char*** argv, char*** env);
+static void (*Perl_sv_free2)(pTHX_ SV*);
+static void (*Perl_sys_init)(int* argc, char*** argv);
 static void (*Perl_sys_term)(void);
 static SV** (*Perl_ISv_ptr)(register PerlInterpreter*);
 static SV*** (*Perl_Istack_max_ptr)(register PerlInterpreter*);
@@ -367,7 +371,8 @@
     {"Perl_TXpv_ptr", (PERL_PROC*)&Perl_TXpv_ptr},
     {"Perl_Tna_ptr", (PERL_PROC*)&Perl_Tna_ptr},
 #else
-    {"Perl_sys_init3", (PERL_PROC*)&Perl_sys_init3},
+    {"Perl_sv_free2", (PERL_PROC*)&Perl_sv_free2},
+    {"Perl_sys_init", (PERL_PROC*)&Perl_sys_init},
     {"Perl_sys_term", (PERL_PROC*)&Perl_sys_term},
     {"Perl_ISv_ptr", (PERL_PROC*)&Perl_ISv_ptr},
     {"Perl_Istack_sp_ptr", (PERL_PROC*)&Perl_Istack_sp_ptr},
@@ -455,7 +460,7 @@
     static char *argv[] = { "", "-e", "" };
 
 #if (PERL_REVISION == 5) && (PERL_VERSION >= 10)
-    Perl_sys_init3(&argc, (char***)&argv, NULL);
+    Perl_sys_init(&argc, (char***)&argv);
 #endif
     perl_interp = perl_alloc();
     perl_construct(perl_interp);
diff -Naur vim72.orig/src/if_python.c vim72/src/if_python.c
--- vim72.orig/src/if_python.c	2008-07-17 14:09:32.000000000 -0700
+++ vim72/src/if_python.c	2009-03-12 11:54:59.902735857 -0700
@@ -531,6 +531,12 @@
 	if (PythonMod_Init())
 	    goto fail;
 
+	/* Remove the element from sys.path that was added because of our
+	 * argv[0] value in PythonMod_Init().  Previously we used an empty
+	 * string, but dependinding on the OS we then get an empty entry or
+	 * the current directory in sys.path. */
+	PyRun_SimpleString("import sys; sys.path = filter(lambda x: x != '/must>not&exist', sys.path)");
+
 	/* the first python thread is vim's, release the lock */
 	Python_SaveThread();
 
@@ -1145,14 +1151,23 @@
 
     /* Check if we run into a recursive loop.  The item must be in lookupDict
      * then and we can use it again. */
-    sprintf(ptrBuf, PRINTF_DECIMAL_LONG_U, (long_u)our_tv);
-    result = PyDict_GetItemString(lookupDict, ptrBuf);
-    if (result != NULL)
-	Py_INCREF(result);
-    else if (our_tv->v_type == VAR_STRING)
+    if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL)
+	    || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL))
+    {
+	sprintf(ptrBuf, PRINTF_DECIMAL_LONG_U,
+	        our_tv->v_type == VAR_LIST ? (long_u)our_tv->vval.v_list
+		                           : (long_u)our_tv->vval.v_dict);
+	result = PyDict_GetItemString(lookupDict, ptrBuf);
+	if (result != NULL)
+	{
+	    Py_INCREF(result);
+	    return result;
+	}
+    }
+
+    if (our_tv->v_type == VAR_STRING)
     {
 	result = Py_BuildValue("s", our_tv->vval.v_string);
-	PyDict_SetItemString(lookupDict, ptrBuf, result);
     }
     else if (our_tv->v_type == VAR_NUMBER)
     {
@@ -1161,7 +1176,6 @@
 	/* For backwards compatibility numbers are stored as strings. */
 	sprintf(buf, "%ld", (long)our_tv->vval.v_number);
 	result = Py_BuildValue("s", buf);
-	PyDict_SetItemString(lookupDict, ptrBuf, result);
     }
 # ifdef FEAT_FLOAT
     else if (our_tv->v_type == VAR_FLOAT)
@@ -1170,7 +1184,6 @@
 
 	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)
@@ -1179,10 +1192,11 @@
 	listitem_T	*curr;
 
 	result = PyList_New(0);
-	PyDict_SetItemString(lookupDict, ptrBuf, result);
 
 	if (list != NULL)
 	{
+	    PyDict_SetItemString(lookupDict, ptrBuf, result);
+
 	    for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
 	    {
 		newObj = VimToPython(&curr->li_tv, depth + 1, lookupDict);
@@ -1194,7 +1208,6 @@
     else if (our_tv->v_type == VAR_DICT)
     {
 	result = PyDict_New();
-	PyDict_SetItemString(lookupDict, ptrBuf, result);
 
 	if (our_tv->vval.v_dict != NULL)
 	{
@@ -1203,6 +1216,8 @@
 	    hashitem_T	*hi;
 	    dictitem_T	*di;
 
+	    PyDict_SetItemString(lookupDict, ptrBuf, result);
+
 	    for (hi = ht->ht_array; todo > 0; ++hi)
 	    {
 		if (!HASHITEM_EMPTY(hi))
@@ -2345,7 +2360,8 @@
 {
     PyObject *mod;
     PyObject *dict;
-    static char *(argv[2]) = {"", NULL};
+    /* The special value is removed from sys.path in Python_Init(). */
+    static char *(argv[2]) = {"/must>not&exist/foo", NULL};
 
     /* Fixups... */
     BufferType.ob_type = &PyType_Type;
diff -Naur vim72.orig/src/if_xcmdsrv.c vim72/src/if_xcmdsrv.c
--- vim72.orig/src/if_xcmdsrv.c	2008-07-18 06:05:03.000000000 -0700
+++ vim72/src/if_xcmdsrv.c	2009-03-12 11:54:43.269670345 -0700
@@ -736,7 +736,7 @@
 		+ serverReply.ga_len;
 	    e.id = w;
 	    ga_init2(&e.strings, 1, 100);
-	    memcpy(p, &e, sizeof(e));
+	    mch_memmove(p, &e, sizeof(e));
 	    serverReply.ga_len++;
 	}
     }
@@ -1018,7 +1018,7 @@
 	p++;
 	count = numItems - (p - regProp);
 	if (count > 0)
-	    memcpy(entry, p, count);
+	    mch_memmove(entry, p, count);
 	XChangeProperty(dpy, RootWindow(dpy, 0), registryProperty, XA_STRING,
 			8, PropModeReplace, regProp,
 			(int)(numItems - (p - entry)));
@@ -1072,7 +1072,7 @@
 		p++;
 		lastHalf = numItems - (p - regProp);
 		if (lastHalf > 0)
-		    memcpy(entry, p, lastHalf);
+		    mch_memmove(entry, p, lastHalf);
 		numItems = (entry - regProp) + lastHalf;
 		p = entry;
 		continue;
diff -Naur vim72.orig/src/macros.h vim72/src/macros.h
--- vim72.orig/src/macros.h	2007-08-04 04:44:18.000000000 -0700
+++ vim72/src/macros.h	2009-03-12 11:55:13.411601900 -0700
@@ -127,15 +127,31 @@
 #ifdef FEAT_LANGMAP
 /*
  * Adjust chars in a language according to 'langmap' option.
- * NOTE that there is NO overhead if 'langmap' is not set; but even
- * when set we only have to do 2 ifs and an array lookup.
+ * NOTE that there is no noticeable overhead if 'langmap' is not set.
+ * When set the overhead for characters < 256 is small.
  * Don't apply 'langmap' if the character comes from the Stuff buffer.
  * The do-while is just to ignore a ';' after the macro.
  */
-# define LANGMAP_ADJUST(c, condition) do { \
-	if (*p_langmap && (condition) && !KeyStuffed && (c) >= 0 && (c) < 256) \
-	    c = langmap_mapchar[c]; \
+# ifdef FEAT_MBYTE
+#  define LANGMAP_ADJUST(c, condition) \
+    do { \
+        if (*p_langmap && (condition) && !KeyStuffed && (c) >= 0) \
+	{ \
+	    if ((c) < 256) \
+		c = langmap_mapchar[c]; \
+	    else \
+		c = langmap_adjust_mb(c); \
+	} \
     } while (0)
+# else
+#  define LANGMAP_ADJUST(c, condition) \
+    do { \
+        if (*p_langmap && (condition) && !KeyStuffed && (c) >= 0 && (c) < 256) \
+            c = langmap_mapchar[c]; \
+    } while (0)
+# endif
+#else
+# define LANGMAP_ADJUST(c, condition) /* nop */
 #endif
 
 /*
diff -Naur vim72.orig/src/main.c vim72/src/main.c
--- vim72.orig/src/main.c	2008-07-24 01:40:56.000000000 -0700
+++ vim72/src/main.c	2009-03-12 11:54:50.142110910 -0700
@@ -645,11 +645,12 @@
 
 #ifdef FEAT_VIMINFO
     /*
-     * Read in registers, history etc, but not marks, from the viminfo file
+     * Read in registers, history etc, but not marks, from the viminfo file.
+     * This is where v:oldfiles gets filled.
      */
     if (*p_viminfo != NUL)
     {
-	read_viminfo(NULL, TRUE, FALSE, FALSE);
+	read_viminfo(NULL, VIF_WANT_INFO | VIF_GET_OLDFILES);
 	TIME_MSG("reading viminfo");
     }
 #endif
@@ -1457,7 +1458,8 @@
 	++initstr;
     }
 
-    if (TOLOWER_ASC(initstr[0]) == 'g' || initstr[0] == 'k')
+    /* "gvim" starts the GUI.  Also accept "Gvim" for MS-Windows. */
+    if (TOLOWER_ASC(initstr[0]) == 'g')
     {
 	main_start_gui();
 #ifdef FEAT_GUI
@@ -1508,7 +1510,8 @@
 early_arg_scan(parmp)
     mparm_T	*parmp;
 {
-#if defined(FEAT_XCLIPBOARD) || defined(FEAT_CLIENTSERVER)
+#if defined(FEAT_XCLIPBOARD) || defined(FEAT_CLIENTSERVER) \
+	|| !defined(FEAT_NETBEANS_INTG)
     int		argc = parmp->argc;
     char	**argv = parmp->argv;
     int		i;
@@ -1580,6 +1583,14 @@
 	else if (STRICMP(argv[i], "--echo-wid") == 0)
 	    echo_wid_arg = TRUE;
 # endif
+# ifndef FEAT_NETBEANS_INTG
+	else if (strncmp(argv[i], "-nb", (size_t)3) == 0)
+        {
+            mch_errmsg(_("'-nb' cannot be used: not enabled at compile time\n"));
+            mch_exit(2);
+        }
+# endif
+
     }
 #endif
 }
@@ -2361,7 +2372,7 @@
      * Is there any other system that cannot do this?
      */
     close(0);
-    dup(2);
+    ignored = dup(2);
 #endif
 }
 
diff -Naur vim72.orig/src/mark.c vim72/src/mark.c
--- vim72.orig/src/mark.c	2008-08-08 15:06:49.000000000 -0700
+++ vim72/src/mark.c	2009-03-12 11:54:40.549496299 -0700
@@ -1627,15 +1627,17 @@
 
 /*
  * Handle marks in the viminfo file:
- * fp_out == NULL   read marks for current buffer only
- * fp_out != NULL   copy marks for buffers not in buffer list
+ * fp_out != NULL: copy marks for buffers not in buffer list
+ * fp_out == NULL && (flags & VIF_WANT_MARKS): read marks for curbuf only
+ * fp_out == NULL && (flags & VIF_GET_OLDFILES | VIF_FORCEIT): fill v:oldfiles
  */
     void
-copy_viminfo_marks(virp, fp_out, count, eof)
+copy_viminfo_marks(virp, fp_out, count, eof, flags)
     vir_T	*virp;
     FILE	*fp_out;
     int		count;
     int		eof;
+    int		flags;
 {
     char_u	*line = virp->vir_line;
     buf_T	*buf;
@@ -1647,10 +1649,23 @@
     char_u	*p;
     char_u	*name_buf;
     pos_T	pos;
+#ifdef FEAT_EVAL
+    list_T	*list = NULL;
+#endif
 
     if ((name_buf = alloc(LSIZE)) == NULL)
 	return;
     *name_buf = NUL;
+
+#ifdef FEAT_EVAL
+    if (fp_out == NULL && (flags & (VIF_GET_OLDFILES | VIF_FORCEIT)))
+    {
+	list = list_alloc();
+	if (list != NULL)
+	    set_vim_var_list(VV_OLDFILES, list);
+    }
+#endif
+
     num_marked_files = get_viminfo_parameter('\'');
     while (!eof && (count < num_marked_files || fp_out == NULL))
     {
@@ -1681,6 +1696,11 @@
 	    p++;
 	*p = NUL;
 
+#ifdef FEAT_EVAL
+	if (list != NULL)
+	    list_append_string(list, str, -1);
+#endif
+
 	/*
 	 * If fp_out == NULL, load marks for current buffer.
 	 * If fp_out != NULL, copy marks for buffers not in buflist.
@@ -1688,7 +1708,7 @@
 	load_marks = copy_marks_out = FALSE;
 	if (fp_out == NULL)
 	{
-	    if (curbuf->b_ffname != NULL)
+	    if ((flags & VIF_WANT_MARKS) && curbuf->b_ffname != NULL)
 	    {
 		if (*name_buf == NUL)	    /* only need to do this once */
 		    home_replace(NULL, curbuf->b_ffname, name_buf, LSIZE, TRUE);
diff -Naur vim72.orig/src/mbyte.c vim72/src/mbyte.c
--- vim72.orig/src/mbyte.c	2008-07-14 05:38:05.000000000 -0700
+++ vim72/src/mbyte.c	2009-03-12 11:54:50.142110910 -0700
@@ -717,7 +717,7 @@
 		     * where mblen() returns 0 for invalid character.
 		     * Therefore, following condition includes 0.
 		     */
-		    (void)mblen(NULL, 0);	/* First reset the state. */
+		    ignored = mblen(NULL, 0);	/* First reset the state. */
 		    if (mblen(buf, (size_t)1) <= 0)
 			n = 2;
 		    else
@@ -2540,7 +2540,6 @@
     return (int)(p - q);
 }
 
-#if defined(FEAT_EVAL) || defined(PROTO)
 /*
  * Copy a character from "*fp" to "*tp" and advance the pointers.
  */
@@ -2555,7 +2554,6 @@
     *tp += l;
     *fp += l;
 }
-#endif
 
 /*
  * Return the offset from "p" to the first byte of a character.  When "p" is
@@ -3133,7 +3131,7 @@
 	else
 	    s = p + 1;
     }
-    for (i = 0; s[i] != NUL && s + i < buf + sizeof(buf) - 1; ++i)
+    for (i = 0; s[i] != NUL && i < sizeof(buf) - 1; ++i)
     {
 	if (s[i] == '_' || s[i] == '-')
 	    buf[i] = '-';
@@ -5280,7 +5278,7 @@
 
 /*ARGSUSED*/
     static void
-preedit_start_cbproc(XIC xic, XPointer client_data, XPointer call_data)
+preedit_start_cbproc(XIC thexic, XPointer client_data, XPointer call_data)
 {
 #ifdef XIM_DEBUG
     xim_log("xim_decide_input_style()\n");
@@ -5314,7 +5312,7 @@
 
 /*ARGSUSED*/
     static void
-preedit_draw_cbproc(XIC xic, XPointer client_data, XPointer call_data)
+preedit_draw_cbproc(XIC thexic, XPointer client_data, XPointer call_data)
 {
     XIMPreeditDrawCallbackStruct *draw_data;
     XIMText	*text;
@@ -5386,7 +5384,7 @@
 			draw_feedback = (char *)alloc(draw_data->chg_first
 							      + text->length);
 		    else
-			draw_feedback = realloc(draw_feedback,
+			draw_feedback = vim_realloc(draw_feedback,
 					 draw_data->chg_first + text->length);
 		    if (draw_feedback != NULL)
 		    {
@@ -5455,7 +5453,7 @@
 
 /*ARGSUSED*/
     static void
-preedit_caret_cbproc(XIC xic, XPointer client_data, XPointer call_data)
+preedit_caret_cbproc(XIC thexic, XPointer client_data, XPointer call_data)
 {
 #ifdef XIM_DEBUG
     xim_log("preedit_caret_cbproc()\n");
@@ -5464,7 +5462,7 @@
 
 /*ARGSUSED*/
     static void
-preedit_done_cbproc(XIC xic, XPointer client_data, XPointer call_data)
+preedit_done_cbproc(XIC thexic, XPointer client_data, XPointer call_data)
 {
 #ifdef XIM_DEBUG
     xim_log("preedit_done_cbproc()\n");
diff -Naur vim72.orig/src/menu.c vim72/src/menu.c
--- vim72.orig/src/menu.c	2008-06-21 12:53:43.000000000 -0700
+++ vim72/src/menu.c	2009-03-12 11:54:28.852745635 -0700
@@ -1120,6 +1120,7 @@
 	parent = menu;
 	menu = menu->children;
     }
+    vim_free(path_name);
 
     /* Now we have found the matching menu, and we list the mappings */
 						    /* Highlight title */
diff -Naur vim72.orig/src/message.c vim72/src/message.c
--- vim72.orig/src/message.c	2008-07-09 11:24:55.000000000 -0700
+++ vim72/src/message.c	2009-03-12 11:55:13.623615309 -0700
@@ -976,7 +976,7 @@
 		    }
 		}
 		else if (msg_scrolled > Rows - 2
-				     && (c == 'j' || c == K_DOWN || c == 'd'))
+			 && (c == 'j' || c == K_DOWN || c == 'd' || c == 'f'))
 		    c = K_IGNORE;
 	    }
 	} while ((had_got_int && c == Ctrl_C)
@@ -2504,7 +2504,6 @@
 	    break;
 
 	case 'u':		/* Up half a page */
-	case K_PAGEUP:
 	    scroll = -(Rows / 2);
 	    break;
 
@@ -2513,10 +2512,12 @@
 	    break;
 
 	case 'b':		/* one page back */
+	case K_PAGEUP:
 	    scroll = -(Rows - 1);
 	    break;
 
 	case ' ':		/* one extra page */
+	case 'f':
 	case K_PAGEDOWN:
 	case K_LEFTMOUSE:
 	    scroll = Rows - 1;
@@ -2552,7 +2553,6 @@
 	    {
 		/* Jump to the choices of the dialog. */
 		retval = TRUE;
-		lines_left = Rows - 1;
 	    }
 	    else
 #endif
@@ -2560,6 +2560,9 @@
 		got_int = TRUE;
 		quit_more = TRUE;
 	    }
+	    /* When there is some more output (wrapping line) display that
+	     * without another prompt. */
+	    lines_left = Rows - 1;
 	    break;
 
 #ifdef FEAT_CLIPBOARD
@@ -3309,7 +3312,10 @@
     {
 	c = gui_mch_dialog(type, title, message, buttons, dfltbutton,
 								   textfield);
-	msg_end_prompt();
+	/* avoid a hit-enter prompt without clearing the cmdline */
+	need_wait_return = FALSE;
+	emsg_on_display = FALSE;
+	cmdline_row = msg_row;
 
 	/* Flush output to avoid that further messages and redrawing is done
 	 * in the wrong order. */
@@ -4556,7 +4562,13 @@
 			remove_trailing_zeroes = TRUE;
 		    }
 
-		    if (fmt_spec == 'f' && abs_f > 1.0e307)
+		    if (fmt_spec == 'f' &&
+#ifdef VAX
+			    abs_f > 1.0e38
+#else
+			    abs_f > 1.0e307
+#endif
+			    )
 		    {
 			/* Avoid a buffer overflow */
 			strcpy(tmp, "inf");
@@ -4585,61 +4597,62 @@
 			if (remove_trailing_zeroes)
 			{
 			    int i;
-			    char *p;
+			    char *tp;
 
 			    /* Using %g or %G: remove superfluous zeroes. */
 			    if (fmt_spec == 'f')
-				p = tmp + str_arg_l - 1;
+				tp = tmp + str_arg_l - 1;
 			    else
 			    {
-				p = (char *)vim_strchr((char_u *)tmp,
+				tp = (char *)vim_strchr((char_u *)tmp,
 						 fmt_spec == 'e' ? 'e' : 'E');
-				if (p != NULL)
+				if (tp != NULL)
 				{
 				    /* Remove superfluous '+' and leading
 				     * zeroes from the exponent. */
-				    if (p[1] == '+')
+				    if (tp[1] == '+')
 				    {
 					/* Change "1.0e+07" to "1.0e07" */
-					STRMOVE(p + 1, p + 2);
+					STRMOVE(tp + 1, tp + 2);
 					--str_arg_l;
 				    }
-				    i = (p[1] == '-') ? 2 : 1;
-				    while (p[i] == '0')
+				    i = (tp[1] == '-') ? 2 : 1;
+				    while (tp[i] == '0')
 				    {
 					/* Change "1.0e07" to "1.0e7" */
-					STRMOVE(p + i, p + i + 1);
+					STRMOVE(tp + i, tp + i + 1);
 					--str_arg_l;
 				    }
-				    --p;
+				    --tp;
 				}
 			    }
 
-			    if (p != NULL && !precision_specified)
+			    if (tp != NULL && !precision_specified)
 				/* Remove trailing zeroes, but keep the one
 				 * just after a dot. */
-				while (p > tmp + 2 && *p == '0' && p[-1] != '.')
+				while (tp > tmp + 2 && *tp == '0'
+							     && tp[-1] != '.')
 				{
-				    STRMOVE(p, p + 1);
-				    --p;
+				    STRMOVE(tp, tp + 1);
+				    --tp;
 				    --str_arg_l;
 				}
 			}
 			else
 			{
-			    char *p;
+			    char *tp;
 
 			    /* Be consistent: some printf("%e") use 1.0e+12
 			     * and some 1.0e+012.  Remove one zero in the last
 			     * case. */
-			    p = (char *)vim_strchr((char_u *)tmp,
+			    tp = (char *)vim_strchr((char_u *)tmp,
 						 fmt_spec == 'e' ? 'e' : 'E');
-			    if (p != NULL && (p[1] == '+' || p[1] == '-')
-					  && p[2] == '0'
-					  && vim_isdigit(p[3])
-					  && vim_isdigit(p[4]))
+			    if (tp != NULL && (tp[1] == '+' || tp[1] == '-')
+					  && tp[2] == '0'
+					  && vim_isdigit(tp[3])
+					  && vim_isdigit(tp[4]))
 			    {
-				STRMOVE(p + 2, p + 3);
+				STRMOVE(tp + 2, tp + 3);
 				--str_arg_l;
 			    }
 			}
diff -Naur vim72.orig/src/misc1.c vim72/src/misc1.c
--- vim72.orig/src/misc1.c	2008-07-12 12:20:53.000000000 -0700
+++ vim72/src/misc1.c	2009-03-12 11:54:40.553496578 -0700
@@ -3245,9 +3245,9 @@
 
     /* When using ":silent" assume that <CR> was entered. */
     if (mouse_used != NULL)
-	MSG_PUTS(_("Type number or click with mouse (<Enter> cancels): "));
+	MSG_PUTS(_("Type number and <Enter> or click with mouse (empty cancels): "));
     else
-	MSG_PUTS(_("Choice number (<Enter> cancels): "));
+	MSG_PUTS(_("Type number and <Enter> (empty cancels): "));
 
     /* Set the state such that text can be selected/copied/pasted and we still
      * get mouse events. */
diff -Naur vim72.orig/src/misc2.c vim72/src/misc2.c
--- vim72.orig/src/misc2.c	2008-07-23 12:12:56.000000000 -0700
+++ vim72/src/misc2.c	2009-03-12 11:55:33.688900964 -0700
@@ -496,7 +496,8 @@
 {
     colnr_T len;
 #ifdef FEAT_VIRTUALEDIT
-    colnr_T oldcol = curwin->w_cursor.col + curwin->w_cursor.coladd;
+    colnr_T oldcol = curwin->w_cursor.col;
+    colnr_T oldcoladd = curwin->w_cursor.col + curwin->w_cursor.coladd;
 #endif
 
     len = (colnr_T)STRLEN(ml_get_curline());
@@ -535,7 +536,13 @@
     if (oldcol == MAXCOL)
 	curwin->w_cursor.coladd = 0;
     else if (ve_flags == VE_ALL)
-	curwin->w_cursor.coladd = oldcol - curwin->w_cursor.col;
+    {
+	if (oldcoladd > curwin->w_cursor.col)
+	    curwin->w_cursor.coladd = oldcoladd - curwin->w_cursor.col;
+	else
+	    /* avoid weird number when there is a miscalculation or overflow */
+	    curwin->w_cursor.coladd = 0;
+    }
 #endif
 }
 
@@ -873,7 +880,7 @@
 	    /* 3. check for available memory: call mch_avail_mem() */
 	    if (mch_avail_mem(TRUE) < KEEP_ROOM && !releasing)
 	    {
-		vim_free((char *)p);	/* System is low... no go! */
+		free((char *)p);	/* System is low... no go! */
 		p = NULL;
 	    }
 	    else
@@ -1010,6 +1017,9 @@
 # if defined(FEAT_PROFILE)
     do_cmdline_cmd((char_u *)"profdel *");
 # endif
+# if defined(FEAT_KEYMAP)
+    do_cmdline_cmd((char_u *)"set keymap=");
+#endif
 
 # ifdef FEAT_TITLE
     free_titles();
@@ -1034,6 +1044,9 @@
     free_regexp_stuff();
     free_tag_stuff();
     free_cd_dir();
+# ifdef FEAT_SIGNS
+    free_signs();
+# endif
 # ifdef FEAT_EVAL
     set_expr_line(NULL);
 # endif
@@ -1257,7 +1270,6 @@
     return escaped_string;
 }
 
-#if !defined(BACKSLASH_IN_FILENAME) || defined(FEAT_EVAL) || defined(PROTO)
 /*
  * Return TRUE when 'shell' has "csh" in the tail.
  */
@@ -1266,9 +1278,7 @@
 {
     return (strstr((char *)gettail(p_sh), "csh") != NULL);
 }
-#endif
 
-#if defined(FEAT_EVAL) || defined(PROTO)
 /*
  * Escape "string" for use as a shell argument with system().
  * This uses single quotes, except when we know we need to use double qoutes
@@ -1391,7 +1401,6 @@
 
     return escaped_string;
 }
-#endif
 
 /*
  * Like vim_strsave(), but make all characters uppercase.
@@ -2565,7 +2574,7 @@
     int		key;
     int		dlen = 0;
 
-    key = find_special_key(srcp, &modifiers, keycode);
+    key = find_special_key(srcp, &modifiers, keycode, FALSE);
     if (key == 0)
 	return 0;
 
@@ -2601,10 +2610,11 @@
  * returns 0 if there is no match.
  */
     int
-find_special_key(srcp, modp, keycode)
+find_special_key(srcp, modp, keycode, keep_x_key)
     char_u	**srcp;
     int		*modp;
-    int		keycode; /* prefer key code, e.g. K_DEL instead of DEL */
+    int		keycode;     /* prefer key code, e.g. K_DEL instead of DEL */
+    int		keep_x_key;  /* don't translate xHome to Home key */
 {
     char_u	*last_dash;
     char_u	*end_of_name;
@@ -2672,7 +2682,8 @@
 	    else
 	    {
 		key = get_special_key_code(last_dash + 1);
-		key = handle_x_keys(key);
+		if (!keep_x_key)
+		    key = handle_x_keys(key);
 	    }
 
 	    /*
@@ -4698,7 +4709,8 @@
 				stackp->ffs_filearray_cur = i + 1;
 				ff_push(search_ctx, stackp);
 
-				simplify_filename(file_path);
+				if (!path_with_url(file_path))
+				    simplify_filename(file_path);
 				if (mch_dirname(ff_expand_buffer, MAXPATHL)
 									== OK)
 				{
diff -Naur vim72.orig/src/move.c vim72/src/move.c
--- vim72.orig/src/move.c	2008-07-12 09:26:47.000000000 -0700
+++ vim72/src/move.c	2009-03-12 11:54:46.913903059 -0700
@@ -280,18 +280,20 @@
 
 	if (curwin->w_botline <= curbuf->b_ml.ml_line_count)
 	{
-	    if (curwin->w_cursor.lnum < curwin->w_botline
-		    && ((long)curwin->w_cursor.lnum
+	    if (curwin->w_cursor.lnum < curwin->w_botline)
+	    {
+	      if (((long)curwin->w_cursor.lnum
 					     >= (long)curwin->w_botline - p_so
 #ifdef FEAT_FOLDING
 			|| hasAnyFolding(curwin)
 #endif
 			))
-	    {
+	      {
 		lineoff_T	loff;
 
-		/* Cursor is above botline, check if there are 'scrolloff'
-		 * window lines below the cursor.  If not, need to scroll. */
+		/* Cursor is (a few lines) above botline, check if there are
+		 * 'scrolloff' window lines below the cursor.  If not, need to
+		 * scroll. */
 		n = curwin->w_empty_rows;
 		loff.lnum = curwin->w_cursor.lnum;
 #ifdef FEAT_FOLDING
@@ -317,6 +319,10 @@
 		if (n >= p_so)
 		    /* sufficient context, no need to scroll */
 		    check_botline = FALSE;
+	      }
+	      else
+		  /* sufficient context, no need to scroll */
+		  check_botline = FALSE;
 	    }
 	    if (check_botline)
 	    {
@@ -509,6 +515,9 @@
     /* Approximate the value of w_botline */
     wp->w_botline += lnum - wp->w_topline;
     wp->w_topline = lnum;
+#ifdef FEAT_AUTOCMD
+    wp->w_topline_was_set = TRUE;
+#endif
 #ifdef FEAT_DIFF
     wp->w_topfill = 0;
 #endif
diff -Naur vim72.orig/src/nbdebug.c vim72/src/nbdebug.c
--- vim72.orig/src/nbdebug.c	2008-06-22 08:38:58.000000000 -0700
+++ vim72/src/nbdebug.c	2009-03-12 11:55:13.487606370 -0700
@@ -33,7 +33,6 @@
 u_int		 nb_dlevel = 0;		/* nb_debug verbosity level */
 
 void		 nbdb(char *, ...);
-void		 nbtrace(char *, ...);
 
 static int	 lookup(char *);
 #ifdef USE_NB_ERRORHANDLER
@@ -100,25 +99,6 @@
 }    /* end nbdebug_log_init */
 
 
-
-
-void
-nbtrace(
-	char		*fmt,
-	...)
-{
-	va_list		 ap;
-
-	if (nb_debug!= NULL && (nb_dlevel & (NB_TRACE | NB_TRACE_VERBOSE))) {
-		va_start(ap, fmt);
-		vfprintf(nb_debug, fmt, ap);
-		va_end(ap);
-		fflush(nb_debug);
-	}
-
-}    /* end nbtrace */
-
-
 void
 nbdbg(
 	char		*fmt,
@@ -136,23 +116,6 @@
 }    /* end nbdbg */
 
 
-void
-nbprt(
-	char		*fmt,
-	...)
-{
-	va_list		 ap;
-
-	if (nb_debug != NULL && nb_dlevel & NB_PRINT) {
-		va_start(ap, fmt);
-		vfprintf(nb_debug, fmt, ap);
-		va_end(ap);
-		fflush(nb_debug);
-	}
-
-}    /* end nbprt */
-
-
 static int
 lookup(
 	char		*file)
diff -Naur vim72.orig/src/nbdebug.h vim72/src/nbdebug.h
--- vim72.orig/src/nbdebug.h	2008-06-22 07:31:50.000000000 -0700
+++ vim72/src/nbdebug.h	2009-03-12 11:55:13.487606370 -0700
@@ -43,8 +43,6 @@
 
 
 void		 nbdbg(char *, ...);
-void		 nbprt(char *, ...);
-void		 nbtrace(char *, ...);
 
 void nbdebug_wait __ARGS((u_int wait_flags, char *wait_var, u_int wait_secs));
 void nbdebug_log_init __ARGS((char *log_var, char *level_var));
@@ -70,19 +68,5 @@
 {
 }
 
-void
-nbprt(
-	char		*fmt,
-	...)
-{
-}
-
-void
-nbtrace(
-	char		*fmt,
-	...)
-{
-}
-
 #endif /* NBDEBUG */
 #endif /* NBDEBUG_H */
diff -Naur vim72.orig/src/netbeans.c vim72/src/netbeans.c
--- vim72.orig/src/netbeans.c	2008-07-13 09:19:54.000000000 -0700
+++ vim72/src/netbeans.c	2009-03-12 11:55:13.479606090 -0700
@@ -1043,7 +1043,7 @@
 	nbdebug(("EVT: %s", buf));
 /*	nb_send(buf, "netbeans_end");    avoid "write failed" messages */
 	if (sd >= 0)
-	    sock_write(sd, buf, (int)STRLEN(buf));  /* ignore errors */
+	    ignored = sock_write(sd, buf, (int)STRLEN(buf));
     }
 }
 
@@ -1921,7 +1921,7 @@
 	    vim_free(path);
 	    if (bufp == NULL)
 	    {
-	    	nbdebug(("    File %s not found in setBufferNumber\n", args));
+		nbdebug(("    File %s not found in setBufferNumber\n", args));
 		EMSG2("E642: File %s not found in setBufferNumber", args);
 		return FAIL;
 	    }
@@ -2277,9 +2277,6 @@
 	    int serNum;
 	    int localTypeNum;
 	    int typeNum;
-# ifdef NBDEBUG
-	    int len;
-# endif
 	    pos_T *pos;
 
 	    if (buf == NULL || buf->bufp == NULL)
@@ -2303,13 +2300,10 @@
 	    pos = get_off_or_lnum(buf->bufp, &args);
 
 	    cp = (char *)args;
-# ifdef NBDEBUG
-	    len =
-# endif
-		strtol(cp, &cp, 10);
+	    ignored = (int)strtol(cp, &cp, 10);
 	    args = (char_u *)cp;
 # ifdef NBDEBUG
-	    if (len != -1)
+	    if (ignored != -1)
 	    {
 		nbdebug(("    partial line annotation -- Not Yet Implemented!\n"));
 	    }
@@ -2321,7 +2315,7 @@
 	    }
 	    if (pos)
 	    {
-		coloncmd(":sign place %d line=%d name=%d buffer=%d",
+		coloncmd(":sign place %d line=%ld name=%d buffer=%d",
 			   serNum, pos->lnum, typeNum, buf->bufp->b_fnum);
 		if (typeNum == curPCtype)
 		    coloncmd(":sign jump %d buffer=%d", serNum,
@@ -2425,7 +2419,7 @@
 				GUARDED) == 0)
 			    {
 				coloncmd(
-				    ":sign place %d line=%d name=%d buffer=%d",
+				    ":sign place %d line=%ld name=%d buffer=%d",
 				     guardId++, lnum, GUARDED,
 				     buf->bufp->b_fnum);
 			    }
@@ -2924,44 +2918,26 @@
 }
 
 /*
- * Tell netbeans a file was closed.
+ * Tell netbeans that a file was deleted or wiped out.
  */
     void
-netbeans_file_closed(buf_T *bufp)
+netbeans_file_killed(buf_T *bufp)
 {
     int		bufno = nb_getbufno(bufp);
     nbbuf_T	*nbbuf = nb_get_buf(bufno);
     char	buffer[2*MAXPATHL];
 
-    if (!haveConnection || bufno < 0)
-	return;
-
-    if (!netbeansCloseFile)
-    {
-	nbdebug(("Ignoring file_closed for %s. File was closed from IDE\n",
-		    bufp->b_ffname));
+    if (!haveConnection || bufno == -1)
 	return;
-    }
-
-    nbdebug(("netbeans_file_closed:\n"));
-    nbdebug(("    Closing bufno: %d", bufno));
-    if (curbuf != NULL && curbuf != bufp)
-    {
-	nbdebug(("    Curbuf bufno:  %d\n", nb_getbufno(curbuf)));
-    }
-    else if (curbuf == bufp)
-    {
-	nbdebug(("    curbuf == bufp\n"));
-    }
 
-    if (bufno <= 0)
-	return;
+    nbdebug(("netbeans_file_killed:\n"));
+    nbdebug(("    Killing bufno: %d", bufno));
 
     sprintf(buffer, "%d:killed=%d\n", bufno, r_cmdno);
 
     nbdebug(("EVT: %s", buffer));
 
-    nb_send(buffer, "netbeans_file_closed");
+    nb_send(buffer, "netbeans_file_killed");
 
     if (nbbuf != NULL)
 	nbbuf->bufp = NULL;
diff -Naur vim72.orig/src/normal.c vim72/src/normal.c
--- vim72.orig/src/normal.c	2008-07-31 13:03:08.000000000 -0700
+++ vim72/src/normal.c	2009-03-12 11:55:13.415602459 -0700
@@ -183,6 +183,8 @@
 static void	nv_cursorhold __ARGS((cmdarg_T *cap));
 #endif
 
+static char *e_noident = N_("E349: No identifier under cursor");
+
 /*
  * Function to be called for a Normal or Visual mode command.
  * The argument is a cmdarg_T.
@@ -578,6 +580,9 @@
     static int	old_mapped_len = 0;
 #endif
     int		idx;
+#ifdef FEAT_EVAL
+    int		set_prevcount = FALSE;
+#endif
 
     vim_memset(&ca, 0, sizeof(ca));	/* also resets ca.retval */
     ca.oap = oap;
@@ -613,7 +618,12 @@
     /* When not finishing an operator and no register name typed, reset the
      * count. */
     if (!finish_op && !oap->regname)
+    {
 	ca.opcount = 0;
+#ifdef FEAT_EVAL
+	set_prevcount = TRUE;
+#endif
+    }
 
 #ifdef FEAT_AUTOCMD
     /* Restore counts from before receiving K_CURSORHOLD.  This means after
@@ -641,10 +651,7 @@
      * Get the command character from the user.
      */
     c = safe_vgetc();
-
-#ifdef FEAT_LANGMAP
     LANGMAP_ADJUST(c, TRUE);
-#endif
 
 #ifdef FEAT_VISUAL
     /*
@@ -717,7 +724,15 @@
 	     * 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);
+	    {
+		long count = ca.count0;
+
+		/* multiply with ca.opcount the same way as below */
+		if (ca.opcount != 0)
+		    count = ca.opcount * (count == 0 ? 1 : count);
+		set_vcount(count, count == 0 ? 1 : count, set_prevcount);
+		set_prevcount = FALSE;  /* only set v:prevcount once */
+	    }
 #endif
 	    if (ctrl_w)
 	    {
@@ -726,9 +741,7 @@
 	    }
 	    ++no_zero_mapping;		/* don't map zero here */
 	    c = plain_vgetc();
-#ifdef FEAT_LANGMAP
 	    LANGMAP_ADJUST(c, TRUE);
-#endif
 	    --no_zero_mapping;
 	    if (ctrl_w)
 	    {
@@ -751,9 +764,7 @@
 	    ++no_mapping;
 	    ++allow_keys;		/* no mapping for nchar, but keys */
 	    c = plain_vgetc();		/* get next character */
-#ifdef FEAT_LANGMAP
 	    LANGMAP_ADJUST(c, TRUE);
-#endif
 	    --no_mapping;
 	    --allow_keys;
 #ifdef FEAT_CMDL_INFO
@@ -804,7 +815,7 @@
      * Only set v:count when called from main() and not a stuffed command.
      */
     if (toplevel && stuff_empty())
-	set_vcount(ca.count0, ca.count1);
+	set_vcount(ca.count0, ca.count1, set_prevcount);
 #endif
 
     /*
@@ -941,9 +952,7 @@
 	     * "gr", "g'" and "g`".
 	     */
 	    ca.nchar = plain_vgetc();
-#ifdef FEAT_LANGMAP
 	    LANGMAP_ADJUST(ca.nchar, TRUE);
-#endif
 #ifdef FEAT_CMDL_INFO
 	    need_flushbuf |= add_to_showcmd(ca.nchar);
 #endif
@@ -1044,10 +1053,8 @@
 		}
 #endif
 
-#ifdef FEAT_LANGMAP
 		/* adjust chars > 127, except after "tTfFr" commands */
 		LANGMAP_ADJUST(*cp, !lang);
-#endif
 #ifdef FEAT_RIGHTLEFT
 		/* adjust Hebrew mapped char */
 		if (p_hkmap && lang && KeyTyped)
@@ -1132,7 +1139,8 @@
 	out_flush();
 #endif
 #ifdef FEAT_AUTOCMD
-    did_cursorhold = FALSE;
+    if (ca.cmdchar != K_IGNORE)
+	did_cursorhold = FALSE;
 #endif
 
     State = NORMAL;
@@ -3509,7 +3517,7 @@
 	if (find_type & FIND_STRING)
 	    EMSG(_("E348: No string under cursor"));
 	else
-	    EMSG(_("E349: No identifier under cursor"));
+	    EMSG(_(e_noident));
 	return 0;
     }
     ptr += col;
@@ -4611,9 +4619,7 @@
 	    ++no_mapping;
 	    ++allow_keys;   /* no mapping for nchar, but allow key codes */
 	    nchar = plain_vgetc();
-#ifdef FEAT_LANGMAP
 	    LANGMAP_ADJUST(nchar, TRUE);
-#endif
 	    --no_mapping;
 	    --allow_keys;
 #ifdef FEAT_CMDL_INFO
@@ -4969,9 +4975,7 @@
 		++no_mapping;
 		++allow_keys;   /* no mapping for nchar, but allow key codes */
 		nchar = plain_vgetc();
-#ifdef FEAT_LANGMAP
 		LANGMAP_ADJUST(nchar, TRUE);
-#endif
 		--no_mapping;
 		--allow_keys;
 #ifdef FEAT_CMDL_INFO
@@ -5469,6 +5473,20 @@
 		STRCPY(buf, "he! ");
 	    else
 	    {
+		/* An external command will probably use an argument starting
+		 * with "-" as an option.  To avoid trouble we skip the "-". */
+		while (*ptr == '-' && n > 0)
+		{
+		    ++ptr;
+		    --n;
+		}
+		if (n == 0)
+		{
+		    EMSG(_(e_noident));	 /* found dashes only */
+		    vim_free(buf);
+		    return;
+		}
+
 		/* When a count is given, turn it into a range.  Is this
 		 * really what we want? */
 		isman = (STRCMP(kp, "man") == 0);
@@ -5511,37 +5529,59 @@
     /*
      * Now grab the chars in the identifier
      */
-    if (cmdchar == '*')
-	aux_ptr = (char_u *)(p_magic ? "/.*~[^$\\" : "/^$\\");
-    else if (cmdchar == '#')
-	aux_ptr = (char_u *)(p_magic ? "/?.*~[^$\\" : "/?^$\\");
-    else if (cmdchar == 'K' && !kp_help)
-	aux_ptr = (char_u *)" \t\\\"|!";
-    else
-	/* Don't escape spaces and Tabs in a tag with a backslash */
-	aux_ptr = (char_u *)"\\|\"";
-
-    p = buf + STRLEN(buf);
-    while (n-- > 0)
-    {
-	/* put a backslash before \ and some others */
-	if (vim_strchr(aux_ptr, *ptr) != NULL)
-	    *p++ = '\\';
-#ifdef FEAT_MBYTE
-	/* When current byte is a part of multibyte character, copy all bytes
-	 * of that character. */
-	if (has_mbyte)
+    if (cmdchar == 'K' && !kp_help)
+    {
+	/* Escape the argument properly for a shell command */
+	ptr = vim_strnsave(ptr, n);
+	p = vim_strsave_shellescape(ptr, TRUE);
+	vim_free(ptr);
+	if (p == NULL)
 	{
-	    int i;
-	    int len = (*mb_ptr2len)(ptr) - 1;
-
-	    for (i = 0; i < len && n >= 1; ++i, --n)
-		*p++ = *ptr++;
+	    vim_free(buf);
+	    return;
+	}
+	buf = (char_u *)vim_realloc(buf, STRLEN(buf) + STRLEN(p) + 1);
+	if (buf == NULL)
+	{
+	    vim_free(buf);
+	    vim_free(p);
+	    return;
 	}
+	STRCAT(buf, p);
+	vim_free(p);
+    }
+    else
+    {
+	if (cmdchar == '*')
+	    aux_ptr = (char_u *)(p_magic ? "/.*~[^$\\" : "/^$\\");
+	else if (cmdchar == '#')
+	    aux_ptr = (char_u *)(p_magic ? "/?.*~[^$\\" : "/?^$\\");
+	else
+	    /* Don't escape spaces and Tabs in a tag with a backslash */
+	    aux_ptr = (char_u *)"\\|\"\n*?[";
+
+	p = buf + STRLEN(buf);
+	while (n-- > 0)
+	{
+	    /* put a backslash before \ and some others */
+	    if (vim_strchr(aux_ptr, *ptr) != NULL)
+		*p++ = '\\';
+#ifdef FEAT_MBYTE
+	    /* When current byte is a part of multibyte character, copy all
+	     * bytes of that character. */
+	    if (has_mbyte)
+	    {
+		int i;
+		int len = (*mb_ptr2len)(ptr) - 1;
+
+		for (i = 0; i < len && n >= 1; ++i, --n)
+		    *p++ = *ptr++;
+	    }
 #endif
-	*p++ = *ptr++;
+	    *p++ = *ptr++;
+	}
+	*p = NUL;
     }
-    *p = NUL;
 
     /*
      * Execute the command.
@@ -6728,6 +6768,8 @@
     /* Visual mode "r" */
     if (VIsual_active)
     {
+	if (got_int)
+	    reset_VIsual();
 	nv_operator(cap);
 	return;
     }
@@ -7784,7 +7826,7 @@
 	else
 	    i = curwin->w_leftcol;
 	/* Go to the middle of the screen line.  When 'number' is on and lines
-	 * are wrapping the middle can be more to the left.*/
+	 * are wrapping the middle can be more to the left. */
 	if (cap->nchar == 'm')
 	    i += (W_WIDTH(curwin) - curwin_col_off()
 		    + ((curwin->w_p_wrap && i > 0)
diff -Naur vim72.orig/src/ops.c vim72/src/ops.c
--- vim72.orig/src/ops.c	2008-06-21 13:08:59.000000000 -0700
+++ vim72/src/ops.c	2009-03-12 11:55:27.544506216 -0700
@@ -72,11 +72,11 @@
  */
 struct block_def
 {
-    int		startspaces;	/* 'extra' cols of first char */
-    int		endspaces;	/* 'extra' cols of first char */
+    int		startspaces;	/* 'extra' cols before first char */
+    int		endspaces;	/* 'extra' cols after last char */
     int		textlen;	/* chars in block */
-    char_u	*textstart;	/* pointer to 1st char in block */
-    colnr_T	textcol;	/* cols of chars (at least part.) in block */
+    char_u	*textstart;	/* pointer to 1st char (partially) in block */
+    colnr_T	textcol;	/* index of chars (partially) in block */
     colnr_T	start_vcol;	/* start col of 1st char wholly inside block */
     colnr_T	end_vcol;	/* start col of 1st char wholly after block */
 #ifdef FEAT_VISUALEXTRA
@@ -382,15 +382,14 @@
 {
     int			left = (oap->op_type == OP_LSHIFT);
     int			oldstate = State;
-    int			total, split;
-    char_u		*newp, *oldp, *midp, *ptr;
+    int			total;
+    char_u		*newp, *oldp;
     int			oldcol = curwin->w_cursor.col;
     int			p_sw = (int)curbuf->b_p_sw;
     int			p_ts = (int)curbuf->b_p_ts;
     struct block_def	bd;
-    int			internal = 0;
     int			incr;
-    colnr_T		vcol, col = 0, ws_vcol;
+    colnr_T		ws_vcol;
     int			i = 0, j = 0;
     int			len;
 
@@ -456,67 +455,89 @@
     }
     else /* left */
     {
-	vcol = oap->start_vcol;
-	/* walk vcol past ws to be removed */
-	for (midp = oldp + bd.textcol;
-	      vcol < (oap->start_vcol + total) && vim_iswhite(*midp); )
-	{
-	    incr = lbr_chartabsize_adv(&midp, (colnr_T)vcol);
-	    vcol += incr;
-	}
-	/* internal is the block-internal ws replacing a split TAB */
-	if (vcol > (oap->start_vcol + total))
-	{
-	    /* we have to split the TAB *(midp-1) */
-	    internal = vcol - (oap->start_vcol + total);
-	}
-	/* if 'expandtab' is not set, use TABs */
+	colnr_T	    destination_col;	/* column to which text in block will
+					   be shifted */
+	char_u	    *verbatim_copy_end;	/* end of the part of the line which is
+					   copied verbatim */
+	colnr_T	    verbatim_copy_width;/* the (displayed) width of this part
+					   of line */
+	unsigned    fill;		/* nr of spaces that replace a TAB */
+	unsigned    new_line_len;	/* the length of the line after the
+					   block shift */
+	size_t	    block_space_width;
+	size_t	    shift_amount;
+	char_u	    *non_white = bd.textstart;
+	colnr_T	    non_white_col;
 
-	split = bd.startspaces + internal;
-	if (split > 0)
-	{
-	    if (!curbuf->b_p_et)
-	    {
-		for (ptr = oldp, col = 0; ptr < oldp+bd.textcol; )
-		    col += lbr_chartabsize_adv(&ptr, (colnr_T)col);
+	/*
+	 * Firstly, let's find the first non-whitespace character that is
+	 * displayed after the block's start column and the character's column
+	 * number. Also, let's calculate the width of all the whitespace
+	 * characters that are displayed in the block and precede the searched
+	 * non-whitespace character.
+	 */
 
-		/* col+1 now equals the start col of the first char of the
-		 * block (may be < oap.start_vcol if we're splitting a TAB) */
-		i = ((col % p_ts) + split) / p_ts; /* number of tabs */
-	    }
-	    if (i)
-		j = ((col % p_ts) + split) % p_ts; /* number of spp */
-	    else
-		j = split;
-	}
+	/* If "bd.startspaces" is set, "bd.textstart" points to the character,
+	 * the part of which is displayed at the block's beginning. Let's start
+	 * searching from the next character. */
+	if (bd.startspaces)
+	    mb_ptr_adv(non_white);
 
-	newp = alloc_check(bd.textcol + i + j + (unsigned)STRLEN(midp) + 1);
-	if (newp == NULL)
-	    return;
-	vim_memset(newp, NUL, (size_t)(bd.textcol + i + j + STRLEN(midp) + 1));
+	/* The character's column is in "bd.start_vcol".  */
+	non_white_col = bd.start_vcol;
 
-	/* copy first part we want to keep */
-	mch_memmove(newp, oldp, (size_t)bd.textcol);
-	/* Now copy any TABS and spp to ensure correct alignment! */
-	while (vim_iswhite(*midp))
+	while (vim_iswhite(*non_white))
 	{
-	    if (*midp == TAB)
-		i++;
-	    else /*space */
-		j++;
-	    midp++;
+	    incr = lbr_chartabsize_adv(&non_white, non_white_col);
+	    non_white_col += incr;
 	}
-	/* We might have an extra TAB worth of spp now! */
-	if (j / p_ts && !curbuf->b_p_et)
+
+	block_space_width = non_white_col - oap->start_vcol;
+	/* We will shift by "total" or "block_space_width", whichever is less.
+	 */
+	shift_amount = (block_space_width < total? block_space_width: total);
+
+	/* The column to which we will shift the text.  */
+	destination_col = non_white_col - shift_amount;
+
+	/* Now let's find out how much of the beginning of the line we can
+	 * reuse without modification.  */
+	verbatim_copy_end = bd.textstart;
+	verbatim_copy_width = bd.start_vcol;
+
+	/* If "bd.startspaces" is set, "bd.textstart" points to the character
+	 * preceding the block. We have to subtract its width to obtain its
+	 * column number.  */
+	if (bd.startspaces)
+	    verbatim_copy_width -= bd.start_char_vcols;
+	while (verbatim_copy_width < destination_col)
 	{
-	    i++;
-	    j -= p_ts;
+	    incr = lbr_chartabsize(verbatim_copy_end, verbatim_copy_width);
+	    if (verbatim_copy_width + incr > destination_col)
+		break;
+	    verbatim_copy_width += incr;
+	    mb_ptr_adv(verbatim_copy_end);
 	}
-	copy_chars(newp + bd.textcol, (size_t)i, TAB);
-	copy_spaces(newp + bd.textcol + i, (size_t)j);
 
-	/* the end */
-	STRMOVE(newp + STRLEN(newp), midp);
+	/* If "destination_col" is different from the width of the initial
+	 * part of the line that will be copied, it means we encountered a tab
+	 * character, which we will have to partly replace with spaces.  */
+	fill = destination_col - verbatim_copy_width;
+
+	/* The replacement line will consist of:
+	 * - the beginning of the original line up to "verbatim_copy_end",
+	 * - "fill" number of spaces,
+	 * - the rest of the line, pointed to by non_white.  */
+	new_line_len = (unsigned)(verbatim_copy_end - oldp)
+		       + fill
+		       + (unsigned)STRLEN(non_white) + 1;
+
+	newp = alloc_check(new_line_len);
+	if (newp == NULL)
+	    return;
+	mch_memmove(newp, oldp, (size_t)(verbatim_copy_end - oldp));
+	copy_spaces(newp + (verbatim_copy_end - oldp), (size_t)fill);
+	STRMOVE(newp + (verbatim_copy_end - oldp) + fill, non_white);
     }
     /* replace the line */
     ml_replace(curwin->w_cursor.lnum, newp, FALSE);
@@ -2209,12 +2230,15 @@
     {
 	for (; pos.lnum <= oap->end.lnum; ++pos.lnum)
 	{
+	    int one_change;
+
 	    block_prep(oap, &bd, pos.lnum, FALSE);
 	    pos.col = bd.textcol;
-	    did_change = swapchars(oap->op_type, &pos, bd.textlen);
+	    one_change = swapchars(oap->op_type, &pos, bd.textlen);
+	    did_change |= one_change;
 
 # ifdef FEAT_NETBEANS_INTG
-	    if (usingNetbeans && did_change)
+	    if (usingNetbeans && one_change)
 	    {
 		char_u *ptr = ml_get_buf(curbuf, pos.lnum, FALSE);
 
@@ -4848,7 +4872,8 @@
  * - textlen includes the first/last char to be (partly) deleted
  * - start/endspaces is the number of columns that are taken by the
  *   first/last deleted char minus the number of columns that have to be
- *   deleted.  for yank and tilde:
+ *   deleted.
+ * for yank and tilde:
  * - textlen includes the first/last char to be wholly yanked
  * - start/endspaces is the number of columns of the first/last yanked char
  *   that are to be yanked.
diff -Naur vim72.orig/src/option.c vim72/src/option.c
--- vim72.orig/src/option.c	2008-07-18 06:05:33.000000000 -0700
+++ vim72/src/option.c	2009-03-12 11:55:13.683619779 -0700
@@ -2593,13 +2593,13 @@
 #ifdef FEAT_VIMINFO
 			    (char_u *)&p_viminfo, PV_NONE,
 #if defined(MSDOS) || defined(MSWIN) || defined(OS2)
-			    {(char_u *)"", (char_u *)"'20,<50,s10,h,rA:,rB:"}
+			    {(char_u *)"", (char_u *)"'100,<50,s10,h,rA:,rB:"}
 #else
 # ifdef AMIGA
 			    {(char_u *)"",
-				 (char_u *)"'20,<50,s10,h,rdf0:,rdf1:,rdf2:"}
+				 (char_u *)"'100,<50,s10,h,rdf0:,rdf1:,rdf2:"}
 # else
-			    {(char_u *)"", (char_u *)"'20,<50,s10,h"}
+			    {(char_u *)"", (char_u *)"'100,<50,s10,h"}
 # endif
 #endif
 #else
@@ -4119,11 +4119,23 @@
 					   && options[opt_idx].var == VAR_WIN)
 		goto skip;
 
-	    /* Disallow changing some options from modelines */
-	    if ((opt_flags & OPT_MODELINE) && (flags & P_SECURE))
+	    /* Disallow changing some options from modelines. */
+	    if (opt_flags & OPT_MODELINE)
 	    {
-		errmsg = (char_u *)_("E520: Not allowed in a modeline");
-		goto skip;
+		if (flags & P_SECURE)
+		{
+		    errmsg = (char_u *)_("E520: Not allowed in a modeline");
+		    goto skip;
+		}
+#ifdef FEAT_DIFF
+		/* In diff mode some options are overruled.  This avoids that
+		 * 'foldmethod' becomes "marker" instead of "diff" and that
+		 * "wrap" gets set. */
+		if (curwin->w_p_diff
+			&& (options[opt_idx].indir == PV_FDM
+			    || options[opt_idx].indir == PV_WRAP))
+		    goto skip;
+#endif
 	    }
 
 #ifdef HAVE_SANDBOX
@@ -5268,6 +5280,21 @@
 }
 #endif
 
+#ifdef FEAT_TITLE
+static void redraw_titles __ARGS((void));
+
+/*
+ * Redraw the window title and/or tab page text later.
+ */
+static void redraw_titles()
+{
+    need_maketitle = TRUE;
+# ifdef FEAT_WINDOWS
+    redraw_tabline = TRUE;
+# endif
+}
+#endif
+
 /*
  * Set a string option to a new value (without checking the effect).
  * The string is copied into allocated memory.
@@ -5407,6 +5434,10 @@
     int		did_chartab = FALSE;
     char_u	**gvarp;
     long_u	free_oldval = (options[opt_idx].flags & P_ALLOCED);
+#ifdef FEAT_GUI
+    /* set when changing an option that only requires a redraw in the GUI */
+    int		redraw_gui_only = FALSE;
+#endif
 
     /* Get the global option to compare with, otherwise we would have to check
      * two values for all local options. */
@@ -5668,7 +5699,7 @@
 	    {
 # ifdef FEAT_TITLE
 		/* May show a "+" in the title now. */
-		need_maketitle = TRUE;
+		redraw_titles();
 # endif
 		/* Add 'fileencoding' to the swap file. */
 		ml_setflags(curbuf);
@@ -5687,7 +5718,7 @@
 	    {
 		errmsg = mb_init();
 # ifdef FEAT_TITLE
-		need_maketitle = TRUE;
+		redraw_titles();
 # endif
 	    }
 	}
@@ -5766,14 +5797,28 @@
 	/* load or unload key mapping tables */
 	errmsg = keymap_init();
 
-	/* When successfully installed a new keymap switch on using it. */
-	if (*curbuf->b_p_keymap != NUL && errmsg == NULL)
+	if (errmsg == NULL)
 	{
-	    curbuf->b_p_iminsert = B_IMODE_LMAP;
-	    if (curbuf->b_p_imsearch != B_IMODE_USE_INSERT)
-		curbuf->b_p_imsearch = B_IMODE_LMAP;
-	    set_iminsert_global();
-	    set_imsearch_global();
+	    if (*curbuf->b_p_keymap != NUL)
+	    {
+		/* Installed a new keymap, switch on using it. */
+		curbuf->b_p_iminsert = B_IMODE_LMAP;
+		if (curbuf->b_p_imsearch != B_IMODE_USE_INSERT)
+		    curbuf->b_p_imsearch = B_IMODE_LMAP;
+	    }
+	    else
+	    {
+		/* Cleared the keymap, may reset 'iminsert' and 'imsearch'. */
+		if (curbuf->b_p_iminsert == B_IMODE_LMAP)
+		    curbuf->b_p_iminsert = B_IMODE_NONE;
+		if (curbuf->b_p_imsearch == B_IMODE_LMAP)
+		    curbuf->b_p_imsearch = B_IMODE_USE_INSERT;
+	    }
+	    if ((opt_flags & OPT_LOCAL) == 0)
+	    {
+		set_iminsert_global();
+		set_imsearch_global();
+	    }
 # ifdef FEAT_WINDOWS
 	    status_redraw_curbuf();
 # endif
@@ -5796,7 +5841,7 @@
 	    else
 		curbuf->b_p_tx = FALSE;
 #ifdef FEAT_TITLE
-	    need_maketitle = TRUE;
+	    redraw_titles();
 #endif
 	    /* update flag in swap file */
 	    ml_setflags(curbuf);
@@ -6055,6 +6100,7 @@
 		    errmsg = (char_u *)N_("E596: Invalid font(s)");
 	    }
 	}
+	redraw_gui_only = TRUE;
     }
 # ifdef FEAT_XFONTSET
     else if (varp == &p_guifontset)
@@ -6063,6 +6109,7 @@
 	    errmsg = (char_u *)N_("E597: can't select fontset");
 	else if (gui.in_use && gui_init_font(p_guifontset, TRUE) != OK)
 	    errmsg = (char_u *)N_("E598: Invalid fontset");
+	redraw_gui_only = TRUE;
     }
 # endif
 # ifdef FEAT_MBYTE
@@ -6072,6 +6119,7 @@
 	    errmsg = (char_u *)N_("E533: can't select wide font");
 	else if (gui_get_wide_font() == FAIL)
 	    errmsg = (char_u *)N_("E534: Invalid wide font");
+	redraw_gui_only = TRUE;
     }
 # endif
 #endif
@@ -6133,13 +6181,24 @@
 #ifdef FEAT_GUI
     /* 'guioptions' */
     else if (varp == &p_go)
+    {
 	gui_init_which_components(oldval);
+	redraw_gui_only = TRUE;
+    }
 #endif
 
 #if defined(FEAT_GUI_TABLINE)
     /* 'guitablabel' */
     else if (varp == &p_gtl)
+    {
 	redraw_tabline = TRUE;
+	redraw_gui_only = TRUE;
+    }
+    /* 'guitabtooltip' */
+    else if (varp == &p_gtt)
+    {
+	redraw_gui_only = TRUE;
+    }
 #endif
 
 #if defined(FEAT_MOUSE_TTY) && (defined(UNIX) || defined(VMS))
@@ -6717,7 +6776,11 @@
 
     if (curwin->w_curswant != MAXCOL)
 	curwin->w_set_curswant = TRUE;  /* in case 'showbreak' changed */
-    check_redraw(options[opt_idx].flags);
+#ifdef FEAT_GUI
+    /* check redraw when it's not a GUI option or the GUI is active. */
+    if (!redraw_gui_only || gui.in_use)
+#endif
+	check_redraw(options[opt_idx].flags);
 
     return errmsg;
 }
@@ -7105,22 +7168,28 @@
 	    curbuf->b_did_warn = FALSE;
 
 #ifdef FEAT_TITLE
-	need_maketitle = TRUE;
+	redraw_titles();
 #endif
     }
 
 #ifdef FEAT_TITLE
     /* when 'modifiable' is changed, redraw the window title */
     else if ((int *)varp == &curbuf->b_p_ma)
-	need_maketitle = TRUE;
+    {
+	redraw_titles();
+    }
     /* 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 */
+    {
+	redraw_titles();
+    }
+# ifdef FEAT_MBYTE
+    /* when 'bomb' is changed, redraw the window title and tab page text */
     else if ((int *)varp == &curbuf->b_p_bomb)
-	need_maketitle = TRUE;
-#endif
+    {
+	redraw_titles();
+    }
+# endif
 #endif
 
     /* when 'bin' is set also set some other options */
@@ -7128,7 +7197,7 @@
     {
 	set_options_bin(old_value, curbuf->b_p_bin, opt_flags);
 #ifdef FEAT_TITLE
-	need_maketitle = TRUE;
+	redraw_titles();
 #endif
     }
 
@@ -7279,7 +7348,7 @@
 	if (!value)
 	    save_file_ff(curbuf);	/* Buffer is unchanged */
 #ifdef FEAT_TITLE
-	need_maketitle = TRUE;
+	redraw_titles();
 #endif
 #ifdef FEAT_AUTOCMD
 	modified_was_set = value;
@@ -7714,7 +7783,7 @@
 	newFoldLevel();
     }
 
-    /* 'foldminlevel' */
+    /* 'foldminlines' */
     else if (pp == &curwin->w_p_fml)
     {
 	foldUpdateAll(curwin);
@@ -7974,6 +8043,11 @@
 	else /* curwin->w_p_scr > curwin->w_height */
 	    curwin->w_p_scr = curwin->w_height;
     }
+    if (p_hi < 0)
+    {
+	errmsg = e_positive;
+	p_hi = 0;
+    }
     if (p_report < 0)
     {
 	errmsg = e_positive;
@@ -8227,13 +8301,13 @@
 	    {
 		if (number == 0 && string != NULL)
 		{
-		    int index;
+		    int idx;
 
 		    /* Either we are given a string or we are setting option
 		     * to zero. */
-		    for (index = 0; string[index] == '0'; ++index)
+		    for (idx = 0; string[idx] == '0'; ++idx)
 			;
-		    if (string[index] != NUL || index == 0)
+		    if (string[idx] != NUL || idx == 0)
 		    {
 			/* There's another character after zeros or the string
 			 * is empty.  In both cases, we are trying to set a
@@ -8323,7 +8397,7 @@
     {
 	--arg;			    /* put arg at the '<' */
 	modifiers = 0;
-	key = find_special_key(&arg, &modifiers, TRUE);
+	key = find_special_key(&arg, &modifiers, TRUE, TRUE);
 	if (modifiers)		    /* can't handle modifiers here */
 	    key = 0;
     }
@@ -10093,25 +10167,110 @@
 
 #ifdef FEAT_LANGMAP
 /*
- * Any character has an equivalent character.  This is used for keyboards that
- * have a special language mode that sends characters above 128 (although
- * other characters can be translated too).
+ * Any character has an equivalent 'langmap' character.  This is used for
+ * keyboards that have a special language mode that sends characters above
+ * 128 (although other characters can be translated too).  The "to" field is a
+ * Vim command character.  This avoids having to switch the keyboard back to
+ * ASCII mode when leaving Insert mode.
+ *
+ * langmap_mapchar[] maps any of 256 chars to an ASCII char used for Vim
+ * commands.
+ * When FEAT_MBYTE is defined langmap_mapga.ga_data is a sorted table of
+ * langmap_entry_T.  This does the same as langmap_mapchar[] for characters >=
+ * 256.
  */
+# ifdef FEAT_MBYTE
+/*
+ * With multi-byte support use growarray for 'langmap' chars >= 256
+ */
+typedef struct
+{
+    int	    from;
+    int     to;
+} langmap_entry_T;
+
+static garray_T langmap_mapga;
+static void langmap_set_entry __ARGS((int from, int to));
 
 /*
- * char_u langmap_mapchar[256];
- * Normally maps each of the 128 upper chars to an <128 ascii char; used to
- * "translate" native lang chars in normal mode or some cases of
- * insert mode without having to tediously switch lang mode back&forth.
+ * Search for an entry in "langmap_mapga" for "from".  If found set the "to"
+ * field.  If not found insert a new entry at the appropriate location.
  */
+    static void
+langmap_set_entry(from, to)
+    int    from;
+    int    to;
+{
+    langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data);
+    int             a = 0;
+    int             b = langmap_mapga.ga_len;
+
+    /* Do a binary search for an existing entry. */
+    while (a != b)
+    {
+	int i = (a + b) / 2;
+	int d = entries[i].from - from;
+
+	if (d == 0)
+	{
+	    entries[i].to = to;
+	    return;
+	}
+	if (d < 0)
+	    a = i + 1;
+	else
+	    b = i;
+    }
+
+    if (ga_grow(&langmap_mapga, 1) != OK)
+	return;  /* out of memory */
+
+    /* insert new entry at position "a" */
+    entries = (langmap_entry_T *)(langmap_mapga.ga_data) + a;
+    mch_memmove(entries + 1, entries,
+			(langmap_mapga.ga_len - a) * sizeof(langmap_entry_T));
+    ++langmap_mapga.ga_len;
+    entries[0].from = from;
+    entries[0].to = to;
+}
+
+/*
+ * Apply 'langmap' to multi-byte character "c" and return the result.
+ */
+    int
+langmap_adjust_mb(c)
+    int c;
+{
+    langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data);
+    int a = 0;
+    int b = langmap_mapga.ga_len;
+
+    while (a != b)
+    {
+	int i = (a + b) / 2;
+	int d = entries[i].from - c;
+
+	if (d == 0)
+	    return entries[i].to;  /* found matching entry */
+	if (d < 0)
+	    a = i + 1;
+	else
+	    b = i;
+    }
+    return c;  /* no entry found, return "c" unmodified */
+}
+# endif
 
     static void
 langmap_init()
 {
     int i;
 
-    for (i = 0; i < 256; i++)		/* we init with a-one-to one map */
-	langmap_mapchar[i] = i;
+    for (i = 0; i < 256; i++)
+	langmap_mapchar[i] = i;	 /* we init with a one-to-one map */
+# ifdef FEAT_MBYTE
+    ga_init2(&langmap_mapga, sizeof(langmap_entry_T), 8);
+# endif
 }
 
 /*
@@ -10125,7 +10284,10 @@
     char_u  *p2;
     int	    from, to;
 
-    langmap_init();			    /* back to one-to-one map first */
+#ifdef FEAT_MBYTE
+    ga_clear(&langmap_mapga);		    /* clear the previous map first */
+#endif
+    langmap_init();			    /* back to one-to-one map */
 
     for (p = p_langmap; p[0] != NUL; )
     {
@@ -10175,7 +10337,13 @@
 							     transchar(from));
 		return;
 	    }
-	    langmap_mapchar[from & 255] = to;
+
+#ifdef FEAT_MBYTE
+	    if (from >= 256)
+		langmap_set_entry(from, to);
+	    else
+#endif
+		langmap_mapchar[from & 255] = to;
 
 	    /* Advance to next pair */
 	    mb_ptr_adv(p);
diff -Naur vim72.orig/src/os_unix.c vim72/src/os_unix.c
--- vim72.orig/src/os_unix.c	2008-08-06 04:01:40.000000000 -0700
+++ vim72/src/os_unix.c	2009-03-12 11:55:13.671618662 -0700
@@ -181,7 +181,8 @@
 	&& defined(FEAT_TITLE) && !defined(FEAT_GUI_GTK)
 # define SET_SIG_ALARM
 static RETSIGTYPE sig_alarm __ARGS(SIGPROTOARG);
-static int sig_alarm_called;
+/* volatile because it is used in signal handler sig_alarm(). */
+static volatile int sig_alarm_called;
 #endif
 static RETSIGTYPE deathtrap __ARGS(SIGPROTOARG);
 
@@ -201,13 +202,16 @@
 # define SIG_ERR	((RETSIGTYPE (*)())-1)
 #endif
 
-static int	do_resize = FALSE;
+/* volatile because it is used in signal handler sig_winch(). */
+static volatile int do_resize = FALSE;
 #ifndef __EMX__
 static char_u	*extra_shell_arg = NULL;
 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() */
+/* volatile because it is used in signal handler deathtrap(). */
+static volatile int deadly_signal = 0;	    /* The signal we caught */
+/* volatile because it is used in signal handler deathtrap(). */
+static volatile int in_mch_delay = FALSE;    /* sleeping in mch_delay() */
 
 static int curr_tmode = TMODE_COOK;	/* contains current terminal mode */
 
@@ -315,12 +319,15 @@
     {-1,	    "Unknown!", FALSE}
 };
 
+/*
+ * Write s[len] to the screen.
+ */
     void
 mch_write(s, len)
     char_u	*s;
     int		len;
 {
-    write(1, (char *)s, len);
+    ignored = (int)write(1, (char *)s, len);
     if (p_wd)		/* Unix is too fast, slow down a bit more */
 	RealWaitForChar(read_cmd_fd, p_wd, NULL);
 }
@@ -799,7 +806,7 @@
 #endif
 
 /*
- * We need correct potatotypes for a signal function, otherwise mean compilers
+ * We need correct prototypes for a signal function, otherwise mean compilers
  * will barf when the second argument to signal() is ``wrong''.
  * Let me try it with a few tricky defines from my own osdef.h	(jw).
  */
@@ -1065,13 +1072,18 @@
     SIGRETURN;
 }
 
-#ifdef _REENTRANT
+#if defined(_REENTRANT) && defined(SIGCONT)
 /*
  * On Solaris with multi-threading, suspending might not work immediately.
  * Catch the SIGCONT signal, which will be used as an indication whether the
  * suspending has been done or not.
+ *
+ * On Linux, signal is not always handled immediately either.
+ * See https://bugs.launchpad.net/bugs/291373
+ *
+ * volatile because it is used in in signal handler sigcont_handler().
  */
-static int sigcont_received;
+static volatile int sigcont_received;
 static RETSIGTYPE sigcont_handler __ARGS(SIGPROTOARG);
 
 /*
@@ -1115,15 +1127,28 @@
     }
 # endif
 
-# ifdef _REENTRANT
+# if defined(_REENTRANT) && defined(SIGCONT)
     sigcont_received = FALSE;
 # endif
     kill(0, SIGTSTP);	    /* send ourselves a STOP signal */
-# ifdef _REENTRANT
-    /* When we didn't suspend immediately in the kill(), do it now.  Happens
-     * on multi-threaded Solaris. */
-    if (!sigcont_received)
-	pause();
+# if defined(_REENTRANT) && defined(SIGCONT)
+    /*
+     * Wait for the SIGCONT signal to be handled. It generally happens
+     * immediately, but somehow not all the time. Do not call pause()
+     * because there would be race condition which would hang Vim if
+     * signal happened in between the test of sigcont_received and the
+     * call to pause(). If signal is not yet received, call sleep(0)
+     * to just yield CPU. Signal should then be received. If somehow
+     * it's still not received, sleep 1, 2, 3 ms. Don't bother waiting
+     * further if signal is not received after 1+2+3+4 ms (not expected
+     * to happen).
+     */
+    {
+	long wait;
+	for (wait = 0; !sigcont_received && wait <= 3L; wait++)
+	    /* Loop is not entered most of the time */
+	    mch_delay(wait, FALSE);
+    }
 # endif
 
 # ifdef FEAT_TITLE
@@ -1172,7 +1197,7 @@
 #ifdef SIGTSTP
     signal(SIGTSTP, restricted ? SIG_IGN : SIG_DFL);
 #endif
-#ifdef _REENTRANT
+#if defined(_REENTRANT) && defined(SIGCONT)
     signal(SIGCONT, sigcont_handler);
 #endif
 
@@ -1231,7 +1256,7 @@
 reset_signals()
 {
     catch_signals(SIG_DFL, SIG_DFL);
-#ifdef _REENTRANT
+#if defined(_REENTRANT) && defined(SIGCONT)
     /* SIGCONT isn't in the list, because its default action is ignore */
     signal(SIGCONT, SIG_DFL);
 #endif
@@ -2905,7 +2930,7 @@
      * Ignore any errors.
      */
 #if defined(HAVE_SIGALTSTACK) || defined(HAVE_SIGSTACK)
-    signal_stack = malloc(SIGSTKSZ);
+    signal_stack = (char *)alloc(SIGSTKSZ);
     init_signal_stack();
 #endif
 }
@@ -2936,7 +2961,8 @@
     }
 #  endif
 # endif
-# ifdef FEAT_X11
+    /* Don't close the display for GTK 1, it is done in exit(). */
+# if defined(FEAT_X11) && (!defined(FEAT_GUI_GTK) || defined(HAVE_GTK2))
     if (x11_display != NULL
 #  ifdef FEAT_XCLIPBOARD
 	    && x11_display != xterm_dpy
@@ -3926,9 +3952,9 @@
 		 */
 		if (fd >= 0)
 		{
-		    dup(fd); /* To replace stdin  (file descriptor 0) */
-		    dup(fd); /* To replace stdout (file descriptor 1) */
-		    dup(fd); /* To replace stderr (file descriptor 2) */
+		    ignored = dup(fd); /* To replace stdin  (fd 0) */
+		    ignored = dup(fd); /* To replace stdout (fd 1) */
+		    ignored = dup(fd); /* To replace stderr (fd 2) */
 
 		    /* Don't need this now that we've duplicated it */
 		    close(fd);
@@ -3946,7 +3972,17 @@
 		 * children can be kill()ed.  Don't do this when using pipes,
 		 * because stdin is not a tty, we would lose /dev/tty. */
 		if (p_stmp)
+		{
 		    (void)setsid();
+#  if defined(SIGHUP)
+		    /* When doing "!xterm&" and 'shell' is bash: the shell
+		     * will exit and send SIGHUP to all processes in its
+		     * group, killing the just started process.  Ignore SIGHUP
+		     * to avoid that. (suggested by Simon Schubert)
+		     */
+		    signal(SIGHUP, SIG_IGN);
+#  endif
+		}
 # endif
 # ifdef FEAT_GUI
 		if (pty_slave_fd >= 0)
@@ -3996,13 +4032,13 @@
 
 		    /* set up stdin/stdout/stderr for the child */
 		    close(0);
-		    dup(pty_slave_fd);
+		    ignored = dup(pty_slave_fd);
 		    close(1);
-		    dup(pty_slave_fd);
+		    ignored = dup(pty_slave_fd);
 		    if (gui.in_use)
 		    {
 			close(2);
-			dup(pty_slave_fd);
+			ignored = dup(pty_slave_fd);
 		    }
 
 		    close(pty_slave_fd);    /* has been dupped, close it now */
@@ -4013,13 +4049,13 @@
 		    /* set up stdin for the child */
 		    close(fd_toshell[1]);
 		    close(0);
-		    dup(fd_toshell[0]);
+		    ignored = dup(fd_toshell[0]);
 		    close(fd_toshell[0]);
 
 		    /* set up stdout for the child */
 		    close(fd_fromshell[0]);
 		    close(1);
-		    dup(fd_fromshell[1]);
+		    ignored = dup(fd_fromshell[1]);
 		    close(fd_fromshell[1]);
 
 # ifdef FEAT_GUI
@@ -4027,7 +4063,7 @@
 		    {
 			/* set up stderr for the child */
 			close(2);
-			dup(1);
+			ignored = dup(1);
 		    }
 # endif
 		}
@@ -4078,6 +4114,9 @@
 		int	    fromshell_fd;
 		garray_T    ga;
 		int	    noread_cnt;
+# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
+		struct timeval  start_tv;
+# endif
 
 # ifdef FEAT_GUI
 		if (pty_master_fd >= 0)
@@ -4158,7 +4197,8 @@
 					    && (lnum !=
 						    curbuf->b_ml.ml_line_count
 						    || curbuf->b_p_eol)))
-				    write(toshell_fd, "\n", (size_t)1);
+				    ignored = write(toshell_fd, "\n",
+								   (size_t)1);
 				++lnum;
 				if (lnum > curbuf->b_op_end.lnum)
 				{
@@ -4186,7 +4226,9 @@
 		    ga_init2(&ga, 1, BUFLEN);
 
 		noread_cnt = 0;
-
+# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
+		gettimeofday(&start_tv, NULL);
+# endif
 		for (;;)
 		{
 		    /*
@@ -4199,25 +4241,34 @@
 		     * that a typed password is echoed for ssh or gpg command.
 		     * Don't get characters when the child has already
 		     * finished (wait_pid == 0).
-		     * Don't get extra characters when we already have one.
 		     * Don't read characters unless we didn't get output for a
-		     * while, avoids that ":r !ls" eats typeahead.
+		     * while (noread_cnt > 4), avoids that ":r !ls" eats
+		     * typeahead.
 		     */
 		    len = 0;
 		    if (!(options & SHELL_EXPAND)
 			    && ((options &
 					 (SHELL_READ|SHELL_WRITE|SHELL_COOKED))
 				      != (SHELL_READ|SHELL_WRITE|SHELL_COOKED)
-#ifdef FEAT_GUI
+# ifdef FEAT_GUI
 						    || gui.in_use
-#endif
+# endif
 						    )
 			    && wait_pid == 0
-			    && (ta_len > 0
-				|| (noread_cnt > 4
-				    && (len = ui_inchar(ta_buf,
-						       BUFLEN, 10L, 0)) > 0)))
+			    && (ta_len > 0 || noread_cnt > 4))
 		    {
+		      if (ta_len == 0)
+		      {
+			  /* Get extra characters when we don't have any.
+			   * Reset the counter and timer. */
+			  noread_cnt = 0;
+# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
+			  gettimeofday(&start_tv, NULL);
+# endif
+			  len = ui_inchar(ta_buf, BUFLEN, 10L, 0);
+		      }
+		      if (ta_len > 0 || len > 0)
+		      {
 			/*
 			 * For pipes:
 			 * Check for CTRL-C: send interrupt signal to child.
@@ -4319,9 +4370,9 @@
 			    {
 				ta_len -= len;
 				mch_memmove(ta_buf, ta_buf + len, ta_len);
-				noread_cnt = 0;
 			    }
 			}
+		      }
 		    }
 
 		    if (got_int)
@@ -4429,6 +4480,25 @@
 			out_flush();
 			if (got_int)
 			    break;
+
+# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
+			{
+			    struct timeval  now_tv;
+			    long	    msec;
+
+			    /* Avoid that we keep looping here without
+			     * checking for a CTRL-C for a long time.  Don't
+			     * break out too often to avoid losing typeahead. */
+			    gettimeofday(&now_tv, NULL);
+			    msec = (now_tv.tv_sec - start_tv.tv_sec) * 1000L
+				+ (now_tv.tv_usec - start_tv.tv_usec) / 1000L;
+			    if (msec > 2000)
+			    {
+				noread_cnt = 5;
+				break;
+			    }
+			}
+# endif
 		    }
 
 		    /* If we already detected the child has finished break the
@@ -5851,7 +5921,9 @@
 	     * we are going to suspend or starting an external process
 	     * so we shouldn't  have problem with this
 	     */
+# ifdef SIGTSTP
 	    signal(SIGTSTP, restricted ? SIG_IGN : SIG_DFL);
+# endif
 	    return 1; /* succeed */
 	}
 	if (gpm_fd == -2)
@@ -6814,7 +6886,8 @@
     if (xsmp_icefd != -1)
     {
 	SmcCloseConnection(xsmp.smcconn, 0, NULL);
-	vim_free(xsmp.clientid);
+	if (xsmp.clientid != NULL)
+	    free(xsmp.clientid);
 	xsmp.clientid = NULL;
 	xsmp_icefd = -1;
     }
diff -Naur vim72.orig/src/proto/eval.pro vim72/src/proto/eval.pro
--- vim72.orig/src/proto/eval.pro	2008-08-09 07:31:25.000000000 -0700
+++ vim72/src/proto/eval.pro	2009-03-12 11:54:47.005909205 -0700
@@ -17,7 +17,7 @@
 int eval_to_bool __ARGS((char_u *arg, int *error, char_u **nextcmd, int skip));
 char_u *eval_to_string_skip __ARGS((char_u *arg, char_u **nextcmd, int skip));
 int skip_expr __ARGS((char_u **pp));
-char_u *eval_to_string __ARGS((char_u *arg, char_u **nextcmd, int dolist));
+char_u *eval_to_string __ARGS((char_u *arg, char_u **nextcmd, int convert));
 char_u *eval_to_string_safe __ARGS((char_u *arg, char_u **nextcmd, int use_sandbox));
 int eval_to_number __ARGS((char_u *expr));
 list_T *eval_spell_expr __ARGS((char_u *badword, char_u *expr));
@@ -46,7 +46,9 @@
 void list_unref __ARGS((list_T *l));
 void list_free __ARGS((list_T *l, int recurse));
 dictitem_T *dict_lookup __ARGS((hashitem_T *hi));
+char_u *list_find_str __ARGS((list_T *l, long idx));
 int list_append_dict __ARGS((list_T *list, dict_T *dict));
+int list_append_string __ARGS((list_T *l, char_u *str, int len));
 int garbage_collect __ARGS((void));
 dict_T *dict_alloc __ARGS((void));
 int dict_add_nr_str __ARGS((dict_T *d, char *key, long nr, char_u *str));
@@ -58,8 +60,10 @@
 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));
-void set_vcount __ARGS((long count, long count1));
+list_T *get_vim_var_list __ARGS((int idx));
+void set_vcount __ARGS((long count, long count1, int set_prevcount));
 void set_vim_var_string __ARGS((int idx, char_u *val, int len));
+void set_vim_var_list __ARGS((int idx, list_T *val));
 void set_reg_var __ARGS((int c));
 char_u *v_exception __ARGS((char_u *oldval));
 char_u *v_throwpoint __ARGS((char_u *oldval));
@@ -94,6 +98,7 @@
 void write_viminfo_varlist __ARGS((FILE *fp));
 int store_session_globals __ARGS((FILE *fd));
 void last_set_msg __ARGS((scid_T scriptID));
+void ex_oldfiles __ARGS((exarg_T *eap));
 int modify_fname __ARGS((char_u *src, int *usedlen, char_u **fnamep, char_u **bufp, int *fnamelen));
 char_u *do_string_sub __ARGS((char_u *str, char_u *pat, char_u *sub, char_u *flags));
 /* vim: set ft=c : */
diff -Naur vim72.orig/src/proto/ex_cmds.pro vim72/src/proto/ex_cmds.pro
--- vim72.orig/src/proto/ex_cmds.pro	2008-08-09 07:31:25.000000000 -0700
+++ vim72/src/proto/ex_cmds.pro	2009-03-12 11:55:13.611614471 -0700
@@ -11,7 +11,7 @@
 char_u *make_filter_cmd __ARGS((char_u *cmd, char_u *itmp, char_u *otmp));
 void append_redir __ARGS((char_u *buf, char_u *opt, char_u *fname));
 int viminfo_error __ARGS((char *errnum, char *message, char_u *line));
-int read_viminfo __ARGS((char_u *file, int want_info, int want_marks, int forceit));
+int read_viminfo __ARGS((char_u *file, int flags));
 void write_viminfo __ARGS((char_u *file, int forceit));
 int viminfo_readline __ARGS((vir_T *virp));
 char_u *viminfo_readstring __ARGS((vir_T *virp, int off, int convert));
@@ -40,6 +40,7 @@
 int read_viminfo_sub_string __ARGS((vir_T *virp, int force));
 void write_viminfo_sub_string __ARGS((FILE *fp));
 void free_old_sub __ARGS((void));
+void free_signs __ARGS((void));
 int prepare_tagpreview __ARGS((int undo_sync));
 void ex_help __ARGS((exarg_T *eap));
 char_u *check_help_lang __ARGS((char_u *arg));
diff -Naur vim72.orig/src/proto/ex_getln.pro vim72/src/proto/ex_getln.pro
--- vim72.orig/src/proto/ex_getln.pro	2008-08-09 07:31:28.000000000 -0700
+++ vim72/src/proto/ex_getln.pro	2009-03-12 11:55:13.703620617 -0700
@@ -4,6 +4,7 @@
 int text_locked __ARGS((void));
 void text_locked_msg __ARGS((void));
 int curbuf_locked __ARGS((void));
+int allbuf_locked __ARGS((void));
 char_u *getexline __ARGS((int c, void *dummy, int indent));
 char_u *getexmodeline __ARGS((int promptc, void *dummy, int indent));
 int cmdline_overstrike __ARGS((void));
@@ -31,7 +32,7 @@
 void set_cmd_context __ARGS((expand_T *xp, char_u *str, int len, int col));
 int expand_cmdline __ARGS((expand_T *xp, char_u *str, int col, int *matchcount, char_u ***matches));
 int ExpandGeneric __ARGS((expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file, char_u *((*func)(expand_T *, int))));
-char_u *globpath __ARGS((char_u *path, char_u *file));
+char_u *globpath __ARGS((char_u *path, char_u *file, int expand_options));
 void init_history __ARGS((void));
 int get_histtype __ARGS((char_u *name));
 void add_to_history __ARGS((int histype, char_u *new_entry, int in_map, int sep));
diff -Naur vim72.orig/src/proto/mark.pro vim72/src/proto/mark.pro
--- vim72.orig/src/proto/mark.pro	2008-08-09 07:31:36.000000000 -0700
+++ vim72/src/proto/mark.pro	2009-03-12 11:54:40.553496578 -0700
@@ -26,5 +26,5 @@
 void write_viminfo_filemarks __ARGS((FILE *fp));
 int removable __ARGS((char_u *name));
 int write_viminfo_marks __ARGS((FILE *fp_out));
-void copy_viminfo_marks __ARGS((vir_T *virp, FILE *fp_out, int count, int eof));
+void copy_viminfo_marks __ARGS((vir_T *virp, FILE *fp_out, int count, int eof, int flags));
 /* vim: set ft=c : */
diff -Naur vim72.orig/src/proto/misc2.pro vim72/src/proto/misc2.pro
--- vim72.orig/src/proto/misc2.pro	2008-08-09 07:31:40.000000000 -0700
+++ vim72/src/proto/misc2.pro	2009-03-12 11:54:56.454515435 -0700
@@ -59,7 +59,7 @@
 int handle_x_keys __ARGS((int key));
 char_u *get_special_key_name __ARGS((int c, int modifiers));
 int trans_special __ARGS((char_u **srcp, char_u *dst, int keycode));
-int find_special_key __ARGS((char_u **srcp, int *modp, int keycode));
+int find_special_key __ARGS((char_u **srcp, int *modp, int keycode, int keep_x_key));
 int extract_modifiers __ARGS((int key, int *modp));
 int find_special_key_in_table __ARGS((int c));
 int get_special_key_code __ARGS((char_u *name));
diff -Naur vim72.orig/src/proto/netbeans.pro vim72/src/proto/netbeans.pro
--- vim72.orig/src/proto/netbeans.pro	2008-08-09 07:31:56.000000000 -0700
+++ vim72/src/proto/netbeans.pro	2009-03-12 11:54:59.854733063 -0700
@@ -11,7 +11,7 @@
 void netbeans_frame_moved __ARGS((int new_x, int new_y));
 void netbeans_file_activated __ARGS((buf_T *bufp));
 void netbeans_file_opened __ARGS((buf_T *bufp));
-void netbeans_file_closed __ARGS((buf_T *bufp));
+void netbeans_file_killed __ARGS((buf_T *bufp));
 void netbeans_inserted __ARGS((buf_T *bufp, linenr_T linenr, colnr_T col, char_u *txt, int newlen));
 void netbeans_removed __ARGS((buf_T *bufp, linenr_T linenr, colnr_T col, long len));
 void netbeans_unmodified __ARGS((buf_T *bufp));
diff -Naur vim72.orig/src/proto/option.pro vim72/src/proto/option.pro
--- vim72.orig/src/proto/option.pro	2008-08-09 07:31:43.000000000 -0700
+++ vim72/src/proto/option.pro	2009-03-12 11:55:13.419602459 -0700
@@ -44,6 +44,7 @@
 void set_context_in_set_cmd __ARGS((expand_T *xp, char_u *arg, int opt_flags));
 int ExpandSettings __ARGS((expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file));
 int ExpandOldSetting __ARGS((int *num_file, char_u ***file));
+int langmap_adjust_mb __ARGS((int c));
 int has_format_option __ARGS((int x));
 int shortmess __ARGS((int x));
 void vimrc_found __ARGS((char_u *fname, char_u *envname));
diff -Naur vim72.orig/src/pty.c vim72/src/pty.c
--- vim72.orig/src/pty.c	2008-06-21 11:52:58.000000000 -0700
+++ vim72/src/pty.c	2009-03-12 11:54:28.844744238 -0700
@@ -270,9 +270,10 @@
 }
 #endif
 
-#if defined(HAVE_SVR4_PTYS) && !defined(PTY_DONE) && !defined(hpux)
+#if defined(HAVE_SVR4_PTYS) && !defined(PTY_DONE) && !defined(hpux) && !defined(MACOS_X)
 
-/* NOTE: Even though HPUX can have /dev/ptmx, the code below doesn't work! */
+/* NOTE: Even though HPUX can have /dev/ptmx, the code below doesn't work!
+ * Same for Mac OS X Leopard. */
 #define PTY_DONE
     int
 OpenPTY(ttyn)
diff -Naur vim72.orig/src/quickfix.c vim72/src/quickfix.c
--- vim72.orig/src/quickfix.c	2008-07-18 05:53:02.000000000 -0700
+++ vim72/src/quickfix.c	2009-03-12 11:55:13.547610560 -0700
@@ -1419,6 +1419,7 @@
     int			opened_window = FALSE;
     win_T		*win;
     win_T		*altwin;
+    int			flags;
 #endif
     int			print_message = TRUE;
     int			len;
@@ -1530,7 +1531,6 @@
     if (qf_ptr->qf_type == 1 && (!curwin->w_buffer->b_help || cmdmod.tab != 0))
     {
 	win_T	*wp;
-	int	n;
 
 	if (cmdmod.tab != 0)
 	    wp = NULL;
@@ -1546,13 +1546,16 @@
 	     * Split off help window; put it at far top if no position
 	     * specified, the current window is vertically split and narrow.
 	     */
-	    n = WSP_HELP;
+	    flags = WSP_HELP;
 # ifdef FEAT_VERTSPLIT
 	    if (cmdmod.split == 0 && curwin->w_width != Columns
 						      && curwin->w_width < 80)
-		n |= WSP_TOP;
+		flags |= WSP_TOP;
 # endif
-	    if (win_split(0, n) == FAIL)
+	    if (qi != &ql_info)
+		flags |= WSP_NEWLOC;  /* don't copy the location list */
+
+	    if (win_split(0, flags) == FAIL)
 		goto theend;
 	    opened_window = TRUE;	/* close it when fail */
 
@@ -1562,7 +1565,6 @@
 	    if (qi != &ql_info)	    /* not a quickfix list */
 	    {
 		/* The new window should use the supplied location list */
-		qf_free_all(curwin);
 		curwin->w_llist = qi;
 		qi->qf_refcount++;
 	    }
@@ -1609,10 +1611,11 @@
 		{
 		    goto_tabpage_win(tp, wp);
 		    usable_win = 1;
-		    break;
+		    goto win_found;
 		}
 	    }
 	}
+win_found:
 
 	/*
 	 * If there is only one window and it is the quickfix window, create a
@@ -1622,7 +1625,10 @@
 	{
 	    ll_ref = curwin->w_llist_ref;
 
-	    if (win_split(0, WSP_ABOVE) == FAIL)
+	    flags = WSP_ABOVE;
+	    if (ll_ref != NULL)
+		flags |= WSP_NEWLOC;
+	    if (win_split(0, flags) == FAIL)
 		goto failed;		/* not enough room for window */
 	    opened_window = TRUE;	/* close it when fail */
 	    p_swb = empty_option;	/* don't split again */
@@ -1634,7 +1640,6 @@
 	    {
 		/* The new window should use the location list from the
 		 * location list window */
-		qf_free_all(curwin);
 		curwin->w_llist = ll_ref;
 		ll_ref->qf_refcount++;
 	    }
@@ -2307,15 +2312,12 @@
 	if (eap->cmdidx == CMD_copen || eap->cmdidx == CMD_cwindow)
 	    /* Create the new window at the very bottom. */
 	    win_goto(lastwin);
-	if (win_split(height, WSP_BELOW) == FAIL)
+	if (win_split(height, WSP_BELOW | WSP_NEWLOC) == FAIL)
 	    return;		/* not enough room for window */
 #ifdef FEAT_SCROLLBIND
 	curwin->w_p_scb = FALSE;
 #endif
 
-	/* Remove the location list for the quickfix window */
-	qf_free_all(curwin);
-
 	if (eap->cmdidx == CMD_lopen || eap->cmdidx == CMD_lwindow)
 	{
 	    /*
diff -Naur vim72.orig/src/regexp.c vim72/src/regexp.c
--- vim72.orig/src/regexp.c	2008-08-07 12:58:50.000000000 -0700
+++ vim72/src/regexp.c	2009-03-12 11:55:13.471605532 -0700
@@ -4532,7 +4532,7 @@
 		cleanup_subexpr();
 		if (!REG_MULTI)		/* Single-line regexp */
 		{
-		    if (reg_endp[no] == NULL)
+		    if (reg_startp[no] == NULL || reg_endp[no] == NULL)
 		    {
 			/* Backref was not set: Match an empty string. */
 			len = 0;
@@ -4548,7 +4548,7 @@
 		}
 		else				/* Multi-line regexp */
 		{
-		    if (reg_endpos[no].lnum < 0)
+		    if (reg_startpos[no].lnum < 0 || reg_endpos[no].lnum < 0)
 		    {
 			/* Backref was not set: Match an empty string. */
 			len = 0;
@@ -7279,13 +7279,11 @@
     }
     else
     {
-	if (submatch_match->endp[no] == NULL)
+	s = submatch_match->startp[no];
+	if (s == NULL || submatch_match->endp[no] == NULL)
 	    retval = NULL;
 	else
-	{
-	    s = submatch_match->startp[no];
 	    retval = vim_strnsave(s, (int)(submatch_match->endp[no] - s));
-	}
     }
 
     return retval;
diff -Naur vim72.orig/src/screen.c vim72/src/screen.c
--- vim72.orig/src/screen.c	2008-07-24 07:45:07.000000000 -0700
+++ vim72/src/screen.c	2009-03-12 11:55:39.893297947 -0700
@@ -2439,9 +2439,17 @@
 
 #ifdef FEAT_SYN_HL
     /* Show 'cursorcolumn' in the fold line. */
-    if (wp->w_p_cuc && (int)wp->w_virtcol + txtcol < W_WIDTH(wp))
-	ScreenAttrs[off + wp->w_virtcol + txtcol] = hl_combine_attr(
-		 ScreenAttrs[off + wp->w_virtcol + txtcol], hl_attr(HLF_CUC));
+    if (wp->w_p_cuc)
+    {
+	txtcol += wp->w_virtcol;
+	if (wp->w_p_wrap)
+	    txtcol -= wp->w_skipcol;
+	else
+	    txtcol -= wp->w_leftcol;
+	if (txtcol >= 0 && txtcol < W_WIDTH(wp))
+	    ScreenAttrs[off + txtcol] = hl_combine_attr(
+				 ScreenAttrs[off + txtcol], hl_attr(HLF_CUC));
+    }
 #endif
 
     SCREEN_LINE(row + W_WINROW(wp), W_WINCOL(wp), (int)W_WIDTH(wp),
@@ -2588,6 +2596,7 @@
     int		noinvcur = FALSE;	/* don't invert the cursor */
 #ifdef FEAT_VISUAL
     pos_T	*top, *bot;
+    int		lnum_in_visual_area = FALSE;
 #endif
     pos_T	pos;
     long	v;
@@ -2784,9 +2793,10 @@
 	    top = &VIsual;
 	    bot = &curwin->w_cursor;
 	}
+	lnum_in_visual_area = (lnum >= top->lnum && lnum <= bot->lnum);
 	if (VIsual_mode == Ctrl_V)	/* block mode */
 	{
-	    if (lnum >= top->lnum && lnum <= bot->lnum)
+	    if (lnum_in_visual_area)
 	    {
 		fromcol = wp->w_old_cursor_fcol;
 		tocol = wp->w_old_cursor_lcol;
@@ -3412,6 +3422,7 @@
 			&& (*mb_ptr2cells)(ptr) > 1)
 #endif
 		    || ((int)vcol_prev == fromcol_prev
+			&& vcol_prev < vcol	/* not at margin */
 			&& vcol < tocol))
 		area_attr = attr;		/* start highlighting */
 	    else if (area_attr != 0
@@ -3544,7 +3555,8 @@
 		/* Use line_attr when not in the Visual or 'incsearch' area
 		 * (area_attr may be 0 when "noinvcur" is set). */
 	    else if (line_attr != 0 && ((fromcol == -10 && tocol == MAXCOL)
-					|| (vcol < fromcol || vcol >= tocol)))
+				|| vcol < fromcol || vcol_prev < fromcol_prev
+				|| vcol >= tocol))
 		char_attr = line_attr;
 #endif
 	    else
@@ -4549,7 +4561,8 @@
 	 * highlight the cursor position itself. */
 	if (wp->w_p_cuc && vcol == (long)wp->w_virtcol
 		&& lnum != wp->w_cursor.lnum
-		&& draw_state == WL_LINE)
+		&& draw_state == WL_LINE
+		&& !lnum_in_visual_area)
 	{
 	    vcol_save_attr = char_attr;
 	    char_attr = hl_combine_attr(char_attr, hl_attr(HLF_CUC));
@@ -5119,8 +5132,8 @@
 #endif
 
 #if defined(FEAT_GUI) || defined(UNIX)
-	    /* The bold trick makes a single row of pixels appear in the next
-	     * character.  When a bold character is removed, the next
+	    /* The bold trick makes a single column of pixels appear in the
+	     * next character.  When a bold character is removed, the next
 	     * character should be redrawn too.  This happens for our own GUI
 	     * and for some xterms. */
 	    if (
@@ -6263,9 +6276,15 @@
     int		pcc[MAX_MCO];
 # endif
 #endif
+#if defined(FEAT_MBYTE) || defined(FEAT_GUI) || defined(UNIX)
+    int		force_redraw_this;
+    int		force_redraw_next = FALSE;
+#endif
+    int		need_redraw;
 
     if (ScreenLines == NULL || row >= screen_Rows)	/* safety check */
 	return;
+    off = LineOffset[row] + col;
 
 #ifdef FEAT_MBYTE
     /* When drawing over the right halve of a double-wide char clear out the
@@ -6275,10 +6294,21 @@
 	    && !gui.in_use
 # endif
 	    && mb_fix_col(col, row) != col)
-	screen_puts_len((char_u *)" ", 1, row, col - 1, 0);
+    {
+	ScreenLines[off - 1] = ' ';
+	ScreenAttrs[off - 1] = 0;
+	if (enc_utf8)
+	{
+	    ScreenLinesUC[off - 1] = 0;
+	    ScreenLinesC[0][off - 1] = 0;
+	}
+	/* redraw the previous cell, make it empty */
+	screen_char(off - 1, row, col - 1);
+	/* force the cell at "col" to be redrawn */
+	force_redraw_next = TRUE;
+    }
 #endif
 
-    off = LineOffset[row] + col;
 #ifdef FEAT_MBYTE
     max_off = LineOffset[row] + screen_Columns;
 #endif
@@ -6342,7 +6372,12 @@
 	}
 #endif
 
-	if (ScreenLines[off] != c
+#if defined(FEAT_MBYTE) || defined(FEAT_GUI) || defined(UNIX)
+	force_redraw_this = force_redraw_next;
+	force_redraw_next = FALSE;
+#endif
+
+	need_redraw = ScreenLines[off] != c
 #ifdef FEAT_MBYTE
 		|| (mbyte_cells == 2
 		    && ScreenLines[off + 1] != (enc_dbcs ? ptr[1] : 0))
@@ -6350,24 +6385,24 @@
 		    && c == 0x8e
 		    && ScreenLines2[off] != ptr[1])
 		|| (enc_utf8
-		    && (ScreenLinesUC[off] != (u8char_T)u8c
+		    && (ScreenLinesUC[off] != (u8char_T)(c >= 0x80 ? u8c : 0)
 			|| screen_comp_differs(off, u8cc)))
 #endif
 		|| ScreenAttrs[off] != attr
-		|| exmode_active
+		|| exmode_active;
+
+	if (need_redraw
+#if defined(FEAT_MBYTE) || defined(FEAT_GUI) || defined(UNIX)
+		|| force_redraw_this
+#endif
 		)
 	{
 #if defined(FEAT_GUI) || defined(UNIX)
 	    /* The bold trick makes a single row of pixels appear in the next
 	     * character.  When a bold character is removed, the next
 	     * character should be redrawn too.  This happens for our own GUI
-	     * and for some xterms.
-	     * Force the redraw by setting the attribute to a different value
-	     * than "attr", the contents of ScreenLines[] may be needed by
-	     * mb_off2cells() further on.
-	     * Don't do this for the last drawn character, because the next
-	     * character may not be redrawn. */
-	    if (
+	     * and for some xterms. */
+	    if (need_redraw && ScreenLines[off] != ' ' && (
 # ifdef FEAT_GUI
 		    gui.in_use
 # endif
@@ -6377,23 +6412,14 @@
 # ifdef UNIX
 		    term_is_xterm
 # endif
-	       )
+		    ))
 	    {
-		int		n;
+		int	n = ScreenAttrs[off];
 
-		n = ScreenAttrs[off];
-# ifdef FEAT_MBYTE
-		if (col + mbyte_cells < screen_Columns
-			&& (n > HL_ALL || (n & HL_BOLD))
-			&& (len < 0 ? ptr[mbyte_blen] != NUL
-					     : ptr + mbyte_blen < text + len))
-		    ScreenAttrs[off + mbyte_cells] = attr + 1;
-# else
-		if (col + 1 < screen_Columns
-			&& (n > HL_ALL || (n & HL_BOLD))
-			&& (len < 0 ? ptr[1] != NUL : ptr + 1 < text + len))
-		    ScreenLines[off + 1] = 0;
-# endif
+		if (n > HL_ALL)
+		    n = syn_attr2attr(n);
+		if (n & HL_BOLD)
+		    force_redraw_next = TRUE;
 	    }
 #endif
 #ifdef FEAT_MBYTE
@@ -6480,6 +6506,20 @@
 	    ++ptr;
 	}
     }
+
+#if defined(FEAT_MBYTE) || defined(FEAT_GUI) || defined(UNIX)
+    /* If we detected the next character needs to be redrawn, but the text
+     * doesn't extend up to there, update the character here. */
+    if (force_redraw_next && col < screen_Columns)
+    {
+# ifdef FEAT_MBYTE
+	if (enc_dbcs != 0 && dbcs_off2cells(off, max_off) > 1)
+	    screen_char_2(off, row, col);
+	else
+# endif
+	    screen_char(off, row, col);
+    }
+#endif
 }
 
 #ifdef FEAT_SEARCH_EXTRA
@@ -7356,7 +7396,11 @@
 #endif
     static int	    entered = FALSE;		/* avoid recursiveness */
     static int	    done_outofmem_msg = FALSE;	/* did outofmem message */
+#ifdef FEAT_AUTOCMD
+    int		    retry_count = 0;
 
+retry:
+#endif
     /*
      * Allocation of the screen buffers is done only when the size changes and
      * when Rows and Columns have been set and we have started doing full
@@ -7440,10 +7484,13 @@
 	{
 	    outofmem = TRUE;
 #ifdef FEAT_WINDOWS
-	    break;
+	    goto give_up;
 #endif
 	}
     }
+#ifdef FEAT_WINDOWS
+give_up:
+#endif
 
 #ifdef FEAT_MBYTE
     for (i = 0; i < p_mco; ++i)
@@ -7628,8 +7675,17 @@
     --RedrawingDisabled;
 
 #ifdef FEAT_AUTOCMD
-    if (starting == 0)
+    /*
+     * Do not apply autocommands more than 3 times to avoid an endless loop
+     * in case applying autocommands always changes Rows or Columns.
+     */
+    if (starting == 0 && ++retry_count <= 3)
+    {
 	apply_autocmds(EVENT_VIMRESIZED, NULL, NULL, FALSE, curbuf);
+	/* In rare cases, autocommands may have altered Rows or Columns,
+	 * jump back to check if we need to allocate the screen again. */
+	goto retry;
+    }
 #endif
 }
 
diff -Naur vim72.orig/src/spell.c vim72/src/spell.c
--- vim72.orig/src/spell.c	2008-07-12 12:20:55.000000000 -0700
+++ vim72/src/spell.c	2009-03-12 11:55:13.363596871 -0700
@@ -77,7 +77,7 @@
 
 /*
  * Do the opposite: based on a maximum end score and a known sound score,
- * compute the the maximum word score that can be used.
+ * compute the maximum word score that can be used.
  */
 #define MAXSCORE(word_score, sound_score) ((4 * word_score - sound_score) / 3)
 
@@ -469,6 +469,7 @@
     garray_T	sl_comppat;	/* CHECKCOMPOUNDPATTERN items */
     regprog_T	*sl_compprog;	/* COMPOUNDRULE turned into a regexp progrm
 				 * (NULL when no compounding) */
+    char_u	*sl_comprules;	/* all COMPOUNDRULE concatenated (or NULL) */
     char_u	*sl_compstartflags; /* flags for first compound word */
     char_u	*sl_compallflags; /* all flags for compound words */
     char_u	sl_nobreak;	/* When TRUE: no spaces between words */
@@ -625,7 +626,7 @@
 /* TRUE if a word appears in the list of banned words.  */
 #define WAS_BANNED(su, word) (!HASHITEM_EMPTY(hash_find(&su->su_banned, word)))
 
-/* Number of suggestions kept when cleaning up.  we need to keep more than
+/* Number of suggestions kept when cleaning up.  We need to keep more than
  * what is displayed, because when rescore_suggestions() is called the score
  * may change and wrong suggestions may be removed later. */
 #define SUG_CLEAN_COUNT(su)    ((su)->su_maxcount < 130 ? 150 : (su)->su_maxcount + 20)
@@ -839,7 +840,10 @@
 static void slang_clear __ARGS((slang_T *lp));
 static void slang_clear_sug __ARGS((slang_T *lp));
 static void find_word __ARGS((matchinf_T *mip, int mode));
+static int match_checkcompoundpattern __ARGS((char_u *ptr, int wlen, garray_T *gap));
 static int can_compound __ARGS((slang_T *slang, char_u *word, char_u *flags));
+static int can_be_compound __ARGS((trystate_T *sp, slang_T *slang, char_u *compflags, int flag));
+static int match_compoundrule __ARGS((slang_T *slang, char_u *compflags));
 static int valid_word_prefix __ARGS((int totprefcnt, int arridx, int flags, char_u *word, slang_T *slang, int cond_req));
 static void find_prefix __ARGS((matchinf_T *mip, int mode));
 static int fold_more __ARGS((matchinf_T *mip));
@@ -1519,6 +1523,11 @@
 					    ((unsigned)flags >> 24)))
 		    continue;
 
+		/* If there is a match with a CHECKCOMPOUNDPATTERN rule
+		 * discard the compound word. */
+		if (match_checkcompoundpattern(ptr, wlen, &slang->sl_comppat))
+		    continue;
+
 		if (mode == FIND_COMPOUND)
 		{
 		    int	    capflags;
@@ -1577,6 +1586,11 @@
 		    if (!can_compound(slang, fword, mip->mi_compflags))
 			continue;
 		}
+		else if (slang->sl_comprules != NULL
+			     && !match_compoundrule(slang, mip->mi_compflags))
+		    /* The compound flags collected so far do not match any
+		     * COMPOUNDRULE, discard the compounded word. */
+		    continue;
 	    }
 
 	    /* Check NEEDCOMPOUND: can't use word without compounding. */
@@ -1727,6 +1741,39 @@
 }
 
 /*
+ * Return TRUE if there is a match between the word ptr[wlen] and
+ * CHECKCOMPOUNDPATTERN rules, assuming that we will concatenate with another
+ * word.
+ * A match means that the first part of CHECKCOMPOUNDPATTERN matches at the
+ * end of ptr[wlen] and the second part matches after it.
+ */
+    static int
+match_checkcompoundpattern(ptr, wlen, gap)
+    char_u	*ptr;
+    int		wlen;
+    garray_T	*gap;  /* &sl_comppat */
+{
+    int		i;
+    char_u	*p;
+    int		len;
+
+    for (i = 0; i + 1 < gap->ga_len; i += 2)
+    {
+	p = ((char_u **)gap->ga_data)[i + 1];
+	if (STRNCMP(ptr + wlen, p, STRLEN(p)) == 0)
+	{
+	    /* Second part matches at start of following compound word, now
+	     * check if first part matches at end of previous word. */
+	    p = ((char_u **)gap->ga_data)[i];
+	    len = (int)STRLEN(p);
+	    if (len <= wlen && STRNCMP(ptr + wlen - len, p, len) == 0)
+		return TRUE;
+	}
+    }
+    return FALSE;
+}
+
+/*
  * Return TRUE if "flags" is a valid sequence of compound flags and "word"
  * does not have too many syllables.
  */
@@ -1773,6 +1820,98 @@
 }
 
 /*
+ * Return TRUE when the sequence of flags in "compflags" plus "flag" can
+ * possibly form a valid compounded word.  This also checks the COMPOUNDRULE
+ * lines if they don't contain wildcards.
+ */
+    static int
+can_be_compound(sp, slang, compflags, flag)
+    trystate_T	*sp;
+    slang_T	*slang;
+    char_u	*compflags;
+    int		flag;
+{
+    /* If the flag doesn't appear in sl_compstartflags or sl_compallflags
+     * then it can't possibly compound. */
+    if (!byte_in_str(sp->ts_complen == sp->ts_compsplit
+		? slang->sl_compstartflags : slang->sl_compallflags, flag))
+	return FALSE;
+
+    /* If there are no wildcards, we can check if the flags collected so far
+     * possibly can form a match with COMPOUNDRULE patterns.  This only
+     * makes sense when we have two or more words. */
+    if (slang->sl_comprules != NULL && sp->ts_complen > sp->ts_compsplit)
+    {
+	int v;
+
+	compflags[sp->ts_complen] = flag;
+	compflags[sp->ts_complen + 1] = NUL;
+	v = match_compoundrule(slang, compflags + sp->ts_compsplit);
+	compflags[sp->ts_complen] = NUL;
+	return v;
+    }
+
+    return TRUE;
+}
+
+
+/*
+ * Return TRUE if the compound flags in compflags[] match the start of any
+ * compound rule.  This is used to stop trying a compound if the flags
+ * collected so far can't possibly match any compound rule.
+ * Caller must check that slang->sl_comprules is not NULL.
+ */
+    static int
+match_compoundrule(slang, compflags)
+    slang_T	*slang;
+    char_u	*compflags;
+{
+    char_u	*p;
+    int		i;
+    int		c;
+
+    /* loop over all the COMPOUNDRULE entries */
+    for (p = slang->sl_comprules; *p != NUL; ++p)
+    {
+	/* loop over the flags in the compound word we have made, match
+	 * them against the current rule entry */
+	for (i = 0; ; ++i)
+	{
+	    c = compflags[i];
+	    if (c == NUL)
+		/* found a rule that matches for the flags we have so far */
+		return TRUE;
+	    if (*p == '/' || *p == NUL)
+		break;  /* end of rule, it's too short */
+	    if (*p == '[')
+	    {
+		int match = FALSE;
+
+		/* compare against all the flags in [] */
+		++p;
+		while (*p != ']' && *p != NUL)
+		    if (*p++ == c)
+			match = TRUE;
+		if (!match)
+		    break;  /* none matches */
+	    }
+	    else if (*p != c)
+		break;  /* flag of word doesn't match flag in pattern */
+	    ++p;
+	}
+
+	/* Skip to the next "/", where the next pattern starts. */
+	p = vim_strchr(p, '/');
+	if (p == NULL)
+	    break;
+    }
+
+    /* Checked all the rules and none of them match the flags, so there
+     * can't possibly be a compound starting with these flags. */
+    return FALSE;
+}
+
+/*
  * Return non-zero if the prefix indicated by "arridx" matches with the prefix
  * ID in "flags" for the word "word".
  * The WF_RAREPFX flag is included in the return value for a rare prefix.
@@ -2237,7 +2376,7 @@
 
 	    /* If we are back at the starting line and there is no match then
 	     * give up. */
-	    if (lnum == wp->w_cursor.lnum && !found_one)
+	    if (lnum == wp->w_cursor.lnum && (!found_one || wrapped))
 		break;
 
 	    /* Skip the characters at the start of the next line that were
@@ -2513,9 +2652,11 @@
     lp->sl_midword = NULL;
 
     vim_free(lp->sl_compprog);
+    vim_free(lp->sl_comprules);
     vim_free(lp->sl_compstartflags);
     vim_free(lp->sl_compallflags);
     lp->sl_compprog = NULL;
+    lp->sl_comprules = NULL;
     lp->sl_compstartflags = NULL;
     lp->sl_compallflags = NULL;
 
@@ -3460,6 +3601,7 @@
     char_u	*pp;
     char_u	*cp;
     char_u	*ap;
+    char_u	*crp;
     int		cnt;
     garray_T	*gap;
 
@@ -3545,6 +3687,12 @@
     slang->sl_compallflags = ap;
     *ap = NUL;
 
+    /* And a list of all patterns in their original form, for checking whether
+     * compounding may work in match_compoundrule().  This is freed when we
+     * encounter a wildcard, the check doesn't work then. */
+    crp = alloc(todo + 1);
+    slang->sl_comprules = crp;
+
     pp = pat;
     *pp++ = '^';
     *pp++ = '\\';
@@ -3587,6 +3735,20 @@
 		    atstart = 0;
 	    }
 	}
+
+	/* Copy flag to "sl_comprules", unless we run into a wildcard. */
+	if (crp != NULL)
+	{
+	    if (c == '+' || c == '*')
+	    {
+		vim_free(slang->sl_comprules);
+		slang->sl_comprules = NULL;
+		crp = NULL;
+	    }
+	    else
+		*crp++ = c;
+	}
+
 	if (c == '/')	    /* slash separates two items */
 	{
 	    *pp++ = '\\';
@@ -3611,6 +3773,9 @@
     *pp++ = '$';
     *pp = NUL;
 
+    if (crp != NULL)
+	*crp = NUL;
+
     slang->sl_compprog = vim_regcomp(pat, RE_MAGIC + RE_STRING + RE_STRICT);
     vim_free(pat);
     if (slang->sl_compprog == NULL)
@@ -4791,13 +4956,16 @@
  * Structure that is used to store the items in the word tree.  This avoids
  * the need to keep track of each allocated thing, everything is freed all at
  * once after ":mkspell" is done.
+ * Note: "sb_next" must be just before "sb_data" to make sure the alignment of
+ * "sb_data" is correct for systems where pointers must be aligned on
+ * pointer-size boundaries and sizeof(pointer) > sizeof(int) (e.g., Sparc).
  */
 #define  SBLOCKSIZE 16000	/* size of sb_data */
 typedef struct sblock_S sblock_T;
 struct sblock_S
 {
-    sblock_T	*sb_next;	/* next block in list */
     int		sb_used;	/* nr of bytes already in use */
+    sblock_T	*sb_next;	/* next block in list */
     char_u	sb_data[1];	/* data, actually longer */
 };
 
@@ -4915,6 +5083,7 @@
 } spellinfo_T;
 
 static afffile_T *spell_read_aff __ARGS((spellinfo_T *spin, char_u *fname));
+static int is_aff_rule __ARGS((char_u **items, int itemcnt, char *rulename, int	 mincount));
 static void aff_process_flags __ARGS((afffile_T *affile, affentry_T *entry));
 static int spell_info_item __ARGS((char_u *s));
 static unsigned affitem2flag __ARGS((int flagtype, char_u *item, char_u	*fname, int lnum));
@@ -4950,7 +5119,7 @@
 static void put_sugtime __ARGS((spellinfo_T *spin, FILE *fd));
 static int write_vim_spell __ARGS((spellinfo_T *spin, char_u *fname));
 static void clear_node __ARGS((wordnode_T *node));
-static int put_node __ARGS((FILE *fd, wordnode_T *node, int index, int regionmask, int prefixtree));
+static int put_node __ARGS((FILE *fd, wordnode_T *node, int idx, int regionmask, int prefixtree));
 static void spell_make_sugfile __ARGS((spellinfo_T *spin, char_u *wfname));
 static int sug_filltree __ARGS((spellinfo_T *spin, slang_T *slang));
 static int sug_maketable __ARGS((spellinfo_T *spin));
@@ -5223,8 +5392,7 @@
 	/* Handle non-empty lines. */
 	if (itemcnt > 0)
 	{
-	    if (STRCMP(items[0], "SET") == 0 && itemcnt == 2
-						       && aff->af_enc == NULL)
+	    if (is_aff_rule(items, itemcnt, "SET", 2) && aff->af_enc == NULL)
 	    {
 #ifdef FEAT_MBYTE
 		/* Setup for conversion from "ENC" to 'encoding'. */
@@ -5239,7 +5407,7 @@
 		    smsg((char_u *)_("Conversion in %s not supported"), fname);
 #endif
 	    }
-	    else if (STRCMP(items[0], "FLAG") == 0 && itemcnt == 2
+	    else if (is_aff_rule(items, itemcnt, "FLAG", 2)
 					      && aff->af_flagtype == AFT_CHAR)
 	    {
 		if (STRCMP(items[1], "long") == 0)
@@ -5284,69 +5452,71 @@
 			spin->si_info = p;
 		    }
 	    }
-	    else if (STRCMP(items[0], "MIDWORD") == 0 && itemcnt == 2
+	    else if (is_aff_rule(items, itemcnt, "MIDWORD", 2)
 							   && midword == NULL)
 	    {
 		midword = getroom_save(spin, items[1]);
 	    }
-	    else if (STRCMP(items[0], "TRY") == 0 && itemcnt == 2)
+	    else if (is_aff_rule(items, itemcnt, "TRY", 2))
 	    {
 		/* ignored, we look in the tree for what chars may appear */
 	    }
 	    /* TODO: remove "RAR" later */
-	    else if ((STRCMP(items[0], "RAR") == 0
-			|| STRCMP(items[0], "RARE") == 0) && itemcnt == 2
-						       && aff->af_rare == 0)
+	    else if ((is_aff_rule(items, itemcnt, "RAR", 2)
+			|| is_aff_rule(items, itemcnt, "RARE", 2))
+							 && aff->af_rare == 0)
 	    {
 		aff->af_rare = affitem2flag(aff->af_flagtype, items[1],
 								 fname, lnum);
 	    }
 	    /* TODO: remove "KEP" later */
-	    else if ((STRCMP(items[0], "KEP") == 0
-		    || STRCMP(items[0], "KEEPCASE") == 0) && itemcnt == 2
+	    else if ((is_aff_rule(items, itemcnt, "KEP", 2)
+			|| is_aff_rule(items, itemcnt, "KEEPCASE", 2))
 						     && aff->af_keepcase == 0)
 	    {
 		aff->af_keepcase = affitem2flag(aff->af_flagtype, items[1],
 								 fname, lnum);
 	    }
-	    else if (STRCMP(items[0], "BAD") == 0 && itemcnt == 2
-						       && aff->af_bad == 0)
+	    else if ((is_aff_rule(items, itemcnt, "BAD", 2)
+			|| is_aff_rule(items, itemcnt, "FORBIDDENWORD", 2))
+							  && aff->af_bad == 0)
 	    {
 		aff->af_bad = affitem2flag(aff->af_flagtype, items[1],
 								 fname, lnum);
 	    }
-	    else if (STRCMP(items[0], "NEEDAFFIX") == 0 && itemcnt == 2
+	    else if (is_aff_rule(items, itemcnt, "NEEDAFFIX", 2)
 						    && aff->af_needaffix == 0)
 	    {
 		aff->af_needaffix = affitem2flag(aff->af_flagtype, items[1],
 								 fname, lnum);
 	    }
-	    else if (STRCMP(items[0], "CIRCUMFIX") == 0 && itemcnt == 2
+	    else if (is_aff_rule(items, itemcnt, "CIRCUMFIX", 2)
 						    && aff->af_circumfix == 0)
 	    {
 		aff->af_circumfix = affitem2flag(aff->af_flagtype, items[1],
 								 fname, lnum);
 	    }
-	    else if (STRCMP(items[0], "NOSUGGEST") == 0 && itemcnt == 2
+	    else if (is_aff_rule(items, itemcnt, "NOSUGGEST", 2)
 						    && aff->af_nosuggest == 0)
 	    {
 		aff->af_nosuggest = affitem2flag(aff->af_flagtype, items[1],
 								 fname, lnum);
 	    }
-	    else if (STRCMP(items[0], "NEEDCOMPOUND") == 0 && itemcnt == 2
+	    else if ((is_aff_rule(items, itemcnt, "NEEDCOMPOUND", 2)
+			|| is_aff_rule(items, itemcnt, "ONLYINCOMPOUND", 2))
 						     && aff->af_needcomp == 0)
 	    {
 		aff->af_needcomp = affitem2flag(aff->af_flagtype, items[1],
 								 fname, lnum);
 	    }
-	    else if (STRCMP(items[0], "COMPOUNDROOT") == 0 && itemcnt == 2
+	    else if (is_aff_rule(items, itemcnt, "COMPOUNDROOT", 2)
 						     && aff->af_comproot == 0)
 	    {
 		aff->af_comproot = affitem2flag(aff->af_flagtype, items[1],
 								 fname, lnum);
 	    }
-	    else if (STRCMP(items[0], "COMPOUNDFORBIDFLAG") == 0
-				   && itemcnt == 2 && aff->af_compforbid == 0)
+	    else if (is_aff_rule(items, itemcnt, "COMPOUNDFORBIDFLAG", 2)
+						   && aff->af_compforbid == 0)
 	    {
 		aff->af_compforbid = affitem2flag(aff->af_flagtype, items[1],
 								 fname, lnum);
@@ -5354,8 +5524,8 @@
 		    smsg((char_u *)_("Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line %d"),
 			    fname, lnum);
 	    }
-	    else if (STRCMP(items[0], "COMPOUNDPERMITFLAG") == 0
-				   && itemcnt == 2 && aff->af_comppermit == 0)
+	    else if (is_aff_rule(items, itemcnt, "COMPOUNDPERMITFLAG", 2)
+						   && aff->af_comppermit == 0)
 	    {
 		aff->af_comppermit = affitem2flag(aff->af_flagtype, items[1],
 								 fname, lnum);
@@ -5363,7 +5533,7 @@
 		    smsg((char_u *)_("Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line %d"),
 			    fname, lnum);
 	    }
-	    else if (STRCMP(items[0], "COMPOUNDFLAG") == 0 && itemcnt == 2
+	    else if (is_aff_rule(items, itemcnt, "COMPOUNDFLAG", 2)
 							 && compflags == NULL)
 	    {
 		/* Turn flag "c" into COMPOUNDRULE compatible string "c+",
@@ -5376,7 +5546,15 @@
 		    compflags = p;
 		}
 	    }
-	    else if (STRCMP(items[0], "COMPOUNDRULE") == 0 && itemcnt == 2)
+	    else if (is_aff_rule(items, itemcnt, "COMPOUNDRULES", 2))
+	    {
+		/* We don't use the count, but do check that it's a number and
+		 * not COMPOUNDRULE mistyped. */
+		if (atoi((char *)items[1]) == 0)
+		    smsg((char_u *)_("Wrong COMPOUNDRULES value in %s line %d: %s"),
+						       fname, lnum, items[1]);
+	    }
+	    else if (is_aff_rule(items, itemcnt, "COMPOUNDRULE", 2))
 	    {
 		/* Concatenate this string to previously defined ones, using a
 		 * slash to separate them. */
@@ -5395,7 +5573,7 @@
 		    compflags = p;
 		}
 	    }
-	    else if (STRCMP(items[0], "COMPOUNDWORDMAX") == 0 && itemcnt == 2
+	    else if (is_aff_rule(items, itemcnt, "COMPOUNDWORDMAX", 2)
 							      && compmax == 0)
 	    {
 		compmax = atoi((char *)items[1]);
@@ -5403,7 +5581,7 @@
 		    smsg((char_u *)_("Wrong COMPOUNDWORDMAX value in %s line %d: %s"),
 						       fname, lnum, items[1]);
 	    }
-	    else if (STRCMP(items[0], "COMPOUNDMIN") == 0 && itemcnt == 2
+	    else if (is_aff_rule(items, itemcnt, "COMPOUNDMIN", 2)
 							   && compminlen == 0)
 	    {
 		compminlen = atoi((char *)items[1]);
@@ -5411,7 +5589,7 @@
 		    smsg((char_u *)_("Wrong COMPOUNDMIN value in %s line %d: %s"),
 						       fname, lnum, items[1]);
 	    }
-	    else if (STRCMP(items[0], "COMPOUNDSYLMAX") == 0 && itemcnt == 2
+	    else if (is_aff_rule(items, itemcnt, "COMPOUNDSYLMAX", 2)
 							   && compsylmax == 0)
 	    {
 		compsylmax = atoi((char *)items[1]);
@@ -5419,32 +5597,29 @@
 		    smsg((char_u *)_("Wrong COMPOUNDSYLMAX value in %s line %d: %s"),
 						       fname, lnum, items[1]);
 	    }
-	    else if (STRCMP(items[0], "CHECKCOMPOUNDDUP") == 0 && itemcnt == 1)
+	    else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDDUP", 1))
 	    {
 		compoptions |= COMP_CHECKDUP;
 	    }
-	    else if (STRCMP(items[0], "CHECKCOMPOUNDREP") == 0 && itemcnt == 1)
+	    else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDREP", 1))
 	    {
 		compoptions |= COMP_CHECKREP;
 	    }
-	    else if (STRCMP(items[0], "CHECKCOMPOUNDCASE") == 0 && itemcnt == 1)
+	    else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDCASE", 1))
 	    {
 		compoptions |= COMP_CHECKCASE;
 	    }
-	    else if (STRCMP(items[0], "CHECKCOMPOUNDTRIPLE") == 0
-							      && itemcnt == 1)
+	    else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDTRIPLE", 1))
 	    {
 		compoptions |= COMP_CHECKTRIPLE;
 	    }
-	    else if (STRCMP(items[0], "CHECKCOMPOUNDPATTERN") == 0
-							      && itemcnt == 2)
+	    else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 2))
 	    {
 		if (atoi((char *)items[1]) == 0)
 		    smsg((char_u *)_("Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"),
 						       fname, lnum, items[1]);
 	    }
-	    else if (STRCMP(items[0], "CHECKCOMPOUNDPATTERN") == 0
-							      && itemcnt == 3)
+	    else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 3))
 	    {
 		garray_T    *gap = &spin->si_comppat;
 		int	    i;
@@ -5463,24 +5638,24 @@
 					       = getroom_save(spin, items[2]);
 		}
 	    }
-	    else if (STRCMP(items[0], "SYLLABLE") == 0 && itemcnt == 2
+	    else if (is_aff_rule(items, itemcnt, "SYLLABLE", 2)
 							  && syllable == NULL)
 	    {
 		syllable = getroom_save(spin, items[1]);
 	    }
-	    else if (STRCMP(items[0], "NOBREAK") == 0 && itemcnt == 1)
+	    else if (is_aff_rule(items, itemcnt, "NOBREAK", 1))
 	    {
 		spin->si_nobreak = TRUE;
 	    }
-	    else if (STRCMP(items[0], "NOSPLITSUGS") == 0 && itemcnt == 1)
+	    else if (is_aff_rule(items, itemcnt, "NOSPLITSUGS", 1))
 	    {
 		spin->si_nosplitsugs = TRUE;
 	    }
-	    else if (STRCMP(items[0], "NOSUGFILE") == 0 && itemcnt == 1)
+	    else if (is_aff_rule(items, itemcnt, "NOSUGFILE", 1))
 	    {
 		spin->si_nosugfile = TRUE;
 	    }
-	    else if (STRCMP(items[0], "PFXPOSTPONE") == 0 && itemcnt == 1)
+	    else if (is_aff_rule(items, itemcnt, "PFXPOSTPONE", 1))
 	    {
 		aff->af_pfxpostpone = TRUE;
 	    }
@@ -5771,24 +5946,20 @@
 		    }
 		}
 	    }
-	    else if (STRCMP(items[0], "FOL") == 0 && itemcnt == 2
-							       && fol == NULL)
+	    else if (is_aff_rule(items, itemcnt, "FOL", 2) && fol == NULL)
 	    {
 		fol = vim_strsave(items[1]);
 	    }
-	    else if (STRCMP(items[0], "LOW") == 0 && itemcnt == 2
-							       && low == NULL)
+	    else if (is_aff_rule(items, itemcnt, "LOW", 2) && low == NULL)
 	    {
 		low = vim_strsave(items[1]);
 	    }
-	    else if (STRCMP(items[0], "UPP") == 0 && itemcnt == 2
-							       && upp == NULL)
+	    else if (is_aff_rule(items, itemcnt, "UPP", 2) && upp == NULL)
 	    {
 		upp = vim_strsave(items[1]);
 	    }
-	    else if ((STRCMP(items[0], "REP") == 0
-			|| STRCMP(items[0], "REPSAL") == 0)
-		    && itemcnt == 2)
+	    else if (is_aff_rule(items, itemcnt, "REP", 2)
+		     || is_aff_rule(items, itemcnt, "REPSAL", 2))
 	    {
 		/* Ignore REP/REPSAL count */;
 		if (!isdigit(*items[1]))
@@ -5819,7 +5990,7 @@
 					 : &spin->si_rep, items[1], items[2]);
 		}
 	    }
-	    else if (STRCMP(items[0], "MAP") == 0 && itemcnt == 2)
+	    else if (is_aff_rule(items, itemcnt, "MAP", 2))
 	    {
 		/* MAP item or count */
 		if (!found_map)
@@ -5856,9 +6027,8 @@
 		    ga_append(&spin->si_map, '/');
 		}
 	    }
-	    /* Accept "SAL from to" and "SAL from to # comment". */
-	    else if (STRCMP(items[0], "SAL") == 0
-		    && (itemcnt == 3 || (itemcnt > 3 && items[3][0] == '#')))
+	    /* Accept "SAL from to" and "SAL from to  #comment". */
+	    else if (is_aff_rule(items, itemcnt, "SAL", 3))
 	    {
 		if (do_sal)
 		{
@@ -5877,12 +6047,12 @@
 								: items[2]);
 		}
 	    }
-	    else if (STRCMP(items[0], "SOFOFROM") == 0 && itemcnt == 2
+	    else if (is_aff_rule(items, itemcnt, "SOFOFROM", 2)
 							  && sofofrom == NULL)
 	    {
 		sofofrom = getroom_save(spin, items[1]);
 	    }
-	    else if (STRCMP(items[0], "SOFOTO") == 0 && itemcnt == 2
+	    else if (is_aff_rule(items, itemcnt, "SOFOTO", 2)
 							    && sofoto == NULL)
 	    {
 		sofoto = getroom_save(spin, items[1]);
@@ -5980,7 +6150,7 @@
 	else if (spin->si_newprefID == 0 || spin->si_newprefID == 127)
 	    MSG(_("Too many compound flags"));
 	else
-	    MSG(_("Too many posponed prefixes and/or compound flags"));
+	    MSG(_("Too many postponed prefixes and/or compound flags"));
     }
 
     if (syllable != NULL)
@@ -6017,6 +6187,22 @@
 }
 
 /*
+ * Return TRUE when items[0] equals "rulename", there are "mincount" items or
+ * a comment is following after item "mincount".
+ */
+    static int
+is_aff_rule(items, itemcnt, rulename, mincount)
+    char_u	**items;
+    int		itemcnt;
+    char	*rulename;
+    int		mincount;
+{
+    return (STRCMP(items[0], rulename) == 0
+	    && (itemcnt == mincount
+		|| (itemcnt > mincount && items[mincount][0] == '#')));
+}
+
+/*
  * For affix "entry" move COMPOUNDFORBIDFLAG and COMPOUNDPERMITFLAG from
  * ae_flags to ae_comppermit and ae_compforbid.
  */
@@ -7926,6 +8112,8 @@
     char_u	*p;
     int		rr;
     int		retval = OK;
+    size_t	fwv = 1;  /* collect return value of fwrite() to avoid
+			     warnings from picky compiler */
 
     fd = mch_fopen((char *)fname, "w");
     if (fd == NULL)
@@ -7936,11 +8124,11 @@
 
     /* <HEADER>: <fileID> <versionnr> */
 							    /* <fileID> */
-    if (fwrite(VIMSPELLMAGIC, VIMSPELLMAGICL, (size_t)1, fd) != 1)
-    {
-	EMSG(_(e_write));
-	retval = FAIL;
-    }
+    fwv &= fwrite(VIMSPELLMAGIC, VIMSPELLMAGICL, (size_t)1, fd);
+    if (fwv != (size_t)1)
+	/* Catch first write error, don't try writing more. */
+	goto theend;
+
     putc(VIMSPELLVERSION, fd);				    /* <versionnr> */
 
     /*
@@ -7955,7 +8143,7 @@
 
 	i = (int)STRLEN(spin->si_info);
 	put_bytes(fd, (long_u)i, 4);			/* <sectionlen> */
-	fwrite(spin->si_info, (size_t)i, (size_t)1, fd); /* <infotext> */
+	fwv &= fwrite(spin->si_info, (size_t)i, (size_t)1, fd); /* <infotext> */
     }
 
     /* SN_REGION: <regionname> ...
@@ -7966,7 +8154,7 @@
 	putc(SNF_REQUIRED, fd);				/* <sectionflags> */
 	l = spin->si_region_count * 2;
 	put_bytes(fd, (long_u)l, 4);			/* <sectionlen> */
-	fwrite(spin->si_region_name, (size_t)l, (size_t)1, fd);
+	fwv &= fwrite(spin->si_region_name, (size_t)l, (size_t)1, fd);
 							/* <regionname> ... */
 	regionmask = (1 << spin->si_region_count) - 1;
     }
@@ -8016,7 +8204,7 @@
 	}
 
 	put_bytes(fd, (long_u)l, 2);			/* <folcharslen> */
-	fwrite(folchars, (size_t)l, (size_t)1, fd);	/* <folchars> */
+	fwv &= fwrite(folchars, (size_t)l, (size_t)1, fd); /* <folchars> */
     }
 
     /* SN_MIDWORD: <midword> */
@@ -8027,7 +8215,8 @@
 
 	i = (int)STRLEN(spin->si_midword);
 	put_bytes(fd, (long_u)i, 4);			/* <sectionlen> */
-	fwrite(spin->si_midword, (size_t)i, (size_t)1, fd); /* <midword> */
+	fwv &= fwrite(spin->si_midword, (size_t)i, (size_t)1, fd);
+							/* <midword> */
     }
 
     /* SN_PREFCOND: <prefcondcnt> <prefcond> ... */
@@ -8113,7 +8302,8 @@
 		p = rr == 1 ? ftp->ft_from : ftp->ft_to;
 		l = (int)STRLEN(p);
 		putc(l, fd);
-		fwrite(p, l, (size_t)1, fd);
+		if (l > 0)
+		    fwv &= fwrite(p, l, (size_t)1, fd);
 	    }
 	}
 
@@ -8131,11 +8321,11 @@
 							/* <sectionlen> */
 
 	put_bytes(fd, (long_u)l, 2);			/* <sofofromlen> */
-	fwrite(spin->si_sofofr, l, (size_t)1, fd);	/* <sofofrom> */
+	fwv &= fwrite(spin->si_sofofr, l, (size_t)1, fd); /* <sofofrom> */
 
 	l = (int)STRLEN(spin->si_sofoto);
 	put_bytes(fd, (long_u)l, 2);			/* <sofotolen> */
-	fwrite(spin->si_sofoto, l, (size_t)1, fd);	/* <sofoto> */
+	fwv &= fwrite(spin->si_sofoto, l, (size_t)1, fd); /* <sofoto> */
     }
 
     /* SN_WORDS: <word> ...
@@ -8160,7 +8350,7 @@
 		    l = (int)STRLEN(hi->hi_key) + 1;
 		    len += l;
 		    if (round == 2)			/* <word> */
-			fwrite(hi->hi_key, (size_t)l, (size_t)1, fd);
+			fwv &= fwrite(hi->hi_key, (size_t)l, (size_t)1, fd);
 		    --todo;
 		}
 	    if (round == 1)
@@ -8176,7 +8366,7 @@
 	putc(0, fd);					/* <sectionflags> */
 	l = spin->si_map.ga_len;
 	put_bytes(fd, (long_u)l, 4);			/* <sectionlen> */
-	fwrite(spin->si_map.ga_data, (size_t)l, (size_t)1, fd);
+	fwv &= fwrite(spin->si_map.ga_data, (size_t)l, (size_t)1, fd);
 							/* <mapstr> */
     }
 
@@ -8232,10 +8422,11 @@
 	{
 	    p = ((char_u **)(spin->si_comppat.ga_data))[i];
 	    putc((int)STRLEN(p), fd);			/* <comppatlen> */
-	    fwrite(p, (size_t)STRLEN(p), (size_t)1, fd);/* <comppattext> */
+	    fwv &= fwrite(p, (size_t)STRLEN(p), (size_t)1, fd);
+							/* <comppattext> */
 	}
 							/* <compflags> */
-	fwrite(spin->si_compflags, (size_t)STRLEN(spin->si_compflags),
+	fwv &= fwrite(spin->si_compflags, (size_t)STRLEN(spin->si_compflags),
 							       (size_t)1, fd);
     }
 
@@ -8259,7 +8450,8 @@
 
 	l = (int)STRLEN(spin->si_syllable);
 	put_bytes(fd, (long_u)l, 4);			/* <sectionlen> */
-	fwrite(spin->si_syllable, (size_t)l, (size_t)1, fd); /* <syllable> */
+	fwv &= fwrite(spin->si_syllable, (size_t)l, (size_t)1, fd);
+							/* <syllable> */
     }
 
     /* end of <SECTIONS> */
@@ -8295,13 +8487,18 @@
 	(void)put_node(fd, tree, 0, regionmask, round == 3);
     }
 
-    /* Write another byte to check for errors. */
+    /* Write another byte to check for errors (file system full). */
     if (putc(0, fd) == EOF)
 	retval = FAIL;
-
+theend:
     if (fclose(fd) == EOF)
 	retval = FAIL;
 
+    if (fwv != (size_t)1)
+	retval = FAIL;
+    if (retval == FAIL)
+	EMSG(_(e_write));
+
     return retval;
 }
 
@@ -9890,6 +10087,7 @@
     char_u	*p;
     int		len;
     int		totlen;
+    size_t	x = 1;  /* collect return value of fwrite() */
 
     if (fd != NULL)
 	put_bytes(fd, (long_u)gap->ga_len, 2);	    /* <prefcondcnt> */
@@ -9906,7 +10104,7 @@
 	    if (fd != NULL)
 	    {
 		fputc(len, fd);
-		fwrite(p, (size_t)len, (size_t)1, fd);
+		x &= fwrite(p, (size_t)len, (size_t)1, fd);
 	    }
 	    totlen += len;
 	}
@@ -11480,15 +11678,24 @@
 		    vim_strncpy(preword + sp->ts_prewordlen,
 			    tword + sp->ts_splitoff,
 			    sp->ts_twordlen - sp->ts_splitoff);
-		    p = preword;
-		    while (*skiptowhite(p) != NUL)
-			p = skipwhite(skiptowhite(p));
-		    if (fword_ends && !can_compound(slang, p,
-						compflags + sp->ts_compsplit))
-			/* Compound is not allowed.  But it may still be
-			 * possible if we add another (short) word. */
+
+		    /* Verify CHECKCOMPOUNDPATTERN  rules. */
+		    if (match_checkcompoundpattern(preword,  sp->ts_prewordlen,
+							  &slang->sl_comppat))
 			compound_ok = FALSE;
 
+		    if (compound_ok)
+		    {
+			p = preword;
+			while (*skiptowhite(p) != NUL)
+			    p = skipwhite(skiptowhite(p));
+			if (fword_ends && !can_compound(slang, p,
+						compflags + sp->ts_compsplit))
+			    /* Compound is not allowed.  But it may still be
+			     * possible if we add another (short) word. */
+			    compound_ok = FALSE;
+		    }
+
 		    /* Get pointer to last char of previous word. */
 		    p = preword + sp->ts_prewordlen;
 		    mb_ptr_back(preword, p);
@@ -11685,10 +11892,9 @@
 			&& (slang->sl_compsylmax < MAXWLEN
 			    || sp->ts_complen + 1 - sp->ts_compsplit
 							  < slang->sl_compmax)
-			&& (byte_in_str(sp->ts_complen == sp->ts_compsplit
-					    ? slang->sl_compstartflags
-					    : slang->sl_compallflags,
-						    ((unsigned)flags >> 24))))
+			&& (can_be_compound(sp, slang,
+					 compflags, ((unsigned)flags >> 24))))
+
 		{
 		    try_compound = TRUE;
 		    compflags[sp->ts_complen] = ((unsigned)flags >> 24);
@@ -14808,7 +15014,7 @@
 
 	case 0:
 	    /*
-	     * Lenghts are equal, thus changes must result in same length: An
+	     * Lengths are equal, thus changes must result in same length: An
 	     * insert is only possible in combination with a delete.
 	     * 1: check if for identical strings
 	     */
diff -Naur vim72.orig/src/structs.h vim72/src/structs.h
--- vim72.orig/src/structs.h	2008-07-30 13:02:50.000000000 -0700
+++ vim72/src/structs.h	2009-03-12 11:54:46.913903059 -0700
@@ -459,7 +459,7 @@
 typedef struct
 {
     int		hide;			/* TRUE when ":hide" was used */
-# ifdef FEAT_BROWSE
+# ifdef FEAT_BROWSE_CMD
     int		browse;			/* TRUE to invoke file dialog */
 # endif
 # ifdef FEAT_WINDOWS
@@ -1784,10 +1784,15 @@
 #endif
 
     /*
-     * The next three specify the offsets for displaying the buffer:
+     * "w_topline", "w_leftcol" and "w_skipcol" specify the offsets for
+     * displaying the buffer.
      */
     linenr_T	w_topline;	    /* buffer line number of the line at the
 				       top of the window */
+#ifdef FEAT_AUTOCMD
+    char	w_topline_was_set;  /* flag set to TRUE when topline is set,
+				       e.g. by winrestview() */
+#endif
 #ifdef FEAT_DIFF
     int		w_topfill;	    /* number of filler lines above w_topline */
     int		w_old_topfill;	    /* w_topfill at last redraw */
diff -Naur vim72.orig/src/tag.c vim72/src/tag.c
--- vim72.orig/src/tag.c	2008-07-16 14:31:30.000000000 -0700
+++ vim72/src/tag.c	2009-03-12 11:55:13.591613075 -0700
@@ -515,7 +515,7 @@
 	     * If a count is supplied to the ":tag <name>" command, then
 	     * jump to count'th matching tag.
 	     */
-	    if (type == DT_TAG && count > 0)
+	    if (type == DT_TAG && *tag != NUL && count > 0)
 		cur_match = count - 1;
 
 	    if (type == DT_SELECT || type == DT_JUMP
@@ -618,7 +618,7 @@
 		taglen_advance(taglen);
 		MSG_PUTS_ATTR(_("file\n"), hl_attr(HLF_T));
 
-		for (i = 0; i < num_matches; ++i)
+		for (i = 0; i < num_matches && !got_int; ++i)
 		{
 		    parse_match(matches[i], &tagp);
 		    if (!new_tag && (
@@ -655,6 +655,8 @@
 		    }
 		    if (msg_col > 0)
 			msg_putchar('\n');
+		    if (got_int)
+			break;
 		    msg_advance(15);
 
 		    /* print any extra fields */
@@ -689,6 +691,8 @@
 				if (msg_col + ptr2cells(p) >= Columns)
 				{
 				    msg_putchar('\n');
+				    if (got_int)
+					break;
 				    msg_advance(15);
 				}
 				p = msg_outtrans_one(p, attr);
@@ -704,6 +708,8 @@
 			if (msg_col > 15)
 			{
 			    msg_putchar('\n');
+			    if (got_int)
+				break;
 			    msg_advance(15);
 			}
 		    }
@@ -734,6 +740,8 @@
 		    {
 			if (msg_col + (*p == TAB ? 1 : ptr2cells(p)) > Columns)
 			    msg_putchar('\n');
+			if (got_int)
+			    break;
 			msg_advance(15);
 
 			/* skip backslash used for escaping command char */
@@ -760,12 +768,9 @@
 		    if (msg_col)
 			msg_putchar('\n');
 		    ui_breakcheck();
-		    if (got_int)
-		    {
-			got_int = FALSE;	/* only stop the listing */
-			break;
-		    }
 		}
+		if (got_int)
+		    got_int = FALSE;	/* only stop the listing */
 		ask_for_selection = TRUE;
 	    }
 #if defined(FEAT_QUICKFIX) && defined(FEAT_EVAL)
@@ -2542,6 +2547,15 @@
 {
     ga_clear_strings(&tag_fnames);
     do_tag(NULL, DT_FREE, 0, 0, 0);
+    tag_freematch();
+
+# if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
+    if (ptag_entry.tagname)
+    {
+        vim_free(ptag_entry.tagname);
+        ptag_entry.tagname = NULL;
+    }
+# endif
 }
 #endif
 
@@ -2725,7 +2739,24 @@
 	 */
 	p_7f = vim_strchr(lbuf, 0x7f);
 	if (p_7f == NULL)
+	{
+etag_fail:
+	    if (vim_strchr(lbuf, '\n') == NULL)
+	    {
+		/* Truncated line.  Ignore it. */
+		if (p_verbose >= 5)
+		{
+		    verbose_enter();
+		    MSG(_("Ignoring long line in tags file"));
+		    verbose_leave();
+		}
+		tagp->command = lbuf;
+		tagp->tagname = lbuf;
+		tagp->tagname_end = lbuf;
+		return OK;
+	    }
 	    return FAIL;
+	}
 
 	/* Find ^A.  If not found the line number is after the 0x7f */
 	p = vim_strchr(p_7f, Ctrl_A);
@@ -2735,7 +2766,7 @@
 	    ++p;
 
 	if (!VIM_ISDIGIT(*p))	    /* check for start of line number */
-	    return FAIL;
+	    goto etag_fail;
 	tagp->command = p;
 
 
@@ -2749,7 +2780,7 @@
 	    /* find end of tagname */
 	    for (p = p_7f - 1; !vim_iswordc(*p); --p)
 		if (p == lbuf)
-		    return FAIL;
+		    goto etag_fail;
 	    tagp->tagname_end = p + 1;
 	    while (p >= lbuf && vim_iswordc(*p))
 		--p;
diff -Naur vim72.orig/src/term.c vim72/src/term.c
--- vim72.orig/src/term.c	2008-07-27 04:48:06.000000000 -0700
+++ vim72/src/term.c	2009-03-12 11:54:59.914737254 -0700
@@ -4920,7 +4920,15 @@
 	key_name[0] = KEY2TERMCAP0(key);
 	key_name[1] = KEY2TERMCAP1(key);
 	if (key_name[0] == KS_KEY)
-	    string[new_slen++] = key_name[1];	/* from ":set <M-b>=xx" */
+	{
+	    /* from ":set <M-b>=xx" */
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+		new_slen += (*mb_char2bytes)(key_name[1], string + new_slen);
+	    else
+#endif
+		string[new_slen++] = key_name[1];
+	}
 	else
 	{
 	    string[new_slen++] = K_SPECIAL;
diff -Naur vim72.orig/src/testdir/Makefile vim72/src/testdir/Makefile
--- vim72.orig/src/testdir/Makefile	2008-06-19 13:29:46.000000000 -0700
+++ vim72/src/testdir/Makefile	2009-03-12 11:55:27.544506216 -0700
@@ -20,21 +20,23 @@
 		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 test63.out \
-		test64.out test65.out
+		test64.out test65.out test66.out
 
 SCRIPTS_GUI = test16.out
 
 .SUFFIXES: .in .out
 
-nongui:	nolog $(SCRIPTS)
-	@echo
-	@cat test.log
-	@echo ALL DONE
+nongui:	nolog $(SCRIPTS) report
+
+gui:	nolog $(SCRIPTS) $(SCRIPTS_GUI) report
 
-gui:	nolog $(SCRIPTS) $(SCRIPTS_GUI)
+report:
 	@echo
-	@cat test.log
-	@echo ALL DONE
+	@echo 'Test results:'
+	@/bin/sh -c "if test -f test.log; \
+		then cat test.log; echo TEST FAILURE; exit 1; \
+		else echo ALL DONE; \
+		fi"
 
 $(SCRIPTS) $(SCRIPTS_GUI): $(VIMPROG)
 
@@ -71,4 +73,4 @@
 test60.out: test60.vim
 
 nolog:
-	-echo Test results: >test.log
+	-rm -f test.log
diff -Naur vim72.orig/src/testdir/Make_ming.mak vim72/src/testdir/Make_ming.mak
--- vim72.orig/src/testdir/Make_ming.mak	1969-12-31 16:00:00.000000000 -0800
+++ vim72/src/testdir/Make_ming.mak	2009-03-12 11:54:40.397486521 -0700
@@ -0,0 +1,91 @@
+# Makefile to run tests for Vim, on Dos-like machines
+# with sh.exe or zsh.exe in the path or not.
+#
+# Author: Bill McCarthy
+#
+# Note that test54 has been removed until it is fixed.
+#
+# Requires a set of Unix tools: echo, diff, etc.
+
+ifneq (sh.exe, $(SHELL))
+DEL = rm -f
+MV = mv
+CP = cp
+DIRSLASH = /
+else
+DEL = del
+MV = rename
+CP = copy
+DIRSLASH = \\
+endif
+
+VIMPROG = ..$(DIRSLASH)vim
+
+# Omitted:
+# test2		"\\tmp" doesn't work.
+# test10	'errorformat' is different
+# test12	can't unlink a swap file
+# test25	uses symbolic link
+# test27	can't edit file with "*" in file name
+# test31	16 bit version runs out of memory...
+
+SCRIPTS16 =	test1.out test19.out test20.out test22.out \
+		test23.out test24.out test28.out test29.out \
+		test35.out test36.out test43.out \
+		test44.out test45.out test46.out test47.out \
+		test48.out test51.out test53.out            \
+		test55.out test56.out test57.out test58.out test59.out \
+		test60.out test61.out test62.out test63.out test64.out
+
+# Had to remove test54 which doesn't work yet.
+#		                                 test54.out
+
+SCRIPTS =	test3.out test4.out test5.out test6.out test7.out \
+		test8.out test9.out test11.out test13.out test14.out \
+		test15.out test17.out test18.out test21.out test26.out \
+		test30.out test31.out test32.out test33.out test34.out \
+		test37.out test38.out test39.out test40.out test41.out \
+		test42.out test52.out test65.out
+
+SCRIPTS32 =	test50.out
+
+SCRIPTS_GUI = test16.out
+
+.SUFFIXES: .in .out
+
+vimall:	fixff $(SCRIPTS16) $(SCRIPTS) $(SCRIPTS_GUI) $(SCRIPTS32)
+	echo ALL DONE
+
+nongui:	fixff $(SCRIPTS16) $(SCRIPTS)
+	echo ALL DONE
+
+small:
+	echo ALL DONE
+
+gui:	fixff $(SCRIPTS16) $(SCRIPTS) $(SCRIPTS_GUI)
+	echo ALL DONE
+
+win32:	fixff $(SCRIPTS16) $(SCRIPTS) $(SCRIPTS32)
+	echo ALL DONE
+
+fixff:
+	-$(VIMPROG) -u dos.vim --noplugin "+argdo set ff=dos|upd" +q *.in *.ok
+
+clean:
+	-$(DEL) *.out
+	-$(DEL) test.ok
+	-$(DEL) small.vim
+	-$(DEL) tiny.vim
+	-$(DEL) mbyte.vim
+	-$(DEL) X*
+	-$(DEL) viminfo
+
+.in.out:
+	$(CP) $*.ok test.ok
+	$(VIMPROG) -u dos.vim -U NONE --noplugin -s dotest.in $*.in
+	diff test.out $*.ok
+	-$(DEL) $*.out
+	$(MV) test.out $*.out
+	-$(DEL) X*
+	-$(DEL) test.ok
+	-$(DEL) viminfo
diff -Naur vim72.orig/src/testdir/test42.ok vim72/src/testdir/test42.ok
--- vim72.orig/src/testdir/test42.ok	2008-02-20 04:27:37.000000000 -0800
+++ vim72/src/testdir/test42.ok	2009-03-12 11:54:40.601499372 -0700
@@ -20,7 +20,7 @@
 ucs-2
 
 
-  fileencoding=ucs-2le
+  fileencoding=utf-16le
   bomb
 ucs-2le
 
diff -Naur vim72.orig/src/testdir/test66.in vim72/src/testdir/test66.in
--- vim72.orig/src/testdir/test66.in	1969-12-31 16:00:00.000000000 -0800
+++ vim72/src/testdir/test66.in	2009-03-12 11:55:27.544506216 -0700
@@ -0,0 +1,25 @@
+
+Test for visual block shift and tab characters.
+
+STARTTEST
+:so small.vim
+/^abcdefgh
+4jI    j<<11|D
+7|a		
+7|a		   
+7|a	       	4k13|4j<
+:$-4,$w! test.out
+:$-4,$s/\s\+//g
+4kI    j<<
+7|a		
+7|a					
+7|a	       		4k13|4j3<
+:$-4,$w >> test.out
+:qa!
+ENDTEST
+
+abcdefghijklmnopqrstuvwxyz
+abcdefghijklmnopqrstuvwxyz
+abcdefghijklmnopqrstuvwxyz
+abcdefghijklmnopqrstuvwxyz
+abcdefghijklmnopqrstuvwxyz
diff -Naur vim72.orig/src/testdir/test66.ok vim72/src/testdir/test66.ok
--- vim72.orig/src/testdir/test66.ok	1969-12-31 16:00:00.000000000 -0800
+++ vim72/src/testdir/test66.ok	2009-03-12 11:55:27.544506216 -0700
@@ -0,0 +1,10 @@
+    abcdefghijklmnopqrstuvwxyz
+abcdefghij
+    abc	    defghijklmnopqrstuvwxyz
+    abc	    defghijklmnopqrstuvwxyz
+    abc	    defghijklmnopqrstuvwxyz
+    abcdefghijklmnopqrstuvwxyz
+abcdefghij
+    abc	    defghijklmnopqrstuvwxyz
+    abc		defghijklmnopqrstuvwxyz
+    abc	    defghijklmnopqrstuvwxyz
diff -Naur vim72.orig/src/ui.c vim72/src/ui.c
--- vim72.orig/src/ui.c	2008-07-14 11:14:56.000000000 -0700
+++ vim72/src/ui.c	2009-03-12 11:54:50.158111748 -0700
@@ -1820,7 +1820,7 @@
 #ifdef HAVE_DUP
 	    /* Use stderr for stdin, also works for shell commands. */
 	    close(0);
-	    dup(2);
+	    ignored = dup(2);
 #else
 	    read_cmd_fd = 2;	/* read from stderr instead of stdin */
 #endif
@@ -2020,7 +2020,7 @@
 
     if (value == NULL || *length == 0)
     {
-	clip_free_selection(cbd);	/* ???  [what's the query?] */
+	clip_free_selection(cbd);	/* nothing received, clear register */
 	*(int *)success = FALSE;
 	return;
     }
@@ -2076,7 +2076,7 @@
 	text_prop.value = (unsigned char *)value;
 	text_prop.encoding = *type;
 	text_prop.format = *format;
-	text_prop.nitems = STRLEN(value);
+	text_prop.nitems = len;
 	status = XmbTextPropertyToTextList(X_DISPLAY, &text_prop,
 							 &text_list, &n_text);
 	if (status != Success || n_text < 1)
@@ -2110,6 +2110,8 @@
     int		i;
     int		nbytes = 0;
     char_u	*buffer;
+    time_t	start_time;
+    int		timed_out = FALSE;
 
     for (i =
 #ifdef FEAT_MBYTE
@@ -2129,6 +2131,7 @@
 	    case 3:  type = text_atom;		break;
 	    default: type = XA_STRING;
 	}
+	success = MAYBE;
 	XtGetSelectionValue(myShell, cbd->sel_atom, type,
 	    clip_x11_request_selection_cb, (XtPointer)&success, CurrentTime);
 
@@ -2141,27 +2144,48 @@
 	 * characters, then they will appear before the one that requested the
 	 * paste!  Don't worry, we will catch up with any other events later.
 	 */
-	for (;;)
+	start_time = time(NULL);
+	while (success == MAYBE)
 	{
-	    if (XCheckTypedEvent(dpy, SelectionNotify, &event))
-		break;
-	    if (XCheckTypedEvent(dpy, SelectionRequest, &event))
-		/* We may get a SelectionRequest here and if we don't handle
-		 * it we hang.  KDE klipper does this, for example. */
+	    if (XCheckTypedEvent(dpy, SelectionNotify, &event)
+		    || XCheckTypedEvent(dpy, SelectionRequest, &event)
+		    || XCheckTypedEvent(dpy, PropertyNotify, &event))
+	    {
+		/* This is where clip_x11_request_selection_cb() should be
+		 * called.  It may actually happen a bit later, so we loop
+		 * until "success" changes.
+		 * We may get a SelectionRequest here and if we don't handle
+		 * it we hang.  KDE klipper does this, for example.
+		 * We need to handle a PropertyNotify for large selections. */
 		XtDispatchEvent(&event);
+		continue;
+	    }
+
+	    /* Time out after 2 to 3 seconds to avoid that we hang when the
+	     * other process doesn't respond.  Note that the SelectionNotify
+	     * event may still come later when the selection owner comes back
+	     * to life and the text gets inserted unexpectedly.  Don't know
+	     * why that happens or how to avoid that :-(. */
+	    if (time(NULL) > start_time + 2)
+	    {
+		timed_out = TRUE;
+		break;
+	    }
 
 	    /* Do we need this?  Probably not. */
 	    XSync(dpy, False);
 
-	    /* Bernhard Walle solved a slow paste response in an X terminal by
-	     * adding: usleep(10000); here. */
+	    /* Wait for 1 msec to avoid that we eat up all CPU time. */
+	    ui_delay(1L, TRUE);
 	}
 
-	/* this is where clip_x11_request_selection_cb() is actually called */
-	XtDispatchEvent(&event);
-
-	if (success)
+	if (success == TRUE)
 	    return;
+
+	/* don't do a retry with another type after timing out, otherwise we
+	 * hang for 15 seconds. */
+	if (timed_out)
+	    break;
     }
 
     /* Final fallback position - use the X CUT_BUFFER0 store */
diff -Naur vim72.orig/src/version.c vim72/src/version.c
--- vim72.orig/src/version.c	2008-08-09 07:24:52.000000000 -0700
+++ vim72/src/version.c	2009-03-12 11:55:39.893297947 -0700
@@ -677,9 +677,280 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    141,
+/**/
+    140,
+/**/
+    139,
+/**/
+    137,
+/**/
+    136,
+/**/
+    135,
+/**/
+    134,
+/**/
+    133,
+/**/
+    132,
+/**/
+    131,
+/**/
+    130,
+/**/
+    129,
+/**/
+    128,
+/**/
+    127,
+/**/
+    126,
+/**/
+    125,
+/**/
+    124,
+/**/
+    123,
+/**/
+    122,
+/**/
+    121,
+/**/
+    120,
+/**/
+    119,
+/**/
+    118,
+/**/
+    117,
+/**/
+    116,
+/**/
+    115,
+/**/
+    114,
+/**/
+    113,
+/**/
+    112,
+/**/
+    111,
+/**/
+    110,
+/**/
+    109,
+/**/
+    108,
+/**/
+    107,
+/**/
+    106,
+/**/
+    105,
+/**/
+    104,
+/**/
+    103,
+/**/
+    102,
+/**/
+    100,
+/**/
+    99,
+/**/
+    98,
+/**/
+    97,
+/**/
+    96,
+/**/
+    95,
+/**/
+    94,
+/**/
+    92,
+/**/
+    91,
+/**/
+    90,
+/**/
+    87,
+/**/
+    86,
+/**/
+    85,
+/**/
+    84,
+/**/
+    83,
+/**/
+    82,
+/**/
+    81,
+/**/
+    80,
+/**/
+    79,
+/**/
+    78,
+/**/
+    77,
+/**/
+    76,
+/**/
+    75,
+/**/
+    73,
+/**/
+    70,
+/**/
+    69,
+/**/
+    68,
+/**/
+    67,
+/**/
+    66,
+/**/
+    65,
+/**/
+    64,
+/**/
+    63,
+/**/
+    62,
+/**/
+    61,
+/**/
+    60,
+/**/
+    59,
+/**/
+    58,
+/**/
+    57,
+/**/
+    56,
+/**/
+    55,
+/**/
+    54,
+/**/
+    53,
+/**/
+    52,
+/**/
+    51,
+/**/
+    50,
+/**/
+    48,
+/**/
+    47,
+/**/
+    46,
+/**/
+    45,
+/**/
+    44,
+/**/
+    43,
+/**/
+    42,
+/**/
+    40,
+/**/
+    39,
+/**/
+    38,
+/**/
+    37,
+/**/
+    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,
+/**/
+    3,
+/**/
+    2,
+/**/
+    1,
+/**/
     0
 };
 
+/*
+ * Place to put a short description when adding a feature with a patch.
+ * Keep it short, e.g.,: "relative numbers", "persistent undo".
+ * Also add a comment marker to separate the lines.
+ * See the official Vim patches for the diff format: It must use a context of
+ * one line only.  Create it by hand or use "diff -C2" and edit the patch.
+ */
+static char *(extra_patches[]) =
+{   /* Add your patch description below this line */
+/**/
+    NULL
+};
+
     int
 highest_patch()
 {
@@ -786,7 +1057,7 @@
     MSG_PUTS(_("\nRISC OS version"));
 #endif
 #ifdef VMS
-    MSG_PUTS("\nOpenVMS version");
+    MSG_PUTS(_("\nOpenVMS version"));
 # ifdef HAVE_PATHDEF
     if (*compiled_arch != NUL)
     {
@@ -825,6 +1096,19 @@
 	}
     }
 
+    /* Print the list of extra patch descriptions if there is at least one. */
+    if (extra_patches[0] != NULL)
+    {
+	MSG_PUTS(_("\nExtra patches: "));
+	s = "";
+	for (i = 0; extra_patches[i] != NULL; ++i)
+	{
+	    MSG_PUTS(s);
+	    s = ", ";
+	    MSG_PUTS(extra_patches[i]);
+	}
+    }
+
 #ifdef MODIFIED_BY
     MSG_PUTS("\n");
     MSG_PUTS(_("Modified by "));
diff -Naur vim72.orig/src/vim.h vim72/src/vim.h
--- vim72.orig/src/vim.h	2008-08-09 09:03:38.000000000 -0700
+++ vim72/src/vim.h	2009-03-12 11:55:13.547610560 -0700
@@ -341,8 +341,14 @@
 #ifdef BACKSLASH_IN_FILENAME
 # define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`%#'\"|!<")
 #else
-# define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<")
-# define SHELL_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<>();&")
+# ifdef VMS
+    /* VMS allows a lot of characters in the file name */
+#  define PATH_ESC_CHARS ((char_u *)" \t\n*?{`\\%#'\"|!")
+#  define SHELL_ESC_CHARS ((char_u *)" \t\n*?{`\\%#'|!()&")
+# else
+#  define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<")
+#  define SHELL_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<>();&")
+# endif
 #endif
 
 #define NUMBUFLEN 30	    /* length of a buffer to store a number in ASCII */
@@ -370,7 +376,7 @@
    * Define __w64 as an empty token for everything but MSVC 7.x or later.
    */
 # if !defined(_MSC_VER)	|| (_MSC_VER < 1300)
-#  define __w64 
+#  define __w64
 # endif
 typedef unsigned long __w64	long_u;
 typedef		 long __w64     long_i;
@@ -1051,6 +1057,7 @@
 #define WSP_HELP	16	/* creating the help window */
 #define WSP_BELOW	32	/* put new window below/right */
 #define WSP_ABOVE	64	/* put new window above/left */
+#define WSP_NEWLOC	128	/* don't copy location list */
 
 /*
  * arguments for gui_set_shellsize()
@@ -1728,7 +1735,8 @@
 #define VV_MOUSE_COL	51
 #define VV_OP		52
 #define VV_SEARCHFORWARD 53
-#define VV_LEN		54	/* number of v: vars */
+#define VV_OLDFILES	54
+#define VV_LEN		55	/* number of v: vars */
 
 #ifdef FEAT_CLIPBOARD
 
@@ -1979,6 +1987,9 @@
 # endif
 #endif
 
+#ifndef FEAT_NETBEANS_INTG
+# undef NBDEBUG
+#endif
 #ifdef NBDEBUG /* Netbeans debugging. */
 # include "nbdebug.h"
 #else
@@ -2054,4 +2065,10 @@
 #define DOSO_VIMRC	1	/* loading vimrc file */
 #define DOSO_GVIMRC	2	/* loading gvimrc file */
 
+/* flags for read_viminfo() and children */
+#define VIF_WANT_INFO		1	/* load non-mark info */
+#define VIF_WANT_MARKS		2	/* load file marks */
+#define VIF_FORCEIT		4	/* overwrite info already read */
+#define VIF_GET_OLDFILES	8	/* load v:oldfiles */
+
 #endif /* VIM__H */
diff -Naur vim72.orig/src/window.c vim72/src/window.c
--- vim72.orig/src/window.c	2008-08-06 04:00:30.000000000 -0700
+++ vim72/src/window.c	2009-03-12 11:55:13.547610560 -0700
@@ -12,7 +12,7 @@
 static int path_is_url __ARGS((char_u *p));
 #if defined(FEAT_WINDOWS) || defined(PROTO)
 static int win_split_ins __ARGS((int size, int flags, win_T *newwin, int dir));
-static void win_init __ARGS((win_T *newp, win_T *oldp));
+static void win_init __ARGS((win_T *newp, win_T *oldp, int flags));
 static void frame_comp_pos __ARGS((frame_T *topfrp, int *row, int *col));
 static void frame_setheight __ARGS((frame_T *curfrp, int height));
 #ifdef FEAT_VERTSPLIT
@@ -593,9 +593,7 @@
 		++allow_keys;   /* no mapping for xchar, but allow key codes */
 		if (xchar == NUL)
 		    xchar = plain_vgetc();
-#ifdef FEAT_LANGMAP
 		LANGMAP_ADJUST(xchar, TRUE);
-#endif
 		--no_mapping;
 		--allow_keys;
 #ifdef FEAT_CMDL_INFO
@@ -912,7 +910,7 @@
 	    return FAIL;
 
 	/* make the contents of the new window the same as the current one */
-	win_init(wp, curwin);
+	win_init(wp, curwin, flags);
     }
 
     /*
@@ -1161,11 +1159,15 @@
  * Initialize window "newp" from window "oldp".
  * Used when splitting a window and when creating a new tab page.
  * The windows will both edit the same buffer.
+ * WSP_NEWLOC may be specified in flags to prevent the location list from
+ * being copied.
  */
+/*ARGSUSED*/
     static void
-win_init(newp, oldp)
+win_init(newp, oldp, flags)
     win_T	*newp;
     win_T	*oldp;
+    int		 flags;
 {
     int		i;
 
@@ -1190,7 +1192,14 @@
     copy_jumplist(oldp, newp);
 #endif
 #ifdef FEAT_QUICKFIX
-    copy_loclist(oldp, newp);
+    if (flags & WSP_NEWLOC)
+    {
+	/* Don't copy the location list.  */
+	newp->w_llist = NULL;
+	newp->w_llist_ref = NULL;
+    }
+    else
+	copy_loclist(oldp, newp);
 #endif
     if (oldp->w_localdir != NULL)
 	newp->w_localdir = vim_strsave(oldp->w_localdir);
@@ -3220,7 +3229,7 @@
     else
     {
 	/* First window in new tab page, initialize it from "oldwin". */
-	win_init(curwin, oldwin);
+	win_init(curwin, oldwin, 0);
 
 # ifdef FEAT_SCROLLBIND
 	/* We don't want scroll-binding in the first window. */
@@ -4028,14 +4037,14 @@
 	    if (mch_dirname(cwd, MAXPATHL) == OK)
 		globaldir = vim_strsave(cwd);
 	}
-	mch_chdir((char *)curwin->w_localdir);
-	shorten_fnames(TRUE);
+	if (mch_chdir((char *)curwin->w_localdir) == 0)
+	    shorten_fnames(TRUE);
     }
     else if (globaldir != NULL)
     {
 	/* Window doesn't have a local directory and we are not in the global
 	 * directory: Change to the global directory. */
-	mch_chdir((char *)globaldir);
+	ignored = mch_chdir((char *)globaldir);
 	vim_free(globaldir);
 	globaldir = NULL;
 	shorten_fnames(TRUE);
diff -Naur vim72.orig/src/workshop.c vim72/src/workshop.c
--- vim72.orig/src/workshop.c	2008-06-21 11:53:26.000000000 -0700
+++ vim72/src/workshop.c	2009-03-12 11:54:50.062104763 -0700
@@ -1121,8 +1121,12 @@
 				      ? (char *)curbuf->b_sfname : "<None>");
 #endif
 
-    strcpy(ffname, (char *) curbuf->b_ffname);
-    *filename = ffname;		/* copy so nobody can change b_ffname */
+    if (curbuf->b_ffname == NULL)
+	ffname[0] = NUL;
+    else
+	/* copy so nobody can change b_ffname */
+	strcpy(ffname, (char *) curbuf->b_ffname);
+    *filename = ffname;
     *curLine = curwin->w_cursor.lnum;
     *curCol = curwin->w_cursor.col;
 
