changeset 167:c93c9cad9618

updated for version 7.0051
author vimboss
date Tue, 22 Feb 2005 08:39:57 +0000
parents 3a28ed993bbe
children 4d9eabb1396e
files runtime/doc/cmdline.txt runtime/doc/editing.txt runtime/doc/gui_w32.txt runtime/doc/insert.txt runtime/doc/mbyte.txt runtime/doc/message.txt runtime/ftplugin/sql.vim runtime/syntax/esmtprc.vim runtime/syntax/sh.vim runtime/syntax/vim.vim src/Makefile src/ex_docmd.c src/fileio.c src/globals.h src/mbyte.c src/message.c src/netbeans.c src/normal.c src/os_unix.c src/po/Make_ming.mak src/po/Makefile src/proto/ex_docmd.pro src/proto/gui_mac.pro src/proto/main.pro src/proto/message.pro src/quickfix.c src/regexp.c src/testdir/test11.in src/vim.h
diffstat 29 files changed, 1283 insertions(+), 360 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/cmdline.txt
+++ b/runtime/doc/cmdline.txt
@@ -1,4 +1,4 @@
-*cmdline.txt*   For Vim version 7.0aa.  Last change: 2005 Jan 13
+*cmdline.txt*   For Vim version 7.0aa.  Last change: 2005 Feb 14
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -17,8 +17,9 @@ 1. Command-line editing		|cmdline-editin
 2. Command-line completion	|cmdline-completion|
 3. Ex command-lines		|cmdline-lines|
 4. Ex command-line ranges	|cmdline-ranges|
-5. Ex special characters	|cmdline-special|
-6. Command-line window		|cmdline-window|
+5. Ex command-line flags	|ex-flags|
+6. Ex special characters	|cmdline-special|
+7. Command-line window		|cmdline-window|
 
 ==============================================================================
 1. Command-line editing					*cmdline-editing*
@@ -668,7 +669,20 @@ Visual Mode and Range					*v_:*
 		lines.
 
 ==============================================================================
-5. Ex special characters				*cmdline-special*
+5. Ex command-line flags				*ex-flags*
+
+These flags are supported by a selection of Ex commands.  They print the line
+that the cursor ends up after executing the command:
+
+	l	output like for |:list|
+	#	add line number
+	p	output like for |:print|
+
+The flags can be combined, thus "l#" uses both a line number and |:list| style
+output.
+
+==============================================================================
+6. Ex special characters				*cmdline-special*
 
 In Ex commands, at places where a file name can be used, the following
 characters have a special meaning.  These can also be used in the expression
--- a/runtime/doc/editing.txt
+++ b/runtime/doc/editing.txt
@@ -1,4 +1,4 @@
-*editing.txt*   For Vim version 7.0aa.  Last change: 2005 Feb 07
+*editing.txt*   For Vim version 7.0aa.  Last change: 2005 Feb 14
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1143,13 +1143,16 @@ You may use the |:cd| and |:lcd| command
 you will not have to type that directory name in front of the file names.  It
 also makes a difference for executing external commands, e.g. ":!ls".
 
+Changing directory fails when the current buffer is modified, the '.' flag is
+present in 'cpoptions' and "!" is not used in the command.
+
 							*:cd* *E472*
-:cd			On non-Unix systems: Print the current directory
+:cd[!]			On non-Unix systems: Print the current directory
 			name.  On Unix systems: Change the current directory
 			to the home directory.  Use |:pwd| to print the
 			current directory on all systems.
 
-:cd {path}		Change the current directory to {path}.
+:cd[!] {path}		Change the current directory to {path}.
 			If {path} is relative, it is searched for in the
 			directories listed in |'cdpath'|.
 			Does not change the meaning of an already opened file,
@@ -1160,19 +1163,19 @@ also makes a difference for executing ex
 				:cd %:h
 <
 							*:cd-* *E186*
