119304Speter/*- 219304Speter * Copyright (c) 1992, 1993, 1994 319304Speter * The Regents of the University of California. All rights reserved. 419304Speter * Copyright (c) 1992, 1993, 1994, 1995, 1996 519304Speter * Keith Bostic. All rights reserved. 619304Speter * 719304Speter * See the LICENSE file for redistribution information. 819304Speter */ 919304Speter 1019304Speter#include "config.h" 1119304Speter 1219304Speter#ifndef lint 13254225Speterstatic const char sccsid[] = "$Id: ex_edit.c,v 10.15 2011/12/22 23:26:50 zy Exp $"; 1419304Speter#endif /* not lint */ 1519304Speter 1619304Speter#include <sys/types.h> 1719304Speter#include <sys/queue.h> 1819304Speter#include <sys/time.h> 1919304Speter 2019304Speter#include <bitstring.h> 2119304Speter#include <errno.h> 2219304Speter#include <limits.h> 2319304Speter#include <stdio.h> 2419304Speter#include <stdlib.h> 2519304Speter#include <string.h> 2619304Speter 2719304Speter#include "../common/common.h" 2819304Speter#include "../vi/vi.h" 2919304Speter 30281373Sbaptstatic int ex_N_edit(SCR *, EXCMD *, FREF *, int); 3119304Speter 3219304Speter/* 3319304Speter * ex_edit -- :e[dit][!] [+cmd] [file] 3419304Speter * :ex[!] [+cmd] [file] 3519304Speter * :vi[sual][!] [+cmd] [file] 3619304Speter * 3719304Speter * Edit a file; if none specified, re-edit the current file. The third 3819304Speter * form of the command can only be executed while in vi mode. See the 3919304Speter * hack in ex.c:ex_cmd(). 4019304Speter * 4119304Speter * !!! 4219304Speter * Historic vi didn't permit the '+' command form without specifying 4319304Speter * a file name as well. This seems unreasonable, so we support it 4419304Speter * regardless. 4519304Speter * 46281373Sbapt * PUBLIC: int ex_edit(SCR *, EXCMD *); 4719304Speter */ 4819304Speterint 49254225Speterex_edit(SCR *sp, EXCMD *cmdp) 5019304Speter{ 5119304Speter FREF *frp; 5219304Speter int attach, setalt; 53254225Speter char *np; 54254225Speter size_t nlen; 5519304Speter 5619304Speter switch (cmdp->argc) { 5719304Speter case 0: 5819304Speter /* 5919304Speter * If the name has been changed, we edit that file, not the 6019304Speter * original name. If the user was editing a temporary file 6119304Speter * (or wasn't editing any file), create another one. The 6219304Speter * reason for not reusing temporary files is that there is 6319304Speter * special exit processing of them, and reuse is tricky. 6419304Speter */ 6519304Speter frp = sp->frp; 6619304Speter if (sp->ep == NULL || F_ISSET(frp, FR_TMPFILE)) { 6719304Speter if ((frp = file_add(sp, NULL)) == NULL) 6819304Speter return (1); 6919304Speter attach = 0; 7019304Speter } else 7119304Speter attach = 1; 7219304Speter setalt = 0; 7319304Speter break; 7419304Speter case 1: 75254225Speter INT2CHAR(sp, cmdp->argv[0]->bp, cmdp->argv[0]->len + 1, 76254225Speter np, nlen); 77254225Speter if ((frp = file_add(sp, np)) == NULL) 7819304Speter return (1); 7919304Speter attach = 0; 8019304Speter setalt = 1; 81254225Speter set_alt_name(sp, np); 8219304Speter break; 8319304Speter default: 8419304Speter abort(); 8519304Speter } 8619304Speter 87254225Speter if (F_ISSET(cmdp, E_NEWSCREEN) || cmdp->cmd == &cmds[C_VSPLIT]) 8819304Speter return (ex_N_edit(sp, cmdp, frp, attach)); 8919304Speter 9019304Speter /* 9119304Speter * Check for modifications. 9219304Speter * 9319304Speter * !!! 9419304Speter * Contrary to POSIX 1003.2-1992, autowrite did not affect :edit. 9519304Speter */ 9619304Speter if (file_m2(sp, FL_ISSET(cmdp->iflags, E_C_FORCE))) 9719304Speter return (1); 9819304Speter 9919304Speter /* Switch files. */ 10019304Speter if (file_init(sp, frp, NULL, (setalt ? FS_SETALT : 0) | 10119304Speter (FL_ISSET(cmdp->iflags, E_C_FORCE) ? FS_FORCE : 0))) 10219304Speter return (1); 10319304Speter 10419304Speter F_SET(sp, SC_FSWITCH); 10519304Speter return (0); 10619304Speter} 10719304Speter 10819304Speter/* 10919304Speter * ex_N_edit -- 11019304Speter * New screen version of ex_edit. 11119304Speter */ 11219304Speterstatic int 113254225Speterex_N_edit(SCR *sp, EXCMD *cmdp, FREF *frp, int attach) 11419304Speter{ 11519304Speter SCR *new; 11619304Speter 11719304Speter /* Get a new screen. */ 11819304Speter if (screen_init(sp->gp, sp, &new)) 11919304Speter return (1); 120254225Speter if ((cmdp->cmd == &cmds[C_VSPLIT] && vs_vsplit(sp, new)) || 121254225Speter (cmdp->cmd != &cmds[C_VSPLIT] && vs_split(sp, new, 0))) { 12219304Speter (void)screen_end(new); 12319304Speter return (1); 12419304Speter } 12519304Speter 12619304Speter /* Get a backing file. */ 12719304Speter if (attach) { 12819304Speter /* Copy file state, keep the screen and cursor the same. */ 12919304Speter new->ep = sp->ep; 13019304Speter ++new->ep->refcnt; 13119304Speter 13219304Speter new->frp = frp; 13319304Speter new->frp->flags = sp->frp->flags; 13419304Speter 13519304Speter new->lno = sp->lno; 13619304Speter new->cno = sp->cno; 137254225Speter 138254225Speter#if defined(USE_WIDECHAR) && defined(USE_ICONV) 139254225Speter /* Synchronize the iconv environments. */ 140254225Speter o_set(new, O_FILEENCODING, OS_STRDUP, 141254225Speter O_STR(sp, O_FILEENCODING), 0); 142254225Speter conv_enc(new, O_FILEENCODING, 0); 143254225Speter#endif 14419304Speter } else if (file_init(new, frp, NULL, 14519304Speter (FL_ISSET(cmdp->iflags, E_C_FORCE) ? FS_FORCE : 0))) { 14619304Speter (void)vs_discard(new, NULL); 14719304Speter (void)screen_end(new); 14819304Speter return (1); 14919304Speter } 15019304Speter 15119304Speter /* Create the argument list. */ 15219304Speter new->cargv = new->argv = ex_buildargv(sp, NULL, frp->name); 15319304Speter 15419304Speter /* Set up the switch. */ 15519304Speter sp->nextdisp = new; 15619304Speter F_SET(sp, SC_SSWITCH); 15719304Speter 15819304Speter return (0); 15919304Speter} 160