diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
index c815f362aa15899ee9bb3e13b75bbfea64a1cb18..e994df88671f2d30b0ec16f4021e868190a3b3cf 100644
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -1,4 +1,4 @@
-*autocmd.txt*   For Vim version 7.0aa.  Last change: 2005 Feb 07
+*autocmd.txt*   For Vim version 7.0aa.  Last change: 2005 Feb 21
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -204,10 +204,12 @@ FilterReadPre			Before reading a file from a filter command.
 				the current buffer, not the name of the
 				temporary file that is the output of the
 				filter command.
+				Not triggered when 'shelltemp' is off.
 							*FilterReadPost*
 FilterReadPost			After reading a file from a filter command.
 				Vim checks the pattern against the name of
 				the current buffer as with FilterReadPre.
+				Not triggered when 'shelltemp' is off.
 							*FileType*
 FileType			When the 'filetype' option has been set.
 				<afile> can be used for the name of the file
@@ -270,11 +272,13 @@ FilterWritePre			Before writing a file for a filter command or
 				the current buffer, not the name of the
 				temporary file that is the output of the
 				filter command.
+				Not triggered when 'shelltemp' is off.
 							*FilterWritePost*
 FilterWritePost			After writing a file for a filter command or
 				making a diff.
 				Vim checks the pattern against the name of
 				the current buffer as with FilterWritePre.
+				Not triggered when 'shelltemp' is off.
 							*FileChangedShell*
 FileChangedShell		When Vim notices that the modification time of
 				a file has changed since editing started.
diff --git a/runtime/doc/change.txt b/runtime/doc/change.txt
index 766bcb0fc0565583fa4c6049ae79c4c4da8050da..379d5e1fa347f3dffac4276a6e0b4ef95c3486e5 100644
--- a/runtime/doc/change.txt
+++ b/runtime/doc/change.txt
@@ -1,4 +1,4 @@
-*change.txt*    For Vim version 7.0aa.  Last change: 2005 Feb 08
+*change.txt*    For Vim version 7.0aa.  Last change: 2005 Feb 21
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -112,19 +112,22 @@ gJ			Join [count] lines, with a minimum of two lines.
 			Vi}
 
 							*:j* *:join*
-:[range]j[oin][!]	Join [range] lines.  Same as "J", except with [!]
+:[range]j[oin][!] [flags]
+			Join [range] lines.  Same as "J", except with [!]
 			the join does not insert or delete any spaces.
 			If a [range] has equal start and end values, this
 			command does nothing.  The default behavior is to
 			join the current line with the line below it.
 			{not in Vi: !}
+			See |ex-flags| for [flags].
 
-:[range]j[oin][!] {count}
+:[range]j[oin][!] {count} [flags]
 			Join {count} lines, starting with [range] (default:
 			current line |cmdline-ranges|).  Same as "J", except
 			with [!] the join does not insert or delete any
 			spaces.
 			{not in Vi: !}
+			See |ex-flags| for [flags].
 
 These commands delete the <EOL> between lines.  This has the effect of joining
 multiple lines into one line.  You can repeat these commands (except ":j") and
@@ -236,10 +239,12 @@ If you prefer "cw" to include the space after a word, use this mapping: >
 	:map cw dwi
 <
 							*:c* *:ch* *:change*
-:{range}c[hange]	Replace lines of text with some different text.
+:{range}c[hange][!]	Replace lines of text with some different text.
 			Type a line containing only "." to stop replacing.
 			Without {range}, this command changes only the current
 			line.
+			Adding [!] toggles 'autoindent' for the time this
+			command is executed.
 
 ==============================================================================
 3. Simple changes					*simple-change*
@@ -424,12 +429,15 @@ SHIFTING LINES LEFT OR RIGHT				*shift-left-right*
 			lines to [indent] (default 0).  {not in Vi}
 
 							*:>*
-:[range]>		Shift {count} [range] lines one 'shiftwidth' right.
+:[range]> [flags]	Shift {count} [range] lines one 'shiftwidth' right.
 			Repeat '>' for shifting multiple 'shiftwidth's.
+			See |ex-flags| for [flags].
 
-:[range]> {count}	Shift {count} lines one 'shiftwidth' right, starting
+:[range]> {count} [flags]
+			Shift {count} lines one 'shiftwidth' right, starting
 			with [range] (default current line |cmdline-ranges|).
 			Repeat '>' for shifting multiple 'shiftwidth's.
+			See |ex-flags| for [flags].
 
 The ">" and "<" commands are handy for changing the indentation within
 programs.  Use the 'shiftwidth' option to set the size of the white space
@@ -519,7 +527,7 @@ comment (starting with '"') after the ":!" command.
 
 4.2 Substitute						*:substitute*
 							*:s* *:su*
