diff --git a/COPYING b/COPYING
index 94a9ed0..f288702 100644
--- a/COPYING
+++ b/COPYING
@@ -1,7 +1,7 @@
                     GNU GENERAL PUBLIC LICENSE
                        Version 3, 29 June 2007
 
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
  Everyone is permitted to copy and distribute verbatim copies
  of this license document, but changing it is not allowed.
 
@@ -645,7 +645,7 @@ the "copyright" line and a pointer to where the full notice is found.
     GNU General Public License for more details.
 
     You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 Also add information on how to contact you by electronic and paper mail.
 
@@ -664,11 +664,11 @@ might be different; for a GUI interface, you would use an "about box".
   You should also get your employer (if you work as a programmer) or school,
 if any, to sign a "copyright disclaimer" for the program, if necessary.
 For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
+<https://www.gnu.org/licenses/>.
 
   The GNU General Public License does not permit incorporating your program
 into proprietary programs.  If your program is a subroutine library, you
 may consider it more useful to permit linking proprietary applications with
 the library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.  But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+<https://www.gnu.org/licenses/why-not-lgpl.html>.
diff --git a/LICENSE b/LICENSE
index 315d1d8..65bce42 100644
--- a/LICENSE
+++ b/LICENSE
@@ -2,7 +2,7 @@
                           ------------
 
 Less
-Copyright (C) 1984-2018  Mark Nudelman
+Copyright (C) 1984-2022  Mark Nudelman
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
diff --git a/Makefile.aut b/Makefile.aut
index f0eb26d..29e7de9 100644
--- a/Makefile.aut
+++ b/Makefile.aut
@@ -69,7 +69,6 @@ ${srcdir}/configure ${srcdir}/defines.h.in: ${srcdir}/configure.ac ${srcdir}/Mak
 funcs.h: ${SRC:%=${srcdir}/%}
 	-mv -f ${srcdir}/funcs.h ${srcdir}/funcs.h.old
 	${srcdir}/${MKFUNCS} ${SRC:%=${srcdir}/%} >${srcdir}/funcs.h
-	if cmp -s funcs.h funcs.h.old; then mv -f funcs.h.old funcs.h; fi
 
 lint:
 	lint -I. ${CPPFLAGS} ${SRC}
@@ -123,7 +122,7 @@ unicode/EastAsianWidth.txt:
 distfiles: ${DISTFILES}
 
 echo_distfiles: 
-	echo ${DISTFILES}
+	@echo ${DISTFILES}
 
 dist: ${DISTFILES}
 	if [ ! -d ${srcdir}/release ]; then mkdir ${srcdir}/release; fi
diff --git a/NEWS b/NEWS
index a403c5d..799e4d5 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,57 @@
   Report bugs, suggestions or comments at 
   https://github.com/gwsw/less/issues.
 
+======================================================================
+
+	Major changes between "less" versions 590 and 600
+
+* Add the --header option.
+
+* Add the --no-number-headers option.
+
+* Add the --status-line option.
+
+* Add the --redraw-on-quit option.
+
+* Add the --search-options option.
+
+* Add 'H' color type to set color of header lines.
+
+* Add #version conditional to lesskey.
+
+* Add += syntax to variable section in lesskey files.
+
+* Allow option name in -- command to end with '=' in addition to '\n'.
+
+* Add $HOME/.config to possible locations of lesskey file.
+
+* Add $XDG_STATE_HOME and $HOME/.local/state to possible locations
+  of history file.
+
+* Don't read or write history file in secure mode.
+
+* Fix display of multibyte and double-width chars in prompt.
+
+* Fix ESC-BACKSPACE command when BACKSPACE key does not send 0x08.
+
+* Add more \k codes to lesskey format.
+
+* Fix bug when empty file is modified while viewing it.
+
+* Fix bug when parsing a malformed lesskey file.
+
+* Fix bug scrolling history when --incsearch is set.
+
+* Fix buffer overflow when invoking lessecho with more than 63 -m/-n options.
+
+* Fix bug restoring color at end of highlighted text.
+
+* Fix bug in parsing lesskey file.
+
+* Defer moving cursor to lower left in some more cases.
+
+* Suppress TAB filename expansion in some cases where it doesn't make sense.
+
 ======================================================================
 
 	Major changes between "less" versions 581 and 590
diff --git a/README b/README
index 955bf82..a4443b6 100644
--- a/README
+++ b/README
@@ -1,6 +1,6 @@
 
     This is the source code distribution of "less".
