git: c77c48892655 - main - MFV: less v668.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 09 Dec 2024 06:53:09 UTC
The branch main has been updated by delphij:
URL: https://cgit.FreeBSD.org/src/commit/?id=c77c488926555ca344ae3a417544cf7a720e1de1
commit c77c488926555ca344ae3a417544cf7a720e1de1
Merge: 908f215e80fa 8c9fd1007159
Author: Xin LI <delphij@FreeBSD.org>
AuthorDate: 2024-12-09 04:50:00 +0000
Commit: Xin LI <delphij@FreeBSD.org>
CommitDate: 2024-12-09 05:22:12 +0000
MFV: less v668.
MFC after: 2 weeks
contrib/less/LICENSE | 2 +-
contrib/less/NEWS | 134 ++++++++
contrib/less/brac.c | 2 +-
contrib/less/ch.c | 131 ++++----
contrib/less/charset.c | 181 +++++-----
contrib/less/charset.h | 2 +-
contrib/less/cmd.h | 6 +-
contrib/less/cmdbuf.c | 217 ++++++------
contrib/less/command.c | 392 ++++++++++++++--------
contrib/less/compose.uni | 2 +-
contrib/less/cvt.c | 33 +-
contrib/less/decode.c | 376 +++++++++++++++------
contrib/less/edit.c | 362 ++++++++++----------
contrib/less/evar.c | 192 +++++++++++
contrib/less/filename.c | 430 ++++++++++++------------
contrib/less/fmt.uni | 2 +-
contrib/less/forwback.c | 84 +++--
contrib/less/funcs.h | 387 ++++++++++++----------
contrib/less/help.c | 54 +--
contrib/less/ifile.c | 18 +-
contrib/less/input.c | 109 +++---
contrib/less/jump.c | 51 ++-
contrib/less/lang.h | 57 ++++
contrib/less/less.h | 125 ++++---
contrib/less/less.hlp | 52 ++-
contrib/less/less.nro | 389 +++++++++++++++++-----
contrib/less/lessecho.c | 15 +-
contrib/less/lessecho.nro | 6 +-
contrib/less/lesskey.c | 73 ++--
contrib/less/lesskey.h | 24 +-
contrib/less/lesskey.nro | 38 ++-
contrib/less/lesskey_parse.c | 114 +++++--
contrib/less/lglob.h | 2 +-
contrib/less/line.c | 440 ++++++++++++++++--------
contrib/less/linenum.c | 83 +++--
contrib/less/lsystem.c | 17 +-
contrib/less/main.c | 272 ++++++++++++---
contrib/less/mark.c | 36 +-
contrib/less/optfunc.c | 533 ++++++++++++++++++-----------
contrib/less/option.c | 262 ++++++++++-----
contrib/less/option.h | 9 +-
contrib/less/opttbl.c | 113 ++++---
contrib/less/os.c | 64 ++--
contrib/less/output.c | 501 ++++++++++++++++------------
contrib/less/pattern.c | 40 +--
contrib/less/pattern.h | 6 +-
contrib/less/pckeys.h | 2 +-
contrib/less/position.c | 70 +++-
contrib/less/position.h | 2 +-
contrib/less/prompt.c | 112 ++++---
contrib/less/regexp.c | 120 +++----
contrib/less/regexp.h | 14 +-
contrib/less/screen.c | 744 ++++++++++++++++++++++++++---------------
contrib/less/scrsize.c | 2 +-
contrib/less/search.c | 774 +++++++++++++++++++++++++++++++++++++------
contrib/less/signal.c | 22 +-
contrib/less/tags.c | 79 ++---
contrib/less/ttyin.c | 47 ++-
contrib/less/ubin.uni | 2 +-
contrib/less/version.c | 47 ++-
contrib/less/wide.uni | 6 +-
contrib/less/xbuf.c | 64 +++-
contrib/less/xbuf.h | 13 +-
usr.bin/less/Makefile | 2 +-
usr.bin/less/defines.h | 62 ++--
65 files changed, 5718 insertions(+), 2904 deletions(-)
diff --cc contrib/less/command.c
index c1003d55fada,000000000000..27eba082e520
mode 100644,000000..100644
--- a/contrib/less/command.c
+++ b/contrib/less/command.c
@@@ -1,2096 -1,0 +1,2226 @@@
+/* $FreeBSD$ */
+/*
- * Copyright (C) 1984-2023 Mark Nudelman
++ * Copyright (C) 1984-2024 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;
++extern lbool search_wrapped;
+#if SHELL_ESCAPE || PIPEC
+extern void *ml_shell;
+#endif
+#if EDITOR
- extern char *editor;
- extern char *editproto;
++extern constant char *editproto;
++#endif
++#if OSC8_LINK
++extern char *osc8_uri;
+#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;
++extern unsigned less_acp;
+#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 lbool optgetname;
+static POSITION bottompos;
+static int save_hshift;
+static int save_bs_mode;
+static int save_proc_backspace;
++static int screen_trashed_value = 0;
++static lbool literal_char = FALSE;
+#if PIPEC
+static char pipec;
+#endif
+
+/* Stack of ungotten chars (via ungetcc) */
+struct ungot {
+ struct ungot *ug_next;
- LWCHAR ug_char;
++ char ug_char;
++ lbool ug_end_command;
+};
+static struct ungot* ungot = NULL;
+
- static void multi_search (char *pattern, int n, int silent);
++static void multi_search(constant 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)
+{
+ clear_attn();
+ clear_bot();
+ flush();
+}
+
+/*
+ * Indicate we are reading a multi-character command.
+ */
+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)
+{
+ if (mca == 0)
+ return;
+ mca = 0;
+}
+
+/*
+ * Set up the display to start a new multi-character command.
+ */
+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)
+{
+ return (mca != 0 && mca != A_PREFIX);
+}
+
+/*
+ * Set up the display to start a new search command.
+ */
+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[INT_STRLEN_BOUND(int)+8];
+ SNPRINTF1(buf, sizeof(buf), "Sub-%d ", i);
+ cmd_putstr(buf);
+ }
+ }
++ if (literal_char)
++ cmd_putstr("Lit ");
+
+#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)
+{
+ mca_search1();
+ set_mlist(ml_search, 0);
+}
+
+/*
+ * Set up the display to start a new toggle-option command.
+ */
+static void mca_opt_toggle(void)
+{
- int no_prompt;
- int flag;
- char *dash;
++ int no_prompt = (optflag & OPT_NO_PROMPT);
++ int flag = (optflag & ~OPT_NO_PROMPT);
++ constant char *dash = (flag == OPT_NO_TOGGLE) ? "_" : "-";
+
- 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)
+{
- char *cbuf;
++ constant char *cbuf;
++ char *p;
+
+ 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)
++ if (!secure_allow(SF_EXAMINE))
+ break;
- edit_list(cbuf);
++ p = save(cbuf);
++ edit_list(p);
++ free(p);
+#if TAGS
+ /* If tag structure is loaded then clean it up. */
+ cleantags();
+#endif
+ break;
+#endif
+#if SHELL_ESCAPE
- case A_SHELL:
++ case A_SHELL: {
+ /*
+ * !! just uses whatever is in shellcmd.
+ * Otherwise, copy cmdbuf to shellcmd,
+ * expanding any special characters ("%" or "#").
+ */
++ constant char *done_msg = (*cbuf == CONTROL('P')) ? NULL : "!done";
++ if (done_msg == NULL)
++ ++cbuf;
+ if (*cbuf != '!')
+ {
+ if (shellcmd != NULL)
+ free(shellcmd);
+ shellcmd = fexpand(cbuf);
+ }
-
- if (secure)
++ if (!secure_allow(SF_SHELL))
+ break;
+ if (shellcmd == NULL)
- lsystem("", "!done");
- else
- lsystem(shellcmd, "!done");
- break;
- case A_PSHELL:
- if (secure)
++ shellcmd = "";
++ lsystem(shellcmd, done_msg);
++ break; }
++ case A_PSHELL: {
++ constant char *done_msg = (*cbuf == CONTROL('P')) ? NULL : "#done";
++ if (done_msg == NULL)
++ ++cbuf;
++ if (!secure_allow(SF_SHELL))
+ break;
- lsystem(pr_expand(cbuf), "#done");
- break;
++ lsystem(pr_expand(cbuf), done_msg);
++ break; }
+#endif
+#if PIPEC
- case A_PIPE:
- if (secure)
++ case A_PIPE: {
++ constant char *done_msg = (*cbuf == CONTROL('P')) ? NULL : "|done";
++ if (done_msg == NULL)
++ ++cbuf;
++ if (!secure_allow(SF_PIPE))
+ break;
+ (void) pipe_mark(pipec, cbuf);
- error("|done", NULL_PARG);
- break;
++ if (done_msg != NULL)
++ error(done_msg, NULL_PARG);
++ break; }
+#endif
+ }
+}
+
+/*
+ * Is a character an erase or kill char?
+ */
- static int is_erase_char(int c)
++static lbool is_erase_char(char c)
+{
+ return (c == erase_char || c == erase2_char || c == kill_char);
+}
+
+/*
+ * Is a character a carriage return or newline?
+ */
- static int is_newline_char(int c)
++static lbool is_newline_char(char c)
+{
+ return (c == '\n' || c == '\r');
+}
+
+/*
+ * Handle the first char of an option (after the initial dash).
+ */
- static int mca_opt_first_char(int c)
++static int mca_opt_first_char(char 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(int c)
++static int mca_opt_nonfirst_char(char c)
+{
- char *p;
- char *oname;
- int err;
++ constant char *p;
++ constant char *oname;
++ lbool ambig;
+
+ 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);
++ curropt = findopt_name(&p, &oname, &ambig);
+ 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)
++ } else if (!ambig)
+ {
+ bell();
+ }
+ return (MCA_MORE);
+}
+
+/*
+ * Handle a char of an option toggle command.
+ */
- static int mca_opt_char(int c)
++static int mca_opt_char(char 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);
++ start_mca(A_OPT_TOGGLE, opt_prompt(curropt), NULL, 0);
+ return (MCA_MORE);
+}
+
+/*
+ * Normalize search type.
+ */
+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(int c)
++static int mca_search_char(char 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)
++ if (len_cmdbuf() > 0 || literal_char)
++ {
++ literal_char = FALSE;
+ 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;
+ search_type &= ~SRCH_WRAP;
+ 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[INT_STRLEN_BOUND(int)+24];
+ 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;
++ case CONTROL('L'):
++ literal_char = TRUE;
++ flag = -1;
++ break;
+ }
+
+ if (flag != 0)
+ {
+ 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(int c)
++static int mca_char(char 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|SRCH_SUBSEARCH_ALL));
- char *pattern = get_cmdbuf();
++ ssize_t save_updown;
++ constant 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;
++ save_updown = save_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)
++ if (is_screen_trashed() || !full_screen)
+ {
+ clear();
+ repaint();
+ }
+ mca_search1();
- updown_match = save_updown_match;
++ restore_updown_match(save_updown);
+ cmd_repaint(NULL);
+ }
+ break;
+ }
+
+ /*
+ * Need another character.
+ */
+ return (MCA_MORE);
+}
+
+/*
+ * Discard any buffered file data.
+ */
+static void clear_buffers(void)
+{
+ if (!(ch_getflags() & CH_CANSEEK))
+ return;
+ ch_flush();
+ clr_linenum();
+#if HILITE_SEARCH
+ clr_hilite();
+#endif
+}
+
++public void screen_trashed_num(int trashed)
++{
++ screen_trashed_value = trashed;
++}
++
++public void screen_trashed(void)
++{
++ screen_trashed_num(1);
++}
++
++public int is_screen_trashed(void)
++{
++ return screen_trashed_value;
++}
++
+/*
+ * Make sure the screen is displayed.
+ */
+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 || !full_screen)
++ } else if (is_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)
++ if (is_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;
*** 3006 LINES SKIPPED ***