-:[range]s[ubstitute]/{pattern}/{string}/[&][c][e][g][p][r][i][I] [count]
+:[range]s[ubstitute]/{pattern}/{string}/[&][#][c][e][g][p][r][i][I] [count]
 			For each line in [range] replace a match of {pattern}
 			with {string}.
 			For the {pattern} see |pattern|.
@@ -533,8 +541,8 @@ comment (starting with '"') after the ":!" command.
 			Also see |cmdline-ranges|.
 			See |:s_flags| for the flags.
 
-:[range]s[ubstitute] [c][e][g][p][r][i][I] [count]
-:[range]&[&][c][e][g][p][r][i][I] [count]			*:&*
+:[range]s[ubstitute] [#][c][e][g][p][r][i][I] [count]
+:[range]&[&][#][c][e][g][p][r][i][I] [count]			*:&*
 			Repeat last :substitute with same search pattern and
 			substitute string, but without the same flags.  You
 			may add extra flags (see |:s_flags|).
@@ -544,7 +552,7 @@ comment (starting with '"') after the ":!" command.
 			'r' flags isn't required, but in scripts it's a good
 			idea to keep it to avoid confusion.
 
-:[range]~[&][c][e][g][p][r][i][I] [count]			*:~*
+:[range]~[&][#][c][e][g][p][r][i][I] [count]			*:~*
 			Repeat last substitute with same substitute string
 			but with last used search pattern.  This is like
 			":&r".  See |:s_flags| for the flags.
@@ -622,7 +630,10 @@ The flags that you can use for the substitute commands:
 	{not in Vi}
 
 [p]	Print the line containing the last substitute.
-	{not in Vi}
+
+[#]	Like [p] and prepend the line number.
+
+[l]	Like [l] but print the text like |:list|.
 
 [r]	Only useful in combination with ":&" or ":s" without arguments.  ":&r"
 	works the same way as ":~":  When the search pattern is empty, use the
@@ -668,6 +679,9 @@ For the definition of a pattern, see |pattern|.
 When the {string} starts with "\=" it is evaluated as an expression, see
 |sub-replace-expression|.  Otherwise these characters in {string} have a
 special meaning:
+								*:s%*
+When {string} is equal to "%" and '/' is included with the 'cpotions' option,
+then the {string} of the previous substitute command is used. |cpo-/|
 
 magic	nomagic	  action    ~
   &	  \&	  replaced with the whole matched pattern	     *s/\&*
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 736ab793bc144eefb10dcb96341249100a6e3ad0..028aa089fc51cb31cd865f4b2807a72241095cbc 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1,4 +1,4 @@
-*eval.txt*      For Vim version 7.0aa.  Last change: 2005 Feb 11
+*eval.txt*      For Vim version 7.0aa.  Last change: 2005 Feb 21
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1484,13 +1484,16 @@ matchstr( {expr}, {pat}[, {start}[, {count}]])
 				String	{count}'th match of {pat} in {expr}
 max({list})			Number	maximum value of items in {list}
 min({list})			Number	minumum value of items in {list}
+mkdir({name} [, {path} [, {prot}]])
+				Number	create directory {name}
 mode()				String	current editing mode
 nextnonblank( {lnum})		Number	line nr of non-blank line >= {lnum}
 nr2char( {expr})		String	single char with ASCII value {expr}
 prevnonblank( {lnum})		Number	line nr of non-blank line <= {lnum}
 range( {expr} [, {max} [, {stride}]])
 				List	items from {expr} to {max}
-readfile({fname} [, {binary}])	List	get list of lines from file {fname}
+readfile({fname} [, {binary} [, {max}]])
+				List	get list of lines from file {fname}
 remote_expr( {server}, {string} [, {idvar}])
 				String	send expression
 remote_foreground( {server})	Number	bring Vim server to the foreground
@@ -3099,6 +3102,19 @@ min({list})	Return the minumum value of all items in {list}.
 		be used as a Number this results in an error.
 		An empty List results in zero.
 
+							*mkdir()* *E749*
+mkdir({name} [, {path} [, {prot}]])
+		Create directory {name}.
+		If {path} is "p" then intermediate directories are created as
+		necessary.  Otherwise it must be "".
+		If {prot} is given it is used to set the protection bits of
+		the new directory.  The default is 0755 (rwxr-xr-x: r/w for
+		the user readable for others).  Use 0700 to make it unreadable
+		for others.
+		This function is not available in the |sandbox|.
+		Not available on all systems.  To check use: >
+			:if exists("*mkdir")
+<
 							*mode()*
 mode()		Return a string that indicates the current mode:
 			n	Normal
@@ -3158,7 +3174,7 @@ range({expr} [, {max} [, {stride}]])				*range()*
 			range(2, -2, -1) 	" [2, 1, 0, -1, -2]
 <
 							*readfile()*
-readfile({fname} [, {binary}])
+readfile({fname} [, {binary} [, {max}]])
 		Read file {fname} and return a List, each line of the file as
 		an item.  Lines broken at NL characters.  Macintosh files
 		separated with CR will result in a single long line (unless a
@@ -3171,9 +3187,16 @@ readfile({fname} [, {binary}])
 		- CR characters that appear before a NL are removed.
 		- Whether the last line ends in a NL or not does not matter.
 		All NUL characters are replaced with a NL character.
-		Note that the whole file is read into memory and there is no
-		recognition of encoding.  Read a file into a buffer if you
-		need to.
+		When {max} is given this specifies the maximum number of lines
+		to be read.  Useful if you only want to check the first ten
+		lines of a file: >
+			:for line in readfile(fname, '', 10)
+			:  if line =~ 'Date' | echo line | endif
+			:endfor
+<		When {max} is zero or negative the result is an empty list.
+		Note that without {max} the whole file is read into memory.
+		Also note that there is no recognition of encoding.  Read a
+		file into a buffer if you need to.
 		When the file can't be opened an error message is given and
 		the result is an empty list.
 		Also see |writefile()|.
@@ -3997,6 +4020,8 @@ extra_search		Compiled with support for |'incsearch'| and
 			|'hlsearch'|
 farsi			Compiled with Farsi support |farsi|.
 file_in_path		Compiled with support for |gf| and |<cfile>|
+filterpipe		When 'shelltemp' is off pipes are used for shell
+			read/write/filter commands
 find_in_path		Compiled with support for include file searches
 			|+find_in_path|.
 fname_case		Case in file names matters (for Amiga, MS-DOS, and
@@ -4374,7 +4399,7 @@ The file "~/vim/bufnetfuncs.vim" should then define functions that start with
 
 
 Using an autoload script ~
-
+							*autoload* *E746*
 Using a script in the "autoload" directory is simpler, but requires using
 exactly the right file name.  A function that can be autoloaded has a name
 like this: >
@@ -4404,9 +4429,24 @@ Vim will look for the file "autoload/foo/bar.vim" in 'runtimepath'.
 The name before the first colon must be at least two characters long,
 otherwise it looks like a scope, such as "s:".
 
+This also works when reading a variable that has not been set yet: >
+
+	:let l = foo:bar:lvar
+
+When assigning a value to such a variable nothing special happens.  This can
+be used to pass settings to the autoload script before it's loaded: >
+
+	:let foo:bar:toggle = 1
+	:call foo:bar:func()
+
 Note that when you make a mistake and call a function that is supposed to be
 defined in an autoload script, but the script doesn't actually define the
 function, the script will be sourced every time you try to call the function.
+And you will get an error message every time.
+
+Also note that if you have two script files, and one calls a function in the
+other and vise versa, before the used function is defined, it won't work.
+Avoid using the autoload functionality at the toplevel.
 
 ==============================================================================
 6. Curly braces names					*curly-braces-names*
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 25558d64238ec7a2839268634f31fb91d6f2b373..e8b4a9d1554591d91be2deef314cae9dab978d60 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1,4 +1,4 @@
-*options.txt*	For Vim version 7.0aa.  Last change: 2005 Feb 10
+*options.txt*	For Vim version 7.0aa.  Last change: 2005 Feb 21
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -1745,9 +1745,11 @@ A jump table for the options with a short description can be found at |Q_op|.
 			enables cancelling the mapping by typing <F1><Esc>.
 								*cpo-l*
 		l	Backslash in a [] range in a search pattern is taken
-			literally, only "\]" is special  See |/[]|
+			literally, only "\]", "\^", "\-" and "\\" are special.
+			See |/[]|
 			   'l' included: "/[ \t]"  finds <Space>, '\' and 't'
 			   'l' excluded: "/[ \t]"  finds <Space> and <Tab>
+			Also see |cpo-\|.
 								*cpo-L*
 		L	When the 'list' option is set, 'wrapmargin',
 			'textwidth', 'softtabstop' and Virtual Replace mode
@@ -1895,17 +1897,31 @@ A jump table for the options with a short description can be found at |Q_op|.
 	    contains	behavior	~
 			 					*cpo-#*
 		#	A count before "D", "o" and "O" has no effect.
+								*cpo-&*
+		&	When ":preserve" was used keep the swap file when
+			exiting normally while this buffer is still loaded.
+			This flag is tested when exiting.
+								*cpo-\*
+		\	Backslash in a [] range in a search pattern is taken
+			literally, only "\]" is special  See |/[]|
+			   'l' included: "/[ \t]"  finds <Space>, '\' and 't'
+			   'l' excluded: "/[ \t]"  finds <Space> and <Tab>
+			Also see |cpo-\|.
+								*cpo-/*
+		/	When "%" is used as the replacement string in a |:s|
+			command, use the previous replacement string. |:s%|
 								*cpo-{*
 		{	The |{| and |}| commands also stop at a "{" character
 			at the start of a line.
+								*cpo-.*
+		.	The ":chdir" and ":cd" commands fail if the current
+			buffer is modified, unless ! is used.  Vim doesn't
+			need this, since it remembers the full path of an
+			opened file.
 								*cpo-bar*
 		|	The value of the $LINES and $COLUMNS environment
 			variables overrule the terminal size values obtained
 			with system specific functions.
-								*cpo-&*
-		&	When ":preserve" was used keep the swap file when
-			exiting normally while this buffer is still loaded.
-			This flag is tested when exiting.
 
 
 						*'cscopepathcomp'* *'cspc'*
@@ -1972,6 +1988,9 @@ A jump table for the options with a short description can be found at |Q_op|.
 	When set to "msg", error messages that would otherwise be omitted will
 	be given anyway.  This is useful when debugging 'foldexpr' or
 	'indentexpr'.
+	When set to "beep", a message will be given when otherwise only a beep
+	would be produced.
+	The values can be combined, separated by a comma.
 
 						*'define'* *'def'*
 'define' 'def'		string	(default "^\s*#\s*define")
@@ -4708,6 +4727,11 @@ A jump table for the options with a short description can be found at |Q_op|.
 	List of items that control the format of the output of |:hardcopy|.
 	See |popt-option|.
 
+						*'prompt'* *'noprompt'*
+'prompt'		boolean	(default on)
+			global
+	When on a ":" prompt is used in Ex mode.
+
 						*'quoteescape'* *'qe'*
 'quoteescape' 'qe'	string	(default "\")
 			local to buffer
@@ -5239,6 +5263,22 @@ A jump table for the options with a short description can be found at |Q_op|.
 	separator.  To test if this is so use: >
 		if exists('+shellslash')
 <
+			*'shelltemp'* *'stmp'* *'noshelltemp'* *'nostmp'*
+'shelltemp' 'stmp'	boolean	(Vi default off, Vim default on)
+			global
+			{not in Vi}
+	When on, use temp files for shell commands.  When off use a pipe.
+	When using a pipe is not possible temp files are used anyway.
+	Currently a pipe is only supported on Unix.  You can check it with: >
+		:if has("filterpipe")
+<	The advantage of using a pipe is that nobody can read the temp file
+	and the 'shell' command does not need to support redirection.
+	The advantage of using a temp file is that the file type and encoding
+	can be detected.
+	The |FilterReadPre|, |FilterReadPost| and |FilterWritePre|,
+	|FilterWritePost| autocommands event are not triggered when
+	'shelltemp' is off.
+
 						*'shelltype'* *'st'*
 'shelltype' 'st'	number	(default 0)
 			global
@@ -5288,7 +5328,8 @@ A jump table for the options with a short description can be found at |Q_op|.
 	|'cindent'|, |>>|, |<<|, etc.
 
 						*'shortmess'* *'shm'*
-'shortmess' 'shm'	string	(Vim default "filnxtToO", Vi default: "")
+'shortmess' 'shm'	string	(Vim default "filnxtToO", Vi default: "",
+							POSIX default: "A")
 			global
 			{not in Vi}
 	This option helps to avoid all the |hit-enter| prompts caused by file
diff --git a/runtime/doc/pattern.txt b/runtime/doc/pattern.txt
index 2ff676ac2d5e1707a05cb134bd65727b830f0854..d12f0a05452bab1619e58e63a119c814d1573acc 100644
--- a/runtime/doc/pattern.txt
+++ b/runtime/doc/pattern.txt
@@ -1,4 +1,4 @@
-*pattern.txt*   For Vim version 7.0aa.  Last change: 2005 Jan 26
+*pattern.txt*   For Vim version 7.0aa.  Last change: 2005 Feb 20
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -522,11 +522,6 @@ An atom can be followed by an indication of how many times the atom can be
 matched and in what way.  This is called a multi.  See |/multi| for an
 overview.
 
-It is not possible to use a multi that can match more than one time after an
-atom that can match an empty string.  That's because this could result in an
-endless loop.  If you try it, you will get this error message: >
-	*, \+ or \{ operand could be empty
-<
 						*/star* */\star* *E56*
 *	(use \* when 'magic' is not set)
 	Matches 0 or more of the preceding atom, as many as possible.
@@ -577,7 +572,7 @@ endless loop.  If you try it, you will get this error message: >
 \{-}	matches 0 or more of the preceding atom, as few as possible
 	{Vi does not have any of these}
 
-	n and m are positive decimal numbers
+	n and m are positive decimal numbers or zero
 
 	If a "-" appears immediately after the "{", then a shortest match
 	first algorithm is used (see example below).  In particular, "\{-}" is
@@ -982,6 +977,17 @@ x	A single character, with no special meaning, matches itself
 	  a list of at least one character, each of which is either '-', '.',
 	  '/', alphabetic, numeric, '_' or '~'.
 	  These items only work for 8-bit characters.
+							*/[[=* *[==]*
+	- An equivalence class.  This means that characters are matched that
+	  have almost the same meaning, e.g., when ignoring accents.  The form
+	  is:
+	  	[=a=]
+	  Currrently this is only implemented for latin1.  Also works for the
+	  latin1 characters in utf-8 and latin9.
+							*/[[.* *[..]*
+	- A collation element.  This currently simply accepts a single
+	  character in the form:
+	  	[.a.]
 							  */\]*
 	- To include a literal ']', '^', '-' or '\' in the collection, put a
 	  backslash before it: "[xyz\]]", "[\^xyz]", "[xy\-z]" and "[xyz\\]".
diff --git a/runtime/doc/repeat.txt b/runtime/doc/repeat.txt
index ef8442b25a7a11fd2a5c21575ee91d92fb31a437..04fb0ada3885f9cbcf92e3496432805db58f6503 100644
--- a/runtime/doc/repeat.txt
+++ b/runtime/doc/repeat.txt
@@ -1,4 +1,4 @@
-*repeat.txt*    For Vim version 7.0aa.  Last change: 2005 Jan 28
+*repeat.txt*    For Vim version 7.0aa.  Last change: 2005 Feb 19
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -81,6 +81,11 @@ This replaces all occurrences of "pat" with "PAT".  The same can be done with:
 	:%s/pat/PAT/g
 Which is two characters shorter!
 
+A special case is using ":visual" as a command.  This will move to a matching
+line, go to Normal mode to let you execute commands there until you use |Q| to
+return to Ex mode.  This will be repeated for each matching line.  While doing
+this you cannot use ":global".
+
 ==============================================================================
 3. Complex repeats					*complex-repeat*
 
@@ -102,7 +107,7 @@ q			Stops recording.  (Implementation note: The 'q' that
 			expression.  The result of the expression is then
 			executed.  See also |@:|.  {Vi: only named registers}
 
-							*@@*
+							*@@* *E748*
 @@			Repeat the previous @{0-9a-z":*} [count] times.
 
 :[addr]*{0-9a-z".=}						*:@* *:star*
diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt
index 46a5e0b02aeef3b5c4f7cb9044b4214595b87170..337c2ca925158d22993c30d5183d61c532e44844 100644
--- a/runtime/doc/starting.txt
+++ b/runtime/doc/starting.txt
@@ -1,4 +1,4 @@
-*starting.txt*  For Vim version 7.0aa.  Last change: 2005 Feb 10
+*starting.txt*  For Vim version 7.0aa.  Last change: 2005 Feb 19
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -263,8 +263,14 @@ a slash.  Thus "-R" means recovery and "-/R" readonly.
 		To be used when Vim is used to execute Ex commands from a file
 		instead of a terminal.  Switches off most prompts and
 		informative messages.  Also warnings and error messages.
-		But ":print" output is displayed.  And when 'verbose' is
-		non-zero messages are printed (for debugging).
+		The output of these commands is displayed (to stdout):
+			:print
+			:list
+			:number
+			:set      to display option values.
+		When 'verbose' is non-zero messages are printed (for
+		debugging, to stderr).
+		'term' and $TERM are not used.
 		If Vim appears to be stuck try typing "qa!<Enter>".  You don't
 		get a prompt thus you can't see Vim is waiting for you to type
 		something.
diff --git a/runtime/doc/tags b/runtime/doc/tags
index bc1e9ef0fe2ccfb02c43d6633c78841649949b37..dedbc71fcede4ff0b7f1d41a6d8d27c667721dad 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -506,6 +506,7 @@ $VIMRUNTIME	starting.txt	/*$VIMRUNTIME*
 'nopi'	options.txt	/*'nopi'*
 'nopreserveindent'	options.txt	/*'nopreserveindent'*
 'nopreviewwindow'	options.txt	/*'nopreviewwindow'*
+'noprompt'	options.txt	/*'noprompt'*
 'nopvw'	options.txt	/*'nopvw'*
 'noreadonly'	options.txt	/*'noreadonly'*
 'noremap'	options.txt	/*'noremap'*
@@ -528,6 +529,7 @@ $VIMRUNTIME	starting.txt	/*$VIMRUNTIME*
 'nosecure'	options.txt	/*'nosecure'*
 'nosft'	options.txt	/*'nosft'*
 'noshellslash'	options.txt	/*'noshellslash'*
+'noshelltemp'	options.txt	/*'noshelltemp'*
 'noshiftround'	options.txt	/*'noshiftround'*
 'noshortname'	options.txt	/*'noshortname'*
 'noshowcmd'	options.txt	/*'noshowcmd'*
@@ -549,6 +551,7 @@ $VIMRUNTIME	starting.txt	/*$VIMRUNTIME*
 'nossl'	options.txt	/*'nossl'*
 'nosta'	options.txt	/*'nosta'*
 'nostartofline'	options.txt	/*'nostartofline'*
+'nostmp'	options.txt	/*'nostmp'*
 'noswapfile'	options.txt	/*'noswapfile'*
 'noswf'	options.txt	/*'noswf'*
 'nota'	options.txt	/*'nota'*
@@ -633,7 +636,7 @@ $VIMRUNTIME	starting.txt	/*$VIMRUNTIME*
 'printmbcharset'	options.txt	/*'printmbcharset'*
 'printmbfont'	options.txt	/*'printmbfont'*
 'printoptions'	options.txt	/*'printoptions'*
-'prompt'	vi_diff.txt	/*'prompt'*
+'prompt'	options.txt	/*'prompt'*
 'pt'	options.txt	/*'pt'*
 'pvh'	options.txt	/*'pvh'*
 'pvw'	options.txt	/*'pvw'*
@@ -687,6 +690,7 @@ $VIMRUNTIME	starting.txt	/*$VIMRUNTIME*
 'shellquote'	options.txt	/*'shellquote'*
 'shellredir'	options.txt	/*'shellredir'*
 'shellslash'	options.txt	/*'shellslash'*
+'shelltemp'	options.txt	/*'shelltemp'*
 'shelltype'	options.txt	/*'shelltype'*
 'shellxquote'	options.txt	/*'shellxquote'*
 'shiftround'	options.txt	/*'shiftround'*
@@ -732,6 +736,7 @@ $VIMRUNTIME	starting.txt	/*$VIMRUNTIME*
 'startofline'	options.txt	/*'startofline'*
 'statusline'	options.txt	/*'statusline'*
 'stl'	options.txt	/*'stl'*
+'stmp'	options.txt	/*'stmp'*
 'sts'	options.txt	/*'sts'*
 'su'	options.txt	/*'su'*
 'sua'	options.txt	/*'sua'*
@@ -1213,6 +1218,8 @@ $VIMRUNTIME	starting.txt	/*$VIMRUNTIME*
 /.	pattern.txt	/*\/.*
 //;	pattern.txt	/*\/\/;*
 /<CR>	pattern.txt	/*\/<CR>*
+/[[.	pattern.txt	/*\/[[.*
+/[[=	pattern.txt	/*\/[[=*
 /[]	pattern.txt	/*\/[]*
 /\	pattern.txt	/*\/\\*
 /\$	pattern.txt	/*\/\\$*
@@ -1848,7 +1855,7 @@ $VIMRUNTIME	starting.txt	/*$VIMRUNTIME*
 :display	change.txt	/*:display*
 :dj	tagsrch.txt	/*:dj*
 :djump	tagsrch.txt	/*:djump*
-:dl	tagsrch.txt	/*:dl*
+:dli	tagsrch.txt	/*:dli*
 :dlist	tagsrch.txt	/*:dlist*
 :do	autocmd.txt	/*:do*
 :doau	autocmd.txt	/*:doau*
@@ -2280,6 +2287,7 @@ $VIMRUNTIME	starting.txt	/*$VIMRUNTIME*
 :rv	starting.txt	/*:rv*
 :rviminfo	starting.txt	/*:rviminfo*
 :s	change.txt	/*:s*
+:s%	change.txt	/*:s%*
 :sN	windows.txt	/*:sN*
 :sNext	windows.txt	/*:sNext*
 :s\=	change.txt	/*:s\\=*
@@ -2840,6 +2848,7 @@ CTRL-M	motion.txt	/*CTRL-M*
 CTRL-N	motion.txt	/*CTRL-N*
 CTRL-O	motion.txt	/*CTRL-O*
 CTRL-P	motion.txt	/*CTRL-P*
+CTRL-Q	gui_w32.txt	/*CTRL-Q*
 CTRL-R	undo.txt	/*CTRL-R*
 CTRL-T	tagsrch.txt	/*CTRL-T*
 CTRL-U	scroll.txt	/*CTRL-U*
@@ -3653,6 +3662,10 @@ E742	eval.txt	/*E742*
 E743	eval.txt	/*E743*
 E744	netbeans.txt	/*E744*
 E745	eval.txt	/*E745*
+E746	eval.txt	/*E746*
+E747	syntax.txt	/*E747*
+E748	repeat.txt	/*E748*
+E749	eval.txt	/*E749*
 E75	vi_diff.txt	/*E75*
 E76	pattern.txt	/*E76*
 E77	message.txt	/*E77*
@@ -3922,6 +3935,7 @@ ZZ	editing.txt	/*ZZ*
 [(	motion.txt	/*[(*
 [++opt]	editing.txt	/*[++opt]*
 [+cmd]	editing.txt	/*[+cmd]*
+[..]	pattern.txt	/*[..]*
 [/	motion.txt	/*[\/*
 [:alnum:]	pattern.txt	/*[:alnum:]*
 [:alpha:]	pattern.txt	/*[:alpha:]*
@@ -3940,6 +3954,7 @@ ZZ	editing.txt	/*ZZ*
 [:upper:]	pattern.txt	/*[:upper:]*
 [:xdigit:]	pattern.txt	/*[:xdigit:]*
 [<MiddleMouse>	change.txt	/*[<MiddleMouse>*
+[==]	pattern.txt	/*[==]*
 [D	tagsrch.txt	/*[D*
 [I	tagsrch.txt	/*[I*
 [M	motion.txt	/*[M*
@@ -4121,6 +4136,7 @@ autocmds-kept	version5.txt	/*autocmds-kept*
 autocommand	autocmd.txt	/*autocommand*
 autocommand-events	autocmd.txt	/*autocommand-events*
 autocommand-pattern	autocmd.txt	/*autocommand-pattern*
+autoload	eval.txt	/*autoload*
 autoload-functions	eval.txt	/*autoload-functions*
 avoid-hit-enter	version5.txt	/*avoid-hit-enter*
 aw	motion.txt	/*aw*
@@ -4385,6 +4401,8 @@ cpo-%	options.txt	/*cpo-%*
 cpo-&	options.txt	/*cpo-&*
 cpo-+	options.txt	/*cpo-+*
 cpo--	options.txt	/*cpo--*
+cpo-.	options.txt	/*cpo-.*
+cpo-/	options.txt	/*cpo-\/*
 cpo-<	options.txt	/*cpo-<*
 cpo->	options.txt	/*cpo->*
 cpo-A	options.txt	/*cpo-A*
@@ -4404,6 +4422,8 @@ cpo-R	options.txt	/*cpo-R*
 cpo-S	options.txt	/*cpo-S*
 cpo-W	options.txt	/*cpo-W*
 cpo-X	options.txt	/*cpo-X*
+cpo-Z	options.txt	/*cpo-Z*
+cpo-\	options.txt	/*cpo-\\*
 cpo-a	options.txt	/*cpo-a*
 cpo-b	options.txt	/*cpo-b*
 cpo-bar	options.txt	/*cpo-bar*
@@ -4655,6 +4675,7 @@ evim.vim	starting.txt	/*evim.vim*
 ex	starting.txt	/*ex*
 ex-cmd-index	index.txt	/*ex-cmd-index*
 ex-edit-index	index.txt	/*ex-edit-index*
+ex-flags	cmdline.txt	/*ex-flags*
 ex:	options.txt	/*ex:*
 except-autocmd	eval.txt	/*except-autocmd*
 except-autocmd-Cmd	eval.txt	/*except-autocmd-Cmd*
@@ -5048,7 +5069,6 @@ hebrew	hebrew.txt	/*hebrew*
 hebrew.txt	hebrew.txt	/*hebrew.txt*
 help	various.txt	/*help*
 help-context	help.txt	/*help-context*
-help-tags	tags	1
 help-translated	various.txt	/*help-translated*
 help-xterm-window	various.txt	/*help-xterm-window*
 help.txt	help.txt	/*help.txt*
@@ -5503,8 +5523,8 @@ messages	message.txt	/*messages*
 meta	intro.txt	/*meta*
 min()	eval.txt	/*min()*
 minimal-features	os_msdos.txt	/*minimal-features*
-missing-commands	vi_diff.txt	/*missing-commands*
 missing-options	vi_diff.txt	/*missing-options*
+mkdir()	eval.txt	/*mkdir()*
 mlang.txt	mlang.txt	/*mlang.txt*
 mode()	eval.txt	/*mode()*
 mode-Ex	intro.txt	/*mode-Ex*
@@ -6132,6 +6152,7 @@ sign.txt	sign.txt	/*sign.txt*
 signs	sign.txt	/*signs*
 simple-change	change.txt	/*simple-change*
 simplify()	eval.txt	/*simplify()*
+simulated-command	vi_diff.txt	/*simulated-command*
 single-repeat	repeat.txt	/*single-repeat*
 skeleton	autocmd.txt	/*skeleton*
 slow-fast-terminal	term.txt	/*slow-fast-terminal*
@@ -6206,6 +6227,7 @@ swap-file	recover.txt	/*swap-file*
 swapfile-changed	version4.txt	/*swapfile-changed*
 syn-sync-grouphere	syntax.txt	/*syn-sync-grouphere*
 syn-sync-groupthere	syntax.txt	/*syn-sync-groupthere*
+syn-sync-linecont	syntax.txt	/*syn-sync-linecont*
 synID()	eval.txt	/*synID()*
 synIDattr()	eval.txt	/*synIDattr()*
 synIDtrans()	eval.txt	/*synIDtrans()*
diff --git a/runtime/doc/windows.txt b/runtime/doc/windows.txt
index f9616a72b9a8bc3874eafcb1678635d1bb1856e1..fb7cf9e1c2b8d804c7f9a5265b20e2904eeb759f 100644
--- a/runtime/doc/windows.txt
+++ b/runtime/doc/windows.txt
@@ -1,4 +1,4 @@
-*windows.txt*   For Vim version 7.0aa.  Last change: 2005 Jan 26
+*windows.txt*   For Vim version 7.0aa.  Last change: 2005 Feb 18
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -587,7 +587,7 @@ can also get to them with the buffer list commands, like ":bnext".
 		not split.  Also see |++opt| and |+cmd|.
 
 						*:sfir* *:sfirst*
-:sfir[st [++opt] [+cmd]
+:sfir[st] [++opt] [+cmd]
 		Same as ":srewind".
 
 						*:sla* *:slast*
diff --git a/runtime/filetype.vim b/runtime/filetype.vim
index fa1908cf70035461d887fb69a26ada3fff314a68..bbbb6d2c14bf4b4131007637298a725afd81b247 100644
--- a/runtime/filetype.vim
+++ b/runtime/filetype.vim
@@ -1,7 +1,7 @@
 " Vim support file to detect file types
 "
 " Maintainer:	Bram Moolenaar <Bram@vim.org>
-" Last Change:	2005 Jan 27
+" Last Change:	2005 Feb 18
 
 " Listen very carefully, I will say this only once
 if exists("did_load_filetypes")
@@ -512,6 +512,9 @@ au BufNewFile,BufRead *.erl			setf erlang
 " Elm Filter Rules file
 au BufNewFile,BufRead filter-rules		setf elmfilt
 
+" ESMTP rc file
+au BufNewFile,BufRead *esmtprc			setf esmtprc
+
 " ESQL-C
 au BufNewFile,BufRead *.ec,*.EC			setf esqlc
 
diff --git a/runtime/ftplugin/vim.vim b/runtime/ftplugin/vim.vim
index fce830e8eaad2d36e550f82431adf893b1bb69ce..698d3ee8708130aa5ce71bdefede99ba2d9c2764 100644
--- a/runtime/ftplugin/vim.vim
+++ b/runtime/ftplugin/vim.vim
@@ -1,7 +1,7 @@
 " Vim filetype plugin
 " Language:	Vim
 " Maintainer:	Bram Moolenaar <Bram@vim.org>
-" Last Change:	2004 Sep 13
+" Last Change:	2005 Feb 14
 
 " Only do this when not done yet for this buffer
 if exists("b:did_ftplugin")
@@ -58,4 +58,6 @@ if exists("loaded_matchit")
 endif
 
 let &cpo = cpo_save
-setlocal cpo+=M		" makes \%( match \)
+
+" removed this, because 'cpoptions' is a global option.
+" setlocal cpo+=M		" makes \%( match \)
diff --git a/src/ex_getln.c b/src/ex_getln.c
index 05c85b49fd6d00ab50e2ee3f37a1628cf1144e06..4c9d17d78f6821376b68202dc261f21df19d8db0 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -681,16 +681,29 @@ getcmdline(firstc, count, indent)
 	if (c == '\n' || c == '\r' || c == K_KENTER || (c == ESC
 			&& (!KeyTyped || vim_strchr(p_cpo, CPO_ESC) != NULL)))
 	{
-	    gotesc = FALSE;	/* Might have typed ESC previously, don't
-				   truncate the cmdline now. */
-	    if (ccheck_abbr(c + ABBR_OFF))
-		goto cmdline_changed;
-	    if (!cmd_silent)
+	    /* In Ex mode a backslash escapes a newline. */
+	    if (exmode_active
+		    && c != ESC
+		    && ccline.cmdpos > 0
+		    && ccline.cmdpos == ccline.cmdlen
+		    && ccline.cmdbuff[ccline.cmdpos - 1] == '\\')
 	    {
-		windgoto(msg_row, 0);
-		out_flush();
+		if (c == K_KENTER)
+		    c = '\n';
+	    }
+	    else
+	    {
+		gotesc = FALSE;	/* Might have typed ESC previously, don't
+				       truncate the cmdline now. */
+		if (ccheck_abbr(c + ABBR_OFF))
+		    goto cmdline_changed;
+		if (!cmd_silent)
+		{
+		    windgoto(msg_row, 0);
+		    out_flush();
+		}
+		break;
 	    }
-	    break;
 	}
 
 	/*
@@ -1879,25 +1892,24 @@ getexline(c, dummy, indent)
  * Get an Ex command line for Ex mode.
  * In Ex mode we only use the OS supplied line editing features and no
  * mappings or abbreviations.
+ * Returns a string in allocated memory or NULL.
  */
 /* ARGSUSED */
     char_u *
-getexmodeline(c, dummy, indent)
-    int		c;		/* normally ':', NUL for ":append" */
+getexmodeline(promptc, dummy, indent)
+    int		promptc;	/* normally ':', NUL for ":append" and '?' for
+				   :s prompt */
     void	*dummy;		/* cookie not used */
     int		indent;		/* indent for inside conditionals */
 {
-    garray_T		line_ga;
-    int			len;
-    int			off = 0;
-    char_u		*pend;
-    int			finished = FALSE;
-#if defined(FEAT_GUI) || defined(NO_COOKED_INPUT)
-    int			startcol = 0;
-    int			c1;
-    int			escaped = FALSE;	/* CTRL-V typed */
-    int			vcol = 0;
-#endif
+    garray_T	line_ga;
+    char_u	*pend;
+    int		startcol = 0;
+    int		c1;
+    int		escaped = FALSE;	/* CTRL-V typed */
+    int		vcol = 0;
+    char_u	*p;
+    int		prev_char = 0;
 
     /* Switch cursor on now.  This avoids that it happens after the "\n", which
      * confuses the system function that computes tabstops. */
@@ -1905,27 +1917,24 @@ getexmodeline(c, dummy, indent)
 
     /* always start in column 0; write a newline if necessary */
     compute_cmdrow();
-    if (msg_col)
+    if ((msg_col || msg_didout) && promptc != '?')
 	msg_putchar('\n');
-    if (c == ':')
+    if (promptc == ':')
     {
 	/* indent that is only displayed, not in the line itself */
-	msg_putchar(':');
+	if (p_prompt)
+	    msg_putchar(':');
 	while (indent-- > 0)
 	    msg_putchar(' ');
-#if defined(FEAT_GUI) || defined(NO_COOKED_INPUT)
 	startcol = msg_col;
-#endif
     }
 
     ga_init2(&line_ga, 1, 30);
 
     /* autoindent for :insert and :append is in the line itself */
-    if (c <= 0)
+    if (promptc <= 0)
     {
-#if defined(FEAT_GUI) || defined(NO_COOKED_INPUT)
 	vcol = indent;
-#endif
 	while (indent >= 8)
 	{
 	    ga_append(&line_ga, TAB);
@@ -1938,198 +1947,180 @@ getexmodeline(c, dummy, indent)
 	    msg_putchar(' ');
 	}
     }
+    ++no_mapping;
+    ++allow_keys;
 
     /*
      * Get the line, one character at a time.
      */
     got_int = FALSE;
-    while (!got_int && !finished)
+    while (!got_int)
     {
 	if (ga_grow(&line_ga, 40) == FAIL)
 	    break;
 	pend = (char_u *)line_ga.ga_data + line_ga.ga_len;
 
-	/* Get one character (inchar gets a third of maxlen characters!) */
-	len = inchar(pend + off, 3, -1L, 0);
-	if (len < 0)
-	    continue;	    /* end of input script reached */
-	/* for a special character, we need at least three characters */
-	if ((*pend == K_SPECIAL || *pend == CSI) && off + len < 3)
-	{
-	    off += len;
-	    continue;
-	}
-	len += off;
-	off = 0;
+	/* Get one character at a time.  Don't use inchar(), it can't handle
+	 * special characters. */
+	c1 = vgetc();
 
 	/*
-	 * When using the GUI, and for systems that don't have cooked input,
-	 * handle line editing here.
+	 * Handle line editing.
+	 * Previously this was left to the system, putting the terminal in
+	 * cooked mode, but then CTRL-D and CTRL-T can't be used properly.
 	 */
-#if defined(FEAT_GUI) || defined(NO_COOKED_INPUT)
-# ifndef NO_COOKED_INPUT
-	if (gui.in_use)
-# endif
+	if (got_int)
 	{
-	    if (got_int)
-	    {
-		msg_putchar('\n');
-		break;
-	    }
+	    msg_putchar('\n');
+	    break;
+	}
 
-	    while (len > 0)
+	if (!escaped)
+	{
+	    /* CR typed means "enter", which is NL */
+	    if (c1 == '\r')
+		c1 = '\n';
+
+	    if (c1 == BS || c1 == K_BS
+			  || c1 == DEL || c1 == K_DEL || c1 == K_KDEL)
 	    {
-		c1 = *pend++;
-		--len;
-		if ((c1 == K_SPECIAL
-#  if !defined(NO_COOKED_INPUT) || defined(FEAT_GUI)
-			    || c1 == CSI
-#  endif
-		    ) && len >= 2)
+		if (line_ga.ga_len > 0)
 		{
-		    c1 = TO_SPECIAL(pend[0], pend[1]);
-		    pend += 2;
-		    len -= 2;
+		    --line_ga.ga_len;
+		    goto redraw;
 		}
+		continue;
+	    }
 
-		if (!escaped)
-		{
-		    /* CR typed means "enter", which is NL */
-		    if (c1 == '\r')
-			c1 = '\n';
-
-		    if (c1 == BS || c1 == K_BS
-				  || c1 == DEL || c1 == K_DEL || c1 == K_KDEL)
-		    {
-			if (line_ga.ga_len > 0)
-			{
-			    int		i, v;
-			    char_u	*q;
-
-			    --line_ga.ga_len;
-			    /* compute column that cursor should be in */
-			    v = 0;
-			    q = ((char_u *)line_ga.ga_data);
-			    for (i = 0; i < line_ga.ga_len; ++i)
-			    {
-				if (*q == TAB)
-				    v += 8 - v % 8;
-				else
-				    v += ptr2cells(q);
-				++q;
-			    }
-			    /* erase characters to position cursor */
-			    while (vcol > v)
-			    {
-				msg_putchar('\b');
-				msg_putchar(' ');
-				msg_putchar('\b');
-				--vcol;
-			    }
-			}
-			continue;
-		    }
-
-		    if (c1 == Ctrl_U)
-		    {
-			msg_col = startcol;
-			msg_clr_eos();
-			line_ga.ga_len = 0;
-			continue;
-		    }
+	    if (c1 == Ctrl_U)
+	    {
+		msg_col = startcol;
+		msg_clr_eos();
+		line_ga.ga_len = 0;
+		continue;
+	    }
 
-		    if (c1 == Ctrl_T)
-			c1 = TAB;	/* very simplistic... */
+	    if (c1 == Ctrl_T)
+	    {
+		p = (char_u *)line_ga.ga_data;
+		p[line_ga.ga_len] = NUL;
+		indent = get_indent_str(p, 8);
+		indent += curbuf->b_p_sw - indent % curbuf->b_p_sw;
+add_indent:
+		while (get_indent_str(p, 8) < indent)
+		{
+		    char_u *s = skipwhite(p);
 
-		    if (c1 == Ctrl_D)
+		    ga_grow(&line_ga, 1);
+		    mch_memmove(s + 1, s, line_ga.ga_len - (s - p) + 1);
+		    *s = ' ';
+		    ++line_ga.ga_len;
+		}
+redraw:
+		/* redraw the line */
+		msg_col = startcol;
+		windgoto(msg_row, msg_col);
+		vcol = 0;
+		for (p = (char_u *)line_ga.ga_data;
+			  p < (char_u *)line_ga.ga_data + line_ga.ga_len; ++p)
+		{
+		    if (*p == TAB)
 		    {
-			char_u	*p;
-
-			/* Delete one shiftwidth. */
-			p = (char_u *)line_ga.ga_data;
-			p[line_ga.ga_len] = NUL;
-			indent = get_indent_str(p, 8);
-			--indent;
-			indent -= indent % 8;
-			while (get_indent_str(p, 8) > indent)
-			{
-			    char_u *s = skipwhite(p);
-
-			    mch_memmove(s - 1, s, line_ga.ga_len - (s - p) + 1);
-			    --line_ga.ga_len;
-			}
-			msg_col = startcol;
-			for (vcol = 0; *p != NUL; ++p)
+			do
 			{
-			    if (*p == TAB)
-			    {
-				do
-				{
-				    msg_putchar(' ');
-				} while (++vcol % 8);
-			    }
-			    else
-			    {
-				msg_outtrans_len(p, 1);
-				vcol += char2cells(*p);
-			    }
-			}
-			msg_clr_eos();
-			continue;
+			    msg_putchar(' ');
+			} while (++vcol % 8);
 		    }
-
-		    if (c1 == Ctrl_V)
+		    else
 		    {
-			escaped = TRUE;
-			continue;
+			msg_outtrans_len(p, 1);
+			vcol += char2cells(*p);
 		    }
 		}
+		msg_clr_eos();
+		continue;
+	    }
 
-		if (IS_SPECIAL(c1))
-		    c1 = '?';
-		((char_u *)line_ga.ga_data)[line_ga.ga_len] = c1;
-		if (c1 == '\n')
-		    msg_putchar('\n');
-		else if (c1 == TAB)
+	    if (c1 == Ctrl_D)
+	    {
+		/* Delete one shiftwidth. */
+		p = (char_u *)line_ga.ga_data;
+		if (prev_char == '0' || prev_char == '^')
 		{
-		    /* Don't use chartabsize(), 'ts' can be different */
-		    do
-		    {
-			msg_putchar(' ');
-		    } while (++vcol % 8);
+		    if (prev_char == '^')
+			ex_keep_indent = TRUE;
+		    indent = 0;
+		    p[--line_ga.ga_len] = NUL;
 		}
 		else
 		{
-		    msg_outtrans_len(
-			     ((char_u *)line_ga.ga_data) + line_ga.ga_len, 1);
-		    vcol += char2cells(c1);
+		    p[line_ga.ga_len] = NUL;
+		    indent = get_indent_str(p, 8);
+		    --indent;
+		    indent -= indent % curbuf->b_p_sw;
+		}
+		while (get_indent_str(p, 8) > indent)
+		{
+		    char_u *s = skipwhite(p);
+
+		    mch_memmove(s - 1, s, line_ga.ga_len - (s - p) + 1);
+		    --line_ga.ga_len;
 		}
-		++line_ga.ga_len;
-		escaped = FALSE;
+		goto add_indent;
+	    }
+
+	    if (c1 == Ctrl_V || c1 == Ctrl_Q)
+	    {
+		escaped = TRUE;
+		continue;
 	    }
-	    windgoto(msg_row, msg_col);
+
+	    /* Ignore special key codes: mouse movement, K_IGNORE, etc. */
+	    if (IS_SPECIAL(c1))
+		continue;
+	}
+
+	if (IS_SPECIAL(c1))
+	    c1 = '?';
+	((char_u *)line_ga.ga_data)[line_ga.ga_len] = c1;
+	prev_char = c1;
+	if (c1 == '\n')
+	    msg_putchar('\n');
+	else if (c1 == TAB)
+	{
+	    /* Don't use chartabsize(), 'ts' can be different */
+	    do
+	    {
+		msg_putchar(' ');
+	    } while (++vcol % 8);
 	}
-# ifndef NO_COOKED_INPUT
 	else
-# endif
-#endif
-#ifndef NO_COOKED_INPUT
 	{
-	    line_ga.ga_len += len;
+	    msg_outtrans_len(
+		     ((char_u *)line_ga.ga_data) + line_ga.ga_len, 1);
+	    vcol += char2cells(c1);
 	}
-#endif
+	++line_ga.ga_len;
+	escaped = FALSE;
+
+	windgoto(msg_row, msg_col);
 	pend = (char_u *)(line_ga.ga_data) + line_ga.ga_len;
-	if (line_ga.ga_len && pend[-1] == '\n')
+
+	/* we are done when a NL is entered, but not when it comes after a
+	 * backslash */
+	if (line_ga.ga_len > 0 && pend[-1] == '\n'
+		&& (line_ga.ga_len <= 1 || pend[-2] != '\\'))
 	{
-	    finished = TRUE;
 	    --line_ga.ga_len;
 	    --pend;
 	    *pend = NUL;
+	    break;
 	}
     }
 
-    /* note that cursor has moved, because of the echoed <CR> */
-    screen_down();
+    --no_mapping;
+    --allow_keys;
+
     /* make following messages go to the next line */
     msg_didout = FALSE;
     msg_col = 0;
@@ -3797,10 +3788,10 @@ addstar(fname, len, context)
 set_expand_context(xp)
     expand_T	*xp;
 {
-    /* only expansion for ':' and '>' commands */
+    /* only expansion for ':', '>' and '=' command-lines */
     if (ccline.cmdfirstc != ':'
 #ifdef FEAT_EVAL
-	    && ccline.cmdfirstc != '>'
+	    && ccline.cmdfirstc != '>' && ccline.cmdfirstc != '='
 #endif
 	    )
     {
@@ -3828,8 +3819,16 @@ set_cmd_context(xp, str, len, col)
 	old_char = str[col];
     str[col] = NUL;
     nextcomm = str;
-    while (nextcomm != NULL)
-	nextcomm = set_one_cmd_context(xp, nextcomm);
+
+#ifdef FEAT_EVAL
+    if (ccline.cmdfirstc == '=')
+	/* pass CMD_SIZE because there is no real command */
+	set_context_for_expression(xp, str, CMD_SIZE);
+    else
+#endif
+	while (nextcomm != NULL)
+	    nextcomm = set_one_cmd_context(xp, nextcomm);
+
     str[col] = old_char;
 }
 
@@ -5477,7 +5476,7 @@ ex_window()
      * Call the main loop until <CR> or CTRL-C is typed.
      */
     cmdwin_result = 0;
-    main_loop(TRUE);
+    main_loop(TRUE, FALSE);
 
     RedrawingDisabled = i;
 
diff --git a/src/gui_mac.c b/src/gui_mac.c
index dbdda8a0da6c6c6eb5c88c34203a196d589b39f0..b43aec0e5c09b1f86f3c008d576ce3bd91fbd739 100644
--- a/src/gui_mac.c
+++ b/src/gui_mac.c
@@ -91,6 +91,19 @@ static    OSType	_ftype = 'TEXT';
 static EventHandlerUPP mouseWheelHandlerUPP = NULL;
 #endif
 
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+# define USE_CARBONKEYHANDLER
+static EventHandlerUPP keyEventHandlerUPP = NULL;
+/* Defined in os_mac_conv.c */
+extern char_u *mac_utf16_to_enc __ARGS((UniChar *from, size_t fromLen, size_t *actualLen));
+extern UniChar *mac_enc_to_utf16 __ARGS((char_u *from, size_t fromLen, size_t *actualLen));
+extern CFStringRef mac_enc_to_cfstring __ARGS((char_u *from, size_t fromLen));
+#endif
+
+#ifdef MACOS_X
+SInt32 gMacSystemVersion;
+#endif
+
 /* Debugging feature: start Vim window OFFSETed */
 #undef USE_OFFSETED_WINDOW
 
@@ -213,6 +226,12 @@ static struct
 } gFontPanelInfo = { 0, 0, 0, false };
 #endif
 
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+# define USE_ATSUI_DRAWING
+ATSUStyle   gFontStyle;
+Boolean	    gIsFontFallbackSet;
+#endif
+
 /*
  * The Quickdraw global is predefined in CodeWarior
  * but is not in Apple MPW
@@ -504,6 +523,63 @@ points_to_pixels(char_u *str, char_u **end, int vertical)
     return pixels;
 }
 
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+/*
+ * Deletes all traces of any Windows-style mnemonic text (including any
+ * parentheses) from a menu item and returns the cleaned menu item title.
+ * The caller is responsible for releasing the returned string.
+ */
+    static CFStringRef
+menu_title_removing_mnemonic(menu)
+    vimmenu_T	*menu;
+{
+    CFStringRef		name;
+    size_t		menuTitleLen;
+    CFIndex		displayLen;
+    CFRange		mnemonicStart;
+    CFRange		mnemonicEnd;
+    CFMutableStringRef	cleanedName;
+
+    menuTitleLen = STRLEN(menu->dname);
+    name = mac_enc_to_cfstring(menu->dname, menuTitleLen);
+
+    if (name)
+    {
+	/* Simple mnemonic-removal algorithm, assumes single parenthesized
+	 * mnemonic character towards the end of the menu text */
+	mnemonicStart = CFStringFind(name, CFSTR("("), kCFCompareBackwards);
+	displayLen = CFStringGetLength(name);
+
+	if (mnemonicStart.location != kCFNotFound
+		&& (mnemonicStart.location + 2) < displayLen
+		&& CFStringGetCharacterAtIndex(name,
+		       mnemonicStart.location + 1) == (UniChar)menu->mnemonic)
+	{
+	    if (CFStringFindWithOptions(name, CFSTR(")"),
+			CFRangeMake(mnemonicStart.location + 1,
+			    displayLen - mnemonicStart.location - 1),
+			kCFCompareBackwards, &mnemonicEnd) &&
+		    (mnemonicStart.location + 2) == mnemonicEnd.location)
+	    {
+		cleanedName = CFStringCreateMutableCopy(NULL, 0, name);
+		if (cleanedName)
+		{
+		    CFStringDelete(cleanedName,
+			    CFRangeMake(mnemonicStart.location,
+				mnemonicEnd.location + 1 -
+				mnemonicStart.location));
+
+		    CFRelease(name);
+		    name = cleanedName;
+		}
+	    }
+	}
+    }
+
+    return name;
+}
+#endif
+
 /*
  * Convert a list of FSSpec aliases into a list of fullpathname
  * character strings.
@@ -1231,20 +1307,19 @@ HandleODocAE(const AppleEvent *theAEvent, AppleEvent *theReply, long refCon)
     /* Select the text if possible */
     if (gotPosition)
     {
-        VIsual_active = TRUE;
-        VIsual_select = FALSE;
-        if (thePosition.lineNum < 0)
+	VIsual_active = TRUE;
+	VIsual_select = FALSE;
+	VIsual = curwin->w_cursor;
+	if (thePosition.lineNum < 0)
 	{
-            VIsual_mode = 'v';
-            VIsual = curwin->w_cursor;
-            goto_byte(thePosition.endRange);
-        }
-        else
+	    VIsual_mode = 'v';
+	    goto_byte(thePosition.endRange);
+	}
+	else
 	{
-            VIsual_mode = 'V';
-            VIsual = curwin->w_cursor;
-            VIsual.col = 0;
-        }
+	    VIsual_mode = 'V';
+	    VIsual.col = 0;
+	}
     }
 #endif
     setcursor();
@@ -1541,25 +1616,47 @@ InstallFontPanelHandler()
  * Fill the buffer pointed to by outName with the name and size
  * of the font currently selected in the Font Panel.
  */
+#define FONT_STYLE_BUFFER_SIZE 32
     static void
 GetFontPanelSelection(char_u* outName)
 {
-    Str255 buf;
-    Boolean isBold = false, isItalic = false;
+    Str255	    buf;
+    ByteCount	    fontNameLen = 0;
+    ATSUFontID	    fid;
+    char_u	    styleString[FONT_STYLE_BUFFER_SIZE];
 
     if (!outName)
 	return;
 
-    (void)FMGetFontFamilyName(gFontPanelInfo.family, buf);
-    p2cstrcpy(outName, buf);
+    if (FMGetFontFamilyName(gFontPanelInfo.family, buf) == noErr)
+    {
+	/* Canonicalize localized font names */
+	if (FMGetFontFromFontFamilyInstance(gFontPanelInfo.family,
+		    gFontPanelInfo.style, &fid, NULL) != noErr)
+	    return;
 
-#if 0 /* TODO: enable when styles are supported in gui_mac_find_font() */
-    isBold = (gFontPanelInfo.style & bold);
-    isItalic = (gFontPanelInfo.style & italic);
-#endif
+	/* Request font name with Mac encoding (otherwise we could
+	 * get an unwanted utf-16 name) */
+	if (ATSUFindFontName(fid, kFontFullName, kFontMacintoshPlatform,
+		    kFontNoScriptCode, kFontNoLanguageCode,
+		    255, outName, &fontNameLen, NULL) != noErr)
+	    return;
 
-    sprintf(&outName[buf[0]], ":h%d%s%s", gFontPanelInfo.size,
-	    (isBold ? ":b" : ""), (isItalic ? ":i" : ""));
+	/* Only encode font size, because style (bold, italic, etc) is
+	 * already part of the font full name */
+	snprintf(styleString, FONT_STYLE_BUFFER_SIZE, ":h%d",
+		gFontPanelInfo.size/*,
+		((gFontPanelInfo.style & bold)!=0 ? ":b" : ""),
+		((gFontPanelInfo.style & italic)!=0 ? ":i" : ""),
+		((gFontPanelInfo.style & underline)!=0 ? ":u" : "")*/);
+
+	if ((fontNameLen + STRLEN(styleString)) < 255)
+	    STRCPY(outName + fontNameLen, styleString);
+    }
+    else
+    {
+	*outName = NULL;
+    }
 }
 #endif
 
@@ -2213,7 +2310,187 @@ gui_mac_doSuspendEvent(event)
 /*
  * Handle the key
  */
+#ifdef USE_CARBONKEYHANDLER
+# define INLINE_KEY_BUFFER_SIZE 80
+    static pascal OSStatus
+gui_mac_doKeyEventCarbon(EventHandlerCallRef nextHandler, EventRef theEvent,
+	void *data)
+{
+    /* Multibyte-friendly key event handler */
+    OSStatus	e = -1;
+    UInt32	actualSize;
+    UniChar	*text;
+    char_u	result[INLINE_KEY_BUFFER_SIZE];
+    short	len = 0;
+    UInt32	key_sym;
+    char	charcode;
+    int		key_char;
+    UInt32	modifiers;
+    size_t	encLen;
+    char_u	*to = NULL;
+    Boolean	isSpecial = FALSE;
+    int		i;
+
+    /* Mask the mouse (as per user setting) */
+    if (p_mh)
+	ObscureCursor();
+
+    do
+    {
+	if (noErr != GetEventParameter(theEvent, kEventParamTextInputSendText,
+		    typeUnicodeText, NULL, 0, &actualSize, NULL))
+	    break;
+
+	text = (UniChar *)alloc(actualSize);
+
+	if (text)
+	{
+	    do
+	    {
+		if (noErr != GetEventParameter(theEvent,
+			    kEventParamTextInputSendText,
+			    typeUnicodeText, NULL, actualSize, NULL, text))
+		    break;
+		EventRef keyEvent;
+		if (noErr != GetEventParameter(theEvent,
+			    kEventParamTextInputSendKeyboardEvent,
+			    typeEventRef, NULL, sizeof(EventRef), NULL, &keyEvent))
+		    break;
+		if (noErr != GetEventParameter(keyEvent,
+			    kEventParamKeyModifiers,
+			    typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers))
+		    break;
+		if (noErr != GetEventParameter(keyEvent,
+			    kEventParamKeyCode,
+			    typeUInt32, NULL, sizeof(UInt32), NULL, &key_sym))
+		    break;
+		if (noErr != GetEventParameter(keyEvent,
+			    kEventParamKeyMacCharCodes,
+			    typeChar, NULL, sizeof(char), NULL, &charcode))
+		    break;
+
+		key_char = charcode;
+
+		if (modifiers & controlKey)
+		{
+		    if ((modifiers & ~(controlKey|shiftKey)) == 0
+			    && (key_char == '2' || key_char == '6'))
+		    {
+			/* CTRL-^ and CTRL-@ don't work in the normal way. */
+			if (key_char == '2')
+			    key_char = Ctrl_AT;
+			else
+			    key_char = Ctrl_HAT;
+
+			text[0] = (UniChar)key_char;
+			modifiers = 0;
+		    }
+		}
+
+		if (modifiers & cmdKey)
+#ifndef USE_CMD_KEY
+		    break;  /* Let system handle Cmd+... */
+#else
+		{
+		    /* Intercept CMD-. */
+		    if (key_char == '.')
+			got_int = TRUE;
+
+		    /* Convert the modifiers */
+		    modifiers = EventModifiers2VimModifiers(modifiers);
+
+		    /* Following code to simplify and consolidate modifiers
+		     * taken liberally from gui_w48.c */
+
+		    key_char = simplify_key(key_char, (int *)&modifiers);
+
+		    /* remove SHIFT for keys that are already shifted, e.g.,
+		     * '(' and '*' */
+		    if (key_char < 0x100 &&
+			    !isalpha(key_char) && isprint(key_char))
+			modifiers &= ~MOD_MASK_SHIFT;
+
+		    /* Interpret META, include SHIFT, etc. */
+		    key_char = extract_modifiers(key_char, (int *)&modifiers);
+		    if (key_char == CSI)
+			key_char = K_CSI;
+
+		    if (modifiers)
+		    {
+			result[len++] = CSI;
+			result[len++] = KS_MODIFIER;
+			result[len++] = modifiers;
+		    }
+
+		    isSpecial = TRUE;
+		}
+#endif
+		else
+		{
+		    /* Find the special key (eg., for cursor keys) */
+		    if (!(actualSize > sizeof(UniChar)) &&
+			    ((text[0] < 0x20) || (text[0] == 0x7f)))
+		    {
+			for (i = 0; special_keys[i].key_sym != (KeySym)0; ++i)
+			    if (special_keys[i].key_sym == key_sym)
+			    {
+				key_char = TO_SPECIAL(special_keys[i].vim_code0,
+					special_keys[i].vim_code1);
+				key_char = simplify_key(key_char,
+					(int *)&modifiers);
+				isSpecial = TRUE;
+				break;
+			    }
+		    }
+		}
+
+		if (isSpecial && IS_SPECIAL(key_char))
+		{
+		    result[len++] = CSI;
+		    result[len++] = K_SECOND(key_char);
+		    result[len++] = K_THIRD(key_char);
+		}
+		else
+		{
+		    encLen = actualSize;
+		    to = mac_utf16_to_enc(text, actualSize, &encLen);
+		}
+
+		if (to)
+		{
+		    /* This is basically add_to_input_buf_csi() */
+		    for (i = 0; i < encLen && len < (INLINE_KEY_BUFFER_SIZE-1); ++i)
+		    {
+			result[len++] = to[i];
+			if (to[i] == CSI)
+			{
+			    result[len++] = KS_EXTRA;
+			    result[len++] = (int)KE_CSI;
+			}
+		    }
+		    vim_free(to);
+		}
 
+		add_to_input_buf(result, len);
+		e = noErr;
+	    }
+	    while (0);
+
+	    vim_free(text);
+	    if (e == noErr)
+	    {
+		/* Fake event to wake up WNE (required to get
+		 * key repeat working */
+		PostEvent(keyUp, 0);
+		return noErr;
+	    }
+	}
+    }
+    while (0);
+
+    return CallNextEventHandler(nextHandler, theEvent);
+}
+#else
     void
 gui_mac_doKeyEvent(EventRecord *theEvent)
 {
@@ -2387,6 +2664,7 @@ gui_mac_doKeyEvent(EventRecord *theEvent)
 
     add_to_input_buf(string, len);
 }
+#endif
 
 /*
  * Handle MouseClick
@@ -2664,11 +2942,12 @@ gui_mac_handle_event(event)
     /* Handle normal event */
     switch (event->what)
     {
+#ifndef USE_CARBONKEYHANDLER
 	case (keyDown):
 	case (autoKey):
 	    gui_mac_doKeyEvent(event);
 	    break;
-
+#endif
 	case (keyUp):
 	    /* We don't care about when the key get release */
 	    break;
@@ -2747,7 +3026,27 @@ gui_mac_find_font(font_name)
     pFontName[0] = STRLEN(font_name);
     *p = c;
 
+    /* Get the font name, minus the style suffix (:h, etc) */
+#if defined(MACOS_X) && defined(USE_CARBONIZED)
+    char_u fontName[256];
+    char_u *styleStart = vim_strchr(font_name, ':');
+    size_t fontNameLen = styleStart ? styleStart - font_name : STRLEN(fontName);
+    vim_strncpy(fontName, font_name, fontNameLen);
+
+    ATSUFontID fontRef;
+    FMFontStyle fontStyle;
+    font_id = 0;
+
+    if (ATSUFindFontFromName(&pFontName[1], pFontName[0], kFontFullName,
+		kFontMacintoshPlatform, kFontNoScriptCode, kFontNoLanguageCode,
+		&fontRef) == noErr)
+    {
+	if (FMGetFontFamilyInstanceFromFont(fontRef, &font_id, &fontStyle) != noErr)
+	    font_id = 0;
+    }
+#else
     GetFNum(pFontName, &font_id);
+#endif
 
     if (font_id == 0)
     {
@@ -2767,7 +3066,17 @@ gui_mac_find_font(font_name)
 	    }
 	}
 	if (changed)
+#if defined(MACOS_X) && defined(USE_CARBONIZED)
+	    if (ATSUFindFontFromName(&pFontName[1], pFontName[0],
+			kFontFullName, kFontNoPlatformCode, kFontNoScriptCode,
+			kFontNoLanguageCode, &fontRef) == noErr)
+	    {
+		if (FMGetFontFamilyInstanceFromFont(fontRef, &font_id, &fontStyle) != noErr)
+		    font_id = 0;
+	    }
+#else
 	    GetFNum(pFontName, &font_id);
+#endif
     }
 
 #else
@@ -2782,7 +3091,12 @@ gui_mac_find_font(font_name)
     {
 	/* Oups, the system font was it the one the user want */
 
+#if defined(MACOS_X) && defined(USE_CARBONIZED)
+	if (FMGetFontFamilyName(systemFont, systemFontname) != noErr)
+	    return NOFONT;
+#else
 	GetFontName(0, systemFontname);
+#endif
 	if (!EqualString(pFontName, systemFontname, false, false))
 	    return NOFONT;
     }
@@ -3079,6 +3393,15 @@ gui_mch_init()
     EventTypeSpec   eventTypeSpec;
     EventHandlerRef mouseWheelHandlerRef;
 #endif
+#ifdef USE_CARBONKEYHANDLER
+    EventHandlerRef keyEventHandlerRef;
+#endif
+
+#ifdef MACOS_X
+    if (Gestalt(gestaltSystemVersion, &gMacSystemVersion) != noErr)
+	gMacSystemVersion = 0x1000; /* Default to minimum sensible value */
+#endif
+
 #if 1
     InitCursor();
 
@@ -3238,9 +3561,24 @@ gui_mch_init()
     }
 #endif
 
+#ifdef USE_CARBONKEYHANDLER
+    eventTypeSpec.eventClass = kEventClassTextInput;
+    eventTypeSpec.eventKind = kEventUnicodeForKeyEvent;
+    keyEventHandlerUPP = NewEventHandlerUPP(gui_mac_doKeyEventCarbon);
+    if (noErr != InstallApplicationEventHandler(keyEventHandlerUPP, 1,
+		&eventTypeSpec, NULL, &keyEventHandlerRef))
+    {
+	keyEventHandlerRef = NULL;
+	DisposeEventHandlerUPP(keyEventHandlerUPP);
+	keyEventHandlerUPP = NULL;
+    }
+#endif
+
+/*
 #ifdef FEAT_MBYTE
-    set_option_value((char_u *)"termencoding", 0L, (char_u *)"macroman", 0);
+    set_option_value((char_u *)"encoding", 0L, (char_u *)"utf-8", 0);
 #endif
+*/
 
     /* TODO: Load bitmap if using TOOLBAR */
     return OK;
@@ -3290,11 +3628,21 @@ gui_mch_exit(int rc)
     /* TODO: find out all what is missing here? */
     DisposeRgn(cursorRgn);
 
+#ifdef USE_CARBONKEYHANDLER
+    if (keyEventHandlerUPP)
+	DisposeEventHandlerUPP(keyEventHandlerUPP);
+#endif
+
 #ifdef USE_MOUSEWHEEL
     if (mouseWheelHandlerUPP != NULL)
 	DisposeEventHandlerUPP(mouseWheelHandlerUPP);
 #endif
 
+#ifdef USE_ATSUI_DRAWING
+    if (gFontStyle)
+	ATSUDisposeStyle(gFontStyle);
+#endif
+
     /* Exit to shell? */
     exit(rc);
 }
@@ -3466,6 +3814,14 @@ gui_mch_init_font(font_name, fontset)
     GuiFont	font;
     char_u	used_font_name[512];
 
+#ifdef USE_ATSUI_DRAWING
+    if (gFontStyle == NULL)
+    {
+	if (ATSUCreateStyle(&gFontStyle) != noErr)
+	    gFontStyle = NULL;
+    }
+#endif
+
     if (font_name == NULL)
     {
 	/* First try to get the suggested font */
@@ -3523,6 +3879,54 @@ gui_mch_init_font(font_name, fontset)
     TextSize(font >> 16);
     TextFont(font & 0xFFFF);
 
+#ifdef USE_ATSUI_DRAWING
+    ATSUFontID			fontID;
+    Fixed			fontSize;
+    ATSStyleRenderingOptions	fontOptions;
+
+    if (gFontStyle)
+    {
+	fontID = font & 0xFFFF;
+	fontSize = Long2Fix(font >> 16);
+
+	/* No antialiasing by default (do not attempt to touch antialising
+	 * options on pre-Jaguar) */
+	fontOptions =
+#ifdef MACOS_X
+	    (gMacSystemVersion >= 0x1020) ?
+	    kATSStyleNoAntiAliasing :
+#endif
+	    kATSStyleNoOptions;
+
+	ATSUAttributeTag attribTags[] =
+	{
+	    kATSUFontTag, kATSUSizeTag, kATSUStyleRenderingOptionsTag,
+	    kATSUMaxATSUITagValue+1
+	};
+	ByteCount attribSizes[] =
+	{
+	    sizeof(ATSUFontID), sizeof(Fixed),
+	    sizeof(ATSStyleRenderingOptions), sizeof font
+	};
+	ATSUAttributeValuePtr attribValues[] =
+	{
+	    &fontID, &fontSize, &fontOptions, &font
+	};
+
+	/* Convert font id to ATSUFontID */
+	if (FMGetFontFromFontFamilyInstance(fontID, 0, &fontID, NULL) == noErr)
+	{
+	    if (ATSUSetAttributes(gFontStyle,
+			(sizeof attribTags)/sizeof(ATSUAttributeTag),
+			attribTags, attribSizes, attribValues) != noErr)
+	    {
+		ATSUDisposeStyle(gFontStyle);
+		gFontStyle = NULL;
+	    }
+	}
+    }
+#endif
+
     GetFontInfo(&font_info);
 
     gui.char_ascent = font_info.ascent;
@@ -3592,9 +3996,99 @@ gui_mch_get_fontname(font, name)
 gui_mch_set_font(font)
     GuiFont	font;
 {
-    /*
-     * TODO: maybe avoid set again the current font.
-     */
+#ifdef USE_ATSUI_DRAWING
+    GuiFont			currFont;
+    ByteCount			actualFontByteCount;
+    ATSUFontID			fontID;
+    Fixed			fontSize;
+    ATSStyleRenderingOptions	fontOptions;
+
+    if (gFontStyle)
+    {
+	/* Avoid setting same font again */
+	if (ATSUGetAttribute(gFontStyle, kATSUMaxATSUITagValue+1, sizeof font,
+		    &currFont, &actualFontByteCount) == noErr &&
+		actualFontByteCount == (sizeof font))
+	{
+	    if (currFont == font)
+		return;
+	}
+
+	fontID = font & 0xFFFF;
+	fontSize = Long2Fix(font >> 16);
+	/* Respect p_antialias setting only for wide font.
+	 * The reason for doing this at the moment is a bit complicated,
+	 * but it's mainly because a) latin (non-wide) aliased fonts
+	 * look bad in OS X 10.3.x and below (due to a bug in ATS), and
+	 * b) wide multibyte input does not suffer from that problem. */
+	fontOptions =
+#ifdef MACOS_X
+	    (p_antialias && (font == gui.wide_font)) ?
+	    kATSStyleNoOptions : kATSStyleNoAntiAliasing;
+#else
+	    kATSStyleNoOptions;
+#endif
+
+	ATSUAttributeTag attribTags[] =
+	{
+	    kATSUFontTag, kATSUSizeTag, kATSUStyleRenderingOptionsTag,
+	    kATSUMaxATSUITagValue+1
+	};
+	ByteCount attribSizes[] =
+	{
+	    sizeof(ATSUFontID), sizeof(Fixed),
+	    sizeof(ATSStyleRenderingOptions), sizeof font
+	};
+	ATSUAttributeValuePtr attribValues[] =
+	{
+	    &fontID, &fontSize, &fontOptions, &font
+	};
+
+	if (FMGetFontFromFontFamilyInstance(fontID, 0, &fontID, NULL) == noErr)
+	{
+	    if (ATSUSetAttributes(gFontStyle,
+			(sizeof attribTags)/sizeof(ATSUAttributeTag),
+			attribTags, attribSizes, attribValues) != noErr)
+	    {
+#ifndef NDEBUG
+		fprintf(stderr, "couldn't set font style\n");
+#endif
+		ATSUDisposeStyle(gFontStyle);
+		gFontStyle = NULL;
+	    }
+	}
+
+    }
+
+    if (!gIsFontFallbackSet)
+    {
+	/* Setup automatic font substitution. The user's guifontwide
+	 * is tried first, then the system tries other fonts. */
+/*
+	ATSUAttributeTag fallbackTags[] = { kATSULineFontFallbacksTag };
+	ByteCount fallbackSizes[] = { sizeof(ATSUFontFallbacks) };
+	ATSUCreateFontFallbacks(&gFontFallbacks);
+	ATSUSetObjFontFallbacks(gFontFallbacks, );
+*/
+	if (gui.wide_font)
+	{
+	    ATSUFontID fallbackFonts;
+	    gIsFontFallbackSet = TRUE;
+
+	    if (FMGetFontFromFontFamilyInstance(
+			(gui.wide_font & 0xFFFF),
+			0,
+			&fallbackFonts,
+			NULL) == noErr)
+	    {
+		ATSUSetFontFallbacks((sizeof fallbackFonts)/sizeof(ATSUFontID), &fallbackFonts, kATSUSequentialFallbacksPreferred);
+	    }
+/*
+	ATSUAttributeValuePtr fallbackValues[] = { };
+*/
+	}
+    }
+#endif
     TextSize(font >> 16);
     TextFont(font & 0xFFFF);
 }
@@ -3820,9 +4314,17 @@ gui_mch_draw_string(row, col, s, len, flags)
     int		flags;
 {
 #if defined(FEAT_GUI) && defined(MACOS_X)
+#ifndef USE_ATSUI_DRAWING
     SInt32	sys_version;
 #endif
+#endif
 #ifdef FEAT_MBYTE
+#ifdef USE_ATSUI_DRAWING
+    /* ATSUI requires utf-16 strings */
+    UniCharCount utf16_len;
+    UniChar *tofree = mac_enc_to_utf16(s, len, (size_t *)&utf16_len);
+    utf16_len /= sizeof(UniChar);
+#else
     char_u	*tofree = NULL;
 
     if (output_conv.vc_type != CONV_NONE)
@@ -3832,8 +4334,11 @@ gui_mch_draw_string(row, col, s, len, flags)
 	    s = tofree;
     }
 #endif
+#endif
 
 #if defined(FEAT_GUI) && defined(MACOS_X)
+    /* ATSUI automatically antialiases text */
+#ifndef USE_ATSUI_DRAWING
     /*
      * On OS X, try using Quartz-style text antialiasing.
      */
@@ -3845,8 +4350,9 @@ gui_mch_draw_string(row, col, s, len, flags)
 	/* Quartz antialiasing is available only in OS 10.2 and later. */
 	UInt32 qd_flags = (p_antialias ?
 			     kQDUseCGTextRendering | kQDUseCGTextMetrics : 0);
-	(void)SwapQDTextFlags(qd_flags);
+	QDSwapTextFlags(qd_flags);
     }
+#endif
 
     /*
      * When antialiasing we're using srcOr mode, we have to clear the block
@@ -3857,18 +4363,37 @@ gui_mch_draw_string(row, col, s, len, flags)
      * The following is like calling gui_mch_clear_block(row, col, row, col +
      * len - 1), but without setting the bg color to gui.back_pixel.
      */
+#ifdef USE_ATSUI_DRAWING
+    if ((flags & DRAW_TRANSP) == 0)
+#else
     if (((sys_version >= 0x1020 && p_antialias) || p_linespace != 0)
 	    && !(flags & DRAW_TRANSP))
+#endif
     {
 	Rect rc;
 
 	rc.left = FILL_X(col);
 	rc.top = FILL_Y(row);
+#ifdef FEAT_MBYTE
+	/* Multibyte computation taken from gui_w32.c */
+	if (has_mbyte)
+	{
+	    int cell_len = 0;
+	    int n;
+
+	    /* Compute the length in display cells. */
+	    for (n = 0; n < len; n += MB_BYTE2LEN(s[n]))
+		cell_len += (*mb_ptr2cells)(s + n);
+	    rc.right = FILL_X(col + cell_len);
+	}
+	else
+#endif
 	rc.right = FILL_X(col + len) + (col + len == Columns);
 	rc.bottom = FILL_Y(row + 1);
 	EraseRect(&rc);
     }
 
+#ifndef USE_ATSUI_DRAWING
     if (sys_version >= 0x1020 && p_antialias)
     {
 	StyleParameter face;
@@ -3887,6 +4412,7 @@ gui_mch_draw_string(row, col, s, len, flags)
 	DrawText((char*)s, 0, len);
     }
     else
+#endif
 #endif
     {
 	/* Use old-style, non-antialiased QuickDraw text rendering. */
@@ -3901,6 +4427,25 @@ gui_mch_draw_string(row, col, s, len, flags)
 	}
 
 	MoveTo(TEXT_X(col), TEXT_Y(row));
+#ifdef USE_ATSUI_DRAWING
+	ATSUTextLayout textLayout;
+
+	if (ATSUCreateTextLayoutWithTextPtr(tofree,
+		    kATSUFromTextBeginning, kATSUToTextEnd,
+		    utf16_len,
+		    (gFontStyle ? 1 : 0), &utf16_len,
+		    (gFontStyle ? &gFontStyle : NULL),
+		    &textLayout) == noErr)
+	{
+	    ATSUSetTransientFontMatching(textLayout, TRUE);
+
+	    ATSUDrawText(textLayout,
+		    kATSUFromTextBeginning, kATSUToTextEnd,
+		    kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc);
+
+	    ATSUDisposeTextLayout(textLayout);
+	}
+#else
 	DrawText((char *)s, 0, len);
 
 
@@ -3916,6 +4461,7 @@ gui_mch_draw_string(row, col, s, len, flags)
 	    MoveTo(FILL_X(col), FILL_Y(row + 1) - 1);
 	    LineTo(FILL_X(col + len) - 1, FILL_Y(row + 1) - 1);
 	}
+#endif
     }
 
 #ifdef FEAT_MBYTE
@@ -4021,14 +4567,16 @@ gui_mch_draw_hollow_cursor(color)
 {
     Rect rc;
 
-    gui_mch_set_fg_color(color);
-
     /*
      * Note: FrameRect() excludes right and bottom of rectangle.
      */
     rc.left = FILL_X(gui.col);
     rc.top = FILL_Y(gui.row);
     rc.right = rc.left + gui.char_width;
+#ifdef FEAT_MBYTE
+    if (mb_lefthalve(gui.row, gui.col))
+	rc.right += gui.char_width;
+#endif
     rc.bottom = rc.top + gui.char_height;
 
     gui_mch_set_fg_color(color);
@@ -4060,7 +4608,8 @@ gui_mch_draw_part_cursor(w, h, color)
 
     gui_mch_set_fg_color(color);
 
-    PaintRect(&rc);
+    FrameRect(&rc);
+//    PaintRect(&rc);
 }
 
 
@@ -4346,11 +4895,11 @@ clip_mch_request_selection(cbd)
 
     if (flavor == 0)
     {
-	error = GetScrapFlavorFlags(scrap, kScrapFlavorTypeText, &scrapFlags);
+	error = GetScrapFlavorFlags(scrap, kScrapFlavorTypeUnicode, &scrapFlags);
 	if (error != noErr)
 	    return;
 
-	error = GetScrapFlavorSize(scrap, kScrapFlavorTypeText, &scrapSize);
+	error = GetScrapFlavorSize(scrap, kScrapFlavorTypeUnicode, &scrapSize);
 	if (error != noErr)
 	    return;
     }
@@ -4374,7 +4923,7 @@ clip_mch_request_selection(cbd)
 	HLock(textOfClip);
 #ifdef USE_CARBONIZED
 	error = GetScrapFlavorData(scrap,
-		flavor ? VIMSCRAPFLAVOR : kScrapFlavorTypeText,
+		flavor ? VIMSCRAPFLAVOR : kScrapFlavorTypeUnicode,
 		&scrapSize, *textOfClip);
 #else
 	scrapSize = GetScrap(textOfClip, 'TEXT', &scrapOffset);
@@ -4387,7 +4936,11 @@ clip_mch_request_selection(cbd)
 	    type = (strchr(*textOfClip, '\r') != NULL) ? MLINE : MCHAR;
 
 	tempclip = lalloc(scrapSize + 1, TRUE);
+#if defined(FEAT_MBYTE) && defined(USE_CARBONIZED)
+	mch_memmove(tempclip, *textOfClip + flavor, scrapSize);
+#else
 	STRNCPY(tempclip, *textOfClip + flavor, scrapSize);
+#endif
 	tempclip[scrapSize] = 0;
 
 	searchCR = (char *)tempclip;
@@ -4400,19 +4953,15 @@ clip_mch_request_selection(cbd)
 
 	}
 
-#ifdef FEAT_MBYTE
-	if (input_conv.vc_type != CONV_NONE)
+#if defined(FEAT_MBYTE) && defined(USE_CARBONIZED)
+	/* Convert from utf-16 (clipboard) */
+	size_t encLen = 0;
+	char_u *to = mac_utf16_to_enc((UniChar *)tempclip, scrapSize, &encLen);
+	if (to)
 	{
-	    char_u	*to;
-	    int		l = scrapSize;
-
-	    to = string_convert(&input_conv, tempclip, &l);
-	    if (to != NULL)
-	    {
-		vim_free(tempclip);
-		tempclip = to;
-		scrapSize = l;
-	    }
+	    scrapSize = encLen;
+	    vim_free(tempclip);
+	    tempclip = to;
 	}
 #endif
 	clip_yank_selection(type, tempclip, scrapSize, cbd);
@@ -4471,19 +5020,14 @@ clip_mch_set_selection(cbd)
 
     type = clip_convert_selection(&str, (long_u *) &scrapSize, cbd);
 
-#ifdef FEAT_MBYTE
-    if (str != NULL && output_conv.vc_type != CONV_NONE)
+#if defined(FEAT_MBYTE) && defined(USE_CARBONIZED)
+    size_t utf16_len = 0;
+    UniChar *to = mac_enc_to_utf16(str, scrapSize, &utf16_len);
+    if (to)
     {
-	char_u	*to;
-	int	l = scrapSize;
-
-	to = string_convert(&output_conv, str, &l);
-	if (to != NULL)
-	{
-	    vim_free(str);
-	    str = to;
-	    scrapSize = l;
-	}
+	scrapSize = utf16_len;
+	vim_free(str);
+	str = (char_u *)to;
     }
 #endif
 
@@ -4504,9 +5048,9 @@ clip_mch_set_selection(cbd)
 
 #ifdef USE_CARBONIZED
 	**textOfClip = type;
-	STRNCPY(*textOfClip + 1, str, scrapSize);
+	mch_memmove(*textOfClip + 1, str, scrapSize);
 	GetCurrentScrap(&scrap);
-	PutScrapFlavor(scrap, kScrapFlavorTypeText, kScrapFlavorMaskNone,
+	PutScrapFlavor(scrap, kScrapFlavorTypeUnicode, kScrapFlavorMaskNone,
 		scrapSize, *textOfClip + 1);
 	PutScrapFlavor(scrap, VIMSCRAPFLAVOR, kScrapFlavorMaskNone,
 		scrapSize + 1, *textOfClip);
@@ -4599,7 +5143,11 @@ gui_mch_add_menu(menu, idx)
      */
     static long	 next_avail_id = 128;
     long	 menu_after_me = 0; /* Default to the end */
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+    CFStringRef name;
+#else
     char_u	*name;
+#endif
     short	 index;
     vimmenu_T	*parent = menu->parent;
     vimmenu_T	*brother = menu->next;
@@ -4625,13 +5173,21 @@ gui_mch_add_menu(menu, idx)
 	menu_after_me = hierMenu;
 
     /* Convert the name */
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+    name = menu_title_removing_mnemonic(menu);
+#else
     name = C2Pascal_save(menu->dname);
+#endif
     if (name == NULL)
 	return;
 
     /* Create the menu unless it's the help menu */
 #ifdef USE_HELPMENU
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+    if (menu->priority == 9999)
+#else
     if (STRNCMP(name, "\4Help", 5) == 0)
+#endif
     {
 	menu->submenu_id = kHMHelpMenuID;
 	menu->submenu_handle = gui.MacOSHelpMenu;
@@ -4644,7 +5200,12 @@ gui_mch_add_menu(menu, idx)
 	 * OSStatus SetMenuTitle(MenuRef, ConstStr255Param title);
 	 */
 	menu->submenu_id = next_avail_id;
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+	if (CreateNewMenu(menu->submenu_id, 0, (MenuRef *)&menu->submenu_handle) == noErr)
+	    SetMenuTitleWithCFString((MenuRef)menu->submenu_handle, name);
+#else
 	menu->submenu_handle = NewMenu(menu->submenu_id, name);
+#endif
 	next_avail_id++;
     }
 
@@ -4676,13 +5237,21 @@ gui_mch_add_menu(menu, idx)
 	 * to avoid special character recognition by InsertMenuItem
 	 */
 	InsertMenuItem(parent->submenu_handle, "\p ", idx); /* afterItem */
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+	SetMenuItemTextWithCFString(parent->submenu_handle, idx+1, name);
+#else
 	SetMenuItemText(parent->submenu_handle, idx+1, name);
+#endif
 	SetItemCmd(parent->submenu_handle, idx+1, 0x1B);
 	SetItemMark(parent->submenu_handle, idx+1, menu->submenu_id);
 	InsertMenu(menu->submenu_handle, hierMenu);
     }
 
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+    CFRelease(name);
+#else
     vim_free(name);
+#endif
 
 #if 0
     /* Done by Vim later on */
@@ -4698,7 +5267,11 @@ gui_mch_add_menu_item(menu, idx)
     vimmenu_T	*menu;
     int		idx;
 {
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+    CFStringRef name;
+#else
     char_u	*name;
+#endif
     vimmenu_T	*parent = menu->parent;
     int		menu_inserted;
 
@@ -4710,7 +5283,11 @@ gui_mch_add_menu_item(menu, idx)
        for older OS call GetMenuItemData (menu, item, isCommandID?, data) */
 
     /* Convert the name */
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+    name = menu_title_removing_mnemonic(menu);
+#else
     name = C2Pascal_save(menu->dname);
+#endif
 
     /* Where are just a menu item, so no handle, no id */
     menu->submenu_id = 0;
@@ -4796,15 +5373,23 @@ gui_mch_add_menu_item(menu, idx)
     if (!menu_inserted)
 	InsertMenuItem(parent->submenu_handle, "\p ", idx); /* afterItem */
     /* Set the menu item name. */
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+    SetMenuItemTextWithCFString(parent->submenu_handle, idx+1, name);
+#else
     SetMenuItemText(parent->submenu_handle, idx+1, name);
+#endif
 
 #if 0
     /* Called by Vim */
     DrawMenuBar();
 #endif
 
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+    CFRelease(name);
+#else
     /* TODO: Can name be freed? */
     vim_free(name);
+#endif
 }
 
     void
@@ -5811,17 +6396,33 @@ gui_mch_settitle(title, icon)
     /* TODO: Get vim to make sure maxlen (from p_titlelen) is smaller
      *       that 256. Even better get it to fit nicely in the titlebar.
      */
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+    CFStringRef windowTitle;
+    size_t	windowTitleLen;
+#else
     char_u   *pascalTitle;
+#endif
 
     if (title == NULL)		/* nothing to do */
 	return;
 
+#if defined(USE_CARBONIZED) && defined(FEAT_MBYTE)
+    windowTitleLen = STRLEN(title);
+    windowTitle  = mac_enc_to_cfstring(title, windowTitleLen);
+
+    if (windowTitle)
+    {
+	SetWindowTitleWithCFString(gui.VimWindow, windowTitle);
+	CFRelease(windowTitle);
+    }
+#else
     pascalTitle = C2Pascal_save(title);
     if (pascalTitle != NULL)
     {
 	SetWTitle(gui.VimWindow, pascalTitle);
 	vim_free(pascalTitle);
     }
+#endif
 }
 #endif
 
diff --git a/src/ops.c b/src/ops.c
index 7c426d147ee071bf74d69f0eb404c043a048fd53..78078c342408e59b3265a0b9b49ae766d6a10efe 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -1105,10 +1105,20 @@ do_execreg(regname, colon, addcr)
     int		remap;
 
     if (regname == '@')			/* repeat previous one */
+    {
+	if (lastc == NUL)
+	{
+	    EMSG(_("E748: No previously used register"));
+	    return FAIL;
+	}
 	regname = lastc;
+    }
 					/* check for valid regname */
     if (regname == '%' || regname == '#' || !valid_yank_reg(regname, FALSE))
+    {
+	emsg_invreg(regname);
 	return FAIL;
+    }
     lastc = regname;
 
 #ifdef FEAT_CLIPBOARD
@@ -3597,7 +3607,13 @@ error:
 	    else
 		curbuf->b_op_end.col = 0;
 
-	    if (flags & PUT_CURSEND)
+	    if (flags & PUT_CURSLINE)
+	    {
+		/* ":put": put cursor on last inserte line */
+		curwin->w_cursor.lnum = lnum;
+		beginline(BL_WHITE | BL_FIX);
+	    }
+	    else if (flags & PUT_CURSEND)
 	    {
 		/* put cursor after inserted text */
 		if (y_type == MLINE)
@@ -3616,7 +3632,7 @@ error:
 	    }
 	    else if (y_type == MLINE)
 	    {
-		/* put cursor onfirst non-blank in first inserted line */
+		/* put cursor on first non-blank in first inserted line */
 		curwin->w_cursor.col = 0;
 		if (dir == FORWARD)
 		    ++curwin->w_cursor.lnum;
@@ -5676,7 +5692,7 @@ write_reg_contents_ex(name, str, maxlen, must_append, yank_type, block_len)
 
     if (!valid_yank_reg(name, TRUE))	    /* check for valid reg name */
     {
-	EMSG2(_("E354: Invalid register name: '%s'"), transchar(name));
+	emsg_invreg(name);
 	return;
     }
 
diff --git a/src/option.c b/src/option.c
index 205b21c20b0cbc33c95bcbf02f6b66f0ee352948..4444b1f8954a595ac61c04e1da6666215d914cef 100644
--- a/src/option.c
+++ b/src/option.c
@@ -1723,8 +1723,8 @@ static struct vimoption
 #endif
 			    },
     {"prompt",	    NULL,   P_BOOL|P_VI_DEF,
-			    (char_u *)NULL, PV_NONE,
-			    {(char_u *)FALSE, (char_u *)0L}},
+			    (char_u *)&p_prompt, PV_NONE,
+			    {(char_u *)TRUE, (char_u *)0L}},
     {"quoteescape", "qe",   P_STRING|P_ALLOCED|P_VI_DEF,
 #ifdef FEAT_TEXTOBJ
 			    (char_u *)&p_qe, PV_QE,
@@ -1922,6 +1922,9 @@ static struct vimoption
 			    (char_u *)NULL, PV_NONE,
 #endif
 			    {(char_u *)FALSE, (char_u *)0L}},
+    {"shelltemp",   "stmp", P_BOOL,
+			    (char_u *)&p_stmp, PV_NONE,
+			    {(char_u *)FALSE, (char_u *)TRUE}},
     {"shelltype",   "st",   P_NUM|P_VI_DEF,
 #ifdef AMIGA
 			    (char_u *)&p_st, PV_NONE,
@@ -2501,7 +2504,7 @@ static char *(p_bsdir_values[]) = {"current", "last", "buffer", NULL};
 static char *(p_scbopt_values[]) = {"ver", "hor", "jump", NULL};
 #endif
 static char *(p_swb_values[]) = {"useopen", "split", NULL};
-static char *(p_debug_values[]) = {"msg", NULL};
+static char *(p_debug_values[]) = {"msg", "beep", NULL};
 #ifdef FEAT_VERTSPLIT
 static char *(p_ead_values[]) = {"both", "ver", "hor", NULL};
 #endif
@@ -2593,7 +2596,10 @@ set_init_1()
 
     /* Use POSIX compatibility when $VIM_POSIX is set. */
     if (mch_getenv((char_u *)"VIM_POSIX") != NULL)
+    {
 	set_string_default("cpo", (char_u *)CPO_ALL);
+	set_string_default("shm", (char_u *)"A");
+    }
 
     /*
      * Find default value for 'shell' option.
@@ -2885,6 +2891,23 @@ set_init_1()
 	    vim_setenv("LANG", buf);
 	}
     }
+# else
+#  ifdef MACOS
+    if (mch_getenv((char_u *)"LANG") == NULL)
+    {
+	char	buf[20];
+	if (LocaleRefGetPartString(NULL,
+		    kLocaleLanguageMask | kLocaleLanguageVariantMask |
+		    kLocaleRegionMask | kLocaleRegionVariantMask,
+		    sizeof buf, buf) == noErr && *buf)
+	{
+	    vim_setenv("LANG", buf);
+#   ifdef HAVE_LOCALE_H
+	    setlocale(LC_ALL, "");
+#   endif
+	}
+    }
+#  endif
 # endif
 
     /* enc_locale() will try to find the encoding of the current locale. */
@@ -3093,6 +3116,9 @@ set_init_2()
      * wrong when the window height changes.
      */
     set_number_default("scroll", (long_u)Rows >> 1);
+    idx = findoption((char_u *)"scroll");
+    if (!(options[idx].flags & P_WAS_SET))
+	set_option_default(idx, OPT_LOCAL, p_cp);
     comp_col();
 
     /*
@@ -3423,7 +3449,8 @@ do_set(arg, opt_flags)
     if (*arg == NUL)
     {
 	showoptions(0, opt_flags);
-	return OK;
+	did_show = TRUE;
+	goto theend;
     }
 
     while (*arg != NUL)		/* loop to process all options */
@@ -3446,12 +3473,16 @@ do_set(arg, opt_flags)
 		set_options_default(OPT_FREE | opt_flags);
 	    }
 	    else
+	    {
 		showoptions(1, opt_flags);
+		did_show = TRUE;
+	    }
 	}
 	else if (STRNCMP(arg, "termcap", 7) == 0 && !(opt_flags & OPT_MODELINE))
 	{
 	    showoptions(2, opt_flags);
 	    show_termcodes();
+	    did_show = TRUE;
 	    arg += 7;
 	}
 	else
@@ -4187,6 +4218,19 @@ skip:
 	arg = skipwhite(arg);
     }
 
+theend:
+    if (silent_mode && did_show)
+    {
+	/* After displaying option values in silent mode. */
+	silent_mode = FALSE;
+	info_message = TRUE;	/* use mch_msg(), not mch_errmsg() */
+	msg_putchar('\n');
+	cursor_on();		/* msg_start() switches it off */
+	out_flush();
+	silent_mode = TRUE;
+	info_message = FALSE;	/* use mch_msg(), not mch_errmsg() */
+    }
+
     return OK;
 }
 
