updated for version 7.0051
diff --git a/src/Makefile b/src/Makefile
index b2dc015..0ea38f7 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -505,6 +505,7 @@
 # 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 @@
 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)
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index d2e933a..2bb5aeb 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -128,6 +128,7 @@
 
 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_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_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 @@
     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 @@
 	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_cmdline(NULL, getexmodeline, NULL, DOCMD_NOWAIT);
 	lines_left = Rows - 1;
 
-	if (prev_line != curwin->w_cursor.lnum && !ex_no_reprint)
+	if ((prev_line != curwin->w_cursor.lnum
+		    || changedtick != curbuf->b_changedtick) && !ex_no_reprint)
 	{
-	    if (ex_pressedreturn)
+	    if (curbuf->b_ml.ml_flags & ML_EMPTY)
+		EMSG(_(e_emptybuf));
+	    else
 	    {
-		/* 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--;
+		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();
 	    }
-	    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"));
+	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 @@
 	/* 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 @@
 
 	/* ignore comment and empty lines */
 	if (*ea.cmd == '"' || *ea.cmd == NUL)
+	{
+	    ex_pressedreturn = TRUE;
 	    goto doend;
+	}
 
 /*
  * 2. handle command modifiers.
@@ -1936,7 +1956,7 @@
 	 */
 	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 @@
 	}
 	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 @@
 	 */
 	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 @@
 
     /*
      * 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 @@
 		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 @@
 {
     int		len;
     char_u	*p;
+    int		i;
 
     /*
      * Isolate the command and search for it in the command table.
@@ -2669,6 +2698,7 @@
      * - 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 @@
 	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 @@
 /*
  * 4. parse command
  */
-
-    cmd = skipwhite(cmd);
     xp->xp_pattern = cmd;
     if (*cmd == NUL)
 	return NULL;
@@ -3281,6 +3325,7 @@
 	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 @@
  * 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 @@
 {
     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 @@
 	if (*cmd != NUL)
 	    ++cmd;
     }
+
+    /* Skip ":" and white space. */
+    while (*cmd == ':')
+	cmd = skipwhite(cmd + 1);
+
     return cmd;
 }
 
@@ -3856,6 +3906,25 @@
 }
 
 /*
+ * 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 @@
 
 #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_print(eap)
     exarg_T	*eap;
 {
-    int		save_list = 0;	    /* init for GCC */
-
-    if (eap->cmdidx == CMD_list)
+    if (curbuf->b_ml.ml_flags & ML_EMPTY)
+	EMSG(_(e_emptybuf));
+    else
     {
-	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
+						 || (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);
     }
 
-    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);
-
     ex_no_reprint = TRUE;
-
-    if (eap->cmdidx == CMD_list)
-	curwin->w_p_list = save_list;
 }
 
 #ifdef FEAT_BYTEOFF
@@ -6689,7 +6754,45 @@
 }
 
 /*
- * ":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 @@
 #ifdef FEAT_WINDOWS
     int		need_hide;
 #endif
+    int		exmode_was = exmode_active;
 
     /*
      * ":vi" command ends Ex mode.
@@ -6720,7 +6824,45 @@
     {
 	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_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 @@
 		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 @@
     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 @@
     exarg_T	*eap;
 {
     smsg((char_u *)"%ld", (long)eap->line2);
+    ex_may_print(eap);
 }
 
     static void
@@ -7361,6 +7531,7 @@
 #ifdef FEAT_VIRTUALEDIT
     virtual_op = MAYBE;
 #endif
+    ex_may_print(eap);
 }
 
 /*
@@ -7377,7 +7548,8 @@
 	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 @@
 	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_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 @@
     }
     do_do_join(eap->line2 - eap->line1 + 1, !eap->forceit);
     beginline(BL_WHITE | BL_FIX);
+    ex_may_print(eap);
 }
 
 /*
@@ -7474,7 +7664,9 @@
 	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 @@
 		    /* 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 @@
     }
 #ifdef FEAT_EVAL
     redir_reg = 0;
+    if (redir_vname)
+    {
+	var_redir_stop();
+	redir_vname = 0;
+    }
 #endif
 }
 
@@ -7774,8 +7989,7 @@
 #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 @@
 #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.
diff --git a/src/fileio.c b/src/fileio.c
index 9dd1d49..0644688 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -140,10 +140,6 @@
 #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 @@
     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 @@
 	    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 @@
     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 @@
      */
     write_no_eol_lnum = read_no_eol_lnum;
 
+#ifdef FEAT_AUTOCMD
     if (!read_stdin && !read_buffer)
     {
 	int m = msg_scroll;
@@ -2628,6 +2626,10 @@
 # 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 @@
 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;
 }
 
