diff options
Diffstat (limited to 'contrib/nvi/ex/ex_edit.c')
-rw-r--r-- | contrib/nvi/ex/ex_edit.c | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/contrib/nvi/ex/ex_edit.c b/contrib/nvi/ex/ex_edit.c new file mode 100644 index 0000000..8b18e0f --- /dev/null +++ b/contrib/nvi/ex/ex_edit.c @@ -0,0 +1,153 @@ +/*- + * Copyright (c) 1992, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * Copyright (c) 1992, 1993, 1994, 1995, 1996 + * Keith Bostic. All rights reserved. + * + * See the LICENSE file for redistribution information. + */ + +#include "config.h" + +#ifndef lint +static const char sccsid[] = "@(#)ex_edit.c 10.10 (Berkeley) 4/27/96"; +#endif /* not lint */ + +#include <sys/types.h> +#include <sys/queue.h> +#include <sys/time.h> + +#include <bitstring.h> +#include <errno.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "../common/common.h" +#include "../vi/vi.h" + +static int ex_N_edit __P((SCR *, EXCMD *, FREF *, int)); + +/* + * ex_edit -- :e[dit][!] [+cmd] [file] + * :ex[!] [+cmd] [file] + * :vi[sual][!] [+cmd] [file] + * + * Edit a file; if none specified, re-edit the current file. The third + * form of the command can only be executed while in vi mode. See the + * hack in ex.c:ex_cmd(). + * + * !!! + * Historic vi didn't permit the '+' command form without specifying + * a file name as well. This seems unreasonable, so we support it + * regardless. + * + * PUBLIC: int ex_edit __P((SCR *, EXCMD *)); + */ +int +ex_edit(sp, cmdp) + SCR *sp; + EXCMD *cmdp; +{ + FREF *frp; + int attach, setalt; + + switch (cmdp->argc) { + case 0: + /* + * If the name has been changed, we edit that file, not the + * original name. If the user was editing a temporary file + * (or wasn't editing any file), create another one. The + * reason for not reusing temporary files is that there is + * special exit processing of them, and reuse is tricky. + */ + frp = sp->frp; + if (sp->ep == NULL || F_ISSET(frp, FR_TMPFILE)) { + if ((frp = file_add(sp, NULL)) == NULL) + return (1); + attach = 0; + } else + attach = 1; + setalt = 0; + break; + case 1: + if ((frp = file_add(sp, cmdp->argv[0]->bp)) == NULL) + return (1); + attach = 0; + setalt = 1; + set_alt_name(sp, cmdp->argv[0]->bp); + break; + default: + abort(); + } + + if (F_ISSET(cmdp, E_NEWSCREEN)) + return (ex_N_edit(sp, cmdp, frp, attach)); + + /* + * Check for modifications. + * + * !!! + * Contrary to POSIX 1003.2-1992, autowrite did not affect :edit. + */ + if (file_m2(sp, FL_ISSET(cmdp->iflags, E_C_FORCE))) + return (1); + + /* Switch files. */ + if (file_init(sp, frp, NULL, (setalt ? FS_SETALT : 0) | + (FL_ISSET(cmdp->iflags, E_C_FORCE) ? FS_FORCE : 0))) + return (1); + + F_SET(sp, SC_FSWITCH); + return (0); +} + +/* + * ex_N_edit -- + * New screen version of ex_edit. + */ +static int +ex_N_edit(sp, cmdp, frp, attach) + SCR *sp; + EXCMD *cmdp; + FREF *frp; + int attach; +{ + SCR *new; + + /* Get a new screen. */ + if (screen_init(sp->gp, sp, &new)) + return (1); + if (vs_split(sp, new, 0)) { + (void)screen_end(new); + return (1); + } + + /* Get a backing file. */ + if (attach) { + /* Copy file state, keep the screen and cursor the same. */ + new->ep = sp->ep; + ++new->ep->refcnt; + + new->frp = frp; + new->frp->flags = sp->frp->flags; + + new->lno = sp->lno; + new->cno = sp->cno; + } else if (file_init(new, frp, NULL, + (FL_ISSET(cmdp->iflags, E_C_FORCE) ? FS_FORCE : 0))) { + (void)vs_discard(new, NULL); + (void)screen_end(new); + return (1); + } + + /* Create the argument list. */ + new->cargv = new->argv = ex_buildargv(sp, NULL, frp->name); + + /* Set up the switch. */ + sp->nextdisp = new; + F_SET(sp, SC_SSWITCH); + + return (0); +} |