@@ -7547,7 +7591,11 @@ showoneopt(p, opt_flags)
     struct vimoption	*p;
     int			opt_flags;	/* OPT_LOCAL or OPT_GLOBAL */
 {
-    char_u		*varp;
+    char_u	*varp;
+    int		save_silent = silent_mode;
+
+    silent_mode = FALSE;
+    info_message = TRUE;	/* use mch_msg(), not mch_errmsg() */
 
     varp = get_varp_scope(p, opt_flags);
 
@@ -7567,6 +7615,9 @@ showoneopt(p, opt_flags)
 	option_value2string(p, opt_flags);
 	msg_outtrans(NameBuff);
     }
+
+    silent_mode = save_silent;
+    info_message = FALSE;
 }
 
 /*
diff --git a/src/option.h b/src/option.h
index 674eb4e5d57887cdffdb25afce3648717db9ff6e..cd05f539e3d2caa0c280d709a072d209e9c3cbd4 100644
--- a/src/option.h
+++ b/src/option.h
@@ -174,10 +174,13 @@
 #define CPO_PARA	'{'	/* "{" is also a paragraph boundary */
 #define CPO_TSIZE	'|'	/* $LINES and $COLUMNS overrule term size */
 #define CPO_PRESERVE	'&'	/* keep swap file after :preserve */
