aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXin LI <delphij@FreeBSD.org>2022-09-05 23:57:47 +0000
committerXin LI <delphij@FreeBSD.org>2022-09-05 23:57:47 +0000
commit2b6624fffa5fac26d860898ddb335f852cfeb6b5 (patch)
tree92ea041c05c83c1d599faa43240614ba6329c977
parent1f8b3bb911e37330e00dab1b1e6cba65c573e63c (diff)
downloadsrc-2b6624fffa5fac26d860898ddb335f852cfeb6b5.tar.gz
src-2b6624fffa5fac26d860898ddb335f852cfeb6b5.zip
Vendor import of less v608.vendor/less/v608
-rw-r--r--COPYING8
-rw-r--r--LICENSE2
-rw-r--r--Makefile.aut38
-rw-r--r--NEWS67
-rw-r--r--README6
-rw-r--r--brac.c6
-rw-r--r--ch.c19
-rw-r--r--charset.c18
-rw-r--r--charset.h2
-rw-r--r--cmd.h3
-rw-r--r--cmdbuf.c91
-rw-r--r--command.c76
-rw-r--r--compose.uni20
-rwxr-xr-xconfigure619
-rw-r--r--configure.ac62
-rw-r--r--cvt.c2
-rw-r--r--decode.c30
-rw-r--r--defines.ds2
-rw-r--r--defines.h.in4
-rw-r--r--defines.o22
-rw-r--r--defines.o92
-rw-r--r--defines.wn2
-rw-r--r--edit.c4
-rw-r--r--filename.c19
-rw-r--r--fmt.uni3
-rw-r--r--forwback.c122
-rw-r--r--funcs.h18
-rw-r--r--help.c20
-rw-r--r--ifile.c2
-rw-r--r--input.c22
-rw-r--r--jump.c2
-rw-r--r--less.h4
-rw-r--r--less.hlp18
-rw-r--r--less.man604
-rw-r--r--less.nro99
-rw-r--r--lessecho.c45
-rw-r--r--lessecho.man2
-rw-r--r--lessecho.nro2
-rw-r--r--lesskey.c11
-rw-r--r--lesskey.h2
-rw-r--r--lesskey.man208
-rw-r--r--lesskey.nro155
-rw-r--r--lesskey_parse.c238
-rw-r--r--lglob.h2
-rw-r--r--line.c285
-rw-r--r--linenum.c23
-rw-r--r--lsystem.c9
-rw-r--r--main.c25
-rw-r--r--mark.c5
-rw-r--r--optfunc.c131
-rw-r--r--option.c4
-rw-r--r--option.h2
-rw-r--r--opttbl.c65
-rw-r--r--os.c18
-rw-r--r--output.c11
-rw-r--r--pattern.c13
-rw-r--r--pattern.h36
-rw-r--r--pckeys.h2
-rw-r--r--position.c3
-rw-r--r--position.h2
-rw-r--r--prompt.c29
-rw-r--r--screen.c62
-rw-r--r--scrsize.c2
-rw-r--r--search.c59
-rw-r--r--signal.c2
-rw-r--r--tags.c8
-rw-r--r--ttyin.c63
-rw-r--r--ubin.uni2
-rw-r--r--version.c27
-rw-r--r--wide.uni25
-rw-r--r--xbuf.c23
-rw-r--r--xbuf.h3
72 files changed, 2425 insertions, 1197 deletions
diff --git a/COPYING b/COPYING
index 94a9ed024d38..f288702d2fa1 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 315d1d86815c..65bce4288972 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 f0eb26d41e23..948532e2f193 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}
@@ -115,32 +114,35 @@ wide.uni: unicode/EastAsianWidth.txt
unicode/UnicodeData.txt:
mkdir -p unicode
- curl -s -u 'anonymous:${EMAIL}' -o $@ ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
+ lftp -c 'open -u "anonymous:${EMAIL}" ftp.unicode.org ; get Public/UNIDATA/UnicodeData.txt -o $@'
+ touch $@
unicode/EastAsianWidth.txt:
mkdir -p unicode
- curl -s -u 'anonymous:${EMAIL}' -o $@ ftp://ftp.unicode.org/Public/UNIDATA/EastAsianWidth.txt
+ lftp -c 'open -u "anonymous:${EMAIL}" ftp.unicode.org ; get Public/UNIDATA/EastAsianWidth.txt -o $@'
+ touch $@
distfiles: ${DISTFILES}
echo_distfiles:
- echo ${DISTFILES}
+ @echo $(subst .nro,.nro.VER,${DISTFILES})
dist: ${DISTFILES}
if [ ! -d ${srcdir}/release ]; then mkdir ${srcdir}/release; fi
@LESSREL=less-${REL} && RELDIR=release/$$LESSREL && \
+ TARF=$$LESSREL-beta.tar.gz && ZIPF=$$LESSREL-beta.zip && \
cd ${srcdir} && \
rm -rf $$RELDIR && mkdir $$RELDIR && \
echo "Preparing $$LESSREL" && \
rm -rf $$LESSREL && mkdir $$LESSREL && \
cp ${DISTFILES} $$LESSREL && \
cd $$LESSREL && chmod -w * && chmod +w ${DISTFILES_W} && chmod +x configure && cd .. && \
- echo "Creating $$RELDIR/${REL}.tar.gz" && \
- tar -cf - $$LESSREL | gzip -c >$$RELDIR/$$LESSREL.tar.gz && \
- echo "Signing $$RELDIR/$$LESSREL.tar.gz" && \
- gpg --detach-sign $$RELDIR/$$LESSREL.tar.gz && \
- mv $$RELDIR/$$LESSREL.tar.gz.sig $$RELDIR/$$LESSREL.sig && \
- echo "Creating $$RELDIR/$$LESSREL.zip" && \
- zip -rq $$RELDIR/$$LESSREL.zip $$LESSREL && \
+ echo "Creating $$RELDIR/$$TARF" && \
+ tar -cf - $$LESSREL | gzip -c >$$RELDIR/$$TARF && \
+ echo "Signing $$RELDIR/$$TARF" && \
+ gpg --detach-sign $$RELDIR/$$TARF && \
+ mv $$RELDIR/$$TARF.sig $$RELDIR/$$LESSREL.sig && \
+ echo "Creating $$RELDIR/$$ZIPF" && \
+ zip -rq $$RELDIR/$$ZIPF $$LESSREL && \
rm -rf $$LESSREL
tagall:
@@ -149,9 +151,11 @@ tagall:
gnu_upload:
@if [ -z "${REL}" ]; then echo "Please set REL=nnn"; exit 1; fi; \
- if [ ! -s release/less-${REL}/less-${REL}.tar.gz ]; then echo "release/less-${REL}/less-${REL}.tar.gz does not exist"; exit 1; fi; \
- cd release/less-${REL} && \
- gpg -b less-${REL}.tar.gz && \
- ( echo "version: 1.2"; echo "directory: less"; echo "filename: less-${REL}.tar.gz" ) > less-${REL}.tar.gz.directive && \
- gpg --clearsign less-${REL}.tar.gz.directive
- @echo "upload ready: cd release/less-${REL}; ftp ftp-upload.gnu.org; cd /incoming/ftp; put less-${REL}.tar.gz less-${REL}.tar.gz.sig less-${REL}.tar.gz.directive.asc"
+ LESSREL=less-${REL} && RELDIR=release/$$LESSREL && \
+ TARF=$$LESSREL-release.tar.gz && \
+ if [ ! -s $$RELDIR/$$TARF ]; then echo "$$RELDIR/$$TARF does not exist"; exit 1; fi; \
+ cd $$RELDIR && \
+ gpg -b $$TARF && \
+ ( echo "version: 1.2"; echo "directory: less"; echo "filename: $$TARF" ) > $$TARF.directive && \
+ gpg --clearsign $$TARF.directive
+ @echo "upload ready: cd $$RELDIR; ftp ftp-upload.gnu.org; cd /incoming/ftp; put $$TARF $$TARF.sig $$TARF.directive.asc"
diff --git a/NEWS b/NEWS
index a403c5d8a875..bcfe4c6c9e38 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,73 @@
======================================================================
+ Major changes between "less" versions 590 and 608
+
+* Add the --header option (github #43).
+
+* Add the --no-number-headers option (github #178).
+
+* Add the --status-line option.
+
+* Add the --redraw-on-quit option (github #36).
+
+* Add the --search-options option (github #213).
+
+* Add the --exit-follow-on-close option (github #244).
+
+* 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 (github #153).
+
+* Add $XDG_STATE_HOME and $HOME/.local/state to possible locations
+ of history file (github #223).
+
+* Don't read or write history file in secure mode (github #201).
+
+* Fix display of multibyte and double-width chars in prompt.
+
+* Fix ESC-BACKSPACE command when BACKSPACE key does not send 0x08
+ (github #188).
+
+* 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 (githb #234).
+
+* Fix bug scrolling history when --incsearch is set (github #214).
+
+* Fix buffer overflow when invoking lessecho with more than 63 -m/-n
+ options (github #198).
+
+* Fix buffer overflow in bin_file (github #271).
+
+* 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.
+
+* Fix termlib detection when compiler doesn't accept
+ calls to undeclared functions.
+
+* Fix bug in input of non-ASCII characters on Windows (github #247)
+
+* Escape filenames when invoking LESSCLOSE.
+
+* Fix bug using multibyte UTF-8 char in search string
+ with --incsearch (github #273).
+
+======================================================================
+
Major changes between "less" versions 581 and 590
* Make less able to read lesskey source files (deprecating lesskey).
diff --git a/README b/README
index 955bf82822ea..a4443b69f273 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 53ada50aab56..58ecf172ae4e 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 379dd84c41b8..bfad09c719f6 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 b37c8a29cbd9..5e9a2d6427b8 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 3e7ecf73db94..aa6273dfda6c 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 c51f0bc5c4f3..b0f3fdb14b1e 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 dd135382aa11..5b5704602d8d 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++ == '.')
{
@@ -1368,6 +1378,9 @@ cmd_int(frac)
public char *
get_cmdbuf(VOID_PARAM)
{
+ if (cmd_mbc_buf_index < cmd_mbc_buf_len)
+ /* Don't return buffer containing an incomplete multibyte char. */
+ return (NULL);
return (cmdbuf);
}
@@ -1401,13 +1414,40 @@ 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 +1462,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 +1553,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 +1645,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 +1710,7 @@ make_file_private(f)
/*
* Does the history file need to be updated?
*/
+#if CMD_HISTORY
static int
histfile_modified(VOID_PARAM)
{
@@ -1682,12 +1720,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 +1742,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 88a2f8b34a7d..524b93892991 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);
}
@@ -233,6 +242,8 @@ exec_mca(VOID_PARAM)
cmd_exec();
cbuf = get_cmdbuf();
+ if (cbuf == NULL)
+ return;
switch (mca)
{
@@ -340,6 +351,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 +369,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'):
@@ -413,6 +425,8 @@ mca_opt_nonfirst_char(c)
if (cmd_char(c) == CC_QUIT)
return (MCA_DONE);
p = get_cmdbuf();
+ if (p == NULL)
+ return (MCA_MORE);
opt_lower = ASCII_IS_LOWER(p[0]);
err = 0;
curropt = findopt_name(&p, &oname, &err);
@@ -463,11 +477,13 @@ 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)
{
parg.p_string = get_cmdbuf();
+ if (parg.p_string == NULL)
+ return (MCA_MORE);
error("There is no --%s option", &parg);
return (MCA_DONE);
}
@@ -508,6 +524,19 @@ mca_opt_char(c)
}
/*
+ * 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.
*/
static int
@@ -557,8 +586,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 +708,14 @@ 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();
+ if (pattern == NULL)
+ return (MCA_MORE);
+ /*
+ * Must save updown_match because mca_search
+ * reinits it. That breaks history scrolling.
+ * {{ This is ugly. mca_search probably shouldn't call set_mlist. }}
+ */
+ int save_updown_match = updown_match;
cmd_exec();
if (*pattern == '\0')
{
@@ -692,7 +728,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 +837,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 +880,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 +958,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);
{
@@ -1280,6 +1316,8 @@ commands(VOID_PARAM)
if (cmd_char(c) == CC_QUIT || len_cmdbuf() == 0)
continue;
cbuf = get_cmdbuf();
+ if (cbuf == NULL)
+ continue;
} else
{
/*
@@ -1603,7 +1641,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 +1653,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 +1773,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/compose.uni b/compose.uni
index bbf4b20387fc..cc7ddcf02bb9 100644
--- a/compose.uni
+++ b/compose.uni
@@ -1,4 +1,4 @@
-/* Generated by "./mkutable -f2 Mn Me -- unicode/UnicodeData.txt" on Tue May 19 14:47:34 PDT 2020 */
+/* Generated by "./mkutable -f2 Mn Me -- unicode/UnicodeData.txt" on Tue Jul 19 12:45:16 PDT 2022 */
{ 0x0300, 0x036f }, /* Mn */
{ 0x0483, 0x0487 }, /* Mn */
{ 0x0488, 0x0489 }, /* Me */
@@ -24,7 +24,8 @@
{ 0x0825, 0x0827 }, /* Mn */
{ 0x0829, 0x082d }, /* Mn */
{ 0x0859, 0x085b }, /* Mn */
- { 0x08d3, 0x08e1 }, /* Mn */
+ { 0x0898, 0x089f }, /* Mn */
+ { 0x08ca, 0x08e1 }, /* Mn */
{ 0x08e3, 0x0902 }, /* Mn */
{ 0x093a, 0x093a }, /* Mn */
{ 0x093c, 0x093c }, /* Mn */
@@ -65,6 +66,7 @@
{ 0x0bcd, 0x0bcd }, /* Mn */
{ 0x0c00, 0x0c00 }, /* Mn */
{ 0x0c04, 0x0c04 }, /* Mn */
+ { 0x0c3c, 0x0c3c }, /* Mn */
{ 0x0c3e, 0x0c40 }, /* Mn */
{ 0x0c46, 0x0c48 }, /* Mn */
{ 0x0c4a, 0x0c4d }, /* Mn */
@@ -115,7 +117,7 @@
{ 0x1160, 0x11ff }, /* Mn */
{ 0x135d, 0x135f }, /* Mn */
{ 0x1712, 0x1714 }, /* Mn */
- { 0x1732, 0x1734 }, /* Mn */
+ { 0x1732, 0x1733 }, /* Mn */
{ 0x1752, 0x1753 }, /* Mn */
{ 0x1772, 0x1773 }, /* Mn */
{ 0x17b4, 0x17b5 }, /* Mn */
@@ -124,6 +126,7 @@
{ 0x17c9, 0x17d3 }, /* Mn */
{ 0x17dd, 0x17dd }, /* Mn */
{ 0x180b, 0x180d }, /* Mn */
+ { 0x180f, 0x180f }, /* Mn */
{ 0x1885, 0x1886 }, /* Mn */
{ 0x18a9, 0x18a9 }, /* Mn */
{ 0x1920, 0x1922 }, /* Mn */
@@ -141,7 +144,7 @@
{ 0x1a7f, 0x1a7f }, /* Mn */
{ 0x1ab0, 0x1abd }, /* Mn */
{ 0x1abe, 0x1abe }, /* Me */
- { 0x1abf, 0x1ac0 }, /* Mn */
+ { 0x1abf, 0x1ace }, /* Mn */
{ 0x1b00, 0x1b03 }, /* Mn */
{ 0x1b34, 0x1b34 }, /* Mn */
{ 0x1b36, 0x1b3a }, /* Mn */
@@ -164,8 +167,7 @@
{ 0x1ced, 0x1ced }, /* Mn */
{ 0x1cf4, 0x1cf4 }, /* Mn */
{ 0x1cf8, 0x1cf9 }, /* Mn */
- { 0x1dc0, 0x1df9 }, /* Mn */
- { 0x1dfb, 0x1dff }, /* Mn */
+ { 0x1dc0, 0x1dff }, /* Mn */
{ 0x20d0, 0x20dc }, /* Mn */
{ 0x20dd, 0x20e0 }, /* Me */
{ 0x20e1, 0x20e1 }, /* Mn */
@@ -229,11 +231,15 @@
{ 0x10d24, 0x10d27 }, /* Mn */
{ 0x10eab, 0x10eac }, /* Mn */
{ 0x10f46, 0x10f50 }, /* Mn */
+ { 0x10f82, 0x10f85 }, /* Mn */
{ 0x11001, 0x11001 }, /* Mn */
{ 0x11038, 0x11046 }, /* Mn */
+ { 0x11070, 0x11070 }, /* Mn */
+ { 0x11073, 0x11074 }, /* Mn */
{ 0x1107f, 0x11081 }, /* Mn */
{ 0x110b3, 0x110b6 }, /* Mn */
{ 0x110b9, 0x110ba }, /* Mn */
+ { 0x110c2, 0x110c2 }, /* Mn */
{ 0x11100, 0x11102 }, /* Mn */
{ 0x11127, 0x1112b }, /* Mn */
{ 0x1112d, 0x11134 }, /* Mn */
@@ -313,6 +319,8 @@
{ 0x16f8f, 0x16f92 }, /* Mn */
{ 0x16fe4, 0x16fe4 }, /* Mn */
{ 0x1bc9d, 0x1bc9e }, /* Mn */
+ { 0x1cf00, 0x1cf2d }, /* Mn */
+ { 0x1cf30, 0x1cf46 }, /* Mn */
{ 0x1d167, 0x1d169 }, /* Mn */
{ 0x1d17b, 0x1d182 }, /* Mn */
{ 0x1d185, 0x1d18b }, /* Mn */
diff --git a/configure b/configure
index 5589f8e761f0..eb346f8a3463 100755
--- a/configure
+++ b/configure
@@ -4048,297 +4048,6 @@ if test "$ac_res" != no; then :
fi
-# Checks for terminal libraries
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working terminal libraries" >&5
-$as_echo_n "checking for working terminal libraries... " >&6; }
-TERMLIBS=
-
-# Check for systems where curses is broken.
-curses_broken=0
-if test x`uname -s` = "xHP-UX" >/dev/null 2>&1; then
-if test x`uname -r` = "xB.11.00" >/dev/null 2>&1; then
- curses_broken=1
-fi
-if test x`uname -r` = "xB.11.11" >/dev/null 2>&1; then
- curses_broken=1
-fi
-fi
-
-if test $curses_broken = 0; then
-
-# -- Try tinfo.
-if test "x$TERMLIBS" = x; then
- if test $have_tinfo = yes; then
- TERMLIBS="-ltinfo"
- SAVE_LIBS=$LIBS
- LIBS="$LIBS $TERMLIBS"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- termok=yes
-else
- termok=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- LIBS=$SAVE_LIBS
- if test $termok = no; then TERMLIBS=""; fi
- fi
-fi
-
-# -- Try tinfow.
-if test "x$TERMLIBS" = x; then
- if test $have_tinfow = yes; then
- TERMLIBS="-ltinfow"
- SAVE_LIBS=$LIBS
- LIBS="$LIBS $TERMLIBS"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- termok=yes
-else
- termok=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- LIBS=$SAVE_LIBS
- if test $termok = no; then TERMLIBS=""; fi
- fi
-fi
-
-# -- Try xcurses.
-if test "x$TERMLIBS" = x; then
- if test $have_xcurses = yes; then
- TERMLIBS="-lxcurses"
- SAVE_LIBS=$LIBS
- LIBS="$LIBS $TERMLIBS"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- termok=yes
-else
- termok=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- LIBS=$SAVE_LIBS
- if test $termok = no; then TERMLIBS=""; fi
- fi
-fi
-
-# -- Try ncursesw.
-if test "x$TERMLIBS" = x; then
- if test $have_ncursesw = yes; then
- TERMLIBS="-lncursesw"
- SAVE_LIBS=$LIBS
- LIBS="$LIBS $TERMLIBS"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- termok=yes
-else
- termok=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- LIBS=$SAVE_LIBS
- if test $termok = no; then TERMLIBS=""; fi
- fi
-fi
-
-# -- Try ncurses.
-if test "x$TERMLIBS" = x; then
- if test $have_ncurses = yes; then
- TERMLIBS="-lncurses"
- SAVE_LIBS=$LIBS
- LIBS="$LIBS $TERMLIBS"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <termcap.h>
-int
-main ()
-{
-tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- termok=yes
-else
- termok=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- LIBS=$SAVE_LIBS
- if test $termok = no; then TERMLIBS=""; fi
- fi
-fi
-
-# -- Try curses.
-if test "x$TERMLIBS" = x; then
- if test $have_curses = yes; then
- TERMLIBS="-lcurses"
- SAVE_LIBS=$LIBS
- LIBS="$LIBS $TERMLIBS"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- termok=yes
-else
- termok=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- LIBS=$SAVE_LIBS
- if test $termok = no; then TERMLIBS=""; fi
- fi
-fi
-
-# -- Try curses & termcap.
-if test "x$TERMLIBS" = x; then
- if test $have_curses = yes; then
- if test $have_termcap = yes; then
- TERMLIBS="-lcurses -ltermcap"
- SAVE_LIBS=$LIBS
- LIBS="$LIBS $TERMLIBS"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- termok=yes
-else
- termok=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- LIBS=$SAVE_LIBS
- if test $termok = no; then TERMLIBS=""; fi
- fi
- fi
-fi
-fi
-
-# -- Try termcap.
-if test "x$TERMLIBS" = x; then
- if test $have_termcap = yes; then
- TERMLIBS="-ltermcap"
- SAVE_LIBS=$LIBS
- LIBS="$LIBS $TERMLIBS"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- termok=yes
-else
- termok=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- LIBS=$SAVE_LIBS
- if test $termok = no; then TERMLIBS=""; fi
- fi
-fi
-
-# -- Try termlib.
-if test "x$TERMLIBS" = x; then
- if test $have_termlib = yes; then
- TERMLIBS="-lcurses -ltermlib"
- SAVE_LIBS=$LIBS
- LIBS="$LIBS $TERMLIBS"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- termok=yes
-else
- termok=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- LIBS=$SAVE_LIBS
- if test $termok = no; then TERMLIBS=""; fi
- fi
-fi
-
-if test "x$TERMLIBS" = x; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: Cannot find terminal libraries - configure failed" >&5
-$as_echo "Cannot find terminal libraries - configure failed" >&6; }
- exit 1
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: using $TERMLIBS" >&5
-$as_echo "using $TERMLIBS" >&6; }
-LIBS="$LIBS $TERMLIBS"
-
# Checks for header files.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
$as_echo_n "checking for ANSI C header files... " >&6; }
@@ -4665,6 +4374,299 @@ $as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h
fi
+# Checks for terminal libraries
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working terminal libraries" >&5
+$as_echo_n "checking for working terminal libraries... " >&6; }
+TERMLIBS=
+include_termcap_h=
+if test "x$ac_cv_header_termcap_h" = xyes; then include_termcap_h="#include <termcap.h>"; fi
+
+# Check for systems where curses is broken.
+curses_broken=0
+if test x`uname -s` = "xHP-UX" >/dev/null 2>&1; then
+if test x`uname -r` = "xB.11.00" >/dev/null 2>&1; then
+ curses_broken=1
+fi
+if test x`uname -r` = "xB.11.11" >/dev/null 2>&1; then
+ curses_broken=1
+fi
+fi
+
+if test $curses_broken = 0; then
+
+# -- Try tinfo.
+if test "x$TERMLIBS" = x; then
+ if test $have_tinfo = yes; then
+ TERMLIBS="-ltinfo"
+ SAVE_LIBS=$LIBS
+ LIBS="$LIBS $TERMLIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$include_termcap_h
+int
+main ()
+{
+tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ termok=yes
+else
+ termok=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS=$SAVE_LIBS
+ if test $termok = no; then TERMLIBS=""; fi
+ fi
+fi
+
+# -- Try tinfow.
+if test "x$TERMLIBS" = x; then
+ if test $have_tinfow = yes; then
+ TERMLIBS="-ltinfow"
+ SAVE_LIBS=$LIBS
+ LIBS="$LIBS $TERMLIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$include_termcap_h
+int
+main ()
+{
+tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ termok=yes
+else
+ termok=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS=$SAVE_LIBS
+ if test $termok = no; then TERMLIBS=""; fi
+ fi
+fi
+
+# -- Try xcurses.
+if test "x$TERMLIBS" = x; then
+ if test $have_xcurses = yes; then
+ TERMLIBS="-lxcurses"
+ SAVE_LIBS=$LIBS
+ LIBS="$LIBS $TERMLIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$include_termcap_h
+int
+main ()
+{
+tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ termok=yes
+else
+ termok=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS=$SAVE_LIBS
+ if test $termok = no; then TERMLIBS=""; fi
+ fi
+fi
+
+# -- Try ncursesw.
+if test "x$TERMLIBS" = x; then
+ if test $have_ncursesw = yes; then
+ TERMLIBS="-lncursesw"
+ SAVE_LIBS=$LIBS
+ LIBS="$LIBS $TERMLIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$include_termcap_h
+int
+main ()
+{
+tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ termok=yes
+else
+ termok=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS=$SAVE_LIBS
+ if test $termok = no; then TERMLIBS=""; fi
+ fi
+fi
+
+# -- Try ncurses.
+if test "x$TERMLIBS" = x; then
+ if test $have_ncurses = yes; then
+ TERMLIBS="-lncurses"
+ SAVE_LIBS=$LIBS
+ LIBS="$LIBS $TERMLIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$include_termcap_h
+int
+main ()
+{
+tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ termok=yes
+else
+ termok=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS=$SAVE_LIBS
+ if test $termok = no; then TERMLIBS=""; fi
+ fi
+fi
+
+# -- Try curses.
+if test "x$TERMLIBS" = x; then
+ if test $have_curses = yes; then
+ TERMLIBS="-lcurses"
+ SAVE_LIBS=$LIBS
+ LIBS="$LIBS $TERMLIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$include_termcap_h
+int
+main ()
+{
+tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ termok=yes
+else
+ termok=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS=$SAVE_LIBS
+ if test $termok = no; then TERMLIBS=""; fi
+ fi
+fi
+
+# -- Try curses & termcap.
+if test "x$TERMLIBS" = x; then
+ if test $have_curses = yes; then
+ if test $have_termcap = yes; then
+ TERMLIBS="-lcurses -ltermcap"
+ SAVE_LIBS=$LIBS
+ LIBS="$LIBS $TERMLIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$include_termcap_h
+int
+main ()
+{
+tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ termok=yes
+else
+ termok=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS=$SAVE_LIBS
+ if test $termok = no; then TERMLIBS=""; fi
+ fi
+ fi
+fi
+fi
+
+# -- Try termcap.
+if test "x$TERMLIBS" = x; then
+ if test $have_termcap = yes; then
+ TERMLIBS="-ltermcap"
+ SAVE_LIBS=$LIBS
+ LIBS="$LIBS $TERMLIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$include_termcap_h
+int
+main ()
+{
+tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ termok=yes
+else
+ termok=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS=$SAVE_LIBS
+ if test $termok = no; then TERMLIBS=""; fi
+ fi
+fi
+
+# -- Try termlib.
+if test "x$TERMLIBS" = x; then
+ if test $have_termlib = yes; then
+ TERMLIBS="-lcurses -ltermlib"
+ SAVE_LIBS=$LIBS
+ LIBS="$LIBS $TERMLIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$include_termcap_h
+int
+main ()
+{
+tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ termok=yes
+else
+ termok=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS=$SAVE_LIBS
+ if test $termok = no; then TERMLIBS=""; fi
+ fi
+fi
+
+if test "x$TERMLIBS" = x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: Cannot find terminal libraries - configure failed" >&5
+$as_echo "Cannot find terminal libraries - configure failed" >&6; }
+ exit 1
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: using $TERMLIBS" >&5
+$as_echo "using $TERMLIBS" >&6; }
+LIBS="$LIBS $TERMLIBS"
+
# Autoheader templates for symbols defined later by AC_DEFINE.
@@ -4696,6 +4698,7 @@ fi
+
# Checks for identifiers.
ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default"
if test "x$ac_cv_type_off_t" = xyes; then :
@@ -4797,6 +4800,28 @@ else
$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; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
# Checks for ANSI function prototypes.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI function prototypes" >&5
@@ -5346,15 +5371,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 21f550a1a609..f7c648142d43 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.
@@ -35,9 +35,22 @@ AC_CHECK_LIB(termlib, tgetent, [have_termlib=yes], [have_termlib=no])
# at least on Solaris 10 (2.10)) and in -lintl on SCO Unix.
AC_SEARCH_LIBS([regcmp], [gen intl PW])
+# Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS([ctype.h errno.h fcntl.h limits.h stdio.h stdlib.h string.h termcap.h termio.h termios.h time.h unistd.h values.h sys/ioctl.h sys/stream.h wctype.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_HEADER_STAT
+AC_C_CONST
+AC_TYPE_OFF_T
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+
# Checks for terminal libraries
AC_MSG_CHECKING([for working terminal libraries])
TERMLIBS=
+include_termcap_h=
+if test "x$ac_cv_header_termcap_h" = xyes; then include_termcap_h="#include <termcap.h>"; fi
# Check for systems where curses is broken.
curses_broken=0
@@ -58,7 +71,7 @@ if test "x$TERMLIBS" = x; then
TERMLIBS="-ltinfo"
SAVE_LIBS=$LIBS
LIBS="$LIBS $TERMLIBS"
- AC_TRY_LINK(, [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
+ AC_TRY_LINK([$include_termcap_h], [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
[termok=yes], [termok=no])
LIBS=$SAVE_LIBS
if test $termok = no; then TERMLIBS=""; fi
@@ -71,7 +84,7 @@ if test "x$TERMLIBS" = x; then
TERMLIBS="-ltinfow"
SAVE_LIBS=$LIBS
LIBS="$LIBS $TERMLIBS"
- AC_TRY_LINK(, [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
+ AC_TRY_LINK([$include_termcap_h], [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
[termok=yes], [termok=no])
LIBS=$SAVE_LIBS
if test $termok = no; then TERMLIBS=""; fi
@@ -84,7 +97,7 @@ if test "x$TERMLIBS" = x; then
TERMLIBS="-lxcurses"
SAVE_LIBS=$LIBS
LIBS="$LIBS $TERMLIBS"
- AC_TRY_LINK(, [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
+ AC_TRY_LINK([$include_termcap_h], [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
[termok=yes], [termok=no])
LIBS=$SAVE_LIBS
if test $termok = no; then TERMLIBS=""; fi
@@ -97,7 +110,7 @@ if test "x$TERMLIBS" = x; then
TERMLIBS="-lncursesw"
SAVE_LIBS=$LIBS
LIBS="$LIBS $TERMLIBS"
- AC_TRY_LINK(, [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
+ AC_TRY_LINK([$include_termcap_h], [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
[termok=yes], [termok=no])
LIBS=$SAVE_LIBS
if test $termok = no; then TERMLIBS=""; fi
@@ -110,7 +123,7 @@ if test "x$TERMLIBS" = x; then
TERMLIBS="-lncurses"
SAVE_LIBS=$LIBS
LIBS="$LIBS $TERMLIBS"
- AC_TRY_LINK([#include <termcap.h>], [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
+ AC_TRY_LINK([$include_termcap_h], [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
[termok=yes], [termok=no])
LIBS=$SAVE_LIBS
if test $termok = no; then TERMLIBS=""; fi
@@ -123,7 +136,7 @@ if test "x$TERMLIBS" = x; then
TERMLIBS="-lcurses"
SAVE_LIBS=$LIBS
LIBS="$LIBS $TERMLIBS"
- AC_TRY_LINK(, [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
+ AC_TRY_LINK([$include_termcap_h], [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
[termok=yes], [termok=no])
LIBS=$SAVE_LIBS
if test $termok = no; then TERMLIBS=""; fi
@@ -137,7 +150,7 @@ if test "x$TERMLIBS" = x; then
TERMLIBS="-lcurses -ltermcap"
SAVE_LIBS=$LIBS
LIBS="$LIBS $TERMLIBS"
- AC_TRY_LINK(, [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
+ AC_TRY_LINK([$include_termcap_h], [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
[termok=yes], [termok=no])
LIBS=$SAVE_LIBS
if test $termok = no; then TERMLIBS=""; fi
@@ -152,7 +165,7 @@ if test "x$TERMLIBS" = x; then
TERMLIBS="-ltermcap"
SAVE_LIBS=$LIBS
LIBS="$LIBS $TERMLIBS"
- AC_TRY_LINK(, [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
+ AC_TRY_LINK([$include_termcap_h], [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
[termok=yes], [termok=no])
LIBS=$SAVE_LIBS
if test $termok = no; then TERMLIBS=""; fi
@@ -165,7 +178,7 @@ if test "x$TERMLIBS" = x; then
TERMLIBS="-lcurses -ltermlib"
SAVE_LIBS=$LIBS
LIBS="$LIBS $TERMLIBS"
- AC_TRY_LINK(, [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
+ AC_TRY_LINK([$include_termcap_h], [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
[termok=yes], [termok=no])
LIBS=$SAVE_LIBS
if test $termok = no; then TERMLIBS=""; fi
@@ -179,17 +192,6 @@ fi
AC_MSG_RESULT(using $TERMLIBS)
LIBS="$LIBS $TERMLIBS"
-# Checks for header files.
-AC_HEADER_STDC
-AC_CHECK_HEADERS([ctype.h errno.h fcntl.h limits.h stdio.h stdlib.h string.h termcap.h termio.h termios.h time.h unistd.h values.h sys/ioctl.h sys/stream.h wctype.h])
-
-# Checks for typedefs, structures, and compiler characteristics.
-AC_HEADER_STAT
-AC_C_CONST
-AC_TYPE_OFF_T
-AC_TYPE_SIZE_T
-AC_HEADER_TIME
-
# Autoheader templates for symbols defined later by AC_DEFINE.
AH_TEMPLATE([HAVE_GNU_REGEX],
[GNU regex library])
@@ -217,6 +219,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 +270,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 +430,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 9cf44b894e7d..bb4649264f12 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 7e9b167bc786..0444cab399c9 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 1bd50261561b..d358fec5e524 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 9a36f1b857f2..e5559d1153f9 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 5499bb401c89..9438bb2634c4 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 cb5de661ec99..28a93d66954c 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 390eb17e834e..30592cad3785 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 529ed75b0afe..151ac744f7b5 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 aba8d3a362e3..6d29753c3d2b 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.
@@ -477,7 +477,7 @@ bin_file(f)
edata = &data[n];
for (p = data; p < edata; )
{
- if (utf_mode && !is_utf8_well_formed(p, edata-data))
+ if (utf_mode && !is_utf8_well_formed(p, edata-p))
{
bin_count++;
utf_skip_to_lead(&p, edata);
@@ -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);
@@ -971,6 +972,8 @@ close_altfile(altfilename, filename)
{
#if HAVE_POPEN
char *lessclose;
+ char *qfilename;
+ char *qaltfilename;
FILE *fd;
char *cmd;
int len;
@@ -985,9 +988,13 @@ close_altfile(altfilename, filename)
error("LESSCLOSE ignored; must contain no more than 2 %%s", NULL_PARG);
return;
}
- len = (int) (strlen(lessclose) + strlen(filename) + strlen(altfilename) + 2);
+ qfilename = shell_quote(filename);
+ qaltfilename = shell_quote(altfilename);
+ len = (int) (strlen(lessclose) + strlen(qfilename) + strlen(qaltfilename) + 2);
cmd = (char *) ecalloc(len, sizeof(char));
- SNPRINTF2(cmd, len, lessclose, filename, altfilename);
+ SNPRINTF2(cmd, len, lessclose, qfilename, qaltfilename);
+ free(qaltfilename);
+ free(qfilename);
fd = shellcmd(cmd);
free(cmd);
if (fd != NULL)
diff --git a/fmt.uni b/fmt.uni
index bef4227fea9e..c4822942a166 100644
--- a/fmt.uni
+++ b/fmt.uni
@@ -1,9 +1,10 @@
-/* Generated by "./mkutable -f2 Cf -- unicode/UnicodeData.txt" on Tue May 19 14:47:34 PDT 2020 */
+/* Generated by "./mkutable -f2 Cf -- unicode/UnicodeData.txt" on Tue Jul 19 12:45:17 PDT 2022 */
{ 0x00ad, 0x00ad }, /* Cf */
{ 0x0600, 0x0605 }, /* Cf */
{ 0x061c, 0x061c }, /* Cf */
{ 0x06dd, 0x06dd }, /* Cf */
{ 0x070f, 0x070f }, /* Cf */
+ { 0x0890, 0x0891 }, /* Cf */
{ 0x08e2, 0x08e2 }, /* Cf */
{ 0x180e, 0x180e }, /* Cf */
{ 0x200b, 0x200f }, /* Cf */
diff --git a/forwback.c b/forwback.c
index e72172bf63db..6f0b118c4b0c 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;
@@ -120,6 +124,94 @@ squish_check(VOID_PARAM)
}
/*
+ * 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;
+ }
+ if (moved)
+ lower_left();
+ return moved;
+}
+
+/*
* Display n lines, scrolling forward,
* starting at position pos in the input file.
* "force" means display the n lines even if we hit end of file.
@@ -138,7 +230,6 @@ forw(n, pos, force, only_last, nblank)
{
int nlines = 0;
int do_repaint;
- static int first_time = 1;
squish_check();
@@ -291,10 +382,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 +421,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 +458,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 330540ac2156..146dffdc0cae 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 9dabd43ca221..75a91d1e1948 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 19:26 on 2022/7/22 */
#include "less.h"
constant char helpdata[] = {
'\n',
@@ -79,7 +79,7 @@ constant char helpdata[] = {
' ',' ','\'','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','G','o',' ','t','o',' ','a',' ','p','r','e','v','i','o','u','s','l','y',' ','m','a','r','k','e','d',' ','p','o','s','i','t','i','o','n','.','\n',
' ',' ','\'','\'',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','G','o',' ','t','o',' ','t','h','e',' ','p','r','e','v','i','o','u','s',' ','p','o','s','i','t','i','o','n','.','\n',
' ',' ','^','X','^','X',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','a','m','e',' ','a','s',' ','\'','.','\n',
-' ',' ','E','S','C','-','M','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ','C','l','e','a','r',' ','a',' ','m','a','r','k','.','\n',
+' ',' ','E','S','C','-','m','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ','C','l','e','a','r',' ','a',' ','m','a','r','k','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
' ',' ',' ',' ',' ',' ',' ',' ','A',' ','m','a','r','k',' ','i','s',' ','a','n','y',' ','u','p','p','e','r','-','c','a','s','e',' ','o','r',' ','l','o','w','e','r','-','c','a','s','e',' ','l','e','t','t','e','r','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','C','e','r','t','a','i','n',' ','m','a','r','k','s',' ','a','r','e',' ','p','r','e','d','e','f','i','n','e','d',':','\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 bc47a666754f..6b3d1ce9a5e3 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 f57c9e3403f2..ffd2f13e3f3f 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 a376486c5e23..ee1b0c632028 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 83e31514be3e..43e2cc476a7d 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 333a0b576c5e..59725788f609 100644
--- a/less.hlp
+++ b/less.hlp
@@ -76,7 +76,7 @@
'_<_l_e_t_t_e_r_> Go to a previously marked position.
'' Go to the previous position.
^X^X Same as '.
- ESC-M_<_l_e_t_t_e_r_> Clear a mark.
+ ESC-m_<_l_e_t_t_e_r_> Clear a mark.
---------------------------------------------------
A mark is any upper-case or lower-case letter.
Certain marks are predefined:
@@ -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 c25b2a1fa560..f5f90f11f484 100644
--- a/less.man
+++ b/less.man
@@ -117,10 +117,13 @@ LESS(1) General Commands Manual LESS(1)
which is growing while it is being viewed. (The behavior is
similar to the "tail -f" command.) To stop waiting for more
data, enter the interrupt character (usually ^C). On some sys-
- tems you can also use ^X.
+ tems you can also use ^X. If the input is a pipe and the
+ --exit-follow-on-close option is in effect, less will automati-
+ cally stop waiting for data when the input side of the pipe is
+ closed.
- ESC-F Like F, but as soon as a line is found which matches the last
- search pattern, the terminal bell is rung and forward scrolling
+ ESC-F Like F, but as soon as a line is found which matches the last
+ search pattern, the terminal bell is rung and forward scrolling
stops.
g or < or ESC-<
@@ -128,12 +131,12 @@ LESS(1) General Commands Manual LESS(1)
ing: this may be slow if N is large.)
G or > or ESC->
- Go to line N in the file, default the end of the file. (Warn-
- ing: this may be slow if N is large, or if N is not specified
+ Go to line N in the file, default the end of the file. (Warn-
+ ing: this may be slow if N is large, or if N is not specified
and standard input, rather than a file, is being read.)
- ESC-G Same as G, except if no number N is specified and the input is
- standard input, goes to the last line which is currently
+ ESC-G Same as G, except if no number N is specified and the input is
+ standard input, goes to the last line which is currently
buffered.
p or % Go to a position N percent into the file. N should be between 0
@@ -142,97 +145,98 @@ LESS(1) General Commands Manual LESS(1)
P Go to the line containing byte offset N in the file.
{ If a left curly bracket appears in the top line displayed on the
- screen, the { command will go to the matching right curly
- bracket. The matching right curly bracket is positioned on the
+ screen, the { command will go to the matching right curly
+ bracket. The matching right curly bracket is positioned on the
bottom line of the screen. If there is more than one left curly
- bracket on the top line, a number N may be used to specify the
+ bracket on the top line, a number N may be used to specify the
N-th bracket on the line.
} If a right curly bracket appears in the bottom line displayed 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, a number N may be used to specify the
- N-th bracket on the line.
+ 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 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.
) Like }, but applies to parentheses rather than curly brackets.
- [ Like {, but applies to square brackets rather than curly brack-
+ [ Like {, but applies to square brackets rather than curly brack-
ets.
- ] Like }, but applies to square brackets rather than curly brack-
+ ] Like }, but applies to square brackets rather than curly brack-
ets.
- ESC-^F Followed by two characters, acts like {, but uses the two char-
- acters as open and close brackets, respectively. For example,
- "ESC ^F < >" could be used to go forward to the > which matches
+ ESC-^F Followed by two characters, acts like {, but uses the two char-
+ acters as open and close brackets, respectively. For example,
+ "ESC ^F < >" could be used to go forward to the > which matches
the < in the top displayed line.
- ESC-^B Followed by two characters, acts like }, but uses the two char-
- acters as open and close brackets, respectively. For example,
+ ESC-^B Followed by two characters, acts like }, but uses the two char-
+ acters as open and close brackets, respectively. For example,
"ESC ^B < >" could be used to go backward to the < which matches
the > in the bottom displayed line.
- m Followed by any lowercase or uppercase letter, marks the first
- displayed line with that letter. If the status column is en-
- abled via the -J option, the status column shows the marked
+ m Followed by any lowercase or uppercase letter, marks the first
+ displayed line with that letter. If the status column is en-
+ abled via the -J option, the status column shows the marked
line.
- M Acts like m, except the last displayed line is marked rather
+ M Acts like m, except the last displayed line is marked rather
than the first displayed line.
- ' (Single quote.) Followed by any lowercase or uppercase letter,
- returns to the position which was previously marked with that
- letter. Followed by another single quote, returns to the posi-
- tion at which the last "large" movement command was executed.
- Followed by a ^ or $, jumps to the beginning or end of the file
- respectively. Marks are preserved when a new file is examined,
+ ' (Single quote.) Followed by any lowercase or uppercase letter,
+ returns to the position which was previously marked with that
+ letter. Followed by another single quote, returns to the posi-
+ tion at which the last "large" movement command was executed.
+ Followed by a ^ or $, jumps to the beginning or end of the file
+ respectively. Marks are preserved when a new file is examined,
so the ' command can be used to switch between input files.
^X^X Same as single quote.
- ESC-m Followed by any lowercase or uppercase letter, clears the mark
+ ESC-m Followed by any lowercase or uppercase letter, clears the mark
identified by that letter.
/pattern
Search forward in the file for the N-th line containing the pat-
tern. N defaults to 1. The pattern is a regular expression, as
- recognized by the regular expression library supplied by your
- system. The search starts at the first line displayed (but see
+ recognized by the regular expression library supplied by your
+ system. The search starts at the first line displayed (but see
the -a and -j options, which change this).
- Certain characters are special if entered at the beginning of
- the pattern; they modify the type of search rather than become
+ Certain characters are special if entered at the beginning of
+ the pattern; they modify the type of search rather than become
part of the pattern:
^N or !
Search for lines which do NOT match the pattern.
^E or *
- Search multiple files. That is, if the search reaches
- the END of the current file without finding a match, the
- search continues in the next file in the command line
+ Search multiple files. That is, if the search reaches
+ the END of the current file without finding a match, the
+ search continues in the next file in the command line
list.
^F or @
- Begin the search at the first line of the FIRST file in
- the command line list, regardless of what is currently
- displayed on the screen or the settings of the -a or -j
+ Begin the search at the first line of the FIRST file in
+ the command line list, regardless of what is currently
+ displayed on the screen or the settings of the -a or -j
options.
- ^K Highlight any text which matches the pattern on the cur-
+ ^K Highlight any text which matches the pattern on the cur-
rent screen, but don't move to the first match (KEEP cur-
rent position).
- ^R Don't interpret regular expression metacharacters; that
+ ^R Don't interpret regular expression metacharacters; that
is, do a simple textual comparison.
- ^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.
+ ^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. If the ^W
+ modifier is set, the ^E modifier is ignored.
?pattern
Search backward in the file for the N-th line containing the
@@ -564,6 +568,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.
@@ -595,8 +601,8 @@ LESS(1) General Commands Manual LESS(1)
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
@@ -636,11 +642,11 @@ LESS(1) General Commands Manual LESS(1)
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
@@ -806,7 +812,7 @@ LESS(1) General Commands Manual LESS(1)
-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
- F command).
+ "F" command).
All prompt strings consist of a sequence of letters and special
escape sequences. See the section on PROMPTS for more details.
@@ -928,8 +934,10 @@ LESS(1) General Commands Manual LESS(1)
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.
+ 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
@@ -997,21 +1005,43 @@ LESS(1) General Commands Manual LESS(1)
calculated if the terminal window is resized, so that the actual
scroll remains at the specified fraction of the screen width.
+ --exit-follow-on-close
+ When using the "F" command on a pipe, less will automatically
+ stop waiting for more data when the input side of the pipe is
+ closed.
+
--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.
+ 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-
ecuting, less will continue to display the contents of the orig-
- inal file despite its name change. If --follow-name is speci-
- fied, during an F command less will periodically attempt to re-
+ inal file despite its name change. If --follow-name is speci-
+ fied, during an F command less will periodically attempt to re-
open the file by name. If the reopen succeeds and the file is a
- different file from the original (which means that a new file
- has been created with the same name as the original (now re-
+ different file from the original (which means that a new file
+ 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
@@ -1047,20 +1077,46 @@ LESS(1) General Commands Manual LESS(1)
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.
It may begin with a two-character attribute indicator like LESS-
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
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 one. After the --use-backslash option, any backslash in an
@@ -1069,9 +1125,9 @@ LESS(1) General Commands Manual LESS(1)
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
- terminal supports ANSI color escape sequences (as defined in EC-
+ Enables colored text in various places. The -D option can be
+ used to change the colors. Colored text works only if the ter-
+ minal supports ANSI color escape sequences (as defined in EC-
MA-48 SGR; see
https://www.ecma-international.org/publications-and-
standards/standards/ecma-48).
@@ -1187,68 +1243,69 @@ LESS(1) General Commands Manual LESS(1)
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.
-
- 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
- system-wide file, key bindings in the local file take precedence over
- those in the system-wide file. If the environment variable
- LESSKEYIN_SYSTEM is set, less uses that as the name of the system-wide
- lesskey file. Otherwise, less looks in a standard place for the sys-
+ "$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
+ system-wide file, key bindings in the local file take precedence over
+ those in the system-wide file. If the environment variable
+ LESSKEYIN_SYSTEM is set, less uses that as the name of the system-wide
+ lesskey file. Otherwise, less looks in a standard place for the sys-
tem-wide lesskey file: On Unix systems, the system-wide lesskey file is
- /usr/local/etc/syslesskey. (However, if less was built with a differ-
- ent sysconf directory than /usr/local/etc, that directory is where the
+ /usr/local/etc/syslesskey. (However, if less was built with a differ-
+ ent sysconf directory than /usr/local/etc, that directory is where the
sysless file is found.) On MS-DOS and Windows systems, the system-wide
- lesskey file is c:\_syslesskey. On OS/2 systems, the system-wide
+ lesskey file is c:\_syslesskey. On OS/2 systems, the system-wide
lesskey file is c:\syslesskey.ini.
Previous versions of less (before v582) used lesskey files with a bina-
- ry format, produced by the lesskey program. It is no longer necessary
+ ry format, produced by the lesskey program. It is no longer necessary
to use the lesskey program.
INPUT PREPROCESSOR
- You may define an "input preprocessor" for less. Before less opens a
+ You may define an "input preprocessor" for less. Before less opens a
file, it first gives your input preprocessor a chance to modify the way
- the contents of the file are displayed. An input preprocessor is sim-
- ply an executable program (or shell script), which writes the contents
+ the contents of the file are displayed. An input preprocessor is sim-
+ ply an executable program (or shell script), which writes the contents
of the file to a different file, called the replacement file. The con-
- tents of the replacement file are then displayed in place of the con-
- tents of the original file. However, it will appear to the user as if
- the original file is opened; that is, less will display the original
+ tents of the replacement file are then displayed in place of the con-
+ tents of the original file. However, it will appear to the user as if
+ the original file is opened; that is, less will display the original
filename as the name of the current file.
- An input preprocessor receives one command line argument, the original
- filename, as entered by the user. It should create the replacement
- file, and when finished, print the name of the replacement file to its
- standard output. If the input preprocessor does not output a replace-
- ment filename, less uses the original file, as normal. The input pre-
- processor is not called when viewing standard input. To set up an in-
- put preprocessor, set the LESSOPEN environment variable to a command
- line which will invoke your input preprocessor. This command line
- should include one occurrence of the string "%s", which will be re-
+ An input preprocessor receives one command line argument, the original
+ filename, as entered by the user. It should create the replacement
+ file, and when finished, print the name of the replacement file to its
+ standard output. If the input preprocessor does not output a replace-
+ ment filename, less uses the original file, as normal. The input pre-
+ processor is not called when viewing standard input. To set up an in-
+ put preprocessor, set the LESSOPEN environment variable to a command
+ line which will invoke your input preprocessor. This command line
+ should include one occurrence of the string "%s", which will be re-
placed by the filename when the input preprocessor command is invoked.
When less closes a file opened in such a way, it will call another pro-
- gram, called the input postprocessor, which may perform any desired
- clean-up action (such as deleting the replacement file created by
+ gram, called the input postprocessor, which may perform any desired
+ clean-up action (such as deleting the replacement file created by
LESSOPEN). This program receives two command line arguments, the orig-
- inal filename as entered by the user, and the name of the replacement
- file. To set up an input postprocessor, set the LESSCLOSE environment
- variable to a command line which will invoke your input postprocessor.
- It may include two occurrences of the string "%s"; the first is re-
- placed with the original name of the file and the second with the name
+ inal filename as entered by the user, and the name of the replacement
+ file. To set up an input postprocessor, set the LESSCLOSE environment
+ variable to a command line which will invoke your input postprocessor.
+ It may include two occurrences of the string "%s"; the first is re-
+ placed with the original name of the file and the second with the name
of the replacement file, which was output by LESSOPEN.
- For example, on many Unix systems, these two scripts will allow you to
+ For example, on many Unix systems, these two scripts will allow you to
keep files in compressed format, but still let less view them directly:
lessopen.sh:
@@ -1268,27 +1325,27 @@ LESS(1) General Commands Manual LESS(1)
#! /bin/sh
rm $2
- To use these scripts, put them both where they can be executed and set
+ To use these scripts, put them both where they can be executed and set
LESSOPEN="lessopen.sh %s", and LESSCLOSE="lessclose.sh %s %s". More
- complex LESSOPEN and LESSCLOSE scripts may be written to accept other
+ complex LESSOPEN and LESSCLOSE scripts may be written to accept other
types of compressed files, and so on.
- It is also possible to set up an input preprocessor to pipe the file
- data directly to less, rather than putting the data into a replacement
+ It is also possible to set up an input preprocessor to pipe the file
+ data directly to less, rather than putting the data into a replacement
file. This avoids the need to decompress the entire file before start-
ing to view it. An input preprocessor that works this way is called an
- input pipe. An input pipe, instead of writing the name of a replace-
+ input pipe. An input pipe, instead of writing the name of a replace-
ment file on its standard output, writes the entire contents of the re-
- placement file on its standard output. If the input pipe does not
- write any characters on its standard output, then there is no replace-
- ment file and less uses the original file, as normal. To use an input
- pipe, make the first character in the LESSOPEN environment variable a
- vertical bar (|) to signify that the input preprocessor is an input
- pipe. As with non-pipe input preprocessors, the command string must
- contain one occurrence of %s, which is replaced with the filename of
+ placement file on its standard output. If the input pipe does not
+ write any characters on its standard output, then there is no replace-
+ ment file and less uses the original file, as normal. To use an input
+ pipe, make the first character in the LESSOPEN environment variable a
+ vertical bar (|) to signify that the input preprocessor is an input
+ pipe. As with non-pipe input preprocessors, the command string must
+ contain one occurrence of %s, which is replaced with the filename of
the input file.
- For example, on many Unix systems, this script will work like the pre-
+ For example, on many Unix systems, this script will work like the pre-
vious example scripts:
lesspipe.sh:
@@ -1305,29 +1362,29 @@ LESS(1) General Commands Manual LESS(1)
LESSOPEN="|lesspipe.sh %s".
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.
-
- When an input pipe is used, a LESSCLOSE postprocessor can be used, but
+ 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 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
- up. In this case, the replacement file name passed to the LESSCLOSE
+ up. In this case, the replacement file name passed to the LESSCLOSE
postprocessor is "-".
- For compatibility with previous versions of less, the input preproces-
+ For compatibility with previous versions of less, the input preproces-
sor or pipe is not used if less is viewing standard input. However, if
- the first character of LESSOPEN is a dash (-), the input preprocessor
- is used on standard input as well as other files. In this case, the
- dash is not considered to be part of the preprocessor command. If
+ the first character of LESSOPEN is a dash (-), the input preprocessor
+ is used on standard input as well as other files. In this case, the
+ dash is not considered to be part of the preprocessor command. If
standard input is being viewed, the input preprocessor is passed a file
- name consisting of a single dash. Similarly, if the first two charac-
- ters of LESSOPEN are vertical bar and dash (|-) or two vertical bars
- and a dash (||-), the input pipe is used on standard input as well as
+ name consisting of a single dash. Similarly, if the first two charac-
+ ters of LESSOPEN are vertical bar and dash (|-) or two vertical bars
+ and a dash (||-), the input pipe is used on standard input as well as
other files. Again, in this case the dash is not considered to be part
of the input pipe command.
@@ -1338,25 +1395,25 @@ LESS(1) General Commands Manual LESS(1)
can be displayed directly to the screen.
control characters
- should not be displayed directly, but are expected to be found
+ should not be displayed directly, but are expected to be found
in ordinary text files (such as backspace and tab).
binary characters
- should not be displayed directly and are not expected to be
+ should not be displayed directly and are not expected to be
found in text files.
A "character set" is simply a description of which characters are to be
- considered normal, control, and binary. The LESSCHARSET environment
- variable may be used to select a character set. Possible values for
+ considered normal, control, and binary. The LESSCHARSET environment
+ variable may be used to select a character set. Possible values for
LESSCHARSET are:
- ascii BS, TAB, NL, CR, and formfeed are control characters, all chars
- with values between 32 and 126 are normal, and all others are
+ ascii BS, TAB, NL, CR, and formfeed are control characters, all chars
+ with values between 32 and 126 are normal, and all others are
binary.
iso8859
- Selects an ISO 8859 character set. This is the same as ASCII,
- except characters between 160 and 255 are treated as normal
+ Selects an ISO 8859 character set. This is the same as ASCII,
+ except characters between 160 and 255 are treated as normal
characters.
latin1 Same as iso8859.
@@ -1368,8 +1425,8 @@ LESS(1) General Commands Manual LESS(1)
ebcdic Selects an EBCDIC character set.
IBM-1047
- Selects an EBCDIC character set used by OS/390 Unix Services.
- This is the EBCDIC analogue of latin1. You get similar results
+ Selects an EBCDIC character set used by OS/390 Unix Services.
+ This is the EBCDIC analogue of latin1. You get similar results
by setting either LESSCHARSET=IBM-1047 or LC_CTYPE=en_US in your
environment.
@@ -1377,29 +1434,29 @@ LESS(1) General Commands Manual LESS(1)
next Selects a character set appropriate for NeXT computers.
- utf-8 Selects the UTF-8 encoding of the ISO 10646 character set.
- UTF-8 is special in that it supports multi-byte characters in
+ utf-8 Selects the UTF-8 encoding of the ISO 10646 character set.
+ UTF-8 is special in that it supports multi-byte characters in
the input file. It is the only character set that supports mul-
ti-byte characters.
windows
- Selects a character set appropriate for Microsoft Windows (cp
+ Selects a character set appropriate for Microsoft Windows (cp
1251).
- In rare cases, it may be desired to tailor less to use a character set
- other than the ones definable by LESSCHARSET. In this case, the envi-
+ In rare cases, it may be desired to tailor less to use a character set
+ other than the ones definable by LESSCHARSET. In this case, the envi-
ronment variable LESSCHARDEF can be used to define a character set. It
should be set to a string where each character in the string represents
- one character in the character set. The character "." is used for a
- normal character, "c" for control, and "b" for binary. A decimal num-
- ber may be used for repetition. For example, "bccc4b." would mean
- character 0 is binary, 1, 2 and 3 are control, 4, 5, 6 and 7 are bina-
+ one character in the character set. The character "." is used for a
+ normal character, "c" for control, and "b" for binary. A decimal num-
+ ber may be used for repetition. For example, "bccc4b." would mean
+ character 0 is binary, 1, 2 and 3 are control, 4, 5, 6 and 7 are bina-
ry, and 8 is normal. All characters after the last are taken to be the
- same as the last, so characters 9 through 255 would be normal. (This
- is an example, and does not necessarily represent any real character
+ same as the last, so characters 9 through 255 would be normal. (This
+ is an example, and does not necessarily represent any real character
set.)
- This table shows the value of LESSCHARDEF which is equivalent to each
+ This table shows the value of LESSCHARDEF which is equivalent to each
of the possible values for LESSCHARSET:
ascii 8bcccbcc18b95.b
@@ -1413,65 +1470,65 @@ LESS(1) General Commands Manual LESS(1)
latin1 8bcccbcc18b95.33b.
next 8bcccbcc18b95.bb125.bb
- If neither LESSCHARSET nor LESSCHARDEF is set, but any of the strings
- "UTF-8", "UTF8", "utf-8" or "utf8" is found in the LC_ALL, LC_CTYPE or
+ If neither LESSCHARSET nor LESSCHARDEF is set, but any of the strings
+ "UTF-8", "UTF8", "utf-8" or "utf8" is found in the LC_ALL, LC_CTYPE or
LANG environment variables, then the default character set is utf-8.
If that string is not found, but your system supports the setlocale in-
- terface, less will use setlocale to determine the character set. set-
- locale is controlled by setting the LANG or LC_CTYPE environment vari-
+ terface, less will use setlocale to determine the character set. set-
+ locale is controlled by setting the LANG or LC_CTYPE environment vari-
ables.
- Finally, if the setlocale interface is also not available, the default
+ Finally, if the setlocale interface is also not available, the default
character set is latin1.
- Control and binary characters are displayed in standout (reverse
+ Control and binary characters are displayed in standout (reverse
video). Each such character is displayed in caret notation if possible
- (e.g. ^A for control-A). Caret notation is used only if inverting the
+ (e.g. ^A for control-A). Caret notation is used only if inverting the
0100 bit results in a normal printable character. Otherwise, the char-
- acter is displayed as a hex number in angle brackets. This format can
- be changed by setting the LESSBINFMT environment variable. LESSBINFMT
+ acter is displayed as a hex number in angle brackets. This format can
+ be changed by setting the LESSBINFMT environment variable. LESSBINFMT
may begin with a "*" and one character to select the display attribute:
- "*k" is blinking, "*d" is bold, "*u" is underlined, "*s" is standout,
- and "*n" is normal. If LESSBINFMT does not begin with a "*", normal
- attribute is assumed. The remainder of LESSBINFMT is a string which
- may include one printf-style escape sequence (a % followed by x, X, o,
- d, etc.). For example, if LESSBINFMT is "*u[%x]", binary characters
- are displayed in underlined hexadecimal surrounded by brackets. The
- default if no LESSBINFMT is specified is "*s<%02X>". Warning: the re-
- sult of expanding the character via LESSBINFMT must be less than 31
+ "*k" is blinking, "*d" is bold, "*u" is underlined, "*s" is standout,
+ and "*n" is normal. If LESSBINFMT does not begin with a "*", normal
+ attribute is assumed. The remainder of LESSBINFMT is a string which
+ may include one printf-style escape sequence (a % followed by x, X, o,
+ d, etc.). For example, if LESSBINFMT is "*u[%x]", binary characters
+ are displayed in underlined hexadecimal surrounded by brackets. The
+ default if no LESSBINFMT is specified is "*s<%02X>". Warning: the re-
+ sult of expanding the character via LESSBINFMT must be less than 31
characters.
When the character set is utf-8, the LESSUTFBINFMT environment variable
acts similarly to LESSBINFMT but it applies to Unicode code points that
- were successfully decoded but are unsuitable for display (e.g., unas-
- signed code points). Its default value is "<U+%04lX>". Note that
- LESSUTFBINFMT and LESSBINFMT share their display attribute setting
- ("*x") so specifying one will affect both; LESSUTFBINFMT is read after
- LESSBINFMT so its setting, if any, will have priority. Problematic
- octets in a UTF-8 file (octets of a truncated sequence, octets of a
- complete but non-shortest form sequence, invalid octets, and stray
- trailing octets) are displayed individually using LESSBINFMT so as to
+ were successfully decoded but are unsuitable for display (e.g., unas-
+ signed code points). Its default value is "<U+%04lX>". Note that
+ LESSUTFBINFMT and LESSBINFMT share their display attribute setting
+ ("*x") so specifying one will affect both; LESSUTFBINFMT is read after
+ LESSBINFMT so its setting, if any, will have priority. Problematic
+ octets in a UTF-8 file (octets of a truncated sequence, octets of a
+ complete but non-shortest form sequence, invalid octets, and stray
+ trailing octets) are displayed individually using LESSBINFMT so as to
facilitate diagnostic of how the UTF-8 file is ill-formed.
PROMPTS
- The -P option allows you to tailor the prompt to your preference. The
- string given to the -P option replaces the specified prompt string.
+ The -P option allows you to tailor the prompt to your preference. The
+ string given to the -P option replaces the specified prompt string.
Certain characters in the string are interpreted specially. The prompt
- mechanism is rather complicated to provide flexibility, but the ordi-
- nary user need not understand the details of constructing personalized
+ mechanism is rather complicated to provide flexibility, but the ordi-
+ nary user need not understand the details of constructing personalized
prompt strings.
- A percent sign followed by a single character is expanded according to
+ A percent sign followed by a single character is expanded according to
what the following character is:
- %bX Replaced by the byte offset into the current input file. The b
+ %bX Replaced by the byte offset into the current input file. The b
is followed by a single character (shown as X above) which spec-
- ifies the line whose byte offset is to be used. If the charac-
- ter is a "t", the byte offset of the top line in the display is
+ ifies the line whose byte offset is to be used. If the charac-
+ ter is a "t", the byte offset of the top line in the display is
used, an "m" means use the middle line, a "b" means use the bot-
- tom line, a "B" means use the line just after the bottom line,
- and a "j" means use the "target" line, as specified by the -j
+ tom line, a "B" means use the line just after the bottom line,
+ and a "j" means use the "target" line, as specified by the -j
option.
%B Replaced by the size of the current input file.
@@ -1479,50 +1536,50 @@ LESS(1) General Commands Manual LESS(1)
%c Replaced by the column number of the text appearing in the first
column of the screen.
- %dX Replaced by the page number of a line in the input file. The
+ %dX Replaced by the page number of a line in the input file. The
line to be used is determined by the X, as with the %b option.
- %D Replaced by the number of pages in the input file, or equiva-
+ %D Replaced by the number of pages in the input file, or equiva-
lently, the page number of the last line in the input file.
- %E Replaced by the name of the editor (from the VISUAL environment
- variable, or the EDITOR environment variable if VISUAL is not
+ %E Replaced by the name of the editor (from the VISUAL environment
+ variable, or the EDITOR environment variable if VISUAL is not
defined). See the discussion of the LESSEDIT feature below.
%f Replaced by the name of the current input file.
- %F Replaced by the last component of the name of the current input
+ %F Replaced by the last component of the name of the current input
file.
- %g Replaced by the shell-escaped name of the current input file.
- This is useful when the expanded string will be used in a shell
+ %g Replaced by the shell-escaped name of the current input file.
+ This is useful when the expanded string will be used in a shell
command, such as in LESSEDIT.
- %i Replaced by the index of the current file in the list of input
+ %i Replaced by the index of the current file in the list of input
files.
- %lX Replaced by the line number of a line in the input file. The
+ %lX Replaced by the line number of a line in the input file. The
line to be used is determined by the X, as with the %b option.
%L Replaced by the line number of the last line in the input file.
%m Replaced by the total number of input files.
- %pX Replaced by the percent into the current input file, based on
- byte offsets. The line used is determined by the X as with the
+ %pX Replaced by the percent into the current input file, based on
+ byte offsets. The line used is determined by the X as with the
%b option.
- %PX Replaced by the percent into the current input file, based on
- line numbers. The line used is determined by the X as with the
+ %PX Replaced by the percent into the current input file, based on
+ line numbers. The line used is determined by the X as with the
%b option.
%s Same as %B.
- %t Causes any trailing spaces to be removed. Usually used at the
+ %t Causes any trailing spaces to be removed. Usually used at the
end of the string, but may appear anywhere.
- %T Normally expands to the word "file". However if viewing files
- via a tags list using the -t option, it expands to the word
+ %T Normally expands to the word "file". However if viewing files
+ via a tags list using the -t option, it expands to the word
"tag".
%x Replaced by the name of the next input file in the list.
@@ -1530,15 +1587,15 @@ LESS(1) General Commands Manual LESS(1)
If any item is unknown (for example, the file size if input is a pipe),
a question mark is printed instead.
- The format of the prompt string can be changed depending on certain
- conditions. A question mark followed by a single character acts like
- an "IF": depending on the following character, a condition is evaluat-
- ed. If the condition is true, any characters following the question
- mark and condition character, up to a period, are included in the
- prompt. If the condition is false, such characters are not included.
- A colon appearing between the question mark and the period can be used
+ The format of the prompt string can be changed depending on certain
+ conditions. A question mark followed by a single character acts like
+ an "IF": depending on the following character, a condition is evaluat-
+ ed. If the condition is true, any characters following the question
+ mark and condition character, up to a period, are included in the
+ prompt. If the condition is false, such characters are not included.
+ A colon appearing between the question mark and the period can be used
to establish an "ELSE": any characters between the colon and the period
- are included in the string if and only if the IF condition is false.
+ are included in the string if and only if the IF condition is false.
Condition characters (which follow a question mark) may be:
?a True if any characters have been included in the prompt so far.
@@ -1553,7 +1610,7 @@ LESS(1) General Commands Manual LESS(1)
?e True if at end-of-file.
- ?f True if there is an input filename (that is, if input is not a
+ ?f True if there is an input filename (that is, if input is not a
pipe).
?lX True if the line number of the specified line is known.
@@ -1564,45 +1621,45 @@ LESS(1) General Commands Manual LESS(1)
?n True if this is the first prompt in a new input file.
- ?pX True if the percent into the current input file, based on byte
+ ?pX True if the percent into the current input file, based on byte
offsets, of the specified line is known.
- ?PX True if the percent into the current input file, based on line
+ ?PX True if the percent into the current input file, based on line
numbers, of the specified line is known.
?s Same as "?B".
- ?x True if there is a next input file (that is, if the current in-
+ ?x True if there is a next input file (that is, if the current in-
put file is not the last one).
Any characters other than the special ones (question mark, colon, peri-
- od, percent, and backslash) become literally part of the prompt. Any
- of the special characters may be included in the prompt literally by
+ od, percent, and backslash) become literally part of the prompt. Any
+ of the special characters may be included in the prompt literally by
preceding it with a backslash.
Some examples:
?f%f:Standard input.
- This prompt prints the filename, if known; otherwise the string "Stan-
+ This prompt prints the filename, if known; otherwise the string "Stan-
dard input".
?f%f .?ltLine %lt:?pt%pt\%:?btByte %bt:-...
- This prompt would print the filename, if known. The filename is fol-
- lowed by the line number, if known, otherwise the percent if known,
+ This prompt would print the filename, if known. The filename is fol-
+ lowed by the line number, if known, otherwise the percent if known,
otherwise the byte offset if known. Otherwise, a dash is printed. No-
- tice how each question mark has a matching period, and how the % after
+ tice how each question mark has a matching period, and how the % after
the %pt is included literally by escaping it with a backslash.
?n?f%f .?m(%T %i of %m) ..?e(END) ?x- Next\: %x..%t";
- This prints the filename if this is the first prompt in a file, fol-
- lowed by the "file N of N" message if there is more than one input
- file. Then, if we are at end-of-file, the string "(END)" is printed
- followed by the name of the next file, if there is one. Finally, any
+ This prints the filename if this is the first prompt in a file, fol-
+ lowed by the "file N of N" message if there is more than one input
+ file. Then, if we are at end-of-file, the string "(END)" is printed
+ followed by the name of the next file, if there is one. Finally, any
trailing spaces are truncated. This is the default prompt. For refer-
- ence, here are the defaults for the other two prompts (-m and -M re-
+ ence, here are the defaults for the other two prompts (-m and -M re-
spectively). Each is broken into two lines here for readability only.
?n?f%f .?m(%T %i of %m) ..?e(END) ?x- Next\: %x.:
@@ -1616,22 +1673,22 @@ LESS(1) General Commands Manual LESS(1)
?f%f .?m(%T %i of %m) .?ltlines %lt-%lb?L/%L. .
byte %bB?s/%s. ?e(END) :?pB%pB\%..%t
- The prompt expansion features are also used for another purpose: if an
- environment variable LESSEDIT is defined, it is used as the command to
- be executed when the v command is invoked. The LESSEDIT string is ex-
- panded in the same way as the prompt strings. The default value for
+ The prompt expansion features are also used for another purpose: if an
+ environment variable LESSEDIT is defined, it is used as the command to
+ be executed when the v command is invoked. The LESSEDIT string is ex-
+ panded in the same way as the prompt strings. The default value for
LESSEDIT is:
%E ?lm+%lm. %g
Note that this expands to the editor name, followed by a + and the line
- number, followed by the shell-escaped file name. If your editor does
- not accept the "+linenumber" syntax, or has other differences in invo-
- cation syntax, the LESSEDIT variable can be changed to modify this de-
+ number, followed by the shell-escaped file name. If your editor does
+ not accept the "+linenumber" syntax, or has other differences in invo-
+ cation syntax, the LESSEDIT variable can be changed to modify this de-
fault.
SECURITY
- When the environment variable LESSSECURE is set to 1, less runs in a
+ When the environment variable LESSSECURE is set to 1, less runs in a
"secure" mode. This means these features are disabled:
! the shell command
@@ -1652,56 +1709,58 @@ 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
If the environment variable LESS_IS_MORE is set to 1, or if the program
- is invoked via a file link named "more", less behaves (mostly) in con-
- formance with the POSIX "more" command specification. In this mode,
+ is invoked via a file link named "more", less behaves (mostly) in con-
+ formance with the POSIX "more" command specification. In this mode,
less behaves differently in these ways:
The -e option works differently. If the -e option is not set, less be-
- haves as if the -e option were set. If the -e option is set, less be-
+ haves as if the -e option were set. If the -e option is set, less be-
haves as if the -E option were set.
- The -m option works differently. If the -m option is not set, the
- medium prompt is used, and it is prefixed with the string "--More--".
+ The -m option works differently. If the -m option is not set, the
+ medium prompt is used, and it is prefixed with the string "--More--".
If the -m option is set, the short prompt is used.
- The -n option acts like the -z option. The normal behavior of the -n
+ The -n option acts like the -z option. The normal behavior of the -n
option is unavailable in this mode.
- The parameter to the -p option is taken to be a less command rather
+ The parameter to the -p option is taken to be a less command rather
than a search pattern.
- The LESS environment variable is ignored, and the MORE environment
+ The LESS environment variable is ignored, and the MORE environment
variable is used in its place.
ENVIRONMENT VARIABLES
Environment variables may be specified either in the system environment
- as usual, or in a lesskey(1) file. If environment variables are de-
+ as usual, or in a lesskey(1) file. If environment variables are de-
fined in more than one place, variables defined in a local lesskey file
take precedence over variables defined in the system environment, which
take precedence over variables defined in the system-wide lesskey file.
COLUMNS
Sets the number of columns on the screen. Takes precedence over
- the number of columns specified by the TERM variable. (But if
+ the number of columns 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
+ WIOCGETD, the window system's idea of the screen size takes
precedence over the LINES and COLUMNS environment variables.)
EDITOR The name of the editor (used for the v command).
- HOME Name of the user's home directory (used to find a lesskey file
+ HOME Name of the user's home directory (used to find a lesskey file
on Unix and OS/2 systems).
HOMEDRIVE, HOMEPATH
- Concatenation of the HOMEDRIVE and HOMEPATH environment vari-
+ Concatenation of the HOMEDRIVE and HOMEPATH environment vari-
ables is the name of the user's home directory if the HOME vari-
able is not set (only in the Windows version).
- INIT Name of the user's init directory (used to find a lesskey file
+ INIT Name of the user's init directory (used to find a lesskey file
on OS/2 systems).
LANG Language for determining the character set.
@@ -1712,12 +1771,12 @@ LESS(1) General Commands Manual LESS(1)
LESS Options which are passed to less automatically.
LESSANSIENDCHARS
- Characters which may end an ANSI color escape sequence (default
+ Characters which may end an ANSI color escape sequence (default
"m").
LESSANSIMIDCHARS
- Characters which may appear between the ESC character and the
- end character in an ANSI color escape sequence (default
+ Characters which may appear between the ESC character and the
+ end character in an ANSI color escape sequence (default
"0123456789:;[?!"'#%()*+ ".
LESSBINFMT
@@ -1734,22 +1793,23 @@ LESS(1) General Commands Manual LESS(1)
LESSECHO
Name of the lessecho program (default "lessecho"). The lessecho
- program is needed to expand metacharacters, such as * and ?, in
+ program is needed to expand metacharacters, such as * and ?, in
filenames on Unix systems.
LESSEDIT
- Editor prototype string (used for the v command). See discus-
+ Editor prototype string (used for the v command). See discus-
sion under PROMPTS.
LESSGLOBALTAGS
- Name of the command used by the -t option to find global tags.
- Normally should be set to "global" if your system has the glob-
+ Name of the command used by the -t option to find global tags.
+ Normally should be set to "global" if your system has the glob-
al(1) command. If not set, global tags are not used.
LESSHISTFILE
- 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
+ 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_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.
@@ -1821,7 +1881,7 @@ LESS(1) General Commands Manual LESS(1)
lesskey(1)
COPYRIGHT
- Copyright (C) 1984-2021 Mark Nudelman
+ Copyright (C) 1984-2022 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-
@@ -1846,4 +1906,4 @@ LESS(1) General Commands Manual LESS(1)
- Version 590: 03 Jun 2021 LESS(1)
+ Version 608: 22 Jul 2022 LESS(1)
diff --git a/less.nro b/less.nro
index 7c8372b500c6..b6dfa431ec84 100644
--- a/less.nro
+++ b/less.nro
@@ -1,5 +1,5 @@
'\" t
-.TH LESS 1 "Version 590: 03 Jun 2021"
+.TH LESS 1 "Version 608: 22 Jul 2022"
.SH NAME
less \- opposite of more
.SH SYNOPSIS
@@ -120,6 +120,10 @@ while it is being viewed.
(The behavior is similar to the "tail \-f" command.)
To stop waiting for more data, enter the interrupt character (usually ^C).
On some systems you can also use ^X.
+If the input is a pipe and the \-\-exit-follow-on-close option is in effect,
+.I less
+will automatically stop waiting for data when the input side
+of the pipe is closed.
.IP "ESC-F"
Like F, but as soon as a line is found which matches
the last search pattern, the terminal bell is rung
@@ -154,7 +158,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 +238,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 +586,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 +622,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 +663,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.
@@ -875,7 +882,7 @@ to that string.
\-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 F command).
+ \-Pw changes the message printed while waiting for data (in the "F" command).
.sp 1
All prompt strings consist of a sequence of
letters and special escape sequences.
@@ -1011,7 +1018,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
@@ -1079,12 +1089,18 @@ If the number is specified as a fraction, the actual number of
scroll positions is recalculated if the terminal window is resized,
so that the actual scroll remains at the specified fraction
of the screen width.
+.IP "\-\-exit-follow-on-close"
+When using the "F" command on a pipe,
+.I less
+will automatically stop waiting for more data when the input side of the
+pipe is closed.
.IP "\-\-file-size"
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 +1114,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,26 +1164,52 @@ 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
removed and the following character is taken literally.
This allows a dollar sign to be included in option strings.
.IP "\-\-use-color"
-Enables the colored text in various places.
-The -D option can be used to change the colors.
+Enables 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 ECMA-48 SGR;
see
@@ -1266,7 +1325,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 +1504,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 +1884,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 +1986,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.
@@ -1996,7 +2057,7 @@ The name of the editor (used for the v command).
.BR lesskey (1)
.
.SH COPYRIGHT
-Copyright (C) 1984-2021 Mark Nudelman
+Copyright (C) 1984-2022 Mark Nudelman
.PP
less is part of the GNU project and is free software.
You can redistribute it and/or modify it
diff --git a/lessecho.c b/lessecho.c
index bfb0f729a8b8..5cd660db50ba 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 ec33d196967e..e18b7fbacc69 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 608: 22 Jul 2022 LESSECHO(1)
diff --git a/lessecho.nro b/lessecho.nro
index 4733a93edd68..5b16d4aa8530 100644
--- a/lessecho.nro
+++ b/lessecho.nro
@@ -1,4 +1,4 @@
-.TH LESSECHO 1 "Version 590: 03 Jun 2021"
+.TH LESSECHO 1 "Version 608: 22 Jul 2022"
.SH NAME
lessecho \- expand metacharacters
.SH SYNOPSIS
diff --git a/lesskey.c b/lesskey.c
index b5130cccb8f7..39ebe8b980a9 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 1e70a7fe09a5..988c6aa50e17 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 56c75db080b6..c5a90a40cc3a 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,88 +16,93 @@ 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
- by less:
+ by less. Documentation on each command can be found in the man page,
+ under the key sequence which invokes the command.
#command
@@ -124,12 +129,12 @@ LESSKEY(1) General Commands Manual LESSKEY(1)
f forw-screen
^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
@@ -190,14 +195,16 @@ LESSKEY(1) General Commands Manual LESSKEY(1)
^X^V examine
: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
+ ## Use a long option name by starting the extra string with ONE dash; eg:
+ ## s toggle-option -log-file
_ display-option
| pipe
v visual
@@ -224,20 +231,20 @@ LESSKEY(1) General Commands Manual LESSKEY(1)
PRECEDENCE
- Commands specified by lesskey take precedence over the default com-
- mands. A default command key may be disabled by including it in the
- input file with the action "invalid". Alternatively, a key may be de-
+ Commands specified by lesskey take precedence over the default com-
+ mands. A default command key may be disabled by including it in the
+ input file with the action "invalid". Alternatively, a key may be de-
fined to do nothing by using the action "noaction". "noaction" is sim-
- ilar to "invalid", but less will give an error beep for an "invalid"
- command, but not for a "noaction" command. In addition, ALL default
+ ilar to "invalid", but less will give an error beep for an "invalid"
+ command, but not for a "noaction" command. In addition, ALL default
commands may be disabled by adding this control line to the input file:
#stop
- This will cause all default commands to be ignored. The #stop line
+ This will cause all default commands to be ignored. The #stop line
should be the last line in that section of the file.
- Be aware that #stop can be dangerous. Since all default commands are
+ Be aware that #stop can be dangerous. Since all default commands are
disabled, you must provide sufficient commands before the #stop line to
enable all necessary actions. For example, failure to provide a "quit"
command can lead to frustration.
@@ -247,21 +254,20 @@ LESSKEY(1) General Commands Manual LESSKEY(1)
#line-edit
- This section specifies new key bindings for the line editing commands,
- in a manner similar to the way key bindings for ordinary commands are
- specified in the #command section. The line-editing section consists
+ This section specifies new key bindings for the line editing commands,
+ in a manner similar to the way key bindings for ordinary commands are
+ specified in the #command section. The line-editing section consists
of a list of keys and actions, one per line as in the example below.
EXAMPLE
The following input file describes the set of default line-editing keys
- used by less:
+ used by less:
#line-edit
\t forw-complete
\17 back-complete
\e\t back-complete
-
^L expand
^V literal
^A literal
@@ -294,25 +300,53 @@ LESSKEY(1) General Commands Manual LESSKEY(1)
#env
- Following this line is a list of environment variable assignments.
- Each line consists of an environment variable name, an equals sign (=)
- and the value to be assigned to the environment variable. White space
- 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
+ Following this line is a list of environment variable assignments.
+ Each line consists of an environment variable name, an equals sign (=)
+ and the value to be assigned to the environment variable. White space
+ 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)
@@ -323,7 +357,7 @@ LESSKEY(1) General Commands Manual LESSKEY(1)
represented as \340 in a lesskey file.
COPYRIGHT
- Copyright (C) 1984-2021 Mark Nudelman
+ Copyright (C) 1984-2022 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-
@@ -346,4 +380,4 @@ LESSKEY(1) General Commands Manual LESSKEY(1)
- Version 590: 03 Jun 2021 LESSKEY(1)
+ Version 608: 22 Jul 2022 LESSKEY(1)
diff --git a/lesskey.nro b/lesskey.nro
index 9b3ec1672f9c..0e8cb1bb96c3 100644
--- a/lesskey.nro
+++ b/lesskey.nro
@@ -1,7 +1,7 @@
'\" t
-.TH LESSKEY 1 "Version 590: 03 Jun 2021"
+.TH LESSKEY 1 "Version 608: 22 Jul 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.
@@ -116,7 +126,11 @@ quits, the first character of the extra string is used as its exit status.
.
.SH EXAMPLE
The following input file describes the set of
-default command keys used by less:
+default command keys used by
+.IR less .
+Documentation on each command can be found in the
+.less
+man page, under the key sequence which invokes the command.
.sp
.RS 5m
.TS
@@ -217,6 +231,8 @@ T prev-tag
- toggle-option
:t toggle-option t
s toggle-option o
+ ## Use a long option name by starting the extra string with ONE dash; eg:
+ ## s toggle-option -log-file\n
\&_ display-option
| pipe
v visual
@@ -282,7 +298,8 @@ one per line as in the example below.
.
.SH EXAMPLE
The following input file describes the set of
-default line-editing keys used by less:
+default line-editing keys used by
+.IR less :
.sp
.RS 5m
.TS
@@ -333,23 +350,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
-configuration information stored in one file.
+version 777.
+Then the following line would assign the command to the Q key, but only in versions of
+.I less
+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)
@@ -360,7 +421,7 @@ which start with a NUL character (0).
This NUL character should be represented as \e340 in a lesskey file.
.
.SH COPYRIGHT
-Copyright (C) 1984-2021 Mark Nudelman
+Copyright (C) 1984-2022 Mark Nudelman
.PP
less is part of the GNU project and is free software.
You can redistribute it and/or modify it
diff --git a/lesskey_parse.c b/lesskey_parse.c
index 18cdf3753d53..7042b6e12708 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 2e5e74ec1900..794488a047e1 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 b8f609e9d4df..2f1b3fb9d2b2 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;
}
/*
@@ -252,6 +275,19 @@ add_linebuf(ch, attr, 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.
*/
static void
@@ -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,12 +362,18 @@ 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++)
- add_pfx(buf[i], AT_NORMAL|AT_COLOR_LINENUM);
+ add_pfx(buf[i], AT_BOLD|AT_COLOR_LINENUM);
add_pfx(' ', AT_NORMAL);
}
end_column = linebuf.pfx_end;
@@ -630,6 +670,20 @@ ansi_done(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.
*/
#define STORE_CHAR(ch,a,rep,pos) \
@@ -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;
}
@@ -956,28 +1035,36 @@ store_ansi(ch, rep, pos)
switch (ansi_step(line_ansi, ch))
{
case ANSI_MID:
- if (!in_hilite)
- STORE_CHAR(ch, AT_ANSI, rep, pos);
+ 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);
+ 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:
+ {
+ /* 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 +1100,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 +1189,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 +1220,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);
}
/*
@@ -1196,6 +1277,14 @@ pdone(endline, chopped, forw)
}
/*
+ * 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.
* We output a newline if we're not at the right edge of the screen,
@@ -1235,7 +1324,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)
@@ -1420,6 +1522,50 @@ back_raw_line(curr_pos, linep, line_lenp)
}
/*
+ * 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.
*/
public int
@@ -1465,16 +1611,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 a3e1b2fcb52d..1808ea97851e 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 5c67526e1030..d817369e42d0 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 724884243ed3..b3ec9afe36e1 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);
+ save_cmdhist();
raw_mode(0);
#if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC
/*
diff --git a/mark.c b/mark.c
index cbb316f276e6..f3bf0c4f6b55 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 9e7c86925b3a..84333b716ac9 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 61247d81ee9b..c4a496eddb4d 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 4a10d6b8b228..2ed238323874 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 73f8435043e6..6da2b305b820 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,14 @@ 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; /* */
+public int exit_F_on_close; /* Exit F command when input closes */
#if HILITE_SEARCH
public int hilite_search; /* Highlight matched search patterns? */
#endif
@@ -139,6 +146,12 @@ 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 };
+static struct optname exit_F_on_close_optname = { "exit-follow-on-close", NULL };
#if LESSTEST
static struct optname ttyin_name_optname = { "tty", NULL };
static struct optname rstat_optname = { "rstat", NULL };
@@ -562,6 +575,54 @@ 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
+ }
+ },
+ { OLETTER_NONE, &exit_F_on_close_optname,
+ BOOL, OPT_OFF, &exit_F_on_close, NULL,
+ {
+ "Don't exit F command when input closes",
+ "Exit F command when input closes",
+ 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 1723787b1c50..22b97de34b1c 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,11 +61,13 @@
#endif
public int reading;
+public int consecutive_nulls = 0;
static jmp_buf read_label;
extern int sigs;
extern int ignore_eoi;
+extern int exit_F_on_close;
#if !MSDOS_COMPILER
extern int tty;
#endif
@@ -157,20 +159,26 @@ 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
if (ignore_eoi && fd != tty)
{
+ int close_events = exit_F_on_close ? POLLERR|POLLHUP : POLLERR;
if (poll_events(tty, POLLIN) && getchr() == CONTROL('X'))
{
sigs |= S_INTERRUPT;
+ reading = 0;
return (READ_INTR);
}
- if (poll_events(fd, POLLERR|POLLHUP))
+ if (poll_events(fd, close_events))
{
sigs |= S_INTERRUPT;
+ reading = 0;
return (READ_INTR);
}
}
@@ -179,11 +187,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 +203,6 @@ start:
{
if (!ignore_eoi)
{
- static int consecutive_nulls = 0;
if (n == 0)
consecutive_nulls++;
else
@@ -203,7 +212,6 @@ start:
}
}
#endif
- reading = 0;
if (n < 0)
{
#if HAVE_ERRNO
@@ -259,7 +267,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 a865f4f0ce0b..3fed3df3ad33 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 c2266fcf68c8..bed36dfd57d1 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 6cd9d1a11b0f..a690b8e9bf51 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 8b21d729935a..a4f9c25ca88d 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 8f6edc939377..eabaf7e66dc2 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 4e0efc7f4c0f..85a110fca0f0 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 0e38c0f6e438..5319c40293bf 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 033a5b9cf23f..7c903ab61eb1 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.
@@ -128,8 +128,10 @@ extern int sc_height;
#endif
#if MSDOS_COMPILER==WIN32C
+#define UTF8_MAX_LENGTH 4
struct keyRecord
{
+ WCHAR unicode;
int ascii;
int scan;
} currentKey;
@@ -234,6 +236,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 +933,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 +1033,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 +1076,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 +1728,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 +1757,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 +2549,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 +2630,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;
@@ -2827,10 +2849,10 @@ win32_kbhit(VOID_PARAM)
*/
do
{
- PeekConsoleInput(tty, &ip, 1, &read);
+ PeekConsoleInputW(tty, &ip, 1, &read);
if (read == 0)
return (FALSE);
- ReadConsoleInput(tty, &ip, 1, &read);
+ ReadConsoleInputW(tty, &ip, 1, &read);
/* generate an X11 mouse sequence from the mouse event */
if (mousecap && ip.EventType == MOUSE_EVENT &&
ip.Event.MouseEvent.dwEventFlags != MOUSE_MOVED)
@@ -2861,11 +2883,13 @@ win32_kbhit(VOID_PARAM)
}
} while (ip.EventType != KEY_EVENT ||
ip.Event.KeyEvent.bKeyDown != TRUE ||
- ip.Event.KeyEvent.wVirtualScanCode == 0 ||
+ (ip.Event.KeyEvent.wVirtualScanCode == 0 && ip.Event.KeyEvent.uChar.UnicodeChar == 0) ||
+ ip.Event.KeyEvent.wVirtualKeyCode == VK_KANJI ||
ip.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT ||
ip.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL ||
ip.Event.KeyEvent.wVirtualKeyCode == VK_MENU);
+ currentKey.unicode = ip.Event.KeyEvent.uChar.UnicodeChar;
currentKey.ascii = ip.Event.KeyEvent.uChar.AsciiChar;
currentKey.scan = ip.Event.KeyEvent.wVirtualScanCode;
keyCount = ip.Event.KeyEvent.wRepeatCount;
@@ -2913,7 +2937,18 @@ win32_kbhit(VOID_PARAM)
public char
WIN32getch(VOID_PARAM)
{
- int ascii;
+ char ascii;
+ static unsigned char utf8[UTF8_MAX_LENGTH];
+ static int utf8_size = 0;
+ static int utf8_next_byte = 0;
+
+ // Return the rest of multibyte character from the prior call
+ if (utf8_next_byte < utf8_size)
+ {
+ ascii = utf8[utf8_next_byte++];
+ return ascii;
+ }
+ utf8_size = 0;
if (pending_scancode)
{
@@ -2930,7 +2965,16 @@ WIN32getch(VOID_PARAM)
continue;
}
keyCount --;
- ascii = currentKey.ascii;
+ // If multibyte character, return its first byte
+ if (currentKey.ascii != currentKey.unicode)
+ {
+ utf8_size = WideCharToMultiByte(CP_UTF8, 0, &currentKey.unicode, 1, &utf8, sizeof(utf8), NULL, NULL);
+ if (utf8_size == 0 )
+ return '\0';
+ ascii = utf8[0];
+ utf8_next_byte = 1;
+ } else
+ ascii = currentKey.ascii;
/*
* On PC's, the extended keys return a 2 byte sequence beginning
* with '00', so if the ascii code is 00, the next byte will be
@@ -2940,7 +2984,7 @@ WIN32getch(VOID_PARAM)
} while (pending_scancode &&
(currentKey.scan == PCK_CAPS_LOCK || currentKey.scan == PCK_NUM_LOCK));
- return ((char)ascii);
+ return ascii;
}
#endif
diff --git a/scrsize.c b/scrsize.c
index ee07cb8af1e6..7ceed58bd755 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 f619fbebeae8..224bc493df4c 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 dd666832e3f5..294fa6a7faf6 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 23a9b92f018b..03e29736488a 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 5bd3385ceadb..4be4527530d9 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/ubin.uni b/ubin.uni
index 10a48d5be50e..661cccb03542 100644
--- a/ubin.uni
+++ b/ubin.uni
@@ -1,4 +1,4 @@
-/* Generated by "./mkutable -f2 Cc Cs Co Zl Zp -- unicode/UnicodeData.txt" on Tue May 19 14:47:34 PDT 2020 */
+/* Generated by "./mkutable -f2 Cc Cs Co Zl Zp -- unicode/UnicodeData.txt" on Tue Jul 19 12:45:17 PDT 2022 */
{ 0x0000, 0x0007 }, /* Cc */
{ 0x000b, 0x000b }, /* Cc */
{ 0x000e, 0x001f }, /* Cc */
diff --git a/version.c b/version.c
index cab2690176fe..44e811604ca6 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,29 @@ 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().
+v601 1/31/22 Add --exit-follow-on-close option.
+v602 3/1/22 Doc changes.
+v603 3/14/22 Fix --header.
+v604 5/14/22 Fix termlib detection; fix non-ASCII input on Windows.
+v605 6/14/22 Update version number.
+v606 7/17/22 Fix bug with multibyte chars and --incsearch;
+ escape filenames in LESSCLOSE; fix bin_file overrun.
+v607 7/19/22 Update Unicode tables.
+v608 7/22/22 Fix highlighting on colored text boundaries.
*/
-char version[] = "590";
+char version[] = "608";
diff --git a/wide.uni b/wide.uni
index f1ec98d21b79..0e9922373409 100644
--- a/wide.uni
+++ b/wide.uni
@@ -1,4 +1,4 @@
-/* Generated by "./mkutable -f1 W F -- unicode/EastAsianWidth.txt" on Tue May 19 14:47:35 PDT 2020 */
+/* Generated by "./mkutable -f1 W F -- unicode/EastAsianWidth.txt" on Tue Jul 19 12:45:19 PDT 2022 */
{ 0x1100, 0x115f }, /* W */
{ 0x231a, 0x231b }, /* W */
{ 0x2329, 0x232a }, /* W */
@@ -64,7 +64,10 @@
{ 0x17000, 0x187f7 }, /* W */
{ 0x18800, 0x18cd5 }, /* W */
{ 0x18d00, 0x18d08 }, /* W */
- { 0x1b000, 0x1b11e }, /* W */
+ { 0x1aff0, 0x1aff3 }, /* W */
+ { 0x1aff5, 0x1affb }, /* W */
+ { 0x1affd, 0x1affe }, /* W */
+ { 0x1b000, 0x1b122 }, /* W */
{ 0x1b150, 0x1b152 }, /* W */
{ 0x1b164, 0x1b167 }, /* W */
{ 0x1b170, 0x1b2fb }, /* W */
@@ -99,20 +102,22 @@
{ 0x1f6cc, 0x1f6cc }, /* W */
{ 0x1f6d0, 0x1f6d2 }, /* W */
{ 0x1f6d5, 0x1f6d7 }, /* W */
+ { 0x1f6dd, 0x1f6df }, /* W */
{ 0x1f6eb, 0x1f6ec }, /* W */
{ 0x1f6f4, 0x1f6fc }, /* W */
{ 0x1f7e0, 0x1f7eb }, /* W */
+ { 0x1f7f0, 0x1f7f0 }, /* W */
{ 0x1f90c, 0x1f93a }, /* W */
{ 0x1f93c, 0x1f945 }, /* W */
- { 0x1f947, 0x1f978 }, /* W */
- { 0x1f97a, 0x1f9cb }, /* W */
- { 0x1f9cd, 0x1f9ff }, /* W */
+ { 0x1f947, 0x1f9ff }, /* W */
{ 0x1fa70, 0x1fa74 }, /* W */
- { 0x1fa78, 0x1fa7a }, /* W */
+ { 0x1fa78, 0x1fa7c }, /* W */
{ 0x1fa80, 0x1fa86 }, /* W */
- { 0x1fa90, 0x1faa8 }, /* W */
- { 0x1fab0, 0x1fab6 }, /* W */
- { 0x1fac0, 0x1fac2 }, /* W */
- { 0x1fad0, 0x1fad6 }, /* W */
+ { 0x1fa90, 0x1faac }, /* W */
+ { 0x1fab0, 0x1faba }, /* W */
+ { 0x1fac0, 0x1fac5 }, /* W */
+ { 0x1fad0, 0x1fad9 }, /* W */
+ { 0x1fae0, 0x1fae7 }, /* W */
+ { 0x1faf0, 0x1faf6 }, /* W */
{ 0x20000, 0x2fffd }, /* W */
{ 0x30000, 0x3fffd }, /* W */
diff --git a/xbuf.c b/xbuf.c
index f20dfae1e7df..4e767e34d193 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 ba62ef1722b1..d317e17868d5 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