diff --git a/src/globals.h b/src/globals.h
index 1df8b87..2c1c53a 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -155,6 +155,7 @@
 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 @@
 						  "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 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 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_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);
diff --git a/src/mbyte.c b/src/mbyte.c
index f309255..89b53c2 100644
--- a/src/mbyte.c
+++ b/src/mbyte.c
@@ -2871,12 +2871,16 @@
 # 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 @@
 # endif
     if (vcp->vc_type == CONV_NONE)
 	return FAIL;
+
     return OK;
 }
 
diff --git a/src/message.c b/src/message.c
index 6f2e7c1..f649484 100644
--- a/src/message.c
+++ b/src/message.c
@@ -518,6 +518,7 @@
 #endif
 
     called_emsg = TRUE;
+    ex_exitval = 1;
 
     /*
      * If "emsg_severe" is TRUE: When an error exception is to be thrown,
@@ -533,7 +534,7 @@
      * 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 @@
 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 @@
     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 @@
     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 @@
  * 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 @@
     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 @@
 
     /* 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 @@
 	{
 	    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 @@
 		    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 @@
 
     if ((redir_fd != NULL
 #ifdef FEAT_EVAL
-			  || redir_reg
+			  || redir_reg || redir_vname
 #endif
 				       ) && !redir_off)
     {
@@ -2533,6 +2545,8 @@
 #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 @@
 #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')
diff --git a/src/netbeans.c b/src/netbeans.c
index ed75470..3eeeb07 100644
--- a/src/netbeans.c
+++ b/src/netbeans.c
@@ -114,14 +114,12 @@
 
 #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 @@
 #else
 # ifdef FEAT_GUI_GTK
 	netbeans_gtk_connect();
+# else
+#  ifdef FEAT_GUI_W32
+	netbeans_w32_connect();
+#  endif
 # endif
 #endif
 
diff --git a/src/normal.c b/src/normal.c
index f13b45e..2ba3f74 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -232,7 +232,11 @@
     {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 @@
  * 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)
diff --git a/src/os_unix.c b/src/os_unix.c
index d89636d..945092f 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -165,6 +165,7 @@
 #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 @@
 #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 @@
 
     out_flush();
     set_signals();
+
+#if defined(MACOS_X) && defined(FEAT_MBYTE)
+    mac_conv_init();
+#endif
 }
 
     static void
@@ -1113,11 +1126,8 @@
     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 @@
 #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()
 {
+    if (silent_mode)
+	return;
     if (newline_on_exit || msg_didout)
     {
 	if (msg_use_printf())
@@ -2764,6 +2787,11 @@
     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 @@
     /* 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 @@
 
 #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 @@
     int		i;
     char_u	*p;
     int		inquote;
-# ifdef FEAT_GUI
     int		pty_master_fd = -1;	    /* for pty's */
+# ifdef FEAT_GUI
     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 @@
     }
     argv[argc] = NULL;
 
-# 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.
+     * 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 (gui.in_use && show_shell_mess)
+    if ((options & (SHELL_READ|SHELL_WRITE))
+# ifdef FEAT_GUI
+	    || (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 @@
 	 * 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 @@
     }
 
     if (!pipe_error)			/* pty or pipe opened or not used */
-# endif
-
     {
 # ifdef __BEOS__
 	beos_cleanup_read_thread();
@@ -3535,15 +3589,20 @@
 	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 @@
 		    close(fd_fromshell[1]);
 		}
 	    }
-# endif
 	}
 	else if (pid == 0)	/* child */
 	{
@@ -3593,13 +3651,17 @@
 		    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 @@
 		 * 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 @@
 		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 @@
 		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 @@
 		    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 @@
 		    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 @@
 	{
 	    /*
 	     * 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 @@
 		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 @@
 		    toshell_fd = dup(pty_master_fd);
 		}
 		else
+# endif
 		{
 		    close(fd_toshell[0]);
 		    close(fd_fromshell[1]);
@@ -3738,6 +3813,76 @@
 		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 @@
 		     * 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 @@
 			 */
 			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 @@
 			    }
 			    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 @@
 			    {
 				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 @@
 				    msg_outtrans_len(ta_buf + i, l);
 				    i += l - 1;
 				}
-#  endif
+# endif
 				else
 				    msg_outtrans_len(ta_buf + i, 1);
 			    }
@@ -3837,18 +3989,37 @@
 			 * 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 @@
 		     * 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 @@
 			    }
 			    buffer_off = 0;
 			}
+# endif /* FEAT_MBYTE */
 			else
-#  endif /* FEAT_MBYTE */
 			{
 			    buffer[len] = NUL;
 			    msg_puts(buffer);
@@ -3931,11 +4120,11 @@
 		     * 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 @@
 		}
 finished:
 		p_more = p_more_save;