+#define CPO_SUBPERCENT	'/'	/* % in :s string uses previous one */
+#define CPO_BACKSL	'\\'	/* \ is not special in [] */
+#define CPO_CHDIR	'.'	/* don't chdir if buffer is modified */
 /* default values for Vim, Vi and POSIX */
 #define CPO_VIM		"aABceFs"
 #define CPO_VI		"aAbBcCdDeEfFgHiIjJkKlLmMnoOpqrRsStuvwWxXyZ$!%*-+<>"
-#define CPO_ALL		"aAbBcCdDeEfFgHiIjJkKlLmMnoOpqrRsStuvwWxXyZ$!%*-+<>#{|&"
+#define CPO_ALL		"aAbBcCdDeEfFgHiIjJkKlLmMnoOpqrRsStuvwWxXyZ$!%*-+<>#{|&/\\."
 
 /* characters for p_ww option: */
 #define WW_ALL		"bshl<>[],~"
@@ -479,6 +482,7 @@ EXTERN char_u	*p_pfn;		/* 'printfont' */
 EXTERN char_u	*p_popt;	/* 'printoptions' */
 EXTERN char_u	*p_header;	/* 'printheader' */
 #endif
+EXTERN int	p_prompt;	/* 'prompt' */
 #ifdef FEAT_GUI
 EXTERN char_u	*p_guifont;	/* 'guifont' */
 # ifdef FEAT_XFONTSET