-    This program is part of the GNU project (http://www.gnu.org).
+    This program is part of the GNU project (https://www.gnu.org).
 
     This program is free software.  You may redistribute it and/or
     modify it under the terms of either:
@@ -20,7 +20,7 @@
 You should build from a clone of a git repository 
 ONLY IF you are doing development on the less source itself.
 If you are merely using less as a tool, you should download a release
-from http://greenwoodsoftware.com and NOT from github.
+from https://greenwoodsoftware.com and NOT from github.
 
 The formatted manual page is in less.man.
 The manual page nroff source is in less.nro.
@@ -33,7 +33,7 @@ INSTALLATION (Unix & Linux systems only):
    if you have not already done so.  
 
 2. If you are building from a clone of a git repository,
-   type "make -f Makefile.aut".
+   type "make -f Makefile.aut distfiles".
    If you are building from a numbered release package (a tar or 
    zip file with a name like less-999.tar.gz or less-999.zip downloaded 
    from greenwoodsoftware.com, not from github), you should skip this step. 
diff --git a/brac.c b/brac.c
index 53ada50..58ecf17 100644
--- a/brac.c
+++ b/brac.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -84,7 +84,11 @@ match_brac(obrac, cbrac, forwdir, n)
 	while ((c = (*chget)()) != EOI)
 	{
 		if (c == obrac)
+		{
+			if (nest == INT_MAX)
+				break;
 			nest++;
+		}
 		else if (c == cbrac && --nest < 0)
 		{
 			/*
diff --git a/ch.c b/ch.c
index 379dd84..bfad09c 100644
--- a/ch.c
+++ b/ch.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -26,6 +26,10 @@ extern dev_t curr_dev;
 extern ino_t curr_ino;
 #endif
 
+#if HAVE_PROCFS
+#include <sys/statfs.h>
+#endif
+
 typedef POSITION BLOCKNUM;
 
 public int ignore_eoi;
@@ -725,7 +729,7 @@ ch_flush(VOID_PARAM)
 	ch_block = 0; /* ch_fpos / LBUFSIZE; */
 	ch_offset = 0; /* ch_fpos % LBUFSIZE; */
 
-#if 1
+#if HAVE_PROCFS
 	/*
 	 * This is a kludge to workaround a Linux kernel bug: files in
 	 * /proc have a size of 0 according to fstat() but have readable 
@@ -734,8 +738,15 @@ ch_flush(VOID_PARAM)
 	 */
 	if (ch_fsize == 0)
 	{
-		ch_fsize = NULL_POSITION;
-		ch_flags &= ~CH_CANSEEK;
+		struct statfs st;
+		if (fstatfs(ch_file, &st) == 0)
+		{
+			if (st.f_type == PROC_SUPER_MAGIC)
+			{
+				ch_fsize = NULL_POSITION;
+				ch_flags &= ~CH_CANSEEK;
+			}
+		}
 	}
 #endif
 
diff --git a/charset.c b/charset.c
index b37c8a2..5e9a2d6 100644
--- a/charset.c
+++ b/charset.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -445,7 +445,7 @@ prchar(c)
 	LWCHAR c;
 {
 	/* {{ This buffer can be overrun if LESSBINFMT is a long string. }} */
-	static char buf[32];
+	static char buf[MAX_PRCHAR_LEN+1];
 
 	c &= 0377;
 	if ((c < 128 || !utf_mode) && !control_char(c))
@@ -480,7 +480,7 @@ prchar(c)
 prutfchar(ch)
 	LWCHAR ch;
 {
-	static char buf[32];
+	static char buf[MAX_PRCHAR_LEN+1];
 
 	if (ch == ESC)
 		strcpy(buf, "ESC");
@@ -805,18 +805,6 @@ is_ubin_char(ch)
 {
 	int ubin = is_in_table(ch, &ubin_table) ||
 	           (bs_mode == BS_CONTROL && is_in_table(ch, &fmt_table));
-#if MSDOS_COMPILER==WIN32C
-	if (!ubin && utf_mode == 2 && ch < 0x10000)
-	{
-		/*
-		 * Consider it binary if it can't be converted.
-		 */
-		BOOL used_default = TRUE;
-		WideCharToMultiByte(GetConsoleOutputCP(), WC_NO_BEST_FIT_CHARS, (LPCWSTR) &ch, 1, NULL, 0, NULL, &used_default);
-		if (used_default)
-			ubin = 1;
-	}
-#endif
 	return ubin;
 }
 
diff --git a/charset.h b/charset.h
index 3e7ecf7..aa6273d 100644
--- a/charset.h
+++ b/charset.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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/cmd.h b/cmd.h
index c51f0bc..b0f3fdb 100644
--- a/cmd.h
+++ b/cmd.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -142,4 +142,5 @@
 #define SK_F1                  14
 #define SK_BACKTAB             15
 #define SK_CTL_BACKSPACE       16
+#define SK_BACKSPACE           17
 #define SK_CONTROL_K           40
diff --git a/cmdbuf.c b/cmdbuf.c
index dd13538..a1c4156 100644
--- a/cmdbuf.c
+++ b/cmdbuf.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -24,6 +24,7 @@ extern int sc_width;
 extern int utf_mode;
 extern int no_hist_dups;
 extern int marks_modified;
+extern int secure;
 
 static char cmdbuf[CMDBUF_SIZE]; /* Buffer for holding a multi-char command */
 static int cmd_col;              /* Current column of the cursor */
@@ -31,7 +32,7 @@ static int prompt_col;           /* Column of cursor just after prompt */
 static char *cp;                 /* Pointer into cmdbuf */
 static int cmd_offset;           /* Index into cmdbuf of first displayed char */
 static int literal;              /* Next input char should not be interpreted */
-static int updown_match = -1;    /* Prefix length in up/down movement */
+public int updown_match = -1;    /* Prefix length in up/down movement */
 
 #if TAB_COMPLETE_FILENAME
 static int cmd_complete LESSPARAMS((int action));
@@ -860,9 +861,10 @@ cmd_edit(c)
 		flags |= ECF_NOHISTORY;
 #endif
 #if TAB_COMPLETE_FILENAME
-	if (curr_mlist == ml_search)
+	if (curr_mlist == ml_search || curr_mlist == NULL)
 		/*
-		 * In a search command; don't accept file-completion cmds.
+		 * Don't accept file-completion cmds in contexts 
+		 * such as search pattern, digits, long option name, etc.
 		 */
 		flags |= ECF_NOCOMPLETE;
 #endif
@@ -1352,7 +1354,15 @@ cmd_int(frac)
 	int err;
 
 	for (p = cmdbuf;  *p >= '0' && *p <= '9';  p++)
-		n = (n * 10) + (*p - '0');
+	{
+		LINENUM nn = (n * 10) + (*p - '0');
+		if (nn < n)
+		{
+			error("Integer is too big", NULL_PARG);
+			return (0);
+		}
+		n = nn;
+	}
 	*frac = 0;
 	if (*p++ == '.')
 	{
@@ -1400,14 +1410,41 @@ mlist_size(ml)
 /*
  * Get the name of the history file.
  */
+	static char *
+histfile_find(must_exist)
+	int must_exist;
+{
+	char *home = lgetenv("HOME");
+	char *name = NULL;
+
+	/* Try in $XDG_STATE_HOME, then in $HOME/.local/state, then in $XDG_DATA_HOME, then in $HOME. */
+#if OS2
+	if (isnullenv(home))
+		home = lgetenv("INIT");
+#endif
+	name = dirfile(lgetenv("XDG_STATE_HOME"), &LESSHISTFILE[1], must_exist);
+	if (name == NULL)
+	{
+		char *dir = dirfile(home, ".local/state", 1);
+		if (dir != NULL)
+		{
+			name = dirfile(dir, &LESSHISTFILE[1], must_exist);
+			free(dir);
+		}
+	}
+	if (name == NULL)
+		name = dirfile(lgetenv("XDG_DATA_HOME"), &LESSHISTFILE[1], must_exist);
+	if (name == NULL)
+		name = dirfile(home, LESSHISTFILE, must_exist);
+	return (name);
+}
+
 	static char *
 histfile_name(must_exist)
 	int must_exist;
 {
-	char *home;
-	char *xdg;
 	char *name;
-	
+
 	/* See if filename is explicitly specified by $LESSHISTFILE. */
 	name = lgetenv("LESSHISTFILE");
 	if (!isnullenv(name))
@@ -1422,25 +1459,14 @@ histfile_name(must_exist)
 	if (strcmp(LESSHISTFILE, "") == 0 || strcmp(LESSHISTFILE, "-") == 0)
 		return (NULL);
 
-	/* Try in $XDG_DATA_HOME first, then in $HOME. */
-	xdg = lgetenv("XDG_DATA_HOME");
-	home = lgetenv("HOME");
-#if OS2
-	if (isnullenv(home))
-		home = lgetenv("INIT");
-#endif
 	name = NULL;
 	if (!must_exist)
 	{
 	 	/* If we're writing the file and the file already exists, use it. */
-		name = dirfile(xdg, &LESSHISTFILE[1], 1);
-		if (name == NULL)
-			name = dirfile(home, LESSHISTFILE, 1);
+		name = histfile_find(1);
 	}
 	if (name == NULL)
-		name = dirfile(xdg, &LESSHISTFILE[1], must_exist);
-	if (name == NULL)
-		name = dirfile(home, LESSHISTFILE, must_exist);
+		name = histfile_find(must_exist);
 	return (name);
 }
 
@@ -1524,17 +1550,22 @@ read_cmdhist(action, uparam, skip_search, skip_shell)
 	int skip_search;
 	int skip_shell;
 {
+	if (secure)
+		return;
 	read_cmdhist2(action, uparam, skip_search, skip_shell);
 	(*action)(uparam, NULL, NULL); /* signal end of file */
 }
 
 	static void
-addhist_init(void *uparam, struct mlist *ml, char *string)
+addhist_init(uparam, ml, string)
+	void *uparam;
+	struct mlist *ml;
+	char constant *string;
 {
 	if (ml != NULL)
 		cmd_addhist(ml, string, 0);
 	else if (string != NULL)
-		restore_mark(string);
+		restore_mark((char*)string); /* stupid const cast */
 }
 #endif /* CMD_HISTORY */
 
@@ -1611,7 +1642,10 @@ struct save_ctx
  * created during this session.
  */
 	static void
-copy_hist(void *uparam, struct mlist *ml, char *string)
+copy_hist(uparam, ml, string)
+	void *uparam;
+	struct mlist *ml;
+	char constant *string;
 {
 	struct save_ctx *ctx = (struct save_ctx *) uparam;
 
@@ -1673,6 +1707,7 @@ make_file_private(f)
 /*
  * Does the history file need to be updated?
  */
+#if CMD_HISTORY
 	static int
 histfile_modified(VOID_PARAM)
 {
@@ -1682,12 +1717,11 @@ histfile_modified(VOID_PARAM)
 	if (mlist_shell.modified)
 		return 1;
 #endif
-#if CMD_HISTORY
 	if (marks_modified)
 		return 1;
-#endif
 	return 0;
 }
+#endif
 
 /*
  * Update the .lesshst file.
@@ -1705,7 +1739,7 @@ save_cmdhist(VOID_PARAM)
 	FILE *fout = NULL;
 	int histsize = 0;
 
-	if (!histfile_modified())
+	if (secure || !histfile_modified())
 		return;
 	histname = histfile_name(0);
 	if (histname == NULL)
diff --git a/command.c b/command.c
index 88a2f8b..2e6ad91 100644
--- a/command.c
+++ b/command.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -48,6 +48,9 @@ extern IFILE curr_ifile;
 extern void *ml_search;
 extern void *ml_examine;
 extern int wheel_lines;
+extern int header_lines;
+extern int def_search_type;
+extern int updown_match;
 #if SHELL_ESCAPE || PIPEC
 extern void *ml_shell;
 #endif
@@ -152,7 +155,7 @@ in_mca(VOID_PARAM)
  * Set up the display to start a new search command.
  */
 	static void
-mca_search(VOID_PARAM)
+mca_search1(VOID_PARAM)
 {
 #if HILITE_SEARCH
 	if (search_type & SRCH_FILTER)
@@ -187,6 +190,12 @@ mca_search(VOID_PARAM)
 	else
 		cmd_putstr("?");
 	forw_prompt = 0;
+}
+
+	static void
+mca_search(VOID_PARAM)
+{
+	mca_search1();
 	set_mlist(ml_search, 0);
 }
 
@@ -340,6 +349,7 @@ is_newline_char(c)
 mca_opt_first_char(c)
 	int c;
 {
+	int no_prompt = (optflag & OPT_NO_PROMPT);
 	int flag = (optflag & ~OPT_NO_PROMPT);
 	if (flag == OPT_NO_TOGGLE)
 	{
@@ -357,14 +367,14 @@ mca_opt_first_char(c)
 		{
 		case '+':
 			/* "-+" = UNSET. */
-			optflag = (flag == OPT_UNSET) ?
-				OPT_TOGGLE : OPT_UNSET;
+			optflag = no_prompt | ((flag == OPT_UNSET) ?
+				OPT_TOGGLE : OPT_UNSET);
 			mca_opt_toggle();
 			return (MCA_MORE);
 		case '!':
 			/* "-!" = SET */
-			optflag = (flag == OPT_SET) ?
-				OPT_TOGGLE : OPT_SET;
+			optflag = no_prompt | ((flag == OPT_SET) ?
+				OPT_TOGGLE : OPT_SET);
 			mca_opt_toggle();
 			return (MCA_MORE);
 		case CONTROL('P'):
@@ -463,7 +473,7 @@ mca_opt_char(c)
 	if (optgetname)
 	{
 		/* We're getting a long option name.  */
-		if (!is_newline_char(c))
+		if (!is_newline_char(c) && c != '=')
 			return (mca_opt_nonfirst_char(c));
 		if (curropt == NULL)
 		{
@@ -507,6 +517,19 @@ mca_opt_char(c)
 	return (MCA_MORE);
 }
 
+/*
+ * Normalize search type.
+ */
+	public int
+norm_search_type(st)
+	int st;
+{
+	/* WRAP and PAST_EOF are mutually exclusive. */
+	if ((st & (SRCH_PAST_EOF|SRCH_WRAP)) == (SRCH_PAST_EOF|SRCH_WRAP))
+		st ^= SRCH_PAST_EOF;
+	return st;
+}
+
 /*
  * Handle a char of a search command.
  */
@@ -557,8 +580,7 @@ mca_search_char(c)
 
 	if (flag != 0)
 	{
-		/* Toggle flag, but keep PAST_EOF and WRAP mutually exclusive. */
-		search_type ^= flag | (search_type & (SRCH_PAST_EOF|SRCH_WRAP));
+		search_type = norm_search_type(search_type ^ flag);
 		mca_search();
 		return (MCA_MORE);
 	}
@@ -680,6 +702,12 @@ mca_char(c)
 			/* Incremental search: do a search after every input char. */
 			int st = (search_type & (SRCH_FORW|SRCH_BACK|SRCH_NO_MATCH|SRCH_NO_REGEX|SRCH_NO_MOVE|SRCH_WRAP));
 			char *pattern = get_cmdbuf();
+			/*
+			 * Must save updown_match because mca_search
+			 * reinits it. That breaks history scrolling.
+			 * {{ This is ugly. mca_search probably shouldn't call set_mlist. }}
+			 */
+			int save_updown_match = updown_match;
 			cmd_exec();
 			if (*pattern == '\0')
 			{
@@ -692,7 +720,8 @@ mca_char(c)
 					undo_search(1);
 			}
 			/* Redraw the search prompt and search string. */
-			mca_search();
+			mca_search1();
+			updown_match = save_updown_match;
 			cmd_repaint(NULL);
 		}
 		break;
@@ -800,7 +829,7 @@ prompt(VOID_PARAM)
 	if (!(ch_getflags() & CH_HELPFILE))
 	{
 		WCHAR w[MAX_PATH+16];
-		p = pr_expand("Less?f - %f.", 0);
+		p = pr_expand("Less?f - %f.");
 		MultiByteToWideChar(CP_ACP, 0, p, -1, w, sizeof(w)/sizeof(*w));
 		SetConsoleTitleW(w);
 	}
@@ -843,9 +872,8 @@ prompt(VOID_PARAM)
 		                    0, w, -1, a, sizeof(a), NULL, NULL);
 		p = a;
 #endif
-		at_enter(AT_STANDOUT|AT_COLOR_PROMPT);
-		putstr(p);
-		at_exit();
+		load_line(p);
+		put_line();
 	}
 	clear_eol();
 }
@@ -922,8 +950,8 @@ getccu(VOID_PARAM)
  */
 	static LWCHAR
 getcc_repl(orig, repl, gr_getc, gr_ungetc)
-	char const* orig;
-	char const* repl;
+	char constant* orig;
+	char constant* repl;
 	LWCHAR (*gr_getc)(VOID_PARAM);
 	void (*gr_ungetc)(LWCHAR);
 {
@@ -1603,7 +1631,7 @@ commands(VOID_PARAM)
 			 * Search forward for a pattern.
 			 * Get the first char of the pattern.
 			 */
-			search_type = SRCH_FORW;
+			search_type = SRCH_FORW | def_search_type;
 			if (number <= 0)
 				number = 1;
 			mca_search();
@@ -1615,7 +1643,7 @@ commands(VOID_PARAM)
 			 * Search backward for a pattern.
 			 * Get the first char of the pattern.
 			 */
-			search_type = SRCH_BACK;
+			search_type = SRCH_BACK | def_search_type;
 			if (number <= 0)
 				number = 1;
 			mca_search();
@@ -1735,7 +1763,7 @@ commands(VOID_PARAM)
 				 */
 				make_display();
 				cmd_exec();
-				lsystem(pr_expand(editproto, 0), (char*)NULL);
+				lsystem(pr_expand(editproto), (char*)NULL);
 				break;
 			}
 #endif
diff --git a/configure b/configure
index 5589f8e..ea63b34 100755
--- a/configure
+++ b/configure
@@ -4694,6 +4694,7 @@ fi
 
 
 
+
 
 
 # Checks for identifiers.
@@ -4792,6 +4793,28 @@ if ac_fn_c_try_compile "$LINENO"; then :
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }; $as_echo "#define HAVE_STAT_INO 1" >>confdefs.h
 
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for procfs" >&5
+$as_echo_n "checking for procfs... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/statfs.h>
+int
+main ()
+{
+struct statfs s; s.f_type = PROC_SUPER_MAGIC; (void) fstatfs(0,&s);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }; $as_echo "#define HAVE_PROCFS 1" >>confdefs.h
+
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
@@ -5346,15 +5369,15 @@ else
 
 #include <sys/types.h>
 #include <regex.h>
-main() { regex_t r; regmatch_t rm; char *text = "xabcy";
-if (regcomp(&r, "abc", 0)) exit(1);
-if (regexec(&r, text, 1, &rm, 0)) exit(1);
+int main() { regex_t r; regmatch_t rm; char *text = "xabcy";
+if (regcomp(&r, "abc", 0)) return (1);
+if (regexec(&r, text, 1, &rm, 0)) return (1);
 #ifndef __WATCOMC__
-if (rm.rm_so != 1) exit(1); /* check for correct offset */
+if (rm.rm_so != 1) return (1); /* check for correct offset */
 #else
-if (rm.rm_sp != text + 1) exit(1); /* check for correct offset */
+if (rm.rm_sp != text + 1) return (1); /* check for correct offset */
 #endif
-exit(0); }
+return (0); }
 _ACEOF
 if ac_fn_c_try_run "$LINENO"; then :
   have_posix_regex=yes
diff --git a/configure.ac b/configure.ac
index 21f550a..15da486 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
 # Process this file with autoconf to produce a configure script.
 
-# Copyright (C) 1984-2011  Mark Nudelman
+# Copyright (C) 1984-2022  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.
@@ -217,6 +217,8 @@ AH_TEMPLATE([HAVE_CONST],
 	[Define HAVE_CONST if your compiler supports the "const" modifier.])
 AH_TEMPLATE([HAVE_STAT_INO],
 	[Define HAVE_STAT_INO if your struct stat has st_ino and st_dev.])
+AH_TEMPLATE([HAVE_PROCFS],
+	[Define HAVE_PROCFS if have have fstatfs with f_type and PROC_SUPER_MAGIC.])
 AH_TEMPLATE([HAVE_TIME_T],
 	[Define HAVE_TIME_T if your system supports the "time_t" type.])
 AH_TEMPLATE([HAVE_STRERROR],
@@ -266,6 +268,10 @@ AC_TRY_COMPILE([#include <sys/types.h>
 #include <sys/stat.h>],
   [struct stat s; dev_t dev = s.st_dev; ino_t ino = s.st_ino;],
   [AC_MSG_RESULT(yes); AC_DEFINE(HAVE_STAT_INO)], [AC_MSG_RESULT(no)])
+AC_MSG_CHECKING(for procfs)
+AC_TRY_COMPILE([#include <sys/statfs.h>],
+  [struct statfs s; s.f_type = PROC_SUPER_MAGIC; (void) fstatfs(0,&s); ],
+  [AC_MSG_RESULT(yes); AC_DEFINE(HAVE_PROCFS)], [AC_MSG_RESULT(no)])
 
 # Checks for ANSI function prototypes.
 AC_MSG_CHECKING(for ANSI function prototypes)
@@ -422,15 +428,15 @@ AC_MSG_CHECKING(for POSIX regcomp)
 AC_TRY_RUN([
 #include <sys/types.h>
 #include <regex.h>
-main() { regex_t r; regmatch_t rm; char *text = "xabcy";
-if (regcomp(&r, "abc", 0)) exit(1);
-if (regexec(&r, text, 1, &rm, 0)) exit(1);
+int main() { regex_t r; regmatch_t rm; char *text = "xabcy";
+if (regcomp(&r, "abc", 0)) return (1);
+if (regexec(&r, text, 1, &rm, 0)) return (1);
 #ifndef __WATCOMC__
-if (rm.rm_so != 1) exit(1); /* check for correct offset */
+if (rm.rm_so != 1) return (1); /* check for correct offset */
 #else
-if (rm.rm_sp != text + 1) exit(1); /* check for correct offset */
+if (rm.rm_sp != text + 1) return (1); /* check for correct offset */
 #endif
-exit(0); }],
+return (0); }],
   have_posix_regex=yes, have_posix_regex=no, have_posix_regex=unknown)
 if test $have_posix_regex = yes; then
   AC_MSG_RESULT(yes)
diff --git a/cvt.c b/cvt.c
index 9cf44b8..bb46492 100644
--- a/cvt.c
+++ b/cvt.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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/decode.c b/decode.c
index 7e9b167..0444cab 100644
--- a/decode.c
+++ b/decode.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -206,7 +206,7 @@ static unsigned char edittable[] =
 	ESC,SK(SK_DELETE),0,            EC_W_DELETE,    /* ESC DELETE */
 	SK(SK_CTL_DELETE),0,            EC_W_DELETE,    /* CTRL-DELETE */
 	SK(SK_CTL_BACKSPACE),0,         EC_W_BACKSPACE, /* CTRL-BACKSPACE */
-	ESC,'\b',0,                     EC_W_BACKSPACE, /* ESC BACKSPACE */
+	ESC,SK(SK_BACKSPACE),0,         EC_W_BACKSPACE, /* ESC BACKSPACE */
 	ESC,'0',0,                      EC_HOME,        /* ESC 0 */
 	SK(SK_HOME),0,                  EC_HOME,        /* HOME */
 	ESC,'$',0,                      EC_END,         /* ESC $ */
@@ -268,7 +268,7 @@ expand_special_keys(table, len)
 			}
 			/*
 			 * After SK_SPECIAL_KEY, next byte is the type
-			 * of special key (one of the SK_* contants),
+			 * of special key (one of the SK_* constants),
 			 * and the byte after that is the number of bytes,
 			 * N, reserved by the abbreviation (including the
 			 * SK_SPECIAL_KEY and key type bytes).
@@ -785,6 +785,7 @@ new_lesskey(buf, len, sysvar)
 	int sysvar;
 {
 	char *p;
+	char *end;
 	int c;
 	int n;
 
@@ -797,6 +798,7 @@ new_lesskey(buf, len, sysvar)
 	    buf[len-1] != C2_END_LESSKEY_MAGIC)
 		return (-1);
 	p = buf + 4;
+	end = buf + len;
 	for (;;)
 	{
 		c = *p++;
@@ -804,16 +806,22 @@ new_lesskey(buf, len, sysvar)
 		{
 		case CMD_SECTION:
 			n = gint(&p);
+			if (n < 0 || p+n >= end)
+				return (-1);
 			add_fcmd_table(p, n);
 			p += n;
 			break;
 		case EDIT_SECTION:
 			n = gint(&p);
+			if (n < 0 || p+n >= end)
+				return (-1);
 			add_ecmd_table(p, n);
 			p += n;
 			break;
 		case VAR_SECTION:
 			n = gint(&p);
+			if (n < 0 || p+n >= end)
+				return (-1);
 			add_var_table((sysvar) ? 
 				&list_sysvar_tables : &list_var_tables, p, n);
 			p += n;
@@ -891,7 +899,8 @@ lesskey(filename, sysvar)
 	 * Figure out if this is an old-style (before version 241)
 	 * or new-style lesskey file format.
 	 */
-	if (buf[0] != C0_LESSKEY_MAGIC || buf[1] != C1_LESSKEY_MAGIC ||
+	if (len < 4 || 
+	    buf[0] != C0_LESSKEY_MAGIC || buf[1] != C1_LESSKEY_MAGIC ||
 	    buf[2] != C2_LESSKEY_MAGIC || buf[3] != C3_LESSKEY_MAGIC)
 		return (old_lesskey(buf, (int)len));
 	return (new_lesskey(buf, (int)len, sysvar));
@@ -943,9 +952,20 @@ add_hometable(call_lesskey, envname, def_filename, sysvar)
 		filename = save(def_filename);
 	else /* def_filename is just basename */
 	{
+		/* Remove first char (normally a dot) unless stored in $HOME. */
 		char *xdg = lgetenv("XDG_CONFIG_HOME");
 		if (!isnullenv(xdg))
-			filename = dirfile(xdg, def_filename+1, 1);
+			filename = dirfile(xdg, &def_filename[1], 1);
+		if (filename == NULL)
+		{
+			char *home = lgetenv("HOME");
+			if (!isnullenv(home))
+			{
+				char *cfg_dir = dirfile(home, ".config", 0);
+				filename = dirfile(cfg_dir, &def_filename[1], 1);
+				free(cfg_dir);
+			}
+		}
 		if (filename == NULL)
 			filename = homefile(def_filename);
 	}
diff --git a/defines.ds b/defines.ds
index 1bd5026..d358fec 100644
--- a/defines.ds
+++ b/defines.ds
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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/defines.h.in b/defines.h.in
index 9a36f1b..e5559d1 100644
--- a/defines.h.in
+++ b/defines.h.in
@@ -282,6 +282,10 @@
 /* POSIX regcomp() and regex.h */
 #undef HAVE_POSIX_REGCOMP
 
+/* Define HAVE_PROCFS if have have fstatfs with f_type and PROC_SUPER_MAGIC.
+   */
+#undef HAVE_PROCFS
+
 /* Define to 1 if you have the `realpath' function. */
 #undef HAVE_REALPATH
 
diff --git a/defines.o2 b/defines.o2
index 5499bb4..9438bb2 100644
--- a/defines.o2
+++ b/defines.o2
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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/defines.o9 b/defines.o9
index cb5de66..28a93d6 100644
--- a/defines.o9
+++ b/defines.o9
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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/defines.wn b/defines.wn
index 390eb17..30592ca 100644
--- a/defines.wn
+++ b/defines.wn
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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/edit.c b/edit.c
index 529ed75..151ac74 100644
--- a/edit.c
+++ b/edit.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -27,6 +27,7 @@ extern int is_tty;
 extern int sigs;
 extern int hshift;
 extern int want_filesize;
+extern int consecutive_nulls;
 extern IFILE curr_ifile;
 extern IFILE old_ifile;
 extern struct scrpos initial_scrpos;
@@ -438,6 +439,7 @@ edit_ifile(ifile)
 	get_pos(curr_ifile, &initial_scrpos);
 	new_file = TRUE;
 	ch_init(f, chflags);
+	consecutive_nulls = 0;
 
 	if (!(chflags & CH_HELPFILE))
 	{
diff --git a/filename.c b/filename.c
index aba8d3a..5824e38 100644
--- a/filename.c
+++ b/filename.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -757,10 +757,11 @@ lglob(filename)
 	 */
 	len = (int) (strlen(lessecho) + strlen(filename) + (7*strlen(metachars())) + 24);
 	cmd = (char *) ecalloc(len, sizeof(char));
-	SNPRINTF4(cmd, len, "%s -p0x%x -d0x%x -e%s ", lessecho, openquote, closequote, esc);
+	SNPRINTF4(cmd, len, "%s -p0x%x -d0x%x -e%s ", lessecho,
+		(unsigned char) openquote, (unsigned char) closequote, esc);
 	free(esc);
 	for (s = metachars();  *s != '\0';  s++)
-		sprintf(cmd + strlen(cmd), "-n0x%x ", *s);
+		sprintf(cmd + strlen(cmd), "-n0x%x ", (unsigned char) *s);
 	sprintf(cmd + strlen(cmd), "-- %s", filename);
 	fd = shellcmd(cmd);
 	free(cmd);
diff --git a/forwback.c b/forwback.c
index e72172b..47f4dd2 100644
--- a/forwback.c
+++ b/forwback.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -20,18 +20,22 @@ public int screen_trashed;
 public int squished;
 public int no_back_scroll = 0;
 public int forw_prompt;
+public int first_time = 1;
 
 extern int sigs;
 extern int top_scroll;
 extern int quiet;
 extern int sc_width, sc_height;
+extern int hshift;
+extern int auto_wrap;
 extern int plusoption;
 extern int forw_scroll;
 extern int back_scroll;
 extern int ignore_eoi;
 extern int clear_bg;
 extern int final_attr;
-extern int oldbot;
+extern int header_lines;
+extern int header_cols;
 #if HILITE_SEARCH
 extern int size_linebuf;
 extern int hilite_search;
@@ -119,6 +123,92 @@ squish_check(VOID_PARAM)
 	repaint();
 }
 
+/*
+ * Read the first pfx columns of the next line.
+ * If skipeol==0 stop there, otherwise read and discard chars to end of line.
+ */
+	static POSITION
+forw_line_pfx(pos, pfx, skipeol)
+	POSITION pos;
+	int pfx;
+	int skipeol;
+{
+	int save_sc_width = sc_width;
+	int save_auto_wrap = auto_wrap;
+	int save_hshift = hshift;
+	/* Set fake sc_width to force only pfx chars to be read. */
+	sc_width = pfx + line_pfx_width();
+	auto_wrap = 0;
+	hshift = 0;
+	pos = forw_line_seg(pos, skipeol, FALSE, FALSE);
+	sc_width = save_sc_width;
+	auto_wrap = save_auto_wrap;
+	hshift = save_hshift;
+	return pos;
+}
+
+/*
+ * Set header text color.
+ * Underline last line of headers, but not at beginning of file
+ * (where there is no gap between the last header line and the next line).
+ */
+	static void
+set_attr_header(ln)
+	int ln;
+{
+	set_attr_line(AT_COLOR_HEADER);
+	if (ln+1 == header_lines && position(0) != ch_zero())
+		set_attr_line(AT_UNDERLINE);
+}
+
+/*
+ * Display file headers, overlaying text already drawn
+ * at top and left of screen.
+ */
+	public int
+overlay_header(VOID_PARAM)
+{
+	POSITION pos = ch_zero(); /* header lines are at beginning of file */
+	int ln;
+	int moved = FALSE;
+
+	if (header_lines > 0)
+	{
+		/* Draw header_lines lines from start of file at top of screen. */
+		home();
+		for (ln = 0; ln < header_lines; ++ln)
+		{
+			pos = forw_line(pos);
+			set_attr_header(ln);
+			clear_eol();
+			put_line();
+		}
+		moved = TRUE;
+	}
+	if (header_cols > 0)
+	{
+		/* Draw header_cols columns at left of each line. */
+		home();
+		pos = ch_zero();
+		for (ln = 0; ln < sc_height-1; ++ln)
+		{
+			if (ln >= header_lines) /* switch from header lines to normal lines */
+				pos = position(ln);
+			if (pos == NULL_POSITION)
+				putchr('\n');
+			else 
+			{
+				/* Need skipeol for all header lines except the last one. */
+				pos = forw_line_pfx(pos, header_cols, ln+1 < header_lines);
+				set_attr_header(ln);
+				put_line();
+			}
+		}
+		moved = TRUE;
+	}
+	return moved;
+}
+
 /*
  * Display n lines, scrolling forward, 
  * starting at position pos in the input file.
@@ -138,7 +228,6 @@ forw(n, pos, force, only_last, nblank)
 {
 	int nlines = 0;
 	int do_repaint;
-	static int first_time = 1;
 
 	squish_check();
 
@@ -291,10 +380,27 @@ forw(n, pos, force, only_last, nblank)
 		forw_prompt = 1;
 	}
 
+	if (header_lines > 0)
+	{
+		/*
+		 * Don't allow ch_zero to appear on screen except at top of screen.
+		 * Otherwise duplicate header lines may be displayed.
+		 */
+		if (onscreen(ch_zero()) > 0)
+		{
+			jump_loc(ch_zero(), 0); /* {{ yuck }} */
+			return;
+		}
+	}
 	if (nlines == 0 && !ignore_eoi)
 		eof_bell();
 	else if (do_repaint)
 		repaint();
+	else
+	{
+		overlay_header();
+		/* lower_left(); {{ considered harmful? }} */
+	}
 	first_time = 0;
 	(void) currline(BOTTOM);
 }
@@ -313,7 +419,7 @@ back(n, pos, force, only_last)
 	int do_repaint;
 
 	squish_check();
-	do_repaint = (n > get_back_scroll() || (only_last && n > sc_height-1));
+	do_repaint = (n > get_back_scroll() || (only_last && n > sc_height-1) || header_lines > 0);
 #if HILITE_SEARCH
 	if (hilite_search == OPT_ONPLUS || is_filtering() || status_col) {
 		prep_hilite((pos < 3*size_linebuf) ?  0 : pos - 3*size_linebuf, pos, -1);
@@ -350,13 +456,15 @@ back(n, pos, force, only_last)
 			put_line();
 		}
 	}
-
 	if (nlines == 0)
 		eof_bell();
 	else if (do_repaint)
 		repaint();
-	else if (!oldbot)
+	else
+	{
+		overlay_header();
 		lower_left();
+	}
 	(void) currline(BOTTOM);
 }
 
diff --git a/funcs.h b/funcs.h
index 330540a..146dffd 100644
--- a/funcs.h
+++ b/funcs.h
@@ -87,6 +87,7 @@ public char * cmd_lastpattern LESSPARAMS ((VOID_PARAM));
 public void init_cmdhist LESSPARAMS ((VOID_PARAM));
 public void save_cmdhist LESSPARAMS ((VOID_PARAM));
 public int in_mca LESSPARAMS ((VOID_PARAM));
+public int norm_search_type LESSPARAMS ((int st));
 public void dispversion LESSPARAMS ((VOID_PARAM));
 public int getcc LESSPARAMS ((VOID_PARAM));
 public void ungetcc LESSPARAMS ((LWCHAR c));
@@ -147,6 +148,7 @@ public char * last_component LESSPARAMS ((char *name));
 public int eof_displayed LESSPARAMS ((VOID_PARAM));
 public int entire_file_displayed LESSPARAMS ((VOID_PARAM));
 public void squish_check LESSPARAMS ((VOID_PARAM));
+public int overlay_header LESSPARAMS ((VOID_PARAM));
 public void forw LESSPARAMS ((int n, POSITION pos, int force, int only_last, int nblank));
 public void back LESSPARAMS ((int n, POSITION pos, int force, int only_last));
 public void forward LESSPARAMS ((int n, int force, int only_last));
@@ -175,7 +177,7 @@ public void * get_altpipe LESSPARAMS ((IFILE ifile));
 public void set_altfilename LESSPARAMS ((IFILE ifile, char *altfilename));
 public char * get_altfilename LESSPARAMS ((IFILE ifile));
 public void if_dump LESSPARAMS ((VOID_PARAM));
-public POSITION forw_line_seg LESSPARAMS ((POSITION curr_pos, int get_segpos));
+public POSITION forw_line_seg LESSPARAMS ((POSITION curr_pos, int skipeol, int rscroll, int nochop));
 public POSITION forw_line LESSPARAMS ((POSITION curr_pos));
 public POSITION back_line LESSPARAMS ((POSITION curr_pos));
 public void set_attnpos LESSPARAMS ((POSITION pos));
@@ -202,11 +204,13 @@ public void ansi_done LESSPARAMS ((struct ansi_state *pansi));
 public int pappend LESSPARAMS ((int c, POSITION pos));
 public int pflushmbc LESSPARAMS ((VOID_PARAM));
 public void pdone LESSPARAMS ((int endline, int chopped, int forw));
+public void set_attr_line LESSPARAMS ((int a));
 public void set_status_col LESSPARAMS ((int c, int attr));
 public int gline LESSPARAMS ((int i, int *ap));
 public void null_line LESSPARAMS ((VOID_PARAM));
 public POSITION forw_raw_line LESSPARAMS ((POSITION curr_pos, char **linep, int *line_lenp));
 public POSITION back_raw_line LESSPARAMS ((POSITION curr_pos, char **linep, int *line_lenp));
+public void load_line LESSPARAMS ((constant char *str));
 public int rrshift LESSPARAMS ((VOID_PARAM));
 public int set_color_map LESSPARAMS ((int attr, char *colorstr));
 public char * get_color_map LESSPARAMS ((int attr));
@@ -216,6 +220,7 @@ public LINENUM find_linenum LESSPARAMS ((POSITION pos));
 public POSITION find_pos LESSPARAMS ((LINENUM linenum));
 public LINENUM currline LESSPARAMS ((int where));
 public void scan_eof LESSPARAMS ((VOID_PARAM));
+public LINENUM vlinenum LESSPARAMS ((LINENUM linenum));
 public void lsystem LESSPARAMS ((char *cmd, char *donemsg));
 public int pipe_mark LESSPARAMS ((int c, char *cmd));
 public int pipe_data LESSPARAMS ((char *cmd, POSITION spos, POSITION epos));
@@ -256,8 +261,11 @@ public void opt_wheel_lines LESSPARAMS ((int type, char *s));
 public void opt_linenum_width LESSPARAMS ((int type, char *s));
 public void opt_status_col_width LESSPARAMS ((int type, char *s));
 public void opt_filesize LESSPARAMS ((int type, char *s));
+public void opt_header LESSPARAMS ((int type, char *s));
+public void opt_search_type LESSPARAMS ((int type, char *s));
 public void opt_ttyin_name LESSPARAMS ((int type, char *s));
 public void opt_rstat LESSPARAMS ((int type, char *s));
+public int chop_line LESSPARAMS ((VOID_PARAM));
 public int get_swindow LESSPARAMS ((VOID_PARAM));
 public char * propt LESSPARAMS ((int c));
 public void scan_option LESSPARAMS ((char *s));
@@ -309,7 +317,7 @@ public int empty_lines LESSPARAMS ((int s, int e));
 public void get_scrpos LESSPARAMS ((struct scrpos *scrpos, int where));
 public int sindex_from_sline LESSPARAMS ((int sline));
 public void init_prompt LESSPARAMS ((VOID_PARAM));
-public char * pr_expand LESSPARAMS ((constant char *proto, int maxwidth));
+public char * pr_expand LESSPARAMS ((constant char *proto));
 public char * eq_message LESSPARAMS ((VOID_PARAM));
 public char * pr_string LESSPARAMS ((VOID_PARAM));
 public char * wait_message LESSPARAMS ((VOID_PARAM));
@@ -342,7 +350,7 @@ public char * prevtag LESSPARAMS ((int n));
 public int ntags LESSPARAMS ((VOID_PARAM));
 public int curr_tag LESSPARAMS ((VOID_PARAM));
 public int edit_tagfile LESSPARAMS ((VOID_PARAM));
-public char * tty_device LESSPARAMS ((VOID_PARAM));
+public int open_tty LESSPARAMS ((VOID_PARAM));
 public void open_getchr LESSPARAMS ((VOID_PARAM));
 public void close_getchr LESSPARAMS ((VOID_PARAM));
 public int default_wheel_lines LESSPARAMS ((VOID_PARAM));
@@ -351,4 +359,6 @@ public int getchr LESSPARAMS ((VOID_PARAM));
 public void xbuf_init LESSPARAMS ((struct xbuffer *xbuf));
 public void xbuf_deinit LESSPARAMS ((struct xbuffer *xbuf));
 public void xbuf_reset LESSPARAMS ((struct xbuffer *xbuf));
-public void xbuf_add LESSPARAMS ((struct xbuffer *xbuf, char ch));
+public void xbuf_add LESSPARAMS ((struct xbuffer *xbuf, int ch));
+public int xbuf_pop LESSPARAMS ((struct xbuffer *buf));
+public void xbuf_set LESSPARAMS ((struct xbuffer *dst, struct xbuffer *src));
diff --git a/help.c b/help.c
index 9dabd43..0a442f0 100644
--- a/help.c
+++ b/help.c
@@ -1,4 +1,4 @@
-/* This file was generated by mkhelp.pl from less.hlp at 17:45 on 2021/6/3 */
+/* This file was generated by mkhelp.pl from less.hlp at 21:45 on 2022/1/7 */
 #include "less.h"
 constant char helpdata[] = {
 '\n',
@@ -164,8 +164,10 @@ constant char helpdata[] = {
 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','I','g','n','o','r','e',' ','t','h','e',' ','L','E','S','S','O','P','E','N',' ','e','n','v','i','r','o','n','m','e','n','t',' ','v','a','r','i','a','b','l','e','.','\n',
 ' ',' ','-','m',' ',' ','-','M',' ',' ','.','.','.','.',' ',' ','-','-','l','o','n','g','-','p','r','o','m','p','t',' ',' ','-','-','L','O','N','G','-','P','R','O','M','P','T','\n',
 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','p','r','o','m','p','t',' ','s','t','y','l','e','.','\n',
-' ',' ','-','n',' ',' ','-','N',' ',' ','.','.','.','.',' ',' ','-','-','l','i','n','e','-','n','u','m','b','e','r','s',' ',' ','-','-','L','I','N','E','-','N','U','M','B','E','R','S','\n',
-' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','u','s','e',' ','l','i','n','e',' ','n','u','m','b','e','r','s','.','\n',
+' ',' ','-','n',' ','.','.','.','.','.','.','.','.','.',' ',' ','-','-','l','i','n','e','-','n','u','m','b','e','r','s','\n',
+' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','u','p','p','r','e','s','s',' ','l','i','n','e',' ','n','u','m','b','e','r','s',' ','i','n',' ','p','r','o','m','p','t','s',' ','a','n','d',' ','m','e','s','s','a','g','e','s','.','\n',
+' ',' ','-','N',' ','.','.','.','.','.','.','.','.','.',' ',' ','-','-','L','I','N','E','-','N','U','M','B','E','R','S','\n',
+' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','l','i','n','e',' ','n','u','m','b','e','r',' ','a','t',' ','s','t','a','r','t',' ','o','f',' ','e','a','c','h',' ','l','i','n','e','.','\n',
 ' ',' ','-','o',' ','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']',' ',' ','.',' ',' ','-','-','l','o','g','-','f','i','l','e','=','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']','\n',
 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','o','p','y',' ','t','o',' ','l','o','g',' ','f','i','l','e',' ','(','s','t','a','n','d','a','r','d',' ','i','n','p','u','t',' ','o','n','l','y',')','.','\n',
 ' ',' ','-','O',' ','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']',' ',' ','.',' ',' ','-','-','L','O','G','-','F','I','L','E','=','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']','\n',
@@ -212,6 +214,8 @@ constant char helpdata[] = {
 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','A','u','t','o','m','a','t','i','c','a','l','l','y',' ','d','e','t','e','r','m','i','n','e',' ','t','h','e',' ','s','i','z','e',' ','o','f',' ','t','h','e',' ','i','n','p','u','t',' ','f','i','l','e','.','\n',
 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','f','o','l','l','o','w','-','n','a','m','e','\n',
 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','T','h','e',' ','F',' ','c','o','m','m','a','n','d',' ','c','h','a','n','g','e','s',' ','f','i','l','e','s',' ','i','f',' ','t','h','e',' ','i','n','p','u','t',' ','f','i','l','e',' ','i','s',' ','r','e','n','a','m','e','d','.','\n',
+' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','h','e','a','d','e','r','=','[','_','\b','N','[',',','_','\b','M',']',']','\n',
+' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','s','e',' ','N',' ','l','i','n','e','s',' ','a','n','d',' ','M',' ','c','o','l','u','m','n','s',' ','t','o',' ','d','i','s','p','l','a','y',' ','f','i','l','e',' ','h','e','a','d','e','r','s','.','\n',
 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','i','n','c','s','e','a','r','c','h','\n',
 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','a','r','c','h',' ','f','i','l','e',' ','a','s',' ','e','a','c','h',' ','p','a','t','t','e','r','n',' ','c','h','a','r','a','c','t','e','r',' ','i','s',' ','t','y','p','e','d',' ','i','n','.','\n',
 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','l','i','n','e','-','n','u','m','-','w','i','d','t','h','=','N','\n',
@@ -222,12 +226,20 @@ constant char helpdata[] = {
 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','s','e','n','d',' ','t','e','r','m','c','a','p',' ','k','e','y','p','a','d',' ','i','n','i','t','/','d','e','i','n','i','t',' ','s','t','r','i','n','g','s','.','\n',
 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','n','o','-','h','i','s','t','d','u','p','s','\n',
 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','m','o','v','e',' ','d','u','p','l','i','c','a','t','e','s',' ','f','r','o','m',' ','c','o','m','m','a','n','d',' ','h','i','s','t','o','r','y','.','\n',
+' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','n','o','-','n','u','m','b','e','r','-','h','e','a','d','e','r','s','\n',
+' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','g','i','v','e',' ','l','i','n','e',' ','n','u','m','b','e','r','s',' ','t','o',' ','h','e','a','d','e','r',' ','l','i','n','e','s','.','\n',
+' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','r','e','d','r','a','w','-','o','n','-','q','u','i','t','\n',
+' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','d','r','a','w',' ','f','i','n','a','l',' ','s','c','r','e','e','n',' ','w','h','e','n',' ','q','u','i','t','t','i','n','g','.','\n',
 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','r','s','c','r','o','l','l','=','C','\n',
 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','t','h','e',' ','c','h','a','r','a','c','t','e','r',' ','u','s','e','d',' ','t','o',' ','m','a','r','k',' ','t','r','u','n','c','a','t','e','d',' ','l','i','n','e','s','.','\n',
 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','s','a','v','e','-','m','a','r','k','s','\n',
 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','t','a','i','n',' ','m','a','r','k','s',' ','a','c','r','o','s','s',' ','i','n','v','o','c','a','t','i','o','n','s',' ','o','f',' ','l','e','s','s','.','\n',
+' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','s','e','a','r','c','h','-','o','p','t','i','o','n','s','=','[','E','F','K','N','R','W','-',']','\n',
+' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','d','e','f','a','u','l','t',' ','o','p','t','i','o','n','s',' ','f','o','r',' ','e','v','e','r','y',' ','s','e','a','r','c','h','.','\n',
 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','s','t','a','t','u','s','-','c','o','l','-','w','i','d','t','h','=','N','\n',
 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','t','h','e',' ','w','i','d','t','h',' ','o','f',' ','t','h','e',' ','-','J',' ','s','t','a','t','u','s',' ','c','o','l','u','m','n',' ','t','o',' ','N',' ','c','h','a','r','a','c','t','e','r','s','.','\n',
+' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','s','t','a','t','u','s','-','l','i','n','e','\n',
+' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','H','i','g','h','l','i','g','h','t',' ','o','r',' ','c','o','l','o','r',' ','t','h','e',' ','e','n','t','i','r','e',' ','l','i','n','e',' ','c','o','n','t','a','i','n','i','n','g',' ','a',' ','m','a','r','k','.','\n',
 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','u','s','e','-','b','a','c','k','s','l','a','s','h','\n',
 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','u','b','s','e','q','u','e','n','t',' ','o','p','t','i','o','n','s',' ','u','s','e',' ','b','a','c','k','s','l','a','s','h',' ','a','s',' ','e','s','c','a','p','e',' ','c','h','a','r','.','\n',
 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','u','s','e','-','c','o','l','o','r','\n',
diff --git a/ifile.c b/ifile.c
index bc47a66..6b3d1ce 100644
--- a/ifile.c
+++ b/ifile.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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/input.c b/input.c
index f57c9e3..ffd2f13 100644
--- a/input.c
+++ b/input.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -20,7 +20,6 @@
 #include "less.h"
 
 extern int squeeze;
-extern int chopline;
 extern int hshift;
 extern int quit_if_one_screen;
 extern int sigs;
@@ -42,9 +41,11 @@ extern int show_attn;
  * of the NEXT line.  The line obtained is the line starting at curr_pos.
  */
 	public POSITION
-forw_line_seg(curr_pos, get_segpos)
+forw_line_seg(curr_pos, skipeol, rscroll, nochop)
 	POSITION curr_pos;
-	int get_segpos;
+	int skipeol;
+	int rscroll;
+	int nochop;
 {
 	POSITION base_pos;
 	POSITION new_pos;
@@ -160,7 +161,7 @@ get_forw_line:
 			 */
 			backchars = pflushmbc();
 			new_pos = ch_tell();
-			if (backchars > 0 && !chopline && hshift == 0)
+			if (backchars > 0 && (nochop || !chop_line()) && hshift == 0)
 			{
 				new_pos -= backchars + 1;
 				endline = FALSE;
@@ -182,7 +183,7 @@ get_forw_line:
 			 * is too long to print in the screen width.
 			 * End the line here.
 			 */
-			if ((chopline || hshift > 0) && !get_segpos)
+			if (skipeol)
 			{
 				/* Read to end of line. */
 				do
@@ -215,7 +216,7 @@ get_forw_line:
 		pappend(' ', ch_tell()-1);
 	}
 #endif
-	pdone(endline, chopped, 1);
+	pdone(endline, rscroll && chopped, 1);
 
 #if HILITE_SEARCH
 	if (is_filtered(base_pos))
@@ -261,7 +262,8 @@ get_forw_line:
 forw_line(curr_pos)
 	POSITION curr_pos;
 {
-	return forw_line_seg(curr_pos, FALSE);
+
+	return forw_line_seg(curr_pos, (chop_line() || hshift > 0), TRUE, FALSE);
 }
 
 /*
@@ -397,7 +399,7 @@ get_back_line:
 		if (c == '\n')
 		{
 			backchars = pflushmbc();
-			if (backchars > 0 && !chopline && hshift == 0)
+			if (backchars > 0 && !chop_line() && hshift == 0)
 			{
 				backchars++;
 				goto shift;
@@ -413,7 +415,7 @@ get_back_line:
 			 * reached our curr_pos yet.  Discard the line
 			 * and start a new one.
 			 */
-			if (chopline || hshift > 0)
+			if (chop_line() || hshift > 0)
 			{
 				endline = TRUE;
 				chopped = TRUE;
diff --git a/jump.c b/jump.c
index a376486..ee1b0c6 100644
--- a/jump.c
+++ b/jump.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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/less.h b/less.h
index 83e3151..43e2cc4 100644
--- a/less.h
+++ b/less.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -231,6 +231,7 @@ typedef off_t           LINENUM;
 #define MAX_LINENUM_WIDTH   16  /* Max width of a line number */
 #define MAX_STATUSCOL_WIDTH 4   /* Max width of the status column */
 #define MAX_UTF_CHAR_LEN    6   /* Max bytes in one UTF-8 char */
+#define MAX_PRCHAR_LEN      31  /* Max chars in prchar() result */
 
 #define NULL_POSITION   ((POSITION)(-1))
 
@@ -406,6 +407,7 @@ struct wchar_range_table
 #define AT_COLOR_PROMPT   (7 << AT_COLOR_SHIFT)
 #define AT_COLOR_RSCROLL  (8 << AT_COLOR_SHIFT)
 #define AT_COLOR_SEARCH   (9 << AT_COLOR_SHIFT)
+#define AT_COLOR_HEADER   (11 << AT_COLOR_SHIFT)
 
 typedef enum { CT_NULL, CT_4BIT, CT_6BIT } COLOR_TYPE;
 
diff --git a/less.hlp b/less.hlp
index 333a0b5..bce7b16 100644
--- a/less.hlp
+++ b/less.hlp
@@ -161,8 +161,10 @@
                   Ignore the LESSOPEN environment variable.
   -m  -M  ....  --long-prompt  --LONG-PROMPT
                   Set prompt style.
-  -n  -N  ....  --line-numbers  --LINE-NUMBERS
-                  Don't use line numbers.
+  -n .........  --line-numbers
+                  Suppress line numbers in prompts and messages.
+  -N .........  --LINE-NUMBERS
+                  Display line number at start of each line.
   -o [_f_i_l_e]  .  --log-file=[_f_i_l_e]
                   Copy to log file (standard input only).
   -O [_f_i_l_e]  .  --LOG-FILE=[_f_i_l_e]
@@ -209,6 +211,8 @@
                   Automatically determine the size of the input file.
                 --follow-name
                   The F command changes files if the input file is renamed.
+                --header=[_N[,_M]]
+                  Use N lines and M columns to display file headers.
                 --incsearch
                   Search file as each pattern character is typed in.
                 --line-num-width=N
@@ -219,12 +223,20 @@
                   Don't send termcap keypad init/deinit strings.
                 --no-histdups
                   Remove duplicates from command history.
+                --no-number-headers
+                  Don't give line numbers to header lines.
+                --redraw-on-quit
+                  Redraw final screen when quitting.
                 --rscroll=C
                   Set the character used to mark truncated lines.
                 --save-marks
                   Retain marks across invocations of less.
+                --search-options=[EFKNRW-]
+                  Set default options for every search.
                 --status-col-width=N
                   Set the width of the -J status column to N characters.
+                --status-line
+                  Highlight or color the entire line containing a mark.
                 --use-backslash
                   Subsequent options use backslash as escape char.
                 --use-color
diff --git a/less.man b/less.man
index c25b2a1..8506002 100644
--- a/less.man
+++ b/less.man
@@ -152,8 +152,8 @@ LESS(1)                     General Commands Manual                    LESS(1)
               the  screen,  the  }  command will go to the matching left curly
               bracket.  The matching left curly bracket is positioned  on  the
               top  line  of the screen.  If there is more than one right curly
-              bracket on the top line, a number N may be used to  specify  the
-              N-th bracket on the line.
+              bracket on the bottom line, a number N may be  used  to  specify
+              the N-th bracket on the line.
 
        (      Like {, but applies to parentheses rather than curly brackets.
 
@@ -232,11 +232,12 @@ LESS(1)                     General Commands Manual                    LESS(1)
               ^W     WRAP  around  the  current  file.  That is, if the search
                      reaches the end of the current  file  without  finding  a
                      match,  the  search  continues from the first line of the
-                     current file up to the line where it started.
+                     current file up to the line where it started.  If the  ^W
+                     modifier is set, the ^E modifier is ignored.
 
        ?pattern
-              Search backward in the file for the  N-th  line  containing  the
-              pattern.   The search starts at the last line displayed (but see
+              Search  backward  in  the  file for the N-th line containing the
+              pattern.  The search starts at the last line displayed (but  see
               the -a and -j options, which change this).
 
               Certain characters are special as in the / command:
@@ -245,24 +246,24 @@ LESS(1)                     General Commands Manual                    LESS(1)
                      Search for lines which do NOT match the pattern.
 
               ^E or *
-                     Search multiple files.  That is, if  the  search  reaches
-                     the  beginning  of  the  current  file  without finding a
-                     match, the search continues in the previous file  in  the
+                     Search  multiple  files.   That is, if the search reaches
+                     the beginning of  the  current  file  without  finding  a
+                     match,  the  search continues in the previous file in the
                      command line list.
 
               ^F or @
                      Begin the search at the last line of the last file in the
-                     command line list, regardless of what is  currently  dis-
-                     played  on the screen or the settings of the -a or -j op-
+                     command  line  list, regardless of what is currently dis-
+                     played on the screen or the settings of the -a or -j  op-
                      tions.
 
               ^K     As in forward searches.
 
               ^R     As in forward searches.
 
-              ^W     WRAP around the current file.  That  is,  if  the  search
+              ^W     WRAP  around  the  current  file.  That is, if the search
                      reaches the beginning of the current file without finding
-                     a match, the search continues from the last line  of  the
+                     a  match,  the search continues from the last line of the
                      current file up to the line where it started.
 
        ESC-/pattern
@@ -271,42 +272,42 @@ LESS(1)                     General Commands Manual                    LESS(1)
        ESC-?pattern
               Same as "?*".
 
-       n      Repeat  previous  search, for N-th line containing the last pat-
-              tern.  If the previous search was modified by ^N, the search  is
-              made  for the N-th line NOT containing the pattern.  If the pre-
-              vious search was modified by ^E, the  search  continues  in  the
-              next  (or  previous)  file if not satisfied in the current file.
-              If the previous search was modified by ^R, the  search  is  done
-              without  using  regular  expressions.  There is no effect if the
+       n      Repeat previous search, for N-th line containing the  last  pat-
+              tern.   If the previous search was modified by ^N, the search is
+              made for the N-th line NOT containing the pattern.  If the  pre-
+              vious  search  was  modified  by ^E, the search continues in the
+              next (or previous) file if not satisfied in  the  current  file.
+              If  the  previous  search was modified by ^R, the search is done
+              without using regular expressions.  There is no  effect  if  the
               previous search was modified by ^F or ^K.
 
        N      Repeat previous search, but in the reverse direction.
 
-       ESC-n  Repeat previous search, but crossing file boundaries.   The  ef-
+       ESC-n  Repeat  previous  search, but crossing file boundaries.  The ef-
               fect is as if the previous search were modified by *.
 
-       ESC-N  Repeat  previous search, but in the reverse direction and cross-
+       ESC-N  Repeat previous search, but in the reverse direction and  cross-
               ing file boundaries.
 
-       ESC-u  Undo search highlighting.   Turn  off  highlighting  of  strings
+       ESC-u  Undo  search  highlighting.   Turn  off  highlighting of strings
               matching the current search pattern.  If highlighting is already
-              off because of a previous ESC-u command, turn highlighting  back
-              on.   Any  search  command  will also turn highlighting back on.
+              off  because of a previous ESC-u command, turn highlighting back
+              on.  Any search command will also  turn  highlighting  back  on.
               (Highlighting can also be disabled by toggling the -G option; in
               that case search commands do not turn highlighting back on.)
 
-       ESC-U  Like  ESC-u  but  also  clears the saved search pattern.  If the
-              status column is enabled via the  -J  option,  this  clears  all
+       ESC-U  Like ESC-u but also clears the saved  search  pattern.   If  the
+              status  column  is  enabled  via  the -J option, this clears all
               search matches marked in the status column.
 
        &pattern
-              Display  only  lines which match the pattern; lines which do not
-              match the pattern are not displayed.  If pattern  is  empty  (if
-              you  type  &  immediately  followed  by ENTER), any filtering is
-              turned off, and all lines are displayed.  While filtering is  in
-              effect,  an  ampersand  is  displayed  at  the  beginning of the
+              Display only lines which match the pattern; lines which  do  not
+              match  the  pattern  are not displayed.  If pattern is empty (if
+              you type & immediately followed  by  ENTER),  any  filtering  is
+              turned  off, and all lines are displayed.  While filtering is in
+              effect, an ampersand  is  displayed  at  the  beginning  of  the
               prompt, as a reminder that some lines in the file may be hidden.
-              Multiple  &  commands  may  be entered, in which case only lines
+              Multiple & commands may be entered, in  which  case  only  lines
               which match all of the patterns will be displayed.
 
               Certain characters are special as in the / command:
@@ -314,98 +315,98 @@ LESS(1)                     General Commands Manual                    LESS(1)
               ^N or !
                      Display only lines which do NOT match the pattern.
 
-              ^R     Don't interpret regular expression  metacharacters;  that
+              ^R     Don't  interpret  regular expression metacharacters; that
                      is, do a simple textual comparison.
 
        :e [filename]
-              Examine  a  new file.  If the filename is missing, the "current"
-              file (see the :n and :p commands below) from the list  of  files
-              in  the  command line is re-examined.  A percent sign (%) in the
-              filename is replaced by the name of the current file.   A  pound
-              sign  (#)  is  replaced  by  the name of the previously examined
-              file.  However, two consecutive percent  signs  are  simply  re-
-              placed  with  a single percent sign.  This allows you to enter a
-              filename that contains a percent sign in the  name.   Similarly,
-              two  consecutive  pound  signs  are replaced with a single pound
-              sign.  The filename is inserted into the command  line  list  of
-              files  so  that it can be seen by subsequent :n and :p commands.
+              Examine a new file.  If the filename is missing,  the  "current"
+              file  (see  the :n and :p commands below) from the list of files
+              in the command line is re-examined.  A percent sign (%)  in  the
+              filename  is  replaced by the name of the current file.  A pound
+              sign (#) is replaced by the  name  of  the  previously  examined
+              file.   However,  two  consecutive  percent signs are simply re-
+              placed with a single percent sign.  This allows you to  enter  a
+              filename  that  contains a percent sign in the name.  Similarly,
+              two consecutive pound signs are replaced  with  a  single  pound
+              sign.   The  filename  is inserted into the command line list of
+              files so that it can be seen by subsequent :n and  :p  commands.
               If the filename consists of several files, they are all inserted
-              into  the  list  of files and the first one is examined.  If the
+              into the list of files and the first one is  examined.   If  the
               filename contains one or more spaces, the entire filename should
               be enclosed in double quotes (also see the -" option).
 
        ^X^V or E
-              Same  as :e.  Warning: some systems use ^V as a special literal-
-              ization character.  On such systems, you may not be able to  use
+              Same as :e.  Warning: some systems use ^V as a special  literal-
+              ization  character.  On such systems, you may not be able to use
               ^V.
 
-       :n     Examine  the next file (from the list of files given in the com-
-              mand line).  If a number N is specified, the N-th next  file  is
+       :n     Examine the next file (from the list of files given in the  com-
+              mand  line).   If a number N is specified, the N-th next file is
               examined.
 
        :p     Examine the previous file in the command line list.  If a number
               N is specified, the N-th previous file is examined.
 
-       :x     Examine the first file in the command line list.  If a number  N
+       :x     Examine  the first file in the command line list.  If a number N
               is specified, the N-th file in the list is examined.
 
        :d     Remove the current file from the list of files.
 
-       t      Go  to the next tag, if there were more than one matches for the
+       t      Go to the next tag, if there were more than one matches for  the
               current tag.  See the -t option for more details about tags.
 
-       T      Go to the previous tag, if there were more than one matches  for
+       T      Go  to the previous tag, if there were more than one matches for
               the current tag.
 
        = or ^G or :f
-              Prints  some  information about the file being viewed, including
-              its name and the line number and byte offset of the bottom  line
-              being  displayed.  If possible, it also prints the length of the
-              file, the number of lines in the file and  the  percent  of  the
+              Prints some information about the file being  viewed,  including
+              its  name and the line number and byte offset of the bottom line
+              being displayed.  If possible, it also prints the length of  the
+              file,  the  number  of  lines in the file and the percent of the
               file above the last displayed line.
 
-       -      Followed  by one of the command line option letters (see OPTIONS
-              below), this will change the setting of that option and print  a
-              message  describing the new setting.  If a ^P (CONTROL-P) is en-
-              tered immediately after the dash, the setting of the  option  is
-              changed  but  no message is printed.  If the option letter has a
-              numeric value (such as -b or -h), or a string value (such as  -P
-              or  -t), a new value may be entered after the option letter.  If
-              no new value is entered, a message describing the  current  set-
+       -      Followed by one of the command line option letters (see  OPTIONS
+              below),  this will change the setting of that option and print a
+              message describing the new setting.  If a ^P (CONTROL-P) is  en-
+              tered  immediately  after the dash, the setting of the option is
+              changed but no message is printed.  If the option letter  has  a
+              numeric  value (such as -b or -h), or a string value (such as -P
+              or -t), a new value may be entered after the option letter.   If
+              no  new  value is entered, a message describing the current set-
               ting is printed and nothing is changed.
 
-       --     Like  the  -  command, but takes a long option name (see OPTIONS
+       --     Like the - command, but takes a long option  name  (see  OPTIONS
               below) rather than a single option letter.  You must press ENTER
-              or  RETURN after typing the option name.  A ^P immediately after
-              the second dash suppresses printing of a message describing  the
+              or RETURN after typing the option name.  A ^P immediately  after
+              the  second dash suppresses printing of a message describing the
               new setting, as in the - command.
 
        -+     Followed by one of the command line option letters this will re-
-              set the option to its default setting and print  a  message  de-
-              scribing  the  new  setting.   (The  "-+X" command does the same
-              thing as "-+X" on the command line.)  This  does  not  work  for
+              set  the  option  to its default setting and print a message de-
+              scribing the new setting.  (The  "-+X"  command  does  the  same
+              thing  as  "-+X"  on  the command line.)  This does not work for
               string-valued options.
 
-       --+    Like  the -+ command, but takes a long option name rather than a
+       --+    Like the -+ command, but takes a long option name rather than  a
               single option letter.
 
-       -!     Followed by one of the command line option  letters,  this  will
-              reset  the  option  to the "opposite" of its default setting and
-              print a message describing the new setting.  This does not  work
+       -!     Followed  by  one  of the command line option letters, this will
+              reset the option to the "opposite" of its  default  setting  and
+              print  a message describing the new setting.  This does not work
               for numeric or string-valued options.
 
-       --!    Like  the -! command, but takes a long option name rather than a
+       --!    Like the -! command, but takes a long option name rather than  a
               single option letter.
 
-       _      (Underscore.)  Followed by one of the command line  option  let-
-              ters,  this  will print a message describing the current setting
+       _      (Underscore.)   Followed  by one of the command line option let-
+              ters, this will print a message describing the  current  setting
               of that option.  The setting of the option is not changed.
 
        __     (Double underscore.)  Like the _ (underscore) command, but takes
               a long option name rather than a single option letter.  You must
               press ENTER or RETURN after typing the option name.
 
-       +cmd   Causes the specified cmd to be executed each time a new file  is
+       +cmd   Causes  the specified cmd to be executed each time a new file is
               examined.  For example, +G causes less to initially display each
               file starting at the end rather than the beginning.
 
@@ -414,51 +415,51 @@ LESS(1)                     General Commands Manual                    LESS(1)
        q or Q or :q or :Q or ZZ
               Exits less.
 
-       The following four commands may or may not be valid, depending on  your
+       The  following four commands may or may not be valid, depending on your
        particular installation.
 
-       v      Invokes  an  editor  to edit the current file being viewed.  The
+       v      Invokes an editor to edit the current file  being  viewed.   The
               editor is taken from the environment variable VISUAL if defined,
-              or  EDITOR if VISUAL is not defined, or defaults to "vi" if nei-
-              ther VISUAL nor EDITOR is defined.  See also the  discussion  of
+              or EDITOR if VISUAL is not defined, or defaults to "vi" if  nei-
+              ther  VISUAL  nor EDITOR is defined.  See also the discussion of
               LESSEDIT under the section on PROMPTS below.
 
        ! shell-command
-              Invokes  a shell to run the shell-command given.  A percent sign
-              (%) in the command is replaced by the name of the current  file.
+              Invokes a shell to run the shell-command given.  A percent  sign
+              (%)  in the command is replaced by the name of the current file.
               A pound sign (#) is replaced by the name of the previously exam-
-              ined file.  "!!" repeats the last shell command.   "!"  with  no
-              shell  command  simply  invokes  a  shell.  On Unix systems, the
-              shell is taken from the environment variable SHELL, or  defaults
-              to  "sh".   On  MS-DOS and OS/2 systems, the shell is the normal
+              ined  file.   "!!"  repeats the last shell command.  "!" with no
+              shell command simply invokes a  shell.   On  Unix  systems,  the
+              shell  is taken from the environment variable SHELL, or defaults
+              to "sh".  On MS-DOS and OS/2 systems, the shell  is  the  normal
               command processor.
 
        | <m> shell-command
-              <m> represents any mark letter.  Pipes a section  of  the  input
-              file  to the given shell command.  The section of the file to be
-              piped is between the position marked by the letter and the  cur-
-              rent  screen.  The entire current screen is included, regardless
-              of whether the marked position is before or  after  the  current
-              screen.   <m> may also be ^ or $ to indicate beginning or end of
-              file respectively.  If <m> is . or newline, the  current  screen
+              <m>  represents  any  mark letter.  Pipes a section of the input
+              file to the given shell command.  The section of the file to  be
+              piped  is between the position marked by the letter and the cur-
+              rent screen.  The entire current screen is included,  regardless
+              of  whether  the  marked position is before or after the current
+              screen.  <m> may also be ^ or $ to indicate beginning or end  of
+              file  respectively.   If <m> is . or newline, the current screen
               is piped.
 
        s filename
-              Save  the  input  to  a file.  This only works if the input is a
+              Save the input to a file.  This only works if  the  input  is  a
               pipe, not an ordinary file.
 
 OPTIONS
-       Command line options are described below.  Most options may be  changed
+       Command  line options are described below.  Most options may be changed
        while less is running, via the "-" command.
 
-       Most  options  may be given in one of two forms: either a dash followed
-       by a single letter, or two dashes followed by a long  option  name.   A
-       long  option name may be abbreviated as long as the abbreviation is un-
-       ambiguous.  For example, --quit-at-eof may be abbreviated  --quit,  but
+       Most options may be given in one of two forms: either a  dash  followed
+       by  a  single  letter, or two dashes followed by a long option name.  A
+       long option name may be abbreviated as long as the abbreviation is  un-
+       ambiguous.   For  example, --quit-at-eof may be abbreviated --quit, but
        not --qui, since both --quit-at-eof and --quiet begin with --qui.  Some
-       long option names are in uppercase, such as --QUIT-AT-EOF, as  distinct
-       from  --quit-at-eof.  Such option names need only have their first let-
-       ter capitalized; the remainder of the name may be in either case.   For
+       long  option names are in uppercase, such as --QUIT-AT-EOF, as distinct
+       from --quit-at-eof.  Such option names need only have their first  let-
+       ter  capitalized; the remainder of the name may be in either case.  For
        example, --Quit-at-eof is equivalent to --QUIT-AT-EOF.
 
        Options are also taken from the environment variable "LESS".  For exam-
@@ -471,76 +472,76 @@ LESS(1)                     General Commands Manual                    LESS(1)
 
        LESS="-options"; export LESS
 
-       On  MS-DOS,  you don't need the quotes, but you should replace any per-
+       On MS-DOS, you don't need the quotes, but you should replace  any  per-
        cent signs in the options string by double percent signs.
 
-       The environment variable is parsed before the command line, so  command
-       line  options override the LESS environment variable.  If an option ap-
+       The  environment variable is parsed before the command line, so command
+       line options override the LESS environment variable.  If an option  ap-
        pears in the LESS variable, it can be reset to its default value on the
        command line by beginning the command line option with "-+".
 
-       Some  options  like -k or -D require a string to follow the option let-
-       ter.  The string for that option is considered to  end  when  a  dollar
-       sign  ($)  is found.  For example, you can set two -D options on MS-DOS
+       Some options like -k or -D require a string to follow the  option  let-
+       ter.   The  string  for  that option is considered to end when a dollar
+       sign ($) is found.  For example, you can set two -D options  on  MS-DOS
        like this:
 
        LESS="Dn9.1$Ds4.1"
 
-       If the --use-backslash option appears earlier in the  options,  then  a
-       dollar  sign or backslash may be included literally in an option string
+       If  the  --use-backslash  option appears earlier in the options, then a
+       dollar sign or backslash may be included literally in an option  string
        by preceding it with a backslash.  If the --use-backslash option is not
-       in  effect, then backslashes are not treated specially, and there is no
+       in effect, then backslashes are not treated specially, and there is  no
        way to include a dollar sign in the option string.
 
        -? or --help
-              This option displays a summary of the commands accepted by  less
-              (the  same  as the h command).  (Depending on how your shell in-
-              terprets the question mark, it may be  necessary  to  quote  the
+              This  option displays a summary of the commands accepted by less
+              (the same as the h command).  (Depending on how your  shell  in-
+              terprets  the  question  mark,  it may be necessary to quote the
               question mark, thus: "-\?".)
 
        -a or --search-skip-screen
-              By  default,  forward searches start at the top of the displayed
-              screen and backwards searches start at the bottom  of  the  dis-
-              played  screen (except for repeated searches invoked by the n or
-              N commands, which start after or before the  "target"  line  re-
-              spectively;  see  the -j option for more about the target line).
-              The -a option causes forward searches to instead  start  at  the
-              bottom  of  the screen and backward searches to start at the top
+              By default, forward searches start at the top of  the  displayed
+              screen  and  backwards  searches start at the bottom of the dis-
+              played screen (except for repeated searches invoked by the n  or
+              N  commands,  which  start after or before the "target" line re-
+              spectively; see the -j option for more about the  target  line).
+              The  -a  option  causes forward searches to instead start at the
+              bottom of the screen and backward searches to start at  the  top
               of the screen, thus skipping all lines displayed on the screen.
 
        -A or --SEARCH-SKIP-SCREEN
-              Causes all forward searches (not just non-repeated searches)  to
-              start  just  after the target line, and all backward searches to
-              start just before the target line.  Thus, forward searches  will
+              Causes  all forward searches (not just non-repeated searches) to
+              start just after the target line, and all backward  searches  to
+              start  just before the target line.  Thus, forward searches will
               skip part of the displayed screen (from the first line up to and
-              including the target line).  Similarly backwards  searches  will
+              including  the  target line).  Similarly backwards searches will
               skip the displayed screen from the last line up to and including
               the target line.  This was the default behavior in less versions
               prior to 441.
 
        -bn or --buffers=n
-              Specifies  the  amount  of  buffer  space less will use for each
-              file, in units of kilobytes (1024 bytes).  By default  64 KB  of
-              buffer  space  is used for each file (unless the file is a pipe;
-              see the -B option).  The -b  option  specifies  instead  that  n
+              Specifies the amount of buffer space  less  will  use  for  each
+              file,  in  units of kilobytes (1024 bytes).  By default 64 KB of
+              buffer space is used for each file (unless the file is  a  pipe;
+              see  the  -B  option).   The  -b option specifies instead that n
               kilobytes of buffer space should be used for each file.  If n is
-              -1, buffer space is unlimited; that is, the entire file  can  be
+              -1,  buffer  space is unlimited; that is, the entire file can be
               read into memory.
 
        -B or --auto-buffers
               By default, when data is read from a pipe, buffers are allocated
               automatically as needed.  If a large amount of data is read from
-              the  pipe,  this  can cause a large amount of memory to be allo-
+              the pipe, this can cause a large amount of memory  to  be  allo-
               cated.  The -B option disables this automatic allocation of buf-
               fers for pipes, so that only 64 KB (or the amount of space spec-
-              ified by the -b option) is used for the pipe.  Warning:  use  of
+              ified  by  the -b option) is used for the pipe.  Warning: use of
               -B can result in erroneous display, since only the most recently
-              viewed part of the piped data is kept  in  memory;  any  earlier
+              viewed  part  of  the  piped data is kept in memory; any earlier
               data is lost.
 
        -c or --clear-screen
-              Causes  full  screen  repaints  to  be painted from the top line
-              down.  By default, full screen repaints are  done  by  scrolling
+              Causes full screen repaints to be  painted  from  the  top  line
+              down.   By  default,  full screen repaints are done by scrolling
               from the bottom of the screen.
 
        -C or --CLEAR-SCREEN
@@ -548,13 +549,13 @@ LESS(1)                     General Commands Manual                    LESS(1)
 
        -d or --dumb
               The -d option suppresses the error message normally displayed if
-              the terminal is dumb; that is, lacks some important  capability,
+              the  terminal is dumb; that is, lacks some important capability,
               such as the ability to clear the screen or scroll backward.  The
-              -d option does not otherwise change the behavior of  less  on  a
+              -d  option  does  not otherwise change the behavior of less on a
               dumb terminal.
 
        -Dxcolor or --color=xcolor
-              Changes  the  color of different parts of the displayed text.  x
+              Changes the color of different parts of the displayed  text.   x
               is a single character which selects the type of text whose color
               is being set:
 
@@ -564,6 +565,8 @@ LESS(1)                     General Commands Manual                    LESS(1)
 
               E      Errors and informational messages.
 
+              H      Header lines and columns, set via the --header option.
+
               M      Mark letters in the status column.
 
               N      Line numbers enabled via the -N option.
@@ -584,28 +587,28 @@ LESS(1)                     General Commands Manual                    LESS(1)
 
               u      Underlined text.
 
-              The  uppercase letters can be used only when the --use-color op-
+              The uppercase letters can be used only when the --use-color  op-
               tion is enabled.  When text color is specified by both an upper-
-              case  letter  and a lowercase letter, the uppercase letter takes
-              precedence.  For example, error messages are normally  displayed
+              case letter and a lowercase letter, the uppercase  letter  takes
+              precedence.   For example, error messages are normally displayed
               as standout text.  So if both "s" and "E" are given a color, the
-              "E" color applies to error messages, and the "s"  color  applies
-              to  other  standout text.  The "d" and "u" letters refer to bold
-              and underline text formed by overstriking with  backspaces  (see
+              "E"  color  applies to error messages, and the "s" color applies
+              to other standout text.  The "d" and "u" letters refer  to  bold
+              and  underline  text formed by overstriking with backspaces (see
               the -u option), not to text using ANSI escape sequences with the
               -R option.
 
-              A lowercase letter may be followed by a + to indicate that  both
-              the  normal format change and the specified color should both be
+              A  lowercase  letter may be followed by a + to indicate that the
+              normal format change and the  specified  color  should  both  be
               used.  For example, -Dug displays underlined text as green with-
-              out  underlining;  the green color has replaced the usual under-
-              line formatting.  But -Du+g displays  underlined  text  as  both
+              out underlining; the green color has replaced the  usual  under-
+              line  formatting.   But  -Du+g  displays underlined text as both
               green and in underlined format.
 
               color is either a 4-bit color string or an 8-bit color string:
 
-              A  4-bit  color string is zero, one or two characters, where the
-              first character specifies the foreground color  and  the  second
+              A 4-bit color string is zero, one or two characters,  where  the
+              first  character  specifies  the foreground color and the second
               specifies the background color as follows:
 
               b      Blue
@@ -624,28 +627,28 @@ LESS(1)                     General Commands Manual                    LESS(1)
 
               y      Yellow
 
-              The  corresponding upper-case letter denotes a brighter shade of
-              the color.  For example, -DNGk displays line numbers  as  bright
-              green  text on a black background, and -DEbR displays error mes-
-              sages as blue text on a bright red background.  If either  char-
-              acter  is a "-" or is omitted, the corresponding color is set to
+              The corresponding upper-case letter denotes a brighter shade  of
+              the  color.   For example, -DNGk displays line numbers as bright
+              green text on a black background, and -DEbR displays error  mes-
+              sages  as blue text on a bright red background.  If either char-
+              acter is a "-" or is omitted, the corresponding color is set  to
               that of normal text.
 
-              An 8-bit color string is one or two decimal  integers  separated
+              An  8-bit  color string is one or two decimal integers separated
               by a dot, where the first integer specifies the foreground color
-              and the second specifies the background color.  Each integer  is
-              a  value  between 0 and 255 inclusive which selects a "CSI 38;5"
+              and  the second specifies the background color.  Each integer is
+              a value between 0 and 255 inclusive which selects a  "CSI  38;5"
               color value (see
-              https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters)
-              If either integer is a "-" or is omitted, the corresponding col-
-              or is set to that of normal text.  On MS-DOS versions  of  less,
-              8-bit color is not supported; instead, decimal values are inter-
-              preted as 4-bit CHAR_INFO.Attributes values (see
+              https://en.wikipedia.org/wiki/ANSI_escape_code#SGR)   If  either
+              integer is a "-" or is omitted, the corresponding color  is  set
+              to that of normal text.  On MS-DOS versions of less, 8-bit color
+              is not supported; instead, decimal  values  are  interpreted  as
+              4-bit CHAR_INFO.Attributes values (see
               https://docs.microsoft.com/en-us/windows/console/char-info-str).
 
        -e or --quit-at-eof
-              Causes less to automatically exit the  second  time  it  reaches
-              end-of-file.   By  default, the only way to exit less is via the
+              Causes  less  to  automatically  exit the second time it reaches
+              end-of-file.  By default, the only way to exit less is  via  the
               "q" command.
 
        -E or --QUIT-AT-EOF
@@ -654,7 +657,7 @@ LESS(1)                     General Commands Manual                    LESS(1)
 
        -f or --force
               Forces non-regular files to be opened.  (A non-regular file is a
-              directory or a device special file.)  Also suppresses the  warn-
+              directory  or a device special file.)  Also suppresses the warn-
               ing message when a binary file is opened.  By default, less will
               refuse to open non-regular files.  Note that some operating sys-
               tems will not allow directories to be read, even if -f is set.
@@ -664,187 +667,187 @@ LESS(1)                     General Commands Manual                    LESS(1)
               played on the first screen.
 
        -g or --hilite-search
-              Normally, less will highlight ALL strings which match  the  last
-              search  command.   The  -g option changes this behavior to high-
-              light only the particular string which was  found  by  the  last
+              Normally,  less  will highlight ALL strings which match the last
+              search command.  The -g option changes this  behavior  to  high-
+              light  only  the  particular  string which was found by the last
               search command.  This can cause less to run somewhat faster than
               the default.
 
        -G or --HILITE-SEARCH
-              The -G option suppresses all highlighting of  strings  found  by
+              The  -G  option  suppresses all highlighting of strings found by
               search commands.
 
        -hn or --max-back-scroll=n
-              Specifies  a  maximum number of lines to scroll backward.  If it
+              Specifies a maximum number of lines to scroll backward.   If  it
               is necessary to scroll backward more than n lines, the screen is
               repainted in a forward direction instead.  (If the terminal does
               not have the ability to scroll backward, -h0 is implied.)
 
        -i or --ignore-case
               Causes searches to ignore case; that is, uppercase and lowercase
-              are  considered identical.  This option is ignored if any upper-
-              case letters appear in the search pattern; in other words, if  a
-              pattern  contains  uppercase  letters, then that search does not
+              are considered identical.  This option is ignored if any  upper-
+              case  letters appear in the search pattern; in other words, if a
+              pattern contains uppercase letters, then that  search  does  not
               ignore case.
 
        -I or --IGNORE-CASE
-              Like -i, but searches ignore case even if the  pattern  contains
+              Like  -i,  but searches ignore case even if the pattern contains
               uppercase letters.
 
        -jn or --jump-target=n
-              Specifies  a line on the screen where the "target" line is to be
-              positioned.  The target line is the line specified by  any  com-
-              mand  to  search for a pattern, jump to a line number, jump to a
+              Specifies a line on the screen where the "target" line is to  be
+              positioned.   The  target line is the line specified by any com-
+              mand to search for a pattern, jump to a line number, jump  to  a
               file percentage or jump to a tag.  The screen line may be speci-
-              fied  by  a number: the top line on the screen is 1, the next is
+              fied by a number: the top line on the screen is 1, the  next  is
               2, and so on.  The number may be negative to specify a line rel-
               ative to the bottom of the screen: the bottom line on the screen
-              is -1, the second to the bottom is -2, and so on.   Alternately,
-              the  screen line may be specified as a fraction of the height of
-              the screen, starting with a decimal point: .5 is in  the  middle
-              of  the screen, .3 is three tenths down from the first line, and
-              so on.  If the line is specified as a fraction, the actual  line
-              number  is  recalculated  if  the terminal window is resized, so
-              that the target line remains at the specified  fraction  of  the
-              screen  height.   If any form of the -j option is used, repeated
+              is  -1, the second to the bottom is -2, and so on.  Alternately,
+              the screen line may be specified as a fraction of the height  of
+              the  screen,  starting with a decimal point: .5 is in the middle
+              of the screen, .3 is three tenths down from the first line,  and
+              so  on.  If the line is specified as a fraction, the actual line
+              number is recalculated if the terminal  window  is  resized,  so
+              that  the  target  line remains at the specified fraction of the
+              screen height.  If any form of the -j option is  used,  repeated
               forward searches (invoked with "n" or "N") begin at the line im-
-              mediately  after the target line, and repeated backward searches
+              mediately after the target line, and repeated backward  searches
               begin at the target line, unless changed by -a or -A.  For exam-
               ple, if "-j4" is used, the target line is the fourth line on the
-              screen, so forward searches begin  at  the  fifth  line  on  the
-              screen.   However nonrepeated searches (invoked with "/" or "?")
-              always begin at the start or end of the current  screen  respec-
+              screen,  so  forward  searches  begin  at  the fifth line on the
+              screen.  However nonrepeated searches (invoked with "/" or  "?")
+              always  begin  at the start or end of the current screen respec-
               tively.
 
        -J or --status-column
-              Displays  a  status  column at the left edge of the screen.  The
-              status column shows the lines that matched the  current  search,
+              Displays a status column at the left edge of  the  screen.   The
+              status  column  shows the lines that matched the current search,
               and any lines that are marked (via the m or M command).
 
        -kfilename or --lesskey-file=filename
               Causes less to open and interpret the named file as a lesskey(1)
-              binary file.  Multiple -k options  may  be  specified.   If  the
-              LESSKEY  or  LESSKEY_SYSTEM environment variable is set, or if a
+              binary  file.   Multiple  -k  options  may be specified.  If the
+              LESSKEY or LESSKEY_SYSTEM environment variable is set, or  if  a
               lesskey file is found in a standard place (see KEY BINDINGS), it
               is also used as a lesskey file.
 
        --lesskey-src=filename
               Causes less to open and interpret the named file as a lesskey(1)
-              source file.  If the LESSKEYIN or  LESSKEYIN_SYSTEM  environment
+              source  file.   If the LESSKEYIN or LESSKEYIN_SYSTEM environment
               variable is set, or if a lesskey source file is found in a stan-
-              dard place (see KEY BINDINGS), it is  also  used  as  a  lesskey
-              source  file.   Prior to version 582, the lesskey program needed
-              to be run to convert a lesskey source file to a  lesskey  binary
-              file  for  less to use.  Newer versions of less read the lesskey
-              source file directly and ignore the binary file  if  the  source
+              dard  place  (see  KEY  BINDINGS),  it is also used as a lesskey
+              source file.  Prior to version 582, the lesskey  program  needed
+              to  be  run to convert a lesskey source file to a lesskey binary
+              file for less to use.  Newer versions of less read  the  lesskey
+              source  file  directly  and ignore the binary file if the source
               file exists.
 
        -K or --quit-on-intr
-              Causes  less  to exit immediately (with status 2) when an inter-
-              rupt character (usually ^C) is typed.   Normally,  an  interrupt
+              Causes less to exit immediately (with status 2) when  an  inter-
+              rupt  character  (usually  ^C) is typed.  Normally, an interrupt
               character causes less to stop whatever it is doing and return to
-              its command prompt.  Note that use of this option makes  it  im-
+              its  command  prompt.  Note that use of this option makes it im-
               possible to return to the command prompt from the "F" command.
 
        -L or --no-lessopen
-              Ignore  the  LESSOPEN  environment  variable (see the INPUT PRE-
-              PROCESSOR section below).  This option can be  set  from  within
-              less,  but  it will apply only to files opened subsequently, not
+              Ignore the LESSOPEN environment variable  (see  the  INPUT  PRE-
+              PROCESSOR  section  below).   This option can be set from within
+              less, but it will apply only to files opened  subsequently,  not
               to the file which is currently open.
 
        -m or --long-prompt
-              Causes less to prompt verbosely (like more),  with  the  percent
+              Causes  less  to  prompt verbosely (like more), with the percent
               into the file.  By default, less prompts with a colon.
 
        -M or --LONG-PROMPT
               Causes less to prompt even more verbosely than more.
 
        -n or --line-numbers
-              Suppresses  line numbers.  The default (to use line numbers) may
-              cause less to run more slowly in some cases, especially  with  a
+              Suppresses line numbers.  The default (to use line numbers)  may
+              cause  less  to run more slowly in some cases, especially with a
               very large input file.  Suppressing line numbers with the -n op-
-              tion will avoid this problem.  Using  line  numbers  means:  the
+              tion  will  avoid  this  problem.  Using line numbers means: the
               line number will be displayed in the verbose prompt and in the =
-              command, and the v command will pass the current line number  to
-              the  editor  (see also the discussion of LESSEDIT in PROMPTS be-
+              command,  and the v command will pass the current line number to
+              the editor (see also the discussion of LESSEDIT in  PROMPTS  be-
               low).
 
        -N or --LINE-NUMBERS
-              Causes a line number to be displayed at the  beginning  of  each
+              Causes  a  line  number to be displayed at the beginning of each
               line in the display.
 
        -ofilename or --log-file=filename
-              Causes  less  to copy its input to the named file as it is being
+              Causes less to copy its input to the named file as it  is  being
               viewed.  This applies only when the input file is a pipe, not an
-              ordinary  file.   If  the file already exists, less will ask for
+              ordinary file.  If the file already exists, less  will  ask  for
               confirmation before overwriting it.
 
        -Ofilename or --LOG-FILE=filename
               The -O option is like -o, but it will overwrite an existing file
               without asking for confirmation.
 
-              If  no log file has been specified, the -o and -O options can be
-              used from within less to specify a log  file.   Without  a  file
+              If no log file has been specified, the -o and -O options can  be
+              used  from  within  less  to specify a log file.  Without a file
               name, they will simply report the name of the log file.  The "s"
               command is equivalent to specifying -o from within less.
 
        -ppattern or --pattern=pattern
-              The -p option on the command line is  equivalent  to  specifying
-              +/pattern;  that  is, it tells less to start at the first occur-
+              The  -p  option  on the command line is equivalent to specifying
+              +/pattern; that is, it tells less to start at the  first  occur-
               rence of pattern in the file.
 
        -Pprompt or --prompt=prompt
-              Provides a way to tailor the three prompt  styles  to  your  own
+              Provides  a  way  to  tailor the three prompt styles to your own
               preference.  This option would normally be put in the LESS envi-
               ronment variable, rather than being typed in with each less com-
               mand.  Such an option must either be the last option in the LESS
               variable, or be terminated by a dollar sign.
-               -Ps followed by a string changes the default (short) prompt  to
+               -Ps  followed by a string changes the default (short) prompt to
               that string.
                -Pm changes the medium (-m) prompt.
                -PM changes the long (-M) prompt.
                -Ph changes the prompt for the help screen.
                -P= changes the message printed by the = command.
-               -Pw  changes the message printed while waiting for data (in the
+               -Pw changes the message printed while waiting for data (in  the
               F command).
 
-              All prompt strings consist of a sequence of letters and  special
+              All  prompt strings consist of a sequence of letters and special
               escape sequences.  See the section on PROMPTS for more details.
 
        -q or --quiet or --silent
-              Causes  moderately  "quiet"  operation: the terminal bell is not
+              Causes moderately "quiet" operation: the terminal  bell  is  not
               rung if an attempt is made to scroll past the end of the file or
               before the beginning of the file.  If the terminal has a "visual
-              bell", it is used instead.  The bell will  be  rung  on  certain
-              other  errors, such as typing an invalid character.  The default
+              bell",  it  is  used  instead.  The bell will be rung on certain
+              other errors, such as typing an invalid character.  The  default
               is to ring the terminal bell in all such cases.
 
        -Q or --QUIET or --SILENT
-              Causes totally "quiet" operation: the  terminal  bell  is  never
-              rung.   If  the  terminal has a "visual bell", it is used in all
+              Causes  totally  "quiet"  operation:  the terminal bell is never
+              rung.  If the terminal has a "visual bell", it is  used  in  all
               cases where the terminal bell would have been rung.
 
        -r or --raw-control-chars
               Causes "raw" control characters to be displayed.  The default is
-              to  display control characters using the caret notation; for ex-
-              ample, a control-A (octal 001) is displayed as  "^A".   Warning:
+              to display control characters using the caret notation; for  ex-
+              ample,  a  control-A (octal 001) is displayed as "^A".  Warning:
               when the -r option is used, less cannot keep track of the actual
-              appearance of the screen (since this depends on how  the  screen
+              appearance  of  the screen (since this depends on how the screen
               responds to each type of control character).  Thus, various dis-
-              play problems may result, such as long lines being split in  the
+              play  problems may result, such as long lines being split in the
               wrong place.
 
               USE OF THE -r OPTION IS NOT RECOMMENDED.
 
        -R or --RAW-CONTROL-CHARS
               Like -r, but only ANSI "color" escape sequences and OSC 8 hyper-
-              link sequences are output in "raw" form.  Unlike -r, the  screen
-              appearance  is  maintained correctly, provided that there are no
-              escape sequences in the file other than these  types  of  escape
-              sequences.   Color  escape sequences are only supported when the
-              color is changed within one line, not across  lines.   In  other
-              words,  the beginning of each line is assumed to be normal (non-
-              colored), regardless of any escape sequences in previous  lines.
+              link  sequences are output in "raw" form.  Unlike -r, the screen
+              appearance is maintained correctly, provided that there  are  no
+              escape  sequences  in  the file other than these types of escape
+              sequences.  Color escape sequences are only supported  when  the
+              color  is  changed  within one line, not across lines.  In other
+              words, the beginning of each line is assumed to be normal  (non-
+              colored),  regardless of any escape sequences in previous lines.
               For the purpose of keeping track of screen appearance, these es-
               cape sequences are assumed to not move the cursor.
 
@@ -852,70 +855,70 @@ LESS(1)                     General Commands Manual                    LESS(1)
 
                    ESC ] 8 ; ... \7
 
-              The terminating sequence may be either a BEL character  (\7)  or
+              The  terminating  sequence may be either a BEL character (\7) or
               the two-character sequence "ESC \".
 
               ANSI color escape sequences are sequences of the form:
 
                    ESC [ ... m
 
-              where  the "..." is zero or more color specification characters.
-              You can make less think that characters other than "m"  can  end
-              ANSI  color escape sequences by setting the environment variable
+              where the "..." is zero or more color specification  characters.
+              You  can  make less think that characters other than "m" can end
+              ANSI color escape sequences by setting the environment  variable
               LESSANSIENDCHARS to the list of characters which can end a color
-              escape  sequence.   And  you can make less think that characters
-              other than the standard ones may appear between the ESC and  the
-              m  by  setting  the environment variable LESSANSIMIDCHARS to the
+              escape sequence.  And you can make less  think  that  characters
+              other  than the standard ones may appear between the ESC and the
+              m by setting the environment variable  LESSANSIMIDCHARS  to  the
               list of characters which can appear.
 
        -s or --squeeze-blank-lines
-              Causes consecutive blank lines to  be  squeezed  into  a  single
+              Causes  consecutive  blank  lines  to  be squeezed into a single
               blank line.  This is useful when viewing nroff output.
 
        -S or --chop-long-lines
-              Causes  lines  longer than the screen width to be chopped (trun-
+              Causes lines longer than the screen width to be  chopped  (trun-
               cated) rather than wrapped.  That is, the portion of a long line
               that does not fit in the screen width is not displayed until you
-              press RIGHT-ARROW.  The default is to wrap long lines; that  is,
+              press  RIGHT-ARROW.  The default is to wrap long lines; that is,
               display the remainder on the next line.
 
        -ttag or --tag=tag
               The -t option, followed immediately by a TAG, will edit the file
-              containing that tag.  For this to work, tag information must  be
-              available;  for  example, there may be a file in the current di-
+              containing  that tag.  For this to work, tag information must be
+              available; for example, there may be a file in the  current  di-
               rectory called "tags", which was previously built by ctags(1) or
               an equivalent command.  If the environment variable LESSGLOBALT-
-              AGS is set, it is taken to be the name of a  command  compatible
-              with  global(1),  and  that command is executed to find the tag.
+              AGS  is  set, it is taken to be the name of a command compatible
+              with global(1), and that command is executed to  find  the  tag.
               (See  http://www.gnu.org/software/global/global.html).   The  -t
-              option  may also be specified from within less (using the - com-
-              mand) as a way of examining a new file.   The  command  ":t"  is
+              option may also be specified from within less (using the -  com-
+              mand)  as  a  way  of examining a new file.  The command ":t" is
               equivalent to specifying -t from within less.
 
        -Ttagsfile or --tag-file=tagsfile
               Specifies a tags file to be used instead of "tags".
 
        -u or --underline-special
-              Causes  backspaces  and carriage returns to be treated as print-
-              able characters; that is, they are sent  to  the  terminal  when
+              Causes backspaces and carriage returns to be treated  as  print-
+              able  characters;  that  is,  they are sent to the terminal when
               they appear in the input.
 
        -U or --UNDERLINE-SPECIAL
-              Causes  backspaces, tabs, carriage returns and "formatting char-
+              Causes backspaces, tabs, carriage returns and "formatting  char-
               acters" (as defined by Unicode) to be treated as control charac-
               ters; that is, they are handled as specified by the -r option.
 
-              By  default, if neither -u nor -U is given, backspaces which ap-
-              pear adjacent to an underscore character are treated  specially:
-              the  underlined  text is displayed using the terminal's hardware
-              underlining capability.  Also, backspaces which  appear  between
-              two  identical  characters are treated specially: the overstruck
+              By default, if neither -u nor -U is given, backspaces which  ap-
+              pear  adjacent to an underscore character are treated specially:
+              the underlined text is displayed using the  terminal's  hardware
+              underlining  capability.   Also, backspaces which appear between
+              two identical characters are treated specially:  the  overstruck
               text is printed using the terminal's hardware boldface capabili-
-              ty.   Other  backspaces  are  deleted,  along with the preceding
-              character.  Carriage returns immediately followed by  a  newline
+              ty.  Other backspaces are  deleted,  along  with  the  preceding
+              character.   Carriage  returns immediately followed by a newline
               are deleted.  Other carriage returns are handled as specified by
-              the -r option.  Unicode formatting characters, such as the  Byte
-              Order  Mark, are sent to the terminal.  Text which is overstruck
+              the  -r option.  Unicode formatting characters, such as the Byte
+              Order Mark, are sent to the terminal.  Text which is  overstruck
               or underlined can be searched for if neither -u nor -U is in ef-
               fect.
 
@@ -923,61 +926,63 @@ LESS(1)                     General Commands Manual                    LESS(1)
               Displays the version number of less.
 
        -w or --hilite-unread
-              Temporarily  highlights  the  first  "new"  line after a forward
+              Temporarily highlights the first  "new"  line  after  a  forward
               movement of a full page.  The first "new" line is the line imme-
-              diately  following  the  line  previously  at  the bottom of the
+              diately following the line  previously  at  the  bottom  of  the
               screen.  Also highlights the target line after a g or p command.
-              The  highlight is removed at the next command which causes move-
-              ment.  The entire line is highlighted, unless the -J  option  is
-              in effect, in which case only the status column is highlighted.
+              The highlight is removed at the next command which causes  move-
+              ment.  If the --status-line option is in effect, the entire line
+              (the width of the screen) is highlighted.  Otherwise,  only  the
+              text  in the line is highlighted, unless the -J option is in ef-
+              fect, in which case only the status column is highlighted.
 
        -W or --HILITE-UNREAD
               Like -w, but temporarily highlights the first new line after any
               forward movement command larger than one line.
 
        -xn,... or --tabs=n,...
-              Sets tab stops.  If only one n is specified, tab stops  are  set
-              at  multiples  of n.  If multiple values separated by commas are
-              specified, tab stops are set at those positions, and  then  con-
-              tinue  with  the  same  spacing  as  the last two.  For example,
-              -x9,17 will set tabs at positions 9, 17, 25, 33, etc.   The  de-
+              Sets  tab  stops.  If only one n is specified, tab stops are set
+              at multiples of n.  If multiple values separated by  commas  are
+              specified,  tab  stops are set at those positions, and then con-
+              tinue with the same spacing  as  the  last  two.   For  example,
+              -x9,17  will  set tabs at positions 9, 17, 25, 33, etc.  The de-
               fault for n is 8.
 
        -X or --no-init
               Disables sending the termcap initialization and deinitialization
-              strings to the terminal.  This is  sometimes  desirable  if  the
-              deinitialization  string does something unnecessary, like clear-
+              strings  to  the  terminal.   This is sometimes desirable if the
+              deinitialization string does something unnecessary, like  clear-
               ing the screen.
 
        -yn or --max-forw-scroll=n
               Specifies a maximum number of lines to scroll forward.  If it is
               necessary to scroll forward more than n lines, the screen is re-
-              painted instead.  The -c or -C option may  be  used  to  repaint
-              from  the top of the screen if desired.  By default, any forward
+              painted  instead.   The  -c  or -C option may be used to repaint
+              from the top of the screen if desired.  By default, any  forward
               movement causes scrolling.
 
        -zn or --window=n or -n
-              Changes the default scrolling window size to n lines.   The  de-
-              fault  is  one screenful.  The z and w commands can also be used
-              to change the window size.  The "z" may be omitted for  compati-
+              Changes  the  default scrolling window size to n lines.  The de-
+              fault is one screenful.  The z and w commands can also  be  used
+              to  change the window size.  The "z" may be omitted for compati-
               bility with some versions of more.  If the number n is negative,
               it indicates n lines less than the current screen size.  For ex-
               ample, if the screen is 24 lines, -z-4 sets the scrolling window
-              to 20 lines.   If  the  screen  is  resized  to  40  lines,  the
+              to  20  lines.   If  the  screen  is  resized  to  40 lines, the
               scrolling window automatically changes to 36 lines.
 
        -"cc or --quotes=cc
-              Changes  the  filename quoting character.  This may be necessary
-              if you are trying to name a file which contains both spaces  and
-              quote  characters.  Followed by a single character, this changes
-              the quote character to that character.  Filenames  containing  a
+              Changes the filename quoting character.  This may  be  necessary
+              if  you are trying to name a file which contains both spaces and
+              quote characters.  Followed by a single character, this  changes
+              the  quote  character to that character.  Filenames containing a
               space should then be surrounded by that character rather than by
-              double quotes.  Followed by two  characters,  changes  the  open
-              quote  to the first character, and the close quote to the second
+              double  quotes.   Followed  by  two characters, changes the open
+              quote to the first character, and the close quote to the  second
               character.  Filenames containing a space should then be preceded
-              by  the  open  quote  character  and followed by the close quote
-              character.  Note  that  even  after  the  quote  characters  are
-              changed,  this  option  remains  -" (a dash followed by a double
+              by the open quote character and  followed  by  the  close  quote
+              character.   Note  that  even  after  the  quote  characters are
+              changed, this option remains -" (a dash  followed  by  a  double
               quote).
 
        -~ or --tilde
@@ -987,20 +992,21 @@ LESS(1)                     General Commands Manual                    LESS(1)
 
        -# or --shift
               Specifies the default number of positions to scroll horizontally
-              in  the RIGHTARROW and LEFTARROW commands.  If the number speci-
-              fied is zero, it sets the default number  of  positions  to  one
+              in the RIGHTARROW and LEFTARROW commands.  If the number  speci-
+              fied  is  zero,  it  sets the default number of positions to one
               half of the screen width.  Alternately, the number may be speci-
-              fied as a fraction of the width of the screen, starting  with  a
-              decimal  point:  .5  is  half  of  the screen width, .3 is three
-              tenths of the screen width, and so on.  If the number is  speci-
+              fied  as  a fraction of the width of the screen, starting with a
+              decimal point: .5 is half of  the  screen  width,  .3  is  three
+              tenths  of the screen width, and so on.  If the number is speci-
               fied as a fraction, the actual number of scroll positions is re-
               calculated if the terminal window is resized, so that the actual
               scroll remains at the specified fraction of the screen width.
 
        --file-size
               If --file-size is specified, less will determine the size of the
-              file immediately after opening the file.  Normally this  is  not
-              done, because it can be slow if the input file is large.
+              file  immediately  after opening the file.  Normally this is not
+              done, because it can be slow if the input file  is  non-seekable
+              (such as a pipe) and is large.
 
        --follow-name
               Normally, if the input file is renamed while an F command is ex-
@@ -1012,22 +1018,38 @@ LESS(1)                     General Commands Manual                    LESS(1)
               has  been  created  with  the same name as the original (now re-
               named) file), less will display the contents of that new file.
 
+       --header
+              Sets the number of header lines and  columns  displayed  on  the
+              screen.   The  value  may be of the form "N,M" where N and M are
+              integers, to set the header lines to N and the header columns to
+              M, or it may be a single integer "N" which sets the header lines
+              to N and the header columns to zero.  When  N  is  nonzero,  the
+              first  N  lines  at  the top of the screen are replaced with the
+              first N lines of the file, regardless of what part of  the  file
+              are  being  viewed.  When M is nonzero, the characters displayed
+              at the beginning of each line are  replaced  with  the  first  M
+              characters of the line, even if the rest of the line is scrolled
+              horizontally.  If either N or M is zero, less  stops  displaying
+              header  lines  or  columns,  respectively.  (Note that it may be
+              necessary to change the setting of the -j option to ensure  that
+              the target line is not obscured by the header line(s).)
+
        --incsearch
-              Subsequent search commands will be "incremental"; that is,  less
-              will  advance  to the next line containing the search pattern as
+              Subsequent  search commands will be "incremental"; that is, less
+              will advance to the next line containing the search  pattern  as
               each character of the pattern is typed in.
 
        --line-num-width
-              Sets the minimum width of the line number field when the -N  op-
+              Sets  the minimum width of the line number field when the -N op-
               tion is in effect.  The default is 7 characters.
 
        --mouse
-              Enables  mouse  input: scrolling the mouse wheel down moves for-
-              ward in the file, scrolling the mouse wheel up  moves  backwards
-              in  the  file,  and  clicking the mouse sets the "#" mark to the
-              line where the mouse is clicked.  The number of lines to  scroll
-              when  the wheel is moved can be set by the --wheel-lines option.
-              Mouse input works only on terminals which support X11 mouse  re-
+              Enables mouse input: scrolling the mouse wheel down  moves  for-
+              ward  in  the file, scrolling the mouse wheel up moves backwards
+              in the file, and clicking the mouse sets the  "#"  mark  to  the
+              line  where the mouse is clicked.  The number of lines to scroll
+              when the wheel is moved can be set by the --wheel-lines  option.
+              Mouse  input works only on terminals which support X11 mouse re-
               porting, and on the Windows version of less.
 
        --MOUSE
@@ -1035,79 +1057,105 @@ LESS(1)                     General Commands Manual                    LESS(1)
               ment is reversed.
 
        --no-keypad
-              Disables sending the keypad initialization and  deinitialization
+              Disables  sending the keypad initialization and deinitialization
               strings to the terminal.  This is sometimes useful if the keypad
               strings make the numeric keypad behave in an undesirable manner.
 
        --no-histdups
-              This option changes the behavior so that if a search  string  or
-              file  name  is  typed  in, and the same string is already in the
+              This  option  changes the behavior so that if a search string or
+              file name is typed in, and the same string  is  already  in  the
               history list, the existing copy is removed from the history list
-              before  the  new one is added.  Thus, a given string will appear
-              only once in the history list.  Normally, a  string  may  appear
+              before the new one is added.  Thus, a given string  will  appear
+              only  once  in  the history list.  Normally, a string may appear
               multiple times.
 
+       --no-number-headers
+              Header lines (defined via the --header option) are not  assigned
+              line numbers.  Line number 1 is assigned to the first line after
+              any header lines.
+
        --rscroll
-              This  option changes the character used to mark truncated lines.
+              This option changes the character used to mark truncated  lines.
               It may begin with a two-character attribute indicator like LESS-
-              BINFMT  does.   If  there is no attribute indicator, standout is
+              BINFMT does.  If there is no attribute  indicator,  standout  is
               used.  If set to "-", truncated lines are not marked.
 
+       --redraw-on-quit
+              When  quitting,  after  sending  the  terminal  deinitialization
+              string, redraws the entire last screen.  On terminals whose ter-
+              minal deinitialization string causes the terminal to switch from
+              an alternate screen, this makes the last screenful of  the  cur-
+              rent file remain visible after less has quit.
+
        --save-marks
-              Save marks in the history file, so  marks  are  retained  across
+              Save  marks  in  the  history file, so marks are retained across
               different invocations of less.
 
+       --search-options
+              Sets default search modifiers.  The value is a string of one  or
+              more of the characters E, F, K, N, R or W.  Setting any of these
+              has the same effect as typing that control character at the  be-
+              ginning of every search pattern.  For example, setting --search-
+              options=W is the same as typing ^W at  the  beginning  of  every
+              pattern.  The value "-" disables all default search modifiers.
+
        --status-col-width
               Sets the width of the status column when the -J option is in ef-
               fect.  The default is 2 characters.
 
+       --status-line
+              If a line is marked, the entire line (rather than just the  sta-
+              tus  column)  is highlighted.  Also lines highlighted due to the
+              -w option will have the entire line highlighted.  If --use-color
+              is set, the line is colored rather than highlighted.
+
        --use-backslash
-              This option changes the interpretations of options which  follow
+              This  option changes the interpretations of options which follow
               this one.  After the --use-backslash option, any backslash in an
-              option string is removed and the following  character  is  taken
-              literally.   This  allows a dollar sign to be included in option
+              option  string  is  removed and the following character is taken
+              literally.  This allows a dollar sign to be included  in  option
               strings.
 
        --use-color
-              Enables the colored text in various places.  The -D  option  can
-              be  used  to  change the colors.  Colored text works only if the
+              Enables  the  colored text in various places.  The -D option can
+              be used to change the colors.  Colored text works  only  if  the
               terminal supports ANSI color escape sequences (as defined in EC-
               MA-48 SGR; see
               https://www.ecma-international.org/publications-and-
               standards/standards/ecma-48).
 
        --wheel-lines=n
-              Set the number of lines  to  scroll  when  the  mouse  wheel  is
-              scrolled  and  the  --mouse or --MOUSE option is in effect.  The
+              Set  the  number  of  lines  to  scroll  when the mouse wheel is
+              scrolled and the --mouse or --MOUSE option is  in  effect.   The
               default is 1 line.
 
-       --     A command line argument of "--" marks the end  of  option  argu-
-              ments.   Any  arguments  following this are interpreted as file-
+       --     A  command  line  argument of "--" marks the end of option argu-
+              ments.  Any arguments following this are  interpreted  as  file-
               names.  This can be useful when viewing a file whose name begins
               with a "-" or "+".
 
-       +      If  a  command  line option begins with +, the remainder of that
-              option is taken to be an initial command to less.  For  example,
-              +G  tells  less  to start at the end of the file rather than the
-              beginning, and +/xyz tells it to start at the  first  occurrence
-              of  "xyz"  in  the file.  As a special case, +<number> acts like
+       +      If a command line option begins with +, the  remainder  of  that
+              option  is taken to be an initial command to less.  For example,
+              +G tells less to start at the end of the file  rather  than  the
+              beginning,  and  +/xyz tells it to start at the first occurrence
+              of "xyz" in the file.  As a special case,  +<number>  acts  like
               +<number>g; that is, it starts the display at the specified line
-              number  (however,  see  the caveat under the "g" command above).
+              number (however, see the caveat under the  "g"  command  above).
               If the option starts with ++, the initial command applies to ev-
-              ery  file  being  viewed, not just the first one.  The + command
+              ery file being viewed, not just the first one.   The  +  command
               described previously may also be used to set (or change) an ini-
               tial command for every file.
 
 LINE EDITING
-       When  entering a command line at the bottom of the screen (for example,
-       a filename for the :e command, or the pattern for  a  search  command),
+       When entering a command line at the bottom of the screen (for  example,
+       a  filename  for  the :e command, or the pattern for a search command),
        certain keys can be used to manipulate the command line.  Most commands
-       have an alternate form in [ brackets ] which can be used if a key  does
-       not  exist  on  a  particular keyboard.  (Note that the forms beginning
-       with ESC do not work in some MS-DOS and Windows systems because ESC  is
-       the  line  erase  character.)  Any of these special keys may be entered
-       literally by preceding it with the "literal" character,  either  ^V  or
-       ^A.   A  backslash itself may also be entered literally by entering two
+       have  an alternate form in [ brackets ] which can be used if a key does
+       not exist on a particular keyboard.  (Note  that  the  forms  beginning
+       with  ESC do not work in some MS-DOS and Windows systems because ESC is
+       the line erase character.)  Any of these special keys  may  be  entered
+       literally  by  preceding  it with the "literal" character, either ^V or
+       ^A.  A backslash itself may also be entered literally by  entering  two
        backslashes.
 
        LEFTARROW [ ESC-h ]
@@ -1117,7 +1165,7 @@ LESS(1)                     General Commands Manual                    LESS(1)
               Move the cursor one space to the right.
 
        ^LEFTARROW [ ESC-b or ESC-LEFTARROW ]
-              (That is, CONTROL and LEFTARROW simultaneously.)  Move the  cur-
+              (That  is, CONTROL and LEFTARROW simultaneously.)  Move the cur-
               sor one word to the left.
 
        ^RIGHTARROW [ ESC-w or ESC-RIGHTARROW ]
@@ -1131,48 +1179,48 @@ LESS(1)                     General Commands Manual                    LESS(1)
               Move the cursor to the end of the line.
 
        BACKSPACE
-              Delete the character to the left of the cursor,  or  cancel  the
+              Delete  the  character  to the left of the cursor, or cancel the
               command if the command line is empty.
 
        DELETE or [ ESC-x ]
               Delete the character under the cursor.
 
        ^BACKSPACE [ ESC-BACKSPACE ]
-              (That  is,  CONTROL  and  BACKSPACE simultaneously.)  Delete the
+              (That is, CONTROL and  BACKSPACE  simultaneously.)   Delete  the
               word to the left of the cursor.
 
        ^DELETE [ ESC-X or ESC-DELETE ]
-              (That is, CONTROL and DELETE simultaneously.)  Delete  the  word
+              (That  is,  CONTROL and DELETE simultaneously.)  Delete the word
               under the cursor.
 
        UPARROW [ ESC-k ]
-              Retrieve  the  previous  command  line.  If you first enter some
-              text and then press UPARROW, it will retrieve the previous  com-
+              Retrieve the previous command line.  If  you  first  enter  some
+              text  and then press UPARROW, it will retrieve the previous com-
               mand which begins with that text.
 
        DOWNARROW [ ESC-j ]
-              Retrieve  the  next  command line.  If you first enter some text
-              and then press DOWNARROW, it  will  retrieve  the  next  command
+              Retrieve the next command line.  If you first  enter  some  text
+              and  then  press  DOWNARROW,  it  will retrieve the next command
               which begins with that text.
 
-       TAB    Complete  the partial filename to the left of the cursor.  If it
-              matches more than one filename, the first match is entered  into
-              the  command  line.   Repeated  TABs  will  cycle thru the other
+       TAB    Complete the partial filename to the left of the cursor.  If  it
+              matches  more than one filename, the first match is entered into
+              the command line.  Repeated  TABs  will  cycle  thru  the  other
               matching filenames.  If the completed filename is a directory, a
-              "/"  is  appended to the filename.  (On MS-DOS systems, a "\" is
-              appended.)  The environment variable LESSSEPARATOR can  be  used
+              "/" is appended to the filename.  (On MS-DOS systems, a  "\"  is
+              appended.)   The  environment variable LESSSEPARATOR can be used
               to specify a different character to append to a directory name.
 
        BACKTAB [ ESC-TAB ]
               Like, TAB, but cycles in the reverse direction thru the matching
               filenames.
 
-       ^L     Complete the partial filename to the left of the cursor.  If  it
+       ^L     Complete  the partial filename to the left of the cursor.  If it
               matches more than one filename, all matches are entered into the
               command line (if they fit).
 
        ^U (Unix and OS/2) or ESC (MS-DOS)
-              Delete the entire command line, or cancel  the  command  if  the
+              Delete  the  entire  command  line, or cancel the command if the
               command line is empty.  If you have changed your line-kill char-
               acter in Unix to something other than ^U, that character is used
               instead of ^U.
@@ -1180,23 +1228,24 @@ LESS(1)                     General Commands Manual                    LESS(1)
        ^G     Delete the entire command line and return to the main prompt.
 
 KEY BINDINGS
-       You  may  define  your  own  less commands by creating a lesskey source
-       file.  This file specifies a set of command keys and an action  associ-
-       ated  with  each  key.   You may also change the line-editing keys (see
-       LINE EDITING), and to set environment variables.   If  the  environment
-       variable  LESSKEYIN  is  set, less uses that as the name of the lesskey
+       You may define your own less commands  by  creating  a  lesskey  source
+       file.   This file specifies a set of command keys and an action associ-
+       ated with each key.  You may also change  the  line-editing  keys  (see
+       LINE  EDITING),  and  to set environment variables.  If the environment
+       variable LESSKEYIN is set, less uses that as the name  of  the  lesskey
        source file.  Otherwise, less looks in a standard place for the lesskey
-       source  file:  On  Unix  systems,  less looks for a lesskey file called
-       "$XDG_CONFIG_HOME/lesskey" or "$HOME/.lesskey".  On MS-DOS and  Windows
-       systems,  less looks for a lesskey file called "$HOME/_lesskey", and if
-       it is not found there, then looks for a lesskey file called  "_lesskey"
-       in  any  directory specified in the PATH environment variable.  On OS/2
-       systems, less looks for a lesskey file called "$HOME/lesskey.ini",  and
-       if  it is not found, then looks for a lesskey file called "lesskey.ini"
-       in any directory specified in the INIT environment variable, and if  it
-       not  found there, then looks for a lesskey file called "lesskey.ini" in
-       any directory specified in the  PATH  environment  variable.   See  the
-       lesskey manual page for more details.
+       source file: On Unix systems, less looks  for  a  lesskey  file  called
+       "$XDG_CONFIG_HOME/lesskey"      or      "$HOME/.config/lesskey"      or
+       "$HOME/.lesskey".  On MS-DOS and Windows  systems,  less  looks  for  a
+       lesskey  file  called  "$HOME/_lesskey",  and if it is not found there,
+       then looks for a lesskey file called "_lesskey" in any directory speci-
+       fied in the PATH environment variable.  On OS/2 systems, less looks for
+       a lesskey file called "$HOME/lesskey.ini", and if it is not found, then
+       looks  for  a lesskey file called "lesskey.ini" in any directory speci-
+       fied in the INIT environment variable, and if it not found there,  then
+       looks  for  a lesskey file called "lesskey.ini" in any directory speci-
+       fied in the PATH environment variable.  See the lesskey manual page for
+       more details.
 
        A  system-wide  lesskey  source  file may also be set up to provide key
        bindings.  If a key is defined in both a local lesskey file and in  the
@@ -1307,12 +1356,12 @@ LESS(1)                     General Commands Manual                    LESS(1)
        Note that a preprocessor cannot output an empty file, since that is in-
        terpreted as meaning there is no replacement, and the original file  is
        used.   To  avoid  this, if LESSOPEN starts with two vertical bars, the
-       exit status of the script becomes meaningful.  If the  exit  status  is
-       zero,  the  output  is considered to be replacement text, even if it is
-       empty.  If the exit status is nonzero, any output is  ignored  and  the
-       original  file  is  used.   For compatibility with previous versions of
-       less, if LESSOPEN starts with only one vertical bar, the exit status of
-       the preprocessor is ignored.
+       exit status of the script determines the behavior when  the  output  is
+       empty.   If  the output is empty and the exit status is zero, the empty
+       output is considered to be replacement text.  If the  output  is  empty
+       and the exit status is nonzero, the original file is used.  For compat-
+       ibility with previous versions of less, if LESSOPEN  starts  with  only
+       one vertical bar, the exit status of the preprocessor is ignored.
 
        When  an input pipe is used, a LESSCLOSE postprocessor can be used, but
        it is usually not necessary since there is no replacement file to clean
@@ -1652,6 +1701,8 @@ LESS(1)                     General Commands Manual                    LESS(1)
 
                      filename completion (TAB, ^L)
 
+                     history file
+
        Less can also be compiled to be permanently in "secure" mode.
 
 COMPATIBILITY WITH MORE
@@ -1750,8 +1801,9 @@ LESS(1)                     General Commands Manual                    LESS(1)
               Name of the history file used to remember  search  commands  and
               shell  commands  between  invocations of less.  If set to "-" or
               "/dev/null", a  history  file  is  not  used.   The  default  is
-              "$XDG_DATA_HOME/lesshst"  or  "$HOME/.lesshst"  on Unix systems,
-              "$HOME/_lesshst"   on    DOS    and    Windows    systems,    or
+              "$XDG_STATE_HOME/lesshst"   or  "$HOME/.local/state/lesshst"  or
+              "$XDG_DATA_HOME/lesshst" or "$HOME/.lesshst"  on  Unix  systems,
+              "$HOME/_lesshst"    on    DOS    and    Windows    systems,   or
               "$HOME/lesshst.ini" or "$INIT/lesshst.ini" on OS/2 systems.
 
        LESSHISTSIZE
@@ -1762,24 +1814,24 @@ LESS(1)                     General Commands Manual                    LESS(1)
               Name of the default lesskey source file.
 
        LESSKEY
-              Name  of  the  default  lesskey  binary  file.  (Not   used   if
+              Name   of   the  default  lesskey  binary  file.  (Not  used  if
               "$LESSKEYIN" exists.)
 
        LESSKEYIN_SYSTEM
               Name of the default system-wide lesskey source file.
 
        LESSKEY_SYSTEM
-              Name  of  the default system-wide lesskey binary file. (Not used
+              Name of the default system-wide lesskey binary file.  (Not  used
               if "$LESSKEYIN_SYSTEM" exists.)
 
        LESSMETACHARS
-              List of characters which are considered "metacharacters" by  the
+              List  of characters which are considered "metacharacters" by the
               shell.
 
        LESSMETAESCAPE
-              Prefix  which  less will add before each metacharacter in a com-
-              mand sent to the shell.  If LESSMETAESCAPE is an  empty  string,
-              commands  containing  metacharacters  will  not be passed to the
+              Prefix which less will add before each metacharacter in  a  com-
+              mand  sent  to the shell.  If LESSMETAESCAPE is an empty string,
+              commands containing metacharacters will not  be  passed  to  the
               shell.
 
        LESSOPEN
@@ -1789,7 +1841,7 @@ LESS(1)                     General Commands Manual                    LESS(1)
               Runs less in "secure" mode.  See discussion under SECURITY.
 
        LESSSEPARATOR
-              String to be appended to a directory name  in  filename  comple-
+              String  to  be  appended to a directory name in filename comple-
               tion.
 
        LESSUTFBINFMT
@@ -1798,19 +1850,19 @@ LESS(1)                     General Commands Manual                    LESS(1)
        LESS_IS_MORE
               Emulate the more(1) command.
 
-       LINES  Sets  the  number of lines on the screen.  Takes precedence over
+       LINES  Sets the number of lines on the screen.  Takes  precedence  over
               the number of lines specified by the TERM variable.  (But if you
-              have  a  windowing system which supports TIOCGWINSZ or WIOCGETD,
-              the window system's idea of the  screen  size  takes  precedence
+              have a windowing system which supports TIOCGWINSZ  or  WIOCGETD,
+              the  window  system's  idea  of the screen size takes precedence
               over the LINES and COLUMNS environment variables.)
 
-       MORE   Options  which  are passed to less automatically when running in
+       MORE   Options which are passed to less automatically when  running  in
               more compatible mode.
 
-       PATH   User's search path (used to find a lesskey file  on  MS-DOS  and
+       PATH   User's  search  path  (used to find a lesskey file on MS-DOS and
               OS/2 systems).
 
-       SHELL  The  shell  used  to execute the ! command, as well as to expand
+       SHELL  The shell used to execute the ! command, as well  as  to  expand
               filenames.
 
        TERM   The type of terminal on which less is being run.
@@ -1823,19 +1875,19 @@ LESS(1)                     General Commands Manual                    LESS(1)
 COPYRIGHT
        Copyright (C) 1984-2021  Mark Nudelman
 
-       less is part of the GNU project and is free software.  You  can  redis-
-       tribute  it and/or modify it under the terms of either (1) the GNU Gen-
-       eral Public License as published by the Free  Software  Foundation;  or
+       less  is  part of the GNU project and is free software.  You can redis-
+       tribute it and/or modify it under the terms of either (1) the GNU  Gen-
+       eral  Public  License  as published by the Free Software Foundation; or
        (2) the Less License.  See the file README in the less distribution for
        more details regarding redistribution.  You should have received a copy
-       of  the  GNU General Public License along with the source for less; see
-       the file COPYING.  If not, write to the Free  Software  Foundation,  59
-       Temple  Place, Suite 330, Boston, MA  02111-1307, USA.  You should also
+       of the GNU General Public License along with the source for  less;  see
+       the  file  COPYING.   If not, write to the Free Software Foundation, 59
+       Temple Place, Suite 330, Boston, MA  02111-1307, USA.  You should  also
        have received a copy of the Less License; see the file LICENSE.
 
        less is distributed in the hope that it will be useful, but WITHOUT ANY
-       WARRANTY;  without even the implied warranty of MERCHANTABILITY or FIT-
-       NESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License  for
+       WARRANTY; without even the implied warranty of MERCHANTABILITY or  FIT-
+       NESS  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
        more details.
 
 AUTHOR
@@ -1846,4 +1898,4 @@ LESS(1)                     General Commands Manual                    LESS(1)
 
 
 
-                           Version 590: 03 Jun 2021                    LESS(1)
+                           Version 600: 07 Jan 2022                    LESS(1)
diff --git a/less.nro b/less.nro
index 7c8372b..f94f198 100644
--- a/less.nro
+++ b/less.nro
@@ -1,5 +1,5 @@
 '\" t
-.TH LESS 1 "Version 590: 03 Jun 2021"
+.TH LESS 1 "Version 600: 07 Jan 2022"
 .SH NAME
 less \- opposite of more
 .SH SYNOPSIS
@@ -154,7 +154,7 @@ on the screen,
 the } command will go to the matching left curly bracket.
 The matching left curly bracket is positioned on the top
 line of the screen.
-If there is more than one right curly bracket on the top line,
+If there is more than one right curly bracket on the bottom line,
 a number N may be used to specify the N-th bracket on the line.
 .IP "("
 Like {, but applies to parentheses rather than curly brackets.
@@ -234,6 +234,7 @@ WRAP around the current file.
 That is, if the search reaches the end of the current file
 without finding a match, the search continues from the first line of the
 current file up to the line where it started.
+If the ^W modifier is set, the ^E modifier is ignored.
 .RE
 .IP ?pattern
 Search backward in the file for the N-th line containing the pattern.
@@ -581,6 +582,8 @@ Binary characters.
 Control characters.
 .IP "E"
 Errors and informational messages.
+.IP "H"
+Header lines and columns, set via the \-\-header option.
 .IP "M"
 Mark letters in the status column.
 .IP "N"
@@ -615,7 +618,7 @@ overstriking with backspaces (see the \-u option),
 not to text using ANSI escape sequences with the \-R option.
 .PP
 A lowercase letter may be followed by a + to indicate that
-both the normal format change and the specified color should both be used.
+the normal format change and the specified color should both be used.
 For example, \-Dug displays underlined text as green without underlining;
 the green color has replaced the usual underline formatting.
 But \-Du+g displays underlined text as both green and in underlined format.
@@ -656,7 +659,7 @@ Each integer is a value between 0 and 255 inclusive which selects
 a "CSI 38;5" color value (see
 .br
 .nh
-https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters)
+https://en.wikipedia.org/wiki/ANSI_escape_code#SGR)
 .hy
 If either integer is a "-" or is omitted,
 the corresponding color is set to that of normal text.
@@ -1011,7 +1014,10 @@ The first "new" line is the line immediately following the line previously
 at the bottom of the screen.
 Also highlights the target line after a g or p command.
 The highlight is removed at the next command which causes movement.
-The entire line is highlighted, unless the \-J option is in effect,
+If the \-\-status-line option is in effect, the entire line
+(the width of the screen) is highlighted.
+Otherwise, only the text in the line is highlighted,
+unless the \-J option is in effect,
 in which case only the status column is highlighted.
 .IP "\-W or \-\-HILITE-UNREAD"
 Like \-w, but temporarily highlights the first new line after any
@@ -1084,7 +1090,8 @@ If \-\-file-size is specified,
 .I less
 will determine the size of the file 
 immediately after opening the file.
-Normally this is not done, because it can be slow if the input file is large.
+Normally this is not done, because it can be slow if the input file 
+is non-seekable (such as a pipe) and is large.
 .IP "\-\-follow-name"
 Normally, if the input file is renamed while an F command is executing,
 .I less
@@ -1098,6 +1105,23 @@ If the reopen succeeds and the file is a different file from the original
 with the same name as the original (now renamed) file),
 .I less
 will display the contents of that new file.
+.IP "\-\-header"
+Sets the number of header lines and columns displayed on the screen.
+The value may be of the form "N,M" where N and M are integers,
+to set the header lines to N and the header columns to M,
+or it may be a single integer "N" which sets the header lines to N 
+and the header columns to zero.
+When N is nonzero, the first N lines at the top
+of the screen are replaced with the first N lines of the file,
+regardless of what part of the file are being viewed.
+When M is nonzero, the characters displayed at the 
+beginning of each line are replaced with the first M characters of the line,
+even if the rest of the line is scrolled horizontally.
+If either N or M is zero, 
+.I less
+stops displaying header lines or columns, respectively.
+(Note that it may be necessary to change the setting of the \-j option
+to ensure that the target line is not obscured by the header line(s).)
 .IP "\-\-incsearch"
 Subsequent search commands will be "incremental"; that is,
 .I less
@@ -1131,18 +1155,44 @@ file name is typed in, and the same string is already in the history list,
 the existing copy is removed from the history list before the new one is added.
 Thus, a given string will appear only once in the history list.
 Normally, a string may appear multiple times.
+.IP "\-\-no-number-headers"
+Header lines (defined via the \-\-header option) are not assigned line numbers.
+Line number 1 is assigned to the first line after any header lines.
 .IP "\-\-rscroll"
 This option changes the character used to mark truncated lines.
 It may begin with a two-character attribute indicator like LESSBINFMT does.
 If there is no attribute indicator, standout is used.
 If set to "\-", truncated lines are not marked.
+.IP "\-\-redraw-on-quit"
+When quitting, after sending the terminal deinitialization string,
+redraws the entire last screen.
+On terminals whose terminal deinitialization string causes the
+terminal to switch from an alternate screen, 
+this makes the last screenful of the current file remain visible after
+.I less
+has quit.
 .IP "\-\-save-marks"
 Save marks in the history file, so marks are retained
 across different invocations of
 .IR less .
+.IP "\-\-search-options"
+Sets default search modifiers. 
+The value is a string of one or more of the characters
+E, F, K, N, R or W.
+Setting any of these has the same effect as typing that
+control character at the beginning of every search pattern.
+For example, setting \-\-search-options=W is the same as
+typing ^W at the beginning of every pattern.
+The value "-" disables all default search modifiers.
 .IP "\-\-status-col-width"
 Sets the width of the status column when the \-J option is in effect.
 The default is 2 characters.
+.IP "\-\-status-line"
+If a line is marked, the entire line (rather than just the status column)
+is highlighted.
+Also lines highlighted due to the \-w option will have
+the entire line highlighted.
+If \-\-use-color is set, the line is colored rather than highlighted.
 .IP "\-\-use-backslash"
 This option changes the interpretations of options which follow this one.
 After the \-\-use-backslash option, any backslash in an option string is
@@ -1266,7 +1316,7 @@ Otherwise,
 looks in a standard place for the lesskey source file:
 On Unix systems,
 .I less
-looks for a lesskey file called "$XDG_CONFIG_HOME/lesskey" or "$HOME/.lesskey".
+looks for a lesskey file called "$XDG_CONFIG_HOME/lesskey" or "$HOME/.config/lesskey" or "$HOME/.lesskey".
 On MS-DOS and Windows systems,
 .I less
 looks for a lesskey file called "$HOME/_lesskey", and if it is not found there,
@@ -1445,11 +1495,11 @@ Note that a preprocessor cannot output an empty file, since that
 is interpreted as meaning there is no replacement, and
 the original file is used.
 To avoid this, if LESSOPEN starts with two vertical bars,
-the exit status of the script becomes meaningful.
-If the exit status is zero, the output is considered to be
-replacement text, even if it is empty.
-If the exit status is nonzero, any output is ignored and the
-original file is used.
+the exit status of the script determines the behavior when the output is empty.
+If the output is empty and the exit status is zero, 
+the empty output is considered to be replacement text.
+If the output is empty and the exit status is nonzero, 
+the original file is used.
 For compatibility with previous versions of
 .IR less ,
 if LESSOPEN starts with only one vertical bar, the exit status
@@ -1825,6 +1875,8 @@ use of tags files
 metacharacters in filenames, such as *
 .IP
 filename completion (TAB, ^L)
+.IP
+history file
 .RE
 .PP
 Less can also be compiled to be permanently in "secure" mode.
@@ -1925,10 +1977,10 @@ Name of the history file used to remember search commands and
 shell commands between invocations of
 .IR less .
 If set to "\-" or "/dev/null", a history file is not used.
-The default is "$XDG_DATA_HOME/lesshst" or "$HOME/.lesshst" on Unix systems,
+The default is "$XDG_STATE_HOME/lesshst" or "$HOME/.local/state/lesshst" or
+"$XDG_DATA_HOME/lesshst" or "$HOME/.lesshst" on Unix systems,
 "$HOME/_lesshst" on DOS and Windows systems,
-or "$HOME/lesshst.ini" or "$INIT/lesshst.ini"
-on OS/2 systems.
+or "$HOME/lesshst.ini" or "$INIT/lesshst.ini" on OS/2 systems.
 .IP LESSHISTSIZE
 The maximum number of commands to save in the history file.
 The default is 100.
diff --git a/lessecho.c b/lessecho.c
index bfb0f72..5cd660d 100644
--- a/lessecho.c
+++ b/lessecho.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -34,8 +34,9 @@ static char openquote = '"';
 static char closequote = '"';
 static char *meta_escape = "\\";
 static char meta_escape_buf[2];
-static char metachars[64] = "";
+static char* metachars = NULL;
 static int num_metachars = 0;
+static int size_metachars = 0;
 
 	static void
 pr_usage(VOID_PARAM)
@@ -140,6 +141,35 @@ lstrtol(s, radix, pend)
 	return (n);
 }
 
+	static void
+add_metachar(ch)
+	int ch;
+{
+	if (num_metachars+1 >= size_metachars)
+	{
+		char *p;
+		size_metachars = (size_metachars > 0) ? size_metachars*2 : 16;
+		p = (char *) malloc(size_metachars);
+		if (p == NULL)
+			pr_error("Cannot allocate memory");
+
+		if (metachars != NULL)
+		{
+			strcpy(p, metachars);
+			free(metachars);
+		}
+		metachars = p;
+	}
+	metachars[num_metachars++] = ch;
+	metachars[num_metachars] = '\0';
+}
+
+	static int
+is_metachar(ch)
+	int ch;
+{
+	return (metachars != NULL && strchr(metachars, ch) != NULL);
+}
 
 #if !HAVE_STRCHR
 	char *
@@ -192,6 +222,7 @@ main(argc, argv)
 			break;
 		case 'f':
 			meta_escape_buf[0] = lstrtol(++arg, 0, &s);
+			meta_escape_buf[1] = '\0';
 			meta_escape = meta_escape_buf;
 			if (s == arg)
 				pr_error("Missing number after -f");
@@ -205,14 +236,12 @@ main(argc, argv)
 				pr_error("Missing number after -p");
 			break;
 		case 'm':
-			metachars[num_metachars++] = *++arg;
-			metachars[num_metachars] = '\0';
+			add_metachar(*++arg);
 			break;
 		case 'n':
-			metachars[num_metachars++] = lstrtol(++arg, 0, &s);
+			add_metachar(lstrtol(++arg, 0, &s));
 			if (s == arg)
 				pr_error("Missing number after -n");
-			metachars[num_metachars] = '\0';
 			break;
 		case '?':
 			pr_usage();
@@ -245,7 +274,7 @@ main(argc, argv)
 		arg = *argv++;
 		for (s = arg;  *s != '\0';  s++)
 		{
-			if (strchr(metachars, *s) != NULL)
+			if (is_metachar(*s))
 			{
 				has_meta = 1;
 				break;
@@ -257,7 +286,7 @@ main(argc, argv)
 		{
 			for (s = arg;  *s != '\0';  s++)
 			{
-				if (strchr(metachars, *s) != NULL)
+				if (is_metachar(*s))
 					printf("%s", meta_escape);
 				printf("%c", *s);
 			}
diff --git a/lessecho.man b/lessecho.man
index ec33d19..a7f1b35 100644
--- a/lessecho.man
+++ b/lessecho.man
@@ -51,4 +51,4 @@ LESSECHO(1)                 General Commands Manual                LESSECHO(1)
 
 
 
-                           Version 590: 03 Jun 2021                LESSECHO(1)
+                           Version 600: 07 Jan 2022                LESSECHO(1)
diff --git a/lessecho.nro b/lessecho.nro
index 4733a93..0abd5d5 100644
--- a/lessecho.nro
+++ b/lessecho.nro
@@ -1,4 +1,4 @@
-.TH LESSECHO 1 "Version 590: 03 Jun 2021"
+.TH LESSECHO 1 "Version 600: 07 Jan 2022"
 .SH NAME
 lessecho \- expand metacharacters
 .SH SYNOPSIS
diff --git a/lesskey.c b/lesskey.c
index b5130cc..39ebe8b 100644
--- a/lesskey.c
+++ b/lesskey.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -122,6 +122,14 @@ lesskey_parse_error(s)
 	fprintf(stderr, "%s\n", s);
 }
 
+	int
+lstrtoi(buf, ebuf)
+	char *buf;
+	char **ebuf;
+{
+	return (int) strtol(buf, ebuf, 10);
+}
+
 	void *
 ecalloc(count, size)
 	int count;
@@ -366,5 +374,6 @@ main(argc, argv)
 	/* File trailer */
 	fputbytes(out, endsection, sizeof(endsection));
 	fputbytes(out, filetrailer, sizeof(filetrailer));
+	fclose(out);
 	return (0);
 }
diff --git a/lesskey.h b/lesskey.h
index 1e70a7f..988c6aa 100644
--- a/lesskey.h
+++ b/lesskey.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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/lesskey.man b/lesskey.man
index 56c75db..579e03b 100644
--- a/lesskey.man
+++ b/lesskey.man
@@ -3,7 +3,7 @@ LESSKEY(1)                  General Commands Manual                 LESSKEY(1)
 
 
 NAME
-       lesskey - specify key bindings for less
+       lesskey - customize key bindings for less
 
 SYNOPSIS (deprecated)
        lesskey [-o output] [--] [input]
@@ -16,84 +16,88 @@ LESSKEY(1)                  General Commands Manual                 LESSKEY(1)
        used by less version 582 and later.  In previous versions  of  less,  a
        separate  program called lesskey was used to compile the lesskey source
        file into a format understood by less.  This  compilation  step  is  no
-       longer  required  and  the  lesskey program is therefore deprecated al-
+       longer  required  and  the lesskey program is therefore deprecated, al-
        though the file format remains supported by less itself.
 
+DESCRIPTION
+       A lesskey file specifies a set of key bindings  and  environment  vari-
+       ables to be used by subsequent invocations of less.
+
 FILE FORMAT
-       The input file consists of one or more sections.  Each  section  starts
-       with  a  line  that  identifies the type of section.  Possible sections
+       The  input  file consists of one or more sections.  Each section starts
+       with a line that identifies the type  of  section.   Possible  sections
        are:
 
        #command
-              Defines new command keys.
+              Customizes command key bindings.
 
        #line-edit
-              Defines new line-editing keys.
+              Customizes line-editing key bindings.
 
        #env   Defines environment variables.
 
-       Blank lines and lines which start with a pound sign  (#)  are  ignored,
-       except for the special section header lines.
+       Blank  lines  and  lines which start with a pound sign (#) are ignored,
+       except as noted below.
 
 COMMAND SECTION
        The command section begins with the line
 
        #command
 
-       If  the command section is the first section in the file, this line may
+       If the command section is the first section in the file, this line  may
        be omitted.  The command section consists of lines of the form:
 
             string <whitespace> action [extra-string] <newline>
 
-       Whitespace is any sequence of one or  more  spaces  and/or  tabs.   The
-       string  is  the command key(s) which invoke the action.  The string may
+       Whitespace  is  any  sequence  of  one or more spaces and/or tabs.  The
+       string is the command key(s) which invoke the action.  The  string  may
        be a single command key, or a sequence of up to 15 keys.  The action is
-       the  name  of  the less action, from the list below.  The characters in
-       the string may appear literally, or be prefixed by a caret to  indicate
-       a  control  key.  A backslash followed by one to three octal digits may
-       be used to specify a character by its octal value.   A  backslash  fol-
+       the name of the less action, from the list below.   The  characters  in
+       the  string may appear literally, or be prefixed by a caret to indicate
+       a control key.  A backslash followed by one to three octal  digits  may
+       be  used  to  specify a character by its octal value.  A backslash fol-
        lowed by certain characters specifies input characters as follows:
 
-       \b     BACKSPACE
-
-       \e     ESCAPE
-
-       \n     NEWLINE
-
-       \r     RETURN
-
-       \t     TAB
-
-       \ku    UP ARROW
-
-       \kd    DOWN ARROW
-
-       \kr    RIGHT ARROW
-
-       \kl    LEFT ARROW
-
-       \kU    PAGE UP
-
-       \kD    PAGE DOWN
-
-       \kh    HOME
-
-       \ke    END
-
-       \kx    DELETE
-
-       A backslash followed by any other character indicates that character is
-       to be taken literally.  Characters which must be preceded by  backslash
-       include caret, space, tab and the backslash itself.
-
-       An action may be followed by an "extra" string.  When such a command is
-       entered while running less, the action is performed, and then the extra
-       string  is  parsed,  just as if it were typed in to less.  This feature
-       can be used in certain cases to extend the functionality of a  command.
-       For  example,  see the "{" and ":t" commands in the example below.  The
-       extra string has a special meaning for the  "quit"  action:  when  less
-       quits, the first character of the extra string is used as its exit sta-
-       tus.
+            \b   BACKSPACE   (0x08)
+            \e   ESCAPE      (0x1B)
+            \n   NEWLINE     (0x0A)
+            \r   RETURN      (0x0D)
+            \t   TAB         (0x09)
+
+            \k followed by a single character represents the char(s)  produced
+            when one of these keys is pressed:
+
+            \kb   BACKSPACE (the BACKSPACE key)
+            \kB   ctrl-BACKSPACE
+            \kd   DOWN ARROW
+            \kD   PAGE DOWN
+            \ke   END
+            \kh   HOME
+            \ki   INSERT
+            \kl   LEFT ARROW
+            \kL   ctrl-LEFT ARROW
+            \kr   RIGHT ARROW
+            \kR   ctrl-RIGHT ARROW
+            \kt   BACKTAB
+            \ku   UP ARROW
+            \kU   PAGE UP
+            \kx   DELETE
+            \kX   ctrl-DELETE
+            \k1   F1
+
+
+            A backslash followed by any other character indicates that charac-
+            ter is to be taken literally.  Characters which must  be  preceded
+            by backslash include caret, space, tab and the backslash itself.
+
+            An  action may be followed by an "extra" string.  When such a com-
+            mand is entered while running less, the action is  performed,  and
+            then  the  extra  string is parsed, just as if it were typed in to
+            less.  This feature can be used in certain  cases  to  extend  the
+            functionality  of  a  command.   For example, see the "{" and ":t"
+            commands in the example below.  The extra  string  has  a  special
+            meaning  for the "quit" action: when less quits, the first charac-
+            ter of the extra string is used as its exit status.
 
 EXAMPLE
        The following input file describes the set of default command keys used
@@ -125,11 +129,11 @@ LESSKEY(1)                  General Commands Manual                 LESSKEY(1)
             ^F         forw-screen
             ^V         forw-screen
             \kD        forw-screen
+
             b          back-screen
             ^B         back-screen
             \ev        back-screen
             \kU        back-screen
-
             z          forw-window
             w          back-window
             \e\40      forw-screen-force
@@ -191,11 +195,11 @@ LESSKEY(1)                  General Commands Manual                 LESSKEY(1)
             :n         next-file
             :p         prev-file
             t          next-tag
+
             T          prev-tag
             :x         index-file
             :d         remove-file
             -          toggle-option
-
             :t         toggle-option t
             s          toggle-option o
             _          display-option
@@ -257,11 +261,11 @@ LESSKEY(1)                  General Commands Manual                 LESSKEY(1)
        used by less:
 
 
+
             #line-edit
             \t           forw-complete
             \17          back-complete
             \e\t         back-complete
-
             ^L           expand
             ^V           literal
             ^A           literal
@@ -300,44 +304,72 @@ LESSKEY(1)                  General Commands Manual                 LESSKEY(1)
        before and after the equals sign is  ignored.   Variables  assigned  in
        this  way  are visible only to less.  If a variable is specified in the
        system environment and also in a lesskey file, the value in the lesskey
-       file  takes precedence.  Although the lesskey file can be used to over-
-       ride variables set in the environment, the main  purpose  of  assigning
-       variables  in the lesskey file is simply to have all less configuration
-       information stored in one file.
+       file takes precedence.
 
-EXAMPLE
-       The following input file sets the -i option whenever less is  run,  and
-       specifies the character set to be "latin1":
+       If the variable name is followed by += rather than =, the string is ap-
+       pended to the variable's existing value.  This currently works only  if
+       any += lines immediately follow the same variable's original definition
+       (with an = line), without any intervening definitions  of  other  vari-
+       ables.   It  can append only to a variable defined earlier in the file;
+       it cannot append to a variable in the system environment.
 
-                 #env
-                 LESS = -i
-                 LESSCHARSET = latin1
+CONDITIONAL CONFIGURATION
+       If a line begins with #version followed by a relational operator and  a
+       version  number, the remainder of the line is parsed if and only if the
+       running version of less (or lesskey) matches the operator.  This can be
+       helpful if a lesskey file is used by different versions of less.
+
+       For  example,  suppose  that  a  new command named 'sideways-search' is
+       added in less version 777.  Then the following line  would  assign  the
+       command  to  the  Q key, but only in versions of less which support it.
+       The line would be ignored by versions earlier than 777.
+
+                 #version >= 777  Q sideways-search
+
+       These six operators are supported:
+
+             >    Greater than
+             <    Less than
+             >=   Greater than or equal to
+             <=   Less than or equal to
+             =    Equal to
+             !=   Not equal to
+
+       The #version feature is not supported in less and lesskey  before  ver-
+       sion 594.  In those older versions, all #version lines are ignored.
+
+EXAMPLE
+       The following input file sets the -i and -S options when is run and, on
+       version 595 and higher, adds a --color option.
 
+          #env
+          LESS = -i -S
+          #version >= 595  LESS += --color=Hkc
 
 SEE ALSO
        less(1)
 
 WARNINGS
-       On  MS-DOS and OS/2 systems, certain keys send a sequence of characters
-       which start with a NUL character (0).  This  NUL  character  should  be
+       On MS-DOS and OS/2 systems, certain keys send a sequence of  characters
+       which  start  with  a  NUL character (0).  This NUL character should be
        represented as \340 in a lesskey file.
 
 COPYRIGHT
        Copyright (C) 1984-2021  Mark Nudelman
 
-       less  is  part of the GNU project and is free software.  You can redis-
-       tribute it and/or modify it under the terms of either (1) the GNU  Gen-
-       eral  Public  License  as published by the Free Software Foundation; or
+       less is part of the GNU project and is free software.  You  can  redis-
+       tribute  it and/or modify it under the terms of either (1) the GNU Gen-
+       eral Public License as published by the Free  Software  Foundation;  or
        (2) the Less License.  See the file README in the less distribution for
        more details regarding redistribution.  You should have received a copy
-       of the GNU General Public License along with the source for  less;  see
-       the  file  COPYING.   If not, write to the Free Software Foundation, 59
-       Temple Place, Suite 330, Boston, MA  02111-1307, USA.  You should  also
+       of  the  GNU General Public License along with the source for less; see
+       the file COPYING.  If not, write to the Free  Software  Foundation,  59
+       Temple  Place, Suite 330, Boston, MA  02111-1307, USA.  You should also
        have received a copy of the Less License; see the file LICENSE.
 
        less is distributed in the hope that it will be useful, but WITHOUT ANY
-       WARRANTY; without even the implied warranty of MERCHANTABILITY or  FIT-
-       NESS  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+       WARRANTY;  without even the implied warranty of MERCHANTABILITY or FIT-
+       NESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License  for
        more details.
 
 AUTHOR
@@ -346,4 +378,4 @@ LESSKEY(1)                  General Commands Manual                 LESSKEY(1)
 
 
 
-                           Version 590: 03 Jun 2021                 LESSKEY(1)
+                           Version 600: 07 Jan 2022                 LESSKEY(1)
diff --git a/lesskey.nro b/lesskey.nro
index 9b3ec16..ef421c9 100644
--- a/lesskey.nro
+++ b/lesskey.nro
@@ -1,7 +1,7 @@
 '\" t
-.TH LESSKEY 1 "Version 590: 03 Jun 2021"
+.TH LESSKEY 1 "Version 600: 07 Jan 2022"
 .SH NAME
-lesskey \- specify key bindings for less
+lesskey \- customize key bindings for less
 .SH "SYNOPSIS (deprecated)"
 .B "lesskey [\-o output] [\-\-] [input]"
 .br
@@ -26,24 +26,30 @@ source file into a format understood by
 .IR less .
 This compilation step is no longer required and the
 .I lesskey
-program is therefore deprecated although the file format remains supported by
+program is therefore deprecated, although the file format remains supported by
 .I less
 itself.
 .PP
+.SH DESCRIPTION
+A
+.I lesskey
+file specifies a set of key bindings and environment variables
+to be used by subsequent invocations of
+.I less.
 .SH FILE FORMAT
 The input file consists of one or more
 .I sections.
 Each section starts with a line that identifies the type of section.
 Possible sections are:
 .IP #command
-Defines new command keys.
+Customizes command key bindings.
 .IP #line-edit
-Defines new line-editing keys.
+Customizes line-editing key bindings.
 .IP #env
 Defines environment variables.
 .PP
 Blank lines and lines which start with a pound sign (#) are ignored,
-except for the special section header lines.
+except as noted below.
 .
 .SH "COMMAND SECTION"
 The command section begins with the line
@@ -66,34 +72,38 @@ A backslash followed by one to three octal digits may be used to
 specify a character by its octal value.
 A backslash followed by certain characters specifies input
 characters as follows:
-.IP \eb
-BACKSPACE
-.IP \ee
-ESCAPE
-.IP \en
-NEWLINE
-.IP \er
-RETURN
-.IP \et
-TAB
-.IP \eku
-UP ARROW
-.IP \ekd
-DOWN ARROW
-.IP \ekr
-RIGHT ARROW
-.IP \ekl
-LEFT ARROW
-.IP \ekU
-PAGE UP
-.IP \ekD
-PAGE DOWN
-.IP \ekh
-HOME
-.IP \eke
-END
-.IP \ekx
-DELETE
+.RS 5m
+.TS
+l l l.
+\eb	BACKSPACE	(0x08)
+\ee	ESCAPE	(0x1B)
+\en	NEWLINE	(0x0A)
+\er	RETURN	(0x0D)
+\et	TAB	(0x09)
+.TE
+.sp
+\ek followed by a single character represents the char(s) produced when one of these keys is pressed:
+.TS
+l l.
+\ekb	BACKSPACE (the BACKSPACE key)
+\ekB	ctrl-BACKSPACE
+\ekd	DOWN ARROW
+\ekD	PAGE DOWN
+\eke	END
+\ekh	HOME
+\eki	INSERT
+\ekl	LEFT ARROW
+\ekL	ctrl-LEFT ARROW
+\ekr	RIGHT ARROW
+\ekR	ctrl-RIGHT ARROW
+\ekt	BACKTAB
+\eku	UP ARROW
+\ekU	PAGE UP
+\ekx	DELETE
+\ekX	ctrl-DELETE
+\ek1	F1
+.TE
+
 .PP
 A backslash followed by any other character indicates that character is
 to be taken literally.
@@ -333,23 +343,67 @@ Variables assigned in this way are visible only to
 .IR less .
 If a variable is specified in the system environment and also in a
 lesskey file, the value in the lesskey file takes precedence.
-Although the lesskey file can be used to override variables set in the
-environment, the main purpose of assigning variables in the lesskey file
-is simply to have all
+.
+.sp
+If the variable name is followed by += rather than =,
+the string is appended to the variable's existing value.
+This currently works only if any += lines immediately follow
+the same variable's original definition (with an = line),
+without any intervening definitions of other variables.
+It can append only to a variable defined earlier in the file;
+it cannot append to a variable in the system environment.
+.
+.SH CONDITIONAL CONFIGURATION
+If a line begins with #version followed by a relational operator and a version number,
+the remainder of the line is parsed if and only if the running version of
+.I less
+(or
+.IR lesskey )
+matches the operator.
+This can be helpful if a lesskey file is used by different versions of
+.IR less .
+.sp
+For example, suppose that a new command named 'sideways-search' is added in 
+.I less
+version 777.
+Then the following line would assign the command to the Q key, but only in versions of
 .I less
-configuration information stored in one file.
+which support it. The line would be ignored by versions earlier than 777.
+.sp
+.nf
+	#version >= 777  Q sideways-search
+.fi
+.sp
+These six operators are supported:
+.RS 5m
+.TS
+l l.
+ >	Greater than
+ <	Less than
+ >=	Greater than or equal to
+ <=	Less than or equal to
+ =	Equal to
+ !=	Not equal to
+.TE
+.RE
+.sp
+The #version feature is not supported in
+.I less
+and
+.I lesskey
+before version 594.
+In those older versions, all #version lines are ignored.
 .
 .SH EXAMPLE
-The following input file sets the \-i option whenever
-.I less
-is run, and specifies the character set to be "latin1":
+The following input file sets the \-i and \-S options when
+.less
+is run and, on version 595 and higher, adds a \-\-color option.
 .sp
 .nf
 	#env
-	LESS = \-i
-	LESSCHARSET = latin1
+	LESS = \-i\ \-S
+	#version\ >=\ 595\ \ LESS\ +=\ \-\-color=Hkc
 .fi
-.sp
 .
 .SH "SEE ALSO"
 .BR less (1)
diff --git a/lesskey_parse.c b/lesskey_parse.c
index 18cdf37..7042b6e 100644
--- a/lesskey_parse.c
+++ b/lesskey_parse.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -21,9 +21,12 @@
 extern void lesskey_parse_error(char *msg);
 extern char *homefile(char *filename);
 extern void *ecalloc(int count, unsigned int size);
+extern int lstrtoi(char *str, char **end);
+extern char version[];
 
 static int linenum;
 static int errors;
+static int less_version = 0;
 static char *lesskey_file;
 
 static struct lesskey_cmdname cmdnames[] = 
@@ -124,13 +127,15 @@ static struct lesskey_cmdname editnames[] =
  * Print a parse error message.
  */
 	static void
-parse_error(s1, s2)
-	char *s1;
-	char *s2;
+parse_error(fmt, arg1)
+	char *fmt;
+	char *arg1;
 {
 	char buf[1024];
+	int n = snprintf(buf, sizeof(buf), "%s: line %d: ", lesskey_file, linenum);
+	if (n >= 0 && n < sizeof(buf))
+		snprintf(buf+n, sizeof(buf)-n, fmt, arg1);
 	++errors;
-	snprintf(buf, sizeof(buf), "%s: line %d: %s%s", lesskey_file, linenum, s1, s2);
 	lesskey_parse_error(buf);
 }
 
@@ -156,6 +161,37 @@ init_tables(tables)
 	xbuf_init(&tables->vartable.buf);
 }
 
+#define CHAR_STRING_LEN 8
+
+	static char *
+char_string(buf, ch, lit)
+	char *buf;
+	int ch;
+	int lit;
+{
+	if (lit || (ch >= 0x20 && ch < 0x7f))
+	{
+		buf[0] = ch;
+		buf[1] = '\0';
+	} else
+	{
+		snprintf(buf, CHAR_STRING_LEN, "\\x%02x", ch);
+	}
+	return buf;
+}
+
+/*
+ * Increment char pointer by one up to terminating nul byte.
+ */
+	static char *
+increment_pointer(p)
+	char *p;
+{
+	if (*p == '\0')
+		return p;
+	return p+1;
+}
+
 /*
  * Parse one character of a string.
  */
@@ -167,7 +203,7 @@ tstr(pp, xlate)
 	char *p;
 	char ch;
 	int i;
-	static char buf[10];
+	static char buf[CHAR_STRING_LEN];
 	static char tstr_control_k[] =
 		{ SK_SPECIAL_KEY, SK_CONTROL_K, 6, 1, 1, 1, '\0' };
 
@@ -191,17 +227,13 @@ tstr(pp, xlate)
 			*pp = p;
 			if (xlate && ch == CONTROL('K'))
 				return tstr_control_k;
-			buf[0] = ch;
-			buf[1] = '\0';
-			return (buf);
+			return char_string(buf, ch, 1);
 		case 'b':
 			*pp = p+1;
 			return ("\b");
 		case 'e':
 			*pp = p+1;
-			buf[0] = ESC;
-			buf[1] = '\0';
-			return (buf);
+			return char_string(buf, ESC, 1);
 		case 'n':
 			*pp = p+1;
 			return ("\n");
@@ -216,19 +248,27 @@ tstr(pp, xlate)
 			{
 				switch (*++p)
 				{
-				case 'u': ch = SK_UP_ARROW; break;
+				case 'b': ch = SK_BACKSPACE; break;
+				case 'B': ch = SK_CTL_BACKSPACE; break;
 				case 'd': ch = SK_DOWN_ARROW; break;
-				case 'r': ch = SK_RIGHT_ARROW; break;
-				case 'l': ch = SK_LEFT_ARROW; break;
-				case 'U': ch = SK_PAGE_UP; break;
 				case 'D': ch = SK_PAGE_DOWN; break;
-				case 'h': ch = SK_HOME; break;
 				case 'e': ch = SK_END; break;
+				case 'h': ch = SK_HOME; break;
+				case 'i': ch = SK_INSERT; break;
+				case 'l': ch = SK_LEFT_ARROW; break;
+				case 'L': ch = SK_CTL_LEFT_ARROW; break;
+				case 'r': ch = SK_RIGHT_ARROW; break;
+				case 'R': ch = SK_CTL_RIGHT_ARROW; break;
+				case 't': ch = SK_BACKTAB; break;
+				case 'u': ch = SK_UP_ARROW; break;
+				case 'U': ch = SK_PAGE_UP; break;
 				case 'x': ch = SK_DELETE; break;
-				default: { char buf[2]; buf[0] = *p; buf[1] = '\0';
-					parse_error("illegal escape sequence \\k", buf);
-					*pp = p+1;
-					return (""); }
+				case 'X': ch = SK_CTL_DELETE; break;
+				case '1': ch = SK_F1; break;
+				default:
+					parse_error("invalid escape sequence \"\\k%s\"", char_string(buf, *p, 0));
+					*pp = increment_pointer(p);
+					return ("");
 				}
 				*pp = p+1;
 				buf[0] = SK_SPECIAL_KEY;
@@ -246,9 +286,8 @@ tstr(pp, xlate)
 			 * Backslash followed by any other char 
 			 * just means that char.
 			 */
-			*pp = p+1;
-			buf[0] = *p;
-			buf[1] = '\0';
+			*pp = increment_pointer(p);
+			char_string(buf, *p, 1);
 			if (xlate && buf[0] == CONTROL('K'))
 				return tstr_control_k;
 			return (buf);
@@ -257,16 +296,14 @@ tstr(pp, xlate)
 		/*
 		 * Caret means CONTROL.
 		 */
-		*pp = p+2;
-		buf[0] = CONTROL(p[1]);
-		buf[1] = '\0';
+		*pp = increment_pointer(p+1);
+		char_string(buf, CONTROL(p[1]), 1);
 		if (xlate && buf[0] == CONTROL('K'))
 			return tstr_control_k;
 		return (buf);
 	}
-	*pp = p+1;
-	buf[0] = *p;
-	buf[1] = '\0';
+	*pp = increment_pointer(p);
+	char_string(buf, *p, 1);
 	if (xlate && buf[0] == CONTROL('K'))
 		return tstr_control_k;
 	return (buf);
@@ -332,6 +369,13 @@ add_cmd_char(c, tables)
 	xbuf_add(&tables->currtable->buf, c);
 }
 
+	static void
+erase_cmd_char(tables)
+	struct lesskey_tables *tables;
+{
+	xbuf_pop(&tables->currtable->buf);
+}
+
 /*
  * Add a string to the output command table.
  */
@@ -345,9 +389,71 @@ add_cmd_str(s, tables)
 }
 
 /*
- * See if we have a special "control" line.
+ * Does a given version number match the running version?
+ * Operator compares the running version to the given version.
  */
 	static int
+match_version(op, ver)
+	char op;
+	int ver;
+{
+	switch (op)
+	{
+	case '>': return less_version > ver;
+	case '<': return less_version < ver;
+	case '+': return less_version >= ver;
+	case '-': return less_version <= ver;
+	case '=': return less_version == ver;
+	case '!': return less_version != ver;
+	default: return 0; /* cannot happen */
+	}
+}
+
+/*
+ * Handle a #version line.
+ * If the version matches, return the part of the line that should be executed.
+ * Otherwise, return NULL.
+ */
+	static char *
+version_line(s, tables)
+	char *s;
+	struct lesskey_tables *tables;
+{
+	char op;
+	int ver;
+	char *e;
+	char buf[CHAR_STRING_LEN];
+
+	s += strlen("#version");
+	s = skipsp(s);
+	op = *s++;
+	/* Simplify 2-char op to one char. */
+	switch (op)
+	{
+	case '<': if (*s == '=') { s++; op = '-'; } break;
+	case '>': if (*s == '=') { s++; op = '+'; } break;
+	case '=': if (*s == '=') { s++; } break;
+	case '!': if (*s == '=') { s++; } break;
+	default: 
+		parse_error("invalid operator '%s' in #version line", char_string(buf, op, 0));
+		return (NULL);
+	}
+	s = skipsp(s);
+	ver = lstrtoi(s, &e);
+	if (e == s)
+	{
+		parse_error("non-numeric version number in #version line", "");
+		return (NULL);
+	}
+	if (!match_version(op, ver))
+		return (NULL);
+	return (e);
+}
+
+/*
+ * See if we have a special "control" line.
+ */
+	static char *
 control_line(s, tables)
 	char *s;
 	struct lesskey_tables *tables;
@@ -357,25 +463,29 @@ control_line(s, tables)
 	if (PREFIX(s, "#line-edit"))
 	{
 		tables->currtable = &tables->edittable;
-		return (1);
+		return (NULL);
 	}
 	if (PREFIX(s, "#command"))
 	{
 		tables->currtable = &tables->cmdtable;
-		return (1);
+		return (NULL);
 	}
 	if (PREFIX(s, "#env"))
 	{
 		tables->currtable = &tables->vartable;
-		return (1);
+		return (NULL);
 	}
 	if (PREFIX(s, "#stop"))
 	{
 		add_cmd_char('\0', tables);
 		add_cmd_char(A_END_LIST, tables);
-		return (1);
+		return (NULL);
 	}
-	return (0);
+	if (PREFIX(s, "#version"))
+	{
+		return (version_line(s, tables));
+	}
+	return (s);
 }
 
 /*
@@ -391,7 +501,7 @@ findaction(actname, tables)
 	for (i = 0;  tables->currtable->names[i].cn_name != NULL;  i++)
 		if (strcmp(tables->currtable->names[i].cn_name, actname) == 0)
 			return (tables->currtable->names[i].cn_action);
-	parse_error("unknown action: ", actname);
+	parse_error("unknown action: \"%s\"", actname);
 	return (A_INVALID);
 }
 
@@ -478,26 +588,37 @@ parse_varline(line, tables)
 {
 	char *s;
 	char *p = line;
+	char *eq;
 
-	do
+	eq = strchr(line, '=');
+	if (eq != NULL && eq > line && eq[-1] == '+')
 	{
-		s = tstr(&p, 0);
-		add_cmd_str(s, tables);
-	} while (*p != '\0' && !issp(*p) && *p != '=');
-	/*
-	 * Terminate the variable name with a null byte.
-	 */
-	add_cmd_char('\0', tables);
-
-	p = skipsp(p);
-	if (*p++ != '=')
+		/*
+		 * Rather ugly way of handling a += line.
+		 * {{ Note that we ignore the variable name and 
+		 *    just append to the previously defined variable. }}
+		 */
+		erase_cmd_char(tables); /* backspace over the final null */
+		p = eq+1;
+	} else
 	{
-		parse_error("missing = in: ", line);
-		return;
+		do
+		{
+			s = tstr(&p, 0);
+			add_cmd_str(s, tables);
+		} while (*p != '\0' && !issp(*p) && *p != '=');
+		/*
+		 * Terminate the variable name with a null byte.
+		 */
+		add_cmd_char('\0', tables);
+		p = skipsp(p);
+		if (*p++ != '=')
+		{
+			parse_error("missing = in variable definition", "");
+			return;
+		}
+		add_cmd_char(EV_OK|A_EXTRA, tables);
 	}
-
-	add_cmd_char(EV_OK|A_EXTRA, tables);
-
 	p = skipsp(p);
 	while (*p != '\0')
 	{
@@ -520,14 +641,15 @@ parse_line(line, tables)
 	/*
 	 * See if it is a control line.
 	 */
-	if (control_line(line, tables))
+	p = control_line(line, tables);
+	if (p == NULL)
 		return;
 	/*
 	 * Skip leading white space.
 	 * Replace the final newline with a null byte.
 	 * Ignore blank lines and comments.
 	 */
-	p = clean_line(line);
+	p = clean_line(p);
 	if (*p == '\0')
 		return;
 
@@ -555,6 +677,8 @@ parse_lesskey(infile, tables)
 	init_tables(tables);
 	errors = 0;
 	linenum = 0;
+	if (less_version == 0)
+		less_version = lstrtoi(version, NULL);
 
 	/*
 	 * Open the input file.
@@ -563,7 +687,7 @@ parse_lesskey(infile, tables)
 		desc = stdin;
 	else if ((desc = fopen(infile, "r")) == NULL)
 	{
-		/* parse_error("cannot open lesskey file ", infile); */
+		/* parse_error("cannot open lesskey file %s", infile); */
 		return (-1);
 	}
 
@@ -575,6 +699,6 @@ parse_lesskey(infile, tables)
 		++linenum;
 		parse_line(line, tables);
 	}
-
+	fclose(desc);
 	return (errors);
 }
diff --git a/lglob.h b/lglob.h
index 2e5e74e..794488a 100644
--- a/lglob.h
+++ b/lglob.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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/line.c b/line.c
index b8f609e..0ef9b07 100644
--- a/line.c
+++ b/line.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -33,11 +33,28 @@ static struct {
 	int pfx_end;  /* Number of chars in pfx */
 } linebuf;
 
+/*
+ * Buffer of ansi sequences which have been shifted off the left edge 
+ * of the screen. 
+ */
 struct xbuffer shifted_ansi;
-struct xbuffer last_ansi;
+
+/*
+ * Ring buffer of last ansi sequences sent.
+ * While sending a line, these will be resent at the end
+ * of any highlighted string, to restore text modes.
+ * {{ Not ideal, since we don't really know how many to resend. }}
+ */
+#define NUM_LAST_ANSIS 3
+static struct xbuffer last_ansi;
+static struct xbuffer last_ansis[NUM_LAST_ANSIS];
+static int curr_last_ansi;
 
 public int size_linebuf = 0; /* Size of line buffer (and attr buffer) */
 static struct ansi_state *line_ansi = NULL;
+static int ansi_in_line;
+static int hlink_in_line;
+static int line_mark_attr;
 static int cshift;   /* Current left-shift of output line buffer */
 public int hshift;   /* Desired left-shift of output line buffer */
 public int tabstops[TABSTOP_MAX] = { 0 }; /* Custom tabstops */
@@ -82,6 +99,7 @@ extern POSITION end_attnpos;
 extern char rscroll_char;
 extern int rscroll_attr;
 extern int use_color;
+extern int status_line;
 
 static char mbc_buf[MAX_UTF_CHAR_LEN];
 static int mbc_buf_len = 0;
@@ -99,6 +117,7 @@ static char color_map[AT_NUM_COLORS][12] = {
 	"kC",  /* AT_COLOR_PROMPT */
 	"kc",  /* AT_COLOR_RSCROLL */
 	"kG",  /* AT_COLOR_SEARCH */
+	"",    /* AT_COLOR_HEADER */
 	"",    /* AT_UNDERLINE */
 	"",    /* AT_BOLD */
 	"",    /* AT_BLINK */
@@ -118,6 +137,8 @@ struct ansi_state {
 	public void
 init_line(VOID_PARAM)
 {
+	int ax;
+
 	end_ansi_chars = lgetenv("LESSANSIENDCHARS");
 	if (isnullenv(end_ansi_chars))
 		end_ansi_chars = "m";
@@ -131,6 +152,9 @@ init_line(VOID_PARAM)
 	size_linebuf = LINEBUF_SIZE;
 	xbuf_init(&shifted_ansi);
 	xbuf_init(&last_ansi);
+	for (ax = 0;  ax < NUM_LAST_ANSIS;  ax++)
+		xbuf_init(&last_ansis[ax]);
+	curr_last_ansi = 0;
 }
 
 /*
@@ -141,15 +165,8 @@ expand_linebuf(VOID_PARAM)
 {
 	/* Double the size of the line buffer. */
 	int new_size = size_linebuf * 2;
-
-	/* Just realloc to expand the buffer, if we can. */
-#if HAVE_REALLOC
-	char *new_buf = (char *) realloc(linebuf.buf, new_size);
-	int *new_attr = (int *) realloc(linebuf.attr, new_size*sizeof(int));
-#else
 	char *new_buf = (char *) calloc(new_size, sizeof(char));
 	int *new_attr = (int *) calloc(new_size, sizeof(int));
-#endif
 	if (new_buf == NULL || new_attr == NULL)
 	{
 		if (new_attr != NULL)
@@ -158,7 +175,6 @@ expand_linebuf(VOID_PARAM)
 			free(new_buf);
 		return 1;
 	}
-#if !HAVE_REALLOC
 	/*
 	 * We just calloc'd the buffers; copy the old contents.
 	 */
@@ -166,7 +182,6 @@ expand_linebuf(VOID_PARAM)
 	memcpy(new_attr, linebuf.attr, size_linebuf * sizeof(int));
 	free(linebuf.attr);
 	free(linebuf.buf);
-#endif
 	linebuf.buf = new_buf;
 	linebuf.attr = new_attr;
 	size_linebuf = new_size;
@@ -203,6 +218,8 @@ inc_end_column(w)
 	public void
 prewind(VOID_PARAM)
 {
+	int ax;
+
 	linebuf.print = 6; /* big enough for longest UTF-8 sequence */
 	linebuf.pfx_end = 0;
 	for (linebuf.end = 0; linebuf.end < linebuf.print; linebuf.end++)
@@ -221,8 +238,14 @@ prewind(VOID_PARAM)
 	is_null_line = 0;
 	pendc = '\0';
 	in_hilite = 0;
+	ansi_in_line = 0;
+	hlink_in_line = 0;
+	line_mark_attr = 0;
 	xbuf_reset(&shifted_ansi);
 	xbuf_reset(&last_ansi);
+	for (ax = 0;  ax < NUM_LAST_ANSIS;  ax++)
+		xbuf_reset(&last_ansis[ax]);
+	curr_last_ansi = 0;
 }
 
 /*
@@ -251,6 +274,19 @@ add_linebuf(ch, attr, w)
 	inc_end_column(w);
 }
 
+/*
+ * Append a string to the line buffer.
+ */
+	static void
+addstr_linebuf(s, attr, cw)
+	char *s;
+	int attr;
+	int cw;
+{
+	for ( ;  *s != '\0';  s++)
+		add_linebuf(*s, attr, cw);
+}
+
 /*
  * Set a character in the line prefix buffer.
  */
@@ -301,22 +337,20 @@ plinestart(pos)
 	/*
 	 * Display a status column if the -J option is set.
 	 */
-	if (status_col)
+	if (status_col || status_line)
 	{
-		int a = AT_NORMAL;
 		char c = posmark(pos);
 		if (c != 0)
-			a |= AT_HILITE|AT_COLOR_MARK;
-		else 
+			line_mark_attr = AT_HILITE|AT_COLOR_MARK;
+		else if (start_attnpos != NULL_POSITION &&
+		         pos >= start_attnpos && pos <= end_attnpos)
+			line_mark_attr = AT_HILITE|AT_COLOR_ATTN;
+		if (status_col)
 		{
-			c = ' ';
-			if (start_attnpos != NULL_POSITION &&
-			    pos >= start_attnpos && pos <= end_attnpos)
-				a |= AT_HILITE|AT_COLOR_ATTN;
+			add_pfx(c ? c : ' ', line_mark_attr); /* column 0: status */
+			while (linebuf.pfx_end < status_col_width)
+				add_pfx(' ', AT_NORMAL);
 		}
-		add_pfx(c, a); /* column 0: status */
-		while (linebuf.pfx_end < status_col_width)
-			add_pfx(' ', AT_NORMAL);
 	}
 
 	/*
@@ -328,8 +362,14 @@ plinestart(pos)
 		char buf[INT_STRLEN_BOUND(linenum) + 2];
 		int len;
 
-		linenumtoa(linenum, buf);
-		len = (int) strlen(buf);
+		linenum = vlinenum(linenum);
+		if (linenum == 0)
+			len = 0;
+		else
+		{
+			linenumtoa(linenum, buf);
+			len = (int) strlen(buf);
+		}
 		for (i = 0; i < linenum_width - len; i++)
 			add_pfx(' ', AT_NORMAL);
 		for (i = 0; i < len; i++)
@@ -629,6 +669,20 @@ ansi_done(pansi)
 	free(pansi);
 }
 
+/*
+ * Will w characters in attribute a fit on the screen?
+ */
+	static int
+fits_on_screen(w, a)
+	int w;
+	int a;
+{
+	if (ctldisp == OPT_ON)
+		/* We're not counting, so say that everything fits. */
+		return 1;
+	return (end_column - cshift + w + attr_ewidth(a) <= sc_width);
+}
+
 /*
  * Append a character and attribute to the line buffer.
  */
@@ -657,7 +711,18 @@ store_char(ch, a, rep, pos)
 	{
 		int matches;
 		int resend_last = 0;
-		int hl_attr = is_hilited_attr(pos, pos+1, 0, &matches);
+		int hl_attr;
+
+		if (pos == NULL_POSITION)
+		{
+			/* Color the prompt unless it has ansi sequences in it. */
+			hl_attr = ansi_in_line ? 0 : AT_STANDOUT|AT_COLOR_PROMPT;
+		} else
+		{
+			hl_attr = is_hilited_attr(pos, pos+1, 0, &matches);
+			if (hl_attr == 0 && status_line)
+				hl_attr = line_mark_attr;
+		}
 		if (hl_attr)
 		{
 			/*
@@ -666,7 +731,7 @@ store_char(ch, a, rep, pos)
 			 */
 			if (a != AT_ANSI)
 			{
-				if (highest_hilite != NULL_POSITION && pos > highest_hilite)
+				if (highest_hilite != NULL_POSITION && pos != NULL_POSITION && pos > highest_hilite)
 					highest_hilite = pos;
 				a |= hl_attr;
 			}
@@ -685,8 +750,13 @@ store_char(ch, a, rep, pos)
 		}
 		if (resend_last)
 		{
-			for (i = 0;  i < last_ansi.end;  i++)
-				STORE_CHAR(last_ansi.data[i], AT_ANSI, NULL, pos);
+			int ai;
+			for (ai = 0;  ai < NUM_LAST_ANSIS;  ai++)
+			{
+				int ax = (curr_last_ansi + ai) % NUM_LAST_ANSIS;
+				for (i = 0;  i < last_ansis[ax].end;  i++)
+					STORE_CHAR(last_ansis[ax].data[i], AT_ANSI, NULL, pos);
+			}
 		}
 	}
 #endif
@@ -700,10 +770,7 @@ store_char(ch, a, rep, pos)
 		w = pwidth(ch, a, prev_ch, prev_a);
 	}
 
-	if (ctldisp != OPT_ON && end_column - cshift + w + attr_ewidth(a) > sc_width)
-		/*
-		 * Won't fit on screen.
-		 */
+	if (!fits_on_screen(w, a))
 		return (1);
 
 	if (rep == NULL)
@@ -768,6 +835,22 @@ store_char(ch, a, rep, pos)
 	return (0);
 }
 
+#define STORE_STRING(s,a,pos) \
+	do { if (store_string((s),(a),(pos))) return (1); } while (0)
+
+	static int
+store_string(s, a, pos)
+	char *s;
+	int a;
+	POSITION pos;
+{
+	if (!fits_on_screen(strlen(s), a))
+		return 1;
+	for ( ;  *s != 0;  s++)
+		STORE_CHAR(*s, a, NULL, pos);
+	return 0;
+}
+
 /*
  * Append a tab to the line buffer.
  * Store spaces to represent the tab.
@@ -808,14 +891,10 @@ store_prchar(c, pos)
 	LWCHAR c;
 	POSITION pos;
 {
-	char *s;
-
 	/*
 	 * Convert to printable representation.
 	 */
-	s = prchar(c);
-	for ( ;  *s != 0;  s++)
-		STORE_CHAR(*s, AT_BINARY|AT_COLOR_CTRL, NULL, pos);
+	STORE_STRING(prchar(c), AT_BINARY|AT_COLOR_CTRL, pos);
 	return 0;
 }
 
@@ -958,26 +1037,37 @@ store_ansi(ch, rep, pos)
 	case ANSI_MID:
 		if (!in_hilite)
 			STORE_CHAR(ch, AT_ANSI, rep, pos);
+		if (line_ansi->hlink)
+			hlink_in_line = 1;
+		xbuf_add(&last_ansi, ch);
 		break;
 	case ANSI_END:
 		if (!in_hilite)
 			STORE_CHAR(ch, AT_ANSI, rep, pos);
 		ansi_done(line_ansi);
 		line_ansi = NULL;
+		xbuf_add(&last_ansi, ch);
+		xbuf_set(&last_ansis[curr_last_ansi], &last_ansi);
+		xbuf_reset(&last_ansi);
+		curr_last_ansi = (curr_last_ansi + 1) % NUM_LAST_ANSIS;
 		break;
-	case ANSI_ERR: {
-		/* Remove whole unrecognized sequence.  */
-		char *start = (cshift < hshift) ? shifted_ansi.data : linebuf.buf;
-		int *end = (cshift < hshift) ? &shifted_ansi.end : &linebuf.end;
-		char *p = start + *end;
-		LWCHAR bch;
-		do {
-			bch = step_char(&p, -1, start);
-		} while (p > start && !IS_CSI_START(bch));
-		*end = (int) (p - start);
+	case ANSI_ERR:
+		if (!in_hilite)
+		{
+			/* Remove whole unrecognized sequence.  */
+			char *start = (cshift < hshift) ? shifted_ansi.data : linebuf.buf;
+			int *end = (cshift < hshift) ? &shifted_ansi.end : &linebuf.end;
+			char *p = start + *end;
+			LWCHAR bch;
+			do {
+				bch = step_char(&p, -1, start);
+			} while (p > start && !IS_CSI_START(bch));
+			*end = (int) (p - start);
+		}
+		xbuf_reset(&last_ansi);
 		ansi_done(line_ansi);
 		line_ansi = NULL;
-		break; }
+		break;
 	}
 	return (0);
 } 
@@ -1013,14 +1103,11 @@ do_append(ch, rep, pos)
 	{
 		line_ansi = ansi_start(ch);
 		if (line_ansi != NULL)
-			xbuf_reset(&last_ansi);
+			ansi_in_line = 1;
 	}
 
 	if (line_ansi != NULL)
-	{
-		xbuf_add(&last_ansi, ch);
 		return store_ansi(ch, rep, pos);
-	}
 
 	if (ch == '\b')
 		return store_bs(ch, rep, pos);
@@ -1105,9 +1192,7 @@ do_append(ch, rep, pos)
 		return store_control_char(ch, rep, pos);
 	} else if (utf_mode && ctldisp != OPT_ON && is_ubin_char(ch))
 	{
-		char *s = prutfchar(ch);
-		for ( ;  *s != 0;  s++)
-			STORE_CHAR(*s, AT_BINARY, NULL, pos);
+		STORE_STRING(prutfchar(ch), AT_BINARY, pos);
 	} else
 	{
 		STORE_CHAR(ch, a, rep, pos);
@@ -1138,12 +1223,11 @@ pflushmbc(VOID_PARAM)
 	static void
 add_attr_normal(VOID_PARAM)
 {
-	char *p = "\033[m";
-
 	if (ctldisp != OPT_ONPLUS || !is_ansi_end('m'))
 		return;
-	for ( ;  *p != '\0';  p++)
-		add_linebuf(*p, AT_ANSI, 0);
+	addstr_linebuf("\033[m", AT_ANSI, 0);
+	if (hlink_in_line) /* Don't send hyperlink clear if we know we don't need to. */
+		addstr_linebuf("\033]8;;\033\\", AT_ANSI, 0);
 }
 
 /*
@@ -1195,6 +1279,14 @@ pdone(endline, chopped, forw)
 		add_attr_normal();
 	}
 
+	/*
+	 * If we're coloring a status line, fill out the line with spaces.
+	 */
+	if (status_line && line_mark_attr != 0) {
+		while (end_column +1 < sc_width + cshift)
+			add_linebuf(' ', line_mark_attr, 1);
+	}
+
 	/*
 	 * Add a newline if necessary,
 	 * and append a '\0' to the end of the line.
@@ -1235,7 +1327,20 @@ pdone(endline, chopped, forw)
 }
 
 /*
- *
+ * Set an attribute on each char of the line in the line buffer.
+ */
+	public void
+set_attr_line(a)
+	int a;
+{
+	int i;
+
+	for (i = linebuf.print;  i < linebuf.end;  i++)
+		linebuf.attr[i] |= a;
+}
+
+/*
+ * Set the char to be displayed in the status column.
  */
 	public void
 set_status_col(c, attr)
@@ -1419,6 +1524,50 @@ back_raw_line(curr_pos, linep, line_lenp)
 	return (new_pos);
 }
 
+/*
+ * Append a string to the line buffer.
+ */
+	static int
+pappstr(str)
+	constant char *str;
+{
+	while (*str != '\0')
+	{
+		if (pappend(*str++, NULL_POSITION))
+			/* Doesn't fit on screen. */
+			return 1;
+	}
+	return 0;
+}
+
+/*
+ * Load a string into the line buffer.
+ * If the string is too long to fit on the screen,
+ * truncate the beginning of the string to fit.
+ */
+	public void
+load_line(str)
+	constant char *str;
+{
+	int save_hshift = hshift;
+
+	hshift = 0;
+	for (;;)
+	{
+		prewind();
+		if (pappstr(str) == 0)
+			break;
+		/*
+		 * Didn't fit on screen; increase left shift by one.
+		 * {{ This gets very inefficient if the string
+		 * is much longer than the screen width. }}
+		 */
+		hshift += 1;
+	}
+	set_linebuf(linebuf.end, '\0', AT_NORMAL);
+	hshift = save_hshift;
+}
+
 /*
  * Find the shift necessary to show the end of the longest displayed line.
  */
@@ -1465,16 +1614,17 @@ color_index(attr)
 		case AT_COLOR_PROMPT:  return 6;
 		case AT_COLOR_RSCROLL: return 7;
 		case AT_COLOR_SEARCH:  return 8;
+		case AT_COLOR_HEADER:  return 9;
 		}
 	}
 	if (attr & AT_UNDERLINE)
-		return 9;
-	if (attr & AT_BOLD)
 		return 10;
-	if (attr & AT_BLINK)
+	if (attr & AT_BOLD)
 		return 11;
-	if (attr & AT_STANDOUT)
+	if (attr & AT_BLINK)
 		return 12;
+	if (attr & AT_STANDOUT)
+		return 13;
 	return -1;
 }
 
diff --git a/linenum.c b/linenum.c
index a3e1b2f..1808ea9 100644
--- a/linenum.c
+++ b/linenum.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -68,6 +68,8 @@ extern int linenums;
 extern int sigs;
 extern int sc_height;
 extern int screen_trashed;
+extern int header_lines;
+extern int nonum_headers;
 
 /*
  * Initialize the line number structures.
@@ -484,11 +486,24 @@ scan_eof(VOID_PARAM)
 	ierror("Determining length of file", NULL_PARG);
 	while (pos != NULL_POSITION)
 	{
-        /* For efficiency, only add one every 256 line numbers. */
-        if ((linenum++ % 256) == 0)
-            add_lnum(linenum, pos);
+		/* For efficiency, only add one every 256 line numbers. */
+		if ((linenum++ % 256) == 0)
+			add_lnum(linenum, pos);
 		pos = forw_raw_line(pos, (char **)NULL, (int *)NULL);
 		if (ABORT_SIGS())
 			break;
 	}
 }
+
+/*
+ * Return a line number adjusted for display
+ * (handles the --no-number-headers option).
+ */
+	public LINENUM
+vlinenum(linenum)
+	LINENUM linenum;
+{
+	if (nonum_headers)
+		linenum = (linenum < header_lines) ? 0 : linenum - header_lines;
+	return linenum;
+}
diff --git a/lsystem.c b/lsystem.c
index 5c67526..d817369 100644
--- a/lsystem.c
+++ b/lsystem.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -117,12 +117,7 @@ lsystem(cmd, donemsg)
 	inp = dup(0);
 	close(0);
 #if !MSDOS_COMPILER
-#if OS2
-	/* The __open() system call translates "/dev/tty" to "con". */
-	if (__open(tty_device(), OPEN_READ) < 0)
-#else
-	if (open(tty_device(), OPEN_READ) < 0)
-#endif
+	if (open_tty() < 0)
 #endif
 		dup(inp);
 #endif
diff --git a/main.c b/main.c
index 7248842..98e6344 100644
--- a/main.c
+++ b/main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -60,8 +60,10 @@ extern int      know_dumb;
 extern int      pr_type;
 extern int      quit_if_one_screen;
 extern int      no_init;
-extern int errmsgs;
-
+extern int      errmsgs;
+extern int      redraw_on_quit;
+extern int      term_init_done;
+extern int      first_time;
 
 /*
  * Entry point.
@@ -139,7 +141,7 @@ main(argc, argv)
 
 	s = lgetenv(less_is_more ? "MORE" : "LESS");
 	if (s != NULL)
-		scan_option(save(s));
+		scan_option(s);
 
 #define isoptstring(s)  (((s)[0] == '-' || (s)[0] == '+') && (s)[1] != '\0')
 	while (argc > 0 && (isoptstring(*argv) || isoptpending()))
@@ -409,12 +411,23 @@ quit(status)
 	rstat('Q');
 #endif /*LESSTEST*/
 	quitting = 1;
-	edit((char*)NULL);
 	save_cmdhist();
 	if (interactive())
 		clear_bot();
 	deinit();
 	flush();
+	if (redraw_on_quit && term_init_done)
+	{
+		/*
+		 * The last file text displayed might have been on an 
+		 * alternate screen, which now (since deinit) cannot be seen.
+		 * redraw_on_quit tells us to redraw it on the main screen.
+		 */
+		first_time = 1; /* Don't print "skipping" or tildes */
+		repaint();
+		flush();
+	}
+	edit((char*)NULL);
 	raw_mode(0);
 #if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC
 	/* 
diff --git a/mark.c b/mark.c
index cbb316f..f3bf0c4 100644
--- a/mark.c
+++ b/mark.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -59,6 +59,9 @@ cmark(m, ifile, pos, ln)
 	m->m_ifile = ifile;
 	m->m_scrpos.pos = pos;
 	m->m_scrpos.ln = ln;
+	if (m->m_filename != NULL)
+		/* Normally should not happen but a corrupt lesshst file can do it. */
+		free(m->m_filename);
 	m->m_filename = NULL;
 }
 
diff --git a/optfunc.c b/optfunc.c
index 9e7c869..84333b7 100644
--- a/optfunc.c
+++ b/optfunc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -59,6 +59,10 @@ extern int linenum_width;
 extern int status_col_width;
 extern int use_color;
 extern int want_filesize;
+extern int header_lines;
+extern int header_cols;
+extern int def_search_type;
+extern int chopline;
 #if LOGFILE
 extern char *namelogfile;
 extern int force_logfile;
@@ -164,7 +168,6 @@ opt_j(type, s)
 	char *s;
 {
 	PARG parg;
-	char buf[24];
 	int len;
 	int err;
 
@@ -199,7 +202,7 @@ opt_j(type, s)
 			error("Position target at screen line %d", &parg);
 		} else
 		{
-
+			char buf[24];
 			SNPRINTF1(buf, sizeof(buf), ".%06ld", jump_sline_fraction);
 			len = (int) strlen(buf);
 			while (len > 2 && buf[len-1] == '0')
@@ -229,7 +232,6 @@ opt_shift(type, s)
 	char *s;
 {
 	PARG parg;
-	char buf[24];
 	int len;
 	int err;
 
@@ -264,7 +266,7 @@ opt_shift(type, s)
 			error("Horizontal shift %d columns", &parg);
 		} else
 		{
-
+			char buf[24];
 			SNPRINTF1(buf, sizeof(buf), ".%06ld", shift_count_fraction);
 			len = (int) strlen(buf);
 			while (len > 2 && buf[len-1] == '0')
@@ -542,7 +544,7 @@ opt__V(type, s)
 		putstr(" regular expressions)\n");
 		{
 			char constant *copyright = 
-				"Copyright (C) 1984-2021  Mark Nudelman\n\n";
+				"Copyright (C) 1984-2022  Mark Nudelman\n\n";
 			putstr(copyright);
 		}
 		if (version[strlen(version)-1] == 'x')
@@ -612,15 +614,16 @@ color_from_namechar(namechar)
 {
 	switch (namechar)
 	{
-	case 'W': case 'A': return AT_COLOR_ATTN;
 	case 'B': return AT_COLOR_BIN;
 	case 'C': return AT_COLOR_CTRL;
 	case 'E': return AT_COLOR_ERROR;
+	case 'H': return AT_COLOR_HEADER;
 	case 'M': return AT_COLOR_MARK;
 	case 'N': return AT_COLOR_LINENUM;
 	case 'P': return AT_COLOR_PROMPT;
 	case 'R': return AT_COLOR_RSCROLL;
 	case 'S': return AT_COLOR_SEARCH;
+	case 'W': case 'A': return AT_COLOR_ATTN;
 	case 'n': return AT_NORMAL;
 	case 's': return AT_STANDOUT;
 	case 'd': return AT_BOLD;
@@ -721,7 +724,7 @@ opt_x(type, s)
 	extern int tabstops[];
 	extern int ntabstops;
 	extern int tabdefault;
-	char msg[60+(4*TABSTOP_MAX)];
+	char msg[60+((INT_STRLEN_BOUND(int)+1)*TABSTOP_MAX)];
 	int i;
 	PARG p;
 
@@ -976,9 +979,111 @@ opt_filesize(type, s)
 	case INIT:
 	case TOGGLE:
 		if (want_filesize && curr_ifile != NULL && ch_length() == NULL_POSITION)
-            scan_eof();
+			scan_eof();
+		break;
+	case QUERY:
+		break;
+	}
+}
+
+/*
+ * Handler for the --header option.
+ */
+	/*ARGSUSED*/
+	public void
+opt_header(type, s)
+	int type;
+	char *s;
+{
+	int err;
+	int n;
+
+	switch (type)
+	{
+	case INIT:
+	case TOGGLE:
+		n = getnum(&s, "header", &err);
+		if (err)
+			error("invalid number of lines", NULL_PARG);
+		else
+		{
+			header_lines = n;
+			header_cols = 0;
+			if (*s == ',')
+			{
+				++s;
+				n = getnum(&s, "header", &err);
+				if (err)
+					error("invalid number of columns", NULL_PARG);
+				else
+					header_cols = n;
+			}
+		}
+		break;
+	case QUERY:
+		{
+			char buf[2*INT_STRLEN_BOUND(int)+2];
+			PARG parg;
+			SNPRINTF2(buf, sizeof(buf), "%d,%d", header_lines, header_cols);
+			parg.p_string = buf;
+			error("header (lines,columns) is %s", &parg);
+		}
+		break;
+	}
+}
+
+/*
+ * Handler for the --search-options option.
+ */
+	/*ARGSUSED*/
+	public void
+opt_search_type(type, s)
+	int type;
+	char *s;
+{
+	int st;
+	PARG parg;
+	char buf[16];
+	char *bp;
+
+	switch (type)
+	{
+	case INIT:
+	case TOGGLE:
+		st = 0;
+		for (;  *s != '\0';  s++)
+		{
+			switch (*s)
+			{
+			case 'E': case 'e': case CONTROL('E'): st |= SRCH_PAST_EOF;   break;
+			case 'F': case 'f': case CONTROL('F'): st |= SRCH_FIRST_FILE; break;
+			case 'K': case 'k': case CONTROL('K'): st |= SRCH_NO_MOVE;    break;
+			case 'N': case 'n': case CONTROL('N'): st |= SRCH_NO_MATCH;   break;
+			case 'R': case 'r': case CONTROL('R'): st |= SRCH_NO_REGEX;   break;
+			case 'W': case 'w': case CONTROL('W'): st |= SRCH_WRAP;       break;
+			case '-': st = 0; break;
+			case '^': break;
+			default:
+				parg.p_char = *s;
+				error("invalid search option '%c'", &parg);
+				return;
+			}
+		}
+		def_search_type = norm_search_type(st);
 		break;
 	case QUERY:
+		bp = buf;
+		if (def_search_type & SRCH_PAST_EOF)   *bp++ = 'E'; 
+		if (def_search_type & SRCH_FIRST_FILE) *bp++ = 'F'; 
+		if (def_search_type & SRCH_NO_MOVE)    *bp++ = 'K'; 
+		if (def_search_type & SRCH_NO_MATCH)   *bp++ = 'N'; 
+		if (def_search_type & SRCH_NO_REGEX)   *bp++ = 'R'; 
+		if (def_search_type & SRCH_WRAP)       *bp++ = 'W'; 
+		if (bp == buf)
+			*bp++ = '-';
+		*bp = '\0';
+		parg.p_string = buf;
+		error("search options: %s", &parg);
 		break;
 	}
 }
@@ -1026,6 +1131,12 @@ opt_rstat(type, s)
 }
 #endif /*LESSTEST*/
 
+	public int
+chop_line(VOID_PARAM)
+{
+	return (chopline || header_cols > 0 || header_lines > 0);
+}
+
 /*
  * Get the "screen window" size.
  */
@@ -1034,6 +1145,6 @@ get_swindow(VOID_PARAM)
 {
 	if (swindow > 0)
 		return (swindow);
-	return (sc_height + swindow);
+	return (sc_height - header_lines + swindow);
 }
 
diff --git a/option.c b/option.c
index 61247d8..c4a496e 100644
--- a/option.c
+++ b/option.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -55,7 +55,7 @@ opt_desc(o)
 propt(c)
 	int c;
 {
-	static char buf[8];
+	static char buf[MAX_PRCHAR_LEN+2];
 
 	sprintf(buf, "-%s", prchar(c));
 	return (buf);
diff --git a/option.h b/option.h
index 4a10d6b..2ed2383 100644
--- a/option.h
+++ b/option.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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/opttbl.c b/opttbl.c
index 73f8435..1328e1e 100644
--- a/opttbl.c
+++ b/opttbl.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -63,7 +63,13 @@ public int linenum_width;       /* Width of line numbers */
 public int status_col_width;    /* Width of status column */
 public int incr_search;         /* Incremental search */
 public int use_color;           /* Use UI color */
-public int want_filesize;       /* */
+public int want_filesize;       /* Scan to EOF if necessary to get file size */
+public int status_line;         /* Highlight entire marked lines */
+public int header_lines;        /* Freeze header lines at top of screen */
+public int header_cols;         /* Freeze header columns at left of screen */
+public int nonum_headers;       /* Don't give headers line numbers */
+public int redraw_on_quit;      /* Redraw last screen after term deinit */
+public int def_search_type;     /* */
 #if HILITE_SEARCH
 public int hilite_search;       /* Highlight matched search patterns? */
 #endif
@@ -139,6 +145,11 @@ static struct optname status_col_width_optname = { "status-col-width", NULL };
 static struct optname incr_search_optname = { "incsearch",       NULL };
 static struct optname use_color_optname = { "use-color",         NULL };
 static struct optname want_filesize_optname = { "file-size",     NULL };
+static struct optname status_line_optname = { "status-line",     NULL };
+static struct optname header_optname = { "header",               NULL };
+static struct optname nonum_headers_optname = { "no-number-headers", NULL };
+static struct optname redraw_on_quit_optname = { "redraw-on-quit", NULL };
+static struct optname search_type_optname = { "search-options", NULL };
 #if LESSTEST
 static struct optname ttyin_name_optname = { "tty",              NULL };
 static struct optname rstat_optname  = { "rstat",                NULL };
@@ -562,6 +573,46 @@ static struct loption option[] =
 			NULL
 		}
 	},
+	{ OLETTER_NONE, &status_line_optname,
+		BOOL|REPAINT, OPT_OFF, &status_line, NULL,
+		{
+			"Don't color each line with its status column color",
+			"Color each line with its status column color",
+			NULL
+		}
+	},
+	{ OLETTER_NONE, &header_optname,
+		STRING|REPAINT, 0, NULL, opt_header,
+		{
+			"Header lines: ",
+			NULL,
+			NULL
+		}
+	},
+	{ OLETTER_NONE, &nonum_headers_optname,
+		BOOL|REPAINT, 0, &nonum_headers, NULL,
+		{
+			"Number header lines",
+			"Don't number header lines",
+			NULL
+		}
+	},
+	{ OLETTER_NONE, &redraw_on_quit_optname,
+		BOOL, OPT_OFF, &redraw_on_quit, NULL,
+		{
+			"Don't redraw screen when quitting",
+			"Redraw last screen when quitting",
+			NULL
+		}
+	},
+	{ OLETTER_NONE, &search_type_optname,
+		STRING, 0, NULL, opt_search_type,
+		{
+			"Search options: ",
+			NULL,
+			NULL
+		}
+	},
 #if LESSTEST
 	{ OLETTER_NONE, &ttyin_name_optname,
 		STRING|NO_TOGGLE, 0, NULL, opt_ttyin_name,
diff --git a/os.c b/os.c
index 1723787..aaeaf0b 100644
--- a/os.c
+++ b/os.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -61,6 +61,7 @@
 #endif
 
 public int reading;
+public int consecutive_nulls = 0;
 
 static jmp_buf read_label;
 
@@ -157,7 +158,10 @@ start:
 		FD_ZERO(&readfds);
 		FD_SET(fd, &readfds);
 		if (select(fd+1, &readfds, 0, 0, 0) == -1)
+		{
+			reading = 0;
 			return (-1);
+		}
 	}
 #endif
 #if USE_POLL
@@ -166,11 +170,13 @@ start:
 		if (poll_events(tty, POLLIN) && getchr() == CONTROL('X'))
 		{
 			sigs |= S_INTERRUPT;
+			reading = 0;
 			return (READ_INTR);
 		}
 		if (poll_events(fd, POLLERR|POLLHUP))
 		{
 			sigs |= S_INTERRUPT;
+			reading = 0;
 			return (READ_INTR);
 		}
 	}
@@ -179,11 +185,13 @@ start:
 	if (win32_kbhit() && WIN32getch() == CONTROL('X'))
 	{
 		sigs |= S_INTERRUPT;
+		reading = 0;
 		return (READ_INTR);
 	}
 #endif
 #endif
 	n = read(fd, buf, len);
+	reading = 0;
 #if 1
 	/*
 	 * This is a kludge to workaround a problem on some systems
@@ -193,7 +201,6 @@ start:
 	{
 		if (!ignore_eoi)
 		{
-			static int consecutive_nulls = 0;
 			if (n == 0)
 				consecutive_nulls++;
 			else
@@ -203,7 +210,6 @@ start:
 		}
 	}
 #endif
-	reading = 0;
 	if (n < 0)
 	{
 #if HAVE_ERRNO
@@ -259,7 +265,7 @@ get_time(VOID_PARAM)
 strerror(err)
 	int err;
 {
-	static char buf[16];
+	static char buf[INT_STRLEN_BOUND(int)+12];
 #if HAVE_SYS_ERRLIST
 	extern char *sys_errlist[];
 	extern int sys_nerr;
diff --git a/output.c b/output.c
index a865f4f..3fed3df 100644
--- a/output.c
+++ b/output.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -594,8 +594,13 @@ less_printf(fmt, parg)
 				parg++;
 				break;
 			case 'c':
-				putchr(parg->p_char);
-				col++;
+				s = prchar(parg->p_char);
+				parg++;
+				while (*s != '\0')
+				{
+					putchr(*s++);
+					col++;
+				}
 				break;
 			case '%':
 				putchr('%');
diff --git a/pattern.c b/pattern.c
index c2266fc..bed36df 100644
--- a/pattern.c
+++ b/pattern.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -14,6 +14,7 @@
 #include "less.h"
 
 extern int caseless;
+extern int is_caseless;
 extern int utf_mode;
 
 /*
@@ -49,7 +50,7 @@ compile_pattern2(pattern, search_type, comp_pattern, show_error)
 #endif
 #if HAVE_POSIX_REGCOMP
 	regex_t *comp = (regex_t *) ecalloc(1, sizeof(regex_t));
-	if (regcomp(comp, pattern, REGCOMP_FLAG))
+	if (regcomp(comp, pattern, REGCOMP_FLAG | (is_caseless ? REG_ICASE : 0)))
 	{
 		free(comp);
 		if (show_error)
@@ -68,7 +69,8 @@ compile_pattern2(pattern, search_type, comp_pattern, show_error)
 	int erroffset;
 	PARG parg;
 	pcre *comp = pcre_compile(pattern,
-			(utf_mode) ? PCRE_UTF8 | PCRE_NO_UTF8_CHECK : 0,
+			((utf_mode) ? PCRE_UTF8 | PCRE_NO_UTF8_CHECK : 0) |
+			(is_caseless ? PCRE_CASELESS : 0),
 			&errstring, &erroffset, NULL);
 	if (comp == NULL)
 	{
@@ -84,7 +86,8 @@ compile_pattern2(pattern, search_type, comp_pattern, show_error)
 	PCRE2_SIZE erroffset;
 	PARG parg;
 	pcre2_code *comp = pcre2_compile((PCRE2_SPTR)pattern, strlen(pattern),
-			0, &errcode, &erroffset, NULL);
+			(is_caseless ? PCRE2_CASELESS : 0),
+			&errcode, &erroffset, NULL);
 	if (comp == NULL)
 	{
 		if (show_error)
@@ -154,7 +157,7 @@ compile_pattern(pattern, search_type, show_error, comp_pattern)
 	char *cvt_pattern;
 	int result;
 
-	if (caseless != OPT_ONPLUS)
+	if (caseless != OPT_ONPLUS || re_handles_caseless)
 		cvt_pattern = pattern;
 	else
 	{
diff --git a/pattern.h b/pattern.h
index 6cd9d1a..a690b8e 100644
--- a/pattern.h
+++ b/pattern.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -10,57 +10,71 @@
 #if HAVE_GNU_REGEX
 #define __USE_GNU 1
 #include <regex.h>
-#define PATTERN_TYPE          struct re_pattern_buffer *
+#define PATTERN_TYPE             struct re_pattern_buffer *
 #define SET_NULL_PATTERN(name)   name = NULL
 #endif
 
+/* ---- POSIX ---- */
 #if HAVE_POSIX_REGCOMP
 #include <regex.h>
 #ifdef REG_EXTENDED
-#define REGCOMP_FLAG    REG_EXTENDED
+#define REGCOMP_FLAG             REG_EXTENDED
 #else
-#define REGCOMP_FLAG    0
+#define REGCOMP_FLAG             0
 #endif
-#define PATTERN_TYPE          regex_t *
+#define PATTERN_TYPE             regex_t *
 #define SET_NULL_PATTERN(name)   name = NULL
+#define re_handles_caseless      TRUE
 #endif
 
+/* ---- PCRE ---- */
 #if HAVE_PCRE
 #include <pcre.h>
-#define PATTERN_TYPE          pcre *
+#define PATTERN_TYPE             pcre *
 #define SET_NULL_PATTERN(name)   name = NULL
+#define re_handles_caseless      TRUE
 #endif
 
+/* ---- PCRE2 ---- */
 #if HAVE_PCRE2
 #define PCRE2_CODE_UNIT_WIDTH 8
 #include <pcre2.h>
-#define PATTERN_TYPE          pcre2_code *
+#define PATTERN_TYPE             pcre2_code *
 #define SET_NULL_PATTERN(name)   name = NULL
+#define re_handles_caseless      TRUE
 #endif
 
+/* ---- RE_COMP  ---- */
 #if HAVE_RE_COMP
 char *re_comp LESSPARAMS ((char*));
 int re_exec LESSPARAMS ((char*));
-#define PATTERN_TYPE          int
+#define PATTERN_TYPE             int
 #define SET_NULL_PATTERN(name)   name = 0
 #endif
 
+/* ---- REGCMP  ---- */
 #if HAVE_REGCMP
 char *regcmp LESSPARAMS ((char*));
 char *regex LESSPARAMS ((char**, char*));
 extern char *__loc1;
-#define PATTERN_TYPE          char **
+#define PATTERN_TYPE             char **
 #define SET_NULL_PATTERN(name)   name = NULL
 #endif
 
+/* ---- REGCOMP  ---- */
 #if HAVE_V8_REGCOMP
 #include "regexp.h"
 extern int reg_show_error;
-#define PATTERN_TYPE          struct regexp *
+#define PATTERN_TYPE             struct regexp *
 #define SET_NULL_PATTERN(name)   name = NULL
 #endif
 
+/* ---- NONE  ---- */
 #if NO_REGEX
-#define PATTERN_TYPE          void *
+#define PATTERN_TYPE             void *
 #define SET_NULL_PATTERN(name)   
 #endif
+
+#ifndef re_handles_caseless
+#define re_handles_caseless      FALSE
+#endif
diff --git a/pckeys.h b/pckeys.h
index 8b21d72..a4f9c25 100644
--- a/pckeys.h
+++ b/pckeys.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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/position.c b/position.c
index 8f6edc9..eabaf7e 100644
--- a/position.c
+++ b/position.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -25,6 +25,7 @@ static POSITION *table = NULL;  /* The position table */
 static int table_size = 0;
 
 extern int sc_width, sc_height;
+extern int header_lines;
 
 /*
  * Return the starting file position of a line displayed on the screen.
diff --git a/position.h b/position.h
index 4e0efc7..85a110f 100644
--- a/position.h
+++ b/position.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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/prompt.c b/prompt.c
index 0e38c0f..5319c40 100644
--- a/prompt.c
+++ b/prompt.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -29,6 +29,7 @@ extern int hshift;
 extern int sc_height;
 extern int jump_sline;
 extern int less_is_more;
+extern int header_lines;
 extern IFILE curr_ifile;
 #if EDITOR
 extern char *editor;
@@ -260,7 +261,7 @@ protochar(c, where, iseditproto)
 	char *s;
 
 #undef  PAGE_NUM
-#define PAGE_NUM(linenum)  ((((linenum) - 1) / (sc_height - 1)) + 1)
+#define PAGE_NUM(linenum)  ((((linenum) - 1) / (sc_height - header_lines - 1)) + 1)
 
 	switch (c)
 	{
@@ -276,7 +277,7 @@ protochar(c, where, iseditproto)
 		break;
 	case 'd': /* Current page number */
 		linenum = currline(where);
-		if (linenum > 0 && sc_height > 1)
+		if (linenum > 0 && sc_height > header_lines + 1)
 			ap_linenum(PAGE_NUM(linenum));
 		else
 			ap_quest();
@@ -325,7 +326,7 @@ protochar(c, where, iseditproto)
 	case 'l': /* Current line number */
 		linenum = currline(where);
 		if (linenum != 0)
-			ap_linenum(linenum);
+			ap_linenum(vlinenum(linenum));
 		else
 			ap_quest();
 		break;
@@ -335,7 +336,7 @@ protochar(c, where, iseditproto)
 		    (linenum = find_linenum(len)) <= 0)
 			ap_quest();
 		else
-			ap_linenum(linenum-1);
+			ap_linenum(vlinenum(linenum-1));
 		break;
 	case 'm': /* Number of files */
 #if TAGS
@@ -484,9 +485,8 @@ wherechar(p, wp)
  * Construct a message based on a prototype string.
  */
 	public char *
-pr_expand(proto, maxwidth)
+pr_expand(proto)
 	constant char *proto;
-	int maxwidth;
 {
 	constant char *p;
 	int c;
@@ -545,14 +545,6 @@ pr_expand(proto, maxwidth)
 
 	if (mp == message)
 		return ("");
-	if (maxwidth > 0 && mp >= message + maxwidth)
-	{
-		/*
-		 * Message is too long.
-		 * Return just the final portion of it.
-		 */
-		return (mp - maxwidth);
-	}
 	return (message);
 }
 
@@ -562,7 +554,7 @@ pr_expand(proto, maxwidth)
 	public char *
 eq_message(VOID_PARAM)
 {
-	return (pr_expand(eqproto, 0));
+	return (pr_expand(eqproto));
 }
 
 /*
@@ -579,8 +571,7 @@ pr_string(VOID_PARAM)
 
 	type = (!less_is_more) ? pr_type : pr_type ? 0 : 1;
 	prompt = pr_expand((ch_getflags() & CH_HELPFILE) ?
-				hproto : prproto[type],
-			sc_width-so_s_width-so_e_width-2);
+				hproto : prproto[type]);
 	new_file = 0;
 	return (prompt);
 }
@@ -591,5 +582,5 @@ pr_string(VOID_PARAM)
 	public char *
 wait_message(VOID_PARAM)
 {
-	return (pr_expand(wproto, sc_width-so_s_width-so_e_width-2));
+	return (pr_expand(wproto));
 }
diff --git a/screen.c b/screen.c
index 033a5b9..aa31804 100644
--- a/screen.c
+++ b/screen.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -234,6 +234,7 @@ public int can_goto_line;               /* Can move cursor to any line */
 public int clear_bg;            /* Clear fills with background color */
 public int missing_cap = 0;     /* Some capability is missing */
 public char *kent = NULL;       /* Keypad ENTER sequence */
+public int term_init_done = FALSE;
 
 static int attrmode = AT_NORMAL;
 static int termcap_debug = -1;
@@ -930,6 +931,7 @@ special_key_str(key)
 	static char k_delete[]          = { '\340', PCK_DELETE, 0  };
 	static char k_ctl_delete[]      = { '\340', PCK_CTL_DELETE, 0  };
 	static char k_ctl_backspace[]   = { '\177', 0 };
+	static char k_backspace[]       = { '\b', 0 };
 	static char k_home[]            = { '\340', PCK_HOME, 0 };
 	static char k_end[]             = { '\340', PCK_END, 0 };
 	static char k_up[]              = { '\340', PCK_UP, 0 };
@@ -1029,6 +1031,9 @@ special_key_str(key)
 	case SK_CTL_DELETE:
 		s = k_ctl_delete;
 		break;
+	case SK_BACKSPACE:
+		s = k_backspace;
+		break;
 	case SK_F1:
 		s = k_f1;
 		break;
@@ -1069,6 +1074,15 @@ special_key_str(key)
 				s = tbuf;
 		}
 		break;
+	case SK_BACKSPACE:
+		s = ltgetstr("kb", &sp);
+		if (s == NULL)
+		{
+				tbuf[0] = '\b';
+				tbuf[1] = '\0';
+				s = tbuf;
+		}
+		break;
 #endif
 	case SK_CONTROL_K:
 		tbuf[0] = CONTROL('K');
@@ -1712,7 +1726,10 @@ init(VOID_PARAM)
 	if (!(quit_if_one_screen && one_screen))
 	{
 		if (!no_init)
+		{
 			ltputs(sc_init, sc_height, putchr);
+			term_init_done = 1;
+		}
 		if (!no_keypad)
 			ltputs(sc_s_keypad, sc_height, putchr);
 		if (mousecap)
@@ -1738,7 +1755,10 @@ init(VOID_PARAM)
 	if (!(quit_if_one_screen && one_screen))
 	{
 		if (!no_init)
+		{
 			win32_init_term();
+			term_init_done = 1;
+		}
 		if (mousecap)
 			init_mouse();
 
@@ -2527,7 +2547,7 @@ tput_fmt(fmt, color, f_putc)
 	int color;
 	int (*f_putc)(int);
 {
-	char buf[32];
+	char buf[INT_STRLEN_BOUND(int)+16];
 	if (color == attrcolor)
 		return;
 	SNPRINTF1(buf, sizeof(buf), fmt, color);
@@ -2608,7 +2628,7 @@ WIN32put_fmt(fmt, color)
 	char *fmt;
 	int color;
 {
-	char buf[16];
+	char buf[INT_STRLEN_BOUND(int)+16];
 	int len = SNPRINTF1(buf, sizeof(buf), fmt, color);
 	WIN32textout(buf, len);
 	return TRUE;
diff --git a/scrsize.c b/scrsize.c
index ee07cb8..7ceed58 100644
--- a/scrsize.c
+++ b/scrsize.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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/search.c b/search.c
index f619fbe..224bc49 100644
--- a/search.c
+++ b/search.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -35,7 +35,6 @@ extern int utf_mode;
 extern int screen_trashed;
 extern int sc_width;
 extern int sc_height;
-extern int chopline;
 extern int hshift;
 #if HILITE_SEARCH
 extern int hilite_search;
@@ -120,7 +119,7 @@ struct pattern_info {
 	
 static struct pattern_info search_info;
 static int is_ucase_pattern;
-static int is_caseless;
+public int is_caseless;
 
 /*
  * Are there any uppercase letters in this string?
@@ -166,6 +165,12 @@ set_pattern(info, pattern, search_type, show_error)
 	int search_type;
 	int show_error;
 {
+	/*
+	 * Ignore case if -I is set OR
+	 * -i is set AND the pattern is all lowercase.
+	 */
+	is_ucase_pattern = (pattern == NULL) ? FALSE : is_ucase(pattern);
+	is_caseless = (is_ucase_pattern && caseless != OPT_ONPLUS) ? 0 : caseless;
 #if !NO_REGEX
 	if (pattern == NULL)
 		SET_NULL_PATTERN(info->compiled);
@@ -182,16 +187,6 @@ set_pattern(info, pattern, search_type, show_error)
 		strcpy(info->text, pattern);
 	}
 	info->search_type = search_type;
-
-	/*
-	 * Ignore case if -I is set OR
-	 * -i is set AND the pattern is all lowercase.
-	 */
-	is_ucase_pattern = is_ucase(pattern);
-	if (is_ucase_pattern && caseless != OPT_ONPLUS)
-		is_caseless = 0;
-	else
-		is_caseless = caseless;
 	return 0;
 }
 
@@ -225,7 +220,7 @@ get_cvt_ops(VOID_PARAM)
 {
 	int ops = 0;
 
-	if (is_caseless) 
+	if (is_caseless && !re_handles_caseless)
 		ops |= CVT_TO_LC;
 	if (bs_mode == BS_SPECIAL)
 		ops |= CVT_BS;
@@ -291,6 +286,7 @@ repaint_hilite(on)
 		goto_line(sindex);
 		put_line();
 	}
+	overlay_header();
 	lower_left();
 	hide_hilite = save_hide_hilite;
 }
@@ -339,6 +335,8 @@ clear_attn(VOID_PARAM)
 			moved = 1;
 		}
 	}
+	if (overlay_header())
+		moved = 1;
 	if (moved)
 		lower_left();
 #endif
@@ -946,7 +944,7 @@ add_hilite(anchor, hl)
 }
 
 /*
- * Hilight every character in a range of displayed characters.
+ * Highlight every character in a range of displayed characters.
  */
 	static void
 create_hilites(linepos, start_index, end_index, chpos)
@@ -1236,7 +1234,7 @@ get_seg(pos, tpos)
 
 	for (seg = 0;;  seg++)
 	{
-		POSITION npos = forw_line_seg(pos, TRUE);
+		POSITION npos = forw_line_seg(pos, FALSE, FALSE, TRUE);
 		if (npos > tpos)
 			return seg;
 		pos = npos;
@@ -1446,7 +1444,7 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos, pla
 						hilite_line(linepos, cline, line_len, chpos, sp, ep, cvt_ops);
 					}
 #endif
-					if (chopline)
+					if (chop_line())
 					{
 						/*
 						 * If necessary, shift horizontally to make sure 
@@ -1460,10 +1458,8 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos, pla
 							int sshift;
 							int eshift;
 							hshift = 0; /* make get_seg count screen lines */
-							chopline = FALSE;
 							sshift = swidth * get_seg(linepos, linepos + chpos[start_off]);
 							eshift = swidth * get_seg(linepos, linepos + chpos[end_off]);
-							chopline = TRUE;
 							if (sshift >= save_hshift && eshift <= save_hshift)
 							{
 								hshift = save_hshift;
@@ -1540,20 +1536,25 @@ hist_pattern(search_type)
 chg_caseless(VOID_PARAM)
 {
 	if (!is_ucase_pattern)
+	{
 		/*
 		 * Pattern did not have uppercase.
-		 * Just set the search caselessness to the global caselessness.
+		 * Set the search caselessness to the global caselessness.
 		 */
 		is_caseless = caseless;
-	else
-	{
 		/*
-		 * Pattern did have uppercase.
-		 * Regenerate the pattern using the new state.
+		 * If regex handles caseless, we need to discard 
+		 * the pattern which was compiled with the old caseless.
 		 */
-		clear_pattern(&search_info);
-		(void) hist_pattern(search_info.search_type);
+		if (!re_handles_caseless)
+			/* We handle caseless, so the pattern doesn't change. */
+			return;
 	}
+	/*
+	 * Regenerate the pattern using the new state.
+	 */
+	clear_pattern(&search_info);
+	(void) hist_pattern(search_info.search_type);
 }
 
 /*
@@ -1908,7 +1909,11 @@ set_filter_pattern(pattern, search_type)
 		/* Create a new filter and add it to the filter_infos list. */
 		filter = ecalloc(1, sizeof(struct pattern_info));
 		init_pattern(filter);
-		set_pattern(filter, pattern, search_type, 1);
+		if (set_pattern(filter, pattern, search_type, 1) < 0)
+		{
+			free(filter);
+			return;
+		}
 		filter->next = filter_infos;
 		filter_infos = filter;
 	}
diff --git a/signal.c b/signal.c
index dd66683..294fa6a 100644
--- a/signal.c
+++ b/signal.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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/tags.c b/tags.c
index 23a9b92..03e2973 100644
--- a/tags.c
+++ b/tags.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -396,7 +396,9 @@ edit_tagfile(VOID_PARAM)
 }
 
 	static int
-curtag_match(char const *line, POSITION linepos)
+curtag_match(line, linepos)
+	char constant *line;
+	POSITION linepos;
 {
 	/*
 	 * Test the line to see if we have a match.
@@ -508,7 +510,7 @@ findgtag(tag, type)
 	char *tag;              /* tag to load */
 	int type;               /* tags type */
 {
-	char buf[256];
+	char buf[1024];
 	FILE *fp;
 	struct tag *tp;
 
diff --git a/ttyin.c b/ttyin.c
index 5bd3385..4be4527 100644
--- a/ttyin.c
+++ b/ttyin.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -36,24 +36,46 @@ extern int sigs;
 extern int utf_mode;
 extern int wheel_lines;
 
-/*
- * Get name of tty device.
- */
 #if !MSDOS_COMPILER
-	public char *
-tty_device(VOID_PARAM)
+	static int
+open_tty_device(dev)
+	constant char* dev;
 {
-	char *dev = NULL;
-#if HAVE_TTYNAME
-	dev = ttyname(2);
+#if OS2
+	/* The __open() system call translates "/dev/tty" to "con". */
+	return __open(dev, OPEN_READ);
+#else
+	return open(dev, OPEN_READ);
 #endif
-	if (dev == NULL)
-		dev = "/dev/tty";
+}
+
+/*
+ * Open the tty device.
+ * Try ttyname(), then try /dev/tty, then use file descriptor 2.
+ * In Unix, file descriptor 2 is usually attached to the screen,
+ * but also usually lets you read from the keyboard.
+ */
+	public int
+open_tty(VOID_PARAM)
+{
+	int fd = -1;
 #if LESSTEST
 	if (ttyin_name != NULL)
-		dev = ttyin_name;
+		fd = open_tty_device(ttyin_name);
 #endif /*LESSTEST*/
-	return dev;
+#if HAVE_TTYNAME
+	if (fd < 0)
+	{
+		constant char *dev = ttyname(2);
+		if (dev != NULL)
+			fd = open_tty_device(dev);
+	}
+#endif
+	if (fd < 0)
+		fd = open_tty_device("/dev/tty");
+	if (fd < 0)
+		fd = 2;
+	return fd;
 }
 #endif /* MSDOS_COMPILER */
 
@@ -93,20 +115,7 @@ open_getchr(VOID_PARAM)
 	(void) __djgpp_set_ctrl_c(1);
 #endif
 #else
-	/*
-	 * Try /dev/tty.
-	 * If that doesn't work, use file descriptor 2,
-	 * which in Unix is usually attached to the screen,
-	 * but also usually lets you read from the keyboard.
-	 */
-#if OS2
-	/* The __open() system call translates "/dev/tty" to "con". */
-	tty = __open(tty_device(), OPEN_READ);
-#else
-	tty = open(tty_device(), OPEN_READ);
-#endif
-	if (tty < 0)
-		tty = 2;
+	tty = open_tty();
 #endif
 #endif
 }
diff --git a/version.c b/version.c
index cab2690..f28ff8d 100644
--- a/version.c
+++ b/version.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2021  Mark Nudelman
+ * Copyright (C) 1984-2022  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.
@@ -931,6 +931,20 @@ v587  5/27/21   Fix --with-secure; fix --file-size message on Windows;
 v588  5/27/21   Fix release.
 v589  5/29/21   Copyright & build changes.
 v590  6/3/21    Fix non-autoconf Makefiles.
+v591  8/8/21    Use \kB for backspace key in lesskey; add more \k codes;
+                handle multibyte chars in prompt.
+v592  8/24/21   Add --status-line option; limit use of /proc kludge; add --header.
+v593  8/30/21   Add header columns, --no-number-headers.
+v594  10/1/21   Let regex library handle caseless; add --redraw-on-quit option;
+                add #version to lesskey.
+v595  10/12/21  Add H color type; add += to lesskey var section; 
+                add --search-options.
+v596  11/8/21   Look for lesskey in $HOME/.config.
+v597  11/16/21  Fix bugs in --header.
+v598  12/6/21   Look for lesshst in $XDG_STATE_HOME and $HOME/.local/state.
+v599  12/28/21  Defer moving to lower left in some cases; 
+                suppress TAB expansion in some cases.
+v600  1/7/22    Use /dev/tty if cannot open ttyname().
 */
 
-char version[] = "590";
+char version[] = "600";
diff --git a/xbuf.c b/xbuf.c
index f20dfae..4e767e3 100644
--- a/xbuf.c
+++ b/xbuf.c
@@ -34,7 +34,7 @@ xbuf_reset(xbuf)
 	public void
 xbuf_add(xbuf, ch)
 	struct xbuffer *xbuf;
-	char ch;
+	int ch;
 {
 	if (xbuf->end >= xbuf->size)
 	{
@@ -50,3 +50,24 @@ xbuf_add(xbuf, ch)
 	}
 	xbuf->data[xbuf->end++] = ch;
 }
+
+	public int
+xbuf_pop(buf)
+	struct xbuffer *buf;
+{
+	if (buf->end == 0)
+		return -1;
+	return buf->data[--(buf->end)];
+}
+
+	public void
+xbuf_set(dst, src)
+	struct xbuffer *dst;
+	struct xbuffer *src;
+{
+	int i;
+
+	xbuf_reset(dst);
+	for (i = 0;  i < src->end;  i++)
+		xbuf_add(dst, src->data[i]);
+}
diff --git a/xbuf.h b/xbuf.h
index ba62ef1..d317e17 100644
--- a/xbuf.h
+++ b/xbuf.h
@@ -10,6 +10,7 @@ struct xbuffer
 
 void xbuf_init(struct xbuffer *xbuf);
 void xbuf_reset(struct xbuffer *xbuf);
-void xbuf_add(struct xbuffer *xbuf, char ch);
+void xbuf_add(struct xbuffer *xbuf, int ch);
+int xbuf_pop(struct xbuffer *xbuf);
 
 #endif