git: 6330c2f5fbbf - stable/14 - MFV less v691

Xin LI <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src,gmane.os.freebsd.devel.stable.scm
Message-ID <[email protected]>
The branch stable/14 has been updated by delphij:

URL: https://cgit.FreeBSD.org/src/commit/?id=6330c2f5fbbf1320d768fa55f267c114654d729b

commit 6330c2f5fbbf1320d768fa55f267c114654d729b
Author:     Xin LI <[email protected]>
AuthorDate: 2026-05-07 03:51:51 +0000
Commit:     Xin LI <[email protected]>
CommitDate: 2026-08-18 02:23:56 +0000

    MFV less v691
    
    Relnotes:       yes
    
    (cherry picked from commit dafba19e42e78cd3d7c9264ece49ddd3d7d70da5)
    
    MFV: less v692.
    
    (cherry picked from commit e2abec625bf07c054f7ac2df2402d6c454113df8)
---
 contrib/less/LICENSE         |    2 +-
 contrib/less/NEWS            |   83 +++
 contrib/less/README          |   60 +-
 contrib/less/brac.c          |    2 +-
 contrib/less/ch.c            |   14 +-
 contrib/less/charset.c       |   31 +-
 contrib/less/charset.h       |    2 +-
 contrib/less/cmd.h           |   26 +-
 contrib/less/cmdbuf.c        |  138 ++--
 contrib/less/command.c       |   87 +--
 contrib/less/compose.uni     |   14 +-
 contrib/less/cvt.c           |    2 +-
 contrib/less/decode.c        |  107 ++-
 contrib/less/edit.c          |   16 +-
 contrib/less/evar.c          |    2 +-
 contrib/less/filename.c      |   20 +-
 contrib/less/fmt.uni         |    2 +-
 contrib/less/forwback.c      |   37 +-
 contrib/less/funcs.h         |   75 ++-
 contrib/less/help.c          |    9 +-
 contrib/less/ifile.c         |   12 +-
 contrib/less/input.c         |    3 +-
 contrib/less/jump.c          |   18 +-
 contrib/less/lang.h          |    5 +-
 contrib/less/less.h          |   19 +-
 contrib/less/less.hlp        |    7 +-
 contrib/less/less.nro        | 1495 ++++++++++++++++++++++++++++--------------
 contrib/less/lessecho.c      |    2 +-
 contrib/less/lessecho.nro    |   37 +-
 contrib/less/lesskey.c       |    2 +-
 contrib/less/lesskey.h       |    2 +-
 contrib/less/lesskey.nro     |  389 +++++++----
 contrib/less/lesskey_parse.c |   37 +-
 contrib/less/lglob.h         |    2 +-
 contrib/less/line.c          |   39 +-
 contrib/less/linenum.c       |    2 +-
 contrib/less/lsystem.c       |   22 +-
 contrib/less/main.c          |   55 +-
 contrib/less/mark.c          |  154 +++--
 contrib/less/omit.uni        |    2 +-
 contrib/less/optfunc.c       |  132 ++--
 contrib/less/option.c        |  134 ++--
 contrib/less/option.h        |    3 +-
 contrib/less/opttbl.c        |   11 +-
 contrib/less/os.c            |   65 +-
 contrib/less/output.c        |   38 +-
 contrib/less/pattern.c       |    2 +-
 contrib/less/pattern.h       |    2 +-
 contrib/less/pckeys.h        |   45 +-
 contrib/less/position.c      |   16 +-
 contrib/less/position.h      |    2 +-
 contrib/less/prompt.c        |   38 +-
 contrib/less/screen.c        |  527 ++++++++++-----
 contrib/less/scrsize.c       |    2 +-
 contrib/less/search.c        |   23 +-
 contrib/less/signal.c        |   30 +-
 contrib/less/tags.c          |    9 +-
 contrib/less/ttyin.c         |    6 +-
 contrib/less/ubin.uni        |    2 +-
 contrib/less/version.c       |   21 +-
 contrib/less/wide.uni        |   23 +-
 contrib/less/xbuf.c          |   12 +-
 contrib/less/xbuf.h          |   11 +-
 usr.bin/less/defines.h       |  116 ++--
 64 files changed, 2852 insertions(+), 1451 deletions(-)