@@ -675,6 +679,7 @@ EXTERN char_u	*p_srr;		/* 'shellredir' */
 #ifdef AMIGA
 EXTERN long	p_st;		/* 'shelltype' */
 #endif
+EXTERN int	p_stmp;		/* 'shelltemp' */
 #ifdef BACKSLASH_IN_FILENAME
 EXTERN int	p_ssl;		/* 'shellslash' */
 #endif
diff --git a/src/os_mac_conv.c b/src/os_mac_conv.c
index 3f64e3da4cb6ae16c7616cbbed82578fc82279e1..68d46c0f2b2b582da8ad50df261927a29843f6dc 100644
--- a/src/os_mac_conv.c
+++ b/src/os_mac_conv.c
@@ -21,6 +21,21 @@ extern char_u *mac_string_convert __ARGS((char_u *ptr, int len, int *lenp, int f
 extern int macroman2enc __ARGS((char_u *ptr, long *sizep, long real_size));
 extern int enc2macroman __ARGS((char_u *from, size_t fromlen, char_u *to, int *tolenp, int maxtolen, char_u *rest, int *restlenp));
 
+extern void	    mac_conv_init __ARGS((void));
+extern void	    mac_conv_cleanup __ARGS((void));
+extern char_u	    *mac_utf16_to_enc __ARGS((UniChar *from, size_t fromLen, size_t *actualLen));
+extern UniChar	    *mac_enc_to_utf16 __ARGS((char_u *from, size_t fromLen, size_t *actualLen));
+extern CFStringRef  mac_enc_to_cfstring __ARGS((char_u *from, size_t fromLen));
+extern char_u	    *mac_precompose_path __ARGS((char_u *decompPath, size_t decompLen, size_t *precompLen));
+
+static char_u	    *mac_utf16_to_utf8 __ARGS((UniChar *from, size_t fromLen, size_t *actualLen));
+static UniChar	    *mac_utf8_to_utf16 __ARGS((char_u *from, size_t fromLen, size_t *actualLen));
+
+/* Converter for composing decomposed HFS+ file paths */
+static TECObjectRef gPathConverter;
+/* Converter used by mac_utf16_to_utf8 */
+static TECObjectRef gUTF16ToUTF8Converter;
+
 /*
  * A Mac version of string_convert_ext() for special cases.
  */
@@ -59,6 +74,8 @@ mac_string_convert(ptr, len, lenp, fail_on_error, from_enc, to_enc, unconvlenp)
 	*unconvlenp = 0;
     cfstr = CFStringCreateWithBytes(NULL, ptr, len, from, 0);
 
+    if(cfstr == NULL)
+	fprintf(stderr, "Encoding failed\n");
     /* When conversion failed, try excluding bytes from the end, helps when
      * there is an incomplete byte sequence.  Only do up to 6 bytes to avoid
      * looping a long time when there really is something unconvertable. */
@@ -70,6 +87,7 @@ mac_string_convert(ptr, len, lenp, fail_on_error, from_enc, to_enc, unconvlenp)
     }
     if (cfstr == NULL)
 	return NULL;
+
     if (to == kCFStringEncodingUTF8)
 	buflen = len * 6 + 1;
     else
@@ -80,6 +98,22 @@ mac_string_convert(ptr, len, lenp, fail_on_error, from_enc, to_enc, unconvlenp)
 	CFRelease(cfstr);
 	return NULL;
     }
