1b8ba871bSPeter Wemm /*-
2b8ba871bSPeter Wemm * Copyright (c) 1992, 1993, 1994
3b8ba871bSPeter Wemm * The Regents of the University of California. All rights reserved.
4b8ba871bSPeter Wemm * Copyright (c) 1992, 1993, 1994, 1995, 1996
5b8ba871bSPeter Wemm * Keith Bostic. All rights reserved.
6b8ba871bSPeter Wemm *
7b8ba871bSPeter Wemm * See the LICENSE file for redistribution information.
8b8ba871bSPeter Wemm */
9b8ba871bSPeter Wemm
10b8ba871bSPeter Wemm #include "config.h"
11b8ba871bSPeter Wemm
12b8ba871bSPeter Wemm #include <sys/types.h>
13b8ba871bSPeter Wemm #include <sys/queue.h>
14b8ba871bSPeter Wemm #include <sys/time.h>
15b8ba871bSPeter Wemm
16b8ba871bSPeter Wemm #include <bitstring.h>
17b8ba871bSPeter Wemm #include <errno.h>
18b8ba871bSPeter Wemm #include <limits.h>
19b8ba871bSPeter Wemm #include <stdio.h>
20b8ba871bSPeter Wemm #include <stdlib.h>
21b8ba871bSPeter Wemm #include <string.h>
22b8ba871bSPeter Wemm
23b8ba871bSPeter Wemm #include "../common/common.h"
24b8ba871bSPeter Wemm #include "../vi/vi.h"
25b8ba871bSPeter Wemm
26*c271fa92SBaptiste Daroussin static int ex_N_edit(SCR *, EXCMD *, FREF *, int);
27b8ba871bSPeter Wemm
28b8ba871bSPeter Wemm /*
29b8ba871bSPeter Wemm * ex_edit -- :e[dit][!] [+cmd] [file]
30b8ba871bSPeter Wemm * :ex[!] [+cmd] [file]
31b8ba871bSPeter Wemm * :vi[sual][!] [+cmd] [file]
32b8ba871bSPeter Wemm *
33b8ba871bSPeter Wemm * Edit a file; if none specified, re-edit the current file. The third
34b8ba871bSPeter Wemm * form of the command can only be executed while in vi mode. See the
35b8ba871bSPeter Wemm * hack in ex.c:ex_cmd().
36b8ba871bSPeter Wemm *
37b8ba871bSPeter Wemm * !!!
38b8ba871bSPeter Wemm * Historic vi didn't permit the '+' command form without specifying
39b8ba871bSPeter Wemm * a file name as well. This seems unreasonable, so we support it
40b8ba871bSPeter Wemm * regardless.
41b8ba871bSPeter Wemm *
42*c271fa92SBaptiste Daroussin * PUBLIC: int ex_edit(SCR *, EXCMD *);
43b8ba871bSPeter Wemm */
44b8ba871bSPeter Wemm int
ex_edit(SCR * sp,EXCMD * cmdp)45f0957ccaSPeter Wemm ex_edit(SCR *sp, EXCMD *cmdp)
46b8ba871bSPeter Wemm {
47b8ba871bSPeter Wemm FREF *frp;
48b8ba871bSPeter Wemm int attach, setalt;
49f0957ccaSPeter Wemm char *np;
50f0957ccaSPeter Wemm size_t nlen;
51b8ba871bSPeter Wemm
52b8ba871bSPeter Wemm switch (cmdp->argc) {
53b8ba871bSPeter Wemm case 0:
54b8ba871bSPeter Wemm /*
55b8ba871bSPeter Wemm * If the name has been changed, we edit that file, not the
56b8ba871bSPeter Wemm * original name. If the user was editing a temporary file
57b8ba871bSPeter Wemm * (or wasn't editing any file), create another one. The
58b8ba871bSPeter Wemm * reason for not reusing temporary files is that there is
59b8ba871bSPeter Wemm * special exit processing of them, and reuse is tricky.
60b8ba871bSPeter Wemm */
61b8ba871bSPeter Wemm frp = sp->frp;
62b8ba871bSPeter Wemm if (sp->ep == NULL || F_ISSET(frp, FR_TMPFILE)) {
63b8ba871bSPeter Wemm if ((frp = file_add(sp, NULL)) == NULL)
64b8ba871bSPeter Wemm return (1);
65b8ba871bSPeter Wemm attach = 0;
66b8ba871bSPeter Wemm } else
67b8ba871bSPeter Wemm attach = 1;
68b8ba871bSPeter Wemm setalt = 0;
69b8ba871bSPeter Wemm break;
70b8ba871bSPeter Wemm case 1:
71f0957ccaSPeter Wemm INT2CHAR(sp, cmdp->argv[0]->bp, cmdp->argv[0]->len + 1,
72f0957ccaSPeter Wemm np, nlen);
73f0957ccaSPeter Wemm if ((frp = file_add(sp, np)) == NULL)
74b8ba871bSPeter Wemm return (1);
75b8ba871bSPeter Wemm attach = 0;
76b8ba871bSPeter Wemm setalt = 1;
77f0957ccaSPeter Wemm set_alt_name(sp, np);
78b8ba871bSPeter Wemm break;
79b8ba871bSPeter Wemm default:
80b8ba871bSPeter Wemm abort();
81b8ba871bSPeter Wemm }
82b8ba871bSPeter Wemm
83f0957ccaSPeter Wemm if (F_ISSET(cmdp, E_NEWSCREEN) || cmdp->cmd == &cmds[C_VSPLIT])
84b8ba871bSPeter Wemm return (ex_N_edit(sp, cmdp, frp, attach));
85b8ba871bSPeter Wemm
86b8ba871bSPeter Wemm /*
87b8ba871bSPeter Wemm * Check for modifications.
88b8ba871bSPeter Wemm *
89b8ba871bSPeter Wemm * !!!
90b8ba871bSPeter Wemm * Contrary to POSIX 1003.2-1992, autowrite did not affect :edit.
91b8ba871bSPeter Wemm */
92b8ba871bSPeter Wemm if (file_m2(sp, FL_ISSET(cmdp->iflags, E_C_FORCE)))
93b8ba871bSPeter Wemm return (1);
94b8ba871bSPeter Wemm
95b8ba871bSPeter Wemm /* Switch files. */
96b8ba871bSPeter Wemm if (file_init(sp, frp, NULL, (setalt ? FS_SETALT : 0) |
97b8ba871bSPeter Wemm (FL_ISSET(cmdp->iflags, E_C_FORCE) ? FS_FORCE : 0)))
98b8ba871bSPeter Wemm return (1);
99b8ba871bSPeter Wemm
100b8ba871bSPeter Wemm F_SET(sp, SC_FSWITCH);
101b8ba871bSPeter Wemm return (0);
102b8ba871bSPeter Wemm }
103b8ba871bSPeter Wemm
104b8ba871bSPeter Wemm /*
105b8ba871bSPeter Wemm * ex_N_edit --
106b8ba871bSPeter Wemm * New screen version of ex_edit.
107b8ba871bSPeter Wemm */
108b8ba871bSPeter Wemm static int
ex_N_edit(SCR * sp,EXCMD * cmdp,FREF * frp,int attach)109f0957ccaSPeter Wemm ex_N_edit(SCR *sp, EXCMD *cmdp, FREF *frp, int attach)
110b8ba871bSPeter Wemm {
111b8ba871bSPeter Wemm SCR *new;
112b8ba871bSPeter Wemm
113b8ba871bSPeter Wemm /* Get a new screen. */
114b8ba871bSPeter Wemm if (screen_init(sp->gp, sp, &new))
115b8ba871bSPeter Wemm return (1);
116f0957ccaSPeter Wemm if ((cmdp->cmd == &cmds[C_VSPLIT] && vs_vsplit(sp, new)) ||
117f0957ccaSPeter Wemm (cmdp->cmd != &cmds[C_VSPLIT] && vs_split(sp, new, 0))) {
118b8ba871bSPeter Wemm (void)screen_end(new);
119b8ba871bSPeter Wemm return (1);
120b8ba871bSPeter Wemm }
121b8ba871bSPeter Wemm
122b8ba871bSPeter Wemm /* Get a backing file. */
123b8ba871bSPeter Wemm if (attach) {
124b8ba871bSPeter Wemm /* Copy file state, keep the screen and cursor the same. */
125b8ba871bSPeter Wemm new->ep = sp->ep;
126b8ba871bSPeter Wemm ++new->ep->refcnt;
127b8ba871bSPeter Wemm
128b8ba871bSPeter Wemm new->frp = frp;
129b8ba871bSPeter Wemm new->frp->flags = sp->frp->flags;
130b8ba871bSPeter Wemm
131b8ba871bSPeter Wemm new->lno = sp->lno;
132b8ba871bSPeter Wemm new->cno = sp->cno;
133f0957ccaSPeter Wemm
134f0957ccaSPeter Wemm #if defined(USE_WIDECHAR) && defined(USE_ICONV)
135f0957ccaSPeter Wemm /* Synchronize the iconv environments. */
136f0957ccaSPeter Wemm o_set(new, O_FILEENCODING, OS_STRDUP,
137f0957ccaSPeter Wemm O_STR(sp, O_FILEENCODING), 0);
138f0957ccaSPeter Wemm conv_enc(new, O_FILEENCODING, 0);
139f0957ccaSPeter Wemm #endif
140b8ba871bSPeter Wemm } else if (file_init(new, frp, NULL,
141b8ba871bSPeter Wemm (FL_ISSET(cmdp->iflags, E_C_FORCE) ? FS_FORCE : 0))) {
142b8ba871bSPeter Wemm (void)vs_discard(new, NULL);
143b8ba871bSPeter Wemm (void)screen_end(new);
144b8ba871bSPeter Wemm return (1);
145b8ba871bSPeter Wemm }
146b8ba871bSPeter Wemm
147b8ba871bSPeter Wemm /* Create the argument list. */
148b8ba871bSPeter Wemm new->cargv = new->argv = ex_buildargv(sp, NULL, frp->name);
149b8ba871bSPeter Wemm
150b8ba871bSPeter Wemm /* Set up the switch. */
151b8ba871bSPeter Wemm sp->nextdisp = new;
152b8ba871bSPeter Wemm F_SET(sp, SC_SSWITCH);
153b8ba871bSPeter Wemm
154b8ba871bSPeter Wemm return (0);
155b8ba871bSPeter Wemm }
156