diff --git a/contrib/less/LICENSE b/contrib/less/LICENSE
index b9b72a3d088b..313cebd4f66f 100644
--- a/contrib/less/LICENSE
+++ b/contrib/less/LICENSE
@@ -2,7 +2,7 @@
                           ------------
 
 Less
-Copyright (C) 1984-2025  Mark Nudelman
+Copyright (C) 1984-2026  Mark Nudelman
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
diff --git a/contrib/less/NEWS b/contrib/less/NEWS
index 442fe21e406a..0f767aaeb059 100644
--- a/contrib/less/NEWS
+++ b/contrib/less/NEWS
@@ -9,6 +9,89 @@
   Report bugs, suggestions or comments at 
   https://github.com/gwsw/less/issues.
 
+======================================================================
+
+	Major changes between "less" versions 691 and 692
+
+* Revert HOME key to scroll to beginning of file and END key
+  to scroll to end of file (github #658).
+
+* Configure tty to leave CR and NL unmodified (github #703).
+
+* Add commands to lesskey parser (forw-bell-hilite, goto-pos and osc8-jump).
+
+* Add key sequences to lesskey parser (\kE, \kF, \kH, \kI, \kM, and \kS).
+
+* Fix bug using negative value with -z option (github #709).
+
+* Fix bug handling empty terminfo capabilties (github #710).
+
+* Fix memory leak in setupterm (github #707).
+
+* Make lesstest ignore system locale (nl_langinfo) (github #708).
+
+======================================================================
+
+	Major changes between "less" versions 685 and 691
+
+* Add --autosave option (github #678).
+
+* Add ESC-f command (github #680).
+
+* Add column number to long prompt and = message.
+
+* Add prompt prototype sequences %C, %W, %Q and ?Q (github #685).
+
+* Map keypad keys, and use terminfo rather than termcap since keypad
+  definitions don't exist in termcap (github #650).
+
+* Change HOME key to scroll fully left and END key to scroll fully right.
+  Add shift-HOME and ctrl-HOME to scroll left and jump to top, and
+  add shift-END and ctrl-END to scroll right and jump to end (github #658).
+
+* Add LESSNOCONFIG environment variable.
+
+* Add --without-termlib to configure (github #701).
+
+* When setting line number colors (-DN), don't force bold attribute.
+  To set bold, you must append "d" or "*" to the color string (github #684).
+
+* While waiting for file data, only ^C or ^X will interrupt, not any command.
+  This reverts to behavior that existed before less-670 (github #700).
+
+* When --save-marks is not used, retain any marks saved in the history file
+  (github #662).
+
+* Defer sending the terminal init string until the first char is read
+  from the input file (github #682).
+
+* Make SIGHUP do an orderly exit like SIGTERM.
+
+* Implement modeline handling in Windows build.
+
+* Fix bugs and improve behavior of screen resize on Windows.
+
+* Fix bug when entering search modifier key at start of non-empty 
+  search string (github #668).
+
+* Fix bug repainting screen with --form-feed (github #672).
+
+* Fix bugs passing invalid negative values to some command line
+  options (github #675).
+
+* Fix incorrect display of Lit indicator (github #670).
+
+* Fix incorrect display when returning to a mark after resizeing window
+  (github #681).
+
+* Fix bug using --pattern with --incsearch (github #696).
+
+* Disallow mouse click to open OSC8 link in SECURE mode (github #676).
+
+* Add SECURE_COMPILE environment variable for Windows builds.
+
+* Update Unicode tables.
+
 ======================================================================
 
 	Major changes between "less" versions 679 and 685
diff --git a/contrib/less/README b/contrib/less/README
index 4bfdc5e5a67f..a6954eb67c1e 100644
--- a/contrib/less/README
+++ b/contrib/less/README
@@ -84,7 +84,7 @@ INSTALLATION (Unix & Linux systems only):
    Makefile now.  Take particular notice of the list of "terminal" 
    libraries in the LIBS definition in the Makefile; these may need 
    to be edited.  The terminal libraries will be some subset of
-       -lncurses  -lcurses  -ltermcap  -ltermlib
+    -ltinfo -ltinfow -lxcurses -lncursesw -lncurses -lcurses -ltermcap -ltermlib
 
    If you wish, you may edit defines.h to remove some optional features.
    If you choose not to include some features in your version, you may
@@ -117,6 +117,29 @@ programmers", not "persons who attempt to circumvent computer security".)
 
 
 
+=======================================================================
+INSTALLATION (Windows-95, Windows-98 and Windows-NT systems only,
+              with Microsoft Visual C++, mingw, or Borland C)
+
+1. Move the distributed source to its own directory.
+
+2. If you wish, you may edit defines.wn to remove some optional features.
+   If you choose not to include some features in your version, you may
+   wish to edit the manual page less.man and the help page help.c
+   to remove the descriptions of the features which you are removing.
+
+3. If you are using Microsoft Visual C++, run "nmake -f Makefile.wnm".
+   If you are using mingw, run "make -f Makefile.wng".
+   If you are using Borland C, run "make -f Makefile.wnb".
+
+   If the environment variable SECURE_COMPILE is to 1 during the make,
+   a "secure" version of less is built, with some features disabled.
+
+4. If the make succeeds, it will generate the programs "less.exe" and
+   "lesskey.exe" in your current directory.  Test the generated programs.
+
+
+
 =======================================================================
 INSTALLATION (MS-DOS systems only,
               with Microsoft C, Borland C, or DJGPP)
@@ -156,34 +179,6 @@ INSTALLATION (MS-DOS systems only,
 
 
 
-=======================================================================
-INSTALLATION (Windows-95, Windows-98 and Windows-NT systems only,
-              with Borland C or Microsoft Visual C++)
-
-1. Move the distributed source to its own directory.
-
-2. If you are using Borland C, rename Makefile.wnb to Makefile.
-   If you are using Microsoft Visual C++, rename Makefile.wnm to Makefile.
-
-3. Check the Makefile to make sure the definitions look ok.
-
-4. If you wish, you may edit defines.wn to remove some optional features.
-   If you choose not to include some features in your version, you may
-   wish to edit the manual page less.man and the help page help.c
-   to remove the descriptions of the features which you are removing.
-
-5. Type "make" and watch the fun.
-
-6. If the make succeeds, it will generate the programs "less.exe" and
-   "lesskey.exe" in your current directory.  Test the generated programs.
-
-7. When satisfied that it works, if you wish to install it
-   in a public place, type "make install".
-   See step 6 of the Unix installation instructions for details
-   on how to change the default installation directories.
-
-
-
 =======================================================================
 INSTALLATION (OS/2 systems only,
               with EMX C)
@@ -245,10 +240,3 @@ INSTALLATION (OS-9 systems only,
    See step 6 of the Unix installation instructions for details
    on how to change the default installation directories.
 
-=======================================================================
-ACKNOWLEDGMENTS:
-  Some versions of the less distribution are packaged using 
-  Info-ZIP's compression utility.
-  Info-ZIP's software is free and can be obtained as source 
-  code or executables from various anonymous-ftp sites,
-  including ftp.uu.net:/pub/archiving/zip.
diff --git a/contrib/less/brac.c b/contrib/less/brac.c
index 36f31d0316f4..b3b74e07d18a 100644
--- a/contrib/less/brac.c
+++ b/contrib/less/brac.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2025  Mark Nudelman
+ * Copyright (C) 1984-2026  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.
diff --git a/contrib/less/ch.c b/contrib/less/ch.c
index fb7572e7f88a..47d31ecffadd 100644
--- a/contrib/less/ch.c
+++ b/contrib/less/ch.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2025  Mark Nudelman
+ * Copyright (C) 1984-2026  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.
@@ -22,7 +22,7 @@
 
 typedef POSITION BLOCKNUM;
 
-public int ignore_eoi;
+public lbool ignore_eoi = FALSE;
 
 /*
  * Pool of buffers holding the most recently used blocks of the input file.
@@ -883,13 +883,13 @@ public void ch_init(int f, int flags, ssize_t nread)
 	 */
 	ch_fsize = (flags & CH_HELPFILE) ? size_helpdata : filesize(ch_file);
 
-	/*
-	 * This is a kludge to workaround a Linux kernel bug: files in some
-	 * pseudo filesystems like /proc and tracefs have a size of 0 according
-	 * to fstat() but have readable data.
-	 */
 	if (ch_fsize == 0 && nread > 0)
 	{
+		/*
+		 * This is a kludge to workaround a Linux kernel bug: files in some
+		 * pseudo filesystems like /proc and tracefs have a size of 0 according
+		 * to fstat() but have readable data.
+		 */
 		ch_flags |= CH_NOTRUSTSIZE;
 	}
 
diff --git a/contrib/less/charset.c b/contrib/less/charset.c
index 0f62739bc88d..74159404148b 100644
--- a/contrib/less/charset.c
+++ b/contrib/less/charset.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2025  Mark Nudelman
+ * Copyright (C) 1984-2026  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.
@@ -202,20 +202,20 @@ static void ichardef_utf(constant char *s)
 			switch (*s++)
 			{
 			case 'b':
-				xbuf_add_data(&user_ubin_array, (unsigned char *) &range, sizeof(range));
+				xbuf_add_data(&user_ubin_array, &range, sizeof(range));
 				break;
 			case 'c':
-				xbuf_add_data(&user_compose_array, (unsigned char *) &range, sizeof(range));
+				xbuf_add_data(&user_compose_array, &range, sizeof(range));
 				break;
 			case 'd':
-				xbuf_add_data(&user_omit_array, (unsigned char *) &range, sizeof(range));
+				xbuf_add_data(&user_omit_array, &range, sizeof(range));
 				break;
 			case 'w':
-				xbuf_add_data(&user_wide_array, (unsigned char *) &range, sizeof(range));
-				xbuf_add_data(&user_prt_array, (unsigned char *) &range, sizeof(range));
+				xbuf_add_data(&user_wide_array, &range, sizeof(range));
+				xbuf_add_data(&user_prt_array, &range, sizeof(range));
 				break;
 			case 'p': case '.':
-				xbuf_add_data(&user_prt_array, (unsigned char *) &range, sizeof(range));
+				xbuf_add_data(&user_prt_array, &range, sizeof(range));
 				break;
 			case '\0':
 				s--;
@@ -429,13 +429,21 @@ static void set_charset(void)
 	/*
 	 * Try using the codeset name as the charset name.
 	 */
-	s = nl_langinfo(CODESET);
-	if (icharset(s, 1))
-		return;
+#if LESSTEST
+	/*
+	 * Don't check nl_langinfo in lesstest mode; charset should come
+	 * only from environment variables, not from the system locale.
+	 */
+	if (0) /* {{ unfortunately it's too early to use is_lesstest }} */
+#endif
+	{
+		s = nl_langinfo(CODESET);
+		if (icharset(s, 1))
+			return;
+	}
 #endif
 #endif
 
-#if HAVE_STRSTR
 	/*
 	 * Check whether LC_ALL, LC_CTYPE or LANG look like UTF-8 is used.
 	 */
@@ -448,7 +456,6 @@ static void set_charset(void)
 			if (icharset("utf-8", 1))
 				return;
 	}
-#endif
 
 #if HAVE_LOCALE
 	/*
diff --git a/contrib/less/charset.h b/contrib/less/charset.h
index 4acf494b4ed5..cf2e02547cb5 100644
--- a/contrib/less/charset.h
+++ b/contrib/less/charset.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2025  Mark Nudelman
+ * Copyright (C) 1984-2026  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.
diff --git a/contrib/less/cmd.h b/contrib/less/cmd.h
index 07c57b111aee..945f99719d0c 100644
--- a/contrib/less/cmd.h
+++ b/contrib/less/cmd.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2025  Mark Nudelman
+ * Copyright (C) 1984-2026  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.
@@ -86,6 +86,7 @@
 #define A_OSC8_JUMP            74
 #define A_START_PASTE          75 /* must not overlap EC_* */
 #define A_END_PASTE            76 /* must not overlap EC_* */
+#define A_F_FOREVER_BELL       77
 
 /* These values must not conflict with any A_* or EC_* value. */
 #define A_INVALID              100
@@ -155,4 +156,27 @@
 #define SK_BACKTAB             15
 #define SK_CTL_BACKSPACE       16
 #define SK_BACKSPACE           17
+#define SK_PAD_U               18
+#define SK_PAD_D               19
+#define SK_PAD_R               20
+#define SK_PAD_L               21
+#define SK_PAD_UR              22
+#define SK_PAD_UL              23
+#define SK_PAD_DR              24
+#define SK_PAD_DL              25
+#define SK_PAD_CENTER          26
+#define SK_PAD_STAR            27
+#define SK_PAD_SLASH           28
+#define SK_PAD_DASH            29
+#define SK_PAD_PLUS            30
+#define SK_PAD_DOT             31
+#define SK_PAD_COMMA           32
+#define SK_PAD_ZERO            33
+#define SK_SHIFT_HOME          34
+#define SK_SHIFT_END           35
+#define SK_CTL_HOME            36
+#define SK_CTL_END             37
+#define SK_SHIFT_LEFT_ARROW    38
+#define SK_SHIFT_RIGHT_ARROW   39
+
 #define SK_CONTROL_K           40
diff --git a/contrib/less/cmdbuf.c b/contrib/less/cmdbuf.c
index f2963cf4c9da..1c3b3d461ad9 100644
--- a/contrib/less/cmdbuf.c
+++ b/contrib/less/cmdbuf.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2025  Mark Nudelman
+ * Copyright (C) 1984-2026  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.
@@ -23,7 +23,7 @@
 extern int sc_width;
 extern int utf_mode;
 extern int no_hist_dups;
-extern int marks_modified;
+extern lbool marks_modified;
 extern int no_paste;
 public lbool pasting = FALSE;
 
@@ -35,6 +35,9 @@ static int cmd_offset;           /* Index into cmdbuf of first displayed char */
 static lbool literal;            /* Next input char should not be interpreted */
 static size_t updown_match;      /* Prefix length in up/down movement */
 static lbool have_updown_match = FALSE;
+#if LESS_INSERT_MODE
+static lbool insert_mode = TRUE;
+#endif
 
 static int cmd_complete(int action);
 /*
@@ -189,7 +192,7 @@ public int len_cmdbuf(void)
  */
 public lbool cmdbuf_empty(void)
 {
-	return cp == cmdbuf && cmd_mbc_buf_len == 0;
+	return cmdbuf[0] == '\0' && cmd_mbc_buf_len == 0;
 }
 
 /*
@@ -454,39 +457,6 @@ static int cmd_left(void)
 	return (CC_OK);
 }
 
-/*
- * Insert a char into the command buffer, at the current position.
- */
-static int cmd_ichar(constant char *cs, size_t clen)
-{
-	char *s;
-	
-	if (strlen(cmdbuf) + clen >= sizeof(cmdbuf)-1)
-	{
-		/* No room in the command buffer for another char. */
-		bell();
-		return (CC_ERROR);
-	}
-		
-	/*
-	 * Make room for the new character (shift the tail of the buffer right).
-	 */
-	for (s = &cmdbuf[strlen(cmdbuf)];  s >= cp;  s--)
-		s[clen] = s[0];
-	/*
-	 * Insert the character into the buffer.
-	 */
-	for (s = cp;  s < cp + clen;  s++)
-		*s = *cs++;
-	/*
-	 * Reprint the tail of the line from the inserted char.
-	 */
-	have_updown_match = FALSE;
-	cmd_repaint(cp);
-	cmd_right();
-	return (CC_OK);
-}
-
 /*
  * Backspace in the command buffer.
  * Delete the char to the left of the cursor.
@@ -502,7 +472,7 @@ static int cmd_erase(void)
 		 * Backspace past beginning of the buffer:
 		 * this usually means abort the command.
 		 */
-		return (CC_QUIT);
+		return CC_QUIT;
 	}
 	/*
 	 * Move cursor left (to the char being erased).
@@ -532,7 +502,7 @@ static int cmd_erase(void)
 	 * to abort the current command, if CF_QUIT_ON_ERASE is set.
 	 */
 	if ((curr_cmdflags & CF_QUIT_ON_ERASE) && cp == cmdbuf && *cp == '\0')
-		return (CC_QUIT);
+		return CC_QUIT;
 	return (CC_OK);
 }
 
@@ -554,6 +524,43 @@ static int cmd_delete(void)
 	return (CC_OK);
 }
 
+/*
+ * Insert a char into the command buffer, at the current position.
+ */
+static int cmd_ichar(constant char *cs, size_t clen)
+{
+	char *s;
+	
+	if (strlen(cmdbuf) + clen >= sizeof(cmdbuf)-1)
+	{
+		/* No room in the command buffer for another char. */
+		lbell();
+		return (CC_ERROR);
+	}
+		
+#if LESS_INSERT_MODE
+	if (!insert_mode)
+		cmd_delete();
+#endif
+	/*
+	 * Make room for the new character (shift the tail of the buffer right).
+	 */
+	for (s = &cmdbuf[strlen(cmdbuf)];  s >= cp;  s--)
+		s[clen] = s[0];
+	/*
+	 * Insert the character into the buffer.
+	 */
+	for (s = cp;  s < cp + clen;  s++)
+		*s = *cs++;
+	/*
+	 * Reprint the tail of the line from the inserted char.
+	 */
+	have_updown_match = FALSE;
+	cmd_repaint(cp);
+	cmd_right();
+	return (CC_OK);
+}
+
 /*
  * Delete the "word" to the left of the cursor.
  */
@@ -612,7 +619,7 @@ static int cmd_kill(void)
 	if (cmdbuf[0] == '\0')
 	{
 		/* Buffer is already empty; abort the current command. */
-		return (CC_QUIT);
+		return CC_QUIT;
 	}
 	cmd_offset = 0;
 	cmd_home();
@@ -625,7 +632,7 @@ static int cmd_kill(void)
 	 * to abort the current command, if CF_QUIT_ON_ERASE is set.
 	 */
 	if (curr_cmdflags & CF_QUIT_ON_ERASE)
-		return (CC_QUIT);
+		return CC_QUIT;
 	return (CC_OK);
 }
 
@@ -660,7 +667,7 @@ static int cmd_updown(int action)
 		/*
 		 * The current command has no history list.
 		 */
-		bell();
+		lbell();
 		return (CC_OK);
 	}
 
@@ -705,7 +712,7 @@ static int cmd_updown(int action)
 	/*
 	 * We didn't find a history entry that matches.
 	 */
-	bell();
+	lbell();
 	return (CC_OK);
 }
 
@@ -796,6 +803,15 @@ public void cmd_addhist(struct mlist *mlist, constant char *cmd, lbool modified)
 	 * Thus, an UPARROW will always retrieve the previous command.
 	 */
 	mlist->curr_mp = ml->next;
+	if (modified)
+	{
+		if (mlist == &mlist_search && autosave_action('/'))
+			save_cmdhist();
+#if SHELL_ESCAPE || PIPEC
+		else if (mlist == &mlist_shell && autosave_action('!'))
+			save_cmdhist();
+#endif
+	}
 #endif
 }
 
@@ -904,6 +920,9 @@ static int cmd_edit(char c, lbool stay_in_completion)
 		return (CC_OK);
 	case EC_INSERT:
 		not_in_completion();
+#if LESS_INSERT_MODE
+		insert_mode = !insert_mode;
+#endif
 		return (CC_OK);
 	case EC_BACKSPACE:
 		not_in_completion();
@@ -914,7 +933,7 @@ static int cmd_edit(char c, lbool stay_in_completion)
 	case EC_ABORT:
 		not_in_completion();
 		(void) cmd_kill();
-		return (CC_QUIT);
+		return CC_QUIT;
 	case EC_W_BACKSPACE:
 		not_in_completion();
 		return (cmd_werase());
@@ -950,17 +969,23 @@ static int cmd_istr(constant char *str)
 {
 	constant char *endline = str + strlen(str);
 	constant char *s;
-	int action;
-	
+	int action = CC_OK;
+#if LESS_INSERT_MODE
+	lbool save_insert_mode = insert_mode;
+	insert_mode = TRUE;
+#endif
 	for (s = str;  *s != '\0';  )
 	{
 		constant char *os = s;
 		step_charc(&s, +1, endline);
 		action = cmd_ichar(os, ptr_diff(s, os));
 		if (action != CC_OK)
-			return (action);
+			break;
 	}
-	return (CC_OK);
+#if LESS_INSERT_MODE
+	insert_mode = save_insert_mode;
+#endif
+	return (action);
 }
 
 /*
@@ -1171,7 +1196,7 @@ static int cmd_complete(int action)
 #endif /* TAB_COMPLETE_FILENAME */
 		if (tk_text == NULL)
 		{
-			bell();
+			lbell();
 			return (CC_OK);
 		}
 		if (action == EC_EXPAND)
@@ -1239,7 +1264,7 @@ static int cmd_complete(int action)
 	
 fail:
 	in_completion = FALSE;
-	bell();
+	lbell();
 	return (CC_OK);
 }
 
@@ -1281,7 +1306,7 @@ static int cmd_uchar(char c, size_t *plen)
 			} else
 			{
 				/* UTF8_INVALID or stray UTF8_TRAIL */
-				bell();
+				lbell();
 				return (CC_ERROR);
 			}
 		} else if (IS_UTF8_TRAIL(c))
@@ -1293,14 +1318,14 @@ static int cmd_uchar(char c, size_t *plen)
 			{
 				/* complete, but not well formed (non-shortest form), sequence */
 				cmd_mbc_buf_len = 0;
-				bell();
+				lbell();
 				return (CC_ERROR);
 			}
 		} else
 		{
 			/* Flush incomplete (truncated) sequence.  */
 			cmd_mbc_buf_len = 0;
-			bell();
+			lbell();
 			/* Handle new char.  */
 			goto retry;
 		}
@@ -1388,7 +1413,6 @@ public LINENUM cmd_int(mutable long *frac)
 {
 	constant char *p;
 	LINENUM n = 0;
-	lbool err;
 
 	for (p = cmdbuf;  *p >= '0' && *p <= '9';  p++)
 	{
@@ -1401,8 +1425,8 @@ public LINENUM cmd_int(mutable long *frac)
 	*frac = 0;
 	if (*p++ == '.')
 	{
-		*frac = getfraction(&p, NULL, &err);
-		/* {{ do something if err is set? }} */
+		/* {{ Just ignore error in fractional part. }} */
+		(void) getfraction(&p, frac);
 	}
 	return (n);
 }
@@ -1447,7 +1471,7 @@ static int mlist_size(struct mlist *ml)
 static char * histfile_find(lbool must_exist)
 {
 	constant char *home = lgetenv("HOME");
-	char *name = NULL;
+	char *name;
 
 	/* Try in $XDG_STATE_HOME, then in $HOME/.local/state, then in $XDG_DATA_HOME, then in $HOME. */
 #if OS2
@@ -1738,7 +1762,7 @@ public void save_cmdhist(void)
 	int skip_shell;
 	struct save_ctx ctx;
 	constant char *s;
-	FILE *fout = NULL;
+	FILE *fout;
 	int histsize = 0;
 
 	if (!secure_allow(SF_HISTORY) || !histfile_modified())
diff --git a/contrib/less/command.c b/contrib/less/command.c
index 390385547385..1bb8d006f8ec 100644
--- a/contrib/less/command.c
+++ b/contrib/less/command.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2025  Mark Nudelman
+ * Copyright (C) 1984-2026  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.
@@ -32,7 +32,7 @@ extern int jump_sline;
 extern lbool quitting;
 extern int wscroll;
 extern int top_scroll;
-extern int ignore_eoi;
+extern lbool ignore_eoi;
 extern int hshift;
 extern int bs_mode;
 extern int proc_backspace;
@@ -49,7 +49,6 @@ extern void *ml_examine;
 extern int wheel_lines;
 extern int def_search_type;
 extern lbool search_wrapped;
-extern lbool no_poll;
 extern int no_paste;
 extern lbool pasting;
 extern int no_edit_warn;
@@ -154,7 +153,7 @@ static void start_mca(int action, constant char *prompt, void *mlist, int cmdfla
 	set_mlist(mlist, cmdflags);
 }
 
-public int in_mca(void)
+public lbool in_mca(void)
 {
 	return (mca != 0 && mca != A_PREFIX);
 }
@@ -476,7 +475,7 @@ static int mca_opt_nonfirst_char(char c)
 		}
 	} else if (!ambig)
 	{
-		bell();
+		lbell();
 	}
 	return (MCA_MORE);
 }
@@ -575,7 +574,10 @@ static int mca_search_char(char c)
 	 */
 	if (!cmdbuf_empty() || literal_char)
 	{
+		lbool was_literal_char = literal_char;
 		literal_char = FALSE;
+		if (was_literal_char)
+			mca_search1();
 		return (NO_MCA);
 	}
 
@@ -639,6 +641,17 @@ static int mca_search_char(char c)
 	return (NO_MCA);
 }
 
+/*
+ * Jump back to the starting position of an incremental search.
+ */
+static void jump_search_incr_pos(void)
+{
+	if (search_incr_pos.pos == NULL_POSITION)
+		return;
+	hshift = search_incr_hshift;
+	jump_loc(search_incr_pos.pos, search_incr_pos.ln);
+}
+
 /*
  * Handle a character of a multi-character command.
  */
@@ -772,30 +785,21 @@ static int mca_char(char c)
 			if (*pattern == '\0')
 			{
 				/* User has backspaced to an empty pattern. */
-				undo_search(1);
-				hshift = search_incr_hshift;
-				jump_loc(search_incr_pos.pos, search_incr_pos.ln);
+				undo_search(TRUE);
+				jump_search_incr_pos();
 			} else
 			{
-				/*
-				 * Suppress tty polling while searching.
-				 * This avoids a problem where tty input
-				 * can cause the search to be interrupted.
-				 */
-				no_poll = TRUE;
 				if (search(st | SRCH_INCR, pattern, 1) != 0)
 				{
 					/* No match, invalid pattern, etc. */
-					undo_search(1);
-					hshift = search_incr_hshift;
-					jump_loc(search_incr_pos.pos, search_incr_pos.ln);
+					undo_search(TRUE);
+					jump_search_incr_pos();
 				}
-				no_poll = FALSE;
 			}
 			/* Redraw the search prompt and search string. */
 			if (is_screen_trashed() || !full_screen)
 			{
-				clear();
+				lclear();
 				repaint();
 			}
 			mca_search1();
@@ -851,7 +855,7 @@ static void make_display(void)
 	 * We need to clear and repaint screen before any change.
 	 */
 	if (!full_screen && !(quit_if_one_screen && one_screen))
-		clear();
+		lclear();
 	/*
 	 * If nothing is displayed yet, display starting from initial_scrpos.
 	 */
@@ -864,9 +868,9 @@ static void make_display(void)
 	} else if (is_screen_trashed() || !full_screen)
 	{
 		int save_top_scroll = top_scroll;
-		int save_ignore_eoi = ignore_eoi;
+		lbool save_ignore_eoi = ignore_eoi;
 		top_scroll = 1;
-		ignore_eoi = 0;
+		ignore_eoi = FALSE;
 		if (is_screen_trashed() == 2)
 		{
 			/* Special case used by ignore_eoi: re-open the input file
@@ -1304,29 +1308,31 @@ static void multi_search(constant char *pattern, int n, int silent)
 /*
  * Forward forever, or until a highlighted line appears.
  */
-static int forw_loop(int until_hilite)
+static int forw_loop(int action)
 {
-	POSITION curr_len;
+	POSITION prev_hilite;
 
 	if (ch_getflags() & CH_HELPFILE)
 		return (A_NOACTION);
 
 	cmd_exec();
 	jump_forw_buffered();
-	curr_len = ch_length();
-	highest_hilite = until_hilite ? curr_len : NULL_POSITION;
-	ignore_eoi = 1;
+	highest_hilite = prev_hilite = 0;
+	ignore_eoi = TRUE;
 	while (!sigs)
 	{
-		if (until_hilite && highest_hilite > curr_len)
+		if (action != A_F_FOREVER && highest_hilite > prev_hilite)
 		{
-			bell();
-			break;
+			lbell();
+			if (action == A_F_UNTIL_HILITE)
+				break;
+			prev_hilite = highest_hilite;
 		}
 		make_display();
 		forward(1, FALSE, FALSE, FALSE);
 	}
-	ignore_eoi = 0;
+	highest_hilite = NULL_POSITION;
+	ignore_eoi = FALSE;
 	ch_set_eof();
 
 	/*
@@ -1334,7 +1340,7 @@ static int forw_loop(int until_hilite)
 	 * a non-abort signal (e.g. window-change).  
 	 */
 	if (sigs && !ABORT_SIGS())
-		return (until_hilite ? A_F_UNTIL_HILITE : A_F_FOREVER);
+		return (action);
 
 	return (A_NOACTION);
 }
@@ -1401,7 +1407,6 @@ public void commands(void)
 #endif
 
 	search_type = SRCH_FORW;
-	wscroll = (sc_height + 1) / 2;
 	newaction = A_NOACTION;
 
 	for (;;)
@@ -1507,7 +1512,9 @@ public void commands(void)
 				 * want erase_char/kill_char to be treated
 				 * as line editing characters.
 				 */
-				constant char tbuf[2] = { c, '\0' };
+				char tbuf[2];
+				tbuf[0] = c;
+				tbuf[1] = '\0';
 				action = fcmd_decode(tbuf, &extra);
 			}
 			/*
@@ -1664,6 +1671,8 @@ public void commands(void)
 			break;
 
*** 8504 LINES SKIPPED ***
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.