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