less: upgrade to v581.

MFC after:	2 weeks
This commit is contained in:
Xin LI 2021-04-18 19:46:19 -07:00
commit 2235c7feac
55 changed files with 3772 additions and 2297 deletions

View File

@ -1,6 +1,6 @@
This file describes how to build and install less using
the "configure" script. This only works on Unix systems.
To install on other systems, read the README file.
This file contains generic instructions on how to build and
install software using autoconf. For specific instructions
on how to build "less", see the README or README.VER file.
Basic Installation
@ -24,8 +24,8 @@ diffs or instructions to the address given in the `README' so they can
be considered for the next release. If at some point `config.cache'
contains results you don't want to keep, you may remove or edit it.
The file `configure.in' is used to create `configure' by a program
called `autoconf'. You only need `configure.in' if you want to change
The file `configure.ac' is used to create `configure' by a program
called `autoconf'. You only need `configure.ac' if you want to change
it or regenerate `configure' using a newer version of `autoconf'.
The simplest way to compile this package is:

View File

@ -4,10 +4,56 @@
======================================================================
For the latest news about less, see the "less" Web page:
http://www.greenwoodsoftware.com/less
https://greenwoodsoftware.com/less
You can also download the latest version of less from there.
To report bugs, suggestions or comments, send email to bug-less@gnu.org
Report bugs, suggestions or comments at
https://github.com/gwsw/less/issues.
======================================================================
Major changes between "less" versions 563 and 581
* Change ESC-u command to toggle, not disable, highlighting per man page.
* Add ESC-U command.
* Add ctrl-W search modifier for wrapping search.
* F command can be interrupted by ^X.
* Support OSC 8 hyperlinks when -R is in effect.
* g command with no number will ignore -j and put first line at top of screen.
* Multiple + or -p command line options are handled better.
* Add the --incsearch option.
* Add the --line-num-width option.
* Add the --status-col-width option.
* Add the --use-color and --color options.
* Display -w highlight even if highlighted line is empty.
* If search result is in a long line, scroll to ensure it is visible.
* Editing the same file under different names now creates only
one entry in the file list.
* Make visual bell more visible on some terminals.
* Ring end-of-file bell no more than once per second.
* Build can use either Python or Perl for Makefile.aut operations.
* Fix crash when using the @ search modifier.
* Fix crash in the 's' command due to duplicate free.
* Fix realpath crash on Darwin.
======================================================================

View File

@ -7,9 +7,9 @@
**************************************************************************
**************************************************************************
Less, version 563
Less, version 581
This is the distribution of less, version 563, released 13 Jun 2020.
This is the distribution of less, version 581, released 06 Apr 2021.
This program is part of the GNU project (http://www.gnu.org).
This program is free software. You may redistribute it and/or
@ -21,33 +21,29 @@
or
2. The Less License, in the file LICENSE.
Please report any problems to bug-less@gnu.org.
See http://www.greenwoodsoftware.com/less for the latest info.
Please report any problems at https://github.com/gwsw/less/issues.
See https://greenwoodsoftware.com/less for the latest info.
Source repository is at https://github.com/gwsw/less.git.
=========================================================================
This is the distribution of "less", a paginator similar to "more" or "pg".
The formatted manual page is in less.man.
The manual page nroff source is in less.nro.
Major changes made since the last posted version are in NEWS.
=======================================================================
PRE-INSTALLATION (when using git)
If you are building from a clone of a git repository,
type "make -f Makefile.aut".
If you are building from a numbered release package (a tar or zip file
with a name like less-999.tar.gz or less-999.zip), you should skip this step.
=======================================================================
INSTALLATION (Unix systems only):
INSTALLATION (Unix & Linux systems only):
1. Move the distributed source to its own directory and unpack it,
if you have not already done so.
2. Type "sh configure".
2. If you are building from a clone of a git repository,
type "make -f Makefile.aut".
If you are building from a numbered release package (a tar or
zip file with a name like less-999.tar.gz or less-999.zip downloaded
from greenwoodsoftware.com, not from github), you should skip this step.
3. Type "sh configure".
This will generate a Makefile and a defines.h.
Warning: if you have a GNU sed, make sure it is version 2.05 or later.
@ -79,7 +75,7 @@ INSTALLATION (Unix systems only):
commands, etc.
3. It is a good idea to look over the generated Makefile and defines.h
4. It is a good idea to look over the generated Makefile and defines.h
and make sure they look ok. If you know of any peculiarities of
your system that configure might not have detected, you may fix the
Makefile now. Take particular notice of the list of "terminal"
@ -93,13 +89,13 @@ INSTALLATION (Unix systems only):
to remove the descriptions of the features which you are removing.
If you edit less.hlp, you should run "make -f Makefile.aut help.c".
4. Type "make" and watch the fun.
5. Type "make" and watch the fun.
5. If the make succeeds, it will generate the programs "less",
6. If the make succeeds, it will generate the programs "less",
"lesskey" and "lessecho" in your current directory. Test the
generated programs.
6. When satisfied that it works, if you wish to install it
7. When satisfied that it works, if you wish to install it
in a public place, type "make install".
The default install destinations are:
@ -108,8 +104,6 @@ INSTALLATION (Unix systems only):
If you want to install any of these files elsewhere, define
bindir and/or mandir to the appropriate directories.
If you have any problems building or running "less", suggestions,
complaints, etc., you may mail to bug-less@gnu.org.
Note to hackers: comments noting possible improvements are enclosed
in double curly brackets {{ like this }}.

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.
@ -311,13 +311,7 @@ ch_get(VOID_PARAM)
parg.p_string = wait_message();
ierror("%s", &parg);
}
#if !MSDOS_COMPILER
sleep(1);
#else
#if MSDOS_COMPILER==WIN32C
Sleep(1000);
#endif
#endif
sleep_ms(2); /* Reduce system load */
slept = TRUE;
#if HAVE_STAT_INO

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.
@ -121,7 +121,7 @@ struct cs_alias {
static char chardef[256];
static char *binfmt = NULL;
static char *utfbinfmt = NULL;
public int binattr = AT_STANDOUT;
public int binattr = AT_STANDOUT|AT_COLOR_BIN;
/*

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.
@ -31,7 +31,6 @@
#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
@ -72,19 +71,19 @@
#define A_CLRMARK 62
#define A_SETMARKBOT 63
#define A_X11MOUSE_IN 64
#define A_X11MOUSE_IGNORE 65
#define A_F_MOUSE 66
#define A_B_MOUSE 67
/* Note "X116" refers to extended (1006) X11 mouse reporting. */
#define A_X116MOUSE_IN 68
#define A_X116MOUSE_IGNORE 69
#define A_CLR_SEARCH 70
/* These values must not conflict with any A_* or EC_* value. */
#define A_INVALID 100
#define A_NOACTION 101
#define A_UINVALID 102
#define A_END_LIST 103
#define A_SPECIAL_KEY 104
#define A_PREFIX 105
#define A_SKIP 127
#define A_EXTRA 0200
@ -111,15 +110,16 @@
#define EC_B_COMPLETE 18
#define EC_LITERAL 19
#define EC_ABORT 20
#define EC_X11MOUSE 21
#define EC_X116MOUSE 22
#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 ECF_PEEK 01
#define ECF_NOHISTORY 02
#define ECF_NOCOMPLETE 04
#define ECF_NORIGHTLEFT 010
/* Environment variable stuff */
#define EV_OK 01

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.
@ -259,17 +259,42 @@ cmd_step_left(pp, pwidth, bswidth)
return cmd_step_common(*pp, ch, p - *pp, pwidth, bswidth);
}
/*
* Put the cursor at "home" (just after the prompt),
* and set cp to the corresponding char in cmdbuf.
*/
static void
cmd_home(VOID_PARAM)
{
while (cmd_col > prompt_col)
{
int width, bswidth;
cmd_step_left(&cp, &width, &bswidth);
while (bswidth-- > 0)
putbs();
cmd_col -= width;
}
cp = &cmdbuf[cmd_offset];
}
/*
* Repaint the line from cp onwards.
* Then position the cursor just after the char old_cp (a pointer into cmdbuf).
*/
static void
public void
cmd_repaint(old_cp)
constant char *old_cp;
{
/*
* Repaint the line from the current position.
*/
if (old_cp == NULL)
{
old_cp = cp;
cmd_home();
}
clear_eol();
while (*cp != '\0')
{
@ -300,26 +325,6 @@ cmd_repaint(old_cp)
cmd_left();
}
/*
* Put the cursor at "home" (just after the prompt),
* and set cp to the corresponding char in cmdbuf.
*/
static void
cmd_home(VOID_PARAM)
{
while (cmd_col > prompt_col)
{
int width, bswidth;
cmd_step_left(&cp, &width, &bswidth);
while (bswidth-- > 0)
putbs();
cmd_col -= width;
}
cp = &cmdbuf[cmd_offset];
}
/*
* Shift the cmdbuf display left a half-screen.
*/
@ -852,20 +857,22 @@ cmd_edit(c)
/*
* No current history; don't accept history manipulation cmds.
*/
flags |= EC_NOHISTORY;
flags |= ECF_NOHISTORY;
#endif
#if TAB_COMPLETE_FILENAME
if (curr_mlist == ml_search)
/*
* In a search command; don't accept file-completion cmds.
*/
flags |= EC_NOCOMPLETE;
flags |= ECF_NOCOMPLETE;
#endif
action = editchar(c, flags);
switch (action)
{
case A_NOACTION:
return (CC_OK);
case EC_RIGHT:
not_in_completion();
return (cmd_right());
@ -934,8 +941,6 @@ cmd_edit(c)
case EC_EXPAND:
return (cmd_complete(action));
#endif
case EC_NOACTION:
return (CC_OK);
default:
not_in_completion();
return (CC_PASS);

View File

@ -1,6 +1,6 @@
/* $FreeBSD$ */
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
@ -61,6 +61,7 @@ extern int screen_trashed; /* The screen has been overwritten */
extern int shift_count;
extern int oldbot;
extern int forw_prompt;
extern int incr_search;
#if MSDOS_COMPILER==WIN32C
extern int utf_mode;
#endif
@ -113,7 +114,6 @@ set_mca(action)
int action;
{
mca = action;
deinit_mouse(); /* we don't want mouse events while entering a cmd */
clear_bot();
clear_cmd();
}
@ -127,7 +127,6 @@ clear_mca(VOID_PARAM)
if (mca == 0)
return;
mca = 0;
init_mouse();
}
/*
@ -177,6 +176,8 @@ mca_search(VOID_PARAM)
cmd_putstr("Keep-pos ");
if (search_type & SRCH_NO_REGEX)
cmd_putstr("Regex-off ");
if (search_type & SRCH_WRAP)
cmd_putstr("Wrap ");
#if HILITE_SEARCH
if (search_type & SRCH_FILTER)
@ -547,6 +548,10 @@ mca_search_char(c)
if (mca != A_FILTER)
flag = SRCH_NO_MOVE;
break;
case CONTROL('W'): /* WRAP around */
if (mca != A_FILTER)
flag = SRCH_WRAP;
break;
case CONTROL('R'): /* Don't use REGULAR EXPRESSIONS */
flag = SRCH_NO_REGEX;
break;
@ -558,7 +563,8 @@ mca_search_char(c)
if (flag != 0)
{
search_type ^= flag;
/* Toggle flag, but keep PAST_EOF and WRAP mutually exclusive. */
search_type ^= flag | (search_type & (SRCH_PAST_EOF|SRCH_WRAP));
mca_search();
return (MCA_MORE);
}
@ -596,9 +602,16 @@ mca_char(c)
* Entering digits of a number.
* Terminated by a non-digit.
*/
if (!((c >= '0' && c <= '9') || c == '.') &&
editchar(c, EC_PEEK|EC_NOHISTORY|EC_NOCOMPLETE|EC_NORIGHTLEFT) == A_INVALID)
if ((c >= '0' && c <= '9') || c == '.')
break;
switch (editchar(c, ECF_PEEK|ECF_NOHISTORY|ECF_NOCOMPLETE|ECF_NORIGHTLEFT))
{
case A_NOACTION:
/*
* Ignore this char and get another one.
*/
return (MCA_MORE);
case A_INVALID:
/*
* Not part of the number.
* End the number and treat this char
@ -651,7 +664,11 @@ mca_char(c)
*/
return (MCA_DONE);
if ((mca == A_F_BRACKET || mca == A_B_BRACKET) && len_cmdbuf() >= 2)
switch (mca)
{
case A_F_BRACKET:
case A_B_BRACKET:
if (len_cmdbuf() >= 2)
{
/*
* Special case for the bracket-matching commands.
@ -661,6 +678,31 @@ mca_char(c)
exec_mca();
return (MCA_DONE);
}
break;
case A_F_SEARCH:
case A_B_SEARCH:
if (incr_search)
{
/* Incremental search: do a search after every input char. */
int st = (search_type & (SRCH_FORW|SRCH_BACK|SRCH_NO_MATCH|SRCH_NO_REGEX|SRCH_NO_MOVE|SRCH_WRAP));
char *pattern = get_cmdbuf();
cmd_exec();
if (*pattern == '\0')
{
/* User has backspaced to an empty pattern. */
undo_search(1);
} else
{
if (search(st | SRCH_INCR, pattern, 1) != 0)
/* No match, invalid pattern, etc. */
undo_search(1);
}
/* Redraw the search prompt and search string. */
mca_search();
cmd_repaint(NULL);
}
break;
}
/*
* Need another character.
@ -695,12 +737,6 @@ make_display(VOID_PARAM)
if (empty_screen())
{
if (initial_scrpos.pos == NULL_POSITION)
/*
* {{ Maybe this should be:
* jump_loc(ch_zero(), jump_sline);
* but this behavior seems rather unexpected
* on the first screen. }}
*/
jump_loc(ch_zero(), 1);
else
jump_loc(initial_scrpos.pos, initial_scrpos.ln);
@ -793,11 +829,16 @@ prompt(VOID_PARAM)
clear_cmd();
forw_prompt = 0;
p = pr_string();
#if HILITE_SEARCH
if (is_filtering())
putstr("& ");
#endif
if (p == NULL || *p == '\0')
{
at_enter(AT_NORMAL|AT_COLOR_PROMPT);
putchr(':');
else
at_exit();
} else
{
#if MSDOS_COMPILER==WIN32C
WCHAR w[MAX_PATH*2];
@ -807,7 +848,7 @@ prompt(VOID_PARAM)
0, w, -1, a, sizeof(a), NULL, NULL);
p = a;
#endif
at_enter(AT_STANDOUT);
at_enter(AT_STANDOUT|AT_COLOR_PROMPT);
putstr(p);
at_exit();
}
@ -843,7 +884,7 @@ getcc_end_command(VOID_PARAM)
return ('\n');
default:
/* Some other incomplete command. Let user complete it. */
return (getchr());
return ((ungot == NULL) ? getchr() : 0);
}
}
@ -856,7 +897,9 @@ getcc_end_command(VOID_PARAM)
static LWCHAR
getccu(VOID_PARAM)
{
LWCHAR c;
LWCHAR c = 0;
while (c == 0)
{
if (ungot == NULL)
{
/* Normal case: no ungotten chars.
@ -874,6 +917,7 @@ getccu(VOID_PARAM)
if (c == CHAR_END_COMMAND)
c = getcc_end_command();
}
}
return (c);
}
@ -947,6 +991,28 @@ ungetcc(c)
ungot = ug;
}
/*
* "Unget" a command character.
* If any other chars are already ungotten, put this one after those.
*/
public void
ungetcc_back(c)
LWCHAR c;
{
struct ungot *ug = (struct ungot *) ecalloc(1, sizeof(struct ungot));
ug->ug_char = c;
ug->ug_next = NULL;
if (ungot == NULL)
ungot = ug;
else
{
struct ungot *pu;
for (pu = ungot; pu->ug_next != NULL; pu = pu->ug_next)
continue;
pu->ug_next = ug;
}
}
/*
* Unget a whole string of command characters.
* The next sequence of getcc()'s will return this string.
@ -955,10 +1021,8 @@ ungetcc(c)
ungetsc(s)
char *s;
{
char *p;
for (p = s + strlen(s) - 1; p >= s; p--)
ungetcc(*p);
while (*s != '\0')
ungetcc_back(*s++);
}
/*
@ -1122,6 +1186,7 @@ commands(VOID_PARAM)
int action;
char *cbuf;
int newaction;
int save_jump_sline;
int save_search_type;
char *extra;
char tbuf[2];
@ -1423,11 +1488,18 @@ commands(VOID_PARAM)
case A_GOLINE:
/*
* Go to line N, default beginning of file.
* If N <= 0, ignore jump_sline in order to avoid
* empty lines before the beginning of the file.
*/
save_jump_sline = jump_sline;
if (number <= 0)
{
number = 1;
jump_sline = 0;
}
cmd_exec();
jump_back(number);
jump_sline = save_jump_sline;
break;
case A_PERCENT:
@ -1493,7 +1565,7 @@ commands(VOID_PARAM)
case A_VERSION:
/*
* Print version number, without the "@(#)".
* Print version number.
*/
cmd_exec();
dispversion();
@ -1604,10 +1676,11 @@ commands(VOID_PARAM)
break;
case A_UNDO_SEARCH:
case A_CLR_SEARCH:
/*
* Clear search string highlighting.
*/
undo_search();
undo_search(action == A_CLR_SEARCH);
break;
case A_HELP:

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.
@ -77,6 +77,7 @@ cvt_text(odst, osrc, chpos, lenp, ops)
{
int src_pos = (int) (src - osrc);
int dst_pos = (int) (dst - odst);
struct ansi_state *pansi;
ch = step_char(&src, +1, src_end);
if ((ops & CVT_BS) && ch == '\b' && dst > odst)
{
@ -85,13 +86,16 @@ cvt_text(odst, osrc, chpos, lenp, ops)
dst--;
} while (dst > odst && utf_mode &&
!IS_ASCII_OCTET(*dst) && !IS_UTF8_LEAD(*dst));
} else if ((ops & CVT_ANSI) && IS_CSI_START(ch))
} else if ((ops & CVT_ANSI) && (pansi = ansi_start(ch)) != NULL)
{
/* Skip to end of ANSI escape sequence. */
src++; /* skip the CSI start char */
while (src < src_end)
if (!is_ansi_middle(*src++))
{
if (ansi_step(pansi, ch) != ANSI_MID)
break;
ch = *src++;
}
ansi_done(pansi);
} else
{
/* Just copy the char to the destination buffer. */

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.
@ -89,6 +89,7 @@ static unsigned char cmdtable[] =
CONTROL('R'),0, A_REPAINT,
CONTROL('L'),0, A_REPAINT,
ESC,'u',0, A_UNDO_SEARCH,
ESC,'U',0, A_CLR_SEARCH,
'g',0, A_GOLINE,
SK(SK_HOME),0, A_GOLINE,
'<',0, A_GOLINE,
@ -215,6 +216,8 @@ static unsigned char edittable[] =
ESC,'j',0, EC_DOWN, /* ESC j */
SK(SK_DOWN_ARROW),0, EC_DOWN, /* DOWNARROW */
CONTROL('G'),0, EC_ABORT, /* CTRL-G */
ESC,'[','M',0, EC_X11MOUSE, /* X11 mouse report */
ESC,'[','<',0, EC_X116MOUSE, /* X11 1006 mouse report */
};
/*
@ -487,11 +490,14 @@ getcc_int(pterm)
* The prefix ("\e[M") has already been read.
*/
static int
x11mouse_action(VOID_PARAM)
x11mouse_action(skip)
int skip;
{
int b = getcc() - X11MOUSE_OFFSET;
int x = getcc() - X11MOUSE_OFFSET-1;
int y = getcc() - X11MOUSE_OFFSET-1;
if (skip)
return (A_NOACTION);
switch (b) {
default:
return (A_NOACTION);
@ -509,7 +515,8 @@ x11mouse_action(VOID_PARAM)
* The prefix ("\e[<") has already been read.
*/
static int
x116mouse_action(VOID_PARAM)
x116mouse_action(skip)
int skip;
{
char ch;
int x, y;
@ -519,6 +526,8 @@ x116mouse_action(VOID_PARAM)
if (x < 0 || ch != ';') return (A_NOACTION);
y = getcc_int(&ch) - 1;
if (y < 0) return (A_NOACTION);
if (skip)
return (A_NOACTION);
switch (b) {
case X11MOUSE_WHEEL_DOWN:
return mouse_wheel_down();
@ -580,9 +589,9 @@ cmd_search(cmd, table, endtable, sp)
a &= ~A_EXTRA;
}
if (a == A_X11MOUSE_IN)
a = x11mouse_action();
a = x11mouse_action(0);
else if (a == A_X116MOUSE_IN)
a = x116mouse_action();
a = x116mouse_action(0);
return (a);
}
} else if (*q == '\0')
@ -924,7 +933,6 @@ editchar(c, flags)
#if MSDOS_COMPILER==WIN32C
if (!win32_kbhit())
#endif
return (EC_LINEKILL);
}
@ -940,9 +948,14 @@ editchar(c, flags)
usercmd[nch+1] = '\0';
nch++;
action = ecmd_decode(usercmd, &s);
} while (action == A_PREFIX);
} while (action == A_PREFIX && nch < MAX_CMDLEN);
if (flags & EC_NORIGHTLEFT)
if (action == EC_X11MOUSE)
return (x11mouse_action(1));
if (action == EC_X116MOUSE)
return (x116mouse_action(1));
if (flags & ECF_NORIGHTLEFT)
{
switch (action)
{
@ -953,7 +966,7 @@ editchar(c, flags)
}
}
#if CMD_HISTORY
if (flags & EC_NOHISTORY)
if (flags & ECF_NOHISTORY)
{
/*
* The caller says there is no history list.
@ -969,7 +982,7 @@ editchar(c, flags)
}
#endif
#if TAB_COMPLETE_FILENAME
if (flags & EC_NOCOMPLETE)
if (flags & ECF_NOCOMPLETE)
{
/*
* The caller says we don't want any filename completion cmds.
@ -985,7 +998,7 @@ editchar(c, flags)
}
}
#endif
if ((flags & EC_PEEK) || action == A_INVALID)
if ((flags & ECF_PEEK) || action == A_INVALID)
{
/*
* We're just peeking, or we didn't understand the command.

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
@ -20,13 +20,12 @@
public int fd0 = 0;
extern int new_file;
extern int errmsgs;
extern int cbufs;
extern char *every_first_cmd;
extern int any_display;
extern int force_open;
extern int is_tty;
extern int sigs;
extern int hshift;
extern IFILE curr_ifile;
extern IFILE old_ifile;
extern struct scrpos initial_scrpos;
@ -47,7 +46,6 @@ public dev_t curr_dev;
public ino_t curr_ino;
#endif
/*
* Textlist functions deal with a list of words separated by spaces.
* init_textlist sets up a textlist structure.
@ -242,7 +240,6 @@ edit_ifile(ifile)
{
int f;
int answer;
int no_display;
int chflags;
char *filename;
char *open_filename;
@ -462,14 +459,12 @@ edit_ifile(ifile)
#endif
if (every_first_cmd != NULL)
{
ungetcc(CHAR_END_COMMAND);
ungetsc(every_first_cmd);
ungetcc_back(CHAR_END_COMMAND);
}
}
no_display = !any_display;
flush();
any_display = TRUE;
if (is_tty)
{
@ -485,6 +480,7 @@ edit_ifile(ifile)
#if HILITE_SEARCH
clr_hilite();
#endif
hshift = 0;
if (strcmp(filename, FAKE_HELPFILE) && strcmp(filename, FAKE_EMPTYFILE))
{
char *qfilename = shell_quote(filename);
@ -492,17 +488,6 @@ edit_ifile(ifile)
free(qfilename);
}
if (no_display && errmsgs > 0)
{
/*
* We displayed some messages on error output
* (file descriptor 2; see error() function).
* Before erasing the screen contents,
* display the file name and wait for a keystroke.
*/
parg.p_string = filename;
error("%s", &parg);
}
}
free(filename);
return (0);
@ -784,6 +769,8 @@ cat_file(VOID_PARAM)
#if LOGFILE
#define OVERWRITE_OPTIONS "Overwrite, Append, Don't log, or Quit?"
/*
* If the user asked for a log file and our input file
* is standard input, create the log file.
@ -827,7 +814,7 @@ use_logfile(filename)
* Ask user what to do.
*/
parg.p_string = filename;
answer = query("Warning: \"%s\" exists; Overwrite, Append or Don't log? ", &parg);
answer = query("Warning: \"%s\" exists; "OVERWRITE_OPTIONS" ", &parg);
}
loop:
@ -855,14 +842,12 @@ use_logfile(filename)
* Don't do anything.
*/
return;
case 'q':
quit(QUIT_OK);
/*NOTREACHED*/
default:
/*
* Eh?
*/
answer = query("Overwrite, Append, or Don't log? (Type \"O\", \"A\", \"D\" or \"q\") ", NULL_PARG);
answer = query(OVERWRITE_OPTIONS" (Type \"O\", \"A\", \"D\" or \"Q\") ", NULL_PARG);
goto loop;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.
@ -486,9 +486,12 @@ bin_file(f)
} else
{
LWCHAR c = step_char(&p, +1, edata);
if (ctldisp == OPT_ONPLUS && IS_CSI_START(c))
skip_ansi(&p, edata);
else if (binary_char(c))
struct ansi_state *pansi;
if (ctldisp == OPT_ONPLUS && (pansi = ansi_start(c)) != NULL)
{
skip_ansi(pansi, &p, edata);
ansi_done(pansi);
} else if (binary_char(c))
bin_count++;
}
}
@ -914,7 +917,7 @@ open_altfile(filename, pf, pfd)
int f;
/*
* The first time we open the file, read one char
* The alt file is a pipe. Read one char
* to see if the pipe will produce any data.
* If it does, push the char back on the pipe.
*/
@ -931,18 +934,22 @@ open_altfile(filename, pf, pfd)
*/
int status = pclose(fd);
if (returnfd > 1 && status == 0) {
/* File is empty. */
*pfd = NULL;
*pf = -1;
return (save(FAKE_EMPTYFILE));
}
/* No alt file. */
return (NULL);
}
/* Alt pipe contains data, so use it. */
ch_ungetchar(c);
*pfd = (void *) fd;
*pf = f;
return (save("-"));
}
#endif
/* The alt file is a regular file. Read its name from LESSOPEN. */
cmd = readfd(fd);
pclose(fd);
if (*cmd == '\0')