+		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);
+		}
 
-#  ifndef MACOS_X_UNIX /* TODO: Is it needed for MACOS_X ? */
 		/*
 		 * 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 @@
 	     */
 	    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 @@
 		    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 @@
 		    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 @@
 		    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);
+		    }
 		}
 	    }
 	}
diff --git a/src/po/Make_ming.mak b/src/po/Make_ming.mak
index 810efb0..db42720 100644
--- 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
 
diff --git a/src/po/Makefile b/src/po/Makefile
index c71df8d..dc94efd 100644
--- 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
 
diff --git a/src/proto/ex_docmd.pro b/src/proto/ex_docmd.pro
index 0a8b5d3..9a0fd2b 100644
--- a/src/proto/ex_docmd.pro
+++ b/src/proto/ex_docmd.pro
@@ -33,6 +33,7 @@
 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));
diff --git a/src/proto/gui_mac.pro b/src/proto/gui_mac.pro
index b5a4638..9a296fd 100644
--- a/src/proto/gui_mac.pro
+++ b/src/proto/gui_mac.pro
@@ -39,6 +39,7 @@
 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));
diff --git a/src/proto/main.pro b/src/proto/main.pro
index bd75174..2ecce79 100644
--- 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));
diff --git a/src/proto/message.pro b/src/proto/message.pro
index 9957b75..647c8d1 100644
--- a/src/proto/message.pro
+++ b/src/proto/message.pro
@@ -9,6 +9,7 @@
 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 @@
 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));
diff --git a/src/quickfix.c b/src/quickfix.c
index a8544b3..079e6c9 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -1456,7 +1456,7 @@
 		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 @@
     exarg_T	*eap;
 {
     regmmatch_T	regmatch;
-    char_u	*save_cpo;
     int		fcount;
     char_u	**fnames;
     char_u	*s;
@@ -2317,10 +2316,6 @@
     }
 #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 @@
 
 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);
 }
 
 /*
diff --git a/src/regexp.c b/src/regexp.c
index a9915a3..c4f8920 100644
--- 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_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 @@
 }
 
 /*
- * 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 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 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 @@
 }
 
 /*
+ * 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 @@
 	*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 @@
 	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 @@
     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 @@
 
     *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 @@
 
 		/* At the start ']' and '-' mean the literal character. */
 		if (*regparse == ']' || *regparse == '-')
+		{
+		    startc = *regparse;
 		    regc(*regparse++);
+		}
 
 		while (*regparse != NUL && *regparse != ']')
 		{
@@ -1845,15 +2005,22 @@
 			}
 			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 @@
 		     * 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 @@
 			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 @@
     static int
 peekchr()
 {
+    static int	after_slash = FALSE;
+
     if (curchr == -1)
     {
 	switch (curchr = regparse[0])
@@ -2392,10 +2578,16 @@
 		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 @@
 		    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 @@
 	*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 @@
 	*(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 @@
 	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 @@
  * 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 @@
 	    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 @@
 		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 @@
 
 	  case NOPEN:	    /* \%( */
 	  case NCLOSE:	    /* \) after \%( */
-		if (regmatch(next))
+		if (regmatch(next, startp))
 		    return TRUE;
 		return FALSE;
 		/* break; Not Reached */
@@ -3856,7 +4055,7 @@
 		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 @@
 		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 @@
 		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 @@
 		    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 @@
 				    ? 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 @@
 		    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 @@
 		    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 @@
 						    || *reginput == nextb_ic)
 			{
 			    reg_save(&save);
-			    if (regmatch(next))
+			    if (regmatch(next, startp))
 				return TRUE;
 			    reg_restore(&save);
 			}
@@ -4271,7 +4470,7 @@
 						    || *reginput == nextb_ic)
 			{
 			    reg_save(&save);
-			    if (regmatch(next))
+			    if (regmatch(next, &save))
 				return TRUE;
 			    reg_restore(&save);
 			}
@@ -4295,7 +4494,7 @@
 		/* 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 @@
 		/* 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 @@
 		 * 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 @@
 		    for (;;)
 		    {
 			reg_restore(&save_start);
-			if (regmatch(OPERAND(scan))
+			if (regmatch(OPERAND(scan), startp)
 				&& reg_save_equal(&behind_pos))
 			{
 			    behind_pos = save_behind_pos;
diff --git a/src/testdir/test11.in b/src/testdir/test11.in
index 0e721b7..063aeb2 100644
--- a/src/testdir/test11.in
+++ b/src/testdir/test11.in
@@ -38,6 +38,7 @@
 :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
diff --git a/src/vim.h b/src/vim.h
index 6d2b249..fa554b0 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -782,6 +782,8 @@
 #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 @@
 /* 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 */