+
+#if 0
+    CFRange convertRange = CFRangeMake(0, CFStringGetLength(cfstr));
+    /*  Determine output buffer size */
+    CFStringGetBytes(cfstr, convertRange, to, NULL, FALSE, NULL, 0, (CFIndex *)&buflen);
+    retval = (buflen > 0) ? alloc(buflen) : NULL;
+    if (retval == NULL) {
+	CFRelease(cfstr);
+	return NULL;
+    }
+
+    if (lenp)
+	*lenp = buflen / sizeof(char_u);
+
+    if (!CFStringGetBytes(cfstr, convertRange, to, NULL, FALSE, retval, buflen, NULL))
+#endif
     if (!CFStringGetCString(cfstr, retval, buflen, to))
     {
 	CFRelease(cfstr);
@@ -89,6 +123,7 @@ mac_string_convert(ptr, len, lenp, fail_on_error, from_enc, to_enc, unconvlenp)
 	    return NULL;
 	}
 
+	fprintf(stderr, "Trying char-by-char conversion...\n");
 	/* conversion failed for the whole string, but maybe it will work
 	 * for each character */
 	for (d = retval, in = 0, out = 0; in < len && out < buflen - 1;)
@@ -128,6 +163,7 @@ mac_string_convert(ptr, len, lenp, fail_on_error, from_enc, to_enc, unconvlenp)
     CFRelease(cfstr);
     if (lenp != NULL)
 	*lenp = strlen(retval);