View File

@ -1,6 +1,6 @@
/* $FreeBSD$ */
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.
@ -49,6 +49,13 @@ extern char *tagoption;
static void
eof_bell(VOID_PARAM)
{
#if HAVE_TIME
static time_type last_eof_bell = 0;
time_type now = get_time();
if (now == last_eof_bell) /* max once per second */
return;
last_eof_bell = now;
#endif
if (quiet == NOT_QUIET)
bell();
else
@ -189,7 +196,7 @@ forw(n, pos, force, only_last, nblank)
{
clear();
home();
} else if (!first_time)
} else if (!first_time && !is_filtering())
{
putstr("...skipping...\n");
}

View File

@ -11,6 +11,7 @@ public void init_mouse LESSPARAMS ((VOID_PARAM));
public void deinit_mouse LESSPARAMS ((VOID_PARAM));
public void init LESSPARAMS ((VOID_PARAM));
public void deinit LESSPARAMS ((VOID_PARAM));
public int interactive LESSPARAMS ((VOID_PARAM));
public void home LESSPARAMS ((VOID_PARAM));
public void add_line LESSPARAMS ((VOID_PARAM));
public void remove_top LESSPARAMS ((int n));
@ -24,12 +25,12 @@ 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 COLOR_TYPE parse_color LESSPARAMS ((char *str, int *p_fg, int *p_bg));
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 int win32_kbhit LESSPARAMS ((VOID_PARAM));
public char WIN32getch LESSPARAMS ((VOID_PARAM));
@ -75,6 +76,7 @@ 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 cmd_repaint LESSPARAMS ((constant char *old_cp));
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));
@ -88,6 +90,7 @@ 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 ungetcc_back LESSPARAMS ((LWCHAR c));
public void ungetsc LESSPARAMS ((char *s));
public LWCHAR peekcc LESSPARAMS ((VOID_PARAM));
public void commands LESSPARAMS ((VOID_PARAM));
@ -155,6 +158,7 @@ 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 char * get_real_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));
@ -169,6 +173,7 @@ public void * get_altpipe LESSPARAMS ((IFILE ifile));
public void set_altfilename LESSPARAMS ((IFILE ifile, char *altfilename));
public char * get_altfilename LESSPARAMS ((IFILE ifile));
public void if_dump LESSPARAMS ((VOID_PARAM));
public POSITION forw_line_seg LESSPARAMS ((POSITION curr_pos, int get_segpos));
public POSITION forw_line LESSPARAMS ((POSITION curr_pos));
public POSITION back_line LESSPARAMS ((POSITION curr_pos));
public void set_attnpos LESSPARAMS ((POSITION pos));
@ -182,20 +187,27 @@ 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 plinestart LESSPARAMS ((POSITION pos));
public int line_pfx_width LESSPARAMS ((VOID_PARAM));
public void pshift_all LESSPARAMS ((VOID_PARAM));
public int pwidth LESSPARAMS ((LWCHAR ch, int a, LWCHAR prev_ch, int prev_a));
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 void skip_ansi LESSPARAMS ((struct ansi_state *pansi, char **pp, constant char *limit));
public struct ansi_state * ansi_start LESSPARAMS ((LWCHAR ch));
public int ansi_step LESSPARAMS ((struct ansi_state *pansi, LWCHAR ch));
public void ansi_done LESSPARAMS ((struct ansi_state *pansi));
public int pappend LESSPARAMS ((int c, POSITION pos));
public int pflushmbc LESSPARAMS ((VOID_PARAM));
public void pdone LESSPARAMS ((int endline, int chopped, int forw));
public void set_status_col LESSPARAMS ((int c));
public void set_status_col LESSPARAMS ((int c, int attr));
public int gline LESSPARAMS ((int i, int *ap));
public void null_line LESSPARAMS ((VOID_PARAM));
public POSITION forw_raw_line LESSPARAMS ((POSITION curr_pos, char **linep, int *line_lenp));
public POSITION back_raw_line LESSPARAMS ((POSITION curr_pos, char **linep, int *line_lenp));
public int rrshift LESSPARAMS ((VOID_PARAM));
public int set_color_map LESSPARAMS ((int attr, char *colorstr));
public char * get_color_map LESSPARAMS ((int attr));
public void clr_linenum LESSPARAMS ((VOID_PARAM));
public void add_lnum LESSPARAMS ((LINENUM linenum, POSITION pos));
public LINENUM find_linenum LESSPARAMS ((POSITION pos));
@ -237,6 +249,10 @@ public void opt_rscroll LESSPARAMS ((int type, char *s));
public void opt_query LESSPARAMS ((int type, char *s));
public void opt_mousecap LESSPARAMS ((int type, char *s));
public void opt_wheel_lines LESSPARAMS ((int type, char *s));
public void opt_linenum_width LESSPARAMS ((int type, char *s));
public void opt_status_col_width LESSPARAMS ((int type, char *s));
public void opt_ttyin_name LESSPARAMS ((int type, char *s));
public void opt_rstat 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));
@ -259,15 +275,18 @@ 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 sleep_ms LESSPARAMS ((int ms));
public void put_line LESSPARAMS ((VOID_PARAM));
public void flush LESSPARAMS ((VOID_PARAM));
public void set_output LESSPARAMS ((int fd));
public int putchr LESSPARAMS ((int c));
public void putstr LESSPARAMS ((constant char *s));
public int less_printf LESSPARAMS ((char *fmt, PARG *parg));
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 int compile_pattern LESSPARAMS ((char *pattern, int search_type, int show_error, 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));
@ -291,14 +310,14 @@ 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 undo_search LESSPARAMS ((int clear));
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 int is_hilited_attr 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));
@ -317,7 +336,9 @@ public char * prevtag LESSPARAMS ((int n));
public int ntags LESSPARAMS ((VOID_PARAM));
public int curr_tag LESSPARAMS ((VOID_PARAM));
public int edit_tagfile LESSPARAMS ((VOID_PARAM));
public char * tty_device LESSPARAMS ((VOID_PARAM));
public void open_getchr LESSPARAMS ((VOID_PARAM));
public void close_getchr LESSPARAMS ((VOID_PARAM));
public int default_wheel_lines LESSPARAMS ((VOID_PARAM));
public void rstat LESSPARAMS ((char st));
public int getchr LESSPARAMS ((VOID_PARAM));

View File

