From nobody Tue Aug 18 20:18:10 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4hPgxZ3GhKz6nnk5 for ; Tue, 18 Aug 2026 20:18:10 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hPgxZ2jSJz3WKn for ; Tue, 18 Aug 2026 20:18:10 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1787084290; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=fgAqm/kP+HbIiuf6y158LbJhy2A2LeYllkuNdLrkKfY=; b=x+5xDfzeLCdaxUh8eW6B/gIdyjAmEManluskkTy3h6dhvFKP5QyjE+tfRobLaYcbjL4uIb BZkDqyZUGdbvo35HQZGnlByP9zMKY1tDQr0uHAE05bbkLUneF2aiNz/DHrL2a5EQHmWSig i3jgfd3WyNl8uuwp2tGNtuxWBpcTHqlOlB2eApledv/o+MGgNVoBamZHB+VZVeJ40HOlhB IaoBqVF9UPmATcvAo98qlFDNkYyN83nyQnIsFy8AIfld++LgUz18ExeUD6/MFqv+TmGc2t Sc2IlwCk1ZjQIcS4GploRH8V/aM4/DThWyQUbXAJ1CNcJCg9tMJjoGQyPGiLRg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1787084290; a=rsa-sha256; cv=none; b=xRQ6f6cwe6rGhIUAISWEV6AbaqsWNu6qhj/4WVTRM//bha7Y6efnDWB9aBZazoZJ5EhIV2 NUdh9kfNF0xFQ+H0+TAp9FTNtmuNebVjqChg0x2kVV1H5cLrX0lZ4wt7ZsbTf4Co8mQ4O2 c0YLrEjSb24HjmgDULGF6g+Hq59mSNdLfSUgViK4u/2/iVz65aB+O+ibpKsjpAUNaPgHNa qPNYdIMwVhbDAmsch1ZaKn+eGJV22mMg3KwNaqjsYMlD50WbLMm+gG4Q5wZ7DWNomrSKmo VslTY8LEcxYe5gPySlQBWtC/MxQZHKwf5y3lH4aWe/a3EdmYfmpLAlo8rtjsig== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1787084290; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=fgAqm/kP+HbIiuf6y158LbJhy2A2LeYllkuNdLrkKfY=; b=eHlbsbK8bRUhMqj5hwO6DwaxWsroJu6UnuDoMj/CyApgTXF2oQVxoK7KCurKuORo1A0MGz KH87zR+ZpaT5IQdfmQdWGGdxTaUSX85ZUSLZGpv7LLbvUTu0ATRLmg1x4/0RLQsAuJude1 O5DKIQJR3EtOO5r8RwwWUYk1An7aDWFe92j6cgCGBAMyVrRII832uhABwlkZrWBh5G5zEc e0tvxNUj2/ugo4Z4ely4HE/IL11vzSoN3qbcuPQ1eXmDFfNgUdD5hHNJxDgf9X4KJF0CrP DEt1nG1nzV2fi8cYruLRW+1wgSNvZqOuoqP9o9kq26yPnaG7Jo2hJUBTZhJapA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hPgxZ0tFBz100f for ; Tue, 18 Aug 2026 20:18:10 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 22f82 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Tue, 18 Aug 2026 20:18:10 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Cc: Xin LI From: Colin Percival Subject: git: 7cc6a5d46484 - releng/14.5 - MFV: less v704. List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: cperciva X-Git-Repository: src X-Git-Refname: refs/heads/releng/14.5 X-Git-Reftype: branch X-Git-Commit: 7cc6a5d46484ef5e8f5d70c7e6170dcd90981b96 Auto-Submitted: auto-generated Date: Tue, 18 Aug 2026 20:18:10 +0000 Message-Id: <6a84be02.22f82.5f0fce29@gitrepo.freebsd.org> The branch releng/14.5 has been updated by cperciva: URL: https://cgit.FreeBSD.org/src/commit/?id=7cc6a5d46484ef5e8f5d70c7e6170dcd90981b96 commit 7cc6a5d46484ef5e8f5d70c7e6170dcd90981b96 Author: Xin LI AuthorDate: 2026-08-15 05:55:38 +0000 Commit: Colin Percival CommitDate: 2026-08-18 20:17:56 +0000 MFV: less v704. (cherry picked from commit fa0dc4f0f96a1b77d4be7bcdbf965897cda14521) (cherry picked from commit 86aea5b4db379327f02ca547575105788bfbe807) Approved by: re (cperciva) --- contrib/less/NEWS | 126 ++++++++++++++++ contrib/less/README | 8 - contrib/less/ch.c | 10 +- contrib/less/charset.c | 25 +-- contrib/less/charset.h | 2 + contrib/less/cmd.h | 3 + contrib/less/cmdbuf.c | 6 +- contrib/less/command.c | 186 ++++++++++++++++------- contrib/less/decode.c | 334 ++++++++++++++++++++++++++++++----------- contrib/less/edit.c | 42 ++++-- contrib/less/filename.c | 20 +-- contrib/less/forwback.c | 53 +++++-- contrib/less/funcs.h | 41 +++-- contrib/less/help.c | 28 ++-- contrib/less/input.c | 12 +- contrib/less/jump.c | 31 ++-- contrib/less/less-osc8-open.sh | 64 ++++++++ contrib/less/less.h | 44 ++++-- contrib/less/less.hlp | 26 ++-- contrib/less/less.nro | 331 ++++++++++++++++++++++++++-------------- contrib/less/lessecho.nro | 2 +- contrib/less/lesskey.nro | 3 +- contrib/less/lesskey_parse.c | 2 + contrib/less/line.c | 62 ++++---- contrib/less/lsystem.c | 2 +- contrib/less/main.c | 73 ++------- contrib/less/mark.c | 50 ++++-- contrib/less/optfunc.c | 200 ++++++++++++++++++++---- contrib/less/opttbl.c | 60 ++++++-- contrib/less/os.c | 45 +++--- contrib/less/output.c | 68 +++++---- contrib/less/pattern.c | 8 +- contrib/less/pattern.h | 10 +- contrib/less/position.c | 82 ++++++---- contrib/less/prompt.c | 33 ++-- contrib/less/regexp.c | 206 +++++++++++++++++-------- contrib/less/regexp.h | 5 +- contrib/less/screen.c | 105 +++++++++---- contrib/less/search.c | 140 ++++++++++------- contrib/less/tags.c | 8 +- contrib/less/ttyin.c | 2 +- contrib/less/version.c | 37 ++++- usr.bin/less/Makefile | 2 +- usr.bin/less/defines.h | 12 ++ 44 files changed, 1845 insertions(+), 764 deletions(-) diff --git a/contrib/less/NEWS b/contrib/less/NEWS index 0f767aaeb059..a031353acf46 100644 --- a/contrib/less/NEWS +++ b/contrib/less/NEWS @@ -9,6 +9,132 @@ Report bugs, suggestions or comments at https://github.com/gwsw/less/issues. +====================================================================== + + Major changes between "less" versions 702 and 704 + +* Fix possibly passing unsafe options to man when opening an + OSC 8 link (github #779). + +* Fix possibly sending unsafe OSC sequence to terminal when file + contains an unterminated OSC sequence (github #781). + +* In Examine and Shell commands, expand % and # to shell-escaped + filenames (github #784). + +====================================================================== + + Major changes between "less" versions 692 and 702 + +* Add --hilite-target option and -DJ to color target line (github #745). + +* Add --past-eof option. + +* Add --end-prompt option. + +* Add --emouse and --rmouse options, and horizontal mouse scrolling + and dragging (github #744). + +* Add -DT option to format tilde lines (github #725). + +* Change OSC 8 link handling: replace LESS_OSC8_xxx with LESS_OSC8_OPEN_xxx. + Remove %O from prompt expansion as no longer needed. + Any use of environment variables LESS_OSC8_xxx need to be manually + changed to use LESS_OSC8_OPEN_xxx. + +* Add ?o to prompt strings, to detect whether an OSC 8 link is selected. + +* When scrolling past end-of-file or before beginning-of-file, + stop when exactly one line is left on screen. + +* Make -w/-W highlight lines when moving backward as well as forward + (github #729). + +* Display pattern in "Pattern not found" message (github #731). + +* Allow m and M commands to take a numeric argument to specify the + line to be marked (github #736). + +* Allow ' command to take a numeric argument to specify the screen + position on which to place the marked line. + +* Allow lesskey to map keypad ENTER with \kpe (github #761). + +* Add "noaction" as a possible action in #line-edit section + in a lesskey file (github #761). + +* Support POSIX character classes with the built-in V8 regex library + (github #732). + +* Change | command to pipe just one line if the marked line is at the + top of the screen (github #733). + +* If OSC8 handler command begins with "-", suppress command echo, + and if it begins with ctrl-P, suppress "done" message (github #747). + +* Don't ask for confirmation when input is a binary file and stdout is + redirected. Fixes infinite loop in that situation (github #719). + +* Make early error messages go to stderr if stdout is redirected + (github #719). + +* Don't retry read after read error; fixes hang when attempting to read + a directory or other unreadable file (github #741). + +* Fix incorrect restoration of saved mark if not at top of screen. + +* With --save-marks, don't save a mark that was cleared with ESC-m. + +* Fix buffer overflow when using malformed lesskey file (github #721). + +* Fix unexpected scrolling past end of file (github #720). + +* Fix bug when env var in LESSKEY_CONTENT partially matches env var + defined in lesskey file (github #727). + +* Fix bug when env var in lesskey file matches tail of env var used + by less (github #728). + +* Fix command parsing bug when one command is a substring of another. + Also fixes --no-paste option (github #724). + +* Fix incorrect display using --color to set character attributes + without color, such as -DS-u (github #730). + +* Fix crash when tags file contains invalid line number 0 (github #743). + +* Fix build when tparm() doesn't use varargs (github #748). + +* Fix prompt overflow when filtering with long prompt (github #749). + +* Fix incorrect highlighting when change -i while filtering (github #750). + +* Fix erroneous error mesage using --show-preproc-error with + some shells (github #753). + +* Fix erroneous highlighting when using a search pattern containing more + than 5 pairs of parentheses with PCRE2 (github #754). + +* When ^X interrupts F mode, discard pending keys as is done when + ^C interrupts it (github #757). + +* Fix bug in Windows where pressing any key during "waiting for data" would + prevent a subsequent ^X from working. + +* Fix erroneous display in some situations when using LESS_LINES (github #759). + +* Fix erroneous display after certain messages are displayed in a + very narrow terminal (github #760). + +* Don't init terminal if stdout is not a tty (github #768). + +* Fix bug clicking OSC 8 link that crosses a screen line boundary + (github #775). + +* Fix beeps when resizing window on Windows (github #771). + +* Fix beeps when paging continuously on Windows (github #772). + ====================================================================== Major changes between "less" versions 691 and 692 diff --git a/contrib/less/README b/contrib/less/README index a6954eb67c1e..384d99155616 100644 --- a/contrib/less/README +++ b/contrib/less/README @@ -108,14 +108,6 @@ INSTALLATION (Unix & Linux systems only): bindir and/or mandir to the appropriate directories. -Note to hackers: comments noting possible improvements are enclosed -in double curly brackets {{ like this }}. - -(Note that the above note was originally written at a time when -"hackers" most commonly meant "enthusiastic and dedicated computer -programmers", not "persons who attempt to circumvent computer security".) - - ======================================================================= INSTALLATION (Windows-95, Windows-98 and Windows-NT systems only, diff --git a/contrib/less/ch.c b/contrib/less/ch.c index 47d31ecffadd..dfe1e7169f72 100644 --- a/contrib/less/ch.c +++ b/contrib/less/ch.c @@ -23,6 +23,7 @@ typedef POSITION BLOCKNUM; public lbool ignore_eoi = FALSE; +public lbool read_error = FALSE; /* * Pool of buffers holding the most recently used blocks of the input file. @@ -292,13 +293,14 @@ static int ch_get(void) if (n < 0) { #if MSDOS_COMPILER==WIN32C - if (errno != EPIPE) + if (errno == EPIPE) + n = 0; + else #endif { - error("read error", NULL_PARG); - clear_eol(); + read_error = TRUE; + return (EOI); } - n = 0; } #if LOGFILE diff --git a/contrib/less/charset.c b/contrib/less/charset.c index 74159404148b..f2020e4ef5c5 100644 --- a/contrib/less/charset.c +++ b/contrib/less/charset.c @@ -585,20 +585,21 @@ public constant char * prutfchar(LWCHAR ch) /* * Get the length of a UTF-8 character in bytes. */ -public int utf_len(char ch) +public int utf_len(char ach) { - if ((ch & 0x80) == 0) + unsigned char ch = (unsigned char) ach; + if (IS_ASCII_OCTET(ch)) return 1; - if ((ch & 0xE0) == 0xC0) + if (IS_UTF8_LEAD2(ch)) return 2; - if ((ch & 0xF0) == 0xE0) + if (IS_UTF8_LEAD3(ch)) return 3; - if ((ch & 0xF8) == 0xF0) + if (IS_UTF8_LEAD4(ch)) return 4; #if 0 - if ((ch & 0xFC) == 0xF8) + if (IS_UTF8_LEAD5(ch)) return 5; - if ((ch & 0xFE) == 0xFC) + if (IS_UTF8_LEAD6(ch)) return 6; #endif /* Invalid UTF-8 encoding. */ @@ -608,16 +609,17 @@ public int utf_len(char ch) /* * Does the parameter point to the lead byte of a well-formed UTF-8 character? */ -public lbool is_utf8_well_formed(constant char *ss, int slen) +public lbool is_utf8_well_formed(constant char *ssa, int slen) { int i; int len; - unsigned char s0 = (unsigned char) ss[0]; + constant unsigned char *ss = (constant unsigned char *) ssa; + unsigned char s0 = ss[0]; - if (IS_UTF8_INVALID(s0)) + if (IS_UTF8_LEAD5(s0) || IS_UTF8_LEAD6(s0) || IS_UTF8_INVALID(s0)) return (FALSE); - len = utf_len(ss[0]); + len = utf_len(s0); if (len > slen) return (FALSE); if (len == 1) @@ -904,6 +906,7 @@ public lbool is_composing_char(LWCHAR ch) public lbool is_ubin_char(LWCHAR ch) { if (is_in_table(ch, &user_prt_table)) return FALSE; + if (ch > MAX_UNICODE) return TRUE; return is_in_table(ch, &user_ubin_table) || (is_in_table(ch, &ubin_table) || (bs_mode == BS_CONTROL && is_in_table(ch, &fmt_table) && diff --git a/contrib/less/charset.h b/contrib/less/charset.h index cf2e02547cb5..dab7474acc73 100644 --- a/contrib/less/charset.h +++ b/contrib/less/charset.h @@ -16,3 +16,5 @@ #define IS_UTF8_LEAD6(c) (((c) & 0xFE) == 0xFC) #define IS_UTF8_INVALID(c) (((c) & 0xFE) == 0xFE) #define IS_UTF8_LEAD(c) (((c) & 0xC0) == 0xC0 && !IS_UTF8_INVALID(c)) + +#define MAX_UNICODE 0x10FFFF diff --git a/contrib/less/cmd.h b/contrib/less/cmd.h index 945f99719d0c..fb66a6adb99d 100644 --- a/contrib/less/cmd.h +++ b/contrib/less/cmd.h @@ -87,6 +87,8 @@ #define A_START_PASTE 75 /* must not overlap EC_* */ #define A_END_PASTE 76 /* must not overlap EC_* */ #define A_F_FOREVER_BELL 77 +#define A_L_MOUSE 78 +#define A_R_MOUSE 79 /* These values must not conflict with any A_* or EC_* value. */ #define A_INVALID 100 @@ -178,5 +180,6 @@ #define SK_CTL_END 37 #define SK_SHIFT_LEFT_ARROW 38 #define SK_SHIFT_RIGHT_ARROW 39 +#define SK_PAD_ENTER 41 #define SK_CONTROL_K 40 diff --git a/contrib/less/cmdbuf.c b/contrib/less/cmdbuf.c index 1c3b3d461ad9..9f13473eba03 100644 --- a/contrib/less/cmdbuf.c +++ b/contrib/less/cmdbuf.c @@ -113,8 +113,8 @@ static struct mlist *curr_mlist = NULL; static int curr_cmdflags; static char cmd_mbc_buf[MAX_UTF_CHAR_LEN]; -static int cmd_mbc_buf_len; -static int cmd_mbc_buf_index; +static size_t cmd_mbc_buf_len; +static size_t cmd_mbc_buf_index; /* @@ -1330,7 +1330,7 @@ static int cmd_uchar(char c, size_t *plen) goto retry; } - *plen = (size_t) cmd_mbc_buf_len; /*{{type-issue}}*/ + *plen = cmd_mbc_buf_len; cmd_mbc_buf_len = 0; } return (CC_PASS); diff --git a/contrib/less/command.c b/contrib/less/command.c index 1bb8d006f8ec..09eb1614c76d 100644 --- a/contrib/less/command.c +++ b/contrib/less/command.c @@ -23,10 +23,11 @@ extern int erase_char, erase2_char, kill_char; extern int sigs; extern int quit_if_one_screen; -extern int one_screen; +extern lbool one_screen; extern int sc_width; extern int sc_height; extern char *kent; +extern lbool kent_mapped; extern int swindow; extern int jump_sline; extern lbool quitting; @@ -48,13 +49,16 @@ extern void *ml_search; extern void *ml_examine; extern int wheel_lines; extern int def_search_type; +extern int hilite_target; extern lbool search_wrapped; extern int no_paste; extern lbool pasting; extern int no_edit_warn; +extern lbool read_error; extern POSITION soft_eof; extern POSITION search_incr_start; extern char *first_cmd_at_prompt; +extern lbool prompting; #if SHELL_ESCAPE || PIPEC extern void *ml_shell; #endif @@ -65,9 +69,9 @@ extern constant char *editproto; extern char *osc8_uri; #endif extern int shift_count; -extern int forw_prompt; +extern lbool forw_prompt; extern int incr_search; -extern int full_screen; +extern lbool full_screen; #if MSDOS_COMPILER==WIN32C extern int utf_mode; extern unsigned less_acp; @@ -85,6 +89,7 @@ static struct loption *curropt; static lbool opt_lower; static int optflag; static lbool optgetname; +static POSITION toppos; static POSITION bottompos; static int save_hshift; static int save_bs_mode; @@ -208,7 +213,7 @@ static void mca_search1(void) cmd_putstr("/"); else cmd_putstr("?"); - forw_prompt = 0; + forw_prompt = FALSE; } static void mca_search(void) @@ -248,7 +253,7 @@ static void mca_opt_toggle(void) cmd_putstr("!"); break; } - forw_prompt = 0; + forw_prompt = FALSE; set_mlist(NULL, CF_OPTION); } @@ -850,12 +855,6 @@ public int is_screen_trashed(void) */ 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)) - lclear(); /* * If nothing is displayed yet, display starting from initial_scrpos. */ @@ -884,12 +883,47 @@ static void make_display(void) } } +/* + * Display any message that needs to be displayed before the prompt. + */ +static void prompt_message(void) +{ + if (read_error) + { + error("read error", NULL_PARG); + read_error = FALSE; + } + if (search_wrapped) + { + if (search_type & SRCH_BACK) + error("Search hit top; continuing at bottom", NULL_PARG); + else + error("Search hit bottom; continuing at top", NULL_PARG); + search_wrapped = FALSE; + } +#if OSC8_LINK + if (osc8_uri != NULL) + { + PARG parg; + parg.p_string = osc8_uri; + error("Link: %s", &parg); + free(osc8_uri); + osc8_uri = NULL; + } +#endif +} + /* * Display the appropriate prompt. */ static void prompt(void) { constant char *p; + int attr; +#if MSDOS_COMPILER==WIN32C + WCHAR w[MAX_PATH*2]; + char a[MAX_PATH*2]; +#endif if (ungot != NULL && !ungot->ug_end_command) { @@ -904,6 +938,10 @@ static void prompt(void) * Make sure the screen is displayed. */ make_display(); + + if (hilite_target) + draw_target_attn(TRUE); /* Redraw target line for --hilite-target. */ + toppos = position(TOP); bottompos = position(BOTTOM_PLUS_ONE); /* @@ -921,7 +959,7 @@ static void prompt(void) entire_file_displayed() && !(ch_getflags() & CH_HELPFILE) && next_ifile(curr_ifile) == NULL_IFILE) quit(QUIT_OK); - quit_if_one_screen = FALSE; /* only get one chance at this */ + quit_if_one_screen = 0; /* only get one chance at this */ if (first_cmd_at_prompt != NULL) { ungetsc(first_cmd_at_prompt); @@ -932,6 +970,7 @@ static void prompt(void) #if MSDOS_COMPILER==WIN32C /* * In Win32, display the file name in the window title. + * {{ Seems like this should be done in edit_ifile, not on every prompt. }} */ if (!(ch_getflags() & CH_HELPFILE)) { @@ -958,50 +997,43 @@ static void prompt(void) if (!forw_prompt) clear_bot(); clear_cmd(); - forw_prompt = 0; + forw_prompt = FALSE; + prompt_message(); + /* We called make_display above, but if prompt_message displayed + * a message longer than the screen width, we may have trashed + * the screen and need to call make_display again. */ + if (is_screen_trashed()) + make_display(); p = pr_string(); -#if HILITE_SEARCH - if (is_filtering()) - putstr("& "); -#endif - if (search_wrapped) - { - if (search_type & SRCH_BACK) - error("Search hit top; continuing at bottom", NULL_PARG); - else - error("Search hit bottom; continuing at top", NULL_PARG); - search_wrapped = FALSE; - } -#if OSC8_LINK - if (osc8_uri != NULL) - { - PARG parg; - parg.p_string = osc8_uri; - error("Link: %s", &parg); - free(osc8_uri); - osc8_uri = NULL; - } -#endif if (p == NULL || *p == '\0') { - at_enter(AT_NORMAL|AT_COLOR_PROMPT); - putchr(':'); - at_exit(); + p = ":"; + attr = AT_NORMAL|AT_COLOR_PROMPT; } else { + attr = AT_STANDOUT|AT_COLOR_PROMPT; #if MSDOS_COMPILER==WIN32C - WCHAR w[MAX_PATH*2]; - char a[MAX_PATH*2]; MultiByteToWideChar(less_acp, 0, p, -1, w, countof(w)); WideCharToMultiByte(utf_mode ? CP_UTF8 : GetConsoleOutputCP(), 0, w, -1, a, sizeof(a), NULL, NULL); p = a; #endif - load_line(p); - put_line(FALSE); } +#if HILITE_SEARCH + if (is_filtering()) + { + constant char *amp = "& "; + load_line(p, attr, strlen(amp)+1); + putstr(amp); + } else +#endif + { + load_line(p, attr, 1); + } + put_line(FALSE); clear_eol(); resume_screen(); + prompting = TRUE; } /* @@ -1139,8 +1171,9 @@ static char getcc_repl(char constant *orig, char constant *repl, char (*gr_getc) */ public char getcc(void) { - /* Replace kent (keypad Enter) with a newline. */ - return getcc_repl(kent, "\n", getccu, ungetcc); + /* Replace kent (keypad Enter) with a newline. + * However don't do this if kent is mapped to a command via lesskey. */ + return getcc_repl(kent_mapped ? NULL : kent, "\n", getccu, ungetcc); } /* @@ -1291,7 +1324,14 @@ static void multi_search(constant char *pattern, int n, int silent) * Print an error message if we haven't already. */ if (n > 0 && !silent) - error("Pattern not found", NULL_PARG); + { + PARG parg; + parg.p_string = prev_pattern_text(); + if (parg.p_string == NULL) /* {{ can this happen? }} */ + error("Pattern not found", NULL_PARG); + else + error("Pattern not found: %s", &parg); + } if (changed_file) { @@ -1348,7 +1388,7 @@ static int forw_loop(int action) /* * Ignore subsequent (pasted) input chars. */ -public void start_ignoring_input() +public void start_ignoring_input(void) { ignoring_input = TRUE; #if HAVE_TIME @@ -1359,7 +1399,7 @@ public void start_ignoring_input() /* * Stop ignoring input chars. */ -public void stop_ignoring_input() +public void stop_ignoring_input(void) { ignoring_input = FALSE; pasting = FALSE; @@ -1443,6 +1483,8 @@ public void commands(void) c = getcc(); again: + if (c == READ_AGAIN) + continue; if (sigs) continue; @@ -1582,12 +1624,13 @@ public void commands(void) if (number <= 0) number = get_swindow(); cmd_exec(); + if (show_attn && toppos != NULL_POSITION && toppos > ch_zero()) + set_attnpos(toppos-1); backward((int) number, FALSE, TRUE, FALSE); break; case A_F_LINE: case A_F_NEWLINE: - /* * Forward N (default 1) line. */ @@ -1607,6 +1650,8 @@ public void commands(void) if (number <= 0) number = 1; cmd_exec(); + if (show_attn == OPT_ONPLUS && number > 1 && toppos != NULL_POSITION && toppos > ch_zero()) + set_attnpos(toppos-1); backward((int) number, FALSE, FALSE, action == A_B_NEWLINE && !chopline); break; @@ -1626,6 +1671,29 @@ public void commands(void) backward(wheel_lines, FALSE, FALSE, FALSE); break; + case A_L_MOUSE: + /* + * Left wheel_lines columns. + */ + cmd_exec(); + pos_rehead(FALSE); + if (wheel_lines > hshift) + hshift = 0; + else + hshift -= wheel_lines; + screen_trashed(); + break; + + case A_R_MOUSE: + /* + * Right wheel_lines columns. + */ + cmd_exec(); + pos_rehead(FALSE); + hshift += wheel_lines; + screen_trashed(); + break; + case A_FF_LINE: /* * Force forward N (default 1) line. @@ -1645,6 +1713,8 @@ public void commands(void) if (number <= 0) number = 1; cmd_exec(); + if (show_attn == OPT_ONPLUS && number > 1 && toppos != NULL_POSITION && toppos > ch_zero()) + set_attnpos(toppos-1); backward((int) number, TRUE, FALSE, FALSE); break; @@ -1667,6 +1737,8 @@ public void commands(void) if (number <= 0) number = get_swindow(); cmd_exec(); + if (show_attn == OPT_ONPLUS && toppos != NULL_POSITION && toppos > ch_zero()) + set_attnpos(toppos-1); backward((int) number, TRUE, FALSE, FALSE); break; @@ -1704,6 +1776,8 @@ public void commands(void) if (number > 0) wscroll = (int) number; cmd_exec(); + if (show_attn == OPT_ONPLUS && toppos != NULL_POSITION && toppos > ch_zero()) + set_attnpos(toppos-1); backward(wscroll, FALSE, FALSE, FALSE); break; @@ -1963,6 +2037,7 @@ public void commands(void) /* * Clear search string highlighting. */ + cmd_exec(); undo_search(action == A_CLR_SEARCH); break; @@ -2229,9 +2304,11 @@ public void commands(void) } start_mca(A_SETMARK, "set mark: ", NULL, 0); c = getcc(); + make_display(); + cmd_exec(); if (is_erase_char(c) || is_newline_char(c)) break; - setmark(c, action == A_SETMARKBOT ? BOTTOM : TOP); + setmark(c, action == A_SETMARKBOT ? BOTTOM : TOP, number); repaint(); break; @@ -2241,6 +2318,7 @@ public void commands(void) */ start_mca(A_CLRMARK, "clear mark: ", NULL, 0); c = getcc(); + cmd_exec(); if (is_erase_char(c) || is_newline_char(c)) break; clrmark(c); @@ -2256,7 +2334,7 @@ public void commands(void) if (is_erase_char(c) || is_newline_char(c)) break; cmd_exec(); - gomark(c); + gomark(c, number); break; case A_PIPE: @@ -2299,7 +2377,7 @@ public void commands(void) number = (shift_count > 0) ? shift_count : sc_width / 2; if (number > hshift) number = hshift; - pos_rehead(); + pos_rehead(FALSE); hshift -= (int) number; screen_trashed(); cmd_exec(); @@ -2313,7 +2391,7 @@ public void commands(void) shift_count = (int) number; else number = (shift_count > 0) ? shift_count : sc_width / 2; - pos_rehead(); + pos_rehead(FALSE); hshift += (int) number; screen_trashed(); cmd_exec(); @@ -2323,7 +2401,7 @@ public void commands(void) /* * Shift view left to margin. */ - pos_rehead(); + pos_rehead(FALSE); hshift = 0; screen_trashed(); cmd_exec(); @@ -2333,7 +2411,7 @@ public void commands(void) /* * Shift view right to view rightmost char on screen. */ - pos_rehead(); + pos_rehead(FALSE); hshift = rrshift(); screen_trashed(); cmd_exec(); diff --git a/contrib/less/decode.c b/contrib/less/decode.c index 3615f5b905d7..393082c84097 100644 --- a/contrib/less/decode.c +++ b/contrib/less/decode.c @@ -34,12 +34,12 @@ #include "lesskey.h" extern int erase_char, erase2_char, kill_char; -extern int mousecap; +extern int emouse; +extern int mouse_reverse; +extern int hshift; extern int sc_height; extern char *no_config; -static constant lbool allow_drag = TRUE; - #if USERFILE /* "content" is lesskey source, never binary. */ static void add_content_table(int (*call_lesskey)(constant char *, lbool), constant char *envname, lbool sysvar); @@ -286,17 +286,19 @@ static unsigned char edittable[] = ESC,'[','2','0','1','~',0, A_END_PASTE, /* close paste bracket */ }; -static unsigned char dflt_vartable[] = +/* + * Default environment variables. + * Note: "\201" is (A_EXTRA|EV_OK). + */ +static char dflt_vartable[] = { - 'L','E','S','S','_','O','S','C','8','_','m','a','n', 0, EV_OK|A_EXTRA, - /* echo '%o' | sed -e "s,^man\:\\([^(]*\\)( *\\([^)]*\\)\.*,-man '\\2' '\\1'," -e"t X" -e"s,\.*,-echo Invalid man link," -e"\: X" */ - 'e','c','h','o',' ','\'','%','o','\'',' ','|',' ','s','e','d',' ','-','e',' ','"','s',',','^','m','a','n','\\',':','\\','\\','(','[','^','(',']','*','\\','\\',')','(',' ','*','\\','\\','(','[','^',')',']','*','\\','\\',')','\\','.','*',',','-','m','a','n',' ','\'','\\','\\','2','\'',' ','\'','\\','\\','1','\'',',','"',' ','-','e','"','t',' ','X','"',' ','-','e','"','s',',','\\','.','*',',','-','e','c','h','o',' ','I','n','v','a','l','i','d',' ','m','a','n',' ','l','i','n','k',',','"',' ','-','e','"','\\',':',' ','X','"', - 0, - - 'L','E','S','S','_','O','S','C','8','_','f','i','l','e', 0, EV_OK|A_EXTRA, - /* eval `echo '%o' | sed -e "s,^file://\\([^/]*\\)\\(.*\\),_H=\\1;_P=\\2;_E=0," -e"t X" -e"s,.*,_E=1," -e": X"`; if [ "$_E" = 1 ]; then echo -echo Invalid file link; elif [ -z "$_H" -o "$_H" = localhost -o "$_H" = $HOSTNAME ]; then echo ":e $_P"; else echo -echo Cannot open remote file on "$_H"; fi */ - 'e','v','a','l',' ','`','e','c','h','o',' ','\'','%','o','\'',' ','|',' ','s','e','d',' ','-','e',' ','"','s',',','^','f','i','l','e','\\',':','/','/','\\','\\','(','[','^','/',']','*','\\','\\',')','\\','\\','(','\\','.','*','\\','\\',')',',','_','H','=','\\','\\','1',';','_','P','=','\\','\\','2',';','_','E','=','0',',','"',' ','-','e','"','t',' ','X','"',' ','-','e','"','s',',','\\','.','*',',','_','E','=','1',',','"',' ','-','e','"','\\',':',' ','X','"','`',';',' ','i','f',' ','[',' ','"','$','_','E','"',' ','=',' ','1',' ',']',';',' ','t','h','e','n',' ','e','c','h','o',' ','-','e','c','h','o',' ','I','n','v','a','l','i','d',' ','f','i','l','e',' ','l','i','n','k',';',' ','e','l','i','f',' ','[',' ','-','z',' ','"','$','_','H','"',' ','-','o',' ','"','$','_','H','"',' ','=',' ','l','o','c','a','l','h','o','s','t',' ','-','o',' ','"','$','_','H','"',' ','=',' ','$','H','O','S','T','N','A','M','E',' ',']',';',' ','t','h','e','n',' ','e','c','h','o',' ','"','\\',':','e' ,' ','$','_','P','"',';',' ','e','l','s','e',' ','e','c','h','o',' ','-','e','c','h','o',' ','C','a','n','n','o','t',' ','o','p','e','n',' ','r','e','m','o','t','e',' ','f','i','l','e',' ','o','n',' ','"','$','_','H','"',';',' ','f','i', - 0, + "LESS_OSC8_OPEN_ANY\0\201" +#ifdef LIBEXECDIR + "-" LIBEXECDIR "/less-osc8-open" +#else + "-less-osc8-open" +#endif + "\0" }; /* @@ -317,6 +319,9 @@ static struct tablelist *list_ecmd_tables = NULL; static struct tablelist *list_var_tables = NULL; static struct tablelist *list_sysvar_tables = NULL; +#if USERFILE +static struct tablelist * find_stop_table(struct tablelist *t); +#endif /* * Expand special key abbreviations in a command table. @@ -335,7 +340,7 @@ static void expand_special_keys(unsigned char *table, size_t len) * Rewrite each command in the table with any * special key abbreviations expanded. */ - for (to = fm; *fm != '\0'; ) + for (to = fm; fm < table + len && *fm != '\0'; ) { if (*fm != SK_SPECIAL_KEY) { @@ -352,7 +357,7 @@ static void expand_special_keys(unsigned char *table, size_t len) * output by the special key on this terminal. */ repl = special_key_str(fm[1]); - klen = fm[2] & 0377; + klen = fm[2]; fm += klen; if (repl == NULL || strlen(repl) > klen) repl = "\377"; @@ -367,10 +372,10 @@ static void expand_special_keys(unsigned char *table, size_t len) while (to <= fm) *to++ = A_SKIP; fm++; - a = *fm++ & 0377; + a = *fm++; if (a & A_EXTRA) { - while (*fm++ != '\0') + while (fm < table + len && *fm++ != '\0') continue; } } @@ -404,12 +409,15 @@ public void expand_cmd_tables(void) */ public void init_cmds(void) { + struct tablelist *t; + unsigned char *udflt_vartable = (unsigned char *) dflt_vartable; + /* * Add the default command tables. */ add_fcmd_table(cmdtable, sizeof(cmdtable)); add_ecmd_table(edittable, sizeof(edittable)); - add_sysvar_table(dflt_vartable, sizeof(dflt_vartable)); + add_sysvar_table(udflt_vartable, sizeof(dflt_vartable)); #if USERFILE #ifdef BINDIR /* For backwards compatibility */ /* Try to add tables in the OLD system lesskey file. */ @@ -449,6 +457,16 @@ public void init_cmds(void) add_content_table(lesskey_content, "LESSKEY_CONTENT_SYSTEM", TRUE); add_content_table(lesskey_content, "LESSKEY_CONTENT", FALSE); + + /* + * If any command table contains a #stop directive, discard all other tables. + */ + t = find_stop_table(list_fcmd_tables); + if (t != NULL) + { + t->t_next = NULL; + list_fcmd_tables = t; + } #endif /* USERFILE */ } @@ -555,7 +573,9 @@ public void add_sysvar_table(unsigned char *buf, size_t len) */ static int mouse_wheel_down(void) { - return ((mousecap == OPT_ONPLUS) ? A_B_MOUSE : A_F_MOUSE); + if (!(emouse & EMOUSE_VSCROLL)) + return A_NOACTION; + return mouse_reverse ? A_B_MOUSE : A_F_MOUSE; } /* @@ -563,7 +583,29 @@ static int mouse_wheel_down(void) */ static int mouse_wheel_up(void) { - return ((mousecap == OPT_ONPLUS) ? A_F_MOUSE : A_B_MOUSE); + if (!(emouse & EMOUSE_VSCROLL)) + return A_NOACTION; + return mouse_reverse ? A_F_MOUSE : A_B_MOUSE; +} + +/* + * Return action for a mouse wheel left event. + */ +static int mouse_wheel_left(void) +{ + if (!(emouse & EMOUSE_HSCROLL)) + return A_NOACTION; + return mouse_reverse ? A_R_MOUSE : A_L_MOUSE; +} + +/* + * Return action for a mouse wheel right event. + */ +static int mouse_wheel_right(void) +{ + if (!(emouse & EMOUSE_HSCROLL)) + return A_NOACTION; + return mouse_reverse ? A_L_MOUSE : A_R_MOUSE; } /* @@ -571,32 +613,48 @@ static int mouse_wheel_up(void) */ static int mouse_button_left(int x, int y, lbool down, lbool drag) { + static int last_drag_x = -1; static int last_drag_y = -1; static int last_click_y = -1; *** 4363 LINES SKIPPED ***