+
     return retval;
 }
 
@@ -230,4 +266,291 @@ enc2macroman(from, fromlen, to, tolenp, maxtolen, rest, restlenp)
     return OK;
 }
 
+/*
+ * Initializes text converters
+ */
+    void
+mac_conv_init()
+{
+    TextEncoding    utf8_encoding;
+    TextEncoding    utf8_hfsplus_encoding;
+    TextEncoding    utf8_canon_encoding;
+    TextEncoding    utf16_encoding;
+
+    utf8_encoding = CreateTextEncoding(kTextEncodingUnicodeDefault,
+	    kTextEncodingDefaultVariant, kUnicodeUTF8Format);
+    utf8_hfsplus_encoding = CreateTextEncoding(kTextEncodingUnicodeDefault,
+	    kUnicodeHFSPlusCompVariant, kUnicodeUTF8Format);
+    utf8_canon_encoding = CreateTextEncoding(kTextEncodingUnicodeDefault,
+	    kUnicodeCanonicalCompVariant, kUnicodeUTF8Format);
+    utf16_encoding = CreateTextEncoding(kTextEncodingUnicodeDefault,
+	    kTextEncodingDefaultVariant, kUnicode16BitFormat);
+
+    if (TECCreateConverter(&gPathConverter, utf8_encoding,
+		utf8_hfsplus_encoding) != noErr)
+	gPathConverter = NULL;
+
+    if (TECCreateConverter(&gUTF16ToUTF8Converter, utf16_encoding,
+		utf8_canon_encoding) != noErr)
+	gUTF16ToUTF8Converter = NULL;
+}
+
+/*
+ * Destroys text converters
+ */
+    void
+mac_conv_cleanup()
+{
+    if (gUTF16ToUTF8Converter)
+    {
+	TECDisposeConverter(gUTF16ToUTF8Converter);
+	gUTF16ToUTF8Converter = NULL;
+    }
+
+    if (gPathConverter)
+    {
+	TECDisposeConverter(gPathConverter);
+	gPathConverter = NULL;
+    }
+}
+
+/*
+ * Conversion from UTF-16 UniChars to 'encoding'
+ */
+    char_u *
+mac_utf16_to_enc(from, fromLen, actualLen)
+    UniChar *from;
+    size_t fromLen;
+    size_t *actualLen;
+{
+    /* Following code borrows somewhat from os_mswin.c */
+    vimconv_T	conv;
+    size_t      utf8_len;
+    char_u      *utf8_str;
+    char_u      *result = NULL;
+
+    /* Convert to utf-8 first, works better with iconv */
+    utf8_len = 0;
+    utf8_str = mac_utf16_to_utf8(from, fromLen, &utf8_len);
+
+    if (utf8_str)
+    {
+	/* We might be called before we have p_enc set up. */
+	conv.vc_type = CONV_NONE;
+
+	/* If encoding (p_enc) is any unicode, it is actually in utf-8 (vim
+	 * internal unicode is always utf-8) so don't convert in such cases */
+
+	if ((enc_canon_props(p_enc) & ENC_UNICODE) == 0)
+	    convert_setup(&conv, (char_u *)"utf-8",
+		    p_enc? p_enc: (char_u *)"macroman");
+	if (conv.vc_type == CONV_NONE)
+	{
+	    /* p_enc is utf-8, so we're done. */
+	    result = utf8_str;
+	}
+	else
+	{
+	    result = string_convert(&conv, utf8_str, (int *)&utf8_len);
+	    vim_free(utf8_str);
+	}
+
+	convert_setup(&conv, NULL, NULL);
+
+	if (actualLen)
+	    *actualLen = utf8_len;
+    }
+    else if (actualLen)
+	*actualLen = 0;
+
+    return result;
+}
+
+/*
+ * Conversion from 'encoding' to UTF-16 UniChars
+ */
+    UniChar *
+mac_enc_to_utf16(from, fromLen, actualLen)
+    char_u *from;
+    size_t fromLen;
+    size_t *actualLen;
+{
+    /* Following code borrows somewhat from os_mswin.c */
+    vimconv_T	conv;
+    size_t      utf8_len;
+    char_u      *utf8_str;
+    UniChar     *result = NULL;
+    Boolean     should_free_utf8 = FALSE;
+
+    do
+    {
+	/* Use MacRoman by default, we might be called before we have p_enc
+	 * set up.  Convert to utf-8 first, works better with iconv().  Does
+	 * nothing if 'encoding' is "utf-8". */
+	conv.vc_type = CONV_NONE;
+	if ((enc_canon_props(p_enc) & ENC_UNICODE) == 0 &&
+		convert_setup(&conv, p_enc ? p_enc : (char_u *)"macroman",
+		    (char_u *)"utf-8") == FAIL)
+	    break;
+
+	if (conv.vc_type != CONV_NONE)
+	{
+	    utf8_len = fromLen;
+	    utf8_str = string_convert(&conv, from, (int *)&utf8_len);
+	    should_free_utf8 = TRUE;
+	}
+	else
+	{
+	    utf8_str = from;
+	    utf8_len = fromLen;
+	}
+
+	if (utf8_str == NULL)
+	    break;
+
+	convert_setup(&conv, NULL, NULL);
+
+	result = mac_utf8_to_utf16(utf8_str, utf8_len, actualLen);
+
+	if (should_free_utf8)
+	    vim_free(utf8_str);
+	return result;
+    }
+    while (0);
+
+    if (actualLen)
+	*actualLen = 0;
+
+    return result;
+}
+
+/*
+ * Converts from UTF-16 UniChars to CFString
+ */
+    CFStringRef
+mac_enc_to_cfstring(from, fromLen)
+    char_u  *from;
+    size_t  fromLen;
+{
+    UniChar	*utf16_str;
+    size_t	utf16_len;
+    CFStringRef	result = NULL;
+
+    utf16_str = mac_enc_to_utf16(from, fromLen, &utf16_len);
+    if (utf16_str)
+    {
+	result = CFStringCreateWithCharacters(NULL, utf16_str, utf16_len/sizeof(UniChar));
+	vim_free(utf16_str);
+    }
+
+    return result;
+}
+
+/*
+ * Converts a decomposed HFS+ UTF-8 path to precomposed UTF-8
+ */
+    char_u *
+mac_precompose_path(decompPath, decompLen, precompLen)
+    char_u  *decompPath;
+    size_t  decompLen;
+    size_t  *precompLen;
+{
+    char_u  *result = NULL;
+    size_t  actualLen = 0;
+
+    if (gPathConverter)
+    {
+	result = alloc(decompLen);
+	if (result)
+	{
+	    if (TECConvertText(gPathConverter, decompPath,
+			decompLen, &decompLen, result,
+			decompLen, &actualLen) != noErr)
+	    {
+		vim_free(result);
+		result = NULL;
+	    }
+	}
+    }
+
+    if (precompLen)
+	*precompLen = actualLen;
+
+    return result;
+}
+
+/*
+ * Converts from UTF-16 UniChars to precomposed UTF-8
+ */
+    char_u *
+mac_utf16_to_utf8(from, fromLen, actualLen)
+    UniChar *from;
+    size_t fromLen;
+    size_t *actualLen;
+{
+    ByteCount		utf8_len;
+    ByteCount		inputRead;
+    char_u		*result;
+
+    if (gUTF16ToUTF8Converter)
+    {
+	result = alloc(fromLen * 6 + 1);
+	if (result && TECConvertText(gUTF16ToUTF8Converter, (ConstTextPtr)from,
+		    fromLen, &inputRead, result,
+		    (fromLen*6+1)*sizeof(char_u), &utf8_len) == noErr)
+	{
+	    TECFlushText(gUTF16ToUTF8Converter, result, (fromLen*6+1)*sizeof(char_u), &inputRead);
+	    utf8_len += inputRead;
+	}
+	else
+	{
+	    vim_free(result);
+	    result = NULL;
+	}
+    }
+    else
+    {
+	result = NULL;
+    }
+
+    if (actualLen)
+	*actualLen = result ? utf8_len : 0;
+
+    return result;
+}
+
+/*
+ * Converts from UTF-8 to UTF-16 UniChars
+ */
+    UniChar *
+mac_utf8_to_utf16(from, fromLen, actualLen)
+    char_u *from;
+    size_t fromLen;
+    size_t *actualLen;
+{
+    CFStringRef  utf8_str;
+    CFRange      convertRange;
+    UniChar      *result = NULL;
+
+    utf8_str = CFStringCreateWithBytes(NULL, from, fromLen,
+	    kCFStringEncodingUTF8, FALSE);
+
+    if (utf8_str == NULL) {
+	if (actualLen)
+	    *actualLen = 0;
+	return NULL;
+    }
+
+    convertRange = CFRangeMake(0, CFStringGetLength(utf8_str));
+    result = (UniChar *)alloc(convertRange.length * sizeof(UniChar));
+
+    CFStringGetCharacters(utf8_str, convertRange, result);
+
+    CFRelease(utf8_str);
+
+    if (actualLen)
+	*actualLen = convertRange.length * sizeof(UniChar);
+
+    return result;
+}
 #endif /* FEAT_MBYTE */
diff --git a/src/po/Make_mvc.mak b/src/po/Make_mvc.mak
index b69b5abc5941aadf22c7a0fb4beb6542413b3935..c902614acb627aa3b85518fface52483eced0a9c 100644
--- a/src/po/Make_mvc.mak
+++ b/src/po/Make_mvc.mak
@@ -6,9 +6,9 @@
 # Please read README_mvc.txt before using this file.
 #
 
-LANGUAGES =	af ca cs de en_GB es fr it ja ko no pl ru sk sv uk zh_TW \
+LANGUAGES =	af ca cs de en_GB es fr ga it ja ko no pl ru sk sv uk zh_TW \
 		zh_TW.UTF-8 zh_CN zh_CN.UTF-8
-MOFILES =	af.mo ca.mo cs.mo de.mo en_GB.mo es.mo fr.mo it.mo ja.mo \
+MOFILES =	af.mo ca.mo cs.mo de.mo en_GB.mo es.mo fr.mo ga.mo it.mo ja.mo \
 		ko.mo no.mo pl.mo ru.mo sk.mo sv.mo uk.mo \
 		zh_TW.mo zh_TW.UTF-8.mo zh_CN.mo zh_CN.UTF-8.mo
 
diff --git a/src/proto/eval.pro b/src/proto/eval.pro
index d85ab2ef0646d5c6b55210956c34919c1b07a531..b4300396727967e25ef050c452e07d5c4ea69104 100644
--- a/src/proto/eval.pro
+++ b/src/proto/eval.pro
@@ -6,6 +6,9 @@ int *func_dbg_tick __ARGS((void *cookie));
 int func_level __ARGS((void *cookie));
 int current_func_returned __ARGS((void));
 void set_internal_string_var __ARGS((char_u *name, char_u *value));
+int var_redir_start __ARGS((char_u *name, int append));
+void var_redir_str __ARGS((char_u *value, int len));
+void var_redir_stop __ARGS((void));
 int eval_charconvert __ARGS((char_u *enc_from, char_u *enc_to, char_u *fname_from, char_u *fname_to));
 int eval_printexpr __ARGS((char_u *fname, char_u *args));
 void eval_diff __ARGS((char_u *origfile, char_u *newfile, char_u *outfile));
diff --git a/src/screen.c b/src/screen.c
index 6271b84c7242998507a8ca1f4b5ed9def86077e3..d3c9552e1ca8bcddb27fa626ce42e6fea52a0a8d 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -6846,18 +6846,6 @@ screen_start()
     screen_cur_row = screen_cur_col = 9999;
 }
 
-/*
- * Note that the cursor has gone down to the next line, column 0.
- * Used for Ex mode.
- */
-    void
-screen_down()
-{
-    screen_cur_col = 0;
-    if (screen_cur_row < Rows - 1)
-	++screen_cur_row;
-}
-
 /*
  * Move the cursor to position "row","col" in the screen.
  * This tries to find the most efficient way to move, minimizing the number of
diff --git a/src/search.c b/src/search.c
index 8520282a94a73a150a4e59bd26db8847a3458272..c9773b5876a306f545ede30213d766f75b288a1b 100644
--- a/src/search.c
+++ b/src/search.c
@@ -4715,7 +4715,7 @@ show_pat_in_path(line, type, did_show, action, fp, lnum, count)
 	    msg_puts_attr(IObuff, hl_attr(HLF_N));
 	    MSG_PUTS(" ");
 	}
-	msg_prt_line(line);
+	msg_prt_line(line, FALSE);
 	out_flush();			/* show one line at a time */
 
 	/* Definition continues until line that doesn't end with '\' */
diff --git a/src/structs.h b/src/structs.h
index 92a8428f10a4866499c097316b062cdc03732876..71c692ad15bfeae94fa5e9f89a8e35ad7c494cd6 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -307,7 +307,8 @@ struct m_block
 {
     mblock_T	*mb_next;	/* pointer to next allocated block */
     size_t	mb_size;	/* total size of all chunks in this block */
-    minfo_T	mb_info;	/* head of free chuck list for this block */
+    size_t	mb_maxsize;	/* size of largest fee chunk */
+    minfo_T	mb_info;	/* head of free chunk list for this block */
 };
 
 /*
@@ -1211,6 +1212,7 @@ struct file_buffer
     minfo_T	*b_m_search;	/* pointer to chunk before previously
 				   allocated/freed chunk */
     mblock_T	*b_mb_current;	/* block where m_search points in */
+
 #ifdef FEAT_INS_EXPAND
     int		b_scanned;	/* ^N/^P have scanned this buffer */
 #endif
diff --git a/src/syntax.c b/src/syntax.c
index bf9360f47ea1034d1a7b9d3ddaca5f7675ae9583..5d08afac09db53060d1e506d7ecee21b7eff5aa1 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -4397,8 +4397,19 @@ syn_cmd_keyword(eap, syncing)
 			add_keyword(kw, syn_id, syn_opt_arg.flags,
 						     syn_opt_arg.cont_in_list,
 						       syn_opt_arg.next_list);
-			if (p == NULL || p[1] == NUL || p[1] == ']')
+			if (p == NULL)
 			    break;
+			if (p[1] == NUL)
+			{
+			    EMSG2(_("E747: Missing ']': %s"), kw);
+			    kw = p + 2;		/* skip over the NUL */
+			    break;
+			}
+			if (p[1] == ']')
+			{
+			    kw = p + 1;		/* skip over the "]" */
+			    break;
+			}
 #ifdef FEAT_MBYTE
 			if (has_mbyte)
 			{
@@ -4418,6 +4429,8 @@ syn_cmd_keyword(eap, syncing)
 	    }
 
 	    vim_free(keyword_copy);
+	    vim_free(syn_opt_arg.cont_in_list);
+	    vim_free(syn_opt_arg.next_list);
 	}
     }
 
@@ -4426,8 +4439,6 @@ syn_cmd_keyword(eap, syncing)
     else
 	EMSG2(_(e_invarg2), arg);
 
-    vim_free(syn_opt_arg.cont_in_list);
-    vim_free(syn_opt_arg.next_list);
     redraw_curbuf_later(NOT_VALID);
     syn_stack_free_all(curbuf);		/* Need to recompute all syntax. */
 }