@ -1,4 +1,4 @@
/* This file was generated by mkhelp.pl from less.hlp at 3:34 on 2020/6/14 */
/* This file was generated by mkhelp.pl from less.hlp at 1:31 on 2021/4/7 */
#include "less.h"
constant char helpdata[] = {
'\n',
@ -45,7 +45,8 @@ constant char helpdata[] = {
' ',' ','E','S','C','-','n',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','R','e','p','e','a','t',' ','p','r','e','v','i','o','u','s',' ','s','e','a','r','c','h',',',' ','s','p','a','n','n','i','n','g',' ','f','i','l','e','s','.','\n',
' ',' ','E','S','C','-','N',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','R','e','p','e','a','t',' ','p','r','e','v','i','o','u','s',' ','s','e','a','r','c','h',',',' ','r','e','v','e','r','s','e',' ','d','i','r','.',' ','&',' ','s','p','a','n','n','i','n','g',' ','f','i','l','e','s','.','\n',
' ',' ','E','S','C','-','u',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','n','d','o',' ','(','t','o','g','g','l','e',')',' ','s','e','a','r','c','h',' ','h','i','g','h','l','i','g','h','t','i','n','g','.','\n',
' ',' ','&','_','\b','p','_','\b','a','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','n',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','D','i','s','p','l','a','y',' ','o','n','l','y',' ','m','a','t','c','h','i','n','g',' ','l','i','n','e','s','\n',
' ',' ','E','S','C','-','U',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','l','e','a','r',' ','s','e','a','r','c','h',' ','h','i','g','h','l','i','g','h','t','i','n','g','.','\n',
' ',' ','&','_','\b','p','_','\b','a','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','n',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','D','i','s','p','l','a','y',' ','o','n','l','y',' ','m','a','t','c','h','i','n','g',' ','l','i','n','e','s','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
' ',' ',' ',' ',' ',' ',' ',' ','A',' ','s','e','a','r','c','h',' ','p','a','t','t','e','r','n',' ','m','a','y',' ','b','e','g','i','n',' ','w','i','t','h',' ','o','n','e',' ','o','r',' ','m','o','r','e',' ','o','f',':','\n',
' ',' ',' ',' ',' ',' ',' ',' ','^','N',' ','o','r',' ','!',' ',' ','S','e','a','r','c','h',' ','f','o','r',' ','N','O','N','-','m','a','t','c','h','i','n','g',' ','l','i','n','e','s','.','\n',
@ -53,6 +54,7 @@ constant char helpdata[] = {
' ',' ',' ',' ',' ',' ',' ',' ','^','F',' ','o','r',' ','@',' ',' ','S','t','a','r','t',' ','s','e','a','r','c','h',' ','a','t',' ','F','I','R','S','T',' ','f','i','l','e',' ','(','f','o','r',' ','/',')',' ','o','r',' ','l','a','s','t',' ','f','i','l','e',' ','(','f','o','r',' ','?',')','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','^','K',' ',' ',' ',' ',' ',' ',' ','H','i','g','h','l','i','g','h','t',' ','m','a','t','c','h','e','s',',',' ','b','u','t',' ','d','o','n','\'','t',' ','m','o','v','e',' ','(','K','E','E','P',' ','p','o','s','i','t','i','o','n',')','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','^','R',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','u','s','e',' ','R','E','G','U','L','A','R',' ','E','X','P','R','E','S','S','I','O','N','S','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','^','W',' ',' ',' ',' ',' ',' ',' ','W','R','A','P',' ','s','e','a','r','c','h',' ','i','f',' ','n','o',' ','m','a','t','c','h',' ','f','o','u','n','d','.','\n',
' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
'\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','J','\b','J','U','\b','U','M','\b','M','P','\b','P','I','\b','I','N','\b','N','G','\b','G','\n',
@ -65,7 +67,7 @@ constant char helpdata[] = {
' ',' ','{',' ',' ','(',' ',' ','[',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','F','i','n','d',' ','c','l','o','s','e',' ','b','r','a','c','k','e','t',' ','}',' ',')',' ',']','.','\n',
' ',' ','}',' ',' ',')',' ',' ',']',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','F','i','n','d',' ','o','p','e','n',' ','b','r','a','c','k','e','t',' ','{',' ','(',' ','[','.','\n',
' ',' ','E','S','C','-','^','F',' ','_','\b','<','_','\b','c','_','\b','1','_','\b','>',' ','_','\b','<','_','\b','c','_','\b','2','_','\b','>',' ',' ','*',' ',' ','F','i','n','d',' ','c','l','o','s','e',' ','b','r','a','c','k','e','t',' ','_','\b','<','_','\b','c','_','\b','2','_','\b','>','.','\n',
' ',' ','E','S','C','-','^','B',' ','_','\b','<','_','\b','c','_','\b','1','_','\b','>',' ','_','\b','<','_','\b','c','_','\b','2','_','\b','>',' ',' ','*',' ',' ','F','i','n','d',' ','o','p','e','n',' ','b','r','a','c','k','e','t',' ','_','\b','<','_','\b','c','_','\b','1','_','\b','>',' ','\n',
' ',' ','E','S','C','-','^','B',' ','_','\b','<','_','\b','c','_','\b','1','_','\b','>',' ','_','\b','<','_','\b','c','_','\b','2','_','\b','>',' ',' ','*',' ',' ','F','i','n','d',' ','o','p','e','n',' ','b','r','a','c','k','e','t',' ','_','\b','<','_','\b','c','_','\b','1','_','\b','>','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
' ',' ',' ',' ',' ',' ',' ',' ','E','a','c','h',' ','"','f','i','n','d',' ','c','l','o','s','e',' ','b','r','a','c','k','e','t','"',' ','c','o','m','m','a','n','d',' ','g','o','e','s',' ','f','o','r','w','a','r','d',' ','t','o',' ','t','h','e',' ','c','l','o','s','e',' ','b','r','a','c','k','e','t',' ','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','m','a','t','c','h','i','n','g',' ','t','h','e',' ','(','_','\b','N','-','t','h',')',' ','o','p','e','n',' ','b','r','a','c','k','e','t',' ','i','n',' ','t','h','e',' ','t','o','p',' ','l','i','n','e','.','\n',
@ -132,8 +134,8 @@ constant char helpdata[] = {
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','p','a','i','n','t',' ','b','y',' ','c','l','e','a','r','i','n','g',' ','r','a','t','h','e','r',' ','t','h','a','n',' ','s','c','r','o','l','l','i','n','g','.','\n',
' ',' ','-','d',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','d','u','m','b','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','u','m','b',' ','t','e','r','m','i','n','a','l','.','\n',
' ',' ','-','D',' ','[','_','\b','x','_','\b','n','_','\b','.','_','\b','n',']',' ',' ','.',' ',' ','-','-','c','o','l','o','r','=','_','\b','x','_','\b','n','_','\b','.','_','\b','n','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','s','c','r','e','e','n',' ','c','o','l','o','r','s','.',' ','(','M','S','-','D','O','S',' ','o','n','l','y',')','\n',
' ',' ','-','D',' ','x','\b','x','_','\b','c','_','\b','o','_','\b','l','_','\b','o','_','\b','r',' ',' ','.',' ',' ','-','-','c','o','l','o','r','=','x','\b','x','_','\b','c','_','\b','o','_','\b','l','_','\b','o','_','\b','r','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','s','c','r','e','e','n',' ','c','o','l','o','r','s','.','\n',
' ',' ','-','e',' ',' ','-','E',' ',' ','.','.','.','.',' ',' ','-','-','q','u','i','t','-','a','t','-','e','o','f',' ',' ','-','-','Q','U','I','T','-','A','T','-','E','O','F','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','Q','u','i','t',' ','a','t',' ','e','n','d',' ','o','f',' ','f','i','l','e','.','\n',
' ',' ','-','f',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','f','o','r','c','e','\n',
@ -205,9 +207,13 @@ constant char helpdata[] = {
' ',' ','-','~',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','t','i','l','d','e','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','d','i','s','p','l','a','y',' ','t','i','l','d','e','s',' ','a','f','t','e','r',' ','e','n','d',' ','o','f',' ','f','i','l','e','.','\n',
' ',' ','-','#',' ','[','_','\b','N',']',' ',' ','.','.','.','.',' ',' ','-','-','s','h','i','f','t','=','[','_','\b','N',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','H','o','r','i','z','o','n','t','a','l',' ','s','c','r','o','l','l',' ','a','m','o','u','n','t',' ','(','0',' ','=',' ','o','n','e',' ','h','a','l','f',' ','s','c','r','e','e','n',' ','w','i','d','t','h',')','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','h','o','r','i','z','o','n','t','a','l',' ','s','c','r','o','l','l',' ','a','m','o','u','n','t',' ','(','0',' ','=',' ','o','n','e',' ','h','a','l','f',' ','s','c','r','e','e','n',' ','w','i','d','t','h',')','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','f','o','l','l','o','w','-','n','a','m','e','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','T','h','e',' ','F',' ','c','o','m','m','a','n','d',' ','c','h','a','n','g','e','s',' ','f','i','l','e','s',' ','i','f',' ','t','h','e',' ','i','n','p','u','t',' ','f','i','l','e',' ','i','s',' ','r','e','n','a','m','e','d','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','i','n','c','s','e','a','r','c','h','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','a','r','c','h',' ','f','i','l','e',' ','a','s',' ','e','a','c','h',' ','p','a','t','t','e','r','n',' ','c','h','a','r','a','c','t','e','r',' ','i','s',' ','t','y','p','e','d',' ','i','n','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','l','i','n','e','-','n','u','m','-','w','i','d','t','h','=','N','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','t','h','e',' ','w','i','d','t','h',' ','o','f',' ','t','h','e',' ','-','N',' ','l','i','n','e',' ','n','u','m','b','e','r',' ','f','i','e','l','d',' ','t','o',' ','N',' ','c','h','a','r','a','c','t','e','r','s','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','m','o','u','s','e','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','n','a','b','l','e',' ','m','o','u','s','e',' ','i','n','p','u','t','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','n','o','-','k','e','y','p','a','d','\n',
@ -218,8 +224,12 @@ constant char helpdata[] = {
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','t','h','e',' ','c','h','a','r','a','c','t','e','r',' ','u','s','e','d',' ','t','o',' ','m','a','r','k',' ','t','r','u','n','c','a','t','e','d',' ','l','i','n','e','s','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','s','a','v','e','-','m','a','r','k','s','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','t','a','i','n',' ','m','a','r','k','s',' ','a','c','r','o','s','s',' ','i','n','v','o','c','a','t','i','o','n','s',' ','o','f',' ','l','e','s','s','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','s','t','a','t','u','s','-','c','o','l','-','w','i','d','t','h','=','N','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','t','h','e',' ','w','i','d','t','h',' ','o','f',' ','t','h','e',' ','-','J',' ','s','t','a','t','u','s',' ','c','o','l','u','m','n',' ','t','o',' ','N',' ','c','h','a','r','a','c','t','e','r','s','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','u','s','e','-','b','a','c','k','s','l','a','s','h','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','u','b','s','e','q','u','e','n','t',' ','o','p','t','i','o','n','s',' ','u','s','e',' ','b','a','c','k','s','l','a','s','h',' ','a','s',' ','e','s','c','a','p','e',' ','c','h','a','r','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','u','s','e','-','c','o','l','o','r','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','n','a','b','l','e','s',' ','c','o','l','o','r','e','d',' ','t','e','x','t','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','w','h','e','e','l','-','l','i','n','e','s','=','N','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','a','c','h',' ','c','l','i','c','k',' ','o','f',' ','t','h','e',' ','m','o','u','s','e',' ','w','h','e','e','l',' ','m','o','v','e','s',' ','N',' ','l','i','n','e','s','.','\n',
'\n',
@ -247,7 +257,5 @@ constant char helpdata[] = {
' ','T','A','B',' ','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',' ','C','o','m','p','l','e','t','e',' ','f','i','l','e','n','a','m','e',' ','&',' ','c','y','c','l','e','.','\n',
' ','S','H','I','F','T','-','T','A','B',' ','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',' ','E','S','C','-','T','A','B',' ',' ',' ','C','o','m','p','l','e','t','e',' ','f','i','l','e','n','a','m','e',' ','&',' ','r','e','v','e','r','s','e',' ','c','y','c','l','e','.','\n',
' ','c','t','r','l','-','L',' ','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.',' ','C','o','m','p','l','e','t','e',' ','f','i','l','e','n','a','m','e',',',' ','l','i','s','t',' ','a','l','l','.','\n',
'\n',
'\n',
0 };
constant int size_helpdata = sizeof(helpdata) - 1;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
@ -27,6 +27,7 @@ struct ifile {
struct ifile *h_next; /* Links for command line list */
struct ifile *h_prev;
char *h_filename; /* Name of the file */
char *h_rfilename; /* Canonical 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 */
@ -46,7 +47,7 @@ struct ifile {
/*
* Anchor for linked list.
*/
static struct ifile anchor = { &anchor, &anchor, NULL, NULL, 0, 0, '\0',
static struct ifile anchor = { &anchor, &anchor, NULL, NULL, NULL, 0, 0, '\0',
{ NULL_POSITION, 0 } };
static int ifiles = 0;
@ -116,10 +117,13 @@ new_ifile(filename, prev)
*/
p = (struct ifile *) ecalloc(1, sizeof(struct ifile));
p->h_filename = save(filename);
p->h_rfilename = lrealpath(filename);
p->h_scrpos.pos = NULL_POSITION;
p->h_opened = 0;
p->h_hold = 0;
p->h_filestate = NULL;
p->h_altfilename = NULL;
p->h_altpipe = NULL;
link_ifile(p, prev);
/*
* {{ It's dodgy to call mark.c functions from here;
@ -150,6 +154,7 @@ del_ifile(h)
curr_ifile = getoff_ifile(curr_ifile);
p = int_ifile(h);
unlink_ifile(p);
free(p->h_rfilename);
free(p->h_filename);
free(p);
}
@ -221,15 +226,17 @@ find_ifile(filename)
for (p = anchor.h_next; p != &anchor; p = p->h_next)
{
if (strcmp(filename, p->h_filename) == 0 ||
strcmp(rfilename, p->h_filename) == 0)
if (strcmp(rfilename, p->h_rfilename) == 0)
{
/*
* If given name is shorter than the name we were
* previously using for this file, adopt shorter name.
*/
if (strlen(filename) < strlen(p->h_filename))
strcpy(p->h_filename, filename);
{
free(p->h_filename);
p->h_filename = save(filename);
}
break;
}
}
@ -257,7 +264,7 @@ get_ifile(filename, prev)
}
/*
* Get the filename associated with a ifile.
* Get the display filename associated with a ifile.
*/
public char *
get_filename(ifile)
@ -268,6 +275,18 @@ get_filename(ifile)
return (int_ifile(ifile)->h_filename);
}
/*
* Get the canonical filename associated with a ifile.
*/
public char *
get_real_filename(ifile)
IFILE ifile;
{
if (ifile == NULL)
return (NULL);
return (int_ifile(ifile)->h_rfilename);
}
/*
* Get the index of the file associated with a ifile.
*/
@ -372,7 +391,7 @@ set_altfilename(ifile, altfilename)
char *altfilename;
{
struct ifile *p = int_ifile(ifile);
if (p->h_altfilename != NULL)
if (p->h_altfilename != NULL && p->h_altfilename != altfilename)
free(p->h_altfilename);
p->h_altfilename = altfilename;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.
@ -31,6 +31,7 @@ extern POSITION end_attnpos;
#if HILITE_SEARCH
extern int hilite_search;
extern int size_linebuf;
extern int show_attn;
#endif
/*
@ -41,8 +42,9 @@ extern int size_linebuf;
* of the NEXT line. The line obtained is the line starting at curr_pos.
*/
public POSITION
forw_line(curr_pos)
forw_line_seg(curr_pos, get_segpos)
POSITION curr_pos;
int get_segpos;
{
POSITION base_pos;
POSITION new_pos;
@ -105,7 +107,7 @@ forw_line(curr_pos)
* Read forward again to the position we should start at.
*/
prewind();
plinenum(base_pos);
plinestart(base_pos);
(void) ch_seek(base_pos);
new_pos = base_pos;
while (new_pos < curr_pos)
@ -180,8 +182,9 @@ forw_line(curr_pos)
* is too long to print in the screen width.
* End the line here.
*/
if (chopline || hshift > 0)
if ((chopline || hshift > 0) && !get_segpos)
{
/* Read to end of line. */
do
{
if (ABORT_SIGS())
@ -205,6 +208,13 @@ forw_line(curr_pos)
c = ch_forw_get();
}
#if HILITE_SEARCH
if (blankline && show_attn)
{
/* Add spurious space to carry possible attn hilite. */
pappend(' ', ch_tell()-1);
}
#endif
pdone(endline, chopped, 1);
#if HILITE_SEARCH
@ -218,8 +228,12 @@ forw_line(curr_pos)
goto get_forw_line;
}
if (status_col && is_hilited(base_pos, ch_tell()-1, 1, NULL))
set_status_col('*');
if (status_col)
{
int attr = is_hilited_attr(base_pos, ch_tell()-1, 1, NULL);
if (attr)
set_status_col('*', attr);
}
#endif
if (squeeze && blankline)
@ -243,6 +257,13 @@ forw_line(curr_pos)
return (new_pos);
}
public POSITION
forw_line(curr_pos)
POSITION curr_pos;
{
return forw_line_seg(curr_pos, FALSE);
}
/*
* Get the previous line.
* A "current" position is passed and a "new" position is returned.
@ -358,7 +379,7 @@ back_line(curr_pos)
}
endline = FALSE;
prewind();
plinenum(new_pos);
plinestart(new_pos);
loop:
begin_new_pos = new_pos;
(void) ch_seek(new_pos);
@ -423,8 +444,12 @@ back_line(curr_pos)
goto get_back_line;
}
if (status_col && curr_pos > 0 && is_hilited(base_pos, curr_pos-1, 1, NULL))
set_status_col('*');
if (status_col && curr_pos > 0)
{
int attr = is_hilited_attr(base_pos, curr_pos-1, 1, NULL);
if (attr)
set_status_col('*', attr);
}
#endif
return (begin_new_pos);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.
@ -227,7 +227,9 @@ void free();
typedef unsigned long LWCHAR;
typedef off_t POSITION;
typedef off_t LINENUM;
#define MIN_LINENUM_WIDTH 7 /* Min printing width of a line number */
#define MIN_LINENUM_WIDTH 7 /* Default min printing width of a line number */
#define MAX_LINENUM_WIDTH 16 /* Max width of a line number */
#define MAX_STATUSCOL_WIDTH 4 /* Max width of the status column */
#define MAX_UTF_CHAR_LEN 6 /* Max bytes in one UTF-8 char */
#define NULL_POSITION ((POSITION)(-1))
@ -307,6 +309,7 @@ typedef union parg
char *p_string;
int p_int;
LINENUM p_linenum;
char p_char;
} PARG;
#define NULL_PARG ((PARG *)NULL)
@ -355,6 +358,7 @@ struct wchar_range_table
#define SRCH_FORW (1 << 0) /* Search forward from current position */
#define SRCH_BACK (1 << 1) /* Search backward from current position */
#define SRCH_NO_MOVE (1 << 2) /* Highlight, but don't move */
#define SRCH_INCR (1 << 3) /* Incremental search */
#define SRCH_FIND_ALL (1 << 4) /* Find and highlight all matches */
#define SRCH_NO_MATCH (1 << 8) /* Search for non-matching lines */
#define SRCH_PAST_EOF (1 << 9) /* Search past end-of-file, into next file */
@ -362,6 +366,7 @@ struct wchar_range_table
#define SRCH_NO_REGEX (1 << 12) /* Don't use regular expressions */
#define SRCH_FILTER (1 << 13) /* Search is for '&' (filter) command */
#define SRCH_AFTER_TARGET (1 << 14) /* Start search after the target line */
#define SRCH_WRAP (1 << 15) /* Wrap-around search (continue at BOF/EOF) */
#define SRCH_REVERSE(t) (((t) & SRCH_FORW) ? \
(((t) & ~SRCH_FORW) | SRCH_BACK) : \
@ -389,6 +394,35 @@ struct wchar_range_table
#define AT_BINARY (1 << 5) /* LESS*BINFMT representation */
#define AT_HILITE (1 << 6) /* Internal highlights (e.g., for search) */
#define AT_COLOR_SHIFT 8
#define AT_NUM_COLORS 16
#define AT_COLOR ((AT_NUM_COLORS-1) << AT_COLOR_SHIFT)
#define AT_COLOR_ATTN (1 << AT_COLOR_SHIFT)
#define AT_COLOR_BIN (2 << AT_COLOR_SHIFT)
#define AT_COLOR_CTRL (3 << AT_COLOR_SHIFT)
#define AT_COLOR_ERROR (4 << AT_COLOR_SHIFT)
#define AT_COLOR_LINENUM (5 << AT_COLOR_SHIFT)
#define AT_COLOR_MARK (6 << AT_COLOR_SHIFT)
#define AT_COLOR_PROMPT (7 << AT_COLOR_SHIFT)
#define AT_COLOR_RSCROLL (8 << AT_COLOR_SHIFT)
#define AT_COLOR_SEARCH (9 << AT_COLOR_SHIFT)
typedef enum { CT_NULL, CT_4BIT, CT_6BIT } COLOR_TYPE;
typedef enum {
CV_BLUE = 1,
CV_GREEN = 2,
CV_RED = 4,
CV_BRIGHT = 8,
CV_NOCHANGE = -2,
CV_ERROR = -1
} COLOR_VALUE;
/* ANSI states */
#define ANSI_MID 1
#define ANSI_ERR 2
#define ANSI_END 3
#if '0' == 240
#define IS_EBCDIC_HOST 1
#endif
@ -535,6 +569,7 @@ struct wchar_range_table
struct mlist;
struct loption;
struct hilite_tree;
struct ansi_state;
#include "pattern.h"
#include "funcs.h"

View File

@ -42,7 +42,8 @@
ESC-n * Repeat previous search, spanning files.
ESC-N * Repeat previous search, reverse dir. & spanning files.
ESC-u Undo (toggle) search highlighting.
&_p_a_t_t_e_r_n * Display only matching lines
ESC-U Clear search highlighting.
&_p_a_t_t_e_r_n * Display only matching lines.
---------------------------------------------------
A search pattern may begin with one or more of:
^N or ! Search for NON-matching lines.
@ -50,6 +51,7 @@
^F or @ Start search at FIRST file (for /) or last file (for ?).
^K Highlight matches, but don't move (KEEP position).
^R Don't use REGULAR EXPRESSIONS.
^W WRAP search if no match found.
---------------------------------------------------------------------------
JJUUMMPPIINNGG
@ -62,7 +64,7 @@
{ ( [ * Find close bracket } ) ].
} ) ] * Find open bracket { ( [.
ESC-^F _<_c_1_> _<_c_2_> * Find close bracket _<_c_2_>.
ESC-^B _<_c_1_> _<_c_2_> * Find open bracket _<_c_1_>
ESC-^B _<_c_1_> _<_c_2_> * Find open bracket _<_c_1_>.
---------------------------------------------------
Each "find close bracket" command goes forward to the close bracket
matching the (_N-th) open bracket in the top line.
@ -129,8 +131,8 @@
Repaint by clearing rather than scrolling.
-d ........ --dumb
Dumb terminal.
-D [_x_n_._n] . --color=_x_n_._n
Set screen colors. (MS-DOS only)
-D xx_c_o_l_o_r . --color=xx_c_o_l_o_r
Set screen colors.
-e -E .... --quit-at-eof --QUIT-AT-EOF
Quit at end of file.
-f ........ --force
@ -202,9 +204,13 @@
-~ ........ --tilde
Don't display tildes after end of file.
-# [_N] .... --shift=[_N]
Horizontal scroll amount (0 = one half screen width)
Set horizontal scroll amount (0 = one half screen width).
--follow-name
The F command changes files if the input file is renamed.
--incsearch
Search file as each pattern character is typed in.
--line-num-width=N
Set the width of the -N line number field to N characters.
--mouse
Enable mouse input.
--no-keypad
@ -215,8 +221,12 @@
Set the character used to mark truncated lines.
--save-marks
Retain marks across invocations of less.
--status-col-width=N
Set the width of the -J status column to N characters.
--use-backslash
Subsequent options use backslash as escape char.
--use-color
Enables colored text.
--wheel-lines=N
Each click of the mouse wheel moves N lines.
@ -244,5 +254,3 @@
TAB ...................................... Complete filename & cycle.
SHIFT-TAB ...................... ESC-TAB Complete filename & reverse cycle.
ctrl-L ................................... Complete filename, list all.

View File

@ -1,5 +1,5 @@
'\" t
.TH LESS 1 "Version 563: 13 Jun 2020"
.TH LESS 1 "Version 581: 06 Apr 2021"
.SH NAME
less \- opposite of more
.SH SYNOPSIS
@ -109,6 +109,7 @@ Scroll horizontally left back to the first column.
Repaint the screen.
.IP R
Repaint the screen, discarding any buffered input.
That is, reload the current file.
Useful if the file is changing while it is being viewed.
.IP "F"
Scroll forward, and keep trying to read when the
@ -117,6 +118,8 @@ Normally this command would be used when already at the end of the file.
It is a way to monitor the tail of a file which is growing
while it is being viewed.
(The behavior is similar to the "tail \-f" command.)
To stop waiting for more data, enter the interrupt character (usually ^C).
On some systems you can also use ^X.
.IP "ESC-F"
Like F, but as soon as a line is found which matches
the last search pattern, the terminal bell is rung
@ -226,6 +229,11 @@ but don't move to the first match (KEEP current position).
.IP "^R"
Don't interpret regular expression metacharacters;
that is, do a simple textual comparison.
.IP "^W"
WRAP around the current file.
That is, if the search reaches the end of the current file
without finding a match, the search continues from the first line of the
current file up to the line where it started.
.RE
.IP ?pattern
Search backward in the file for the N-th line containing the pattern.
@ -250,6 +258,11 @@ or the settings of the \-a or \-j options.
As in forward searches.
.IP "^R"
As in forward searches.
.IP "^W"
WRAP around the current file.
That is, if the search reaches the beginning of the current file
without finding a match, the search continues from the last line of the
current file up to the line where it started.
.RE
.IP "ESC-/pattern"
Same as "/*".
@ -280,6 +293,10 @@ turn highlighting back on.
Any search command will also turn highlighting back on.
(Highlighting can also be disabled by toggling the \-G option;
in that case search commands do not turn highlighting back on.)
.IP "ESC-U"
Like ESC-u but also clears the saved search pattern.
If the status column is enabled via the \-J option,
this clears all search matches marked in the status column.
.IP "&pattern"
Display only lines which match the pattern;
lines which do not match the pattern are not displayed.
@ -288,6 +305,8 @@ any filtering is turned off, and all lines are displayed.
While filtering is in effect, an ampersand is displayed at the
beginning of the prompt,
as a reminder that some lines in the file may be hidden.
Multiple & commands may be entered, in which case only lines
which match all of the patterns will be displayed.
.sp
Certain characters are special as in the / command:
.RS
@ -552,20 +571,105 @@ The \-d option does not otherwise change the behavior of
.I less
on a dumb terminal.
.IP "\-D\fBx\fP\fIcolor\fP or \-\-color=\fBx\fP\fIcolor\fP"
[MS-DOS only]
Sets the color of the text displayed.
\fBx\fP is a single character which selects the type of text whose color is
being set: n=normal, s=standout, d=bold, u=underlined, k=blink.
\fIcolor\fP 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 \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).
.
Changes the color of different parts of the displayed text.
\fBx\fP is a single character which selects the type of text
whose color is being set:
.RS
.IP "B"
Binary characters.
.IP "C"
Control characters.
.IP "E"
Errors and informational messages.
.IP "M"
Mark letters in the status column.
.IP "N"
Line numbers enabled via the \-N option.
.IP "P"
Prompts.
.IP "R"
The rscroll character.
.IP "S"
Search results.
.IP "W"
The highlight enabled via the \-w option.
.IP "d"
Bold text.
.IP "k"
Blinking text.
.IP "s"
Standout text.
.IP "u"
Underlined text.
.RE
.RS
The uppercase letters can be used only when the \-\-use-color option is enabled.
When text color is specified by both an uppercase letter and a lowercase letter,
the uppercase letter takes precedence.
For example, error messages are normally displayed as standout text.
So if both "s" and "E" are given a color, the "E" color applies
to error messages, and the "s" color applies to other standout text.
The "d" and "u" letters refer to bold and underline text formed by
overstriking with backspaces (see the \-u option),
not to text using ANSI escape sequences with the \-R option.
.PP
A lowercase letter may be followed by a + to indicate that
both the normal format change and the specified color should both be used.
For example, \-Dug displays underlined text as green without underlining;
the green color has replaced the usual underline formatting.
But \-Du+g displays underlined text as both green and in underlined format.
.PP
\fIcolor\fP is either a 4-bit color string or an 8-bit color string:
.PP
A 4-bit color string is zero, one or two characters, where
the first character specifies the foreground color and
the second specifies the background color as follows:
.IP "b"
Blue
.IP "c"
Cyan
.IP "g"
Green
.IP "k"
Black
.IP "m"
Magenta
.IP "r"
Red
.IP "w"
White
.IP "y"
Yellow
.PP
The corresponding upper-case letter denotes a brighter shade of the color.
For example, \-DNGk displays line numbers as bright green text on a black
background, and \-DEbR displays error messages as blue text on a
bright red background.
If either character is a "-" or is omitted, the corresponding color
is set to that of normal text.
.PP
An 8-bit color string is one or two decimal integers separated by a dot,
where the first integer specifies the foreground color and
the second specifies the background color.
Each integer is a value between 0 and 255 inclusive which selects
a "CSI 38;5" color value (see
.br
.nh
https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters)
.hy
If either integer is a "-" or is omitted,
the corresponding color is set to that of normal text.
On MS-DOS versions of
.IR less ,
8-bit color is not supported; instead, decimal values are interpreted as 4-bit
CHAR_INFO.Attributes values
(see
.br
.nh
https://docs.microsoft.com/en-us/windows/console/char-info-str).
.hy
.RE
.IP "\-e or \-\-quit-at-eof"
Causes
.I less
@ -650,7 +754,6 @@ always begin at the start or end of the current screen respectively.
Displays a status column at the left edge of the screen.
The status column shows the lines that matched the current search,
and any lines that are marked (via the m or M command).
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
.I less
@ -676,7 +779,8 @@ command prompt from the "F" command.
.IP "\-L or \-\-no-lessopen"
Ignore the LESSOPEN environment variable
(see the INPUT PREPROCESSOR section below).
This option can be set from within \fIless\fP,
This option can be set from within
.IR less ,
but it will apply only to files opened subsequently, not to the
file which is currently open.
.IP "\-m or \-\-long-prompt"
@ -776,16 +880,33 @@ cannot keep track of the actual appearance of the screen
each type of control character).
Thus, various display problems may result,
such as long lines being split in the wrong place.
.sp
USE OF THE \-r OPTION IS NOT RECOMMENDED.
.IP "\-R or \-\-RAW-CONTROL-CHARS"
Like \-r, but only ANSI "color" escape sequences are output in "raw" form.
Unlike \-r, the screen appearance is maintained correctly in most cases.
ANSI "color" escape sequences are sequences of the form:
Like \-r, but only ANSI "color" escape sequences and OSC 8 hyperlink
sequences are output in "raw" form.
Unlike \-r, the screen appearance is maintained correctly,
provided that there are no escape sequences in the file
other than these types of escape sequences.
Color escape sequences are only supported when the color
is changed within one line, not across lines.
In other words, the beginning of each line is assumed to be
normal (non-colored), regardless of any escape sequences in previous lines.
For the purpose of keeping track of screen appearance,
these escape sequences are assumed to not move the cursor.
.sp
OSC 8 hyperlinks are sequences of the form:
.sp
ESC ] 8 ; \&...\& \\7
.sp
The terminating sequence may be either a BEL character (\\7)
or the two-character sequence "ESC \\".
.sp
ANSI color escape sequences are sequences of the form:
.sp
ESC [ \&...\& m
.sp
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.
where the "...\&" is zero or more color specification characters.
You can make
.I less
think that characters other than "m" can end ANSI color escape sequences
@ -820,7 +941,10 @@ If the environment variable LESSGLOBALTAGS is set, it is taken to be
the name of a command compatible with
.IR global (1),
and that command is executed to find the tag.
(See http://www.gnu.org/software/global/global.html).
(See
.nh
http://www.gnu.org/software/global/global.html).
.hy
The \-t option may also be specified from within
.I less
(using the \- command) as a way of examining a new file.
@ -848,6 +972,8 @@ using the terminal's hardware boldface 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.
Unicode formatting characters, such as the Byte Order Mark,
are sent to the terminal.
Text which is overstruck or underlined can be searched for
if neither \-u nor \-U is in effect.
.IP "\-V or \-\-version"
@ -941,6 +1067,14 @@ If the reopen succeeds and the file is a different file from the original
with the same name as the original (now renamed) file),
.I less
will display the contents of that new file.
.IP "\-\-incsearch"
Subsequent search commands will be "incremental"; that is,
.I less
will advance to the next line containing the search pattern
as each character of the pattern is typed in.
.IP "\-\-line-num-width"
Sets the minimum width of the line number field when the \-N option is in effect.
The default is 7 characters.
.IP "\-\-mouse"
Enables mouse input:
scrolling the mouse wheel down moves forward in the file,
@ -973,12 +1107,26 @@ If there is no attribute indicator, standout is used.
If set to "\-", truncated lines are not marked.
.IP "\-\-save-marks"
Save marks in the history file, so marks are retained
across different invocations of \fIless\fP.
across different invocations of
.IR less .
.IP "\-\-status-col-width"
Sets the width of the status column when the \-J option is in effect.
The default is 2 characters.
.IP "\-\-use-backslash"
This option changes the interpretations of options which follow this one.
After the \-\-use-backslash option, any backslash in an option string is
removed and the following character is taken literally.
This allows a dollar sign to be included in option strings.
.IP "\-\-use-color"
Enables the colored text in various places.
The -D option can be used to change the colors.
Colored text works only if the terminal supports
ANSI color escape sequences (as defined in ECMA-48 SGR;
see
.br
.nh
https://www.ecma-international.org/publications-and-standards/standards/ecma-48).
.hy
.IP "\-\-wheel-lines=\fIn\fP"
Set the number of lines to scroll when the mouse wheel is scrolled
and the \-\-mouse or \-\-MOUSE option is in effect.
@ -1004,7 +1152,7 @@ The + command described previously
may also be used to set (or change) an initial command for every file.
.
.SH "LINE EDITING"
When entering command line at the bottom of the screen
When entering a command line at the bottom of the screen
(for example, a filename for the :e command,
or the pattern for a search command),
certain keys can be used to manipulate the command line.
@ -1804,7 +1952,7 @@ The name of the editor (used for the v command).
.BR lesskey (1)
.
.SH COPYRIGHT
Copyright (C) 1984-2020 Mark Nudelman
Copyright (C) 1984-2021 Mark Nudelman
.PP
less is part of the GNU project and is free software.
You can redistribute it and/or modify it
@ -1833,4 +1981,4 @@ Report bugs at https://github.com/gwsw/less/issues.
.br
For more information, see the less homepage at
.br
http://www.greenwoodsoftware.com/less.
https://greenwoodsoftware.com/less.

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.

View File

@ -1,4 +1,4 @@
.TH LESSECHO 1 "Version 563: 13 Jun 2020"
.TH LESSECHO 1 "Version 581: 06 Apr 2021"
.SH NAME
lessecho \- expand metacharacters
.SH SYNOPSIS
@ -19,7 +19,7 @@ are surrounded by quotes instead.
.TP
.B \-ox
Specifies "x", rather than double-quote, to be the open quote character,
which is used if the -e- option is specified.
which is used if the \-e- option is specified.
.TP
.B \-cx
Specifies "x" to be the close quote character.
@ -42,11 +42,11 @@ Specifies "n" to be the escape char for metachars, as an integer.
.TP
.B \-a
Specifies that all arguments are to be quoted.
The default is that only arguments containing metacharacters are quoted
The default is that only arguments containing metacharacters are quoted.
.SH "SEE ALSO"
.BR less (1)
.SH AUTHOR
This manual page was written by Thomas Schoepf <schoepf@debian.org>,
for the Debian GNU/Linux system (but may be used by others).
.PP
Send bug reports or comments to bug-less@gnu.org.
Report bugs at https://github.com/gwsw/less/issues.

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.
@ -153,6 +153,7 @@ struct cmdname cmdnames[] =
{ "toggle-flag", A_OPT_TOGGLE },
{ "toggle-option", A_OPT_TOGGLE },
{ "undo-hilite", A_UNDO_SEARCH },
{ "clear-search", A_CLR_SEARCH },
{ "version", A_VERSION },
{ "visual", A_VISUAL },
{ NULL, 0 }
@ -459,7 +460,7 @@ tstr(pp, xlate)
*pp = p+2;
buf[0] = CONTROL(p[1]);
buf[1] = '\0';
if (buf[0] == CONTROL('K'))
if (xlate && buf[0] == CONTROL('K'))
return tstr_control_k;
return (buf);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.

View File

@ -1,5 +1,5 @@
'\" t
.TH LESSKEY 1 "Version 563: 13 Jun 2020"
.TH LESSKEY 1 "Version 581: 06 Apr 2021"
.SH NAME
lesskey \- specify key bindings for less
.SH SYNOPSIS
@ -18,10 +18,10 @@ The input file is a text file which describes the key bindings.
If the input file is "\-", standard input is read.
If no input file is specified, a standard filename is used
as the name of the input file, which depends on the system being used:
On Unix systems, $HOME/.lesskey is used;
on MS-DOS systems, $HOME/_lesskey is used;
and on OS/2 systems $HOME/lesskey.ini is used,
or $INIT/lesskey.ini if $HOME is undefined.
On Unix systems, "$HOME/.lesskey" is used;
on MS-DOS systems, "$HOME/_lesskey" is used;
and on OS/2 systems "$HOME/lesskey.ini" is used,
or "$INIT/lesskey.ini" if $HOME is undefined.
The output file is a binary file which is used by
.IR less .
If no output file is specified,
@ -29,10 +29,10 @@ and the environment variable LESSKEY is set,
the value of LESSKEY is used as the name of the output file.
Otherwise, a standard filename is used as the name of the output file,
which depends on the system being used:
On Unix and OS-9 systems, $HOME/.less is used;
on MS-DOS systems, $HOME/_less is used;
and on OS/2 systems, $HOME/less.ini is used,
or $INIT/less.ini if $HOME is undefined.
On Unix and OS-9 systems, "$HOME/.less" is used;
on MS-DOS systems, "$HOME/_less" is used;
and on OS/2 systems, "$HOME/less.ini" is used,
or "$INIT/less.ini" if $HOME is undefined.
If the output file already exists,
.I lesskey
will overwrite it.
@ -123,7 +123,7 @@ For example, see the "{" and ":t" commands in the example below.
The extra string has a special meaning for the "quit" action:
when
.I less
quits, first character of the extra string is used as its exit status.
quits, the first character of the extra string is used as its exit status.
.
.SH EXAMPLE
The following input file describes the set of
@ -171,6 +171,7 @@ r repaint
^R repaint
^L repaint
\eeu undo-hilite
\eeU clear-search
g goto-line
\ekh goto-line
< goto-line
@ -370,7 +371,7 @@ which start with a NUL character (0).
This NUL character should be represented as \e340 in a lesskey file.
.
.SH COPYRIGHT
Copyright (C) 1984-2020 Mark Nudelman
Copyright (C) 1984-2021 Mark Nudelman
.PP
less is part of the GNU project and is free software.
You can redistribute it and/or modify it
@ -395,4 +396,4 @@ See the GNU General Public License for more details.
.
Mark Nudelman
.br
Send bug reports or comments to <bug-less@gnu.org>.
Report bugs at https://github.com/gwsw/less/issues.

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.
@ -248,6 +248,8 @@ longish(VOID_PARAM)
static void
abort_long(VOID_PARAM)
{
if (loopcount >= 0)
return;
if (linenums == OPT_ONPLUS)
/*
* We were displaying line numbers, so need to repaint.
@ -308,6 +310,7 @@ find_linenum(pos)
#if HAVE_TIME
startime = get_time();
#endif
loopcount = 0;
if (p == &anchor || pos - p->prev->pos < p->pos - pos)
{
/*
@ -316,7 +319,6 @@ find_linenum(pos)
p = p->prev;
if (ch_seek(p->pos))
return (0);
loopcount = 0;
for (linenum = p->line, cpos = p->pos; cpos < pos; linenum++)
{
/*
@ -348,7 +350,6 @@ find_linenum(pos)
*/
if (ch_seek(p->pos))
return (0);
loopcount = 0;
for (linenum = p->line, cpos = p->pos; cpos > pos; linenum--)
{
/*
@ -368,7 +369,7 @@ find_linenum(pos)
*/
add_lnum(linenum, cpos);
}
loopcount = 0;
return (linenum);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.
@ -116,11 +116,13 @@ lsystem(cmd, donemsg)
*/
inp = dup(0);
close(0);
#if !MSDOS_COMPILER
#if OS2
/* The __open() system call translates "/dev/tty" to "con". */
if (__open("/dev/tty", OPEN_READ) < 0)
if (__open(tty_device(), OPEN_READ) < 0)
#else
if (open("/dev/tty", OPEN_READ) < 0)
if (open(tty_device(), OPEN_READ) < 0)
#endif
#endif
dup(inp);
#endif

View File

@ -1,6 +1,6 @@
/* $FreeBSD$ */
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
@ -25,7 +25,6 @@ public int is_tty;
public IFILE curr_ifile = NULL_IFILE;
public IFILE old_ifile = NULL_IFILE;
public struct scrpos initial_scrpos;
public int any_display = FALSE;
public POSITION start_attnpos = NULL_POSITION;
public POSITION end_attnpos = NULL_POSITION;
public int wscroll;
@ -59,10 +58,10 @@ public int one_screen;
extern int less_is_more;
extern int missing_cap;
extern int know_dumb;
extern int no_init;
extern int pr_type;
extern int quit_if_one_screen;
extern int no_init;
extern int errmsgs;
/*
@ -84,10 +83,14 @@ main(argc, argv)
progname = *argv++;
argc--;
#if SECURE
secure = 1;
#else
secure = 0;
s = lgetenv("LESSSECURE");
if (!isnullenv(s))
secure = 1;
#endif
#ifdef WIN32
if (getenv("HOME") == NULL)
@ -228,6 +231,7 @@ main(argc, argv)
* Output is not a tty.
* Just copy the input file(s) to output.
*/
set_output(1); /* write to stdout */
SET_BINARY(1);
if (edit_first() == 0)
{
@ -291,6 +295,18 @@ main(argc, argv)
}
}
if (errmsgs > 0)
{
/*
* We displayed some messages on error output
* (file descriptor 2; see flush()).
* Before erasing the screen contents, wait for a keystroke.
*/
less_printf("Press RETURN to continue ", NULL_PARG);
get_return();
putchr('\n');
}
set_output(1);
init();
commands();
quit(QUIT_OK);
@ -397,10 +413,13 @@ quit(status)
status = save_status;
else
save_status = status;
#if LESSTEST
rstat('Q');
#endif /*LESSTEST*/
quitting = 1;
edit((char*)NULL);
save_cmdhist();
if (any_display && is_tty)
if (interactive())
clear_bot();
deinit();
flush();

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.
@ -116,13 +116,17 @@ mark_get_ifile(m)
getumark(c)
int c;
{
PARG parg;
if (c >= 'a' && c <= 'z')
return (&marks[c-'a']);
if (c >= 'A' && c <= 'Z')
return (&marks[c-'A'+26]);
if (c == '\'')
return (&marks[LASTMARK]);
if (c == '#')
return (&marks[MOUSEMARK]);
error("Invalid mark letter", NULL_PARG);
parg.p_char = (char) c;
error("Invalid mark letter %c", &parg);
return (NULL);
}
@ -259,6 +263,7 @@ lastmark(VOID_PARAM)
if (scrpos.pos == NULL_POSITION)
return;
cmark(&marks[LASTMARK], curr_ifile, scrpos.pos, scrpos.ln);
marks_modified = 1;
}
/*
@ -370,7 +375,7 @@ mark_check_ifile(ifile)
IFILE ifile;
{
int i;
char *filename = lrealpath(get_filename(ifile));
char *filename = get_real_filename(ifile);
for (i = 0; i < NMARKS; i++)
{
@ -384,7 +389,6 @@ mark_check_ifile(ifile)
free(mark_filename);
}
}
free(filename);
}
#if CMD_HISTORY
@ -403,7 +407,7 @@ save_marks(fout, hdr)
return;
fprintf(fout, "%s\n", hdr);
for (i = 0; i < NUMARKS; i++)
for (i = 0; i < NMARKS; i++)
{
char *filename;
struct mark *m = &marks[i];
@ -413,12 +417,10 @@ save_marks(fout, hdr)
postoa(m->m_scrpos.pos, pos_str);
filename = m->m_filename;
if (filename == NULL)
filename = get_filename(m->m_ifile);
filename = lrealpath(filename);
filename = get_real_filename(m->m_ifile);
if (strcmp(filename, "-") != 0)
fprintf(fout, "m %c %d %s %s\n",
m->m_letter, m->m_scrpos.ln, pos_str, filename);
free(filename);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
@ -36,7 +36,7 @@ extern int sc_width;
extern int sc_height;
extern int secure;
extern int dohelp;
extern int any_display;
extern int is_tty;
extern char openquote;
extern char closequote;
extern char *prproto[];
@ -55,6 +55,9 @@ extern int rscroll_attr;
extern int mousecap;
extern int wheel_lines;
extern int less_is_more;
extern int linenum_width;
extern int status_col_width;
extern int use_color;
#if LOGFILE
extern char *namelogfile;
extern int force_logfile;
@ -65,6 +68,10 @@ public char *tagoption = NULL;
extern char *tags;
extern char ztags[];
#endif
#if LESSTEST
extern char *ttyin_name;
extern int rstat_file;
#endif /*LESSTEST*/
#if MSDOS_COMPILER
extern int nm_fg_color, nm_bg_color;
extern int bo_fg_color, bo_bg_color;
@ -395,13 +402,13 @@ opt_p(type, s)
} else
{
plusoption = TRUE;
ungetcc(CHAR_END_COMMAND);
ungetsc(s);
/*
* {{ This won't work if the "/" command is
* changed or invalidated by a .lesskey file. }}
*/
ungetsc("/");
ungetsc(s);
ungetcc_back(CHAR_END_COMMAND);
}
break;
}
@ -504,20 +511,28 @@ opt__V(type, s)
dispversion();
break;
case INIT:
/*
* Force output to stdout per GNU standard for --version output.
*/
any_display = 1;
set_output(1); /* Force output to stdout per GNU standard for --version output. */
putstr("less ");
putstr(version);
putstr(" (");
putstr(pattern_lib_name());
putstr(" regular expressions)\n");
putstr("Copyright (C) 1984-2020 Mark Nudelman\n\n");
{
char constant *copyright = "Copyright (C) 1984-2021 Mark Nudelman\n\n";
if (copyright[0] == '@')
copyright = "Copyright (C) 1984 Mark Nudelman\n\n";
putstr(copyright);
}
if (version[strlen(version)-1] == 'x')
{
putstr("** This is an EXPERIMENTAL build of the 'less' software,\n");
putstr("** and may not function correctly.\n");
putstr("** Obtain release builds from the web page below.\n\n");
}
putstr("less comes with NO WARRANTY, to the extent permitted by law.\n");
putstr("For information about the terms of redistribution,\n");
putstr("see the file named README in the less distribution.\n");
putstr("Home page: http://www.greenwoodsoftware.com/less\n");
putstr("Home page: https://greenwoodsoftware.com/less\n");
quit(QUIT_OK);
break;
}
@ -534,54 +549,64 @@ colordesc(s, fg_color, bg_color)
int *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)
{
#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;
else
{
s++;
bg = getnum(&s, "D", &err);
if (err)
if (*s == '\0')
{
error("Missing bg color in -D", NULL_PARG);
*fg_color = nm_fg_color | ul;
*bg_color = nm_bg_color;
return;
}
}
#if MSDOS_COMPILER==WIN32C
if (*s == 'u')
#endif
if (parse_color(s, &fg, &bg) == CT_NULL)
{
ul = COMMON_LVB_UNDERSCORE;
++s;
}
PARG p;
p.p_string = s;
error("Invalid color string \"%s\"", &p);
} else
{
if (fg == CV_NOCHANGE)
fg = nm_fg_color;
if (bg == CV_NOCHANGE)
bg = nm_bg_color;
#if MSDOS_COMPILER==WIN32C
fg |= ul;
#endif
if (*s != '\0')
error("Extra characters at end of -D option", NULL_PARG);
*fg_color = fg;
*bg_color = bg;
}
}
#endif
static int
color_from_namechar(namechar)
char namechar;
{
switch (namechar)
{
case 'A': return AT_COLOR_ATTN;
case 'B': return AT_COLOR_BIN;
case 'C': return AT_COLOR_CTRL;
case 'E': return AT_COLOR_ERROR;
case 'M': return AT_COLOR_MARK;
case 'N': return AT_COLOR_LINENUM;
case 'P': return AT_COLOR_PROMPT;
case 'R': return AT_COLOR_RSCROLL;
case 'S': return AT_COLOR_SEARCH;
case 'n': return AT_NORMAL;
case 's': return AT_STANDOUT;
case 'd': return AT_BOLD;
case 'u': return AT_UNDERLINE;
case 'k': return AT_BLINK;
default: return -1;
}
}
/*
* Handler for the -D option.
@ -593,33 +618,51 @@ opt_D(type, s)
char *s;
{
PARG p;
int attr;
switch (type)
{
case INIT:
case TOGGLE:
switch (*s++)
#if MSDOS_COMPILER
if (*s == 'a')
{
case 'n':
colordesc(s, &nm_fg_color, &nm_bg_color);
break;
case 'd':
colordesc(s, &bo_fg_color, &bo_bg_color);
break;
case 'u':
colordesc(s, &ul_fg_color, &ul_bg_color);
break;
case 'k':
colordesc(s, &bl_fg_color, &bl_bg_color);
break;
case 's':
colordesc(s, &so_fg_color, &so_bg_color);
break;
case 'a':
sgr_mode = !sgr_mode;
break;
default:
error("-D must be followed by n, d, u, k, s or a", NULL_PARG);
}
#endif
attr = color_from_namechar(s[0]);
if (attr < 0)
{
p.p_char = s[0];
error("Invalid color specifier '%c'", &p);
return;
}
if (!use_color && (attr & AT_COLOR))
{
error("Set --use-color before changing colors", NULL_PARG);
return;
}
s++;
#if MSDOS_COMPILER
if (!(attr & AT_COLOR))
{
switch (attr)
{
case AT_NORMAL:
colordesc(s, &nm_fg_color, &nm_bg_color);
break;
case AT_BOLD:
colordesc(s, &bo_fg_color, &bo_bg_color);
break;
case AT_UNDERLINE:
colordesc(s, &ul_fg_color, &ul_bg_color);
break;
case AT_BLINK:
colordesc(s, &bl_fg_color, &bl_bg_color);
break;
case AT_STANDOUT:
colordesc(s, &so_fg_color, &so_bg_color);
break;
}
if (type == TOGGLE)
@ -627,14 +670,23 @@ opt_D(type, s)
at_enter(AT_STANDOUT);
at_exit();
}
} else
#endif
if (set_color_map(attr, s) < 0)
{
p.p_string = s;
error("Invalid color string \"%s\"", &p);
return;
}
break;
#if MSDOS_COMPILER
case QUERY:
p.p_string = (sgr_mode) ? "on" : "off";
error("SGR mode is %s", &p);
break;
}
}
#endif
}
}
/*
* Handler for the -x option.
@ -759,7 +811,7 @@ opt_rscroll(type, s)
} else
{
rscroll_char = *fmt ? *fmt : '>';
rscroll_attr = attr;
rscroll_attr = attr|AT_COLOR_RSCROLL;
}
break; }
case QUERY: {
@ -834,6 +886,103 @@ opt_wheel_lines(type, s)
}
}
/*
* Handler for the --line-number-width option.
*/
/*ARGSUSED*/
public void
opt_linenum_width(type, s)
int type;
char *s;
{
PARG parg;
switch (type)
{
case INIT:
case TOGGLE:
if (linenum_width > MAX_LINENUM_WIDTH)
{
parg.p_int = MAX_LINENUM_WIDTH;
error("Line number width must not be larger than %d", &parg);
linenum_width = MIN_LINENUM_WIDTH;
}
break;
case QUERY:
break;
}
}
/*
* Handler for the --status-column-width option.
*/
/*ARGSUSED*/
public void
opt_status_col_width(type, s)
int type;
char *s;
{
PARG parg;
switch (type)
{
case INIT:
case TOGGLE:
if (status_col_width > MAX_STATUSCOL_WIDTH)
{
parg.p_int = MAX_STATUSCOL_WIDTH;
error("Status column width must not be larger than %d", &parg);
status_col_width = 2;
}
break;
case QUERY:
break;
}
}
#if LESSTEST
/*
* Handler for the --tty option.
*/
/*ARGSUSED*/
public void
opt_ttyin_name(type, s)
int type;
char *s;
{
switch (type)
{
case INIT:
ttyin_name = s;
is_tty = 1;
break;
}
}
/*
* Handler for the --rstat option.
*/
/*ARGSUSED*/
public void
opt_rstat(type, s)
int type;
char *s;
{
switch (type)
{
case INIT:
rstat_file = open(s, O_WRONLY|O_CREAT, 0664);
if (rstat_file < 0)
{
PARG parg;
parg.p_string = s;
error("Cannot create rstat file \"%s\"", &parg);
}
break;
}
}
#endif /*LESSTEST*/
/*
* Get the "screen window" size.
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
@ -23,8 +23,7 @@
static struct loption *pendopt;
public int plusoption = FALSE;
static char *optstring LESSPARAMS((char *s, char **p_str, char *printopt,
char *validchars));
static char *optstring LESSPARAMS((char *s, char **p_str, char *printopt, char *validchars));
static int flip_triple LESSPARAMS((int val, int lc));
extern int screen_trashed;
@ -157,8 +156,8 @@ scan_option(s)
every_first_cmd = save(str+1);
} else
{
ungetcc(CHAR_END_COMMAND);
ungetsc(str);
ungetcc_back(CHAR_END_COMMAND);
}
free(str);
continue;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
@ -59,6 +59,10 @@ public int no_hist_dups; /* Remove dups from history list */
public int mousecap; /* Allow mouse for scrolling */
public int wheel_lines; /* Number of lines to scroll on mouse wheel scroll */
public int perma_marks; /* Save marks in history file */
public int linenum_width; /* Width of line numbers */
public int status_col_width; /* Width of status column */
public int incr_search; /* Incremental search */
public int use_color; /* Use UI color */
#if HILITE_SEARCH
public int hilite_search; /* Highlight matched search patterns? */
#endif
@ -73,9 +77,7 @@ static struct optname b_optname = { "buffers", NULL };
static struct optname B__optname = { "auto-buffers", NULL };
static struct optname c_optname = { "clear-screen", NULL };
static struct optname d_optname = { "dumb", NULL };
#if MSDOS_COMPILER
static struct optname D__optname = { "color", NULL };
#endif
static struct optname e_optname = { "quit-at-eof", NULL };
static struct optname f_optname = { "force", NULL };
static struct optname F__optname = { "quit-if-one-screen", NULL };
@ -128,6 +130,14 @@ static struct optname nohistdups_optname = { "no-histdups", NULL };
static struct optname mousecap_optname = { "mouse", NULL };
static struct optname wheel_lines_optname = { "wheel-lines", NULL };
static struct optname perma_marks_optname = { "save-marks", NULL };
static struct optname linenum_width_optname = { "line-num-width", NULL };
static struct optname status_col_width_optname = { "status-col-width", NULL };
static struct optname incr_search_optname = { "incsearch", NULL };
static struct optname use_color_optname = { "use-color", NULL };
#if LESSTEST
static struct optname ttyin_name_optname = { "tty", NULL };
static struct optname rstat_optname = { "rstat", NULL };
#endif /*LESSTEST*/
/*
@ -185,16 +195,14 @@ static struct loption option[] =
NULL
}
},
#if MSDOS_COMPILER
{ 'D', &D__optname,
STRING|REPAINT, 0, NULL, opt_D,
STRING|REPAINT|NO_QUERY, 0, NULL, opt_D,
{
"color desc: ",
"Dadknsu0123456789.",
NULL,
NULL
}
},
#endif
{ 'e', &e_optname,
TRIPLE, OPT_OFF, &quit_at_eof, NULL,
{
@ -503,6 +511,56 @@ static struct loption option[] =
NULL
}
},
{ OLETTER_NONE, &linenum_width_optname,
NUMBER|REPAINT, MIN_LINENUM_WIDTH, &linenum_width, opt_linenum_width,
{
"Line number width: ",
"Line number width is %d chars",
NULL
}
},
{ OLETTER_NONE, &status_col_width_optname,
NUMBER|REPAINT, 2, &status_col_width, opt_status_col_width,
{
"Status column width: ",
"Status column width is %d chars",
NULL
}
},
{ OLETTER_NONE, &incr_search_optname,
BOOL, OPT_OFF, &incr_search, NULL,
{
"Incremental search is off",
"Incremental search is on",
NULL
}
},
{ OLETTER_NONE, &use_color_optname,
BOOL|REPAINT, OPT_OFF, &use_color, NULL,
{
"Don't use color",
"Use color",
NULL
}
},
#if LESSTEST
{ OLETTER_NONE, &ttyin_name_optname,
STRING|NO_TOGGLE, 0, NULL, opt_ttyin_name,
{
NULL,
NULL,
NULL
}
},
{ OLETTER_NONE, &rstat_optname,
STRING|NO_TOGGLE, 0, NULL, opt_rstat,
{
NULL,
NULL,
NULL
}
},
#endif /*LESSTEST*/
{ '\0', NULL, NOVAR, 0, NULL, NULL, { NULL, NULL, NULL } }
};

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
@ -23,6 +23,9 @@
#include "less.h"
#include <signal.h>
#include <setjmp.h>
#if MSDOS_COMPILER==WIN32C
#include <windows.h>
#endif
#if HAVE_TIME_H
#include <time.h>
#endif
@ -33,6 +36,15 @@
#include <values.h>
#endif
#if HAVE_POLL && !MSDOS_COMPILER && !defined(__APPLE__)
#define USE_POLL 1
#else
#define USE_POLL 0
#endif
#if USE_POLL
#include <poll.h>
#endif
/*
* BSD setjmp() saves (and longjmp() restores) the signal mask.
* This costs a system call or two per setjmp(), so if possible we clear the
@ -53,6 +65,27 @@ public int reading;
static jmp_buf read_label;
extern int sigs;
extern int ignore_eoi;
#if !MSDOS_COMPILER
extern int tty;
#endif
#if USE_POLL
/*
* Return true if one of the events has occurred on the specified file.
*/
static int
poll_events(fd, events)
int fd;
int events;
{
struct pollfd poller = { fd, events, 0 };
int n = poll(&poller, 1, 0);
if (n <= 0)
return 0;
return (poller.revents & events);
}
#endif
/*
* Like read() system call, but is deliberately interruptible.
@ -126,6 +159,29 @@ iread(fd, buf, len)
if (select(fd+1, &readfds, 0, 0, 0) == -1)
return (-1);
}
#endif
#if USE_POLL
if (ignore_eoi && fd != tty)
{
if (poll_events(tty, POLLIN) && getchr() == CONTROL('X'))
{
sigs |= S_INTERRUPT;
return (READ_INTR);
}
if (poll_events(fd, POLLERR|POLLHUP))
{
sigs |= S_INTERRUPT;
return (READ_INTR);
}
}
#else
#if MSDOS_COMPILER==WIN32C
if (win32_kbhit() && WIN32getch() == CONTROL('X'))
{
sigs |= S_INTERRUPT;
return (READ_INTR);
}
#endif
#endif
n = read(fd, buf, len);
#if 1
@ -135,7 +191,6 @@ iread(fd, buf, len)
* start returning 0 forever, instead of -1.
*/
{
extern int ignore_eoi;
if (!ignore_eoi)
{
static int consecutive_nulls = 0;
@ -204,18 +259,16 @@ get_time(VOID_PARAM)
strerror(err)
int err;
{
#if HAVE_SYS_ERRLIST
static char buf[16];
#if HAVE_SYS_ERRLIST
extern char *sys_errlist[];
extern int sys_nerr;
if (err < sys_nerr)
return sys_errlist[err];
#endif
sprintf(buf, "Error %d", err);
return buf;
#else
return ("cannot open");
#endif
}
#endif
@ -356,3 +409,24 @@ isatty(f)
}
#endif
public void
sleep_ms(ms)
int ms;
{
#if MSDOS_COMPILER==WIN32C
Sleep(ms);
#else
#if HAVE_NANOSLEEP
int sec = ms / 1000;
struct timespec t = { sec, (ms - sec*1000) * 1000000 };
nanosleep(&t, NULL);
#else
#if HAVE_USLEEP
usleep(ms);
#else
sleep((ms+999) / 1000);
#endif
#endif
#endif
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
@ -29,7 +29,6 @@ extern int sigs;
extern int sc_width;
extern int so_s_width, so_e_width;
extern int screen_trashed;
extern int any_display;
extern int is_tty;
extern int oldbot;
@ -42,7 +41,7 @@ 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;
extern int vt_enabled;
#endif
#endif
@ -82,47 +81,13 @@ put_line(VOID_PARAM)
static char obuf[OUTBUF_SIZE];
static char *ob = obuf;
static int outfd = 2; /* stderr */
/*
* Flush buffered output.
*
* If we haven't displayed any file data yet,
* output messages on error output (file descriptor 2),
* otherwise output on standard output (file descriptor 1).
*
* This has the desirable effect of producing all
* error messages on error output if standard output
* is directed to a file. It also does the same if
* we never produce any real output; for example, if
* the input file(s) cannot be opened. If we do
* eventually produce output, code in edit() makes
* sure these messages can be seen before they are
* overwritten or scrolled away.
*/
public void
flush(VOID_PARAM)
{
int n;
int fd;
n = (int) (ob - obuf);
if (n == 0)
return;
#if MSDOS_COMPILER==MSOFTC
if (is_tty && any_display)
{
*ob = '\0';
_outtext(obuf);
ob = obuf;
return;
}
#else
#if MSDOS_COMPILER==WIN32C || MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
if (is_tty && any_display)
static void
win_flush(VOID_PARAM)
{
*ob = '\0';
if (ctldisp != OPT_ONPLUS)
if (ctldisp != OPT_ONPLUS || (vt_enabled && sgr_mode))
WIN32textout(obuf, ob - obuf);
else
{
@ -266,11 +231,6 @@ flush(VOID_PARAM)
at |= 2;
break;
case 4: /* underline on */
#if MSDOS_COMPILER==WIN32C
if (have_ul)
bgi = COMMON_LVB_UNDERSCORE >> 4;
else
#endif
bgi = 8;
at |= 4;
break;
@ -366,12 +326,12 @@ flush(VOID_PARAM)
}
if (at & 16)
f = b ^ 8;
f &= 0xf;
#if MSDOS_COMPILER==WIN32C
b &= 0xf | (COMMON_LVB_UNDERSCORE >> 4);
f &= 0xf | COMMON_LVB_UNDERSCORE;
#else
b &= 0xf;
f &= 0xf;
#endif
b &= 0xf;
WIN32setcolors(f, b);
p_next = anchor = p + 1;
} else
@ -382,14 +342,67 @@ flush(VOID_PARAM)
WIN32textout(anchor, ob - anchor);
}
ob = obuf;
}
#endif
/*
* Flush buffered output.
*
* If we haven't displayed any file data yet,
* output messages on error output (file descriptor 2),
* otherwise output on standard output (file descriptor 1).
*
* This has the desirable effect of producing all
* error messages on error output if standard output
* is directed to a file. It also does the same if
* we never produce any real output; for example, if
* the input file(s) cannot be opened. If we do
* eventually produce output, code in edit() makes
* sure these messages can be seen before they are
* overwritten or scrolled away.
*/
public void
flush(VOID_PARAM)
{
int n;
n = (int) (ob - obuf);
if (n == 0)
return;
ob = obuf;
#if MSDOS_COMPILER==MSOFTC
if (interactive())
{
obuf[n] = '\0';
_outtext(obuf);
return;
}
#else
#if MSDOS_COMPILER==WIN32C || MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
if (interactive())
{
ob = obuf + n;
*ob = '\0';
win_flush();
return;
}
#endif
#endif
fd = (any_display) ? 1 : 2;
if (write(fd, obuf, n) != n)
if (write(outfd, obuf, n) != n)
screen_trashed = 1;
ob = obuf;
}
/*
* Set the output file descriptor (1=stdout or 2=stderr).
*/
public void
set_output(fd)
int fd;
{
flush();
outfd = fd;
}
/*
@ -491,8 +504,8 @@ type funcname(buf, ebuf) \
char **ebuf; \
{ \
type val = 0; \
for (;;) { \
char c = *buf++; \
for (;; buf++) { \
char c = *buf; \
if (c < '0' || c > '9') break; \
val = 10 * val + c - '0'; \
} \
@ -534,8 +547,11 @@ iprint_linenum(num)
/*
* This function implements printf-like functionality
* using a more portable argument list mechanism than printf's.
*
* {{ This paranoia about the portability of printf dates from experiences
* with systems in the 1980s and is of course no longer necessary. }}
*/
static int
public int
less_printf(fmt, parg)
char *fmt;
PARG *parg;
@ -572,6 +588,10 @@ less_printf(fmt, parg)
col += iprint_linenum(parg->p_linenum);
parg++;
break;
case 'c':
putchr(parg->p_char);
col++;
break;
case '%':
putchr('%');
break;
@ -615,24 +635,20 @@ error(fmt, parg)
errmsgs++;
if (any_display && is_tty)
{
if (!oldbot)
squish_check();
at_exit();
clear_bot();
at_enter(AT_STANDOUT);
col += so_s_width;
}
col += less_printf(fmt, parg);
if (!(any_display && is_tty))
if (!interactive())
{
less_printf(fmt, parg);
putchr('\n');
return;
}
if (!oldbot)
squish_check();
at_exit();
clear_bot();
at_enter(AT_STANDOUT|AT_COLOR_ERROR);
col += so_s_width;
col += less_printf(fmt, parg);
putstr(return_to_continue);
at_exit();
col += sizeof(return_to_continue) + so_e_width;
@ -667,7 +683,7 @@ ierror(fmt, parg)
{
at_exit();
clear_bot();
at_enter(AT_STANDOUT);
at_enter(AT_STANDOUT|AT_COLOR_ERROR);
(void) less_printf(fmt, parg);
putstr(intr_to_abort);
at_exit();
@ -687,22 +703,24 @@ query(fmt, parg)
int c;
int col = 0;
if (any_display && is_tty)
if (interactive())
clear_bot();
(void) less_printf(fmt, parg);
c = getchr();
if (!(any_display && is_tty))
if (interactive())
{
putchr('\n');
return (c);
}
lower_left();
if (col >= sc_width)
screen_trashed = 1;
flush();
} else
{
putchr('\n');
}
if (c == 'Q')
quit(QUIT_OK);
return (c);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.
@ -145,9 +145,10 @@ compile_pattern2(pattern, search_type, comp_pattern, show_error)
* Like compile_pattern2, but convert the pattern to lowercase if necessary.
*/
public int
compile_pattern(pattern, search_type, comp_pattern)
compile_pattern(pattern, search_type, show_error, comp_pattern)
char *pattern;
int search_type;
int show_error;
PATTERN_TYPE *comp_pattern;
{
char *cvt_pattern;
@ -160,7 +161,7 @@ compile_pattern(pattern, search_type, comp_pattern)
cvt_pattern = (char*) ecalloc(1, cvt_length(strlen(pattern), CVT_TO_LC));
cvt_text(cvt_pattern, pattern, (int *)NULL, (int *)NULL, CVT_TO_LC);
}
result = compile_pattern2(cvt_pattern, search_type, comp_pattern, 1);
result = compile_pattern2(cvt_pattern, search_type, comp_pattern, show_error);
if (cvt_pattern != pattern)
free(cvt_pattern);
return (result);
@ -214,6 +215,7 @@ uncompile_pattern(pattern)
#endif
}
#if 0
/*
* Can a pattern be successfully compiled?
*/
@ -224,13 +226,14 @@ valid_pattern(pattern)
PATTERN_TYPE comp_pattern;
int result;
CLEAR_PATTERN(comp_pattern);
SET_NULL_PATTERN(comp_pattern);
result = compile_pattern2(pattern, 0, &comp_pattern, 0);
if (result != 0)
return (0);
uncompile_pattern(&comp_pattern);
return (1);
}
#endif
/*
* Is a compiled pattern null?

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.
@ -11,7 +11,7 @@
#define __USE_GNU 1
#include <regex.h>
#define PATTERN_TYPE struct re_pattern_buffer *
#define CLEAR_PATTERN(name) name = NULL
#define SET_NULL_PATTERN(name) name = NULL
#endif
#if HAVE_POSIX_REGCOMP
@ -23,27 +23,27 @@ extern int less_is_more;
#define REGCOMP_FLAG 0
#endif
#define PATTERN_TYPE regex_t *
#define CLEAR_PATTERN(name) name = NULL
#define SET_NULL_PATTERN(name) name = NULL
#endif
#if HAVE_PCRE
#include <pcre.h>
#define PATTERN_TYPE pcre *
#define CLEAR_PATTERN(name) name = NULL
#define SET_NULL_PATTERN(name) name = NULL
#endif
#if HAVE_PCRE2
#define PCRE2_CODE_UNIT_WIDTH 8
#include <pcre2.h>
#define PATTERN_TYPE pcre2_code *
#define CLEAR_PATTERN(name) name = NULL
#define SET_NULL_PATTERN(name) name = NULL
#endif
#if HAVE_RE_COMP
char *re_comp LESSPARAMS ((char*));
int re_exec LESSPARAMS ((char*));
#define PATTERN_TYPE int
#define CLEAR_PATTERN(name) name = 0
#define SET_NULL_PATTERN(name) name = 0
#endif
#if HAVE_REGCMP
@ -51,17 +51,17 @@ char *regcmp LESSPARAMS ((char*));
char *regex LESSPARAMS ((char**, char*));
extern char *__loc1;
#define PATTERN_TYPE char **
#define CLEAR_PATTERN(name) name = NULL
#define SET_NULL_PATTERN(name) name = NULL
#endif
#if HAVE_V8_REGCOMP
#include "regexp.h"
extern int reg_show_error;
#define PATTERN_TYPE struct regexp *
#define CLEAR_PATTERN(name) name = NULL
#define SET_NULL_PATTERN(name) name = NULL
#endif
#if NO_REGEX
#define PATTERN_TYPE void *
#define CLEAR_PATTERN(name)
#define SET_NULL_PATTERN(name)
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
@ -35,6 +35,19 @@ extern int fd0;
#endif
#include <time.h>
#ifndef FOREGROUND_BLUE
#define FOREGROUND_BLUE 0x0001
#endif
#ifndef FOREGROUND_GREEN
#define FOREGROUND_GREEN 0x0002
#endif
#ifndef FOREGROUND_RED
#define FOREGROUND_RED 0x0004
#endif
#ifndef FOREGROUND_INTENSITY
#define FOREGROUND_INTENSITY 0x0008
#endif
#else
#if HAVE_SYS_IOCTL_H
@ -95,7 +108,9 @@ static char *windowid;
static int videopages;
static long msec_loops;
static int flash_created = 0;
#define SETCOLORS(fg,bg) { _settextcolor(fg); _setbkcolor(bg); }
#define SET_FG_COLOR(fg) _settextcolor(fg)
#define SET_BG_COLOR(bg) _setbkcolor(bg)
#define SETCOLORS(fg,bg) { SET_FG_COLOR(fg); SET_BG_COLOR(bg); }
#endif
#if MSDOS_COMPILER==BORLANDC
@ -106,7 +121,9 @@ static int flash_created = 0;
#define _settextposition(y,x) gotoxy(x,y)
#define _clearscreen(m) clrscr()
#define _outtext(s) cputs(s)
#define SETCOLORS(fg,bg) { textcolor(fg); textbackground(bg); }
#define SET_FG_COLOR(fg) textcolor(fg)
#define SET_BG_COLOR(bg) textbackground(bg)
#define SETCOLORS(fg,bg) { SET_FG_COLOR(fg); SET_BG_COLOR(bg); }
extern int sc_height;
#endif
@ -139,9 +156,11 @@ static void win32_deinit_term();
#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) \
#define APPLY_COLORS() { if (SetConsoleTextAttribute(con_out, curr_attr) == 0) \
error("SETCOLORS failed", NULL_PARG); }
#define SET_FG_COLOR(fg) { curr_attr |= (fg); APPLY_COLORS(); }
#define SET_BG_COLOR(bg) { curr_attr |= ((bg)<<4); APPLY_COLORS(); }
#define SETCOLORS(fg,bg) { curr_attr = MAKEATTR(fg,bg); APPLY_COLORS(); }
#endif
#if MSDOS_COMPILER
@ -159,7 +178,8 @@ 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? */
static DWORD init_output_mode; /* The initial console output mode */
public int vt_enabled = -1; /* Is virtual terminal processing available? */
#endif
#else
@ -192,6 +212,8 @@ static char
*sc_e_mousecap, /* End mouse capture mode */
*sc_init, /* Startup terminal initialization */
*sc_deinit; /* Exit terminal de-initialization */
static int attrcolor = -1;
#endif
static int init_done = 0;
@ -217,6 +239,9 @@ static int attrmode = AT_NORMAL;
static int termcap_debug = -1;
extern int binattr;
extern int one_screen;
#if LESSTEST
extern char *ttyin_name;
#endif /*LESSTEST*/
#if !MSDOS_COMPILER
static char *cheaper LESSPARAMS((char *t1, char *t2, char *def));
@ -249,6 +274,8 @@ extern int top_scroll;
extern int quit_if_one_screen;
extern int oldbot;
extern int mousecap;
extern int is_tty;
extern int use_color;
#if HILITE_SEARCH
extern int hilite_search;
#endif
@ -816,10 +843,10 @@ scrsize(VOID_PARAM)
#endif
#endif
if (sys_height > 0)
sc_height = sys_height;
else if ((s = lgetenv("LINES")) != NULL)
if ((s = lgetenv("LINES")) != NULL)
sc_height = atoi(s);
else if (sys_height > 0)
sc_height = sys_height;
#if !MSDOS_COMPILER
else if ((n = ltgetnum("li")) > 0)
sc_height = n;
@ -827,10 +854,10 @@ scrsize(VOID_PARAM)
if (sc_height <= 0)
sc_height = DEF_SC_HEIGHT;
if (sys_width > 0)
sc_width = sys_width;
else if ((s = lgetenv("COLUMNS")) != NULL)
if ((s = lgetenv("COLUMNS")) != NULL)
sc_width = atoi(s);
else if (sys_width > 0)
sc_width = sys_width;
#if !MSDOS_COMPILER
else if ((n = ltgetnum("co")) > 0)
sc_width = n;
@ -1093,6 +1120,7 @@ get_term(VOID_PARAM)
* before any file operations have been done on fd0.
*/
SET_BINARY(0);
GetConsoleMode(con_out, &init_output_mode);
GetConsoleScreenBufferInfo(con_out, &scr);
curr_attr = scr.wAttributes;
sy_bg_color = (curr_attr & BG_COLORS) >> 4; /* normalize */
@ -1497,6 +1525,34 @@ initcolor(VOID_PARAM)
#if MSDOS_COMPILER==WIN32C
/*
* Enable virtual terminal processing, if available.
*/
static void
win32_init_vt_term(VOID_PARAM)
{
DWORD output_mode;
if (vt_enabled == 0 || (vt_enabled == 1 && con_out == con_out_ours))
return;
GetConsoleMode(con_out, &output_mode);
vt_enabled = SetConsoleMode(con_out,
output_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
if (vt_enabled)
{
auto_wrap = 0;
ignaw = 1;
}
}
static void
win32_deinit_vt_term(VOID_PARAM)
{
if (vt_enabled == 1 && con_out == con_out_save)
SetConsoleMode(con_out, init_output_mode);
}
/*
* Termcap-like init with a private win32 console.
*/
@ -1513,8 +1569,6 @@ win32_init_term(VOID_PARAM)
if (con_out_ours == INVALID_HANDLE_VALUE)
{
DWORD output_mode;
/*
* Create our own screen buffer, so that we
* may restore the original when done.
@ -1525,12 +1579,6 @@ win32_init_term(VOID_PARAM)
(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;
@ -1556,6 +1604,68 @@ win32_deinit_term(VOID_PARAM)
#endif
#if !MSDOS_COMPILER
static void
do_tputs(str, affcnt, f_putc)
char *str;
int affcnt;
int (*f_putc)(int);
{
#if LESSTEST
if (ttyin_name != NULL)
putstr(str);
else
#endif /*LESSTEST*/
tputs(str, affcnt, f_putc);
}
/*
* Like tputs but we handle $<...> delay strings here because
* some implementations of tputs don't perform delays correctly.
*/
static void
ltputs(str, affcnt, f_putc)
char *str;
int affcnt;
int (*f_putc)(int);
{
while (str != NULL && *str != '\0')
{
#if HAVE_STRSTR
char *obrac = strstr(str, "$<");
if (obrac != NULL)
{
char str2[64];
int slen = obrac - str;
if (slen < sizeof(str2))
{
int delay;
/* Output first part of string (before "$<"). */
memcpy(str2, str, slen);
str2[slen] = '\0';
do_tputs(str2, affcnt, f_putc);
str += slen + 2;
/* Perform the delay. */
delay = lstrtoi(str, &str);
if (*str == '*')
delay *= affcnt;
flush();
sleep_ms(delay);
/* Skip past closing ">" at end of delay string. */
str = strstr(str, ">");
if (str != NULL)
str++;
continue;
}
}
#endif
/* Pass the rest of the string to tputs and we're done. */
do_tputs(str, affcnt, f_putc);
break;
}
}
#endif /* MSDOS_COMPILER */
/*
* Configure the termimal so mouse clicks and wheel moves
* produce input to less.
@ -1566,7 +1676,7 @@ init_mouse(VOID_PARAM)
if (!mousecap)
return;
#if !MSDOS_COMPILER
tputs(sc_s_mousecap, sc_height, putchr);
ltputs(sc_s_mousecap, sc_height, putchr);
#else
#if MSDOS_COMPILER==WIN32C
SetConsoleMode(tty, ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT
@ -1586,7 +1696,7 @@ deinit_mouse(VOID_PARAM)
if (!mousecap)
return;
#if !MSDOS_COMPILER
tputs(sc_e_mousecap, sc_height, putchr);
ltputs(sc_e_mousecap, sc_height, putchr);
#else
#if MSDOS_COMPILER==WIN32C
SetConsoleMode(tty, ENABLE_PROCESSED_INPUT | ENABLE_EXTENDED_FLAGS
@ -1605,11 +1715,12 @@ init(VOID_PARAM)
if (!(quit_if_one_screen && one_screen))
{
if (!no_init)
tputs(sc_init, sc_height, putchr);
ltputs(sc_init, sc_height, putchr);
if (!no_keypad)
tputs(sc_s_keypad, sc_height, putchr);
ltputs(sc_s_keypad, sc_height, putchr);
init_mouse();
}
init_done = 1;
if (top_scroll)
{
int i;
@ -1633,11 +1744,12 @@ init(VOID_PARAM)
init_mouse();
}
win32_init_vt_term();
#endif
init_done = 1;
initcolor();
flush();
#endif
init_done = 1;
}
/*
@ -1653,14 +1765,15 @@ deinit(VOID_PARAM)
{
deinit_mouse();
if (!no_keypad)
tputs(sc_e_keypad, sc_height, putchr);
ltputs(sc_e_keypad, sc_height, putchr);
if (!no_init)
tputs(sc_deinit, sc_height, putchr);
ltputs(sc_deinit, sc_height, putchr);
}
#else
/* Restore system colors. */
SETCOLORS(sy_fg_color, sy_bg_color);
#if MSDOS_COMPILER==WIN32C
win32_deinit_vt_term();
if (!(quit_if_one_screen && one_screen))
{
deinit_mouse();
@ -1675,14 +1788,31 @@ deinit(VOID_PARAM)
init_done = 0;
}
/*
* Are we interactive (ie. writing to an initialized tty)?
*/
public int
interactive(VOID_PARAM)
{
return (is_tty && init_done);
}
static void
assert_interactive(VOID_PARAM)
{
if (interactive()) return;
/* abort(); */
}
/*
* Home cursor (move to upper left corner of screen).
*/
public void
home(VOID_PARAM)
{
assert_interactive();
#if !MSDOS_COMPILER
tputs(sc_home, 1, putchr);
ltputs(sc_home, 1, putchr);
#else
flush();
_settextposition(1,1);
@ -1696,8 +1826,9 @@ home(VOID_PARAM)
public void
add_line(VOID_PARAM)
{
assert_interactive();
#if !MSDOS_COMPILER
tputs(sc_addline, sc_height, putchr);
ltputs(sc_addline, sc_height, putchr);
#else
flush();
#if MSDOS_COMPILER==MSOFTC
@ -1905,10 +2036,9 @@ win32_scroll_up(n)
public void
lower_left(VOID_PARAM)
{
if (!init_done)
return;
assert_interactive();
#if !MSDOS_COMPILER
tputs(sc_lower_left, 1, putchr);
ltputs(sc_lower_left, 1, putchr);
#else
flush();
_settextposition(sc_height, 1);
@ -1921,9 +2051,11 @@ lower_left(VOID_PARAM)
public void
line_left(VOID_PARAM)
{
assert_interactive();
#if !MSDOS_COMPILER
tputs(sc_return, 1, putchr);
ltputs(sc_return, 1, putchr);
#else
{
int row;
flush();
#if MSDOS_COMPILER==WIN32C
@ -1943,6 +2075,7 @@ line_left(VOID_PARAM)
#endif
#endif
_settextposition(row, 1);
}
#endif
}
@ -1984,8 +2117,9 @@ check_winch(VOID_PARAM)
goto_line(sindex)
int sindex;
{
assert_interactive();
#if !MSDOS_COMPILER
tputs(tgoto(sc_move, 0, sindex), 1, putchr);
ltputs(tgoto(sc_move, 0, sindex), 1, putchr);
#else
flush();
_settextposition(sindex+1, 1);
@ -2052,7 +2186,7 @@ vbell(VOID_PARAM)
#if !MSDOS_COMPILER
if (*sc_visual_bell == '\0')
return;
tputs(sc_visual_bell, sc_height, putchr);
ltputs(sc_visual_bell, sc_height, putchr);
#else
#if MSDOS_COMPILER==DJGPPC
ScreenVisualBell();
@ -2142,8 +2276,9 @@ bell(VOID_PARAM)
public void
clear(VOID_PARAM)
{
assert_interactive();
#if !MSDOS_COMPILER
tputs(sc_clear, sc_height, putchr);
ltputs(sc_clear, sc_height, putchr);
#else
flush();
#if MSDOS_COMPILER==WIN32C
@ -2161,8 +2296,9 @@ clear(VOID_PARAM)
public void
clear_eol(VOID_PARAM)
{
/* assert_interactive();*/
#if !MSDOS_COMPILER
tputs(sc_eol_clear, 1, putchr);
ltputs(sc_eol_clear, 1, putchr);
#else
#if MSDOS_COMPILER==MSOFTC
short top, left;
@ -2220,13 +2356,14 @@ clear_eol(VOID_PARAM)
static void
clear_eol_bot(VOID_PARAM)
{
assert_interactive();
#if MSDOS_COMPILER
clear_eol();
#else
if (below_mem)
tputs(sc_eos_clear, 1, putchr);
ltputs(sc_eos_clear, 1, putchr);
else
tputs(sc_eol_clear, 1, putchr);
ltputs(sc_eol_clear, 1, putchr);
#endif
}
@ -2259,42 +2396,305 @@ clear_bot(VOID_PARAM)
}
}
/*
* Color string may be "x[y]" where x and y are 4-bit color chars,
* or "N[.M]" where N and M are decimal integers>
* Any of x,y,N,M may also be "-" to mean "unchanged".
*/
/*
* Parse a 4-bit color char.
*/
static int
parse_color4(ch)
char ch;
{
switch (ch)
{
case 'k': return 0;
case 'r': return CV_RED;
case 'g': return CV_GREEN;
case 'y': return CV_RED|CV_GREEN;
case 'b': return CV_BLUE;
case 'm': return CV_RED|CV_BLUE;
case 'c': return CV_GREEN|CV_BLUE;
case 'w': return CV_RED|CV_GREEN|CV_BLUE;
case 'K': return 0|CV_BRIGHT;
case 'R': return CV_RED|CV_BRIGHT;
case 'G': return CV_GREEN|CV_BRIGHT;
case 'Y': return CV_RED|CV_GREEN|CV_BRIGHT;
case 'B': return CV_BLUE|CV_BRIGHT;
case 'M': return CV_RED|CV_BLUE|CV_BRIGHT;
case 'C': return CV_GREEN|CV_BLUE|CV_BRIGHT;
case 'W': return CV_RED|CV_GREEN|CV_BLUE|CV_BRIGHT;
case '-': return CV_NOCHANGE;
default: return CV_ERROR;
}
}
/*
* Parse a color as a decimal integer.
*/
static int
parse_color6(ps)
char **ps;
{
if (**ps == '-')
{
(*ps)++;
return CV_NOCHANGE;
} else
{
char *ops = *ps;
int color = lstrtoi(ops, ps);
if (*ps == ops)
return CV_ERROR;
return color;
}
}
/*
* Parse a color pair and return the foreground/background values.
* Return type of color specifier:
* CV_4BIT: fg/bg values are OR of CV_{RGB} bits.
* CV_6BIT: fg/bg values are integers entered by user.
*/
public COLOR_TYPE
parse_color(str, p_fg, p_bg)
char *str;
int *p_fg;
int *p_bg;
{
int fg;
int bg;
COLOR_TYPE type = CT_NULL;
if (str == NULL || *str == '\0')
return CT_NULL;
if (*str == '+')
str++; /* ignore leading + */
fg = parse_color4(str[0]);
bg = parse_color4((strlen(str) < 2) ? '-' : str[1]);
if (fg != CV_ERROR && bg != CV_ERROR)
type = CT_4BIT;
else
{
fg = parse_color6(&str);
bg = (fg != CV_ERROR && *str++ == '.') ? parse_color6(&str) : CV_NOCHANGE;
if (fg != CV_ERROR && bg != CV_ERROR)
type = CT_6BIT;
}
if (p_fg != NULL) *p_fg = fg;
if (p_bg != NULL) *p_bg = bg;
return type;
}
#if !MSDOS_COMPILER
static int
sgr_color(color)
int color;
{
switch (color)
{
case 0: return 30;
case CV_RED: return 31;
case CV_GREEN: return 32;
case CV_RED|CV_GREEN: return 33;
case CV_BLUE: return 34;
case CV_RED|CV_BLUE: return 35;
case CV_GREEN|CV_BLUE: return 36;
case CV_RED|CV_GREEN|CV_BLUE: return 37;
case CV_BRIGHT: return 90;
case CV_RED|CV_BRIGHT: return 91;
case CV_GREEN|CV_BRIGHT: return 92;
case CV_RED|CV_GREEN|CV_BRIGHT: return 93;
case CV_BLUE|CV_BRIGHT: return 94;
case CV_RED|CV_BLUE|CV_BRIGHT: return 95;
case CV_GREEN|CV_BLUE|CV_BRIGHT: return 96;
case CV_RED|CV_GREEN|CV_BLUE|CV_BRIGHT: return 97;
default: return color;
}
}
static void
tput_fmt(fmt, color, f_putc)
char *fmt;
int color;
int (*f_putc)(int);
{
char buf[16];
if (color == attrcolor)
return;
SNPRINTF1(buf, sizeof(buf), fmt, color);
ltputs(buf, 1, f_putc);
attrcolor = color;
}
static void
tput_color(str, f_putc)
char *str;
int (*f_putc)(int);
{
int fg;
int bg;
if (str != NULL && strcmp(str, "*") == 0)
{
/* Special case: reset to normal */
tput_fmt(ESCS"[m", -1, f_putc);
return;
}
switch (parse_color(str, &fg, &bg))
{
case CT_4BIT:
if (fg >= 0)
tput_fmt(ESCS"[%dm", sgr_color(fg), f_putc);
if (bg >= 0)
tput_fmt(ESCS"[%dm", sgr_color(bg)+10, f_putc);
break;
case CT_6BIT:
if (fg >= 0)
tput_fmt(ESCS"[38;5;%dm", fg, f_putc);
if (bg >= 0)
tput_fmt(ESCS"[48;5;%dm", bg, f_putc);
break;
default:
break;
}
}
static void
tput_inmode(mode_str, attr, attr_bit, f_putc)
char *mode_str;
int attr;
int attr_bit;
int (*f_putc)(int);
{
char *color_str;
if ((attr & attr_bit) == 0)
return;
color_str = get_color_map(attr_bit);
if (color_str == NULL || *color_str == '\0' || *color_str == '+')
{
ltputs(mode_str, 1, f_putc);
if (color_str == NULL || *color_str++ != '+')
return;
}
/* Color overrides mode string */
tput_color(color_str, f_putc);
}
static void
tput_outmode(mode_str, attr_bit, f_putc)
char *mode_str;
int attr_bit;
int (*f_putc)(int);
{
if ((attrmode & attr_bit) == 0)
return;
ltputs(mode_str, 1, f_putc);
}
#else /* MSDOS_COMPILER */
#if MSDOS_COMPILER==WIN32C
static int
WIN32put_fmt(fmt, color)
char *fmt;
int color;
{
char buf[16];
int len = SNPRINTF1(buf, sizeof(buf), fmt, color);
WIN32textout(buf, len);
return TRUE;
}
#endif
static int
win_set_color(attr)
int attr;
{
int fg;
int bg;
int out = FALSE;
char *str = get_color_map(attr);
if (str == NULL || str[0] == '\0')
return FALSE;
switch (parse_color(str, &fg, &bg))
{
case CT_4BIT:
if (fg >= 0 && bg >= 0)
{
SETCOLORS(fg, bg);
out = TRUE;
} else if (fg >= 0)
{
SET_FG_COLOR(fg);
out = TRUE;
} else if (bg >= 0)
{
SET_BG_COLOR(bg);
out = TRUE;
}
break;
#if MSDOS_COMPILER==WIN32C
case CT_6BIT:
if (vt_enabled)
{
if (fg > 0)
out = WIN32put_fmt(ESCS"[38;5;%dm", fg);
if (bg > 0)
out = WIN32put_fmt(ESCS"[48;5;%dm", bg);
}
break;
#endif
default:
break;
}
return out;
}
#endif /* MSDOS_COMPILER */
public void
at_enter(attr)
int attr;
{
attr = apply_at_specials(attr);
#if !MSDOS_COMPILER
/* The one with the most priority is last. */
if (attr & AT_UNDERLINE)
tputs(sc_u_in, 1, putchr);
if (attr & AT_BOLD)
tputs(sc_b_in, 1, putchr);
if (attr & AT_BLINK)
tputs(sc_bl_in, 1, putchr);
if (attr & AT_STANDOUT)
tputs(sc_s_in, 1, putchr);
tput_inmode(sc_u_in, attr, AT_UNDERLINE, putchr);
tput_inmode(sc_b_in, attr, AT_BOLD, putchr);
tput_inmode(sc_bl_in, attr, AT_BLINK, putchr);
/* Don't use standout and color at the same time. */
if (use_color && (attr & AT_COLOR))
tput_color(get_color_map(attr), putchr);
else
tput_inmode(sc_s_in, attr, AT_STANDOUT, putchr);
#else
flush();
/* The one with the most priority is first. */
if (attr & AT_STANDOUT)
if ((attr & AT_COLOR) && use_color)
{
win_set_color(attr);
} else if (attr & AT_STANDOUT)
{
SETCOLORS(so_fg_color, so_bg_color);
} else if (attr & AT_BLINK)
{
SETCOLORS(bl_fg_color, bl_bg_color);
}
else if (attr & AT_BOLD)
} else if (attr & AT_BOLD)
{
SETCOLORS(bo_fg_color, bo_bg_color);
}
else if (attr & AT_UNDERLINE)
} else if (attr & AT_UNDERLINE)
{
SETCOLORS(ul_fg_color, ul_bg_color);
}
#endif
attrmode = attr;
}
@ -2303,19 +2703,15 @@ at_exit(VOID_PARAM)
{
#if !MSDOS_COMPILER
/* Undo things in the reverse order we did them. */
if (attrmode & AT_STANDOUT)
tputs(sc_s_out, 1, putchr);
if (attrmode & AT_BLINK)
tputs(sc_bl_out, 1, putchr);
if (attrmode & AT_BOLD)
tputs(sc_b_out, 1, putchr);
if (attrmode & AT_UNDERLINE)
tputs(sc_u_out, 1, putchr);
tput_color("*", putchr);
tput_outmode(sc_s_out, AT_STANDOUT, putchr);
tput_outmode(sc_bl_out, AT_BLINK, putchr);
tput_outmode(sc_b_out, AT_BOLD, putchr);
tput_outmode(sc_u_out, AT_UNDERLINE, putchr);
#else
flush();
SETCOLORS(nm_fg_color, nm_bg_color);
#endif
attrmode = AT_NORMAL;
}
@ -2357,57 +2753,6 @@ apply_at_specials(attr)
return attr;
}
#if 0 /* No longer used */
/*
* Erase the character to the left of the cursor
* and move the cursor left.
*/
public void
backspace(VOID_PARAM)
{
#if !MSDOS_COMPILER
/*
* Erase the previous character by overstriking with a space.
*/
tputs(sc_backspace, 1, putchr);
putchr(' ');
tputs(sc_backspace, 1, putchr);
#else
#if MSDOS_COMPILER==MSOFTC
struct rccoord tpos;
flush();
tpos = _gettextposition();
if (tpos.col <= 1)
return;
_settextposition(tpos.row, tpos.col-1);
_outtext(" ");
_settextposition(tpos.row, tpos.col-1);
#else
#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
cputs("\b");
#else
#if MSDOS_COMPILER==WIN32C
COORD cpos;
DWORD cChars;
CONSOLE_SCREEN_BUFFER_INFO scr;
flush();
GetConsoleScreenBufferInfo(con_out, &scr);
cpos = scr.dwCursorPosition;
if (cpos.X <= 0)
return;
cpos.X--;
SetConsoleCursorPosition(con_out, cpos);
FillConsoleOutputCharacter(con_out, (TCHAR)' ', 1, cpos, &cChars);
SetConsoleCursorPosition(con_out, cpos);
#endif
#endif
#endif
#endif
}
#endif /* 0 */
/*
* Output a plain backspace, without erasing the previous char.
*/
@ -2419,7 +2764,7 @@ putbs(VOID_PARAM)
else
{
#if !MSDOS_COMPILER
tputs(sc_backspace, 1, putchr);
ltputs(sc_backspace, 1, putchr);
#else
int row, col;
@ -2638,3 +2983,4 @@ WIN32textout(text, len)
#endif
}
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
@ -33,6 +33,10 @@ extern POSITION start_attnpos;
extern POSITION end_attnpos;
extern int utf_mode;
extern int screen_trashed;
extern int sc_width;
extern int sc_height;
extern int chopline;
extern int hshift;
#if HILITE_SEARCH
extern int hilite_search;
extern int size_linebuf;
@ -41,8 +45,7 @@ extern int can_goto_line;
static int hide_hilite;
static POSITION prep_startpos;
static POSITION prep_endpos;
static int is_caseless;
static int is_ucase_pattern;
extern POSITION xxpos;
/*
* Structures for maintaining a set of ranges for hilites and filtered-out
@ -94,6 +97,7 @@ struct hilite_tree
static struct hilite_tree hilite_anchor = HILITE_INITIALIZER();
static struct hilite_tree filter_anchor = HILITE_INITIALIZER();
static struct pattern_info *filter_infos = NULL;
#endif
@ -105,6 +109,7 @@ struct pattern_info {
PATTERN_TYPE compiled;
char* text;
int search_type;
struct pattern_info *next;
};
#if NO_REGEX
@ -114,7 +119,8 @@ struct pattern_info {
#endif
static struct pattern_info search_info;
static struct pattern_info filter_info;
static int is_ucase_pattern;
static int is_caseless;
/*
* Are there any uppercase letters in this string?
@ -135,19 +141,35 @@ is_ucase(str)
return (0);
}
/*
* Discard a saved pattern.
*/
static void
clear_pattern(info)
struct pattern_info *info;
{
if (info->text != NULL)
free(info->text);
info->text = NULL;
#if !NO_REGEX
uncompile_pattern(&info->compiled);
#endif
}
/*
* Compile and save a search pattern.
*/
static int
set_pattern(info, pattern, search_type)
set_pattern(info, pattern, search_type, show_error)
struct pattern_info *info;
char *pattern;
int search_type;
int show_error;
{
#if !NO_REGEX
if (pattern == NULL)
CLEAR_PATTERN(info->compiled);
else if (compile_pattern(pattern, search_type, &info->compiled) < 0)
SET_NULL_PATTERN(info->compiled);
else if (compile_pattern(pattern, search_type, show_error, &info->compiled) < 0)
return -1;
#endif
/* Pattern compiled successfully; save the text too. */
@ -173,21 +195,6 @@ set_pattern(info, pattern, search_type)
return 0;
}
/*
* Discard a saved pattern.
*/
static void
clear_pattern(info)
struct pattern_info *info;
{
if (info->text != NULL)
free(info->text);
info->text = NULL;
#if !NO_REGEX
uncompile_pattern(&info->compiled);
#endif
}
/*
* Initialize saved pattern to nothing.
*/
@ -195,9 +202,10 @@ clear_pattern(info)
init_pattern(info)
struct pattern_info *info;
{
CLEAR_PATTERN(info->compiled);
SET_NULL_PATTERN(info->compiled);
info->text = NULL;
info->search_type = 0;
info->next = NULL;
}
/*
@ -207,7 +215,6 @@ init_pattern(info)
init_search(VOID_PARAM)
{
init_pattern(&search_info);
init_pattern(&filter_info);
}
/*
@ -217,18 +224,13 @@ init_search(VOID_PARAM)
get_cvt_ops(VOID_PARAM)
{
int ops = 0;
if (is_caseless || bs_mode == BS_SPECIAL)
{
if (is_caseless)
ops |= CVT_TO_LC;
if (bs_mode == BS_SPECIAL)
ops |= CVT_BS;
if (bs_mode != BS_CONTROL)
ops |= CVT_CRLF;
} else if (bs_mode != BS_CONTROL)
{
ops |= CVT_CRLF;
}
if (ctldisp == OPT_ONPLUS)
ops |= CVT_ANSI;
return (ops);
@ -292,6 +294,7 @@ repaint_hilite(on)
lower_left();
hide_hilite = save_hide_hilite;
}
#endif
/*
* Clear the attn hilite.
@ -299,6 +302,7 @@ repaint_hilite(on)
public void
clear_attn(VOID_PARAM)
{
#if HILITE_SEARCH
int sindex;
POSITION old_start_attnpos;
POSITION old_end_attnpos;
@ -337,27 +341,30 @@ clear_attn(VOID_PARAM)
}
if (moved)
lower_left();
}
#endif
}
/*
* Hide search string highlighting.
* Toggle or clear search string highlighting.
*/
public void
undo_search(VOID_PARAM)
undo_search(clear)
int clear;
{
if (!prev_pattern(&search_info))
clear_pattern(&search_info);
#if HILITE_SEARCH
if (clear)
{
clr_hilite();
} else
{
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);
#endif
}
@ -601,7 +608,7 @@ prev_unfiltered(pos)
* If nohide is nonzero, don't consider hide_hilite.
*/
public int
is_hilited(pos, epos, nohide, p_matches)
is_hilited_attr(pos, epos, nohide, p_matches)
POSITION pos;
POSITION epos;
int nohide;
@ -614,12 +621,12 @@ is_hilited(pos, epos, nohide, p_matches)
if (!status_col &&
start_attnpos != NULL_POSITION &&
pos < end_attnpos &&
(epos == NULL_POSITION || epos > start_attnpos))
pos <= end_attnpos &&
(epos == NULL_POSITION || epos >= start_attnpos))
/*
* The attn line overlaps this range.
*/
return (1);
return (AT_HILITE|AT_COLOR_ATTN);
match = is_hilited_range(pos, epos);
if (!match)
@ -631,7 +638,7 @@ is_hilited(pos, epos, nohide, p_matches)
* hilite in status column. In this case we want to return
* hilite status even if hiliting is disabled or hidden.
*/
return (1);
return (AT_HILITE|AT_COLOR_SEARCH);
/*
* Report matches, even if we're hiding highlights.
@ -650,7 +657,7 @@ is_hilited(pos, epos, nohide, p_matches)
*/
return (0);
return (1);
return (AT_HILITE|AT_COLOR_SEARCH);
}
/*
@ -1155,11 +1162,92 @@ search_pos(search_type)
return (pos);
}
/*
* Check to see if the line matches the filter pattern.
* If so, add an entry to the filter list.
*/
#if HILITE_SEARCH
static int
matches_filters(pos, cline, line_len, chpos, linepos, sp, ep)
POSITION pos;
char *cline;
int line_len;
int *chpos;
POSITION linepos;
char **sp;
char **ep;
{
struct pattern_info *filter;
for (filter = filter_infos; filter != NULL; filter = filter->next)
{
int line_filter = match_pattern(info_compiled(filter), filter->text,
cline, line_len, sp, ep, 0, filter->search_type);
if (line_filter)
{
struct hilite hl;
hl.hl_startpos = linepos;
hl.hl_endpos = pos;
add_hilite(&filter_anchor, &hl);
free(cline);
free(chpos);
return (1);
}
}
return (0);
}
#endif
/*
* Get the position of the first char in the screen line which
* puts tpos on screen.
*/
static POSITION
get_lastlinepos(pos, tpos, sheight)
POSITION pos;
POSITION tpos;
int sheight;
{
int nlines;
for (nlines = 0;; nlines++)
{
POSITION npos = forw_line(pos);
if (npos > tpos)
{
if (nlines < sheight)
return NULL_POSITION;
return pos;
}
pos = npos;
}
}
/*
* Get the segment index of tpos in the line starting at pos.
* A segment is a string of printable chars that fills the screen width.
*/
static int
get_seg(pos, tpos)
POSITION pos;
POSITION tpos;
{
int seg;
for (seg = 0;; seg++)
{
POSITION npos = forw_line_seg(pos, TRUE);
if (npos > tpos)
return seg;
pos = npos;
}
}
/*
* Search a subset of the file, specified by start/end position.
*/
static int
search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos, plastlinepos)
POSITION pos;
POSITION endpos;
int search_type;
@ -1167,6 +1255,7 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
int maxlines;
POSITION *plinepos;
POSITION *pendpos;
POSITION *plastlinepos;
{
char *line;
char *cline;
@ -1178,9 +1267,14 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
int cvt_len;
int *chpos;
POSITION linepos, oldpos;
int swidth = sc_width - line_pfx_width();
int sheight = sc_height - sindex_from_sline(jump_sline);
linenum = find_linenum(pos);
oldpos = pos;
/* When the search wraps around, end at starting position. */
if ((search_type & SRCH_WRAP) && endpos == NULL_POSITION)
endpos = pos;
for (;;)
{
/*
@ -1196,7 +1290,9 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
return (-1);
}
if ((endpos != NULL_POSITION && pos >= endpos) || maxlines == 0)
if ((endpos != NULL_POSITION && !(search_type & SRCH_WRAP) &&
(((search_type & SRCH_FORW) && pos >= endpos) ||
((search_type & SRCH_BACK) && pos <= endpos))) || maxlines == 0)
{
/*
* Reached end position without a match.
@ -1235,6 +1331,35 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
/*
* Reached EOF/BOF without a match.
*/
if (search_type & SRCH_WRAP)
{
/*
* The search wraps around the current file, so
* try to continue at BOF/EOF.
*/
if (search_type & SRCH_FORW)
{
pos = ch_zero();
} else
{
pos = ch_length();
if (pos == NULL_POSITION)
{
(void) ch_end_seek();
pos = ch_length();
}
}
if (pos != NULL_POSITION) {
/*
* Wrap-around was successful. Clear
* the flag so we don't wrap again, and
* continue the search at new pos.
*/
search_type &= ~SRCH_WRAP;
linenum = find_linenum(pos);
continue;
}
}
if (pendpos != NULL)
*pendpos = oldpos;
return (matches);
@ -1252,8 +1377,10 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
add_lnum(linenum, pos);
oldpos = pos;
#if HILITE_SEARCH
if (is_filtered(linepos))
continue;
#endif
/*
* If it's a caseless search, convert the line to lowercase.
@ -1267,26 +1394,15 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
#if HILITE_SEARCH
/*
* Check to see if the line matches the filter pattern.
* If so, add an entry to the filter list.
* If any filters are in effect, ignore non-matching lines.
*/
if (((search_type & SRCH_FIND_ALL) ||
if (filter_infos != NULL &&
((search_type & SRCH_FIND_ALL) ||
prep_startpos == NULL_POSITION ||
linepos < prep_startpos || linepos >= prep_endpos) &&
prev_pattern(&filter_info)) {
int line_filter = match_pattern(info_compiled(&filter_info), filter_info.text,
cline, line_len, &sp, &ep, 0, filter_info.search_type);
if (line_filter)
{
struct hilite hl;
hl.hl_startpos = linepos;
hl.hl_endpos = pos;
add_hilite(&filter_anchor, &hl);
free(cline);
free(chpos);
linepos < prep_startpos || linepos >= prep_endpos)) {
if (matches_filters(pos, cline, line_len, chpos, linepos, &sp, &ep))
continue;
}
}
#endif
/*
@ -1330,6 +1446,50 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
hilite_line(linepos, cline, line_len, chpos, sp, ep, cvt_ops);
}
#endif
if (chopline)
{
/*
* If necessary, shift horizontally to make sure
* search match is fully visible.
*/
if (sp != NULL && ep != NULL)
{
int start_off = sp - cline;
int end_off = ep - cline;
int save_hshift = hshift;
int sshift;
int eshift;
hshift = 0; /* make get_seg count screen lines */
chopline = FALSE;
sshift = swidth * get_seg(linepos, linepos + chpos[start_off]);
eshift = swidth * get_seg(linepos, linepos + chpos[end_off]);
chopline = TRUE;
if (sshift >= save_hshift && eshift <= save_hshift)
{
hshift = save_hshift;
} else
{
hshift = sshift;
screen_trashed = 1;
}
}
} else if (plastlinepos != NULL)
{
/*
* If the line is so long that the highlighted match
* won't be seen when the line is displayed normally
* (starting at the first char) because it fills the whole
* screen and more, scroll forward until the last char
* of the match appears in the last line on the screen.
* lastlinepos is the position of the first char of that last line.
*/
if (ep != NULL)
{
int end_off = ep - cline;
if (end_off >= swidth * sheight / 4) /* heuristic */
*plastlinepos = get_lastlinepos(linepos, linepos + chpos[end_off], sheight);
}
}
free(cline);
free(chpos);
if (plinepos != NULL)
@ -1358,8 +1518,8 @@ hist_pattern(search_type)
if (pattern == NULL)
return (0);
if (set_pattern(&search_info, pattern, search_type) < 0)
return (0);
if (set_pattern(&search_info, pattern, search_type, 1) < 0)
return (-1);
#if HILITE_SEARCH
if (hilite_search == OPT_ONPLUS && !hide_hilite)
@ -1392,7 +1552,7 @@ chg_caseless(VOID_PARAM)
* Regenerate the pattern using the new state.
*/
clear_pattern(&search_info);
hist_pattern(search_info.search_type);
(void) hist_pattern(search_info.search_type);
}
}
@ -1412,6 +1572,8 @@ search(search_type, pattern, n)
int n;
{
POSITION pos;
POSITION opos;
POSITION lastlinepos = NULL_POSITION;
if (pattern == NULL || *pattern == '\0')
{
@ -1419,9 +1581,12 @@ search(search_type, pattern, n)
* A null pattern means use the previously compiled pattern.
*/
search_type |= SRCH_AFTER_TARGET;
if (!prev_pattern(&search_info) && !hist_pattern(search_type))
if (!prev_pattern(&search_info))
{
int r = hist_pattern(search_type);
if (r == 0)
error("No previous regular expression", NULL_PARG);
if (r <= 0)
return (-1);
}
if ((search_type & SRCH_NO_REGEX) !=
@ -1455,7 +1620,8 @@ search(search_type, pattern, n)
/*
* Compile the pattern.
*/
if (set_pattern(&search_info, pattern, search_type) < 0)
int show_error = !(search_type & SRCH_INCR);
if (set_pattern(&search_info, pattern, search_type, show_error) < 0)
return (-1);
#if HILITE_SEARCH
if (hilite_search || status_col)
@ -1483,6 +1649,7 @@ search(search_type, pattern, n)
* Figure out where to start the search.
*/
pos = search_pos(search_type);
opos = position(sindex_from_sline(jump_sline));
if (pos == NULL_POSITION)
{
/*
@ -1490,14 +1657,16 @@ search(search_type, pattern, n)
*/
if (search_type & SRCH_PAST_EOF)
return (n);
#if HILITE_SEARCH
if (hilite_search == OPT_ON || status_col)
repaint_hilite(1);
#endif
error("Nothing to search", NULL_PARG);
return (-1);
}
n = search_range(pos, NULL_POSITION, search_type, n, -1,
&pos, (POSITION*)NULL);
&pos, (POSITION*)NULL, &lastlinepos);
if (n != 0)
{
/*
@ -1518,6 +1687,9 @@ search(search_type, pattern, n)
/*
* Go to the matching line.
*/
if (lastlinepos != NULL_POSITION)
jump_loc(lastlinepos, BOTTOM);
else if (pos != opos)
jump_loc(pos, jump_sline);
}
@ -1531,7 +1703,6 @@ search(search_type, pattern, n)
return (0);
}
#if HILITE_SEARCH
/*
* Prepare hilites in a given range of the file.
@ -1665,7 +1836,7 @@ prep_hilite(spos, epos, maxlines)
search_type |= (search_info.search_type & SRCH_NO_REGEX);
for (;;)
{
result = search_range(spos, epos, search_type, 0, maxlines, (POSITION*)NULL, &new_epos);
result = search_range(spos, epos, search_type, 0, maxlines, (POSITION*)NULL, &new_epos, (POSITION*)NULL);
if (result < 0)
return;
if (prep_endpos == NULL_POSITION || new_epos > prep_endpos)
@ -1718,11 +1889,29 @@ set_filter_pattern(pattern, search_type)
char *pattern;
int search_type;
{
struct pattern_info *filter;
clr_filter();
if (pattern == NULL || *pattern == '\0')
clear_pattern(&filter_info);
else
set_pattern(&filter_info, pattern, search_type);
{
/* Clear and free all filters. */
for (filter = filter_infos; filter != NULL; )
{
struct pattern_info *next_filter = filter->next;
clear_pattern(filter);
free(filter);
filter = next_filter;
}
filter_infos = NULL;
} else
{
/* Create a new filter and add it to the filter_infos list. */
filter = ecalloc(1, sizeof(struct pattern_info));
init_pattern(filter);
set_pattern(filter, pattern, search_type, 1);
filter->next = filter_infos;
filter_infos = filter;
}
screen_trashed = 1;
}
@ -1734,7 +1923,7 @@ is_filtering(VOID_PARAM)
{
if (ch_getflags() & CH_HELPFILE)
return (0);
return prev_pattern(&filter_info);
return (filter_infos != NULL);
}
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
@ -34,9 +34,11 @@ extern int linenums;
extern int wscroll;
extern int reading;
extern int quit_on_intr;
extern int less_is_more;
extern int secure;
extern long jump_sline_fraction;
extern int less_is_more;
/*
* Interrupt signal handler.
*/
@ -63,6 +65,9 @@ u_interrupt(type)
#endif
if (less_is_more)
quit(0);
#if HILITE_SEARCH
set_filter_pattern(NULL, 0);
#endif
if (reading)
intread(); /* May longjmp */
}
@ -125,6 +130,9 @@ wbreak_handler(dwCtrlType)
case CTRL_C_EVENT:
case CTRL_BREAK_EVENT:
sigs |= S_INTERRUPT;
#if HILITE_SEARCH
set_filter_pattern(NULL, 0);
#endif
return (TRUE);
default:
break;
@ -158,7 +166,7 @@ init_signals(on)
(void) LSIGNAL(SIGINT, u_interrupt);
#endif
#ifdef SIGTSTP
(void) LSIGNAL(SIGTSTP, stop);
(void) LSIGNAL(SIGTSTP, secure ? SIG_IGN : stop);
#endif
#ifdef SIGWINCH
(void) LSIGNAL(SIGWINCH, winch);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.
@ -50,8 +50,7 @@ static char *nextgtag(VOID_PARAM);
static char *prevgtag(VOID_PARAM);
static POSITION ctagsearch(VOID_PARAM);
static POSITION gtagsearch(VOID_PARAM);
static int getentry LESSPARAMS((char *buf, char **tag, char **file,
char **line));
static int getentry LESSPARAMS((char *buf, char **tag, char **file, char **line));
/*
* The list of tags generated by the last findgtag() call.

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.
@ -28,10 +28,35 @@ public HANDLE tty;
#else
public int tty;
#endif
#if LESSTEST
public char *ttyin_name = NULL;
public int rstat_file = -1;
#endif /*LESSTEST*/
extern int sigs;
extern int utf_mode;
extern int wheel_lines;
/*
* Get name of tty device.
*/
#if !MSDOS_COMPILER
public char *
tty_device(VOID_PARAM)
{
char *dev = NULL;
#if HAVE_TTYNAME
dev = ttyname(2);
#endif
if (dev == NULL)
dev = "/dev/tty";
#if LESSTEST
if (ttyin_name != NULL)
dev = ttyin_name;
#endif /*LESSTEST*/
return dev;
}
#endif /* MSDOS_COMPILER */
/*
* Open keyboard for input.
*/
@ -76,9 +101,9 @@ open_getchr(VOID_PARAM)
*/
#if OS2
/* The __open() system call translates "/dev/tty" to "con". */
tty = __open("/dev/tty", OPEN_READ);
tty = __open(tty_device(), OPEN_READ);
#else
tty = open("/dev/tty", OPEN_READ);
tty = open(tty_device(), OPEN_READ);
#endif
if (tty < 0)
tty = 2;
@ -131,6 +156,18 @@ default_wheel_lines(VOID_PARAM)
return lines;
}
#if LESSTEST
public void
rstat(st)
char st;
{
if (rstat_file < 0)
return;
lseek(rstat_file, SEEK_SET, 0);
write(rstat_file, &st, 1);
}
#endif /*LESSTEST*/
/*
* Get a character from the keyboard.
*/
@ -142,11 +179,11 @@ getchr(VOID_PARAM)
do
{
flush();
#if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC
/*
* In raw read, we don't see ^C so look here for it.
*/
flush();
#if MSDOS_COMPILER==WIN32C
if (ABORT_SIGS())
return (READ_INTR);
@ -158,11 +195,17 @@ getchr(VOID_PARAM)
if (c == '\003')
return (READ_INTR);
#else
#if LESSTEST
rstat('R');
#endif /*LESSTEST*/
{
unsigned char uc;
result = iread(tty, &uc, sizeof(char));
c = (char) uc;
}
#if LESSTEST
rstat('B');
#endif /*LESSTEST*/
if (result == READ_INTR)
return (READ_INTR);
if (result < 0)

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 1984-2020 Mark Nudelman
* Copyright (C) 1984-2021 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.
@ -894,6 +894,31 @@ v560 5/3/20 Fix regression when command results in no movement;
v561 5/11/20 Fix erroneous EOF calculation when F command is interrupted.
v562 5/19/20 Update Unicode tables; minor doc formatting.
v563 6/13/20 Fix crash due to realpath() incompatibility.
v564 8/25/20 Handle realpath consistently; update docs.
v565 11/3/20 Add ESC-U command, optimize calls to realpath().
v566 11/25/20 Fix crash when reopening a file while using LESSOPEN;
support OSC 8 hyperlinks.
v567 11/25/20 Fix typo.
v568 11/29/20 Fix some hyperlink bugs; add ^W search modifier
(thanks to Arminius); allow Makefile.aut to use Python
instead of Perl (thanks to Charlie Lin).
v569 12/1/20 Allow multiple & filters (thanks to Mattias Johansson),
allow ^X to exit F command.
v570 12/12/20 Better handling of multiple + or -p options;
fix bugs in horizontal scrolling.
v571 12/30/20 Add --line-num-width and --status-col-width options.
v572 1/4/21 Save lastmark in history file; don't toggle mouse reporting;
implement termcap delays.
v573 1/9/21 Limit eof bell to 1 per second.
v574 1/13/21 Add incremental search.
v575 1/17/21 Fix build without HILITE_SEARCH;
fix bug with ^K in lesskey extra string.
v576 2/4/21 Make sure search result is visible; add --use-color and --color.
v577 2/9/21 Use ttyname to get name of tty device.
v578 2/9/21 Doc
v579 2/14/21 Fix double-width char bugs and non-match search crash.
v580 3/2/21 Some color fixes; fix compiler warnings; some lesstest support.
v581 4/6/21 Ignore SIGTSTP in secure mode; don't print "skipping" when filtering.
*/
char version[] = "563";
char version[] = "581";

View File

@ -1,4 +1,3 @@
/* $FreeBSD$ */
/* defines.h. Generated from defines.h.in by configure. */
/* defines.h.in. Generated from configure.ac by autoheader. */
@ -259,6 +258,9 @@
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `nanosleep' function. */
#define HAVE_NANOSLEEP 1
/* Define HAVE_OSPEED if your termcap library has the ospeed variable. */
#define HAVE_OSPEED 1
@ -268,6 +270,9 @@
/* PCRE2 (Perl-compatible regular expression) library */
/* #undef HAVE_PCRE2 */
/* Define to 1 if you have the `poll' function. */
#define HAVE_POLL 1
/* Define to 1 if you have the `popen' function. */
#define HAVE_POPEN 1
@ -361,12 +366,18 @@
/* Define HAVE_TIME_T if your system supports the "time_t" type. */
#define HAVE_TIME_T 1
/* Define to 1 if you have the `ttyname' function. */
#define HAVE_TTYNAME 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define HAVE_UPPER_LOWER if you have isupper, islower, toupper, tolower. */
#define HAVE_UPPER_LOWER 1
/* Define to 1 if you have the `usleep' function. */
#define HAVE_USLEEP 1
/* Henry Spencer V8 regcomp() and regexp.h */
/* #undef HAVE_V8_REGCOMP */