aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXin LI <delphij@FreeBSD.org>2017-11-20 06:53:49 +0000
committerXin LI <delphij@FreeBSD.org>2017-11-20 06:53:49 +0000
commitee3dcfe98fdc32918e3476f437b9603983d6d0be (patch)
tree62ec9b28431130ee7fc5037091ea243b4304955f
parent6f90225e8378d85045013553763bd7483670441c (diff)
downloadsrc-ee3dcfe98fdc32918e3476f437b9603983d6d0be.tar.gz
src-ee3dcfe98fdc32918e3476f437b9603983d6d0be.zip
Vendor import of less v529.vendor/less/v529
Notes
Notes: svn path=/vendor/less/dist/; revision=326007 svn path=/vendor/less/v529/; revision=326008; tag=vendor/less/v529
-rw-r--r--Makefile.aut23
-rw-r--r--Makefile.in2
-rw-r--r--NEWS50
-rw-r--r--README5
-rw-r--r--ch.c5
-rw-r--r--charset.c105
-rw-r--r--cmd.h224
-rw-r--r--cmdbuf.c24
-rw-r--r--command.c343
-rw-r--r--compose.uni40
-rw-r--r--configure.ac2
-rw-r--r--cvt.c2
-rw-r--r--decode.c32
-rw-r--r--defines.h.in2
-rw-r--r--edit.c255
-rw-r--r--filename.c122
-rw-r--r--fmt.uni19
-rw-r--r--forwback.c8
-rw-r--r--funcs.h610
-rw-r--r--help.c6
-rw-r--r--ifile.c49
-rw-r--r--input.c11
-rw-r--r--jump.c23
-rw-r--r--less.h7
-rw-r--r--less.hlp4
-rw-r--r--less.man269
-rw-r--r--less.nro75
-rw-r--r--lessecho.man2
-rw-r--r--lessecho.nro2
-rw-r--r--lesskey.c2
-rw-r--r--lesskey.man4
-rw-r--r--lesskey.nro4
-rw-r--r--line.c182
-rw-r--r--main.c25
-rw-r--r--mark.c48
-rw-r--r--mkfuncs.pl2
-rw-r--r--mkhelp.c68
-rwxr-xr-xmkhelp.pl44
-rwxr-xr-xmkutable11
-rw-r--r--optfunc.c80
-rw-r--r--option.h2
-rw-r--r--opttbl.c7
-rw-r--r--output.c32
-rw-r--r--pattern.h8
-rw-r--r--position.c41
-rw-r--r--prompt.c2
-rw-r--r--screen.c46
-rw-r--r--search.c81
-rw-r--r--signal.c36
-rw-r--r--tags.c56
-rw-r--r--ubin.uni24
-rw-r--r--version.c43
-rw-r--r--wide.uni24
53 files changed, 1943 insertions, 1250 deletions
diff --git a/Makefile.aut b/Makefile.aut
index 24ee3f200901..8816902220b3 100644
--- a/Makefile.aut
+++ b/Makefile.aut
@@ -3,7 +3,7 @@
EMAIL = bug-less@gnu.org
HOMEPAGE = http://www.greenwoodsoftware.com/less
SHELL = /bin/sh
-RCS = rcs
+GIT = git
NROFF = nroff -man
srcdir = .
@@ -22,7 +22,7 @@ DISTFILES_W = \
defines.wn Makefile.wnm Makefile.wnb \
configure
UNICODE_FILES = \
- compose.uni ubin.uni wide.uni
+ compose.uni fmt.uni ubin.uni wide.uni
DISTFILES = \
${SRC} regexp.c regexp.h \
COPYING INSTALL LICENSE Makefile.in Makefile.aut NEWS README \
@@ -32,7 +32,7 @@ DISTFILES = \
install.sh defines.h.in mkinstalldirs \
less.nro less.man lesskey.nro lesskey.man lessecho.nro lessecho.man \
less.hlp \
- mkfuncs.pl mkhelp.c \
+ mkfuncs.pl mkhelp.pl \
mkutable $(UNICODE_FILES) \
${DISTFILES_W}
@@ -46,15 +46,12 @@ release: .FORCE
.FORCE:
-help.c: less.hlp mkhelp
+help.c: less.hlp
-mv -f ${srcdir}/help.c ${srcdir}/help.c.old
rm -rf help.c
- ./mkhelp < less.hlp > help.c
+ ${srcdir}/mkhelp.pl < less.hlp > help.c
if cmp -s help.c help.c.old; then mv -f help.c.old help.c; fi
-mkhelp: mkhelp.c
- ${CC} -o mkhelp mkhelp.c
-
${srcdir}/configure: ${srcdir}/configure.ac \
${srcdir}/Makefile.in
cd ${srcdir}; autoheader; autoconf
@@ -108,8 +105,10 @@ ${srcdir}/lessecho.man: ${srcdir}/lessecho.nro
compose.uni: unicode/UnicodeData.txt
./mkutable -f2 Mn Me -- unicode/UnicodeData.txt > $@
+fmt.uni: unicode/UnicodeData.txt
+ ./mkutable -f2 Cf -- unicode/UnicodeData.txt > $@
ubin.uni: unicode/UnicodeData.txt
- ./mkutable -f2 Cc Cf Cs Co Zl Zp -- unicode/UnicodeData.txt > $@
+ ./mkutable -f2 Cc Cs Co Zl Zp -- unicode/UnicodeData.txt > $@
wide.uni: unicode/EastAsianWidth.txt
./mkutable -f1 W F -- unicode/EastAsianWidth.txt > $@
@@ -130,6 +129,7 @@ dist: ${DISTFILES}
tar -cf - $$REL | gzip -c >release/$$REL/$$REL.tar.gz; \
echo "Signing release/$$REL/$$REL.tar.gz"; \
gpg --detach-sign release/$$REL/$$REL.tar.gz; \
+ mv release/$$REL/$$REL.tar.gz.sig release/$$REL/$$REL.sig; \
echo "Creating release/$$REL/$$REL.zip"; \
zip -rq release/$$REL/$$REL.zip $$REL; \
rm -rf $$REL
@@ -137,7 +137,4 @@ dist: ${DISTFILES}
tagall:
@REL=`sed -e '/char version/!d' -e 's/[^0-9.]*\([0-9.]*\).*/v\1/' -e q ${srcdir}/version.c`; \
echo "tagging $$REL"; \
- for f in ${srcdir}/RCS/*,v; do \
- REV=`co -p $$f 2>&1 | sed -e '1d' -e '3,$$d' -e 's/revision //'`; \
- ${RCS} -N$$REL:$$REV $$f; \
- done
+ $(GIT) tag -f "$$REL"
diff --git a/Makefile.in b/Makefile.in
index 8c8aed81edc0..c9cbf8e82e9a 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -62,6 +62,8 @@ lesskey$(EXEEXT): lesskey.${O} version.${O}
lessecho$(EXEEXT): lessecho.${O} version.${O}
${CC} ${LDFLAGS} -o $@ lessecho.${O} version.${O}
+charset.${O}: compose.uni ubin.uni wide.uni
+
${OBJ}: ${srcdir}/less.h ${srcdir}/funcs.h defines.h
install: all ${srcdir}/less.nro ${srcdir}/lesskey.nro ${srcdir}/lessecho.nro installdirs
diff --git a/NEWS b/NEWS
index e8bb6efc0019..8dd4dec33b12 100644
--- a/NEWS
+++ b/NEWS
@@ -11,18 +11,60 @@
======================================================================
- Major changes between "less" versions 487 and 491
+ Major changes between "less" versions 487 and 529
* Don't output terminal init sequence if using -F and file fits on one screen.
-* Use ANSI prototypes in funcs.h declarations.
+* When using -S, mark truncated lines with a special character.
+ The character can be changed or disabled via the new --rscroll option.
-* Fix some const mismatches.
+* New command M marks the last line displayed on the screen.
-* Remove "register" in variable declarations.
+* New command ESC-m removes a line mark.
+
+* Status column (enabled via -J) now shows mark letters.
+
+* Status column shows search matches even if highlighting is disabled via -G.
+
+* A second ESC-u command will clear search match markers in the status column.
+
+* Do same ANSI escape code filtering for tag matching that we do for
+ searching, to help when viewing syntax-highlighted code.
+
+* Catch SIGTERM and clean up before exiting.
+
+* Fix bug initializing default charset on Windows.
+
+* Handle keypad ENTER key correctly if it sends something other than newline.
+
+* Fix buffering bug when using stdin with a LESSOPEN pipe.
+
+* On Windows, allow 'u' in -D option to enable underlining.
+
+* On Windows, use underline in sgr mode.
+
+* On Windows, convert UTF-8 to multibyte if console is not UTF-8.
+
+* Update Unicode tables to 2017-03-08.
+
+* Pass-thru Unicode formating chars (Cf type) instead of treating them
+ as binary chars. But treat them as binary if -U is set.
+
+* Fix erroneous binary file warning when UTF-8 file contains ANSI SGR sequences.
+
+* Fix bugs when using LESSOPEN and switching between stdin and other files.
+
+* Fix some bugs handling filenames containing shell metacharacters.
* Fix some memory leaks.
+* Allow some debugging environment variables to be set in lesskey file.
+
+* Code improvements:
+ . Use ANSI prototypes in funcs.h declarations.
+ . Fix some const mismatches.
+ . Remove archaic "register" in variable declarations.
+
======================================================================
Major changes between "less" versions 481 and 487
diff --git a/README b/README
index 81bb95ab7962..bec1c6a5ab1c 100644
--- a/README
+++ b/README
@@ -1,7 +1,7 @@
- Less, version 491
+ Less, version 529
- This is the distribution of less, version 491, released 07 Apr 2017.
+ This is the distribution of less, version 529, released 13 Nov 2017.
This program is part of the GNU project (http://www.gnu.org).
This program is free software. You may redistribute it and/or
@@ -15,6 +15,7 @@
Please report any problems to bug-less@gnu.org.
See http://www.greenwoodsoftware.com/less for the latest info.
+ Source repository is at https://github.com/gwsw/less.git.
=========================================================================
diff --git a/ch.c b/ch.c
index 0fc65aca2848..47c1a32350f5 100644
--- a/ch.c
+++ b/ch.c
@@ -867,13 +867,12 @@ ch_init(f, flags)
calloc(1, sizeof(struct filestate));
thisfile->buflist.next = thisfile->buflist.prev = END_OF_CHAIN;
thisfile->nbufs = 0;
- thisfile->flags = 0;
+ thisfile->flags = flags;
thisfile->fpos = 0;
thisfile->block = 0;
thisfile->offset = 0;
thisfile->file = -1;
thisfile->fsize = NULL_POSITION;
- ch_flags = flags;
init_hashtbl();
/*
* Try to seek; set CH_CANSEEK if it works.
@@ -898,7 +897,7 @@ ch_close()
if (thisfile == NULL)
return;
- if (ch_flags & (CH_CANSEEK|CH_POPENED|CH_HELPFILE))
+ if ((ch_flags & (CH_CANSEEK|CH_POPENED|CH_HELPFILE)) && !(ch_flags & CH_KEEPOPEN))
{
/*
* We can seek or re-open, so we don't need to keep buffers.
diff --git a/charset.c b/charset.c
index 7aec0ea140e8..88978918e45f 100644
--- a/charset.c
+++ b/charset.c
@@ -22,6 +22,13 @@
#include "charset.h"
+#if MSDOS_COMPILER==WIN32C
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
+extern int bs_mode;
+
public int utf_mode = 0;
/*
@@ -215,7 +222,13 @@ icharset(name, no_error)
{
ichardef(p->desc);
if (p->p_flag != NULL)
+ {
+#if MSDOS_COMPILER==WIN32C
+ *(p->p_flag) = 1 + (GetConsoleOutputCP() != CP_UTF8);
+#else
*(p->p_flag) = 1;
+#endif
+ }
return (1);
}
}
@@ -251,16 +264,17 @@ ilocale()
/*
* Define the printing format for control (or binary utf) chars.
*/
- static void
-setbinfmt(s, fmtvarptr, default_fmt)
+ public void
+setfmt(s, fmtvarptr, attrptr, default_fmt)
char *s;
char **fmtvarptr;
+ int *attrptr;
char *default_fmt;
{
if (s && utf_mode)
{
/* It would be too hard to account for width otherwise. */
- char *t = s;
+ char constant *t = s;
while (*t)
{
if (*t < ' ' || *t > '~')
@@ -282,15 +296,15 @@ setbinfmt(s, fmtvarptr, default_fmt)
* Select the attributes if it starts with "*".
*/
attr:
- if (*s == '*')
+ if (*s == '*' && s[1] != '\0')
{
switch (s[1])
{
- case 'd': binattr = AT_BOLD; break;
- case 'k': binattr = AT_BLINK; break;
- case 's': binattr = AT_STANDOUT; break;
- case 'u': binattr = AT_UNDERLINE; break;
- default: binattr = AT_NORMAL; break;
+ case 'd': *attrptr = AT_BOLD; break;
+ case 'k': *attrptr = AT_BLINK; break;
+ case 's': *attrptr = AT_STANDOUT; break;
+ case 'u': *attrptr = AT_UNDERLINE; break;
+ default: *attrptr = AT_NORMAL; break;
}
s += 2;
}
@@ -305,6 +319,14 @@ set_charset()
{
char *s;
+#if MSDOS_COMPILER==WIN32C
+ /*
+ * If the Windows console is using UTF-8, we'll use it too.
+ */
+ if (GetConsoleOutputCP() == CP_UTF8)
+ if (icharset("utf-8", 1))
+ return;
+#endif
/*
* See if environment variable LESSCHARSET is defined.
*/
@@ -354,6 +376,7 @@ set_charset()
* rather than from predefined charset entry.
*/
ilocale();
+#else
#if MSDOS_COMPILER
/*
* Default to "dos".
@@ -383,10 +406,10 @@ init_charset()
set_charset();
s = lgetenv("LESSBINFMT");
- setbinfmt(s, &binfmt, "*s<%02X>");
+ setfmt(s, &binfmt, &binattr, "*s<%02X>");
s = lgetenv("LESSUTFBINFMT");
- setbinfmt(s, &utfbinfmt, "<U+%04lX>");
+ setfmt(s, &utfbinfmt, &binattr, "<U+%04lX>");
}
/*
@@ -543,34 +566,19 @@ is_utf8_well_formed(ss, slen)
}
/*
- * Return number of invalid UTF-8 sequences found in a buffer.
+ * Skip bytes until a UTF-8 lead byte (11xxxxxx) or ASCII byte (0xxxxxxx) is found.
*/
- public int
-utf_bin_count(data, len)
- char *data;
- int len;
+ public void
+utf_skip_to_lead(pp, limit)
+ char **pp;
+ char *limit;
{
- int bin_count = 0;
- while (len > 0)
- {
- if (is_utf8_well_formed(data, len))
- {
- int clen = utf_len(*data & 0377);
- data += clen;
- len -= clen;
- } else
- {
- /* Skip to next lead byte. */
- bin_count++;
- do {
- ++data;
- --len;
- } while (len > 0 && !IS_UTF8_LEAD(*data & 0377));
- }
- }
- return (bin_count);
+ do {
+ ++(*pp);
+ } while (*pp < limit && !IS_UTF8_LEAD((*pp)[0] & 0377) && !IS_ASCII_OCTET((*pp)[0]));
}
+
/*
* Get the value of a UTF-8 character.
*/
@@ -690,9 +698,9 @@ step_char(pp, dir, limit)
{
/* It's easy if chars are one byte. */
if (dir > 0)
- ch = (LWCHAR) ((p < limit) ? *p++ : 0);
+ ch = (LWCHAR) (unsigned char) ((p < limit) ? *p++ : 0);
else
- ch = (LWCHAR) ((p > limit) ? *--p : 0);
+ ch = (LWCHAR) (unsigned char) ((p > limit) ? *--p : 0);
} else if (dir > 0)
{
len = utf_len(*p);
@@ -740,6 +748,10 @@ DECLARE_RANGE_TABLE_START(wide)
#include "wide.uni"
DECLARE_RANGE_TABLE_END(wide)
+DECLARE_RANGE_TABLE_START(fmt)
+#include "fmt.uni"
+DECLARE_RANGE_TABLE_END(fmt)
+
/* comb_table is special pairs, not ranges. */
static struct wchar_range comb_table[] = {
{0x0644,0x0622}, {0x0644,0x0623}, {0x0644,0x0625}, {0x0644,0x0627},
@@ -780,7 +792,8 @@ is_in_table(ch, table)
is_composing_char(ch)
LWCHAR ch;
{
- return is_in_table(ch, &compose_table);
+ return is_in_table(ch, &compose_table) ||
+ (bs_mode != BS_CONTROL && is_in_table(ch, &fmt_table));
}
/*
@@ -790,7 +803,21 @@ is_composing_char(ch)
is_ubin_char(ch)
LWCHAR ch;
{
- return is_in_table(ch, &ubin_table);
+ 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/cmd.h b/cmd.h
index 0c221b83459a..632b65ea3c4e 100644
--- a/cmd.h
+++ b/cmd.h
@@ -8,129 +8,131 @@
*/
-#define MAX_USERCMD 1000
-#define MAX_CMDLEN 16
+#define MAX_USERCMD 1000
+#define MAX_CMDLEN 16
-#define A_B_LINE 2
-#define A_B_SCREEN 3
-#define A_B_SCROLL 4
-#define A_B_SEARCH 5
-#define A_DIGIT 6
-#define A_DISP_OPTION 7
-#define A_DEBUG 8
-#define A_EXAMINE 9
-#define A_FIRSTCMD 10
-#define A_FREPAINT 11
-#define A_F_LINE 12
-#define A_F_SCREEN 13
-#define A_F_SCROLL 14
-#define A_F_SEARCH 15
-#define A_GOEND 16
-#define A_GOLINE 17
-#define A_GOMARK 18
-#define A_HELP 19
-#define A_NEXT_FILE 20
-#define A_PERCENT 21
-#define A_PREFIX 22
-#define A_PREV_FILE 23
-#define A_QUIT 24
-#define A_REPAINT 25
-#define A_SETMARK 26
-#define A_SHELL 27
-#define A_STAT 28
-#define A_FF_LINE 29
-#define A_BF_LINE 30
-#define A_VERSION 31
-#define A_VISUAL 32
-#define A_F_WINDOW 33
-#define A_B_WINDOW 34
-#define A_F_BRACKET 35
-#define A_B_BRACKET 36
-#define A_PIPE 37
-#define A_INDEX_FILE 38
-#define A_UNDO_SEARCH 39
-#define A_FF_SCREEN 40
-#define A_LSHIFT 41
-#define A_RSHIFT 42
-#define A_AGAIN_SEARCH 43
-#define A_T_AGAIN_SEARCH 44
-#define A_REVERSE_SEARCH 45
-#define A_T_REVERSE_SEARCH 46
-#define A_OPT_TOGGLE 47
-#define A_OPT_SET 48
-#define A_OPT_UNSET 49
-#define A_F_FOREVER 50
-#define A_GOPOS 51
-#define A_REMOVE_FILE 52
-#define A_NEXT_TAG 53
-#define A_PREV_TAG 54
-#define A_FILTER 55
-#define A_F_UNTIL_HILITE 56
-#define A_GOEND_BUF 57
-#define A_LLSHIFT 58
-#define A_RRSHIFT 59
+#define A_B_LINE 2
+#define A_B_SCREEN 3
+#define A_B_SCROLL 4
+#define A_B_SEARCH 5
+#define A_DIGIT 6
+#define A_DISP_OPTION 7
+#define A_DEBUG 8
+#define A_EXAMINE 9
+#define A_FIRSTCMD 10
+#define A_FREPAINT 11
+#define A_F_LINE 12
+#define A_F_SCREEN 13
+#define A_F_SCROLL 14
+#define A_F_SEARCH 15
+#define A_GOEND 16
+#define A_GOLINE 17
+#define A_GOMARK 18
+#define A_HELP 19
+#define A_NEXT_FILE 20
+#define A_PERCENT 21
+#define A_PREFIX 22
+#define A_PREV_FILE 23
+#define A_QUIT 24
+#define A_REPAINT 25
+#define A_SETMARK 26
+#define A_SHELL 27
+#define A_STAT 28
+#define A_FF_LINE 29
+#define A_BF_LINE 30
+#define A_VERSION 31
+#define A_VISUAL 32
+#define A_F_WINDOW 33
+#define A_B_WINDOW 34
+#define A_F_BRACKET 35
+#define A_B_BRACKET 36
+#define A_PIPE 37
+#define A_INDEX_FILE 38
+#define A_UNDO_SEARCH 39
+#define A_FF_SCREEN 40
+#define A_LSHIFT 41
+#define A_RSHIFT 42
+#define A_AGAIN_SEARCH 43
+#define A_T_AGAIN_SEARCH 44
+#define A_REVERSE_SEARCH 45
+#define A_T_REVERSE_SEARCH 46
+#define A_OPT_TOGGLE 47
+#define A_OPT_SET 48
+#define A_OPT_UNSET 49
+#define A_F_FOREVER 50
+#define A_GOPOS 51
+#define A_REMOVE_FILE 52
+#define A_NEXT_TAG 53
+#define A_PREV_TAG 54
+#define A_FILTER 55
+#define A_F_UNTIL_HILITE 56
+#define A_GOEND_BUF 57
+#define A_LLSHIFT 58
+#define A_RRSHIFT 59
+#define A_CLRMARK 62
+#define A_SETMARKBOT 63
-#define A_INVALID 100
-#define A_NOACTION 101
-#define A_UINVALID 102
-#define A_END_LIST 103
-#define A_SPECIAL_KEY 104
+#define A_INVALID 100
+#define A_NOACTION 101
+#define A_UINVALID 102
+#define A_END_LIST 103
+#define A_SPECIAL_KEY 104
-#define A_SKIP 127
+#define A_SKIP 127
-#define A_EXTRA 0200
+#define A_EXTRA 0200
/* Line editing characters */
-#define EC_BACKSPACE 1
-#define EC_LINEKILL 2
-#define EC_RIGHT 3
-#define EC_LEFT 4
-#define EC_W_LEFT 5
-#define EC_W_RIGHT 6
-#define EC_INSERT 7
-#define EC_DELETE 8
-#define EC_HOME 9
-#define EC_END 10
-#define EC_W_BACKSPACE 11
-#define EC_W_DELETE 12
-#define EC_UP 13
-#define EC_DOWN 14
-#define EC_EXPAND 15
-#define EC_F_COMPLETE 17
-#define EC_B_COMPLETE 18
-#define EC_LITERAL 19
-#define EC_ABORT 20
+#define EC_BACKSPACE 1
+#define EC_LINEKILL 2
+#define EC_RIGHT 3
+#define EC_LEFT 4
+#define EC_W_LEFT 5
+#define EC_W_RIGHT 6
+#define EC_INSERT 7
+#define EC_DELETE 8
+#define EC_HOME 9
+#define EC_END 10
+#define EC_W_BACKSPACE 11
+#define EC_W_DELETE 12
+#define EC_UP 13
+#define EC_DOWN 14
+#define EC_EXPAND 15
+#define EC_F_COMPLETE 17
+#define EC_B_COMPLETE 18
+#define EC_LITERAL 19
+#define EC_ABORT 20
-#define EC_NOACTION 101
-#define EC_UINVALID 102
+#define EC_NOACTION 101
+#define EC_UINVALID 102
/* Flags for editchar() */
-#define EC_PEEK 01
-#define EC_NOHISTORY 02
-#define EC_NOCOMPLETE 04
-#define EC_NORIGHTLEFT 010
+#define EC_PEEK 01
+#define EC_NOHISTORY 02
+#define EC_NOCOMPLETE 04
+#define EC_NORIGHTLEFT 010
/* Environment variable stuff */
-#define EV_OK 01
+#define EV_OK 01
/* Special keys (keys which output different strings on different terminals) */
-#define SK_SPECIAL_KEY CONTROL('K')
-#define SK_RIGHT_ARROW 1
-#define SK_LEFT_ARROW 2
-#define SK_UP_ARROW 3
-#define SK_DOWN_ARROW 4
-#define SK_PAGE_UP 5
-#define SK_PAGE_DOWN 6
-#define SK_HOME 7
-#define SK_END 8
-#define SK_DELETE 9
-#define SK_INSERT 10
-#define SK_CTL_LEFT_ARROW 11
-#define SK_CTL_RIGHT_ARROW 12
-#define SK_CTL_DELETE 13
-#define SK_F1 14
-#define SK_BACKTAB 15
-#define SK_CTL_BACKSPACE 16
-#define SK_CONTROL_K 40
+#define SK_SPECIAL_KEY CONTROL('K')
+#define SK_RIGHT_ARROW 1
+#define SK_LEFT_ARROW 2
+#define SK_UP_ARROW 3
+#define SK_DOWN_ARROW 4
+#define SK_PAGE_UP 5
+#define SK_PAGE_DOWN 6
+#define SK_HOME 7
+#define SK_END 8
+#define SK_DELETE 9
+#define SK_INSERT 10
+#define SK_CTL_LEFT_ARROW 11
+#define SK_CTL_RIGHT_ARROW 12
+#define SK_CTL_DELETE 13
+#define SK_F1 14
+#define SK_BACKTAB 15
+#define SK_CTL_BACKSPACE 16
+#define SK_CONTROL_K 40
diff --git a/cmdbuf.c b/cmdbuf.c
index 02fa231f2e29..db5b2595f9a5 100644
--- a/cmdbuf.c
+++ b/cmdbuf.c
@@ -40,7 +40,7 @@ static int in_completion = 0;
static char *tk_text;
static char *tk_original;
static char *tk_ipoint;
-static char *tk_trial;
+static char *tk_trial = NULL;
static struct textlist tk_tlist;
#endif
@@ -323,8 +323,8 @@ cmd_home()
static void
cmd_lshift()
{
- constant char *s;
- constant char *save_cp;
+ char *s;
+ char *save_cp;
int cols;
/*
@@ -342,7 +342,7 @@ cmd_lshift()
while (*s != '\0')
{
int width;
- constant char *ns = s;
+ char *ns = s;
cmd_step_right(&ns, &width, NULL);
if (width > 0)
break;
@@ -361,8 +361,8 @@ cmd_lshift()
static void
cmd_rshift()
{
- constant char *s;
- constant char *save_cp;
+ char *s;
+ char *save_cp;
int cols;
/*
@@ -427,8 +427,9 @@ cmd_right()
cmd_left()
{
char *ncp;
- int width, bswidth;
-
+ int width = 0;
+ int bswidth = 0;
+
if (cp <= cmdbuf)
{
/* Already at the beginning of the line */
@@ -1223,6 +1224,13 @@ cmd_char(c)
*cmd_mbc_buf = c;
if (IS_ASCII_OCTET(c))
cmd_mbc_buf_len = 1;
+#if MSDOS_COMPILER || OS2
+ else if (c == (unsigned char) '\340' && IS_ASCII_OCTET(peekcc()))
+ {
+ /* Assume a special key. */
+ cmd_mbc_buf_len = 1;
+ }
+#endif
else if (IS_UTF8_LEAD(c))
{
cmd_mbc_buf_len = utf_len(c);
diff --git a/command.c b/command.c
index 56d22c688361..332d23c4dd14 100644
--- a/command.c
+++ b/command.c
@@ -26,6 +26,7 @@ extern int quit_if_one_screen;
extern int squished;
extern int sc_width;
extern int sc_height;
+extern char *kent;
extern int swindow;
extern int jump_sline;
extern int quitting;
@@ -36,9 +37,11 @@ extern int secure;
extern int hshift;
extern int bs_mode;
extern int show_attn;
+extern int status_col;
extern POSITION highest_hilite;
+extern POSITION start_attnpos;
+extern POSITION end_attnpos;
extern char *every_first_cmd;
-extern char *curr_altfilename;
extern char version[];
extern struct scrpos initial_scrpos;
extern IFILE curr_ifile;
@@ -55,7 +58,6 @@ extern int screen_trashed; /* The screen has been overwritten */
extern int shift_count;
extern int oldbot;
extern int forw_prompt;
-extern int same_pos_bell;
#if SHELL_ESCAPE
static char *shellcmd = NULL; /* For holding last shell command for "!!" */
@@ -75,10 +77,10 @@ static int save_bs_mode;
static char pipec;
#endif
+/* Stack of ungotten chars (via ungetcc) */
struct ungot {
struct ungot *ug_next;
- char ug_char;
- char ug_end_command;
+ LWCHAR ug_char;
};
static struct ungot* ungot = NULL;
@@ -92,9 +94,7 @@ static void multi_search();
static void
cmd_exec()
{
-#if HILITE_SEARCH
- clear_attn();
-#endif
+ clear_attn();
clear_bot();
flush();
}
@@ -301,11 +301,21 @@ is_erase_char(c)
}
/*
+ * Is a character a carriage return or newline?
+ */
+ static int
+is_newline_char(c)
+ int c;
+{
+ return (c == '\n' || c == '\r');
+}
+
+/*
* Handle the first char of an option (after the initial dash).
*/
static int
mca_opt_first_char(c)
- int c;
+ int c;
{
int flag = (optflag & ~OPT_NO_PROMPT);
if (flag == OPT_NO_TOGGLE)
@@ -425,7 +435,7 @@ mca_opt_char(c)
if (optgetname)
{
/* We're getting a long option name. */
- if (c != '\n' && c != '\r')
+ if (!is_newline_char(c))
return (mca_opt_nonfirst_char(c));
if (curropt == NULL)
{
@@ -589,7 +599,7 @@ mca_char(c)
/*
* The multichar command is terminated by a newline.
*/
- if (c == '\n' || c == '\r')
+ if (is_newline_char(c))
{
/*
* Execute the command.
@@ -687,7 +697,7 @@ prompt()
{
constant char *p;
- if (ungot != NULL && !ungot->ug_end_command)
+ if (ungot != NULL && ungot->ug_char != CHAR_END_COMMAND)
{
/*
* No prompt necessary if commands are from
@@ -769,74 +779,122 @@ dispversion()
}
/*
+ * Return a character to complete a partial command, if possible.
+ */
+ static LWCHAR
+getcc_end_command()
+{
+ switch (mca)
+ {
+ case A_DIGIT:
+ /* We have a number but no command. Treat as #g. */
+ return ('g');
+ case A_F_SEARCH:
+ case A_B_SEARCH:
+ /* We have "/string" but no newline. Add the \n. */
+ return ('\n');
+ default:
+ /* Some other incomplete command. Let user complete it. */
+ return (getchr());
+ }
+}
+
+/*
* Get command character.
* The character normally comes from the keyboard,
* but may come from ungotten characters
* (characters previously given to ungetcc or ungetsc).
*/
- public int
-getcc()
+ static LWCHAR
+getccu()
{
+ LWCHAR c;
if (ungot == NULL)
{
- /*
- * Normal case: no ungotten chars, so get one from the user.
- */
- return (getchr());
- }
-
- /*
- * Return the next ungotten char.
- */
+ /* Normal case: no ungotten chars.
+ * Get char from the user. */
+ c = getchr();
+ } else
{
+ /* Ungotten chars available:
+ * Take the top of stack (most recent). */
struct ungot *ug = ungot;
- char c = ug->ug_char;
- int end_command = ug->ug_end_command;
+ c = ug->ug_char;
ungot = ug->ug_next;
free(ug);
- if (end_command)
- {
- /*
- * Command is incomplete, so try to complete it.
- */
- switch (mca)
- {
- case A_DIGIT:
- /*
- * We have a number but no command. Treat as #g.
- */
- return ('g');
- case A_F_SEARCH:
- case A_B_SEARCH:
- /*
- * We have "/string" but no newline. Add the \n.
- */
- return ('\n');
+ if (c == CHAR_END_COMMAND)
+ c = getcc_end_command();
+ }
+ return (c);
+}
- default:
- /*
- * Some other incomplete command. Let user complete it.
- */
- return (getchr());
- }
+/*
+ * Get a command character, but if we receive the orig sequence,
+ * convert it to the repl sequence.
+ */
+ static LWCHAR
+getcc_repl(orig, repl, gr_getc, gr_ungetc)
+ char const* orig;
+ char const* repl;
+ LWCHAR (*gr_getc)(VOID_PARAM);
+ void (*gr_ungetc)(LWCHAR);
+{
+ LWCHAR c;
+ LWCHAR keys[16];
+ int ki = 0;
+
+ c = (*gr_getc)();
+ if (orig == NULL || orig[0] == '\0')
+ return c;
+ for (;;)
+ {
+ keys[ki] = c;
+ if (c != orig[ki] || ki >= sizeof(keys)-1)
+ {
+ /* This is not orig we have been receiving.
+ * If we have stashed chars in keys[],
+ * unget them and return the first one. */
+ while (ki > 0)
+ (*gr_ungetc)(keys[ki--]);
+ return keys[0];
+ }
+ if (orig[++ki] == '\0')
+ {
+ /* We've received the full orig sequence.
+ * Return the repl sequence. */
+ ki = strlen(repl)-1;
+ while (ki > 0)
+ (*gr_ungetc)(repl[ki--]);
+ return repl[0];
}
- return (c);
+ /* We've received a partial orig sequence (ki chars of it).
+ * Get next char and see if it continues to match orig. */
+ c = (*gr_getc)();
}
}
/*
+ * Get command character.
+ */
+ public int
+getcc()
+{
+ /* Replace kent (keypad Enter) with a newline. */
+ return getcc_repl(kent, "\n", getccu, ungetcc);
+}
+
+/*
* "Unget" a command character.
* The next getcc() will return this character.
*/
public void
ungetcc(c)
- int c;
+ LWCHAR c;
{
struct ungot *ug = (struct ungot *) ecalloc(1, sizeof(struct ungot));
- ug->ug_char = (char) c;
- ug->ug_end_command = (c == CHAR_END_COMMAND);
+ ug->ug_char = c;
ug->ug_next = ungot;
ungot = ug;
}
@@ -856,6 +914,17 @@ ungetsc(s)
}
/*
+ * Peek the next command character, without consuming it.
+ */
+ public LWCHAR
+peekcc()
+{
+ LWCHAR c = getcc();
+ ungetcc(c);
+ return c;
+}
+
+/*
* Search for a pattern, possibly in multiple files.
* If SRCH_FIRST_FILE is set, begin searching at the first file.
* If SRCH_PAST_EOF is set, continue the search thru multiple files.
@@ -1471,6 +1540,9 @@ commands()
break;
case A_UNDO_SEARCH:
+ /*
+ * Clear search string highlighting.
+ */
undo_search();
break;
@@ -1489,60 +1561,54 @@ commands()
break;
case A_EXAMINE:
-#if EXAMINE
/*
* Edit a new file. Get the filename.
*/
- if (secure)
+#if EXAMINE
+ if (!secure)
{
- error("Command not available", NULL_PARG);
- break;
+ start_mca(A_EXAMINE, "Examine: ", ml_examine, 0);
+ c = getcc();
+ goto again;
}
- start_mca(A_EXAMINE, "Examine: ", ml_examine, 0);
- c = getcc();
- goto again;
-#else
+#endif
error("Command not available", NULL_PARG);
break;
-#endif
case A_VISUAL:
/*
* Invoke an editor on the input file.
*/
#if EDITOR
- if (secure)
+ if (!secure)
{
- error("Command not available", NULL_PARG);
- break;
- }
- if (ch_getflags() & CH_HELPFILE)
- break;
- if (strcmp(get_filename(curr_ifile), "-") == 0)
- {
- error("Cannot edit standard input", NULL_PARG);
+ if (ch_getflags() & CH_HELPFILE)
+ break;
+ if (strcmp(get_filename(curr_ifile), "-") == 0)
+ {
+ error("Cannot edit standard input", NULL_PARG);
+ break;
+ }
+ if (get_altfilename(curr_ifile) != NULL)
+ {
+ error("WARNING: This file was viewed via LESSOPEN",
+ NULL_PARG);
+ }
+ start_mca(A_SHELL, "!", ml_shell, 0);
+ /*
+ * Expand the editor prototype string
+ * and pass it to the system to execute.
+ * (Make sure the screen is displayed so the
+ * expansion of "+%lm" works.)
+ */
+ make_display();
+ cmd_exec();
+ lsystem(pr_expand(editproto, 0), (char*)NULL);
break;
}
- if (curr_altfilename != NULL)
- {
- error("WARNING: This file was viewed via LESSOPEN",
- NULL_PARG);
- }
- start_mca(A_SHELL, "!", ml_shell, 0);
- /*
- * Expand the editor prototype string
- * and pass it to the system to execute.
- * (Make sure the screen is displayed so the
- * expansion of "+%lm" works.)
- */
- make_display();
- cmd_exec();
- lsystem(pr_expand(editproto, 0), (char*)NULL);
- break;
-#else
+#endif
error("Command not available", NULL_PARG);
break;
-#endif
case A_NEXT_FILE:
/*
@@ -1588,6 +1654,9 @@ commands()
break;
case A_NEXT_TAG:
+ /*
+ * Jump to the next tag in the current tag list.
+ */
#if TAGS
if (number <= 0)
number = 1;
@@ -1597,6 +1666,7 @@ commands()
error("No next tag", NULL_PARG);
break;
}
+ cmd_exec();
if (edit(tagfile) == 0)
{
POSITION pos = tagsearch();
@@ -1609,6 +1679,9 @@ commands()
break;
case A_PREV_TAG:
+ /*
+ * Jump to the previous tag in the current tag list.
+ */
#if TAGS
if (number <= 0)
number = 1;
@@ -1618,6 +1691,7 @@ commands()
error("No previous tag", NULL_PARG);
break;
}
+ cmd_exec();
if (edit(tagfile) == 0)
{
POSITION pos = tagsearch();
@@ -1640,6 +1714,9 @@ commands()
break;
case A_REMOVE_FILE:
+ /*
+ * Remove a file from the input file list.
+ */
if (ch_getflags() & CH_HELPFILE)
break;
old_ifile = curr_ifile;
@@ -1658,6 +1735,9 @@ commands()
break;
case A_OPT_TOGGLE:
+ /*
+ * Change the setting of an option.
+ */
optflag = OPT_TOGGLE;
optgetname = FALSE;
mca_opt_toggle();
@@ -1666,7 +1746,7 @@ commands()
case A_DISP_OPTION:
/*
- * Report a flag setting.
+ * Report the setting of an option.
*/
optflag = OPT_NO_TOGGLE;
optgetname = FALSE;
@@ -1687,69 +1767,78 @@ commands()
* Shell escape.
*/
#if SHELL_ESCAPE
- if (secure)
+ if (!secure)
{
- error("Command not available", NULL_PARG);
- break;
+ start_mca(A_SHELL, "!", ml_shell, 0);
+ c = getcc();
+ goto again;
}
- start_mca(A_SHELL, "!", ml_shell, 0);
- c = getcc();
- goto again;
-#else
+#endif
error("Command not available", NULL_PARG);
break;
-#endif
case A_SETMARK:
+ case A_SETMARKBOT:
/*
* Set a mark.
*/
if (ch_getflags() & CH_HELPFILE)
break;
- start_mca(A_SETMARK, "mark: ", (void*)NULL, 0);
+ start_mca(A_SETMARK, "set mark: ", (void*)NULL, 0);
+ c = getcc();
+ if (is_erase_char(c) || is_newline_char(c))
+ break;
+ setmark(c, action == A_SETMARKBOT ? BOTTOM : TOP);
+ repaint();
+ break;
+
+ case A_CLRMARK:
+ /*
+ * Clear a mark.
+ */
+ start_mca(A_CLRMARK, "clear mark: ", (void*)NULL, 0);
c = getcc();
- if (c == erase_char || c == erase2_char ||
- c == kill_char || c == '\n' || c == '\r')
+ if (is_erase_char(c) || is_newline_char(c))
break;
- setmark(c);
+ clrmark(c);
+ repaint();
break;
case A_GOMARK:
/*
- * Go to a mark.
+ * Jump to a marked position.
*/
start_mca(A_GOMARK, "goto mark: ", (void*)NULL, 0);
c = getcc();
- if (c == erase_char || c == erase2_char ||
- c == kill_char || c == '\n' || c == '\r')
+ if (is_erase_char(c) || is_newline_char(c))
break;
cmd_exec();
gomark(c);
break;
case A_PIPE:
+ /*
+ * Write part of the input to a pipe to a shell command.
+ */
#if PIPEC
- if (secure)
+ if (!secure)
{
- error("Command not available", NULL_PARG);
- break;
+ start_mca(A_PIPE, "|mark: ", (void*)NULL, 0);
+ c = getcc();
+ if (is_erase_char(c))
+ break;
+ if (is_newline_char(c))
+ c = '.';
+ if (badmark(c))
+ break;
+ pipec = c;
+ start_mca(A_PIPE, "!", ml_shell, 0);
+ c = getcc();
+ goto again;
}
- start_mca(A_PIPE, "|mark: ", (void*)NULL, 0);
- c = getcc();
- if (c == erase_char || c == erase2_char || c == kill_char)
- break;
- if (c == '\n' || c == '\r')
- c = '.';
- if (badmark(c))
- break;
- pipec = c;
- start_mca(A_PIPE, "!", ml_shell, 0);
- c = getcc();
- goto again;
-#else
+#endif
error("Command not available", NULL_PARG);
break;
-#endif
case A_B_BRACKET:
case A_F_BRACKET:
@@ -1758,6 +1847,9 @@ commands()
goto again;
case A_LSHIFT:
+ /*
+ * Shift view left.
+ */
if (number > 0)
shift_count = number;
else
@@ -1770,6 +1862,9 @@ commands()
break;
case A_RSHIFT:
+ /*
+ * Shift view right.
+ */
if (number > 0)
shift_count = number;
else
@@ -1780,11 +1875,17 @@ commands()
break;
case A_LLSHIFT:
+ /*
+ * Shift view left to margin.
+ */
hshift = 0;
screen_trashed = 1;
break;
case A_RRSHIFT:
+ /*
+ * Shift view right to view rightmost char on screen.
+ */
hshift = rrshift();
screen_trashed = 1;
break;
diff --git a/compose.uni b/compose.uni
index e3e1fa4017eb..2a4b18025259 100644
--- a/compose.uni
+++ b/compose.uni
@@ -1,4 +1,5 @@
-/* Generated by "./mkutable -f2 Mn Me -- unicode/UnicodeData.txt" on Tue Sep 20 10:51:43 PDT 2016 */
+/* Generated by "./mkutable -f2 Mn Me Cf -- unicode/UnicodeData.txt" on Tue Jul 25 09:04:35 PDT 2017 */
+ { 0x00ad, 0x00ad }, /* Cf */
{ 0x0300, 0x036f }, /* Mn */
{ 0x0483, 0x0487 }, /* Mn */
{ 0x0488, 0x0489 }, /* Me */
@@ -7,13 +8,17 @@
{ 0x05c1, 0x05c2 }, /* Mn */
{ 0x05c4, 0x05c5 }, /* Mn */
{ 0x05c7, 0x05c7 }, /* Mn */
+ { 0x0600, 0x0605 }, /* Cf */
{ 0x0610, 0x061a }, /* Mn */
+ { 0x061c, 0x061c }, /* Cf */
{ 0x064b, 0x065f }, /* Mn */
{ 0x0670, 0x0670 }, /* Mn */
{ 0x06d6, 0x06dc }, /* Mn */
+ { 0x06dd, 0x06dd }, /* Cf */
{ 0x06df, 0x06e4 }, /* Mn */
{ 0x06e7, 0x06e8 }, /* Mn */
{ 0x06ea, 0x06ed }, /* Mn */
+ { 0x070f, 0x070f }, /* Cf */
{ 0x0711, 0x0711 }, /* Mn */
{ 0x0730, 0x074a }, /* Mn */
{ 0x07a6, 0x07b0 }, /* Mn */
@@ -24,6 +29,7 @@
{ 0x0829, 0x082d }, /* Mn */
{ 0x0859, 0x085b }, /* Mn */
{ 0x08d4, 0x08e1 }, /* Mn */
+ { 0x08e2, 0x08e2 }, /* Cf */
{ 0x08e3, 0x0902 }, /* Mn */
{ 0x093a, 0x093a }, /* Mn */
{ 0x093c, 0x093c }, /* Mn */
@@ -50,6 +56,7 @@
{ 0x0ac7, 0x0ac8 }, /* Mn */
{ 0x0acd, 0x0acd }, /* Mn */
{ 0x0ae2, 0x0ae3 }, /* Mn */
+ { 0x0afa, 0x0aff }, /* Mn */
{ 0x0b01, 0x0b01 }, /* Mn */
{ 0x0b3c, 0x0b3c }, /* Mn */
{ 0x0b3f, 0x0b3f }, /* Mn */
@@ -72,7 +79,8 @@
{ 0x0cc6, 0x0cc6 }, /* Mn */
{ 0x0ccc, 0x0ccd }, /* Mn */
{ 0x0ce2, 0x0ce3 }, /* Mn */
- { 0x0d01, 0x0d01 }, /* Mn */
+ { 0x0d00, 0x0d01 }, /* Mn */
+ { 0x0d3b, 0x0d3c }, /* Mn */
{ 0x0d41, 0x0d44 }, /* Mn */
{ 0x0d4d, 0x0d4d }, /* Mn */
{ 0x0d62, 0x0d63 }, /* Mn */
@@ -118,6 +126,7 @@
{ 0x17c9, 0x17d3 }, /* Mn */
{ 0x17dd, 0x17dd }, /* Mn */
{ 0x180b, 0x180d }, /* Mn */
+ { 0x180e, 0x180e }, /* Cf */
{ 0x1885, 0x1886 }, /* Mn */
{ 0x18a9, 0x18a9 }, /* Mn */
{ 0x1920, 0x1922 }, /* Mn */
@@ -157,8 +166,12 @@
{ 0x1ced, 0x1ced }, /* Mn */
{ 0x1cf4, 0x1cf4 }, /* Mn */
{ 0x1cf8, 0x1cf9 }, /* Mn */
- { 0x1dc0, 0x1df5 }, /* Mn */
+ { 0x1dc0, 0x1df9 }, /* Mn */
{ 0x1dfb, 0x1dff }, /* Mn */
+ { 0x200b, 0x200f }, /* Cf */
+ { 0x202a, 0x202e }, /* Cf */
+ { 0x2060, 0x2064 }, /* Cf */
+ { 0x2066, 0x206f }, /* Cf */
{ 0x20d0, 0x20dc }, /* Mn */
{ 0x20dd, 0x20e0 }, /* Me */
{ 0x20e1, 0x20e1 }, /* Mn */
@@ -206,6 +219,8 @@
{ 0xfb1e, 0xfb1e }, /* Mn */
{ 0xfe00, 0xfe0f }, /* Mn */
{ 0xfe20, 0xfe2f }, /* Mn */
+ { 0xfeff, 0xfeff }, /* Cf */
+ { 0xfff9, 0xfffb }, /* Cf */
{ 0x101fd, 0x101fd }, /* Mn */
{ 0x102e0, 0x102e0 }, /* Mn */
{ 0x10376, 0x1037a }, /* Mn */
@@ -220,6 +235,7 @@
{ 0x1107f, 0x11081 }, /* Mn */
{ 0x110b3, 0x110b6 }, /* Mn */
{ 0x110b9, 0x110ba }, /* Mn */
+ { 0x110bd, 0x110bd }, /* Cf */
{ 0x11100, 0x11102 }, /* Mn */
{ 0x11127, 0x1112b }, /* Mn */
{ 0x1112d, 0x11134 }, /* Mn */
@@ -259,6 +275,15 @@
{ 0x1171d, 0x1171f }, /* Mn */
{ 0x11722, 0x11725 }, /* Mn */
{ 0x11727, 0x1172b }, /* Mn */
+ { 0x11a01, 0x11a06 }, /* Mn */
+ { 0x11a09, 0x11a0a }, /* Mn */
+ { 0x11a33, 0x11a38 }, /* Mn */
+ { 0x11a3b, 0x11a3e }, /* Mn */
+ { 0x11a47, 0x11a47 }, /* Mn */
+ { 0x11a51, 0x11a56 }, /* Mn */
+ { 0x11a59, 0x11a5b }, /* Mn */
+ { 0x11a8a, 0x11a96 }, /* Mn */
+ { 0x11a98, 0x11a99 }, /* Mn */
{ 0x11c30, 0x11c36 }, /* Mn */
{ 0x11c38, 0x11c3d }, /* Mn */
{ 0x11c3f, 0x11c3f }, /* Mn */
@@ -266,11 +291,18 @@
{ 0x11caa, 0x11cb0 }, /* Mn */
{ 0x11cb2, 0x11cb3 }, /* Mn */
{ 0x11cb5, 0x11cb6 }, /* Mn */
+ { 0x11d31, 0x11d36 }, /* Mn */
+ { 0x11d3a, 0x11d3a }, /* Mn */
+ { 0x11d3c, 0x11d3d }, /* Mn */
+ { 0x11d3f, 0x11d45 }, /* Mn */
+ { 0x11d47, 0x11d47 }, /* Mn */
{ 0x16af0, 0x16af4 }, /* Mn */
{ 0x16b30, 0x16b36 }, /* Mn */
{ 0x16f8f, 0x16f92 }, /* Mn */
{ 0x1bc9d, 0x1bc9e }, /* Mn */
+ { 0x1bca0, 0x1bca3 }, /* Cf */
{ 0x1d167, 0x1d169 }, /* Mn */
+ { 0x1d173, 0x1d17a }, /* Cf */
{ 0x1d17b, 0x1d182 }, /* Mn */
{ 0x1d185, 0x1d18b }, /* Mn */
{ 0x1d1aa, 0x1d1ad }, /* Mn */
@@ -288,4 +320,6 @@
{ 0x1e026, 0x1e02a }, /* Mn */
{ 0x1e8d0, 0x1e8d6 }, /* Mn */
{ 0x1e944, 0x1e94a }, /* Mn */
+ { 0xe0001, 0xe0001 }, /* Cf */
+ { 0xe0020, 0xe007f }, /* Cf */
{ 0xe0100, 0xe01ef }, /* Mn */
diff --git a/configure.ac b/configure.ac
index 383f840c5335..3616ef035f71 100644
--- a/configure.ac
+++ b/configure.ac
@@ -659,7 +659,7 @@ AH_TOP([
/*
* Default shell metacharacters and meta-escape character.
*/
-#define DEF_METACHARS "; *?\t\n'\"()<>[]|&^`#\\$%=~"
+#define DEF_METACHARS "; *?\t\n'\"()<>[]|&^`#\\$%=~{},"
#define DEF_METAESCAPE "\\"
/*
diff --git a/cvt.c b/cvt.c
index 54473e0c0863..3a779490439d 100644
--- a/cvt.c
+++ b/cvt.c
@@ -83,7 +83,7 @@ cvt_text(odst, osrc, chpos, lenp, ops)
/* Delete backspace and preceding char. */
do {
dst--;
- } while (dst > odst &&
+ } while (dst > odst && utf_mode &&
!IS_ASCII_OCTET(*dst) && !IS_UTF8_LEAD(*dst));
} else if ((ops & CVT_ANSI) && IS_CSI_START(ch))
{
diff --git a/decode.c b/decode.c
index 851672a1b0df..80f47f99d155 100644
--- a/decode.c
+++ b/decode.c
@@ -140,6 +140,8 @@ static unsigned char cmdtable[] =
ESC,'N',0, A_T_REVERSE_SEARCH,
'&',0, A_FILTER,
'm',0, A_SETMARK,
+ 'M',0, A_SETMARKBOT,
+ ESC,'m',0, A_CLRMARK,
'\'',0, A_GOMARK,
CONTROL('X'),CONTROL('X'),0, A_GOMARK,
'E',0, A_EXAMINE,
@@ -291,6 +293,33 @@ expand_special_keys(table, len)
}
/*
+ * Expand special key abbreviations in a list of command tables.
+ */
+ static void
+expand_cmd_table(tlist)
+ struct tablelist *tlist;
+{
+ struct tablelist *t;
+ for (t = tlist; t != NULL; t = t->t_next)
+ {
+ expand_special_keys(t->t_start, t->t_end - t->t_start);
+ }
+}
+
+/*
+ * Expand special key abbreviations in all command tables.
+ */
+ public void
+expand_cmd_tables()
+{
+ expand_cmd_table(list_fcmd_tables);
+ expand_cmd_table(list_ecmd_tables);
+ expand_cmd_table(list_var_tables);
+ expand_cmd_table(list_sysvar_tables);
+}
+
+
+/*
* Initialize the command lists.
*/
public void
@@ -342,7 +371,6 @@ add_cmd_table(tlist, buf, len)
{
return (-1);
}
- expand_special_keys(buf, len);
t->t_start = buf;
t->t_end = buf + len;
t->t_next = *tlist;
@@ -661,9 +689,7 @@ lesskey(filename, sysvar)
/*
* Try to open the lesskey file.
*/
- filename = shell_unquote(filename);
f = open(filename, OPEN_READ);
- free(filename);
if (f < 0)
return (1);
diff --git a/defines.h.in b/defines.h.in
index 161f928e1027..874c15057a2b 100644
--- a/defines.h.in
+++ b/defines.h.in
@@ -167,7 +167,7 @@
/*
* Default shell metacharacters and meta-escape character.
*/
-#define DEF_METACHARS "; *?\t\n'\"()<>[]|&^`#\\$%=~"
+#define DEF_METACHARS "; *?\t\n'\"()<>[]|&^`#\\$%=~{},"
#define DEF_METAESCAPE "\\"
/*
diff --git a/edit.c b/edit.c
index f2a74a049200..7dc80bbd6453 100644
--- a/edit.c
+++ b/edit.c
@@ -9,9 +9,13 @@
#include "less.h"
+#include "position.h"
#if HAVE_STAT
#include <sys/stat.h>
#endif
+#if OS2
+#include <signal.h>
+#endif
public int fd0 = 0;
@@ -43,9 +47,6 @@ public dev_t curr_dev;
public ino_t curr_ino;
#endif
-char *curr_altfilename = NULL;
-static void *curr_altpipe;
-
/*
* Textlist functions deal with a list of words separated by spaces.
@@ -149,12 +150,33 @@ back_textlist(tlist, prev)
}
/*
+ * Close a pipe opened via popen.
+ */
+ static void
+close_pipe(FILE *pipefd)
+{
+ if (pipefd == NULL)
+ return;
+#if OS2
+ /*
+ * The pclose function of OS/2 emx sometimes fails.
+ * Send SIGINT to the piped process before closing it.
+ */
+ kill(pipefd->_pid, SIGINT);
+#endif
+ pclose(pipefd);
+}
+
+/*
* Close the current input file.
*/
static void
close_file()
{
struct scrpos scrpos;
+ int chflags;
+ FILE *altpipe;
+ char *altfilename;
if (curr_ifile == NULL_IFILE)
return;
@@ -163,7 +185,7 @@ close_file()
* Save the current position so that we can return to
* the same position if we edit this file again.
*/
- get_scrpos(&scrpos);
+ get_scrpos(&scrpos, TOP);
if (scrpos.pos != NULL_POSITION)
{
store_pos(curr_ifile, &scrpos);
@@ -172,17 +194,23 @@ close_file()
/*
* Close the file descriptor, unless it is a pipe.
*/
+ chflags = ch_getflags();
ch_close();
/*
* If we opened a file using an alternate name,
* do special stuff to close it.
*/
- if (curr_altfilename != NULL)
+ altfilename = get_altfilename(curr_ifile);
+ if (altfilename != NULL)
{
- close_altfile(curr_altfilename, get_filename(curr_ifile),
- curr_altpipe);
- free(curr_altfilename);
- curr_altfilename = NULL;
+ altpipe = get_altpipe(curr_ifile);
+ if (altpipe != NULL && !(chflags & CH_KEEPOPEN))
+ {
+ close_pipe(altpipe);
+ set_altpipe(curr_ifile, NULL);
+ }
+ close_altfile(altfilename, get_filename(curr_ifile));
+ set_altfilename(curr_ifile, NULL);
}
curr_ifile = NULL_IFILE;
#if HAVE_STAT_INO
@@ -218,9 +246,8 @@ edit_ifile(ifile)
int chflags;
char *filename;
char *open_filename;
- char *qopen_filename;
char *alt_filename;
- void *alt_pipe;
+ void *altpipe;
IFILE was_curr_ifile;
PARG parg;
@@ -270,107 +297,129 @@ edit_ifile(ifile)
}
filename = save(get_filename(ifile));
+
/*
* See if LESSOPEN specifies an "alternate" file to open.
*/
- alt_pipe = NULL;
- alt_filename = open_altfile(filename, &f, &alt_pipe);
- open_filename = (alt_filename != NULL) ? alt_filename : filename;
- qopen_filename = shell_unquote(open_filename);
-
- chflags = 0;
- if (alt_pipe != NULL)
+ altpipe = get_altpipe(ifile);
+ if (altpipe != NULL)
{
/*
- * The alternate "file" is actually a pipe.
- * f has already been set to the file descriptor of the pipe
- * in the call to open_altfile above.
- * Keep the file descriptor open because it was opened
- * via popen(), and pclose() wants to close it.
+ * File is already open.
+ * chflags and f are not used by ch_init if ifile has
+ * filestate which should be the case if we're here.
+ * Set them here to avoid uninitialized variable warnings.
*/
- chflags |= CH_POPENED;
- } else if (strcmp(open_filename, "-") == 0)
- {
- /*
- * Use standard input.
- * Keep the file descriptor open because we can't reopen it.
- */
- f = fd0;
- chflags |= CH_KEEPOPEN;
- /*
- * Must switch stdin to BINARY mode.
- */
- SET_BINARY(f);
-#if MSDOS_COMPILER==DJGPPC
- /*
- * Setting stdin to binary by default causes
- * Ctrl-C to not raise SIGINT. We must undo
- * that side-effect.
- */
- __djgpp_set_ctrl_c(1);
-#endif
- } else if (strcmp(open_filename, FAKE_EMPTYFILE) == 0)
- {
+ chflags = 0;
f = -1;
- chflags |= CH_NODATA;
- } else if (strcmp(open_filename, FAKE_HELPFILE) == 0)
- {
- f = -1;
- chflags |= CH_HELPFILE;
- } else if ((parg.p_string = bad_file(open_filename)) != NULL)
+ alt_filename = get_altfilename(ifile);
+ open_filename = (alt_filename != NULL) ? alt_filename : filename;
+ } else
{
- /*
- * It looks like a bad file. Don't try to open it.
- */
- error("%s", &parg);
- free(parg.p_string);
- err1:
- if (alt_filename != NULL)
+ if (strcmp(filename, FAKE_HELPFILE) == 0 ||
+ strcmp(filename, FAKE_EMPTYFILE) == 0)
+ alt_filename = NULL;
+ else
+ alt_filename = open_altfile(filename, &f, &altpipe);
+
+ open_filename = (alt_filename != NULL) ? alt_filename : filename;
+
+ chflags = 0;
+ if (altpipe != NULL)
{
- close_altfile(alt_filename, filename, alt_pipe);
- free(alt_filename);
- }
- del_ifile(ifile);
- free(qopen_filename);
- free(filename);
- /*
- * Re-open the current file.
- */
- if (was_curr_ifile == ifile)
+ /*
+ * The alternate "file" is actually a pipe.
+ * f has already been set to the file descriptor of the pipe
+ * in the call to open_altfile above.
+ * Keep the file descriptor open because it was opened
+ * via popen(), and pclose() wants to close it.
+ */
+ chflags |= CH_POPENED;
+ if (strcmp(filename, "-") == 0)
+ chflags |= CH_KEEPOPEN;
+ } else if (strcmp(filename, "-") == 0)
{
+ /*
+ * Use standard input.
+ * Keep the file descriptor open because we can't reopen it.
+ */
+ f = fd0;
+ chflags |= CH_KEEPOPEN;
/*
- * Whoops. The "current" ifile is the one we just deleted.
- * Just give up.
+ * Must switch stdin to BINARY mode.
*/
- quit(QUIT_ERROR);
- }
- reedit_ifile(was_curr_ifile);
- return (1);
- } else if ((f = open(qopen_filename, OPEN_READ)) < 0)
- {
- /*
- * Got an error trying to open it.
- */
- parg.p_string = errno_message(filename);
- error("%s", &parg);
- free(parg.p_string);
- goto err1;
- } else
- {
- chflags |= CH_CANSEEK;
- if (!force_open && !opened(ifile) && bin_file(f))
+ SET_BINARY(f);
+#if MSDOS_COMPILER==DJGPPC
+ /*
+ * Setting stdin to binary by default causes
+ * Ctrl-C to not raise SIGINT. We must undo
+ * that side-effect.
+ */
+ __djgpp_set_ctrl_c(1);
+#endif
+ } else if (strcmp(open_filename, FAKE_EMPTYFILE) == 0)
+ {
+ f = -1;
+ chflags |= CH_NODATA;
+ } else if (strcmp(open_filename, FAKE_HELPFILE) == 0)
+ {
+ f = -1;
+ chflags |= CH_HELPFILE;
+ } else if ((parg.p_string = bad_file(open_filename)) != NULL)
{
/*
- * Looks like a binary file.
- * Ask user if we should proceed.
+ * It looks like a bad file. Don't try to open it.
*/
- parg.p_string = filename;
- answer = query("\"%s\" may be a binary file. See it anyway? ",
- &parg);
- if (answer != 'y' && answer != 'Y')
+ error("%s", &parg);
+ free(parg.p_string);
+ err1:
+ if (alt_filename != NULL)
{
- close(f);
+ close_pipe(altpipe);
+ close_altfile(alt_filename, filename);
+ free(alt_filename);
+ }
+ del_ifile(ifile);
+ free(filename);
+ /*
+ * Re-open the current file.
+ */
+ if (was_curr_ifile == ifile)
+ {
+ /*
+ * Whoops. The "current" ifile is the one we just deleted.
+ * Just give up.
+ */
+ quit(QUIT_ERROR);
+ }
+ reedit_ifile(was_curr_ifile);
+ return (1);
+ } else if ((f = open(open_filename, OPEN_READ)) < 0)
+ {
+ /*
+ * Got an error trying to open it.
+ */
+ parg.p_string = errno_message(filename);
+ error("%s", &parg);
+ free(parg.p_string);
goto err1;
+ } else
+ {
+ chflags |= CH_CANSEEK;
+ if (!force_open && !opened(ifile) && bin_file(f))
+ {
+ /*
+ * Looks like a binary file.
+ * Ask user if we should proceed.
+ */
+ parg.p_string = filename;
+ answer = query("\"%s\" may be a binary file. See it anyway? ",
+ &parg);
+ if (answer != 'y' && answer != 'Y')
+ {
+ close(f);
+ goto err1;
+ }
}
}
}
@@ -385,8 +434,8 @@ edit_ifile(ifile)
unsave_ifile(was_curr_ifile);
}
curr_ifile = ifile;
- curr_altfilename = alt_filename;
- curr_altpipe = alt_pipe;
+ set_altfilename(curr_ifile, alt_filename);
+ set_altpipe(curr_ifile, altpipe);
set_open(curr_ifile); /* File has been opened */
get_pos(curr_ifile, &initial_scrpos);
new_file = TRUE;
@@ -400,9 +449,10 @@ edit_ifile(ifile)
#endif
#if HAVE_STAT_INO
/* Remember the i-number and device of the opened file. */
+ if (strcmp(open_filename, "-") != 0)
{
struct stat statbuf;
- int r = stat(qopen_filename, &statbuf);
+ int r = stat(open_filename, &statbuf);
if (r == 0)
{
curr_ino = statbuf.st_ino;
@@ -417,7 +467,6 @@ edit_ifile(ifile)
}
}
- free(qopen_filename);
no_display = !any_display;
flush();
any_display = TRUE;
@@ -468,6 +517,7 @@ edit_list(filelist)
char *filename;
char *gfilelist;
char *gfilename;
+ char *qfilename;
struct textlist tl_files;
struct textlist tl_gfiles;
@@ -489,8 +539,10 @@ edit_list(filelist)
gfilename = NULL;
while ((gfilename = forw_textlist(&tl_gfiles, gfilename)) != NULL)
{
- if (edit(gfilename) == 0 && good_filename == NULL)
+ qfilename = shell_unquote(gfilename);
+ if (edit(qfilename) == 0 && good_filename == NULL)
good_filename = get_filename(curr_ifile);
+ free(qfilename);
}
free(gfilelist);
}
@@ -747,7 +799,6 @@ use_logfile(filename)
/*
* {{ We could use access() here. }}
*/
- filename = shell_unquote(filename);
exists = open(filename, OPEN_READ);
if (exists >= 0)
close(exists);
@@ -816,10 +867,8 @@ loop:
*/
parg.p_string = filename;
error("Cannot write to \"%s\"", &parg);
- free(filename);
return;
}
- free(filename);
SET_BINARY(logfile);
}
diff --git a/filename.c b/filename.c
index a153207ba635..983a02b0e062 100644
--- a/filename.c
+++ b/filename.c
@@ -32,9 +32,6 @@
#include <modes.h>
#endif
#endif
-#if OS2
-#include <signal.h>
-#endif
#if HAVE_STAT
#include <sys/stat.h>
@@ -46,7 +43,6 @@
#endif
#endif
-
extern int force_open;
extern int secure;
extern int use_lessopen;
@@ -226,7 +222,6 @@ dirfile(dirname, filename)
char *filename;
{
char *pathname;
- char *qpathname;
int len;
int f;
@@ -243,8 +238,7 @@ dirfile(dirname, filename)
/*
* Make sure the file exists.
*/
- qpathname = shell_unquote(pathname);
- f = open(qpathname, OPEN_READ);
+ f = open(pathname, OPEN_READ);
if (f < 0)
{
free(pathname);
@@ -253,7 +247,6 @@ dirfile(dirname, filename)
{
close(f);
}
- free(qpathname);
return (pathname);
}
@@ -474,7 +467,7 @@ bin_file(f)
int bin_count = 0;
char data[256];
char* p;
- char* pend;
+ char* edata;
if (!seekable(f))
return (0);
@@ -483,21 +476,19 @@ bin_file(f)
n = read(f, data, sizeof(data));
if (n <= 0)
return (0);
- if (utf_mode)
+ edata = &data[n];
+ for (p = data; p < edata; )
{
- bin_count = utf_bin_count(data, n);
- } else
- {
- pend = &data[n];
- for (p = data; p < pend; )
+ if (utf_mode && !is_utf8_well_formed(p, edata-data))
+ {
+ bin_count++;
+ utf_skip_to_lead(&p, edata);
+ } else
{
- LWCHAR c = step_char(&p, +1, pend);
+ LWCHAR c = step_char(&p, +1, edata);
if (ctldisp == OPT_ONPLUS && IS_CSI_START(c))
- {
- do {
- c = step_char(&p, +1, pend);
- } while (p < pend && is_ansi_middle(c));
- } else if (binary_char(c))
+ skip_ansi(&p, edata);
+ else if (binary_char(c))
bin_count++;
}
}
@@ -632,12 +623,10 @@ lglob(filename)
char *filename;
{
char *gfilename;
- char *ofilename;
- ofilename = fexpand(filename);
+ filename = fexpand(filename);
if (secure)
- return (ofilename);
- filename = shell_unquote(ofilename);
+ return (filename);
#ifdef DECL_GLOB_LIST
{
@@ -652,8 +641,7 @@ lglob(filename)
GLOB_LIST(filename, list);
if (GLOB_LIST_FAILED(list))
{
- free(filename);
- return (ofilename);
+ return (filename);
}
length = 1; /* Room for trailing null byte */
for (SCAN_GLOB_LIST(list, p))
@@ -693,15 +681,14 @@ lglob(filename)
char *p;
int len;
int n;
- char *pathname;
- char *qpathname;
+ char *pfilename;
+ char *qfilename;
DECL_GLOB_NAME(fnd,drive,dir,fname,ext,handle)
GLOB_FIRST_NAME(filename, &fnd, handle);
if (GLOB_FIRST_FAILED(handle))
{
- free(filename);
- return (ofilename);
+ return (filename);
}
_splitpath(filename, drive, dir, fname, ext);
@@ -710,13 +697,13 @@ lglob(filename)
p = gfilename;
do {
n = (int) (strlen(drive) + strlen(dir) + strlen(fnd.GLOB_NAME) + 1);
- pathname = (char *) ecalloc(n, sizeof(char));
- SNPRINTF3(pathname, n, "%s%s%s", drive, dir, fnd.GLOB_NAME);
- qpathname = shell_quote(pathname);
- free(pathname);
- if (qpathname != NULL)
+ pfilename = (char *) ecalloc(n, sizeof(char));
+ SNPRINTF3(pfilename, n, "%s%s%s", drive, dir, fnd.GLOB_NAME);
+ qfilename = shell_quote(pfilename);
+ free(pfilename);
+ if (qfilename != NULL)
{
- n = (int) strlen(qpathname);
+ n = (int) strlen(qfilename);
while (p - gfilename + n + 2 >= len)
{
/*
@@ -731,8 +718,8 @@ lglob(filename)
gfilename = p;
p = gfilename + strlen(gfilename);
}
- strcpy(p, qpathname);
- free(qpathname);
+ strcpy(p, qfilename);
+ free(qfilename);
p += n;
*p++ = ' ';
}
@@ -764,8 +751,7 @@ lglob(filename)
esc = shell_quote(esc);
if (esc == NULL)
{
- free(filename);
- return (ofilename);
+ return (filename);
}
lessecho = lgetenv("LESSECHO");
if (lessecho == NULL || *lessecho == '\0')
@@ -773,13 +759,13 @@ lglob(filename)
/*
* Invoke lessecho, and read its output (a globbed list of filenames).
*/
- len = (int) (strlen(lessecho) + strlen(ofilename) + (7*strlen(metachars())) + 24);
+ 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);
free(esc);
for (s = metachars(); *s != '\0'; s++)
sprintf(cmd + strlen(cmd), "-n0x%x ", *s);
- sprintf(cmd + strlen(cmd), "-- %s", ofilename);
+ sprintf(cmd + strlen(cmd), "-- %s", filename);
fd = shellcmd(cmd);
free(cmd);
if (fd == NULL)
@@ -788,16 +774,14 @@ lglob(filename)
* Cannot create the pipe.
* Just return the original (fexpanded) filename.
*/
- free(filename);
- return (ofilename);
+ return (filename);
}
gfilename = readfd(fd);
pclose(fd);
if (*gfilename == '\0')
{
free(gfilename);
- free(filename);
- return (ofilename);
+ return (save(filename));
}
}
#else
@@ -809,7 +793,6 @@ lglob(filename)
#endif
#endif
free(filename);
- free(ofilename);
return (gfilename);
}
@@ -853,6 +836,7 @@ open_altfile(filename, pf, pfd)
return (NULL);
#else
char *lessopen;
+ char *qfilename;
char *cmd;
int len;
FILE *fd;
@@ -879,24 +863,28 @@ open_altfile(filename, pf, pfd)
returnfd++;
#endif
}
- if (*lessopen == '-') {
+ if (*lessopen == '-')
+ {
/*
* Lessopen preprocessor will accept "-" as a filename.
*/
lessopen++;
- } else {
+ } else
+ {
if (strcmp(filename, "-") == 0)
return (NULL);
}
- if (num_pct_s(lessopen) > 1)
+ if (num_pct_s(lessopen) != 1)
{
- error("Invalid LESSOPEN variable", NULL_PARG);
+ error("LESSOPEN ignored: must contain exactly one %%s", NULL_PARG);
return (NULL);
}
- len = (int) (strlen(lessopen) + strlen(filename) + 2);
+ qfilename = shell_quote(filename);
+ len = (int) (strlen(lessopen) + strlen(qfilename) + 2);
cmd = (char *) ecalloc(len, sizeof(char));
- SNPRINTF1(cmd, len, lessopen, filename);
+ SNPRINTF1(cmd, len, lessopen, qfilename);
+ free(qfilename);
fd = shellcmd(cmd);
free(cmd);
if (fd == NULL)
@@ -909,11 +897,12 @@ open_altfile(filename, pf, pfd)
#if HAVE_FILENO
if (returnfd)
{
- int f;
char c;
+ int f;
/*
- * Read one char to see if the pipe will produce any data.
+ * The first time we open the file, read one char
+ * to see if the pipe will produce any data.
* If it does, push the char back on the pipe.
*/
f = fileno(fd);
@@ -956,10 +945,9 @@ open_altfile(filename, pf, pfd)
* Close a replacement file.
*/
public void
-close_altfile(altfilename, filename, pipefd)
+close_altfile(altfilename, filename)
char *altfilename;
char *filename;
- void *pipefd;
{
#if HAVE_POPEN
char *lessclose;
@@ -969,22 +957,12 @@ close_altfile(altfilename, filename, pipefd)
if (secure)
return;
- if (pipefd != NULL)
- {
-#if OS2
- /*
- * The pclose function of OS/2 emx sometimes fails.
- * Send SIGINT to the piped process before closing it.
- */
- kill(((FILE*)pipefd)->_pid, SIGINT);
-#endif
- pclose((FILE*) pipefd);
- }
+ ch_ungetchar(-1);
if ((lessclose = lgetenv("LESSCLOSE")) == NULL)
return;
if (num_pct_s(lessclose) > 2)
{
- error("Invalid LESSCLOSE variable", NULL_PARG);
+ error("LESSCLOSE ignored; must contain no more than 2 %%s", NULL_PARG);
return;
}
len = (int) (strlen(lessclose) + strlen(filename) + strlen(altfilename) + 2);
@@ -1006,7 +984,6 @@ is_dir(filename)
{
int isdir = 0;
- filename = shell_unquote(filename);
#if HAVE_STAT
{
int r;
@@ -1027,7 +1004,6 @@ is_dir(filename)
}
#endif
#endif
- free(filename);
return (isdir);
}
@@ -1042,7 +1018,6 @@ bad_file(filename)
{
char *m = NULL;
- filename = shell_unquote(filename);
if (!force_open && is_dir(filename))
{
static char is_a_dir[] = " is a directory";
@@ -1074,7 +1049,6 @@ bad_file(filename)
}
#endif
}
- free(filename);
return (m);
}
diff --git a/fmt.uni b/fmt.uni
new file mode 100644
index 000000000000..a0bad7784506
--- /dev/null
+++ b/fmt.uni
@@ -0,0 +1,19 @@
+/* Generated by "./mkutable -f2 Cf -- unicode/UnicodeData.txt" on Sun Nov 12 16:13:49 PST 2017 */
+ { 0x00ad, 0x00ad }, /* Cf */
+ { 0x0600, 0x0605 }, /* Cf */
+ { 0x061c, 0x061c }, /* Cf */
+ { 0x06dd, 0x06dd }, /* Cf */
+ { 0x070f, 0x070f }, /* Cf */
+ { 0x08e2, 0x08e2 }, /* Cf */
+ { 0x180e, 0x180e }, /* Cf */
+ { 0x200b, 0x200f }, /* Cf */
+ { 0x202a, 0x202e }, /* Cf */
+ { 0x2060, 0x2064 }, /* Cf */
+ { 0x2066, 0x206f }, /* Cf */
+ { 0xfeff, 0xfeff }, /* Cf */
+ { 0xfff9, 0xfffb }, /* Cf */
+ { 0x110bd, 0x110bd }, /* Cf */
+ { 0x1bca0, 0x1bca3 }, /* Cf */
+ { 0x1d173, 0x1d17a }, /* Cf */
+ { 0xe0001, 0xe0001 }, /* Cf */
+ { 0xe0020, 0xe007f }, /* Cf */
diff --git a/forwback.c b/forwback.c
index dc6cac98afbb..680fa251b12e 100644
--- a/forwback.c
+++ b/forwback.c
@@ -285,7 +285,7 @@ forw(n, pos, force, only_last, nblank)
forw_prompt = 1;
}
- if (nlines == 0 && same_pos_bell)
+ if (nlines == 0 && !ignore_eoi && same_pos_bell)
eof_bell();
else if (do_repaint)
repaint();
@@ -446,15 +446,15 @@ get_back_scroll()
}
/*
- * Get line count of file up to the screen height + 1 char
+ * Return number of displayable lines in the file.
+ * Stop counting at screen height + 1.
*/
public int
get_line_count()
{
int nlines;
- POSITION pos;
+ POSITION pos = ch_zero();
- pos = ch_zero();
for (nlines = 0; nlines <= sc_height; nlines++)
{
pos = forw_line(pos);
diff --git a/funcs.h b/funcs.h
index 1fe28c849474..d70c359df5a3 100644
--- a/funcs.h
+++ b/funcs.h
@@ -1,300 +1,310 @@
-public char * save LESSPARAMS((constant char *s));
-public VOID_POINTER ecalloc LESSPARAMS((int count, unsigned int size));
-public char * skipsp LESSPARAMS((char *s));
-public int sprefix LESSPARAMS((char *ps, char *s, int uppercase));
-public void quit LESSPARAMS((int status));
-public void raw_mode LESSPARAMS((int on));
-public void scrsize LESSPARAMS((VOID_PARAM));
-public char * special_key_str LESSPARAMS((int key));
-public void get_term LESSPARAMS((VOID_PARAM));
-public void init LESSPARAMS((VOID_PARAM));
-public void deinit LESSPARAMS((VOID_PARAM));
-public void home LESSPARAMS((VOID_PARAM));
-public void add_line LESSPARAMS((VOID_PARAM));
-public void remove_top LESSPARAMS((int n));
-public void win32_scroll_up LESSPARAMS((int n));
-public void lower_left LESSPARAMS((VOID_PARAM));
-public void line_left LESSPARAMS((VOID_PARAM));
-public void check_winch LESSPARAMS((VOID_PARAM));
-public void goto_line LESSPARAMS((int slinenum));
-public void vbell LESSPARAMS((VOID_PARAM));
-public void bell LESSPARAMS((VOID_PARAM));
-public void clear LESSPARAMS((VOID_PARAM));
-public void clear_eol LESSPARAMS((VOID_PARAM));
-public void clear_bot LESSPARAMS((VOID_PARAM));
-public void at_enter LESSPARAMS((int attr));
-public void at_exit LESSPARAMS((VOID_PARAM));
-public void at_switch LESSPARAMS((int attr));
-public int is_at_equiv LESSPARAMS((int attr1, int attr2));
-public int apply_at_specials LESSPARAMS((int attr));
-public void backspace LESSPARAMS((VOID_PARAM));
-public void putbs LESSPARAMS((VOID_PARAM));
-public char WIN32getch LESSPARAMS((int tty));
-public void WIN32setcolors LESSPARAMS((int fg, int bg));
-public void WIN32textout LESSPARAMS((char *text, int len));
-public void match_brac LESSPARAMS((int obrac, int cbrac, int forwdir, int n));
-public void ch_ungetchar LESSPARAMS((int c));
-public void end_logfile LESSPARAMS((VOID_PARAM));
-public void sync_logfile LESSPARAMS((VOID_PARAM));
-public int ch_seek LESSPARAMS((POSITION pos));
-public int ch_end_seek LESSPARAMS((VOID_PARAM));
-public int ch_end_buffer_seek LESSPARAMS((VOID_PARAM));
-public int ch_beg_seek LESSPARAMS((VOID_PARAM));
-public POSITION ch_length LESSPARAMS((VOID_PARAM));
-public POSITION ch_tell LESSPARAMS((VOID_PARAM));
-public int ch_forw_get LESSPARAMS((VOID_PARAM));
-public int ch_back_get LESSPARAMS((VOID_PARAM));
-public void ch_setbufspace LESSPARAMS((int bufspace));
-public void ch_flush LESSPARAMS((VOID_PARAM));
-public int seekable LESSPARAMS((int f));
-public void ch_set_eof LESSPARAMS((VOID_PARAM));
-public void ch_init LESSPARAMS((int f, int flags));
-public void ch_close LESSPARAMS((VOID_PARAM));
-public int ch_getflags LESSPARAMS((VOID_PARAM));
-public void ch_dump LESSPARAMS((VOID_PARAM));
-public void init_charset LESSPARAMS((VOID_PARAM));
-public int binary_char LESSPARAMS((LWCHAR c));
-public int control_char LESSPARAMS((LWCHAR c));
-public char * prchar LESSPARAMS((LWCHAR c));
-public char * prutfchar LESSPARAMS((LWCHAR ch));
-public int utf_len LESSPARAMS((unsigned char ch));
-public int is_utf8_well_formed LESSPARAMS((char *ss, int slen));
-public int utf_bin_count LESSPARAMS((char *data, int len));
-public LWCHAR get_wchar LESSPARAMS((constant char *p));
-public void put_wchar LESSPARAMS((char **pp, LWCHAR ch));
-public LWCHAR step_char LESSPARAMS((char **pp, signed int dir, constant char *limit));
-public int is_composing_char LESSPARAMS((LWCHAR ch));
-public int is_ubin_char LESSPARAMS((LWCHAR ch));
-public int is_wide_char LESSPARAMS((LWCHAR ch));
-public int is_combining_char LESSPARAMS((LWCHAR ch1, LWCHAR ch2));
-public void cmd_reset LESSPARAMS((VOID_PARAM));
-public void clear_cmd LESSPARAMS((VOID_PARAM));
-public void cmd_putstr LESSPARAMS((constant char *s));
-public int len_cmdbuf LESSPARAMS((VOID_PARAM));
-public void set_mlist LESSPARAMS((void *mlist, int cmdflags));
-public void cmd_addhist LESSPARAMS((struct mlist *mlist, constant char *cmd, int modified));
-public void cmd_accept LESSPARAMS((VOID_PARAM));
-public int cmd_char LESSPARAMS((int c));
-public LINENUM cmd_int LESSPARAMS((long *frac));
-public char * get_cmdbuf LESSPARAMS((VOID_PARAM));
-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 void dispversion LESSPARAMS((VOID_PARAM));
-public int getcc LESSPARAMS((VOID_PARAM));
-public void ungetcc LESSPARAMS((int c));
-public void ungetsc LESSPARAMS((char *s));
-public void commands LESSPARAMS((VOID_PARAM));
-public int cvt_length LESSPARAMS((int len, int ops));
-public int * cvt_alloc_chpos LESSPARAMS((int len));
-public void cvt_text LESSPARAMS((char *odst, char *osrc, int *chpos, int *lenp, int ops));
-public void init_cmds LESSPARAMS((VOID_PARAM));
-public void add_fcmd_table LESSPARAMS((char *buf, int len));
-public void add_ecmd_table LESSPARAMS((char *buf, int len));
-public int fcmd_decode LESSPARAMS((char *cmd, char **sp));
-public int ecmd_decode LESSPARAMS((char *cmd, char **sp));
-public char * lgetenv LESSPARAMS((char *var));
-public int lesskey LESSPARAMS((char *filename, int sysvar));
-public void add_hometable LESSPARAMS((char *envname, char *def_filename, int sysvar));
-public int editchar LESSPARAMS((int c, int flags));
-public void init_textlist LESSPARAMS((struct textlist *tlist, char *str));
-public char * forw_textlist LESSPARAMS((struct textlist *tlist, char *prev));
-public char * back_textlist LESSPARAMS((struct textlist *tlist, char *prev));
-public int edit LESSPARAMS((char *filename));
-public int edit_ifile LESSPARAMS((IFILE ifile));
-public int edit_list LESSPARAMS((char *filelist));
-public int edit_first LESSPARAMS((VOID_PARAM));
-public int edit_last LESSPARAMS((VOID_PARAM));
-public int edit_next LESSPARAMS((int n));
-public int edit_prev LESSPARAMS((int n));
-public int edit_index LESSPARAMS((int n));
-public IFILE save_curr_ifile LESSPARAMS((VOID_PARAM));
-public void unsave_ifile LESSPARAMS((IFILE save_ifile));
-public void reedit_ifile LESSPARAMS((IFILE save_ifile));
-public void reopen_curr_ifile LESSPARAMS((VOID_PARAM));
-public int edit_stdin LESSPARAMS((VOID_PARAM));
-public void cat_file LESSPARAMS((VOID_PARAM));
-public void use_logfile LESSPARAMS((char *filename));
-public char * shell_unquote LESSPARAMS((char *str));
-public char * get_meta_escape LESSPARAMS((VOID_PARAM));
-public char * shell_quote LESSPARAMS((char *s));
-public char * homefile LESSPARAMS((char *filename));
-public char * fexpand LESSPARAMS((char *s));
-public char * fcomplete LESSPARAMS((char *s));
-public int bin_file LESSPARAMS((int f));
-public char * lglob LESSPARAMS((char *filename));
-public char * open_altfile LESSPARAMS((char *filename, int *pf, void **pfd));
-public void close_altfile LESSPARAMS((char *altfilename, char *filename, void *pipefd));
-public int is_dir LESSPARAMS((char *filename));
-public char * bad_file LESSPARAMS((char *filename));
-public POSITION filesize LESSPARAMS((int f));
-public char * shell_coption LESSPARAMS((VOID_PARAM));
-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 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));
-public void backward LESSPARAMS((int n, int force, int only_last));
-public int get_back_scroll LESSPARAMS((VOID_PARAM));
-public int get_line_count LESSPARAMS((VOID_PARAM));
-public void del_ifile LESSPARAMS((IFILE h));
-public IFILE next_ifile LESSPARAMS((IFILE h));
-public IFILE prev_ifile LESSPARAMS((IFILE h));
-public IFILE getoff_ifile LESSPARAMS((IFILE ifile));
-public int nifile LESSPARAMS((VOID_PARAM));
-public IFILE get_ifile LESSPARAMS((char *filename, IFILE prev));
-public char * get_filename LESSPARAMS((IFILE ifile));
-public int get_index LESSPARAMS((IFILE ifile));
-public void store_pos LESSPARAMS((IFILE ifile, struct scrpos *scrpos));
-public void get_pos LESSPARAMS((IFILE ifile, struct scrpos *scrpos));
-public void set_open LESSPARAMS((IFILE ifile));
-public int opened LESSPARAMS((IFILE ifile));
-public void hold_ifile LESSPARAMS((IFILE ifile, int incr));
-public int held_ifile LESSPARAMS((IFILE ifile));
-public void * get_filestate LESSPARAMS((IFILE ifile));
-public void set_filestate LESSPARAMS((IFILE ifile, void *filestate));
-public void if_dump LESSPARAMS((VOID_PARAM));
-public POSITION forw_line LESSPARAMS((POSITION curr_pos));
-public POSITION back_line LESSPARAMS((POSITION curr_pos));
-public void set_attnpos LESSPARAMS((POSITION pos));
-public void jump_forw LESSPARAMS((VOID_PARAM));
-public void jump_forw_buffered LESSPARAMS((VOID_PARAM));
-public void jump_back LESSPARAMS((LINENUM linenum));
-public void repaint LESSPARAMS((VOID_PARAM));
-public void jump_percent LESSPARAMS((int percent, long fraction));
-public void jump_line_loc LESSPARAMS((POSITION pos, int sline));
-public void jump_loc LESSPARAMS((POSITION pos, int sline));
-public void init_line LESSPARAMS((VOID_PARAM));
-public int is_ascii_char LESSPARAMS((LWCHAR ch));
-public void prewind LESSPARAMS((VOID_PARAM));
-public void plinenum LESSPARAMS((POSITION pos));
-public void pshift_all LESSPARAMS((VOID_PARAM));
-public int is_ansi_end LESSPARAMS((LWCHAR ch));
-public int is_ansi_middle LESSPARAMS((LWCHAR ch));
-public int pappend LESSPARAMS((unsigned char c, POSITION pos));
-public int pflushmbc LESSPARAMS((VOID_PARAM));
-public void pdone LESSPARAMS((int endline, int forw));
-public void set_status_col LESSPARAMS((char c));
-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 int rrshift LESSPARAMS((VOID_PARAM));
-public void clr_linenum LESSPARAMS((VOID_PARAM));
-public void add_lnum LESSPARAMS((LINENUM linenum, POSITION pos));
-public LINENUM find_linenum LESSPARAMS((POSITION pos));
-public POSITION find_pos LESSPARAMS((LINENUM linenum));
-public LINENUM currline LESSPARAMS((int where));
-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));
-public void init_mark LESSPARAMS((VOID_PARAM));
-public int badmark LESSPARAMS((int c));
-public void setmark LESSPARAMS((int c));
-public void lastmark LESSPARAMS((VOID_PARAM));
-public void gomark LESSPARAMS((int c));
-public POSITION markpos LESSPARAMS((int c));
-public void unmark LESSPARAMS((IFILE ifile));
-public void opt_o LESSPARAMS((int type, char *s));
-public void opt__O LESSPARAMS((int type, char *s));
-public void opt_j LESSPARAMS((int type, char *s));
-public void calc_jump_sline LESSPARAMS((VOID_PARAM));
-public void opt_shift LESSPARAMS((int type, char *s));
-public void calc_shift_count LESSPARAMS((VOID_PARAM));
-public void opt_k LESSPARAMS((int type, char *s));
-public void opt_t LESSPARAMS((int type, char *s));
-public void opt__T LESSPARAMS((int type, char *s));
-public void opt_p LESSPARAMS((int type, char *s));
-public void opt__P LESSPARAMS((int type, char *s));
-public void opt_b LESSPARAMS((int type, char *s));
-public void opt_i LESSPARAMS((int type, char *s));
-public void opt__V LESSPARAMS((int type, char *s));
-public void opt_D LESSPARAMS((int type, char *s));
-public void opt_x LESSPARAMS((int type, char *s));
-public void opt_quote LESSPARAMS((int type, char *s));
-public void opt_query LESSPARAMS((int type, char *s));
-public int get_swindow LESSPARAMS((VOID_PARAM));
-public char * propt LESSPARAMS((int c));
-public void scan_option LESSPARAMS((char *s));
-public void toggle_option LESSPARAMS((struct loption *o, int lower, char *s, int how_toggle));
-public int opt_has_param LESSPARAMS((struct loption *o));
-public char * opt_prompt LESSPARAMS((struct loption *o));
-public int isoptpending LESSPARAMS((VOID_PARAM));
-public void nopendopt LESSPARAMS((VOID_PARAM));
-public int getnum LESSPARAMS((char **sp, char *printopt, int *errp));
-public long getfraction LESSPARAMS((char **sp, char *printopt, int *errp));
-public int get_quit_at_eof LESSPARAMS((VOID_PARAM));
-public void init_option LESSPARAMS((VOID_PARAM));
-public struct loption * findopt LESSPARAMS((int c));
-public struct loption * findopt_name LESSPARAMS((char **p_optname, char **p_oname, int *p_err));
-public int iread LESSPARAMS((int fd, unsigned char *buf, unsigned int len));
-public void intread LESSPARAMS((VOID_PARAM));
-public time_type get_time LESSPARAMS((VOID_PARAM));
-public char * errno_message LESSPARAMS((char *filename));
-public int percentage LESSPARAMS((POSITION num, POSITION den));
-public POSITION percent_pos LESSPARAMS((POSITION pos, int percent, long fraction));
-public int os9_signal LESSPARAMS((int type, RETSIGTYPE (*handler)()));
-public void put_line LESSPARAMS((VOID_PARAM));
-public void flush LESSPARAMS((VOID_PARAM));
-public int putchr LESSPARAMS((int c));
-public void putstr LESSPARAMS((constant char *s));
-public void get_return LESSPARAMS((VOID_PARAM));
-public void error LESSPARAMS((char *fmt, PARG *parg));
-public void ierror LESSPARAMS((char *fmt, PARG *parg));
-public int query LESSPARAMS((char *fmt, PARG *parg));
-public int compile_pattern LESSPARAMS((char *pattern, int search_type, PATTERN_TYPE *comp_pattern));
-public void uncompile_pattern LESSPARAMS((PATTERN_TYPE *pattern));
-public int valid_pattern LESSPARAMS((char *pattern));
-public int is_null_pattern LESSPARAMS((PATTERN_TYPE pattern));
-public int match_pattern LESSPARAMS((PATTERN_TYPE pattern, char *tpattern, char *line, int line_len, char **sp, char **ep, int notbol, int search_type));
-public POSITION position LESSPARAMS((int where));
-public void add_forw_pos LESSPARAMS((POSITION pos));
-public void add_back_pos LESSPARAMS((POSITION pos));
-public void pos_clear LESSPARAMS((VOID_PARAM));
-public void pos_init LESSPARAMS((VOID_PARAM));
-public int onscreen LESSPARAMS((POSITION pos));
-public int empty_screen LESSPARAMS((VOID_PARAM));
-public int empty_lines LESSPARAMS((int s, int e));
-public void get_scrpos LESSPARAMS((struct scrpos *scrpos));
-public int adjsline LESSPARAMS((int sline));
-public void init_prompt LESSPARAMS((VOID_PARAM));
-public char * pr_expand LESSPARAMS((constant char *proto, int maxwidth));
-public char * eq_message LESSPARAMS((VOID_PARAM));
-public char * pr_string LESSPARAMS((VOID_PARAM));
-public char * wait_message LESSPARAMS((VOID_PARAM));
-public void init_search LESSPARAMS((VOID_PARAM));
-public void repaint_hilite LESSPARAMS((int on));
-public void clear_attn LESSPARAMS((VOID_PARAM));
-public void undo_search LESSPARAMS((VOID_PARAM));
-public void clr_hlist LESSPARAMS((struct hilite_tree *anchor));
-public void clr_hilite LESSPARAMS((VOID_PARAM));
-public void clr_filter LESSPARAMS((VOID_PARAM));
-public int is_filtered LESSPARAMS((POSITION pos));
-public POSITION next_unfiltered LESSPARAMS((POSITION pos));
-public POSITION prev_unfiltered LESSPARAMS((POSITION pos));
-public int is_hilited LESSPARAMS((POSITION pos, POSITION epos, int nohide, int *p_matches));
-public void chg_hilite LESSPARAMS((VOID_PARAM));
-public void chg_caseless LESSPARAMS((VOID_PARAM));
-public int search LESSPARAMS((int search_type, char *pattern, int n));
-public void prep_hilite LESSPARAMS((POSITION spos, POSITION epos, int maxlines));
-public void set_filter_pattern LESSPARAMS((char *pattern, int search_type));
-public int is_filtering LESSPARAMS((VOID_PARAM));
-public RETSIGTYPE winch LESSPARAMS((int type));
-public RETSIGTYPE winch LESSPARAMS((int type));
-public void init_signals LESSPARAMS((int on));
-public void psignals LESSPARAMS((VOID_PARAM));
-public void cleantags LESSPARAMS((VOID_PARAM));
-public int gettagtype LESSPARAMS((VOID_PARAM));
-public void findtag LESSPARAMS((char *tag));
-public POSITION tagsearch LESSPARAMS((VOID_PARAM));
-public char * nexttag LESSPARAMS((int n));
-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 void open_getchr LESSPARAMS((VOID_PARAM));
-public void close_getchr LESSPARAMS((VOID_PARAM));
-public int getchr LESSPARAMS((VOID_PARAM));
+public char * save LESSPARAMS ((constant char *s));
+public VOID_POINTER ecalloc LESSPARAMS ((int count, unsigned int size));
+public char * skipsp LESSPARAMS ((char *s));
+public int sprefix LESSPARAMS ((char *ps, char *s, int uppercase));
+public void quit LESSPARAMS ((int status));
+public void raw_mode LESSPARAMS ((int on));
+public void scrsize LESSPARAMS ((VOID_PARAM));
+public char * special_key_str LESSPARAMS ((int key));
+public void get_term LESSPARAMS ((VOID_PARAM));
+public void init LESSPARAMS ((VOID_PARAM));
+public void deinit LESSPARAMS ((VOID_PARAM));
+public void home LESSPARAMS ((VOID_PARAM));
+public void add_line LESSPARAMS ((VOID_PARAM));
+public void remove_top LESSPARAMS ((int n));
+public void win32_scroll_up LESSPARAMS ((int n));
+public void lower_left LESSPARAMS ((VOID_PARAM));
+public void line_left LESSPARAMS ((VOID_PARAM));
+public void check_winch LESSPARAMS ((VOID_PARAM));
+public void goto_line LESSPARAMS ((int sindex));
+public void vbell LESSPARAMS ((VOID_PARAM));
+public void bell LESSPARAMS ((VOID_PARAM));
+public void clear LESSPARAMS ((VOID_PARAM));
+public void clear_eol LESSPARAMS ((VOID_PARAM));
+public void clear_bot LESSPARAMS ((VOID_PARAM));
+public void at_enter LESSPARAMS ((int attr));
+public void at_exit LESSPARAMS ((VOID_PARAM));
+public void at_switch LESSPARAMS ((int attr));
+public int is_at_equiv LESSPARAMS ((int attr1, int attr2));
+public int apply_at_specials LESSPARAMS ((int attr));
+public void backspace LESSPARAMS ((VOID_PARAM));
+public void putbs LESSPARAMS ((VOID_PARAM));
+public char WIN32getch LESSPARAMS ((int tty));
+public void WIN32setcolors LESSPARAMS ((int fg, int bg));
+public void WIN32textout LESSPARAMS ((char *text, int len));
+public void match_brac LESSPARAMS ((int obrac, int cbrac, int forwdir, int n));
+public void ch_ungetchar LESSPARAMS ((int c));
+public void end_logfile LESSPARAMS ((VOID_PARAM));
+public void sync_logfile LESSPARAMS ((VOID_PARAM));
+public int ch_seek LESSPARAMS ((POSITION pos));
+public int ch_end_seek LESSPARAMS ((VOID_PARAM));
+public int ch_end_buffer_seek LESSPARAMS ((VOID_PARAM));
+public int ch_beg_seek LESSPARAMS ((VOID_PARAM));
+public POSITION ch_length LESSPARAMS ((VOID_PARAM));
+public POSITION ch_tell LESSPARAMS ((VOID_PARAM));
+public int ch_forw_get LESSPARAMS ((VOID_PARAM));
+public int ch_back_get LESSPARAMS ((VOID_PARAM));
+public void ch_setbufspace LESSPARAMS ((int bufspace));
+public void ch_flush LESSPARAMS ((VOID_PARAM));
+public int seekable LESSPARAMS ((int f));
+public void ch_set_eof LESSPARAMS ((VOID_PARAM));
+public void ch_init LESSPARAMS ((int f, int flags));
+public void ch_close LESSPARAMS ((VOID_PARAM));
+public int ch_getflags LESSPARAMS ((VOID_PARAM));
+public void ch_dump LESSPARAMS ((VOID_PARAM));
+public void setfmt LESSPARAMS ((char *s, char **fmtvarptr, int *attrptr, char *default_fmt));
+public void init_charset LESSPARAMS ((VOID_PARAM));
+public int binary_char LESSPARAMS ((LWCHAR c));
+public int control_char LESSPARAMS ((LWCHAR c));
+public char * prchar LESSPARAMS ((LWCHAR c));
+public char * prutfchar LESSPARAMS ((LWCHAR ch));
+public int utf_len LESSPARAMS ((unsigned char ch));
+public int is_utf8_well_formed LESSPARAMS ((char *ss, int slen));
+public void utf_skip_to_lead LESSPARAMS ((char **pp, char *limit));
+public LWCHAR get_wchar LESSPARAMS ((constant char *p));
+public void put_wchar LESSPARAMS ((char **pp, LWCHAR ch));
+public LWCHAR step_char LESSPARAMS ((char **pp, signed int dir, constant char *limit));
+public int is_composing_char LESSPARAMS ((LWCHAR ch));
+public int is_ubin_char LESSPARAMS ((LWCHAR ch));
+public int is_wide_char LESSPARAMS ((LWCHAR ch));
+public int is_combining_char LESSPARAMS ((LWCHAR ch1, LWCHAR ch2));
+public void cmd_reset LESSPARAMS ((VOID_PARAM));
+public void clear_cmd LESSPARAMS ((VOID_PARAM));
+public void cmd_putstr LESSPARAMS ((constant char *s));
+public int len_cmdbuf LESSPARAMS ((VOID_PARAM));
+public void set_mlist LESSPARAMS ((void *mlist, int cmdflags));
+public void cmd_addhist LESSPARAMS ((struct mlist *mlist, constant char *cmd, int modified));
+public void cmd_accept LESSPARAMS ((VOID_PARAM));
+public int cmd_char LESSPARAMS ((int c));
+public LINENUM cmd_int LESSPARAMS ((long *frac));
+public char * get_cmdbuf LESSPARAMS ((VOID_PARAM));
+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 void dispversion LESSPARAMS ((VOID_PARAM));
+public int getcc LESSPARAMS ((VOID_PARAM));
+public void ungetcc LESSPARAMS ((LWCHAR c));
+public void ungetsc LESSPARAMS ((char *s));
+public LWCHAR peekcc LESSPARAMS ((VOID_PARAM));
+public void commands LESSPARAMS ((VOID_PARAM));
+public int cvt_length LESSPARAMS ((int len, int ops));
+public int * cvt_alloc_chpos LESSPARAMS ((int len));
+public void cvt_text LESSPARAMS ((char *odst, char *osrc, int *chpos, int *lenp, int ops));
+public void expand_cmd_tables LESSPARAMS ((VOID_PARAM));
+public void init_cmds LESSPARAMS ((VOID_PARAM));
+public void add_fcmd_table LESSPARAMS ((char *buf, int len));
+public void add_ecmd_table LESSPARAMS ((char *buf, int len));
+public int fcmd_decode LESSPARAMS ((char *cmd, char **sp));
+public int ecmd_decode LESSPARAMS ((char *cmd, char **sp));
+public char * lgetenv LESSPARAMS ((char *var));
+public int lesskey LESSPARAMS ((char *filename, int sysvar));
+public void add_hometable LESSPARAMS ((char *envname, char *def_filename, int sysvar));
+public int editchar LESSPARAMS ((int c, int flags));
+public void init_textlist LESSPARAMS ((struct textlist *tlist, char *str));
+public char * forw_textlist LESSPARAMS ((struct textlist *tlist, char *prev));
+public char * back_textlist LESSPARAMS ((struct textlist *tlist, char *prev));
+public int edit LESSPARAMS ((char *filename));
+public int edit_ifile LESSPARAMS ((IFILE ifile));
+public int edit_list LESSPARAMS ((char *filelist));
+public int edit_first LESSPARAMS ((VOID_PARAM));
+public int edit_last LESSPARAMS ((VOID_PARAM));
+public int edit_next LESSPARAMS ((int n));
+public int edit_prev LESSPARAMS ((int n));
+public int edit_index LESSPARAMS ((int n));
+public IFILE save_curr_ifile LESSPARAMS ((VOID_PARAM));
+public void unsave_ifile LESSPARAMS ((IFILE save_ifile));
+public void reedit_ifile LESSPARAMS ((IFILE save_ifile));
+public void reopen_curr_ifile LESSPARAMS ((VOID_PARAM));
+public int edit_stdin LESSPARAMS ((VOID_PARAM));
+public void cat_file LESSPARAMS ((VOID_PARAM));
+public void use_logfile LESSPARAMS ((char *filename));
+public char * shell_unquote LESSPARAMS ((char *str));
+public char * get_meta_escape LESSPARAMS ((VOID_PARAM));
+public char * shell_quote LESSPARAMS ((char *s));
+public char * homefile LESSPARAMS ((char *filename));
+public char * fexpand LESSPARAMS ((char *s));
+public char * fcomplete LESSPARAMS ((char *s));
+public int bin_file LESSPARAMS ((int f));
+public char * lglob LESSPARAMS ((char *filename));
+public char * open_altfile LESSPARAMS ((char *filename, int *pf, void **pfd));
+public void close_altfile LESSPARAMS ((char *altfilename, char *filename));
+public int is_dir LESSPARAMS ((char *filename));
+public char * bad_file LESSPARAMS ((char *filename));
+public POSITION filesize LESSPARAMS ((int f));
+public char * shell_coption LESSPARAMS ((VOID_PARAM));
+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 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));
+public void backward LESSPARAMS ((int n, int force, int only_last));
+public int get_back_scroll LESSPARAMS ((VOID_PARAM));
+public int get_line_count LESSPARAMS ((VOID_PARAM));
+public void del_ifile LESSPARAMS ((IFILE h));
+public IFILE next_ifile LESSPARAMS ((IFILE h));
+public IFILE prev_ifile LESSPARAMS ((IFILE h));
+public IFILE getoff_ifile LESSPARAMS ((IFILE ifile));
+public int nifile LESSPARAMS ((VOID_PARAM));
+public IFILE get_ifile LESSPARAMS ((char *filename, IFILE prev));
+public char * get_filename LESSPARAMS ((IFILE ifile));
+public int get_index LESSPARAMS ((IFILE ifile));
+public void store_pos LESSPARAMS ((IFILE ifile, struct scrpos *scrpos));
+public void get_pos LESSPARAMS ((IFILE ifile, struct scrpos *scrpos));
+public void set_open LESSPARAMS ((IFILE ifile));
+public int opened LESSPARAMS ((IFILE ifile));
+public void hold_ifile LESSPARAMS ((IFILE ifile, int incr));
+public int held_ifile LESSPARAMS ((IFILE ifile));
+public void * get_filestate LESSPARAMS ((IFILE ifile));
+public void set_filestate LESSPARAMS ((IFILE ifile, void *filestate));
+public void set_altpipe LESSPARAMS ((IFILE ifile, void *p));
+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 LESSPARAMS ((POSITION curr_pos));
+public POSITION back_line LESSPARAMS ((POSITION curr_pos));
+public void set_attnpos LESSPARAMS ((POSITION pos));
+public void jump_forw LESSPARAMS ((VOID_PARAM));
+public void jump_forw_buffered LESSPARAMS ((VOID_PARAM));
+public void jump_back LESSPARAMS ((LINENUM linenum));
+public void repaint LESSPARAMS ((VOID_PARAM));
+public void jump_percent LESSPARAMS ((int percent, long fraction));
+public void jump_line_loc LESSPARAMS ((POSITION pos, int sline));
+public void jump_loc LESSPARAMS ((POSITION pos, int sline));
+public void init_line LESSPARAMS ((VOID_PARAM));
+public int is_ascii_char LESSPARAMS ((LWCHAR ch));
+public void prewind LESSPARAMS ((VOID_PARAM));
+public void plinenum LESSPARAMS ((POSITION pos));
+public void pshift_all LESSPARAMS ((VOID_PARAM));
+public int is_ansi_end LESSPARAMS ((LWCHAR ch));
+public int is_ansi_middle LESSPARAMS ((LWCHAR ch));
+public void skip_ansi LESSPARAMS ((char **pp, constant char *limit));
+public int pappend LESSPARAMS ((unsigned char c, POSITION pos));
+public int pflushmbc LESSPARAMS ((VOID_PARAM));
+public void pdone LESSPARAMS ((int endline, int chopped, int forw));
+public void set_status_col LESSPARAMS ((char c));
+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 int rrshift LESSPARAMS ((VOID_PARAM));
+public void clr_linenum LESSPARAMS ((VOID_PARAM));
+public void add_lnum LESSPARAMS ((LINENUM linenum, POSITION pos));
+public LINENUM find_linenum LESSPARAMS ((POSITION pos));
+public POSITION find_pos LESSPARAMS ((LINENUM linenum));
+public LINENUM currline LESSPARAMS ((int where));
+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));
+public void init_mark LESSPARAMS ((VOID_PARAM));
+public int badmark LESSPARAMS ((int c));
+public void setmark LESSPARAMS ((int c, int where));
+public void clrmark LESSPARAMS ((int c));
+public void lastmark LESSPARAMS ((VOID_PARAM));
+public void gomark LESSPARAMS ((int c));
+public POSITION markpos LESSPARAMS ((int c));
+public char posmark LESSPARAMS ((POSITION pos));
+public void unmark LESSPARAMS ((IFILE ifile));
+public void opt_o LESSPARAMS ((int type, char *s));
+public void opt__O LESSPARAMS ((int type, char *s));
+public void opt_j LESSPARAMS ((int type, char *s));
+public void calc_jump_sline LESSPARAMS ((VOID_PARAM));
+public void opt_shift LESSPARAMS ((int type, char *s));
+public void calc_shift_count LESSPARAMS ((VOID_PARAM));
+public void opt_k LESSPARAMS ((int type, char *s));
+public void opt_t LESSPARAMS ((int type, char *s));
+public void opt__T LESSPARAMS ((int type, char *s));
+public void opt_p LESSPARAMS ((int type, char *s));
+public void opt__P LESSPARAMS ((int type, char *s));
+public void opt_b LESSPARAMS ((int type, char *s));
+public void opt_i LESSPARAMS ((int type, char *s));
+public void opt__V LESSPARAMS ((int type, char *s));
+public void opt_D LESSPARAMS ((int type, char *s));
+public void opt_x LESSPARAMS ((int type, char *s));
+public void opt_quote LESSPARAMS ((int type, char *s));
+public void opt_rscroll LESSPARAMS ((int type, char *s));
+public void opt_query LESSPARAMS ((int type, char *s));
+public int get_swindow LESSPARAMS ((VOID_PARAM));
+public char * propt LESSPARAMS ((int c));
+public void scan_option LESSPARAMS ((char *s));
+public void toggle_option LESSPARAMS ((struct loption *o, int lower, char *s, int how_toggle));
+public int opt_has_param LESSPARAMS ((struct loption *o));
+public char * opt_prompt LESSPARAMS ((struct loption *o));
+public int isoptpending LESSPARAMS ((VOID_PARAM));
+public void nopendopt LESSPARAMS ((VOID_PARAM));
+public int getnum LESSPARAMS ((char **sp, char *printopt, int *errp));
+public long getfraction LESSPARAMS ((char **sp, char *printopt, int *errp));
+public int get_quit_at_eof LESSPARAMS ((VOID_PARAM));
+public void init_option LESSPARAMS ((VOID_PARAM));
+public struct loption * findopt LESSPARAMS ((int c));
+public struct loption * findopt_name LESSPARAMS ((char **p_optname, char **p_oname, int *p_err));
+public int iread LESSPARAMS ((int fd, unsigned char *buf, unsigned int len));
+public void intread LESSPARAMS ((VOID_PARAM));
+public time_type get_time LESSPARAMS ((VOID_PARAM));
+public char * errno_message LESSPARAMS ((char *filename));
+public int percentage LESSPARAMS ((POSITION num, POSITION den));
+public POSITION percent_pos LESSPARAMS ((POSITION pos, int percent, long fraction));
+public int os9_signal LESSPARAMS ((int type, RETSIGTYPE (*handler)()));
+public void put_line LESSPARAMS ((VOID_PARAM));
+public void flush LESSPARAMS ((VOID_PARAM));
+public int putchr LESSPARAMS ((int c));
+public void putstr LESSPARAMS ((constant char *s));
+public void get_return LESSPARAMS ((VOID_PARAM));
+public void error LESSPARAMS ((char *fmt, PARG *parg));
+public void ierror LESSPARAMS ((char *fmt, PARG *parg));
+public int query LESSPARAMS ((char *fmt, PARG *parg));
+public int compile_pattern LESSPARAMS ((char *pattern, int search_type, PATTERN_TYPE *comp_pattern));
+public void uncompile_pattern LESSPARAMS ((PATTERN_TYPE *pattern));
+public int valid_pattern LESSPARAMS ((char *pattern));
+public int is_null_pattern LESSPARAMS ((PATTERN_TYPE pattern));
+public int match_pattern LESSPARAMS ((PATTERN_TYPE pattern, char *tpattern, char *line, int line_len, char **sp, char **ep, int notbol, int search_type));
+public POSITION position LESSPARAMS ((int sindex));
+public void add_forw_pos LESSPARAMS ((POSITION pos));
+public void add_back_pos LESSPARAMS ((POSITION pos));
+public void pos_clear LESSPARAMS ((VOID_PARAM));
+public void pos_init LESSPARAMS ((VOID_PARAM));
+public int onscreen LESSPARAMS ((POSITION pos));
+public int empty_screen LESSPARAMS ((VOID_PARAM));
+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 * eq_message LESSPARAMS ((VOID_PARAM));
+public char * pr_string LESSPARAMS ((VOID_PARAM));
+public char * wait_message LESSPARAMS ((VOID_PARAM));
+public void init_search LESSPARAMS ((VOID_PARAM));
+public void repaint_hilite LESSPARAMS ((int on));
+public void clear_attn LESSPARAMS ((VOID_PARAM));
+public void undo_search LESSPARAMS ((VOID_PARAM));
+public void clr_hlist LESSPARAMS ((struct hilite_tree *anchor));
+public void clr_hilite LESSPARAMS ((VOID_PARAM));
+public void clr_filter LESSPARAMS ((VOID_PARAM));
+public int is_filtered LESSPARAMS ((POSITION pos));
+public POSITION next_unfiltered LESSPARAMS ((POSITION pos));
+public POSITION prev_unfiltered LESSPARAMS ((POSITION pos));
+public int is_hilited LESSPARAMS ((POSITION pos, POSITION epos, int nohide, int *p_matches));
+public void chg_hilite LESSPARAMS ((VOID_PARAM));
+public void chg_caseless LESSPARAMS ((VOID_PARAM));
+public int search LESSPARAMS ((int search_type, char *pattern, int n));
+public void prep_hilite LESSPARAMS ((POSITION spos, POSITION epos, int maxlines));
+public void set_filter_pattern LESSPARAMS ((char *pattern, int search_type));
+public int is_filtering LESSPARAMS ((VOID_PARAM));
+public RETSIGTYPE winch LESSPARAMS ((int type));
+public void init_signals LESSPARAMS ((int on));
+public void psignals LESSPARAMS ((VOID_PARAM));
+public void cleantags LESSPARAMS ((VOID_PARAM));
+public int gettagtype LESSPARAMS ((VOID_PARAM));
+public void findtag LESSPARAMS ((char *tag));
+public POSITION tagsearch LESSPARAMS ((VOID_PARAM));
+public char * nexttag LESSPARAMS ((int n));
+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 void open_getchr LESSPARAMS ((VOID_PARAM));
+public void close_getchr LESSPARAMS ((VOID_PARAM));
+public int getchr LESSPARAMS ((VOID_PARAM));
diff --git a/help.c b/help.c
index 3b0d1bd94f72..1daad8cc55f0 100644
--- a/help.c
+++ b/help.c
@@ -1,4 +1,4 @@
-/* This file was generated by mkhelp from less.hlp */
+/* This file was generated by mkhelp.pl from less.hlp at 17:31 on 2017/11/13 */
#include "less.h"
constant char helpdata[] = {
'\n',
@@ -72,10 +72,12 @@ constant char helpdata[] = {
' ',' ',' ',' ',' ',' ',' ',' ','E','a','c','h',' ','"','f','i','n','d',' ','o','p','e','n',' ','b','r','a','c','k','e','t','"',' ','c','o','m','m','a','n','d',' ','g','o','e','s',' ','b','a','c','k','w','a','r','d',' ','t','o',' ','t','h','e',' ','o','p','e','n',' ','b','r','a','c','k','e','t',' ','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','m','a','t','c','h','i','n','g',' ','t','h','e',' ','(','_','\b','N','-','t','h',')',' ','c','l','o','s','e',' ','b','r','a','c','k','e','t',' ','i','n',' ','t','h','e',' ','b','o','t','t','o','m',' ','l','i','n','e','.','\n',
'\n',
-' ',' ','m','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','M','a','r','k',' ','t','h','e',' ','c','u','r','r','e','n','t',' ','p','o','s','i','t','i','o','n',' ','w','i','t','h',' ','<','l','e','t','t','e','r','>','.','\n',
+' ',' ','m','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','M','a','r','k',' ','t','h','e',' ','c','u','r','r','e','n','t',' ','t','o','p',' ','l','i','n','e',' ','w','i','t','h',' ','<','l','e','t','t','e','r','>','.','\n',
+' ',' ','M','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','M','a','r','k',' ','t','h','e',' ','c','u','r','r','e','n','t',' ','b','o','t','t','o','m',' ','l','i','n','e',' ','w','i','t','h',' ','<','l','e','t','t','e','r','>','.','\n',
' ',' ','\'','_','\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',
' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\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',
diff --git a/ifile.c b/ifile.c
index 53a280c406c4..613312b1c2a0 100644
--- a/ifile.c
+++ b/ifile.c
@@ -24,14 +24,16 @@
extern IFILE curr_ifile;
struct ifile {
- struct ifile *h_next; /* Links for command line list */
+ struct ifile *h_next; /* Links for command line list */
struct ifile *h_prev;
- char *h_filename; /* Name of the file */
- void *h_filestate; /* File state (used in ch.c) */
- int h_index; /* Index within command line list */
- int h_hold; /* Hold count */
- char h_opened; /* Has this ifile been opened? */
- struct scrpos h_scrpos; /* Saved position within the file */
+ char *h_filename; /* Name of the file */
+ void *h_filestate; /* File state (used in ch.c) */
+ int h_index; /* Index within command line list */
+ int h_hold; /* Hold count */
+ char h_opened; /* Has this ifile been opened? */
+ struct scrpos h_scrpos; /* Saved position within the file */
+ void *h_altpipe; /* Alt pipe */
+ char *h_altfilename; /* Alt filename */
};
/*
@@ -328,6 +330,39 @@ set_filestate(ifile, filestate)
int_ifile(ifile)->h_filestate = filestate;
}
+ public void
+set_altpipe(ifile, p)
+ IFILE ifile;
+ void *p;
+{
+ int_ifile(ifile)->h_altpipe = p;
+}
+
+ public void *
+get_altpipe(ifile)
+ IFILE ifile;
+{
+ return (int_ifile(ifile)->h_altpipe);
+}
+
+ public void
+set_altfilename(ifile, altfilename)
+ IFILE ifile;
+ char *altfilename;
+{
+ struct ifile *p = int_ifile(ifile);
+ if (p->h_altfilename != NULL)
+ free(p->h_altfilename);
+ p->h_altfilename = altfilename;
+}
+
+ public char *
+get_altfilename(ifile)
+ IFILE ifile;
+{
+ return (int_ifile(ifile)->h_altfilename);
+}
+
#if 0
public void
if_dump()
diff --git a/input.c b/input.c
index 34689bf6a5a5..27be124c7417 100644
--- a/input.c
+++ b/input.c
@@ -7,7 +7,6 @@
* For more information, see the README file.
*/
-
/*
* High level routines dealing with getting lines of input
* from the file being viewed.
@@ -50,6 +49,7 @@ forw_line(curr_pos)
int c;
int blankline;
int endline;
+ int chopped;
int backchars;
get_forw_line:
@@ -143,6 +143,7 @@ get_forw_line:
/*
* Read each character in the line and append to the line buffer.
*/
+ chopped = FALSE;
for (;;)
{
if (ABORT_SIGS())
@@ -193,6 +194,7 @@ get_forw_line:
new_pos = ch_tell();
endline = TRUE;
quit_if_one_screen = FALSE;
+ chopped = TRUE;
} else
{
new_pos = ch_tell() - backchars;
@@ -203,7 +205,7 @@ get_forw_line:
c = ch_forw_get();
}
- pdone(endline, 1);
+ pdone(endline, chopped, 1);
#if HILITE_SEARCH
if (is_filtered(base_pos))
@@ -255,6 +257,7 @@ back_line(curr_pos)
POSITION new_pos, begin_new_pos, base_pos;
int c;
int endline;
+ int chopped;
int backchars;
get_back_line:
@@ -359,6 +362,7 @@ get_back_line:
loop:
begin_new_pos = new_pos;
(void) ch_seek(new_pos);
+ chopped = FALSE;
do
{
@@ -391,6 +395,7 @@ get_back_line:
if (chopline || hshift > 0)
{
endline = TRUE;
+ chopped = TRUE;
quit_if_one_screen = FALSE;
break;
}
@@ -405,7 +410,7 @@ get_back_line:
}
} while (new_pos < curr_pos);
- pdone(endline, 0);
+ pdone(endline, chopped, 0);
#if HILITE_SEARCH
if (is_filtered(base_pos))
diff --git a/jump.c b/jump.c
index 618d0b87105b..2c7d28bd72c2 100644
--- a/jump.c
+++ b/jump.c
@@ -51,7 +51,7 @@ jump_forw()
end_pos = ch_tell();
pos = back_line(end_pos);
if (pos == NULL_POSITION)
- jump_loc((POSITION)0, sc_height-1);
+ jump_loc(ch_zero(), sc_height-1);
else
{
jump_loc(pos, sc_height-1);
@@ -122,11 +122,11 @@ repaint()
* Start at the line currently at the top of the screen
* and redisplay the screen.
*/
- get_scrpos(&scrpos);
+ get_scrpos(&scrpos, TOP);
pos_clear();
if (scrpos.pos == NULL_POSITION)
/* Screen hasn't been drawn yet. */
- jump_loc(0, 0);
+ jump_loc(ch_zero(), 1);
else
jump_loc(scrpos.pos, scrpos.ln);
}
@@ -201,13 +201,14 @@ jump_loc(pos, sline)
int sline;
{
int nline;
+ int sindex;
POSITION tpos;
POSITION bpos;
/*
* Normalize sline.
*/
- sline = adjsline(sline);
+ sindex = sindex_from_sline(sline);
if ((nline = onscreen(pos)) >= 0)
{
@@ -215,10 +216,10 @@ jump_loc(pos, sline)
* The line is currently displayed.
* Just scroll there.
*/
- nline -= sline;
+ nline -= sindex;
if (nline > 0)
forw(nline, position(BOTTOM_PLUS_ONE), 1, 0, 0);
- else
+ else if (nline < 0)
back(-nline, position(TOP), 1, 0);
#if HILITE_SEARCH
if (show_attn)
@@ -251,7 +252,7 @@ jump_loc(pos, sline)
* call forw() and put the desired line at the
* sline-th line on the screen.
*/
- for (nline = 0; nline < sline; nline++)
+ for (nline = 0; nline < sindex; nline++)
{
if (bpos != NULL_POSITION && pos <= bpos)
{
@@ -260,7 +261,7 @@ jump_loc(pos, sline)
* close enough to the current screen
* that we can just scroll there after all.
*/
- forw(sc_height-sline+nline-1, bpos, 1, 0, 0);
+ forw(sc_height-sindex+nline-1, bpos, 1, 0, 0);
#if HILITE_SEARCH
if (show_attn)
repaint_hilite(1);
@@ -282,16 +283,16 @@ jump_loc(pos, sline)
lastmark();
squished = 0;
screen_trashed = 0;
- forw(sc_height-1, pos, 1, 0, sline-nline);
+ forw(sc_height-1, pos, 1, 0, sindex-nline);
} else
{
/*
* The desired line is before the current screen.
* Move forward in the file far enough so that we
* can call back() and put the desired line at the
- * sline-th line on the screen.
+ * sindex-th line on the screen.
*/
- for (nline = sline; nline < sc_height - 1; nline++)
+ for (nline = sindex; nline < sc_height - 1; nline++)
{
pos = forw_line(pos);
if (pos == NULL_POSITION)
diff --git a/less.h b/less.h
index 69576bbde4cd..39ca65e2a4be 100644
--- a/less.h
+++ b/less.h
@@ -514,7 +514,6 @@ struct wchar_range_table
#define CH_HELPFILE 010
#define CH_NODATA 020 /* Special case for zero length files */
-
#define ch_zero() ((POSITION)0)
#define FAKE_HELPFILE "@/\\less/\\help/\\file/\\@"
@@ -539,6 +538,6 @@ struct hilite_tree;
#include "funcs.h"
/* Functions not included in funcs.h */
-void postoa();
-void linenumtoa();
-void inttoa();
+void postoa LESSPARAMS ((POSITION, char*));
+void linenumtoa LESSPARAMS ((LINENUM, char*));
+void inttoa LESSPARAMS ((int, char*));
diff --git a/less.hlp b/less.hlp
index 255dc7e0ab2b..0bbada91bb94 100644
--- a/less.hlp
+++ b/less.hlp
@@ -69,10 +69,12 @@
Each "find open bracket" command goes backward to the open bracket
matching the (_N-th) close bracket in the bottom line.
- m_<_l_e_t_t_e_r_> Mark the current position with <letter>.
+ m_<_l_e_t_t_e_r_> Mark the current top line with <letter>.
+ M_<_l_e_t_t_e_r_> Mark the current bottom line with <letter>.
'_<_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.
---------------------------------------------------
A mark is any upper-case or lower-case letter.
Certain marks are predefined:
diff --git a/less.man b/less.man
index bb2016573f00..d9f4b13989e5 100644
--- a/less.man
+++ b/less.man
@@ -29,7 +29,7 @@ LESS(1) General Commands Manual LESS(1)
a hardcopy terminal, lines which should be printed at the top of the
screen are prefixed with a caret.)
- Commands are based on both more and vi. Commands may be preceded by a
+ Commands are based on both more and vi. Commands may be preceded by a
decimal number, called N in the descriptions below. The number is used
by some commands, as indicated.
@@ -175,19 +175,27 @@ LESS(1) General Commands Manual LESS(1)
"ESC ^B < >" could be used to go backward to the < which matches
the > in the bottom displayed line.
- m Followed by any lowercase letter, marks the current position
- with that letter.
+ m Followed by any lowercase or uppercase letter, marks the first
+ displayed line with that letter. If the status column is
+ enabled via the -J option, the status column shows the marked
+ line.
- ' (Single quote.) Followed by any lowercase letter, returns to
- the position which was previously marked with that letter. Fol-
- lowed by another single quote, returns to the position 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 ' com-
- mand can be used to switch between input files.
+ 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,
+ 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
+ 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
@@ -388,7 +396,7 @@ LESS(1) General Commands Manual LESS(1)
V Prints the version number of less being run.
q or Q or :q or :Q or ZZ
- Exits less.
+ Exits less.
The following four commands may or may not be valid, depending on your
particular installation.
@@ -412,10 +420,12 @@ LESS(1) General Commands Manual LESS(1)
| <m> shell-command
<m> represents any mark letter. Pipes a section of the input
file to the given shell command. The section of the file to be
- piped is between the first line on the current screen and the
- position marked by the letter. <m> may also be ^ or $ to indi-
- cate beginning or end of file respectively. If <m> is . or new-
- line, the current screen is piped.
+ piped is between the position marked by the letter and the cur-
+ rent screen. The entire current screen is included, regardless
+ of whether the marked position is before or after the current
+ screen. <m> may also be ^ or $ to indicate beginning or end of
+ file respectively. If <m> is . or newline, the current screen
+ is piped.
s filename
Save the input to a file. This only works if the input is a
@@ -437,11 +447,11 @@ LESS(1) General Commands Manual LESS(1)
Options are also taken from the environment variable "LESS". For exam-
ple, to avoid typing "less -options ..." each time less is invoked, you
- might tell csh:
+ might tell csh:
setenv LESS "-options"
- or if you use sh:
+ or if you use sh:
LESS="-options"; export LESS
@@ -518,7 +528,7 @@ LESS(1) General Commands Manual LESS(1)
from the bottom of the screen.
-C or --CLEAR-SCREEN
- Same as -c, for compatibility with older versions of less.
+ Same as -c, for compatibility with older versions of less.
-d or --dumb
The -d option suppresses the error message normally displayed if
@@ -534,8 +544,10 @@ LESS(1) General Commands Manual LESS(1)
color is a pair of numbers separated by a period. The first
number selects the foreground color and the second selects the
background color of the text. A single number N is the same as
- N.M, where M is the normal background color. x may also be a to
- toggle strict ANSI sequence rendering (SGR mode).
+ N.M, where M is the normal background color. The color may
+ start or end with u to use underline (with the normal color, if
+ by itself), if the system supports it (Windows only). x may
+ also be a to toggle strict ANSI sequence rendering (SGR mode).
-e or --quit-at-eof
@@ -613,9 +625,9 @@ LESS(1) General Commands Manual LESS(1)
-J or --status-column
Displays a status column at the left edge of the screen. The
- status column shows the lines that matched the current search.
- The status column is also used if the -w or -W option is in
- effect.
+ status column shows the lines that matched the current search,
+ and any lines that are marked (via the m or M command). The
+ status column is also used if the -w or -W option is in effect.
-kfilename or --lesskey-file=filename
Causes less to open and interpret the named file as a lesskey
@@ -642,7 +654,7 @@ LESS(1) General Commands Manual LESS(1)
into the file. By default, less prompts with a colon.
-M or --LONG-PROMPT
- Causes less to prompt even more verbosely than more.
+ Causes less to prompt even more verbosely than more.
-n or --line-numbers
Suppresses line numbers. The default (to use line numbers) may
@@ -671,7 +683,7 @@ LESS(1) General Commands Manual LESS(1)
If no log file has been specified, the -o and -O options can be
used from within less to specify a log file. Without a file
name, they will simply report the name of the log file. The "s"
- command is equivalent to specifying -o from within less.
+ command is equivalent to specifying -o from within less.
-ppattern or --pattern=pattern
The -p option on the command line is equivalent to specifying
@@ -691,110 +703,111 @@ 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). All prompt strings consist of a sequence of letters
- and special escape sequences. See the section on PROMPTS for
- more details.
+ F command).
+
+ All prompt strings consist of a sequence of letters and special
+ escape sequences. See the section on PROMPTS for more details.
-q or --quiet or --silent
- Causes moderately "quiet" operation: the terminal bell is not
+ Causes moderately "quiet" operation: the terminal bell is not
rung if an attempt is made to scroll past the end of the file or
before the beginning of the file. If the terminal has a "visual
- bell", it is used instead. The bell will be rung on certain
- other errors, such as typing an invalid character. The default
+ bell", it is used instead. The bell will be rung on certain
+ other errors, such as typing an invalid character. The default
is to ring the terminal bell in all such cases.
-Q or --QUIET or --SILENT
- Causes totally "quiet" operation: the terminal bell is never
+ Causes totally "quiet" operation: the terminal bell is never
rung.
-r or --raw-control-chars
Causes "raw" control characters to be displayed. The default is
- to display control characters using the caret notation; for
+ to display control characters using the caret notation; for
example, a control-A (octal 001) is displayed as "^A". Warning:
when the -r option is used, less cannot keep track of the actual
- appearance of the screen (since this depends on how the screen
+ appearance of the screen (since this depends on how the screen
responds to each type of control character). Thus, various dis-
- play problems may result, such as long lines being split in the
+ play problems may result, such as long lines being split in the
wrong place.
-R or --RAW-CONTROL-CHARS
- Like -r, but only ANSI "color" escape sequences are output in
+ Like -r, but only ANSI "color" escape sequences are output in
"raw" form. Unlike -r, the screen appearance is maintained cor-
rectly in most cases. ANSI "color" escape sequences are
sequences of the form:
ESC [ ... m
- where the "..." is zero or more color specification characters
- For the purpose of keeping track of screen appearance, ANSI
- color escape sequences are assumed to not move the cursor. You
- can make less think that characters other than "m" can end ANSI
- color escape sequences by setting the environment variable
+ where the "..." is zero or more color specification characters
+ For the purpose of keeping track of screen appearance, ANSI
+ color escape sequences are assumed to not move the cursor. You
+ can make less think that characters other than "m" can end ANSI
+ color escape sequences by setting the environment variable
LESSANSIENDCHARS to the list of characters which can end a color
- escape sequence. And you can make less think that characters
- other than the standard ones may appear between the ESC and the
- m by setting the environment variable LESSANSIMIDCHARS to the
+ escape sequence. And you can make less think that characters
+ other than the standard ones may appear between the ESC and the
+ m by setting the environment variable LESSANSIMIDCHARS to the
list of characters which can appear.
-s or --squeeze-blank-lines
- Causes consecutive blank lines to be squeezed into a single
+ Causes consecutive blank lines to be squeezed into a single
blank line. This is useful when viewing nroff output.
-S or --chop-long-lines
- Causes lines longer than the screen width to be chopped (trun-
+ Causes lines longer than the screen width to be chopped (trun-
cated) rather than wrapped. That is, the portion of a long line
that does not fit in the screen width is not shown. The default
- is to wrap long lines; that is, display the remainder on the
+ is to wrap long lines; that is, display the remainder on the
next line.
-ttag or --tag=tag
The -t option, followed immediately by a TAG, will edit the file
- containing that tag. For this to work, tag information must be
- available; for example, there may be a file in the current
+ containing that tag. For this to work, tag information must be
+ available; for example, there may be a file in the current
directory called "tags", which was previously built by ctags (1)
or an equivalent command. If the environment variable LESSGLOB-
- ALTAGS is set, it is taken to be the name of a command compati-
- ble with global (1), and that command is executed to find the
+ ALTAGS is set, it is taken to be the name of a command compati-
+ ble with global (1), and that command is executed to find the
tag. (See http://www.gnu.org/software/global/global.html). The
- -t option may also be specified from within less (using the -
- command) as a way of examining a new file. The command ":t" is
- equivalent to specifying -t from within less.
+ -t option may also be specified from within less (using the -
+ command) as a way of examining a new file. The command ":t" is
+ equivalent to specifying -t from within less.
-Ttagsfile or --tag-file=tagsfile
Specifies a tags file to be used instead of "tags".
-u or --underline-special
- Causes backspaces and carriage returns to be treated as print-
- able characters; that is, they are sent to the terminal when
+ Causes backspaces and carriage returns to be treated as print-
+ able characters; that is, they are sent to the terminal when
they appear in the input.
-U or --UNDERLINE-SPECIAL
- Causes backspaces, tabs and carriage returns to be treated as
- control characters; that is, they are handled as specified by
- the -r option.
-
- By default, if neither -u nor -U is given, backspaces which
- appear adjacent to an underscore character are treated spe-
- cially: the underlined text is displayed using the terminal's
- hardware underlining capability. Also, backspaces which appear
- between two identical characters are treated specially: the
- overstruck text is printed using the terminal's hardware bold-
- face capability. Other backspaces are deleted, along with the
+ Causes backspaces, tabs, carriage returns and "formatting char-
+ acters" (as defined by Unicode) to be treated as control charac-
+ ters; that is, they are handled as specified by the -r option.
+
+ By default, if neither -u nor -U is given, backspaces which
+ appear adjacent to an underscore character are treated spe-
+ cially: the underlined text is displayed using the terminal's
+ hardware underlining capability. Also, backspaces which appear
+ between two identical characters are treated specially: the
+ overstruck text is printed using the terminal's hardware bold-
+ face capability. Other backspaces are deleted, along with the
preceding character. Carriage returns immediately followed by a
- newline are deleted. Other carriage returns are handled as
- specified by the -r option. Text which is overstruck or under-
+ newline are deleted. Other carriage returns are handled as
+ specified by the -r option. Text which is overstruck or under-
lined can be searched for if neither -u nor -U is in effect.
-V or --version
- Displays the version number of less.
+ Displays the version number of less.
-w or --hilite-unread
- Temporarily highlights the first "new" line after a forward
+ Temporarily highlights the first "new" line after a forward
movement of a full page. The first "new" line is the line imme-
- diately following the line previously at the bottom of the
+ diately following the line previously at the bottom of the
screen. Also highlights the target line after a g or p command.
- The highlight is removed at the next command which causes move-
- ment. The entire line is highlighted, unless the -J option is
+ 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.
-W or --HILITE-UNREAD
@@ -802,48 +815,48 @@ LESS(1) General Commands Manual LESS(1)
forward movement command larger than one line.
-xn,... or --tabs=n,...
- Sets tab stops. If only one n is specified, tab stops are set
- at multiples of n. If multiple values separated by commas are
- specified, tab stops are set at those positions, and then con-
- tinue with the same spacing as the last two. For example,
- -x9,17 will set tabs at positions 9, 17, 25, 33, etc. The
+ Sets tab stops. If only one n is specified, tab stops are set
+ at multiples of n. If multiple values separated by commas are
+ specified, tab stops are set at those positions, and then con-
+ tinue with the same spacing as the last two. For example,
+ -x9,17 will set tabs at positions 9, 17, 25, 33, etc. The
default for n is 8.
-X or --no-init
Disables sending the termcap initialization and deinitialization
- strings to the terminal. This is sometimes desirable if the
- deinitialization string does something unnecessary, like clear-
+ strings to the terminal. This is sometimes desirable if the
+ deinitialization string does something unnecessary, like clear-
ing the screen.
-yn or --max-forw-scroll=n
Specifies a maximum number of lines to scroll forward. If it is
- necessary to scroll forward more than n lines, the screen is
- repainted instead. The -c or -C option may be used to repaint
- from the top of the screen if desired. By default, any forward
+ necessary to scroll forward more than n lines, the screen is
+ repainted instead. The -c or -C option may be used to repaint
+ from the top of the screen if desired. By default, any forward
movement causes scrolling.
- -[z]n or --window=n
- Changes the default scrolling window size to n lines. The
+ -zn or --window=n or -n
+ Changes the default scrolling window size to n lines. The
default is one screenful. The z and w commands can also be used
- to change the window size. The "z" may be omitted for compati-
- bility with some versions of more. If the number n is negative,
- it indicates n lines less than the current screen size. For
+ to change the window size. The "z" may be omitted for compati-
+ bility with some versions of more. If the number n is negative,
+ it indicates n lines less than the current screen size. For
example, if the screen is 24 lines, -z-4 sets the scrolling win-
- dow to 20 lines. If the screen is resized to 40 lines, the
+ dow to 20 lines. If the screen is resized to 40 lines, the
scrolling window automatically changes to 36 lines.
- -"cc or --quotes=cc
- Changes the filename quoting character. This may be necessary
- if you are trying to name a file which contains both spaces and
- quote characters. Followed by a single character, this changes
- the quote character to that character. Filenames containing a
+ -"cc or --quotes=cc
+ Changes the filename quoting character. This may be necessary
+ if you are trying to name a file which contains both spaces and
+ quote characters. Followed by a single character, this changes
+ the quote character to that character. Filenames containing a
space should then be surrounded by that character rather than by
- double quotes. Followed by two characters, changes the open
- quote to the first character, and the close quote to the second
+ double quotes. Followed by two characters, changes the open
+ quote to the first character, and the close quote to the second
character. Filenames containing a space should then be preceded
- by the open quote character and followed by the close quote
- character. Note that even after the quote characters are
- changed, this option remains -" (a dash followed by a double
+ by the open quote character and followed by the close quote
+ character. Note that even after the quote characters are
+ changed, this option remains -" (a dash followed by a double
quote).
-~ or --tilde
@@ -853,46 +866,52 @@ LESS(1) General Commands Manual LESS(1)
-# or --shift
Specifies the default number of positions to scroll horizontally
- in the RIGHTARROW and LEFTARROW commands. If the number speci-
- fied is zero, it sets the default number of positions to one
+ in the RIGHTARROW and LEFTARROW commands. If the number speci-
+ fied is zero, it sets the default number of positions to one
half of the screen width. Alternately, the number may be speci-
- fied as a fraction of the width of the screen, starting with a
- decimal point: .5 is half of the screen width, .3 is three
- tenths of the screen width, and so on. If the number is speci-
- fied as a fraction, 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
+ fied as a fraction of the width of the screen, starting with a
+ decimal point: .5 is half of the screen width, .3 is three
+ tenths of the screen width, and so on. If the number is speci-
+ fied as a fraction, the actual number of scroll positions is
+ recalculated if the terminal window is resized, so that the
+ actual scroll remains at the specified fraction of the screen
width.
--follow-name
- Normally, if the input file is renamed while an F command is
- executing, less will continue to display the contents of the
- original file despite its name change. If --follow-name is
+ Normally, if the input file is renamed while an F command is
+ executing, less will continue to display the contents of the
+ original file despite its name change. If --follow-name is
specified, during an F command less will periodically attempt to
reopen 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
+ a different file from the original (which means that a new file
+ has been created with the same name as the original (now
renamed) file), less will display the contents of that new file.
--no-keypad
- Disables sending the keypad initialization and deinitialization
+ Disables sending the keypad initialization and deinitialization
strings to the terminal. This is sometimes useful if the keypad
strings make the numeric keypad behave in an undesirable manner.
--use-backslash
- This option changes the interpretations of options which follow
+ This option changes the interpretations of options which follow
this one. After the --use-backslash option, any backslash in an
- option string is removed and the following character is taken
- literally. This allows a dollar sign to be included in option
+ option string is removed and the following character is taken
+ literally. This allows a dollar sign to be included in option
strings.
+ --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.
+
-- A command line argument of "--" marks the end of option argu-
ments. Any arguments following this are interpreted as file-
names. This can be useful when viewing a file whose name begins
with a "-" or "+".
+ If a command line option begins with +, the remainder of that
- option is taken to be an initial command to less. For example,
+ option is taken to be an initial command to less. For example,
+G tells less to start at the end of the file rather than the
beginning, and +/xyz tells it to start at the first occurrence
of "xyz" in the file. As a special case, +<number> acts like
@@ -1019,7 +1038,7 @@ LESS(1) General Commands Manual LESS(1)
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
@@ -1077,7 +1096,7 @@ LESS(1) General Commands Manual LESS(1)
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
+ 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-
@@ -1108,10 +1127,10 @@ LESS(1) General Commands Manual LESS(1)
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
+ 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
+ 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
@@ -1119,7 +1138,7 @@ LESS(1) General Commands Manual LESS(1)
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
@@ -1550,7 +1569,7 @@ LESS(1) General Commands Manual LESS(1)
LESSHISTFILE
Name of the history file used to remember search commands and
- shell commands between invocations of less. If set to "-" or
+ shell commands between invocations of less. If set to "-" or
"/dev/null", a history file is not used. The default is
"$HOME/.lesshst" on Unix systems, "$HOME/_lesshst" on DOS and
Windows systems, or "$HOME/lesshst.ini" or "$INIT/lesshst.ini"
@@ -1645,4 +1664,4 @@ LESS(1) General Commands Manual LESS(1)
- Version 491: 07 Apr 2017 LESS(1)
+ Version 529: 13 Nov 2017 LESS(1)
diff --git a/less.nro b/less.nro
index 2f7bb7faa1de..0b706c3f4f04 100644
--- a/less.nro
+++ b/less.nro
@@ -1,4 +1,4 @@
-.TH LESS 1 "Version 491: 07 Apr 2017"
+.TH LESS 1 "Version 529: 13 Nov 2017"
.SH NAME
less \- opposite of more
.SH SYNOPSIS
@@ -44,7 +44,7 @@ of the screen are prefixed with a caret.)
Commands are based on both
.I more
and
-.I vi.
+.IR vi .
Commands may be preceded by a decimal number,
called N in the descriptions below.
The number is used by some commands, as indicated.
@@ -174,11 +174,16 @@ respectively.
For example, "ESC ^B < >" could be used to
go backward to the < which matches the > in the bottom displayed line.
.IP m
-Followed by any lowercase letter,
-marks the current position with that letter.
+Followed by any lowercase or uppercase letter,
+marks the first displayed line with that letter.
+If the status column is enabled via the \-J option,
+the status column shows the marked line.
+.IP M
+Acts like m, except the last displayed line is marked
+rather than the first displayed line.
.IP "'"
(Single quote.)
-Followed by any lowercase letter, returns to the position which
+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 position at
which the last "large" movement command was executed.
@@ -188,6 +193,9 @@ Marks are preserved when a new file is examined,
so the ' command can be used to switch between input files.
.IP "^X^X"
Same as single quote.
+.IP "ESC-m"
+Followed by any lowercase or uppercase letter,
+clears the mark identified by that letter.
.IP /pattern
Search forward in the file for the N-th line containing the pattern.
N defaults to 1.
@@ -392,7 +400,7 @@ Prints the version number of
being run.
.IP "q or Q or :q or :Q or ZZ"
Exits
-.I less.
+.IR less .
.PP
The following
four
@@ -417,8 +425,10 @@ On MS-DOS and OS/2 systems, the shell is the normal command processor.
.IP "| <m> shell-command"
<m> represents any mark letter.
Pipes a section of the input file to the given shell command.
-The section of the file to be piped is between the first line on
-the current screen and the position marked by the letter.
+The section of the file to be piped is between the position marked by
+the letter and the current screen.
+The entire current screen is included, regardless of whether the
+marked position is before or after the current screen.
<m> may also be ^ or $ to indicate beginning or end of file respectively.
If <m> is \&.\& or newline, the current screen is piped.
.IP "s filename"
@@ -449,12 +459,12 @@ For example,
to avoid typing "less \-options \&...\&" each time
.I less
is invoked, you might tell
-.I csh:
+.IR csh :
.sp
setenv LESS "\-options"
.sp
or if you use
-.I sh:
+.IR sh :
.sp
LESS="\-options"; export LESS
.sp
@@ -532,7 +542,7 @@ By default,
full screen repaints are done by scrolling from the bottom of the screen.
.IP "\-C or \-\-CLEAR-SCREEN"
Same as \-c, for compatibility with older versions of
-.I less.
+.IR less .
.IP "\-d or \-\-dumb"
The \-d option suppresses the error message
normally displayed if the terminal is dumb;
@@ -551,6 +561,8 @@ The first number selects the foreground color and the second selects
the background color of the text.
A single number \fIN\fP is the same as \fIN.M\fP,
where \fIM\fP is the normal background color.
+The color may start or end with \fBu\fP to use underline (with the normal
+color, if by itself), if the system supports it (Windows only).
\fBx\fP may also be \fBa\fP to toggle strict ANSI sequence rendering (SGR mode).
.IP "\-e or \-\-quit-at-eof"
@@ -635,7 +647,8 @@ However nonrepeated searches (invoked with "/" or "?")
always begin at the start or end of the current screen respectively.
.IP "\-J or \-\-status-column"
Displays a status column at the left edge of the screen.
-The status column shows the lines that matched the current search.
+The status column shows the lines that matched the current search,
+and any lines that are marked (via the m or M command).
The status column is also used if the \-w or \-W option is in effect.
.IP "\-k\fIfilename\fP or \-\-lesskey-file=\fIfilename\fP"
Causes
@@ -677,7 +690,7 @@ prompts with a colon.
Causes
.I less
to prompt even more verbosely than
-.I more.
+.IR more .
.IP "\-n or \-\-line-numbers"
Suppresses line numbers.
The default (to use line numbers) may cause
@@ -710,7 +723,7 @@ the \-o and \-O options can be used from within
to specify a log file.
Without a file name, they will simply report the name of the log file.
The "s" command is equivalent to specifying \-o from within
-.I less.
+.IR less .
.IP "\-p\fIpattern\fP or \-\-pattern=\fIpattern\fP"
The \-p option on the command line is equivalent to
specifying +/\fIpattern\fP;
@@ -733,6 +746,7 @@ to that string.
\-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).
+
All prompt strings consist of a sequence of
letters and special escape sequences.
See the section on PROMPTS for more details.
@@ -808,15 +822,15 @@ The \-t option may also be specified from within
.I less
(using the \- command) as a way of examining a new file.
The command ":t" is equivalent to specifying \-t from within
-.I less.
+.IR less .
.IP "\-T\fItagsfile\fP or \-\-tag-file=\fItagsfile\fP"
Specifies a tags file to be used instead of "tags".
.IP "\-u or \-\-underline-special"
Causes backspaces and carriage returns to be treated as printable characters;
that is, they are sent to the terminal when they appear in the input.
.IP "\-U or \-\-UNDERLINE-SPECIAL"
-Causes backspaces, tabs and carriage returns to be
-treated as control characters;
+Causes backspaces, tabs, carriage returns and "formatting characters"
+(as defined by Unicode) to be treated as control characters;
that is, they are handled as specified by the \-r option.
.sp
By default, if neither \-u nor \-U is given,
@@ -835,7 +849,7 @@ Text which is overstruck or underlined can be searched for
if neither \-u nor \-U is in effect.
.IP "\-V or \-\-version"
Displays the version number of
-.I less.
+.IR less .
.IP "\-w or \-\-hilite-unread"
Temporarily highlights the first "new" line after a forward movement
of a full page.
@@ -868,12 +882,12 @@ the screen is repainted instead.
The \-c or \-C option may be used to repaint from the top of
the screen if desired.
By default, any forward movement causes scrolling.
-.IP "\-[z]\fIn\fP or \-\-window=\fIn\fP"
+.IP "\-z\fIn\fP or \-\-window=\fIn\fP or \-\fIn\fP"
Changes the default scrolling window size to \fIn\fP lines.
The default is one screenful.
The z and w commands can also be used to change the window size.
The "z" may be omitted for compatibility with some versions of
-.I more.
+.IR more .
If the number
.I n
is negative, it indicates
@@ -882,7 +896,7 @@ lines less than the current screen size.
For example, if the screen is 24 lines, \fI\-z\-4\fP sets the
scrolling window to 20 lines. If the screen is resized to 40 lines,
the scrolling window automatically changes to 36 lines.
-.IP "\-\fI\(dqcc\fP\ or\ \-\-quotes=\fIcc\fP"
+.IP "\-\(dq\fIcc\fP\ or\ \-\-quotes=\fIcc\fP"
Changes the filename quoting character.
This may be necessary if you are trying to name a file
which contains both spaces and quote characters.
@@ -934,6 +948,11 @@ 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 "\-\-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 \-\-
A command line argument of "\-\-" marks the end of option arguments.
Any arguments following this are interpreted as filenames.
@@ -941,7 +960,7 @@ This can be useful when viewing a file whose name begins with a "\-" or "+".
.IP +
If a command line option begins with \fB+\fP,
the remainder of that option is taken to be an initial command to
-.I less.
+.IR less .
For example, +G tells
.I less
to start at the end of the file rather than the beginning,
@@ -1080,7 +1099,7 @@ On OS/2 systems, the system-wide lesskey file is c:\esysless.ini.
.SH "INPUT PREPROCESSOR"
You may define an "input preprocessor" for
-.I less.
+.IR less .
Before
.I less
opens a file, it first gives your input preprocessor a chance to modify the
@@ -1165,7 +1184,7 @@ to accept other types of compressed files, and so on.
.PP
It is also possible to set up an input preprocessor to
pipe the file data directly to
-.I less,
+.IR less ,
rather than putting the data into a replacement file.
This avoids the need to decompress the entire file before
starting to view it.
@@ -1210,11 +1229,11 @@ 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 empty.
+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
-.I less,
+.IR less ,
if LESSOPEN starts with only one vertical bar, the exit status
of the preprocessor is ignored.
.PP
@@ -1225,7 +1244,7 @@ In this case, the replacement file name passed to the LESSCLOSE
postprocessor is "\-".
.PP
For compatibility with previous versions of
-.I less,
+.IR less ,
the input preprocessor or pipe is not used if
.I less
is viewing standard input.
@@ -1685,7 +1704,7 @@ Normally should be set to "global" if your system has the
.IP LESSHISTFILE
Name of the history file used to remember search commands and
shell commands between invocations of
-.I less.
+.IR less .
If set to "\-" or "/dev/null", a history file is not used.
The default is "$HOME/.lesshst" on Unix systems, "$HOME/_lesshst" on
DOS and Windows systems, or "$HOME/lesshst.ini" or "$INIT/lesshst.ini"
diff --git a/lessecho.man b/lessecho.man
index 466e4c68baab..70e8d383e337 100644
--- a/lessecho.man
+++ b/lessecho.man
@@ -51,4 +51,4 @@ LESSECHO(1) General Commands Manual LESSECHO(1)
- Version 491: 07 Apr 2017 LESSECHO(1)
+ Version 529: 13 Nov 2017 LESSECHO(1)
diff --git a/lessecho.nro b/lessecho.nro
index f5922fa4ab79..703ffe54a043 100644
--- a/lessecho.nro
+++ b/lessecho.nro
@@ -1,4 +1,4 @@
-.TH LESSECHO 1 "Version 491: 07 Apr 2017"
+.TH LESSECHO 1 "Version 529: 13 Nov 2017"
.SH NAME
lessecho \- expand metacharacters
.SH SYNOPSIS
diff --git a/lesskey.c b/lesskey.c
index 686f6e4ffdad..fa1ab6d3a452 100644
--- a/lesskey.c
+++ b/lesskey.c
@@ -99,6 +99,7 @@ struct cmdname cmdnames[] =
{ "back-scroll", A_B_SCROLL },
{ "back-search", A_B_SEARCH },
{ "back-window", A_B_WINDOW },
+ { "clear-mark", A_CLRMARK },
{ "debug", A_DEBUG },
{ "digit", A_DIGIT },
{ "display-flag", A_DISP_OPTION },
@@ -146,6 +147,7 @@ struct cmdname cmdnames[] =
{ "reverse-search-all", A_T_REVERSE_SEARCH },
{ "right-scroll", A_RSHIFT },
{ "set-mark", A_SETMARK },
+ { "set-mark-bottom", A_SETMARKBOT },
{ "shell", A_SHELL },
{ "status", A_STAT },
{ "toggle-flag", A_OPT_TOGGLE },
diff --git a/lesskey.man b/lesskey.man
index 0deca67f18a4..0ff5e3ff6711 100644
--- a/lesskey.man
+++ b/lesskey.man
@@ -191,6 +191,8 @@ LESSKEY(1) General Commands Manual LESSKEY(1)
\eN reverse-search-all
& filter
m set-mark
+ M set-mark-bottom
+ \em clear-mark
' goto-mark
^X^X goto-mark
E examine
@@ -359,4 +361,4 @@ LESSKEY(1) General Commands Manual LESSKEY(1)
- Version 491: 07 Apr 2017 LESSKEY(1)
+ Version 529: 13 Nov 2017 LESSKEY(1)
diff --git a/lesskey.nro b/lesskey.nro
index a13be9329c97..d7e059fbf813 100644
--- a/lesskey.nro
+++ b/lesskey.nro
@@ -1,4 +1,4 @@
-.TH LESSKEY 1 "Version 491: 07 Apr 2017"
+.TH LESSKEY 1 "Version 529: 13 Nov 2017"
.SH NAME
lesskey \- specify key bindings for less
.SH SYNOPSIS
@@ -208,6 +208,8 @@ default command keys used by less:
\eeN reverse-search-all
& filter
m set-mark
+ M set-mark-bottom
+ \eem clear-mark
' goto-mark
^X^X goto-mark
E examine
diff --git a/line.c b/line.c
index 3715d5805af4..dd890f3db3ff 100644
--- a/line.c
+++ b/line.c
@@ -7,7 +7,6 @@
* For more information, see the README file.
*/
-
/*
* Routines to manipulate the "line buffer".
* The line buffer holds a line of output as it is being built
@@ -18,6 +17,11 @@
#include "charset.h"
#include "position.h"
+#if MSDOS_COMPILER==WIN32C
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
static char *linebuf = NULL; /* Buffer which holds the current output line */
static char *attr = NULL; /* Extension of linebuf to hold attributes */
public int size_linebuf = 0; /* Size of line buffer (and attr buffer) */
@@ -32,6 +36,8 @@ public POSITION highest_hilite; /* Pos of last hilite in file found so far */
static int curr; /* Index into linebuf */
static int column; /* Printable length, accounting for
backspaces, etc. */
+static int right_curr;
+static int right_column;
static int overstrike; /* Next char should overstrike previous char */
static int last_overstrike = AT_NORMAL;
static int is_null_line; /* There is no current line */
@@ -41,9 +47,9 @@ static POSITION pendpos;
static char *end_ansi_chars;
static char *mid_ansi_chars;
-static int attr_swidth();
-static int attr_ewidth();
-static int do_append();
+static int attr_swidth LESSPARAMS ((int a));
+static int attr_ewidth LESSPARAMS ((int a));
+static int do_append LESSPARAMS ((LWCHAR ch, char *rep, POSITION pos));
extern int sigs;
extern int bs_mode;
@@ -61,6 +67,8 @@ extern int sc_width, sc_height;
extern int utf_mode;
extern POSITION start_attnpos;
extern POSITION end_attnpos;
+extern LWCHAR rscroll_char;
+extern int rscroll_attr;
static char mbc_buf[MAX_UTF_CHAR_LEN];
static int mbc_buf_len = 0;
@@ -152,6 +160,8 @@ prewind()
{
curr = 0;
column = 0;
+ right_curr = 0;
+ right_column = 0;
cshift = 0;
overstrike = 0;
last_overstrike = AT_NORMAL;
@@ -160,7 +170,33 @@ prewind()
pendc = '\0';
lmargin = 0;
if (status_col)
- lmargin += 1;
+ lmargin += 2;
+}
+
+/*
+ * Set a character in the line buffer.
+ */
+ static void
+set_linebuf(n, ch, a)
+ int n;
+ LWCHAR ch;
+ char a;
+{
+ linebuf[n] = ch;
+ attr[n] = a;
+}
+
+/*
+ * Append a character to the line buffer.
+ */
+ static void
+add_linebuf(ch, a, w)
+ LWCHAR ch;
+ char a;
+ int w;
+{
+ set_linebuf(curr++, ch, a);
+ column += w;
}
/*
@@ -191,45 +227,48 @@ plinenum(pos)
*/
if (status_col)
{
- linebuf[curr] = ' ';
- if (start_attnpos != NULL_POSITION &&
- pos >= start_attnpos && pos < end_attnpos)
- attr[curr] = AT_NORMAL|AT_HILITE;
- else
- attr[curr] = AT_NORMAL;
- curr++;
- column++;
+ int a = AT_NORMAL;
+ char c = posmark(pos);
+ if (c != 0)
+ a |= AT_HILITE;
+ else
+ {
+ c = ' ';
+ if (start_attnpos != NULL_POSITION &&
+ pos >= start_attnpos && pos <= end_attnpos)
+ a |= AT_HILITE;
+ }
+ add_linebuf(c, a, 1); /* column 0: status */
+ add_linebuf(' ', AT_NORMAL, 1); /* column 1: empty */
}
+
/*
* Display the line number at the start of each line
* if the -N option is set.
*/
if (linenums == OPT_ONPLUS)
{
- char buf[INT_STRLEN_BOUND(pos) + 2];
+ char buf[INT_STRLEN_BOUND(linenum) + 2];
+ int pad = 0;
int n;
linenumtoa(linenum, buf);
n = (int) strlen(buf);
if (n < MIN_LINENUM_WIDTH)
- n = MIN_LINENUM_WIDTH;
- sprintf(linebuf+curr, "%*s ", n, buf);
- n++; /* One space after the line number. */
+ pad = MIN_LINENUM_WIDTH - n;
+ for (i = 0; i < pad; i++)
+ add_linebuf(' ', AT_NORMAL, 1);
for (i = 0; i < n; i++)
- attr[curr+i] = AT_BOLD;
- curr += n;
- column += n;
- lmargin += n;
+ add_linebuf(buf[i], AT_BOLD, 1);
+ add_linebuf(' ', AT_NORMAL, 1);
+ lmargin += n + pad + 1;
}
-
/*
* Append enough spaces to bring us to the lmargin.
*/
while (column < lmargin)
{
- linebuf[curr] = ' ';
- attr[curr++] = AT_NORMAL;
- column++;
+ add_linebuf(' ', AT_NORMAL, 1);
}
}
@@ -540,7 +579,7 @@ is_ansi_end(ch)
}
/*
- *
+ * Can a char appear in an ANSI escape sequence, before the end char?
*/
public int
is_ansi_middle(ch)
@@ -554,6 +593,23 @@ is_ansi_middle(ch)
}
/*
+ * Skip past an ANSI escape sequence.
+ * pp is initially positioned just after the CSI_START char.
+ */
+ public void
+skip_ansi(pp, limit)
+ char **pp;
+ constant char *limit;
+{
+ LWCHAR c;
+ do {
+ c = step_char(pp, +1, limit);
+ } while (*pp < limit && is_ansi_middle(c));
+ /* Note that we discard final char, for which is_ansi_middle is false. */
+}
+
+
+/*
* Append a character and attribute to the line buffer.
*/
#define STORE_CHAR(ch,a,rep,pos) \
@@ -648,11 +704,15 @@ store_char(ch, a, rep, pos)
return (1);
}
+ if (column > right_column && w > 0)
+ {
+ right_column = column;
+ right_curr = curr;
+ }
+
while (replen-- > 0)
{
- linebuf[curr] = *rep++;
- attr[curr] = a;
- curr++;
+ add_linebuf(*rep++, a, 0);
}
column += w;
return (0);
@@ -1000,11 +1060,26 @@ pflushmbc()
}
/*
+ * Switch to normal attribute at end of line.
+ */
+ static void
+add_attr_normal()
+{
+ char *p = "\033[m";
+
+ if (ctldisp != OPT_ONPLUS || !is_ansi_end('m'))
+ return;
+ for ( ; *p != '\0'; p++)
+ add_linebuf(*p, AT_ANSI, 0);
+}
+
+/*
* Terminate the line in the line buffer.
*/
public void
-pdone(endline, forw)
+pdone(endline, chopped, forw)
int endline;
+ int chopped;
int forw;
{
(void) pflushmbc();
@@ -1023,15 +1098,34 @@ pdone(endline, forw)
if (cshift < hshift)
pshift(hshift - cshift);
- if (ctldisp == OPT_ONPLUS && is_ansi_end('m'))
+ if (chopped && rscroll_char)
{
- /* Switch to normal attribute at end of line. */
- char *p = "\033[m";
- for ( ; *p != '\0'; p++)
+ /*
+ * Display the right scrolling char.
+ * If we've already filled the rightmost screen char
+ * (in the buffer), overwrite it.
+ */
+ if (column >= sc_width)
{
- linebuf[curr] = *p;
- attr[curr++] = AT_ANSI;
+ /* We've already written in the rightmost char. */
+ column = right_column;
+ curr = right_curr;
}
+ add_attr_normal();
+ while (column < sc_width-1)
+ {
+ /*
+ * Space to last (rightmost) char on screen.
+ * This may be necessary if the char we overwrote
+ * was double-width.
+ */
+ add_linebuf(' ', AT_NORMAL, 1);
+ }
+ /* Print rscroll char. It must be single-width. */
+ add_linebuf(rscroll_char, rscroll_attr, 1);
+ } else
+ {
+ add_attr_normal();
}
/*
@@ -1049,9 +1143,7 @@ pdone(endline, forw)
*/
if (column < sc_width || !auto_wrap || (endline && ignaw) || ctldisp == OPT_ON)
{
- linebuf[curr] = '\n';
- attr[curr] = AT_NORMAL;
- curr++;
+ add_linebuf('\n', AT_NORMAL, 0);
}
else if (ignaw && column >= sc_width && forw)
{
@@ -1069,13 +1161,10 @@ pdone(endline, forw)
* char on the next line. We don't need to do this "nudge"
* at the top of the screen anyway.
*/
- linebuf[curr] = ' ';
- attr[curr++] = AT_NORMAL;
- linebuf[curr] = '\b';
- attr[curr++] = AT_NORMAL;
+ add_linebuf(' ', AT_NORMAL, 1);
+ add_linebuf('\b', AT_NORMAL, -1);
}
- linebuf[curr] = '\0';
- attr[curr] = AT_NORMAL;
+ set_linebuf(curr, '\0', AT_NORMAL);
}
/*
@@ -1085,8 +1174,7 @@ pdone(endline, forw)
set_status_col(c)
char c;
{
- linebuf[0] = c;
- attr[0] = AT_NORMAL|AT_HILITE;
+ set_linebuf(0, c, AT_NORMAL|AT_HILITE);
}
/*
diff --git a/main.c b/main.c
index b44d88a506fe..179bd78c4331 100644
--- a/main.c
+++ b/main.c
@@ -112,8 +112,9 @@ main(argc, argv)
* Command line arguments override environment arguments.
*/
is_tty = isatty(1);
- get_term();
init_cmds();
+ get_term();
+ expand_cmd_tables();
init_charset();
init_line();
init_cmdhist();
@@ -181,7 +182,6 @@ main(argc, argv)
ifile = get_ifile(FAKE_HELPFILE, ifile);
while (argc-- > 0)
{
- char *filename;
#if (MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC)
/*
* Because the "shell" doesn't expand filename patterns,
@@ -190,25 +190,24 @@ main(argc, argv)
* Expand the pattern and iterate over the expanded list.
*/
struct textlist tlist;
+ char *filename;
char *gfilename;
+ char *qfilename;
gfilename = lglob(*argv++);
init_textlist(&tlist, gfilename);
filename = NULL;
while ((filename = forw_textlist(&tlist, filename)) != NULL)
{
- (void) get_ifile(filename, ifile);
+ qfilename = shell_unquote(filename);
+ (void) get_ifile(qfilename, ifile);
+ free(qfilename);
ifile = prev_ifile(NULL_IFILE);
}
free(gfilename);
#else
- filename = shell_quote(*argv);
- if (filename == NULL)
- filename = *argv;
- argv++;
- (void) get_ifile(filename, ifile);
+ (void) get_ifile(*argv++, ifile);
ifile = prev_ifile(NULL_IFILE);
- free(filename);
#endif
}
/*
@@ -281,17 +280,11 @@ main(argc, argv)
{
if (edit_first()) /* Edit first valid file in cmd line */
quit(QUIT_ERROR);
- /*
- * In case that we have only one file and -F, have to get a line
- * count fot init(). If the line count is less then a height of a term,
- * the content of the file is printed out and then less quits. Otherwise
- * -F can not be used
- */
if (quit_if_one_screen)
{
if (nifile() == 1)
line_count = get_line_count();
- else /* In case more than one file, -F can not be used */
+ else /* If more than one file, -F can not be used */
quit_if_one_screen = FALSE;
}
}
diff --git a/mark.c b/mark.c
index 12a0b6c159ff..fbdac6e3f461 100644
--- a/mark.c
+++ b/mark.c
@@ -9,6 +9,7 @@
#include "less.h"
+#include "position.h"
extern IFILE curr_ifile;
extern int sc_height;
@@ -86,7 +87,7 @@ getmark(c)
}
m = &sm;
m->m_scrpos.pos = ch_tell();
- m->m_scrpos.ln = sc_height-1;
+ m->m_scrpos.ln = sc_height;
m->m_ifile = curr_ifile;
break;
case '.':
@@ -94,7 +95,7 @@ getmark(c)
* Current position in the current file.
*/
m = &sm;
- get_scrpos(&m->m_scrpos);
+ get_scrpos(&m->m_scrpos, TOP);
m->m_ifile = curr_ifile;
break;
case '\'':
@@ -134,8 +135,9 @@ badmark(c)
* Set a user-defined mark.
*/
public void
-setmark(c)
+setmark(c, where)
int c;
+ int where;
{
struct mark *m;
struct scrpos scrpos;
@@ -143,12 +145,27 @@ setmark(c)
m = getumark(c);
if (m == NULL)
return;
- get_scrpos(&scrpos);
+ get_scrpos(&scrpos, where);
m->m_scrpos = scrpos;
m->m_ifile = curr_ifile;
}
/*
+ * Clear a user-defined mark.
+ */
+ public void
+clrmark(c)
+ int c;
+{
+ struct mark *m;
+
+ m = getumark(c);
+ if (m == NULL)
+ return;
+ m->m_scrpos.pos = NULL_POSITION;
+}
+
+/*
* Set lmark (the mark named by the apostrophe).
*/
public void
@@ -158,7 +175,7 @@ lastmark()
if (ch_getflags() & CH_HELPFILE)
return;
- get_scrpos(&scrpos);
+ get_scrpos(&scrpos, TOP);
if (scrpos.pos == NULL_POSITION)
return;
marks[LASTMARK].m_scrpos = scrpos;
@@ -235,6 +252,27 @@ markpos(c)
}
/*
+ * Return the mark associated with a given position, if any.
+ */
+ public char
+posmark(pos)
+ POSITION pos;
+{
+ int i;
+
+ /* Only lower case and upper case letters */
+ for (i = 0; i < 26*2; i++)
+ {
+ if (marks[i].m_ifile == curr_ifile && marks[i].m_scrpos.pos == pos)
+ {
+ if (i < 26) return 'a' + i;
+ return 'A' + i - 26;
+ }
+ }
+ return 0;
+}
+
+/*
* Clear the marks associated with a specified ifile.
*/
public void
diff --git a/mkfuncs.pl b/mkfuncs.pl
index 87875f9a1acf..35417339791f 100644
--- a/mkfuncs.pl
+++ b/mkfuncs.pl
@@ -11,7 +11,7 @@ while (<>) {
$state = 1;
$params = 0;
} elsif ($state == 1 and /(\w+)\s*\(/) {
- $def .= " $1 LESSPARAMS((";
+ $def .= " $1 LESSPARAMS ((";
$state = 2;
} elsif ($state == 2) {
if (/^{/) {
diff --git a/mkhelp.c b/mkhelp.c
deleted file mode 100644
index 16275d4bcf13..000000000000
--- a/mkhelp.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 1984-2017 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.
- *
- * For more information, see the README file.
- */
-
-
-/*
- * Silly little program to generate the help.c source file
- * from the less.hlp text file.
- * help.c just contains a char array whose contents are
- * the contents of less.hlp.
- */
-
-#include <stdio.h>
-
- int
-main(argc, argv)
- int argc;
- char *argv[];
-{
- int ch;
- int prevch;
-
- printf("/* This file was generated by mkhelp from less.hlp */\n");
- printf("#include \"less.h\"\n");
- printf("constant char helpdata[] = {\n");
- ch = 0;
- while (prevch = ch, (ch = getchar()) != EOF)
- {
- switch (ch)
- {
- case '\'':
- printf("'\\'',");
- break;
- case '\\':
- printf("'\\\\',");
- break;
- case '\b':
- printf("'\\b',");
- break;
- case '\t':
- printf("'\\t',");
- break;
- case '\n':
- if (prevch != '\r')
- printf("'\\n',\n");
- break;
- case '\r':
- if (prevch != '\n')
- printf("'\\n',\n");
- break;
- default:
- if (ch >= ' ' && ch < 0x7f)
- printf("'%c',", ch);
- else
- printf("0x%02x,", ch);
- break;
- }
- }
- /* Add an extra null char to avoid having a trailing comma. */
- printf(" 0 };\n");
- printf("constant int size_helpdata = sizeof(helpdata) - 1;\n");
- return (0);
-}
diff --git a/mkhelp.pl b/mkhelp.pl
new file mode 100755
index 000000000000..a826e208dca9
--- /dev/null
+++ b/mkhelp.pl
@@ -0,0 +1,44 @@
+#! /usr/bin/perl
+use strict;
+
+# Silly little program to generate the help.c source file
+# from the less.hlp text file.
+# The output of this script is a C program defining a char array
+# whose content is the input to this script.
+
+{
+ my ($sec,$min,$hour,$mday,$mon,$year) = gmtime();
+ printf "/* This file was generated by mkhelp.pl from less.hlp at %d:%02d on %d/%d/%d */\n",
+ $hour, $min, $year+1900, $mon+1, $mday;
+ print "#include \"less.h\"\n";
+ print "constant char helpdata[] = {\n";
+ my $ch = 0;
+ my $prevch;
+ for (;;) {
+ $prevch = $ch;
+ $ch = getc();
+ last if not defined $ch;
+ if ($ch eq "'") {
+ print "'\\'',";
+ } elsif ($ch eq "\\") {
+ print "'\\\\',";
+ } elsif ($ch eq "\b") {
+ print "'\\b',";
+ } elsif ($ch eq "\t") {
+ print "'\\t',";
+ } elsif ($ch eq "\n") {
+ print "'\\n',\n" if $prevch ne "\r";
+ } elsif ($ch eq "\r") {
+ print "'\\n',\n" if $prevch ne "\n";
+ } else {
+ if (ord($ch) >= ord(' ') && ord($ch) < 0x7f) {
+ print "'$ch',";
+ } else {
+ printf "0x%02x,", ord($ch);
+ }
+ }
+ }
+ # Add an extra null char to avoid having a trailing comma.
+ print " 0 };\n";
+ print "constant int size_helpdata = sizeof(helpdata) - 1;\n";
+}
diff --git a/mkutable b/mkutable
index ff107b51f007..276062876bc9 100755
--- a/mkutable
+++ b/mkutable
@@ -11,6 +11,16 @@ use vars qw( $opt_f $opt_n );
use Getopt::Std;
my $type_field = 2;
+# Override Unicode tables for certain control chars
+# that are expected to be found in normal text files.
+my %force_space = (
+ 0x08 => 1, # backspace
+ 0x09 => 1, # tab
+ 0x0a => 1, # newline
+ 0x0c => 1, # form feed
+ 0x0d => 1, # carriage return
+);
+
exit (main() ? 0 : 1);
sub main {
@@ -47,6 +57,7 @@ sub main {
my $type = $fields[$type_field];
$type =~ s/\s//g;
for ($last_code = $lo_code; $last_code <= $hi_code; ++$last_code) {
+ $type = 'Zs' if $force_space{$last_code};
output(\%out, $last_code, $type);
}
}
diff --git a/optfunc.c b/optfunc.c
index 4c79fe3f16b9..9185c011b108 100644
--- a/optfunc.c
+++ b/optfunc.c
@@ -50,6 +50,8 @@ extern int jump_sline;
extern long jump_sline_fraction;
extern int shift_count;
extern long shift_count_fraction;
+extern LWCHAR rscroll_char;
+extern int rscroll_attr;
extern int less_is_more;
#if LOGFILE
extern char *namelogfile;
@@ -68,6 +70,11 @@ extern int ul_fg_color, ul_bg_color;
extern int so_fg_color, so_bg_color;
extern int bl_fg_color, bl_bg_color;
extern int sgr_mode;
+#if MSDOS_COMPILER==WIN32C
+#ifndef COMMON_LVB_UNDERSCORE
+#define COMMON_LVB_UNDERSCORE 0x8000
+#endif
+#endif
#endif
@@ -81,6 +88,7 @@ opt_o(type, s)
char *s;
{
PARG parg;
+ char *filename;
if (secure)
{
@@ -106,7 +114,9 @@ opt_o(type, s)
s = skipsp(s);
if (namelogfile != NULL)
free(namelogfile);
- namelogfile = lglob(s);
+ filename = lglob(s);
+ namelogfile = shell_unquote(filename);
+ free(filename);
use_logfile(namelogfile);
sync_logfile();
break;
@@ -336,6 +346,7 @@ opt__T(type, s)
char *s;
{
PARG parg;
+ char *filename;
switch (type)
{
@@ -346,7 +357,9 @@ opt__T(type, s)
s = skipsp(s);
if (tags != NULL && tags != ztags)
free(tags);
- tags = lglob(s);
+ filename = lglob(s);
+ tags = shell_unquote(filename);
+ free(filename);
break;
case QUERY:
parg.p_string = tags;
@@ -540,12 +553,27 @@ colordesc(s, fg_color, bg_color)
{
int fg, bg;
int err;
-
+#if MSDOS_COMPILER==WIN32C
+ int ul = 0;
+
+ if (*s == 'u')
+ {
+ ul = COMMON_LVB_UNDERSCORE;
+ ++s;
+ }
+#endif
fg = getnum(&s, "D", &err);
if (err)
{
- error("Missing fg color in -D", NULL_PARG);
- return;
+#if MSDOS_COMPILER==WIN32C
+ if (ul)
+ fg = nm_fg_color;
+ else
+#endif
+ {
+ error("Missing fg color in -D", NULL_PARG);
+ return;
+ }
}
if (*s != '.')
bg = nm_bg_color;
@@ -559,6 +587,14 @@ colordesc(s, fg_color, bg_color)
return;
}
}
+#if MSDOS_COMPILER==WIN32C
+ if (*s == 'u')
+ {
+ ul = COMMON_LVB_UNDERSCORE;
+ ++s;
+ }
+ fg |= ul;
+#endif
if (*s != '\0')
error("Extra characters at end of -D option", NULL_PARG);
*fg_color = fg;
@@ -718,6 +754,40 @@ opt_quote(type, s)
}
/*
+ * Handler for the --rscroll option.
+ */
+ /*ARGSUSED*/
+ public void
+opt_rscroll(type, s)
+ int type;
+ char *s;
+{
+ PARG p;
+
+ switch (type)
+ {
+ case INIT:
+ case TOGGLE: {
+ char *fmt;
+ int attr = AT_STANDOUT;
+ setfmt(s, &fmt, &attr, "*s>");
+ if (strcmp(fmt, "-") == 0)
+ {
+ rscroll_char = 0;
+ } else
+ {
+ rscroll_char = *fmt ? *fmt : '>';
+ rscroll_attr = attr;
+ }
+ break; }
+ case QUERY: {
+ p.p_string = rscroll_char ? prchar(rscroll_char) : "-";
+ error("rscroll char is %s", &p);
+ break; }
+ }
+}
+
+/*
* "-?" means display a help message.
* If from the command line, exit immediately.
*/
diff --git a/option.h b/option.h
index 6adcdde27dbe..b253da86f102 100644
--- a/option.h
+++ b/option.h
@@ -60,7 +60,7 @@ struct loption
int otype; /* Type of the option */
int odefault; /* Default value */
int *ovar; /* Pointer to the associated variable */
- void (*ofunc) LESSPARAMS((int, char*)); /* Pointer to special handling function */
+ void (*ofunc) LESSPARAMS ((int, char*)); /* Pointer to special handling function */
char *odesc[3]; /* Description of each value */
};
diff --git a/opttbl.c b/opttbl.c
index 58ec347f4b68..0c68ccc3cd0f 100644
--- a/opttbl.c
+++ b/opttbl.c
@@ -53,6 +53,8 @@ public int quit_on_intr; /* Quit on interrupt */
public int follow_mode; /* F cmd Follows file desc or file name? */
public int oldbot; /* Old bottom of screen behavior {{REMOVE}} */
public int opt_use_backslash; /* Use backslash escaping in option parsing */
+public LWCHAR rscroll_char; /* Char which marks chopped lines with -S */
+public int rscroll_attr; /* Attribute of rscroll_char */
#if HILITE_SEARCH
public int hilite_search; /* Highlight matched search patterns? */
#endif
@@ -117,6 +119,7 @@ static struct optname keypad_optname = { "no-keypad", NULL };
static struct optname oldbot_optname = { "old-bot", NULL };
static struct optname follow_optname = { "follow-name", NULL };
static struct optname use_backslash_optname = { "use-backslash", NULL };
+static struct optname rscroll_optname = { "rscroll", NULL };
/*
@@ -456,6 +459,10 @@ static struct loption option[] =
NULL
}
},
+ { OLETTER_NONE, &rscroll_optname,
+ STRING|REPAINT|INIT_HANDLER, 0, NULL, opt_rscroll,
+ { "right scroll character: ", NULL, NULL }
+ },
{ '\0', NULL, NOVAR, 0, NULL, NULL, { NULL, NULL, NULL } }
};
diff --git a/output.c b/output.c
index cd9ccc25e7e1..c6a998120555 100644
--- a/output.c
+++ b/output.c
@@ -15,6 +15,9 @@
#include "less.h"
#if MSDOS_COMPILER==WIN32C
#include "windows.h"
+#ifndef COMMON_LVB_UNDERSCORE
+#define COMMON_LVB_UNDERSCORE 0x8000
+#endif
#endif
public int errmsgs; /* Count of messages displayed by error() */
@@ -38,6 +41,9 @@ extern int ul_fg_color, ul_bg_color;
extern int so_fg_color, so_bg_color;
extern int bl_fg_color, bl_bg_color;
extern int sgr_mode;
+#if MSDOS_COMPILER==WIN32C
+extern int have_ul;
+#endif
#endif
/*
@@ -127,9 +133,9 @@ flush()
* the -D command-line option.
*/
char *anchor, *p, *p_next;
- static unsigned char fg, fgi, bg, bgi;
- static unsigned char at;
- unsigned char f, b;
+ static int fg, fgi, bg, bgi;
+ static int at;
+ int f, b;
#if MSDOS_COMPILER==WIN32C
/* Screen colors used by 3x and 4x SGR commands. */
static unsigned char screen_color[] = {
@@ -259,8 +265,13 @@ flush()
case 7: /* inverse on */
at |= 2;
break;
- case 4: /* underline on */
- bgi = 8;
+ case 4: /* underline on */
+#if MSDOS_COMPILER==WIN32C
+ if (have_ul)
+ bgi = COMMON_LVB_UNDERSCORE >> 4;
+ else
+#endif
+ bgi = 8;
at |= 4;
break;
case 5: /* slow blink on */
@@ -356,7 +367,11 @@ flush()
if (at & 16)
f = b ^ 8;
f &= 0xf;
- b &= 0xf;
+#if MSDOS_COMPILER==WIN32C
+ b &= 0xf | (COMMON_LVB_UNDERSCORE >> 4);
+#else
+ b &= 0xf;
+#endif
WIN32setcolors(f, b);
p_next = anchor = p + 1;
} else
@@ -536,6 +551,9 @@ less_printf(fmt, parg)
col += iprint_linenum(parg->p_linenum);
parg++;
break;
+ case '%':
+ putchr('%');
+ break;
}
}
}
@@ -600,7 +618,7 @@ error(fmt, parg)
get_return();
lower_left();
- clear_eol();
+ clear_eol();
if (col >= sc_width)
/*
diff --git a/pattern.h b/pattern.h
index a2a4e0c660d6..7bde5c7fa171 100644
--- a/pattern.h
+++ b/pattern.h
@@ -32,15 +32,15 @@
#endif
#if HAVE_RE_COMP
-char *re_comp();
-int re_exec();
+char *re_comp LESSPARAMS ((char*));
+int re_exec LESSPARAMS ((char*));
#define PATTERN_TYPE int
#define CLEAR_PATTERN(name) name = 0
#endif
#if HAVE_REGCMP
-char *regcmp();
-char *regex();
+char *regcmp LESSPARAMS ((char*));
+char *regex LESSPARAMS ((char**, char*));
extern char *__loc1;
#define PATTERN_TYPE char **
#define CLEAR_PATTERN(name) name = NULL
diff --git a/position.c b/position.c
index d5e949e2919c..ae3899c1e95e 100644
--- a/position.c
+++ b/position.c
@@ -36,21 +36,22 @@ extern int sc_width, sc_height;
* the line after the bottom line on the screen
*/
public POSITION
-position(where)
- int where;
+position(sindex)
+ int sindex;
{
- switch (where)
+ switch (sindex)
{
case BOTTOM:
- where = sc_height - 2;
+ sindex = sc_height - 2;
break;
case BOTTOM_PLUS_ONE:
- where = sc_height - 1;
+ sindex = sc_height - 1;
break;
case MIDDLE:
- where = (sc_height - 1) / 2;
+ sindex = (sc_height - 1) / 2;
+ break;
}
- return (table[where]);
+ return (table[sindex]);
}
/*
@@ -115,7 +116,7 @@ pos_init()
*/
if (table != NULL)
{
- get_scrpos(&scrpos);
+ get_scrpos(&scrpos, TOP);
free((char*)table);
} else
scrpos.pos = NULL_POSITION;
@@ -176,22 +177,34 @@ empty_lines(s, e)
* the screen line to a number > 0.
*/
public void
-get_scrpos(scrpos)
+get_scrpos(scrpos, where)
struct scrpos *scrpos;
+ int where;
{
int i;
+ int dir;
+ int last;
+
+ switch (where)
+ {
+ case TOP: i = 0; dir = +1; last = sc_height-2; break;
+ default: i = sc_height-2; dir = -1; last = 0; break;
+ }
/*
* Find the first line on the screen which has something on it,
* and return the screen line number and the file position.
*/
- for (i = 0; i < sc_height; i++)
+ for (;; i += dir)
+ {
if (table[i] != NULL_POSITION)
{
scrpos->ln = i+1;
scrpos->pos = table[i];
return;
}
+ if (i == last) break;
+ }
/*
* The screen is empty.
*/
@@ -208,7 +221,7 @@ get_scrpos(scrpos)
* relative to the bottom of the screen.
*/
public int
-adjsline(sline)
+sindex_from_sline(sline)
int sline;
{
/*
@@ -218,12 +231,12 @@ adjsline(sline)
if (sline < 0)
sline += sc_height;
/*
- * Can't be less than 1 or greater than sc_height-1.
+ * Can't be less than 1 or greater than sc_height.
*/
if (sline <= 0)
sline = 1;
- if (sline >= sc_height)
- sline = sc_height - 1;
+ if (sline > sc_height)
+ sline = sc_height;
/*
* Return zero-based line number, not one-based.
*/
diff --git a/prompt.c b/prompt.c
index bf4f7291df28..3067d2bbe3c3 100644
--- a/prompt.c
+++ b/prompt.c
@@ -464,7 +464,7 @@ wherechar(p, wp)
case 'm': *wp = MIDDLE; break;
case 'b': *wp = BOTTOM; break;
case 'B': *wp = BOTTOM_PLUS_ONE; break;
- case 'j': *wp = adjsline(jump_sline); break;
+ case 'j': *wp = sindex_from_sline(jump_sline); break;
default: *wp = TOP; p--; break;
}
}
diff --git a/screen.c b/screen.c
index 5b3682731d10..dfee5d217040 100644
--- a/screen.c
+++ b/screen.c
@@ -126,16 +126,21 @@ static HANDLE con_out_save = INVALID_HANDLE_VALUE; /* previous console */
static HANDLE con_out_ours = INVALID_HANDLE_VALUE; /* our own */
HANDLE con_out = INVALID_HANDLE_VALUE; /* current console */
+extern int utf_mode;
extern int quitting;
static void win32_init_term();
static void win32_deinit_term();
+#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
+#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 4
+#endif
+
#define FG_COLORS (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY)
#define BG_COLORS (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY)
#define MAKEATTR(fg,bg) ((WORD)((fg)|((bg)<<4)))
#define SETCOLORS(fg,bg) { curr_attr = MAKEATTR(fg,bg); \
if (SetConsoleTextAttribute(con_out, curr_attr) == 0) \
- error("SETCOLORS failed"); }
+ error("SETCOLORS failed", NULL_PARG); }
#endif
#if MSDOS_COMPILER
@@ -152,7 +157,9 @@ public int bl_bg_color;
static int sy_fg_color; /* Color of system text (before less) */
static int sy_bg_color;
public int sgr_mode; /* Honor ANSI sequences rather than using above */
-
+#if MSDOS_COMPILER==WIN32C
+public int have_ul; /* Is underline available? */
+#endif
#else
/*
@@ -201,6 +208,7 @@ public int above_mem, below_mem; /* Memory retained above/below screen */
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 */
static int attrmode = AT_NORMAL;
extern int binattr;
@@ -1210,7 +1218,8 @@ get_term()
sc_e_keypad = ltgetstr("ke", &sp);
if (sc_e_keypad == NULL)
sc_e_keypad = "";
-
+ kent = ltgetstr("@8", &sp);
+
sc_init = ltgetstr("ti", &sp);
if (sc_init == NULL)
sc_init = "";
@@ -1498,6 +1507,8 @@ win32_init_term()
if (con_out_ours == INVALID_HANDLE_VALUE)
{
+ DWORD output_mode;
+
/*
* Create our own screen buffer, so that we
* may restore the original when done.
@@ -1508,6 +1519,12 @@ win32_init_term()
(LPSECURITY_ATTRIBUTES) NULL,
CONSOLE_TEXTMODE_BUFFER,
(LPVOID) NULL);
+ /*
+ * Enable underline, if available.
+ */
+ GetConsoleMode(con_out_ours, &output_mode);
+ have_ul = SetConsoleMode(con_out_ours,
+ output_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
}
size.X = scr.srWindow.Right - scr.srWindow.Left + 1;
@@ -1828,6 +1845,8 @@ win32_scroll_up(n)
public void
lower_left()
{
+ if (!init_done)
+ return;
#if !MSDOS_COMPILER
tputs(sc_lower_left, 1, putchr);
#else
@@ -1902,14 +1921,14 @@ check_winch()
* Goto a specific line on the screen.
*/
public void
-goto_line(slinenum)
- int slinenum;
+goto_line(sindex)
+ int sindex;
{
#if !MSDOS_COMPILER
- tputs(tgoto(sc_move, 0, slinenum), 1, putchr);
+ tputs(tgoto(sc_move, 0, sindex), 1, putchr);
#else
flush();
- _settextposition(slinenum+1, 1);
+ _settextposition(sindex+1, 1);
#endif
}
@@ -2508,7 +2527,18 @@ WIN32textout(text, len)
{
#if MSDOS_COMPILER==WIN32C
DWORD written;
- WriteConsole(con_out, text, len, &written, NULL);
+ if (utf_mode == 2)
+ {
+ /*
+ * We've got UTF-8 text in a non-UTF-8 console. Convert it to
+ * wide and use WriteConsoleW.
+ */
+ WCHAR wtext[1024];
+ len = MultiByteToWideChar(CP_UTF8, 0, text, len, wtext,
+ sizeof(wtext)/sizeof(*wtext));
+ WriteConsoleW(con_out, wtext, len, &written, NULL);
+ } else
+ WriteConsole(con_out, text, len, &written, NULL);
#else
char c = text[len];
text[len] = '\0';
diff --git a/search.c b/search.c
index 84f9288a229c..72191889af97 100644
--- a/search.c
+++ b/search.c
@@ -258,7 +258,7 @@ prev_pattern(info)
repaint_hilite(on)
int on;
{
- int slinenum;
+ int sindex;
POSITION pos;
int save_hide_hilite;
@@ -280,13 +280,13 @@ repaint_hilite(on)
return;
}
- for (slinenum = TOP; slinenum < TOP + sc_height-1; slinenum++)
+ for (sindex = TOP; sindex < TOP + sc_height-1; sindex++)
{
- pos = position(slinenum);
+ pos = position(sindex);
if (pos == NULL_POSITION)
continue;
(void) forw_line(pos);
- goto_line(slinenum);
+ goto_line(sindex);
put_line();
}
lower_left();
@@ -299,7 +299,7 @@ repaint_hilite(on)
public void
clear_attn()
{
- int slinenum;
+ int sindex;
POSITION old_start_attnpos;
POSITION old_end_attnpos;
POSITION pos;
@@ -320,17 +320,17 @@ clear_attn()
if (squished)
repaint();
- for (slinenum = TOP; slinenum < TOP + sc_height-1; slinenum++)
+ for (sindex = TOP; sindex < TOP + sc_height-1; sindex++)
{
- pos = position(slinenum);
+ pos = position(sindex);
if (pos == NULL_POSITION)
continue;
- epos = position(slinenum+1);
- if (pos < old_end_attnpos &&
+ epos = position(sindex+1);
+ if (pos <= old_end_attnpos &&
(epos == NULL_POSITION || epos > old_start_attnpos))
{
(void) forw_line(pos);
- goto_line(slinenum);
+ goto_line(sindex);
put_line();
moved = 1;
}
@@ -348,9 +348,14 @@ undo_search()
{
if (!prev_pattern(&search_info))
{
- error("No previous regular expression", NULL_PARG);
- return;
+ if (hilite_anchor.first == NULL)
+ {
+ error("No previous regular expression", NULL_PARG);
+ return;
+ }
+ clr_hilite(); /* Next time, hilite_anchor.first will be NULL. */
}
+ clear_pattern(&search_info);
#if HILITE_SEARCH
hide_hilite = !hide_hilite;
repaint_hilite(1);
@@ -620,11 +625,18 @@ is_hilited(pos, epos, nohide, p_matches)
if (!match)
return (0);
- if (p_matches != NULL)
+ if (p_matches == NULL)
/*
- * Report matches, even if we're hiding highlights.
+ * Kinda kludgy way to recognize that caller is checking for
+ * hilite in status column. In this case we want to return
+ * hilite status even if hiliting is disabled or hidden.
*/
- *p_matches = 1;
+ return (1);
+
+ /*
+ * Report matches, even if we're hiding highlights.
+ */
+ *p_matches = 1;
if (hilite_search == 0)
/*
@@ -1023,7 +1035,7 @@ hilite_screen()
{
struct scrpos scrpos;
- get_scrpos(&scrpos);
+ get_scrpos(&scrpos, TOP);
if (scrpos.pos == NULL_POSITION)
return;
prep_hilite(scrpos.pos, position(BOTTOM_PLUS_ONE), -1);
@@ -1058,7 +1070,7 @@ search_pos(search_type)
int search_type;
{
POSITION pos;
- int linenum;
+ int sindex;
if (empty_screen())
{
@@ -1081,7 +1093,7 @@ search_pos(search_type)
pos = ch_length();
}
}
- linenum = 0;
+ sindex = 0;
} else
{
int add_one = 0;
@@ -1092,18 +1104,18 @@ search_pos(search_type)
* Search does not include current screen.
*/
if (search_type & SRCH_FORW)
- linenum = sc_height-1; /* BOTTOM_PLUS_ONE */
+ sindex = sc_height-1; /* BOTTOM_PLUS_ONE */
else
- linenum = 0; /* TOP */
+ sindex = 0; /* TOP */
} else if (how_search == OPT_ONPLUS && !(search_type & SRCH_AFTER_TARGET))
{
/*
* Search includes all of displayed screen.
*/
if (search_type & SRCH_FORW)
- linenum = 0; /* TOP */
+ sindex = 0; /* TOP */
else
- linenum = sc_height-1; /* BOTTOM_PLUS_ONE */
+ sindex = sc_height-1; /* BOTTOM_PLUS_ONE */
} else
{
/*
@@ -1111,11 +1123,11 @@ search_pos(search_type)
* It starts at the jump target (if searching backwards),
* or at the jump target plus one (if forwards).
*/
- linenum = adjsline(jump_sline);
+ sindex = sindex_from_sline(jump_sline);
if (search_type & SRCH_FORW)
add_one = 1;
}
- pos = position(linenum);
+ pos = position(sindex);
if (add_one)
pos = forw_raw_line(pos, (char **)NULL, (int *)NULL);
}
@@ -1127,17 +1139,17 @@ search_pos(search_type)
{
while (pos == NULL_POSITION)
{
- if (++linenum >= sc_height)
+ if (++sindex >= sc_height)
break;
- pos = position(linenum);
+ pos = position(sindex);
}
} else
{
while (pos == NULL_POSITION)
{
- if (--linenum < 0)
+ if (--sindex < 0)
break;
- pos = position(linenum);
+ pos = position(sindex);
}
}
return (pos);
@@ -1419,7 +1431,7 @@ search(search_type, pattern, n)
return -1;
}
#if HILITE_SEARCH
- if (hilite_search == OPT_ON)
+ if (hilite_search == OPT_ON || status_col)
{
/*
* Erase the highlights currently on screen.
@@ -1446,7 +1458,7 @@ search(search_type, pattern, n)
if (set_pattern(&search_info, pattern, search_type) < 0)
return (-1);
#if HILITE_SEARCH
- if (hilite_search)
+ if (hilite_search || status_col)
{
/*
* Erase the highlights currently on screen.
@@ -1456,7 +1468,7 @@ search(search_type, pattern, n)
hide_hilite = 0;
clr_hilite();
}
- if (hilite_search == OPT_ONPLUS)
+ if (hilite_search == OPT_ONPLUS || status_col)
{
/*
* Highlight any matches currently on screen,
@@ -1478,7 +1490,8 @@ search(search_type, pattern, n)
*/
if (search_type & SRCH_PAST_EOF)
return (n);
- /* repaint(); -- why was this here? */
+ if (hilite_search == OPT_ON || status_col)
+ repaint_hilite(1);
error("Nothing to search", NULL_PARG);
return (-1);
}
@@ -1491,7 +1504,7 @@ search(search_type, pattern, n)
* Search was unsuccessful.
*/
#if HILITE_SEARCH
- if (hilite_search == OPT_ON && n > 0)
+ if ((hilite_search == OPT_ON || status_col) && n > 0)
/*
* Redisplay old hilites.
*/
@@ -1509,7 +1522,7 @@ search(search_type, pattern, n)
}
#if HILITE_SEARCH
- if (hilite_search == OPT_ON)
+ if (hilite_search == OPT_ON || status_col)
/*
* Display new hilites in the matching line.
*/
diff --git a/signal.c b/signal.c
index 03c389c39e89..f53b2f90e832 100644
--- a/signal.c
+++ b/signal.c
@@ -78,22 +78,16 @@ stop(type)
}
#endif
+#undef SIG_LESSWINDOW
#ifdef SIGWINCH
-/*
- * "Window" change handler
- */
- /* ARGSUSED*/
- public RETSIGTYPE
-winch(type)
- int type;
-{
- LSIGNAL(SIGWINCH, winch);
- sigs |= S_WINCH;
- if (reading)
- intread();
-}
+#define SIG_LESSWINDOW SIGWINCH
#else
#ifdef SIGWIND
+#define SIG_LESSWINDOW SIGWIND
+#endif
+#endif
+
+#ifdef SIG_LESSWINDOW
/*
* "Window" change handler
*/
@@ -102,13 +96,12 @@ winch(type)
winch(type)
int type;
{
- LSIGNAL(SIGWIND, winch);
+ LSIGNAL(SIG_LESSWINDOW, winch);
sigs |= S_WINCH;
if (reading)
intread();
}
#endif
-#endif
#if MSDOS_COMPILER==WIN32C
/*
@@ -133,6 +126,13 @@ wbreak_handler(dwCtrlType)
}
#endif
+ static RETSIGTYPE
+terminate(type)
+ int type;
+{
+ quit(15);
+}
+
/*
* Set up the signal handlers.
*/
@@ -161,6 +161,9 @@ init_signals(on)
#ifdef SIGQUIT
(void) LSIGNAL(SIGQUIT, SIG_IGN);
#endif
+#ifdef SIGTERM
+ (void) LSIGNAL(SIGTERM, terminate);
+#endif
} else
{
/*
@@ -182,6 +185,9 @@ init_signals(on)
#ifdef SIGQUIT
(void) LSIGNAL(SIGQUIT, SIG_DFL);
#endif
+#ifdef SIGTERM
+ (void) LSIGNAL(SIGTERM, SIG_DFL);
+#endif
}
}
diff --git a/tags.c b/tags.c
index f59d25b411f4..ebb30488de1e 100644
--- a/tags.c
+++ b/tags.c
@@ -22,6 +22,7 @@ static int curseq;
extern int linenums;
extern int sigs;
+extern int ctldisp;
enum tag_result {
TAG_FOUND,
@@ -100,6 +101,8 @@ cleantags()
while ((tp = taglist.tl_first) != TAG_END)
{
TAG_RM(tp);
+ free(tp->tag_file);
+ free(tp->tag_pattern);
free(tp);
}
curtag = NULL;
@@ -384,6 +387,26 @@ edit_tagfile()
return (edit(curtag->tag_file));
}
+ static int
+curtag_match(char const *line, POSITION linepos)
+{
+ /*
+ * Test the line to see if we have a match.
+ * Use strncmp because the pattern may be
+ * truncated (in the tags file) if it is too long.
+ * If tagendline is set, make sure we match all
+ * the way to end of line (no extra chars after the match).
+ */
+ int len = (int) strlen(curtag->tag_pattern);
+ if (strncmp(curtag->tag_pattern, line, len) == 0 &&
+ (!curtag->tag_endline || line[len] == '\0' || line[len] == '\r'))
+ {
+ curtag->tag_linenum = find_linenum(linepos);
+ return 1;
+ }
+ return 0;
+}
+
/*
* Search for a tag.
* This is a stripped-down version of search().
@@ -398,13 +421,14 @@ ctagsearch()
{
POSITION pos, linepos;
LINENUM linenum;
- int len;
+ int line_len;
char *line;
+ int found;
pos = ch_zero();
linenum = find_linenum(pos);
- for (;;)
+ for (found = 0; !found;)
{
/*
* Get lines until we find a matching one or
@@ -418,7 +442,7 @@ ctagsearch()
* starting position of that line in linepos.
*/
linepos = pos;
- pos = forw_raw_line(pos, &line, (int *)NULL);
+ pos = forw_raw_line(pos, &line, &line_len);
if (linenum != 0)
linenum++;
@@ -439,19 +463,21 @@ ctagsearch()
if (linenums)
add_lnum(linenum, pos);
- /*
- * Test the line to see if we have a match.
- * Use strncmp because the pattern may be
- * truncated (in the tags file) if it is too long.
- * If tagendline is set, make sure we match all
- * the way to end of line (no extra chars after the match).
- */
- len = (int) strlen(curtag->tag_pattern);
- if (strncmp(curtag->tag_pattern, line, len) == 0 &&
- (!curtag->tag_endline || line[len] == '\0' || line[len] == '\r'))
+ if (ctldisp != OPT_ONPLUS)
{
- curtag->tag_linenum = find_linenum(linepos);
- break;
+ if (curtag_match(line, linepos))
+ found = 1;
+ } else
+ {
+ int cvt_ops = CVT_ANSI;
+ int cvt_len = cvt_length(line_len, cvt_ops);
+ int *chpos = cvt_alloc_chpos(cvt_len);
+ char *cline = (char *) ecalloc(1, cvt_len);
+ cvt_text(cline, line, chpos, &line_len, cvt_ops);
+ if (curtag_match(cline, linepos))
+ found = 1;
+ free(chpos);
+ free(cline);
}
}
diff --git a/ubin.uni b/ubin.uni
index 17c45903003f..888fe75ca841 100644
--- a/ubin.uni
+++ b/ubin.uni
@@ -1,32 +1,16 @@
-/* Generated by "./mkutable -f2 Cc Cf Cs Co Zl Zp -- unicode/UnicodeData.txt" on Tue Sep 20 10:51:43 PDT 2016 */
- { 0x0000, 0x001f }, /* Cc */
+/* Generated by "./mkutable -f2 Cc Cs Co Zl Zp -- unicode/UnicodeData.txt" on Tue Jul 25 09:04:35 PDT 2017 */
+ { 0x0000, 0x0007 }, /* Cc */
+ { 0x000b, 0x000b }, /* Cc */
+ { 0x000e, 0x001f }, /* Cc */
{ 0x007f, 0x009f }, /* Cc */
- { 0x00ad, 0x00ad }, /* Cf */
- { 0x0600, 0x0605 }, /* Cf */
- { 0x061c, 0x061c }, /* Cf */
- { 0x06dd, 0x06dd }, /* Cf */
- { 0x070f, 0x070f }, /* Cf */
- { 0x08e2, 0x08e2 }, /* Cf */
- { 0x180e, 0x180e }, /* Cf */
- { 0x200b, 0x200f }, /* Cf */
{ 0x2028, 0x2028 }, /* Zl */
{ 0x2029, 0x2029 }, /* Zp */
- { 0x202a, 0x202e }, /* Cf */
- { 0x2060, 0x2064 }, /* Cf */
- { 0x2066, 0x206f }, /* Cf */
{ 0xd800, 0xd800 }, /* Cs */
{ 0xdb7f, 0xdb80 }, /* Cs */
{ 0xdbff, 0xdc00 }, /* Cs */
{ 0xdfff, 0xdfff }, /* Cs */
{ 0xe000, 0xe000 }, /* Co */
{ 0xf8ff, 0xf8ff }, /* Co */
- { 0xfeff, 0xfeff }, /* Cf */
- { 0xfff9, 0xfffb }, /* Cf */
- { 0x110bd, 0x110bd }, /* Cf */
- { 0x1bca0, 0x1bca3 }, /* Cf */
- { 0x1d173, 0x1d17a }, /* Cf */
- { 0xe0001, 0xe0001 }, /* Cf */
- { 0xe0020, 0xe007f }, /* Cf */
{ 0xf0000, 0xf0000 }, /* Co */
{ 0xffffd, 0xffffd }, /* Co */
{ 0x100000, 0x100000 }, /* Co */
diff --git a/version.c b/version.c
index 3240d4b2ce25..d1e18d06a78c 100644
--- a/version.c
+++ b/version.c
@@ -811,6 +811,47 @@ v489 3/30/17 Make -F not do init/deinit if file fits on one screen
(thanks to Jindrich Novy).
v490 4/5/17 Switch to ANSI prototypes in funcs.h; remove "register".
v491 4/7/17 Fix signed char bug.
+v492 4/21/17 Handle SIGTERM.
+v493 6/22/17 Fix bug initializing charset in MSDOS build.
+v494 6/26/17 Update Unicode tables; make Cf chars composing not binary.
+v495 7/3/17 Improve binary file detection (thanks to Bela Lubkin);
+ do -R filter when matching tags (thanks to Matthew Malcomson).
+v496 7/5/17 Add LESSRSCROLL marker.
+v497 7/5/17 Sync.
+v498 7/7/17 Fix early truncation of text if last char is double-width.
+v499 7/10/17 Misc fixes.
+v500 7/11/17 Fix bug where certain env variables couldn't be set in lesskey.
+v501 7/12/17 Make sure rscroll char is standout by default.
+v502 7/13/17 Control rscroll char via command line option not env variable.
+v503 7/13/17 Switch to git.
+v504 7/13/17 Call opt_rscroll at startup; change mkhelp.c to mkhelp.pl.
+v505 7/17/17 Add M and ESC-M commands;
+ fix buffer handling with stdin and LESSOPEN.
+v506 7/17/17 On Windows, convert UTF-8 to multibyte if console is not UTF-8;
+ handle extended chars on input (thanks to Jason Hood).
+v507 7/18/17 Fix some bugs handling filenames containing shell metachars.
+v508 7/19/17 Fix bugs when using LESSOPEN to read stdin.
+v509 7/19/17 Fix another stdin bug.
+v510 7/20/17 Fix bug in determining when to reopen a file.
+v511 7/25/17 Fix bugs in recent MSDOS changes (thanks to Jason Hood).
+v512 7/26/17 Fix MSDOS build.
+v513 7/26/17 Fix switch to normal attr at end of line with -R and rscroll.
+v514 7/27/17 Fix bug in fcomplete when pattern does not match a file.
+v515 7/28/17 Allow 'u' in -D option on Windows.
+v516 7/29/17 Fix bug using LESSOPEN with filename containing metachars.
+v517 7/30/17 Status column shows matches even if hiliting is disabled via -G.
+v518 8/1/17 Use underline in sgr mode in MSDOS (thanks to Jason Hood).
+v519 8/10/17 Fix rscroll bug when last char of line starts coloration.
+v520 9/3/17 Fix compiler warning.
+v521 10/20/17 Fix binary file warning in UTF-8 files with SGI sequences.
+v522 10/20/17 Handle keypad ENTER key properly.
+v523 10/23/17 Cleanup.
+v524 10/24/17 Fix getcc bug.
+v525 10/24/17 Change M command to mark last displayed line.
+v526 10/25/17 Fix search hilite bug introduced in v517.
+v527 10/30/17 Fix search hilite bug on last page with -a.
+v528 11/3/17 Make second ESC-u clear status column.
+v529 11/12/17 Display Unicode formatting chars in hex if -U is set.
*/
-char version[] = "491";
+char version[] = "529";
diff --git a/wide.uni b/wide.uni
index 17c385914f7a..801a3525e4a5 100644
--- a/wide.uni
+++ b/wide.uni
@@ -1,4 +1,4 @@
-/* Generated by "./mkutable -f1 W F -- unicode/EastAsianWidth.txt" on Tue Sep 20 10:51:43 PDT 2016 */
+/* Generated by "./mkutable -f1 W F -- unicode/EastAsianWidth.txt" on Tue Jul 25 09:04:35 PDT 2017 */
{ 0x1100, 0x115f }, /* W */
{ 0x231a, 0x231b }, /* W */
{ 0x2329, 0x232a }, /* W */
@@ -42,7 +42,7 @@
{ 0x3001, 0x303e }, /* W */
{ 0x3041, 0x3096 }, /* W */
{ 0x3099, 0x30ff }, /* W */
- { 0x3105, 0x312d }, /* W */
+ { 0x3105, 0x312e }, /* W */
{ 0x3131, 0x318e }, /* W */
{ 0x3190, 0x31ba }, /* W */
{ 0x31c0, 0x31e3 }, /* W */
@@ -61,10 +61,11 @@
{ 0xfe68, 0xfe6b }, /* W */
{ 0xff01, 0xff60 }, /* F */
{ 0xffe0, 0xffe6 }, /* F */
- { 0x16fe0, 0x16fe0 }, /* W */
+ { 0x16fe0, 0x16fe1 }, /* W */
{ 0x17000, 0x187ec }, /* W */
{ 0x18800, 0x18af2 }, /* W */
- { 0x1b000, 0x1b001 }, /* W */
+ { 0x1b000, 0x1b11e }, /* W */
+ { 0x1b170, 0x1b2fb }, /* W */
{ 0x1f004, 0x1f004 }, /* W */
{ 0x1f0cf, 0x1f0cf }, /* W */
{ 0x1f18e, 0x1f18e }, /* W */
@@ -73,6 +74,7 @@
{ 0x1f210, 0x1f23b }, /* W */
{ 0x1f240, 0x1f248 }, /* W */
{ 0x1f250, 0x1f251 }, /* W */
+ { 0x1f260, 0x1f265 }, /* W */
{ 0x1f300, 0x1f320 }, /* W */
{ 0x1f32d, 0x1f335 }, /* W */
{ 0x1f337, 0x1f37c }, /* W */
@@ -95,14 +97,12 @@
{ 0x1f6cc, 0x1f6cc }, /* W */
{ 0x1f6d0, 0x1f6d2 }, /* W */
{ 0x1f6eb, 0x1f6ec }, /* W */
- { 0x1f6f4, 0x1f6f6 }, /* W */
- { 0x1f910, 0x1f91e }, /* W */
- { 0x1f920, 0x1f927 }, /* W */
- { 0x1f930, 0x1f930 }, /* W */
- { 0x1f933, 0x1f93e }, /* W */
- { 0x1f940, 0x1f94b }, /* W */
- { 0x1f950, 0x1f95e }, /* W */
- { 0x1f980, 0x1f991 }, /* W */
+ { 0x1f6f4, 0x1f6f8 }, /* W */
+ { 0x1f910, 0x1f93e }, /* W */
+ { 0x1f940, 0x1f94c }, /* W */
+ { 0x1f950, 0x1f96b }, /* W */
+ { 0x1f980, 0x1f997 }, /* W */
{ 0x1f9c0, 0x1f9c0 }, /* W */
+ { 0x1f9d0, 0x1f9e6 }, /* W */
{ 0x20000, 0x2fffd }, /* W */
{ 0x30000, 0x3fffd }, /* W */