11133e27eSPeter Avalos /*
2*e433da38SAaron LI * Copyright (C) 1984-2024 Mark Nudelman
31133e27eSPeter Avalos *
41133e27eSPeter Avalos * You may distribute under the terms of either the GNU General Public
51133e27eSPeter Avalos * License or the Less License, as specified in the README file.
61133e27eSPeter Avalos *
7e639dc31SJohn Marino * For more information, see the README file.
81133e27eSPeter Avalos */
91133e27eSPeter Avalos
101133e27eSPeter Avalos
111133e27eSPeter Avalos /*
121133e27eSPeter Avalos * User-level command processor.
131133e27eSPeter Avalos */
141133e27eSPeter Avalos
151133e27eSPeter Avalos #include "less.h"
161133e27eSPeter Avalos #if MSDOS_COMPILER==WIN32C
171133e27eSPeter Avalos #include <windows.h>
181133e27eSPeter Avalos #endif
191133e27eSPeter Avalos #include "position.h"
201133e27eSPeter Avalos #include "option.h"
211133e27eSPeter Avalos #include "cmd.h"
221133e27eSPeter Avalos
231133e27eSPeter Avalos extern int erase_char, erase2_char, kill_char;
241133e27eSPeter Avalos extern int sigs;
251133e27eSPeter Avalos extern int quit_if_one_screen;
26320d7c8aSAaron LI extern int one_screen;
271133e27eSPeter Avalos extern int sc_width;
281133e27eSPeter Avalos extern int sc_height;
2902d62a0fSDaniel Fojt extern char *kent;
301133e27eSPeter Avalos extern int swindow;
311133e27eSPeter Avalos extern int jump_sline;
321133e27eSPeter Avalos extern int quitting;
331133e27eSPeter Avalos extern int wscroll;
341133e27eSPeter Avalos extern int top_scroll;
351133e27eSPeter Avalos extern int ignore_eoi;
361133e27eSPeter Avalos extern int hshift;
37fa0be7c5SJohn Marino extern int bs_mode;
38320d7c8aSAaron LI extern int proc_backspace;
391133e27eSPeter Avalos extern int show_attn;
40e639dc31SJohn Marino extern POSITION highest_hilite;
411133e27eSPeter Avalos extern char *every_first_cmd;
421133e27eSPeter Avalos extern char version[];
431133e27eSPeter Avalos extern struct scrpos initial_scrpos;
441133e27eSPeter Avalos extern IFILE curr_ifile;
4502d62a0fSDaniel Fojt extern void *ml_search;
4602d62a0fSDaniel Fojt extern void *ml_examine;
4702d62a0fSDaniel Fojt extern int wheel_lines;
480c7ad07eSAntonio Huete Jimenez extern int def_search_type;
49*e433da38SAaron LI extern lbool search_wrapped;
501133e27eSPeter Avalos #if SHELL_ESCAPE || PIPEC
5102d62a0fSDaniel Fojt extern void *ml_shell;
521133e27eSPeter Avalos #endif
531133e27eSPeter Avalos #if EDITOR
54*e433da38SAaron LI extern constant char *editproto;
551133e27eSPeter Avalos #endif
56*e433da38SAaron LI #if OSC8_LINK
57*e433da38SAaron LI extern char *osc8_uri;
58*e433da38SAaron LI #endif
591133e27eSPeter Avalos extern int shift_count;
601133e27eSPeter Avalos extern int forw_prompt;
610c7ad07eSAntonio Huete Jimenez extern int incr_search;
62320d7c8aSAaron LI extern int full_screen;
6302d62a0fSDaniel Fojt #if MSDOS_COMPILER==WIN32C
6402d62a0fSDaniel Fojt extern int utf_mode;
65*e433da38SAaron LI extern unsigned less_acp;
6602d62a0fSDaniel Fojt #endif
671133e27eSPeter Avalos
681133e27eSPeter Avalos #if SHELL_ESCAPE
691133e27eSPeter Avalos static char *shellcmd = NULL; /* For holding last shell command for "!!" */
701133e27eSPeter Avalos #endif
711133e27eSPeter Avalos static int mca; /* The multicharacter command (action) */
721133e27eSPeter Avalos static int search_type; /* The previous type of search */
73320d7c8aSAaron LI static int last_search_type; /* Type of last executed search */
741133e27eSPeter Avalos static LINENUM number; /* The number typed by the user */
751133e27eSPeter Avalos static long fraction; /* The fractional part of the number */
7625ce721eSPeter Avalos static struct loption *curropt;
7725ce721eSPeter Avalos static int opt_lower;
781133e27eSPeter Avalos static int optflag;
79*e433da38SAaron LI static lbool optgetname;
801133e27eSPeter Avalos static POSITION bottompos;
811133e27eSPeter Avalos static int save_hshift;
82fa0be7c5SJohn Marino static int save_bs_mode;
83320d7c8aSAaron LI static int save_proc_backspace;
84*e433da38SAaron LI static int screen_trashed_value = 0;
85*e433da38SAaron LI static lbool literal_char = FALSE;
861133e27eSPeter Avalos #if PIPEC
871133e27eSPeter Avalos static char pipec;
881133e27eSPeter Avalos #endif
891133e27eSPeter Avalos
9002d62a0fSDaniel Fojt /* Stack of ungotten chars (via ungetcc) */
9125ce721eSPeter Avalos struct ungot {
9225ce721eSPeter Avalos struct ungot *ug_next;
93*e433da38SAaron LI char ug_char;
94*e433da38SAaron LI lbool ug_end_command;
9525ce721eSPeter Avalos };
9625ce721eSPeter Avalos static struct ungot* ungot = NULL;
9725ce721eSPeter Avalos
98*e433da38SAaron LI static void multi_search(constant char *pattern, int n, int silent);
991133e27eSPeter Avalos
1001133e27eSPeter Avalos /*
1011133e27eSPeter Avalos * Move the cursor to start of prompt line before executing a command.
1021133e27eSPeter Avalos * This looks nicer if the command takes a long time before
1031133e27eSPeter Avalos * updating the screen.
1041133e27eSPeter Avalos */
cmd_exec(void)105320d7c8aSAaron LI static void cmd_exec(void)
1061133e27eSPeter Avalos {
1071133e27eSPeter Avalos clear_attn();
1081133e27eSPeter Avalos clear_bot();
1091133e27eSPeter Avalos flush();
1101133e27eSPeter Avalos }
1111133e27eSPeter Avalos
1121133e27eSPeter Avalos /*
11302d62a0fSDaniel Fojt * Indicate we are reading a multi-character command.
11402d62a0fSDaniel Fojt */
set_mca(int action)115320d7c8aSAaron LI static void set_mca(int action)
11602d62a0fSDaniel Fojt {
11702d62a0fSDaniel Fojt mca = action;
11802d62a0fSDaniel Fojt clear_bot();
11902d62a0fSDaniel Fojt clear_cmd();
12002d62a0fSDaniel Fojt }
12102d62a0fSDaniel Fojt
12202d62a0fSDaniel Fojt /*
12302d62a0fSDaniel Fojt * Indicate we are not reading a multi-character command.
12402d62a0fSDaniel Fojt */
clear_mca(void)125320d7c8aSAaron LI static void clear_mca(void)
12602d62a0fSDaniel Fojt {
12702d62a0fSDaniel Fojt if (mca == 0)
12802d62a0fSDaniel Fojt return;
12902d62a0fSDaniel Fojt mca = 0;
13002d62a0fSDaniel Fojt }
13102d62a0fSDaniel Fojt
13202d62a0fSDaniel Fojt /*
1331133e27eSPeter Avalos * Set up the display to start a new multi-character command.
1341133e27eSPeter Avalos */
start_mca(int action,constant char * prompt,void * mlist,int cmdflags)135320d7c8aSAaron LI static void start_mca(int action, constant char *prompt, void *mlist, int cmdflags)
1361133e27eSPeter Avalos {
13702d62a0fSDaniel Fojt set_mca(action);
1381133e27eSPeter Avalos cmd_putstr(prompt);
1391133e27eSPeter Avalos set_mlist(mlist, cmdflags);
1401133e27eSPeter Avalos }
1411133e27eSPeter Avalos
in_mca(void)142320d7c8aSAaron LI public int in_mca(void)
1431133e27eSPeter Avalos {
1441133e27eSPeter Avalos return (mca != 0 && mca != A_PREFIX);
1451133e27eSPeter Avalos }
1461133e27eSPeter Avalos
1471133e27eSPeter Avalos /*
1481133e27eSPeter Avalos * Set up the display to start a new search command.
1491133e27eSPeter Avalos */
mca_search1(void)150320d7c8aSAaron LI static void mca_search1(void)
1511133e27eSPeter Avalos {
152320d7c8aSAaron LI int i;
153320d7c8aSAaron LI
1548be36e5bSPeter Avalos #if HILITE_SEARCH
1558be36e5bSPeter Avalos if (search_type & SRCH_FILTER)
15602d62a0fSDaniel Fojt set_mca(A_FILTER);
1578be36e5bSPeter Avalos else
1588be36e5bSPeter Avalos #endif
1591133e27eSPeter Avalos if (search_type & SRCH_FORW)
16002d62a0fSDaniel Fojt set_mca(A_F_SEARCH);
1611133e27eSPeter Avalos else
16202d62a0fSDaniel Fojt set_mca(A_B_SEARCH);
1631133e27eSPeter Avalos
1641133e27eSPeter Avalos if (search_type & SRCH_NO_MATCH)
1651133e27eSPeter Avalos cmd_putstr("Non-match ");
1661133e27eSPeter Avalos if (search_type & SRCH_FIRST_FILE)
1671133e27eSPeter Avalos cmd_putstr("First-file ");
1681133e27eSPeter Avalos if (search_type & SRCH_PAST_EOF)
1691133e27eSPeter Avalos cmd_putstr("EOF-ignore ");
1701133e27eSPeter Avalos if (search_type & SRCH_NO_MOVE)
1711133e27eSPeter Avalos cmd_putstr("Keep-pos ");
1721133e27eSPeter Avalos if (search_type & SRCH_NO_REGEX)
1731133e27eSPeter Avalos cmd_putstr("Regex-off ");
1740c7ad07eSAntonio Huete Jimenez if (search_type & SRCH_WRAP)
1750c7ad07eSAntonio Huete Jimenez cmd_putstr("Wrap ");
176320d7c8aSAaron LI for (i = 1; i <= NUM_SEARCH_COLORS; i++)
177320d7c8aSAaron LI {
178320d7c8aSAaron LI if (search_type & SRCH_SUBSEARCH(i))
179320d7c8aSAaron LI {
180320d7c8aSAaron LI char buf[INT_STRLEN_BOUND(int)+8];
181320d7c8aSAaron LI SNPRINTF1(buf, sizeof(buf), "Sub-%d ", i);
182320d7c8aSAaron LI cmd_putstr(buf);
183320d7c8aSAaron LI }
184320d7c8aSAaron LI }
185*e433da38SAaron LI if (literal_char)
186*e433da38SAaron LI cmd_putstr("Lit ");
1871133e27eSPeter Avalos
1888be36e5bSPeter Avalos #if HILITE_SEARCH
1898be36e5bSPeter Avalos if (search_type & SRCH_FILTER)
1908be36e5bSPeter Avalos cmd_putstr("&/");
1918be36e5bSPeter Avalos else
1928be36e5bSPeter Avalos #endif
1931133e27eSPeter Avalos if (search_type & SRCH_FORW)
1941133e27eSPeter Avalos cmd_putstr("/");
1951133e27eSPeter Avalos else
1961133e27eSPeter Avalos cmd_putstr("?");
1979b760066SJohn Marino forw_prompt = 0;
1980c7ad07eSAntonio Huete Jimenez }
1990c7ad07eSAntonio Huete Jimenez
mca_search(void)200320d7c8aSAaron LI static void mca_search(void)
2010c7ad07eSAntonio Huete Jimenez {
2020c7ad07eSAntonio Huete Jimenez mca_search1();
2031133e27eSPeter Avalos set_mlist(ml_search, 0);
2041133e27eSPeter Avalos }
2051133e27eSPeter Avalos
2061133e27eSPeter Avalos /*
2071133e27eSPeter Avalos * Set up the display to start a new toggle-option command.
2081133e27eSPeter Avalos */
mca_opt_toggle(void)209320d7c8aSAaron LI static void mca_opt_toggle(void)
2101133e27eSPeter Avalos {
211*e433da38SAaron LI int no_prompt = (optflag & OPT_NO_PROMPT);
212*e433da38SAaron LI int flag = (optflag & ~OPT_NO_PROMPT);
213*e433da38SAaron LI constant char *dash = (flag == OPT_NO_TOGGLE) ? "_" : "-";
2141133e27eSPeter Avalos
21502d62a0fSDaniel Fojt set_mca(A_OPT_TOGGLE);
2161133e27eSPeter Avalos cmd_putstr(dash);
2171133e27eSPeter Avalos if (optgetname)
2181133e27eSPeter Avalos cmd_putstr(dash);
2191133e27eSPeter Avalos if (no_prompt)
2201133e27eSPeter Avalos cmd_putstr("(P)");
2211133e27eSPeter Avalos switch (flag)
2221133e27eSPeter Avalos {
2231133e27eSPeter Avalos case OPT_UNSET:
2241133e27eSPeter Avalos cmd_putstr("+");
2251133e27eSPeter Avalos break;
2261133e27eSPeter Avalos case OPT_SET:
2271133e27eSPeter Avalos cmd_putstr("!");
2281133e27eSPeter Avalos break;
2291133e27eSPeter Avalos }
2309b760066SJohn Marino forw_prompt = 0;
2311133e27eSPeter Avalos set_mlist(NULL, 0);
2321133e27eSPeter Avalos }
2331133e27eSPeter Avalos
2341133e27eSPeter Avalos /*
2351133e27eSPeter Avalos * Execute a multicharacter command.
2361133e27eSPeter Avalos */
exec_mca(void)237320d7c8aSAaron LI static void exec_mca(void)
2381133e27eSPeter Avalos {
239*e433da38SAaron LI constant char *cbuf;
240*e433da38SAaron LI char *p;
2411133e27eSPeter Avalos
2421133e27eSPeter Avalos cmd_exec();
2431133e27eSPeter Avalos cbuf = get_cmdbuf();
2440c7ad07eSAntonio Huete Jimenez if (cbuf == NULL)
2450c7ad07eSAntonio Huete Jimenez return;
2461133e27eSPeter Avalos
2471133e27eSPeter Avalos switch (mca)
2481133e27eSPeter Avalos {
2491133e27eSPeter Avalos case A_F_SEARCH:
2501133e27eSPeter Avalos case A_B_SEARCH:
251fa0be7c5SJohn Marino multi_search(cbuf, (int) number, 0);
2521133e27eSPeter Avalos break;
2538be36e5bSPeter Avalos #if HILITE_SEARCH
2548be36e5bSPeter Avalos case A_FILTER:
2558be36e5bSPeter Avalos search_type ^= SRCH_NO_MATCH;
2568be36e5bSPeter Avalos set_filter_pattern(cbuf, search_type);
2578be36e5bSPeter Avalos break;
2588be36e5bSPeter Avalos #endif
2591133e27eSPeter Avalos case A_FIRSTCMD:
2601133e27eSPeter Avalos /*
2611133e27eSPeter Avalos * Skip leading spaces or + signs in the string.
2621133e27eSPeter Avalos */
2631133e27eSPeter Avalos while (*cbuf == '+' || *cbuf == ' ')
2641133e27eSPeter Avalos cbuf++;
2651133e27eSPeter Avalos if (every_first_cmd != NULL)
2661133e27eSPeter Avalos free(every_first_cmd);
2671133e27eSPeter Avalos if (*cbuf == '\0')
2681133e27eSPeter Avalos every_first_cmd = NULL;
2691133e27eSPeter Avalos else
2701133e27eSPeter Avalos every_first_cmd = save(cbuf);
2711133e27eSPeter Avalos break;
2721133e27eSPeter Avalos case A_OPT_TOGGLE:
27325ce721eSPeter Avalos toggle_option(curropt, opt_lower, cbuf, optflag);
27425ce721eSPeter Avalos curropt = NULL;
2751133e27eSPeter Avalos break;
2761133e27eSPeter Avalos case A_F_BRACKET:
2771133e27eSPeter Avalos match_brac(cbuf[0], cbuf[1], 1, (int) number);
2781133e27eSPeter Avalos break;
2791133e27eSPeter Avalos case A_B_BRACKET:
2801133e27eSPeter Avalos match_brac(cbuf[1], cbuf[0], 0, (int) number);
2811133e27eSPeter Avalos break;
2821133e27eSPeter Avalos #if EXAMINE
2831133e27eSPeter Avalos case A_EXAMINE:
284*e433da38SAaron LI if (!secure_allow(SF_EXAMINE))
2851133e27eSPeter Avalos break;
286*e433da38SAaron LI p = save(cbuf);
287*e433da38SAaron LI edit_list(p);
288*e433da38SAaron LI free(p);
2891133e27eSPeter Avalos #if TAGS
2901133e27eSPeter Avalos /* If tag structure is loaded then clean it up. */
2911133e27eSPeter Avalos cleantags();
2921133e27eSPeter Avalos #endif
2931133e27eSPeter Avalos break;
2941133e27eSPeter Avalos #endif
2951133e27eSPeter Avalos #if SHELL_ESCAPE
296*e433da38SAaron LI case A_SHELL: {
2971133e27eSPeter Avalos /*
2981133e27eSPeter Avalos * !! just uses whatever is in shellcmd.
2991133e27eSPeter Avalos * Otherwise, copy cmdbuf to shellcmd,
3001133e27eSPeter Avalos * expanding any special characters ("%" or "#").
3011133e27eSPeter Avalos */
302*e433da38SAaron LI constant char *done_msg = (*cbuf == CONTROL('P')) ? NULL : "!done";
303*e433da38SAaron LI if (done_msg == NULL)
304*e433da38SAaron LI ++cbuf;
3051133e27eSPeter Avalos if (*cbuf != '!')
3061133e27eSPeter Avalos {
3071133e27eSPeter Avalos if (shellcmd != NULL)
3081133e27eSPeter Avalos free(shellcmd);
3091133e27eSPeter Avalos shellcmd = fexpand(cbuf);
3101133e27eSPeter Avalos }
311*e433da38SAaron LI if (!secure_allow(SF_SHELL))
3121133e27eSPeter Avalos break;
3131133e27eSPeter Avalos if (shellcmd == NULL)
314*e433da38SAaron LI shellcmd = "";
315*e433da38SAaron LI lsystem(shellcmd, done_msg);
316*e433da38SAaron LI break; }
317*e433da38SAaron LI case A_PSHELL: {
318*e433da38SAaron LI constant char *done_msg = (*cbuf == CONTROL('P')) ? NULL : "#done";
319*e433da38SAaron LI if (done_msg == NULL)
320*e433da38SAaron LI ++cbuf;
321*e433da38SAaron LI if (!secure_allow(SF_SHELL))
3221133e27eSPeter Avalos break;
323*e433da38SAaron LI lsystem(pr_expand(cbuf), done_msg);
324*e433da38SAaron LI break; }
3251133e27eSPeter Avalos #endif
3261133e27eSPeter Avalos #if PIPEC
327*e433da38SAaron LI case A_PIPE: {
328*e433da38SAaron LI constant char *done_msg = (*cbuf == CONTROL('P')) ? NULL : "|done";
329*e433da38SAaron LI if (done_msg == NULL)
330*e433da38SAaron LI ++cbuf;
331*e433da38SAaron LI if (!secure_allow(SF_PIPE))
3321133e27eSPeter Avalos break;
3331133e27eSPeter Avalos (void) pipe_mark(pipec, cbuf);
334*e433da38SAaron LI if (done_msg != NULL)
335*e433da38SAaron LI error(done_msg, NULL_PARG);
336*e433da38SAaron LI break; }
3371133e27eSPeter Avalos #endif
3381133e27eSPeter Avalos }
3391133e27eSPeter Avalos }
3401133e27eSPeter Avalos
3411133e27eSPeter Avalos /*
34225ce721eSPeter Avalos * Is a character an erase or kill char?
3431133e27eSPeter Avalos */
is_erase_char(char c)344*e433da38SAaron LI static lbool is_erase_char(char c)
3451133e27eSPeter Avalos {
34625ce721eSPeter Avalos return (c == erase_char || c == erase2_char || c == kill_char);
3471133e27eSPeter Avalos }
3481133e27eSPeter Avalos
3491133e27eSPeter Avalos /*
35002d62a0fSDaniel Fojt * Is a character a carriage return or newline?
35102d62a0fSDaniel Fojt */
is_newline_char(char c)352*e433da38SAaron LI static lbool is_newline_char(char c)
35302d62a0fSDaniel Fojt {
35402d62a0fSDaniel Fojt return (c == '\n' || c == '\r');
35502d62a0fSDaniel Fojt }
35602d62a0fSDaniel Fojt
35702d62a0fSDaniel Fojt /*
35825ce721eSPeter Avalos * Handle the first char of an option (after the initial dash).
3591133e27eSPeter Avalos */
mca_opt_first_char(char c)360*e433da38SAaron LI static int mca_opt_first_char(char c)
3611133e27eSPeter Avalos {
3620c7ad07eSAntonio Huete Jimenez int no_prompt = (optflag & OPT_NO_PROMPT);
36325ce721eSPeter Avalos int flag = (optflag & ~OPT_NO_PROMPT);
3641133e27eSPeter Avalos if (flag == OPT_NO_TOGGLE)
3651133e27eSPeter Avalos {
3661133e27eSPeter Avalos switch (c)
3671133e27eSPeter Avalos {
3681133e27eSPeter Avalos case '_':
3691133e27eSPeter Avalos /* "__" = long option name. */
3701133e27eSPeter Avalos optgetname = TRUE;
3711133e27eSPeter Avalos mca_opt_toggle();
3721133e27eSPeter Avalos return (MCA_MORE);
3731133e27eSPeter Avalos }
3741133e27eSPeter Avalos } else
3751133e27eSPeter Avalos {
3761133e27eSPeter Avalos switch (c)
3771133e27eSPeter Avalos {
3781133e27eSPeter Avalos case '+':
3791133e27eSPeter Avalos /* "-+" = UNSET. */
3800c7ad07eSAntonio Huete Jimenez optflag = no_prompt | ((flag == OPT_UNSET) ?
3810c7ad07eSAntonio Huete Jimenez OPT_TOGGLE : OPT_UNSET);
3821133e27eSPeter Avalos mca_opt_toggle();
3831133e27eSPeter Avalos return (MCA_MORE);
3841133e27eSPeter Avalos case '!':
3851133e27eSPeter Avalos /* "-!" = SET */
3860c7ad07eSAntonio Huete Jimenez optflag = no_prompt | ((flag == OPT_SET) ?
3870c7ad07eSAntonio Huete Jimenez OPT_TOGGLE : OPT_SET);
3881133e27eSPeter Avalos mca_opt_toggle();
3891133e27eSPeter Avalos return (MCA_MORE);
3901133e27eSPeter Avalos case CONTROL('P'):
3911133e27eSPeter Avalos optflag ^= OPT_NO_PROMPT;
3921133e27eSPeter Avalos mca_opt_toggle();
3931133e27eSPeter Avalos return (MCA_MORE);
3941133e27eSPeter Avalos case '-':
3951133e27eSPeter Avalos /* "--" = long option name. */
3961133e27eSPeter Avalos optgetname = TRUE;
3971133e27eSPeter Avalos mca_opt_toggle();
3981133e27eSPeter Avalos return (MCA_MORE);
3991133e27eSPeter Avalos }
4001133e27eSPeter Avalos }
40125ce721eSPeter Avalos /* Char was not handled here. */
40225ce721eSPeter Avalos return (NO_MCA);
4031133e27eSPeter Avalos }
40425ce721eSPeter Avalos
4051133e27eSPeter Avalos /*
40625ce721eSPeter Avalos * Add a char to a long option name.
40725ce721eSPeter Avalos * See if we've got a match for an option name yet.
4081133e27eSPeter Avalos * If so, display the complete name and stop
4091133e27eSPeter Avalos * accepting chars until user hits RETURN.
4101133e27eSPeter Avalos */
mca_opt_nonfirst_char(char c)411*e433da38SAaron LI static int mca_opt_nonfirst_char(char c)
41225ce721eSPeter Avalos {
413*e433da38SAaron LI constant char *p;
414*e433da38SAaron LI constant char *oname;
415*e433da38SAaron LI lbool ambig;
4161133e27eSPeter Avalos
41725ce721eSPeter Avalos if (curropt != NULL)
4181133e27eSPeter Avalos {
4191133e27eSPeter Avalos /*
4201133e27eSPeter Avalos * Already have a match for the name.
4211133e27eSPeter Avalos * Don't accept anything but erase/kill.
4221133e27eSPeter Avalos */
42325ce721eSPeter Avalos if (is_erase_char(c))
4241133e27eSPeter Avalos return (MCA_DONE);
4251133e27eSPeter Avalos return (MCA_MORE);
4261133e27eSPeter Avalos }
4271133e27eSPeter Avalos /*
4281133e27eSPeter Avalos * Add char to cmd buffer and try to match
4291133e27eSPeter Avalos * the option name.
4301133e27eSPeter Avalos */
4311133e27eSPeter Avalos if (cmd_char(c) == CC_QUIT)
4321133e27eSPeter Avalos return (MCA_DONE);
4331133e27eSPeter Avalos p = get_cmdbuf();
4340c7ad07eSAntonio Huete Jimenez if (p == NULL)
4350c7ad07eSAntonio Huete Jimenez return (MCA_MORE);
43625ce721eSPeter Avalos opt_lower = ASCII_IS_LOWER(p[0]);
437*e433da38SAaron LI curropt = findopt_name(&p, &oname, &ambig);
43825ce721eSPeter Avalos if (curropt != NULL)
4391133e27eSPeter Avalos {
4401133e27eSPeter Avalos /*
4411133e27eSPeter Avalos * Got a match.
44225ce721eSPeter Avalos * Remember the option and
4431133e27eSPeter Avalos * display the full option name.
4441133e27eSPeter Avalos */
4451133e27eSPeter Avalos cmd_reset();
4461133e27eSPeter Avalos mca_opt_toggle();
4471133e27eSPeter Avalos for (p = oname; *p != '\0'; p++)
4481133e27eSPeter Avalos {
4491133e27eSPeter Avalos c = *p;
45025ce721eSPeter Avalos if (!opt_lower && ASCII_IS_LOWER(c))
4511133e27eSPeter Avalos c = ASCII_TO_UPPER(c);
4521133e27eSPeter Avalos if (cmd_char(c) != CC_OK)
4531133e27eSPeter Avalos return (MCA_DONE);
4541133e27eSPeter Avalos }
455*e433da38SAaron LI } else if (!ambig)
45602d62a0fSDaniel Fojt {
45702d62a0fSDaniel Fojt bell();
4581133e27eSPeter Avalos }
4591133e27eSPeter Avalos return (MCA_MORE);
4601133e27eSPeter Avalos }
46125ce721eSPeter Avalos
46225ce721eSPeter Avalos /*
46325ce721eSPeter Avalos * Handle a char of an option toggle command.
46425ce721eSPeter Avalos */
mca_opt_char(char c)465*e433da38SAaron LI static int mca_opt_char(char c)
46625ce721eSPeter Avalos {
46725ce721eSPeter Avalos PARG parg;
46825ce721eSPeter Avalos
46925ce721eSPeter Avalos /*
47025ce721eSPeter Avalos * This may be a short option (single char),
47125ce721eSPeter Avalos * or one char of a long option name,
47225ce721eSPeter Avalos * or one char of the option parameter.
47325ce721eSPeter Avalos */
47425ce721eSPeter Avalos if (curropt == NULL && len_cmdbuf() == 0)
47525ce721eSPeter Avalos {
47625ce721eSPeter Avalos int ret = mca_opt_first_char(c);
47725ce721eSPeter Avalos if (ret != NO_MCA)
47825ce721eSPeter Avalos return (ret);
47925ce721eSPeter Avalos }
48025ce721eSPeter Avalos if (optgetname)
48125ce721eSPeter Avalos {
48225ce721eSPeter Avalos /* We're getting a long option name. */
4830c7ad07eSAntonio Huete Jimenez if (!is_newline_char(c) && c != '=')
48425ce721eSPeter Avalos return (mca_opt_nonfirst_char(c));
48525ce721eSPeter Avalos if (curropt == NULL)
48625ce721eSPeter Avalos {
48725ce721eSPeter Avalos parg.p_string = get_cmdbuf();
4880c7ad07eSAntonio Huete Jimenez if (parg.p_string == NULL)
4890c7ad07eSAntonio Huete Jimenez return (MCA_MORE);
49025ce721eSPeter Avalos error("There is no --%s option", &parg);
49125ce721eSPeter Avalos return (MCA_DONE);
49225ce721eSPeter Avalos }
49325ce721eSPeter Avalos optgetname = FALSE;
49425ce721eSPeter Avalos cmd_reset();
4951133e27eSPeter Avalos } else
4961133e27eSPeter Avalos {
49725ce721eSPeter Avalos if (is_erase_char(c))
49825ce721eSPeter Avalos return (NO_MCA);
49925ce721eSPeter Avalos if (curropt != NULL)
50025ce721eSPeter Avalos /* We're getting the option parameter. */
50125ce721eSPeter Avalos return (NO_MCA);
50225ce721eSPeter Avalos curropt = findopt(c);
50325ce721eSPeter Avalos if (curropt == NULL)
5041133e27eSPeter Avalos {
50525ce721eSPeter Avalos parg.p_string = propt(c);
50625ce721eSPeter Avalos error("There is no %s option", &parg);
50725ce721eSPeter Avalos return (MCA_DONE);
50825ce721eSPeter Avalos }
50902d62a0fSDaniel Fojt opt_lower = ASCII_IS_LOWER(c);
51025ce721eSPeter Avalos }
51125ce721eSPeter Avalos /*
51225ce721eSPeter Avalos * If the option which was entered does not take a
51325ce721eSPeter Avalos * parameter, toggle the option immediately,
51425ce721eSPeter Avalos * so user doesn't have to hit RETURN.
51525ce721eSPeter Avalos */
51625ce721eSPeter Avalos if ((optflag & ~OPT_NO_PROMPT) != OPT_TOGGLE ||
51725ce721eSPeter Avalos !opt_has_param(curropt))
51825ce721eSPeter Avalos {
51902d62a0fSDaniel Fojt toggle_option(curropt, opt_lower, "", optflag);
5201133e27eSPeter Avalos return (MCA_DONE);
5211133e27eSPeter Avalos }
5221133e27eSPeter Avalos /*
52325ce721eSPeter Avalos * Display a prompt appropriate for the option parameter.
5241133e27eSPeter Avalos */
525*e433da38SAaron LI start_mca(A_OPT_TOGGLE, opt_prompt(curropt), NULL, 0);
5261133e27eSPeter Avalos return (MCA_MORE);
52725ce721eSPeter Avalos }
5281133e27eSPeter Avalos
5291133e27eSPeter Avalos /*
5300c7ad07eSAntonio Huete Jimenez * Normalize search type.
5310c7ad07eSAntonio Huete Jimenez */
norm_search_type(int st)532320d7c8aSAaron LI public int norm_search_type(int st)
5330c7ad07eSAntonio Huete Jimenez {
5340c7ad07eSAntonio Huete Jimenez /* WRAP and PAST_EOF are mutually exclusive. */
5350c7ad07eSAntonio Huete Jimenez if ((st & (SRCH_PAST_EOF|SRCH_WRAP)) == (SRCH_PAST_EOF|SRCH_WRAP))
5360c7ad07eSAntonio Huete Jimenez st ^= SRCH_PAST_EOF;
5370c7ad07eSAntonio Huete Jimenez return st;
5380c7ad07eSAntonio Huete Jimenez }
5390c7ad07eSAntonio Huete Jimenez
5400c7ad07eSAntonio Huete Jimenez /*
54125ce721eSPeter Avalos * Handle a char of a search command.
54225ce721eSPeter Avalos */
mca_search_char(char c)543*e433da38SAaron LI static int mca_search_char(char c)
54425ce721eSPeter Avalos {
54525ce721eSPeter Avalos int flag = 0;
54625ce721eSPeter Avalos
54725ce721eSPeter Avalos /*
5481133e27eSPeter Avalos * Certain characters as the first char of
5491133e27eSPeter Avalos * the pattern have special meaning:
5501133e27eSPeter Avalos * ! Toggle the NO_MATCH flag
5511133e27eSPeter Avalos * * Toggle the PAST_EOF flag
5521133e27eSPeter Avalos * @ Toggle the FIRST_FILE flag
5531133e27eSPeter Avalos */
554*e433da38SAaron LI if (len_cmdbuf() > 0 || literal_char)
555*e433da38SAaron LI {
556*e433da38SAaron LI literal_char = FALSE;
55725ce721eSPeter Avalos return (NO_MCA);
558*e433da38SAaron LI }
5591133e27eSPeter Avalos
5601133e27eSPeter Avalos switch (c)
5611133e27eSPeter Avalos {
5621133e27eSPeter Avalos case CONTROL('E'): /* ignore END of file */
5631133e27eSPeter Avalos case '*':
5648be36e5bSPeter Avalos if (mca != A_FILTER)
5651133e27eSPeter Avalos flag = SRCH_PAST_EOF;
566320d7c8aSAaron LI search_type &= ~SRCH_WRAP;
5671133e27eSPeter Avalos break;
5681133e27eSPeter Avalos case CONTROL('F'): /* FIRST file */
5691133e27eSPeter Avalos case '@':
5708be36e5bSPeter Avalos if (mca != A_FILTER)
5711133e27eSPeter Avalos flag = SRCH_FIRST_FILE;
5721133e27eSPeter Avalos break;
5731133e27eSPeter Avalos case CONTROL('K'): /* KEEP position */
5748be36e5bSPeter Avalos if (mca != A_FILTER)
5751133e27eSPeter Avalos flag = SRCH_NO_MOVE;
5761133e27eSPeter Avalos break;
577320d7c8aSAaron LI case CONTROL('S'): { /* SUBSEARCH */
578320d7c8aSAaron LI char buf[INT_STRLEN_BOUND(int)+24];
579320d7c8aSAaron LI SNPRINTF1(buf, sizeof(buf), "Sub-pattern (1-%d):", NUM_SEARCH_COLORS);
580320d7c8aSAaron LI clear_bot();
581320d7c8aSAaron LI cmd_putstr(buf);
582320d7c8aSAaron LI flush();
583320d7c8aSAaron LI c = getcc();
584320d7c8aSAaron LI if (c >= '1' && c <= '0'+NUM_SEARCH_COLORS)
585320d7c8aSAaron LI flag = SRCH_SUBSEARCH(c-'0');
586320d7c8aSAaron LI else
587320d7c8aSAaron LI flag = -1; /* calls mca_search() below to repaint */
588320d7c8aSAaron LI break; }
5890c7ad07eSAntonio Huete Jimenez case CONTROL('W'): /* WRAP around */
5900c7ad07eSAntonio Huete Jimenez if (mca != A_FILTER)
5910c7ad07eSAntonio Huete Jimenez flag = SRCH_WRAP;
5920c7ad07eSAntonio Huete Jimenez break;
5931133e27eSPeter Avalos case CONTROL('R'): /* Don't use REGULAR EXPRESSIONS */
5941133e27eSPeter Avalos flag = SRCH_NO_REGEX;
5951133e27eSPeter Avalos break;
5961133e27eSPeter Avalos case CONTROL('N'): /* NOT match */
5971133e27eSPeter Avalos case '!':
5981133e27eSPeter Avalos flag = SRCH_NO_MATCH;
5991133e27eSPeter Avalos break;
600*e433da38SAaron LI case CONTROL('L'):
601*e433da38SAaron LI literal_char = TRUE;
602*e433da38SAaron LI flag = -1;
603*e433da38SAaron LI break;
6041133e27eSPeter Avalos }
60525ce721eSPeter Avalos
6061133e27eSPeter Avalos if (flag != 0)
6071133e27eSPeter Avalos {
608320d7c8aSAaron LI if (flag != -1)
6090c7ad07eSAntonio Huete Jimenez search_type = norm_search_type(search_type ^ flag);
6101133e27eSPeter Avalos mca_search();
6111133e27eSPeter Avalos return (MCA_MORE);
6121133e27eSPeter Avalos }
61325ce721eSPeter Avalos return (NO_MCA);
61425ce721eSPeter Avalos }
61525ce721eSPeter Avalos
61625ce721eSPeter Avalos /*
61725ce721eSPeter Avalos * Handle a character of a multi-character command.
61825ce721eSPeter Avalos */
mca_char(char c)619*e433da38SAaron LI static int mca_char(char c)
62025ce721eSPeter Avalos {
62125ce721eSPeter Avalos int ret;
62225ce721eSPeter Avalos
62325ce721eSPeter Avalos switch (mca)
62425ce721eSPeter Avalos {
62525ce721eSPeter Avalos case 0:
62625ce721eSPeter Avalos /*
62725ce721eSPeter Avalos * We're not in a multicharacter command.
62825ce721eSPeter Avalos */
62925ce721eSPeter Avalos return (NO_MCA);
63025ce721eSPeter Avalos
63125ce721eSPeter Avalos case A_PREFIX:
63225ce721eSPeter Avalos /*
63325ce721eSPeter Avalos * In the prefix of a command.
63425ce721eSPeter Avalos * This not considered a multichar command
63525ce721eSPeter Avalos * (even tho it uses cmdbuf, etc.).
63625ce721eSPeter Avalos * It is handled in the commands() switch.
63725ce721eSPeter Avalos */
63825ce721eSPeter Avalos return (NO_MCA);
63925ce721eSPeter Avalos
64025ce721eSPeter Avalos case A_DIGIT:
64125ce721eSPeter Avalos /*
64225ce721eSPeter Avalos * Entering digits of a number.
64325ce721eSPeter Avalos * Terminated by a non-digit.
64425ce721eSPeter Avalos */
6450c7ad07eSAntonio Huete Jimenez if ((c >= '0' && c <= '9') || c == '.')
6460c7ad07eSAntonio Huete Jimenez break;
6470c7ad07eSAntonio Huete Jimenez switch (editchar(c, ECF_PEEK|ECF_NOHISTORY|ECF_NOCOMPLETE|ECF_NORIGHTLEFT))
64825ce721eSPeter Avalos {
6490c7ad07eSAntonio Huete Jimenez case A_NOACTION:
6500c7ad07eSAntonio Huete Jimenez /*
6510c7ad07eSAntonio Huete Jimenez * Ignore this char and get another one.
6520c7ad07eSAntonio Huete Jimenez */
6530c7ad07eSAntonio Huete Jimenez return (MCA_MORE);
6540c7ad07eSAntonio Huete Jimenez case A_INVALID:
65525ce721eSPeter Avalos /*
65625ce721eSPeter Avalos * Not part of the number.
65725ce721eSPeter Avalos * End the number and treat this char
65825ce721eSPeter Avalos * as a normal command character.
65925ce721eSPeter Avalos */
66025ce721eSPeter Avalos number = cmd_int(&fraction);
66102d62a0fSDaniel Fojt clear_mca();
66225ce721eSPeter Avalos cmd_accept();
66325ce721eSPeter Avalos return (NO_MCA);
66425ce721eSPeter Avalos }
66525ce721eSPeter Avalos break;
66625ce721eSPeter Avalos
66725ce721eSPeter Avalos case A_OPT_TOGGLE:
66825ce721eSPeter Avalos ret = mca_opt_char(c);
66925ce721eSPeter Avalos if (ret != NO_MCA)
67025ce721eSPeter Avalos return (ret);
67125ce721eSPeter Avalos break;
67225ce721eSPeter Avalos
67325ce721eSPeter Avalos case A_F_SEARCH:
67425ce721eSPeter Avalos case A_B_SEARCH:
67525ce721eSPeter Avalos case A_FILTER:
67625ce721eSPeter Avalos ret = mca_search_char(c);
67725ce721eSPeter Avalos if (ret != NO_MCA)
67825ce721eSPeter Avalos return (ret);
67925ce721eSPeter Avalos break;
68025ce721eSPeter Avalos
68125ce721eSPeter Avalos default:
68225ce721eSPeter Avalos /* Other multicharacter command. */
6831133e27eSPeter Avalos break;
6841133e27eSPeter Avalos }
6851133e27eSPeter Avalos
6861133e27eSPeter Avalos /*
68725ce721eSPeter Avalos * The multichar command is terminated by a newline.
6881133e27eSPeter Avalos */
68902d62a0fSDaniel Fojt if (is_newline_char(c))
6901133e27eSPeter Avalos {
6911133e27eSPeter Avalos /*
6921133e27eSPeter Avalos * Execute the command.
6931133e27eSPeter Avalos */
6941133e27eSPeter Avalos exec_mca();
6951133e27eSPeter Avalos return (MCA_DONE);
6961133e27eSPeter Avalos }
6971133e27eSPeter Avalos
6981133e27eSPeter Avalos /*
6991133e27eSPeter Avalos * Append the char to the command buffer.
7001133e27eSPeter Avalos */
7011133e27eSPeter Avalos if (cmd_char(c) == CC_QUIT)
7021133e27eSPeter Avalos /*
7031133e27eSPeter Avalos * Abort the multi-char command.
7041133e27eSPeter Avalos */
7051133e27eSPeter Avalos return (MCA_DONE);
7061133e27eSPeter Avalos
7070c7ad07eSAntonio Huete Jimenez switch (mca)
7080c7ad07eSAntonio Huete Jimenez {
7090c7ad07eSAntonio Huete Jimenez case A_F_BRACKET:
7100c7ad07eSAntonio Huete Jimenez case A_B_BRACKET:
7110c7ad07eSAntonio Huete Jimenez if (len_cmdbuf() >= 2)
7121133e27eSPeter Avalos {
7131133e27eSPeter Avalos /*
7141133e27eSPeter Avalos * Special case for the bracket-matching commands.
7151133e27eSPeter Avalos * Execute the command after getting exactly two
7161133e27eSPeter Avalos * characters from the user.
7171133e27eSPeter Avalos */
7181133e27eSPeter Avalos exec_mca();
7191133e27eSPeter Avalos return (MCA_DONE);
7201133e27eSPeter Avalos }
7210c7ad07eSAntonio Huete Jimenez break;
7220c7ad07eSAntonio Huete Jimenez case A_F_SEARCH:
7230c7ad07eSAntonio Huete Jimenez case A_B_SEARCH:
7240c7ad07eSAntonio Huete Jimenez if (incr_search)
7250c7ad07eSAntonio Huete Jimenez {
7260c7ad07eSAntonio Huete Jimenez /* Incremental search: do a search after every input char. */
727320d7c8aSAaron LI int st = (search_type & (SRCH_FORW|SRCH_BACK|SRCH_NO_MATCH|SRCH_NO_REGEX|SRCH_NO_MOVE|SRCH_WRAP|SRCH_SUBSEARCH_ALL));
728*e433da38SAaron LI ssize_t save_updown;
729*e433da38SAaron LI constant char *pattern = get_cmdbuf();
7300c7ad07eSAntonio Huete Jimenez if (pattern == NULL)
7310c7ad07eSAntonio Huete Jimenez return (MCA_MORE);
7320c7ad07eSAntonio Huete Jimenez /*
7330c7ad07eSAntonio Huete Jimenez * Must save updown_match because mca_search
7340c7ad07eSAntonio Huete Jimenez * reinits it. That breaks history scrolling.
7350c7ad07eSAntonio Huete Jimenez * {{ This is ugly. mca_search probably shouldn't call set_mlist. }}
7360c7ad07eSAntonio Huete Jimenez */
737*e433da38SAaron LI save_updown = save_updown_match();
7380c7ad07eSAntonio Huete Jimenez cmd_exec();
7390c7ad07eSAntonio Huete Jimenez if (*pattern == '\0')
7400c7ad07eSAntonio Huete Jimenez {
7410c7ad07eSAntonio Huete Jimenez /* User has backspaced to an empty pattern. */
7420c7ad07eSAntonio Huete Jimenez undo_search(1);
7430c7ad07eSAntonio Huete Jimenez } else
7440c7ad07eSAntonio Huete Jimenez {
7450c7ad07eSAntonio Huete Jimenez if (search(st | SRCH_INCR, pattern, 1) != 0)
7460c7ad07eSAntonio Huete Jimenez /* No match, invalid pattern, etc. */
7470c7ad07eSAntonio Huete Jimenez undo_search(1);
7480c7ad07eSAntonio Huete Jimenez }
7490c7ad07eSAntonio Huete Jimenez /* Redraw the search prompt and search string. */
750*e433da38SAaron LI if (is_screen_trashed() || !full_screen)
751320d7c8aSAaron LI {
752320d7c8aSAaron LI clear();
753320d7c8aSAaron LI repaint();
754320d7c8aSAaron LI }
7550c7ad07eSAntonio Huete Jimenez mca_search1();
756*e433da38SAaron LI restore_updown_match(save_updown);
7570c7ad07eSAntonio Huete Jimenez cmd_repaint(NULL);
7580c7ad07eSAntonio Huete Jimenez }
7590c7ad07eSAntonio Huete Jimenez break;
7600c7ad07eSAntonio Huete Jimenez }
7611133e27eSPeter Avalos
7621133e27eSPeter Avalos /*
7631133e27eSPeter Avalos * Need another character.
7641133e27eSPeter Avalos */
7651133e27eSPeter Avalos return (MCA_MORE);
7661133e27eSPeter Avalos }
7671133e27eSPeter Avalos
7681133e27eSPeter Avalos /*
7691133e27eSPeter Avalos * Discard any buffered file data.
7701133e27eSPeter Avalos */
clear_buffers(void)771320d7c8aSAaron LI static void clear_buffers(void)
7721133e27eSPeter Avalos {
7731133e27eSPeter Avalos if (!(ch_getflags() & CH_CANSEEK))
7741133e27eSPeter Avalos return;
7751133e27eSPeter Avalos ch_flush();
7761133e27eSPeter Avalos clr_linenum();
7771133e27eSPeter Avalos #if HILITE_SEARCH
7781133e27eSPeter Avalos clr_hilite();
7791133e27eSPeter Avalos #endif
7801133e27eSPeter Avalos }
7811133e27eSPeter Avalos
screen_trashed_num(int trashed)782*e433da38SAaron LI public void screen_trashed_num(int trashed)
783*e433da38SAaron LI {
784*e433da38SAaron LI screen_trashed_value = trashed;
785*e433da38SAaron LI }
786*e433da38SAaron LI
screen_trashed(void)787*e433da38SAaron LI public void screen_trashed(void)
788*e433da38SAaron LI {
789*e433da38SAaron LI screen_trashed_num(1);
790*e433da38SAaron LI }
791*e433da38SAaron LI
is_screen_trashed(void)792*e433da38SAaron LI public int is_screen_trashed(void)
793*e433da38SAaron LI {
794*e433da38SAaron LI return screen_trashed_value;
795*e433da38SAaron LI }
796*e433da38SAaron LI
7971133e27eSPeter Avalos /*
7981133e27eSPeter Avalos * Make sure the screen is displayed.
7991133e27eSPeter Avalos */
make_display(void)800320d7c8aSAaron LI static void make_display(void)
8011133e27eSPeter Avalos {
8021133e27eSPeter Avalos /*
803320d7c8aSAaron LI * If not full_screen, we can't rely on scrolling to fill the screen.
804320d7c8aSAaron LI * We need to clear and repaint screen before any change.
805320d7c8aSAaron LI */
806320d7c8aSAaron LI if (!full_screen && !(quit_if_one_screen && one_screen))
807320d7c8aSAaron LI clear();
808320d7c8aSAaron LI /*
8091133e27eSPeter Avalos * If nothing is displayed yet, display starting from initial_scrpos.
8101133e27eSPeter Avalos */
8111133e27eSPeter Avalos if (empty_screen())
8121133e27eSPeter Avalos {
8131133e27eSPeter Avalos if (initial_scrpos.pos == NULL_POSITION)
8141133e27eSPeter Avalos jump_loc(ch_zero(), 1);
8151133e27eSPeter Avalos else
8161133e27eSPeter Avalos jump_loc(initial_scrpos.pos, initial_scrpos.ln);
817*e433da38SAaron LI } else if (is_screen_trashed() || !full_screen)
8181133e27eSPeter Avalos {
8191133e27eSPeter Avalos int save_top_scroll = top_scroll;
8201133e27eSPeter Avalos int save_ignore_eoi = ignore_eoi;
8211133e27eSPeter Avalos top_scroll = 1;
8221133e27eSPeter Avalos ignore_eoi = 0;
823*e433da38SAaron LI if (is_screen_trashed() == 2)
8241133e27eSPeter Avalos {
8251133e27eSPeter Avalos /* Special case used by ignore_eoi: re-open the input file
8261133e27eSPeter Avalos * and jump to the end of the file. */
8271133e27eSPeter Avalos reopen_curr_ifile();
8281133e27eSPeter Avalos jump_forw();
8291133e27eSPeter Avalos }
8301133e27eSPeter Avalos repaint();
8311133e27eSPeter Avalos top_scroll = save_top_scroll;
8321133e27eSPeter Avalos ignore_eoi = save_ignore_eoi;
8331133e27eSPeter Avalos }
8341133e27eSPeter Avalos }
8351133e27eSPeter Avalos
8361133e27eSPeter Avalos /*
8371133e27eSPeter Avalos * Display the appropriate prompt.
8381133e27eSPeter Avalos */
prompt(void)839320d7c8aSAaron LI static void prompt(void)
8401133e27eSPeter Avalos {
84102d62a0fSDaniel Fojt constant char *p;
8421133e27eSPeter Avalos
843*e433da38SAaron LI if (ungot != NULL && !ungot->ug_end_command)
8441133e27eSPeter Avalos {
8451133e27eSPeter Avalos /*
8461133e27eSPeter Avalos * No prompt necessary if commands are from
8471133e27eSPeter Avalos * ungotten chars rather than from the user.
8481133e27eSPeter Avalos */
8491133e27eSPeter Avalos return;
8501133e27eSPeter Avalos }
8511133e27eSPeter Avalos
8521133e27eSPeter Avalos /*
8531133e27eSPeter Avalos * Make sure the screen is displayed.
8541133e27eSPeter Avalos */
8551133e27eSPeter Avalos make_display();
8561133e27eSPeter Avalos bottompos = position(BOTTOM_PLUS_ONE);
8571133e27eSPeter Avalos
8581133e27eSPeter Avalos /*
8598be36e5bSPeter Avalos * If we've hit EOF on the last file and the -E flag is set, quit.
8601133e27eSPeter Avalos */
8618be36e5bSPeter Avalos if (get_quit_at_eof() == OPT_ONPLUS &&
8628be36e5bSPeter Avalos eof_displayed() && !(ch_getflags() & CH_HELPFILE) &&
8631133e27eSPeter Avalos next_ifile(curr_ifile) == NULL_IFILE)
8641133e27eSPeter Avalos quit(QUIT_OK);
8658be36e5bSPeter Avalos
8661133e27eSPeter Avalos /*
8678be36e5bSPeter Avalos * If the entire file is displayed and the -F flag is set, quit.
8681133e27eSPeter Avalos */
8698be36e5bSPeter Avalos if (quit_if_one_screen &&
8708be36e5bSPeter Avalos entire_file_displayed() && !(ch_getflags() & CH_HELPFILE) &&
8711133e27eSPeter Avalos next_ifile(curr_ifile) == NULL_IFILE)
8721133e27eSPeter Avalos quit(QUIT_OK);
8730c7ad07eSAntonio Huete Jimenez quit_if_one_screen = FALSE; /* only get one chance at this */
8741133e27eSPeter Avalos
8751133e27eSPeter Avalos #if MSDOS_COMPILER==WIN32C
8761133e27eSPeter Avalos /*
8771133e27eSPeter Avalos * In Win32, display the file name in the window title.
8781133e27eSPeter Avalos */
8791133e27eSPeter Avalos if (!(ch_getflags() & CH_HELPFILE))
88002d62a0fSDaniel Fojt {
88102d62a0fSDaniel Fojt WCHAR w[MAX_PATH+16];
8820c7ad07eSAntonio Huete Jimenez p = pr_expand("Less?f - %f.");
883*e433da38SAaron LI MultiByteToWideChar(less_acp, 0, p, -1, w, countof(w));
88402d62a0fSDaniel Fojt SetConsoleTitleW(w);
88502d62a0fSDaniel Fojt }
8861133e27eSPeter Avalos #endif
88702d62a0fSDaniel Fojt
8881133e27eSPeter Avalos /*
8891133e27eSPeter Avalos * Select the proper prompt and display it.
8901133e27eSPeter Avalos */
8911133e27eSPeter Avalos /*
8921133e27eSPeter Avalos * If the previous action was a forward movement,
8931133e27eSPeter Avalos * don't clear the bottom line of the display;
8941133e27eSPeter Avalos * just print the prompt since the forward movement guarantees
8951133e27eSPeter Avalos * that we're in the right position to display the prompt.
8961133e27eSPeter Avalos * Clearing the line could cause a problem: for example, if the last
8971133e27eSPeter Avalos * line displayed ended at the right screen edge without a newline,
8981133e27eSPeter Avalos * then clearing would clear the last displayed line rather than
8991133e27eSPeter Avalos * the prompt line.
9001133e27eSPeter Avalos */
9011133e27eSPeter Avalos if (!forw_prompt)
9021133e27eSPeter Avalos clear_bot();
9031133e27eSPeter Avalos clear_cmd();
9041133e27eSPeter Avalos forw_prompt = 0;
9051133e27eSPeter Avalos p = pr_string();
9060c7ad07eSAntonio Huete Jimenez #if HILITE_SEARCH
9078be36e5bSPeter Avalos if (is_filtering())
9088be36e5bSPeter Avalos putstr("& ");
9090c7ad07eSAntonio Huete Jimenez #endif
910*e433da38SAaron LI if (search_wrapped)
911*e433da38SAaron LI {
912*e433da38SAaron LI if (search_type & SRCH_BACK)
913*e433da38SAaron LI error("Search hit top; continuing at bottom", NULL_PARG);
914*e433da38SAaron LI else
915*e433da38SAaron LI error("Search hit bottom; continuing at top", NULL_PARG);
916*e433da38SAaron LI search_wrapped = FALSE;
917*e433da38SAaron LI }
918*e433da38SAaron LI #if OSC8_LINK
919*e433da38SAaron LI if (osc8_uri != NULL)
920*e433da38SAaron LI {
921*e433da38SAaron LI PARG parg;
922*e433da38SAaron LI parg.p_string = osc8_uri;
923*e433da38SAaron LI error("Link: %s", &parg);
924*e433da38SAaron LI free(osc8_uri);
925*e433da38SAaron LI osc8_uri = NULL;
926*e433da38SAaron LI }
927*e433da38SAaron LI #endif
9281133e27eSPeter Avalos if (p == NULL || *p == '\0')
9290c7ad07eSAntonio Huete Jimenez {
9300c7ad07eSAntonio Huete Jimenez at_enter(AT_NORMAL|AT_COLOR_PROMPT);
9311133e27eSPeter Avalos putchr(':');
9320c7ad07eSAntonio Huete Jimenez at_exit();
9330c7ad07eSAntonio Huete Jimenez } else
9341133e27eSPeter Avalos {
93502d62a0fSDaniel Fojt #if MSDOS_COMPILER==WIN32C
93602d62a0fSDaniel Fojt WCHAR w[MAX_PATH*2];
93702d62a0fSDaniel Fojt char a[MAX_PATH*2];
938*e433da38SAaron LI MultiByteToWideChar(less_acp, 0, p, -1, w, countof(w));
93902d62a0fSDaniel Fojt WideCharToMultiByte(utf_mode ? CP_UTF8 : GetConsoleOutputCP(),
94002d62a0fSDaniel Fojt 0, w, -1, a, sizeof(a), NULL, NULL);
94102d62a0fSDaniel Fojt p = a;
94202d62a0fSDaniel Fojt #endif
9430c7ad07eSAntonio Huete Jimenez load_line(p);
9440c7ad07eSAntonio Huete Jimenez put_line();
9451133e27eSPeter Avalos }
9461133e27eSPeter Avalos clear_eol();
9471133e27eSPeter Avalos }
9481133e27eSPeter Avalos
9491133e27eSPeter Avalos /*
9501133e27eSPeter Avalos * Display the less version message.
9511133e27eSPeter Avalos */
dispversion(void)952320d7c8aSAaron LI public void dispversion(void)
9531133e27eSPeter Avalos {
9541133e27eSPeter Avalos PARG parg;
9551133e27eSPeter Avalos
9561133e27eSPeter Avalos parg.p_string = version;
9571133e27eSPeter Avalos error("less %s", &parg);
9581133e27eSPeter Avalos }
9591133e27eSPeter Avalos
9601133e27eSPeter Avalos /*
96102d62a0fSDaniel Fojt * Return a character to complete a partial command, if possible.
96202d62a0fSDaniel Fojt */
getcc_end_command(void)963*e433da38SAaron LI static char getcc_end_command(void)
96402d62a0fSDaniel Fojt {
965*e433da38SAaron LI int ch;
96602d62a0fSDaniel Fojt switch (mca)
96702d62a0fSDaniel Fojt {
96802d62a0fSDaniel Fojt case A_DIGIT:
96902d62a0fSDaniel Fojt /* We have a number but no command. Treat as #g. */
97002d62a0fSDaniel Fojt return ('g');
97102d62a0fSDaniel Fojt case A_F_SEARCH:
97202d62a0fSDaniel Fojt case A_B_SEARCH:
973320d7c8aSAaron LI case A_FILTER:
97402d62a0fSDaniel Fojt /* We have "/string" but no newline. Add the \n. */
97502d62a0fSDaniel Fojt return ('\n');
97602d62a0fSDaniel Fojt default:
97702d62a0fSDaniel Fojt /* Some other incomplete command. Let user complete it. */
978*e433da38SAaron LI if (ungot != NULL)
979*e433da38SAaron LI return ('\0');
980*e433da38SAaron LI ch = getchr();
981*e433da38SAaron LI if (ch < 0) ch = '\0';
982*e433da38SAaron LI return (char) ch;
98302d62a0fSDaniel Fojt }
98402d62a0fSDaniel Fojt }
98502d62a0fSDaniel Fojt
98602d62a0fSDaniel Fojt /*
987*e433da38SAaron LI * Get a command character from the ungotten stack.
988*e433da38SAaron LI */
get_ungot(lbool * p_end_command)989*e433da38SAaron LI static char get_ungot(lbool *p_end_command)
990*e433da38SAaron LI {
991*e433da38SAaron LI struct ungot *ug = ungot;
992*e433da38SAaron LI char c = ug->ug_char;
993*e433da38SAaron LI if (p_end_command != NULL)
994*e433da38SAaron LI *p_end_command = ug->ug_end_command;
995*e433da38SAaron LI ungot = ug->ug_next;
996*e433da38SAaron LI free(ug);
997*e433da38SAaron LI return c;
998*e433da38SAaron LI }
999*e433da38SAaron LI
1000*e433da38SAaron LI /*
1001*e433da38SAaron LI * Delete all ungotten characters.
1002*e433da38SAaron LI */
getcc_clear(void)1003*e433da38SAaron LI public void getcc_clear(void)
1004*e433da38SAaron LI {
1005*e433da38SAaron LI while (ungot != NULL)
1006*e433da38SAaron LI (void) get_ungot(NULL);
1007*e433da38SAaron LI }
1008*e433da38SAaron LI
1009*e433da38SAaron LI /*
10101133e27eSPeter Avalos * Get command character.
10111133e27eSPeter Avalos * The character normally comes from the keyboard,
10121133e27eSPeter Avalos * but may come from ungotten characters
10131133e27eSPeter Avalos * (characters previously given to ungetcc or ungetsc).
10141133e27eSPeter Avalos */
getccu(void)1015*e433da38SAaron LI static char getccu(void)
10161133e27eSPeter Avalos {
1017*e433da38SAaron LI int c = 0;
10180c7ad07eSAntonio Huete Jimenez while (c == 0)
10190c7ad07eSAntonio Huete Jimenez {
1020fa0be7c5SJohn Marino if (ungot == NULL)
102125ce721eSPeter Avalos {
102202d62a0fSDaniel Fojt /* Normal case: no ungotten chars.
102302d62a0fSDaniel Fojt * Get char from the user. */
102402d62a0fSDaniel Fojt c = getchr();
1025*e433da38SAaron LI if (c < 0) return ('\0');
102602d62a0fSDaniel Fojt } else
1027fa0be7c5SJohn Marino {
102802d62a0fSDaniel Fojt /* Ungotten chars available:
102902d62a0fSDaniel Fojt * Take the top of stack (most recent). */
1030*e433da38SAaron LI lbool end_command;
1031*e433da38SAaron LI c = get_ungot(&end_command);
1032*e433da38SAaron LI if (end_command)
103302d62a0fSDaniel Fojt c = getcc_end_command();
10341133e27eSPeter Avalos }
10350c7ad07eSAntonio Huete Jimenez }
1036*e433da38SAaron LI return ((char) c);
103725ce721eSPeter Avalos }
103802d62a0fSDaniel Fojt
103902d62a0fSDaniel Fojt /*
104002d62a0fSDaniel Fojt * Get a command character, but if we receive the orig sequence,
104102d62a0fSDaniel Fojt * convert it to the repl sequence.
104202d62a0fSDaniel Fojt */
getcc_repl(char constant * orig,char constant * repl,char (* gr_getc)(void),void (* gr_ungetc)(char))1043*e433da38SAaron LI static char getcc_repl(char constant *orig, char constant *repl, char (*gr_getc)(void), void (*gr_ungetc)(char))
104402d62a0fSDaniel Fojt {
1045*e433da38SAaron LI char c;
1046*e433da38SAaron LI char keys[16];
1047*e433da38SAaron LI size_t ki = 0;
104802d62a0fSDaniel Fojt
104902d62a0fSDaniel Fojt c = (*gr_getc)();
105002d62a0fSDaniel Fojt if (orig == NULL || orig[0] == '\0')
105102d62a0fSDaniel Fojt return c;
105202d62a0fSDaniel Fojt for (;;)
105302d62a0fSDaniel Fojt {
105402d62a0fSDaniel Fojt keys[ki] = c;
105502d62a0fSDaniel Fojt if (c != orig[ki] || ki >= sizeof(keys)-1)
105602d62a0fSDaniel Fojt {
105702d62a0fSDaniel Fojt /* This is not orig we have been receiving.
105802d62a0fSDaniel Fojt * If we have stashed chars in keys[],
105902d62a0fSDaniel Fojt * unget them and return the first one. */
106002d62a0fSDaniel Fojt while (ki > 0)
106102d62a0fSDaniel Fojt (*gr_ungetc)(keys[ki--]);
106202d62a0fSDaniel Fojt return keys[0];
106302d62a0fSDaniel Fojt }
106402d62a0fSDaniel Fojt if (orig[++ki] == '\0')
106502d62a0fSDaniel Fojt {
106602d62a0fSDaniel Fojt /* We've received the full orig sequence.
106702d62a0fSDaniel Fojt * Return the repl sequence. */
106802d62a0fSDaniel Fojt ki = strlen(repl)-1;
106902d62a0fSDaniel Fojt while (ki > 0)
107002d62a0fSDaniel Fojt (*gr_ungetc)(repl[ki--]);
107102d62a0fSDaniel Fojt return repl[0];
107202d62a0fSDaniel Fojt }
107302d62a0fSDaniel Fojt /* We've received a partial orig sequence (ki chars of it).
107402d62a0fSDaniel Fojt * Get next char and see if it continues to match orig. */
107502d62a0fSDaniel Fojt c = (*gr_getc)();
107602d62a0fSDaniel Fojt }
107702d62a0fSDaniel Fojt }
107802d62a0fSDaniel Fojt
107902d62a0fSDaniel Fojt /*
108002d62a0fSDaniel Fojt * Get command character.
108102d62a0fSDaniel Fojt */
getcc(void)1082*e433da38SAaron LI public char getcc(void)
108302d62a0fSDaniel Fojt {
108402d62a0fSDaniel Fojt /* Replace kent (keypad Enter) with a newline. */
108502d62a0fSDaniel Fojt return getcc_repl(kent, "\n", getccu, ungetcc);
108625ce721eSPeter Avalos }
108725ce721eSPeter Avalos
10881133e27eSPeter Avalos /*
10891133e27eSPeter Avalos * "Unget" a command character.
10901133e27eSPeter Avalos * The next getcc() will return this character.
10911133e27eSPeter Avalos */
ungetcc(char c)1092*e433da38SAaron LI public void ungetcc(char c)
10931133e27eSPeter Avalos {
109425ce721eSPeter Avalos struct ungot *ug = (struct ungot *) ecalloc(1, sizeof(struct ungot));
109525ce721eSPeter Avalos
109602d62a0fSDaniel Fojt ug->ug_char = c;
109725ce721eSPeter Avalos ug->ug_next = ungot;
109825ce721eSPeter Avalos ungot = ug;
10991133e27eSPeter Avalos }
11001133e27eSPeter Avalos
11011133e27eSPeter Avalos /*
11020c7ad07eSAntonio Huete Jimenez * "Unget" a command character.
11030c7ad07eSAntonio Huete Jimenez * If any other chars are already ungotten, put this one after those.
11040c7ad07eSAntonio Huete Jimenez */
ungetcc_back1(char c,lbool end_command)1105*e433da38SAaron LI static void ungetcc_back1(char c, lbool end_command)
11060c7ad07eSAntonio Huete Jimenez {
11070c7ad07eSAntonio Huete Jimenez struct ungot *ug = (struct ungot *) ecalloc(1, sizeof(struct ungot));
11080c7ad07eSAntonio Huete Jimenez ug->ug_char = c;
1109*e433da38SAaron LI ug->ug_end_command = end_command;
11100c7ad07eSAntonio Huete Jimenez ug->ug_next = NULL;
11110c7ad07eSAntonio Huete Jimenez if (ungot == NULL)
11120c7ad07eSAntonio Huete Jimenez ungot = ug;
11130c7ad07eSAntonio Huete Jimenez else
11140c7ad07eSAntonio Huete Jimenez {
11150c7ad07eSAntonio Huete Jimenez struct ungot *pu;
11160c7ad07eSAntonio Huete Jimenez for (pu = ungot; pu->ug_next != NULL; pu = pu->ug_next)
11170c7ad07eSAntonio Huete Jimenez continue;
11180c7ad07eSAntonio Huete Jimenez pu->ug_next = ug;
11190c7ad07eSAntonio Huete Jimenez }
11200c7ad07eSAntonio Huete Jimenez }
11210c7ad07eSAntonio Huete Jimenez
ungetcc_back(char c)1122*e433da38SAaron LI public void ungetcc_back(char c)
1123*e433da38SAaron LI {
1124*e433da38SAaron LI ungetcc_back1(c, FALSE);
1125*e433da38SAaron LI }
1126*e433da38SAaron LI
ungetcc_end_command(void)1127*e433da38SAaron LI public void ungetcc_end_command(void)
1128*e433da38SAaron LI {
1129*e433da38SAaron LI ungetcc_back1('\0', TRUE);
1130*e433da38SAaron LI }
1131*e433da38SAaron LI
11320c7ad07eSAntonio Huete Jimenez /*
11331133e27eSPeter Avalos * Unget a whole string of command characters.
11341133e27eSPeter Avalos * The next sequence of getcc()'s will return this string.
11351133e27eSPeter Avalos */
ungetsc(constant char * s)1136*e433da38SAaron LI public void ungetsc(constant char *s)
11371133e27eSPeter Avalos {
11380c7ad07eSAntonio Huete Jimenez while (*s != '\0')
11390c7ad07eSAntonio Huete Jimenez ungetcc_back(*s++);
11401133e27eSPeter Avalos }
11411133e27eSPeter Avalos
11421133e27eSPeter Avalos /*
114302d62a0fSDaniel Fojt * Peek the next command character, without consuming it.
114402d62a0fSDaniel Fojt */
peekcc(void)1145*e433da38SAaron LI public char peekcc(void)
114602d62a0fSDaniel Fojt {
1147*e433da38SAaron LI char c = getcc();
114802d62a0fSDaniel Fojt ungetcc(c);
114902d62a0fSDaniel Fojt return c;
115002d62a0fSDaniel Fojt }
115102d62a0fSDaniel Fojt
115202d62a0fSDaniel Fojt /*
11531133e27eSPeter Avalos * Search for a pattern, possibly in multiple files.
11541133e27eSPeter Avalos * If SRCH_FIRST_FILE is set, begin searching at the first file.
11551133e27eSPeter Avalos * If SRCH_PAST_EOF is set, continue the search thru multiple files.
11561133e27eSPeter Avalos */
multi_search(constant char * pattern,int n,int silent)1157*e433da38SAaron LI static void multi_search(constant char *pattern, int n, int silent)
11581133e27eSPeter Avalos {
115902d62a0fSDaniel Fojt int nomore;
11601133e27eSPeter Avalos IFILE save_ifile;
1161*e433da38SAaron LI lbool changed_file;
11621133e27eSPeter Avalos
1163*e433da38SAaron LI changed_file = FALSE;
11641133e27eSPeter Avalos save_ifile = save_curr_ifile();
11651133e27eSPeter Avalos
1166320d7c8aSAaron LI if ((search_type & (SRCH_FORW|SRCH_BACK)) == 0)
1167320d7c8aSAaron LI search_type |= SRCH_FORW;
11681133e27eSPeter Avalos if (search_type & SRCH_FIRST_FILE)
11691133e27eSPeter Avalos {
11701133e27eSPeter Avalos /*
11711133e27eSPeter Avalos * Start at the first (or last) file
11721133e27eSPeter Avalos * in the command line list.
11731133e27eSPeter Avalos */
11741133e27eSPeter Avalos if (search_type & SRCH_FORW)
11751133e27eSPeter Avalos nomore = edit_first();
11761133e27eSPeter Avalos else
11771133e27eSPeter Avalos nomore = edit_last();
11781133e27eSPeter Avalos if (nomore)
11791133e27eSPeter Avalos {
11801133e27eSPeter Avalos unsave_ifile(save_ifile);
11811133e27eSPeter Avalos return;
11821133e27eSPeter Avalos }
1183*e433da38SAaron LI changed_file = TRUE;
11841133e27eSPeter Avalos search_type &= ~SRCH_FIRST_FILE;
11851133e27eSPeter Avalos }
11861133e27eSPeter Avalos
11871133e27eSPeter Avalos for (;;)
11881133e27eSPeter Avalos {
11891133e27eSPeter Avalos n = search(search_type, pattern, n);
11901133e27eSPeter Avalos /*
11911133e27eSPeter Avalos * The SRCH_NO_MOVE flag doesn't "stick": it gets cleared
11921133e27eSPeter Avalos * after being used once. This allows "n" to work after
11931133e27eSPeter Avalos * using a /@@ search.
11941133e27eSPeter Avalos */
11951133e27eSPeter Avalos search_type &= ~SRCH_NO_MOVE;
1196320d7c8aSAaron LI last_search_type = search_type;
11971133e27eSPeter Avalos if (n == 0)
11981133e27eSPeter Avalos {
11991133e27eSPeter Avalos /*
12001133e27eSPeter Avalos * Found it.
12011133e27eSPeter Avalos */
12021133e27eSPeter Avalos unsave_ifile(save_ifile);
12031133e27eSPeter Avalos return;
12041133e27eSPeter Avalos }
12051133e27eSPeter Avalos
12061133e27eSPeter Avalos if (n < 0)
12071133e27eSPeter Avalos /*
12081133e27eSPeter Avalos * Some kind of error in the search.
12091133e27eSPeter Avalos * Error message has been printed by search().
12101133e27eSPeter Avalos */
12111133e27eSPeter Avalos break;
12121133e27eSPeter Avalos
12131133e27eSPeter Avalos if ((search_type & SRCH_PAST_EOF) == 0)
12141133e27eSPeter Avalos /*
12151133e27eSPeter Avalos * We didn't find a match, but we're
12161133e27eSPeter Avalos * supposed to search only one file.
12171133e27eSPeter Avalos */
12181133e27eSPeter Avalos break;
12191133e27eSPeter Avalos /*
12201133e27eSPeter Avalos * Move on to the next file.
12211133e27eSPeter Avalos */
12221133e27eSPeter Avalos if (search_type & SRCH_FORW)
12231133e27eSPeter Avalos nomore = edit_next(1);
12241133e27eSPeter Avalos else
12251133e27eSPeter Avalos nomore = edit_prev(1);
12261133e27eSPeter Avalos if (nomore)
12271133e27eSPeter Avalos break;
1228*e433da38SAaron LI changed_file = TRUE;
12291133e27eSPeter Avalos }
12301133e27eSPeter Avalos
12311133e27eSPeter Avalos /*
12321133e27eSPeter Avalos * Didn't find it.
12331133e27eSPeter Avalos * Print an error message if we haven't already.
12341133e27eSPeter Avalos */
1235fa0be7c5SJohn Marino if (n > 0 && !silent)
12361133e27eSPeter Avalos error("Pattern not found", NULL_PARG);
12371133e27eSPeter Avalos
12381133e27eSPeter Avalos if (changed_file)
12391133e27eSPeter Avalos {
12401133e27eSPeter Avalos /*
12411133e27eSPeter Avalos * Restore the file we were originally viewing.
12421133e27eSPeter Avalos */
12431133e27eSPeter Avalos reedit_ifile(save_ifile);
12441133e27eSPeter Avalos } else
12451133e27eSPeter Avalos {
12461133e27eSPeter Avalos unsave_ifile(save_ifile);
12471133e27eSPeter Avalos }
12481133e27eSPeter Avalos }
12491133e27eSPeter Avalos
12501133e27eSPeter Avalos /*
1251e639dc31SJohn Marino * Forward forever, or until a highlighted line appears.
1252e639dc31SJohn Marino */
forw_loop(int until_hilite)1253320d7c8aSAaron LI static int forw_loop(int until_hilite)
1254e639dc31SJohn Marino {
1255e639dc31SJohn Marino POSITION curr_len;
1256e639dc31SJohn Marino
1257e639dc31SJohn Marino if (ch_getflags() & CH_HELPFILE)
1258e639dc31SJohn Marino return (A_NOACTION);
1259e639dc31SJohn Marino
1260e639dc31SJohn Marino cmd_exec();
1261fa0be7c5SJohn Marino jump_forw_buffered();
1262e639dc31SJohn Marino curr_len = ch_length();
1263e639dc31SJohn Marino highest_hilite = until_hilite ? curr_len : NULL_POSITION;
1264e639dc31SJohn Marino ignore_eoi = 1;
1265e639dc31SJohn Marino while (!sigs)
1266e639dc31SJohn Marino {
1267e639dc31SJohn Marino if (until_hilite && highest_hilite > curr_len)
1268e639dc31SJohn Marino {
1269e639dc31SJohn Marino bell();
1270e639dc31SJohn Marino break;
1271e639dc31SJohn Marino }
1272e639dc31SJohn Marino make_display();
1273e639dc31SJohn Marino forward(1, 0, 0);
1274e639dc31SJohn Marino }
1275e639dc31SJohn Marino ignore_eoi = 0;
1276e639dc31SJohn Marino ch_set_eof();
1277e639dc31SJohn Marino
1278e639dc31SJohn Marino /*
1279e639dc31SJohn Marino * This gets us back in "F mode" after processing
1280e639dc31SJohn Marino * a non-abort signal (e.g. window-change).
1281e639dc31SJohn Marino */
1282e639dc31SJohn Marino if (sigs && !ABORT_SIGS())
1283e639dc31SJohn Marino return (until_hilite ? A_F_UNTIL_HILITE : A_F_FOREVER);
1284e639dc31SJohn Marino
1285e639dc31SJohn Marino return (A_NOACTION);
1286e639dc31SJohn Marino }
1287e639dc31SJohn Marino
1288e639dc31SJohn Marino /*
12891133e27eSPeter Avalos * Main command processor.
12901133e27eSPeter Avalos * Accept and execute commands until a quit command.
12911133e27eSPeter Avalos */
commands(void)1292320d7c8aSAaron LI public void commands(void)
12931133e27eSPeter Avalos {
1294*e433da38SAaron LI char c;
129502d62a0fSDaniel Fojt int action;
1296*e433da38SAaron LI constant char *cbuf;
1297*e433da38SAaron LI constant char *msg;
12981133e27eSPeter Avalos int newaction;
12990c7ad07eSAntonio Huete Jimenez int save_jump_sline;
13001133e27eSPeter Avalos int save_search_type;
1301*e433da38SAaron LI constant char *extra;
13021133e27eSPeter Avalos PARG parg;
13031133e27eSPeter Avalos IFILE old_ifile;
13041133e27eSPeter Avalos IFILE new_ifile;
1305*e433da38SAaron LI constant char *tagfile;
13061133e27eSPeter Avalos
13071133e27eSPeter Avalos search_type = SRCH_FORW;
13081133e27eSPeter Avalos wscroll = (sc_height + 1) / 2;
13091133e27eSPeter Avalos newaction = A_NOACTION;
13101133e27eSPeter Avalos
13111133e27eSPeter Avalos for (;;)
13121133e27eSPeter Avalos {
131302d62a0fSDaniel Fojt clear_mca();
13141133e27eSPeter Avalos cmd_accept();
13151133e27eSPeter Avalos number = 0;
131625ce721eSPeter Avalos curropt = NULL;
13171133e27eSPeter Avalos
13181133e27eSPeter Avalos /*
13191133e27eSPeter Avalos * See if any signals need processing.
13201133e27eSPeter Avalos */
13211133e27eSPeter Avalos if (sigs)
13221133e27eSPeter Avalos {
13231133e27eSPeter Avalos psignals();
13241133e27eSPeter Avalos if (quitting)
13251133e27eSPeter Avalos quit(QUIT_SAVED_STATUS);
13261133e27eSPeter Avalos }
13271133e27eSPeter Avalos
13281133e27eSPeter Avalos /*
13291133e27eSPeter Avalos * See if window size changed, for systems that don't
13301133e27eSPeter Avalos * generate SIGWINCH.
13311133e27eSPeter Avalos */
13321133e27eSPeter Avalos check_winch();
13331133e27eSPeter Avalos
13341133e27eSPeter Avalos /*
13351133e27eSPeter Avalos * Display prompt and accept a character.
13361133e27eSPeter Avalos */
13371133e27eSPeter Avalos cmd_reset();
13381133e27eSPeter Avalos prompt();
13391133e27eSPeter Avalos if (sigs)
13401133e27eSPeter Avalos continue;
13411133e27eSPeter Avalos if (newaction == A_NOACTION)
13421133e27eSPeter Avalos c = getcc();
13431133e27eSPeter Avalos
13441133e27eSPeter Avalos again:
13451133e27eSPeter Avalos if (sigs)
13461133e27eSPeter Avalos continue;
13471133e27eSPeter Avalos
13481133e27eSPeter Avalos if (newaction != A_NOACTION)
13491133e27eSPeter Avalos {
13501133e27eSPeter Avalos action = newaction;
13511133e27eSPeter Avalos newaction = A_NOACTION;
13521133e27eSPeter Avalos } else
13531133e27eSPeter Avalos {
13541133e27eSPeter Avalos /*
13551133e27eSPeter Avalos * If we are in a multicharacter command, call mca_char.
13561133e27eSPeter Avalos * Otherwise we call fcmd_decode to determine the
13571133e27eSPeter Avalos * action to be performed.
13581133e27eSPeter Avalos */
13591133e27eSPeter Avalos if (mca)
13601133e27eSPeter Avalos switch (mca_char(c))
13611133e27eSPeter Avalos {
13621133e27eSPeter Avalos case MCA_MORE:
13631133e27eSPeter Avalos /*
13641133e27eSPeter Avalos * Need another character.
13651133e27eSPeter Avalos */
13661133e27eSPeter Avalos c = getcc();
13671133e27eSPeter Avalos goto again;
13681133e27eSPeter Avalos case MCA_DONE:
13691133e27eSPeter Avalos /*
13701133e27eSPeter Avalos * Command has been handled by mca_char.
13711133e27eSPeter Avalos * Start clean with a prompt.
13721133e27eSPeter Avalos */
13731133e27eSPeter Avalos continue;
13741133e27eSPeter Avalos case NO_MCA:
13751133e27eSPeter Avalos /*
13761133e27eSPeter Avalos * Not a multi-char command
13771133e27eSPeter Avalos * (at least, not anymore).
13781133e27eSPeter Avalos */
13791133e27eSPeter Avalos break;
13801133e27eSPeter Avalos }
13811133e27eSPeter Avalos
13821133e27eSPeter Avalos /*
13831133e27eSPeter Avalos * Decode the command character and decide what to do.
13841133e27eSPeter Avalos */
1385*e433da38SAaron LI extra = NULL;
13861133e27eSPeter Avalos if (mca)
13871133e27eSPeter Avalos {
13881133e27eSPeter Avalos /*
13891133e27eSPeter Avalos * We're in a multichar command.
13901133e27eSPeter Avalos * Add the character to the command buffer
13911133e27eSPeter Avalos * and display it on the screen.
13921133e27eSPeter Avalos * If the user backspaces past the start
13931133e27eSPeter Avalos * of the line, abort the command.
13941133e27eSPeter Avalos */
13951133e27eSPeter Avalos if (cmd_char(c) == CC_QUIT || len_cmdbuf() == 0)
13961133e27eSPeter Avalos continue;
13971133e27eSPeter Avalos cbuf = get_cmdbuf();
13980c7ad07eSAntonio Huete Jimenez if (cbuf == NULL)
13990c7ad07eSAntonio Huete Jimenez continue;
1400*e433da38SAaron LI action = fcmd_decode(cbuf, &extra);
14011133e27eSPeter Avalos } else
14021133e27eSPeter Avalos {
14031133e27eSPeter Avalos /*
14041133e27eSPeter Avalos * Don't use cmd_char if we're starting fresh
14051133e27eSPeter Avalos * at the beginning of a command, because we
14061133e27eSPeter Avalos * don't want to echo the command until we know
14071133e27eSPeter Avalos * it is a multichar command. We also don't
14081133e27eSPeter Avalos * want erase_char/kill_char to be treated
14091133e27eSPeter Avalos * as line editing characters.
14101133e27eSPeter Avalos */
1411*e433da38SAaron LI constant char tbuf[2] = { c, '\0' };
1412*e433da38SAaron LI action = fcmd_decode(tbuf, &extra);
14131133e27eSPeter Avalos }
14141133e27eSPeter Avalos /*
14151133e27eSPeter Avalos * If an "extra" string was returned,
14161133e27eSPeter Avalos * process it as a string of command characters.
14171133e27eSPeter Avalos */
14181133e27eSPeter Avalos if (extra != NULL)
14191133e27eSPeter Avalos ungetsc(extra);
14201133e27eSPeter Avalos }
14211133e27eSPeter Avalos /*
14221133e27eSPeter Avalos * Clear the cmdbuf string.
14231133e27eSPeter Avalos * (But not if we're in the prefix of a command,
14241133e27eSPeter Avalos * because the partial command string is kept there.)
14251133e27eSPeter Avalos */
14261133e27eSPeter Avalos if (action != A_PREFIX)
14271133e27eSPeter Avalos cmd_reset();
14281133e27eSPeter Avalos
14291133e27eSPeter Avalos switch (action)
14301133e27eSPeter Avalos {
14311133e27eSPeter Avalos case A_DIGIT:
14321133e27eSPeter Avalos /*
14331133e27eSPeter Avalos * First digit of a number.
14341133e27eSPeter Avalos */
1435*e433da38SAaron LI start_mca(A_DIGIT, ":", NULL, CF_QUIT_ON_ERASE);
14361133e27eSPeter Avalos goto again;
14371133e27eSPeter Avalos
14381133e27eSPeter Avalos case A_F_WINDOW:
14391133e27eSPeter Avalos /*
14401133e27eSPeter Avalos * Forward one window (and set the window size).
14411133e27eSPeter Avalos */
14421133e27eSPeter Avalos if (number > 0)
14431133e27eSPeter Avalos swindow = (int) number;
14441133e27eSPeter Avalos /* FALLTHRU */
14451133e27eSPeter Avalos case A_F_SCREEN:
14461133e27eSPeter Avalos /*
14471133e27eSPeter Avalos * Forward one screen.
14481133e27eSPeter Avalos */
14491133e27eSPeter Avalos if (number <= 0)
14501133e27eSPeter Avalos number = get_swindow();
14511133e27eSPeter Avalos cmd_exec();
14521133e27eSPeter Avalos if (show_attn)
14531133e27eSPeter Avalos set_attnpos(bottompos);
14541133e27eSPeter Avalos forward((int) number, 0, 1);
14551133e27eSPeter Avalos break;
14561133e27eSPeter Avalos
14571133e27eSPeter Avalos case A_B_WINDOW:
14581133e27eSPeter Avalos /*
14591133e27eSPeter Avalos * Backward one window (and set the window size).
14601133e27eSPeter Avalos */
14611133e27eSPeter Avalos if (number > 0)
14621133e27eSPeter Avalos swindow = (int) number;
14631133e27eSPeter Avalos /* FALLTHRU */
14641133e27eSPeter Avalos case A_B_SCREEN:
14651133e27eSPeter Avalos /*
14661133e27eSPeter Avalos * Backward one screen.
14671133e27eSPeter Avalos */
14681133e27eSPeter Avalos if (number <= 0)
14691133e27eSPeter Avalos number = get_swindow();
14701133e27eSPeter Avalos cmd_exec();
14711133e27eSPeter Avalos backward((int) number, 0, 1);
14721133e27eSPeter Avalos break;
14731133e27eSPeter Avalos
14741133e27eSPeter Avalos case A_F_LINE:
14751133e27eSPeter Avalos /*
14761133e27eSPeter Avalos * Forward N (default 1) line.
14771133e27eSPeter Avalos */
14781133e27eSPeter Avalos if (number <= 0)
14791133e27eSPeter Avalos number = 1;
14801133e27eSPeter Avalos cmd_exec();
14811133e27eSPeter Avalos if (show_attn == OPT_ONPLUS && number > 1)
14821133e27eSPeter Avalos set_attnpos(bottompos);
14831133e27eSPeter Avalos forward((int) number, 0, 0);
14841133e27eSPeter Avalos break;
14851133e27eSPeter Avalos
14861133e27eSPeter Avalos case A_B_LINE:
14871133e27eSPeter Avalos /*
14881133e27eSPeter Avalos * Backward N (default 1) line.
14891133e27eSPeter Avalos */
14901133e27eSPeter Avalos if (number <= 0)
14911133e27eSPeter Avalos number = 1;
14921133e27eSPeter Avalos cmd_exec();
14931133e27eSPeter Avalos backward((int) number, 0, 0);
14941133e27eSPeter Avalos break;
14951133e27eSPeter Avalos
149602d62a0fSDaniel Fojt case A_F_MOUSE:
149702d62a0fSDaniel Fojt /*
149802d62a0fSDaniel Fojt * Forward wheel_lines lines.
149902d62a0fSDaniel Fojt */
150002d62a0fSDaniel Fojt cmd_exec();
150102d62a0fSDaniel Fojt forward(wheel_lines, 0, 0);
150202d62a0fSDaniel Fojt break;
150302d62a0fSDaniel Fojt
150402d62a0fSDaniel Fojt case A_B_MOUSE:
150502d62a0fSDaniel Fojt /*
150602d62a0fSDaniel Fojt * Backward wheel_lines lines.
150702d62a0fSDaniel Fojt */
150802d62a0fSDaniel Fojt cmd_exec();
150902d62a0fSDaniel Fojt backward(wheel_lines, 0, 0);
151002d62a0fSDaniel Fojt break;
151102d62a0fSDaniel Fojt
15121133e27eSPeter Avalos case A_FF_LINE:
15131133e27eSPeter Avalos /*
15141133e27eSPeter Avalos * Force forward N (default 1) line.
15151133e27eSPeter Avalos */
15161133e27eSPeter Avalos if (number <= 0)
15171133e27eSPeter Avalos number = 1;
15181133e27eSPeter Avalos cmd_exec();
15191133e27eSPeter Avalos if (show_attn == OPT_ONPLUS && number > 1)
15201133e27eSPeter Avalos set_attnpos(bottompos);
15211133e27eSPeter Avalos forward((int) number, 1, 0);
15221133e27eSPeter Avalos break;
15231133e27eSPeter Avalos
15241133e27eSPeter Avalos case A_BF_LINE:
15251133e27eSPeter Avalos /*
15261133e27eSPeter Avalos * Force backward N (default 1) line.
15271133e27eSPeter Avalos */
15281133e27eSPeter Avalos if (number <= 0)
15291133e27eSPeter Avalos number = 1;
15301133e27eSPeter Avalos cmd_exec();
15311133e27eSPeter Avalos backward((int) number, 1, 0);
15321133e27eSPeter Avalos break;
15331133e27eSPeter Avalos
15341133e27eSPeter Avalos case A_FF_SCREEN:
15351133e27eSPeter Avalos /*
15361133e27eSPeter Avalos * Force forward one screen.
15371133e27eSPeter Avalos */
15381133e27eSPeter Avalos if (number <= 0)
15391133e27eSPeter Avalos number = get_swindow();
15401133e27eSPeter Avalos cmd_exec();
15411133e27eSPeter Avalos if (show_attn == OPT_ONPLUS)
15421133e27eSPeter Avalos set_attnpos(bottompos);
15431133e27eSPeter Avalos forward((int) number, 1, 0);
15441133e27eSPeter Avalos break;
15451133e27eSPeter Avalos
15461133e27eSPeter Avalos case A_F_FOREVER:
15471133e27eSPeter Avalos /*
15481133e27eSPeter Avalos * Forward forever, ignoring EOF.
15491133e27eSPeter Avalos */
1550fa0be7c5SJohn Marino if (show_attn)
1551fa0be7c5SJohn Marino set_attnpos(bottompos);
1552e639dc31SJohn Marino newaction = forw_loop(0);
15531133e27eSPeter Avalos break;
1554e639dc31SJohn Marino
1555e639dc31SJohn Marino case A_F_UNTIL_HILITE:
1556e639dc31SJohn Marino newaction = forw_loop(1);
15571133e27eSPeter Avalos break;
15581133e27eSPeter Avalos
15591133e27eSPeter Avalos case A_F_SCROLL:
15601133e27eSPeter Avalos /*
15611133e27eSPeter Avalos * Forward N lines
15621133e27eSPeter Avalos * (default same as last 'd' or 'u' command).
15631133e27eSPeter Avalos */
15641133e27eSPeter Avalos if (number > 0)
15651133e27eSPeter Avalos wscroll = (int) number;
15661133e27eSPeter Avalos cmd_exec();
15671133e27eSPeter Avalos if (show_attn == OPT_ONPLUS)
15681133e27eSPeter Avalos set_attnpos(bottompos);
15691133e27eSPeter Avalos forward(wscroll, 0, 0);
15701133e27eSPeter Avalos break;
15711133e27eSPeter Avalos
15721133e27eSPeter Avalos case A_B_SCROLL:
15731133e27eSPeter Avalos /*
15741133e27eSPeter Avalos * Forward N lines
15751133e27eSPeter Avalos * (default same as last 'd' or 'u' command).
15761133e27eSPeter Avalos */
15771133e27eSPeter Avalos if (number > 0)
15781133e27eSPeter Avalos wscroll = (int) number;
15791133e27eSPeter Avalos cmd_exec();
15801133e27eSPeter Avalos backward(wscroll, 0, 0);
15811133e27eSPeter Avalos break;
15821133e27eSPeter Avalos
15831133e27eSPeter Avalos case A_FREPAINT:
15841133e27eSPeter Avalos /*
15851133e27eSPeter Avalos * Flush buffers, then repaint screen.
15861133e27eSPeter Avalos * Don't flush the buffers on a pipe!
15871133e27eSPeter Avalos */
15881133e27eSPeter Avalos clear_buffers();
15891133e27eSPeter Avalos /* FALLTHRU */
15901133e27eSPeter Avalos case A_REPAINT:
15911133e27eSPeter Avalos /*
15921133e27eSPeter Avalos * Repaint screen.
15931133e27eSPeter Avalos */
15941133e27eSPeter Avalos cmd_exec();
15951133e27eSPeter Avalos repaint();
15961133e27eSPeter Avalos break;
15971133e27eSPeter Avalos
15981133e27eSPeter Avalos case A_GOLINE:
15991133e27eSPeter Avalos /*
16001133e27eSPeter Avalos * Go to line N, default beginning of file.
16010c7ad07eSAntonio Huete Jimenez * If N <= 0, ignore jump_sline in order to avoid
16020c7ad07eSAntonio Huete Jimenez * empty lines before the beginning of the file.
16031133e27eSPeter Avalos */
16040c7ad07eSAntonio Huete Jimenez save_jump_sline = jump_sline;
16051133e27eSPeter Avalos if (number <= 0)
16060c7ad07eSAntonio Huete Jimenez {
16071133e27eSPeter Avalos number = 1;
16080c7ad07eSAntonio Huete Jimenez jump_sline = 0;
16090c7ad07eSAntonio Huete Jimenez }
16101133e27eSPeter Avalos cmd_exec();
16111133e27eSPeter Avalos jump_back(number);
16120c7ad07eSAntonio Huete Jimenez jump_sline = save_jump_sline;
16131133e27eSPeter Avalos break;
16141133e27eSPeter Avalos
16151133e27eSPeter Avalos case A_PERCENT:
16161133e27eSPeter Avalos /*
16171133e27eSPeter Avalos * Go to a specified percentage into the file.
16181133e27eSPeter Avalos */
16191133e27eSPeter Avalos if (number < 0)
16201133e27eSPeter Avalos {
16211133e27eSPeter Avalos number = 0;
16221133e27eSPeter Avalos fraction = 0;
16231133e27eSPeter Avalos }
162402d62a0fSDaniel Fojt if (number > 100 || (number == 100 && fraction != 0))
16251133e27eSPeter Avalos {
16261133e27eSPeter Avalos number = 100;
16271133e27eSPeter Avalos fraction = 0;
16281133e27eSPeter Avalos }
16291133e27eSPeter Avalos cmd_exec();
16301133e27eSPeter Avalos jump_percent((int) number, fraction);
16311133e27eSPeter Avalos break;
16321133e27eSPeter Avalos
16331133e27eSPeter Avalos case A_GOEND:
16341133e27eSPeter Avalos /*
16351133e27eSPeter Avalos * Go to line N, default end of file.
16361133e27eSPeter Avalos */
16371133e27eSPeter Avalos cmd_exec();
16381133e27eSPeter Avalos if (number <= 0)
16391133e27eSPeter Avalos jump_forw();
16401133e27eSPeter Avalos else
16411133e27eSPeter Avalos jump_back(number);
16421133e27eSPeter Avalos break;
16431133e27eSPeter Avalos
1644fa0be7c5SJohn Marino case A_GOEND_BUF:
1645fa0be7c5SJohn Marino /*
1646fa0be7c5SJohn Marino * Go to line N, default last buffered byte.
1647fa0be7c5SJohn Marino */
1648fa0be7c5SJohn Marino cmd_exec();
1649fa0be7c5SJohn Marino if (number <= 0)
1650fa0be7c5SJohn Marino jump_forw_buffered();
1651fa0be7c5SJohn Marino else
1652fa0be7c5SJohn Marino jump_back(number);
1653fa0be7c5SJohn Marino break;
1654fa0be7c5SJohn Marino
16551133e27eSPeter Avalos case A_GOPOS:
16561133e27eSPeter Avalos /*
16571133e27eSPeter Avalos * Go to a specified byte position in the file.
16581133e27eSPeter Avalos */
16591133e27eSPeter Avalos cmd_exec();
16601133e27eSPeter Avalos if (number < 0)
16611133e27eSPeter Avalos number = 0;
16621133e27eSPeter Avalos jump_line_loc((POSITION) number, jump_sline);
16631133e27eSPeter Avalos break;
16641133e27eSPeter Avalos
16651133e27eSPeter Avalos case A_STAT:
16661133e27eSPeter Avalos /*
16671133e27eSPeter Avalos * Print file name, etc.
16681133e27eSPeter Avalos */
16691133e27eSPeter Avalos if (ch_getflags() & CH_HELPFILE)
16701133e27eSPeter Avalos break;
16711133e27eSPeter Avalos cmd_exec();
16721133e27eSPeter Avalos parg.p_string = eq_message();
16731133e27eSPeter Avalos error("%s", &parg);
16741133e27eSPeter Avalos break;
16751133e27eSPeter Avalos
16761133e27eSPeter Avalos case A_VERSION:
16771133e27eSPeter Avalos /*
16780c7ad07eSAntonio Huete Jimenez * Print version number.
16791133e27eSPeter Avalos */
16801133e27eSPeter Avalos cmd_exec();
16811133e27eSPeter Avalos dispversion();
16821133e27eSPeter Avalos break;
16831133e27eSPeter Avalos
16841133e27eSPeter Avalos case A_QUIT:
16851133e27eSPeter Avalos /*
16861133e27eSPeter Avalos * Exit.
16871133e27eSPeter Avalos */
16881133e27eSPeter Avalos if (curr_ifile != NULL_IFILE &&
16891133e27eSPeter Avalos ch_getflags() & CH_HELPFILE)
16901133e27eSPeter Avalos {
16911133e27eSPeter Avalos /*
16921133e27eSPeter Avalos * Quit while viewing the help file
16931133e27eSPeter Avalos * just means return to viewing the
16941133e27eSPeter Avalos * previous file.
16951133e27eSPeter Avalos */
16961133e27eSPeter Avalos hshift = save_hshift;
1697fa0be7c5SJohn Marino bs_mode = save_bs_mode;
1698320d7c8aSAaron LI proc_backspace = save_proc_backspace;
16991133e27eSPeter Avalos if (edit_prev(1) == 0)
17001133e27eSPeter Avalos break;
17011133e27eSPeter Avalos }
17021133e27eSPeter Avalos if (extra != NULL)
17031133e27eSPeter Avalos quit(*extra);
17041133e27eSPeter Avalos quit(QUIT_OK);
17051133e27eSPeter Avalos break;
17061133e27eSPeter Avalos
17071133e27eSPeter Avalos /*
17081133e27eSPeter Avalos * Define abbreviation for a commonly used sequence below.
17091133e27eSPeter Avalos */
17101133e27eSPeter Avalos #define DO_SEARCH() \
17111133e27eSPeter Avalos if (number <= 0) number = 1; \
17121133e27eSPeter Avalos mca_search(); \
17131133e27eSPeter Avalos cmd_exec(); \
1714*e433da38SAaron LI multi_search(NULL, (int) number, 0);
17151133e27eSPeter Avalos
17161133e27eSPeter Avalos case A_F_SEARCH:
17171133e27eSPeter Avalos /*
17181133e27eSPeter Avalos * Search forward for a pattern.
17191133e27eSPeter Avalos * Get the first char of the pattern.
17201133e27eSPeter Avalos */
17210c7ad07eSAntonio Huete Jimenez search_type = SRCH_FORW | def_search_type;
17221133e27eSPeter Avalos if (number <= 0)
17231133e27eSPeter Avalos number = 1;
1724*e433da38SAaron LI literal_char = FALSE;
17251133e27eSPeter Avalos mca_search();
17261133e27eSPeter Avalos c = getcc();
17271133e27eSPeter Avalos goto again;
17281133e27eSPeter Avalos
17291133e27eSPeter Avalos case A_B_SEARCH:
17301133e27eSPeter Avalos /*
17311133e27eSPeter Avalos * Search backward for a pattern.
17321133e27eSPeter Avalos * Get the first char of the pattern.
17331133e27eSPeter Avalos */
17340c7ad07eSAntonio Huete Jimenez search_type = SRCH_BACK | def_search_type;
17351133e27eSPeter Avalos if (number <= 0)
17361133e27eSPeter Avalos number = 1;
1737*e433da38SAaron LI literal_char = FALSE;
17381133e27eSPeter Avalos mca_search();
17391133e27eSPeter Avalos c = getcc();
17401133e27eSPeter Avalos goto again;
17411133e27eSPeter Avalos
1742*e433da38SAaron LI case A_OSC8_F_SEARCH:
1743*e433da38SAaron LI #if OSC8_LINK
1744*e433da38SAaron LI cmd_exec();
1745*e433da38SAaron LI if (number <= 0)
1746*e433da38SAaron LI number = 1;
1747*e433da38SAaron LI osc8_search(SRCH_FORW, NULL, number);
1748*e433da38SAaron LI #else
1749*e433da38SAaron LI error("Command not available", NULL_PARG);
1750*e433da38SAaron LI #endif
1751*e433da38SAaron LI break;
1752*e433da38SAaron LI
1753*e433da38SAaron LI case A_OSC8_B_SEARCH:
1754*e433da38SAaron LI #if OSC8_LINK
1755*e433da38SAaron LI cmd_exec();
1756*e433da38SAaron LI if (number <= 0)
1757*e433da38SAaron LI number = 1;
1758*e433da38SAaron LI osc8_search(SRCH_BACK, NULL, number);
1759*e433da38SAaron LI #else
1760*e433da38SAaron LI error("Command not available", NULL_PARG);
1761*e433da38SAaron LI #endif
1762*e433da38SAaron LI break;
1763*e433da38SAaron LI
1764*e433da38SAaron LI case A_OSC8_OPEN:
1765*e433da38SAaron LI #if OSC8_LINK
1766*e433da38SAaron LI if (secure_allow(SF_OSC8_OPEN))
1767*e433da38SAaron LI {
1768*e433da38SAaron LI cmd_exec();
1769*e433da38SAaron LI osc8_open();
1770*e433da38SAaron LI break;
1771*e433da38SAaron LI }
1772*e433da38SAaron LI #endif
1773*e433da38SAaron LI error("Command not available", NULL_PARG);
1774*e433da38SAaron LI break;
1775*e433da38SAaron LI
1776*e433da38SAaron LI case A_OSC8_JUMP:
1777*e433da38SAaron LI #if OSC8_LINK
1778*e433da38SAaron LI cmd_exec();
1779*e433da38SAaron LI osc8_jump();
1780*e433da38SAaron LI #else
1781*e433da38SAaron LI error("Command not available", NULL_PARG);
1782*e433da38SAaron LI #endif
1783*e433da38SAaron LI break;
1784*e433da38SAaron LI
17858be36e5bSPeter Avalos case A_FILTER:
17868be36e5bSPeter Avalos #if HILITE_SEARCH
17878be36e5bSPeter Avalos search_type = SRCH_FORW | SRCH_FILTER;
1788*e433da38SAaron LI literal_char = FALSE;
17898be36e5bSPeter Avalos mca_search();
17908be36e5bSPeter Avalos c = getcc();
17918be36e5bSPeter Avalos goto again;
17928be36e5bSPeter Avalos #else
17938be36e5bSPeter Avalos error("Command not available", NULL_PARG);
17948be36e5bSPeter Avalos break;
17958be36e5bSPeter Avalos #endif
17968be36e5bSPeter Avalos
17971133e27eSPeter Avalos case A_AGAIN_SEARCH:
17981133e27eSPeter Avalos /*
17991133e27eSPeter Avalos * Repeat previous search.
18001133e27eSPeter Avalos */
1801320d7c8aSAaron LI search_type = last_search_type;
18021133e27eSPeter Avalos DO_SEARCH();
18031133e27eSPeter Avalos break;
18041133e27eSPeter Avalos
18051133e27eSPeter Avalos case A_T_AGAIN_SEARCH:
18061133e27eSPeter Avalos /*
18071133e27eSPeter Avalos * Repeat previous search, multiple files.
18081133e27eSPeter Avalos */
1809320d7c8aSAaron LI search_type = last_search_type | SRCH_PAST_EOF;
18101133e27eSPeter Avalos DO_SEARCH();
18111133e27eSPeter Avalos break;
18121133e27eSPeter Avalos
18131133e27eSPeter Avalos case A_REVERSE_SEARCH:
18141133e27eSPeter Avalos /*
18151133e27eSPeter Avalos * Repeat previous search, in reverse direction.
18161133e27eSPeter Avalos */
1817320d7c8aSAaron LI save_search_type = search_type = last_search_type;
18181133e27eSPeter Avalos search_type = SRCH_REVERSE(search_type);
18191133e27eSPeter Avalos DO_SEARCH();
1820320d7c8aSAaron LI last_search_type = save_search_type;
18211133e27eSPeter Avalos break;
18221133e27eSPeter Avalos
18231133e27eSPeter Avalos case A_T_REVERSE_SEARCH:
18241133e27eSPeter Avalos /*
18251133e27eSPeter Avalos * Repeat previous search,
18261133e27eSPeter Avalos * multiple files in reverse direction.
18271133e27eSPeter Avalos */
1828320d7c8aSAaron LI save_search_type = search_type = last_search_type;
1829320d7c8aSAaron LI search_type = SRCH_REVERSE(search_type) | SRCH_PAST_EOF;
18301133e27eSPeter Avalos DO_SEARCH();
1831320d7c8aSAaron LI last_search_type = save_search_type;
18321133e27eSPeter Avalos break;
18331133e27eSPeter Avalos
18341133e27eSPeter Avalos case A_UNDO_SEARCH:
18350c7ad07eSAntonio Huete Jimenez case A_CLR_SEARCH:
183602d62a0fSDaniel Fojt /*
183702d62a0fSDaniel Fojt * Clear search string highlighting.
183802d62a0fSDaniel Fojt */
18390c7ad07eSAntonio Huete Jimenez undo_search(action == A_CLR_SEARCH);
18401133e27eSPeter Avalos break;
18411133e27eSPeter Avalos
18421133e27eSPeter Avalos case A_HELP:
18431133e27eSPeter Avalos /*
18441133e27eSPeter Avalos * Help.
18451133e27eSPeter Avalos */
18461133e27eSPeter Avalos if (ch_getflags() & CH_HELPFILE)
18471133e27eSPeter Avalos break;
18481133e27eSPeter Avalos cmd_exec();
18491133e27eSPeter Avalos save_hshift = hshift;
18501133e27eSPeter Avalos hshift = 0;
1851fa0be7c5SJohn Marino save_bs_mode = bs_mode;
1852fa0be7c5SJohn Marino bs_mode = BS_SPECIAL;
1853320d7c8aSAaron LI save_proc_backspace = proc_backspace;
1854320d7c8aSAaron LI proc_backspace = OPT_OFF;
18551133e27eSPeter Avalos (void) edit(FAKE_HELPFILE);
18561133e27eSPeter Avalos break;
18571133e27eSPeter Avalos
18581133e27eSPeter Avalos case A_EXAMINE:
18591133e27eSPeter Avalos /*
18601133e27eSPeter Avalos * Edit a new file. Get the filename.
18611133e27eSPeter Avalos */
186202d62a0fSDaniel Fojt #if EXAMINE
1863*e433da38SAaron LI if (secure_allow(SF_EXAMINE))
18641133e27eSPeter Avalos {
18651133e27eSPeter Avalos start_mca(A_EXAMINE, "Examine: ", ml_examine, 0);
18661133e27eSPeter Avalos c = getcc();
18671133e27eSPeter Avalos goto again;
186802d62a0fSDaniel Fojt }
186902d62a0fSDaniel Fojt #endif
18701133e27eSPeter Avalos error("Command not available", NULL_PARG);
18711133e27eSPeter Avalos break;
18721133e27eSPeter Avalos
18731133e27eSPeter Avalos case A_VISUAL:
18741133e27eSPeter Avalos /*
18751133e27eSPeter Avalos * Invoke an editor on the input file.
18761133e27eSPeter Avalos */
18771133e27eSPeter Avalos #if EDITOR
1878*e433da38SAaron LI if (secure_allow(SF_EDIT))
18791133e27eSPeter Avalos {
18801133e27eSPeter Avalos if (ch_getflags() & CH_HELPFILE)
18811133e27eSPeter Avalos break;
18821133e27eSPeter Avalos if (strcmp(get_filename(curr_ifile), "-") == 0)
18831133e27eSPeter Avalos {
18841133e27eSPeter Avalos error("Cannot edit standard input", NULL_PARG);
18851133e27eSPeter Avalos break;
18861133e27eSPeter Avalos }
188702d62a0fSDaniel Fojt if (get_altfilename(curr_ifile) != NULL)
18881133e27eSPeter Avalos {
18891133e27eSPeter Avalos error("WARNING: This file was viewed via LESSOPEN",
18901133e27eSPeter Avalos NULL_PARG);
18911133e27eSPeter Avalos }
18921133e27eSPeter Avalos start_mca(A_SHELL, "!", ml_shell, 0);
18931133e27eSPeter Avalos /*
18941133e27eSPeter Avalos * Expand the editor prototype string
18951133e27eSPeter Avalos * and pass it to the system to execute.
18961133e27eSPeter Avalos * (Make sure the screen is displayed so the
18971133e27eSPeter Avalos * expansion of "+%lm" works.)
18981133e27eSPeter Avalos */
18991133e27eSPeter Avalos make_display();
19001133e27eSPeter Avalos cmd_exec();
1901*e433da38SAaron LI lsystem(pr_expand(editproto), NULL);
19021133e27eSPeter Avalos break;
190302d62a0fSDaniel Fojt }
190402d62a0fSDaniel Fojt #endif
19051133e27eSPeter Avalos error("Command not available", NULL_PARG);
19061133e27eSPeter Avalos break;
19071133e27eSPeter Avalos
19081133e27eSPeter Avalos case A_NEXT_FILE:
19091133e27eSPeter Avalos /*
19101133e27eSPeter Avalos * Examine next file.
19111133e27eSPeter Avalos */
19121133e27eSPeter Avalos #if TAGS
19131133e27eSPeter Avalos if (ntags())
19141133e27eSPeter Avalos {
19151133e27eSPeter Avalos error("No next file", NULL_PARG);
19161133e27eSPeter Avalos break;
19171133e27eSPeter Avalos }
19181133e27eSPeter Avalos #endif
19191133e27eSPeter Avalos if (number <= 0)
19201133e27eSPeter Avalos number = 1;
19211133e27eSPeter Avalos if (edit_next((int) number))
19221133e27eSPeter Avalos {
19238be36e5bSPeter Avalos if (get_quit_at_eof() && eof_displayed() &&
19241133e27eSPeter Avalos !(ch_getflags() & CH_HELPFILE))
19251133e27eSPeter Avalos quit(QUIT_OK);
19261133e27eSPeter Avalos parg.p_string = (number > 1) ? "(N-th) " : "";
19271133e27eSPeter Avalos error("No %snext file", &parg);
19281133e27eSPeter Avalos }
19291133e27eSPeter Avalos break;
19301133e27eSPeter Avalos
19311133e27eSPeter Avalos case A_PREV_FILE:
19321133e27eSPeter Avalos /*
19331133e27eSPeter Avalos * Examine previous file.
19341133e27eSPeter Avalos */
19351133e27eSPeter Avalos #if TAGS
19361133e27eSPeter Avalos if (ntags())
19371133e27eSPeter Avalos {
19381133e27eSPeter Avalos error("No previous file", NULL_PARG);
19391133e27eSPeter Avalos break;
19401133e27eSPeter Avalos }
19411133e27eSPeter Avalos #endif
19421133e27eSPeter Avalos if (number <= 0)
19431133e27eSPeter Avalos number = 1;
19441133e27eSPeter Avalos if (edit_prev((int) number))
19451133e27eSPeter Avalos {
19461133e27eSPeter Avalos parg.p_string = (number > 1) ? "(N-th) " : "";
19471133e27eSPeter Avalos error("No %sprevious file", &parg);
19481133e27eSPeter Avalos }
19491133e27eSPeter Avalos break;
19501133e27eSPeter Avalos
19511133e27eSPeter Avalos case A_NEXT_TAG:
195202d62a0fSDaniel Fojt /*
195302d62a0fSDaniel Fojt * Jump to the next tag in the current tag list.
195402d62a0fSDaniel Fojt */
19551133e27eSPeter Avalos #if TAGS
19561133e27eSPeter Avalos if (number <= 0)
19571133e27eSPeter Avalos number = 1;
19581133e27eSPeter Avalos tagfile = nexttag((int) number);
19591133e27eSPeter Avalos if (tagfile == NULL)
19601133e27eSPeter Avalos {
19611133e27eSPeter Avalos error("No next tag", NULL_PARG);
19621133e27eSPeter Avalos break;
19631133e27eSPeter Avalos }
196402d62a0fSDaniel Fojt cmd_exec();
19651133e27eSPeter Avalos if (edit(tagfile) == 0)
19661133e27eSPeter Avalos {
19671133e27eSPeter Avalos POSITION pos = tagsearch();
19681133e27eSPeter Avalos if (pos != NULL_POSITION)
19691133e27eSPeter Avalos jump_loc(pos, jump_sline);
19701133e27eSPeter Avalos }
19711133e27eSPeter Avalos #else
19721133e27eSPeter Avalos error("Command not available", NULL_PARG);
19731133e27eSPeter Avalos #endif
19741133e27eSPeter Avalos break;
19751133e27eSPeter Avalos
19761133e27eSPeter Avalos case A_PREV_TAG:
197702d62a0fSDaniel Fojt /*
197802d62a0fSDaniel Fojt * Jump to the previous tag in the current tag list.
197902d62a0fSDaniel Fojt */
19801133e27eSPeter Avalos #if TAGS
19811133e27eSPeter Avalos if (number <= 0)
19821133e27eSPeter Avalos number = 1;
19831133e27eSPeter Avalos tagfile = prevtag((int) number);
19841133e27eSPeter Avalos if (tagfile == NULL)
19851133e27eSPeter Avalos {
19861133e27eSPeter Avalos error("No previous tag", NULL_PARG);
19871133e27eSPeter Avalos break;
19881133e27eSPeter Avalos }
198902d62a0fSDaniel Fojt cmd_exec();
19901133e27eSPeter Avalos if (edit(tagfile) == 0)
19911133e27eSPeter Avalos {
19921133e27eSPeter Avalos POSITION pos = tagsearch();
19931133e27eSPeter Avalos if (pos != NULL_POSITION)
19941133e27eSPeter Avalos jump_loc(pos, jump_sline);
19951133e27eSPeter Avalos }
19961133e27eSPeter Avalos #else
19971133e27eSPeter Avalos error("Command not available", NULL_PARG);
19981133e27eSPeter Avalos #endif
19991133e27eSPeter Avalos break;
20001133e27eSPeter Avalos
20011133e27eSPeter Avalos case A_INDEX_FILE:
20021133e27eSPeter Avalos /*
20031133e27eSPeter Avalos * Examine a particular file.
20041133e27eSPeter Avalos */
20051133e27eSPeter Avalos if (number <= 0)
20061133e27eSPeter Avalos number = 1;
20071133e27eSPeter Avalos if (edit_index((int) number))
20081133e27eSPeter Avalos error("No such file", NULL_PARG);
20091133e27eSPeter Avalos break;
20101133e27eSPeter Avalos
20111133e27eSPeter Avalos case A_REMOVE_FILE:
201202d62a0fSDaniel Fojt /*
201302d62a0fSDaniel Fojt * Remove a file from the input file list.
201402d62a0fSDaniel Fojt */
20151133e27eSPeter Avalos if (ch_getflags() & CH_HELPFILE)
20161133e27eSPeter Avalos break;
20171133e27eSPeter Avalos old_ifile = curr_ifile;
20181133e27eSPeter Avalos new_ifile = getoff_ifile(curr_ifile);
20191133e27eSPeter Avalos if (new_ifile == NULL_IFILE)
20201133e27eSPeter Avalos {
20211133e27eSPeter Avalos bell();
20221133e27eSPeter Avalos break;
20231133e27eSPeter Avalos }
20241133e27eSPeter Avalos if (edit_ifile(new_ifile) != 0)
20251133e27eSPeter Avalos {
20261133e27eSPeter Avalos reedit_ifile(old_ifile);
20271133e27eSPeter Avalos break;
20281133e27eSPeter Avalos }
20291133e27eSPeter Avalos del_ifile(old_ifile);
20301133e27eSPeter Avalos break;
20311133e27eSPeter Avalos
20321133e27eSPeter Avalos case A_OPT_TOGGLE:
203302d62a0fSDaniel Fojt /*
203402d62a0fSDaniel Fojt * Change the setting of an option.
203502d62a0fSDaniel Fojt */
20361133e27eSPeter Avalos optflag = OPT_TOGGLE;
20371133e27eSPeter Avalos optgetname = FALSE;
20381133e27eSPeter Avalos mca_opt_toggle();
20391133e27eSPeter Avalos c = getcc();
2040*e433da38SAaron LI msg = opt_toggle_disallowed(c);
2041*e433da38SAaron LI if (msg != NULL)
20420c7ad07eSAntonio Huete Jimenez {
2043*e433da38SAaron LI error(msg, NULL_PARG);
20440c7ad07eSAntonio Huete Jimenez break;
20450c7ad07eSAntonio Huete Jimenez }
20461133e27eSPeter Avalos goto again;
20471133e27eSPeter Avalos
20481133e27eSPeter Avalos case A_DISP_OPTION:
20491133e27eSPeter Avalos /*
205002d62a0fSDaniel Fojt * Report the setting of an option.
20511133e27eSPeter Avalos */
20521133e27eSPeter Avalos optflag = OPT_NO_TOGGLE;
20531133e27eSPeter Avalos optgetname = FALSE;
20541133e27eSPeter Avalos mca_opt_toggle();
20551133e27eSPeter Avalos c = getcc();
20561133e27eSPeter Avalos goto again;
20571133e27eSPeter Avalos
20581133e27eSPeter Avalos case A_FIRSTCMD:
20591133e27eSPeter Avalos /*
20601133e27eSPeter Avalos * Set an initial command for new files.
20611133e27eSPeter Avalos */
2062*e433da38SAaron LI start_mca(A_FIRSTCMD, "+", NULL, 0);
20631133e27eSPeter Avalos c = getcc();
20641133e27eSPeter Avalos goto again;
20651133e27eSPeter Avalos
20661133e27eSPeter Avalos case A_SHELL:
2067320d7c8aSAaron LI case A_PSHELL:
20681133e27eSPeter Avalos /*
20691133e27eSPeter Avalos * Shell escape.
20701133e27eSPeter Avalos */
20711133e27eSPeter Avalos #if SHELL_ESCAPE
2072*e433da38SAaron LI if (secure_allow(SF_SHELL))
20731133e27eSPeter Avalos {
2074320d7c8aSAaron LI start_mca(action, (action == A_SHELL) ? "!" : "#", ml_shell, 0);
20751133e27eSPeter Avalos c = getcc();
20761133e27eSPeter Avalos goto again;
207702d62a0fSDaniel Fojt }
207802d62a0fSDaniel Fojt #endif
20791133e27eSPeter Avalos error("Command not available", NULL_PARG);
20801133e27eSPeter Avalos break;
20811133e27eSPeter Avalos
20821133e27eSPeter Avalos case A_SETMARK:
208302d62a0fSDaniel Fojt case A_SETMARKBOT:
20841133e27eSPeter Avalos /*
20851133e27eSPeter Avalos * Set a mark.
20861133e27eSPeter Avalos */
20871133e27eSPeter Avalos if (ch_getflags() & CH_HELPFILE)
20881133e27eSPeter Avalos break;
2089*e433da38SAaron LI start_mca(A_SETMARK, "set mark: ", NULL, 0);
20901133e27eSPeter Avalos c = getcc();
209102d62a0fSDaniel Fojt if (is_erase_char(c) || is_newline_char(c))
20921133e27eSPeter Avalos break;
209302d62a0fSDaniel Fojt setmark(c, action == A_SETMARKBOT ? BOTTOM : TOP);
209402d62a0fSDaniel Fojt repaint();
209502d62a0fSDaniel Fojt break;
209602d62a0fSDaniel Fojt
209702d62a0fSDaniel Fojt case A_CLRMARK:
209802d62a0fSDaniel Fojt /*
209902d62a0fSDaniel Fojt * Clear a mark.
210002d62a0fSDaniel Fojt */
2101*e433da38SAaron LI start_mca(A_CLRMARK, "clear mark: ", NULL, 0);
210202d62a0fSDaniel Fojt c = getcc();
210302d62a0fSDaniel Fojt if (is_erase_char(c) || is_newline_char(c))
210402d62a0fSDaniel Fojt break;
210502d62a0fSDaniel Fojt clrmark(c);
210602d62a0fSDaniel Fojt repaint();
21071133e27eSPeter Avalos break;
21081133e27eSPeter Avalos
21091133e27eSPeter Avalos case A_GOMARK:
21101133e27eSPeter Avalos /*
211102d62a0fSDaniel Fojt * Jump to a marked position.
21121133e27eSPeter Avalos */
2113*e433da38SAaron LI start_mca(A_GOMARK, "goto mark: ", NULL, 0);
21141133e27eSPeter Avalos c = getcc();
211502d62a0fSDaniel Fojt if (is_erase_char(c) || is_newline_char(c))
21161133e27eSPeter Avalos break;
21171133e27eSPeter Avalos cmd_exec();
21181133e27eSPeter Avalos gomark(c);
21191133e27eSPeter Avalos break;
21201133e27eSPeter Avalos
21211133e27eSPeter Avalos case A_PIPE:
212202d62a0fSDaniel Fojt /*
212302d62a0fSDaniel Fojt * Write part of the input to a pipe to a shell command.
212402d62a0fSDaniel Fojt */
21251133e27eSPeter Avalos #if PIPEC
2126*e433da38SAaron LI if (secure_allow(SF_PIPE))
21271133e27eSPeter Avalos {
2128*e433da38SAaron LI start_mca(A_PIPE, "|mark: ", NULL, 0);
21291133e27eSPeter Avalos c = getcc();
213002d62a0fSDaniel Fojt if (is_erase_char(c))
21311133e27eSPeter Avalos break;
213202d62a0fSDaniel Fojt if (is_newline_char(c))
21331133e27eSPeter Avalos c = '.';
21341133e27eSPeter Avalos if (badmark(c))
21351133e27eSPeter Avalos break;
21361133e27eSPeter Avalos pipec = c;
21371133e27eSPeter Avalos start_mca(A_PIPE, "!", ml_shell, 0);
21381133e27eSPeter Avalos c = getcc();
21391133e27eSPeter Avalos goto again;
214002d62a0fSDaniel Fojt }
214102d62a0fSDaniel Fojt #endif
21421133e27eSPeter Avalos error("Command not available", NULL_PARG);
21431133e27eSPeter Avalos break;
21441133e27eSPeter Avalos
21451133e27eSPeter Avalos case A_B_BRACKET:
21461133e27eSPeter Avalos case A_F_BRACKET:
2147*e433da38SAaron LI start_mca(action, "Brackets: ", NULL, 0);
21481133e27eSPeter Avalos c = getcc();
21491133e27eSPeter Avalos goto again;
21501133e27eSPeter Avalos
21511133e27eSPeter Avalos case A_LSHIFT:
215202d62a0fSDaniel Fojt /*
215302d62a0fSDaniel Fojt * Shift view left.
215402d62a0fSDaniel Fojt */
21551133e27eSPeter Avalos if (number > 0)
2156*e433da38SAaron LI shift_count = (int) number;
21571133e27eSPeter Avalos else
2158*e433da38SAaron LI number = (shift_count > 0) ? shift_count : sc_width / 2;
21591133e27eSPeter Avalos if (number > hshift)
21601133e27eSPeter Avalos number = hshift;
2161*e433da38SAaron LI pos_rehead();
2162*e433da38SAaron LI hshift -= (int) number;
2163*e433da38SAaron LI screen_trashed();
21641133e27eSPeter Avalos break;
21651133e27eSPeter Avalos
21661133e27eSPeter Avalos case A_RSHIFT:
216702d62a0fSDaniel Fojt /*
216802d62a0fSDaniel Fojt * Shift view right.
216902d62a0fSDaniel Fojt */
21701133e27eSPeter Avalos if (number > 0)
2171*e433da38SAaron LI shift_count = (int) number;
21721133e27eSPeter Avalos else
2173*e433da38SAaron LI number = (shift_count > 0) ? shift_count : sc_width / 2;
2174*e433da38SAaron LI pos_rehead();
2175*e433da38SAaron LI hshift += (int) number;
2176*e433da38SAaron LI screen_trashed();
21771133e27eSPeter Avalos break;
21781133e27eSPeter Avalos
217902d62a0fSDaniel Fojt case A_LLSHIFT:
218002d62a0fSDaniel Fojt /*
218102d62a0fSDaniel Fojt * Shift view left to margin.
218202d62a0fSDaniel Fojt */
2183*e433da38SAaron LI pos_rehead();
218402d62a0fSDaniel Fojt hshift = 0;
2185*e433da38SAaron LI screen_trashed();
218602d62a0fSDaniel Fojt break;
218702d62a0fSDaniel Fojt
218802d62a0fSDaniel Fojt case A_RRSHIFT:
218902d62a0fSDaniel Fojt /*
219002d62a0fSDaniel Fojt * Shift view right to view rightmost char on screen.
219102d62a0fSDaniel Fojt */
2192*e433da38SAaron LI pos_rehead();
219302d62a0fSDaniel Fojt hshift = rrshift();
2194*e433da38SAaron LI screen_trashed();
219502d62a0fSDaniel Fojt break;
219602d62a0fSDaniel Fojt
21971133e27eSPeter Avalos case A_PREFIX:
21981133e27eSPeter Avalos /*
21991133e27eSPeter Avalos * The command is incomplete (more chars are needed).
22001133e27eSPeter Avalos * Display the current char, so the user knows
22011133e27eSPeter Avalos * what's going on, and get another character.
22021133e27eSPeter Avalos */
22031133e27eSPeter Avalos if (mca != A_PREFIX)
22041133e27eSPeter Avalos {
22051133e27eSPeter Avalos cmd_reset();
2206*e433da38SAaron LI start_mca(A_PREFIX, " ", NULL, CF_QUIT_ON_ERASE);
22071133e27eSPeter Avalos (void) cmd_char(c);
22081133e27eSPeter Avalos }
22091133e27eSPeter Avalos c = getcc();
22101133e27eSPeter Avalos goto again;
22111133e27eSPeter Avalos
22121133e27eSPeter Avalos case A_NOACTION:
22131133e27eSPeter Avalos break;
22141133e27eSPeter Avalos
22151133e27eSPeter Avalos default:
22161133e27eSPeter Avalos bell();
22171133e27eSPeter Avalos break;
22181133e27eSPeter Avalos }
22191133e27eSPeter Avalos }
22201133e27eSPeter Avalos }
2221