-:cd -			Change to the previous current directory (before the
+:cd[!] -		Change to the previous current directory (before the
 			previous ":cd {path}" command). {not in Vi}
 
 							*:chd* *:chdir*
-:chd[ir] [path]		Same as |:cd|.
+:chd[ir][!] [path]	Same as |:cd|.
 
 							*:lc* *:lcd*
-:lc[d] {path}		Like |:cd|, but only set the current directory for the
+:lc[d][!] {path}	Like |:cd|, but only set the current directory for the
 			current window.  The current directory for other
 			windows is not changed. {not in Vi}
 
 							*:lch* *:lchdir*
-:lch[dir]		Same as |:lcd|. {not in Vi}
+:lch[dir][!]		Same as |:lcd|. {not in Vi}
 
 							*:pw* *:pwd* *E187*
 :pw[d]			Print the current directory name.  {Vi: no pwd}
--- a/runtime/doc/gui_w32.txt
+++ b/runtime/doc/gui_w32.txt
@@ -1,4 +1,4 @@
-*gui_w32.txt*   For Vim version 7.0aa.  Last change: 2005 Jan 07
+*gui_w32.txt*   For Vim version 7.0aa.  Last change: 2005 Feb 14
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -235,7 +235,7 @@ cancel an operation.  Use CTRL-Break for
 
 CTRL-Z is used for undo.  This means you can't suspend Vim.
 
-							*CTRL-V-alternative*
+						*CTRL-V-alternative* *CTRL-Q*
 Since CTRL-V is used to paste, you can't use it to start a blockwise Visual
 selection.  You can use CTRL-Q instead.  You can also use CTRL-Q in Insert
 mode and Command-line mode to get the old meaning of CTRL-V.  But CTRL-Q
--- a/runtime/doc/insert.txt
+++ b/runtime/doc/insert.txt
@@ -1,4 +1,4 @@
-*insert.txt*    For Vim version 7.0aa.  Last change: 2005 Feb 08
+*insert.txt*    For Vim version 7.0aa.  Last change: 2005 Feb 21
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -970,18 +970,29 @@ too long when appending characters a lin
 9. Ex insert commands					*inserting-ex*
 
 							*:a* *:append*
-:{range}a[ppend]	Insert several lines of text below the specified
+:{range}a[ppend][!]	Insert several lines of text below the specified
 			line.  If the {range} is missing, the text will be
 			inserted after the current line.
+			Adding [!] toggles 'autoindent' for the time this
+			command is executed.
 
 							*:i* *:in* *:insert*
-:{range}i[nsert]	Insert several lines of text above the specified
+:{range}i[nsert][!]	Insert several lines of text above the specified
 			line.  If the {range} is missing, the text will be
 			inserted before the current line.
+			Adding [!] toggles 'autoindent' for the time this
+			command is executed.
 
 These two commands will keep on asking for lines, until you type a line
 containing only a ".".  Watch out for lines starting with a backslash, see
 |line-continuation|.
+When these commands are used with |:global| or |:vglobal| then the lines are
+obtained from the text following the command.  Separate lines with a NL
+escaped with a backslash: >
+	:global/abc/insert\
+	one line\
+	another line
+The final "." is not needed then.
 NOTE: ":append" and ":insert" don't work properly in between ":if" and
 ":endif", ":for" and ":endfor", ":while" and ":endwhile".
 
--- a/runtime/doc/mbyte.txt
+++ b/runtime/doc/mbyte.txt
@@ -1,4 +1,4 @@
-*mbyte.txt*     For Vim version 7.0aa.  Last change: 2004 Dec 19
+*mbyte.txt*     For Vim version 7.0aa.  Last change: 2005 Feb 13
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar et al.
@@ -1319,7 +1319,7 @@ a zero if necessary.
 COMMAND ARGUMENTS					*utf-8-char-arg*
 
 Commands like |f|, |F|, |t| and |r| take an argument of one character.  For
-UTF-8 this argument may include one or two composing characters.  These needs
+UTF-8 this argument may include one or two composing characters.  These need
 to be produced together with the base character, Vim doesn't wait for the next
 character to be typed to find out if it is a composing character or not.
 Using 'keymap' or |:lmap| is a nice way to type these characters.
--- a/runtime/doc/message.txt
+++ b/runtime/doc/message.txt
@@ -1,4 +1,4 @@
-*message.txt*   For Vim version 7.0aa.  Last change: 2005 Jan 08
+*message.txt*   For Vim version 7.0aa.  Last change: 2005 Feb 13
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -364,7 +364,8 @@ cannot be written.  You need to give the
 
 When using the '~' character in a pattern, it is replaced with the previously
 used pattern in a ":substitute" command.  This fails when no such command has
-been used yet.  See |/~|.
+been used yet.  See |/~|.  This also happens when using ":s/pat/%/", where the
+"%" stands for the previous substitute string.
 
 							*E35*  >
   No previous regular expression
--- a/runtime/ftplugin/sql.vim
+++ b/runtime/ftplugin/sql.vim
@@ -1,35 +1,198 @@
-" Vim filetype plugin file
-" Language:	SQL (Common for Oracle, Microsoft SQL Server, Sybase)
-" Version:	0.02
-" Maintainer:	David Fishburn <fishburn@ianywhere.com>
-" Last Change:	Tue May 27 2003 09:33:31
+" SQL filetype plugin file
+" Language:    SQL (Common for Oracle, Microsoft SQL Server, Sybase)
+" Version:     0.08
+" Maintainer:  David Fishburn <fishburn at ianywhere dot com>
+" Last Change: Mon Feb 21 2005 7:27:36 AM
+" Download:    http://vim.sourceforge.net/script.php?script_id=454
 
 " This file should only contain values that are common to all SQL languages
 " Oracle, Microsoft SQL Server, Sybase ASA/ASE, MySQL, and so on
 " If additional features are required create:
-" vimfiles/after/ftplugin/sql.vim
-" to override and add any of your own settings
+"        vimfiles/after/ftplugin/sql.vim (Windows)
+"        .vim/after/ftplugin/sql.vim     (Unix)
+" to override and add any of your own settings.
 
 " Only do this when not done yet for this buffer
 if exists("b:did_ftplugin")
   finish
 endif
 
+let s:save_cpo = &cpo
+set cpo=
+
 " Don't load another plugin for this buffer
 let b:did_ftplugin = 1
 
+" Some standard expressions for use with the matchit strings
+let s:notend = '\%(\<end\s\+\)\@<!'
+let s:when_no_matched_or_others = '\%(\<when\>\%(\s\+\%(\%(\<not\>\s\+\)\?<matched\>\)\|\<others\>\)\@!\)'
+let s:or_replace = '\%(or\s\+replace\s\+\)\?'
+
 " Define patterns for the matchit macro
 if !exists("b:match_words")
     " SQL is generally case insensitive
     let b:match_ignorecase = 1
+
+    " Handle the following:
+    " if
+    " elseif | elsif
+    " else [if]
+    " end if
+    "
+    " [while condition] loop
+    "     leave
+    "     break
+    "     continue
+    "     exit
+    " end loop
+    "
+    " for
+    "     leave
+    "     break
+    "     continue
+    "     exit
+    " end loop
+    "
+    " do
+    "     statements
+    " doend
+    "
+    " case
+    " when 
+    " when
+    " default
+    " end case
+    "
+    " merge
+    " when not matched
+    " when matched
+    "
+    " EXCEPTION
+    " WHEN column_not_found THEN
+    " WHEN OTHERS THEN
+    "
+    " create[ or replace] procedure|function|event
+
     let b:match_words =
-		\ '\<begin\>:\<end\>\(;\)\?$,'.
-		\ '\<if\>:\<elsif\>:\<elseif\>:\<else\>:'.
-		\ '\%(\<end\s\+\)\@<!' . '\<if\>:\<end\s\+if\>,'.
-		\ '\<loop\>:\<break\>:\<continue\>:'.
-		\ '\%(\<end\s\+\)\@<!' . '\<loop\>:\<end\s\+loop\>,'.
-		\ '\<for\>:\<break\>:\<continue\>:'.
-		\ '\%(\<end\s\+\)\@<!' . '\<for\>:\<end\s\+for\>,'.
-		\ '\<case\>:\<when\>:\<default\>:'.
-		\ '\%(\<end\s\+\)\@<!' . '\<case\>:\<end\s\+case\>'
+		\ '\<begin\>:\<end\>\W*$,'.
+		\
+                \ s:notend . '\<if\>:'.
+                \ '\<elsif\>\|\<elseif\>\|\<else\>:'.
+                \ '\<end\s\+if\>,'.
+                \
+                \ '\<do\>\|'.
+                \ '\<while\>\|'.
+                \ '\%(' . s:notend . '\<loop\>\)\|'.
+                \ '\%(' . s:notend . '\<for\>\):'.
+                \ '\<exit\>\|\<leave\>\|\<break\>\|\<continue\>:'.
+                \ '\%(\<end\s\+\%(for\|loop\>\)\)\|\<doend\>,'.
+                \
+                \ '\%('. s:notend . '\<case\>\):'.
+                \ '\%('.s:when_no_matched_or_others.'\):'.
+                \ '\%(\<when\s\+others\>\|\<end\s\+case\>\),' .
+                \
+                \ '\<merge\>:' .
+                \ '\<when\s\+not\s\+matched\>:' .
+                \ '\<when\s\+matched\>,' .
+                \
+                \ '\%(\<create\s\+' . s:or_replace . '\)\?'.
+                \ '\%(function\|procedure\|event\):'.
+                \ '\<returns\?\>'
+                " \ '\<begin\>\|\<returns\?\>:'.
+                " \ '\<end\>\(;\)\?\s*$'
+                " \ '\<exception\>:'.s:when_no_matched_or_others.
+                " \ ':\<when\s\+others\>,'.
+		"
+                " \ '\%(\<exception\>\|\%('. s:notend . '\<case\>\)\):'.
+                " \ '\%(\<default\>\|'.s:when_no_matched_or_others.'\):'.
+                " \ '\%(\%(\<when\s\+others\>\)\|\<end\s\+case\>\),' .
 endif
+
+" Define how to find the macro definition of a variable using the various
+" [d, [D, [_CTRL_D and so on features
+" Match these values ignoring case
+" ie  DECLARE varname INTEGER
+let &l:define = '\c\(DECLARE\|IN\|OUT\|INOUT\)\s*'
+
+
+" Mappings to move to the next BEGIN ... END block
+" \W - no characters or digits
+nmap <buffer> <silent> ]] :call search('\c^\s*begin\>', 'W' )<CR>
+nmap <buffer> <silent> [[ :call search('\c^\s*begin\>', 'bW' )<CR>
+nmap <buffer> <silent> ][ :call search('\c^\s*end\W*$', 'W' )<CR>
+nmap <buffer> <silent> [] :call search('\c^\s*end\W*$', 'bW' )<CR>
+vmap <buffer> <silent> ]] /\c^\s*begin\><CR>
+vmap <buffer> <silent> [[ ?\c^\s*begin<CR>
+vmap <buffer> <silent> ][ /\c^\s*end\W*$<CR>
+vmap <buffer> <silent> [] ?\c^\s*end\W*$<CR>
+
+
+" Predefined SQL objects what are used by the below mappings using
+" the ]} style maps.
+" This global variable allows the users to override it's value
+" from within their vimrc.
+if !exists('g:ftplugin_sql_objects')
+    let g:ftplugin_sql_objects = 'function,procedure,event,' .
+                \ '\(existing\\|global\s\+temporary\s\+\)\?table,trigger' .
+                \ ',schema,service,publication,database,datatype,domain' .
+                \ ',index,subscription,synchronization,view,variable'
+endif
+
+let s:ftplugin_sql_objects = 
+            \ '\c^\s*' .
+            \ '\(create\s\+\(or\s\+replace\s\+\)\?\)\?' .
+            \ '\<\(' .
+            \ substitute(g:ftplugin_sql_objects, ',', '\\\\|', 'g') .
+            \ '\)\>' 
+
+" Mappings to move to the next CREATE ... block
+" map <buffer> <silent> ]} :call search(g:ftplugin_sql_objects, 'W' )<CR>
+" nmap <buffer> <silent> [{ :call search('\c^\s*\(create\s\+\(or\s\+replace\s\+\)\?\)\?\<\(function\\|procedure\\|event\\|table\\|trigger\\|schema\)\>', 'bW' )<CR>
+" exec 'nmap <buffer> <silent> ]} /'.s:ftplugin_sql_objects.'<CR>'
+exec "nmap <buffer> <silent> ]} :call search('".s:ftplugin_sql_objects."', 'W')<CR>"
+exec "nmap <buffer> <silent> [{ :call search('".s:ftplugin_sql_objects."', 'bW')<CR>"
+" Could not figure out how to use a :call search() string in visual mode
+" without it ending visual mode
+exec 'vmap <buffer> <silent> ]} /'.s:ftplugin_sql_objects.'<CR>'
+exec 'vmap <buffer> <silent> [{ ?'.s:ftplugin_sql_objects.'<CR>'
+" vmap <buffer> <silent> ]} /\c^\s*\(create\s\+\(or\s\+replace\s\+\)\?\)\?\<\(function\\|procedure\\|event\\|table\\|trigger\\|schema\)\><CR>
+" vmap <buffer> <silent> [{ ?\c^\s*\(create\s\+\(or\s\+replace\s\+\)\?\)\?\<\(function\\|procedure\\|event\\|table\\|trigger\\|schema\)\><CR>
+
+" Mappings to move to the next COMMENT
+"
+" Had to double the \ for the \| separator since this has a special
+" meaning on maps
+let b:comment_leader = '\(--\\|\/\/\\|\*\\|\/\*\\|\*\/\)'
+" Find the start of the next comment
+let b:comment_start  = '^\(\s*'.b:comment_leader.'.*\n\)\@<!'.
+            \ '\(\s*'.b:comment_leader.'\)'
+" Find the end of the previous comment
+let b:comment_end = '\(^\s*'.b:comment_leader.'.*\n\)'.
+            \ '\(^\s*'.b:comment_leader.'\)\@!'
+" Skip over the comment
+let b:comment_jump_over  = "call search('".
+            \ '^\(\s*'.b:comment_leader.'.*\n\)\@<!'.
+            \ "', 'W')"
+let b:comment_skip_back  = "call search('".
+            \ '^\(\s*'.b:comment_leader.'.*\n\)\@<!'.
+            \ "', 'bW')"
+" Move to the start and end of comments
+exec 'nnoremap <silent><buffer> ]" /'.b:comment_start.'<CR>'
+exec 'nnoremap <silent><buffer> [" /'.b:comment_end.'<CR>'
+exec 'vnoremap <silent><buffer> ]" /'.b:comment_start.'<CR>'
+exec 'vnoremap <silent><buffer> [" /'.b:comment_end.'<CR>'
+
+" Comments can be of the form:
+"   /*
+"    *
+"    */
+" or
+"   // 
+" or
+"   --
+setlocal comments=s1:/*,mb:*,ex:*/,:--,://
+
+let &cpo = s:save_cpo
+
+" vim:sw=4:ff=unix:
+
new file mode 100644
--- /dev/null
+++ b/runtime/syntax/esmtprc.vim
@@ -0,0 +1,34 @@
+" Vim syntax file
+" Language:	Esmtp setup file (based on esmtp 0.5.0)
+" Maintainer:	Kornel Kielczewski <kornel@gazeta.pl>
+" Last Change:	16 Feb 2005
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+"All options
+:syntax keyword	esmtprcOptions hostname username password starttls certificate_passphrase preconnect identity mda
+
+"All keywords
+:syntax keyword esmtprcIdentifier default enabled disabled required
+
+"We're trying to be smarer than /."*@.*/ :)
+:syntax match esmtprcAddress /[a-z0-9_.-]*[a-z0-9]\+@[a-z0-9_.-]*[a-z0-9]\+\.[a-z]\+/
+:syntax match esmtprcFulladd /[a-z0-9_.-]*[a-z0-9]\+\.[a-z]\+:[0-9]\+/
+ 
+"String..
+:syntax region esmtprcString start=/"/ end=/"/
+
+
+:highlight link esmtprcOptions		Label
+:highlight link esmtprcString 		String
+:highlight link esmtprcAddress		Type
+:highlight link esmtprcIdentifier 	Identifier
+:highlight link esmtprcFulladd		Include
+
+let b:current_syntax="esmtprc"
--- a/runtime/syntax/sh.vim
+++ b/runtime/syntax/sh.vim
@@ -2,8 +2,8 @@
 " Language:		shell (sh) Korn shell (ksh) bash (sh)
 " Maintainer:		Dr. Charles E. Campbell, Jr.  <NdrOchipS@PcampbellAfamily.Mbiz>
 " Previous Maintainer:	Lennart Schultz <Lennart.Schultz@ecmwf.int>
-" Last Change:		Dec 28, 2004
-" Version:		71
+" Last Change:		Feb 16, 2005
+" Version:		72
 " URL:		http://www.erols.com/astronaut/vim/index.html#vimlinks_syntax
 "
 " Using the following VIM variables: {{{1
@@ -63,24 +63,24 @@ syn case match
 
 " Clusters: contains=@... clusters {{{1
 "==================================
-syn cluster shCaseEsacList	contains=shCaseStart,shCase,shCaseBar,shCaseIn,shComment,shDeref,shDerefSimple,shCaseCommandSub,shCaseSingleQuote,shCaseDoubleQuote,shSpecial
+syn cluster shCaseEsacList	contains=shCaseStart,shCase,shCaseBar,shCaseIn,shComment,shDeref,shDerefSimple,shCaseCommandSub,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote,shSpecial
 syn cluster shCaseList	contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shRedir,shSetList,shSource,shStatement,shVariable,bkshFunction,shSpecial
 syn cluster shColonList	contains=@shCaseList
-syn cluster shCommandSubList	contains=shArithmetic,shDeref,shDerefSimple,shNumber,shOperator,shPosnParm,shSpecial,shSingleQuote,shDoubleQuote,shStatement,shVariable,shSubSh,shAlias,shTest
+syn cluster shCommandSubList	contains=shArithmetic,shDeref,shDerefSimple,shNumber,shOperator,shPosnParm,shSpecial,shExSingleQuote,shSingleQuote,shDoubleQuote,shStatement,shVariable,shSubSh,shAlias,shTest
 syn cluster shDblQuoteList	contains=shCommandSub,shDeref,shDerefSimple,shSpecial,shPosnParm
 syn cluster shDerefList	contains=shDeref,shDerefSimple,shDerefVar,shDerefSpecial,shDerefWordError
 syn cluster shDerefVarList	contains=shDerefOp,shDerefVarArray,shDerefOpError
-syn cluster shEchoList	contains=shArithmetic,shCommandSub,shDeref,shDerefSimple,shExpr,shSingleQuote,shDoubleQuote,shSpecial
-syn cluster shExprList1	contains=shCharClass,shNumber,shOperator,shSingleQuote,shDoubleQuote,shSpecial,shExpr,shDblBrace,shDeref,shDerefSimple
+syn cluster shEchoList	contains=shArithmetic,shCommandSub,shDeref,shDerefSimple,shExpr,shExSingleQuote,shSingleQuote,shDoubleQuote,shSpecial
+syn cluster shExprList1	contains=shCharClass,shNumber,shOperator,shExSingleQuote,shSingleQuote,shDoubleQuote,shSpecial,shExpr,shDblBrace,shDeref,shDerefSimple
 syn cluster shExprList2	contains=@shExprList1,@shCaseList,shTest
 syn cluster shFunctionList	contains=@shCaseList,shOperator
 syn cluster shHereBeginList	contains=@shCommandSubList
 syn cluster shHereList	contains=shBeginHere,shHerePayload
 syn cluster shHereListDQ	contains=shBeginHere,@shDblQuoteList,shHerePayload
-syn cluster shIdList	contains=shCommandSub,shWrapLineOperator,shIdWhiteSpace,shDeref,shDerefSimple,shSpecial,shRedir,shSingleQuote,shDoubleQuote,shExpr
+syn cluster shIdList	contains=shCommandSub,shWrapLineOperator,shIdWhiteSpace,shDeref,shDerefSimple,shSpecial,shRedir,shExSingleQuote,shSingleQuote,shDoubleQuote,shExpr
 syn cluster shLoopList	contains=@shCaseList,shTestOpr,shExpr,shDblBrace,shConditional,shCaseEsac,shTest
 syn cluster shSubShList	contains=@shCaseList
-syn cluster shTestList	contains=shCharClass,shComment,shCommandSub,shDeref,shDerefSimple,shDoubleQuote,shExpr,shExpr,shNumber,shOperator,shSingleQuote,shSpecial,shTestOpr,shTest
+syn cluster shTestList	contains=shCharClass,shComment,shCommandSub,shDeref,shDerefSimple,shDoubleQuote,shExpr,shExpr,shNumber,shOperator,shExSingleQuote,shSingleQuote,shSpecial,shTestOpr,shTest
 
 
 " Echo: {{{1
@@ -90,7 +90,7 @@ syn region shEcho matchgroup=shStatement
 syn region shEcho matchgroup=shStatement start="\<print\>" skip="\\$" matchgroup=shOperator end="$" matchgroup=NONE end="[<>;&|()]"me=e-1 end="\d[<>]"me=e-2 end="#"me=e-1 contains=@shEchoList
 
 " This must be after the strings, so that bla \" be correct
-syn region shEmbeddedEcho contained matchgroup=shStatement start="\<print\>" skip="\\$" matchgroup=shOperator end="$" matchgroup=NONE end="[<>;&|`)]"me=e-1 end="\d[<>]"me=e-2 end="#"me=e-1 contains=shNumber,shSingleQuote,shDeref,shDerefSimple,shSpecialVar,shSpecial,shOperator,shDoubleQuote,shCharClass
+syn region shEmbeddedEcho contained matchgroup=shStatement start="\<print\>" skip="\\$" matchgroup=shOperator end="$" matchgroup=NONE end="[<>;&|`)]"me=e-1 end="\d[<>]"me=e-2 end="#"me=e-1 contains=shNumber,shExSingleQuote,shSingleQuote,shDeref,shDerefSimple,shSpecialVar,shSpecial,shOperator,shDoubleQuote,shCharClass
 
 " Alias: {{{1
 " =====
@@ -124,7 +124,7 @@ syn match   shOption  "\s--\S\+"ms=s+1
 syn match   shOperator	"[!&;|]"
 syn match   shOperator	"\[[[^:]\|\]]"
 syn match   shOperator	"!\=="		skipwhite nextgroup=shPattern
-syn match   shPattern	"\<\S\+\())\)\@="	contained contains=shSingleQuote,shDoubleQuote,shDeref
+syn match   shPattern	"\<\S\+\())\)\@="	contained contains=shExSingleQuote,shSingleQuote,shDoubleQuote,shDeref
 
 " Subshells: {{{1
 " ==========
@@ -163,12 +163,17 @@ endif
 
 " Case: case...esac {{{1
 " ====
-syn match   shCaseBar	contained skipwhite "[^|"`'()]\{-}|"hs=e		nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseSingleQuote,shCaseDoubleQuote
+syn match   shCaseBar	contained skipwhite "[^|"`'()]\{-}|"hs=e		nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
 syn match   shCaseStart	contained skipwhite skipnl "("			nextgroup=shCase,shCaseBar
 syn region  shCase	contained skipwhite skipnl matchgroup=shSnglCase start="[^$()]\{-})"ms=s,hs=e  end=";;" end="esac"me=s-1 contains=@shCaseList nextgroup=shCaseStart,shCase,,shComment
 syn region  shCaseEsac	matchgroup=shConditional start="\<case\>" end="\<esac\>"	contains=@shCaseEsacList
-syn keyword shCaseIn	contained skipwhite skipnl in			nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseSingleQuote,shCaseDoubleQuote
-syn region  shCaseSingleQuote	matchgroup=shOperator start=+'+ skip=+\\\\\|\\.+ end=+'+	contains=shStringSpecial		skipwhite skipnl nextgroup=shCaseBar	contained
+syn keyword shCaseIn	contained skipwhite skipnl in			nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
+if exists("b:is_bash")
+ syn region  shCaseExSingleQuote	matchgroup=shOperator start=+\$'+ skip=+\\\\\|\\.+ end=+'+	contains=shStringSpecial,shSpecial	skipwhite skipnl nextgroup=shCaseBar	contained
+else
+ syn region  shCaseExSingleQuote	matchgroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+	contains=shStringSpecial	skipwhite skipnl nextgroup=shCaseBar	contained
+endif
+syn region  shCaseSingleQuote	matchgroup=shOperator start=+'+ end=+'+	contains=shStringSpecial		skipwhite skipnl nextgroup=shCaseBar	contained
 syn region  shCaseDoubleQuote	matchgroup=shOperator start=+"+ skip=+\\\\\|\\.+ end=+"+	contains=@shDblQuoteList,shStringSpecial	skipwhite skipnl nextgroup=shCaseBar	contained
 syn region  shCaseCommandSub	start=+`+ skip=+\\\\\|\\.+ end=+`+		contains=@shCommandSubList		skipwhite skipnl nextgroup=shCaseBar	contained
 
@@ -188,7 +193,7 @@ if exists("b:is_kornshell") || exists("b
  syn region shArithmetic matchgroup=shArithRegion  start="\$((" skip='\\\\\|\\.' end="))" contains=@shCommandSubList
  syn match  shSkipInitWS contained	"^\s\+"
 else
- syn region shCommandSub matchgroup=Error start="$(" end=")" contains=@shCommandSubList
+ syn region shCommandSub matchgroup=Error start="\$(" end=")" contains=@shCommandSubList
 endif
 
 if exists("b:is_bash")
@@ -213,7 +218,16 @@ syn region  shColon	start="^\s*:" end="$
 " String And Character Constants: {{{1
 "================================
 syn match   shNumber	"-\=\<\d\+\>"
-syn match   shSpecial	"\\\d\d\d\|\\[abcfnrtv0]"	contained
+if exists("b:is_bash")
+ syn match   shSpecial	"\\\o\o\o\|\\x\x\x\|\\c.\|\\[abefnrtv]"	contained
+else
+ syn match   shSpecial	"\\\d\d\d\|\\[abcfnrtv0]"	contained
+endif
+if exists("b:is_bash")
+ syn region  shExSingleQuote	matchgroup=shOperator start=+\$'+ skip=+\\\\\|\\.+ end=+'+	contains=shStringSpecial,shSpecial
+else
+ syn region  shExSingleQuote	matchGroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+	contains=shStringSpecial,shSpecial
+endif
 syn region  shSingleQuote	matchgroup=shOperator start=+'+ end=+'+		contains=shStringSpecial
 syn region  shDoubleQuote	matchgroup=shOperator start=+"+ skip=+\\"+ end=+"+	contains=@shDblQuoteList,shStringSpecial
 syn match   shStringSpecial	"[^[:print:]]"	contained
@@ -314,7 +328,7 @@ endif
 "=============
 syn match  shVariable "\<\([bwglsav]:\)\=[a-zA-Z0-9.!@_%+,]*\ze="	nextgroup=shSetIdentifier
 syn match  shIdWhiteSpace  contained	"\s"
-syn match  shSetIdentifier contained	"="	nextgroup=shPattern,shDeref,shDerefSimple,shDoubleQuote,shSingleQuote
+syn match  shSetIdentifier contained	"="	nextgroup=shPattern,shDeref,shDerefSimple,shDoubleQuote,shSingleQuote,shExSingleQuote
 if exists("b:is_bash")
   syn region shSetList matchgroup=shSet start="\<\(declare\|typeset\|local\|export\|unset\)\>\ze[^/]" end="$" matchgroup=shOperator end="[;&]"me=e-1 matchgroup=NONE end="#\|="me=e-1 contains=@shIdList
   syn region shSetList matchgroup=shSet start="\<set\>[^/]"me=e-1 end="$" end="\\ze[|)]"		 matchgroup=shOperator end="[;&]"me=e-1 matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList
@@ -448,32 +462,30 @@ syn sync match shWhileSync	grouphere	shR
 " Default Highlighting: {{{1
 " =====================
 hi def link shArithRegion	shShellVariables
+hi def link shBeginHere	shRedir
 hi def link shCaseBar	shConditional
-hi def link shCaseIn	shConditional
 hi def link shCaseCommandSub	shCommandSub
 hi def link shCaseDoubleQuote	shDoubleQuote
+hi def link shCaseIn	shConditional
 hi def link shCaseSingleQuote	shSingleQuote
 hi def link shCaseStart	shConditional
 hi def link shCmdSubRegion	shShellVariables
 hi def link shColon	shStatement
-
+hi def link shDerefOp	shOperator
+hi def link shDerefPatStringOp	shDerefOp
+hi def link shDerefPatString	shDerefPattern
+hi def link shDerefPOL	shDerefOp
 hi def link shDeref	shShellVariables
-hi def link shDerefOp	shOperator
-
-hi def link shDerefVar	shDeref
-hi def link shDerefPOL	shDerefOp
-hi def link shDerefPatString	shDerefPattern
-hi def link shDerefPatStringOp	shDerefOp
 hi def link shDerefSimple	shDeref
 hi def link shDerefSpecial	shDeref
 hi def link shDerefString	shDoubleQuote
-hi def link shHerePayload	shHereDoc
-hi def link shBeginHere	shRedir
-
+hi def link shDerefVar	shDeref
 hi def link shDoubleQuote	shString
 hi def link shEcho	shString
 hi def link shEmbeddedEcho	shString
+hi def link shExSingleQuote	shSingleQuote
 hi def link shHereDoc	shString
+hi def link shHerePayload	shHereDoc
 hi def link shLoop	shStatement
 hi def link shOption	shCommandSub
 hi def link shPattern	shString
--- a/runtime/syntax/vim.vim
+++ b/runtime/syntax/vim.vim
@@ -1,8 +1,8 @@
 " Vim syntax file
 " Language:	Vim 7.0 script
 " Maintainer:	Dr. Charles E. Campbell, Jr. <NdrOchipS@PcampbellAfamily.Mbiz>
-" Last Change:	February 09, 2005
-" Version:	7.0-04
+" Last Change:	Feb 14, 2005
+" Version:	7.0-05
 " Automatically generated keyword lists: {{{1
 
 " Quit when a syntax file was already loaded {{{2
@@ -16,7 +16,7 @@ syn keyword vimTodo contained	COMBAK	NOT
 syn cluster vimCommentGroup	contains=vimTodo
 
 " regular vim commands {{{2
-syn keyword vimCommand contained	ab[breviate] abc[lear] abo[veleft] al[l] arga[dd] argd[elete] argdo arge[dit] argg[lobal] argl[ocal] ar[gs] argu[ment] as[cii] bad[d] ba[ll] bd[elete] be bel[owright] bf[irst] bl[ast] bm[odified] bn[ext] bN[ext] bo[tright] bp[revious] brea[k] breaka[dd] breakd[el] breakl[ist] br[ewind] bro[wse] bufdo b[uffer] buffers bun[load] bw[ipeout] ca[bbrev] cabc[lear] cal[l] cat[ch] cb[uffer] cc ccl[ose] cd ce[nter] cf[ile] cfir[st] cg[etfile] c[hange] changes chd[ir] che[ckpath] checkt[ime] cla[st] cl[ist] clo[se] cmapc[lear] cnew[er] cn[ext] cN[ext] cnf[ile] cNf[ile] cnorea[bbrev] col[der] colo[rscheme] comc[lear] comp[iler] conf[irm] con[tinue] cope[n] co[py] cpf[ile] cp[revious] cq[uit] cr[ewind] cuna[bbrev] cu[nmap] cw[indow] debugg[reedy] delc[ommand] d[elete] DeleteFirst delf[unction] delm[arks] diffg[et] diffoff diffpatch diffpu[t] diffsplit diffthis dig[raphs] di[splay] dj[ump] dl[ist] dr[op] ds[earch] dsp[lit] echoe[rr] echom[sg] echon e[dit] el[se] elsei[f] em[enu] emenu* endfo[r] endf[unction] en[dif] endt[ry] endw[hile] ene[w] ex exi[t] exu[sage] f[ile] files filetype fina[lly] fin[d] fini[sh] fir[st] fix[del] fo[ld] foldc[lose] folddoc[losed] foldd[oopen] foldo[pen] for fu[nction] g[lobal] go[to] gr[ep] grepa[dd] ha[rdcopy] h[elp] helpf[ind] helpg[rep] helpt[ags] hid[e] his[tory] I ia[bbrev] iabc[lear] if ij[ump] il[ist] imapc[lear] inorea[bbrev] is[earch] isp[lit] iuna[bbrev] iu[nmap] j[oin] ju[mps] k keepalt keepj[umps] kee[pmarks] lan[guage] la[st] lc[d] lch[dir] le[ft] lefta[bove] l[ist] lm[ap] lmapc[lear] ln[oremap] lo[adview] loc[kmarks] lockv[ar] ls lu[nmap] mak[e] ma[rk] marks mat[ch] menut[ranslate] mk[exrc] mks[ession] mkvie[w] mkv[imrc] mod[e] m[ove] mzf[ile] mz[scheme] nbkey new n[ext] N[ext] nmapc[lear] noh[lsearch] norea[bbrev] Nread nu[mber] nun[map] Nw omapc[lear] on[ly] o[pen] opt[ions] ou[nmap] pc[lose] ped[it] pe[rl] perld[o] po[p] popu popu[p] pp[op] pre[serve] prev[ious] p[rint] P[rint] prompt promptf[ind] promptr[epl] ps[earch] pta[g] ptf[irst] ptj[ump] ptl[ast] ptn[ext] ptN[ext] ptp[revious] ptr[ewind] pts[elect] pu[t] pw[d] pyf[ile] py[thon] qa[ll] q[uit] quita[ll] r[ead] rec[over] redi[r] red[o] redr[aw] redraws[tatus] reg[isters] res[ize] ret[ab] retu[rn] rew[ind] ri[ght] rightb[elow] rub[y] rubyd[o] rubyf[ile] ru[ntime] rv[iminfo] sal[l] sandbox sa[rgument] sav[eas] sba[ll] sbf[irst] sbl[ast] sbm[odified] sbn[ext] sbN[ext] sbp[revious] sbr[ewind] sb[uffer] scripte[ncoding] scrip[tnames] se[t] setf[iletype] setg[lobal] setl[ocal] sf[ind] sfir[st sh[ell] sign sil[ent] sim[alt] sla[st] sl[eep] sm[agic] sn[ext] sN[ext] sni[ff] sno[magic] so[urce] sp[lit] spr[evious] sre[wind] sta[g] star[tinsert] startr[eplace] stj[ump] st[op] stopi[nsert] sts[elect] sun[hide] sus[pend] sv[iew] syncbind t ta[g] tags tc[l] tcld[o] tclf[ile] te[aroff] tf[irst] the th[row] tj[ump] tl[ast] tm tm[enu] tn[ext] tN[ext] to[pleft] tp[revious] tr[ewind] try ts[elect] tu tu[nmenu] una[bbreviate] u[ndo] unh[ide] unlo[ckvar] unm[ap] up[date] verb[ose] ve[rsion] vert[ical] v[global] vie[w] vim[grep] vimgrepa[dd] vi[sual] viu[sage] vmapc[lear] vne[w] vs[plit] vu[nmap] wa[ll] wh[ile] winc[md] windo winp[os] winpos* win[size] wn[ext] wN[ext] wp[revious] wq wqa[ll] w[rite] ws[verb] wv[iminfo] X xa[ll] x[it] y[ank] 
+syn keyword vimCommand contained	ab[breviate] abc[lear] abo[veleft] al[l] arga[dd] argd[elete] argdo arge[dit] argg[lobal] argl[ocal] ar[gs] argu[ment] as[cii] bad[d] ba[ll] bd[elete] be bel[owright] bf[irst] bl[ast] bm[odified] bn[ext] bN[ext] bo[tright] bp[revious] brea[k] breaka[dd] breakd[el] breakl[ist] br[ewind] bro[wse] bufdo b[uffer] buffers bun[load] bw[ipeout] ca[bbrev] cabc[lear] cal[l] cat[ch] cb[uffer] cc ccl[ose] cd ce[nter] cf[ile] cfir[st] cg[etfile] c[hange] changes chd[ir] che[ckpath] checkt[ime] cla[st] cl[ist] clo[se] cmapc[lear] cnew[er] cn[ext] cN[ext] cnf[ile] cNf[ile] cnorea[bbrev] col[der] colo[rscheme] comc[lear] comp[iler] conf[irm] con[tinue] cope[n] co[py] cpf[ile] cp[revious] cq[uit] cr[ewind] cuna[bbrev] cu[nmap] cw[indow] debugg[reedy] delc[ommand] d[elete] DeleteFirst delf[unction] delm[arks] diffg[et] diffoff diffpatch diffpu[t] diffsplit diffthis dig[raphs] di[splay] dj[ump] dl[ist] dr[op] ds[earch] dsp[lit] echoe[rr] echom[sg] echon e[dit] el[se] elsei[f] em[enu] emenu* endfo[r] endf[unction] en[dif] endt[ry] endw[hile] ene[w] ex exi[t] exu[sage] f[ile] files filetype fina[lly] fin[d] fini[sh] fir[st] fix[del] fo[ld] foldc[lose] folddoc[losed] foldd[oopen] foldo[pen] for fu[nction] g[lobal] go[to] gr[ep] grepa[dd] ha[rdcopy] h[elp] helpf[ind] helpg[rep] helpt[ags] hid[e] his[tory] I ia[bbrev] iabc[lear] if ij[ump] il[ist] imapc[lear] inorea[bbrev] is[earch] isp[lit] iuna[bbrev] iu[nmap] j[oin] ju[mps] k keepalt keepj[umps] kee[pmarks] lan[guage] la[st] lc[d] lch[dir] le[ft] lefta[bove] l[ist] lm[ap] lmapc[lear] ln[oremap] lo[adview] loc[kmarks] lockv[ar] ls lu[nmap] mak[e] ma[rk] marks mat[ch] menut[ranslate] mk[exrc] mks[ession] mkvie[w] mkv[imrc] mod[e] m[ove] mzf[ile] mz[scheme] nbkey new n[ext] N[ext] nmapc[lear] noh[lsearch] norea[bbrev] Nread nu[mber] nun[map] Nw omapc[lear] on[ly] o[pen] opt[ions] ou[nmap] pc[lose] ped[it] pe[rl] perld[o] po[p] popu popu[p] pp[op] pre[serve] prev[ious] p[rint] P[rint] prompt promptf[ind] promptr[epl] ps[earch] pta[g] ptf[irst] ptj[ump] ptl[ast] ptn[ext] ptN[ext] ptp[revious] ptr[ewind] pts[elect] pu[t] pw[d] pyf[ile] py[thon] qa[ll] q[uit] quita[ll] r[ead] rec[over] redi[r] red[o] redr[aw] redraws[tatus] reg[isters] res[ize] ret[ab] retu[rn] rew[ind] ri[ght] rightb[elow] rub[y] rubyd[o] rubyf[ile] ru[ntime] rv[iminfo] sal[l] sandbox sa[rgument] sav[eas] sba[ll] sbf[irst] sbl[ast] sbm[odified] sbn[ext] sbN[ext] sbp[revious] sbr[ewind] sb[uffer] scripte[ncoding] scrip[tnames] se[t] setf[iletype] setg[lobal] setl[ocal] sf[ind] sfir[st] sh[ell] sign sil[ent] sim[alt] sla[st] sl[eep] sm[agic] sn[ext] sN[ext] sni[ff] sno[magic] so[urce] sp[lit] spr[evious] sre[wind] sta[g] star[tinsert] startr[eplace] stj[ump] st[op] stopi[nsert] sts[elect] sun[hide] sus[pend] sv[iew] syncbind t ta[g] tags tc[l] tcld[o] tclf[ile] te[aroff] tf[irst] the th[row] tj[ump] tl[ast] tm tm[enu] tn[ext] tN[ext] to[pleft] tp[revious] tr[ewind] try ts[elect] tu tu[nmenu] una[bbreviate] u[ndo] unh[ide] unlo[ckvar] unm[ap] up[date] verb[ose] ve[rsion] vert[ical] v[global] vie[w] vim[grep] vimgrepa[dd] vi[sual] viu[sage] vmapc[lear] vne[w] vs[plit] vu[nmap] wa[ll] wh[ile] winc[md] windo winp[os] winpos* win[size] wn[ext] wN[ext] wp[revious] wq wqa[ll] w[rite] ws[verb] wv[iminfo] X xa[ll] x[it] y[ank] 
 syn match   vimCommand contained	"\<z[-+^.=]"
 
 " vimOptions are caught only when contained in a vimSet {{{2
@@ -389,13 +389,14 @@ syn match   vimMtchComment	contained	'"[
 
 " Syntax: sync {{{2
 " ============
-syn keyword vimSynType	contained	sync	skipwhite	nextgroup=vimSyncC,vimSyncLines,vimSyncMatch,vimSyncError,vimSyncLinecont,vimSyncRegion
+syn keyword vimSynType	contained	sync	skipwhite	nextgroup=vimSyncC,vimSyncLines,vimSyncMatch,vimSyncError,vimSyncLinebreak,vimSyncLinecont,vimSyncRegion
 if !exists("g:vimsyntax_noerror")
  syn match   vimSyncError	contained	"\i\+"
 endif
 syn keyword vimSyncC	contained	ccomment	clear	fromstart
 syn keyword vimSyncMatch	contained	match	skipwhite	nextgroup=vimSyncGroupName
 syn keyword vimSyncRegion	contained	region	skipwhite	nextgroup=vimSynReg
+syn match   vimSyncLinebreak	contained	"\<linebreaks="	skipwhite	nextgroup=vimNumber
 syn keyword vimSyncLinecont	contained	linecont	skipwhite	nextgroup=vimSynRegPat
 syn match   vimSyncLines	contained	"\(min\|max\)\=lines="	nextgroup=vimNumber
 syn match   vimSyncGroupName	contained	"\k\+"	skipwhite	nextgroup=vimSyncKey
--- a/src/Makefile
+++ b/src/Makefile
@@ -505,6 +505,7 @@ CClink = $(CC)
 # Often used for GCC: mixed optimizing, lot of optimizing, debugging
 #CFLAGS = -g -O2 -fno-strength-reduce -Wall -Wshadow -Wmissing-prototypes
 #CFLAGS = -g -O2 -fno-strength-reduce -Wall -Wmissing-prototypes
+#CFLAGS = -g -Wall -Wmissing-prototypes
 #CFLAGS = -O6 -fno-strength-reduce -Wall -Wshadow -Wmissing-prototypes
 #CFLAGS = -g -DDEBUG -Wall -Wshadow -Wmissing-prototypes
 #CFLAGS = -g -O2 '-DSTARTUPTIME="vimstartup"' -fno-strength-reduce -Wall -Wmissing-prototypes
@@ -2410,6 +2411,11 @@ install_macosx: $(APPDIR)
 bundle-dir: $(APPDIR)/Contents $(VIMTARGET)
 	-@srcdir=`pwd`; cd $(HELPSOURCE); $(MAKE) VIMEXE=$$srcdir/$(VIMTARGET) vimtags
 	cp -R ../runtime $(APPDIR)
+# When using CVS some CVS directories might have been copied.
+	cvs=`find $(APPDIR) \( -name CVS -o -name AAPDIR \) -print`; \
+	      if test -n "$$cvs"; then \
+		 rm -rf $$cvs; \
+	      fi
 
 bundle-executable: $(VIMTARGET)
 	cp $(VIMTARGET) $(APPDIR)/Contents/MacOS/$(VIMTARGET)
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -128,6 +128,7 @@ static int	getargopt __ARGS((exarg_T *ea
 
 static int	check_more __ARGS((int, int));
 static linenr_T get_address __ARGS((char_u **, int skip, int to_other_file));
+static void	get_flags __ARGS((exarg_T *eap));
 #if !defined(FEAT_PERL) || !defined(FEAT_PYTHON) || !defined(FEAT_TCL) \
 	|| !defined(FEAT_RUBY) || !defined(FEAT_MZSCHEME)
 static void	ex_script_ni __ARGS((exarg_T *eap));
@@ -185,6 +186,7 @@ static void	ex_recover __ARGS((exarg_T *
 static void	ex_mode __ARGS((exarg_T *eap));
 static void	ex_wrongmodifier __ARGS((exarg_T *eap));
 static void	ex_find __ARGS((exarg_T *eap));
+static void	ex_open __ARGS((exarg_T *eap));
 static void	ex_edit __ARGS((exarg_T *eap));
 #if !defined(FEAT_GUI) && !defined(FEAT_CLIENTSERVER)
 # define ex_drop		ex_ni
@@ -271,6 +273,7 @@ static void	ex_winpos __ARGS((exarg_T *e
 static void	ex_operators __ARGS((exarg_T *eap));
 static void	ex_put __ARGS((exarg_T *eap));
 static void	ex_copymove __ARGS((exarg_T *eap));
+static void	ex_may_print __ARGS((exarg_T *eap));
 static void	ex_submagic __ARGS((exarg_T *eap));
 static void	ex_join __ARGS((exarg_T *eap));
 static void	ex_at __ARGS((exarg_T *eap));
@@ -570,19 +573,22 @@ do_exmode(improved)
     int		save_msg_scroll;
     int		prev_msg_row;
     linenr_T	prev_line;
+    int		changedtick;
+
+    if (improved)
+	exmode_active = EXMODE_VIM;
+    else
+	exmode_active = EXMODE_NORMAL;
+    State = NORMAL;
+
+    /* When using ":global /pat/ visual" and then "Q" we return to continue
+     * the :global command. */
+    if (global_busy)
+	return;
 
     save_msg_scroll = msg_scroll;
     ++RedrawingDisabled;	    /* don't redisplay the window */
     ++no_wait_return;		    /* don't wait for return */
-    if (improved)
-	exmode_active = EXMODE_VIM;
-    else
-    {
-	settmode(TMODE_COOK);
-	exmode_active = EXMODE_NORMAL;
-    }
-
-    State = NORMAL;
 #ifdef FEAT_GUI
     /* Ignore scrollbar and mouse events in Ex mode */
     ++hold_gui_events;
@@ -606,6 +612,7 @@ do_exmode(improved)
 	need_wait_return = FALSE;
 	ex_pressedreturn = FALSE;
 	ex_no_reprint = FALSE;
+	changedtick = curbuf->b_changedtick;
 	prev_msg_row = msg_row;
 	prev_line = curwin->w_cursor.lnum;
 #ifdef FEAT_SNIFF
@@ -620,29 +627,38 @@ do_exmode(improved)
 	    do_cmdline(NULL, getexmodeline, NULL, DOCMD_NOWAIT);
 	lines_left = Rows - 1;
 
-	if (prev_line != curwin->w_cursor.lnum && !ex_no_reprint)
-	{
-	    if (ex_pressedreturn)
-	    {
-		/* go up one line, to overwrite the ":<CR>" line, so the
-		 * output doensn't contain empty lines. */
-		msg_row = prev_msg_row;
-		if (prev_msg_row == Rows - 1)
-		    msg_row--;
-	    }
-	    msg_col = 0;
-	    print_line_no_prefix(curwin->w_cursor.lnum, FALSE);
-	    msg_clr_eos();
-	}
-	else if (ex_pressedreturn)	/* must be at EOF */
-	    EMSG(_("E501: At end-of-file"));
+	if ((prev_line != curwin->w_cursor.lnum
+		    || changedtick != curbuf->b_changedtick) && !ex_no_reprint)
+	{
+	    if (curbuf->b_ml.ml_flags & ML_EMPTY)
+		EMSG(_(e_emptybuf));
+	    else
+	    {
+		if (ex_pressedreturn)
+		{
+		    /* go up one line, to overwrite the ":<CR>" line, so the
+		     * output doensn't contain empty lines. */
+		    msg_row = prev_msg_row;
+		    if (prev_msg_row == Rows - 1)
+			msg_row--;
+		}
+		msg_col = 0;
+		print_line_no_prefix(curwin->w_cursor.lnum, FALSE, FALSE);
+		msg_clr_eos();
+	    }
+	}
+	else if (ex_pressedreturn && !ex_no_reprint)	/* must be at EOF */
+	{
+	    if (curbuf->b_ml.ml_flags & ML_EMPTY)
+		EMSG(_(e_emptybuf));
+	    else
+		EMSG(_("E501: At end-of-file"));
+	}
     }
 
 #ifdef FEAT_GUI
     --hold_gui_events;
 #endif
-    if (!improved)
-	settmode(TMODE_RAW);
     --RedrawingDisabled;
     --no_wait_return;
     update_screen(CLEAR);
@@ -1663,7 +1679,8 @@ do_one_cmd(cmdlinep, sourcing,
 	/* in ex mode, an empty line works like :+ */
 	if (*ea.cmd == NUL && exmode_active
 			&& (getline_equal(getline, cookie, getexmodeline)
-			    || getline_equal(getline, cookie, getexline)))
+			    || getline_equal(getline, cookie, getexline))
+			&& curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
 	{
 	    ea.cmd = (char_u *)"+";
 	    ex_pressedreturn = TRUE;
@@ -1671,7 +1688,10 @@ do_one_cmd(cmdlinep, sourcing,
 
 	/* ignore comment and empty lines */
 	if (*ea.cmd == '"' || *ea.cmd == NUL)
+	{
+	    ex_pressedreturn = TRUE;
 	    goto doend;
+	}
 
 /*
  * 2. handle command modifiers.
@@ -1936,7 +1956,7 @@ do_one_cmd(cmdlinep, sourcing,
 	 */
 	if (ea.skip)	    /* skip this if inside :if */
 	    goto doend;
-	if (*ea.cmd == '|')
+	if (*ea.cmd == '|' || (exmode_active && ea.line1 != ea.line2))
 	{
 	    ea.cmdidx = CMD_print;
 	    ea.argt = RANGE+COUNT+TRLBAR;
@@ -1948,14 +1968,12 @@ do_one_cmd(cmdlinep, sourcing,
 	}
 	else if (ea.addr_count != 0)
 	{
-	    if (ea.line2 < 0)
-		errormsg = invalid_range(&ea);
+	    if (ea.line2 < 0 || ea.line2 > curbuf->b_ml.ml_line_count)
+		errormsg = (char_u *)_(e_invrange);
 	    else
 	    {
 		if (ea.line2 == 0)
 		    curwin->w_cursor.lnum = 1;
-		else if (ea.line2 > curbuf->b_ml.ml_line_count)
-		    curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
 		else
 		    curwin->w_cursor.lnum = ea.line2;
 		beginline(BL_SOL | BL_FIX);
@@ -2090,7 +2108,7 @@ do_one_cmd(cmdlinep, sourcing,
 	 */
 	if (!global_busy && ea.line1 > ea.line2)
 	{
-	    if (sourcing)
+	    if (sourcing || exmode_active)
 	    {
 		errormsg = (char_u *)_("E493: Backwards range given");
 		goto doend;
@@ -2280,9 +2298,13 @@ do_one_cmd(cmdlinep, sourcing,
 
     /*
      * Check for <newline> to end a shell command.
-     * Also do this for ":read !cmd" and ":write !cmd".
+     * Also do this for ":read !cmd", ":write !cmd" and ":global".
+     * Any others?
      */
-    else if (ea.cmdidx == CMD_bang || ea.usefilter)
+    else if (ea.cmdidx == CMD_bang
+	    || ea.cmdidx == CMD_global
+	    || ea.cmdidx == CMD_vglobal
+	    || ea.usefilter)
     {
 	for (p = ea.arg; *p; ++p)
 	{
@@ -2367,6 +2389,12 @@ do_one_cmd(cmdlinep, sourcing,
 		ea.line2 = curbuf->b_ml.ml_line_count;
 	}
     }
+
+    /*
+     * Check for flags: 'l', 'p' and '#'.
+     */
+    if (ea.argt & EXFLAGS)
+	get_flags(&ea);
 						/* no arguments allowed */
     if (!ni && !(ea.argt & EXTRA) && *ea.arg != NUL
 			      && vim_strchr((char_u *)"|\"", *ea.arg) == NULL)
@@ -2661,6 +2689,7 @@ find_command(eap, full)
 {
     int		len;
     char_u	*p;
+    int		i;
 
     /*
      * Isolate the command and search for it in the command table.
@@ -2669,6 +2698,7 @@ find_command(eap, full)
      * - the 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r'
      *	    but :sre[wind] is another command, as are :scrip[tnames],
      *	    :scs[cope], :sim[alt], :sig[ns] and :sil[ent].
+     * - the "d" command can directly be followed by 'l' or 'p' flag.
      */
     p = eap->cmd;
     if (*p == 'k')
@@ -2694,6 +2724,22 @@ find_command(eap, full)
 	if (p == eap->cmd && vim_strchr((char_u *)"@*!=><&~#", *p) != NULL)
 	    ++p;
 	len = (int)(p - eap->cmd);
+	if (*eap->cmd == 'd' && (p[-1] == 'l' || p[-1] == 'p'))
+	{
+	    /* Check for ":dl", ":dell", etc. to ":deletel": that's
+	     * :delete with the 'l' flag.  Same for 'p'. */
+	    for (i = 0; i < len; ++i)
+		if (eap->cmd[i] != "delete"[i])
+		    break;
+	    if (i == len - 1)
+	    {
+		--len;
+		if (p[-1] == 'l')
+		    eap->flags |= EXFLAG_LIST;
+		else
+		    eap->flags |= EXFLAG_PRINT;
+	    }
+	}
 
 	if (ASCII_ISLOWER(*eap->cmd))
 	    eap->cmdidx = cmdidxs[CharOrdLow(*eap->cmd)];
@@ -2928,8 +2974,6 @@ set_one_cmd_context(xp, buff)
 /*
  * 4. parse command
  */
-
-    cmd = skipwhite(cmd);
     xp->xp_pattern = cmd;
     if (*cmd == NUL)
 	return NULL;
@@ -3281,6 +3325,7 @@ set_one_cmd_context(xp, buff)
 	case CMD_botright:
 	case CMD_browse:
 	case CMD_confirm:
+	case CMD_debug:
 	case CMD_folddoclosed:
 	case CMD_folddoopen:
 	case CMD_hide:
@@ -3633,6 +3678,7 @@ set_one_cmd_context(xp, buff)
  * Backslashed delimiters after / or ? will be skipped, and commands will
  * not be expanded between /'s and ?'s or after "'".
  *
+ * Also skip white space and ":" characters.
  * Returns the "cmd" pointer advanced to beyond the range.
  */
     char_u *
@@ -3642,8 +3688,7 @@ skip_range(cmd, ctx)
 {
     int		delim;
 
-    while (*cmd != NUL && (vim_isspace(*cmd) || VIM_ISDIGIT(*cmd) ||
-			    vim_strchr((char_u *)".$%'/?-+,;", *cmd) != NULL))
+    while (vim_strchr((char_u *)" \t0123456789.$%'/?-+,;", *cmd) != NULL)
     {
 	if (*cmd == '\'')
 	{
@@ -3662,6 +3707,11 @@ skip_range(cmd, ctx)
 	if (*cmd != NUL)
 	    ++cmd;
     }
+
+    /* Skip ":" and white space. */
+    while (*cmd == ':')
+	cmd = skipwhite(cmd + 1);
+
     return cmd;
 }
 
@@ -3856,6 +3906,25 @@ error:
 }
 
 /*
+ * Get flags from an Ex command argument.
+ */
+    static void
+get_flags(eap)
+    exarg_T *eap;
+{
+    while (vim_strchr((char_u *)"lp#", *eap->arg) != NULL)
+    {
+	if (*eap->arg == 'l')
+	    eap->flags |= EXFLAG_LIST;
+	else if (*eap->arg == 'p')
+	    eap->flags |= EXFLAG_PRINT;
+	else
+	    eap->flags |= EXFLAG_NR;
+	eap->arg = skipwhite(eap->arg + 1);
+    }
+}
+
+/*
  * Function called for command which is Not Implemented.  NI!
  */
     void
@@ -4280,7 +4349,7 @@ separate_nextcmd(eap)
 
 #ifdef FEAT_EVAL
 	/* Skip over `=expr` when wildcards are expanded. */
-	else if (p[0] == '`' && p[1] == '=')
+	else if (p[0] == '`' && p[1] == '=' && (eap->argt & XFILE))
 	{
 	    p += 2;
 	    (void)skip_expr(&p);
@@ -6116,31 +6185,27 @@ ex_exit(eap)
 ex_print(eap)
     exarg_T	*eap;
 {
-    int		save_list = 0;	    /* init for GCC */
-
-    if (eap->cmdidx == CMD_list)
-    {
-	save_list = curwin->w_p_list;
-	curwin->w_p_list = 1;
-    }
-
-    for ( ;!got_int; ui_breakcheck())
-    {
-	print_line(eap->line1,
-		   (eap->cmdidx == CMD_number || eap->cmdidx == CMD_pound));
-	if (++eap->line1 > eap->line2)
-	    break;
-	out_flush();	    /* show one line at a time */
-    }
-    setpcmark();
-    /* put cursor at last line */
-    curwin->w_cursor.lnum = eap->line2;
-    beginline(BL_SOL | BL_FIX);
+    if (curbuf->b_ml.ml_flags & ML_EMPTY)
+	EMSG(_(e_emptybuf));
+    else
+    {
+	for ( ;!got_int; ui_breakcheck())
+	{
+	    print_line(eap->line1,
+		    (eap->cmdidx == CMD_number || eap->cmdidx == CMD_pound
+						 || (eap->flags & EXFLAG_NR)),
+		    eap->cmdidx == CMD_list || (eap->flags & EXFLAG_LIST));
+	    if (++eap->line1 > eap->line2)
+		break;
+	    out_flush();	    /* show one line at a time */
+	}
+	setpcmark();
+	/* put cursor at last line */
+	curwin->w_cursor.lnum = eap->line2;
+	beginline(BL_SOL | BL_FIX);
+    }
 
     ex_no_reprint = TRUE;
-
-    if (eap->cmdidx == CMD_list)
-	curwin->w_p_list = save_list;
 }
 
 #ifdef FEAT_BYTEOFF
@@ -6689,7 +6754,45 @@ ex_find(eap)
 }
 
 /*
- * ":edit", ":badd".
+ * ":open" simulation: for now just work like ":visual".
+ */
+    static void
+ex_open(eap)
+    exarg_T	*eap;
+{
+    regmatch_T	regmatch;
+    char_u	*p;
+
+    curwin->w_cursor.lnum = eap->line2;
+    beginline(BL_SOL | BL_FIX);
+    if (*eap->arg == '/')
+    {
+	/* ":open /pattern/": put cursor in column found with pattern */
+	++eap->arg;
+	p = skip_regexp(eap->arg, '/', p_magic, NULL);
+	*p = NUL;
+	regmatch.regprog = vim_regcomp(eap->arg, p_magic ? RE_MAGIC : 0);
+	if (regmatch.regprog != NULL)
+	{
+	    regmatch.rm_ic = p_ic;
+	    p = ml_get_curline();
+	    if (vim_regexec(&regmatch, p, (colnr_T)0))
+		curwin->w_cursor.col = regmatch.startp[0] - p;
+	    else
+		EMSG(_(e_nomatch));
+	    vim_free(regmatch.regprog);
+	}
+	/* Move to the NUL, ignore any other arguments. */
+	eap->arg += STRLEN(eap->arg);
+    }
+    check_cursor();
+
+    eap->cmdidx = CMD_visual;
+    do_exedit(eap, NULL);
+}
+
+/*
+ * ":edit", ":badd", ":visual".
  */
     static void
 ex_edit(eap)
@@ -6711,6 +6814,7 @@ do_exedit(eap, old_curwin)
 #ifdef FEAT_WINDOWS
     int		need_hide;
 #endif
+    int		exmode_was = exmode_active;
 
     /*
      * ":vi" command ends Ex mode.
@@ -6720,7 +6824,45 @@ do_exedit(eap, old_curwin)
     {
 	exmode_active = FALSE;
 	if (*eap->arg == NUL)
+	{
+	    /* Special case:  ":global/pat/visual\NLvi-commands" */
+	    if (global_busy)
+	    {
+		int	rd = RedrawingDisabled;
+		int	nwr = no_wait_return;
+		int	ms = msg_scroll;
+#ifdef FEAT_GUI
+		int	he = hold_gui_events;
+#endif
+
+		if (eap->nextcmd != NULL)
+		{
+		    stuffReadbuff(eap->nextcmd);
+		    eap->nextcmd = NULL;
+		}
+
+		if (exmode_was != EXMODE_VIM)
+		    settmode(TMODE_RAW);
+		RedrawingDisabled = 0;
+		no_wait_return = 0;
+		need_wait_return = FALSE;
+		msg_scroll = 0;
+#ifdef FEAT_GUI
+		hold_gui_events = 0;
+#endif
+		must_redraw = CLEAR;
+
+		main_loop(FALSE, TRUE);
+
+		RedrawingDisabled = rd;
+		no_wait_return = nwr;
+		msg_scroll = ms;
+#ifdef FEAT_GUI
+		hold_gui_events = he;
+#endif
+	    }
 	    return;
+	}
     }
 
     if ((eap->cmdidx == CMD_new
@@ -6961,7 +7103,9 @@ ex_syncbind(eap)
 ex_read(eap)
     exarg_T	*eap;
 {
-    int	    i;
+    int		i;
+    int		empty = (curbuf->b_ml.ml_flags & ML_EMPTY);
+    linenr_T	lnum;
 
     if (eap->usefilter)			/* :r!cmd */
 	do_bang(1, eap, FALSE, FALSE, TRUE);
@@ -7011,7 +7155,25 @@ ex_read(eap)
 		EMSG2(_(e_notopen), eap->arg);
 	}
 	else
+	{
+	    if (empty && exmode_active)
+	    {
+		/* Delete the empty line that remains.  Historically ex does
+		 * this but vi doesn't. */
+		if (eap->line2 == 0)
+		    lnum = curbuf->b_ml.ml_line_count;
+		else
+		    lnum = 1;
+		if (*ml_get(lnum) == NUL)
+		{
+		    ml_delete(lnum, FALSE);
+		    deleted_lines_mark(lnum, 1L);
+		    if (curwin->w_cursor.lnum >= lnum)
+			--curwin->w_cursor.lnum;
+		}
+	    }
 	    redraw_curbuf_later(VALID);
+	}
     }
 }
 
@@ -7034,6 +7196,13 @@ ex_cd(eap)
     else
 #endif
     {
+	if (vim_strchr(p_cpo, CPO_CHDIR) != NULL && curbufIsChanged()
+							     && !eap->forceit)
+	{
+	    EMSG(_("E747: Cannot change directory, buffer is modifed (add ! to override)"));
+	    return;
+	}
+
 	/* ":cd -": Change to previous directory */
 	if (STRCMP(new_dir, "-") == 0)
 	{
@@ -7132,6 +7301,7 @@ ex_equal(eap)
     exarg_T	*eap;
 {
     smsg((char_u *)"%ld", (long)eap->line2);
+    ex_may_print(eap);
 }
 
     static void
@@ -7361,6 +7531,7 @@ ex_operators(eap)
 #ifdef FEAT_VIRTUALEDIT
     virtual_op = MAYBE;
 #endif
+    ex_may_print(eap);
 }
 
 /*
@@ -7377,7 +7548,8 @@ ex_put(eap)
 	eap->forceit = TRUE;
     }
     curwin->w_cursor.lnum = eap->line2;
-    do_put(eap->regname, eap->forceit ? BACKWARD : FORWARD, 1L, PUT_LINE);
+    do_put(eap->regname, eap->forceit ? BACKWARD : FORWARD, 1L,
+						       PUT_LINE|PUT_CURSLINE);
 }
 
 /*
@@ -7395,6 +7567,7 @@ ex_copymove(eap)
 	eap->nextcmd = NULL;
 	return;
     }
+    get_flags(eap);
 
     /*
      * move or copy lines from 'eap->line1'-'eap->line2' to below line 'n'
@@ -7414,6 +7587,22 @@ ex_copymove(eap)
 	ex_copy(eap->line1, eap->line2, n);
     u_clearline();
     beginline(BL_SOL | BL_FIX);
+    ex_may_print(eap);
+}
+
+/*
+ * Print the current line if flags were given to the Ex command.
+ */
+    static void
+ex_may_print(eap)
+    exarg_T	*eap;
+{
+    if (eap->flags != 0)
+    {
+	print_line(curwin->w_cursor.lnum, (eap->flags & EXFLAG_NR),
+						  (eap->flags & EXFLAG_LIST));
+	ex_no_reprint = TRUE;
+    }
 }
 
 /*
@@ -7451,6 +7640,7 @@ ex_join(eap)
     }
     do_do_join(eap->line2 - eap->line1 + 1, !eap->forceit);
     beginline(BL_WHITE | BL_FIX);
+    ex_may_print(eap);
 }
 
 /*
@@ -7474,7 +7664,9 @@ ex_at(eap)
 	c = '@';
     /* put the register in mapbuf */
     if (do_execreg(c, TRUE, vim_strchr(p_cpo, CPO_EXECBUF) != NULL) == FAIL)
+    {
 	beep_flush();
+    }
     else
     {
 	int	save_efr = exec_from_reg;
@@ -7602,18 +7794,36 @@ ex_redir(eap)
 		    /* make register empty */
 		    write_reg_contents(redir_reg, (char_u *)"", -1, FALSE);
 		}
-		if (*arg != NUL)
-		    EMSG2(_(e_invarg2), eap->arg);
+	    }
+	    if (*arg != NUL)
+	    {
+		EMSG2(_(e_invarg2), eap->arg);
+		redir_reg = 0;
+	    }
+	}
+	else if (*arg == '=' && arg[1] == '>')
+	{
+	    int append;
+
+	    /* redirect to a variable */
+	    close_redir();
+	    arg += 2;
+
+	    if (*arg == '>')
+	    {
+		++arg;
+		append = TRUE;
 	    }
 	    else
-		EMSG2(_(e_invarg2), eap->arg);
+		append = FALSE;
+
+	    if (var_redir_start(skipwhite(arg), append) == OK)
+		redir_vname = 1;
 	}
 #endif
 
 	/* TODO: redirect to a buffer */
 
-	/* TODO: redirect to an internal variable */
-
 	else
 	    EMSG2(_(e_invarg2), eap->arg);
     }
@@ -7690,6 +7900,11 @@ close_redir()
     }
 #ifdef FEAT_EVAL
     redir_reg = 0;
+    if (redir_vname)
+    {
+	var_redir_stop();
+	redir_vname = 0;
+    }
 #endif
 }
 
@@ -7774,8 +7989,7 @@ ex_mkrc(eap)
 #if defined(FEAT_SESSION) && defined(vim_mkdir)
     /* When using 'viewdir' may have to create the directory. */
     if (using_vdir && !mch_isdir(p_vdir))
-	if (vim_mkdir(p_vdir, 0755) != 0)
-	    EMSG2(_("E739: Cannot create directory: %s"), p_vdir);
+	vim_mkdir_emsg(p_vdir, 0755);
 #endif
 
     fd = open_exfile(fname, eap->forceit, WRITEBIN);
@@ -7893,6 +8107,22 @@ theend:
 #endif
 }
 
+#if ((defined(FEAT_SESSION) || defined(FEAT_EVAL)) && defined(vim_mkdir)) \
+	|| defined(PROTO)
+    int
+vim_mkdir_emsg(name, prot)
+    char_u	*name;
+    int		prot;
+{
+    if (vim_mkdir(name, prot) != 0)
+    {
+	EMSG2(_("E739: Cannot create directory: %s"), name);
+	return FAIL;
+    }
+    return OK;
+}
+#endif
+
 /*
  * Open a file for writing for an Ex command, with some checks.
  * Return file descriptor, or NULL on failure.
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -140,10 +140,6 @@ static int get_mac_fio_flags __ARGS((cha
 #endif
 static int move_lines __ARGS((buf_T *frombuf, buf_T *tobuf));
 
-static linenr_T	write_no_eol_lnum = 0;	/* non-zero lnum when last line of
-					   next binary write should not have
-					   an end-of-line */
-
     void
 filemess(buf, name, s, attr)
     buf_T	*buf;
@@ -288,9 +284,7 @@ readfile(fname, sfname, from, lines_to_s
     int		conv_restlen = 0;	/* nr of bytes in conv_rest[] */
 #endif
 
-#ifdef FEAT_AUTOCMD
     write_no_eol_lnum = 0;	/* in case it was set by the previous read */
-#endif
 
     /*
      * If there is no file name yet, use the one for the read file.
@@ -308,6 +302,10 @@ readfile(fname, sfname, from, lines_to_s
 	    curbuf->b_flags |= BF_NOTEDITED;
     }
 
+    /* After reading a file the cursor line changes but we don't want to
+     * display the line. */
+    ex_no_reprint = TRUE;
+
     /*
      * For Unix: Use the short file name whenever possible.
      * Avoids problems with networks and when directory names are changed.
@@ -2230,7 +2228,6 @@ failed:
     check_marks_read();
 #endif
 
-#ifdef FEAT_AUTOCMD
     /*
      * Trick: We remember if the last line of the read didn't have
      * an eol for when writing it again.  This is required for
@@ -2238,6 +2235,7 @@ failed:
      */
     write_no_eol_lnum = read_no_eol_lnum;
 
+#ifdef FEAT_AUTOCMD
     if (!read_stdin && !read_buffer)
     {
 	int m = msg_scroll;
@@ -2628,6 +2626,10 @@ buf_write(buf, fname, sfname, start, end
 # endif
 #endif
 
+    /* After writing a file changedtick changes but we don't want to display
+     * the line. */
+    ex_no_reprint = TRUE;
+
     /*
      * If there is no file name yet, use the one for the written file.
      * BF_NOTEDITED is set to reflect this (in case the write fails).
@@ -6267,7 +6269,7 @@ buf_store_time(buf, st, fname)
 write_lnum_adjust(offset)
     linenr_T	offset;
 {
-    if (write_no_eol_lnum)		/* only if there is a missing eol */
+    if (write_no_eol_lnum != 0)		/* only if there is a missing eol */
 	write_no_eol_lnum += offset;
 }
 
--- a/src/globals.h
+++ b/src/globals.h
@@ -155,6 +155,7 @@ EXTERN int	did_endif INIT(= FALSE);    /
 EXTERN int	did_emsg;		    /* set by emsg() when the message
 					       is displayed or thrown */
 EXTERN int	called_emsg;		    /* always set by emsg() */
+EXTERN int	ex_exitval INIT(= 0);	    /* exit value for ex mode */
 EXTERN int	emsg_on_display INIT(= FALSE);	/* there is an error message */
 EXTERN int	rc_did_emsg INIT(= FALSE);  /* vim_regcomp() called emsg() */
 
@@ -181,6 +182,7 @@ EXTERN int	x_force_connect INIT(= FALSE)
 						  "exclude" in 'clipboard'. */
 # endif
 #endif
+EXTERN int	ex_keep_indent INIT(= FALSE); /* getexmodeline(): keep indent */
 EXTERN int	vgetc_busy INIT(= FALSE);   /* inside vgetc() now */
 
 EXTERN int	didset_vim INIT(= FALSE);   /* did set $VIM ourselves */
@@ -927,6 +929,10 @@ EXTERN int	autocmd_bufnr INIT(= 0);     
 EXTERN char_u	*autocmd_match INIT(= NULL); /* name for <amatch> on cmdline */
 #endif
 
+EXTERN linenr_T	write_no_eol_lnum INIT(= 0); /* non-zero lnum when last line
+						of next binary write should
+						not have an end-of-line */
+
 #ifdef FEAT_WINDOWS
 EXTERN int	postponed_split INIT(= 0);  /* for CTRL-W CTRL-] command */
 EXTERN int	postponed_split_flags INIT(= 0);  /* args for win_split() */
@@ -957,6 +963,7 @@ EXTERN int  redir_off INIT(= FALSE);	/* 
 EXTERN FILE *redir_fd INIT(= NULL);	/* message redirection file */
 #ifdef FEAT_EVAL
 EXTERN int  redir_reg INIT(= 0);	/* message redirection register */
+EXTERN int  redir_vname INIT(= 0);	/* message redirection variable */
 #endif
 
 #ifdef FEAT_LANGMAP
@@ -1399,14 +1406,12 @@ EXTERN char_u e_invexprmsg[]	INIT(=N_("E
 EXTERN char_u e_guarded[]	INIT(=N_("E463: Region is guarded, cannot modify"));
 EXTERN char_u e_nbreadonly[]	INIT(=N_("E744: NetBeans does not allow changes in read-only files"));
 #endif
-#if defined(FEAT_EVAL) || defined(FEAT_SYN_HL)
 EXTERN char_u e_intern2[]	INIT(=N_("E685: Internal error: %s"));
-#endif
 #if defined(HAVE_SETJMP_H) || defined(HAVE_TRY_EXCEPT)
 EXTERN char_u e_complex[]	INIT(=N_("E361: Crash intercepted; regexp too complex?"));
 #endif
 EXTERN char_u e_outofstack[]	INIT(=N_("E363: pattern caused out-of-stack error"));
-
+EXTERN char_u e_emptybuf[]	INIT(=N_("E749: empty buffer"));
 
 #ifdef MACOS_X_UNIX
 EXTERN short disallow_gui	INIT(= FALSE);
--- a/src/mbyte.c
+++ b/src/mbyte.c
@@ -2871,12 +2871,16 @@ enc_locale()
 # ifdef HAVE_NL_LANGINFO_CODESET
     if ((s = nl_langinfo(CODESET)) == NULL || *s == NUL)
 # endif
-# if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
+# ifdef MACOS
+	s = "utf-8";
+# else
+#  if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
 	if ((s = setlocale(LC_CTYPE, NULL)) == NULL || *s == NUL)
-# endif
+#  endif
 	    if ((s = getenv("LC_ALL")) == NULL || *s == NUL)
 		if ((s = getenv("LC_CTYPE")) == NULL || *s == NUL)
 		    s = getenv("LANG");
+# endif
 
     if (s == NULL || *s == NUL)
 	return FAIL;
@@ -5578,6 +5582,7 @@ convert_setup(vcp, from, to)
 # endif
     if (vcp->vc_type == CONV_NONE)
 	return FAIL;
+
     return OK;
 }
 
--- a/src/message.c
+++ b/src/message.c
@@ -518,6 +518,7 @@ emsg(s)
 #endif
 
     called_emsg = TRUE;
+    ex_exitval = 1;
 
     /*
      * If "emsg_severe" is TRUE: When an error exception is to be thrown,
@@ -533,7 +534,7 @@ emsg(s)
      * If 'debug' is set: do error message anyway, but without side effects.
      * If "emsg_skip" is set: never do error messages.
      */
-    if ((emsg_off > 0 && *p_debug == NUL)
+    if ((emsg_off > 0 && vim_strchr(p_debug, 'm') == NULL)
 #ifdef FEAT_EVAL
 	    || emsg_skip > 0
 #endif
@@ -638,7 +639,7 @@ emsg2(s, a1)
 emsg3(s, a1, a2)
     char_u *s, *a1, *a2;
 {
-    if ((emsg_off > 0 && *p_debug == NUL)
+    if ((emsg_off > 0 && vim_strchr(p_debug, 'm') == NULL)
 #ifdef FEAT_EVAL
 	    || emsg_skip > 0
 #endif
@@ -667,7 +668,7 @@ emsgn(s, n)
     char_u	*s;
     long	n;
 {
-    if ((emsg_off > 0 && *p_debug == NUL)
+    if ((emsg_off > 0 && vim_strchr(p_debug, 'm') == NULL)
 #ifdef FEAT_EVAL
 	    || emsg_skip > 0
 #endif
@@ -677,6 +678,13 @@ emsgn(s, n)
     return emsg(IObuff);
 }
 
+    void
+emsg_invreg(name)
+    int	    name;
+{
+    EMSG2(_("E354: Invalid register name: '%s'"), transchar(name));
+}
+
 /*
  * Like msg(), but truncate to a single line if p_shm contains 't', or when
  * "force" is TRUE.  This truncates in another way as for normal messages.
@@ -1481,8 +1489,9 @@ str2specialbuf(sp, buf, len)
  * print line for :print or :list command
  */
     void
-msg_prt_line(s)
+msg_prt_line(s, list)
     char_u	*s;
+    int		list;
 {
     int		c;
     int		col = 0;
@@ -1497,8 +1506,11 @@ msg_prt_line(s)
     char_u	buf[MB_MAXBYTES + 1];
 #endif
 
+    if (curwin->w_p_list)
+	list = TRUE;
+
     /* find start of trailing whitespace */
-    if (curwin->w_p_list && lcs_trail)
+    if (list && lcs_trail)
     {
 	trail = s + STRLEN(s);
 	while (trail > s && vim_iswhite(trail[-1]))
@@ -1507,7 +1519,7 @@ msg_prt_line(s)
 
     /* output a space for an empty line, otherwise the line will be
      * overwritten */
-    if (*s == NUL && !(curwin->w_p_list && lcs_eol != NUL))
+    if (*s == NUL && !(list && lcs_eol != NUL))
 	msg_putchar(' ');
 
     for (;;)
@@ -1535,11 +1547,11 @@ msg_prt_line(s)
 	{
 	    attr = 0;
 	    c = *s++;
-	    if (c == TAB && (!curwin->w_p_list || lcs_tab1))
+	    if (c == TAB && (!list || lcs_tab1))
 	    {
 		/* tab amount depends on current column */
 		n_extra = curbuf->b_p_ts - col % curbuf->b_p_ts - 1;
-		if (!curwin->w_p_list)
+		if (!list)
 		{
 		    c = ' ';
 		    c_extra = ' ';
@@ -1551,7 +1563,7 @@ msg_prt_line(s)
 		    attr = hl_attr(HLF_8);
 		}
 	    }
-	    else if (c == NUL && curwin->w_p_list && lcs_eol != NUL)
+	    else if (c == NUL && list && lcs_eol != NUL)
 	    {
 		p_extra = (char_u *)"";
 		c_extra = NUL;
@@ -2521,7 +2533,7 @@ redir_write(str, maxlen)
 
     if ((redir_fd != NULL
 #ifdef FEAT_EVAL
-			  || redir_reg
+			  || redir_reg || redir_vname
 #endif
 				       ) && !redir_off)
     {
@@ -2533,6 +2545,8 @@ redir_write(str, maxlen)
 #ifdef FEAT_EVAL
 		if (redir_reg)
 		    write_reg_contents(redir_reg, (char_u *)" ", -1, TRUE);
+		else if (redir_vname)
+		    var_redir_str((char_u *)" ", -1);
 		else if (redir_fd)
 #endif
 		    fputs(" ", redir_fd);
@@ -2543,13 +2557,15 @@ redir_write(str, maxlen)
 #ifdef FEAT_EVAL
 	if (redir_reg)
 	    write_reg_contents(redir_reg, s, maxlen, TRUE);
+	if (redir_vname)
+	    var_redir_str(s, maxlen);
 #endif
 
 	/* Adjust the current column */
 	while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen))
 	{
 #ifdef FEAT_EVAL
-	    if (!redir_reg && redir_fd != NULL)
+	    if (!redir_reg && !redir_vname && redir_fd != NULL)
 #endif
 		putc(*s, redir_fd);
 	    if (*s == '\r' || *s == '\n')
--- a/src/netbeans.c
+++ b/src/netbeans.c
@@ -114,14 +114,12 @@ BalloonEval	*balloonEval = NULL;
 
 #ifdef FEAT_GUI_MOTIF
 static void netbeans_Xt_connect __ARGS((void *context));
-#else
-# ifdef FEAT_GUI_GTK
+#endif
+#ifdef FEAT_GUI_GTK
 static void netbeans_gtk_connect __ARGS((void));
-# else
-#  ifdef FEAT_GUI_W32
+#endif
+#ifdef FEAT_GUI_W32
 static void netbeans_w32_connect __ARGS((void));
-#  endif
-# endif
 #endif
 
 static int dosetvisible = FALSE;
@@ -2559,6 +2557,10 @@ netbeans_startup_done(void)
 #else
 # ifdef FEAT_GUI_GTK
 	netbeans_gtk_connect();
+# else
+#  ifdef FEAT_GUI_W32
+	netbeans_w32_connect();
+#  endif
 # endif
 #endif
 
--- a/src/normal.c
+++ b/src/normal.c
@@ -232,7 +232,11 @@ static const struct nv_cmd
     {Ctrl_N,	nv_down,	NV_STS,			FALSE},
     {Ctrl_O,	nv_ctrlo,	0,			0},
     {Ctrl_P,	nv_up,		NV_STS,			FALSE},
+#ifdef FEAT_VISUAL
+    {Ctrl_Q,	nv_visual,	0,			FALSE},
+#else
     {Ctrl_Q,	nv_ignore,	0,			0},
+#endif
     {Ctrl_R,	nv_redo,	0,			0},
     {Ctrl_S,	nv_ignore,	0,			0},
     {Ctrl_T,	nv_tagpop,	NV_NCW,			0},
@@ -6852,11 +6856,15 @@ nv_regname(cap)
  * Handle "v", "V" and "CTRL-V" commands.
  * Also for "gh", "gH" and "g^H" commands: Always start Select mode, cap->arg
  * is TRUE.
+ * Handle CTRL-Q just like CTRL-V.
  */
     static void
 nv_visual(cap)
     cmdarg_T	*cap;
 {
+    if (cap->cmdchar == Ctrl_Q)
+	cap->cmdchar = Ctrl_V;
+
     /* 'v', 'V' and CTRL-V can be used while an operator is pending to make it
      * characterwise, linewise, or blockwise. */
     if (cap->oap->op_type != OP_NOP)
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -165,6 +165,7 @@ static int sig_alarm_called;
 #endif
 static RETSIGTYPE deathtrap __ARGS(SIGPROTOARG);
 
+static void catch_int_signal __ARGS((void));
 static void set_signals __ARGS((void));
 static void catch_signals __ARGS((RETSIGTYPE (*func_deadly)(), RETSIGTYPE (*func_other)()));
 #ifndef __EMX__
@@ -175,6 +176,14 @@ static int  have_dollars __ARGS((int, ch
 #ifndef NO_EXPANDPATH
 static int	pstrcmp __ARGS((const void *, const void *));
 static int	unix_expandpath __ARGS((garray_T *gap, char_u *path, int wildoff, int flags));
+# if defined(MACOS_X) && defined(FEAT_MBYTE)
+extern char_u	*mac_precompose_path __ARGS((char_u *decompPath, size_t decompLen, size_t *precompLen));
+# endif
+#endif
+
+#if defined(MACOS_X) && defined(FEAT_MBYTE)
+extern void	mac_conv_init __ARGS((void));
+extern void	mac_conv_cleanup __ARGS((void));
 #endif
 
 #ifndef __EMX__
@@ -1083,6 +1092,10 @@ mch_init()
 
     out_flush();
     set_signals();
+
+#if defined(MACOS_X) && defined(FEAT_MBYTE)
+    mac_conv_init();
+#endif
 }
 
     static void
@@ -1113,11 +1126,8 @@ set_signals()
     signal(SIGPIPE, SIG_IGN);
 #endif
 
-    /*
-     * We want to catch CTRL-C (only works while in Cooked mode).
-     */
 #ifdef SIGINT
-    signal(SIGINT, (RETSIGTYPE (*)())catch_sigint);
+    catch_int_signal();
 #endif
 
     /*
@@ -1149,6 +1159,17 @@ set_signals()
 #endif
 }
 
+#if defined(SIGINT) || defined(PROTO)
+/*
+ * Catch CTRL-C (only works while in Cooked mode).
+ */
+    static void
+catch_int_signal()
+{
+    signal(SIGINT, (RETSIGTYPE (*)())catch_sigint);
+}
+#endif
+
     void
 reset_signals()
 {
@@ -2694,6 +2715,8 @@ static void exit_scroll __ARGS((void));
     static void
 exit_scroll()
 {
+    if (silent_mode)
+	return;
     if (newline_on_exit || msg_didout)
     {
 	if (msg_use_printf())
@@ -2764,6 +2787,11 @@ mch_exit(r)
     if (gui.in_use)
 	gui_exit(r);
 #endif
+
+#if defined(MACOS_X) && defined(FEAT_MBYTE)
+    mac_conv_cleanup();
+#endif
+
 #ifdef __QNX__
     /* A core dump won't be created if the signal handler
      * doesn't return, so we can't call exit() */
@@ -3282,6 +3310,27 @@ mch_new_shellsize()
     /* Nothing to do. */
 }
 
+#ifndef USE_SYSTEM
+static void append_ga_line __ARGS((garray_T *gap));
+
+/*
+ * Append the text in "gap" below the cursor line and clear "gap".
+ */
+    static void
+append_ga_line(gap)
+    garray_T	*gap;
+{
+    /* Remove trailing CR. */
+    if (gap->ga_len > 0
+	    && !curbuf->b_p_bin
+	    && ((char_u *)gap->ga_data)[gap->ga_len - 1] == CAR)
+	--gap->ga_len;
+    ga_append(gap, NUL);
+    ml_append(curwin->w_cursor.lnum++, gap->ga_data, 0, FALSE);
+    gap->ga_len = 0;
+}
+#endif
+
     int
 mch_call_shell(cmd, options)
     char_u	*cmd;
@@ -3398,11 +3447,12 @@ mch_call_shell(cmd, options)
 
 #else /* USE_SYSTEM */	    /* don't use system(), use fork()/exec() */
 
-#define EXEC_FAILED 122	    /* Exit code when shell didn't execute.  Don't use
-			       127, some shell use that already */
+# define EXEC_FAILED 122    /* Exit code when shell didn't execute.  Don't use
+			       127, some shells use that already */
 
     char_u	*newcmd = NULL;
     pid_t	pid;
+    pid_t	wpid = 0;
     pid_t	wait_pid = 0;
 # ifdef HAVE_UNION_WAIT
     union wait	status;
@@ -3415,19 +3465,19 @@ mch_call_shell(cmd, options)
     int		i;
     char_u	*p;
     int		inquote;
+    int		pty_master_fd = -1;	    /* for pty's */
 # ifdef FEAT_GUI
-    int		pty_master_fd = -1;	    /* for pty's */
     int		pty_slave_fd = -1;
     char	*tty_name;
+# endif
     int		fd_toshell[2];	    /* for pipes */
     int		fd_fromshell[2];
     int		pipe_error = FALSE;
-#  ifdef HAVE_SETENV
+# ifdef HAVE_SETENV
     char	envbuf[50];
-#  else
+# else
     static char	envbuf_Rows[20];
     static char	envbuf_Columns[20];
-#  endif
 # endif
     int		did_settmode = FALSE; /* TRUE when settmode(TMODE_RAW) called */
 
@@ -3480,19 +3530,24 @@ mch_call_shell(cmd, options)
     }
     argv[argc] = NULL;
 
+    /*
+     * For the GUI, when writing the output into the buffer and when reading
+     * input from the buffer: Try using a pseudo-tty to get the stdin/stdout
+     * of the executed command into the Vim window.  Or use a pipe.
+     */
+    if ((options & (SHELL_READ|SHELL_WRITE))
 # ifdef FEAT_GUI
-    /*
-     * For the GUI: Try using a pseudo-tty to get the stdin/stdout of the
-     * executed command into the Vim window.  Or use a pipe.
-     */
-    if (gui.in_use && show_shell_mess)
+	    || (gui.in_use && show_shell_mess)
+# endif
+		    )
     {
+# ifdef FEAT_GUI
 	/*
 	 * Try to open a master pty.
 	 * If this works, open the slave pty.
 	 * If the slave can't be opened, close the master pty.
 	 */
-	if (p_guipty)
+	if (p_guipty && !(options & (SHELL_READ|SHELL_WRITE)))
 	{
 	    pty_master_fd = OpenPTY(&tty_name);	    /* open pty */
 	    if (pty_master_fd >= 0 && ((pty_slave_fd =
@@ -3506,6 +3561,7 @@ mch_call_shell(cmd, options)
 	 * If not opening a pty or it didn't work, try using pipes.
 	 */
 	if (pty_master_fd < 0)
+# endif
 	{
 	    pipe_error = (pipe(fd_toshell) < 0);
 	    if (!pipe_error)			    /* pipe create OK */
@@ -3526,8 +3582,6 @@ mch_call_shell(cmd, options)
     }
 
     if (!pipe_error)			/* pty or pipe opened or not used */
-# endif
-
     {
 # ifdef __BEOS__
 	beos_cleanup_read_thread();
@@ -3535,15 +3589,20 @@ mch_call_shell(cmd, options)
 	if ((pid = fork()) == -1)	/* maybe we should use vfork() */
 	{
 	    MSG_PUTS(_("\nCannot fork\n"));
+	    if ((options & (SHELL_READ|SHELL_WRITE))
 # ifdef FEAT_GUI
-	    if (gui.in_use && show_shell_mess)
+		|| (gui.in_use && show_shell_mess)
+# endif
+		    )
 	    {
+# ifdef FEAT_GUI
 		if (pty_master_fd >= 0)		/* close the pseudo tty */
 		{
 		    close(pty_master_fd);
 		    close(pty_slave_fd);
 		}
 		else				/* close the pipes */
+# endif
 		{
 		    close(fd_toshell[0]);
 		    close(fd_toshell[1]);
@@ -3551,7 +3610,6 @@ mch_call_shell(cmd, options)
 		    close(fd_fromshell[1]);
 		}
 	    }
-# endif
 	}
 	else if (pid == 0)	/* child */
 	{
@@ -3593,13 +3651,17 @@ mch_call_shell(cmd, options)
 		    close(fd);
 		}
 	    }
+	    else if ((options & (SHELL_READ|SHELL_WRITE))
 # ifdef FEAT_GUI
-	    else if (gui.in_use)
+		    || gui.in_use
+# endif
+		    )
 	    {
 
-#  ifdef HAVE_SETSID
+# ifdef HAVE_SETSID
 		(void)setsid();
-#  endif
+# endif
+# ifdef FEAT_GUI
 		/* push stream discipline modules */
 		if (options & SHELL_COOKED)
 		    SetupSlavePTY(pty_slave_fd);
@@ -3608,8 +3670,9 @@ mch_call_shell(cmd, options)
 		 * unless run by root) */
 		ioctl(pty_slave_fd, TIOCSCTTY, (char *)NULL);
 #  endif
+# endif
 		/* Simulate to have a dumb terminal (for now) */
-#  ifdef HAVE_SETENV
+# ifdef HAVE_SETENV
 		setenv("TERM", "dumb", 1);
 		sprintf((char *)envbuf, "%ld", Rows);
 		setenv("ROWS", (char *)envbuf, 1);
@@ -3617,7 +3680,7 @@ mch_call_shell(cmd, options)
 		setenv("LINES", (char *)envbuf, 1);
 		sprintf((char *)envbuf, "%ld", Columns);
 		setenv("COLUMNS", (char *)envbuf, 1);
-#  else
+# else
 		/*
 		 * Putenv does not copy the string, it has to remain valid.
 		 * Use a static array to avoid loosing allocated memory.
@@ -3629,8 +3692,9 @@ mch_call_shell(cmd, options)
 		putenv(envbuf_Rows);
 		sprintf(envbuf_Columns, "COLUMNS=%ld", Columns);
 		putenv(envbuf_Columns);
-#  endif
-
+# endif
+
+# ifdef FEAT_GUI
 		if (pty_master_fd >= 0)
 		{
 		    close(pty_master_fd);   /* close master side of pty */
@@ -3646,6 +3710,7 @@ mch_call_shell(cmd, options)
 		    close(pty_slave_fd);    /* has been dupped, close it now */
 		}
 		else
+# endif
 		{
 		    /* set up stdin for the child */
 		    close(fd_toshell[1]);
@@ -3664,7 +3729,7 @@ mch_call_shell(cmd, options)
 		    dup(1);
 		}
 	    }
-# endif /* FEAT_GUI */
+
 	    /*
 	     * There is no type cast for the argv, because the type may be
 	     * different on different machines. This may cause a warning
@@ -3679,21 +3744,27 @@ mch_call_shell(cmd, options)
 	{
 	    /*
 	     * While child is running, ignore terminating signals.
+	     * Do catch CTRL-C, so that "got_int" is set.
 	     */
 	    catch_signals(SIG_IGN, SIG_ERR);
-
-# ifdef FEAT_GUI
+	    catch_int_signal();
 
 	    /*
 	     * For the GUI we redirect stdin, stdout and stderr to our window.
+	     * This is also used to pipe stdin/stdout to/from the external
+	     * command.
 	     */
-	    if (gui.in_use && show_shell_mess)
+	    if ((options & (SHELL_READ|SHELL_WRITE))
+# ifdef FEAT_GUI
+		    || (gui.in_use && show_shell_mess)
+# endif
+	       )
 	    {
-#  define BUFLEN 100		/* length for buffer, pseudo tty limit is 128 */
+# define BUFLEN 100		/* length for buffer, pseudo tty limit is 128 */
 		char_u	    buffer[BUFLEN + 1];
-#  ifdef FEAT_MBYTE
+# ifdef FEAT_MBYTE
 		int	    buffer_off = 0;	/* valid bytes in buffer[] */
-#  endif
+# endif
 		char_u	    ta_buf[BUFLEN + 1];	/* TypeAHead */
 		int	    ta_len = 0;		/* valid bytes in ta_buf[] */
 		int	    len;
@@ -3702,7 +3773,10 @@ mch_call_shell(cmd, options)
 		int	    c;
 		int	    toshell_fd;
 		int	    fromshell_fd;
-
+		garray_T    ga;
+		int	    noread_cnt;
+
+# ifdef FEAT_GUI
 		if (pty_master_fd >= 0)
 		{
 		    close(pty_slave_fd);	/* close slave side of pty */
@@ -3710,6 +3784,7 @@ mch_call_shell(cmd, options)
 		    toshell_fd = dup(pty_master_fd);
 		}
 		else
+# endif
 		{
 		    close(fd_toshell[0]);
 		    close(fd_fromshell[1]);
@@ -3738,6 +3813,76 @@ mch_call_shell(cmd, options)
 		old_State = State;
 		State = EXTERNCMD;	/* don't redraw at window resize */
 
+		if (options & SHELL_WRITE && toshell_fd >= 0)
+		{
+		    /* Fork a process that will write the lines to the
+		     * external program. */
+		    if ((wpid = fork()) == -1)
+		    {
+			MSG_PUTS(_("\nCannot fork\n"));
+		    }
+		    else if (wpid == 0)
+		    {
+			linenr_T    lnum = curbuf->b_op_start.lnum;
+			int	    written = 0;
+			char_u	    *p = ml_get(lnum);
+			char_u	    *s;
+			size_t	    l;
+
+			/* child */
+			for (;;)
+			{
+			    l = STRLEN(p + written);
+			    if (l == 0)
+				len = 0;
+			    else if (p[written] == NL)
+				/* NL -> NUL translation */
+				len = write(toshell_fd, "", (size_t)1);
+			    else
+			    {
+				s = vim_strchr(p + written, NL);
+				len = write(toshell_fd, (char *)p + written,
+					   s == NULL ? l : s - (p + written));
+			    }
+			    if (len == l)
+			    {
+				/* Finished a line, add a NL, unless this line
+				 * should not have one. */
+				if (lnum != curbuf->b_op_end.lnum
+					|| !curbuf->b_p_bin
+					|| (lnum != write_no_eol_lnum
+					    && (lnum !=
+						    curbuf->b_ml.ml_line_count
+						    || curbuf->b_p_eol)))
+				    write(toshell_fd, "\n", (size_t)1);
+				++lnum;
+				if (lnum > curbuf->b_op_end.lnum)
+				{
+				    /* finished all the lines, close pipe */
+				    close(toshell_fd);
+				    toshell_fd = -1;
+				    break;
+				}
+				p = ml_get(lnum);
+				written = 0;
+			    }
+			    else if (len > 0)
+				written += len;
+			}
+			_exit(0);
+		    }
+		    else
+		    {
+			close(toshell_fd);
+			toshell_fd = -1;
+		    }
+		}
+
+		if (options & SHELL_READ)
+		    ga_init2(&ga, 1, BUFLEN);
+
+		noread_cnt = 0;
+
 		for (;;)
 		{
 		    /*
@@ -3745,12 +3890,15 @@ mch_call_shell(cmd, options)
 		     * if there are any.  Don't do this if we are expanding
 		     * wild cards (would eat typeahead).  Don't get extra
 		     * characters when we already have one.
+		     * Don't read characters unless we didn't get output for a
+		     * while, avoids that ":r !ls" eats typeahead.
 		     */
 		    len = 0;
 		    if (!(options & SHELL_EXPAND)
 			    && (ta_len > 0
-				|| (len = ui_inchar(ta_buf, BUFLEN, 10L,
-								     0)) > 0))
+				|| (noread_cnt > 4
+				    && (len = ui_inchar(ta_buf,
+						       BUFLEN, 10L, 0)) > 0)))
 		    {
 			/*
 			 * For pipes:
@@ -3759,19 +3907,23 @@ mch_call_shell(cmd, options)
 			 */
 			if (len == 1 && (pty_master_fd < 0 || cmd != NULL))
 			{
-#  ifdef SIGINT
+# ifdef SIGINT
 			    /*
 			     * Send SIGINT to the child's group or all
 			     * processes in our group.
 			     */
 			    if (ta_buf[ta_len] == Ctrl_C
 					       || ta_buf[ta_len] == intr_char)
-#   ifdef HAVE_SETSID
+			    {
+#  ifdef HAVE_SETSID
 				kill(-pid, SIGINT);
-#   else
+#  else
 				kill(0, SIGINT);
-#   endif
 #  endif
+				if (wpid > 0)
+				    kill(wpid, SIGINT);
+			    }
+# endif
 			    if (pty_master_fd < 0 && toshell_fd >= 0
 					       && ta_buf[ta_len] == Ctrl_D)
 			    {
@@ -3799,10 +3951,10 @@ mch_call_shell(cmd, options)
 			    }
 			    else if (ta_buf[i] == '\r')
 				ta_buf[i] = '\n';
-#  ifdef FEAT_MBYTE
+# ifdef FEAT_MBYTE
 			    if (has_mbyte)
 				i += (*mb_ptr2len_check)(ta_buf + i) - 1;
-#  endif
+# endif
 			}
 
 			/*
@@ -3815,7 +3967,7 @@ mch_call_shell(cmd, options)
 			    {
 				if (ta_buf[i] == '\n' || ta_buf[i] == '\b')
 				    msg_putchar(ta_buf[i]);
-#  ifdef FEAT_MBYTE
+# ifdef FEAT_MBYTE
 				else if (has_mbyte)
 				{
 				    int l = (*mb_ptr2len_check)(ta_buf + i);
@@ -3823,7 +3975,7 @@ mch_call_shell(cmd, options)
 				    msg_outtrans_len(ta_buf + i, l);
 				    i += l - 1;
 				}
-#  endif
+# endif
 				else
 				    msg_outtrans_len(ta_buf + i, 1);
 			    }
@@ -3837,18 +3989,37 @@ mch_call_shell(cmd, options)
 			 * Write the characters to the child, unless EOF has
 			 * been typed for pipes.  Write one character at a
 			 * time, to avoid loosing too much typeahead.
+			 * When writing buffer lines, drop the typed
+			 * characters (only check for CTRL-C).
 			 */
-			if (toshell_fd >= 0)
+			if (options & SHELL_WRITE)
+			    ta_len = 0;
+			else if (toshell_fd >= 0)
 			{
 			    len = write(toshell_fd, (char *)ta_buf, (size_t)1);
 			    if (len > 0)
 			    {
 				ta_len -= len;
 				mch_memmove(ta_buf, ta_buf + len, ta_len);
+				noread_cnt = 0;
 			    }
 			}
 		    }
 
+		    if (got_int)
+		    {
+			/* CTRL-C sends a signal to the child, we ignore it
+			 * ourselves */
+#  ifdef HAVE_SETSID
+			kill(-pid, SIGINT);
+#  else
+			kill(0, SIGINT);
+#  endif
+			if (wpid > 0)
+			    kill(wpid, SIGINT);
+			got_int = FALSE;
+		    }
+
 		    /*
 		     * Check if the child has any characters to be printed.
 		     * Read them and write them to our window.	Repeat this as
@@ -3858,24 +4029,42 @@ mch_call_shell(cmd, options)
 		     * TODO: This should handle escape sequences, compatible
 		     * to some terminal (vt52?).
 		     */
+		    ++noread_cnt;
 		    while (RealWaitForChar(fromshell_fd, 10L, NULL))
 		    {
 			len = read(fromshell_fd, (char *)buffer
-#  ifdef FEAT_MBYTE
+# ifdef FEAT_MBYTE
 				+ buffer_off, (size_t)(BUFLEN - buffer_off)
-#  else
+# else
 				, (size_t)BUFLEN
-#  endif
+# endif
 				);
 			if (len <= 0)		    /* end of file or error */
 			    goto finished;
-#  ifdef FEAT_MBYTE
-			len += buffer_off;
-			buffer[len] = NUL;
-			if (has_mbyte)
+
+			noread_cnt = 0;
+			if (options & SHELL_READ)
+			{
+			    /* Do NUL -> NL translation, append NL separated
+			     * lines to the current buffer. */
+			    for (i = 0; i < len; ++i)
+			    {
+				if (buffer[i] == NL)
+				    append_ga_line(&ga);
+				else if (buffer[i] == NUL)
+				    ga_append(&ga, NL);
+				else
+				    ga_append(&ga, buffer[i]);
+			    }
+			}
+# ifdef FEAT_MBYTE
+			else if (has_mbyte)
 			{
 			    int		l;
 
+			    len += buffer_off;
+			    buffer[len] = NUL;
+
 			    /* Check if the last character in buffer[] is
 			     * incomplete, keep these bytes for the next
 			     * round. */
@@ -3913,8 +4102,8 @@ mch_call_shell(cmd, options)
 			    }
 			    buffer_off = 0;
 			}
+# endif /* FEAT_MBYTE */
 			else
-#  endif /* FEAT_MBYTE */
 			{
 			    buffer[len] = NUL;
 			    msg_puts(buffer);
@@ -3931,11 +4120,11 @@ mch_call_shell(cmd, options)
 		     * Check if the child still exists, before checking for
 		     * typed characters (otherwise we would loose typeahead).
 		     */
-#  ifdef __NeXT__
+# ifdef __NeXT__
 		    wait_pid = wait4(pid, &status, WNOHANG, (struct rusage *) 0);
-#  else
+# else
 		    wait_pid = waitpid(pid, &status, WNOHANG);
-#  endif
+# endif
 		    if ((wait_pid == (pid_t)-1 && errno == ECHILD)
 			    || (wait_pid == pid && WIFEXITED(status)))
 		    {
@@ -3946,20 +4135,29 @@ mch_call_shell(cmd, options)
 		}
 finished:
 		p_more = p_more_save;
-
-#  ifndef MACOS_X_UNIX /* TODO: Is it needed for MACOS_X ? */
+		if (options & SHELL_READ)
+		{
+		    if (ga.ga_len > 0)
+		    {
+			append_ga_line(&ga);
+			/* remember that the NL was missing */
+			write_no_eol_lnum = curwin->w_cursor.lnum;
+		    }
+		    else
+			write_no_eol_lnum = 0;
+		    ga_clear(&ga);
+		}
+
 		/*
 		 * Give all typeahead that wasn't used back to ui_inchar().
 		 */
 		if (ta_len)
 		    ui_inchar_undo(ta_buf, ta_len);
-#  endif
 		State = old_State;
 		if (toshell_fd >= 0)
 		    close(toshell_fd);
 		close(fromshell_fd);
 	    }
-# endif /* FEAT_GUI */
 
 	    /*
 	     * Wait until our child has exited.
@@ -3970,7 +4168,7 @@ finished:
 	     */
 	    while (wait_pid != pid)
 	    {
-#ifdef _THREAD_SAFE
+# ifdef _THREAD_SAFE
 		/* Ugly hack: when compiled with Python threads are probably
 		 * used, in which case wait() sometimes hangs for no obvious
 		 * reason.  Use waitpid() instead and loop (like the GUI). */
@@ -3985,9 +4183,9 @@ finished:
 		    mch_delay(10L, TRUE);
 		    continue;
 		}
-#else
+# else
 		wait_pid = wait(&status);
-#endif
+# endif
 		if (wait_pid <= 0
 # ifdef ECHILD
 			&& errno == ECHILD
@@ -3996,6 +4194,11 @@ finished:
 		    break;
 	    }
 
+	    /* Make sure the child that writes to the external program is
+	     * dead. */
+	    if (wpid > 0)
+		kill(wpid, SIGKILL);
+
 	    /*
 	     * Set to raw mode right now, otherwise a CTRL-C after
 	     * catch_signals() will kill Vim.
@@ -4656,7 +4859,19 @@ unix_expandpath(gap, path, wildoff, flag
 		    if (*path_end != NUL)
 			backslash_halve(buf + len + 1);
 		    if (mch_getperm(buf) >= 0)	/* add existing file */
+		    {
+#if defined(MACOS_X) && defined(FEAT_MBYTE)
+			size_t precomp_len = STRLEN(buf)+1;
+			char_u *precomp_buf =
+			    mac_precompose_path(buf, precomp_len, &precomp_len);
+			if (precomp_buf)
+			{
+			    mch_memmove(buf, precomp_buf, precomp_len);
+			    vim_free(precomp_buf);
+			}
+#endif
 			addfile(gap, buf, flags);
+		    }
 		}
 	    }
 	}
--- a/src/po/Make_ming.mak
+++ b/src/po/Make_ming.mak
@@ -10,9 +10,9 @@
 # language (xx) and add it to the next three lines.
 #
 
-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
 
--- a/src/po/Makefile
+++ b/src/po/Makefile
@@ -4,9 +4,9 @@
 # Note: ja.sjis, *.cp1250 and zh_CN.cp936 are only for MS-Windows, they are
 # not installed on Unix
 
-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
 
--- a/src/proto/ex_docmd.pro
+++ b/src/proto/ex_docmd.pro
@@ -33,6 +33,7 @@ void alist_slash_adjust __ARGS((void));
 void ex_splitview __ARGS((exarg_T *eap));
 void do_exedit __ARGS((exarg_T *eap, win_T *old_curwin));
 void do_sleep __ARGS((long msec));
+int vim_mkdir_emsg __ARGS((char_u *name, int prot));
 FILE *open_exfile __ARGS((char_u *fname, int forceit, char *mode));
 void update_topline_cursor __ARGS((void));
 void exec_normal_cmd __ARGS((char_u *cmd, int remap, int silent));
--- a/src/proto/gui_mac.pro
+++ b/src/proto/gui_mac.pro
@@ -39,6 +39,7 @@ void gui_mch_destroy_scrollbar __ARGS((s
 int gui_mch_adjust_charsize __ARGS((void));
 int gui_mch_init_font __ARGS((char_u *font_name, int fontset));
 GuiFont gui_mch_get_font __ARGS((char_u *name, int giveErrorIfMissing));
+char_u *gui_mch_get_fontname __ARGS((GuiFont font, char_u *name));
 GuiFont gui_mac_find_font __ARGS((char_u *font_name));
 void gui_mch_set_font __ARGS((GuiFont font));
 int gui_mch_same_font __ARGS((GuiFont f1, GuiFont f2));
--- a/src/proto/main.pro
+++ b/src/proto/main.pro
@@ -1,5 +1,5 @@
 /* main.c */
-void main_loop __ARGS((int cmdwin));
+void main_loop __ARGS((int cmdwin, int noexmode));
 void getout_preserve_modified __ARGS((int exitval));
 void getout __ARGS((int exitval));
 int process_env __ARGS((char_u *env, int is_viminit));
--- a/src/proto/message.pro
+++ b/src/proto/message.pro
@@ -9,6 +9,7 @@ int emsg __ARGS((char_u *s));
 int emsg2 __ARGS((char_u *s, char_u *a1));
 int emsg3 __ARGS((char_u *s, char_u *a1, char_u *a2));
 int emsgn __ARGS((char_u *s, long n));
+void emsg_invreg __ARGS((int name));
 char_u *msg_trunc_attr __ARGS((char_u *s, int force, int attr));
 char_u *msg_may_trunc __ARGS((int force, char_u *s));
 void ex_messages __ARGS((exarg_T *eap));
@@ -31,7 +32,7 @@ void msg_make __ARGS((char_u *arg));
 int msg_outtrans_special __ARGS((char_u *strstart, int from));
 char_u *str2special __ARGS((char_u **sp, int from));
 void str2specialbuf __ARGS((char_u *sp, char_u *buf, int len));
-void msg_prt_line __ARGS((char_u *s));
+void msg_prt_line __ARGS((char_u *s, int list));
 void msg_puts __ARGS((char_u *s));
 void msg_puts_title __ARGS((char_u *s));
 void msg_puts_long __ARGS((char_u *longstr));
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -1456,7 +1456,7 @@ qf_list(eap)
 		qf_fmt_text((fname != NULL || qfp->qf_lnum != 0)
 				     ? skipwhite(qfp->qf_text) : qfp->qf_text,
 							      IObuff, IOSIZE);
-		msg_prt_line(IObuff);
+		msg_prt_line(IObuff, FALSE);
 		out_flush();		/* show one line at a time */
 		need_return = TRUE;
 		last_printed = i;
@@ -2279,7 +2279,6 @@ ex_vimgrep(eap)
     exarg_T	*eap;
 {
     regmmatch_T	regmatch;
-    char_u	*save_cpo;
     int		fcount;
     char_u	**fnames;
     char_u	*s;
@@ -2317,10 +2316,6 @@ ex_vimgrep(eap)
     }
 #endif
 
-    /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
-    save_cpo = p_cpo;
-    p_cpo = empty_option;
-
     /* Get the search pattern: either white-separated or enclosed in // */
     regmatch.regprog = NULL;
     p = skip_vimgrep_pat(eap->arg, &s);
@@ -2545,12 +2540,6 @@ jumpend:
 
 theend:
     vim_free(regmatch.regprog);
-
-    /* Only resture 'cpo' when it wasn't set in the mean time. */
-    if (p_cpo == empty_option)
-	p_cpo = save_cpo;
-    else
-	free_string_option(save_cpo);
 }
 
 /*
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -74,11 +74,12 @@
  * (Here we have one of the subtle syntax dependencies:	an individual BRANCH
  * (as opposed to a collection of them) is never concatenated with anything
  * because of operator precedence).  The "next" pointer of a BRACES_COMPLEX
- * node points to the node after the stuff to be repeated.  The operand of some
- * types of node is a literal string; for others, it is a node leading into a
- * sub-FSM.  In particular, the operand of a BRANCH node is the first node of
- * the branch.	(NB this is *not* a tree structure: the tail of the branch
- * connects to the thing following the set of BRANCHes.)
+ * node points to the node after the stuff to be repeated.
+ * The operand of some types of node is a literal string; for others, it is a
+ * node leading into a sub-FSM.  In particular, the operand of a BRANCH node
+ * is the first node of the branch.
+ * (NB this is *not* a tree structure: the tail of the branch connects to the
+ * thing following the set of BRANCHes.)
  *
  * pattern	is coded like:
  *
@@ -97,6 +98,14 @@
  *		     +---------------------------------------------+
  *
  *
+ *		       +----------------------+
+ *		       V		      |
+ * <aa>\+	BRANCH <aa> --> BRANCH --> BACK BRANCH --> NOTHING --> END
+ *		     |	             |	        ^		       ^
+ *		     |	             +----------+		       |
+ *		     +-------------------------------------------------+
+ *
+ *
  *					+-------------------------+
  *					V			  |
  * <aa>\{}	BRANCH BRACE_LIMITS --> BRACE_COMPLEX <aa> --> BACK  END
@@ -386,7 +395,10 @@ static char_u REGEXP_INRANGE[] = "]^-n\\
 static char_u REGEXP_ABBR[] = "nrtebdoxuU";
 
 static int	backslash_trans __ARGS((int c));
-static int	skip_class_name __ARGS((char_u **pp));
+static int	get_char_class __ARGS((char_u **pp));
+static int	get_equi_class __ARGS((char_u **pp));
+static void	reg_equi_class __ARGS((int c));
+static int	get_coll_element __ARGS((char_u **pp));
 static char_u	*skip_anyof __ARGS((char_u *p));
 static void	init_class_tab __ARGS((void));
 
@@ -408,12 +420,12 @@ backslash_trans(c)
 }
 
 /*
- * Check for a character class name.  "pp" points to the '['.
+ * Check for a character class name "[:name:]".  "pp" points to the '['.
  * Returns one of the CLASS_ items. CLASS_NONE means that no item was
  * recognized.  Otherwise "pp" is advanced to after the item.
  */
     static int
-skip_class_name(pp)
+get_char_class(pp)
     char_u	**pp;
 {
     static const char *(class_names[]) =
@@ -467,55 +479,6 @@ skip_class_name(pp)
 }
 
 /*
- * Skip over a "[]" range.
- * "p" must point to the character after the '['.
- * The returned pointer is on the matching ']', or the terminating NUL.
- */
-    static char_u *
-skip_anyof(p)
-    char_u	*p;
-{
-    int		cpo_lit;	/* 'cpoptions' contains 'l' flag */
-#ifdef FEAT_MBYTE
-    int		l;
-#endif
-
-    cpo_lit = (!reg_syn && vim_strchr(p_cpo, CPO_LITERAL) != NULL);
-
-    if (*p == '^')	/* Complement of range. */
-	++p;
-    if (*p == ']' || *p == '-')
-	++p;
-    while (*p != NUL && *p != ']')
-    {
-#ifdef FEAT_MBYTE
-	if (has_mbyte && (l = (*mb_ptr2len_check)(p)) > 1)
-	    p += l;
-	else
-#endif
-	    if (*p == '-')
-	    {
-		++p;
-		if (*p != ']' && *p != NUL)
-		    mb_ptr_adv(p);
-	    }
-	else if (*p == '\\'
-		&& (vim_strchr(REGEXP_INRANGE, p[1]) != NULL
-		    || (!cpo_lit && vim_strchr(REGEXP_ABBR, p[1]) != NULL)))
-	    p += 2;
-	else if (*p == '[')
-	{
-	    if (skip_class_name(&p) == CLASS_NONE)
-		++p; /* It was not a class name */
-	}
-	else
-	    ++p;
-    }
-
-    return p;
-}
-
-/*
  * Specific version of character class functions.
  * Using a table to keep this fast.
  */
@@ -695,6 +658,8 @@ static char_u	*regnext __ARGS((char_u *)
 static void	regc __ARGS((int b));
 #ifdef FEAT_MBYTE
 static void	regmbc __ARGS((int c));
+#else
+# define regmbc(c) regc(c)
 #endif
 static void	reginsert __ARGS((int, char_u *));
 static void	reginsert_limits __ARGS((int, long, long, char_u *));
@@ -725,6 +690,210 @@ re_lookbehind(prog)
 }
 
 /*
+ * Check for an equivalence class name "[=a=]".  "pp" points to the '['.
+ * Returns a character representing the class. Zero means that no item was
+ * recognized.  Otherwise "pp" is advanced to after the item.
+ */
+    static int
+get_equi_class(pp)
+    char_u	**pp;
+{
+    int		c;
+    int		l = 1;
+    char_u	*p = *pp;
+
+    if (p[1] == '=')
+    {
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	    l = mb_ptr2len_check(p + 2);
+#endif
+	if (p[l + 2] == '=' && p[l + 3] == ']')
+	{
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+		c = mb_ptr2char(p + 2);
+	    else
+#endif
+		c = p[2];
+	    *pp += l + 4;
+	    return c;
+	}
+    }
+    return 0;
+}
+
+/*
+ * Produce the bytes for equivalence class "c".
+ * Currently only handles latin1, latin9 and utf-8.
+ */
+    static void
+reg_equi_class(c)
+    int	    c;
+{
+#ifdef FEAT_MBYTE
+    if (enc_utf8 || STRCMP(p_enc, "latin1") == 0
+					      || STRCMP(p_enc, "latin9") == 0)
+#endif
+    {
+	switch (c)
+	{
+	    case 'A': case 'À': case 'Á': case 'Â':
+	    case 'Ã': case 'Ä': case 'Å':
+		      regmbc('A'); regmbc('À'); regmbc('Á'); regmbc('Â');
+		      regmbc('Ã'); regmbc('Ä'); regmbc('Å');
+		      return;
+	    case 'C': case 'Ç':
+		      regmbc('C'); regmbc('Ç');
+		      return;
+	    case 'E': case 'È': case 'É': case 'Ê': case 'Ë':
+		      regmbc('E'); regmbc('È'); regmbc('É'); regmbc('Ê');
+		      regmbc('Ë');
+		      return;
+	    case 'I': case 'Ì': case 'Í': case 'Î': case 'Ï':
+		      regmbc('I'); regmbc('Ì'); regmbc('Í'); regmbc('Î');
+		      regmbc('Ï');
+		      return;
+	    case 'N': case 'Ñ':
+		      regmbc('N'); regmbc('Ñ');
+		      return;
+	    case 'O': case 'Ò': case 'Ó': case 'Ô': case 'Õ': case 'Ö':
+		      regmbc('O'); regmbc('Ò'); regmbc('Ó'); regmbc('Ô');
+		      regmbc('Õ'); regmbc('Ö');
+		      return;
+	    case 'U': case 'Ù': case 'Ú': case 'Û': case 'Ü':
+		      regmbc('U'); regmbc('Ù'); regmbc('Ú'); regmbc('Û');
+		      regmbc('Ü');
+		      return;
+	    case 'Y': case 'Ý':
+		      regmbc('Y'); regmbc('Ý');
+		      return;
+	    case 'a': case 'à': case 'á': case 'â':
+	    case 'ã': case 'ä': case 'å':
+		      regmbc('a'); regmbc('à'); regmbc('á'); regmbc('â');
+		      regmbc('ã'); regmbc('ä'); regmbc('å');
+		      return;
+	    case 'c': case 'ç':
+		      regmbc('c'); regmbc('ç');
+		      return;
+	    case 'e': case 'è': case 'é': case 'ê': case 'ë':
+		      regmbc('e'); regmbc('è'); regmbc('é'); regmbc('ê');
+		      regmbc('ë');
+		      return;
+	    case 'i': case 'ì': case 'í': case 'î': case 'ï':
+		      regmbc('i'); regmbc('ì'); regmbc('í'); regmbc('î');
+		      regmbc('ï');
+		      return;
+	    case 'n': case 'ñ':
+		      regmbc('n'); regmbc('ñ');
+		      return;
+	    case 'o': case 'ò': case 'ó': case 'ô': case 'õ': case 'ö':
+		      regmbc('o'); regmbc('ò'); regmbc('ó'); regmbc('ô');
+		      regmbc('õ'); regmbc('ö');
+		      return;
+	    case 'u': case 'ù': case 'ú': case 'û': case 'ü':
+		      regmbc('u'); regmbc('ù'); regmbc('ú'); regmbc('û');
+		      regmbc('ü');
+		      return;
+	    case 'y': case 'ý': case 'ÿ':
+		      regmbc('y'); regmbc('ý'); regmbc('ÿ');
+		      return;
+	}
+    }
+    regmbc(c);
+}
+
+/*
+ * Check for a collating element "[.a.]".  "pp" points to the '['.
+ * Returns a character. Zero means that no item was recognized.  Otherwise
+ * "pp" is advanced to after the item.
+ * Currently only single characters are recognized!
+ */
+    static int
+get_coll_element(pp)
+    char_u	**pp;
+{
+    int		c;
+    int		l = 1;
+    char_u	*p = *pp;
+
+    if (p[1] == '.')
+    {
+#ifdef FEAT_MBYTE
+	if (has_mbyte)
+	    l = mb_ptr2len_check(p + 2);
+#endif
+	if (p[l + 2] == '.' && p[l + 3] == ']')
+	{
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+		c = mb_ptr2char(p + 2);
+	    else
+#endif
+		c = p[2];
+	    *pp += l + 4;
+	    return c;
+	}
+    }
+    return 0;
+}
+
+
+/*
+ * Skip over a "[]" range.
+ * "p" must point to the character after the '['.
+ * The returned pointer is on the matching ']', or the terminating NUL.
+ */
+    static char_u *
+skip_anyof(p)
+    char_u	*p;
+{
+    int		cpo_lit;	/* 'cpoptions' contains 'l' flag */
+    int		cpo_bsl;	/* 'cpoptions' contains '\' flag */
+#ifdef FEAT_MBYTE
+    int		l;
+#endif
+
+    cpo_lit = (!reg_syn && vim_strchr(p_cpo, CPO_LITERAL) != NULL);
+    cpo_bsl = (!reg_syn && vim_strchr(p_cpo, CPO_BACKSL) != NULL);
+
+    if (*p == '^')	/* Complement of range. */
+	++p;
+    if (*p == ']' || *p == '-')
+	++p;
+    while (*p != NUL && *p != ']')
+    {
+#ifdef FEAT_MBYTE
+	if (has_mbyte && (l = (*mb_ptr2len_check)(p)) > 1)
+	    p += l;
+	else
+#endif
+	    if (*p == '-')
+	    {
+		++p;
+		if (*p != ']' && *p != NUL)
+		    mb_ptr_adv(p);
+	    }
+	else if (*p == '\\'
+		&& !cpo_bsl
+		&& (vim_strchr(REGEXP_INRANGE, p[1]) != NULL
+		    || (!cpo_lit && vim_strchr(REGEXP_ABBR, p[1]) != NULL)))
+	    p += 2;
+	else if (*p == '[')
+	{
+	    if (get_char_class(&p) == CLASS_NONE
+		    && get_equi_class(&p) == 0
+		    && get_coll_element(&p) == 0)
+		++p; /* It was not a class name */
+	}
+	else
+	    ++p;
+    }
+
+    return p;
+}
+
+/*
  * Skip past regular expression.
  * Stop at end of "startp" or where "dirc" is found ('/', '?', etc).
  * Take care of characters with a backslash in front of it.
@@ -1251,16 +1420,6 @@ regpiece(flagp)
 	*flagp = flags;
 	return ret;
     }
-    if (!(flags & HASWIDTH) && re_multi_type(op) == MULTI_MULT)
-    {
-	if (op == Magic('*'))
-	    EMSG_M_RET_NULL(_("E56: %s* operand could be empty"),
-						       reg_magic >= MAGIC_ON);
-	if (op == Magic('+'))
-	    EMSG_M_RET_NULL(_("E57: %s+ operand could be empty"),
-						       reg_magic == MAGIC_ALL);
-	/* "\{}" is checked below, it's allowed when there is an upper limit */
-    }
     /* default flags */
     *flagp = (WORST | SPSTART | (flags & (HASNL | HASLOOKBH)));
 
@@ -1338,10 +1497,6 @@ regpiece(flagp)
 	case Magic('{'):
 	    if (!read_limits(&minval, &maxval))
 		return NULL;
-	    if (!(flags & HASWIDTH) && (maxval > minval
-				 ? maxval >= MAX_LIMIT : minval >= MAX_LIMIT))
-		EMSG_M_RET_NULL(_("E58: %s{ operand could be empty"),
-						      reg_magic == MAGIC_ALL);
 	    if (flags & SIMPLE)
 	    {
 		reginsert(BRACE_SIMPLE, ret);
@@ -1391,6 +1546,7 @@ regatom(flagp)
     char_u	    *ret;
     int		    flags;
     int		    cpo_lit;	    /* 'cpoptions' contains 'l' flag */
+    int		    cpo_bsl;	    /* 'cpoptions' contains '\' flag */
     int		    c;
     static char_u   *classchars = (char_u *)".iIkKfFpPsSdDxXoOwWhHaAlLuU";
     static int	    classcodes[] = {ANY, IDENT, SIDENT, KWORD, SKWORD,
@@ -1406,6 +1562,7 @@ regatom(flagp)
 
     *flagp = WORST;		/* Tentatively. */
     cpo_lit = (!reg_syn && vim_strchr(p_cpo, CPO_LITERAL) != NULL);
+    cpo_bsl = (!reg_syn && vim_strchr(p_cpo, CPO_BACKSL) != NULL);
 
     c = getchr();
     switch (c)
@@ -1827,7 +1984,10 @@ collection:
 
 		/* At the start ']' and '-' mean the literal character. */
 		if (*regparse == ']' || *regparse == '-')
+		{
+		    startc = *regparse;
 		    regc(*regparse++);
+		}
 
 		while (*regparse != NUL && *regparse != ']')
 		{
@@ -1845,15 +2005,22 @@ collection:
 			}
 			else
 			{
+			    /* Also accept "a-[.z.]" */
+			    endc = 0;
+			    if (*regparse == '[')
+				endc = get_coll_element(&regparse);
+			    if (endc == 0)
+			    {
 #ifdef FEAT_MBYTE
-			    if (has_mbyte)
-				endc = mb_ptr2char_adv(&regparse);
-			    else
+				if (has_mbyte)
+				    endc = mb_ptr2char_adv(&regparse);
+				else
 #endif
-				endc = *regparse++;
+				    endc = *regparse++;
+			    }
 
 			    /* Handle \o40, \x20 and \u20AC style sequences */
-			    if (endc == '\\' && !cpo_lit)
+			    if (endc == '\\' && !cpo_lit && !cpo_bsl)
 				endc = coll_get_char();
 
 			    if (startc > endc)
@@ -1892,8 +2059,10 @@ collection:
 		     * Only "\]", "\^", "\]" and "\\" are special in Vi.  Vim
 		     * accepts "\t", "\e", etc., but only when the 'l' flag in
 		     * 'cpoptions' is not included.
+		     * Posix doesn't recognize backslash at all.
 		     */
 		    else if (*regparse == '\\'
+			    && !cpo_bsl
 			    && (vim_strchr(REGEXP_INRANGE, regparse[1]) != NULL
 				|| (!cpo_lit
 				    && vim_strchr(REGEXP_ABBR,
@@ -1942,15 +2111,30 @@ collection:
 			int c_class;
 			int cu;
 
-			c_class = skip_class_name(&regparse);
+			c_class = get_char_class(&regparse);
 			startc = -1;
 			/* Characters assumed to be 8 bits! */
 			switch (c_class)
 			{
 			    case CLASS_NONE:
-				/* literal '[', allow [[-x] as a range */
-				startc = *regparse++;
-				regc(startc);
+				c_class = get_equi_class(&regparse);
+				if (c_class != 0)
+				{
+				    /* produce equivalence class */
+				    reg_equi_class(c_class);
+				}
+				else if ((c_class =
+					    get_coll_element(&regparse)) != 0)
+				{
+				    /* produce a collating element */
+				    regmbc(c_class);
+				}
+				else
+				{
+				    /* literal '[', allow [[-x] as a range */
+				    startc = *regparse++;
+				    regc(startc);
+				}
 				break;
 			    case CLASS_ALNUM:
 				for (cu = 1; cu <= 255; cu++)
@@ -2354,6 +2538,8 @@ initchr(str)
     static int
 peekchr()
 {
+    static int	after_slash = FALSE;
+
     if (curchr == -1)
     {
 	switch (curchr = regparse[0])
@@ -2392,10 +2578,16 @@ peekchr()
 		curchr = Magic(curchr);
 	    break;
 	case '*':
-	    /* * is not magic as the very first character, eg "?*ptr" and when
-	     * after '^', eg "/^*ptr" */
-	    if (reg_magic >= MAGIC_ON && !at_start
-				 && !(prev_at_start && prevchr == Magic('^')))
+	    /* * is not magic as the very first character, eg "?*ptr", when
+	     * after '^', eg "/^*ptr" and when after "\(", "\|", "\&".  But
+	     * "\(\*" is not magic, thus must be magic if "after_slash" */
+	    if (reg_magic >= MAGIC_ON
+		    && !at_start
+		    && !(prev_at_start && prevchr == Magic('^'))
+		    && (after_slash
+			|| (prevchr != Magic('(')
+			    && prevchr != Magic('&')
+			    && prevchr != Magic('|'))))
 		curchr = Magic('*');
 	    break;
 	case '^':
@@ -2460,8 +2652,10 @@ peekchr()
 		    prev_at_start = at_start;
 		    at_start = FALSE;	/* be able to say "/\*ptr" */
 		    ++regparse;
+		    ++after_slash;
 		    peekchr();
 		    --regparse;
+		    --after_slash;
 		    curchr = toggle_Magic(curchr);
 		}
 		else if (vim_strchr(REGEXP_ABBR, c))
@@ -2723,7 +2917,7 @@ read_limits(minval, maxval)
 	*maxval = MAX_LIMIT;	    /* It was \{} or \{-} */
     if (*regparse == '\\')
 	regparse++;	/* Allow either \{...} or \{...\} */
-    if (*regparse != '}' || (*maxval == 0 && *minval == 0))
+    if (*regparse != '}')
     {
 	sprintf((char *)IObuff, _("E554: Syntax error in %s{...}"),
 					  reg_magic == MAGIC_ALL ? "" : "\\");
@@ -2815,7 +3009,7 @@ static void	save_se_one __ARGS((save_se_
 	*(pp) = (savep)->se_u.ptr; }
 
 static int	re_num_cmp __ARGS((long_u val, char_u *scan));
-static int	regmatch __ARGS((char_u *prog));
+static int	regmatch __ARGS((char_u *prog, regsave_T *startp));
 static int	regrepeat __ARGS((char_u *p, long maxcount));
 
 #ifdef DEBUG
@@ -3273,7 +3467,7 @@ regtry(prog, col)
 	need_clear_zsubexpr = TRUE;
 #endif
 
-    if (regmatch(prog->program + 1))
+    if (regmatch(prog->program + 1, NULL))
     {
 	cleanup_subexpr();
 	if (REG_MULTI)
@@ -3379,8 +3573,9 @@ static long	bl_maxval;
  * undefined state!
  */
     static int
-regmatch(scan)
+regmatch(scan, startp)
     char_u	*scan;		/* Current node. */
+    regsave_T	*startp;	/* start position for BACK */
 {
     char_u	*next;		/* Next node. */
     int		op;
@@ -3803,6 +3998,10 @@ regmatch(scan)
 	    break;
 
 	  case BACK:
+	    /* When we run into BACK without matching something non-empty, we
+	     * fail. */
+	    if (startp != NULL && reg_save_equal(startp))
+		return FALSE;
 	    break;
 
 	  case MOPEN + 0:   /* Match start: \zs */
@@ -3823,7 +4022,7 @@ regmatch(scan)
 		cleanup_subexpr();
 		save_se(&save, &reg_startpos[no], &reg_startp[no]);
 
-		if (regmatch(next))
+		if (regmatch(next, startp))
 		    return TRUE;
 
 		restore_se(&save, &reg_startpos[no], &reg_startp[no]);
@@ -3833,7 +4032,7 @@ regmatch(scan)
 
 	  case NOPEN:	    /* \%( */
 	  case NCLOSE:	    /* \) after \%( */
-		if (regmatch(next))
+		if (regmatch(next, startp))
 		    return TRUE;
 		return FALSE;
 		/* break; Not Reached */
@@ -3856,7 +4055,7 @@ regmatch(scan)
 		cleanup_zsubexpr();
 		save_se(&save, &reg_startzpos[no], &reg_startzp[no]);
 
-		if (regmatch(next))
+		if (regmatch(next, startp))
 		    return TRUE;
 
 		restore_se(&save, &reg_startzpos[no], &reg_startzp[no]);
@@ -3883,7 +4082,7 @@ regmatch(scan)
 		cleanup_subexpr();
 		save_se(&save, &reg_endpos[no], &reg_endp[no]);
 
-		if (regmatch(next))
+		if (regmatch(next, startp))
 		    return TRUE;
 
 		restore_se(&save, &reg_endpos[no], &reg_endp[no]);
@@ -3909,7 +4108,7 @@ regmatch(scan)
 		cleanup_zsubexpr();
 		save_se(&save, &reg_endzpos[no], &reg_endzp[no]);
 
-		if (regmatch(next))
+		if (regmatch(next, startp))
 		    return TRUE;
 
 		restore_se(&save, &reg_endzpos[no], &reg_endzp[no]);
@@ -4076,7 +4275,7 @@ regmatch(scan)
 		    do
 		    {
 			reg_save(&save);
-			if (regmatch(OPERAND(scan)))
+			if (regmatch(OPERAND(scan), &save))
 			    return TRUE;
 			reg_restore(&save);
 			scan = regnext(scan);
@@ -4134,7 +4333,7 @@ regmatch(scan)
 				    ? brace_min[no] : brace_max[no]))
 		{
 		    reg_save(&save);
-		    if (regmatch(OPERAND(scan)))
+		    if (regmatch(OPERAND(scan), &save))
 			return TRUE;
 		    reg_restore(&save);
 		    --brace_count[no];	/* failed, decrement match count */
@@ -4148,11 +4347,11 @@ regmatch(scan)
 		    if (brace_count[no] <= brace_max[no])
 		    {
 			reg_save(&save);
-			if (regmatch(OPERAND(scan)))
+			if (regmatch(OPERAND(scan), &save))
 			    return TRUE;	/* matched some more times */
 			reg_restore(&save);
 			--brace_count[no];  /* matched just enough times */
-			/* continue with the items after \{} */
+			/* {  continue with the items after \{} */
 		    }
 		}
 		else
@@ -4161,7 +4360,7 @@ regmatch(scan)
 		    if (brace_count[no] <= brace_min[no])
 		    {
 			reg_save(&save);
-			if (regmatch(next))
+			if (regmatch(next, &save))
 			    return TRUE;
 			reg_restore(&save);
 			next = OPERAND(scan);
@@ -4234,7 +4433,7 @@ regmatch(scan)
 						    || *reginput == nextb_ic)
 			{
 			    reg_save(&save);
-			    if (regmatch(next))
+			    if (regmatch(next, startp))
 				return TRUE;
 			    reg_restore(&save);
 			}
@@ -4271,7 +4470,7 @@ regmatch(scan)
 						    || *reginput == nextb_ic)
 			{
 			    reg_save(&save);
-			    if (regmatch(next))
+			    if (regmatch(next, &save))
 				return TRUE;
 			    reg_restore(&save);
 			}
@@ -4295,7 +4494,7 @@ regmatch(scan)
 		/* If the operand matches, we fail.  Otherwise backup and
 		 * continue with the next item. */
 		reg_save(&save);
-		if (regmatch(OPERAND(scan)))
+		if (regmatch(OPERAND(scan), startp))
 		    return FALSE;
 		reg_restore(&save);
 	    }
@@ -4309,7 +4508,7 @@ regmatch(scan)
 		/* If the operand doesn't match, we fail.  Otherwise backup
 		 * and continue with the next item. */
 		reg_save(&save);
-		if (!regmatch(OPERAND(scan)))
+		if (!regmatch(OPERAND(scan), startp))
 		    return FALSE;
 		if (op == MATCH)	    /* zero-width */
 		    reg_restore(&save);
@@ -4331,7 +4530,7 @@ regmatch(scan)
 		 * faster.
 		 */
 		reg_save(&save_start);
-		if (regmatch(next))
+		if (regmatch(next, startp))
 		{
 		    /* save the position after the found match for next */
 		    reg_save(&save_after);
@@ -4347,7 +4546,7 @@ regmatch(scan)
 		    for (;;)
 		    {
 			reg_restore(&save_start);
-			if (regmatch(OPERAND(scan))
+			if (regmatch(OPERAND(scan), startp)
 				&& reg_save_equal(&behind_pos))
 			{
 			    behind_pos = save_behind_pos;
--- a/src/testdir/test11.in
+++ b/src/testdir/test11.in
@@ -38,6 +38,7 @@ STARTTEST
 :au BufReadPost     *.gz   !gzip <afile>:r
 :e! Xtestfile.gz                " Edit compressed file
 :w>>test.out                    " Append it to the output file
+:set shelltemp                  " need temp files here
 :au FilterReadPre   *.out  call rename(expand("<afile>"), expand("<afile>").".t")
 :au FilterReadPre   *.out  !sed s/e/E/ <afile>.t ><afile>
 :au FilterReadPre   *.out  !rm <afile>.t
--- a/src/vim.h
+++ b/src/vim.h
@@ -782,6 +782,8 @@ extern char *(*dyn_libintl_textdomain)(c
 #define SHELL_COOKED	4	/* set term to cooked mode */
 #define SHELL_DOOUT	8	/* redirecting output */
 #define SHELL_SILENT	16	/* don't print error returned by command */
+#define SHELL_READ	32	/* read lines and insert into buffer */
+#define SHELL_WRITE	64	/* write lines from buffer */
 
 /* Values returned by mch_nodetype() */
 #define NODE_NORMAL	0	/* file or directory, check with mch_isdir()*/
@@ -885,9 +887,10 @@ extern char *(*dyn_libintl_textdomain)(c
 /* flags for do_put() */
 #define PUT_FIXINDENT	1	/* make indent look nice */
 #define PUT_CURSEND	2	/* leave cursor after end of new text */
-#define PUT_LINE	4	/* put register as lines */
-#define PUT_LINE_SPLIT	8	/* split line for linewise register */
-#define PUT_LINE_FORWARD 16	/* put linewise register below Visual sel. */
+#define PUT_CURSLINE	4	/* leave cursor on last line of new text */
+#define PUT_LINE	8	/* put register as lines */
+#define PUT_LINE_SPLIT	16	/* split line for linewise register */
+#define PUT_LINE_FORWARD 32	/* put linewise register below Visual sel. */
 
 /* flags for set_indent() */
 #define SIN_CHANGED	1	/* call changed_bytes() when line changed */