diff --git a/src/term.c b/src/term.c
index 386b05cf5b5ce36bae29f89f6c2625e29b63b532..12c506ab27bc195e09b641899161f46bfb02f05b 100644
--- a/src/term.c
+++ b/src/term.c
@@ -1590,6 +1590,10 @@ set_termname(term)
     char_u	*error_msg = NULL;
     char_u	*bs_p, *del_p;
 
+    /* In silect mode (ex -s) we don't use the 'term' option. */
+    if (silent_mode)
+	return OK;
+
     detected_8bit = FALSE;		/* reset 8-bit detection */
 
     if (term_is_builtin(term))
@@ -3146,10 +3150,6 @@ settmode(tmode)
 
     if (full_screen)
     {
-	/* In Ex mode, never set to RAW */
-	if (exmode_active == EXMODE_NORMAL)
-	    tmode = TMODE_COOK;
-
 	/*
 	 * When returning after calling a shell we want to really set the
 	 * terminal to raw mode, even though we think it already is, because
diff --git a/src/undo.c b/src/undo.c
index bdba903d8893bc4c844939e8bc396188f6d39eeb..4675d997268f447c673dc3a8f077a86cc7fc2408 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -41,24 +41,33 @@
  * curbuf->b_u_curhead points to the header of the last undo (the next redo),
  * or is NULL if nothing has been undone.
  *
- * All data is allocated with u_alloc_line(), thus it will be freed as soon as
- * we switch files!
+ * All data is allocated with U_ALLOC_LINE(), it will be freed as soon as the
+ * buffer is unloaded.
  */
 
 #include "vim.h"
 
+/* See below: use malloc()/free() for memory management. */
+#define U_USE_MALLOC 1
+
 static u_entry_T *u_get_headentry __ARGS((void));
 static void u_getbot __ARGS((void));
 static int u_savecommon __ARGS((linenr_T, linenr_T, linenr_T));
 static void u_doit __ARGS((int count));
 static void u_undoredo __ARGS((void));
 static void u_undo_end __ARGS((void));
-static void u_freelist __ARGS((struct u_header *));
+static void u_freelist __ARGS((buf_T *buf, struct u_header *));
 static void u_freeentry __ARGS((u_entry_T *, long));
 
-static char_u *u_blockalloc __ARGS((long_u));
-static void u_free_line __ARGS((char_u *, int keep));
-static char_u *u_alloc_line __ARGS((unsigned));
+#ifdef U_USE_MALLOC
+# define U_FREE_LINE(ptr) vim_free(ptr)
+# define U_ALLOC_LINE(size) lalloc((long_u)((size) + 1), FALSE)
+#else
+static void u_free_line __ARGS((char_u *ptr, int keep));
+static char_u *u_alloc_line __ARGS((unsigned size));
+# define U_FREE_LINE(ptr) u_free_line((ptr), FALSE)
+# define U_ALLOC_LINE(size) u_alloc_line(size)
+#endif
 static char_u *u_save_line __ARGS((linenr_T));
 
 static long	u_newcount, u_oldcount;
@@ -227,13 +236,13 @@ u_savecommon(top, bot, newbot)
 	 * including curbuf->b_u_curhead
 	 */
 	while (curbuf->b_u_curhead != NULL)
-	    u_freelist(curbuf->b_u_newhead);
+	    u_freelist(curbuf, curbuf->b_u_newhead);
 
 	/*
 	 * free headers to keep the size right
 	 */
 	while (curbuf->b_u_numhead > p_ul && curbuf->b_u_oldhead != NULL)
-	    u_freelist(curbuf->b_u_oldhead);
+	    u_freelist(curbuf, curbuf->b_u_oldhead);
 
 	if (p_ul < 0)		/* no undo at all */
 	{
@@ -244,7 +253,7 @@ u_savecommon(top, bot, newbot)
 	/*
 	 * make a new header entry
 	 */
-	uhp = (struct u_header *)u_alloc_line((unsigned)
+	uhp = (struct u_header *)U_ALLOC_LINE((unsigned)
 						     sizeof(struct u_header));
 	if (uhp == NULL)
 	    goto nomem;
@@ -364,7 +373,7 @@ u_savecommon(top, bot, newbot)
     /*
      * add lines in front of entry list
      */
-    uep = (u_entry_T *)u_alloc_line((unsigned)sizeof(u_entry_T));
+    uep = (u_entry_T *)U_ALLOC_LINE((unsigned)sizeof(u_entry_T));
     if (uep == NULL)
 	goto nomem;
 
@@ -384,9 +393,9 @@ u_savecommon(top, bot, newbot)
 	curbuf->b_u_newhead->uh_getbot_entry = uep;
     }
 
-    if (size)
+    if (size > 0)
     {
-	if ((uep->ue_array = (char_u **)u_alloc_line(
+	if ((uep->ue_array = (char_u **)U_ALLOC_LINE(
 				(unsigned)(sizeof(char_u *) * size))) == NULL)
 	{
 	    u_freeentry(uep, 0L);
@@ -609,9 +618,9 @@ u_undoredo()
 	empty_buffer = FALSE;
 
 	/* delete the lines between top and bot and save them in newarray */
-	if (oldsize)
+	if (oldsize > 0)
 	{
-	    if ((newarray = (char_u **)u_alloc_line(
+	    if ((newarray = (char_u **)U_ALLOC_LINE(
 			    (unsigned)(sizeof(char_u *) * oldsize))) == NULL)
 	    {
 		do_outofmem_msg((long_u)(sizeof(char_u *) * oldsize));
@@ -654,9 +663,9 @@ u_undoredo()
 		    ml_replace((linenr_T)1, uep->ue_array[i], TRUE);
 		else
 		    ml_append(lnum, uep->ue_array[i], (colnr_T)0, FALSE);
-		u_free_line(uep->ue_array[i], FALSE);
+		U_FREE_LINE(uep->ue_array[i]);
 	    }
-	    u_free_line((char_u *)uep->ue_array, FALSE);
+	    U_FREE_LINE((char_u *)uep->ue_array);
 	}
 
 	/* adjust marks */
@@ -870,7 +879,8 @@ u_getbot()
  * u_freelist: free one entry list and adjust the pointers
  */
     static void
-u_freelist(uhp)
+u_freelist(buf, uhp)
+    buf_T	    *buf;
     struct u_header *uhp;
 {
     u_entry_T	*uep, *nuep;
@@ -881,21 +891,21 @@ u_freelist(uhp)
 	u_freeentry(uep, uep->ue_size);
     }
 
-    if (curbuf->b_u_curhead == uhp)
-	curbuf->b_u_curhead = NULL;
+    if (buf->b_u_curhead == uhp)
+	buf->b_u_curhead = NULL;
 
     if (uhp->uh_next == NULL)
-	curbuf->b_u_oldhead = uhp->uh_prev;
+	buf->b_u_oldhead = uhp->uh_prev;
     else
 	uhp->uh_next->uh_prev = uhp->uh_prev;
 
     if (uhp->uh_prev == NULL)
-	curbuf->b_u_newhead = uhp->uh_next;
+	buf->b_u_newhead = uhp->uh_next;
     else
 	uhp->uh_prev->uh_next = uhp->uh_next;
 
-    u_free_line((char_u *)uhp, FALSE);
-    --curbuf->b_u_numhead;
+    U_FREE_LINE((char_u *)uhp);
+    --buf->b_u_numhead;
 }
 
 /*
@@ -907,8 +917,8 @@ u_freeentry(uep, n)
     long	    n;
 {
     while (n)
-	u_free_line(uep->ue_array[--n], FALSE);
-    u_free_line((char_u *)uep, FALSE);
+	U_FREE_LINE(uep->ue_array[--n]);
+    U_FREE_LINE((char_u *)uep);
 }
 
 /*
@@ -955,7 +965,7 @@ u_clearline()
 {
     if (curbuf->b_u_line_ptr != NULL)
     {
-	u_free_line(curbuf->b_u_line_ptr, FALSE);
+	U_FREE_LINE(curbuf->b_u_line_ptr);
 	curbuf->b_u_line_ptr = NULL;
 	curbuf->b_u_line_lnum = 0;
     }
@@ -993,7 +1003,7 @@ u_undoline()
     }
     ml_replace(curbuf->b_u_line_lnum, curbuf->b_u_line_ptr, TRUE);
     changed_bytes(curbuf->b_u_line_lnum, 0);
-    u_free_line(curbuf->b_u_line_ptr, FALSE);
+    U_FREE_LINE(curbuf->b_u_line_ptr);
     curbuf->b_u_line_ptr = oldp;
 
     t = curbuf->b_u_line_colnr;
@@ -1004,7 +1014,40 @@ u_undoline()
 }
 
 /*
- * storage allocation for the undo lines and blocks of the current file
+ * There are two implementations of the memory management for undo:
+ * 1. Use the standard malloc()/free() functions.
+ *    This should be fast for allocating memory, but when a buffer is
+ *    abandoned every single allocated chunk must be freed, which may be slow.
+ * 2. Allocate larger blocks of memory and keep track of chunks ourselves.
+ *    This is fast for abandoning, but the use of linked lists is slow for
+ *    finding a free chunk.  Esp. when a lot of lines are changed or deleted.
+ * A bit of profiling showed that the first method is faster, especially when
+ * making a large number of changes, under the condition that malloc()/free()
+ * is implemented efficiently.
+ */
+#ifdef U_USE_MALLOC
+/*
+ * Version of undo memory allocation using malloc()/free()
+ *
+ * U_FREE_LINE() and U_ALLOC_LINE() are macros that invoke vim_free() and
+ * lalloc() directly.
+ */
+
+/*
+ * Free all allocated memory blocks for the buffer 'buf'.
+ */
+    void
+u_blockfree(buf)
+    buf_T	*buf;
+{
+    while (buf->b_u_newhead != NULL)
+	u_freelist(buf, buf->b_u_newhead);
+}
+
+#else
+/*
+ * Storage allocation for the undo lines and blocks of the current file.
+ * Version where Vim keeps track of the available memory.
  */
 
 /*
@@ -1071,6 +1114,8 @@ u_undoline()
 # define M_OFFSET (sizeof(short_u))
 #endif
 
+static char_u *u_blockalloc __ARGS((long_u));
+
 /*
  * Allocate a block of memory and link it in the allocated block list.
  */
@@ -1092,6 +1137,7 @@ u_blockalloc(size)
 	    ;
 	p->mb_next = next;		/* link in block list */
 	p->mb_size = size;
+	p->mb_maxsize = 0;		/* nothing free yet */
 	mp->mb_next = p;
 	p->mb_info.m_next = NULL;	/* clear free list */
 	p->mb_info.m_size = 0;
@@ -1135,6 +1181,7 @@ u_free_line(ptr, keep)
     minfo_T	*mp;
     mblock_T	*nextb;
     mblock_T	*prevb;
+    long_u	maxsize;
 
     if (ptr == NULL || ptr == IObuff)
 	return;	/* illegal address can happen in out-of-memory situations */
@@ -1212,11 +1259,13 @@ u_free_line(ptr, keep)
     }
     else
 	mp->m_next = next;
+    maxsize = mp->m_size;
 
     /* if *curr and *mp are concatenated, join them */
     if (prev != NULL && (char_u *)curr + curr->m_size == (char_u *)mp)
     {
 	curr->m_size += mp->m_size;
+	maxsize = curr->m_size;
 	curr->m_next = mp->m_next;
 	curbuf->b_m_search = prev;
     }
@@ -1244,6 +1293,8 @@ u_free_line(ptr, keep)
 	curbuf->b_mb_current = NULL;
 	curbuf->b_m_search = NULL;
     }
+    else if (curbuf->b_mb_current->mb_maxsize < maxsize)
+	curbuf->b_mb_current->mb_maxsize = maxsize;
 }
 
 /*
@@ -1282,48 +1333,56 @@ u_alloc_line(size)
 	curbuf->b_m_search = &(curbuf->b_block_head.mb_info);
     }
 
-    /* search for space in free list */
-    mprev = curbuf->b_m_search;
+    /* Search for a block with enough space. */
     mbp = curbuf->b_mb_current;
-    mp = curbuf->b_m_search->m_next;
-    if (mp == NULL)
+    while (mbp->mb_maxsize < size_align)
     {
-	if (mbp->mb_next)
+	if (mbp->mb_next != NULL)
 	    mbp = mbp->mb_next;
 	else
 	    mbp = &curbuf->b_block_head;
-	mp = curbuf->b_m_search = &(mbp->mb_info);
+	if (mbp == curbuf->b_mb_current)
+	{
+	    int	n = (size_align > (MEMBLOCKSIZE / 4)
+					     ? size_align : MEMBLOCKSIZE);
+
+	    /* Back where we started in block list: need to add a new block
+	     * with enough space. */
+	    mp = (minfo_T *)u_blockalloc((long_u)n);
+	    if (mp == NULL)
+		return (NULL);
+	    mp->m_size = n;
+	    u_free_line((char_u *)mp + M_OFFSET, TRUE);
+	    mbp = curbuf->b_mb_current;
+	    break;
+	}
     }
-    while (mp->m_size < size)
+    if (mbp != curbuf->b_mb_current)
+	curbuf->b_m_search = &(mbp->mb_info);
+
+    /* In this block find a chunk with enough space. */
+    mprev = curbuf->b_m_search;
+    mp = curbuf->b_m_search->m_next;
+    while (1)
     {
-	if (mp == curbuf->b_m_search)	    /* back where we started in free
-					       chunk list */
+	if (mp == NULL)			    /* at end of the list */
+	    mp = &(mbp->mb_info);	    /* wrap around to begin */
+	if (mp->m_size >= size)
+	    break;
+	if (mp == curbuf->b_m_search)
 	{
-	    if (mbp->mb_next)
-		mbp = mbp->mb_next;
-	    else
-		mbp = &curbuf->b_block_head;
-	    mp = curbuf->b_m_search = &(mbp->mb_info);
-	    if (mbp == curbuf->b_mb_current)	/* back where we started in
-						   block list */
-	    {
-		int	n = (size_align > (MEMBLOCKSIZE / 4)
-						 ? size_align : MEMBLOCKSIZE);
-
-		mp = (minfo_T *)u_blockalloc((long_u)n);
-		if (mp == NULL)
-		    return (NULL);
-		mp->m_size = n;
-		u_free_line((char_u *)mp + M_OFFSET, TRUE);
-		mp = curbuf->b_m_search;
-		mbp = curbuf->b_mb_current;
-	    }
+	    /* back where we started in free chunk list: "cannot happen" */
+	    EMSG2(_(e_intern2), "u_alloc_line()");
+	    return NULL;
 	}
 	mprev = mp;
-	if ((mp = mp->m_next) == NULL)	    /* at end of the list */
-	    mp = &(mbp->mb_info);	    /* wrap around to begin */
+	mp = mp->m_next;
     }
 
+    /* when using the largest chunk adjust mb_maxsize */
+    if (mp->m_size >= mbp->mb_maxsize)
+	mbp->mb_maxsize = 0;
+
     /* if the chunk we found is large enough, split it up in two */
     if ((long)mp->m_size - size_align >= (long)(sizeof(minfo_T) + 1))
     {
@@ -1340,11 +1399,18 @@ u_alloc_line(size)
     curbuf->b_m_search = mprev;
     curbuf->b_mb_current = mbp;
 
+    /* If using the largest chunk need to find the new largest chunk */
+    if (mbp->mb_maxsize == 0)
+	for (mp2 = &(mbp->mb_info); mp2 != NULL; mp2 = mp2->m_next)
+	    if (mbp->mb_maxsize < mp2->m_size)
+		mbp->mb_maxsize = mp2->m_size;
+
     mp = (minfo_T *)((char_u *)mp + M_OFFSET);
     *(char_u *)mp = NUL;		    /* set the first byte to NUL */
 
     return ((char_u *)mp);
 }
+#endif
 
 /*
  * u_save_line(): allocate memory with u_alloc_line() and copy line 'lnum'
@@ -1360,7 +1426,7 @@ u_save_line(lnum)
 
     src = ml_get(lnum);
     len = (unsigned)STRLEN(src);
-    if ((dst = u_alloc_line(len)) != NULL)
+    if ((dst = U_ALLOC_LINE(len)) != NULL)
 	mch_memmove(dst, src, (size_t)(len + 1));
     return (dst);
 }
diff --git a/src/version.h b/src/version.h
index 1925a60e67271375ae1a421693b8c9f9ea40b4b3..f73c68e4f76a5c6c27b884b4733b6036c6f58b85 100644
--- a/src/version.h
+++ b/src/version.h
@@ -36,5 +36,5 @@
 #define VIM_VERSION_NODOT	"vim70aa"
 #define VIM_VERSION_SHORT	"7.0aa"
 #define VIM_VERSION_MEDIUM	"7.0aa ALPHA"
-#define VIM_VERSION_LONG	"VIM - Vi IMproved 7.0aa ALPHA (2005 Feb 12)"
-#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0aa ALPHA (2005 Feb 12, compiled "
+#define VIM_VERSION_LONG	"VIM - Vi IMproved 7.0aa ALPHA (2005 Feb 21)"
+#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0aa ALPHA (2005 Feb 21, compiled "