The branch releng/15.1 has been updated by cperciva:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=109324d5e7ab893c15540fe97325b3eeaee88d20

commit 109324d5e7ab893c15540fe97325b3eeaee88d20
Author:     Xin LI <[email protected]>
AuthorDate: 2026-05-07 03:51:51 +0000
Commit:     Colin Percival <[email protected]>
CommitDate: 2026-05-07 17:24:43 +0000

    MFV less v691
    
    Approved by:    re (cperciva)
    Relnotes:       yes
    
    (cherry picked from commit dafba19e42e78cd3d7c9264ece49ddd3d7d70da5)
    
    MFV: less v692.
    
    (cherry picked from commit e2abec625bf07c054f7ac2df2402d6c454113df8)
    (cherry picked from commit 423b0bc492d5264ee518c6569d3c90ee0efb338c)
---
 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);
                        }
                        /*
*** 8507 LINES SKIPPED ***

Reply via email to