xref: /freebsd/contrib/less/command.c (revision aa22b8b6698584311a0760f139016a04309b0504)
1a8f92a7cSPaul Saab /* $FreeBSD$ */
2a5f0fb15SPaul Saab /*
3720c436cSXin LI  * Copyright (C) 1984-2007  Mark Nudelman
4a5f0fb15SPaul Saab  *
5a5f0fb15SPaul Saab  * You may distribute under the terms of either the GNU General Public
6a5f0fb15SPaul Saab  * License or the Less License, as specified in the README file.
7a5f0fb15SPaul Saab  *
8a5f0fb15SPaul Saab  * For more information about less, or for information on how to
9a5f0fb15SPaul Saab  * contact the author, see the README file.
10a5f0fb15SPaul Saab  */
11a5f0fb15SPaul Saab 
12a5f0fb15SPaul Saab 
13a5f0fb15SPaul Saab /*
14a5f0fb15SPaul Saab  * User-level command processor.
15a5f0fb15SPaul Saab  */
16a5f0fb15SPaul Saab 
17a5f0fb15SPaul Saab #include "less.h"
188fd4165cSPaul Saab #if MSDOS_COMPILER==WIN32C
198fd4165cSPaul Saab #include <windows.h>
208fd4165cSPaul Saab #endif
21a5f0fb15SPaul Saab #include "position.h"
22a5f0fb15SPaul Saab #include "option.h"
23a5f0fb15SPaul Saab #include "cmd.h"
24a5f0fb15SPaul Saab 
2589dd99dcSXin LI extern int erase_char, erase2_char, kill_char;
26a5f0fb15SPaul Saab extern int sigs;
27a5f0fb15SPaul Saab extern int quit_if_one_screen;
28a5f0fb15SPaul Saab extern int squished;
29a5f0fb15SPaul Saab extern int hit_eof;
30a5f0fb15SPaul Saab extern int sc_width;
31a5f0fb15SPaul Saab extern int sc_height;
32a5f0fb15SPaul Saab extern int swindow;
33a5f0fb15SPaul Saab extern int jump_sline;
34a5f0fb15SPaul Saab extern int quitting;
35a5f0fb15SPaul Saab extern int wscroll;
36a5f0fb15SPaul Saab extern int top_scroll;
37a5f0fb15SPaul Saab extern int ignore_eoi;
38a5f0fb15SPaul Saab extern int secure;
39a5f0fb15SPaul Saab extern int hshift;
40a5f0fb15SPaul Saab extern int show_attn;
41720c436cSXin LI extern int less_is_more;
42a5f0fb15SPaul Saab extern char *every_first_cmd;
43a5f0fb15SPaul Saab extern char *curr_altfilename;
44a5f0fb15SPaul Saab extern char version[];
45a5f0fb15SPaul Saab extern struct scrpos initial_scrpos;
46a5f0fb15SPaul Saab extern IFILE curr_ifile;
47a5f0fb15SPaul Saab extern void constant *ml_search;
48a5f0fb15SPaul Saab extern void constant *ml_examine;
49a5f0fb15SPaul Saab #if SHELL_ESCAPE || PIPEC
50a5f0fb15SPaul Saab extern void constant *ml_shell;
51a5f0fb15SPaul Saab #endif
52a5f0fb15SPaul Saab #if EDITOR
53a5f0fb15SPaul Saab extern char *editor;
54a5f0fb15SPaul Saab extern char *editproto;
55a5f0fb15SPaul Saab #endif
56a5f0fb15SPaul Saab extern int screen_trashed;	/* The screen has been overwritten */
5715596da4SPaul Saab extern int shift_count;
58720c436cSXin LI extern int oldbot;
59720c436cSXin LI extern int forw_prompt;
60a5f0fb15SPaul Saab 
61a5f0fb15SPaul Saab static char ungot[UNGOT_SIZE];
62a5f0fb15SPaul Saab static char *ungotp = NULL;
63a5f0fb15SPaul Saab #if SHELL_ESCAPE
64a5f0fb15SPaul Saab static char *shellcmd = NULL;	/* For holding last shell command for "!!" */
65a5f0fb15SPaul Saab #endif
66a5f0fb15SPaul Saab static int mca;			/* The multicharacter command (action) */
67a5f0fb15SPaul Saab static int search_type;		/* The previous type of search */
681ede1615STim J. Robbins static LINENUM number;		/* The number typed by the user */
69720c436cSXin LI static long fraction;		/* The fractional part of the number */
70a5f0fb15SPaul Saab static char optchar;
71a5f0fb15SPaul Saab static int optflag;
72a5f0fb15SPaul Saab static int optgetname;
73a5f0fb15SPaul Saab static POSITION bottompos;
7489dd99dcSXin LI static int save_hshift;
75a5f0fb15SPaul Saab #if PIPEC
76a5f0fb15SPaul Saab static char pipec;
77a5f0fb15SPaul Saab #endif
78a5f0fb15SPaul Saab 
79a5f0fb15SPaul Saab static void multi_search();
80a5f0fb15SPaul Saab 
81a5f0fb15SPaul Saab /*
82720c436cSXin LI  * Move the cursor to start of prompt line before executing a command.
83a5f0fb15SPaul Saab  * This looks nicer if the command takes a long time before
84a5f0fb15SPaul Saab  * updating the screen.
85a5f0fb15SPaul Saab  */
86a5f0fb15SPaul Saab 	static void
87a5f0fb15SPaul Saab cmd_exec()
88a5f0fb15SPaul Saab {
89a5f0fb15SPaul Saab 	clear_attn();
90aa22b8b6SXin LI 	clear_bot();
91a5f0fb15SPaul Saab 	flush();
92a5f0fb15SPaul Saab }
93a5f0fb15SPaul Saab 
94a5f0fb15SPaul Saab /*
95a5f0fb15SPaul Saab  * Set up the display to start a new multi-character command.
96a5f0fb15SPaul Saab  */
97a5f0fb15SPaul Saab 	static void
98a5f0fb15SPaul Saab start_mca(action, prompt, mlist, cmdflags)
99a5f0fb15SPaul Saab 	int action;
100a5f0fb15SPaul Saab 	char *prompt;
101a5f0fb15SPaul Saab 	void *mlist;
102a5f0fb15SPaul Saab 	int cmdflags;
103a5f0fb15SPaul Saab {
104a5f0fb15SPaul Saab 	mca = action;
105720c436cSXin LI 	clear_bot();
106a5f0fb15SPaul Saab 	clear_cmd();
107a5f0fb15SPaul Saab 	cmd_putstr(prompt);
108a5f0fb15SPaul Saab 	set_mlist(mlist, cmdflags);
109a5f0fb15SPaul Saab }
110a5f0fb15SPaul Saab 
111a5f0fb15SPaul Saab 	public int
112a5f0fb15SPaul Saab in_mca()
113a5f0fb15SPaul Saab {
114a5f0fb15SPaul Saab 	return (mca != 0 && mca != A_PREFIX);
115a5f0fb15SPaul Saab }
116a5f0fb15SPaul Saab 
117a5f0fb15SPaul Saab /*
118a5f0fb15SPaul Saab  * Set up the display to start a new search command.
119a5f0fb15SPaul Saab  */
120a5f0fb15SPaul Saab 	static void
121a5f0fb15SPaul Saab mca_search()
122a5f0fb15SPaul Saab {
123a5f0fb15SPaul Saab 	if (search_type & SRCH_FORW)
124a5f0fb15SPaul Saab 		mca = A_F_SEARCH;
125a5f0fb15SPaul Saab 	else
126a5f0fb15SPaul Saab 		mca = A_B_SEARCH;
127a5f0fb15SPaul Saab 
128720c436cSXin LI 	clear_bot();
129a5f0fb15SPaul Saab 	clear_cmd();
130a5f0fb15SPaul Saab 
131a5f0fb15SPaul Saab 	if (search_type & SRCH_NO_MATCH)
132a5f0fb15SPaul Saab 		cmd_putstr("Non-match ");
133a5f0fb15SPaul Saab 	if (search_type & SRCH_FIRST_FILE)
134a5f0fb15SPaul Saab 		cmd_putstr("First-file ");
135a5f0fb15SPaul Saab 	if (search_type & SRCH_PAST_EOF)
136a5f0fb15SPaul Saab 		cmd_putstr("EOF-ignore ");
137a5f0fb15SPaul Saab 	if (search_type & SRCH_NO_MOVE)
138a5f0fb15SPaul Saab 		cmd_putstr("Keep-pos ");
139a5f0fb15SPaul Saab 	if (search_type & SRCH_NO_REGEX)
140a5f0fb15SPaul Saab 		cmd_putstr("Regex-off ");
141a5f0fb15SPaul Saab 
142a5f0fb15SPaul Saab 	if (search_type & SRCH_FORW)
143a5f0fb15SPaul Saab 		cmd_putstr("/");
144a5f0fb15SPaul Saab 	else
145a5f0fb15SPaul Saab 		cmd_putstr("?");
146a5f0fb15SPaul Saab 	set_mlist(ml_search, 0);
147a5f0fb15SPaul Saab }
148a5f0fb15SPaul Saab 
149a5f0fb15SPaul Saab /*
150a5f0fb15SPaul Saab  * Set up the display to start a new toggle-option command.
151a5f0fb15SPaul Saab  */
152a5f0fb15SPaul Saab 	static void
153a5f0fb15SPaul Saab mca_opt_toggle()
154a5f0fb15SPaul Saab {
155a5f0fb15SPaul Saab 	int no_prompt;
156a5f0fb15SPaul Saab 	int flag;
157a5f0fb15SPaul Saab 	char *dash;
158a5f0fb15SPaul Saab 
159a5f0fb15SPaul Saab 	no_prompt = (optflag & OPT_NO_PROMPT);
160a5f0fb15SPaul Saab 	flag = (optflag & ~OPT_NO_PROMPT);
161a5f0fb15SPaul Saab 	dash = (flag == OPT_NO_TOGGLE) ? "_" : "-";
162a5f0fb15SPaul Saab 
163a5f0fb15SPaul Saab 	mca = A_OPT_TOGGLE;
164720c436cSXin LI 	clear_bot();
165a5f0fb15SPaul Saab 	clear_cmd();
166a5f0fb15SPaul Saab 	cmd_putstr(dash);
167a5f0fb15SPaul Saab 	if (optgetname)
168a5f0fb15SPaul Saab 		cmd_putstr(dash);
169a5f0fb15SPaul Saab 	if (no_prompt)
170a5f0fb15SPaul Saab 		cmd_putstr("(P)");
171a5f0fb15SPaul Saab 	switch (flag)
172a5f0fb15SPaul Saab 	{
173a5f0fb15SPaul Saab 	case OPT_UNSET:
174a5f0fb15SPaul Saab 		cmd_putstr("+");
175a5f0fb15SPaul Saab 		break;
176a5f0fb15SPaul Saab 	case OPT_SET:
177a5f0fb15SPaul Saab 		cmd_putstr("!");
178a5f0fb15SPaul Saab 		break;
179a5f0fb15SPaul Saab 	}
180a5f0fb15SPaul Saab 	set_mlist(NULL, 0);
181a5f0fb15SPaul Saab }
182a5f0fb15SPaul Saab 
183a5f0fb15SPaul Saab /*
184a5f0fb15SPaul Saab  * Execute a multicharacter command.
185a5f0fb15SPaul Saab  */
186a5f0fb15SPaul Saab 	static void
187a5f0fb15SPaul Saab exec_mca()
188a5f0fb15SPaul Saab {
189a5f0fb15SPaul Saab 	register char *cbuf;
190a5f0fb15SPaul Saab 
191a5f0fb15SPaul Saab 	cmd_exec();
192a5f0fb15SPaul Saab 	cbuf = get_cmdbuf();
193a5f0fb15SPaul Saab 
194a5f0fb15SPaul Saab 	switch (mca)
195a5f0fb15SPaul Saab 	{
196a5f0fb15SPaul Saab 	case A_F_SEARCH:
197a5f0fb15SPaul Saab 	case A_B_SEARCH:
1981ede1615STim J. Robbins 		multi_search(cbuf, (int) number);
199a5f0fb15SPaul Saab 		break;
200a5f0fb15SPaul Saab 	case A_FIRSTCMD:
201a5f0fb15SPaul Saab 		/*
202a5f0fb15SPaul Saab 		 * Skip leading spaces or + signs in the string.
203a5f0fb15SPaul Saab 		 */
204a5f0fb15SPaul Saab 		while (*cbuf == '+' || *cbuf == ' ')
205a5f0fb15SPaul Saab 			cbuf++;
206a5f0fb15SPaul Saab 		if (every_first_cmd != NULL)
207a5f0fb15SPaul Saab 			free(every_first_cmd);
208a5f0fb15SPaul Saab 		if (*cbuf == '\0')
209a5f0fb15SPaul Saab 			every_first_cmd = NULL;
210a5f0fb15SPaul Saab 		else
211a5f0fb15SPaul Saab 			every_first_cmd = save(cbuf);
212a5f0fb15SPaul Saab 		break;
213a5f0fb15SPaul Saab 	case A_OPT_TOGGLE:
214a5f0fb15SPaul Saab 		toggle_option(optchar, cbuf, optflag);
215a5f0fb15SPaul Saab 		optchar = '\0';
216a5f0fb15SPaul Saab 		break;
217a5f0fb15SPaul Saab 	case A_F_BRACKET:
2181ede1615STim J. Robbins 		match_brac(cbuf[0], cbuf[1], 1, (int) number);
219a5f0fb15SPaul Saab 		break;
220a5f0fb15SPaul Saab 	case A_B_BRACKET:
2211ede1615STim J. Robbins 		match_brac(cbuf[1], cbuf[0], 0, (int) number);
222a5f0fb15SPaul Saab 		break;
223a5f0fb15SPaul Saab #if EXAMINE
224a5f0fb15SPaul Saab 	case A_EXAMINE:
225a5f0fb15SPaul Saab 		if (secure)
226a5f0fb15SPaul Saab 			break;
227a5f0fb15SPaul Saab 		edit_list(cbuf);
2281ede1615STim J. Robbins #if TAGS
2298fd4165cSPaul Saab 		/* If tag structure is loaded then clean it up. */
2308fd4165cSPaul Saab 		cleantags();
2311ede1615STim J. Robbins #endif
232a5f0fb15SPaul Saab 		break;
233a5f0fb15SPaul Saab #endif
234a5f0fb15SPaul Saab #if SHELL_ESCAPE
235a5f0fb15SPaul Saab 	case A_SHELL:
236a5f0fb15SPaul Saab 		/*
237a5f0fb15SPaul Saab 		 * !! just uses whatever is in shellcmd.
238a5f0fb15SPaul Saab 		 * Otherwise, copy cmdbuf to shellcmd,
239a5f0fb15SPaul Saab 		 * expanding any special characters ("%" or "#").
240a5f0fb15SPaul Saab 		 */
241a5f0fb15SPaul Saab 		if (*cbuf != '!')
242a5f0fb15SPaul Saab 		{
243a5f0fb15SPaul Saab 			if (shellcmd != NULL)
244a5f0fb15SPaul Saab 				free(shellcmd);
245a5f0fb15SPaul Saab 			shellcmd = fexpand(cbuf);
246a5f0fb15SPaul Saab 		}
247a5f0fb15SPaul Saab 
248a5f0fb15SPaul Saab 		if (secure)
249a5f0fb15SPaul Saab 			break;
250a5f0fb15SPaul Saab 		if (shellcmd == NULL)
251a5f0fb15SPaul Saab 			lsystem("", "!done");
252a5f0fb15SPaul Saab 		else
253a5f0fb15SPaul Saab 			lsystem(shellcmd, "!done");
254a5f0fb15SPaul Saab 		break;
255a5f0fb15SPaul Saab #endif
256a5f0fb15SPaul Saab #if PIPEC
257a5f0fb15SPaul Saab 	case A_PIPE:
258a5f0fb15SPaul Saab 		if (secure)
259a5f0fb15SPaul Saab 			break;
260a5f0fb15SPaul Saab 		(void) pipe_mark(pipec, cbuf);
261a5f0fb15SPaul Saab 		error("|done", NULL_PARG);
262a5f0fb15SPaul Saab 		break;
263a5f0fb15SPaul Saab #endif
264a5f0fb15SPaul Saab 	}
265a5f0fb15SPaul Saab }
266a5f0fb15SPaul Saab 
267a5f0fb15SPaul Saab /*
268a5f0fb15SPaul Saab  * Add a character to a multi-character command.
269a5f0fb15SPaul Saab  */
270a5f0fb15SPaul Saab 	static int
271a5f0fb15SPaul Saab mca_char(c)
272a5f0fb15SPaul Saab 	int c;
273a5f0fb15SPaul Saab {
274a5f0fb15SPaul Saab 	char *p;
275a5f0fb15SPaul Saab 	int flag;
276a5f0fb15SPaul Saab 	char buf[3];
277a5f0fb15SPaul Saab 	PARG parg;
278a5f0fb15SPaul Saab 
279a5f0fb15SPaul Saab 	switch (mca)
280a5f0fb15SPaul Saab 	{
281a5f0fb15SPaul Saab 	case 0:
282a5f0fb15SPaul Saab 		/*
283a5f0fb15SPaul Saab 		 * Not in a multicharacter command.
284a5f0fb15SPaul Saab 		 */
285a5f0fb15SPaul Saab 		return (NO_MCA);
286a5f0fb15SPaul Saab 
287a5f0fb15SPaul Saab 	case A_PREFIX:
288a5f0fb15SPaul Saab 		/*
289a5f0fb15SPaul Saab 		 * In the prefix of a command.
290a5f0fb15SPaul Saab 		 * This not considered a multichar command
291a5f0fb15SPaul Saab 		 * (even tho it uses cmdbuf, etc.).
292a5f0fb15SPaul Saab 		 * It is handled in the commands() switch.
293a5f0fb15SPaul Saab 		 */
294a5f0fb15SPaul Saab 		return (NO_MCA);
295a5f0fb15SPaul Saab 
296a5f0fb15SPaul Saab 	case A_DIGIT:
297a5f0fb15SPaul Saab 		/*
298a5f0fb15SPaul Saab 		 * Entering digits of a number.
299a5f0fb15SPaul Saab 		 * Terminated by a non-digit.
300a5f0fb15SPaul Saab 		 */
301720c436cSXin LI 		if (!((c >= '0' && c <= '9') || c == '.') &&
3028fd4165cSPaul Saab 		  editchar(c, EC_PEEK|EC_NOHISTORY|EC_NOCOMPLETE|EC_NORIGHTLEFT) == A_INVALID)
303a5f0fb15SPaul Saab 		{
304a5f0fb15SPaul Saab 			/*
305a5f0fb15SPaul Saab 			 * Not part of the number.
306a5f0fb15SPaul Saab 			 * Treat as a normal command character.
307a5f0fb15SPaul Saab 			 */
308720c436cSXin LI 			number = cmd_int(&fraction);
309a5f0fb15SPaul Saab 			mca = 0;
310a5f0fb15SPaul Saab 			cmd_accept();
311a5f0fb15SPaul Saab 			return (NO_MCA);
312a5f0fb15SPaul Saab 		}
313a5f0fb15SPaul Saab 		break;
314a5f0fb15SPaul Saab 
315a5f0fb15SPaul Saab 	case A_OPT_TOGGLE:
316a5f0fb15SPaul Saab 		/*
317a5f0fb15SPaul Saab 		 * Special case for the TOGGLE_OPTION command.
318a5f0fb15SPaul Saab 		 * If the option letter which was entered is a
319a5f0fb15SPaul Saab 		 * single-char option, execute the command immediately,
320a5f0fb15SPaul Saab 		 * so user doesn't have to hit RETURN.
321a5f0fb15SPaul Saab 		 * If the first char is + or -, this indicates
322a5f0fb15SPaul Saab 		 * OPT_UNSET or OPT_SET respectively, instead of OPT_TOGGLE.
323a5f0fb15SPaul Saab 		 * "--" begins inputting a long option name.
324a5f0fb15SPaul Saab 		 */
325a5f0fb15SPaul Saab 		if (optchar == '\0' && len_cmdbuf() == 0)
326a5f0fb15SPaul Saab 		{
327a5f0fb15SPaul Saab 			flag = (optflag & ~OPT_NO_PROMPT);
328a5f0fb15SPaul Saab 			if (flag == OPT_NO_TOGGLE)
329a5f0fb15SPaul Saab 			{
330a5f0fb15SPaul Saab 				switch (c)
331a5f0fb15SPaul Saab 				{
332a5f0fb15SPaul Saab 				case '_':
333a5f0fb15SPaul Saab 					/* "__" = long option name. */
334a5f0fb15SPaul Saab 					optgetname = TRUE;
335a5f0fb15SPaul Saab 					mca_opt_toggle();
336a5f0fb15SPaul Saab 					return (MCA_MORE);
337a5f0fb15SPaul Saab 				}
338a5f0fb15SPaul Saab 			} else
339a5f0fb15SPaul Saab 			{
340a5f0fb15SPaul Saab 				switch (c)
341a5f0fb15SPaul Saab 				{
342a5f0fb15SPaul Saab 				case '+':
343a5f0fb15SPaul Saab 					/* "-+" = UNSET. */
344a5f0fb15SPaul Saab 					optflag = (flag == OPT_UNSET) ?
345a5f0fb15SPaul Saab 						OPT_TOGGLE : OPT_UNSET;
346a5f0fb15SPaul Saab 					mca_opt_toggle();
347a5f0fb15SPaul Saab 					return (MCA_MORE);
348a5f0fb15SPaul Saab 				case '!':
349a5f0fb15SPaul Saab 					/* "-!" = SET */
350a5f0fb15SPaul Saab 					optflag = (flag == OPT_SET) ?
351a5f0fb15SPaul Saab 						OPT_TOGGLE : OPT_SET;
352a5f0fb15SPaul Saab 					mca_opt_toggle();
353a5f0fb15SPaul Saab 					return (MCA_MORE);
354a5f0fb15SPaul Saab 				case CONTROL('P'):
355a5f0fb15SPaul Saab 					optflag ^= OPT_NO_PROMPT;
356a5f0fb15SPaul Saab 					mca_opt_toggle();
357a5f0fb15SPaul Saab 					return (MCA_MORE);
358a5f0fb15SPaul Saab 				case '-':
359a5f0fb15SPaul Saab 					/* "--" = long option name. */
360a5f0fb15SPaul Saab 					optgetname = TRUE;
361a5f0fb15SPaul Saab 					mca_opt_toggle();
362a5f0fb15SPaul Saab 					return (MCA_MORE);
363a5f0fb15SPaul Saab 				}
364a5f0fb15SPaul Saab 			}
365a5f0fb15SPaul Saab 		}
366a5f0fb15SPaul Saab 		if (optgetname)
367a5f0fb15SPaul Saab 		{
368a5f0fb15SPaul Saab 			/*
369a5f0fb15SPaul Saab 			 * We're getting a long option name.
370a5f0fb15SPaul Saab 			 * See if we've matched an option name yet.
371a5f0fb15SPaul Saab 			 * If so, display the complete name and stop
372a5f0fb15SPaul Saab 			 * accepting chars until user hits RETURN.
373a5f0fb15SPaul Saab 			 */
3741ede1615STim J. Robbins 			struct loption *o;
375a5f0fb15SPaul Saab 			char *oname;
376a5f0fb15SPaul Saab 			int lc;
377a5f0fb15SPaul Saab 
378a5f0fb15SPaul Saab 			if (c == '\n' || c == '\r')
379a5f0fb15SPaul Saab 			{
380a5f0fb15SPaul Saab 				/*
381a5f0fb15SPaul Saab 				 * When the user hits RETURN, make sure
382a5f0fb15SPaul Saab 				 * we've matched an option name, then
383a5f0fb15SPaul Saab 				 * pretend he just entered the equivalent
384a5f0fb15SPaul Saab 				 * option letter.
385a5f0fb15SPaul Saab 				 */
386a5f0fb15SPaul Saab 				if (optchar == '\0')
387a5f0fb15SPaul Saab 				{
388a5f0fb15SPaul Saab 					parg.p_string = get_cmdbuf();
389a5f0fb15SPaul Saab 					error("There is no --%s option", &parg);
390a5f0fb15SPaul Saab 					return (MCA_DONE);
391a5f0fb15SPaul Saab 				}
392a5f0fb15SPaul Saab 				optgetname = FALSE;
393a5f0fb15SPaul Saab 				cmd_reset();
394a5f0fb15SPaul Saab 				c = optchar;
395a5f0fb15SPaul Saab 			} else
396a5f0fb15SPaul Saab 			{
397a5f0fb15SPaul Saab 				if (optchar != '\0')
398a5f0fb15SPaul Saab 				{
399a5f0fb15SPaul Saab 					/*
400a5f0fb15SPaul Saab 					 * Already have a match for the name.
401a5f0fb15SPaul Saab 					 * Don't accept anything but erase/kill.
402a5f0fb15SPaul Saab 					 */
40389dd99dcSXin LI 					if (c == erase_char ||
40489dd99dcSXin LI 					    c == erase2_char ||
40589dd99dcSXin LI 					    c == kill_char)
406a5f0fb15SPaul Saab 						return (MCA_DONE);
407a5f0fb15SPaul Saab 					return (MCA_MORE);
408a5f0fb15SPaul Saab 				}
409a5f0fb15SPaul Saab 				/*
410a5f0fb15SPaul Saab 				 * Add char to cmd buffer and try to match
411a5f0fb15SPaul Saab 				 * the option name.
412a5f0fb15SPaul Saab 				 */
413a5f0fb15SPaul Saab 				if (cmd_char(c) == CC_QUIT)
414a5f0fb15SPaul Saab 					return (MCA_DONE);
415a5f0fb15SPaul Saab 				p = get_cmdbuf();
41689dd99dcSXin LI 				lc = ASCII_IS_LOWER(p[0]);
417a5f0fb15SPaul Saab 				o = findopt_name(&p, &oname, NULL);
418a5f0fb15SPaul Saab 				if (o != NULL)
419a5f0fb15SPaul Saab 				{
420a5f0fb15SPaul Saab 					/*
421a5f0fb15SPaul Saab 					 * Got a match.
422a5f0fb15SPaul Saab 					 * Remember the option letter and
423a5f0fb15SPaul Saab 					 * display the full option name.
424a5f0fb15SPaul Saab 					 */
425a5f0fb15SPaul Saab 					optchar = o->oletter;
42689dd99dcSXin LI 					if (!lc && ASCII_IS_LOWER(optchar))
42789dd99dcSXin LI 						optchar = ASCII_TO_UPPER(optchar);
428a5f0fb15SPaul Saab 					cmd_reset();
429a5f0fb15SPaul Saab 					mca_opt_toggle();
430a5f0fb15SPaul Saab 					for (p = oname;  *p != '\0';  p++)
431a5f0fb15SPaul Saab 					{
432a5f0fb15SPaul Saab 						c = *p;
43389dd99dcSXin LI 						if (!lc && ASCII_IS_LOWER(c))
43489dd99dcSXin LI 							c = ASCII_TO_UPPER(c);
435a5f0fb15SPaul Saab 						if (cmd_char(c) != CC_OK)
436a5f0fb15SPaul Saab 							return (MCA_DONE);
437a5f0fb15SPaul Saab 					}
438a5f0fb15SPaul Saab 				}
439a5f0fb15SPaul Saab 				return (MCA_MORE);
440a5f0fb15SPaul Saab 			}
441a5f0fb15SPaul Saab 		} else
442a5f0fb15SPaul Saab 		{
44389dd99dcSXin LI 			if (c == erase_char || c == erase2_char || c == kill_char)
444a5f0fb15SPaul Saab 				break;
445a5f0fb15SPaul Saab 			if (optchar != '\0')
446a5f0fb15SPaul Saab 				/* We already have the option letter. */
447a5f0fb15SPaul Saab 				break;
448a5f0fb15SPaul Saab 		}
449a5f0fb15SPaul Saab 
450a5f0fb15SPaul Saab 		optchar = c;
451a5f0fb15SPaul Saab 		if ((optflag & ~OPT_NO_PROMPT) != OPT_TOGGLE ||
452a5f0fb15SPaul Saab 		    single_char_option(c))
453a5f0fb15SPaul Saab 		{
454a5f0fb15SPaul Saab 			toggle_option(c, "", optflag);
455a5f0fb15SPaul Saab 			return (MCA_DONE);
456a5f0fb15SPaul Saab 		}
457a5f0fb15SPaul Saab 		/*
458a5f0fb15SPaul Saab 		 * Display a prompt appropriate for the option letter.
459a5f0fb15SPaul Saab 		 */
460a5f0fb15SPaul Saab 		if ((p = opt_prompt(c)) == NULL)
461a5f0fb15SPaul Saab 		{
462a5f0fb15SPaul Saab 			buf[0] = '-';
463a5f0fb15SPaul Saab 			buf[1] = c;
464a5f0fb15SPaul Saab 			buf[2] = '\0';
465a5f0fb15SPaul Saab 			p = buf;
466a5f0fb15SPaul Saab 		}
467a5f0fb15SPaul Saab 		start_mca(A_OPT_TOGGLE, p, (void*)NULL, 0);
468a5f0fb15SPaul Saab 		return (MCA_MORE);
469a5f0fb15SPaul Saab 
470a5f0fb15SPaul Saab 	case A_F_SEARCH:
471a5f0fb15SPaul Saab 	case A_B_SEARCH:
472a5f0fb15SPaul Saab 		/*
473a5f0fb15SPaul Saab 		 * Special case for search commands.
474a5f0fb15SPaul Saab 		 * Certain characters as the first char of
475a5f0fb15SPaul Saab 		 * the pattern have special meaning:
476a5f0fb15SPaul Saab 		 *	!  Toggle the NO_MATCH flag
477a5f0fb15SPaul Saab 		 *	*  Toggle the PAST_EOF flag
478a5f0fb15SPaul Saab 		 *	@  Toggle the FIRST_FILE flag
479a5f0fb15SPaul Saab 		 */
480a5f0fb15SPaul Saab 		if (len_cmdbuf() > 0)
481a5f0fb15SPaul Saab 			/*
482a5f0fb15SPaul Saab 			 * Only works for the first char of the pattern.
483a5f0fb15SPaul Saab 			 */
484a5f0fb15SPaul Saab 			break;
485a5f0fb15SPaul Saab 
486a5f0fb15SPaul Saab 		flag = 0;
487a5f0fb15SPaul Saab 		switch (c)
488a5f0fb15SPaul Saab 		{
489a5f0fb15SPaul Saab 		case '*':
490720c436cSXin LI 			if (less_is_more)
491a8f92a7cSPaul Saab 				break;
492a8f92a7cSPaul Saab 		case CONTROL('E'): /* ignore END of file */
493a5f0fb15SPaul Saab 			flag = SRCH_PAST_EOF;
494a5f0fb15SPaul Saab 			break;
495a5f0fb15SPaul Saab 		case '@':
496720c436cSXin LI 			if (less_is_more)
497a8f92a7cSPaul Saab 				break;
498a8f92a7cSPaul Saab 		case CONTROL('F'): /* FIRST file */
499a5f0fb15SPaul Saab 			flag = SRCH_FIRST_FILE;
500a5f0fb15SPaul Saab 			break;
501a5f0fb15SPaul Saab 		case CONTROL('K'): /* KEEP position */
502a5f0fb15SPaul Saab 			flag = SRCH_NO_MOVE;
503a5f0fb15SPaul Saab 			break;
504a5f0fb15SPaul Saab 		case CONTROL('R'): /* Don't use REGULAR EXPRESSIONS */
505a5f0fb15SPaul Saab 			flag = SRCH_NO_REGEX;
506a5f0fb15SPaul Saab 			break;
507a5f0fb15SPaul Saab 		case CONTROL('N'): /* NOT match */
508a5f0fb15SPaul Saab 		case '!':
509a5f0fb15SPaul Saab 			flag = SRCH_NO_MATCH;
510a5f0fb15SPaul Saab 			break;
511a5f0fb15SPaul Saab 		}
512a5f0fb15SPaul Saab 		if (flag != 0)
513a5f0fb15SPaul Saab 		{
514a5f0fb15SPaul Saab 			search_type ^= flag;
515a5f0fb15SPaul Saab 			mca_search();
516a5f0fb15SPaul Saab 			return (MCA_MORE);
517a5f0fb15SPaul Saab 		}
518a5f0fb15SPaul Saab 		break;
519a5f0fb15SPaul Saab 	}
520a5f0fb15SPaul Saab 
521a5f0fb15SPaul Saab 	/*
522a5f0fb15SPaul Saab 	 * Any other multicharacter command
523a5f0fb15SPaul Saab 	 * is terminated by a newline.
524a5f0fb15SPaul Saab 	 */
525a5f0fb15SPaul Saab 	if (c == '\n' || c == '\r')
526a5f0fb15SPaul Saab 	{
527a5f0fb15SPaul Saab 		/*
528a5f0fb15SPaul Saab 		 * Execute the command.
529a5f0fb15SPaul Saab 		 */
530a5f0fb15SPaul Saab 		exec_mca();
531a5f0fb15SPaul Saab 		return (MCA_DONE);
532a5f0fb15SPaul Saab 	}
533a5f0fb15SPaul Saab 
534a5f0fb15SPaul Saab 	/*
535a5f0fb15SPaul Saab 	 * Append the char to the command buffer.
536a5f0fb15SPaul Saab 	 */
537a5f0fb15SPaul Saab 	if (cmd_char(c) == CC_QUIT)
538a5f0fb15SPaul Saab 		/*
539a5f0fb15SPaul Saab 		 * Abort the multi-char command.
540a5f0fb15SPaul Saab 		 */
541a5f0fb15SPaul Saab 		return (MCA_DONE);
542a5f0fb15SPaul Saab 
543a5f0fb15SPaul Saab 	if ((mca == A_F_BRACKET || mca == A_B_BRACKET) && len_cmdbuf() >= 2)
544a5f0fb15SPaul Saab 	{
545a5f0fb15SPaul Saab 		/*
546a5f0fb15SPaul Saab 		 * Special case for the bracket-matching commands.
547a5f0fb15SPaul Saab 		 * Execute the command after getting exactly two
548a5f0fb15SPaul Saab 		 * characters from the user.
549a5f0fb15SPaul Saab 		 */
550a5f0fb15SPaul Saab 		exec_mca();
551a5f0fb15SPaul Saab 		return (MCA_DONE);
552a5f0fb15SPaul Saab 	}
553a5f0fb15SPaul Saab 
554a5f0fb15SPaul Saab 	/*
555a5f0fb15SPaul Saab 	 * Need another character.
556a5f0fb15SPaul Saab 	 */
557a5f0fb15SPaul Saab 	return (MCA_MORE);
558a5f0fb15SPaul Saab }
559a5f0fb15SPaul Saab 
560a5f0fb15SPaul Saab /*
561a5f0fb15SPaul Saab  * Make sure the screen is displayed.
562a5f0fb15SPaul Saab  */
563a5f0fb15SPaul Saab 	static void
564a5f0fb15SPaul Saab make_display()
565a5f0fb15SPaul Saab {
566a5f0fb15SPaul Saab 	/*
567a5f0fb15SPaul Saab 	 * If nothing is displayed yet, display starting from initial_scrpos.
568a5f0fb15SPaul Saab 	 */
569a5f0fb15SPaul Saab 	if (empty_screen())
570a5f0fb15SPaul Saab 	{
571a5f0fb15SPaul Saab 		if (initial_scrpos.pos == NULL_POSITION)
572a5f0fb15SPaul Saab 			/*
573a5f0fb15SPaul Saab 			 * {{ Maybe this should be:
574a5f0fb15SPaul Saab 			 *    jump_loc(ch_zero(), jump_sline);
575a5f0fb15SPaul Saab 			 *    but this behavior seems rather unexpected
576a5f0fb15SPaul Saab 			 *    on the first screen. }}
577a5f0fb15SPaul Saab 			 */
578a5f0fb15SPaul Saab 			jump_loc(ch_zero(), 1);
579a5f0fb15SPaul Saab 		else
580a5f0fb15SPaul Saab 			jump_loc(initial_scrpos.pos, initial_scrpos.ln);
581a5f0fb15SPaul Saab 	} else if (screen_trashed)
582a5f0fb15SPaul Saab 	{
583a5f0fb15SPaul Saab 		int save_top_scroll;
584a5f0fb15SPaul Saab 		save_top_scroll = top_scroll;
585a5f0fb15SPaul Saab 		top_scroll = 1;
586a5f0fb15SPaul Saab 		repaint();
587a5f0fb15SPaul Saab 		top_scroll = save_top_scroll;
588a5f0fb15SPaul Saab 	}
589a5f0fb15SPaul Saab }
590a5f0fb15SPaul Saab 
591a5f0fb15SPaul Saab /*
592a5f0fb15SPaul Saab  * Display the appropriate prompt.
593a5f0fb15SPaul Saab  */
594a5f0fb15SPaul Saab 	static void
595a5f0fb15SPaul Saab prompt()
596a5f0fb15SPaul Saab {
597a5f0fb15SPaul Saab 	register char *p;
598a5f0fb15SPaul Saab 
599a5f0fb15SPaul Saab 	if (ungotp != NULL && ungotp > ungot)
600a5f0fb15SPaul Saab 	{
601a5f0fb15SPaul Saab 		/*
602a5f0fb15SPaul Saab 		 * No prompt necessary if commands are from
603a5f0fb15SPaul Saab 		 * ungotten chars rather than from the user.
604a5f0fb15SPaul Saab 		 */
605a5f0fb15SPaul Saab 		return;
606a5f0fb15SPaul Saab 	}
607a5f0fb15SPaul Saab 
608a5f0fb15SPaul Saab 	/*
609a5f0fb15SPaul Saab 	 * Make sure the screen is displayed.
610a5f0fb15SPaul Saab 	 */
611a5f0fb15SPaul Saab 	make_display();
612a5f0fb15SPaul Saab 	bottompos = position(BOTTOM_PLUS_ONE);
613a5f0fb15SPaul Saab 
614a5f0fb15SPaul Saab 	/*
61589dd99dcSXin LI 	 * If we've hit EOF on the last file, and the -E flag is set
61689dd99dcSXin LI 	 * (or -F is set and this is the first prompt), then quit.
61789dd99dcSXin LI 	 * {{ Relying on "first prompt" to detect a single-screen file
61889dd99dcSXin LI 	 * fails if +G is used, for example. }}
619a5f0fb15SPaul Saab 	 */
620720c436cSXin LI 	if ((get_quit_at_eof() == OPT_ONPLUS || quit_if_one_screen) &&
621a5f0fb15SPaul Saab 	    hit_eof && !(ch_getflags() & CH_HELPFILE) &&
622a5f0fb15SPaul Saab 	    next_ifile(curr_ifile) == NULL_IFILE)
623a5f0fb15SPaul Saab 		quit(QUIT_OK);
624a5f0fb15SPaul Saab 	quit_if_one_screen = FALSE;
625a5f0fb15SPaul Saab #if 0 /* This doesn't work well because some "te"s clear the screen. */
626a5f0fb15SPaul Saab 	/*
627a5f0fb15SPaul Saab 	 * If the -e flag is set and we've hit EOF on the last file,
628a5f0fb15SPaul Saab 	 * and the file is squished (shorter than the screen), quit.
629a5f0fb15SPaul Saab 	 */
630720c436cSXin LI 	if (get_quit_at_eof() && squished &&
631a5f0fb15SPaul Saab 	    next_ifile(curr_ifile) == NULL_IFILE)
632a5f0fb15SPaul Saab 		quit(QUIT_OK);
633a5f0fb15SPaul Saab #endif
634a5f0fb15SPaul Saab 
6358fd4165cSPaul Saab #if MSDOS_COMPILER==WIN32C
6368fd4165cSPaul Saab 	/*
6378fd4165cSPaul Saab 	 * In Win32, display the file name in the window title.
6388fd4165cSPaul Saab 	 */
6398fd4165cSPaul Saab 	if (!(ch_getflags() & CH_HELPFILE))
6408fd4165cSPaul Saab 		SetConsoleTitle(pr_expand("Less?f - %f.", 0));
6418fd4165cSPaul Saab #endif
642a5f0fb15SPaul Saab 	/*
643a5f0fb15SPaul Saab 	 * Select the proper prompt and display it.
644a5f0fb15SPaul Saab 	 */
645720c436cSXin LI 	/*
646720c436cSXin LI 	 * If the previous action was a forward movement,
647720c436cSXin LI 	 * don't clear the bottom line of the display;
648720c436cSXin LI 	 * just print the prompt since the forward movement guarantees
649720c436cSXin LI 	 * that we're in the right position to display the prompt.
650720c436cSXin LI 	 * Clearing the line could cause a problem: for example, if the last
651720c436cSXin LI 	 * line displayed ended at the right screen edge without a newline,
652720c436cSXin LI 	 * then clearing would clear the last displayed line rather than
653720c436cSXin LI 	 * the prompt line.
654720c436cSXin LI 	 */
655720c436cSXin LI 	if (!forw_prompt)
656720c436cSXin LI 		clear_bot();
657a5f0fb15SPaul Saab 	clear_cmd();
658720c436cSXin LI 	forw_prompt = 0;
659a5f0fb15SPaul Saab 	p = pr_string();
66089dd99dcSXin LI 	if (p == NULL || *p == '\0')
661a5f0fb15SPaul Saab 		putchr(':');
662a5f0fb15SPaul Saab 	else
663a5f0fb15SPaul Saab 	{
66489dd99dcSXin LI 		at_enter(AT_STANDOUT);
665a5f0fb15SPaul Saab 		putstr(p);
66689dd99dcSXin LI 		at_exit();
667a5f0fb15SPaul Saab 	}
668720c436cSXin LI 	clear_eol();
669a5f0fb15SPaul Saab }
670a5f0fb15SPaul Saab 
671a5f0fb15SPaul Saab /*
672a5f0fb15SPaul Saab  * Display the less version message.
673a5f0fb15SPaul Saab  */
674a5f0fb15SPaul Saab 	public void
675a5f0fb15SPaul Saab dispversion()
676a5f0fb15SPaul Saab {
677a5f0fb15SPaul Saab 	PARG parg;
678a5f0fb15SPaul Saab 
679a5f0fb15SPaul Saab 	parg.p_string = version;
680a5f0fb15SPaul Saab 	error("less %s", &parg);
681a5f0fb15SPaul Saab }
682a5f0fb15SPaul Saab 
683a5f0fb15SPaul Saab /*
684a5f0fb15SPaul Saab  * Get command character.
685a5f0fb15SPaul Saab  * The character normally comes from the keyboard,
686a5f0fb15SPaul Saab  * but may come from ungotten characters
687a5f0fb15SPaul Saab  * (characters previously given to ungetcc or ungetsc).
688a5f0fb15SPaul Saab  */
689a5f0fb15SPaul Saab 	public int
690a5f0fb15SPaul Saab getcc()
691a5f0fb15SPaul Saab {
692a5f0fb15SPaul Saab 	if (ungotp == NULL)
693a5f0fb15SPaul Saab 		/*
694a5f0fb15SPaul Saab 		 * Normal case: no ungotten chars, so get one from the user.
695a5f0fb15SPaul Saab 		 */
696a5f0fb15SPaul Saab 		return (getchr());
697a5f0fb15SPaul Saab 
698a5f0fb15SPaul Saab 	if (ungotp > ungot)
699a5f0fb15SPaul Saab 		/*
700a5f0fb15SPaul Saab 		 * Return the next ungotten char.
701a5f0fb15SPaul Saab 		 */
702a5f0fb15SPaul Saab 		return (*--ungotp);
703a5f0fb15SPaul Saab 
704a5f0fb15SPaul Saab 	/*
705a5f0fb15SPaul Saab 	 * We have just run out of ungotten chars.
706a5f0fb15SPaul Saab 	 */
707a5f0fb15SPaul Saab 	ungotp = NULL;
708a5f0fb15SPaul Saab 	if (len_cmdbuf() == 0 || !empty_screen())
709a5f0fb15SPaul Saab 		return (getchr());
710a5f0fb15SPaul Saab 	/*
711a5f0fb15SPaul Saab 	 * Command is incomplete, so try to complete it.
712a5f0fb15SPaul Saab 	 */
713a5f0fb15SPaul Saab 	switch (mca)
714a5f0fb15SPaul Saab 	{
715a5f0fb15SPaul Saab 	case A_DIGIT:
716a5f0fb15SPaul Saab 		/*
717a5f0fb15SPaul Saab 		 * We have a number but no command.  Treat as #g.
718a5f0fb15SPaul Saab 		 */
719a5f0fb15SPaul Saab 		return ('g');
720a5f0fb15SPaul Saab 
721a5f0fb15SPaul Saab 	case A_F_SEARCH:
722a5f0fb15SPaul Saab 	case A_B_SEARCH:
723a5f0fb15SPaul Saab 		/*
724a5f0fb15SPaul Saab 		 * We have "/string" but no newline.  Add the \n.
725a5f0fb15SPaul Saab 		 */
726a5f0fb15SPaul Saab 		return ('\n');
727a5f0fb15SPaul Saab 
728a5f0fb15SPaul Saab 	default:
729a5f0fb15SPaul Saab 		/*
730a5f0fb15SPaul Saab 		 * Some other incomplete command.  Let user complete it.
731a5f0fb15SPaul Saab 		 */
732a5f0fb15SPaul Saab 		return (getchr());
733a5f0fb15SPaul Saab 	}
734a5f0fb15SPaul Saab }
735a5f0fb15SPaul Saab 
736a5f0fb15SPaul Saab /*
737a5f0fb15SPaul Saab  * "Unget" a command character.
738a5f0fb15SPaul Saab  * The next getcc() will return this character.
739a5f0fb15SPaul Saab  */
740a5f0fb15SPaul Saab 	public void
741a5f0fb15SPaul Saab ungetcc(c)
742a5f0fb15SPaul Saab 	int c;
743a5f0fb15SPaul Saab {
744a5f0fb15SPaul Saab 	if (ungotp == NULL)
745a5f0fb15SPaul Saab 		ungotp = ungot;
746a5f0fb15SPaul Saab 	if (ungotp >= ungot + sizeof(ungot))
747a5f0fb15SPaul Saab 	{
748a5f0fb15SPaul Saab 		error("ungetcc overflow", NULL_PARG);
749a5f0fb15SPaul Saab 		quit(QUIT_ERROR);
750a5f0fb15SPaul Saab 	}
751a5f0fb15SPaul Saab 	*ungotp++ = c;
752a5f0fb15SPaul Saab }
753a5f0fb15SPaul Saab 
754a5f0fb15SPaul Saab /*
755a5f0fb15SPaul Saab  * Unget a whole string of command characters.
756a5f0fb15SPaul Saab  * The next sequence of getcc()'s will return this string.
757a5f0fb15SPaul Saab  */
758a5f0fb15SPaul Saab 	public void
759a5f0fb15SPaul Saab ungetsc(s)
760a5f0fb15SPaul Saab 	char *s;
761a5f0fb15SPaul Saab {
762a5f0fb15SPaul Saab 	register char *p;
763a5f0fb15SPaul Saab 
764a5f0fb15SPaul Saab 	for (p = s + strlen(s) - 1;  p >= s;  p--)
765a5f0fb15SPaul Saab 		ungetcc(*p);
766a5f0fb15SPaul Saab }
767a5f0fb15SPaul Saab 
768a5f0fb15SPaul Saab /*
769a5f0fb15SPaul Saab  * Search for a pattern, possibly in multiple files.
770a5f0fb15SPaul Saab  * If SRCH_FIRST_FILE is set, begin searching at the first file.
771a5f0fb15SPaul Saab  * If SRCH_PAST_EOF is set, continue the search thru multiple files.
772a5f0fb15SPaul Saab  */
773a5f0fb15SPaul Saab 	static void
774a5f0fb15SPaul Saab multi_search(pattern, n)
775a5f0fb15SPaul Saab 	char *pattern;
776a5f0fb15SPaul Saab 	int n;
777a5f0fb15SPaul Saab {
778a5f0fb15SPaul Saab 	register int nomore;
779a5f0fb15SPaul Saab 	IFILE save_ifile;
780a5f0fb15SPaul Saab 	int changed_file;
781a5f0fb15SPaul Saab 
782a5f0fb15SPaul Saab 	changed_file = 0;
783a5f0fb15SPaul Saab 	save_ifile = save_curr_ifile();
784a5f0fb15SPaul Saab 
785a5f0fb15SPaul Saab 	if (search_type & SRCH_FIRST_FILE)
786a5f0fb15SPaul Saab 	{
787a5f0fb15SPaul Saab 		/*
788a5f0fb15SPaul Saab 		 * Start at the first (or last) file
789a5f0fb15SPaul Saab 		 * in the command line list.
790a5f0fb15SPaul Saab 		 */
791a5f0fb15SPaul Saab 		if (search_type & SRCH_FORW)
792a5f0fb15SPaul Saab 			nomore = edit_first();
793a5f0fb15SPaul Saab 		else
794a5f0fb15SPaul Saab 			nomore = edit_last();
795a5f0fb15SPaul Saab 		if (nomore)
796a5f0fb15SPaul Saab 		{
797a5f0fb15SPaul Saab 			unsave_ifile(save_ifile);
798a5f0fb15SPaul Saab 			return;
799a5f0fb15SPaul Saab 		}
800a5f0fb15SPaul Saab 		changed_file = 1;
801a5f0fb15SPaul Saab 		search_type &= ~SRCH_FIRST_FILE;
802a5f0fb15SPaul Saab 	}
803a5f0fb15SPaul Saab 
804a5f0fb15SPaul Saab 	for (;;)
805a5f0fb15SPaul Saab 	{
806a5f0fb15SPaul Saab 		n = search(search_type, pattern, n);
807a5f0fb15SPaul Saab 		/*
808a5f0fb15SPaul Saab 		 * The SRCH_NO_MOVE flag doesn't "stick": it gets cleared
809a5f0fb15SPaul Saab 		 * after being used once.  This allows "n" to work after
810a5f0fb15SPaul Saab 		 * using a /@@ search.
811a5f0fb15SPaul Saab 		 */
812a5f0fb15SPaul Saab 		search_type &= ~SRCH_NO_MOVE;
813a5f0fb15SPaul Saab 		if (n == 0)
814a5f0fb15SPaul Saab 		{
815a5f0fb15SPaul Saab 			/*
816a5f0fb15SPaul Saab 			 * Found it.
817a5f0fb15SPaul Saab 			 */
818a5f0fb15SPaul Saab 			unsave_ifile(save_ifile);
819a5f0fb15SPaul Saab 			return;
820a5f0fb15SPaul Saab 		}
821a5f0fb15SPaul Saab 
822a5f0fb15SPaul Saab 		if (n < 0)
823a5f0fb15SPaul Saab 			/*
824a5f0fb15SPaul Saab 			 * Some kind of error in the search.
825a5f0fb15SPaul Saab 			 * Error message has been printed by search().
826a5f0fb15SPaul Saab 			 */
827a5f0fb15SPaul Saab 			break;
828a5f0fb15SPaul Saab 
829a5f0fb15SPaul Saab 		if ((search_type & SRCH_PAST_EOF) == 0)
830a5f0fb15SPaul Saab 			/*
831a5f0fb15SPaul Saab 			 * We didn't find a match, but we're
832a5f0fb15SPaul Saab 			 * supposed to search only one file.
833a5f0fb15SPaul Saab 			 */
834a5f0fb15SPaul Saab 			break;
835a5f0fb15SPaul Saab 		/*
836a5f0fb15SPaul Saab 		 * Move on to the next file.
837a5f0fb15SPaul Saab 		 */
838a5f0fb15SPaul Saab 		if (search_type & SRCH_FORW)
839a5f0fb15SPaul Saab 			nomore = edit_next(1);
840a5f0fb15SPaul Saab 		else
841a5f0fb15SPaul Saab 			nomore = edit_prev(1);
842a5f0fb15SPaul Saab 		if (nomore)
843a5f0fb15SPaul Saab 			break;
844a5f0fb15SPaul Saab 		changed_file = 1;
845a5f0fb15SPaul Saab 	}
846a5f0fb15SPaul Saab 
847a5f0fb15SPaul Saab 	/*
848a5f0fb15SPaul Saab 	 * Didn't find it.
849a5f0fb15SPaul Saab 	 * Print an error message if we haven't already.
850a5f0fb15SPaul Saab 	 */
851a5f0fb15SPaul Saab 	if (n > 0)
852a5f0fb15SPaul Saab 		error("Pattern not found", NULL_PARG);
853a5f0fb15SPaul Saab 
854a5f0fb15SPaul Saab 	if (changed_file)
855a5f0fb15SPaul Saab 	{
856a5f0fb15SPaul Saab 		/*
857a5f0fb15SPaul Saab 		 * Restore the file we were originally viewing.
858a5f0fb15SPaul Saab 		 */
859a5f0fb15SPaul Saab 		reedit_ifile(save_ifile);
86089dd99dcSXin LI 	} else
86189dd99dcSXin LI 	{
86289dd99dcSXin LI 		unsave_ifile(save_ifile);
863a5f0fb15SPaul Saab 	}
864a5f0fb15SPaul Saab }
865a5f0fb15SPaul Saab 
866a5f0fb15SPaul Saab /*
867a5f0fb15SPaul Saab  * Main command processor.
868a5f0fb15SPaul Saab  * Accept and execute commands until a quit command.
869a5f0fb15SPaul Saab  */
870a5f0fb15SPaul Saab 	public void
871a5f0fb15SPaul Saab commands()
872a5f0fb15SPaul Saab {
873a5f0fb15SPaul Saab 	register int c;
874a5f0fb15SPaul Saab 	register int action;
875a5f0fb15SPaul Saab 	register char *cbuf;
876a5f0fb15SPaul Saab 	int newaction;
877a5f0fb15SPaul Saab 	int save_search_type;
878a5f0fb15SPaul Saab 	char *extra;
879a5f0fb15SPaul Saab 	char tbuf[2];
880a5f0fb15SPaul Saab 	PARG parg;
881a5f0fb15SPaul Saab 	IFILE old_ifile;
882a5f0fb15SPaul Saab 	IFILE new_ifile;
8838fd4165cSPaul Saab 	char *tagfile;
884a5f0fb15SPaul Saab 
885a5f0fb15SPaul Saab 	search_type = SRCH_FORW;
886a5f0fb15SPaul Saab 	wscroll = (sc_height + 1) / 2;
887a5f0fb15SPaul Saab 	newaction = A_NOACTION;
888a5f0fb15SPaul Saab 
889a5f0fb15SPaul Saab 	for (;;)
890a5f0fb15SPaul Saab 	{
891a5f0fb15SPaul Saab 		mca = 0;
892a5f0fb15SPaul Saab 		cmd_accept();
893a5f0fb15SPaul Saab 		number = 0;
894a5f0fb15SPaul Saab 		optchar = '\0';
895a5f0fb15SPaul Saab 
896a5f0fb15SPaul Saab 		/*
897a5f0fb15SPaul Saab 		 * See if any signals need processing.
898a5f0fb15SPaul Saab 		 */
899a5f0fb15SPaul Saab 		if (sigs)
900a5f0fb15SPaul Saab 		{
901a5f0fb15SPaul Saab 			psignals();
902a5f0fb15SPaul Saab 			if (quitting)
903a5f0fb15SPaul Saab 				quit(QUIT_SAVED_STATUS);
904a5f0fb15SPaul Saab 		}
905a5f0fb15SPaul Saab 
906a5f0fb15SPaul Saab 		/*
907a5f0fb15SPaul Saab 		 * See if window size changed, for systems that don't
908a5f0fb15SPaul Saab 		 * generate SIGWINCH.
909a5f0fb15SPaul Saab 		 */
910a5f0fb15SPaul Saab 		check_winch();
911a5f0fb15SPaul Saab 
912a5f0fb15SPaul Saab 		/*
913a5f0fb15SPaul Saab 		 * Display prompt and accept a character.
914a5f0fb15SPaul Saab 		 */
915a5f0fb15SPaul Saab 		cmd_reset();
916a5f0fb15SPaul Saab 		prompt();
917a5f0fb15SPaul Saab 		if (sigs)
918a5f0fb15SPaul Saab 			continue;
919a5f0fb15SPaul Saab 		if (newaction == A_NOACTION)
920a5f0fb15SPaul Saab 			c = getcc();
921a5f0fb15SPaul Saab 
922a5f0fb15SPaul Saab 	again:
923a5f0fb15SPaul Saab 		if (sigs)
924a5f0fb15SPaul Saab 			continue;
925a5f0fb15SPaul Saab 
926a5f0fb15SPaul Saab 		if (newaction != A_NOACTION)
927a5f0fb15SPaul Saab 		{
928a5f0fb15SPaul Saab 			action = newaction;
929a5f0fb15SPaul Saab 			newaction = A_NOACTION;
930a5f0fb15SPaul Saab 		} else
931a5f0fb15SPaul Saab 		{
932a5f0fb15SPaul Saab 			/*
933a5f0fb15SPaul Saab 			 * If we are in a multicharacter command, call mca_char.
934a5f0fb15SPaul Saab 			 * Otherwise we call fcmd_decode to determine the
935a5f0fb15SPaul Saab 			 * action to be performed.
936a5f0fb15SPaul Saab 			 */
937a5f0fb15SPaul Saab 			if (mca)
938a5f0fb15SPaul Saab 				switch (mca_char(c))
939a5f0fb15SPaul Saab 				{
940a5f0fb15SPaul Saab 				case MCA_MORE:
941a5f0fb15SPaul Saab 					/*
942a5f0fb15SPaul Saab 					 * Need another character.
943a5f0fb15SPaul Saab 					 */
944a5f0fb15SPaul Saab 					c = getcc();
945a5f0fb15SPaul Saab 					goto again;
946a5f0fb15SPaul Saab 				case MCA_DONE:
947a5f0fb15SPaul Saab 					/*
948a5f0fb15SPaul Saab 					 * Command has been handled by mca_char.
949a5f0fb15SPaul Saab 					 * Start clean with a prompt.
950a5f0fb15SPaul Saab 					 */
951a5f0fb15SPaul Saab 					continue;
952a5f0fb15SPaul Saab 				case NO_MCA:
953a5f0fb15SPaul Saab 					/*
954a5f0fb15SPaul Saab 					 * Not a multi-char command
955a5f0fb15SPaul Saab 					 * (at least, not anymore).
956a5f0fb15SPaul Saab 					 */
957a5f0fb15SPaul Saab 					break;
958a5f0fb15SPaul Saab 				}
959a5f0fb15SPaul Saab 
960a5f0fb15SPaul Saab 			/*
961a5f0fb15SPaul Saab 			 * Decode the command character and decide what to do.
962a5f0fb15SPaul Saab 			 */
963a5f0fb15SPaul Saab 			if (mca)
964a5f0fb15SPaul Saab 			{
965a5f0fb15SPaul Saab 				/*
966a5f0fb15SPaul Saab 				 * We're in a multichar command.
967a5f0fb15SPaul Saab 				 * Add the character to the command buffer
968a5f0fb15SPaul Saab 				 * and display it on the screen.
969a5f0fb15SPaul Saab 				 * If the user backspaces past the start
970a5f0fb15SPaul Saab 				 * of the line, abort the command.
971a5f0fb15SPaul Saab 				 */
972a5f0fb15SPaul Saab 				if (cmd_char(c) == CC_QUIT || len_cmdbuf() == 0)
973a5f0fb15SPaul Saab 					continue;
974a5f0fb15SPaul Saab 				cbuf = get_cmdbuf();
975a5f0fb15SPaul Saab 			} else
976a5f0fb15SPaul Saab 			{
977a5f0fb15SPaul Saab 				/*
978a5f0fb15SPaul Saab 				 * Don't use cmd_char if we're starting fresh
979a5f0fb15SPaul Saab 				 * at the beginning of a command, because we
980a5f0fb15SPaul Saab 				 * don't want to echo the command until we know
981a5f0fb15SPaul Saab 				 * it is a multichar command.  We also don't
982a5f0fb15SPaul Saab 				 * want erase_char/kill_char to be treated
983a5f0fb15SPaul Saab 				 * as line editing characters.
984a5f0fb15SPaul Saab 				 */
985a5f0fb15SPaul Saab 				tbuf[0] = c;
986a5f0fb15SPaul Saab 				tbuf[1] = '\0';
987a5f0fb15SPaul Saab 				cbuf = tbuf;
988a5f0fb15SPaul Saab 			}
989a5f0fb15SPaul Saab 			extra = NULL;
990a5f0fb15SPaul Saab 			action = fcmd_decode(cbuf, &extra);
991a5f0fb15SPaul Saab 			/*
992a5f0fb15SPaul Saab 			 * If an "extra" string was returned,
993a5f0fb15SPaul Saab 			 * process it as a string of command characters.
994a5f0fb15SPaul Saab 			 */
995a5f0fb15SPaul Saab 			if (extra != NULL)
996a5f0fb15SPaul Saab 				ungetsc(extra);
997a5f0fb15SPaul Saab 		}
998a5f0fb15SPaul Saab 		/*
999a5f0fb15SPaul Saab 		 * Clear the cmdbuf string.
1000a5f0fb15SPaul Saab 		 * (But not if we're in the prefix of a command,
1001a5f0fb15SPaul Saab 		 * because the partial command string is kept there.)
1002a5f0fb15SPaul Saab 		 */
1003a5f0fb15SPaul Saab 		if (action != A_PREFIX)
1004a5f0fb15SPaul Saab 			cmd_reset();
1005a5f0fb15SPaul Saab 
1006a5f0fb15SPaul Saab 		switch (action)
1007a5f0fb15SPaul Saab 		{
1008a5f0fb15SPaul Saab 		case A_DIGIT:
1009a5f0fb15SPaul Saab 			/*
1010a5f0fb15SPaul Saab 			 * First digit of a number.
1011a5f0fb15SPaul Saab 			 */
1012a5f0fb15SPaul Saab 			start_mca(A_DIGIT, ":", (void*)NULL, CF_QUIT_ON_ERASE);
1013a5f0fb15SPaul Saab 			goto again;
1014a5f0fb15SPaul Saab 
1015a5f0fb15SPaul Saab 		case A_F_WINDOW:
1016a5f0fb15SPaul Saab 			/*
1017a5f0fb15SPaul Saab 			 * Forward one window (and set the window size).
1018a5f0fb15SPaul Saab 			 */
1019a5f0fb15SPaul Saab 			if (number > 0)
10201ede1615STim J. Robbins 				swindow = (int) number;
1021a5f0fb15SPaul Saab 			/* FALLTHRU */
1022a5f0fb15SPaul Saab 		case A_F_SCREEN:
1023a5f0fb15SPaul Saab 			/*
1024a5f0fb15SPaul Saab 			 * Forward one screen.
1025a5f0fb15SPaul Saab 			 */
1026a5f0fb15SPaul Saab 			if (number <= 0)
1027a5f0fb15SPaul Saab 				number = get_swindow();
1028a5f0fb15SPaul Saab 			cmd_exec();
1029a5f0fb15SPaul Saab 			if (show_attn)
1030a5f0fb15SPaul Saab 				set_attnpos(bottompos);
10311ede1615STim J. Robbins 			forward((int) number, 0, 1);
1032a5f0fb15SPaul Saab 			break;
1033a5f0fb15SPaul Saab 
1034a5f0fb15SPaul Saab 		case A_B_WINDOW:
1035a5f0fb15SPaul Saab 			/*
1036a5f0fb15SPaul Saab 			 * Backward one window (and set the window size).
1037a5f0fb15SPaul Saab 			 */
1038a5f0fb15SPaul Saab 			if (number > 0)
10391ede1615STim J. Robbins 				swindow = (int) number;
1040a5f0fb15SPaul Saab 			/* FALLTHRU */
1041a5f0fb15SPaul Saab 		case A_B_SCREEN:
1042a5f0fb15SPaul Saab 			/*
1043a5f0fb15SPaul Saab 			 * Backward one screen.
1044a5f0fb15SPaul Saab 			 */
1045a5f0fb15SPaul Saab 			if (number <= 0)
1046a5f0fb15SPaul Saab 				number = get_swindow();
1047a5f0fb15SPaul Saab 			cmd_exec();
10481ede1615STim J. Robbins 			backward((int) number, 0, 1);
1049a5f0fb15SPaul Saab 			break;
1050a5f0fb15SPaul Saab 
1051a5f0fb15SPaul Saab 		case A_F_LINE:
1052a5f0fb15SPaul Saab 			/*
1053a5f0fb15SPaul Saab 			 * Forward N (default 1) line.
1054a5f0fb15SPaul Saab 			 */
1055a5f0fb15SPaul Saab 			if (number <= 0)
1056a5f0fb15SPaul Saab 				number = 1;
1057a5f0fb15SPaul Saab 			cmd_exec();
1058a5f0fb15SPaul Saab 			if (show_attn == OPT_ONPLUS && number > 1)
1059a5f0fb15SPaul Saab 				set_attnpos(bottompos);
10601ede1615STim J. Robbins 			forward((int) number, 0, 0);
1061a5f0fb15SPaul Saab 			break;
1062a5f0fb15SPaul Saab 
1063a5f0fb15SPaul Saab 		case A_B_LINE:
1064a5f0fb15SPaul Saab 			/*
1065a5f0fb15SPaul Saab 			 * Backward N (default 1) line.
1066a5f0fb15SPaul Saab 			 */
1067a5f0fb15SPaul Saab 			if (number <= 0)
1068a5f0fb15SPaul Saab 				number = 1;
1069a5f0fb15SPaul Saab 			cmd_exec();
10701ede1615STim J. Robbins 			backward((int) number, 0, 0);
1071a5f0fb15SPaul Saab 			break;
1072a5f0fb15SPaul Saab 
1073a5f0fb15SPaul Saab 		case A_FF_LINE:
1074a5f0fb15SPaul Saab 			/*
1075a5f0fb15SPaul Saab 			 * Force forward N (default 1) line.
1076a5f0fb15SPaul Saab 			 */
1077a5f0fb15SPaul Saab 			if (number <= 0)
1078a5f0fb15SPaul Saab 				number = 1;
1079a5f0fb15SPaul Saab 			cmd_exec();
1080a5f0fb15SPaul Saab 			if (show_attn == OPT_ONPLUS && number > 1)
1081a5f0fb15SPaul Saab 				set_attnpos(bottompos);
10821ede1615STim J. Robbins 			forward((int) number, 1, 0);
1083a5f0fb15SPaul Saab 			break;
1084a5f0fb15SPaul Saab 
1085a5f0fb15SPaul Saab 		case A_BF_LINE:
1086a5f0fb15SPaul Saab 			/*
1087a5f0fb15SPaul Saab 			 * Force backward N (default 1) line.
1088a5f0fb15SPaul Saab 			 */
1089a5f0fb15SPaul Saab 			if (number <= 0)
1090a5f0fb15SPaul Saab 				number = 1;
1091a5f0fb15SPaul Saab 			cmd_exec();
10921ede1615STim J. Robbins 			backward((int) number, 1, 0);
1093a5f0fb15SPaul Saab 			break;
1094a5f0fb15SPaul Saab 
1095a5f0fb15SPaul Saab 		case A_FF_SCREEN:
1096a5f0fb15SPaul Saab 			/*
1097a5f0fb15SPaul Saab 			 * Force forward one screen.
1098a5f0fb15SPaul Saab 			 */
1099a5f0fb15SPaul Saab 			if (number <= 0)
1100a5f0fb15SPaul Saab 				number = get_swindow();
1101a5f0fb15SPaul Saab 			cmd_exec();
1102a5f0fb15SPaul Saab 			if (show_attn == OPT_ONPLUS)
1103a5f0fb15SPaul Saab 				set_attnpos(bottompos);
11041ede1615STim J. Robbins 			forward((int) number, 1, 0);
1105a5f0fb15SPaul Saab 			break;
1106a5f0fb15SPaul Saab 
1107a5f0fb15SPaul Saab 		case A_F_FOREVER:
1108a5f0fb15SPaul Saab 			/*
1109a5f0fb15SPaul Saab 			 * Forward forever, ignoring EOF.
1110a5f0fb15SPaul Saab 			 */
1111a5f0fb15SPaul Saab 			if (ch_getflags() & CH_HELPFILE)
1112a5f0fb15SPaul Saab 				break;
1113a5f0fb15SPaul Saab 			cmd_exec();
1114a5f0fb15SPaul Saab 			jump_forw();
1115a5f0fb15SPaul Saab 			ignore_eoi = 1;
1116a5f0fb15SPaul Saab 			hit_eof = 0;
1117a5f0fb15SPaul Saab 			while (!sigs)
1118a5f0fb15SPaul Saab 				forward(1, 0, 0);
1119a5f0fb15SPaul Saab 			ignore_eoi = 0;
1120a5f0fb15SPaul Saab 			/*
1121a5f0fb15SPaul Saab 			 * This gets us back in "F mode" after processing
1122a5f0fb15SPaul Saab 			 * a non-abort signal (e.g. window-change).
1123a5f0fb15SPaul Saab 			 */
1124a5f0fb15SPaul Saab 			if (sigs && !ABORT_SIGS())
1125a5f0fb15SPaul Saab 				newaction = A_F_FOREVER;
1126a5f0fb15SPaul Saab 			break;
1127a5f0fb15SPaul Saab 
1128a5f0fb15SPaul Saab 		case A_F_SCROLL:
1129a5f0fb15SPaul Saab 			/*
1130a5f0fb15SPaul Saab 			 * Forward N lines
1131a5f0fb15SPaul Saab 			 * (default same as last 'd' or 'u' command).
1132a5f0fb15SPaul Saab 			 */
1133a5f0fb15SPaul Saab 			if (number > 0)
11341ede1615STim J. Robbins 				wscroll = (int) number;
1135a5f0fb15SPaul Saab 			cmd_exec();
1136a5f0fb15SPaul Saab 			if (show_attn == OPT_ONPLUS)
1137a5f0fb15SPaul Saab 				set_attnpos(bottompos);
1138a5f0fb15SPaul Saab 			forward(wscroll, 0, 0);
1139a5f0fb15SPaul Saab 			break;
1140a5f0fb15SPaul Saab 
1141a5f0fb15SPaul Saab 		case A_B_SCROLL:
1142a5f0fb15SPaul Saab 			/*
1143a5f0fb15SPaul Saab 			 * Forward N lines
1144a5f0fb15SPaul Saab 			 * (default same as last 'd' or 'u' command).
1145a5f0fb15SPaul Saab 			 */
1146a5f0fb15SPaul Saab 			if (number > 0)
11471ede1615STim J. Robbins 				wscroll = (int) number;
1148a5f0fb15SPaul Saab 			cmd_exec();
1149a5f0fb15SPaul Saab 			backward(wscroll, 0, 0);
1150a5f0fb15SPaul Saab 			break;
1151a5f0fb15SPaul Saab 
1152a5f0fb15SPaul Saab 		case A_FREPAINT:
1153a5f0fb15SPaul Saab 			/*
1154a5f0fb15SPaul Saab 			 * Flush buffers, then repaint screen.
1155a5f0fb15SPaul Saab 			 * Don't flush the buffers on a pipe!
1156a5f0fb15SPaul Saab 			 */
1157a5f0fb15SPaul Saab 			if (ch_getflags() & CH_CANSEEK)
1158a5f0fb15SPaul Saab 			{
1159a5f0fb15SPaul Saab 				ch_flush();
1160a5f0fb15SPaul Saab 				clr_linenum();
1161a5f0fb15SPaul Saab #if HILITE_SEARCH
1162a5f0fb15SPaul Saab 				clr_hilite();
1163a5f0fb15SPaul Saab #endif
1164a5f0fb15SPaul Saab 			}
1165a5f0fb15SPaul Saab 			/* FALLTHRU */
1166a5f0fb15SPaul Saab 		case A_REPAINT:
1167a5f0fb15SPaul Saab 			/*
1168a5f0fb15SPaul Saab 			 * Repaint screen.
1169a5f0fb15SPaul Saab 			 */
1170a5f0fb15SPaul Saab 			cmd_exec();
1171a5f0fb15SPaul Saab 			repaint();
1172a5f0fb15SPaul Saab 			break;
1173a5f0fb15SPaul Saab 
1174a5f0fb15SPaul Saab 		case A_GOLINE:
1175a5f0fb15SPaul Saab 			/*
1176a5f0fb15SPaul Saab 			 * Go to line N, default beginning of file.
1177a5f0fb15SPaul Saab 			 */
1178a5f0fb15SPaul Saab 			if (number <= 0)
1179a5f0fb15SPaul Saab 				number = 1;
1180a5f0fb15SPaul Saab 			cmd_exec();
1181a5f0fb15SPaul Saab 			jump_back(number);
1182a5f0fb15SPaul Saab 			break;
1183a5f0fb15SPaul Saab 
1184a5f0fb15SPaul Saab 		case A_PERCENT:
1185a5f0fb15SPaul Saab 			/*
1186a5f0fb15SPaul Saab 			 * Go to a specified percentage into the file.
1187a5f0fb15SPaul Saab 			 */
1188a5f0fb15SPaul Saab 			if (number < 0)
1189720c436cSXin LI 			{
1190a5f0fb15SPaul Saab 				number = 0;
1191720c436cSXin LI 				fraction = 0;
1192720c436cSXin LI 			}
1193a5f0fb15SPaul Saab 			if (number > 100)
1194720c436cSXin LI 			{
1195a5f0fb15SPaul Saab 				number = 100;
1196720c436cSXin LI 				fraction = 0;
1197720c436cSXin LI 			}
1198a5f0fb15SPaul Saab 			cmd_exec();
1199720c436cSXin LI 			jump_percent((int) number, fraction);
1200a5f0fb15SPaul Saab 			break;
1201a5f0fb15SPaul Saab 
1202a5f0fb15SPaul Saab 		case A_GOEND:
1203a5f0fb15SPaul Saab 			/*
1204a5f0fb15SPaul Saab 			 * Go to line N, default end of file.
1205a5f0fb15SPaul Saab 			 */
1206a5f0fb15SPaul Saab 			cmd_exec();
1207a5f0fb15SPaul Saab 			if (number <= 0)
1208a5f0fb15SPaul Saab 				jump_forw();
1209a5f0fb15SPaul Saab 			else
1210a5f0fb15SPaul Saab 				jump_back(number);
1211a5f0fb15SPaul Saab 			break;
1212a5f0fb15SPaul Saab 
1213a5f0fb15SPaul Saab 		case A_GOPOS:
1214a5f0fb15SPaul Saab 			/*
1215a5f0fb15SPaul Saab 			 * Go to a specified byte position in the file.
1216a5f0fb15SPaul Saab 			 */
1217a5f0fb15SPaul Saab 			cmd_exec();
1218a5f0fb15SPaul Saab 			if (number < 0)
1219a5f0fb15SPaul Saab 				number = 0;
1220a5f0fb15SPaul Saab 			jump_line_loc((POSITION) number, jump_sline);
1221a5f0fb15SPaul Saab 			break;
1222a5f0fb15SPaul Saab 
1223a5f0fb15SPaul Saab 		case A_STAT:
1224a5f0fb15SPaul Saab 			/*
1225a5f0fb15SPaul Saab 			 * Print file name, etc.
1226a5f0fb15SPaul Saab 			 */
1227a5f0fb15SPaul Saab 			if (ch_getflags() & CH_HELPFILE)
1228a5f0fb15SPaul Saab 				break;
1229a5f0fb15SPaul Saab 			cmd_exec();
1230a5f0fb15SPaul Saab 			parg.p_string = eq_message();
1231a5f0fb15SPaul Saab 			error("%s", &parg);
1232a5f0fb15SPaul Saab 			break;
1233a5f0fb15SPaul Saab 
1234a5f0fb15SPaul Saab 		case A_VERSION:
1235a5f0fb15SPaul Saab 			/*
1236a5f0fb15SPaul Saab 			 * Print version number, without the "@(#)".
1237a5f0fb15SPaul Saab 			 */
1238a5f0fb15SPaul Saab 			cmd_exec();
1239a5f0fb15SPaul Saab 			dispversion();
1240a5f0fb15SPaul Saab 			break;
1241a5f0fb15SPaul Saab 
1242a5f0fb15SPaul Saab 		case A_QUIT:
1243a5f0fb15SPaul Saab 			/*
1244a5f0fb15SPaul Saab 			 * Exit.
1245a5f0fb15SPaul Saab 			 */
1246a5f0fb15SPaul Saab 			if (curr_ifile != NULL_IFILE &&
1247a5f0fb15SPaul Saab 			    ch_getflags() & CH_HELPFILE)
1248a5f0fb15SPaul Saab 			{
1249a5f0fb15SPaul Saab 				/*
1250a5f0fb15SPaul Saab 				 * Quit while viewing the help file
1251a5f0fb15SPaul Saab 				 * just means return to viewing the
1252a5f0fb15SPaul Saab 				 * previous file.
1253a5f0fb15SPaul Saab 				 */
125489dd99dcSXin LI 				hshift = save_hshift;
1255a5f0fb15SPaul Saab 				if (edit_prev(1) == 0)
1256a5f0fb15SPaul Saab 					break;
1257a5f0fb15SPaul Saab 			}
1258a5f0fb15SPaul Saab 			if (extra != NULL)
1259a5f0fb15SPaul Saab 				quit(*extra);
1260a5f0fb15SPaul Saab 			quit(QUIT_OK);
1261a5f0fb15SPaul Saab 			break;
1262a5f0fb15SPaul Saab 
1263a5f0fb15SPaul Saab /*
1264a5f0fb15SPaul Saab  * Define abbreviation for a commonly used sequence below.
1265a5f0fb15SPaul Saab  */
1266a5f0fb15SPaul Saab #define	DO_SEARCH()	if (number <= 0) number = 1;	\
1267a5f0fb15SPaul Saab 			mca_search();			\
1268a5f0fb15SPaul Saab 			cmd_exec();			\
12691ede1615STim J. Robbins 			multi_search((char *)NULL, (int) number);
1270a5f0fb15SPaul Saab 
1271a5f0fb15SPaul Saab 
1272a5f0fb15SPaul Saab 		case A_F_SEARCH:
1273a5f0fb15SPaul Saab 			/*
1274a5f0fb15SPaul Saab 			 * Search forward for a pattern.
1275a5f0fb15SPaul Saab 			 * Get the first char of the pattern.
1276a5f0fb15SPaul Saab 			 */
1277a5f0fb15SPaul Saab 			search_type = SRCH_FORW;
1278a5f0fb15SPaul Saab 			if (number <= 0)
1279a5f0fb15SPaul Saab 				number = 1;
1280a5f0fb15SPaul Saab 			mca_search();
1281a5f0fb15SPaul Saab 			c = getcc();
1282a5f0fb15SPaul Saab 			goto again;
1283a5f0fb15SPaul Saab 
1284a5f0fb15SPaul Saab 		case A_B_SEARCH:
1285a5f0fb15SPaul Saab 			/*
1286a5f0fb15SPaul Saab 			 * Search backward for a pattern.
1287a5f0fb15SPaul Saab 			 * Get the first char of the pattern.
1288a5f0fb15SPaul Saab 			 */
1289a5f0fb15SPaul Saab 			search_type = SRCH_BACK;
1290a5f0fb15SPaul Saab 			if (number <= 0)
1291a5f0fb15SPaul Saab 				number = 1;
1292a5f0fb15SPaul Saab 			mca_search();
1293a5f0fb15SPaul Saab 			c = getcc();
1294a5f0fb15SPaul Saab 			goto again;
1295a5f0fb15SPaul Saab 
1296a5f0fb15SPaul Saab 		case A_AGAIN_SEARCH:
1297a5f0fb15SPaul Saab 			/*
1298a5f0fb15SPaul Saab 			 * Repeat previous search.
1299a5f0fb15SPaul Saab 			 */
1300a5f0fb15SPaul Saab 			DO_SEARCH();
1301a5f0fb15SPaul Saab 			break;
1302a5f0fb15SPaul Saab 
1303a5f0fb15SPaul Saab 		case A_T_AGAIN_SEARCH:
1304a5f0fb15SPaul Saab 			/*
1305a5f0fb15SPaul Saab 			 * Repeat previous search, multiple files.
1306a5f0fb15SPaul Saab 			 */
1307a5f0fb15SPaul Saab 			search_type |= SRCH_PAST_EOF;
1308a5f0fb15SPaul Saab 			DO_SEARCH();
1309a5f0fb15SPaul Saab 			break;
1310a5f0fb15SPaul Saab 
1311a5f0fb15SPaul Saab 		case A_REVERSE_SEARCH:
1312a5f0fb15SPaul Saab 			/*
1313a5f0fb15SPaul Saab 			 * Repeat previous search, in reverse direction.
1314a5f0fb15SPaul Saab 			 */
1315a5f0fb15SPaul Saab 			save_search_type = search_type;
1316a5f0fb15SPaul Saab 			search_type = SRCH_REVERSE(search_type);
1317a5f0fb15SPaul Saab 			DO_SEARCH();
1318a5f0fb15SPaul Saab 			search_type = save_search_type;
1319a5f0fb15SPaul Saab 			break;
1320a5f0fb15SPaul Saab 
1321a5f0fb15SPaul Saab 		case A_T_REVERSE_SEARCH:
1322a5f0fb15SPaul Saab 			/*
1323a5f0fb15SPaul Saab 			 * Repeat previous search,
1324a5f0fb15SPaul Saab 			 * multiple files in reverse direction.
1325a5f0fb15SPaul Saab 			 */
1326a5f0fb15SPaul Saab 			save_search_type = search_type;
1327a5f0fb15SPaul Saab 			search_type = SRCH_REVERSE(search_type);
1328a5f0fb15SPaul Saab 			search_type |= SRCH_PAST_EOF;
1329a5f0fb15SPaul Saab 			DO_SEARCH();
1330a5f0fb15SPaul Saab 			search_type = save_search_type;
1331a5f0fb15SPaul Saab 			break;
1332a5f0fb15SPaul Saab 
1333a5f0fb15SPaul Saab 		case A_UNDO_SEARCH:
1334a5f0fb15SPaul Saab 			undo_search();
1335a5f0fb15SPaul Saab 			break;
1336a5f0fb15SPaul Saab 
1337a5f0fb15SPaul Saab 		case A_HELP:
1338a5f0fb15SPaul Saab 			/*
1339a5f0fb15SPaul Saab 			 * Help.
1340a5f0fb15SPaul Saab 			 */
1341a5f0fb15SPaul Saab 			if (ch_getflags() & CH_HELPFILE)
1342a5f0fb15SPaul Saab 				break;
1343a5f0fb15SPaul Saab 			cmd_exec();
134489dd99dcSXin LI 			save_hshift = hshift;
134589dd99dcSXin LI 			hshift = 0;
1346a5f0fb15SPaul Saab 			(void) edit(FAKE_HELPFILE);
1347a5f0fb15SPaul Saab 			break;
1348a5f0fb15SPaul Saab 
1349a5f0fb15SPaul Saab 		case A_EXAMINE:
1350a5f0fb15SPaul Saab #if EXAMINE
1351a5f0fb15SPaul Saab 			/*
1352a5f0fb15SPaul Saab 			 * Edit a new file.  Get the filename.
1353a5f0fb15SPaul Saab 			 */
1354a5f0fb15SPaul Saab 			if (secure)
1355a5f0fb15SPaul Saab 			{
1356a5f0fb15SPaul Saab 				error("Command not available", NULL_PARG);
1357a5f0fb15SPaul Saab 				break;
1358a5f0fb15SPaul Saab 			}
1359a5f0fb15SPaul Saab 			start_mca(A_EXAMINE, "Examine: ", ml_examine, 0);
1360a5f0fb15SPaul Saab 			c = getcc();
1361a5f0fb15SPaul Saab 			goto again;
1362a5f0fb15SPaul Saab #else
1363a5f0fb15SPaul Saab 			error("Command not available", NULL_PARG);
1364a5f0fb15SPaul Saab 			break;
1365a5f0fb15SPaul Saab #endif
1366a5f0fb15SPaul Saab 
1367a5f0fb15SPaul Saab 		case A_VISUAL:
1368a5f0fb15SPaul Saab 			/*
1369a5f0fb15SPaul Saab 			 * Invoke an editor on the input file.
1370a5f0fb15SPaul Saab 			 */
1371a5f0fb15SPaul Saab #if EDITOR
1372a5f0fb15SPaul Saab 			if (secure)
1373a5f0fb15SPaul Saab 			{
1374a5f0fb15SPaul Saab 				error("Command not available", NULL_PARG);
1375a5f0fb15SPaul Saab 				break;
1376a5f0fb15SPaul Saab 			}
1377a5f0fb15SPaul Saab 			if (ch_getflags() & CH_HELPFILE)
1378a5f0fb15SPaul Saab 				break;
1379a5f0fb15SPaul Saab 			if (strcmp(get_filename(curr_ifile), "-") == 0)
1380a5f0fb15SPaul Saab 			{
1381a5f0fb15SPaul Saab 				error("Cannot edit standard input", NULL_PARG);
1382a5f0fb15SPaul Saab 				break;
1383a5f0fb15SPaul Saab 			}
1384a5f0fb15SPaul Saab 			if (curr_altfilename != NULL)
1385a5f0fb15SPaul Saab 			{
138689dd99dcSXin LI 				error("WARNING: This file was viewed via LESSOPEN",
1387a5f0fb15SPaul Saab 					NULL_PARG);
1388a5f0fb15SPaul Saab 			}
1389a5f0fb15SPaul Saab 			start_mca(A_SHELL, "!", ml_shell, 0);
1390a5f0fb15SPaul Saab 			/*
1391a5f0fb15SPaul Saab 			 * Expand the editor prototype string
1392a5f0fb15SPaul Saab 			 * and pass it to the system to execute.
1393a5f0fb15SPaul Saab 			 * (Make sure the screen is displayed so the
1394a5f0fb15SPaul Saab 			 * expansion of "+%lm" works.)
1395a5f0fb15SPaul Saab 			 */
1396a5f0fb15SPaul Saab 			make_display();
1397a5f0fb15SPaul Saab 			cmd_exec();
1398a5f0fb15SPaul Saab 			lsystem(pr_expand(editproto, 0), (char*)NULL);
1399a5f0fb15SPaul Saab 			break;
1400a5f0fb15SPaul Saab #else
1401a5f0fb15SPaul Saab 			error("Command not available", NULL_PARG);
1402a5f0fb15SPaul Saab 			break;
1403a5f0fb15SPaul Saab #endif
1404a5f0fb15SPaul Saab 
1405a5f0fb15SPaul Saab 		case A_NEXT_FILE:
1406a5f0fb15SPaul Saab 			/*
1407a5f0fb15SPaul Saab 			 * Examine next file.
1408a5f0fb15SPaul Saab 			 */
14091ede1615STim J. Robbins #if TAGS
14108fd4165cSPaul Saab 			if (ntags())
14118fd4165cSPaul Saab 			{
14128fd4165cSPaul Saab 				error("No next file", NULL_PARG);
14138fd4165cSPaul Saab 				break;
14148fd4165cSPaul Saab 			}
14151ede1615STim J. Robbins #endif
1416a5f0fb15SPaul Saab 			if (number <= 0)
1417a5f0fb15SPaul Saab 				number = 1;
14181ede1615STim J. Robbins 			if (edit_next((int) number))
1419a5f0fb15SPaul Saab 			{
1420720c436cSXin LI 				if (get_quit_at_eof() && hit_eof &&
1421a5f0fb15SPaul Saab 				    !(ch_getflags() & CH_HELPFILE))
1422a5f0fb15SPaul Saab 					quit(QUIT_OK);
1423a5f0fb15SPaul Saab 				parg.p_string = (number > 1) ? "(N-th) " : "";
1424a5f0fb15SPaul Saab 				error("No %snext file", &parg);
1425a5f0fb15SPaul Saab 			}
1426a5f0fb15SPaul Saab 			break;
1427a5f0fb15SPaul Saab 
1428a5f0fb15SPaul Saab 		case A_PREV_FILE:
1429a5f0fb15SPaul Saab 			/*
1430a5f0fb15SPaul Saab 			 * Examine previous file.
1431a5f0fb15SPaul Saab 			 */
14321ede1615STim J. Robbins #if TAGS
14338fd4165cSPaul Saab 			if (ntags())
14348fd4165cSPaul Saab 			{
14358fd4165cSPaul Saab 				error("No previous file", NULL_PARG);
14368fd4165cSPaul Saab 				break;
14378fd4165cSPaul Saab 			}
14381ede1615STim J. Robbins #endif
1439a5f0fb15SPaul Saab 			if (number <= 0)
1440a5f0fb15SPaul Saab 				number = 1;
14411ede1615STim J. Robbins 			if (edit_prev((int) number))
1442a5f0fb15SPaul Saab 			{
1443a5f0fb15SPaul Saab 				parg.p_string = (number > 1) ? "(N-th) " : "";
1444a5f0fb15SPaul Saab 				error("No %sprevious file", &parg);
1445a5f0fb15SPaul Saab 			}
1446a5f0fb15SPaul Saab 			break;
1447a5f0fb15SPaul Saab 
14488fd4165cSPaul Saab 		case A_NEXT_TAG:
14491ede1615STim J. Robbins #if TAGS
14508fd4165cSPaul Saab 			if (number <= 0)
14518fd4165cSPaul Saab 				number = 1;
14521ede1615STim J. Robbins 			tagfile = nexttag((int) number);
14538fd4165cSPaul Saab 			if (tagfile == NULL)
14548fd4165cSPaul Saab 			{
14558fd4165cSPaul Saab 				error("No next tag", NULL_PARG);
14568fd4165cSPaul Saab 				break;
14578fd4165cSPaul Saab 			}
14588fd4165cSPaul Saab 			if (edit(tagfile) == 0)
14598fd4165cSPaul Saab 			{
14608fd4165cSPaul Saab 				POSITION pos = tagsearch();
14618fd4165cSPaul Saab 				if (pos != NULL_POSITION)
14628fd4165cSPaul Saab 					jump_loc(pos, jump_sline);
14638fd4165cSPaul Saab 			}
14641ede1615STim J. Robbins #else
14651ede1615STim J. Robbins 			error("Command not available", NULL_PARG);
14661ede1615STim J. Robbins #endif
14678fd4165cSPaul Saab 			break;
14688fd4165cSPaul Saab 
14698fd4165cSPaul Saab 		case A_PREV_TAG:
14701ede1615STim J. Robbins #if TAGS
14718fd4165cSPaul Saab 			if (number <= 0)
14728fd4165cSPaul Saab 				number = 1;
14731ede1615STim J. Robbins 			tagfile = prevtag((int) number);
14748fd4165cSPaul Saab 			if (tagfile == NULL)
14758fd4165cSPaul Saab 			{
14768fd4165cSPaul Saab 				error("No previous tag", NULL_PARG);
14778fd4165cSPaul Saab 				break;
14788fd4165cSPaul Saab 			}
14798fd4165cSPaul Saab 			if (edit(tagfile) == 0)
14808fd4165cSPaul Saab 			{
14818fd4165cSPaul Saab 				POSITION pos = tagsearch();
14828fd4165cSPaul Saab 				if (pos != NULL_POSITION)
14838fd4165cSPaul Saab 					jump_loc(pos, jump_sline);
14848fd4165cSPaul Saab 			}
14851ede1615STim J. Robbins #else
14861ede1615STim J. Robbins 			error("Command not available", NULL_PARG);
14871ede1615STim J. Robbins #endif
14888fd4165cSPaul Saab 			break;
14898fd4165cSPaul Saab 
1490a5f0fb15SPaul Saab 		case A_INDEX_FILE:
1491a5f0fb15SPaul Saab 			/*
1492a5f0fb15SPaul Saab 			 * Examine a particular file.
1493a5f0fb15SPaul Saab 			 */
1494a5f0fb15SPaul Saab 			if (number <= 0)
1495a5f0fb15SPaul Saab 				number = 1;
14961ede1615STim J. Robbins 			if (edit_index((int) number))
1497a5f0fb15SPaul Saab 				error("No such file", NULL_PARG);
1498a5f0fb15SPaul Saab 			break;
1499a5f0fb15SPaul Saab 
1500a5f0fb15SPaul Saab 		case A_REMOVE_FILE:
1501a5f0fb15SPaul Saab 			if (ch_getflags() & CH_HELPFILE)
1502a5f0fb15SPaul Saab 				break;
1503a5f0fb15SPaul Saab 			old_ifile = curr_ifile;
1504a5f0fb15SPaul Saab 			new_ifile = getoff_ifile(curr_ifile);
1505a5f0fb15SPaul Saab 			if (new_ifile == NULL_IFILE)
1506a5f0fb15SPaul Saab 			{
1507a5f0fb15SPaul Saab 				bell();
1508a5f0fb15SPaul Saab 				break;
1509a5f0fb15SPaul Saab 			}
1510a5f0fb15SPaul Saab 			if (edit_ifile(new_ifile) != 0)
1511a5f0fb15SPaul Saab 			{
1512a5f0fb15SPaul Saab 				reedit_ifile(old_ifile);
1513a5f0fb15SPaul Saab 				break;
1514a5f0fb15SPaul Saab 			}
1515a5f0fb15SPaul Saab 			del_ifile(old_ifile);
1516a5f0fb15SPaul Saab 			break;
1517a5f0fb15SPaul Saab 
1518a5f0fb15SPaul Saab 		case A_OPT_TOGGLE:
1519a5f0fb15SPaul Saab 			optflag = OPT_TOGGLE;
1520a5f0fb15SPaul Saab 			optgetname = FALSE;
1521a5f0fb15SPaul Saab 			mca_opt_toggle();
1522a5f0fb15SPaul Saab 			c = getcc();
1523a5f0fb15SPaul Saab 			goto again;
1524a5f0fb15SPaul Saab 
1525a5f0fb15SPaul Saab 		case A_DISP_OPTION:
1526a5f0fb15SPaul Saab 			/*
1527a5f0fb15SPaul Saab 			 * Report a flag setting.
1528a5f0fb15SPaul Saab 			 */
1529a5f0fb15SPaul Saab 			optflag = OPT_NO_TOGGLE;
1530a5f0fb15SPaul Saab 			optgetname = FALSE;
1531a5f0fb15SPaul Saab 			mca_opt_toggle();
1532a5f0fb15SPaul Saab 			c = getcc();
1533a5f0fb15SPaul Saab 			goto again;
1534a5f0fb15SPaul Saab 
1535a5f0fb15SPaul Saab 		case A_FIRSTCMD:
1536a5f0fb15SPaul Saab 			/*
1537a5f0fb15SPaul Saab 			 * Set an initial command for new files.
1538a5f0fb15SPaul Saab 			 */
1539a5f0fb15SPaul Saab 			start_mca(A_FIRSTCMD, "+", (void*)NULL, 0);
1540a5f0fb15SPaul Saab 			c = getcc();
1541a5f0fb15SPaul Saab 			goto again;
1542a5f0fb15SPaul Saab 
1543a5f0fb15SPaul Saab 		case A_SHELL:
1544a5f0fb15SPaul Saab 			/*
1545a5f0fb15SPaul Saab 			 * Shell escape.
1546a5f0fb15SPaul Saab 			 */
1547a5f0fb15SPaul Saab #if SHELL_ESCAPE
1548a5f0fb15SPaul Saab 			if (secure)
1549a5f0fb15SPaul Saab 			{
1550a5f0fb15SPaul Saab 				error("Command not available", NULL_PARG);
1551a5f0fb15SPaul Saab 				break;
1552a5f0fb15SPaul Saab 			}
1553a5f0fb15SPaul Saab 			start_mca(A_SHELL, "!", ml_shell, 0);
1554a5f0fb15SPaul Saab 			c = getcc();
1555a5f0fb15SPaul Saab 			goto again;
1556a5f0fb15SPaul Saab #else
1557a5f0fb15SPaul Saab 			error("Command not available", NULL_PARG);
1558a5f0fb15SPaul Saab 			break;
1559a5f0fb15SPaul Saab #endif
1560a5f0fb15SPaul Saab 
1561a5f0fb15SPaul Saab 		case A_SETMARK:
1562a5f0fb15SPaul Saab 			/*
1563a5f0fb15SPaul Saab 			 * Set a mark.
1564a5f0fb15SPaul Saab 			 */
1565a5f0fb15SPaul Saab 			if (ch_getflags() & CH_HELPFILE)
1566a5f0fb15SPaul Saab 				break;
1567a5f0fb15SPaul Saab 			start_mca(A_SETMARK, "mark: ", (void*)NULL, 0);
1568a5f0fb15SPaul Saab 			c = getcc();
156989dd99dcSXin LI 			if (c == erase_char || c == erase2_char ||
157089dd99dcSXin LI 			    c == kill_char || c == '\n' || c == '\r')
1571a5f0fb15SPaul Saab 				break;
1572a5f0fb15SPaul Saab 			setmark(c);
1573a5f0fb15SPaul Saab 			break;
1574a5f0fb15SPaul Saab 
1575a5f0fb15SPaul Saab 		case A_GOMARK:
1576a5f0fb15SPaul Saab 			/*
1577a5f0fb15SPaul Saab 			 * Go to a mark.
1578a5f0fb15SPaul Saab 			 */
1579a5f0fb15SPaul Saab 			start_mca(A_GOMARK, "goto mark: ", (void*)NULL, 0);
1580a5f0fb15SPaul Saab 			c = getcc();
158189dd99dcSXin LI 			if (c == erase_char || c == erase2_char ||
158289dd99dcSXin LI 			    c == kill_char || c == '\n' || c == '\r')
1583a5f0fb15SPaul Saab 				break;
1584a5f0fb15SPaul Saab 			gomark(c);
1585a5f0fb15SPaul Saab 			break;
1586a5f0fb15SPaul Saab 
1587a5f0fb15SPaul Saab 		case A_PIPE:
1588a5f0fb15SPaul Saab #if PIPEC
1589a5f0fb15SPaul Saab 			if (secure)
1590a5f0fb15SPaul Saab 			{
1591a5f0fb15SPaul Saab 				error("Command not available", NULL_PARG);
1592a5f0fb15SPaul Saab 				break;
1593a5f0fb15SPaul Saab 			}
1594a5f0fb15SPaul Saab 			start_mca(A_PIPE, "|mark: ", (void*)NULL, 0);
1595a5f0fb15SPaul Saab 			c = getcc();
159689dd99dcSXin LI 			if (c == erase_char || c == erase2_char || c == kill_char)
1597a5f0fb15SPaul Saab 				break;
1598a5f0fb15SPaul Saab 			if (c == '\n' || c == '\r')
1599a5f0fb15SPaul Saab 				c = '.';
1600a5f0fb15SPaul Saab 			if (badmark(c))
1601a5f0fb15SPaul Saab 				break;
1602a5f0fb15SPaul Saab 			pipec = c;
1603a5f0fb15SPaul Saab 			start_mca(A_PIPE, "!", ml_shell, 0);
1604a5f0fb15SPaul Saab 			c = getcc();
1605a5f0fb15SPaul Saab 			goto again;
1606a5f0fb15SPaul Saab #else
1607a5f0fb15SPaul Saab 			error("Command not available", NULL_PARG);
1608a5f0fb15SPaul Saab 			break;
1609a5f0fb15SPaul Saab #endif
1610a5f0fb15SPaul Saab 
1611a5f0fb15SPaul Saab 		case A_B_BRACKET:
1612a5f0fb15SPaul Saab 		case A_F_BRACKET:
1613a5f0fb15SPaul Saab 			start_mca(action, "Brackets: ", (void*)NULL, 0);
1614a5f0fb15SPaul Saab 			c = getcc();
1615a5f0fb15SPaul Saab 			goto again;
1616a5f0fb15SPaul Saab 
1617a5f0fb15SPaul Saab 		case A_LSHIFT:
16188fd4165cSPaul Saab 			if (number > 0)
16198fd4165cSPaul Saab 				shift_count = number;
16208fd4165cSPaul Saab 			else
162115596da4SPaul Saab 				number = (shift_count > 0) ?
162215596da4SPaul Saab 					shift_count : sc_width / 2;
1623a5f0fb15SPaul Saab 			if (number > hshift)
1624a5f0fb15SPaul Saab 				number = hshift;
1625a5f0fb15SPaul Saab 			hshift -= number;
1626a5f0fb15SPaul Saab 			screen_trashed = 1;
1627a5f0fb15SPaul Saab 			break;
1628a5f0fb15SPaul Saab 
1629a5f0fb15SPaul Saab 		case A_RSHIFT:
16308fd4165cSPaul Saab 			if (number > 0)
16318fd4165cSPaul Saab 				shift_count = number;
16328fd4165cSPaul Saab 			else
163315596da4SPaul Saab 				number = (shift_count > 0) ?
163415596da4SPaul Saab 					shift_count : sc_width / 2;
1635a5f0fb15SPaul Saab 			hshift += number;
1636a5f0fb15SPaul Saab 			screen_trashed = 1;
1637a5f0fb15SPaul Saab 			break;
1638a5f0fb15SPaul Saab 
1639a5f0fb15SPaul Saab 		case A_PREFIX:
1640a5f0fb15SPaul Saab 			/*
1641a5f0fb15SPaul Saab 			 * The command is incomplete (more chars are needed).
1642a5f0fb15SPaul Saab 			 * Display the current char, so the user knows
1643a5f0fb15SPaul Saab 			 * what's going on, and get another character.
1644a5f0fb15SPaul Saab 			 */
1645a5f0fb15SPaul Saab 			if (mca != A_PREFIX)
1646a5f0fb15SPaul Saab 			{
1647a5f0fb15SPaul Saab 				cmd_reset();
1648a5f0fb15SPaul Saab 				start_mca(A_PREFIX, " ", (void*)NULL,
1649a5f0fb15SPaul Saab 					CF_QUIT_ON_ERASE);
1650a5f0fb15SPaul Saab 				(void) cmd_char(c);
1651a5f0fb15SPaul Saab 			}
1652a5f0fb15SPaul Saab 			c = getcc();
1653a5f0fb15SPaul Saab 			goto again;
1654a5f0fb15SPaul Saab 
1655a5f0fb15SPaul Saab 		case A_NOACTION:
1656a5f0fb15SPaul Saab 			break;
1657a5f0fb15SPaul Saab 
1658a5f0fb15SPaul Saab 		default:
1659a5f0fb15SPaul Saab 			bell();
1660a5f0fb15SPaul Saab 			break;
1661a5f0fb15SPaul Saab 		}
1662a5f0fb15SPaul Saab 	}
1663a5f0fb15SPaul Saab }
1664