do_exedit(
    exarg_T	*eap,
    win_T	*old_curwin)	    /* curwin before doing a split or NULL */
{
    int		n;
    int		need_hide;
    int		exmode_was = exmode_active;

    /*
     * ":vi" command ends Ex mode.
     */
    if (exmode_active && (eap->cmdidx == CMD_visual
						|| eap->cmdidx == CMD_view))
    {
	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
		|| eap->cmdidx == CMD_tabnew
		|| eap->cmdidx == CMD_tabedit
		|| eap->cmdidx == CMD_vnew) && *eap->arg == NUL)
    {
	/* ":new" or ":tabnew" without argument: edit an new empty buffer */
	setpcmark();
	(void)do_ecmd(0, NULL, NULL, eap, ECMD_ONE,
		      ECMD_HIDE + (eap->forceit ? ECMD_FORCEIT : 0),
		      old_curwin == NULL ? curwin : NULL);
    }
    else if ((eap->cmdidx != CMD_split && eap->cmdidx != CMD_vsplit)
	    || *eap->arg != NUL
#ifdef FEAT_BROWSE
	    || cmdmod.browse
#endif
	    )
    {
	/* Can't edit another file when "curbuf_lock" is set.  Only ":edit"
	 * can bring us here, others are stopped earlier. */
	if (*eap->arg != NUL && curbuf_locked())
	    return;

	n = readonlymode;
	if (eap->cmdidx == CMD_view || eap->cmdidx == CMD_sview)
	    readonlymode = TRUE;
	else if (eap->cmdidx == CMD_enew)
	    readonlymode = FALSE;   /* 'readonly' doesn't make sense in an
				       empty buffer */
	setpcmark();
	if (do_ecmd(0, (eap->cmdidx == CMD_enew ? NULL : eap->arg),
		    NULL, eap,
		    /* ":edit" goes to first line if Vi compatible */
		    (*eap->arg == NUL && eap->do_ecmd_lnum == 0
				      && vim_strchr(p_cpo, CPO_GOTO1) != NULL)
					       ? ECMD_ONE : eap->do_ecmd_lnum,
		    (buf_hide(curbuf) ? ECMD_HIDE : 0)
		    + (eap->forceit ? ECMD_FORCEIT : 0)
		      /* after a split we can use an existing buffer */
		    + (old_curwin != NULL ? ECMD_OLDBUF : 0)
		    + (eap->cmdidx == CMD_badd ? ECMD_ADDBUF : 0 )
		    , old_curwin == NULL ? curwin : NULL) == FAIL)
	{
	    /* Editing the file failed.  If the window was split, close it. */
	    if (old_curwin != NULL)
	    {
		need_hide = (curbufIsChanged() && curbuf->b_nwindows <= 1);
		if (!need_hide || buf_hide(curbuf))
		{
#if defined(FEAT_EVAL)
		    cleanup_T   cs;

		    /* Reset the error/interrupt/exception state here so that
		     * aborting() returns FALSE when closing a window. */
		    enter_cleanup(&cs);
#endif
#ifdef FEAT_GUI
		    need_mouse_correct = TRUE;
#endif
		    win_close(curwin, !need_hide && !buf_hide(curbuf));

#if defined(FEAT_EVAL)
		    /* Restore the error/interrupt/exception state if not
		     * discarded by a new aborting error, interrupt, or
		     * uncaught exception. */
		    leave_cleanup(&cs);
#endif
		}
	    }
	}
	else if (readonlymode && curbuf->b_nwindows == 1)
	{
	    /* When editing an already visited buffer, 'readonly' won't be set
	     * but the previous value is kept.  With ":view" and ":sview" we
	     * want the  file to be readonly, except when another window is
	     * editing the same buffer. */
	    curbuf->b_p_ro = TRUE;
	}
	readonlymode = n;
    }
    else
    {
	if (eap->do_ecmd_cmd != NULL)
	    do_cmdline_cmd(eap->do_ecmd_cmd);
#ifdef FEAT_TITLE
	n = curwin->w_arg_idx_invalid;
#endif
	check_arg_idx(curwin);
#ifdef FEAT_TITLE
	if (n != curwin->w_arg_idx_invalid)
	    maketitle();
#endif
    }

    /*
     * if ":split file" worked, set alternate file name in old window to new
     * file
     */
    if (old_curwin != NULL
	    && *eap->arg != NUL
	    && curwin != old_curwin
	    && win_valid(old_curwin)
	    && old_curwin->w_buffer != curbuf
	    && !cmdmod.keepalt)
	old_curwin->w_alt_fnum = curbuf->b_fnum;

    ex_no_reprint = TRUE;
}