2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
5 * %sccs.include.redist.c%
9 static char sccsid
[] = "$Id: ex_args.c,v 8.13 1993/12/20 09:35:28 bostic Exp $ (Berkeley) $Date: 1993/12/20 09:35:28 $";
12 #include <sys/types.h>
22 * ex_next -- :next [files]
23 * Edit the next file, optionally setting the list of files.
26 * The :next command behaved differently from the :rewind command in
27 * historic vi. See nvi/docs/autowrite for details, but the basic
28 * idea was that it ignored the force flag if the autowrite flag was
29 * set. This implementation handles them all identically.
41 MODIFY_CHECK(sp
, ep
, F_ISSET(cmdp
, E_FORCE
));
44 /* Mark all the current files as ignored. */
45 for (frp
= sp
->frefq
.cqh_first
;
46 frp
!= (FREF
*)&sp
->frefq
; frp
= frp
->q
.cqe_next
)
47 F_SET(frp
, FR_IGNORE
);
49 /* Add the new files into the file list. */
50 for (argv
= cmdp
->argv
; argv
[0]->len
!= 0; ++argv
)
51 if (file_add(sp
, NULL
, argv
[0]->bp
, 0) == NULL
)
54 if ((frp
= file_first(sp
)) == NULL
)
56 } else if ((frp
= file_next(sp
, sp
->a_frp
)) == NULL
) {
57 msgq(sp
, M_ERR
, "No more files to edit.");
62 * There's a tricky sequence, where the user edits two files, e.g.
63 * "x" and "y". While in "x", they do ":e y|:f foo", which changes
64 * the name of that FRP entry. Then, the :n command finds the file
65 * "y" with a name change. If the file name has been changed, get
66 * a new FREF for the original file name, and make it be the one that
67 * is displayed in the argument list, not the one with the name change.
69 if (frp
->cname
!= NULL
) {
70 F_SET(frp
, FR_IGNORE
);
71 name
= frp
->name
== NULL
? frp
->tname
: frp
->name
;
72 if ((frp
= file_add(sp
, sp
->a_frp
, name
, 0)) == NULL
)
75 if (file_init(sp
, frp
, NULL
, F_ISSET(cmdp
, E_FORCE
)))
84 * Edit the previous file.
95 MODIFY_CHECK(sp
, ep
, F_ISSET(cmdp
, E_FORCE
));
97 if ((frp
= file_prev(sp
, sp
->a_frp
)) == NULL
) {
98 msgq(sp
, M_ERR
, "No previous files to edit.");
102 /* See comment in ex_next(). */
103 if (frp
->cname
!= NULL
) {
104 F_SET(frp
, FR_IGNORE
);
105 name
= frp
->name
== NULL
? frp
->tname
: frp
->name
;
106 if ((frp
= file_add(sp
, frp
, name
, 0)) == NULL
)
109 if (file_init(sp
, frp
, NULL
, F_ISSET(cmdp
, E_FORCE
)))
112 F_SET(sp
, S_FSWITCH
);
118 * Re-edit the list of files.
130 * Historic practice -- you can rewind to the current file.
132 if ((frp
= file_first(sp
)) == NULL
) {
133 msgq(sp
, M_ERR
, "No previous files to rewind.");
137 MODIFY_CHECK(sp
, ep
, F_ISSET(cmdp
, E_FORCE
));
141 * Historic practice, turn off the edited bit. The :next and :prev
142 * code will discard any name changes, so ignore them here. Start
143 * at the beginning of the file, too.
145 for (tfrp
= sp
->frefq
.cqh_first
;
146 tfrp
!= (FREF
*)&sp
->frefq
; tfrp
= tfrp
->q
.cqe_next
)
147 F_CLR(tfrp
, FR_CHANGEWRITE
| FR_CURSORSET
| FR_EDITED
);
149 if (file_init(sp
, frp
, NULL
, F_ISSET(cmdp
, E_FORCE
)))
152 F_SET(sp
, S_FSWITCH
);
158 * Display the list of files.
161 ex_args(sp
, ep
, cmdp
)
167 int cnt
, col
, iscur
, len
, nlen
, sep
;
172 * Ignore files that aren't in the "argument" list unless they are the
173 * one we're currently editing. I'm not sure this is right, but the
174 * historic vi behavior of not showing the current file if it was the
175 * result of a ":e" command, or if the file name was changed was wrong.
176 * This is actually pretty tricky, don't modify it without thinking it
177 * through. There have been a lot of problems in here.
179 * Also, historic practice was to display the original name of the file
180 * even if the user had used a file command to change the file name.
181 * Confusing, at best. We show both names: the original as that's what
182 * the user will get in a next, prev or rewind, and the new one since
183 * that's what the user is actually editing now.
185 * When we find the "argument" FREF, i.e. the current location in the
186 * user's argument list, if it's not the same as the current FREF, we
187 * display the current FREF as following the argument in the list.
188 * This means that if the user edits three files, "x", "y" and "z", and
189 * then does a :e command in the file "x" to edit "z", "z" will appear
193 for (cnt
= 1, frp
= sp
->frefq
.cqh_first
;
194 frp
!= (FREF
*)&sp
->frefq
; frp
= frp
->q
.cqe_next
) {
197 * If the last argument FREF structure, and we're editing
198 * it, set the current bit. Otherwise, we'll display it,
199 * then the file we're editing, and the latter will have
200 * the current bit set.
202 if (frp
== sp
->a_frp
) {
203 if (frp
== sp
->frp
&& frp
->cname
== NULL
)
205 } else if (F_ISSET(frp
, FR_IGNORE
))
207 name
= frp
->name
== NULL
? frp
->tname
: frp
->name
;
209 * Mistake. The user edited a temporary file (vi /tmp), then
210 * switched to another file (:e file). The argument FREF is
211 * pointing to the temporary file, but it doesn't have a name.
212 * Gracefully recover through the creative use of goto's.
216 extra
: nlen
= strlen(name
);
217 col
+= len
= nlen
+ sep
+ (iscur
? 2 : 0);
218 if (col
>= sp
->cols
- 1) {
221 (void)ex_printf(EXCOOKIE
, "\n");
222 } else if (cnt
!= 1) {
224 (void)ex_printf(EXCOOKIE
, " ");
229 (void)ex_printf(EXCOOKIE
, "[%s]", name
);
231 (void)ex_printf(EXCOOKIE
, "%s", name
);
232 testcur
: if (frp
== sp
->a_frp
) {
234 name
= FILENAME(sp
->frp
);
242 /* This should never happen; left in because it's been known to. */
244 (void)ex_printf(EXCOOKIE
, "No files.\n");
246 (void)ex_printf(EXCOOKIE
, "\n");