git: d713e0891ff9 - main - MFV: less v632.
- Reply: John Baldwin : "Re: git: d713e0891ff9 - main - MFV: less v632."
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 02 May 2023 03:45:11 UTC
The branch main has been updated by delphij:
URL: https://cgit.FreeBSD.org/src/commit/?id=d713e0891ff9ab8246245c3206851d486ecfdd37
commit d713e0891ff9ab8246245c3206851d486ecfdd37
Merge: 83d5725005c5 159d764c1668
Author: Xin LI <delphij@FreeBSD.org>
AuthorDate: 2023-05-02 03:43:57 +0000
Commit: Xin LI <delphij@FreeBSD.org>
CommitDate: 2023-05-02 03:43:57 +0000
MFV: less v632.
MFC after: 2 weeks
contrib/less/LICENSE | 2 +-
contrib/less/NEWS | 79 ++++-
contrib/less/brac.c | 9 +-
contrib/less/ch.c | 321 ++++++++-----------
contrib/less/charset.c | 234 +++++++++-----
contrib/less/charset.h | 2 +-
contrib/less/cmd.h | 3 +-
contrib/less/cmdbuf.c | 211 +++---------
contrib/less/command.c | 200 ++++++------
contrib/less/compose.uni | 14 +-
contrib/less/cvt.c | 19 +-
contrib/less/decode.c | 144 ++-------
contrib/less/edit.c | 357 +++++++++++++++------
contrib/less/filename.c | 137 ++++----
contrib/less/fmt.uni | 4 +-
contrib/less/forwback.c | 64 +---
contrib/less/funcs.h | 748 ++++++++++++++++++++++---------------------
contrib/less/help.c | 46 ++-
contrib/less/ifile.c | 118 ++-----
contrib/less/input.c | 203 +++++++++---
contrib/less/jump.c | 37 +--
contrib/less/less.h | 89 +++--
contrib/less/less.hlp | 44 ++-
contrib/less/less.nro | 677 ++++++++++++++++++++++++++-------------
contrib/less/lessecho.c | 44 +--
contrib/less/lessecho.nro | 38 +--
contrib/less/lesskey.c | 66 ++--
contrib/less/lesskey.h | 2 +-
contrib/less/lesskey.nro | 62 ++--
contrib/less/lesskey_parse.c | 111 ++-----
contrib/less/lglob.h | 2 +-
contrib/less/line.c | 467 ++++++++++++---------------
contrib/less/linenum.c | 53 ++-
contrib/less/lsystem.c | 18 +-
contrib/less/main.c | 54 ++--
contrib/less/mark.c | 84 ++---
contrib/less/mkutable | 15 +-
contrib/less/optfunc.c | 314 ++++++++----------
contrib/less/option.c | 105 ++----
contrib/less/option.h | 4 +-
contrib/less/opttbl.c | 116 +++++--
contrib/less/os.c | 231 +++++++------
contrib/less/output.c | 135 ++++----
contrib/less/pattern.c | 176 +++++-----
contrib/less/pattern.h | 10 +-
contrib/less/pckeys.h | 2 +-
contrib/less/position.c | 41 +--
contrib/less/position.h | 2 +-
contrib/less/prompt.c | 78 ++---
contrib/less/screen.c | 562 +++++++++++++++-----------------
contrib/less/scrsize.c | 2 +-
contrib/less/search.c | 370 ++++++++-------------
contrib/less/signal.c | 29 +-
contrib/less/tags.c | 87 ++---
contrib/less/ttyin.c | 52 +--
contrib/less/ubin.uni | 16 +-
contrib/less/version.c | 31 +-
contrib/less/wide.uni | 22 +-
contrib/less/xbuf.c | 150 +++++++--
contrib/less/xbuf.h | 7 +-
usr.bin/less/defines.h | 24 +-
61 files changed, 3721 insertions(+), 3623 deletions(-)
diff --cc contrib/less/command.c
index 8bd999e9f7a3,000000000000..88c0cb49ee77
mode 100644,000000..100644
--- a/contrib/less/command.c
+++ b/contrib/less/command.c
@@@ -1,2099 -1,0 +1,2095 @@@
+/* $FreeBSD$ */
+/*
- * Copyright (C) 1984-2022 Mark Nudelman
++ * Copyright (C) 1984-2023 Mark Nudelman
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Less License, as specified in the README file.
+ *
+ * For more information, see the README file.
+ */
+
+
+/*
+ * User-level command processor.
+ */
+
+#include "less.h"
+#if MSDOS_COMPILER==WIN32C
+#include <windows.h>
+#endif
+#include "position.h"
+#include "option.h"
+#include "cmd.h"
+
+extern int erase_char, erase2_char, kill_char;
+extern int sigs;
+extern int quit_if_one_screen;
++extern int one_screen;
+extern int squished;
+extern int sc_width;
+extern int sc_height;
+extern char *kent;
+extern int swindow;
+extern int jump_sline;
+extern int quitting;
+extern int wscroll;
+extern int top_scroll;
+extern int ignore_eoi;
+extern int secure;
+extern int hshift;
+extern int bs_mode;
++extern int proc_backspace;
+extern int show_attn;
+extern int less_is_more;
+extern int status_col;
+extern POSITION highest_hilite;
+extern POSITION start_attnpos;
+extern POSITION end_attnpos;
+extern char *every_first_cmd;
+extern char version[];
+extern struct scrpos initial_scrpos;
+extern IFILE curr_ifile;
+extern void *ml_search;
+extern void *ml_examine;
+extern int wheel_lines;
+extern int header_lines;
+extern int def_search_type;
+extern int updown_match;
+#if SHELL_ESCAPE || PIPEC
+extern void *ml_shell;
+#endif
+#if EDITOR
+extern char *editor;
+extern char *editproto;
+#endif
+extern int screen_trashed; /* The screen has been overwritten */
+extern int shift_count;
+extern int oldbot;
+extern int forw_prompt;
+extern int incr_search;
++extern int full_screen;
+#if MSDOS_COMPILER==WIN32C
+extern int utf_mode;
+#endif
+
+#if SHELL_ESCAPE
+static char *shellcmd = NULL; /* For holding last shell command for "!!" */
+#endif
+static int mca; /* The multicharacter command (action) */
+static int search_type; /* The previous type of search */
++static int last_search_type; /* Type of last executed search */
+static LINENUM number; /* The number typed by the user */
+static long fraction; /* The fractional part of the number */
+static struct loption *curropt;
+static int opt_lower;
+static int optflag;
+static int optgetname;
+static POSITION bottompos;
+static int save_hshift;
+static int save_bs_mode;
++static int save_proc_backspace;
+#if PIPEC
+static char pipec;
+#endif
+
+/* Stack of ungotten chars (via ungetcc) */
+struct ungot {
+ struct ungot *ug_next;
+ LWCHAR ug_char;
+};
+static struct ungot* ungot = NULL;
+
- static void multi_search LESSPARAMS((char *pattern, int n, int silent));
++static void multi_search (char *pattern, int n, int silent);
+
+/*
+ * Move the cursor to start of prompt line before executing a command.
+ * This looks nicer if the command takes a long time before
+ * updating the screen.
+ */
- static void
- cmd_exec(VOID_PARAM)
++static void cmd_exec(void)
+{
+ clear_attn();
+ clear_bot();
+ flush();
+}
+
+/*
+ * Indicate we are reading a multi-character command.
+ */
- static void
- set_mca(action)
- int action;
++static void set_mca(int action)
+{
+ mca = action;
+ clear_bot();
+ clear_cmd();
+}
+
+/*
+ * Indicate we are not reading a multi-character command.
+ */
- static void
- clear_mca(VOID_PARAM)
++static void clear_mca(void)
+{
+ if (mca == 0)
+ return;
+ mca = 0;
+}
+
+/*
+ * Set up the display to start a new multi-character command.
+ */
- static void
- start_mca(action, prompt, mlist, cmdflags)
- int action;
- constant char *prompt;
- void *mlist;
- int cmdflags;
++static void start_mca(int action, constant char *prompt, void *mlist, int cmdflags)
+{
+ set_mca(action);
+ cmd_putstr(prompt);
+ set_mlist(mlist, cmdflags);
+}
+
- public int
- in_mca(VOID_PARAM)
++public int in_mca(void)
+{
+ return (mca != 0 && mca != A_PREFIX);
+}
+
+/*
+ * Set up the display to start a new search command.
+ */
- static void
- mca_search1(VOID_PARAM)
++static void mca_search1(void)
+{
++ int i;
++
+#if HILITE_SEARCH
+ if (search_type & SRCH_FILTER)
+ set_mca(A_FILTER);
+ else
+#endif
+ if (search_type & SRCH_FORW)
+ set_mca(A_F_SEARCH);
+ else
+ set_mca(A_B_SEARCH);
+
+ if (search_type & SRCH_NO_MATCH)
+ cmd_putstr("Non-match ");
+ if (search_type & SRCH_FIRST_FILE)
+ cmd_putstr("First-file ");
+ if (search_type & SRCH_PAST_EOF)
+ cmd_putstr("EOF-ignore ");
+ if (search_type & SRCH_NO_MOVE)
+ cmd_putstr("Keep-pos ");
+ if (search_type & SRCH_NO_REGEX)
+ cmd_putstr("Regex-off ");
+ if (search_type & SRCH_WRAP)
+ cmd_putstr("Wrap ");
++ for (i = 1; i <= NUM_SEARCH_COLORS; i++)
++ {
++ if (search_type & SRCH_SUBSEARCH(i))
++ {
++ char buf[8];
++ SNPRINTF1(buf, sizeof(buf), "Sub-%d ", i);
++ cmd_putstr(buf);
++ }
++ }
+
+#if HILITE_SEARCH
+ if (search_type & SRCH_FILTER)
+ cmd_putstr("&/");
+ else
+#endif
+ if (search_type & SRCH_FORW)
+ cmd_putstr("/");
+ else
+ cmd_putstr("?");
+ forw_prompt = 0;
+}
+
- static void
- mca_search(VOID_PARAM)
++static void mca_search(void)
+{
+ mca_search1();
+ set_mlist(ml_search, 0);
+}
+
+/*
+ * Set up the display to start a new toggle-option command.
+ */
- static void
- mca_opt_toggle(VOID_PARAM)
++static void mca_opt_toggle(void)
+{
+ int no_prompt;
+ int flag;
+ char *dash;
+
+ no_prompt = (optflag & OPT_NO_PROMPT);
+ flag = (optflag & ~OPT_NO_PROMPT);
+ dash = (flag == OPT_NO_TOGGLE) ? "_" : "-";
+
+ set_mca(A_OPT_TOGGLE);
+ cmd_putstr(dash);
+ if (optgetname)
+ cmd_putstr(dash);
+ if (no_prompt)
+ cmd_putstr("(P)");
+ switch (flag)
+ {
+ case OPT_UNSET:
+ cmd_putstr("+");
+ break;
+ case OPT_SET:
+ cmd_putstr("!");
+ break;
+ }
+ forw_prompt = 0;
+ set_mlist(NULL, 0);
+}
+
+/*
+ * Execute a multicharacter command.
+ */
- static void
- exec_mca(VOID_PARAM)
++static void exec_mca(void)
+{
+ char *cbuf;
+
+ cmd_exec();
+ cbuf = get_cmdbuf();
+ if (cbuf == NULL)
+ return;
+
+ switch (mca)
+ {
+ case A_F_SEARCH:
+ case A_B_SEARCH:
+ multi_search(cbuf, (int) number, 0);
+ break;
+#if HILITE_SEARCH
+ case A_FILTER:
+ search_type ^= SRCH_NO_MATCH;
+ set_filter_pattern(cbuf, search_type);
+ break;
+#endif
+ case A_FIRSTCMD:
+ /*
+ * Skip leading spaces or + signs in the string.
+ */
+ while (*cbuf == '+' || *cbuf == ' ')
+ cbuf++;
+ if (every_first_cmd != NULL)
+ free(every_first_cmd);
+ if (*cbuf == '\0')
+ every_first_cmd = NULL;
+ else
+ every_first_cmd = save(cbuf);
+ break;
+ case A_OPT_TOGGLE:
+ toggle_option(curropt, opt_lower, cbuf, optflag);
+ curropt = NULL;
+ break;
+ case A_F_BRACKET:
+ match_brac(cbuf[0], cbuf[1], 1, (int) number);
+ break;
+ case A_B_BRACKET:
+ match_brac(cbuf[1], cbuf[0], 0, (int) number);
+ break;
+#if EXAMINE
+ case A_EXAMINE:
+ if (secure)
+ break;
+ edit_list(cbuf);
+#if TAGS
+ /* If tag structure is loaded then clean it up. */
+ cleantags();
+#endif
+ break;
+#endif
+#if SHELL_ESCAPE
+ case A_SHELL:
+ /*
+ * !! just uses whatever is in shellcmd.
+ * Otherwise, copy cmdbuf to shellcmd,
+ * expanding any special characters ("%" or "#").
+ */
+ if (*cbuf != '!')
+ {
+ if (shellcmd != NULL)
+ free(shellcmd);
+ shellcmd = fexpand(cbuf);
+ }
+
+ if (secure)
+ break;
+ if (shellcmd == NULL)
+ lsystem("", "!done");
+ else
+ lsystem(shellcmd, "!done");
+ break;
++ case A_PSHELL:
++ if (secure)
++ break;
++ lsystem(pr_expand(cbuf), "#done");
++ break;
+#endif
+#if PIPEC
+ case A_PIPE:
+ if (secure)
+ break;
+ (void) pipe_mark(pipec, cbuf);
+ error("|done", NULL_PARG);
+ break;
+#endif
+ }
+}
+
+/*
+ * Is a character an erase or kill char?
+ */
- static int
- is_erase_char(c)
- int c;
++static int is_erase_char(int c)
+{
+ return (c == erase_char || c == erase2_char || c == kill_char);
+}
+
+/*
+ * Is a character a carriage return or newline?
+ */
- static int
- is_newline_char(c)
- int c;
++static int is_newline_char(int c)
+{
+ return (c == '\n' || c == '\r');
+}
+
+/*
+ * Handle the first char of an option (after the initial dash).
+ */
- static int
- mca_opt_first_char(c)
- int c;
++static int mca_opt_first_char(int c)
+{
+ int no_prompt = (optflag & OPT_NO_PROMPT);
+ int flag = (optflag & ~OPT_NO_PROMPT);
+ if (flag == OPT_NO_TOGGLE)
+ {
+ switch (c)
+ {
+ case '_':
+ /* "__" = long option name. */
+ optgetname = TRUE;
+ mca_opt_toggle();
+ return (MCA_MORE);
+ }
+ } else
+ {
+ switch (c)
+ {
+ case '+':
+ /* "-+" = UNSET. */
+ optflag = no_prompt | ((flag == OPT_UNSET) ?
+ OPT_TOGGLE : OPT_UNSET);
+ mca_opt_toggle();
+ return (MCA_MORE);
+ case '!':
+ /* "-!" = SET */
+ optflag = no_prompt | ((flag == OPT_SET) ?
+ OPT_TOGGLE : OPT_SET);
+ mca_opt_toggle();
+ return (MCA_MORE);
+ case CONTROL('P'):
+ optflag ^= OPT_NO_PROMPT;
+ mca_opt_toggle();
+ return (MCA_MORE);
+ case '-':
+ /* "--" = long option name. */
+ optgetname = TRUE;
+ mca_opt_toggle();
+ return (MCA_MORE);
+ }
+ }
+ /* Char was not handled here. */
+ return (NO_MCA);
+}
+
+/*
+ * Add a char to a long option name.
+ * See if we've got a match for an option name yet.
+ * If so, display the complete name and stop
+ * accepting chars until user hits RETURN.
+ */
- static int
- mca_opt_nonfirst_char(c)
- int c;
++static int mca_opt_nonfirst_char(int c)
+{
+ char *p;
+ char *oname;
+ int err;
+
+ if (curropt != NULL)
+ {
+ /*
+ * Already have a match for the name.
+ * Don't accept anything but erase/kill.
+ */
+ if (is_erase_char(c))
+ return (MCA_DONE);
+ return (MCA_MORE);
+ }
+ /*
+ * Add char to cmd buffer and try to match
+ * the option name.
+ */
+ if (cmd_char(c) == CC_QUIT)
+ return (MCA_DONE);
+ p = get_cmdbuf();
+ if (p == NULL)
+ return (MCA_MORE);
+ opt_lower = ASCII_IS_LOWER(p[0]);
+ err = 0;
+ curropt = findopt_name(&p, &oname, &err);
+ if (curropt != NULL)
+ {
+ /*
+ * Got a match.
+ * Remember the option and
+ * display the full option name.
+ */
+ cmd_reset();
+ mca_opt_toggle();
+ for (p = oname; *p != '\0'; p++)
+ {
+ c = *p;
+ if (!opt_lower && ASCII_IS_LOWER(c))
+ c = ASCII_TO_UPPER(c);
+ if (cmd_char(c) != CC_OK)
+ return (MCA_DONE);
+ }
+ } else if (err != OPT_AMBIG)
+ {
+ bell();
+ }
+ return (MCA_MORE);
+}
+
+/*
+ * Handle a char of an option toggle command.
+ */
- static int
- mca_opt_char(c)
- int c;
++static int mca_opt_char(int c)
+{
+ PARG parg;
+
+ /*
+ * This may be a short option (single char),
+ * or one char of a long option name,
+ * or one char of the option parameter.
+ */
+ if (curropt == NULL && len_cmdbuf() == 0)
+ {
+ int ret = mca_opt_first_char(c);
+ if (ret != NO_MCA)
+ return (ret);
+ }
+ if (optgetname)
+ {
+ /* We're getting a long option name. */
+ if (!is_newline_char(c) && c != '=')
+ return (mca_opt_nonfirst_char(c));
+ if (curropt == NULL)
+ {
+ parg.p_string = get_cmdbuf();
+ if (parg.p_string == NULL)
+ return (MCA_MORE);
+ error("There is no --%s option", &parg);
+ return (MCA_DONE);
+ }
+ optgetname = FALSE;
+ cmd_reset();
+ } else
+ {
+ if (is_erase_char(c))
+ return (NO_MCA);
+ if (curropt != NULL)
+ /* We're getting the option parameter. */
+ return (NO_MCA);
+ curropt = findopt(c);
+ if (curropt == NULL)
+ {
+ parg.p_string = propt(c);
+ error("There is no %s option", &parg);
+ return (MCA_DONE);
+ }
+ opt_lower = ASCII_IS_LOWER(c);
+ }
+ /*
+ * If the option which was entered does not take a
+ * parameter, toggle the option immediately,
+ * so user doesn't have to hit RETURN.
+ */
+ if ((optflag & ~OPT_NO_PROMPT) != OPT_TOGGLE ||
+ !opt_has_param(curropt))
+ {
+ toggle_option(curropt, opt_lower, "", optflag);
+ return (MCA_DONE);
+ }
+ /*
+ * Display a prompt appropriate for the option parameter.
+ */
+ start_mca(A_OPT_TOGGLE, opt_prompt(curropt), (void*)NULL, 0);
+ return (MCA_MORE);
+}
+
+/*
+ * Normalize search type.
+ */
- public int
- norm_search_type(st)
- int st;
++public int norm_search_type(int st)
+{
+ /* WRAP and PAST_EOF are mutually exclusive. */
+ if ((st & (SRCH_PAST_EOF|SRCH_WRAP)) == (SRCH_PAST_EOF|SRCH_WRAP))
+ st ^= SRCH_PAST_EOF;
+ return st;
+}
+
+/*
+ * Handle a char of a search command.
+ */
- static int
- mca_search_char(c)
- int c;
++static int mca_search_char(int c)
+{
+ int flag = 0;
+
+ /*
+ * Certain characters as the first char of
+ * the pattern have special meaning:
+ * ! Toggle the NO_MATCH flag
+ * * Toggle the PAST_EOF flag
+ * @ Toggle the FIRST_FILE flag
+ */
+ if (len_cmdbuf() > 0)
+ return (NO_MCA);
+
+ switch (c)
+ {
+ case '*':
+ if (less_is_more)
+ break;
+ case CONTROL('E'): /* ignore END of file */
+ if (mca != A_FILTER)
+ flag = SRCH_PAST_EOF;
+ break;
+ case '@':
+ if (less_is_more)
+ break;
+ case CONTROL('F'): /* FIRST file */
+ if (mca != A_FILTER)
+ flag = SRCH_FIRST_FILE;
+ break;
+ case CONTROL('K'): /* KEEP position */
+ if (mca != A_FILTER)
+ flag = SRCH_NO_MOVE;
+ break;
++ case CONTROL('S'): { /* SUBSEARCH */
++ char buf[32];
++ SNPRINTF1(buf, sizeof(buf), "Sub-pattern (1-%d):", NUM_SEARCH_COLORS);
++ clear_bot();
++ cmd_putstr(buf);
++ flush();
++ c = getcc();
++ if (c >= '1' && c <= '0'+NUM_SEARCH_COLORS)
++ flag = SRCH_SUBSEARCH(c-'0');
++ else
++ flag = -1; /* calls mca_search() below to repaint */
++ break; }
+ case CONTROL('W'): /* WRAP around */
+ if (mca != A_FILTER)
+ flag = SRCH_WRAP;
+ break;
+ case CONTROL('R'): /* Don't use REGULAR EXPRESSIONS */
+ flag = SRCH_NO_REGEX;
+ break;
+ case CONTROL('N'): /* NOT match */
+ case '!':
+ flag = SRCH_NO_MATCH;
+ break;
+ }
+
+ if (flag != 0)
+ {
- search_type = norm_search_type(search_type ^ flag);
++ if (flag != -1)
++ search_type = norm_search_type(search_type ^ flag);
+ mca_search();
+ return (MCA_MORE);
+ }
+ return (NO_MCA);
+}
+
+/*
+ * Handle a character of a multi-character command.
+ */
- static int
- mca_char(c)
- int c;
++static int mca_char(int c)
+{
+ int ret;
+
+ switch (mca)
+ {
+ case 0:
+ /*
+ * We're not in a multicharacter command.
+ */
+ return (NO_MCA);
+
+ case A_PREFIX:
+ /*
+ * In the prefix of a command.
+ * This not considered a multichar command
+ * (even tho it uses cmdbuf, etc.).
+ * It is handled in the commands() switch.
+ */
+ return (NO_MCA);
+
+ case A_DIGIT:
+ /*
+ * Entering digits of a number.
+ * Terminated by a non-digit.
+ */
+ if ((c >= '0' && c <= '9') || c == '.')
+ break;
+ switch (editchar(c, ECF_PEEK|ECF_NOHISTORY|ECF_NOCOMPLETE|ECF_NORIGHTLEFT))
+ {
+ case A_NOACTION:
+ /*
+ * Ignore this char and get another one.
+ */
+ return (MCA_MORE);
+ case A_INVALID:
+ /*
+ * Not part of the number.
+ * End the number and treat this char
+ * as a normal command character.
+ */
+ number = cmd_int(&fraction);
+ clear_mca();
+ cmd_accept();
+ return (NO_MCA);
+ }
+ break;
+
+ case A_OPT_TOGGLE:
+ ret = mca_opt_char(c);
+ if (ret != NO_MCA)
+ return (ret);
+ break;
+
+ case A_F_SEARCH:
+ case A_B_SEARCH:
+ case A_FILTER:
+ ret = mca_search_char(c);
+ if (ret != NO_MCA)
+ return (ret);
+ break;
+
+ default:
+ /* Other multicharacter command. */
+ break;
+ }
+
+ /*
+ * The multichar command is terminated by a newline.
+ */
+ if (is_newline_char(c))
+ {
+ /*
+ * Execute the command.
+ */
+ exec_mca();
+ return (MCA_DONE);
+ }
+
+ /*
+ * Append the char to the command buffer.
+ */
+ if (cmd_char(c) == CC_QUIT)
+ /*
+ * Abort the multi-char command.
+ */
+ return (MCA_DONE);
+
+ switch (mca)
+ {
+ case A_F_BRACKET:
+ case A_B_BRACKET:
+ if (len_cmdbuf() >= 2)
+ {
+ /*
+ * Special case for the bracket-matching commands.
+ * Execute the command after getting exactly two
+ * characters from the user.
+ */
+ exec_mca();
+ return (MCA_DONE);
+ }
+ break;
+ case A_F_SEARCH:
+ case A_B_SEARCH:
+ if (incr_search)
+ {
+ /* Incremental search: do a search after every input char. */
- int st = (search_type & (SRCH_FORW|SRCH_BACK|SRCH_NO_MATCH|SRCH_NO_REGEX|SRCH_NO_MOVE|SRCH_WRAP));
++ int st = (search_type & (SRCH_FORW|SRCH_BACK|SRCH_NO_MATCH|SRCH_NO_REGEX|SRCH_NO_MOVE|SRCH_WRAP|SRCH_SUBSEARCH_ALL));
+ char *pattern = get_cmdbuf();
+ if (pattern == NULL)
+ return (MCA_MORE);
+ /*
+ * Must save updown_match because mca_search
+ * reinits it. That breaks history scrolling.
+ * {{ This is ugly. mca_search probably shouldn't call set_mlist. }}
+ */
+ int save_updown_match = updown_match;
+ cmd_exec();
+ if (*pattern == '\0')
+ {
+ /* User has backspaced to an empty pattern. */
+ undo_search(1);
+ } else
+ {
+ if (search(st | SRCH_INCR, pattern, 1) != 0)
+ /* No match, invalid pattern, etc. */
+ undo_search(1);
+ }
+ /* Redraw the search prompt and search string. */
++ if (!full_screen)
++ {
++ clear();
++ repaint();
++ }
+ mca_search1();
+ updown_match = save_updown_match;
+ cmd_repaint(NULL);
+ }
+ break;
+ }
+
+ /*
+ * Need another character.
+ */
+ return (MCA_MORE);
+}
+
+/*
+ * Discard any buffered file data.
+ */
- static void
- clear_buffers(VOID_PARAM)
++static void clear_buffers(void)
+{
+ if (!(ch_getflags() & CH_CANSEEK))
+ return;
+ ch_flush();
+ clr_linenum();
+#if HILITE_SEARCH
+ clr_hilite();
+#endif
+}
+
+/*
+ * Make sure the screen is displayed.
+ */
- static void
- make_display(VOID_PARAM)
++static void make_display(void)
+{
++ /*
++ * If not full_screen, we can't rely on scrolling to fill the screen.
++ * We need to clear and repaint screen before any change.
++ */
++ if (!full_screen && !(quit_if_one_screen && one_screen))
++ clear();
+ /*
+ * If nothing is displayed yet, display starting from initial_scrpos.
+ */
+ if (empty_screen())
+ {
+ if (initial_scrpos.pos == NULL_POSITION)
+ jump_loc(ch_zero(), 1);
+ else
+ jump_loc(initial_scrpos.pos, initial_scrpos.ln);
- } else if (screen_trashed)
++ } else if (screen_trashed || !full_screen)
+ {
+ int save_top_scroll = top_scroll;
+ int save_ignore_eoi = ignore_eoi;
+ top_scroll = 1;
+ ignore_eoi = 0;
+ if (screen_trashed == 2)
+ {
+ /* Special case used by ignore_eoi: re-open the input file
+ * and jump to the end of the file. */
+ reopen_curr_ifile();
+ jump_forw();
+ }
+ repaint();
+ top_scroll = save_top_scroll;
+ ignore_eoi = save_ignore_eoi;
+ }
+}
+
+/*
+ * Display the appropriate prompt.
+ */
- static void
- prompt(VOID_PARAM)
++static void prompt(void)
+{
+ constant char *p;
+
+ if (ungot != NULL && ungot->ug_char != CHAR_END_COMMAND)
+ {
+ /*
+ * No prompt necessary if commands are from
+ * ungotten chars rather than from the user.
+ */
+ return;
+ }
+
+ /*
+ * Make sure the screen is displayed.
+ */
+ make_display();
+ bottompos = position(BOTTOM_PLUS_ONE);
+
+ /*
+ * If we've hit EOF on the last file and the -E flag is set, quit.
+ */
+ if (get_quit_at_eof() == OPT_ONPLUS &&
+ eof_displayed() && !(ch_getflags() & CH_HELPFILE) &&
+ next_ifile(curr_ifile) == NULL_IFILE)
+ quit(QUIT_OK);
+
+ /*
+ * If the entire file is displayed and the -F flag is set, quit.
+ */
+ if (quit_if_one_screen &&
*** 3700 LINES SKIPPED ***