MFV: less v710.

MFC after:	1 week
This commit is contained in:
Xin LI committed 2026-09-19 11:20:29 -07:00
commit 4523eebc6c
58 files changed
+3285 -1810

No files matched your search

+4
View File
@@ -51,6 +51,10 @@
# xargs -n1 | sort | uniq -d;
# done
# 20260918: lesskey(1) removed, lesskey(5) man page added
OLD_FILES+=usr/bin/lesskey
OLD_FILES+=usr/share/man/man1/lesskey.1.gz
# 20260813: lib9p.so becomes a private library
OLD_LIBS+=usr/lib/lib9p.so.1
+21
View File
@@ -27,6 +27,27 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 16.x IS SLOW:
world, or to merely disable the most expensive debugging functionality
at runtime, run "ln -s 'abort:false,junk:false' /etc/malloc.conf".)
20260919:
less(1) has been updated to version 710, which removes the obsolete
lesskey(1) utility. It is no longer built or installed, and the
manual page describing the lesskey file format has moved from
lesskey(1) to lesskey(5).
No separate compilation step is needed any more: less(1) has been
able to read plain-text lesskey files directly since version 590,
imported into FreeBSD in 2021. Keep your key bindings in the
plain-text ~/.lesskey (or the file named by $LESSKEYIN) rather than
compiling them into the binary ~/.less; system-wide bindings belong
in /etc/syslesskey (or $LESSKEYIN_SYSTEM) rather than /etc/sysless.
If both forms are present, the plain-text one is used and the binary
one is ignored.
Existing binary lesskey files are still read, so nothing stops
working immediately, but they can no longer be generated or
regenerated. Binary files produced by lesskey from less 240 or
older are no longer supported at all and must be rewritten in the
plain-text format.
20260916:
mfiutil(8)/mrsasutil(8) now display and parse the Exx:Syy drive
location notation using the controller's enclosure device ID (EID)
+81
View File
@@ -9,6 +9,87 @@
Report bugs, suggestions or comments at
https://github.com/gwsw/less/issues.
======================================================================
Major changes between "less" versions 704 and 710
* Add || command.
* In | and || commands, ^N allows entering line number instead of mark letter.
* Add "ESC-]" / "ESC-RIGHTARROW" (right-limit-scroll) command (github #783).
* In lesskey files, add \k^x syntax for control chars and \k+x syntax
for shifted chars.
* Underline OSC 8 links in text.
* Add -DO for custom coloring of OSC 8 links.
* Add LESSMSG, which allows translation of messages into other languages.
* Add LESSSECURE_DISALLOW.
* Add LESS_SHELL_COPTION.
* Add %G, %y, and %% in prompt strings.
* Add lesskey support for shift-uparrow, shift-downarrow, shift-pageup,
shift-pagedown, ctl-uparrow, ctl-downarrow, ctl-pageup, ctl-pagedown,
shift-delete.
* Change "make check" to use nonstandard object and binary file names,
to avoid accidentally installing test binaries (github #791).
* Fix issues on systems with volatile getenv return values.
* Improve error handling for malformed binary lesskey file.
* Improve messaging when using __mouse after --emouse (github #808).
* Remove support for obsolete pre-241 lesskey binary format.
* Remove obsolete lesskey program.
* Move lesskey man page to section 5.
* Update display when resize window while in F mode on Windows.
* Fix missing "END" message at end of &-filtered output (github #774).
* Fix missing bell with G command at end of &-filtered output (github #774).
* Don't reset signal handlers in a subprocess on Windows.
* Fix ' command to not modify the mark when given a numeric argument
(github #799).
* Fix erroneous message from --rscroll command when rscroll char is non-ASCII.
* Fix unexpected exit when TERM is invalid (github #809).
* Fix possible crash when use ":e #" after ":d" (github #810).
* Fix infinite loop if invalid option letter in LESS_UNSUPPORT.
* Fix crash if run !! command with no previous ! command (github #812).
* Fix inability to run a shell command starting with "!" character.
* Fix bugs using ^S search modifier (github #814).
* Fix display bugs when a status message contains non-ASCII chars
or is displayed on a very narrow screen (github #816).
* Fix bug defining command which has a built-in command as a prefix
(github #795).
* Fix string overrrun if input contains "\e\0".
* Fix memory leak when using ${...} in lesskey file.
* Fix status column display when long line is marked (github #820).
======================================================================
Major changes between "less" versions 702 and 704
+8 -9
View File
@@ -23,12 +23,12 @@
* The characters which serve as "open bracket" and
* "close bracket" are given.
*/
public void match_brac(char obrac, char cbrac, int forwdir, int n)
public void match_brac(char obrac, char cbrac, lbool forwdir, int n)
{
int c;
int nest;
POSITION pos;
int (*chget)();
int (*chget)(void);
extern int ch_forw_get(), ch_back_get();
@@ -41,9 +41,9 @@ public void match_brac(char obrac, char cbrac, int forwdir, int n)
if (pos == NULL_POSITION || ch_seek(pos))
{
if (forwdir)
error("Nothing in top line", NULL_PARG);
error(LM(Nothing_in_top_line), NULL_PARG);
else
error("Nothing in bottom line", NULL_PARG);
error(LM(Nothing_in_bottom_line), NULL_PARG);
return;
}
@@ -55,9 +55,9 @@ public void match_brac(char obrac, char cbrac, int forwdir, int n)
if ((c = ch_forw_get()) == '\n' || c == EOI)
{
if (forwdir)
error("No bracket in top line", NULL_PARG);
error(LM(No_bracket_in_top_line), NULL_PARG);
else
error("No bracket in bottom line", NULL_PARG);
error(LM(No_bracket_in_bottom_line), NULL_PARG);
return;
}
} while (c != obrac || --n > 0);
@@ -83,8 +83,7 @@ public void match_brac(char obrac, char cbrac, int forwdir, int n)
if (nest == INT_MAX)
break;
nest++;
}
else if (c == cbrac && --nest < 0)
} else if (c == cbrac && --nest < 0)
{
/*
* Found the matching bracket.
@@ -95,5 +94,5 @@ public void match_brac(char obrac, char cbrac, int forwdir, int n)
return;
}
}
error("No matching bracket", NULL_PARG);
error(LM(No_matching_bracket), NULL_PARG);
}
+31 -15
View File
@@ -124,8 +124,8 @@ extern int autobuf;
extern int sigs;
extern int follow_mode;
extern lbool waiting_for_data;
extern constant char helpdata[];
extern constant int size_helpdata;
extern constant char *help_data;
extern constant int size_help_data;
extern IFILE curr_ifile;
#if LOGFILE
extern int logfile;
@@ -256,7 +256,7 @@ static int ch_get(void)
return ('?');
if (less_lseek(ch_file, (less_off_t)pos, SEEK_SET) == BAD_LSEEK)
{
error("seek error", NULL_PARG);
error(LM(seek_error), NULL_PARG);
clear_eol();
return (EOI);
}
@@ -275,10 +275,12 @@ static int ch_get(void)
ch_have_ungotchar = FALSE;
} else if (ch_flags & CH_HELPFILE)
{
bp->data[bp->datasize] = (unsigned char) helpdata[ch_fpos];
bp->data[bp->datasize] = (unsigned char) help_data[ch_fpos];
n = 1;
} else
{
if (ch_file < 0)
return (EOI);
n = iread(ch_file, &bp->data[bp->datasize], LBUFSIZE - bp->datasize);
}
@@ -324,7 +326,22 @@ static int ch_get(void)
/* Either end of file or no data available.
* read_again indicates the latter. */
if (!read_again)
{
ch_fsize = pos;
if (ch_flags & CH_POPENED)
{
/*
* ch_file is a pipe from a LESSOPEN child program.
* Since we've read to EOF, the child should have exited.
* Close the pipe now so the child does not remain a
* zombie. This also reports any error status from the
* child if -show-preproc-errors is enabled.
*/
close_pipe(get_altpipe(curr_ifile));
set_altpipe(curr_ifile, NULL);
ch_file = -1;
}
}
if (ignore_eoi || read_again)
{
/* Wait a while, then try again. */
@@ -388,7 +405,7 @@ public void ch_ungetchar(int c)
else
{
if (ch_have_ungotchar)
error("ch_ungetchar overrun", NULL_PARG);
error(LM(ch_ungetchar_overrun), NULL_PARG);
ch_ungotchar = (unsigned char) c;
ch_have_ungotchar = TRUE;
}
@@ -408,7 +425,7 @@ public void end_logfile(void)
if (!tried && ch_fsize == NULL_POSITION)
{
tried = TRUE;
ierror("Finishing logfile", NULL_PARG);
ierror(LM(Finishing_logfile), NULL_PARG);
while (ch_forw_get() != EOI)
if (ABORT_SIGS())
break;
@@ -454,8 +471,7 @@ public void sync_logfile(void)
}
if (!wrote && !warned)
{
error("Warning: log file is incomplete",
NULL_PARG);
error(LM(log_file_is_incomplete), NULL_PARG);
warned = TRUE;
}
}
@@ -614,7 +630,7 @@ public POSITION ch_length(void)
if (ignore_eoi)
return (NULL_POSITION);
if (ch_flags & CH_HELPFILE)
return (size_helpdata);
return (size_help_data);
if (ch_flags & CH_NODATA)
return (0);
return (ch_fsize);
@@ -745,7 +761,7 @@ public void ch_flush(void)
ch_flags &= ~CH_CANSEEK;
} else
{
ch_fsize = (ch_flags & CH_HELPFILE) ? size_helpdata : filesize(ch_file);
ch_fsize = (ch_flags & CH_HELPFILE) ? size_help_data : filesize(ch_file);
}
if (less_lseek(ch_file, (less_off_t)0, SEEK_SET) == BAD_LSEEK)
@@ -755,7 +771,7 @@ public void ch_flush(void)
* there's a good chance we're at the beginning anyway.
* {{ I think this is bogus reasoning. }}
*/
error("seek error to 0", NULL_PARG);
error(LM(seek_error_to_0), NULL_PARG);
}
}
@@ -818,7 +834,7 @@ static void ch_delbufs(void)
/*
* Is it possible to seek on a file descriptor?
*/
public int seekable(int f)
public lbool seekable(int f)
{
#if MSDOS_COMPILER
extern int fd0;
@@ -828,7 +844,7 @@ public int seekable(int f)
* In MS-DOS, pipes are seekable. Check for
* standard input, and pretend it is not seekable.
*/
return (0);
return (FALSE);
}
#endif
return (less_lseek(f, (less_off_t)1, SEEK_SET) != BAD_LSEEK);
@@ -883,7 +899,7 @@ public void ch_init(int f, int flags, ssize_t nread)
/*
* Figure out the size of the file, if we can.
*/
ch_fsize = (flags & CH_HELPFILE) ? size_helpdata : filesize(ch_file);
ch_fsize = (flags & CH_HELPFILE) ? size_help_data : filesize(ch_file);
if (ch_fsize == 0 && nread > 0)
{
@@ -924,7 +940,7 @@ public void ch_close(void)
* But don't really close it if it was opened via popen(),
* because pclose() wants to close it.
*/
if (!(ch_flags & (CH_POPENED|CH_HELPFILE)))
if (ch_file >= 0 && !(ch_flags & (CH_POPENED|CH_HELPFILE)))
close(ch_file);
ch_file = -1;
} else
+25 -22
View File
@@ -191,12 +191,12 @@ static void ichardef_utf(constant char *s)
wchar_range_get(&s, &range);
if (range.last == 0)
{
error("invalid hex number(s) in LESSUTFCHARDEF", NULL_PARG);
error(LM(invalid_hex_number_in_LESSUTFCHARDEF), NULL_PARG);
quit(QUIT_ERROR);
}
if (*s++ != ':')
{
error("missing colon in LESSUTFCHARDEF", NULL_PARG);
error(LM(missing_colon_in_LESSUTFCHARDEF), NULL_PARG);
quit(QUIT_ERROR);
}
switch (*s++)
@@ -279,7 +279,7 @@ static void ichardef(constant char *s)
default:
invalid_chardef:
error("invalid chardef", NULL_PARG);
error(LM(invalid_chardef), NULL_PARG);
quit(QUIT_ERROR);
/*NOTREACHED*/
}
@@ -288,7 +288,7 @@ static void ichardef(constant char *s)
{
if (cp >= chardef + sizeof(chardef))
{
error("chardef longer than 256", NULL_PARG);
error(LM(chardef_longer_than_256), NULL_PARG);
quit(QUIT_ERROR);
/*NOTREACHED*/
}
@@ -305,7 +305,7 @@ static void ichardef(constant char *s)
* Define a charset, given a charset name.
* The valid charset names are listed in the "charsets" array.
*/
static int icharset(constant char *name, int no_error)
static int icharset(constant char *name, lbool no_error)
{
struct charset *p;
struct cs_alias *a;
@@ -341,7 +341,7 @@ static int icharset(constant char *name, int no_error)
}
if (!no_error) {
error("invalid charset name", NULL_PARG);
error(LM(invalid_charset_name), NULL_PARG);
quit(QUIT_ERROR);
}
return (0);
@@ -353,9 +353,9 @@ static int icharset(constant char *name, int no_error)
*/
static void ilocale(void)
{
int c;
size_t c;
for (c = 0; c < (int) sizeof(chardef); c++)
for (c = 0; c < sizeof(chardef); c++)
{
if (isprint(c))
chardef[c] = 0;
@@ -411,7 +411,7 @@ static void set_charset(void)
* See if environment variable LESSCHARSET is defined.
*/
s = lgetenv("LESSCHARSET");
if (icharset(s, 0))
if (icharset(s, FALSE))
return;
/*
@@ -438,7 +438,7 @@ static void set_charset(void)
#endif
{
s = nl_langinfo(CODESET);
if (icharset(s, 1))
if (icharset(s, TRUE))
return;
}
#endif
@@ -453,7 +453,7 @@ static void set_charset(void)
{
if ( strstr(s, "UTF-8") != NULL || strstr(s, "utf-8") != NULL
|| strstr(s, "UTF8") != NULL || strstr(s, "utf8") != NULL)
if (icharset("utf-8", 1))
if (icharset("utf-8", TRUE))
return;
}
@@ -466,12 +466,12 @@ static void set_charset(void)
#else
#if MSDOS_COMPILER
#if MSDOS_COMPILER==WIN32C
(void) icharset("utf-8", 1);
(void) icharset("utf-8", TRUE);
#else
(void) icharset("dos", 1);
(void) icharset("dos", TRUE);
#endif
#else
(void) icharset("utf-8", 1);
(void) icharset("utf-8", TRUE);
#endif
#endif
}
@@ -527,7 +527,7 @@ public constant char * prchar(LWCHAR c)
/* {{ Fixed buffer size means LESSBINFMT etc can be truncated. }} */
static char buf[MAX_PRCHAR_LEN+1];
c &= 0377; /*{{type-issue}}*/
c = (unsigned char) c; /* {{ parameter is interpreted as a byte }} */
if ((c < 128 || !utf_mode) && !control_char(c))
SNPRINTF1(buf, sizeof(buf), "%c", (int) c);
else if (c == ESC)
@@ -617,27 +617,28 @@ public lbool is_utf8_well_formed(constant char *ssa, int slen)
unsigned char s0 = ss[0];
if (IS_UTF8_LEAD5(s0) || IS_UTF8_LEAD6(s0) || IS_UTF8_INVALID(s0))
return (FALSE);
return (FALSE); /* invalid lead byte */
len = utf_len(s0);
if (len > slen)
return (FALSE);
return (FALSE); /* UTF-8 sequence doesn't fit in buffer */
if (len == 1)
return (TRUE);
if (len == 2)
{
if (s0 < 0xC2)
return (FALSE);
return (FALSE); /* overlong (fits in 1 byte) */
} else
{
/* mask = byte with len high-order bits set to 1, others 0 */
unsigned char mask = (unsigned char) (~((1 << (8-len)) - 1));
if (s0 == mask && (ss[1] & mask) == 0x80)
return (FALSE);
return (FALSE); /* overlong (fits in fewer bytes) */
}
for (i = 1; i < len; i++)
if (!IS_UTF8_TRAIL(ss[i]))
return (FALSE);
return (FALSE); /* not a continuation byte */
return (TRUE);
}
@@ -651,7 +652,6 @@ public void utf_skip_to_lead(constant char **pp, constant char *limit)
} while (*pp < limit && !IS_UTF8_LEAD((*pp)[0] & 0377) && !IS_ASCII_OCTET((*pp)[0]));
}
/*
* Get the value of a UTF-8 character.
*/
@@ -755,7 +755,8 @@ public void put_wchar(mutable char **pp, LWCHAR ch)
}
/*
* Step forward or backward one character in a string.
* Step forward (dir > 0) or backward (dir < 0) one character in a string.
* If dir > 0, limit is end of string; if dir < 0, limit is start of string.
*/
public LWCHAR step_charc(constant char **pp, signed int dir, constant char *limit)
{
@@ -779,6 +780,7 @@ public LWCHAR step_charc(constant char **pp, signed int dir, constant char *limi
len = utf_len(*p);
if (p + len > limit || !is_utf8_well_formed(p, len))
{
/* Invalid UTF-8 sequence; just take the next byte as a character. */
ch = (LWCHAR) (unsigned char) *p++;
} else
{
@@ -797,6 +799,7 @@ public LWCHAR step_charc(constant char **pp, signed int dir, constant char *limi
len = utf_len(*--p);
if (p + len != *pp || !is_utf8_well_formed(p, len))
{
/* Invalid UTF-8 sequence; just take the next byte as a character. */
p = *pp - 1;
ch = (LWCHAR) (unsigned char) *p;
} else
+11 -2
View File
@@ -89,6 +89,7 @@
#define A_F_FOREVER_BELL 77
#define A_L_MOUSE 78
#define A_R_MOUSE 79
#define A_RSHIFT_LIMIT 80
/* These values must not conflict with any A_* or EC_* value. */
#define A_INVALID 100
@@ -180,6 +181,14 @@
#define SK_CTL_END 37
#define SK_SHIFT_LEFT_ARROW 38
#define SK_SHIFT_RIGHT_ARROW 39
#define SK_PAD_ENTER 41
#define SK_CONTROL_K 40
#define SK_PAD_ENTER 41
#define SK_SHIFT_UP_ARROW 42
#define SK_SHIFT_DOWN_ARROW 43
#define SK_CTL_UP_ARROW 44
#define SK_CTL_DOWN_ARROW 45
#define SK_SHIFT_DELETE 46
#define SK_SHIFT_PAGE_UP 47
#define SK_SHIFT_PAGE_DOWN 48
#define SK_CTL_PAGE_UP 49
#define SK_CTL_PAGE_DOWN 50
+19 -14
View File
@@ -358,7 +358,7 @@ static void cmd_lshift(void)
s = ns;
}
cmd_offset = (int) (s - cmdbuf);
cmd_offset = (int) ptr_diff(s, cmdbuf);
save_cp = cp;
cmd_home();
cmd_repaint(save_cp);
@@ -387,7 +387,7 @@ static void cmd_rshift(void)
cols += width;
}
cmd_offset = (int) (s - cmdbuf);
cmd_offset = (int) ptr_diff(s, cmdbuf);
save_cp = cp;
cmd_home();
cmd_repaint(save_cp);
@@ -479,7 +479,7 @@ static int cmd_erase(void)
*/
s = cp;
cmd_left();
clen = (int) (s - cp);
clen = (int) ptr_diff(s, cp);
/*
* Remove the char from the buffer (shift the buffer left).
@@ -993,10 +993,12 @@ static int cmd_istr(constant char *str)
*/
static void set_tk_original(constant char *word)
{
size_t len = ptr_diff(cp, word);
if (tk_original != NULL)
free(tk_original);
tk_original = (char *) ecalloc(ptr_diff(cp,word)+1, sizeof(char));
strncpy(tk_original, word, ptr_diff(cp,word));
tk_original = (char *) ecalloc(len+1, sizeof(char));
strncpy(tk_original, word, len);
tk_original[len] = '\0';
}
#if TAB_COMPLETE_FILENAME
@@ -1418,15 +1420,18 @@ public LINENUM cmd_int(mutable long *frac)
{
if (ckd_mul(&n, n, 10) || ckd_add(&n, n, *p - '0'))
{
error("Integer is too big", NULL_PARG);
error(LM(Integer_is_too_big), NULL_PARG);
return (0);
}
}
*frac = 0;
if (*p++ == '.')
if (frac != NULL)
{
/* {{ Just ignore error in fractional part. }} */
(void) getfraction(&p, frac);
*frac = 0;
if (*p++ == '.')
{
/* {{ Just ignore error in fractional part. }} */
(void) getfraction(&p, frac);
}
}
return (n);
}
@@ -1481,7 +1486,7 @@ static char * histfile_find(lbool must_exist)
name = dirfile(lgetenv("XDG_STATE_HOME"), &LESSHISTFILE[1], must_exist);
if (name == NULL)
{
char *dir = dirfile(home, ".local/state", 1);
char *dir = dirfile(home, ".local/state", TRUE);
if (dir != NULL)
{
name = dirfile(dir, &LESSHISTFILE[1], must_exist);
@@ -1606,7 +1611,7 @@ static void addhist_init(void *uparam, struct mlist *ml, constant char *string)
{
(void) uparam;
if (ml != NULL)
cmd_addhist(ml, string, 0);
cmd_addhist(ml, string, FALSE);
else if (string != NULL)
restore_mark(string);
}
@@ -1721,8 +1726,8 @@ static void make_file_private(FILE *f)
#if HAVE_FCHMOD
lbool do_chmod = TRUE;
#if HAVE_STAT
struct stat statbuf;
int r = fstat(fileno(f), &statbuf);
less_stat_t statbuf;
int r = less_fstat(fileno(f), &statbuf);
if (r < 0 || !S_ISREG(statbuf.st_mode))
/* Don't chmod if not a regular file. */
do_chmod = FALSE;
+165 -63
View File
@@ -38,7 +38,7 @@ extern int hshift;
extern int bs_mode;
extern int proc_backspace;
extern int show_attn;
extern int less_is_more;
extern lbool less_is_more;
extern int chopline;
extern POSITION highest_hilite;
extern char *every_first_cmd;
@@ -103,7 +103,8 @@ static int search_incr_hshift;
static time_type ignoring_input_time;
#endif
#if PIPEC
static char pipec;
static POSITION pipe_pos1;
static POSITION pipe_pos2;
#endif
/* Stack of ungotten chars (via ungetcc) */
@@ -181,28 +182,34 @@ static void mca_search1(void)
set_mca(A_B_SEARCH);
if (search_type & SRCH_NO_MATCH)
cmd_putstr("Non-match ");
cmd_putstr(LM(Non_match));
if (search_type & SRCH_FIRST_FILE)
cmd_putstr("First-file ");
cmd_putstr(LM(First_file));
if (search_type & SRCH_PAST_EOF)
cmd_putstr("EOF-ignore ");
cmd_putstr(LM(EOF_ignore));
if (search_type & SRCH_NO_MOVE)
cmd_putstr("Keep-pos ");
cmd_putstr(LM(Keep_pos));
if (search_type & SRCH_NO_REGEX)
cmd_putstr("Regex-off ");
cmd_putstr(LM(Regex_off));
if (search_type & SRCH_WRAP)
cmd_putstr("Wrap ");
cmd_putstr(LM(Wrap));
for (i = 1; i <= NUM_SEARCH_COLORS; i++)
{
if (search_type & SRCH_SUBSEARCH(i))
{
char buf[INT_STRLEN_BOUND(int)+8];
SNPRINTF1(buf, sizeof(buf), "Sub-%d ", i);
static char *buf = NULL;
static size_t buflen;
if (buf == NULL)
{
buflen = INT_STRLEN_BOUND(int)+strlen(LM(Sub_X)+1);
buf = ecalloc(buflen, sizeof(char));
}
SNPRINTF1(buf, buflen, LM(Sub_X), i);
cmd_putstr(buf);
}
}
if (literal_char)
cmd_putstr("Lit ");
cmd_putstr(LM(Lit));
#if HILITE_SEARCH
if (search_type & SRCH_FILTER)
@@ -300,10 +307,10 @@ static void exec_mca(void)
curropt = NULL;
break;
case A_F_BRACKET:
match_brac(cbuf[0], cbuf[1], 1, (int) number);
match_brac(cbuf[0], cbuf[1], TRUE, (int) number);
break;
case A_B_BRACKET:
match_brac(cbuf[1], cbuf[0], 0, (int) number);
match_brac(cbuf[1], cbuf[0], FALSE, (int) number);
break;
#if EXAMINE
case A_EXAMINE: {
@@ -329,7 +336,7 @@ static void exec_mca(void)
constant char *done_msg = (*cbuf == CONTROL('P')) ? NULL : "!done";
if (done_msg == NULL)
++cbuf;
if (*cbuf != '!')
if (strcmp(cbuf, "!") != 0)
{
if (shellcmd != NULL)
free(shellcmd);
@@ -337,9 +344,7 @@ static void exec_mca(void)
}
if (!secure_allow(SF_SHELL))
break;
if (shellcmd == NULL)
shellcmd = "";
lsystem(shellcmd, done_msg);
lsystem(shellcmd == NULL ? "" : shellcmd, done_msg);
break; }
case A_PSHELL: {
constant char *done_msg = (*cbuf == CONTROL('P')) ? NULL : "#done";
@@ -357,7 +362,7 @@ static void exec_mca(void)
++cbuf;
if (!secure_allow(SF_PIPE))
break;
(void) pipe_mark(pipec, cbuf);
(void) pipe_pos(cbuf, pipe_pos1, pipe_pos2);
if (done_msg != NULL)
error(done_msg, NULL_PARG);
break; }
@@ -513,7 +518,7 @@ static int mca_opt_char(char c)
parg.p_string = get_cmdbuf();
if (parg.p_string == NULL)
return (MCA_MORE);
error("There is no --%s option", &parg);
error(LM(There_is_no__X_option), &parg);
return (MCA_DONE);
}
optgetname = FALSE;
@@ -529,7 +534,7 @@ static int mca_opt_char(char c)
if (curropt == NULL)
{
parg.p_string = propt(c);
error("There is no %s option", &parg);
error(LM(There_is_no_X_option), &parg);
return (MCA_DONE);
}
opt_lower = ASCII_IS_LOWER(c);
@@ -608,8 +613,14 @@ static int mca_search_char(char c)
flag = SRCH_NO_MOVE;
break;
case CONTROL('S'): { /* SUBSEARCH */
char buf[INT_STRLEN_BOUND(int)+24];
SNPRINTF1(buf, sizeof(buf), "Sub-pattern (1-%d):", NUM_SEARCH_COLORS);
static char *buf = NULL;
static size_t buflen;
if (buf == NULL)
{
buflen = INT_STRLEN_BOUND(int)+strlen(LM(Sub_pattern_1_X))+1;
buf = ecalloc(buflen, sizeof(char));
}
SNPRINTF1(buf, buflen, LM(Sub_pattern_1_X), NUM_SEARCH_COLORS);
clear_bot();
cmd_putstr(buf);
flush();
@@ -890,15 +901,15 @@ static void prompt_message(void)
{
if (read_error)
{
error("read error", NULL_PARG);
error(LM(read_error), NULL_PARG);
read_error = FALSE;
}
if (search_wrapped)
{
if (search_type & SRCH_BACK)
error("Search hit top; continuing at bottom", NULL_PARG);
error(LM(Search_hit_top), NULL_PARG);
else
error("Search hit bottom; continuing at top", NULL_PARG);
error(LM(Search_hit_bottom), NULL_PARG);
search_wrapped = FALSE;
}
#if OSC8_LINK
@@ -906,7 +917,7 @@ static void prompt_message(void)
{
PARG parg;
parg.p_string = osc8_uri;
error("Link: %s", &parg);
error(LM(Link_X), &parg);
free(osc8_uri);
osc8_uri = NULL;
}
@@ -1328,9 +1339,9 @@ static void multi_search(constant char *pattern, int n, int silent)
PARG parg;
parg.p_string = prev_pattern_text();
if (parg.p_string == NULL) /* {{ can this happen? }} */
error("Pattern not found", NULL_PARG);
error(LM(Pattern_not_found), NULL_PARG);
else
error("Pattern not found: %s", &parg);
error(LM(Pattern_not_found_X), &parg);
}
if (changed_file)
@@ -1425,6 +1436,72 @@ public lbool is_ignoring_input(int action)
return (action != A_PREFIX);
}
#if PIPEC
/*
* Read a mark char or line number from the user for use by the pipe command.
* If mark_char != NULL, accept *mark_char as well as the normal mark chars.
* Also return the entered mark char in *mark_char.
*/
static POSITION get_pipe_pos(constant char *mark_msg, constant char *line_msg, mutable char *mark_char)
{
lbool get_line = FALSE;
char spec_char = '\0';
char c;
start_mca(A_PIPE, mark_msg, NULL, 0);
if (mark_char != NULL)
{
spec_char = *mark_char;
*mark_char = '\0';
}
for (;;)
{
c = getcc();
if (spec_char != '\0' && c == spec_char)
{
*mark_char = c;
return NULL_POSITION;
}
if (c == CONTROL('N')) /* toggle between reading mark and line number */
{
get_line = !get_line;
cmd_reset();
start_mca(A_PIPE, get_line ? line_msg : mark_msg, NULL, 0);
} else if (get_line) /* reading line number */
{
if ((c >= '0' && c <= '9') || is_erase_char(c))
{
if (cmd_char(c) == CC_QUIT)
return NULL_POSITION;
} else if (is_newline_char(c))
{
POSITION pos;
LINENUM lnum = cmd_int(NULL);
cmd_reset();
if (lnum == 0 || (pos = find_pos(lnum)) == NULL_POSITION)
{
error(LM(Invalid_line_number), NULL_PARG);
return NULL_POSITION;
}
return pos;
} else
lbell();
} else /* reading mark char */
{
if (is_erase_char(c))
return NULL_POSITION;
if (is_newline_char(c))
c = '.';
if (badmark(c))
return NULL_POSITION;
if (mark_char != NULL)
*mark_char = c;
return markpos(c);
}
}
}
#endif /* PIPEC */
/*
* Main command processor.
* Accept and execute commands until a quit command.
@@ -1749,7 +1826,7 @@ public void commands(void)
* Forward forever, ignoring EOF.
*/
if (get_altfilename(curr_ifile) != NULL)
error("Warning: command may not work correctly when file is viewed via LESSOPEN", NULL_PARG);
error(LM(command_may_not_work_correctly_with_LESSOPEN), NULL_PARG);
if (show_attn)
set_attnpos(bottompos);
newaction = forw_loop(action);
@@ -1886,6 +1963,7 @@ public void commands(void)
/*
* Exit.
*/
cmd_exec();
if (curr_ifile != NULL_IFILE &&
ch_getflags() & CH_HELPFILE)
{
@@ -1947,7 +2025,7 @@ public void commands(void)
number = 1;
osc8_search(SRCH_FORW, NULL, number);
#else
error("Command not available", NULL_PARG);
error(LM(Command_not_available), NULL_PARG);
#endif
break;
@@ -1958,7 +2036,7 @@ public void commands(void)
number = 1;
osc8_search(SRCH_BACK, NULL, number);
#else
error("Command not available", NULL_PARG);
error(LM(Command_not_available), NULL_PARG);
#endif
break;
@@ -1971,7 +2049,7 @@ public void commands(void)
break;
}
#endif
error("Command not available", NULL_PARG);
error(LM(Command_not_available), NULL_PARG);
break;
case A_OSC8_JUMP:
@@ -1979,7 +2057,7 @@ public void commands(void)
cmd_exec();
osc8_jump();
#else
error("Command not available", NULL_PARG);
error(LM(Command_not_available), NULL_PARG);
#endif
break;
@@ -1991,7 +2069,7 @@ public void commands(void)
c = getcc();
goto again;
#else
error("Command not available", NULL_PARG);
error(LM(Command_not_available), NULL_PARG);
break;
#endif
@@ -2064,12 +2142,12 @@ public void commands(void)
#if EXAMINE
if (secure_allow(SF_EXAMINE))
{
start_mca(A_EXAMINE, "Examine: ", ml_examine, 0);
start_mca(A_EXAMINE, LM(Examine), ml_examine, 0);
c = getcc();
goto again;
}
#endif
error("Command not available", NULL_PARG);
error(LM(Command_not_available), NULL_PARG);
break;
case A_VISUAL:
@@ -2083,12 +2161,12 @@ public void commands(void)
break;
if (strcmp(get_filename(curr_ifile), "-") == 0)
{
error("Cannot edit standard input", NULL_PARG);
error(LM(Cannot_edit_standard_input), NULL_PARG);
break;
}
if (!no_edit_warn && get_altfilename(curr_ifile) != NULL)
{
error("WARNING: This file was viewed via LESSOPEN", NULL_PARG);
error(LM(This_file_was_viewed_via_LESSOPEN), NULL_PARG);
}
start_mca(A_SHELL, "!", ml_shell, 0);
/*
@@ -2103,7 +2181,7 @@ public void commands(void)
break;
}
#endif
error("Command not available", NULL_PARG);
error(LM(Command_not_available), NULL_PARG);
break;
case A_NEXT_FILE:
@@ -2113,7 +2191,7 @@ public void commands(void)
#if TAGS
if (ntags())
{
error("No next file", NULL_PARG);
error(LM(No_next_file), NULL_PARG);
break;
}
#endif
@@ -2126,7 +2204,7 @@ public void commands(void)
!(ch_getflags() & CH_HELPFILE))
quit(QUIT_OK);
parg.p_string = (number > 1) ? "(N-th) " : "";
error("No %snext file", &parg);
error(LM(No_X_next_file), &parg);
}
break;
@@ -2137,7 +2215,7 @@ public void commands(void)
#if TAGS
if (ntags())
{
error("No previous file", NULL_PARG);
error(LM(No_previous_file), NULL_PARG);
break;
}
#endif
@@ -2147,7 +2225,7 @@ public void commands(void)
if (edit_prev((int) number))
{
parg.p_string = (number > 1) ? "(N-th) " : "";
error("No %sprevious file", &parg);
error(LM(No_X_previous_file), &parg);
}
break;
@@ -2161,7 +2239,7 @@ public void commands(void)
tagfile = nexttag((int) number);
if (tagfile == NULL)
{
error("No next tag", NULL_PARG);
error(LM(No_next_tag), NULL_PARG);
break;
}
cmd_exec();
@@ -2172,7 +2250,7 @@ public void commands(void)
jump_loc(pos, jump_sline);
}
#else
error("Command not available", NULL_PARG);
error(LM(Command_not_available), NULL_PARG);
#endif
break;
@@ -2186,7 +2264,7 @@ public void commands(void)
tagfile = prevtag((int) number);
if (tagfile == NULL)
{
error("No previous tag", NULL_PARG);
error(LM(No_previous_tag), NULL_PARG);
break;
}
cmd_exec();
@@ -2197,7 +2275,7 @@ public void commands(void)
jump_loc(pos, jump_sline);
}
#else
error("Command not available", NULL_PARG);
error(LM(Command_not_available), NULL_PARG);
#endif
break;
@@ -2209,7 +2287,7 @@ public void commands(void)
number = 1;
cmd_exec();
if (edit_index((int) number))
error("No such file", NULL_PARG);
error(LM(No_such_file), NULL_PARG);
break;
case A_REMOVE_FILE:
@@ -2281,7 +2359,7 @@ public void commands(void)
goto again;
}
#endif
error("Command not available", NULL_PARG);
error(LM(Command_not_available), NULL_PARG);
break;
case A_SETMARK:
@@ -2302,7 +2380,7 @@ public void commands(void)
}
break;
}
start_mca(A_SETMARK, "set mark: ", NULL, 0);
start_mca(A_SETMARK, LM(set_mark), NULL, 0);
c = getcc();
make_display();
cmd_exec();
@@ -2316,7 +2394,7 @@ public void commands(void)
/*
* Clear a mark.
*/
start_mca(A_CLRMARK, "clear mark: ", NULL, 0);
start_mca(A_CLRMARK, LM(clear_mark), NULL, 0);
c = getcc();
cmd_exec();
if (is_erase_char(c) || is_newline_char(c))
@@ -2329,7 +2407,7 @@ public void commands(void)
/*
* Jump to a marked position.
*/
start_mca(A_GOMARK, "goto mark: ", NULL, 0);
start_mca(A_GOMARK, LM(goto_mark), NULL, 0);
c = getcc();
if (is_erase_char(c) || is_newline_char(c))
break;
@@ -2344,26 +2422,43 @@ public void commands(void)
#if PIPEC
if (secure_allow(SF_PIPE))
{
start_mca(A_PIPE, "|mark: ", NULL, 0);
c = getcc();
if (is_erase_char(c))
break;
if (is_newline_char(c))
c = '.';
if (badmark(c))
break;
pipec = c;
char mark_char = '|';
pipe_pos1 = get_pipe_pos(LM(pipe_mark), LM(pipe_line_number), &mark_char);
if (mark_char == '|') /* double pipe: read two marks */
{
if ((pipe_pos1 = get_pipe_pos(LM(pipe_first_mark), LM(pipe_first_line_number), NULL)) == NULL_POSITION ||
(pipe_pos2 = get_pipe_pos(LM(pipe_second_mark), LM(pipe_second_line_number), NULL)) == NULL_POSITION)
{
getcc_clear();
break;
}
} else
{
if (pipe_pos1 == NULL_POSITION)
{
getcc_clear();
break;
}
if (mark_char == '.') /* special case: pipe current screen */
{
pipe_pos1 = markpos(':');
pipe_pos2 = markpos(';');
} else
{
pipe_pos2 = NULL_POSITION;
}
}
start_mca(A_PIPE, "!", ml_shell, 0);
c = getcc();
goto again;
}
#endif
error("Command not available", NULL_PARG);
error(LM(Command_not_available), NULL_PARG);
break;
case A_B_BRACKET:
case A_F_BRACKET:
start_mca(action, "Brackets: ", NULL, 0);
start_mca(action, LM(Brackets), NULL, 0);
c = getcc();
goto again;
@@ -2384,6 +2479,7 @@ public void commands(void)
break;
case A_RSHIFT:
case A_RSHIFT_LIMIT:
/*
* Shift view right.
*/
@@ -2392,6 +2488,12 @@ public void commands(void)
else
number = (shift_count > 0) ? shift_count : sc_width / 2;
pos_rehead(FALSE);
if (action == A_RSHIFT_LIMIT)
{
int ll = longest_line_width();
if (hshift + sc_width + (int) number > ll)
number = ll - hshift - sc_width;
}
hshift += (int) number;
screen_trashed();
cmd_exec();
+246 -129
View File
@@ -38,7 +38,7 @@ extern int emouse;
extern int mouse_reverse;
extern int hshift;
extern int sc_height;
extern char *no_config;
extern constant char *no_config;
#if USERFILE
/* "content" is lesskey source, never binary. */
@@ -122,6 +122,8 @@ static unsigned char cmdtable[] =
SK(SK_CTL_LEFT_ARROW),0, A_LLSHIFT,
SK(SK_SHIFT_RIGHT_ARROW),0, A_RRSHIFT,
SK(SK_SHIFT_LEFT_ARROW),0, A_LLSHIFT,
ESC,SK(SK_RIGHT_ARROW),0, A_RSHIFT_LIMIT,
ESC,']',0, A_RSHIFT_LIMIT,
'{',0, A_F_BRACKET|A_EXTRA, '{','}',0,
'}',0, A_B_BRACKET|A_EXTRA, '{','}',0,
'(',0, A_F_BRACKET|A_EXTRA, '(',')',0,
@@ -208,6 +210,23 @@ static unsigned char cmdtable[] =
SK(SK_PAD_COMMA),0, A_NOACTION,
SK(SK_PAD_ZERO),0, A_NOACTION|A_EXTRA, '0',0,
SK(SK_PAD_CENTER),0, A_NOACTION,
SK(SK_CTL_UP_ARROW),0, A_NOACTION,
SK(SK_CTL_DOWN_ARROW),0, A_NOACTION,
SK(SK_SHIFT_UP_ARROW),0, A_NOACTION,
SK(SK_SHIFT_DOWN_ARROW),0, A_NOACTION,
SK(SK_DELETE),0, A_NOACTION,
SK(SK_CTL_DELETE),0, A_NOACTION,
SK(SK_SHIFT_DELETE),0, A_NOACTION,
SK(SK_INSERT),0, A_NOACTION,
SK(SK_BACKTAB),0, A_NOACTION,
SK(SK_BACKSPACE),0, A_NOACTION,
SK(SK_CTL_BACKSPACE),0, A_NOACTION,
SK(SK_SHIFT_PAGE_UP),0, A_NOACTION,
SK(SK_SHIFT_PAGE_DOWN),0, A_NOACTION,
SK(SK_CTL_PAGE_UP),0, A_NOACTION,
SK(SK_CTL_PAGE_DOWN),0, A_NOACTION,
'\b',0, A_NOACTION,
'\177',0, A_NOACTION,
ESC,'[','2','0','0','~',0, A_START_PASTE,
ESC,'[','2','0','1','~',0, A_END_PASTE,
@@ -280,6 +299,19 @@ static unsigned char edittable[] =
SK(SK_PAD_COMMA),0, A_NOACTION|A_EXTRA, ',',0,
SK(SK_PAD_ZERO),0, A_NOACTION|A_EXTRA, '0',0,
SK(SK_PAD_CENTER),0, A_NOACTION,
SK(SK_CTL_UP_ARROW),0, A_NOACTION,
SK(SK_CTL_DOWN_ARROW),0, A_NOACTION,
SK(SK_SHIFT_UP_ARROW),0, A_NOACTION,
SK(SK_SHIFT_DOWN_ARROW),0, A_NOACTION,
SK(SK_SHIFT_DELETE),0, A_NOACTION,
SK(SK_PAGE_UP),0, A_NOACTION,
SK(SK_PAGE_DOWN),0, A_NOACTION,
SK(SK_SHIFT_LEFT_ARROW),0, A_NOACTION,
SK(SK_SHIFT_RIGHT_ARROW),0, A_NOACTION,
SK(SK_SHIFT_PAGE_UP),0, A_NOACTION,
SK(SK_SHIFT_PAGE_DOWN),0, A_NOACTION,
SK(SK_CTL_PAGE_UP),0, A_NOACTION,
SK(SK_CTL_PAGE_DOWN),0, A_NOACTION,
ESC,'[','M',0, EC_X11MOUSE, /* X11 mouse report */
ESC,'[','<',0, EC_X116MOUSE, /* X11 1006 mouse report */
ESC,'[','2','0','0','~',0, A_START_PASTE, /* open paste bracket */
@@ -359,11 +391,25 @@ static void expand_special_keys(unsigned char *table, size_t len)
repl = special_key_str(fm[1]);
klen = fm[2];
fm += klen;
if (klen < 3)
{
/* Malformed entry; N cannot be less than 3.
* Skip this entry and (for simplicity) the rest of the table. */
return;
}
if (repl == NULL || strlen(repl) > klen)
repl = "\377";
if (to + strlen(repl) + 1 > table + len)
{
/* Replacement string won't fit in table.
* This cannot happen unless klen is wrong. */
return;
}
while (*repl != '\0')
*to++ = (unsigned char) *repl++; /*{{type-issue}}*/
}
if (fm + 2 > table + len)
return; /* last entry is truncated */
*to++ = '\0';
/*
* Fill any unused bytes between end of command and
@@ -404,12 +450,86 @@ public void expand_cmd_tables(void)
expand_cmd_table(list_sysvar_tables);
}
/*
* Add a command table.
*/
static int add_cmd_table(struct tablelist **tlist, unsigned char *buf, size_t len)
{
struct tablelist *t;
if (len == 0)
return (0);
/*
* Allocate a tablelist structure, initialize it,
* and link it into the list of tables.
*/
if ((t = (struct tablelist *)
calloc(1, sizeof(struct tablelist))) == NULL)
{
return (-1);
}
t->t_start = buf;
t->t_end = buf + len;
t->t_next = NULL;
if (*tlist == NULL)
*tlist = t;
else
{
struct tablelist *e;
for (e = *tlist; e->t_next != NULL; e = e->t_next)
continue;
e->t_next = t;
}
return (0);
}
/*
* Add a command table.
*/
static void add_fcmd_table(unsigned char *buf, size_t len)
{
if (add_cmd_table(&list_fcmd_tables, buf, len) < 0)
error(LM(some_commands_disabled), NULL_PARG);
}
/*
* Add an editing command table.
*/
static void add_ecmd_table(unsigned char *buf, size_t len)
{
if (add_cmd_table(&list_ecmd_tables, buf, len) < 0)
error(LM(some_edit_commands_disabled), NULL_PARG);
}
/*
* Add an environment variable table.
*/
static void add_var_table(struct tablelist **tlist, mutable unsigned char *buf, size_t len)
{
struct xbuffer xbuf;
xbuf_init(&xbuf);
expand_evars((mutable char*)buf, len, &xbuf); /*{{unsigned-issue}}*/
/* {{ We leak the table in buf. expand_evars scribbled in it so it's useless anyway. }} */
if (add_cmd_table(tlist, xbuf.data, xbuf.end) < 0)
error(LM(environment_variables_from_lesskey_file_unavailable), NULL_PARG);
}
static void add_uvar_table(unsigned char *buf, size_t len)
{
add_var_table(&list_var_tables, buf, len);
}
static void add_sysvar_table(unsigned char *buf, size_t len)
{
add_var_table(&list_sysvar_tables, buf, len);
}
/*
* Initialize the command lists.
*/
public void init_cmds(void)
{
struct tablelist *t;
unsigned char *udflt_vartable = (unsigned char *) dflt_vartable;
/*
@@ -461,48 +581,17 @@ public void init_cmds(void)
/*
* If any command table contains a #stop directive, discard all other tables.
*/
t = find_stop_table(list_fcmd_tables);
if (t != NULL)
{
t->t_next = NULL;
list_fcmd_tables = t;
struct tablelist *t = find_stop_table(list_fcmd_tables);
if (t != NULL)
{
t->t_next = NULL;
list_fcmd_tables = t;
}
}
#endif /* USERFILE */
}
/*
* Add a command table.
*/
static int add_cmd_table(struct tablelist **tlist, unsigned char *buf, size_t len)
{
struct tablelist *t;
if (len == 0)
return (0);
/*
* Allocate a tablelist structure, initialize it,
* and link it into the list of tables.
*/
if ((t = (struct tablelist *)
calloc(1, sizeof(struct tablelist))) == NULL)
{
return (-1);
}
t->t_start = buf;
t->t_end = buf + len;
t->t_next = NULL;
if (*tlist == NULL)
*tlist = t;
else
{
struct tablelist *e;
for (e = *tlist; e->t_next != NULL; e = e->t_next)
continue;
e->t_next = t;
}
return (0);
}
/*
* Remove the last command table in a list.
*/
@@ -526,48 +615,6 @@ static void pop_cmd_table(struct tablelist **tlist)
free(t);
}
/*
* Add a command table.
*/
public void add_fcmd_table(unsigned char *buf, size_t len)
{
if (add_cmd_table(&list_fcmd_tables, buf, len) < 0)
error("Warning: some commands disabled", NULL_PARG);
}
/*
* Add an editing command table.
*/
public void add_ecmd_table(unsigned char *buf, size_t len)
{
if (add_cmd_table(&list_ecmd_tables, buf, len) < 0)
error("Warning: some edit commands disabled", NULL_PARG);
}
/*
* Add an environment variable table.
*/
static void add_var_table(struct tablelist **tlist, mutable unsigned char *buf, size_t len)
{
struct xbuffer xbuf;
xbuf_init(&xbuf);
expand_evars((mutable char*)buf, len, &xbuf); /*{{unsigned-issue}}*/
/* {{ We leak the table in buf. expand_evars scribbled in it so it's useless anyway. }} */
if (add_cmd_table(tlist, xbuf.data, xbuf.end) < 0)
error("Warning: environment variables from lesskey file unavailable", NULL_PARG);
}
public void add_uvar_table(unsigned char *buf, size_t len)
{
add_var_table(&list_var_tables, buf, len);
}
public void add_sysvar_table(unsigned char *buf, size_t len)
{
add_var_table(&list_sysvar_tables, buf, len);
}
/*
* Return action for a mouse wheel down event.
*/
@@ -816,27 +863,50 @@ static size_t cmd_match(constant char *goal, constant char *str)
}
/*
* Return pointer to next command table entry.
* Also return the action and the extra string from the entry.
* Skip to next null byte in entry, and return pointer to it.
* Return NULL if no null byte is found before end.
*/
static constant unsigned char * cmd_next_entry(constant unsigned char *entry, mutable int *action, mutable constant unsigned char **extra, mutable size_t *cmdlen)
static constant unsigned char * skip_to_null(constant unsigned char *entry, constant unsigned char *end)
{
for (;;)
{
if (entry >= end)
return NULL;
if (*entry == '\0')
return entry;
++entry;
}
}
/*
* Return pointer to next command table entry.
* Also return the command length, the action code and the extra string
* from the current entry.
* Return NULL if the entry is truncated.
*/
static constant unsigned char * cmd_next_entry(constant unsigned char *entry, constant unsigned char *end, mutable int *action, mutable constant unsigned char **extra, mutable size_t *cmdlen)
{
int a;
constant unsigned char *oentry = entry;
while (*entry != '\0') /* skip cmd */
++entry;
entry = skip_to_null(entry, end); /* skip to end of cmd */
if (entry == NULL)
return NULL;
if (cmdlen != NULL)
*cmdlen = ptr_diff(entry, oentry);
do
a = *++entry; /* get action */
while (a == A_SKIP);
do { /* skip any A_SKIP bytes between cmd and action */
if (++entry >= end)
return NULL;
a = *entry;
} while (a == A_SKIP);
++entry; /* skip action */
if (extra != NULL)
*extra = (a & A_EXTRA) ? entry : NULL;
if (a & A_EXTRA)
{
while (*entry++ != '\0') /* skip extra string */
continue;
entry = skip_to_null(entry, end); /* skip to end of extra string */
if (entry == NULL)
return NULL;
++entry; /* skip null at end of extra string */
a &= ~A_EXTRA;
}
if (action != NULL)
@@ -844,6 +914,7 @@ static constant unsigned char * cmd_next_entry(constant unsigned char *entry, mu
return entry;
}
#if USERFILE
/*
* Does a command table contain a #stop directive?
*/
@@ -854,7 +925,9 @@ static lbool table_has_stop(struct tablelist *t)
while (entry < t->t_end)
{
int action;
entry = cmd_next_entry(entry, &action, NULL, NULL);
entry = cmd_next_entry(entry, t->t_end, &action, NULL, NULL);
if (entry == NULL)
break;
if (action == A_END_LIST)
return TRUE;
}
@@ -873,9 +946,10 @@ static struct tablelist * find_stop_table(struct tablelist *t)
}
return NULL;
}
#endif /* USERFILE */
/*
* Search a single command table for the command string in cmd.
* Search a list of command tables for the command string in cmd.
*/
static int cmd_decode(struct tablelist *tlist, constant char *cmd, lbool anchored, constant char **extra)
{
@@ -902,10 +976,16 @@ static int cmd_decode(struct tablelist *tlist, constant char *cmd, lbool anchore
tmatch = (strcmp((constant char *) table, cmd) == 0) ? strlen(cmd) : 0;
else
tmatch = cmd_match((constant char *) table, cmd);
table = cmd_next_entry(table, &taction, &textra, &tcmdlen);
table = cmd_next_entry(table, tlist->t_end, &taction, &textra, &tcmdlen);
if (table == NULL)
{
/* Truncated/malformed entry; ignore this entry and move to next table. */
tlist = tlist->t_next;
continue;
}
if (table >= endtable)
{
/* End of table; move to next table. */
/* Last entry in table; process this entry then move to next table. */
tlist = tlist->t_next;
table = NULL;
}
@@ -919,7 +999,7 @@ static int cmd_decode(struct tablelist *tlist, constant char *cmd, lbool anchore
action = taction;
if (extra != NULL)
*extra = (constant char *) textra;
} else if (tmatch > 0 && (tmatch > match_len || action == A_INVALID))
} else if (tmatch > 0 && (tmatch > match_len || !anchored))
{
/* cmd is a prefix of this table entry */
action = A_PREFIX;
@@ -947,7 +1027,7 @@ public int fcmd_decode(constant char *cmd, constant char **sp)
/*
* Decode a command from the edittables list.
*/
public int ecmd_decode(constant char *cmd, constant char **sp)
static int ecmd_decode(constant char *cmd, constant char **sp)
{
return (cmd_decode(list_ecmd_tables, cmd, FALSE, sp));
}
@@ -993,7 +1073,7 @@ static int csl_bitmap_error(constant char *pfx, constant char *type, size_t len,
/*
* Return the bit value of a csl_bitmap name.
*/
public int csl_bitmap_bit(constant char *name, size_t len, struct csl_bitmap_def *defs, int num_defs, constant char *pfx)
static int csl_bitmap_bit(constant char *name, size_t len, struct csl_bitmap_def *defs, int num_defs, constant char *pfx)
{
int i;
int match = -1;
@@ -1003,12 +1083,12 @@ public int csl_bitmap_bit(constant char *name, size_t len, struct csl_bitmap_def
if (strncmp(defs[i].bit_name, name, len) == 0)
{
if (match >= 0) /* name is ambiguous */
return csl_bitmap_error(pfx, "ambiguous", len, name);
return csl_bitmap_error(pfx, LM(ambiguous), len, name);
match = i;
}
}
if (match < 0)
return csl_bitmap_error(pfx, "invalid", len, name);
return csl_bitmap_error(pfx, LM(invalid), len, name);
return defs[match].bit_value;
}
@@ -1063,6 +1143,52 @@ static lbool ignore_env(constant char *var)
return parse_csl(word_no_match, no_config, (void*) var);
}
#if !GETENV_NONVOLATILE
/*
* Cache for environment variables.
* We keep them in a cache to ensure that lgetenv always returns
* a string with indefinite lifetime. POSIX specifies that a string
* returned from getenv may be overwritten by a subsequent getenv.
*/
struct env_cache {
struct env_cache *ec_next;
char *ec_var;
char *ec_value;
};
static struct env_cache *env_cache_list = NULL;
/*
* Add an environment variable to the cache.
*/
static void addenv_cache(constant char *var, constant char *value)
{
struct env_cache *ec = ecalloc(1, sizeof(struct env_cache));
ec->ec_var = save(var);
ec->ec_value = save(value);
ec->ec_next = env_cache_list;
env_cache_list = ec;
}
/*
* Find an environment variable in the cache.
*/
static constant char * getenv_cache(constant char *var)
{
struct env_cache *ec;
for (ec = env_cache_list; ec != NULL; ec = ec->ec_next)
{
if (strcmp(var, ec->ec_var) == 0)
return ec->ec_value;
}
return NULL;
}
#endif /* GETENV_NONVOLATILE */
/*
* Get the value of an environment variable.
* Looks first in the lesskey file, then in the real environment.
@@ -1077,9 +1203,19 @@ public constant char * lgetenv(constant char *var)
a = cmd_decode(list_var_tables, var, TRUE, &s);
if (a == EV_OK)
return (s);
s = getenv(var);
if (s != NULL && *s != '\0')
#if !GETENV_NONVOLATILE
s = getenv_cache(var);
if (!isnullenv(s))
return (s);
#endif
s = getenv(var);
if (!isnullenv(s))
{
#if !GETENV_NONVOLATILE
addenv_cache(var, s);
#endif
return (s);
}
a = cmd_decode(list_sysvar_tables, var, TRUE, &s);
if (a == EV_OK)
return (s);
@@ -1100,7 +1236,7 @@ public constant char * lgetenv_ext(constant char *var, unsigned char *env_buf, s
for (; e < env_buf_len; e++)
if (env_buf[e] == '\0')
break;
if (e >= env_buf_len) break;
if (e+1 >= env_buf_len) break;
if (env_buf[++e] & A_EXTRA)
{
for (e = e+1; e < env_buf_len; e++)
@@ -1112,7 +1248,7 @@ public constant char * lgetenv_ext(constant char *var, unsigned char *env_buf, s
env_end = e;
}
/* Temporarily add env_buf to var_tables, do the lookup, then remove it. */
add_uvar_table(env_buf, env_end);
add_cmd_table(&list_var_tables, env_buf, env_end);
r = lgetenv(var);
pop_cmd_table(&list_var_tables);
return r;
@@ -1141,24 +1277,6 @@ static size_t gint(unsigned char **sp)
return (n);
}
/*
* Process an old (pre-v241) lesskey file.
*/
static int old_lesskey(unsigned char *buf, size_t len)
{
/*
* Old-style lesskey file.
* The file must end with either
* ...,cmd,0,action
* or ...,cmd,0,action|A_EXTRA,string,0
* So the last byte or the second to last byte must be zero.
*/
if (buf[len-1] != '\0' && buf[len-2] != '\0')
return (-1);
add_fcmd_table(buf, len);
return (0);
}
/*
* Process a new (post-v241) lesskey file.
*/
@@ -1275,13 +1393,12 @@ public int lesskey(constant char *filename, lbool sysvar)
}
/*
* Figure out if this is an old-style (before version 241)
* or new-style lesskey file format.
* Verify lesskey file header.
*/
if (len < 4 ||
buf[0] != C0_LESSKEY_MAGIC || buf[1] != C1_LESSKEY_MAGIC ||
buf[2] != C2_LESSKEY_MAGIC || buf[3] != C3_LESSKEY_MAGIC)
return (old_lesskey(buf, (size_t) len));
return (-1);
return (new_lesskey(buf, (size_t) len, sysvar));
}
@@ -1315,7 +1432,7 @@ public int lesskey_content(constant char *content, lbool sysvar)
return lesskey_text(content, sysvar, TRUE);
}
void lesskey_parse_error(char *s)
public void lesskey_parse_error(constant char *s)
{
PARG parg;
parg.p_string = s;
@@ -1345,14 +1462,14 @@ static int add_hometable(int (*call_lesskey)(constant char *, lbool), constant c
/* Remove first char (normally a dot) unless stored in $HOME. */
constant char *xdg = lgetenv("XDG_CONFIG_HOME");
if (!isnullenv(xdg))
filename = dirfile(xdg, &def_filename[1], 1);
filename = dirfile(xdg, &def_filename[1], TRUE);
if (filename == NULL)
{
constant char *home = lgetenv("HOME");
if (!isnullenv(home))
{
char *cfg_dir = dirfile(home, ".config", 0);
filename = dirfile(cfg_dir, &def_filename[1], 1);
char *cfg_dir = dirfile(home, ".config", FALSE);
filename = dirfile(cfg_dir, &def_filename[1], TRUE);
free(cfg_dir);
}
}
+27 -21
View File
@@ -259,7 +259,7 @@ static void check_modelines(void)
/*
* Close a pipe opened via popen.
*/
static void close_pipe(FILE *pipefd)
public void close_pipe(FILE *pipefd)
{
int status;
char *p;
@@ -296,7 +296,7 @@ static void close_pipe(FILE *pipefd)
if (s <= 128)
{
parg.p_int = s;
error("Input preprocessor failed (status %d)", &parg);
error(LM(Input_preprocessor_failed), &parg);
return;
}
/*
@@ -325,21 +325,21 @@ static void close_pipe(FILE *pipefd)
ch_length() != NULL_POSITION)
{
parg.p_string = signal_message(sig);
error("Input preprocessor terminated: %s", &parg);
error(LM(Input_preprocessor_terminated_X), &parg);
}
return;
}
if (status != 0)
{
parg.p_int = status;
error("Input preprocessor exited with status %x", &parg);
error(LM(Input_preprocessor_exited_with_status_X), &parg);
}
}
/*
* Drain and close an input pipe if needed.
*/
public void close_altpipe(IFILE ifile)
static void close_altpipe(IFILE ifile)
{
FILE *altpipe = get_altpipe(ifile);
if (altpipe != NULL && !(ch_getflags() & CH_KEEPOPEN))
@@ -421,7 +421,7 @@ public int edit(constant char *filename)
/*
* Clean up what edit_ifile did before error return.
*/
static int edit_error(constant char *filename, constant char *alt_filename, void *altpipe, IFILE ifile)
static int edit_error(constant char *filename, constant char *alt_filename, FILE *altpipe, IFILE ifile)
{
if (alt_filename != NULL)
{
@@ -456,7 +456,7 @@ public int edit_ifile(IFILE ifile)
constant char *filename;
constant char *open_filename;
char *alt_filename;
void *altpipe;
FILE *altpipe;
IFILE was_curr_ifile;
char *p;
PARG parg;
@@ -570,7 +570,9 @@ public int edit_ifile(IFILE ifile)
* Ask user if we should proceed.
*/
parg.p_string = filename;
answer = query("\"%s\" may be a binary file. See it anyway? ", &parg);
answer = query(LM(X_may_be_a_binary_file), &parg);
if (answer == 'q')
quit(QUIT_OK);
if (answer != 'y' && answer != 'Y')
{
close(f);
@@ -583,7 +585,7 @@ public int edit_ifile(IFILE ifile)
{
PARG parg;
parg.p_string = filename;
error("%s is a terminal (use -f to open it)", &parg);
error(LM(X_is_a_terminal), &parg);
return edit_error(filename, alt_filename, altpipe, ifile);
}
}
@@ -641,10 +643,11 @@ public int edit_ifile(IFILE ifile)
#endif
#if HAVE_STAT_INO
/* Remember the i-number and device of the opened file. */
if (strcmp(open_filename, "-") != 0)
curr_ino = curr_dev = 0;
if (!is_fake_pathname(open_filename))
{
struct stat statbuf;
int r = stat(open_filename, &statbuf);
less_stat_t statbuf;
int r = less_stat(open_filename, &statbuf);
if (r == 0)
{
curr_ino = statbuf.st_ino;
@@ -681,8 +684,13 @@ public int edit_ifile(IFILE ifile)
if (strcmp(filename, FAKE_HELPFILE) && strcmp(filename, FAKE_EMPTYFILE))
{
char *qfilename = shell_quote(filename);
cmd_addhist(ml_examine, qfilename, 1);
free(qfilename);
if (qfilename == NULL)
cmd_addhist(ml_examine, filename, TRUE);
else
{
cmd_addhist(ml_examine, qfilename, TRUE);
free(qfilename);
}
}
if (want_filesize)
scan_eof();
@@ -918,8 +926,8 @@ public int edit_stdin(void)
{
if (isatty(fd0))
{
error("Missing filename (\"less --help\" for help)", NULL_PARG);
quit(QUIT_OK);
error(LM(Missing_filename), NULL_PARG);
quit(QUIT_ERROR);
}
return (edit("-"));
}
@@ -939,8 +947,6 @@ public void cat_file(void)
#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.
@@ -982,7 +988,7 @@ public void use_logfile(constant char *filename)
* Ask user what to do.
*/
parg.p_string = filename;
answer = query("Warning: \"%s\" exists; "OVERWRITE_OPTIONS" ", &parg);
answer = query(LM(X_exists), &parg);
}
loop:
@@ -1015,7 +1021,7 @@ loop:
* Eh?
*/
answer = query(OVERWRITE_OPTIONS" (Type \"O\", \"A\", \"D\" or \"Q\") ", NULL_PARG);
answer = query(LM(Overwrite), NULL_PARG);
goto loop;
}
@@ -1025,7 +1031,7 @@ loop:
* Error in opening logfile.
*/
parg.p_string = filename;
error("Cannot write to \"%s\"", &parg);
error(LM(Cannot_write_to_X), &parg);
return;
}
SET_BINARY(logfile);
+97 -36
View File
@@ -146,20 +146,55 @@ static lbool must_quote(char c)
*/
public char * shell_quoten(constant char *s, size_t slen)
{
constant char *p;
char *np;
char *newstr;
char *np;
constant char *p;
lbool use_quotes = FALSE;
constant char *es = s + slen;
#if MSDOS_COMPILER
int cbs = 0; /* consecutive backslashes */
if (slen == 0)
use_quotes = TRUE;
else
{
for (p = s; p < es; ++p)
{
if (*p == ' ' || *p == '\t')
{
use_quotes = TRUE;
break;
}
}
}
newstr = np = (char *) ecalloc(2*slen+3, sizeof(char));
if (use_quotes)
*np++ = '"';
while (s < es)
{
if (*s == '\\' || *s == '"')
*np++ = '\\';
else
np -= cbs;
cbs = (*s == '\\') ? cbs + 1 : 0;
*np++ = *s++;
}
if (use_quotes)
*np++ = '"';
else
np -= cbs;
*np = '\0';
#else
size_t len;
constant char *esc = get_meta_escape();
size_t esclen = strlen(esc);
lbool use_quotes = FALSE;
lbool have_quotes = FALSE;
/*
* Determine how big a string we need to allocate.
*/
len = 1; /* Trailing null byte */
for (p = s; p < s + slen; p++)
for (p = s; p < es; p++)
{
len++;
if (*p == openquote || *p == closequote)
@@ -203,7 +238,6 @@ public char * shell_quoten(constant char *s, size_t slen)
SNPRINTF4(newstr, len, "%c%.*s%c", openquote, (int) slen, s, closequote);
} else
{
constant char *es = s + slen;
while (s < es)
{
if (!metachar(*s))
@@ -225,6 +259,7 @@ public char * shell_quoten(constant char *s, size_t slen)
}
*np = '\0';
}
#endif
return (newstr);
}
@@ -237,7 +272,7 @@ public char * shell_quote(constant char *s)
* Return a pathname that points to a specified file in a specified directory.
* Return NULL if the file does not exist in the directory.
*/
public char * dirfile(constant char *dirname, constant char *filename, int must_exist)
public char * dirfile(constant char *dirname, constant char *filename, lbool must_exist)
{
char *pathname;
size_t len;
@@ -279,12 +314,12 @@ public char * homefile(constant char *filename)
char *pathname;
/* Try $HOME/filename. */
pathname = dirfile(lgetenv("HOME"), filename, 1);
pathname = dirfile(lgetenv("HOME"), filename, TRUE);
if (pathname != NULL)
return (pathname);
#if OS2
/* Try $INIT/filename. */
pathname = dirfile(lgetenv("INIT"), filename, 1);
pathname = dirfile(lgetenv("INIT"), filename, TRUE);
if (pathname != NULL)
return (pathname);
#endif
@@ -373,8 +408,8 @@ static size_t fexpand_copy(constant char *fr, char *to)
/*
* Expand a string, substituting any "%" with the current filename,
* and any "#" with the previous filename.
* But a string of N "%"s is just replaced with N-1 "%"s.
* Likewise for a string of N "#"s.
* But two consecutive "%"s are just replaced with one "%".
* Likewise for two consecutive "#"s.
* {{ This is a lot of work just to support % and #. }}
*/
public char * fexpand(constant char *s)
@@ -555,26 +590,31 @@ static FILE * shellcmd(constant char *cmd)
shell = lgetenv("SHELL");
if (!isnullenv(shell))
{
char *scmd;
char *esccmd;
constant char *copt = shell_coption();
/*
* Read the output of <$SHELL -c cmd>.
* Escape any metacharacters in the command.
*/
esccmd = shell_quote(cmd);
if (esccmd == NULL)
if (copt == NULL)
{
fd = popen(cmd, "r");
} else
{
constant char *copt = shell_coption();
size_t len = strlen(shell) + strlen(esccmd) + strlen(copt) + 3;
scmd = (char *) ecalloc(len, sizeof(char));
SNPRINTF3(scmd, len, "%s %s %s", shell, copt, esccmd);
free(esccmd);
fd = popen(scmd, "r");
free(scmd);
char *esccmd = shell_quote(cmd);
if (esccmd == NULL)
{
error(LM(cannot_quote_command), NULL_PARG);
return NULL;
} else
{
size_t len = strlen(shell) + strlen(esccmd) + strlen(copt) + 3;
char *scmd = (char *) ecalloc(len, sizeof(char));
SNPRINTF3(scmd, len, "%s %s %s", shell, copt, esccmd);
fd = popen(scmd, "r");
free(scmd);
free(esccmd);
}
}
} else
#endif
@@ -847,7 +887,7 @@ static int num_pct_s(constant char *lessopen)
* See if we should open a "replacement file"
* instead of the file we're about to open.
*/
public char * open_altfile(constant char *filename, int *pf, void **pfd)
public char * open_altfile(constant char *filename, int *pf, FILE **pfd)
{
#if !HAVE_POPEN
return (NULL);
@@ -875,7 +915,7 @@ public char * open_altfile(constant char *filename, int *pf, void **pfd)
* a "pipe preprocessor".
*/
#if !HAVE_FILENO
error("LESSOPEN pipe is not supported", NULL_PARG);
error(LM(LESSOPEN_pipe_is_not_supported), NULL_PARG);
return (NULL);
#else
lessopen++;
@@ -895,11 +935,15 @@ public char * open_altfile(constant char *filename, int *pf, void **pfd)
}
if (num_pct_s(lessopen) != 1)
{
error("LESSOPEN ignored: must contain exactly one %%s", NULL_PARG);
error(LM(LESSOPEN_ignored), NULL_PARG);
return (NULL);
}
qfilename = shell_quote(filename);
if (qfilename == NULL)
{
return (NULL);
}
len = strlen(lessopen) + strlen(qfilename) + 2;
cmd = (char *) ecalloc(len, sizeof(char));
SNPRINTF1(cmd, len, lessopen, qfilename);
@@ -947,7 +991,7 @@ public char * open_altfile(constant char *filename, int *pf, void **pfd)
}
/* Alt pipe contains data, so use it. */
ch_ungetchar(c);
*pfd = (void *) fd;
*pfd = fd;
*pf = f;
return (save("-"));
}
@@ -986,11 +1030,18 @@ public void close_altfile(constant char *altfilename, constant char *filename)
return;
if (num_pct_s(lessclose) > 2)
{
error("LESSCLOSE ignored; must contain no more than 2 %%s", NULL_PARG);
error(LM(LESSCLOSE_ignored), NULL_PARG);
return;
}
qfilename = shell_quote(filename);
if (qfilename == NULL)
return;
qaltfilename = shell_quote(altfilename);
if (qaltfilename == NULL)
{
free(qfilename);
return;
}
len = strlen(lessclose) + strlen(qfilename) + strlen(qaltfilename) + 2;
cmd = (char *) ecalloc(len, sizeof(char));
SNPRINTF2(cmd, len, lessclose, qfilename, qaltfilename);
@@ -1044,11 +1095,10 @@ public char * bad_file(constant char *filename)
if (!force_open && is_dir(filename))
{
static char is_a_dir[] = " is a directory";
m = (char *) ecalloc(strlen(filename) + sizeof(is_a_dir),
sizeof(char));
constant char *is_a_dir = LM(is_a_directory);
m = (char *) ecalloc(strlen(filename) + strlen(is_a_dir) + 2, sizeof(char));
strcpy(m, filename);
strcat(m, " ");
strcat(m, is_a_dir);
} else
{
@@ -1065,10 +1115,10 @@ public char * bad_file(constant char *filename)
m = NULL;
} else if (!S_ISREG(statbuf.st_mode))
{
static char not_reg[] = " is not a regular file (use -f to see it)";
m = (char *) ecalloc(strlen(filename) + sizeof(not_reg),
sizeof(char));
constant char *not_reg = LM(is_not_a_regular_file);
m = (char *) ecalloc(strlen(filename) + strlen(not_reg) + 2, sizeof(char));
strcpy(m, filename);
strcat(m, " ");
strcat(m, not_reg);
}
#endif
@@ -1082,17 +1132,23 @@ public char * bad_file(constant char *filename)
*/
public POSITION filesize(int f)
{
if (f < 0)
return (NULL_POSITION);
#if HAVE_STAT
{
less_stat_t statbuf;
if (less_fstat(f, &statbuf) >= 0)
return ((POSITION) statbuf.st_size);
}
#else
#ifdef _OSK
{
long size;
if ((size = (long) _gs_size(f)) >= 0)
return ((POSITION) size);
}
#endif
#endif
return (seek_filesize(f));
@@ -1106,9 +1162,9 @@ public lbool curr_ifile_changed(void)
* or if the file is smaller than it previously was,
* the file must be different.
*/
struct stat st;
less_stat_t st;
POSITION curr_pos = ch_tell();
int r = stat(get_filename(curr_ifile), &st);
int r = less_stat(get_filename(curr_ifile), &st);
if (r == 0 && (st.st_ino != curr_ino ||
st.st_dev != curr_dev ||
(curr_pos != NULL_POSITION && st.st_size < curr_pos)))
@@ -1122,7 +1178,12 @@ public lbool curr_ifile_changed(void)
*/
public constant char * shell_coption(void)
{
return ("-c");
constant char *copt = lgetenv("LESS_SHELL_COPTION");
if (isnullenv(copt))
copt = "-c";
else if (strcmp(copt, "-") == 0)
copt = NULL;
return copt;
}
/*
+6 -5
View File
@@ -16,7 +16,7 @@
#include "less.h"
#include "position.h"
extern int less_is_more;
extern lbool less_is_more;
public lbool squished;
public lbool no_back_scroll = FALSE;
@@ -110,7 +110,7 @@ public lbool entire_file_displayed(void)
return (FALSE);
/* Make sure first line of file is displayed. */
pos = position(0);
pos = position(TOP);
return (pos == NULL_POSITION || pos == 0);
}
@@ -156,7 +156,7 @@ static POSITION forw_line_pfx(POSITION pos, int pfx, int skipeol)
static void set_attr_header(int ln)
{
set_attr_line(AT_COLOR_HEADER);
if (ln+1 == header_lines && position(0) != header_start_pos)
if (ln+1 == header_lines && position(TOP) != header_start_pos)
set_attr_line(AT_UNDERLINE);
}
@@ -273,7 +273,8 @@ public void forw(int n, POSITION pos, lbool force, lbool only_last, lbool to_new
need_home = TRUE;
} else if (!first_time && !is_filtering() && full_screen)
{
putstr("...skipping...\n");
putstr(LM(skipping));
putstr("\n");
}
}
}
@@ -404,7 +405,7 @@ public void back(int n, POSITION pos, lbool force, lbool only_last, lbool to_new
/*
* Get the previous line of input.
*/
pos = back_line(pos, &newline);
pos = back_line(pos, NULL, &newline);
if (to_newline && !newline)
++n;
if (pos == NULL_POSITION)
+20 -23
View File
@@ -6,13 +6,14 @@ public char * skipsp(char *s);
public constant char * skipspc(constant char *s);
public size_t sprefix(constant char *ps, constant char *s, int uppercase);
public void quit(int status);
public int secure_allow(int features);
public void raw_mode(int on);
public lbool secure_allow(unsigned int features);
public void raw_mode(lbool on);
public void scrsize(void);
public void screen_size_changed(void);
public constant char * special_key_str(int key);
public void init_win_colors(void);
public void get_term(void);
public void update_term(void);
public void init_mouse(void);
public void deinit_mouse(void);
public void suspend_screen(void);
@@ -52,7 +53,7 @@ public int WIN32getch(void);
public void win32_getch_clear(void);
public void WIN32setcolors(int fg, int bg);
public void WIN32textout(constant char *text, size_t len);
public void match_brac(char obrac, char cbrac, int forwdir, int n);
public void match_brac(char obrac, char cbrac, lbool forwdir, int n);
public void ch_ungetchar(int c);
public void end_logfile(void);
public void sync_logfile(void);
@@ -67,7 +68,7 @@ public int ch_forw_get(void);
public int ch_back_get(void);
public void ch_setbufspace(ssize_t bufspace);
public void ch_flush(void);
public int seekable(int f);
public lbool seekable(int f);
public void ch_set_eof(void);
public void ch_init(int f, int flags, ssize_t nread);
public void ch_close(void);
@@ -131,14 +132,8 @@ public int * cvt_alloc_chpos(size_t len);
public void cvt_text(mutable char *odst, constant char *osrc, mutable int *chpos, mutable size_t *lenp, int ops);
public void expand_cmd_tables(void);
public void init_cmds(void);
public void add_fcmd_table(unsigned char *buf, size_t len);
public void add_ecmd_table(unsigned char *buf, size_t len);
public void add_uvar_table(unsigned char *buf, size_t len);
public void add_sysvar_table(unsigned char *buf, size_t len);
public int fcmd_decode(constant char *cmd, constant char **sp);
public int ecmd_decode(constant char *cmd, constant char **sp);
public lbool parse_csl(lbool (*func)(constant char *word, size_t wlen, void *arg), constant char *str, void *arg);
public int csl_bitmap_bit(constant char *name, size_t len, struct csl_bitmap_def *defs, int num_defs, constant char *pfx);
public int parse_csl_bitmap(constant char *str, struct csl_bitmap_def *defs, int num_defs, constant char *pfx);
public constant char * lgetenv(constant char *var);
public constant char * lgetenv_ext(constant char *var, unsigned char *env_buf, size_t env_buf_len);
@@ -146,11 +141,12 @@ public lbool isnullenv(constant char *s);
public int lesskey(constant char *filename, lbool sysvar);
public int lesskey_src(constant char *filename, lbool sysvar);
public int lesskey_content(constant char *content, lbool sysvar);
public void lesskey_parse_error(constant char *s);
public int editchar(char c, int flags);
public void init_textlist(struct textlist *tlist, mutable char *str);
public constant char * forw_textlist(constant struct textlist *tlist, constant char *prev);
public constant char * back_textlist(constant struct textlist *tlist, constant char *prev);
public void close_altpipe(IFILE ifile);
public void close_pipe(FILE *pipefd);
public void check_altpipe_error(void);
public int edit(constant char *filename);
public int edit_ifile(IFILE ifile);
@@ -172,7 +168,7 @@ public char * shell_unquote(constant char *str);
public constant char * get_meta_escape(void);
public char * shell_quoten(constant char *s, size_t slen);
public char * shell_quote(constant char *s);
public char * dirfile(constant char *dirname, constant char *filename, int must_exist);
public char * dirfile(constant char *dirname, constant char *filename, lbool must_exist);
public char * homefile(constant char *filename);
public char * fexpand(constant char *s);
public char * fcomplete(constant char *s);
@@ -181,7 +177,7 @@ public char * readfd(FILE *fd);
public char * lglob(constant char *afilename);
public lbool is_fake_pathname(constant char *path);
public char * lrealpath(constant char *path);
public char * open_altfile(constant char *filename, int *pf, void **pfd);
public char * open_altfile(constant char *filename, int *pf, FILE **pfd);
public void close_altfile(constant char *altfilename, constant char *filename);
public lbool is_dir(constant char *filename);
public char * bad_file(constant char *filename);
@@ -217,14 +213,14 @@ public void hold_ifile(IFILE ifile, int incr);
public int held_ifile(IFILE ifile);
public void * get_filestate(IFILE ifile);
public void set_filestate(IFILE ifile, void *filestate);
public void set_altpipe(IFILE ifile, void *p);
public void *get_altpipe(IFILE ifile);
public void set_altpipe(IFILE ifile, FILE *p);
public FILE *get_altpipe(IFILE ifile);
public void set_altfilename(IFILE ifile, char *altfilename);
public char * get_altfilename(IFILE ifile);
public void if_dump(void);
public POSITION forw_line_seg(POSITION curr_pos, lbool skipeol, lbool rscroll, lbool nochop, lbool full_pad, lbool rforw, POSITION *p_linepos, lbool *p_newline);
public POSITION forw_line(POSITION curr_pos, POSITION *p_linepos, lbool *p_newline);
public POSITION back_line(POSITION curr_pos, lbool *p_newline);
public POSITION back_line(POSITION curr_pos, POSITION *p_linepos, lbool *p_newline);
public void set_attnpos(POSITION pos);
public void jump_forw(void);
public void jump_forw_buffered(void);
@@ -234,13 +230,15 @@ public void jump_percent(int percent, long fraction);
public void jump_line_loc(POSITION pos, int sline);
public POSITION after_header_pos(POSITION pos);
public void jump_loc(POSITION pos, int sline);
public int parse_lesskey(constant char *infile, struct lesskey_tables *tables);
public int parse_lesskey_content(constant char *content, struct lesskey_tables *tables);
public void init_line(void);
public lbool is_ascii_char(LWCHAR ch);
public POSITION line_position(void);
public lbool is_line_contig_pos(POSITION pos);
public void set_line_contig_pos(POSITION pos);
public void prewind(lbool contig);
public void plinestart(POSITION pos);
public void plinestart(POSITION line_pos, POSITION curr_pos);
public unsigned line_pfx_width(void);
public void pshift_all(void);
public int pwidth(LWCHAR ch, int a, LWCHAR prev_ch, int prev_a);
@@ -281,9 +279,10 @@ public POSITION find_pos(LINENUM linenum);
public LINENUM currline(int where);
public void scan_eof(void);
public LINENUM vlinenum(LINENUM linenum);
public void lmsg_init(constant char *lmsg_file);
public constant char * lmsg(lessmsg_id id);
public void lsystem(constant char *cmd, constant char *donemsg);
public int pipe_mark(char c, constant char *cmd);
public int pipe_data(constant char *cmd, POSITION spos, POSITION epos);
public int pipe_pos(constant char *cmd, POSITION mpos1, POSITION mpos2);
public void init_mark(void);
public lbool badmark(char c);
public void setmark(char c, int where, LINENUM linenum);
@@ -381,7 +380,7 @@ public void set_output(int fd, lbool no_term_init);
public int putchr(int ch);
public void clear_bot_if_needed(void);
public void putstr(constant char *s);
public int less_printf(constant char *fmt, constant PARG *parg);
public void less_printf(constant char *fmt, constant PARG *parg);
public void get_return(void);
public void error(constant char *fmt, constant PARG *parg);
public void ierror(constant char *fmt, constant PARG *parg);
@@ -420,7 +419,6 @@ public void draw_target_attn(lbool hilite);
public void clear_attn(void);
public void undo_search(lbool clear);
public lbool undo_osc8(void);
public void clr_hlist(struct hilite_tree *anchor);
public void clr_hilite(void);
public void clr_filter(void);
public void set_header(POSITION pos);
@@ -439,10 +437,9 @@ public void prep_hilite(POSITION spos, POSITION epos, int maxlines);
public void set_filter_pattern(constant char *pattern, int search_type);
public lbool is_filtering(void);
public RETSIGTYPE lwinch(int type);
public void init_signals(int on);
public void init_signals(lbool on);
public void psignals(void);
public void cleantags(void);
public int gettagtype(void);
public void findtag(constant char *tag);
public POSITION tagsearch(void);
public constant char * nexttag(int n);
+5 -1
View File
@@ -1,4 +1,4 @@
/* This file was generated by mkhelp.pl from less.hlp at 23:54 on 2026/5/30 */
/* This file was generated by mkhelp.pl from less.hlp at 1:42 on 2026/9/9 */
#include "less.h"
constant char helpdata[] = {
'\n',
@@ -16,6 +16,8 @@ constant char helpdata[] = {
'\n',
' ',' ','e',' ',' ','^','E',' ',' ','j',' ',' ','^','N',' ',' ','C','R',' ',' ','*',' ',' ','F','o','r','w','a','r','d',' ',' ','o','n','e',' ','l','i','n','e',' ',' ',' ','(','o','r',' ','_','\b','N',' ','l','i','n','e','s',')','.','\n',
' ',' ','y',' ',' ','^','Y',' ',' ','k',' ',' ','^','K',' ',' ','^','P',' ',' ','*',' ',' ','B','a','c','k','w','a','r','d',' ','o','n','e',' ','l','i','n','e',' ',' ',' ','(','o','r',' ','_','\b','N',' ','l','i','n','e','s',')','.','\n',
' ',' ','J',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','F','o','r','w','a','r','d',' ',' ','o','n','e',' ','l','i','n','e',',',' ','b','u','t',' ','d','o','n','\'','t',' ','s','t','o','p',' ','a','t',' ','e','n','d','-','o','f','-','f','i','l','e','.','\n',
' ',' ','K',' ',' ','Y',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','B','a','c','k','w','a','r','d',' ','o','n','e',' ','l','i','n','e',',',' ','b','u','t',' ','d','o','n','\'','t',' ','s','t','o','p',' ','a','t',' ','b','e','g','i','n','n','i','n','g','-','o','f','-','f','i','l','e','.','\n',
' ',' ','E','S','C','-','j',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','F','o','r','w','a','r','d',' ',' ','o','n','e',' ','f','i','l','e',' ','l','i','n','e',' ','(','o','r',' ','_','\b','N',' ','f','i','l','e',' ','l','i','n','e','s',')','.','\n',
' ',' ','E','S','C','-','k',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','B','a','c','k','w','a','r','d',' ','o','n','e',' ','f','i','l','e',' ','l','i','n','e',' ','(','o','r',' ','_','\b','N',' ','f','i','l','e',' ','l','i','n','e','s',')','.','\n',
' ',' ','f',' ',' ','^','F',' ',' ','^','V',' ',' ','S','P','A','C','E',' ',' ','*',' ',' ','F','o','r','w','a','r','d',' ',' ','o','n','e',' ','w','i','n','d','o','w',' ','(','o','r',' ','_','\b','N',' ','l','i','n','e','s',')','.','\n',
@@ -28,6 +30,7 @@ constant char helpdata[] = {
' ',' ','u',' ',' ','^','U',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','B','a','c','k','w','a','r','d',' ','o','n','e',' ','h','a','l','f','-','w','i','n','d','o','w',' ','(','a','n','d',' ','s','e','t',' ','h','a','l','f','-','w','i','n','d','o','w',' ','t','o',' ','_','\b','N',')','.','\n',
' ',' ','E','S','C','-',')',' ',' ','R','i','g','h','t','A','r','r','o','w',' ','*',' ',' ','R','i','g','h','t',' ','o','n','e',' ','h','a','l','f',' ','s','c','r','e','e','n',' ','w','i','d','t','h',' ','(','o','r',' ','_','\b','N',' ','p','o','s','i','t','i','o','n','s',')','.','\n',
' ',' ','E','S','C','-','(',' ',' ','L','e','f','t','A','r','r','o','w',' ',' ','*',' ',' ','L','e','f','t',' ',' ','o','n','e',' ','h','a','l','f',' ','s','c','r','e','e','n',' ','w','i','d','t','h',' ','(','o','r',' ','_','\b','N',' ','p','o','s','i','t','i','o','n','s',')','.','\n',
' ',' ','E','S','C','-',']',' ',' ','E','S','C','-','R','A','r','r','o','w',' ','*',' ',' ','R','i','g','h','t',' ','l','i','k','e',' ','E','S','C','-',')',' ','b','u','t',' ','s','t','o','p',' ','a','t',' ','l','o','n','g','e','s','t',' ','l','i','n','e','.','\n',
' ',' ','E','S','C','-','}',' ',' ','^','R','i','g','h','t','A','r','r','o','w',' ',' ',' ','R','i','g','h','t',' ','t','o',' ','l','a','s','t',' ','c','o','l','u','m','n',' ','d','i','s','p','l','a','y','e','d','.','\n',
' ',' ','E','S','C','-','{',' ',' ','^','L','e','f','t','A','r','r','o','w',' ',' ',' ',' ','L','e','f','t',' ',' ','t','o',' ','f','i','r','s','t',' ','c','o','l','u','m','n','.','\n',
' ',' ','F',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','F','o','r','w','a','r','d',' ','f','o','r','e','v','e','r',';',' ','l','i','k','e',' ','"','t','a','i','l',' ','-','f','"','.','\n',
@@ -120,6 +123,7 @@ constant char helpdata[] = {
' ',' ','!','_','\b','c','_','\b','o','_','\b','m','_','\b','m','_','\b','a','_','\b','n','_','\b','d',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','x','e','c','u','t','e',' ','t','h','e',' ','s','h','e','l','l',' ','c','o','m','m','a','n','d',' ','w','i','t','h',' ','$','S','H','E','L','L','.','\n',
' ',' ','#','_','\b','c','_','\b','o','_','\b','m','_','\b','m','_','\b','a','_','\b','n','_','\b','d',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','x','e','c','u','t','e',' ','t','h','e',' ','s','h','e','l','l',' ','c','o','m','m','a','n','d',',',' ','e','x','p','a','n','d','e','d',' ','l','i','k','e',' ','a',' ','p','r','o','m','p','t','.','\n',
' ',' ','|','X','\b','X','_','\b','c','_','\b','o','_','\b','m','_','\b','m','_','\b','a','_','\b','n','_','\b','d',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','P','i','p','e',' ','f','i','l','e',' ','b','e','t','w','e','e','n',' ','c','u','r','r','e','n','t',' ','p','o','s',' ','&',' ','m','a','r','k',' ','X','\b','X',' ','t','o',' ','s','h','e','l','l',' ','c','o','m','m','a','n','d','.','\n',
' ',' ','|','|','X','\b','X','Y','\b','Y','_','\b','c','_','\b','o','_','\b','m','_','\b','m','_','\b','a','_','\b','n','_','\b','d',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','P','i','p','e',' ','f','i','l','e',' ','b','e','t','w','e','e','n',' ','m','a','r','k',' ','X','\b','X',' ','a','n','d',' ','m','a','r','k',' ','Y','\b','Y',' ','t','o',' ','s','h','e','l','l',' ','c','o','m','m','a','n','d','.','\n',
' ',' ','s',' ','_','\b','f','_','\b','i','_','\b','l','_','\b','e',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','a','v','e',' ','i','n','p','u','t',' ','t','o',' ','a',' ','f','i','l','e','.','\n',
' ',' ','v',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','d','i','t',' ','t','h','e',' ','c','u','r','r','e','n','t',' ','f','i','l','e',' ','w','i','t','h',' ','$','V','I','S','U','A','L',' ','o','r',' ','$','E','D','I','T','O','R','.','\n',
' ',' ','V',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','P','r','i','n','t',' ','v','e','r','s','i','o','n',' ','n','u','m','b','e','r',' ','o','f',' ','"','l','e','s','s','"','.','\n',
+6 -3
View File
@@ -22,6 +22,7 @@
#include "less.h"
extern IFILE curr_ifile;
extern IFILE old_ifile;
struct ifile {
struct ifile *h_next; /* Links for command line list */
@@ -33,7 +34,7 @@ struct ifile {
int h_hold; /* Hold count */
lbool h_opened; /* Has this ifile been opened? */
struct scrpos h_scrpos; /* Saved position within the file */
void *h_altpipe; /* Alt pipe */
FILE *h_altpipe; /* Alt pipe */
char *h_altfilename; /* Alt filename */
};
@@ -139,6 +140,8 @@ public void del_ifile(IFILE h)
unmark(h);
if (h == curr_ifile)
curr_ifile = getoff_ifile(curr_ifile);
if (h == old_ifile)
old_ifile = NULL_IFILE;
p = int_ifile(h);
unlink_ifile(p);
free(p->h_rfilename);
@@ -319,12 +322,12 @@ public void set_filestate(IFILE ifile, void *filestate)
int_ifile(ifile)->h_filestate = filestate;
}
public void set_altpipe(IFILE ifile, void *p)
public void set_altpipe(IFILE ifile, FILE *p)
{
int_ifile(ifile)->h_altpipe = p;
}
public void *get_altpipe(IFILE ifile)
public FILE *get_altpipe(IFILE ifile)
{
return (int_ifile(ifile)->h_altpipe);
}
+9 -5
View File
@@ -146,13 +146,13 @@ get_forw_line:
if (is_line_contig_pos(curr_pos))
{
prewind(TRUE);
plinestart(base_pos);
plinestart(base_pos, curr_pos);
ch_seek(curr_pos);
new_pos = curr_pos;
} else
{
prewind(FALSE);
plinestart(base_pos);
plinestart(base_pos, curr_pos);
ch_seek(base_pos);
new_pos = base_pos;
while (new_pos < curr_pos)
@@ -355,7 +355,7 @@ public POSITION forw_line(POSITION curr_pos, POSITION *p_linepos, lbool *p_newli
* a line. The new position is the position of the first character
* of the PREVIOUS line. The line obtained is the one starting at new_pos.
*/
public POSITION back_line(POSITION curr_pos, lbool *p_newline)
public POSITION back_line(POSITION curr_pos, POSITION *p_linepos, lbool *p_newline)
{
POSITION base_pos;
POSITION new_pos;
@@ -368,6 +368,8 @@ public POSITION back_line(POSITION curr_pos, lbool *p_newline)
POSITION wrap_pos;
lbool skipped_leading;
if (p_linepos != NULL)
*p_linepos = NULL_POSITION;
get_back_line:
if (p_newline != NULL)
*p_newline = TRUE;
@@ -459,9 +461,9 @@ get_back_line:
return (NULL_POSITION);
}
endline = FALSE;
prewind(FALSE);
plinestart(new_pos);
loop:
prewind(FALSE);
plinestart(new_pos, new_pos);
wrap_pos = NULL_POSITION;
skipped_leading = FALSE;
begin_new_pos = new_pos;
@@ -583,6 +585,8 @@ get_back_line:
if (status_col)
init_status_col(base_pos, line_position(), edisp_pos, new_pos);
#endif
if (p_linepos != NULL)
*p_linepos = curr_pos;
return (begin_new_pos);
}
+13 -10
View File
@@ -24,6 +24,7 @@ extern int quit_if_one_screen;
extern lbool one_screen;
extern lbool full_screen;
extern POSITION header_start_pos;
extern POSITION soft_eof;
/*
* Jump to the end of the file.
@@ -32,14 +33,16 @@ public void jump_forw(void)
{
POSITION pos;
POSITION end_pos;
POSITION bot_pos;
if (ch_end_seek())
{
error("Cannot seek to end of file", NULL_PARG);
error(LM(Cannot_seek_to_end_of_file), NULL_PARG);
return;
}
end_pos = ch_tell();
if (position(sc_height-1) == end_pos)
bot_pos = position(BOTTOM_PLUS_ONE);
if (bot_pos == end_pos || (bot_pos == soft_eof && soft_eof != NULL_POSITION))
{
eof_bell();
return;
@@ -56,7 +59,7 @@ public void jump_forw(void)
* to get to the beginning of the last line.
*/
pos_clear();
pos = back_line(end_pos, NULL);
pos = back_line(end_pos, &soft_eof, NULL);
if (pos == NULL_POSITION)
jump_loc(ch_zero(), sc_height-1);
else
@@ -76,7 +79,7 @@ public void jump_forw_buffered(void)
if (ch_end_buffer_seek())
{
error("Cannot seek to end of buffers", NULL_PARG);
error(LM(Cannot_seek_to_end_of_buffers), NULL_PARG);
return;
}
end = ch_tell();
@@ -107,11 +110,11 @@ public void jump_back(LINENUM linenum)
} else if (linenum <= 1 && ch_beg_seek() == 0)
{
jump_loc(ch_tell(), jump_sline);
error("Cannot seek to beginning of file", NULL_PARG);
error(LM(Cannot_seek_to_beginning_of_file), NULL_PARG);
} else
{
parg.p_linenum = linenum;
error("Cannot seek to line number %n", &parg);
error(LM(Cannot_seek_to_line_number_X), &parg);
}
}
@@ -147,12 +150,12 @@ public void jump_percent(int percent, long fraction)
*/
if ((len = ch_length()) == NULL_POSITION)
{
ierror("Determining length of file", NULL_PARG);
ierror(LM(Determining_length_of_file), NULL_PARG);
ch_end_seek();
}
if ((len = ch_length()) == NULL_POSITION)
{
error("Don't know length of file", NULL_PARG);
error(LM(Dont_know_length_of_file), NULL_PARG);
return;
}
pos = percent_pos(len, percent, fraction);
@@ -270,7 +273,7 @@ public void jump_loc(POSITION pos, int sline)
*/
if (ch_seek(pos))
{
error("Cannot seek to that file position", NULL_PARG);
error(LM(Cannot_seek_to_that_file_position), NULL_PARG);
return;
}
@@ -304,7 +307,7 @@ public void jump_loc(POSITION pos, int sline)
#endif
return;
}
pos = back_line(pos, NULL);
pos = back_line(pos, NULL, NULL);
if (pos == NULL_POSITION)
{
/*
+10 -6
View File
@@ -80,6 +80,7 @@
#define muldiv(val,num,den) umuldiv((uintmax)(val), (uintmax)(num), (uintmax)(den))
#include "lang.h"
#include "lmsg.h"
#if defined UINTMAX_MAX
typedef uintmax_t uintmax;
@@ -142,13 +143,13 @@ void free();
#if HAVE_UPPER_LOWER
#define IS_UPPER(c) (is_ascii_char(c) && isupper((unsigned char) (c)))
#define IS_LOWER(c) (is_ascii_char(c) && islower((unsigned char) (c)))
#define TO_UPPER(c) (is_ascii_char(c) ? toupper((unsigned char) (c)) : (c))
#define TO_LOWER(c) (is_ascii_char(c) ? tolower((unsigned char) (c)) : (c))
#define TO_UPPER(c) (is_ascii_char(c) ? (LWCHAR) toupper((unsigned char) (c)) : (LWCHAR) (c))
#define TO_LOWER(c) (is_ascii_char(c) ? (LWCHAR) tolower((unsigned char) (c)) : (LWCHAR) (c))
#else
#define IS_UPPER(c) (is_ascii_char(c) && ASCII_IS_UPPER(c))
#define IS_LOWER(c) (is_ascii_char(c) && ASCII_IS_LOWER(c))
#define TO_UPPER(c) (is_ascii_char(c) ? ASCII_TO_UPPER(c) : (c))
#define TO_LOWER(c) (is_ascii_char(c) ? ASCII_TO_LOWER(c) : (c))
#define TO_UPPER(c) (is_ascii_char(c) ? (LWCHAR) ASCII_TO_UPPER(c) : (LWCHAR) (c))
#define TO_LOWER(c) (is_ascii_char(c) ? (LWCHAR) ASCII_TO_LOWER(c) : (LWCHAR) (c))
#endif
#endif
@@ -413,11 +414,12 @@ typedef enum osc8_state {
OSC_INTRO, /* Waiting for intro char, usually ']' */
OSC_TYPENUM, /* Reading OS command type */
OSC_STRING, /* Reading OS command string */
OSC_END_CSI, /* Waiting for backslash after the final ESC. */
OSC_STRING_CSI, /* Waiting for backslash after the final ESC. */
OSC_END, /* At end */
OSC8_PARAMS, /* In the OSC8 parameters */
OSC8_URI, /* In the OSC8 URI */
OSC8_URI_CSI, /* Waiting for backslash after the final ESC. */
OSC8_NOT, /* This is not an OSC8 link */
} osc8_state;
@@ -459,7 +461,8 @@ typedef enum osc8_state {
#define AT_COLOR_SEARCH (10 << AT_COLOR_SHIFT)
#define AT_COLOR_TILDE (11 << AT_COLOR_SHIFT)
#define AT_COLOR_TARGET (12 << AT_COLOR_SHIFT)
#define AT_COLOR_SS_OFFSET 13 /* largest AT_COLOR_* value + 1 */
#define AT_COLOR_OSC8 (13 << AT_COLOR_SHIFT)
#define AT_COLOR_SS_OFFSET 14 /* largest AT_COLOR_* value + 1 */
#define NUM_SEARCH_COLORS 5
#define AT_NUM_COLORS (AT_COLOR_SS_OFFSET + NUM_SEARCH_COLORS)
#define AT_COLOR_SUBSEARCH(i) ((AT_COLOR_SS_OFFSET+(i)-1) << AT_COLOR_SHIFT)
@@ -680,6 +683,7 @@ struct mlist;
struct loption;
struct hilite_tree;
struct ansi_state;
struct lesskey_tables;
#include "pattern.h"
#include "xbuf.h"
#include "funcs.h"
+4
View File
@@ -13,6 +13,8 @@
e ^E j ^N CR * Forward one line (or _N lines).
y ^Y k ^K ^P * Backward one line (or _N lines).
J * Forward one line, but don't stop at end-of-file.
K Y * Backward one line, but don't stop at beginning-of-file.
ESC-j * Forward one file line (or _N file lines).
ESC-k * Backward one file line (or _N file lines).
f ^F ^V SPACE * Forward one window (or _N lines).
@@ -25,6 +27,7 @@
u ^U * Backward one half-window (and set half-window to _N).
ESC-) RightArrow * Right one half screen width (or _N positions).
ESC-( LeftArrow * Left one half screen width (or _N positions).
ESC-] ESC-RArrow * Right like ESC-) but stop at longest line.
ESC-} ^RightArrow Right to last column displayed.
ESC-{ ^LeftArrow Left to first column.
F Forward forever; like "tail -f".
@@ -117,6 +120,7 @@
!_c_o_m_m_a_n_d Execute the shell command with $SHELL.
#_c_o_m_m_a_n_d Execute the shell command, expanded like a prompt.
|XX_c_o_m_m_a_n_d Pipe file between current pos & mark XX to shell command.
||XXYY_c_o_m_m_a_n_d Pipe file between mark XX and mark YY to shell command.
s _f_i_l_e Save input to a file.
v Edit the current file with $VISUAL or $EDITOR.
V Print version number of "less".
+174 -64
View File
@@ -1,5 +1,5 @@
'\" t
.TH LESS 1 "30 May 2026" "less 704"
.TH LESS 1 "08 Sep 2026" "less 710"
.\" Define a string for the caret ("hat") as portably as possible.
.ie \n(.g .ds ^ \(ha
.el .ds ^ ^
@@ -14,6 +14,43 @@
.\" compatibility, else interpolate nothing.
.ie \n(.g .ds : \:
.el .ds : \" empty
.\" Define local versions of groff's "an-ext.tmac" macros if needed.
.ds %% \" empty
.if \n(.g .ig %%
.\" Prepare link text for mail/web hyperlinks. `MT` and `UR` call this.
.de mV
. ds mU \\$1\"
..
.
.
.\" Emit hyperlink. The optional argument supplies trailing punctuation
.\" after link text. `ME` and `UE` call this.
.de mQ
. mY
. nh
<\\*(mU>\\$1
. hy \\n(mH
. rm mU
..
.
.
.\" Start URL.
.\" .UR url
.if !\n(.g-\n(mG \{\
.de UR
. mV \\$1
..
.\}
.
.
.\" End URL.
.\" .UE [punctuation]
.if !\n(.g-\n(mG \{\
.de UE
. mQ \\$1
..
.\}
.%%
.SH NAME
less \- display the contents of a file in a terminal
.SH SYNOPSIS
@@ -22,8 +59,10 @@ less \- display the contents of a file in a terminal
.na
.B less
.\" AT&T man(7) macros accept six arguments at most.
.RB [ \- [ + ] aABcCdeEfFgGiIJKLmMnNqQrRsSuUVwWX\*~\c
]
.\" DWB 3.3 has a bug when a sixth argument is long and interpolates a
.\" string. <https://github.com/n-t-roff/DWB3.3/issues/10>
.RB [ \- [ + ]
.BR aABcCdeEfFgGiIJKLmMnNqQrRsSuUVwWX\*~ ]
.RB [ \-b\ \c
.IR size ]
.RB [ \-D\ \c
@@ -38,7 +77,7 @@ less \- display the contents of a file in a terminal
}
.IR log-file ]
.RB [ \-p\ \c
.I pattern ]
.IR pattern ]
.RB [ \-P\ \c
.IR prompt ]
.RB [ \-t\ \c
@@ -164,6 +203,10 @@ While the text is scrolled, it acts as though the
.B "\-S"
option
(chop lines) were in effect.
.IP "ESC-] or ESC-RIGHTARROW"
Scroll horizontally right N characters like RIGHTARROW,
but stop scrolling when the last (rightmost) character on the
displayed screen becomes visible at the right margin.
.IP "ESC-( or LEFTARROW"
Scroll horizontally left N characters, default half the screen width
(see the
@@ -491,6 +534,10 @@ the entire filename should be enclosed in double quotes
(also see the
.B "\-\[dq]"
option).
Any shell metacharacters in the filename, such as "*" and "?", are
expanded by the shell named in the SHELL environment variable.
(Note that some shells may execute external programs if
certain metacharacters are used, such as backticks or dollar signs.)
.IP "\*^X\*^V or E"
Same as :e.
Warning: some systems use \*^V as a special literalization character.
@@ -527,7 +574,8 @@ If possible, it also prints the length of the file,
the number of lines in the file
and the percent of the file above the last displayed line.
.IP \-
Followed by one of the command line option letters (see OPTIONS below),
Followed by one of the command line option letters
(see \*(lqOPTIONS\*(rq below),
this will change the setting of that option
and print a message describing the new setting.
If a \*^P (CONTROL-P) is entered immediately after the dash,
@@ -544,7 +592,8 @@ a new value may be entered after the option letter.
If no new value is entered, a message describing
the current setting is printed and nothing is changed.
.IP \-\-
Like the \- command, but takes a long option name (see OPTIONS below)
Like the \- command, but takes a long option name
(see \*(lqOPTIONS\*(rq below),
rather than a single option letter.
Press ENTER or RETURN after typing the option name to change it.
You can enter just the beginning of an option name,
@@ -607,9 +656,11 @@ or defaults to "vi" if neither VISUAL nor EDITOR is defined.
See also the discussion of LESSEDIT under the section on PROMPTS below.
.IP "! \fIshell-command\fP"
Invokes a shell to run the shell-command given.
A percent sign (%) in the filename is replaced by the
shell-escaped name of the current file.
A pound sign (#) is replaced by the shell-escaped name of the previously examined file.
A percent sign (%) in the command is replaced by the name of the
current file.
Two consecutive percent signs (%%) are replaced with a single percent sign.
A pound sign (#) is replaced by the name of the previously examined file.
Two consecutive pound signs (##) are replaced with a single pound sign.
"!!" repeats the last shell command.
"!" with no shell command invokes an interactive shell.
If a \*^P (CONTROL-P) is entered immediately after the !,
@@ -622,7 +673,7 @@ Similar to the "!" command,
except that the command is expanded in the same way as prompt strings.
For example, the name of the current file would be given as "%f".
.IP "| <\fIm\fP> \fIshell-command\fP"
<m> represents any mark letter.
<m> represents any mark character.
Pipes a section of the input file to the given shell command.
If the marked line is before the top line of the current screen,
the section to be piped is between the marked line and the bottom line
@@ -630,10 +681,22 @@ of the current screen, inclusive.
Otherwise (if the marked line is the top line of the current screen
or after it) the section of the file to be piped is between the top line
of the current screen and the marked line, inclusive.
<m> may also be \*^ or $ to indicate beginning or end of file respectively.
If <m> is \&.\& or newline, the current screen is piped.
If a \*^P (CONTROL-P) is entered immediately after the mark letter,
<m> may also be "\*^" or "$" to indicate beginning or end of file respectively.
If <m> is "\&.\&" or newline, the currently displayed screen is piped.
You can type \*^N in place of <m> in order to enter
a line number instead of a mark letter.
If a \*^P (CONTROL-P) is entered at the start of the shell command,
no "done" message is printed after the shell command is executed.
.IP "|| <\fIm1\fP> <\fIm2\fP> \fIshell-command\fP"
Like "|", pipes a section of the input file to the given shell command.
The section of the file to be piped is between the two lines marked
with <m1> and <m2>, inclusive.
The line marked by <m1> may be either before or after the line marked by <m2> in the file.
Either mark may be "\*^" or "$" to indicate beginning or end of file respectively.
":" or newline indicates the first line displayed on the screen,
and ";" indicates the last line displayed on the screen.
You can type \*^N in place of either <m1> or <m2> in order to enter
a line number instead of a mark letter.
.IP "s \fIfilename\fP"
Save the input to a file.
This works only if the input is a pipe, not an ordinary file.
@@ -741,7 +804,7 @@ and
.B "\-\-modelines"
begin with
.BR "\-\-mo" "."
.PP
Some long option names are in uppercase, such as
.BR "\-\-QUIT\-AT\-EOF" ","
as
@@ -909,6 +972,8 @@ Mark letters in the status column.
Line numbers enabled via the
.B "\-N"
option.
.IP "O"
OSC 8 hyperlinks.
.IP "P"
Prompts.
.IP "R"
@@ -1005,10 +1070,11 @@ 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
.nh
https://\*:en\*:.wikipedia\*:.org/\*:wiki/\*:ANSI_escape_code\*:#SGR).
.hy
a "CSI 38;5" color value
(an
.UR https://\*:en\*:.wikipedia\*:.org/\*:wiki/\*:ANSI_escape_code\*:#SGR
SGR escape sequence
.UE ).
If either integer is a "\-" or is omitted,
the corresponding color is set to that of normal text.
.PP
@@ -1041,14 +1107,11 @@ For historical reasons, when a lowercase color selector letter
is followed by a numeric color value,
the number is not interpreted as an "CSI 38;5" color value as described above,
but instead as a 4-bit
.nh
CHAR_INFO.Attributes
.hy
value, between 0 and 15 inclusive
(see
.nh
https://\*:learn\*:.microsoft\*:.com/\*:en\-us/\*:windows/\*:console/\*:char\-info\-str).
.hy
.UR https://\*:learn\*:.microsoft\*:.com/\*:en\-us/\*:windows/\
\*:console/\*:char\-info\-str
CHAR_INFO.Attributes
.UE
value, between 0 and 15 inclusive.
.IP
To avoid confusion, it is recommended that the equivalent letters rather than numbers
be used after a lowercase color selector on MS-DOS/Windows.
@@ -1207,7 +1270,7 @@ option is in effect.
Causes
.B less
to open and interpret the named file as a
.BR lesskey (1)
.BR lesskey (5)
binary file.
Multiple
.B "\-k"
@@ -1224,7 +1287,7 @@ below.
Causes
.B less
to open and interpret the named file as a
.BR lesskey (1)
.BR lesskey (5)
source file.
If the LESSKEYIN or LESSKEYIN_SYSTEM environment variable is set, or
if a lesskey source file is found in a standard place (see KEY BINDINGS),
@@ -1249,7 +1312,7 @@ below.
Causes
.B less
to interpret the specified text as the contents of a
.BR lesskey (1)
.BR lesskey (5)
source file.
In the text,
.B lesskey
@@ -1260,7 +1323,10 @@ Warning: certain environment variables such as
LESS, LESSSECURE, LESSCHARSET and others,
which are used early in startup,
cannot be set in a file specified by a command line option
.RB "(" "\-\-lesskey" ", " "\-\-lesskey\-src" " or " "\-\-lesskey\-content" ")."
.RB ( \-\-lesskey ,
.B \-\-lesskey\-src
or
.BR \-\-lesskey\-content ).
When using a
.B lesskey
file to set environment variables, it is safer to use the
@@ -1514,10 +1580,10 @@ If the environment variable LESSGLOBALTAGS is set, it is taken to be
the name of a command compatible with
.BR global (1),
and that command is executed to find the tag.
(See
.nh
http://\*:www\*:.gnu\*:.org/\*:software/\*:global/\*:global\*:.html).
.hy
(See the
.UR http://\*:www\*:.gnu\*:.org/\*:software/\*:global/\*:global\*:.html
GNU global home page
.UE .)
The
.B "\-t"
option may also be specified from within
@@ -1643,7 +1709,8 @@ lines less than the current screen size.
For example, if the screen is 24 lines,
.B "\-z\-4"
sets the
scrolling window to 20 lines. If the screen is later resized to 40 lines,
scrolling window to 20 lines.
If the screen is later resized to 40 lines,
the scrolling window automatically changes to 36 lines.
.IP "\fB\-""\fP\fIcc\fP\ or\ \fB\-\-quotes=\fP\fIcc\fP"
Changes the filename quoting character.
@@ -1660,7 +1727,7 @@ character and followed by the close quote character.
Note that even after the quote characters are changed, this option
remains \-" (a dash followed by a double quote).
.IP "\fB\-\*~\fP or \fB\-\-tilde\fP"
Normally lines after end of file are displayed as a single tilde (\*~).
Normally, lines after end of file are displayed as a single tilde (\*~).
This option causes lines after end of file to be displayed as blank lines.
.IP "\fB\-#\fP or \fB\-\-shift\fP"
Specifies the default number of positions to scroll horizontally
@@ -1673,7 +1740,7 @@ screen width, \&.3 is three tenths of the screen width, and so on.
If the number is specified as a fraction, the actual number of
scroll positions is recalculated if the terminal window is resized.
.IP "\fB\-\-autosave=\fP\fIactions\fP
Normally the history file is saved only when
Normally, the history file is saved only when
.B less
exits.
This option specifies other actions which will cause the history file to be saved.
@@ -1979,7 +2046,7 @@ Searches do not include header lines or header columns.
.IP "\fB\-\-no\-vbell\fP"
Disables the terminal's visual bell.
.IP "\fB\-\-past\-eof\fP"
Normally scrolling commands (other than J, K, ESC-SPACE and ESC-b)
Normally, scrolling commands (other than J, K, ESC-SPACE and ESC-b)
stop scrolling when end-of-file is reached scrolling forward, or
beginning-of-file is reached scrolling backward.
This option makes all scrolling commands continue past end-of-file
@@ -2121,9 +2188,10 @@ The
option can be used to change the colors.
Colored text works only if the terminal supports
ANSI color escape sequences (as defined in
.nh
https://\*:www\*:.ecma\-international\*:.org/\*:publications\-and\-standards/\*:standards/\*:ecma\-48).
.hy
.UR https://\*:www\*:.ecma\-international\*:.org/\
\*:publications\-and\-standards/\*:standards/\*:ecma\-48)
ECMA-48
.UE .
.IP "\fB\-\-wheel\-lines=\fP\fIn\fP"
Set the number of lines or columns to scroll when the mouse wheel is scrolled
and the
@@ -2245,7 +2313,7 @@ You may also change the line-editing keys (see LINE EDITING),
and set environment variables used by
.BR less .
See the
.BR lesskey (1)
.BR lesskey (5)
manual page for details about the file format.
.PP
If the environment variable LESSKEYIN is set,
@@ -2326,6 +2394,7 @@ to a command line which will invoke your input preprocessor.
This command line should include one occurrence of the string "%s",
which will be replaced by the filename
when the input preprocessor command is invoked.
Two consecutive percent signs are replaced with a single percent sign.
.PP
When
.B less
@@ -2341,6 +2410,7 @@ It may include two occurrences of the string "%s";
the first is replaced with the original name of the file and
the second with the name of the replacement file,
which was output by LESSOPEN.
Two consecutive percent signs are replaced with a single percent sign.
.PP
For example, on many Unix systems, these two scripts will allow you
to keep files in compressed format, but still let
@@ -2504,7 +2574,8 @@ Selects a character set appropriate for MS-DOS.
Selects an EBCDIC character set.
.IP IBM\-1047
Selects an EBCDIC character set used by OS/390 Unix Services.
This is the EBCDIC analogue of latin1. You get similar results
This is the EBCDIC analogue of latin1.
You get similar results
by setting either LESSCHARSET=IBM\-1047 or LC_CTYPE=en_US
in your environment.
.IP koi8\-r
@@ -2573,7 +2644,8 @@ interface is also not available, the default character set is utf\-8.
.PP
Control and binary characters are displayed in standout (reverse video).
Each such character is displayed in caret notation if possible
(e.g.\& \*^A for control-A). Caret notation is used only if
(e.g.\& \*^A for control-A).
Caret notation is used only if
inverting the 0100 bit results in a normal printable character.
Otherwise, the character is displayed as a hex number in angle brackets.
This format can be changed by
@@ -2704,9 +2776,9 @@ The line to be used is determined by the \fIX\fP, as with the %b option.
Replaced by the number of pages in the input file,
or equivalently, the page number of the last line in the input file.
.IP "%E"
Replaced by the name of the editor (from the VISUAL environment variable,
or the EDITOR environment variable if VISUAL is not defined).
See the discussion of the LESSEDIT feature below.
Replaced by the value of the VISUAL environment variable,
or the EDITOR environment variable if VISUAL is not defined.
See the usage example at the LESSEDIT feature below.
.IP "%f"
Replaced by the name of the current input file.
.IP "%F"
@@ -2715,6 +2787,8 @@ Replaced by the last component of the name of the current input file.
Replaced by the shell-escaped name of the current input file.
This is useful when the expanded string will be used in a shell command,
such as in LESSEDIT.
.IP "%G"
Replaced by the shell-escaped last component of the name of the current input file.
.IP "%i"
Replaced by the index of the current file in the list of
input files.
@@ -2752,6 +2826,10 @@ Replaced by the width of the longest line currently displayed on the screen.
Note that using this sequence can make displaying the prompt be slower than usual.
.IP "%x"
Replaced by the name of the next input file in the list.
.IP "%y"
Replaced by the shell-escaped name of the next input file in the list.
.IP "%%"
Replaced by a single percent sign.
.PP
If any item is unknown (for example, the file size if input
is a pipe), a question mark is printed instead.
@@ -2907,10 +2985,11 @@ and filename completion (TAB, \*^L)
.IP "history"
history file
.IP "lesskey"
use of lesskey files
use of lesskey files, including the
.B "\-k"
and
.BR "\-\-lesskey\-src" ")"
.B "\-\-lesskey\-src"
options, and all environment variables whose name begins with "LESSKEY"
.IP "lessopen"
input preprocessor (LESSOPEN environment variable)
.IP "logfile"
@@ -2945,8 +3024,12 @@ LESSSECURE_ALLOW=hist,edit
were set, all of the above features would be disabled
except for history files and the edit command.
.PP
The LESSSECURE_DISALLOW environment variable can be set to a comma-separated list
of names of features which are selectively disabled when LESSSECURE is not set.
.PP
Less can also be compiled to be permanently in "secure" mode.
In that case, the LESSSECURE and LESSSECURE_ALLOW variables are ignored.
In that case, all of the above features are disabled,
and the LESSSECURE, LESSSECURE_ALLOW and LESSSECURE_DISALLOW variables are ignored.
.
.SH "COMPATIBILITY WITH MORE"
If the environment variable LESS_IS_MORE is set to 1,
@@ -3007,10 +3090,10 @@ command rather than a search pattern.
The LESS environment variable is ignored,
and the MORE environment variable is used in its place.
.
.SH "ENVIRONMENT VARIABLES"
.SH ENVIRONMENT
Environment variables may be specified either in the system environment
as usual, or in a
.BR lesskey (1)
.BR lesskey (5)
file.
If environment variables are defined in more than one place,
variables defined in a local lesskey file take precedence over
@@ -3086,7 +3169,8 @@ Name of the command used by the
option to find global tags.
Normally should be set to "global" if your system has the
.BR global (1)
command. If not set, global tags are not used.
command.
If not set, global tags are not used.
.IP LESSHISTFILE
Name of the history file used to remember search commands and
shell commands between invocations of
@@ -3146,6 +3230,9 @@ See discussion under SECURITY.
.IP LESSSECURE_ALLOW
Enables individual features which are normally disabled by LESSSECURE.
See discussion under SECURITY.
.IP LESSSECURE_DISALLOW
When LESSSECURE is not set, LESSSECURE_DISALLOW can disable individual features.
See discussion under SECURITY.
.IP LESSSEPARATOR
String to be appended to a directory name in filename completion
(default "\e" on MS-DOS, Windows, and OS/2; otherwise "/").
@@ -3181,6 +3268,18 @@ The default is 4000 (4 seconds).
Emulate the
.BR more (1)
command.
.IP LESSMSG
When set to the name of a
.I lessmsg
file, messages displayed by less are taken from that file.
This can be used to translate
.B less
messages into another language.
See the file
.B lessmsg
in the
.B less
distribution for more details.
.IP LESS_OSC8_OPEN_xxx
Where "xxx" is a URI scheme such as "http" or "file",
sets an OSC 8 handler for opening OSC 8 links containing a URI with that scheme.
@@ -3190,6 +3289,19 @@ no specific LESS_OSC8_OPEN_xxx handler set for the "xxx" scheme.
.IP LESS_OSC8_OPEN_NONE
Sets an OSC 8 handler for opening OSC 8 links which contain no scheme
(that is, there is no colon in the URI).
.IP LESS_SHELL_COPTION
Normally when executing a shell command
.B cmd
(via \fB!\fP, \fB#\fP, or \fB|\fP, or a LESSOPEN command),
if the SHELL environment variable is set, the command
is invoked as "\fB$SHELL -c cmd\fP".
If the LESS_SHELL_COPTION environment variable is set, its value
is used instead of "\fB-c\fP" in that invocation.
If LESS_SHELL_COPTION is set to a single dash,
.B less
acts as if SHELL were not set, and therefore invokes
.B cmd
directly.
.IP LESS_SHELL_LINES
When the
.B "\-F"
@@ -3293,7 +3405,7 @@ Possible location of the history file; see the description of the LESSHISTFILE e
Possible location of the history file; see the description of the LESSHISTFILE environment variable.
.
.SH "SEE ALSO"
.BR lesskey (1),
.BR lesskey (5),
.BR lessecho (1)
.
.SH COPYRIGHT
@@ -3322,13 +3434,11 @@ See the GNU General Public License for more details.
.
Mark Nudelman
.br
Report bugs at
.nh
https://\*:github\*:.com/\*:gwsw/\*:less/\*:issues.
.hy
.br
For more information, see the less homepage at
.br
.nh
https://\*:greenwoodsoftware\*:.com/\*:less.
.hy
Report bugs at
.UR https://\*:github\*:.com/\*:gwsw/\*:less/\*:issues
.UE .
For more information, see the
.UR https://\*:greenwoodsoftware\*:.com/\*:less
.I less
home page
.UE .
+62 -5
View File
@@ -1,9 +1,64 @@
.TH LESSECHO 1 "30 May 2026" "less 704"
.TH LESSECHO 1 "08 Sep 2026" "less 710"
.\" Define a string to interpolate the hyphenless break point escape
.\" sequence (for URLs and similar) if the formatter claims groff
.\" compatibility, else interpolate nothing.
.ie \n(.g .ds : \:
.el .ds : \" empty
.\" Define local versions of groff's "an-ext.tmac" macros if needed.
.ds %% \" empty
.if \n(.g .ig %%
.\" Prepare link text for mail/web hyperlinks. `MT` and `UR` call this.
.de mV
. ds mU \\$1\"
..
.
.
.\" Emit hyperlink. The optional argument supplies trailing punctuation
.\" after link text. `ME` and `UE` call this.
.de mQ
. mY
. nh
<\\*(mU>\\$1
. hy \\n(mH
. rm mU
..
.
.
.\" Start URL.
.\" .UR url
.if !\n(.g-\n(mG \{\
.de UR
. mV \\$1
..
.\}
.
.
.\" End URL.
.\" .UE [punctuation]
.if !\n(.g-\n(mG \{\
.de UE
. mQ \\$1
..
.\}
.
.
.\" Start email address.
.\" .MT address
.if !\n(.g-\n(mG \{\
.de MT
. mV \\$1
..
.\}
.
.
.\" End email address.
.\" .ME [punctuation]
.if !\n(.g-\n(mG \{\
.de ME
. mQ \\$1
..
.\}
.%%
.SH NAME
lessecho \- expand metacharacters
.SH SYNOPSIS
@@ -74,10 +129,12 @@ 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 <[email protected]>,
This manual page was written by
.MT [email protected]
Thomas Schoepf
.ME ,
for the Debian GNU/Linux system (but may be used by others).
.PP
Report bugs at
.nh
https://\*:github\*:.com/\*:gwsw/\*:less/\*:issues.
.hy
.UR https://\*:github\*:.com/\*:gwsw/\*:less/\*:issues
.UE .
-364
View File
@@ -1,364 +0,0 @@
/*
* Copyright (C) 1984-2026 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information, see the README file.
*/
/*
* lesskey [-o output] [input]
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Make a .less file.
* If no input file is specified, standard input is used.
* If no output file is specified, $HOME/.less is used.
*
* The .less file is used to specify (to "less") user-defined
* key bindings. Basically any sequence of 1 to MAX_CMDLEN
* keystrokes may be bound to an existing less function.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* The input file is an ascii file consisting of a
* sequence of lines of the form:
* string <whitespace> action [chars] <newline>
*
* "string" is a sequence of command characters which form
* the new user-defined command. The command
* characters may be:
* 1. The actual character itself.
* 2. A character preceded by ^ to specify a
* control character (e.g. ^X means control-X).
* 3. A backslash followed by one to three octal digits
* to specify a character by its octal value.
* 4. A backslash followed by b, e, n, r or t
* to specify \b, ESC, \n, \r or \t, respectively.
* 5. Any character (other than those mentioned above) preceded
* by a \ to specify the character itself (characters which
* must be preceded by \ include ^, \, and whitespace.
* "action" is the name of a "less" action, from the table below.
* "chars" is an optional sequence of characters which is treated
* as keyboard input after the command is executed.
*
* Blank lines and lines which start with # are ignored,
* except for the special control lines:
* #command Signals the beginning of the command
* keys section.
* #line-edit Signals the beginning of the line-editing
* keys section.
* #env Signals the beginning of the environment
* variable section.
* #stop Stops command parsing in less;
* causes all default keys to be disabled.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* The output file is a non-ascii file, consisting of a header,
* one or more sections, and a trailer.
* Each section begins with a section header, a section length word
* and the section data. Normally there are three sections:
* CMD_SECTION Definition of command keys.
* EDIT_SECTION Definition of editing keys.
* END_SECTION A special section header, with no
* length word or section data.
*
* Section data consists of zero or more byte sequences of the form:
* string <0> <action>
* or
* string <0> <action|A_EXTRA> chars <0>
*
* "string" is the command string.
* "<0>" is one null byte.
* "<action>" is one byte containing the action code (the A_xxx value).
* If action is ORed with A_EXTRA, the action byte is followed
* by the null-terminated "chars" string.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
#include "defines.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "lesskey.h"
#include "cmd.h"
constant char fileheader[] = {
C0_LESSKEY_MAGIC,
C1_LESSKEY_MAGIC,
C2_LESSKEY_MAGIC,
C3_LESSKEY_MAGIC
};
constant char filetrailer[] = {
C0_END_LESSKEY_MAGIC,
C1_END_LESSKEY_MAGIC,
C2_END_LESSKEY_MAGIC
};
constant char cmdsection[1] = { CMD_SECTION };
constant char editsection[1] = { EDIT_SECTION };
constant char varsection[1] = { VAR_SECTION };
constant char endsection[1] = { END_SECTION };
constant char *infile = NULL;
constant char *outfile = NULL;
extern char version[];
static void usage(void)
{
fprintf(stderr, "usage: lesskey [-o output] [input]\n");
exit(1);
}
void lesskey_parse_error(constant char *s)
{
fprintf(stderr, "%s\n", s);
}
int lstrtoi(constant char *buf, constant char **ebuf, int radix)
{
return (int) strtol(buf, (char**)ebuf, radix);
}
void out_of_memory(void)
{
fprintf(stderr, "lesskey: cannot allocate memory\n");
exit(1);
}
void * ecalloc(size_t count, size_t size)
{
void *p;
p = calloc(count, size);
if (p == NULL)
out_of_memory();
return (p);
}
static char * mkpathname(constant char *dirname, constant char *filename)
{
char *pathname;
pathname = ecalloc(strlen(dirname) + strlen(filename) + 2, sizeof(char));
strcpy(pathname, dirname);
strcat(pathname, PATHNAME_SEP);
strcat(pathname, filename);
return (pathname);
}
/*
* Figure out the name of a default file (in the user's HOME directory).
*/
char * homefile(constant char *filename)
{
constant char *p;
char *pathname;
if ((p = getenv("HOME")) != NULL && *p != '\0')
pathname = mkpathname(p, filename);
#if OS2
else if ((p = getenv("INIT")) != NULL && *p != '\0')
pathname = mkpathname(p, filename);
#endif
else
{
fprintf(stderr, "cannot find $HOME - using current directory\n");
pathname = mkpathname(".", filename);
}
return (pathname);
}
/*
* Parse command line arguments.
*/
static void parse_args(int argc, constant char **argv)
{
constant char *arg;
outfile = NULL;
while (--argc > 0)
{
arg = *++argv;
if (arg[0] != '-')
/* Arg does not start with "-"; it's not an option. */
break;
if (arg[1] == '\0')
/* "-" means standard input. */
break;
if (arg[1] == '-' && arg[2] == '\0')
{
/* "--" means end of options. */
argc--;
argv++;
break;
}
switch (arg[1])
{
case '-':
if (strncmp(arg, "--output", 8) == 0)
{
if (arg[8] == '\0')
outfile = &arg[8];
else if (arg[8] == '=')
outfile = &arg[9];
else
usage();
goto opt_o;
}
if (strcmp(arg, "--version") == 0)
{
goto opt_V;
}
usage();
break;
case 'o':
outfile = &argv[0][2];
opt_o:
if (*outfile == '\0')
{
if (--argc <= 0)
usage();
outfile = *(++argv);
}
break;
case 'V':
opt_V:
printf("lesskey version %s\n", version);
exit(0);
default:
usage();
}
}
if (argc > 1)
usage();
/*
* Open the input file, or use DEF_LESSKEYINFILE if none specified.
*/
if (argc > 0)
infile = *argv;
}
/*
* Output some bytes.
*/
static void fputbytes(FILE *fd, constant char *buf, size_t len)
{
while (len-- > 0)
{
fwrite(buf, sizeof(char), 1, fd);
buf++;
}
}
/*
* Output an integer, in special KRADIX form.
*/
static void fputint(FILE *fd, size_t val)
{
char c1, c2;
if (val >= KRADIX*KRADIX)
{
fprintf(stderr, "error: cannot write %ld, max %ld\n",
(long) val, (long) (KRADIX*KRADIX));
exit(1);
}
c1 = (char) (val % KRADIX);
val /= KRADIX;
c2 = (char) (val % KRADIX);
val /= KRADIX;
if (val != 0) {
fprintf(stderr, "error: %ld exceeds max integer size (%ld)\n",
(long) val, (long) (KRADIX*KRADIX));
exit(1);
}
fwrite(&c1, sizeof(char), 1, fd);
fwrite(&c2, sizeof(char), 1, fd);
}
int main(int argc, constant char *argv[])
{
struct lesskey_tables tables;
FILE *out;
int errors;
#ifdef WIN32
if (getenv("HOME") == NULL)
{
/*
* If there is no HOME environment variable,
* try the concatenation of HOMEDRIVE + HOMEPATH.
*/
constant char *drive = getenv("HOMEDRIVE");
constant char *path = getenv("HOMEPATH");
if (drive != NULL && path != NULL)
{
char *env = (char *) ecalloc(strlen(drive) +
strlen(path) + 6, sizeof(char));
strcpy(env, "HOME=");
strcat(env, drive);
strcat(env, path);
putenv(env);
}
}
#endif /* WIN32 */
/*
* Process command line arguments.
*/
parse_args(argc, argv);
errors = parse_lesskey(infile, &tables);
if (errors)
{
fprintf(stderr, "%d errors; no output produced\n", errors);
return (1);
}
fprintf(stderr, "NOTE: lesskey is deprecated.\n It is no longer necessary to run lesskey,\n when using less version 582 and later.\n");
/*
* Write the output file.
* If no output file was specified, use "$HOME/.less"
*/
if (outfile == NULL)
outfile = getenv("LESSKEY");
if (outfile == NULL)
outfile = homefile(LESSKEYFILE);
if ((out = fopen(outfile, "wb")) == NULL)
{
#if HAVE_PERROR
perror(outfile);
#else
fprintf(stderr, "Cannot open %s\n", outfile);
#endif
return (1);
}
/* File header */
fputbytes(out, fileheader, sizeof(fileheader));
/* Command key section */
fputbytes(out, cmdsection, sizeof(cmdsection));
fputint(out, tables.cmdtable.buf.end);
fputbytes(out, xbuf_char_data(&tables.cmdtable.buf), tables.cmdtable.buf.end);
/* Edit key section */
fputbytes(out, editsection, sizeof(editsection));
fputint(out, tables.edittable.buf.end);
fputbytes(out, xbuf_char_data(&tables.edittable.buf), tables.edittable.buf.end);
/* Environment variable section */
fputbytes(out, varsection, sizeof(varsection));
fputint(out, tables.vartable.buf.end);
fputbytes(out, xbuf_char_data(&tables.vartable.buf), tables.vartable.buf.end);
/* File trailer */
fputbytes(out, endsection, sizeof(endsection));
fputbytes(out, filetrailer, sizeof(filetrailer));
fclose(out);
return (0);
}
-22
View File
@@ -40,12 +40,6 @@
/* */
#define KRADIX 64
struct lesskey_cmdname
{
constant char *cn_name;
int cn_action;
};
struct lesskey_table
{
constant struct lesskey_cmdname *names;
@@ -61,19 +55,3 @@ struct lesskey_tables
struct lesskey_table vartable;
};
extern int parse_lesskey(constant char *infile, struct lesskey_tables *tables);
extern int parse_lesskey_content(constant char *content, struct lesskey_tables *tables);
/* keep in sync with less.h */
#if HAVE_SNPRINTF
#define SNPRINTF1(str, size, fmt, v1) snprintf((str), (size), (fmt), (v1))
#define SNPRINTF2(str, size, fmt, v1, v2) snprintf((str), (size), (fmt), (v1), (v2))
#define SNPRINTF3(str, size, fmt, v1, v2, v3) snprintf((str), (size), (fmt), (v1), (v2), (v3))
#define SNPRINTF4(str, size, fmt, v1, v2, v3, v4) snprintf((str), (size), (fmt), (v1), (v2), (v3), (v4))
#else
/* Use unsafe sprintf if we don't have snprintf. */
#define SNPRINTF1(str, size, fmt, v1) sprintf((str), (fmt), (v1))
#define SNPRINTF2(str, size, fmt, v1, v2) sprintf((str), (fmt), (v1), (v2))
#define SNPRINTF3(str, size, fmt, v1, v2, v3) sprintf((str), (fmt), (v1), (v2), (v3))
#define SNPRINTF4(str, size, fmt, v1, v2, v3, v4) sprintf((str), (fmt), (v1), (v2), (v3), (v4))
#endif
+63 -57
View File
@@ -1,5 +1,5 @@
'\" t
.TH LESSKEY 1 "30 May 2026" "less 704"
.TH LESSKEY 5 "08 Sep 2026" "less 710"
.\" Define a string for the caret ("hat") as portably as possible.
.ie \n(.g .ds ^ \(ha
.el .ds ^ ^
@@ -11,51 +11,51 @@
.\" compatibility, else interpolate nothing.
.ie \n(.g .ds : \:
.el .ds : \" empty
.\" Define local versions of groff's "an-ext.tmac" macros if needed.
.ds %% \" empty
.if \n(.g .ig %%
.\" Prepare link text for mail/web hyperlinks. `MT` and `UR` call this.
.de mV
. ds mU \\$1\"
..
.
.
.\" Emit hyperlink. The optional argument supplies trailing punctuation
.\" after link text. `ME` and `UE` call this.
.de mQ
. mY
. nh
<\\*(mU>\\$1
. hy \\n(mH
. rm mU
..
.
.
.\" Start URL.
.\" .UR url
.if !\n(.g-\n(mG \{\
.de UR
. mV \\$1
..
.\}
.
.
.\" End URL.
.\" .UE [punctuation]
.if !\n(.g-\n(mG \{\
.de UE
. mQ \\$1
..
.\}
.%%
.SH NAME
lesskey \- customize key bindings for less
.SH "SYNOPSIS (deprecated)"
.B lesskey
.RB [ \-o
.IR output ]
.B \-\-
.I input
.br
.B lesskey
.RB [ \-\-output=\c
.IR output ]
.B \-\-
.I input
.PP
.B "lesskey \-V"
.br
.B "lesskey \-\-version"
.SH SCOPE
This document describes the format of the
.B lesskey
source file, which is used by
.B less
version 582 and later.
In previous versions of
.BR less ,
a separate program called
.B lesskey
was used to compile the
.B lesskey
source file into a format understood by
.BR less .
This compilation step is no longer required and the
.B lesskey
program is therefore deprecated, although the file format remains supported by
.B less
itself.
.PP
.SH DESCRIPTION
A
.B lesskey
file specifies a set of key bindings and environment variables
to be used by subsequent invocations of
.BR less .
.SH FILE FORMAT
.BR less (1).
The input file consists of one or more
.IR sections .
Each section starts with a line that identifies the type of section.
@@ -109,28 +109,37 @@ when one of these keys is pressed:
.RS 5m
.TS
l l.
\ekb BACKSPACE (the BACKSPACE key; may be different than \eb)
\ekB ctrl-BACKSPACE
\ekb BACKSPACE (may be different than \eb)
\ek\*^b or \ekB ctrl-BACKSPACE
\ekd DOWN ARROW
\ek\*^d ctrl-DOWN ARROW
\ek+d shift-DOWN ARROW
\ekD PAGE DOWN
\ek^D ctrl-PAGE DOWN
\ek+D shift-PAGE DOWN
\eke END
\ekE ctrl-END
\ekF shift-END
\ek\*^e or \ekE ctrl-END
\ek+e or \ekF shift-END
\ekh HOME
\ekH ctrl-HOME
\ekI shift-HOME
\ek\*^h or \ekH ctrl-HOME
\ek+h or \ekI shift-HOME
\eki INSERT
\ekl LEFT ARROW
\ekL ctrl-LEFT ARROW
\ekM shift-LEFT ARROW
\ek\*^l or \ekL ctrl-LEFT ARROW
\ek+l or \ekM shift-LEFT ARROW
\ekr RIGHT ARROW
\ekR ctrl-RIGHT ARROW
\ekS shift-RIGHT ARROW
\ek\*^r or \ekR ctrl-RIGHT ARROW
\ek+r or \ekS shift-RIGHT ARROW
\ekt BACKTAB
\eku UP ARROW
\ek\*^u ctrl-UP ARROW
\ek+u shift-UP ARROW
\ekU PAGE UP
\ek^U ctrl-PAGE UP
\ek+U shift-PAGE UP
\ekx DELETE
\ekX ctrl-DELETE
\ek\*^x or \ekX ctrl-DELETE
\ek+x shift-DELETE
\ek1 F1
\ekp1 lower left key on the numeric keypad
\ekp2 lower center key on the numeric keypad
@@ -251,10 +260,12 @@ p percent
% percent
\ee( left\-scroll
\ee) right\-scroll
\ee] right\-limit\-scroll
\ee{ no\-scroll
\ee} end\-scroll
\ekl left\-scroll
\ekr right\-scroll
\ee\ekr right\-limit\-scroll
\ekL no\-scroll
\ekM no\-scroll
\ekR end\-scroll
@@ -507,8 +518,6 @@ the syntax ${NAME/STRING1/REPL1/STRING2/REPL2} and so on.
If a line begins with #version followed by a relational operator and a version number,
the remainder of the line is parsed if and only if the running version of
.B less
(or
.BR lesskey )
matches the operator.
This can be helpful if a lesskey file is used by different versions of
.BR less .
@@ -541,8 +550,6 @@ l l.
.PP
The #version feature is not supported in
.B less
and
.B lesskey
before version 594.
In those older versions, all #version lines are ignored.
.
@@ -596,6 +603,5 @@ See the GNU General Public License for more details.
Mark Nudelman
.br
Report bugs at
.nh
https://\*:github\*:.com/\*:gwsw/\*:less/\*:issues.
.hy
.UR https://\*:github\*:.com/\*:gwsw/\*:less/\*:issues
.UE .
+55 -28
View File
@@ -7,21 +7,21 @@
* For more information, see the README file.
*/
#include "defines.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "less.h"
#include "lesskey.h"
#include "cmd.h"
#include "xbuf.h"
#if USERFILE
#define CONTROL(c) ((c)&037)
#define ESC CONTROL('[')
extern void lesskey_parse_error(char *msg);
extern char *homefile(char *filename);
extern void *ecalloc(size_t count, size_t size);
extern int lstrtoi(char *str, char **end, int radix);
struct lesskey_cmdname
{
constant char *cn_name;
int cn_action;
};
extern char version[];
static int linenum;
@@ -98,6 +98,7 @@ static constant struct lesskey_cmdname cmdnames[] =
{ "reverse-search", A_REVERSE_SEARCH },
{ "reverse-search-all", A_T_REVERSE_SEARCH },
{ "right-scroll", A_RSHIFT },
{ "right-limit-scroll", A_RSHIFT_LIMIT },
{ "set-mark", A_SETMARK },
{ "set-mark-bottom", A_SETMARKBOT },
{ "shell", A_SHELL },
@@ -251,6 +252,7 @@ static constant char * tstr(char **pp, int xlate)
case 'k':
if (xlate)
{
char *seq = p-1;
ch = 0;
switch (*++p)
{
@@ -277,6 +279,35 @@ static constant char * tstr(char **pp, int xlate)
case 'x': ch = SK_DELETE; break;
case 'X': ch = SK_CTL_DELETE; break;
case '1': ch = SK_F1; break;
case '^':
switch (*++p)
{
case 'b': ch = SK_CTL_BACKSPACE; break;
case 'd': ch = SK_CTL_DOWN_ARROW; break;
case 'D': ch = SK_CTL_PAGE_DOWN; break;
case 'e': ch = SK_CTL_END; break;
case 'h': ch = SK_CTL_HOME; break;
case 'l': ch = SK_CTL_LEFT_ARROW; break;
case 'r': ch = SK_CTL_RIGHT_ARROW; break;
case 'u': ch = SK_CTL_UP_ARROW; break;
case 'U': ch = SK_CTL_PAGE_UP; break;
case 'x': ch = SK_CTL_DELETE; break;
}
break;
case '+':
switch (*++p)
{
case 'd': ch = SK_SHIFT_DOWN_ARROW; break;
case 'D': ch = SK_SHIFT_PAGE_DOWN; break;
case 'e': ch = SK_SHIFT_END; break;
case 'h': ch = SK_SHIFT_HOME; break;
case 'l': ch = SK_SHIFT_LEFT_ARROW; break;
case 'r': ch = SK_SHIFT_RIGHT_ARROW; break;
case 'u': ch = SK_SHIFT_UP_ARROW; break;
case 'U': ch = SK_SHIFT_PAGE_UP; break;
case 'x': ch = SK_SHIFT_DELETE; break;
}
break;
case 'p':
switch (*++p)
{
@@ -302,7 +333,11 @@ static constant char * tstr(char **pp, int xlate)
}
if (ch == 0)
{
parse_error("invalid escape sequence \"\\k%s\"", char_string(buf, *p, 0));
char seq_buf[8];
size_t len = p - seq + 1;
strncpy(seq_buf, seq, len);
seq_buf[len] = '\0';
parse_error(LM(invalid_escape_sequence), seq_buf);
*pp = increment_pointer(p);
return ("");
}
@@ -350,16 +385,6 @@ static int issp(char ch)
return (ch == ' ' || ch == '\t');
}
/*
* Skip leading spaces in a string.
*/
static char * skipsp(char *s)
{
while (issp(*s))
s++;
return (s);
}
/*
* Skip non-space characters in a string.
*/
@@ -449,14 +474,14 @@ static char * version_line(char *s)
case '=': if (*s == '=') { s++; } break;
case '!': if (*s == '=') { s++; } break;
default:
parse_error("invalid operator '%s' in #version line", char_string(buf, op, 0));
parse_error(LM(invalid_operator_X_in_version_line), char_string(buf, op, 0));
return (NULL);
}
s = skipsp(s);
ver = lstrtoi(s, &e, 10);
if (e == s)
{
parse_error("non-numeric version number in #version line", "");
parse_error(LM(non_numeric_version_number_in_version_line), "");
return (NULL);
}
if (!match_version(op, ver))
@@ -509,7 +534,7 @@ static int findaction(char *actname, struct lesskey_tables *tables)
for (i = 0; tables->currtable->names[i].cn_name != NULL; i++)
if (strcmp(tables->currtable->names[i].cn_name, actname) == 0)
return (tables->currtable->names[i].cn_action);
parse_error("unknown action: \"%s\"", actname);
parse_error(LM(unknown_action_X), actname);
return (A_INVALID);
}
@@ -548,7 +573,7 @@ static void parse_cmdline(char *p, struct lesskey_tables *tables)
p = skipsp(p);
if (*p == '\0')
{
parse_error("missing action", "");
parse_error(LM(missing_action), "");
return;
}
actname = p;
@@ -616,7 +641,7 @@ static void parse_varline(char *line, struct lesskey_tables *tables)
p = skipsp(p);
if (*p++ != '=')
{
parse_error("missing = in variable definition", "");
parse_error(LM(missing_eq_in_variable_definition), "");
return;
}
add_cmd_char(EV_OK|A_EXTRA, tables);
@@ -661,7 +686,7 @@ static void parse_line(char *line, struct lesskey_tables *tables)
/*
* Parse a lesskey source file and store result in tables.
*/
int parse_lesskey(constant char *infile, struct lesskey_tables *tables)
public int parse_lesskey(constant char *infile, struct lesskey_tables *tables)
{
FILE *desc;
char line[1024];
@@ -683,7 +708,7 @@ int parse_lesskey(constant char *infile, struct lesskey_tables *tables)
desc = stdin;
else if ((desc = fopen(lesskey_file, "r")) == NULL)
{
/* parse_error("cannot open lesskey file %s", lesskey_file); */
/* No error message since we try several possible files. */
errors = -1;
}
@@ -708,7 +733,7 @@ int parse_lesskey(constant char *infile, struct lesskey_tables *tables)
/*
* Parse a lesskey source content and store result in tables.
*/
int parse_lesskey_content(constant char *content, struct lesskey_tables *tables)
public int parse_lesskey_content(constant char *content, struct lesskey_tables *tables)
{
size_t cx = 0;
@@ -739,3 +764,5 @@ int parse_lesskey_content(constant char *content, struct lesskey_tables *tables)
lesskey_file = NULL;
return (errors);
}
#endif /* USERFILE */
+372
View File
@@ -0,0 +1,372 @@
# This is the default lessmsg file for less.
# Messages defined in this file are compiled into the less executable.
# This file can also be used as a template for creating a custom lessmsg file.
# This file defines a list of mappings from a symbol name to a message string.
# Each line in the file contains the symbol name, followed by one or more
# ASCII spaces, followed by the message string.
# To include a literal double-quote character in the message string, use
# the C-style escape sequence \". Similarly, use \\ to include a literal
# backslash, \n for newline, \r for carriage return, and \t for tab.
# You can also use \xDD where DD is a hexadecimal number, or \DDD where DDD
# is an octal number, to encode a character using its ASCII value.
# Non-ASCII characters should be encoded as UTF-8 bytes.
# A backslash at the end of a line indicates continuation onto the next line.
# The backslash and following newline are removed from the line.
# (Continuation lines work only in custom lessmsg files, not in the lessmsg
# file which is compiled into less.)
# Any spaces at the end of a line are significant, and will be included
# in the message string. To make it easier to see that such trailing
# spaces are present, you may wish to encode them as \40 or \x20.
# Any printf-style format specifiers in a string (%s, %d, %x, etc) should be
# retained in the new message. Do not remove such specifiers or add new ones.
# To use a custom lessmsg file, copy this file and modify any messages desired,
# then set your LESSMSG environment variable to the name of the file.
# In each modified line, you should leave the symbol name unchanged, and
# modify only the message string.
# The default value of each symbol is built into less, so you can simply
# delete any lines that you do not wish to modify, and less will use the
# default value.
Nothing_in_top_line Nothing in top line
Nothing_in_bottom_line Nothing in bottom line
No_bracket_in_top_line No bracket in top line
No_bracket_in_bottom_line No bracket in bottom line
No_matching_bracket No matching bracket
invalid_hex_number_in_LESSUTFCHARDEF invalid hex number(s) in LESSUTFCHARDEF
missing_colon_in_LESSUTFCHARDEF missing colon in LESSUTFCHARDEF
invalid_chardef invalid chardef
chardef_longer_than_256 chardef longer than 256
invalid_charset_name invalid charset name
seek_error seek error
ch_ungetchar_overrun ch_ungetchar overrun
Finishing_logfile Finishing logfile
log_file_is_incomplete Warning: log file is incomplete
seek_error_to_0 seek error to 0
Integer_is_too_big Integer is too big
Non_match Non-match\40
First_file First-file\40
EOF_ignore EOF-ignore\40
Keep_pos Keep-pos\40
Regex_off Regex-off\40
Wrap Wrap\40
Lit Lit\40
Sub_X Sub-%d\40
There_is_no_X_option There is no %s option
There_is_no__X_option There is no --%s option
Sub_pattern_1_X Sub-pattern (1-%d):
read_error read error
Search_hit_top Search hit top; continuing at bottom
Search_hit_bottom Search hit bottom; continuing at top
Link_X Link: %s
Pattern_not_found Pattern not found
Pattern_not_found_X Pattern not found: %s
Invalid_line_number Invalid line number
command_may_not_work_correctly_with_LESSOPEN Warning: command may not work correctly when file is viewed via LESSOPEN
Command_not_available Command not available
Examine Examine:\40
Cannot_edit_standard_input Cannot edit standard input
This_file_was_viewed_via_LESSOPEN WARNING: This file was viewed via LESSOPEN
No_next_file No next file
No_X_next_file No %snext file
No_previous_file No previous file
No_X_previous_file No %sprevious file
No_next_tag No next tag
No_previous_tag No previous tag
No_such_file No such file
set_mark set mark:\40
clear_mark clear mark:\40
goto_mark goto mark:\40
pipe_mark |mark:\40
pipe_line_number |line number:\40
pipe_first_mark |first mark:\40
pipe_first_line_number |first line number:\40
pipe_second_mark |second mark:\40
pipe_second_line_number |second line number:\40
Brackets Brackets:\40
some_commands_disabled Warning: some commands disabled
some_edit_commands_disabled Warning: some edit commands disabled
environment_variables_from_lesskey_file_unavailable Warning: environment variables from lesskey file unavailable
ambiguous ambiguous
invalid invalid
Input_preprocessor_failed Input preprocessor failed (status %d)
Input_preprocessor_terminated_X Input preprocessor terminated: %s
Input_preprocessor_exited_with_status_X Input preprocessor exited with status %x
X_may_be_a_binary_file \"%s\" may be a binary file. See it anyway?\40
X_is_a_terminal %s is a terminal (use -f to open it)
Missing_filename Missing filename (\"less --help\" for help)
X_exists Warning: \"%s\" exists; Overwrite, Append, Don't log, or Quit?\40
Overwrite Overwrite, Append, Don't log, or Quit? (Type \"O\", \"A\", \"D\" or \"Q\")\40
Cannot_write_to_X Cannot write to \"%s\"
cannot_quote_command cannot quote command
LESSOPEN_pipe_is_not_supported LESSOPEN pipe is not supported
LESSOPEN_ignored LESSOPEN ignored: must contain exactly one %%s
LESSCLOSE_ignored LESSCLOSE ignored; must contain no more than 2 %%s
is_a_directory is a directory
is_not_a_regular_file is not a regular file (use -f to see it)
skipping ...skipping...
Cannot_seek_to_end_of_file Cannot seek to end of file
Cannot_seek_to_end_of_buffers Cannot seek to end of buffers
Cannot_seek_to_beginning_of_file Cannot seek to beginning of file
Cannot_seek_to_line_number_X Cannot seek to line number %n
Determining_length_of_file Determining length of file
Dont_know_length_of_file Don't know length of file
Cannot_seek_to_that_file_position Cannot seek to that file position
Calculating_line_numbers Calculating line numbers
Line_numbers_turned_off Line numbers turned off
press_RETURN (press RETURN)
Cannot_seek_to_start_position Cannot seek to start position
Cannot_create_pipe Cannot create pipe
cannot_use_unicode_arguments WARNING: cannot use unicode arguments
terminal_is_not_fully_functional WARNING: terminal is not fully functional
No_filenames_allowed_with_t_option No filenames allowed with -t option
Press_RETURN_to_continue Press RETURN to continue\40
Cannot_allocate_memory Cannot allocate memory
Invalid_mark_letter_X Invalid mark letter %c
Mark_not_set Mark not set
Cannot_find_line_number_X Cannot find line number %n
Mark_not_in_current_file Mark not in current file
log_file_support_is_not_available log file support is not available
Input_is_not_a_pipe Input is not a pipe
Log_file_is_already_in_use Log file is already in use
No_log_file No log file
Log_file_X Log file \"%s\"
Invalid_fraction_in_X Invalid fraction in %s
Position_target_at_screen_line_X Position target at screen line %d
Position_target_at_screen_position_X Position target at screen position %s
Horizontal_shift_X_columns Horizontal shift %d columns
Horizontal_shift_X_of_screen_width Horizontal shift %s of screen width
Cannot_use_lesskey_file_X Cannot use lesskey file \"%s\"
Cannot_use_lesskey_source_file_X Cannot use lesskey source file \"%s\"
Error_in_lesskey_content Error in lesskey content
tags_support_is_not_available tags support is not available
Tags_file_X Tags file \"%s\"
Prompt_medium_X Prompt (medium): %s
Prompt_long_X Prompt (long): %s
Prompt_short_X Prompt (short): %s
nothing (nothing)
Print_after_medium_prompt_X Print after medium prompt: %s
Print_after_long_prompt_X Print after long prompt: %s
Print_after_short_prompt_X Print after short prompt: %s
Autosave_actions_X Autosave actions: %s
Invalid_color_string_X Invalid color string \"%s\"
on on
off off
SGR_mode_is_X SGR mode is %s
Invalid_color_specifier_X Invalid color specifier '%c'
Set__use_color_before_changing_colors Set --use-color before changing colors
Tab_stops Tab stops\40
and_then and then\40
every_X_spaces every %d spaces
dq_must_be_followed_by_1_or_2_chars -\" must be followed by 1 or 2 chars
quotes_X quotes %s
cannot_set_rscroll_to_a_wide_character cannot set rscroll to a wide character
rscroll_character_is_X rscroll character is %s
Use_h_for_help Use \"h\" for help
Search_match_shift_is_X Search match shift is %d
Search_match_shift_is_X_of_screen_width Search match shift is %s of screen width
Ignore_mouse_input Ignore mouse input
Mouse_features_enabled_X Mouse features enabled: %s
Line_number_width_must_not_be_larger_than_X Line number width must not be larger than %d
Status_column_width_must_not_be_larger_than_X Status column width must not be larger than %d
interrupt_character_is_X interrupt character is %s
Header_is_X Header (lines,columns,line-number) is %s
invalid_search_option_X invalid search option '%c'
search_options_X search options: %s
Search_does_not_include_header_lines_or_columns Search does not include header lines or columns
Search_includes_header_columns_but_not_header_lines Search includes header columns but not header lines
Search_includes_header_lines_but_not_header_columns Search includes header lines but not header columns
Search_includes_header_lines_and_columns Search includes header lines and columns
There_is_no_X_option_help There is no %s option (\"less --help\" for help)
There_is_no__X_option_help There is no --%s option (\"less --help\" for help)
The_X_option_should_not_be_followed_by_eq The --%s option should not be followed by =
X_is_an_ambiguous_abbreviation --%s is an ambiguous abbreviation (\"less --help\" for help)
No_such_option No such option
Cannot_change_the_X_option Cannot change the %s option
Cannot_query_the_X_option Cannot query the %s option
Cannot_use_or_for_a_string_option Cannot use \"-+\" or \"-!\" for a string option
Cant_use_for_a_numeric_option Can't use \"-!\" for a numeric option
Value_is_required_after_X Value is required after %s
Number_too_large_in_X Number too large in %s
Negative_number_not_allowed_in_X Negative number not allowed in %s
Number_is_required_after_X Number is required after %s
Search_includes_displayed_screen Search includes displayed screen
Search_skips_displayed_screen Search skips displayed screen
Search_includes_all_of_displayed_screen Search includes all of displayed screen
Max_buffer_space_per_file Max buffer space per file (K):\40
Max_buffer_space_per_file_X Max buffer space per file: %dK
Dont_automatically_allocate_buffers Don't automatically allocate buffers
Automatically_allocate_buffers_when_needed Automatically allocate buffers when needed
Repaint_by_scrolling_from_bottom_of_screen Repaint by scrolling from bottom of screen
Repaint_by_painting_from_top_of_screen Repaint by painting from top of screen
Assume_intelligent_terminal Assume intelligent terminal
Assume_dumb_terminal Assume dumb terminal
Dont_quit_at_end_of_file Don't quit at end-of-file
Quit_at_end_of_file Quit at end-of-file
Quit_immediately_at_end_of_file Quit immediately at end-of-file
Open_only_regular_files Open only regular files
Open_even_non_regular_files Open even non-regular files
Dont_quit_if_end_of_file_on_first_screen Don't quit if end-of-file on first screen
Quit_if_end_of_file_on_first_screen Quit if end-of-file on first screen
Dont_highlight_search_matches Don't highlight search matches
Highlight_matches_for_previous_search_only Highlight matches for previous search only
Highlight_all_matches_for_previous_search_pattern Highlight all matches for previous search pattern
Backwards_scroll_limit Backwards scroll limit:\40
Backwards_scroll_limit_is_X_lines Backwards scroll limit is %d lines
Case_is_significant_in_searches Case is significant in searches
Ignore_case_in_searches Ignore case in searches
Ignore_case_in_searches_and_in_patterns Ignore case in searches and in patterns
Target_line Target line:\40
Dont_display_a_status_column Don't display a status column
Display_a_status_column Display a status column
Interrupt_returns_to_prompt Interrupt (ctrl-C) returns to prompt
Interrupt_exits_less Interrupt (ctrl-C) exits less
Dont_use_the_LESSOPEN_filter Don't use the LESSOPEN filter
Use_the_LESSOPEN_filter Use the LESSOPEN filter
Short_prompt Short prompt
Medium_prompt Medium prompt
Long_prompt Long prompt
Dont_use_line_numbers Don't use line numbers
Use_line_numbers Use line numbers
Constantly_display_line_numbers Constantly display line numbers
Ring_the_bell_for_errors_AND_at_eof Ring the bell for errors AND at eof/bof
Ring_the_bell_for_errors_but_not_at_eof Ring the bell for errors but not at eof/bof
Never_ring_the_bell Never ring the bell
Display_control_characters_as_caret Display control characters as ^X
Display_control_characters_directly Display control characters directly (not recommended)
Display_ANSI_sequences_directly Display ANSI sequences directly, other control characters as ^X
Display_all_blank_lines Display all blank lines
Squeeze_multiple_blank_lines Squeeze multiple blank lines
Fold_long_lines Fold long lines
Chop_long_lines Chop long lines
Display_underlined_text_in_underline_mode Display underlined text in underline mode
Backspaces_cause_overstrike Backspaces cause overstrike
Print_backspace_as_caret Print backspace as ^H
Dont_highlight_target_line Don't highlight target line
Highlight_target_line Highlight target line
Dont_highlight_first_unread_line Don't highlight first unread line
Highlight_first_unread_line_after_forward_screen Highlight first unread line after forward-screen
Highlight_first_unread_line_after_any_forward_movement Highlight first unread line after any forward movement
Send_init_deinit_strings_to_terminal Send init/deinit strings to terminal
Dont_use_init_deinit_strings Don't use init/deinit strings
Forward_scroll_limit Forward scroll limit:\40
Forward_scroll_limit_is_X_lines Forward scroll limit is %d lines
Scroll_window_size Scroll window size:\40
Scroll_window_size_is_X_lines Scroll window size is %d lines
Dont_show_tildes_after_end_of_file Don't show tildes after end of file
Show_tildes_after_end_of_file Show tildes after end of file
Use_keypad_mode Use keypad mode
Dont_use_keypad_mode Don't use keypad mode
Use_new_bottom_of_screen_behavior Use new bottom of screen behavior
Use_old_bottom_of_screen_behavior Use old bottom of screen behavior
F_command_follows_file_descriptor F command follows file descriptor
F_command_follows_file_name F command follows file name
Dont_use_backslash_escaping_in_command_line_parameters Don't use backslash escaping in command line parameters
Use_backslash_escaping_in_command_line_parameters Use backslash escaping in command line parameters
Allow_duplicates_in_history_list Allow duplicates in history list
Remove_duplicates_from_history_list Remove duplicates from history list
Use_the_mouse_for_scrolling_vertically Use the mouse for scrolling vertically
Use_the_mouse_for_scrolling_vertically_reverse Use the mouse for scrolling vertically (reverse)
Normal_mouse_scroll_direction Normal mouse scroll direction
Reverse_mouse_scroll_direction Reverse mouse scroll direction
Lines_to_scroll_on_mouse_wheel Lines to scroll on mouse wheel:\40
Scroll_X_lines_on_mouse_wheel Scroll %d line(s) on mouse wheel
Dont_save_marks_in_history_file Don't save marks in history file
Save_marks_in_history_file Save marks in history file
Line_number_width Line number width:\40
Line_number_width_is_X_chars Line number width is %d chars
Status_column_width Status column width:\40
Status_column_width_is_X_chars Status column width is %d chars
Incremental_search_is_off Incremental search is off
Incremental_search_is_on Incremental search is on
Dont_use_color Don't use color
Use_color Use color
Dont_get_size_of_each_file Don't get size of each file
Get_size_of_each_file Get size of each file
Line_highlight_applies_to_text_only Line highlight applies to text only
Line_highlight_applies_to_entire_width_of_screen Line highlight applies to entire width of screen
Accept_pasted_input Accept pasted input
Ignore_pasted_input Ignore pasted input
Dont_stop_on_form_feed Don't stop on form feed
Stop_on_form_feed Stop on form feed
Stop_scrolling_at_end_of_file Stop scrolling at end of file
Dont_stop_scrolling_at_end_of_file Don't stop scrolling at end of file
Number_header_lines Number header lines
Dont_number_header_lines Don't number header lines
Dont_redraw_screen_when_quitting Don't redraw screen when quitting
Redraw_last_screen_when_quitting Redraw last screen when quitting
Search_options Search options:\40
Dont_exit_F_command_when_input_closes Don't exit F command when input closes
Exit_F_command_when_input_closes Exit F command when input closes
Display_visual_bell Display visual bell
Dont_display_visual_bell Don't display visual bell
Lines_to_read_looking_for_modelines Lines to read looking for modelines:\40
Read_X_lines_looking_for_modelines Read %d lines looking for modelines
Wrap_lines_at_any_character Wrap lines at any character
Wrap_lines_at_spaces Wrap lines at spaces
Dont_show_error_message_if_preprocessor_fails Don't show error message if preprocessor fails
Show_error_message_if_preprocessor_fails Show error message if preprocessor fails
Backspace_handling_is_specified_by_the_U_option Backspace handling is specified by the -U option
Display_underline_text_in_underline_mode Display underline text in underline mode
Print_backspaces_as_caret Print backspaces as ^H
Tab_handling_is_specified_by_the_U_option Tab handling is specified by the -U option
Expand_tabs_to_spaces Expand tabs to spaces
Print_tabs_as_caret Print tabs as ^I
Carriage_return_handling_is_specified_by_the_U_option Carriage return handling is specified by the -U option
Delete_carriage_return_before_newline Delete carriage return before newline
Print_carriage_return_as_caret Print carriage return as ^M
color_desc color desc:\40
log_file log file:\40
Log_file Log file:\40
prompt prompt:\40
tag tag:\40
tags_file tags file:\40
Tab_stops_ Tab stops:\40
quotes quotes:\40
Horizontal_shift Horizontal shift:\40
rscroll_character rscroll character:\40
Mouse_features Mouse features:\40
Header_lines Header lines:\40
Warn_when_editing_a_file_opened_via_LESSOPEN Warn when editing a file opened via LESSOPEN
Dont_warn_when_editing_a_file_opened_via_LESSOPEN Don't warn when editing a file opened via LESSOPEN
interrupt_character interrupt character:\40
Search_match_shift Search match shift:\40
Autosave_actions Autosave actions:\40
Print_after_prompt Print after prompt:\40
Error_X Error %d
cannot_open cannot open
Invalid_pattern Invalid pattern
No_previous_regular_expression No previous regular expression
Nothing_to_search Nothing to search
OSC_8_link_not_found OSC 8 link not found
No_OSC8_link_selected No OSC8 link selected
Cannot_find_OSC8_link Cannot find OSC8 link
No_handler_for_X_link_type No handler for \"%s\" link type
Cannot_quote_URI Cannot quote URI
link_done link done
Please_re_enter_search_pattern Please re-enter search pattern
No_tags_file No tags file
No_such_tag_in_tags_file No such tag in tags file
unknown_tag_type unknown tag type
Tag_not_found Tag not found
invalid_escape_sequence invalid escape sequence \"%s\"
invalid_operator_X_in_version_line invalid operator '%s' in #version line
non_numeric_version_number_in_version_line non-numeric version number in #version line
unknown_action_X unknown action: \"%s\"
missing_action missing action
missing_eq_in_variable_definition missing = in variable definition
# The help file can be overridden with the "HELP" symbol.
# Normally this will be a multi-line string, so it is convenient to define
# it here as a list of lines, each ending with a newline and backslash to
# continue the message on the next line. The last line should not have a
# final backslash.
#
# Example (remove initial ## from each line):
#
##HELP \
##First line of example help file.\n\
##Second line of help file.\n\
##Last line of help file.\n
+331
View File
@@ -0,0 +1,331 @@
M(Nothing_in_top_line,"Nothing in top line")
M(Nothing_in_bottom_line,"Nothing in bottom line")
M(No_bracket_in_top_line,"No bracket in top line")
M(No_bracket_in_bottom_line,"No bracket in bottom line")
M(No_matching_bracket,"No matching bracket")
M(invalid_hex_number_in_LESSUTFCHARDEF,"invalid hex number(s) in LESSUTFCHARDEF")
M(missing_colon_in_LESSUTFCHARDEF,"missing colon in LESSUTFCHARDEF")
M(invalid_chardef,"invalid chardef")
M(chardef_longer_than_256,"chardef longer than 256")
M(invalid_charset_name,"invalid charset name")
M(seek_error,"seek error")
M(ch_ungetchar_overrun,"ch_ungetchar overrun")
M(Finishing_logfile,"Finishing logfile")
M(log_file_is_incomplete,"Warning: log file is incomplete")
M(seek_error_to_0,"seek error to 0")
M(Integer_is_too_big,"Integer is too big")
M(Non_match,"Non-match\40")
M(First_file,"First-file\40")
M(EOF_ignore,"EOF-ignore\40")
M(Keep_pos,"Keep-pos\40")
M(Regex_off,"Regex-off\40")
M(Wrap,"Wrap\40")
M(Lit,"Lit\40")
M(Sub_X,"Sub-%d\40")
M(There_is_no_X_option,"There is no %s option")
M(There_is_no__X_option,"There is no --%s option")
M(Sub_pattern_1_X,"Sub-pattern (1-%d):")
M(read_error,"read error")
M(Search_hit_top,"Search hit top; continuing at bottom")
M(Search_hit_bottom,"Search hit bottom; continuing at top")
M(Link_X,"Link: %s")
M(Pattern_not_found,"Pattern not found")
M(Pattern_not_found_X,"Pattern not found: %s")
M(Invalid_line_number,"Invalid line number")
M(command_may_not_work_correctly_with_LESSOPEN,"Warning: command may not work correctly when file is viewed via LESSOPEN")
M(Command_not_available,"Command not available")
M(Examine,"Examine:\40")
M(Cannot_edit_standard_input,"Cannot edit standard input")
M(This_file_was_viewed_via_LESSOPEN,"WARNING: This file was viewed via LESSOPEN")
M(No_next_file,"No next file")
M(No_X_next_file,"No %snext file")
M(No_previous_file,"No previous file")
M(No_X_previous_file,"No %sprevious file")
M(No_next_tag,"No next tag")
M(No_previous_tag,"No previous tag")
M(No_such_file,"No such file")
M(set_mark,"set mark:\40")
M(clear_mark,"clear mark:\40")
M(goto_mark,"goto mark:\40")
M(pipe_mark,"|mark:\40")
M(pipe_line_number,"|line number:\40")
M(pipe_first_mark,"|first mark:\40")
M(pipe_first_line_number,"|first line number:\40")
M(pipe_second_mark,"|second mark:\40")
M(pipe_second_line_number,"|second line number:\40")
M(Brackets,"Brackets:\40")
M(some_commands_disabled,"Warning: some commands disabled")
M(some_edit_commands_disabled,"Warning: some edit commands disabled")
M(environment_variables_from_lesskey_file_unavailable,"Warning: environment variables from lesskey file unavailable")
M(ambiguous,"ambiguous")
M(invalid,"invalid")
M(Input_preprocessor_failed,"Input preprocessor failed (status %d)")
M(Input_preprocessor_terminated_X,"Input preprocessor terminated: %s")
M(Input_preprocessor_exited_with_status_X,"Input preprocessor exited with status %x")
M(X_may_be_a_binary_file,"\"%s\" may be a binary file. See it anyway?\40")
M(X_is_a_terminal,"%s is a terminal (use -f to open it)")
M(Missing_filename,"Missing filename (\"less --help\" for help)")
M(X_exists,"Warning: \"%s\" exists; Overwrite, Append, Don't log, or Quit?\40")
M(Overwrite,"Overwrite, Append, Don't log, or Quit? (Type \"O\", \"A\", \"D\" or \"Q\")\40")
M(Cannot_write_to_X,"Cannot write to \"%s\"")
M(cannot_quote_command,"cannot quote command")
M(LESSOPEN_pipe_is_not_supported,"LESSOPEN pipe is not supported")
M(LESSOPEN_ignored,"LESSOPEN ignored: must contain exactly one %%s")
M(LESSCLOSE_ignored,"LESSCLOSE ignored; must contain no more than 2 %%s")
M(is_a_directory,"is a directory")
M(is_not_a_regular_file,"is not a regular file (use -f to see it)")
M(skipping,"...skipping...")
M(Cannot_seek_to_end_of_file,"Cannot seek to end of file")
M(Cannot_seek_to_end_of_buffers,"Cannot seek to end of buffers")
M(Cannot_seek_to_beginning_of_file,"Cannot seek to beginning of file")
M(Cannot_seek_to_line_number_X,"Cannot seek to line number %n")
M(Determining_length_of_file,"Determining length of file")
M(Dont_know_length_of_file,"Don't know length of file")
M(Cannot_seek_to_that_file_position,"Cannot seek to that file position")
M(Calculating_line_numbers,"Calculating line numbers")
M(Line_numbers_turned_off,"Line numbers turned off")
M(press_RETURN,"(press RETURN)")
M(Cannot_seek_to_start_position,"Cannot seek to start position")
M(Cannot_create_pipe,"Cannot create pipe")
M(cannot_use_unicode_arguments,"WARNING: cannot use unicode arguments")
M(terminal_is_not_fully_functional,"WARNING: terminal is not fully functional")
M(No_filenames_allowed_with_t_option,"No filenames allowed with -t option")
M(Press_RETURN_to_continue,"Press RETURN to continue\40")
M(Cannot_allocate_memory,"Cannot allocate memory")
M(Invalid_mark_letter_X,"Invalid mark letter %c")
M(Mark_not_set,"Mark not set")
M(Cannot_find_line_number_X,"Cannot find line number %n")
M(Mark_not_in_current_file,"Mark not in current file")
M(log_file_support_is_not_available,"log file support is not available")
M(Input_is_not_a_pipe,"Input is not a pipe")
M(Log_file_is_already_in_use,"Log file is already in use")
M(No_log_file,"No log file")
M(Log_file_X,"Log file \"%s\"")
M(Invalid_fraction_in_X,"Invalid fraction in %s")
M(Position_target_at_screen_line_X,"Position target at screen line %d")
M(Position_target_at_screen_position_X,"Position target at screen position %s")
M(Horizontal_shift_X_columns,"Horizontal shift %d columns")
M(Horizontal_shift_X_of_screen_width,"Horizontal shift %s of screen width")
M(Cannot_use_lesskey_file_X,"Cannot use lesskey file \"%s\"")
M(Cannot_use_lesskey_source_file_X,"Cannot use lesskey source file \"%s\"")
M(Error_in_lesskey_content,"Error in lesskey content")
M(tags_support_is_not_available,"tags support is not available")
M(Tags_file_X,"Tags file \"%s\"")
M(Prompt_medium_X,"Prompt (medium): %s")
M(Prompt_long_X,"Prompt (long): %s")
M(Prompt_short_X,"Prompt (short): %s")
M(nothing,"(nothing)")
M(Print_after_medium_prompt_X,"Print after medium prompt: %s")
M(Print_after_long_prompt_X,"Print after long prompt: %s")
M(Print_after_short_prompt_X,"Print after short prompt: %s")
M(Autosave_actions_X,"Autosave actions: %s")
M(Invalid_color_string_X,"Invalid color string \"%s\"")
M(on,"on")
M(off,"off")
M(SGR_mode_is_X,"SGR mode is %s")
M(Invalid_color_specifier_X,"Invalid color specifier '%c'")
M(Set__use_color_before_changing_colors,"Set --use-color before changing colors")
M(Tab_stops,"Tab stops\40")
M(and_then,"and then\40")
M(every_X_spaces,"every %d spaces")
M(dq_must_be_followed_by_1_or_2_chars,"-\" must be followed by 1 or 2 chars")
M(quotes_X,"quotes %s")
M(cannot_set_rscroll_to_a_wide_character,"cannot set rscroll to a wide character")
M(rscroll_character_is_X,"rscroll character is %s")
M(Use_h_for_help,"Use \"h\" for help")
M(Search_match_shift_is_X,"Search match shift is %d")
M(Search_match_shift_is_X_of_screen_width,"Search match shift is %s of screen width")
M(Ignore_mouse_input,"Ignore mouse input")
M(Mouse_features_enabled_X,"Mouse features enabled: %s")
M(Line_number_width_must_not_be_larger_than_X,"Line number width must not be larger than %d")
M(Status_column_width_must_not_be_larger_than_X,"Status column width must not be larger than %d")
M(interrupt_character_is_X,"interrupt character is %s")
M(Header_is_X,"Header (lines,columns,line-number) is %s")
M(invalid_search_option_X,"invalid search option '%c'")
M(search_options_X,"search options: %s")
M(Search_does_not_include_header_lines_or_columns,"Search does not include header lines or columns")
M(Search_includes_header_columns_but_not_header_lines,"Search includes header columns but not header lines")
M(Search_includes_header_lines_but_not_header_columns,"Search includes header lines but not header columns")
M(Search_includes_header_lines_and_columns,"Search includes header lines and columns")
M(There_is_no_X_option_help,"There is no %s option (\"less --help\" for help)")
M(There_is_no__X_option_help,"There is no --%s option (\"less --help\" for help)")
M(The_X_option_should_not_be_followed_by_eq,"The --%s option should not be followed by =")
M(X_is_an_ambiguous_abbreviation,"--%s is an ambiguous abbreviation (\"less --help\" for help)")
M(No_such_option,"No such option")
M(Cannot_change_the_X_option,"Cannot change the %s option")
M(Cannot_query_the_X_option,"Cannot query the %s option")
M(Cannot_use_or_for_a_string_option,"Cannot use \"-+\" or \"-!\" for a string option")
M(Cant_use_for_a_numeric_option,"Can't use \"-!\" for a numeric option")
M(Value_is_required_after_X,"Value is required after %s")
M(Number_too_large_in_X,"Number too large in %s")
M(Negative_number_not_allowed_in_X,"Negative number not allowed in %s")
M(Number_is_required_after_X,"Number is required after %s")
M(Search_includes_displayed_screen,"Search includes displayed screen")
M(Search_skips_displayed_screen,"Search skips displayed screen")
M(Search_includes_all_of_displayed_screen,"Search includes all of displayed screen")
M(Max_buffer_space_per_file,"Max buffer space per file (K):\40")
M(Max_buffer_space_per_file_X,"Max buffer space per file: %dK")
M(Dont_automatically_allocate_buffers,"Don't automatically allocate buffers")
M(Automatically_allocate_buffers_when_needed,"Automatically allocate buffers when needed")
M(Repaint_by_scrolling_from_bottom_of_screen,"Repaint by scrolling from bottom of screen")
M(Repaint_by_painting_from_top_of_screen,"Repaint by painting from top of screen")
M(Assume_intelligent_terminal,"Assume intelligent terminal")
M(Assume_dumb_terminal,"Assume dumb terminal")
M(Dont_quit_at_end_of_file,"Don't quit at end-of-file")
M(Quit_at_end_of_file,"Quit at end-of-file")
M(Quit_immediately_at_end_of_file,"Quit immediately at end-of-file")
M(Open_only_regular_files,"Open only regular files")
M(Open_even_non_regular_files,"Open even non-regular files")
M(Dont_quit_if_end_of_file_on_first_screen,"Don't quit if end-of-file on first screen")
M(Quit_if_end_of_file_on_first_screen,"Quit if end-of-file on first screen")
M(Dont_highlight_search_matches,"Don't highlight search matches")
M(Highlight_matches_for_previous_search_only,"Highlight matches for previous search only")
M(Highlight_all_matches_for_previous_search_pattern,"Highlight all matches for previous search pattern")
M(Backwards_scroll_limit,"Backwards scroll limit:\40")
M(Backwards_scroll_limit_is_X_lines,"Backwards scroll limit is %d lines")
M(Case_is_significant_in_searches,"Case is significant in searches")
M(Ignore_case_in_searches,"Ignore case in searches")
M(Ignore_case_in_searches_and_in_patterns,"Ignore case in searches and in patterns")
M(Target_line,"Target line:\40")
M(Dont_display_a_status_column,"Don't display a status column")
M(Display_a_status_column,"Display a status column")
M(Interrupt_returns_to_prompt,"Interrupt (ctrl-C) returns to prompt")
M(Interrupt_exits_less,"Interrupt (ctrl-C) exits less")
M(Dont_use_the_LESSOPEN_filter,"Don't use the LESSOPEN filter")
M(Use_the_LESSOPEN_filter,"Use the LESSOPEN filter")
M(Short_prompt,"Short prompt")
M(Medium_prompt,"Medium prompt")
M(Long_prompt,"Long prompt")
M(Dont_use_line_numbers,"Don't use line numbers")
M(Use_line_numbers,"Use line numbers")
M(Constantly_display_line_numbers,"Constantly display line numbers")
M(Ring_the_bell_for_errors_AND_at_eof,"Ring the bell for errors AND at eof/bof")
M(Ring_the_bell_for_errors_but_not_at_eof,"Ring the bell for errors but not at eof/bof")
M(Never_ring_the_bell,"Never ring the bell")
M(Display_control_characters_as_caret,"Display control characters as ^X")
M(Display_control_characters_directly,"Display control characters directly (not recommended)")
M(Display_ANSI_sequences_directly,"Display ANSI sequences directly, other control characters as ^X")
M(Display_all_blank_lines,"Display all blank lines")
M(Squeeze_multiple_blank_lines,"Squeeze multiple blank lines")
M(Fold_long_lines,"Fold long lines")
M(Chop_long_lines,"Chop long lines")
M(Display_underlined_text_in_underline_mode,"Display underlined text in underline mode")
M(Backspaces_cause_overstrike,"Backspaces cause overstrike")
M(Print_backspace_as_caret,"Print backspace as ^H")
M(Dont_highlight_target_line,"Don't highlight target line")
M(Highlight_target_line,"Highlight target line")
M(Dont_highlight_first_unread_line,"Don't highlight first unread line")
M(Highlight_first_unread_line_after_forward_screen,"Highlight first unread line after forward-screen")
M(Highlight_first_unread_line_after_any_forward_movement,"Highlight first unread line after any forward movement")
M(Send_init_deinit_strings_to_terminal,"Send init/deinit strings to terminal")
M(Dont_use_init_deinit_strings,"Don't use init/deinit strings")
M(Forward_scroll_limit,"Forward scroll limit:\40")
M(Forward_scroll_limit_is_X_lines,"Forward scroll limit is %d lines")
M(Scroll_window_size,"Scroll window size:\40")
M(Scroll_window_size_is_X_lines,"Scroll window size is %d lines")
M(Dont_show_tildes_after_end_of_file,"Don't show tildes after end of file")
M(Show_tildes_after_end_of_file,"Show tildes after end of file")
M(Use_keypad_mode,"Use keypad mode")
M(Dont_use_keypad_mode,"Don't use keypad mode")
M(Use_new_bottom_of_screen_behavior,"Use new bottom of screen behavior")
M(Use_old_bottom_of_screen_behavior,"Use old bottom of screen behavior")
M(F_command_follows_file_descriptor,"F command follows file descriptor")
M(F_command_follows_file_name,"F command follows file name")
M(Dont_use_backslash_escaping_in_command_line_parameters,"Don't use backslash escaping in command line parameters")
M(Use_backslash_escaping_in_command_line_parameters,"Use backslash escaping in command line parameters")
M(Allow_duplicates_in_history_list,"Allow duplicates in history list")
M(Remove_duplicates_from_history_list,"Remove duplicates from history list")
M(Use_the_mouse_for_scrolling_vertically,"Use the mouse for scrolling vertically")
M(Use_the_mouse_for_scrolling_vertically_reverse,"Use the mouse for scrolling vertically (reverse)")
M(Normal_mouse_scroll_direction,"Normal mouse scroll direction")
M(Reverse_mouse_scroll_direction,"Reverse mouse scroll direction")
M(Lines_to_scroll_on_mouse_wheel,"Lines to scroll on mouse wheel:\40")
M(Scroll_X_lines_on_mouse_wheel,"Scroll %d line(s) on mouse wheel")
M(Dont_save_marks_in_history_file,"Don't save marks in history file")
M(Save_marks_in_history_file,"Save marks in history file")
M(Line_number_width,"Line number width:\40")
M(Line_number_width_is_X_chars,"Line number width is %d chars")
M(Status_column_width,"Status column width:\40")
M(Status_column_width_is_X_chars,"Status column width is %d chars")
M(Incremental_search_is_off,"Incremental search is off")
M(Incremental_search_is_on,"Incremental search is on")
M(Dont_use_color,"Don't use color")
M(Use_color,"Use color")
M(Dont_get_size_of_each_file,"Don't get size of each file")
M(Get_size_of_each_file,"Get size of each file")
M(Line_highlight_applies_to_text_only,"Line highlight applies to text only")
M(Line_highlight_applies_to_entire_width_of_screen,"Line highlight applies to entire width of screen")
M(Accept_pasted_input,"Accept pasted input")
M(Ignore_pasted_input,"Ignore pasted input")
M(Dont_stop_on_form_feed,"Don't stop on form feed")
M(Stop_on_form_feed,"Stop on form feed")
M(Stop_scrolling_at_end_of_file,"Stop scrolling at end of file")
M(Dont_stop_scrolling_at_end_of_file,"Don't stop scrolling at end of file")
M(Number_header_lines,"Number header lines")
M(Dont_number_header_lines,"Don't number header lines")
M(Dont_redraw_screen_when_quitting,"Don't redraw screen when quitting")
M(Redraw_last_screen_when_quitting,"Redraw last screen when quitting")
M(Search_options,"Search options:\40")
M(Dont_exit_F_command_when_input_closes,"Don't exit F command when input closes")
M(Exit_F_command_when_input_closes,"Exit F command when input closes")
M(Display_visual_bell,"Display visual bell")
M(Dont_display_visual_bell,"Don't display visual bell")
M(Lines_to_read_looking_for_modelines,"Lines to read looking for modelines:\40")
M(Read_X_lines_looking_for_modelines,"Read %d lines looking for modelines")
M(Wrap_lines_at_any_character,"Wrap lines at any character")
M(Wrap_lines_at_spaces,"Wrap lines at spaces")
M(Dont_show_error_message_if_preprocessor_fails,"Don't show error message if preprocessor fails")
M(Show_error_message_if_preprocessor_fails,"Show error message if preprocessor fails")
M(Backspace_handling_is_specified_by_the_U_option,"Backspace handling is specified by the -U option")
M(Display_underline_text_in_underline_mode,"Display underline text in underline mode")
M(Print_backspaces_as_caret,"Print backspaces as ^H")
M(Tab_handling_is_specified_by_the_U_option,"Tab handling is specified by the -U option")
M(Expand_tabs_to_spaces,"Expand tabs to spaces")
M(Print_tabs_as_caret,"Print tabs as ^I")
M(Carriage_return_handling_is_specified_by_the_U_option,"Carriage return handling is specified by the -U option")
M(Delete_carriage_return_before_newline,"Delete carriage return before newline")
M(Print_carriage_return_as_caret,"Print carriage return as ^M")
M(color_desc,"color desc:\40")
M(log_file,"log file:\40")
M(Log_file,"Log file:\40")
M(prompt,"prompt:\40")
M(tag,"tag:\40")
M(tags_file,"tags file:\40")
M(Tab_stops_,"Tab stops:\40")
M(quotes,"quotes:\40")
M(Horizontal_shift,"Horizontal shift:\40")
M(rscroll_character,"rscroll character:\40")
M(Mouse_features,"Mouse features:\40")
M(Header_lines,"Header lines:\40")
M(Warn_when_editing_a_file_opened_via_LESSOPEN,"Warn when editing a file opened via LESSOPEN")
M(Dont_warn_when_editing_a_file_opened_via_LESSOPEN,"Don't warn when editing a file opened via LESSOPEN")
M(interrupt_character,"interrupt character:\40")
M(Search_match_shift,"Search match shift:\40")
M(Autosave_actions,"Autosave actions:\40")
M(Print_after_prompt,"Print after prompt:\40")
M(Error_X,"Error %d")
M(cannot_open,"cannot open")
M(Invalid_pattern,"Invalid pattern")
M(No_previous_regular_expression,"No previous regular expression")
M(Nothing_to_search,"Nothing to search")
M(OSC_8_link_not_found,"OSC 8 link not found")
M(No_OSC8_link_selected,"No OSC8 link selected")
M(Cannot_find_OSC8_link,"Cannot find OSC8 link")
M(No_handler_for_X_link_type,"No handler for \"%s\" link type")
M(Cannot_quote_URI,"Cannot quote URI")
M(link_done,"link done")
M(Please_re_enter_search_pattern,"Please re-enter search pattern")
M(No_tags_file,"No tags file")
M(No_such_tag_in_tags_file,"No such tag in tags file")
M(unknown_tag_type,"unknown tag type")
M(Tag_not_found,"Tag not found")
M(invalid_escape_sequence,"invalid escape sequence \"%s\"")
M(invalid_operator_X_in_version_line,"invalid operator '%s' in #version line")
M(non_numeric_version_number_in_version_line,"non-numeric version number in #version line")
M(unknown_action_X,"unknown action: \"%s\"")
M(missing_action,"missing action")
M(missing_eq_in_variable_definition,"missing = in variable definition")
M(s,"s")
M(dot_d,".d")
M(neg_dot_d,"-.d")
M(d_comma,"d,")
+5
View File
@@ -0,0 +1,5 @@
# Internal lessmsg values which should never be changed.
s s
dot_d .d
neg_dot_d -.d
d_comma d,
+70 -36
View File
@@ -55,7 +55,6 @@ static size_t size_linebuf = 0; /* Size of line buffer (and attr buffer) */
static struct ansi_state *line_ansi = NULL;
static lbool ansi_in_line;
static int ff_starts_line;
static lbool hlink_in_line;
static int line_mark_attr;
static int cshift; /* Current left-shift of output line buffer */
public int hshift; /* Desired left-shift of output line buffer */
@@ -79,12 +78,14 @@ static constant char *mid_ansi_chars;
static constant char *osc_ansi_chars;
static int osc_ansi_allow_count;
static long *osc_ansi_allow;
static lbool in_osc8_link;
static lbool in_hilite;
static lbool clear_after_line;
static int attr_swidth(int a);
static int attr_ewidth(int a);
static int do_append(LWCHAR ch, constant char *rep, POSITION pos);
static void resend_last_ansi(POSITION pos);
extern int sigs;
extern int bs_mode;
@@ -137,6 +138,7 @@ static struct color_map color_map[] = {
{ AT_COLOR_SEARCH, "kG" },
{ AT_COLOR_TILDE, "-d" },
{ AT_COLOR_TARGET, "-u" },
{ AT_COLOR_OSC8, "-u" },
{ AT_COLOR_SUBSEARCH(1), "ky" },
{ AT_COLOR_SUBSEARCH(2), "wb" },
{ AT_COLOR_SUBSEARCH(3), "YM" },
@@ -293,8 +295,15 @@ public void prewind(lbool contig)
int ax;
xbuf_reset(&shifted_ansi);
if (contig && linebuf.prev_end != 0)
pshift(linebuf.prev_end);
if (contig)
{
if (linebuf.prev_end != 0)
pshift(linebuf.prev_end);
/* Don't reset in_osc8_link, since we may be in a wrapped OSC 8 sequence. */
} else
{
in_osc8_link = FALSE;
}
linebuf.print = 6; /* big enough for longest UTF-8 sequence */
linebuf.pfx_end = 0;
for (linebuf.end = 0; linebuf.end < linebuf.print; linebuf.end++)
@@ -315,7 +324,6 @@ public void prewind(lbool contig)
in_hilite = FALSE;
ansi_in_line = FALSE;
ff_starts_line = -1;
hlink_in_line = FALSE;
clear_after_line = FALSE;
line_mark_attr = 0;
line_pos = NULL_POSITION;
@@ -381,7 +389,7 @@ static void add_pfx(char ch, int attr)
/*
* Insert the status column and line number into the line buffer.
*/
public void plinestart(POSITION pos)
public void plinestart(POSITION line_pos, POSITION curr_pos)
{
LINENUM linenum = 0;
@@ -395,7 +403,7 @@ public void plinestart(POSITION pos)
* {{ Since forw_raw_line modifies linebuf, we must
* do this first, before storing anything in linebuf. }}
*/
linenum = find_linenum(pos);
linenum = find_linenum(line_pos);
}
/*
@@ -403,11 +411,11 @@ public void plinestart(POSITION pos)
*/
if (status_col || status_line)
{
char c = posmark(pos);
char c = posmark(curr_pos);
if (c != 0)
line_mark_attr = AT_HILITE|AT_COLOR_MARK;
else if (start_attnpos != NULL_POSITION &&
pos >= start_attnpos && pos <= end_attnpos)
line_pos >= start_attnpos && line_pos <= end_attnpos)
line_mark_attr = AT_HILITE|AT_COLOR_ATTN;
if (status_col)
{
@@ -691,7 +699,7 @@ public struct ansi_state * ansi_start(LWCHAR ch)
static lbool valid_osc_intro(char ch, lbool content)
{
constant char *p = strchr(osc_ansi_chars, ch);
if (p == NULL)
if (p == NULL || *p == '\0')
return FALSE;
return (!content || p[1] == '*');
}
@@ -763,7 +771,7 @@ static ansi_state ansi_step2(struct ansi_state *pansi, LWCHAR ch, lbool content)
return osc_return(pansi, (pansi->otype == 8) ? OSC8_PARAMS : OSC_STRING, ANSI_MID);
/* OSC is untyped */
if (IS_CSI_START(ch))
return osc_return(pansi, OSC_END_CSI, ANSI_MID);
return osc_return(pansi, OSC_STRING_CSI, ANSI_MID);
if (ch == '\7')
return osc_return(pansi, OSC_END, ANSI_END);
return osc_return(pansi, OSC_STRING, ANSI_MID);
@@ -779,16 +787,18 @@ static ansi_state ansi_step2(struct ansi_state *pansi, LWCHAR ch, lbool content)
if (IS_CSI_START(ch))
{
pansi->escs_in_seq++;
return osc_return(pansi, OSC_END_CSI, ANSI_MID);
return osc_return(pansi,
pansi->ostate == OSC8_URI ? OSC8_URI_CSI : OSC_STRING_CSI, ANSI_MID);
}
/* Stay in same ostate */
return ANSI_MID;
case OSC_END_CSI:
case OSC8_URI_CSI:
case OSC_STRING_CSI:
/* Got ESC of ST, expect backslash next. */
if (ch == '\\')
return osc_return(pansi, OSC_END, valid_osc_type(pansi->otype, content) ? ANSI_END : ANSI_ERR);
/* ESC not followed by backslash. */
return osc_return(pansi, OSC_STRING, ANSI_MID);
return osc_return(pansi, pansi->ostate == OSC8_URI_CSI ? OSC8_URI : OSC_STRING, ANSI_MID);
case OSC_END:
return ANSI_END;
case OSC8_NOT:
@@ -859,14 +869,21 @@ static int store_char(LWCHAR ch, int a, constant char *rep, POSITION pos)
#if HILITE_SEARCH
{
int matches;
int resend_last = 0;
int hl_attr = 0;
int link_attr = 0;
if (pos != NULL_POSITION && a != AT_ANSI)
{
hl_attr = is_hilited_attr(pos, pos+1, 0, &matches);
if (hl_attr == 0 && status_line)
hl_attr = line_mark_attr;
if (in_osc8_link)
{
if (hl_attr != 0)
link_attr = hl_attr | AT_UNDERLINE;
else
link_attr = use_color ? AT_COLOR_OSC8 : AT_UNDERLINE;
}
}
if (hl_attr)
{
@@ -880,24 +897,15 @@ static int store_char(LWCHAR ch, int a, constant char *rep, POSITION pos)
in_hilite = TRUE;
} else
{
a |= link_attr;
if (in_hilite)
{
/*
* This is the first non-hilited char after a hilite.
* Resend the last ANSI seq to restore color.
* Resend the last ANSI sequence(s) to restore color.
*/
resend_last = 1;
}
in_hilite = FALSE;
}
if (resend_last)
{
int ai;
for (ai = 0; ai < NUM_LAST_ANSIS; ai++)
{
int ax = (curr_last_ansi + ai) % NUM_LAST_ANSIS;
for (i = 0; i < last_ansis[ax].end; i++)
STORE_CHAR(last_ansis[ax].data[i], AT_ANSI, NULL, pos);
in_hilite = FALSE;
resend_last_ansi(pos);
}
}
}
@@ -1067,7 +1075,7 @@ static int flush_mbc_buf(POSITION pos)
int i;
for (i = 0; i < mbc_buf_index; i++)
if (store_prchar((LWCHAR) mbc_buf[i], pos))
if (store_prchar((LWCHAR) (unsigned char) mbc_buf[i], pos))
return mbc_buf_index - i;
return 0;
}
@@ -1212,25 +1220,35 @@ static void remove_ansi(void)
static int store_ansi(LWCHAR ch, constant char *rep, POSITION pos)
{
osc8_state prev_ostate = ansi_osc8_state(line_ansi);
switch (ansi_step2(line_ansi, ch, pos != NULL_POSITION))
{
case ANSI_MID:
case ANSI_MID: {
STORE_CHAR(ch, AT_ANSI, rep, pos);
switch (ansi_osc8_state(line_ansi))
{
case OSC_TYPENUM: case OSC_STRING: hlink_in_line = TRUE; break;
case OSC8_PARAMS: in_osc8_link = FALSE; break;
case OSC8_URI: if (prev_ostate == OSC8_URI) in_osc8_link = TRUE; break;
default: break;
}
xbuf_add_char(&last_ansi, (char) ch);
break;
break; }
case ANSI_END:
STORE_CHAR(ch, AT_ANSI, rep, pos);
/* Save the ANSI sequence, in case we need to resend it.
* But don't save OSC 8 sequences; they never need to be resent. */
if (ansi_osc8_state(line_ansi) == OSC_START)
{
xbuf_add_char(&last_ansi, (char) ch);
xbuf_set(&last_ansis[curr_last_ansi], &last_ansi);
curr_last_ansi = (curr_last_ansi + 1) % NUM_LAST_ANSIS;
}
xbuf_reset(&last_ansi);
ansi_done(line_ansi);
line_ansi = NULL;
xbuf_add_char(&last_ansi, (char) ch);
xbuf_set(&last_ansis[curr_last_ansi], &last_ansi);
xbuf_reset(&last_ansi);
curr_last_ansi = (curr_last_ansi + 1) % NUM_LAST_ANSIS;
/* After ending an OSC 8 sequence, resend the last SGR sequence to restore color. */
if (prev_ostate != OSC_START)
resend_last_ansi(pos);
break;
case ANSI_ERR:
remove_ansi();
@@ -1243,6 +1261,22 @@ static int store_ansi(LWCHAR ch, constant char *rep, POSITION pos)
return (0);
}
/*
* Resend the last ANSI sequence(s) to restore color after we have temporarily
* overridden the color with a hilite or OSC 8 link.
*/
static void resend_last_ansi(POSITION pos)
{
int ai;
for (ai = 0; ai < NUM_LAST_ANSIS; ai++)
{
int ax = (curr_last_ansi + ai) % NUM_LAST_ANSIS;
size_t i;
for (i = 0; i < last_ansis[ax].end; i++)
store_char(last_ansis[ax].data[i], AT_ANSI, NULL, pos);
}
}
static int store_bs(LWCHAR ch, constant char *rep, POSITION pos)
{
if (proc_backspace == OPT_ONPLUS || (bs_mode == BS_CONTROL && proc_backspace == OPT_OFF))
@@ -1409,7 +1443,7 @@ static void add_attr_normal(void)
if (ctldisp != OPT_ONPLUS || !is_ansi_end('m'))
return;
addstr_linebuf("\033[m", AT_ANSI, 0);
if (hlink_in_line) /* Don't send hyperlink clear if we know we don't need to. */
if (in_osc8_link) /* Don't send hyperlink clear if we know we don't need to. */
addstr_linebuf("\033]8;;\033\\", AT_ANSI, 0);
}
+3 -3
View File
@@ -205,7 +205,7 @@ public void add_lnum(LINENUM linenum, POSITION pos)
*/
static void longloopmessage(void)
{
ierror("Calculating line numbers", NULL_PARG);
ierror(LM(Calculating_line_numbers), NULL_PARG);
}
struct delayed_msg
@@ -261,7 +261,7 @@ static void abort_delayed_msg(struct delayed_msg *dmsg)
*/
screen_trashed();
linenums = 0;
error("Line numbers turned off", NULL_PARG);
error(LM(Line_numbers_turned_off), NULL_PARG);
}
/*
@@ -468,7 +468,7 @@ public LINENUM currline(int where)
static void detlenmessage(void)
{
ierror("Determining length of file", NULL_PARG);
ierror(LM(Determining_length_of_file), NULL_PARG);
}
/*
+218
View File
@@ -0,0 +1,218 @@
/*
* Copyright (C) 1984-2026 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information, see the README file.
*/
#include "less.h"
struct lmsg_sym { lessmsg_id id; constant char *sym; };
/*
* lmsgs is the array of all messages, indexed by lmsg id.
* Initialize it to the default messages.
* Individual message can be overridden by a custom lessmsg file.
*/
#undef M
#define M(sym,msg) msg,
static char *lmsgs[] = {
NULL, /* id 0 (LM_NULL) is not in lessmsg.inc */
#include "lessmsg.inc"
};
/*
* lmsg_syms is the map of symbol names to lmsg ids.
*/
#undef M
#define M(sym,msg) { LM_##sym, #sym },
static constant struct lmsg_sym lmsg_syms[] = {
#include "lessmsg.inc"
M(HELP,"")
};
/*
* For historical reasons the help file is stored separately rather than
* in the lmsgs array but it can still be overridden by a lessmsg file.
*/
public char *help_data;
public int size_help_data;
extern char helpdata[];
extern int size_helpdata;
/*
* Report an error in a lessmsg file.
*/
static void lmsg_error(constant char *err, constant char *lmsg_file, int linenum)
{
PARG parg[3];
parg[0].p_string = lmsg_file;
parg[1].p_int = linenum;
parg[2].p_string = err;
error("Error in lessmsg file %s line %d: %s", parg);
}
/*
* Return a numeric lmsg id given a symbolic name.
*/
static lessmsg_id lmsg_id(constant char *sym)
{
size_t i;
for (i = 0; i < countof(lmsg_syms); i++)
if (strcmp(sym, lmsg_syms[i].sym) == 0)
return lmsg_syms[i].id;
return LM_NULL;
}
/*
* Return a numeric char value from a string.
*/
static char numeric_char(char **pp, int radix, constant char *lmsg_file, int linenum)
{
constant int max_chars = (radix == 16) ? 2 : 3;
char nbuf[4]; /* max_chars+1 */
char *p = *pp;
int val;
strncpy(nbuf, p, max_chars);
nbuf[max_chars] = '\0';
val = lstrtoi(nbuf, &p, radix);
if (p == nbuf || val < 0 || val > 255)
{
lmsg_error("invalid numeric char value", lmsg_file, linenum);
return '?';
}
*pp += ptr_diff(p,nbuf);
return (char) val;
}
/*
* Process one character in a lessmsg file.
*/
static char * lmsg_char(char *mp, char *line, size_t line_size, FILE* fd, struct xbuffer *xbuf, constant char *lmsg_file, int *linenum)
{
if (*mp != '\\')
xbuf_add_char(xbuf, *mp++);
else
{
/* Handle backslash escape. */
switch (*++mp)
{
case '\0': break;
case 'n': xbuf_add_char(xbuf, '\n'); ++mp; break;
case 'r': xbuf_add_char(xbuf, '\r'); ++mp; break;
case 't': xbuf_add_char(xbuf, '\t'); ++mp; break;
case '\n': case '\r': /* continued on next line */
if (fgets(line, line_size, fd) != NULL)
{
++*linenum;
mp = line;
}
break;
case 'x': /* hex value */
++mp;
xbuf_add_char(xbuf, numeric_char(&mp, 16, lmsg_file, *linenum));
break;
default:
if (*mp >= '0' && *mp <= '7') /* octal value */
xbuf_add_char(xbuf, numeric_char(&mp, 8, lmsg_file, *linenum));
else /* literal char */
xbuf_add_char(xbuf, *mp++);
break;
}
}
return mp;
}
/*
* Process one line in a lessmsg file.
*/
static lbool lmsg_line(char *line, size_t line_size, FILE* fd, struct xbuffer *xbuf, constant char *lmsg_file, int *linenum)
{
lessmsg_id id;
char *msg;
char *mp;
char *sym = skipsp(line);
if (sym[0] == '\n' || sym[0] == '\r' || sym[0] == '#')
return TRUE; /* skip comments and blank lines */
msg = strchr(sym, ' ');
if (msg == NULL)
{
lmsg_error("missing space", lmsg_file, *linenum);
return FALSE;
}
*msg++ = '\0'; /* terminate symbol */
msg = skipsp(msg);
id = lmsg_id(sym);
if (id == 0)
{
lmsg_error("unknown lessmsg symbol", lmsg_file, *linenum);
return FALSE;
}
/* Copy the message string into xbuf. */
xbuf_reset(xbuf);
for (mp = msg; *mp != '\0' && *mp != '\n' && *mp != '\r'; )
mp = lmsg_char(mp, line, line_size, fd, xbuf, lmsg_file, linenum);
/* Store the message string in the table. */
msg = saven(xbuf_char_data(xbuf), xbuf->end);
if (id == LM_HELP)
{
help_data = msg;
size_help_data = xbuf->end;
} else
lmsgs[id] = msg;
return TRUE;
}
/*
* Initialize the lmsgs array from an lmsg file.
*/
public void lmsg_init(constant char *lmsg_file)
{
FILE *fd;
char line[512];
struct xbuffer xbuf;
int linenum;
PARG parg;
help_data = helpdata;
size_help_data = size_helpdata;
if (isnullenv(lmsg_file))
return;
fd = fopen(lmsg_file, "r");
if (fd == NULL)
{
parg.p_string = lmsg_file;
error("Cannot open lessmsg file %s", &parg);
return;
}
xbuf_init(&xbuf); /* for efficiency, init once here and reuse for each line */
linenum = 0;
while (fgets(line, sizeof(line), fd) != NULL)
{
++linenum;
lmsg_line(line, sizeof(line), fd, &xbuf, lmsg_file, &linenum);
}
xbuf_deinit(&xbuf);
fclose(fd);
}
/*
* Return the string associated with a numeric lmsg id.
*/
public constant char * lmsg(lessmsg_id id)
{
#if 1
if (id <= 0 || id >= countof(lmsgs))
{
PARG parg;
parg.p_int = (int) id;
error("invalid lessmsg id %d", &parg);
return NULL;
}
#endif
return lmsgs[id];
}
+24
View File
@@ -0,0 +1,24 @@
/*
* Copyright (C) 1984-2026 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information, see the README file.
*/
/*
* Define the LM_* symbols.
* */
#undef M
#define M(sym,msg) LM_##sym,
typedef enum lessmsg_id {
LM_NULL = 0,
#include "lessmsg.inc"
LM_HELP
} lessmsg_id;
/*
* Use LM(sym) to get the message string for the symbol LM_sym.
*/
#define LM(sym) lmsg(LM_##sym)
+65 -59
View File
@@ -95,15 +95,19 @@ public void lsystem(constant char *cmd, constant char *donemsg)
*/
term_deinit();
flush(); /* Make sure the deinit chars get out */
raw_mode(0);
raw_mode(FALSE);
#if MSDOS_COMPILER==WIN32C
close_getchr();
#endif
#if !MSDOS_COMPILER
/*
* Restore signals to their defaults.
* But not on Windows, since signals are received by background processes
* and a ctrl-C while running the child would kill this instance of less.
*/
init_signals(0);
init_signals(FALSE);
#endif
#if HAVE_DUP
/*
@@ -133,14 +137,19 @@ public void lsystem(constant char *cmd, constant char *donemsg)
p = save(shell);
else
{
char *esccmd = shell_quote(cmd);
if (esccmd != NULL)
constant char *copt = shell_coption();
if (copt == NULL)
p = save(cmd);
else
{
constant char *copt = shell_coption();
size_t len = strlen(shell) + strlen(esccmd) + strlen(copt) + 3;
p = (char *) ecalloc(len, sizeof(char));
SNPRINTF3(p, len, "%s %s %s", shell, copt, esccmd);
free(esccmd);
char *esccmd = shell_quote(cmd);
if (esccmd != NULL)
{
size_t len = strlen(shell) + strlen(esccmd) + strlen(copt) + 3;
p = (char *) ecalloc(len, sizeof(char));
SNPRINTF3(p, len, "%s %s %s", shell, copt, esccmd);
free(esccmd);
}
}
}
}
@@ -183,12 +192,15 @@ public void lsystem(constant char *cmd, constant char *donemsg)
#if MSDOS_COMPILER==WIN32C
open_getchr();
#endif
init_signals(1);
raw_mode(1);
#if !MSDOS_COMPILER
init_signals(TRUE);
#endif
raw_mode(TRUE);
if (donemsg != NULL)
{
putstr(donemsg);
putstr(" (press RETURN)");
putstr(" ");
putstr(LM(press_RETURN));
get_return();
putchr('\n');
flush();
@@ -234,51 +246,11 @@ public void lsystem(constant char *cmd, constant char *donemsg)
#endif
#if PIPEC
/*
* Pipe a section of the input file into the given shell command.
* The section to be piped is the section "between" the current
* position and the position marked by the given letter.
*
* If the mark is after the current screen, the section between
* the top line displayed and the mark is piped.
* If the mark is before the current screen, the section between
* the mark and the bottom line displayed is piped.
* If the mark is on the current screen, or if the mark is ".",
* the whole current screen is piped.
*/
public int pipe_mark(char c, constant char *cmd)
{
POSITION mpos, tpos, bpos;
/*
* mpos = the marked position.
* tpos = top of screen.
* bpos = bottom of screen.
*/
mpos = markpos(c);
if (mpos == NULL_POSITION)
return (-1);
tpos = position(TOP);
if (tpos == NULL_POSITION)
tpos = ch_zero();
bpos = position(BOTTOM);
if (c == '.')
return (pipe_data(cmd, tpos, bpos));
else if (mpos < tpos)
return (pipe_data(cmd, mpos, bpos));
else if (bpos == NULL_POSITION)
return (pipe_data(cmd, tpos, bpos));
else
return (pipe_data(cmd, tpos, mpos));
}
/*
* Create a pipe to the given shell command.
* Feed it the file contents between the positions spos and epos.
*/
public int pipe_data(constant char *cmd, POSITION spos, POSITION epos)
static int pipe_data(constant char *cmd, POSITION spos, POSITION epos)
{
FILE *f;
int c;
@@ -291,13 +263,13 @@ public int pipe_data(constant char *cmd, POSITION spos, POSITION epos)
*/
if (ch_seek(spos) != 0)
{
error("Cannot seek to start position", NULL_PARG);
error(LM(Cannot_seek_to_start_position), NULL_PARG);
return (-1);
}
if ((f = popen(cmd, "w")) == NULL)
{
error("Cannot create pipe", NULL_PARG);
error(LM(Cannot_create_pipe), NULL_PARG);
return (-1);
}
clear_bot();
@@ -307,8 +279,10 @@ public int pipe_data(constant char *cmd, POSITION spos, POSITION epos)
term_deinit();
flush();
raw_mode(0);
init_signals(0);
raw_mode(FALSE);
#if !MSDOS_COMPILER
init_signals(FALSE);
#endif
#if MSDOS_COMPILER==WIN32C
close_getchr();
#endif
@@ -349,8 +323,10 @@ public int pipe_data(constant char *cmd, POSITION spos, POSITION epos)
#if MSDOS_COMPILER==WIN32C
open_getchr();
#endif
init_signals(1);
raw_mode(1);
#if !MSDOS_COMPILER
init_signals(TRUE);
#endif
raw_mode(TRUE);
term_init();
screen_trashed();
#if defined(SIGWINCH) || defined(SIGWIND)
@@ -360,4 +336,34 @@ public int pipe_data(constant char *cmd, POSITION spos, POSITION epos)
return (0);
}
/*
* Pipe a section of the input file into the given shell command.
* If mpos2 is not NULL_POSITION, the section between
* mpos1 and mpos2 is piped.
* Otherwise, if mpos1 is before the current screen,
* the section between mpos1 and the bottom line displayed is piped.
* Otherwise, the section between the top line displayed and
* mpos1 is piped.
*/
public int pipe_pos(constant char *cmd, POSITION mpos1, POSITION mpos2)
{
POSITION tpos, bpos;
tpos = position(TOP);
if (tpos == NULL_POSITION)
tpos = ch_zero();
bpos = position(BOTTOM);
if (mpos2 != NULL_POSITION)
{
if (mpos1 < mpos2)
return pipe_data(cmd, mpos1, mpos2);
else
return pipe_data(cmd, mpos2, mpos1);
} else if (mpos1 < tpos)
return pipe_data(cmd, mpos1, bpos);
else
return pipe_data(cmd, tpos, mpos1);
}
#endif
+39 -27
View File
@@ -36,12 +36,12 @@ public struct scrpos initial_scrpos;
public POSITION start_attnpos = NULL_POSITION;
public POSITION end_attnpos = NULL_POSITION;
public int wscroll;
public constant char *progname;
static constant char *progname;
public lbool quitting = FALSE;
public lbool dohelp = FALSE;
public char * init_header = NULL;
public char * no_config = NULL;
static int secure_allow_features;
public constant char * no_config = NULL;
static unsigned int secure_allow_features;
#if LOGFILE
public int logfile = -1;
@@ -69,7 +69,7 @@ static wchar_t consoleTitle[256];
#endif
public lbool one_screen;
extern int less_is_more;
extern lbool less_is_more;
extern lbool missing_cap;
extern int know_dumb;
extern int quit_if_one_screen;
@@ -149,7 +149,7 @@ static void try_utf8_locale(int *pargc, constant char ***pargv)
goto cleanup;
bad_args:
error("WARNING: cannot use unicode arguments", NULL_PARG);
error(LM(cannot_use_unicode_arguments), NULL_PARG);
setlocale(LC_ALL, locale_orig);
cleanup:
@@ -191,6 +191,11 @@ static void init_secure(void)
if (!isnullenv(str))
secure_allow_features = parse_csl_bitmap(str,
security_features, countof(security_features), "LESSSECURE_ALLOW");
str = lgetenv("LESSSECURE_DISALLOW");
if (!isnullenv(str))
secure_allow_features &=~ parse_csl_bitmap(str,
security_features, countof(security_features), "LESSSECURE_DISALLOW");
#endif
}
@@ -209,7 +214,8 @@ int main(int argc, constant char *argv[])
lbool end_opts = FALSE;
lbool posixly_correct;
no_config = getenv("LESSNOCONFIG");
no_config = lgetenv("LESSNOCONFIG");
lmsg_init(lgetenv("LESSMSG"));
#if MSDOS_COMPILER==WIN32C && (defined(__MINGW32__) || defined(_MSC_VER))
if (GetACP() != CP_UTF8) /* not using a UTF-8 manifest */
@@ -226,14 +232,14 @@ int main(int argc, constant char *argv[])
init_secure();
#ifdef WIN32
if (getenv("HOME") == NULL)
if (lgetenv("HOME") == NULL)
{
/*
* If there is no HOME environment variable,
* try the concatenation of HOMEDRIVE + HOMEPATH.
*/
char *drive = getenv("HOMEDRIVE");
char *path = getenv("HOMEPATH");
constant char *drive = lgetenv("HOMEDRIVE");
constant char *path = lgetenv("HOMEPATH");
if (drive != NULL && path != NULL)
{
char *env = (char *) ecalloc(strlen(drive) +
@@ -268,7 +274,7 @@ int main(int argc, constant char *argv[])
*/
if (strcmp(last_component(progname), "more") == 0 &&
isnullenv(lgetenv("LESS_IS_MORE"))) {
less_is_more = 1;
less_is_more = TRUE;
scan_option("-fG", FALSE);
}
@@ -282,7 +288,9 @@ int main(int argc, constant char *argv[])
#define isoptstring(s) less_is_more ? (((s)[0] == '-') && (s)[1] != '\0') : \
(((s)[0] == '-' || (s)[0] == '+') && (s)[1] != '\0')
xbuf_init(&xfiles);
posixly_correct = (lgetenv("POSIXLY_CORRECT") != NULL);
/* Don't use lgetenv because POSIXLY_CORRECT is considered to be true
* if it is set to an empty string. */
posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
for (i = 0; i < argc; i++)
{
if (strcmp(argv[i], "--") == 0)
@@ -305,7 +313,7 @@ int main(int argc, constant char *argv[])
* following string, but there was no following string.
*/
nopendopt();
quit(QUIT_OK);
quit(QUIT_ERROR);
}
if (less_is_more)
@@ -379,21 +387,22 @@ int main(int argc, constant char *argv[])
* Just copy the input file(s) to output.
*/
SET_BINARY(1);
if (edit_first() == 0)
{
set_output(1, TRUE); /* write to stdout */
do {
cat_file();
} while (edit_next(1) == 0);
}
if (edit_first())
quit(QUIT_ERROR);
set_output(1, TRUE); /* write to stdout */
do {
cat_file();
} while (edit_next(1) == 0);
quit(QUIT_OK);
}
if (missing_cap && !know_dumb && !less_is_more)
error("WARNING: terminal is not fully functional", NULL_PARG);
error(LM(terminal_is_not_fully_functional), NULL_PARG);
open_getchr();
raw_mode(1);
init_signals(1);
init_signals(TRUE);
#if HAVE_TIME
less_start_time = get_time();
#endif
@@ -412,7 +421,7 @@ int main(int argc, constant char *argv[])
*/
if (nifile() > 0)
{
error("No filenames allowed with -t option", NULL_PARG);
error(LM(No_filenames_allowed_with_t_option), NULL_PARG);
quit(QUIT_ERROR);
}
findtag(tagoption);
@@ -458,12 +467,15 @@ int main(int argc, constant char *argv[])
* (file descriptor 2; see flush()).
* Before erasing the screen contents, wait for a keystroke.
*/
less_printf("Press RETURN to continue ", NULL_PARG);
PARG parg;
parg.p_string = LM(Press_RETURN_to_continue);
less_printf("%s", &parg);
get_return();
putchr('\n');
}
set_output(1, FALSE);
#if MSDOS_COMPILER
raw_mode(TRUE);
term_init();
#endif
commands();
@@ -491,7 +503,7 @@ public char * save(constant char *s)
public void out_of_memory(void)
{
error("Cannot allocate memory", NULL_PARG);
error(LM(Cannot_allocate_memory), NULL_PARG);
quit(QUIT_ERROR);
}
@@ -592,7 +604,7 @@ public void quit(int status)
}
edit((char*)NULL);
save_cmdhist();
raw_mode(0);
raw_mode(FALSE);
#if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC
/*
* If we don't close 2, we get some garbage from
@@ -612,7 +624,7 @@ public void quit(int status)
/*
* Are all the features in the features mask allowed by security?
*/
public int secure_allow(int features)
public lbool secure_allow(unsigned int features)
{
return ((secure_allow_features & features) == features);
}
+23 -17
View File
@@ -146,7 +146,7 @@ static struct mark * getumark(char c)
{
PARG parg;
parg.p_char = (char) c;
error("Invalid mark letter %c", &parg);
error(LM(Invalid_mark_letter_X), &parg);
return NULL;
}
return &marks[index];
@@ -178,26 +178,34 @@ static struct mark * getmark(char c)
*/
if (ch_end_seek())
{
error("Cannot seek to end of file", NULL_PARG);
error(LM(Cannot_seek_to_end_of_file), NULL_PARG);
return (NULL);
}
m = &sm;
pos = ch_tell();
if (pos == NULL_POSITION)
return (NULL);
pos = back_line(pos, NULL);
pos = back_line(pos, NULL, NULL);
if (pos == NULL_POSITION)
return (NULL);
cmark(m, curr_ifile, pos, sc_height-1);
break;
case '.':
case '.': case ':':
/*
* Current position in the current file.
* Top line on screen.
*/
m = &sm;
get_scrpos(&m->m_scrpos, TOP);
cmark(m, curr_ifile, m->m_scrpos.pos, m->m_scrpos.ln);
break;
case ';':
/*
* Bottom line on screen.
*/
m = &sm;
get_scrpos(&m->m_scrpos, BOTTOM);
cmark(m, curr_ifile, m->m_scrpos.pos, m->m_scrpos.ln);
break;
case '\'':
/*
* The "last mark".
@@ -213,7 +221,7 @@ static struct mark * getmark(char c)
break;
if (!mark_is_set(m))
{
error("Mark not set", NULL_PARG);
error(LM(Mark_not_set), NULL_PARG);
return (NULL);
}
break;
@@ -257,7 +265,7 @@ public void setmark(char c, int where, LINENUM linenum)
{
PARG parg;
parg.p_linenum = linenum;
error("Cannot find line number %n", &parg);
error(LM(Cannot_find_line_number_X), &parg);
return;
}
get_scrpos_pos(&scrpos, where, pos);
@@ -321,8 +329,6 @@ public void gomark(char c, int sline)
m = getmark(c);
if (m == NULL)
return;
if (sline != 0)
m->m_scrpos.ln = sline;
/*
* If we're trying to go to the lastmark and
@@ -345,8 +351,9 @@ public void gomark(char c, int sline)
if (edit_ifile(m->m_ifile))
return;
}
jump_loc(scrpos.pos, scrpos.ln);
if (sline == 0)
sline = m->m_scrpos.ln;
jump_loc(scrpos.pos, sline);
}
/*
@@ -366,7 +373,7 @@ public POSITION markpos(char c)
if (m->m_ifile != curr_ifile)
{
error("Mark not in current file", NULL_PARG);
error(LM(Mark_not_in_current_file), NULL_PARG);
return (NULL_POSITION);
}
return (m->m_scrpos.pos);
@@ -485,22 +492,21 @@ public void restore_mark(constant char *line)
int ln;
POSITION pos;
#define skip_whitespace while (*line == ' ') line++
if (*line++ != 'm')
return;
skip_whitespace;
line = skipspc(line);
index = mark_index(*line++);
if (index < 0)
return;
skip_whitespace;
line = skipspc(line);
ln = lstrtoic(line, &line, 10);
if (ln < 0)
return;
skip_whitespace;
line = skipspc(line);
pos = lstrtoposc(line, &line, 10);
if (pos < 0)
return;
skip_whitespace;
line = skipspc(line);
/* Save in both active marks table and file_marks table. */
cmarkf(&marks[index], NULL_IFILE, pos, ln, line);
cmarkf(&file_marks[index], NULL_IFILE, pos, ln, line);
+93 -64
View File
@@ -58,7 +58,7 @@ extern int emouse;
extern int mouse_reverse;
extern int xmouse;
extern int wheel_lines;
extern int less_is_more;
extern lbool less_is_more;
extern int linenum_width;
extern int status_col_width;
extern int use_color;
@@ -73,6 +73,7 @@ extern int tabdefault;
extern int no_paste;
extern int hilite_target;
extern char intr_char;
extern int utf_mode;
extern int nosearch_header_lines;
extern int nosearch_header_cols;
extern POSITION header_start_pos;
@@ -122,7 +123,7 @@ public void opt_o(int type, constant char *s)
if (!secure_allow(SF_LOGFILE))
{
error("log file support is not available", NULL_PARG);
error(LM(log_file_support_is_not_available), NULL_PARG);
return;
}
switch (type)
@@ -133,12 +134,12 @@ public void opt_o(int type, constant char *s)
case TOGGLE:
if (ch_getflags() & CH_CANSEEK)
{
error("Input is not a pipe", NULL_PARG);
error(LM(Input_is_not_a_pipe), NULL_PARG);
return;
}
if (logfile >= 0)
{
error("Log file is already in use", NULL_PARG);
error(LM(Log_file_is_already_in_use), NULL_PARG);
return;
}
s = skipspc(s);
@@ -152,11 +153,11 @@ public void opt_o(int type, constant char *s)
break;
case QUERY:
if (logfile < 0)
error("No log file", NULL_PARG);
error(LM(No_log_file), NULL_PARG);
else
{
parg.p_string = namelogfile;
error("Log file \"%s\"", &parg);
error(LM(Log_file_X), &parg);
}
break;
}
@@ -183,7 +184,7 @@ static void toggle_fraction(int *num, long *frac, constant char *s, constant cha
{
PARG parg;
parg.p_string = printopt;
error("Invalid fraction in %s", &parg);
error(LM(Invalid_fraction_in_X), &parg);
return;
}
} else
@@ -231,7 +232,7 @@ public void opt_j(int type, constant char *s)
break;
case QUERY:
query_fraction(jump_sline_arg, jump_sline_fraction,
"Position target at screen line %d", "Position target at screen position %s");
LM(Position_target_at_screen_line_X), LM(Position_target_at_screen_position_X));
break;
}
}
@@ -267,7 +268,7 @@ public void opt_shift(int type, constant char *s)
break;
case QUERY:
query_fraction(shift_count, shift_count_fraction,
"Horizontal shift %d columns", "Horizontal shift %s of screen width");
LM(Horizontal_shift_X_columns), LM(Horizontal_shift_X_of_screen_width));
break;
}
}
@@ -287,10 +288,10 @@ public void opt_k(int type, constant char *s)
switch (type)
{
case INIT:
if (lesskey(s, 0))
if (lesskey(s, FALSE))
{
parg.p_string = s;
error("Cannot use lesskey file \"%s\"", &parg);
error(LM(Cannot_use_lesskey_file_X), &parg);
}
break;
}
@@ -304,10 +305,10 @@ public void opt_ks(int type, constant char *s)
switch (type)
{
case INIT:
if (lesskey_src(s, 0))
if (lesskey_src(s, FALSE))
{
parg.p_string = s;
error("Cannot use lesskey source file \"%s\"", &parg);
error(LM(Cannot_use_lesskey_source_file_X), &parg);
}
break;
}
@@ -318,9 +319,9 @@ public void opt_kc(int type, constant char *s)
switch (type)
{
case INIT:
if (lesskey_content(s, 0))
if (lesskey_content(s, FALSE))
{
error("Error in lesskey content", NULL_PARG);
error(LM(Error_in_lesskey_content), NULL_PARG);
}
break;
}
@@ -334,6 +335,7 @@ public void opt_kc(int type, constant char *s)
*/
public void opt__S(int type, constant char *s)
{
(void)s;
switch (type)
{
case TOGGLE:
@@ -360,7 +362,7 @@ public void opt_t(int type, constant char *s)
case TOGGLE:
if (!secure_allow(SF_TAGS))
{
error("tags support is not available", NULL_PARG);
error(LM(tags_support_is_not_available), NULL_PARG);
break;
}
findtag(skipspc(s));
@@ -404,7 +406,7 @@ public void opt__T(int type, constant char *s)
break;
case QUERY:
parg.p_string = tags;
error("Tags file \"%s\"", &parg);
error(LM(Tags_file_X), &parg);
break;
}
}
@@ -475,9 +477,9 @@ public void opt__P(int type, constant char *s)
parg.p_string = prproto[pr_type];
switch (pr_type)
{
case PR_MEDIUM: error("Prompt (medium): %s", &parg); break;
case PR_LONG: error("Prompt (long): %s", &parg); break;
default: error("Prompt (short): %s", &parg); break;
case PR_MEDIUM: error(LM(Prompt_medium_X), &parg); break;
case PR_LONG: error(LM(Prompt_long_X), &parg); break;
default: error(LM(Prompt_short_X), &parg); break;
}
break;
}
@@ -509,12 +511,12 @@ public void opt_end_prompt(int type, constant char *s)
case QUERY:
parg.p_string = eprproto[pr_type];
if (parg.p_string == NULL)
parg.p_string = "(nothing)";
parg.p_string = LM(nothing);
switch (pr_type)
{
case PR_MEDIUM: error("Print after medium prompt: %s", &parg); break;
case PR_LONG: error("Print after long prompt: %s", &parg); break;
default: error("Print after short prompt: %s", &parg); break;
case PR_MEDIUM: error(LM(Print_after_medium_prompt_X), &parg); break;
case PR_LONG: error(LM(Print_after_long_prompt_X), &parg); break;
default: error(LM(Print_after_short_prompt_X), &parg); break;
}
break;
}
@@ -539,7 +541,7 @@ public void opt_autosave(int type, constant char *s)
break;
case QUERY:
parg.p_string = (autosave != NULL) ? autosave : "-";
error("Autosave actions: %s", &parg);
error(LM(Autosave_actions_X), &parg);
break;
}
}
@@ -550,6 +552,7 @@ public void opt_autosave(int type, constant char *s)
/*ARGSUSED*/
public void opt_b(int type, constant char *s)
{
(void)s;
switch (type)
{
case INIT:
@@ -570,6 +573,7 @@ public void opt_b(int type, constant char *s)
/*ARGSUSED*/
public void opt_i(int type, constant char *s)
{
(void)s;
switch (type)
{
case TOGGLE:
@@ -587,6 +591,7 @@ public void opt_i(int type, constant char *s)
/*ARGSUSED*/
public void opt__V(int type, constant char *s)
{
(void)s;
switch (type)
{
case TOGGLE:
@@ -635,7 +640,7 @@ static void colordesc(constant char *s, int *fg_color, int *bg_color, int *dattr
{
PARG p;
p.p_string = s;
error("Invalid color string \"%s\"", &p);
error(LM(Invalid_color_string_X), &p);
} else
{
*fg_color = fg;
@@ -662,6 +667,7 @@ static int color_from_namechar(char namechar)
case 'J': return AT_COLOR_TARGET;
case 'M': return AT_COLOR_MARK;
case 'N': return AT_COLOR_LINENUM;
case 'O': return AT_COLOR_OSC8;
case 'P': return AT_COLOR_PROMPT;
case 'R': return AT_COLOR_RSCROLL;
case 'S': return AT_COLOR_SEARCH;
@@ -698,8 +704,8 @@ public void opt_D(int type, constant char *s)
sgr_mode = !sgr_mode;
if (type == TOGGLE)
{
p.p_string = (sgr_mode) ? "on" : "off";
error("SGR mode is %s", &p);
p.p_string = (sgr_mode) ? LM(on) : LM(off);
error(LM(SGR_mode_is_X), &p);
}
break;
}
@@ -708,12 +714,12 @@ public void opt_D(int type, constant char *s)
if (attr < 0)
{
p.p_char = s[0];
error("Invalid color specifier '%c'", &p);
error(LM(Invalid_color_specifier_X), &p);
return;
}
if (!use_color && (attr & AT_COLOR))
{
error("Set --use-color before changing colors", NULL_PARG);
error(LM(Set__use_color_before_changing_colors), NULL_PARG);
return;
}
s++;
@@ -749,7 +755,7 @@ public void opt_D(int type, constant char *s)
if (set_color_map(attr, s) < 0)
{
p.p_string = s;
error("Invalid color string \"%s\"", &p);
error(LM(Invalid_color_string_X), &p);
return;
}
break;
@@ -792,7 +798,8 @@ public void set_tabs(constant char *s, size_t len)
*/
public void opt_x(int type, constant char *s)
{
char msg[60+((INT_STRLEN_BOUND(int)+1)*TABSTOP_MAX)];
size_t msglen;
char *msg;
int i;
PARG p;
@@ -803,7 +810,9 @@ public void opt_x(int type, constant char *s)
set_tabs(s, strlen(s));
break;
case QUERY:
strcpy(msg, "Tab stops ");
msglen = strlen(LM(Tab_stops)) + strlen(LM(and_then)) + strlen(LM(every_X_spaces)) + ((INT_STRLEN_BOUND(int)+1)*ntabstops) + 2;
msg = ecalloc(msglen, sizeof(char));
strcpy(msg, LM(Tab_stops));
if (ntabstops > 2)
{
for (i = 1; i < ntabstops; i++)
@@ -812,12 +821,13 @@ public void opt_x(int type, constant char *s)
strcat(msg, ",");
sprintf(msg+strlen(msg), "%d", tabstops[i]);
}
sprintf(msg+strlen(msg), " and then ");
strcat(msg, " ");
strcat(msg, LM(and_then));
}
sprintf(msg+strlen(msg), "every %d spaces",
tabdefault);
sprintf(msg+strlen(msg), LM(every_X_spaces), tabdefault);
p.p_string = msg;
error("%s", &p);
free(msg);
break;
}
}
@@ -842,7 +852,7 @@ public void opt_quote(int type, constant char *s)
}
if (s[1] != '\0' && s[2] != '\0')
{
error("-\" must be followed by 1 or 2 chars", NULL_PARG);
error(LM(dq_must_be_followed_by_1_or_2_chars), NULL_PARG);
return;
}
openquote = s[0];
@@ -856,7 +866,7 @@ public void opt_quote(int type, constant char *s)
buf[1] = closequote;
buf[2] = '\0';
parg.p_string = buf;
error("quotes %s", &parg);
error(LM(quotes_X), &parg);
break;
}
}
@@ -888,15 +898,15 @@ public void opt_rscroll(int type, constant char *s)
{
LWCHAR ch = step_charc(&fmt, +1, fmt+strlen(fmt));
if (pwidth(ch, rscroll_attr, 0, 0) > 1)
error("cannot set rscroll to a wide character", NULL_PARG);
error(LM(cannot_set_rscroll_to_a_wide_character), NULL_PARG);
else
rscroll_char = ch;
}
}
break; }
case QUERY: {
p.p_string = rscroll_char ? prchar((LWCHAR) rscroll_char) : "-";
error("rscroll character is %s", &p);
p.p_string = rscroll_char == 0 ? "-" : utf_mode ? prutfchar(rscroll_char) : prchar(rscroll_char);
error(LM(rscroll_character_is_X), &p);
break; }
}
}
@@ -908,11 +918,12 @@ public void opt_rscroll(int type, constant char *s)
/*ARGSUSED*/
public void opt_query(int type, constant char *s)
{
(void)s;
switch (type)
{
case QUERY:
case TOGGLE:
error("Use \"h\" for help", NULL_PARG);
error(LM(Use_h_for_help), NULL_PARG);
break;
case INIT:
dohelp = TRUE;
@@ -931,7 +942,7 @@ public void opt_match_shift(int type, constant char *s)
break;
case QUERY:
query_fraction(match_shift, match_shift_fraction,
"Search match shift is %d", "Search match shift is %s of screen width");
LM(Search_match_shift_is_X), LM(Search_match_shift_is_X_of_screen_width));
break;
}
}
@@ -1008,9 +1019,9 @@ public void opt_emouse(int type, constant char *s)
*bp = '\0';
parg.p_string = buf;
if (buf[0] == '\0')
error("Ignore mouse input", NULL_PARG);
error(LM(Ignore_mouse_input), NULL_PARG);
else
error("Mouse features enabled: %s", &parg);
error(LM(Mouse_features_enabled_X), &parg);
break; }
}
}
@@ -1021,23 +1032,32 @@ public void opt_emouse(int type, constant char *s)
/*ARGSUSED*/
public void opt_mouse(int type, constant char *s)
{
(void)s;
switch (type)
{
case INIT:
case TOGGLE:
switch (xmouse)
if (emouse == 0)
{
case OPT_OFF:
opt_emouse(type, "-");
break;
case OPT_ON:
case OPT_ONPLUS:
opt_emouse(type, "vmove,click");
mouse_reverse = (xmouse == OPT_ONPLUS);
break;
} else
{
opt_emouse(type, "-");
xmouse = 0;
}
break;
case QUERY:
if (type == INIT)
break;
/*FALLTHRU*/
case QUERY: /* odesc[] entries are NULL so we can do the QUERY here */
if (emouse == (EMOUSE_VSCROLL|EMOUSE_VDRAG|EMOUSE_LCLICK|EMOUSE_RCLICK))
{
if (mouse_reverse)
error(LM(Use_the_mouse_for_scrolling_vertically_reverse), NULL_PARG);
else
error(LM(Use_the_mouse_for_scrolling_vertically), NULL_PARG);
} else
opt_emouse(QUERY, NULL);
break;
}
}
@@ -1048,6 +1068,7 @@ public void opt_mouse(int type, constant char *s)
/*ARGSUSED*/
public void opt_wheel_lines(int type, constant char *s)
{
(void)s;
switch (type)
{
case INIT:
@@ -1068,6 +1089,7 @@ public void opt_linenum_width(int type, constant char *s)
{
PARG parg;
(void)s;
switch (type)
{
case INIT:
@@ -1075,7 +1097,7 @@ public void opt_linenum_width(int type, constant char *s)
if (linenum_width > MAX_LINENUM_WIDTH)
{
parg.p_int = MAX_LINENUM_WIDTH;
error("Line number width must not be larger than %d", &parg);
error(LM(Line_number_width_must_not_be_larger_than_X), &parg);
linenum_width = MIN_LINENUM_WIDTH;
}
break;
@@ -1092,6 +1114,7 @@ public void opt_status_col_width(int type, constant char *s)
{
PARG parg;
(void)s;
switch (type)
{
case INIT:
@@ -1099,7 +1122,7 @@ public void opt_status_col_width(int type, constant char *s)
if (status_col_width > MAX_STATUSCOL_WIDTH)
{
parg.p_int = MAX_STATUSCOL_WIDTH;
error("Status column width must not be larger than %d", &parg);
error(LM(Status_column_width_must_not_be_larger_than_X), &parg);
status_col_width = 2;
}
break;
@@ -1114,6 +1137,7 @@ public void opt_status_col_width(int type, constant char *s)
/*ARGSUSED*/
public void opt_filesize(int type, constant char *s)
{
(void)s;
switch (type)
{
case INIT:
@@ -1161,7 +1185,7 @@ public void opt_intr(int type, constant char *s)
break;
case QUERY: {
p.p_string = prchar((LWCHAR) intr_char);
error("interrupt character is %s", &p);
error(LM(interrupt_character_is_X), &p);
break; }
}
}
@@ -1247,7 +1271,7 @@ public void opt_header(int type, constant char *s)
PARG parg;
SNPRINTF3(buf, sizeof(buf), "%ld,%ld,%ld", (long) header_lines, (long) header_cols, (long) find_linenum(header_start_pos));
parg.p_string = buf;
error("Header (lines,columns,line-number) is %s", &parg);
error(LM(Header_is_X), &parg);
break; }
}
}
@@ -1258,6 +1282,7 @@ public void opt_header(int type, constant char *s)
/*ARGSUSED*/
public void opt_hilite_target(int type, constant char *s)
{
(void)s;
switch (type)
{
case INIT:
@@ -1306,7 +1331,7 @@ public void opt_search_type(int type, constant char *s)
break;
}
parg.p_char = *s;
error("invalid search option '%c'", &parg);
error(LM(invalid_search_option_X), &parg);
return;
}
}
@@ -1327,7 +1352,7 @@ public void opt_search_type(int type, constant char *s)
*bp++ = '-';
*bp = '\0';
parg.p_string = buf;
error("search options: %s", &parg);
error(LM(search_options_X), &parg);
break;
}
}
@@ -1348,37 +1373,41 @@ static void do_nosearch_headers(int type, int no_header_lines, int no_header_col
/*FALLTHRU*/
case QUERY:
if (nosearch_header_lines && nosearch_header_cols)
error("Search does not include header lines or columns", NULL_PARG);
error(LM(Search_does_not_include_header_lines_or_columns), NULL_PARG);
else if (nosearch_header_lines)
error("Search includes header columns but not header lines", NULL_PARG);
error(LM(Search_includes_header_columns_but_not_header_lines), NULL_PARG);
else if (nosearch_header_cols)
error("Search includes header lines but not header columns", NULL_PARG);
error(LM(Search_includes_header_lines_but_not_header_columns), NULL_PARG);
else
error("Search includes header lines and columns", NULL_PARG);
error(LM(Search_includes_header_lines_and_columns), NULL_PARG);
}
}
/*ARGSUSED*/
public void opt_nosearch_headers(int type, constant char *s)
{
(void)s;
do_nosearch_headers(type, 1, 1);
}
/*ARGSUSED*/
public void opt_nosearch_header_lines(int type, constant char *s)
{
(void)s;
do_nosearch_headers(type, 1, 0);
}
/*ARGSUSED*/
public void opt_nosearch_header_cols(int type, constant char *s)
{
(void)s;
do_nosearch_headers(type, 0, 1);
}
/*ARGSUSED*/
public void opt_no_paste(int type, constant char *s)
{
(void)s;
switch (type)
{
case TOGGLE:
+31 -28
View File
@@ -26,7 +26,7 @@ public lbool plusoption = FALSE;
static constant char *optstring(constant char *s, char **p_str, constant char *printopt, constant char *validchars);
static int flip_triple(int val, lbool lc);
extern int less_is_more;
extern lbool less_is_more;
extern int quit_at_eof;
extern char *every_first_cmd;
extern int opt_use_backslash;
@@ -186,7 +186,7 @@ public void scan_option(constant char *s, lbool is_env)
if (o == NULL)
{
parg.p_string = printopt;
error("There is no %s option (\"less --help\" for help)", &parg);
error(LM(There_is_no_X_option_help), &parg);
return;
}
} else
@@ -213,8 +213,7 @@ public void scan_option(constant char *s, lbool is_env)
(o->otype & OTYPE) != O_NUMBER)
{
parg.p_string = printopt;
error("The --%s option should not be followed by =",
&parg);
error(LM(The_X_option_should_not_be_followed_by_eq), &parg);
return;
}
s++;
@@ -230,9 +229,9 @@ public void scan_option(constant char *s, lbool is_env)
{
parg.p_string = printopt;
if (ambig)
error("--%s is an ambiguous abbreviation (\"less --help\" for help)", &parg);
error(LM(X_is_an_ambiguous_abbreviation), &parg);
else
error("There is no --%s option (\"less --help\" for help)", &parg);
error(LM(There_is_no__X_option_help), &parg);
return;
}
}
@@ -327,21 +326,21 @@ public lbool toggle_option(struct loption *o, lbool lower, constant char *s, int
if (o == NULL)
{
error("No such option", NULL_PARG);
error(LM(No_such_option), NULL_PARG);
return FALSE;
}
if (how_toggle == OPT_TOGGLE && (o->otype & O_NO_TOGGLE))
{
parg.p_string = opt_desc(o);
error("Cannot change the %s option", &parg);
error(LM(Cannot_change_the_X_option), &parg);
return FALSE;
}
if (how_toggle == OPT_NO_TOGGLE && (o->otype & O_NO_QUERY))
{
parg.p_string = opt_desc(o);
error("Cannot query the %s option", &parg);
error(LM(Cannot_query_the_X_option), &parg);
return FALSE;
}
@@ -425,8 +424,7 @@ public lbool toggle_option(struct loption *o, lbool lower, constant char *s, int
{
case OPT_SET:
case OPT_UNSET:
error("Cannot use \"-+\" or \"-!\" for a string option",
NULL_PARG);
error(LM(Cannot_use_or_for_a_string_option), NULL_PARG);
return FALSE;
}
break;
@@ -444,8 +442,7 @@ public lbool toggle_option(struct loption *o, lbool lower, constant char *s, int
*(o->ovar) = o->odefault;
break;
case OPT_SET:
error("Can't use \"-!\" for a numeric option",
NULL_PARG);
error(LM(Cant_use_for_a_numeric_option), NULL_PARG);
return FALSE;
}
break;
@@ -476,7 +473,7 @@ public lbool toggle_option(struct loption *o, lbool lower, constant char *s, int
/*
* Print the odesc message.
*/
if (o->ovar != NULL)
if (o->ovar != NULL && o->odesc[*(o->ovar)] != NULL)
error(o->odesc[*(o->ovar)], NULL_PARG);
break;
case O_NUMBER:
@@ -484,8 +481,11 @@ public lbool toggle_option(struct loption *o, lbool lower, constant char *s, int
* The message is in odesc[1] and has a %d for
* the value of the variable.
*/
parg.p_int = *(o->ovar);
error(o->odesc[1], &parg);
if (o->odesc[1] != NULL)
{
parg.p_int = *(o->ovar);
error(o->odesc[1], &parg);
}
break;
case O_STRING:
if (how_toggle != OPT_NO_TOGGLE && o->ofunc != NULL)
@@ -543,7 +543,7 @@ public constant char * opt_toggle_disallowed(int c)
{
case 'o':
if (ch_getflags() & CH_CANSEEK)
return "Input is not a pipe";
return LM(Input_is_not_a_pipe);
break;
}
return NULL;
@@ -568,7 +568,7 @@ static void nostring(constant char *printopt)
{
PARG parg;
parg.p_string = printopt;
error("Value is required after %s", &parg);
error(LM(Value_is_required_after_X), &parg);
}
/*
@@ -668,9 +668,9 @@ static lbool num_error(constant char *printopt, num_error_type error_type)
PARG parg;
switch (error_type)
{
case NUM_ERR_OVERFLOW: msg = "Number too large in %s"; break;
case NUM_ERR_NEG: msg = "Negative number not allowed in %s"; break;
default: msg = "Number is required after %s"; break;
case NUM_ERR_OVERFLOW: msg = LM(Number_too_large_in_X); break;
case NUM_ERR_NEG: msg = LM(Negative_number_not_allowed_in_X); break;
default: msg = LM(Number_is_required_after_X); break;
}
parg.p_string = printopt;
error(msg, &parg);
@@ -753,6 +753,7 @@ public lbool getfraction(constant char **sp, mutable long *p_frac)
*/
public void init_unsupport(void)
{
PARG parg;
constant char *s = lgetenv("LESS_UNSUPPORT");
if (isnullenv(s))
return;
@@ -761,17 +762,19 @@ public void init_unsupport(void)
struct loption *opt;
s = skipspc(s);
if (*s == '\0') break;
if (*s == '-' && *++s == '\0') break;
if (*s == '-') /* long option name */
parg.p_string = s;
if (s[0] == '-' && s[1] == '-') /* long option name */
{
++s;
opt = findopt_name(&s, NULL, NULL);
s += 2;
opt = (*s == '\0') ? NULL : findopt_name(&s, NULL, NULL);
} else /* short (single-char) option */
{
opt = findopt(*s);
if (opt != NULL) ++s;
if (*s == '-') s++;
opt = (*s == '\0') ? NULL : findopt(*s++);
}
if (opt != NULL)
if (opt == NULL)
error("invalid option in LESS_UNSUPPORT: %s", &parg);
else
opt->otype |= O_UNSUPPORTED;
}
}
+1
View File
@@ -63,6 +63,7 @@ struct loption
int odefault; /* Default value */
int *ovar; /* Pointer to the associated variable */
void (*ofunc)(int, constant char*); /* Pointer to special handling function */
lessmsg_id odescid[3]; /* lmsg id for description of each value */
constant char *odesc[3]; /* Description of each value */
};
+342 -280
View File
@@ -98,7 +98,7 @@ public char *end_prompt; /* Printed after clearing the prompt */
public int hilite_search; /* Highlight matched search patterns? */
#endif
public int less_is_more = 0; /* Make compatible with POSIX more */
public lbool less_is_more = FALSE; /* Make compatible with POSIX more */
/*
* Long option names.
@@ -213,134 +213,151 @@ static struct optname ttyin_name_optname = { "tty", NULL };
* a new value, and odesc[1] is the description, which should contain
* one %d which is replaced by the value of the number.
* For STRING options, odesc[0] is the prompt to use when entering
* a new value, and odesc[1], if not NULL, is the set of characters
* that are valid in the string.
* a new value, and odesc[1], if not NULL, is a description of the
* characters that are valid in the string (see optstring()).
*/
static struct loption option[] =
{
{ 'a', &a_optname,
O_TRIPLE, OPT_ONPLUS, &how_search, NULL,
{
"Search includes displayed screen",
"Search skips displayed screen",
"Search includes all of displayed screen"
}
LM_Search_includes_displayed_screen,
LM_Search_skips_displayed_screen,
LM_Search_includes_all_of_displayed_screen
},
{ NULL, NULL, NULL }
},
{ 'b', &b_optname,
O_NUMBER|O_INIT_HANDLER, 64, &bufspace, opt_b,
{
"Max buffer space per file (K): ",
"Max buffer space per file: %dK",
NULL
}
LM_Max_buffer_space_per_file,
LM_Max_buffer_space_per_file_X,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ 'B', &B__optname,
O_BOOL, OPT_ON, &autobuf, NULL,
{
"Don't automatically allocate buffers",
"Automatically allocate buffers when needed",
NULL
}
LM_Dont_automatically_allocate_buffers,
LM_Automatically_allocate_buffers_when_needed,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ 'c', &c_optname,
O_TRIPLE, OPT_OFF, &top_scroll, NULL,
{
"Repaint by scrolling from bottom of screen",
"Repaint by painting from top of screen",
"Repaint by painting from top of screen"
}
LM_Repaint_by_scrolling_from_bottom_of_screen,
LM_Repaint_by_painting_from_top_of_screen,
LM_Repaint_by_painting_from_top_of_screen,
},
{ NULL, NULL, NULL }
},
{ 'd', &d_optname,
O_BOOL|O_NO_TOGGLE, OPT_OFF, &know_dumb, NULL,
{
"Assume intelligent terminal",
"Assume dumb terminal",
NULL
}
LM_Assume_intelligent_terminal,
LM_Assume_dumb_terminal,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ 'D', &D__optname,
O_STRING|O_REPAINT|O_NO_QUERY, 0, NULL, opt_D,
{ "color desc: ", "s", NULL }
{ LM_color_desc, LM_s, LM_NULL },
{ NULL, NULL, NULL }
},
{ 'e', &e_optname,
O_TRIPLE, OPT_OFF, &quit_at_eof, NULL,
{
"Don't quit at end-of-file",
"Quit at end-of-file",
"Quit immediately at end-of-file"
}
LM_Dont_quit_at_end_of_file,
LM_Quit_at_end_of_file,
LM_Quit_immediately_at_end_of_file
},
{ NULL, NULL, NULL }
},
{ 'f', &f_optname,
O_BOOL, OPT_OFF, &force_open, NULL,
{
"Open only regular files",
"Open even non-regular files",
NULL
}
LM_Open_only_regular_files,
LM_Open_even_non_regular_files,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ 'F', &F__optname,
O_BOOL, OPT_OFF, &quit_if_one_screen, NULL,
{
"Don't quit if end-of-file on first screen",
"Quit if end-of-file on first screen",
NULL
}
LM_Dont_quit_if_end_of_file_on_first_screen,
LM_Quit_if_end_of_file_on_first_screen,
LM_NULL
},
{ NULL, NULL, NULL }
},
#if HILITE_SEARCH
{ 'g', &g_optname,
O_TRIPLE|O_HL_REPAINT, OPT_ONPLUS, &hilite_search, NULL,
{
"Don't highlight search matches",
"Highlight matches for previous search only",
"Highlight all matches for previous search pattern",
}
LM_Dont_highlight_search_matches,
LM_Highlight_matches_for_previous_search_only,
LM_Highlight_all_matches_for_previous_search_pattern,
},
{ NULL, NULL, NULL }
},
#endif
{ 'h', &h_optname,
O_NUMBER, -1, &back_scroll, NULL,
{
"Backwards scroll limit: ",
"Backwards scroll limit is %d lines",
NULL
}
LM_Backwards_scroll_limit,
LM_Backwards_scroll_limit_is_X_lines,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ 'i', &i_optname,
O_TRIPLE|O_HL_REPAINT, OPT_OFF, &caseless, opt_i,
{
"Case is significant in searches",
"Ignore case in searches",
"Ignore case in searches and in patterns"
}
LM_Case_is_significant_in_searches,
LM_Ignore_case_in_searches,
LM_Ignore_case_in_searches_and_in_patterns,
},
{ NULL, NULL, NULL }
},
{ 'j', &j_optname,
O_STRING, 0, NULL, opt_j,
{
"Target line: ",
"-.d",
NULL
}
LM_Target_line,
LM_neg_dot_d,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ 'J', &J__optname,
O_BOOL|O_REPAINT, OPT_OFF, &status_col, NULL,
{
"Don't display a status column",
"Display a status column",
NULL
}
LM_Dont_display_a_status_column,
LM_Display_a_status_column,
LM_NULL
},
{ NULL, NULL, NULL }
},
#if USERFILE
{ 'k', &k_optname,
O_STRING|O_NO_TOGGLE|O_NO_QUERY, 0, NULL, opt_k,
{ LM_NULL, LM_NULL, LM_NULL },
{ NULL, NULL, NULL }
},
#if HAVE_LESSKEYSRC
{ OLETTER_NONE, &kc_optname,
O_STRING|O_NO_TOGGLE|O_NO_QUERY, 0, NULL, opt_kc,
{ LM_NULL, LM_NULL, LM_NULL },
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &ks_optname,
O_STRING|O_NO_TOGGLE|O_NO_QUERY, 0, NULL, opt_ks,
{ LM_NULL, LM_NULL, LM_NULL },
{ NULL, NULL, NULL }
},
#endif /* HAVE_LESSKEYSRC */
@@ -348,480 +365,525 @@ static struct loption option[] =
{ 'K', &K__optname,
O_BOOL, OPT_OFF, &quit_on_intr, NULL,
{
"Interrupt (ctrl-C) returns to prompt",
"Interrupt (ctrl-C) exits less",
NULL
}
LM_Dont_quit_if_end_of_file_on_first_screen,
LM_Interrupt_exits_less,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ 'L', &L__optname,
O_BOOL, OPT_ON, &use_lessopen, NULL,
{
"Don't use the LESSOPEN filter",
"Use the LESSOPEN filter",
NULL
}
LM_Dont_use_the_LESSOPEN_filter,
LM_Use_the_LESSOPEN_filter,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ 'm', &m_optname,
O_TRIPLE, OPT_OFF, &pr_type, NULL,
{
"Short prompt",
"Medium prompt",
"Long prompt"
}
LM_Short_prompt,
LM_Medium_prompt,
LM_Long_prompt,
},
{ NULL, NULL, NULL }
},
{ 'n', &n_optname,
O_TRIPLE|O_REPAINT, OPT_ON, &linenums, NULL,
{
"Don't use line numbers",
"Use line numbers",
"Constantly display line numbers"
}
LM_Dont_use_line_numbers,
LM_Use_line_numbers,
LM_Constantly_display_line_numbers,
},
{ NULL, NULL, NULL }
},
#if LOGFILE
{ 'o', &o_optname,
O_STRING, 0, NULL, opt_o,
{ "log file: ", NULL, NULL }
{ LM_log_file, LM_NULL, LM_NULL },
{ NULL, NULL, NULL }
},
{ 'O', &O__optname,
O_STRING, 0, NULL, opt__O,
{ "Log file: ", NULL, NULL }
{ LM_Log_file, LM_NULL, LM_NULL },
{ NULL, NULL, NULL }
},
#endif
{ 'p', &p_optname,
O_STRING|O_NO_TOGGLE|O_NO_QUERY, 0, NULL, opt_p,
{ LM_NULL, LM_NULL, LM_NULL },
{ NULL, NULL, NULL }
},
{ 'P', &P__optname,
O_STRING, 0, NULL, opt__P,
{ "prompt: ", NULL, NULL }
{ LM_prompt, LM_NULL, LM_NULL },
{ NULL, NULL, NULL }
},
{ 'q', &q_optname,
O_TRIPLE, OPT_OFF, &quiet, NULL,
{
"Ring the bell for errors AND at eof/bof",
"Ring the bell for errors but not at eof/bof",
"Never ring the bell"
}
LM_Ring_the_bell_for_errors_AND_at_eof,
LM_Ring_the_bell_for_errors_but_not_at_eof,
LM_Never_ring_the_bell,
},
{ NULL, NULL, NULL }
},
{ 'r', &r_optname,
O_TRIPLE|O_REPAINT, OPT_OFF, &ctldisp, NULL,
{
"Display control characters as ^X",
"Display control characters directly (not recommended)",
"Display ANSI sequences directly, other control characters as ^X"
}
LM_Display_control_characters_as_caret,
LM_Display_control_characters_directly,
LM_Display_ANSI_sequences_directly,
},
{ NULL, NULL, NULL }
},
{ 's', &s_optname,
O_BOOL|O_REPAINT, OPT_OFF, &squeeze, NULL,
{
"Display all blank lines",
"Squeeze multiple blank lines",
NULL
}
LM_Display_all_blank_lines,
LM_Squeeze_multiple_blank_lines,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ 'S', &S__optname,
O_BOOL|O_REPAINT, OPT_OFF, &chopline, opt__S,
{
"Fold long lines",
"Chop long lines",
NULL
}
LM_Fold_long_lines,
LM_Chop_long_lines,
LM_NULL
},
{ NULL, NULL, NULL }
},
#if TAGS
{ 't', &t_optname,
O_STRING|O_NO_QUERY, 0, NULL, opt_t,
{ "tag: ", NULL, NULL }
{ LM_tag, LM_NULL, LM_NULL },
{ NULL, NULL, NULL }
},
{ 'T', &T__optname,
O_STRING, 0, NULL, opt__T,
{ "tags file: ", NULL, NULL }
{ LM_tags_file, LM_NULL, LM_NULL },
{ NULL, NULL, NULL }
},
#endif
{ 'u', &u_optname,
O_TRIPLE|O_REPAINT|O_HL_REPAINT, OPT_OFF, &bs_mode, NULL,
{
"Display underlined text in underline mode",
"Backspaces cause overstrike",
"Print backspace as ^H"
}
LM_Display_underlined_text_in_underline_mode,
LM_Backspaces_cause_overstrike,
LM_Print_backspace_as_caret,
},
{ NULL, NULL, NULL }
},
{ 'V', &V__optname,
O_NOVAR, 0, NULL, opt__V,
{ LM_NULL, LM_NULL, LM_NULL },
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &hilite_target_optname,
O_BOOL, OPT_OFF, &hilite_target, opt_hilite_target,
{
"Don't highlight target line",
"Highlight target line",
NULL
}
LM_Dont_highlight_target_line,
LM_Highlight_target_line,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ 'w', &w_optname,
O_TRIPLE|O_REPAINT, OPT_OFF, &show_attn, NULL,
{
"Don't highlight first unread line",
"Highlight first unread line after forward-screen",
"Highlight first unread line after any forward movement",
}
LM_Dont_highlight_first_unread_line,
LM_Highlight_first_unread_line_after_forward_screen,
LM_Highlight_first_unread_line_after_any_forward_movement,
},
{ NULL, NULL, NULL }
},
{ 'x', &x_optname,
O_STRING|O_REPAINT, 0, NULL, opt_x,
{
"Tab stops: ",
"d,",
NULL
}
{ LM_Tab_stops_, LM_d_comma, LM_NULL },
{ NULL, NULL, NULL }
},
{ 'X', &X__optname,
O_BOOL|O_NO_TOGGLE, OPT_OFF, &no_init, NULL,
{
"Send init/deinit strings to terminal",
"Don't use init/deinit strings",
NULL
}
LM_Send_init_deinit_strings_to_terminal,
LM_Dont_use_init_deinit_strings,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ 'y', &y_optname,
O_NUMBER, -1, &forw_scroll, NULL,
{
"Forward scroll limit: ",
"Forward scroll limit is %d lines",
NULL
}
LM_Forward_scroll_limit,
LM_Forward_scroll_limit_is_X_lines,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ 'z', &z_optname,
O_NUMBER|O_NEGOK, -1, &swindow, NULL,
{
"Scroll window size: ",
"Scroll window size is %d lines",
NULL
}
LM_Scroll_window_size,
LM_Scroll_window_size_is_X_lines,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ '"', &quote_optname,
O_STRING, 0, NULL, opt_quote,
{ "quotes: ", "s", NULL }
{ LM_quotes, LM_s, LM_NULL },
{ NULL, NULL, NULL }
},
{ '~', &tilde_optname,
O_BOOL|O_REPAINT, OPT_ON, &twiddle, NULL,
{
"Don't show tildes after end of file",
"Show tildes after end of file",
NULL
}
LM_Dont_show_tildes_after_end_of_file,
LM_Show_tildes_after_end_of_file,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ '?', &query_optname,
O_NOVAR, 0, NULL, opt_query,
{ LM_NULL, LM_NULL, LM_NULL },
{ NULL, NULL, NULL }
},
{ '#', &pound_optname,
O_STRING, 0, NULL, opt_shift,
{
"Horizontal shift: ",
".d",
NULL
}
{ LM_Horizontal_shift, LM_dot_d, LM_NULL },
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &keypad_optname,
O_BOOL|O_NO_TOGGLE, OPT_OFF, &no_keypad, NULL,
{
"Use keypad mode",
"Don't use keypad mode",
NULL
}
LM_Use_keypad_mode,
LM_Dont_use_keypad_mode,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &oldbot_optname,
O_BOOL, OPT_OFF, &oldbot, NULL,
{
"Use new bottom of screen behavior",
"Use old bottom of screen behavior",
NULL
}
LM_Use_new_bottom_of_screen_behavior,
LM_Use_old_bottom_of_screen_behavior,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &follow_optname,
O_BOOL, FOLLOW_DESC, &follow_mode, NULL,
{
"F command follows file descriptor",
"F command follows file name",
NULL
}
LM_F_command_follows_file_descriptor,
LM_F_command_follows_file_name,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &use_backslash_optname,
O_BOOL, OPT_OFF, &opt_use_backslash, NULL,
{
"Don't use backslash escaping in command line parameters",
"Use backslash escaping in command line parameters",
NULL
}
LM_Dont_use_backslash_escaping_in_command_line_parameters,
LM_Use_backslash_escaping_in_command_line_parameters,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &rscroll_optname,
O_STRING|O_REPAINT|O_INIT_HANDLER, 0, NULL, opt_rscroll,
{ "rscroll character: ", "s", NULL }
{ LM_rscroll_character, LM_s, LM_NULL },
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &nohistdups_optname,
O_BOOL, OPT_OFF, &no_hist_dups, NULL,
{
"Allow duplicates in history list",
"Remove duplicates from history list",
NULL
}
LM_Allow_duplicates_in_history_list,
LM_Remove_duplicates_from_history_list,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &mouse_optname,
O_TRIPLE, OPT_OFF, &xmouse, opt_mouse,
{
"Ignore mouse input",
"Use the mouse for scrolling vertically",
"Use the mouse for scrolling vertically (reverse)"
}
{ LM_NULL, LM_NULL, LM_NULL },
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &emouse_optname,
O_STRING, 0, NULL, opt_emouse,
{ "Mouse features: ", "s", NULL }
{ LM_Mouse_features, LM_s, LM_NULL },
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &mouse_reverse_optname,
O_BOOL, OPT_OFF, &mouse_reverse, NULL,
{
"Normal mouse scroll direction",
"Reverse mouse scroll direction",
NULL
}
LM_Normal_mouse_scroll_direction,
LM_Reverse_mouse_scroll_direction,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &wheel_lines_optname,
O_NUMBER|O_INIT_HANDLER, 0, &wheel_lines, opt_wheel_lines,
{
"Lines to scroll on mouse wheel: ",
"Scroll %d line(s) on mouse wheel",
NULL
}
LM_Lines_to_scroll_on_mouse_wheel,
LM_Scroll_X_lines_on_mouse_wheel,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &perma_marks_optname,
O_BOOL, OPT_OFF, &perma_marks, NULL,
{
"Don't save marks in history file",
"Save marks in history file",
NULL
}
LM_Dont_save_marks_in_history_file,
LM_Save_marks_in_history_file,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &linenum_width_optname,
O_NUMBER|O_REPAINT, MIN_LINENUM_WIDTH, &linenum_width, opt_linenum_width,
{
"Line number width: ",
"Line number width is %d chars",
NULL
}
LM_Line_number_width,
LM_Line_number_width_is_X_chars,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &status_col_width_optname,
O_NUMBER|O_REPAINT, 2, &status_col_width, opt_status_col_width,
{
"Status column width: ",
"Status column width is %d chars",
NULL
}
LM_Status_column_width,
LM_Status_column_width_is_X_chars,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &incr_search_optname,
O_BOOL, OPT_OFF, &incr_search, NULL,
{
"Incremental search is off",
"Incremental search is on",
NULL
}
LM_Incremental_search_is_off,
LM_Incremental_search_is_on,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &use_color_optname,
O_BOOL|O_REPAINT, OPT_OFF, &use_color, NULL,
{
"Don't use color",
"Use color",
NULL
}
LM_Dont_use_color,
LM_Use_color,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &want_filesize_optname,
O_BOOL|O_REPAINT, OPT_OFF, &want_filesize, opt_filesize,
{
"Don't get size of each file",
"Get size of each file",
NULL
}
LM_Dont_get_size_of_each_file,
LM_Get_size_of_each_file,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &status_line_optname,
O_BOOL|O_REPAINT, OPT_OFF, &status_line, NULL,
{
"Line highlight applies to text only",
"Line highlight applies to entire width of screen",
NULL
}
LM_Line_highlight_applies_to_text_only,
LM_Line_highlight_applies_to_entire_width_of_screen,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &header_optname,
O_STRING|O_REPAINT, 0, NULL, opt_header,
{ "Header lines: ", "d,", NULL }
{ LM_Header_lines, LM_d_comma, LM_NULL },
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &no_paste_optname,
O_BOOL, OPT_OFF, &no_paste, opt_no_paste,
{
"Accept pasted input",
"Ignore pasted input",
NULL
}
LM_Accept_pasted_input,
LM_Ignore_pasted_input,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &form_feed_optname,
O_BOOL, OPT_OFF, &stop_on_form_feed, NULL,
{
"Don't stop on form feed",
"Stop on form feed",
NULL
}
LM_Dont_stop_on_form_feed,
LM_Stop_on_form_feed,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &past_eof_optname,
O_BOOL, OPT_OFF, &past_eof, NULL,
{
"Stop scrolling at end of file",
"Don't stop scrolling at end of file",
NULL
}
LM_Stop_scrolling_at_end_of_file,
LM_Dont_stop_scrolling_at_end_of_file,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &no_edit_warn_optname,
O_BOOL, OPT_OFF, &no_edit_warn, NULL,
{
"Warn when editing a file opened via LESSOPEN",
"Don't warn when editing a file opened via LESSOPEN",
NULL
}
LM_Warn_when_editing_a_file_opened_via_LESSOPEN,
LM_Dont_warn_when_editing_a_file_opened_via_LESSOPEN,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &nonum_headers_optname,
O_BOOL|O_REPAINT, 0, &nonum_headers, NULL,
{
"Number header lines",
"Don't number header lines",
NULL
}
LM_Number_header_lines,
LM_Dont_number_header_lines,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &nosearch_headers_optname,
O_BOOL|O_HL_REPAINT, 0, NULL, opt_nosearch_headers,
{
NULL, NULL, NULL
}
{ LM_NULL, LM_NULL, LM_NULL },
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &nosearch_header_lines_optname,
O_BOOL|O_HL_REPAINT, 0, NULL, opt_nosearch_header_lines,
{
NULL, NULL, NULL
}
{ LM_NULL, LM_NULL, LM_NULL },
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &nosearch_header_cols_optname,
O_BOOL|O_HL_REPAINT, 0, NULL, opt_nosearch_header_cols,
{
NULL, NULL, NULL
}
{ LM_NULL, LM_NULL, LM_NULL },
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &redraw_on_quit_optname,
O_BOOL, OPT_OFF, &redraw_on_quit, NULL,
{
"Don't redraw screen when quitting",
"Redraw last screen when quitting",
NULL
}
LM_Dont_redraw_screen_when_quitting,
LM_Redraw_last_screen_when_quitting,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &search_type_optname,
O_STRING, 0, NULL, opt_search_type,
{ "Search options: ", "s", NULL }
{ LM_Search_options, LM_s, LM_NULL },
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &exit_F_on_close_optname,
O_BOOL, OPT_OFF, &exit_F_on_close, NULL,
{
"Don't exit F command when input closes",
"Exit F command when input closes",
NULL
}
LM_Dont_exit_F_command_when_input_closes,
LM_Exit_F_command_when_input_closes,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &no_vbell_optname,
O_BOOL, OPT_OFF, &no_vbell, NULL,
{
"Display visual bell",
"Don't display visual bell",
NULL
}
LM_Display_visual_bell,
LM_Dont_display_visual_bell,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &modelines_optname,
O_NUMBER, 0, &modelines, NULL,
{
"Lines to read looking for modelines: ",
"Read %d lines looking for modelines",
NULL
}
LM_Lines_to_read_looking_for_modelines,
LM_Read_X_lines_looking_for_modelines,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &intr_optname,
O_STRING, 0, NULL, opt_intr,
{ "interrupt character: ", "s", NULL }
{ LM_interrupt_character, LM_s, LM_NULL },
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &wordwrap_optname,
O_BOOL|O_REPAINT, OPT_OFF, &wordwrap, NULL,
{
"Wrap lines at any character",
"Wrap lines at spaces",
NULL
}
LM_Wrap_lines_at_any_character,
LM_Wrap_lines_at_spaces,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &show_preproc_error_optname,
O_BOOL, OPT_OFF, &show_preproc_error, NULL,
{
"Don't show error message if preprocessor fails",
"Show error message if preprocessor fails",
NULL
}
LM_Dont_show_error_message_if_preprocessor_fails,
LM_Show_error_message_if_preprocessor_fails,
LM_NULL
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &proc_backspace_optname,
O_TRIPLE|O_REPAINT|O_HL_REPAINT, OPT_OFF, &proc_backspace, NULL,
{
"Backspace handling is specified by the -U option",
"Display underline text in underline mode",
"Print backspaces as ^H"
}
LM_Backspace_handling_is_specified_by_the_U_option,
LM_Display_underline_text_in_underline_mode,
LM_Print_backspaces_as_caret,
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &proc_tab_optname,
O_TRIPLE|O_REPAINT|O_HL_REPAINT, OPT_OFF, &proc_tab, NULL,
{
"Tab handling is specified by the -U option",
"Expand tabs to spaces",
"Print tabs as ^I"
}
LM_Tab_handling_is_specified_by_the_U_option,
LM_Expand_tabs_to_spaces,
LM_Print_tabs_as_caret,
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &proc_return_optname,
O_TRIPLE|O_REPAINT|O_HL_REPAINT, OPT_OFF, &proc_return, NULL,
{
"Carriage return handling is specified by the -U option",
"Delete carriage return before newline",
"Print carriage return as ^M"
}
LM_Carriage_return_handling_is_specified_by_the_U_option,
LM_Delete_carriage_return_before_newline,
LM_Print_carriage_return_as_caret,
},
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &first_cmd_at_prompt_optname,
O_STRING|O_NO_TOGGLE|O_NO_QUERY, 0, NULL, opt_first_cmd_at_prompt,
{ LM_NULL, LM_NULL, LM_NULL },
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &match_shift_optname,
O_STRING|O_INIT_HANDLER, 0, NULL, opt_match_shift,
{
"Search match shift: ",
".d",
NULL
}
{ LM_Search_match_shift, LM_dot_d, LM_NULL },
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &autosave_optname,
O_STRING|O_INIT_HANDLER, 0, NULL, opt_autosave,
{ "Autosave actions: ", "s", NULL }
{ LM_Autosave_actions, LM_s, LM_NULL },
{ NULL, NULL, NULL }
},
{ OLETTER_NONE, &end_prompt_optname,
O_STRING, 0, NULL, opt_end_prompt,
{ "Print after prompt: ", "s", NULL }
{ LM_Print_after_prompt, LM_s, LM_NULL },
{ NULL, NULL, NULL }
},
#if LESSTEST
{ OLETTER_NONE, &ttyin_name_optname,
O_STRING|O_NO_TOGGLE, 0, NULL, opt_ttyin_name,
{
NULL,
NULL,
NULL
}
{ LM_NULL, LM_NULL, LM_NULL },
{ NULL, NULL, NULL }
},
#endif /*LESSTEST*/
{ '\0', NULL, O_NOVAR, 0, NULL, NULL, { NULL, NULL, NULL } }
{ '\0', NULL, O_NOVAR, 0, NULL, NULL,
{ LM_NULL, LM_NULL, LM_NULL },
{ NULL, NULL, NULL }
}
};
@@ -835,13 +897,13 @@ public void init_option(void)
p = lgetenv("LESS_IS_MORE");
if (!isnullenv(p) && !(p[0] == '0' && p[1] == '\0'))
less_is_more = 1;
less_is_more = TRUE;
for (o = option; o->oletter != '\0'; o++)
{
/*
* Set each variable to its default.
*/
int i;
for (i = 0; i < 3; i++)
o->odesc[i] = (o->odescid[i] == LM_NULL) ? NULL : lmsg(o->odescid[i]);
if (o->ovar != NULL)
*(o->ovar) = o->odefault;
if (o->otype & O_INIT_HANDLER)
+1 -1
View File
@@ -85,7 +85,7 @@ public lbool getting_one_screen = FALSE;
/* Milliseconds to wait for data before displaying "waiting for data" message. */
static int waiting_for_data_delay = 4000;
/* Max milliseconds expected to "normally" read and display a screen of text. */
public int screenfill_ms = 3000;
static int screenfill_ms = 3000;
static JUMP_BUF read_label;
static JUMP_BUF open_label;
+23 -44
View File
@@ -307,7 +307,7 @@ static void win_flush(void)
* in such case, once it happens, we keep passthrough sequences
* until we know we're in sync again - on a valid reset.
*/
static int sgr_bad_sync;
static lbool sgr_bad_sync;
for (anchor = p_next = obuf;
(p_next = memchr(p_next, ESC, ob - p_next)) != NULL; )
@@ -344,7 +344,7 @@ static void win_flush(void)
anchor = p_next = p;
update_sgr(&sgr, 0);
set_win_colors(&sgr);
sgr_bad_sync = 0;
sgr_bad_sync = FALSE;
continue;
}
p_next = p;
@@ -388,9 +388,9 @@ static void win_flush(void)
bad_code = update_sgr(&sgr, code);
if (bad_code)
sgr_bad_sync = 1;
sgr_bad_sync = TRUE;
else if (code == 0)
sgr_bad_sync = 0;
sgr_bad_sync = FALSE;
p = q;
}
@@ -492,7 +492,10 @@ public int putchr(int ch)
* as part of a term_deinit/term_init pair, so we shouldn't do it here.
*/
if (!term_init_ever && outfd == 1)
{
raw_mode(TRUE);
term_init();
}
if (prompting)
{
constant char *epr = end_pr_string();
@@ -571,7 +574,7 @@ TYPE_TO_A_FUNC(inttoa, int)
type cfuncname(constant char *buf, constant char **ebuf, int radix) \
{ \
type val = 0; \
lbool v = 0; \
lbool v = FALSE; \
for (;; buf++) { \
char c = *buf; \
int digit = (c >= '0' && c <= '9') ? c - '0' : (c >= 'a' && c <= 'f') ? c - 'a' + 10 : (c >= 'A' && c <= 'F') ? c - 'A' + 10 : -1; \
@@ -598,12 +601,11 @@ STR_TO_TYPE_FUNC(lstrtoul, lstrtoulc, unsigned long)
* Print an integral type.
*/
#define IPRINT_FUNC(funcname, type, typetoa) \
static int funcname(type num, int radix) \
static void funcname(type num, int radix) \
{ \
char buf[INT_STRLEN_BOUND(num)]; \
typetoa(num, buf, radix); \
putstr(buf); \
return (int) strlen(buf); \
}
IPRINT_FUNC(iprint_int, int, inttoa)
@@ -616,19 +618,16 @@ IPRINT_FUNC(iprint_linenum, LINENUM, linenumtoa)
* {{ This paranoia about the portability of printf dates from experiences
* with systems in the 1980s and is of course no longer necessary. }}
*/
public int less_printf(constant char *fmt, constant PARG *parg)
public void less_printf(constant char *fmt, constant PARG *parg)
{
constant char *s;
constant char *es;
int col;
col = 0;
while (*fmt != '\0')
{
if (*fmt != '%')
{
putchr(*fmt++);
col++;
} else
{
++fmt;
@@ -642,33 +641,25 @@ public int less_printf(constant char *fmt, constant PARG *parg)
{
LWCHAR ch = step_charc(&s, +1, es);
constant char *ps = utf_mode ? prutfchar(ch) : prchar(ch);
while (*ps != '\0')
{
putchr(*ps++);
col++;
}
putstr(ps);
}
break;
case 'd':
col += iprint_int(parg->p_int, 10);
iprint_int(parg->p_int, 10);
parg++;
break;
case 'x':
col += iprint_int(parg->p_int, 16);
iprint_int(parg->p_int, 16);
parg++;
break;
case 'n':
col += iprint_linenum(parg->p_linenum, 10);
iprint_linenum(parg->p_linenum, 10);
parg++;
break;
case 'c':
s = prchar((LWCHAR) parg->p_char);
parg++;
while (*s != '\0')
{
putchr(*s++);
col++;
}
putstr(s);
break;
case '%':
putchr('%');
@@ -676,7 +667,6 @@ public int less_printf(constant char *fmt, constant PARG *parg)
}
}
}
return (col);
}
/*
@@ -704,9 +694,6 @@ public void get_return(void)
*/
public void error(constant char *fmt, constant PARG *parg)
{
int col = 0;
static char return_to_continue[] = " (press RETURN)";
errmsgs++;
if (!interactive())
@@ -721,24 +708,17 @@ public void error(constant char *fmt, constant PARG *parg)
at_exit();
clear_bot();
at_enter(AT_STANDOUT|AT_COLOR_ERROR);
col += so_s_width;
col += less_printf(fmt, parg);
putstr(return_to_continue);
less_printf(fmt, parg);
putstr(" ");
putstr(LM(press_RETURN));
at_exit();
col += (int) sizeof(return_to_continue) + so_e_width;
get_return();
lower_left();
clear_eol();
if (col >= sc_width)
/*
* Printing the message has probably scrolled the screen.
* {{ Unless the terminal doesn't have auto margins,
* in which case we just hammered on the right margin. }}
*/
screen_trashed();
/* Printing the message may have scrolled the screen. */
screen_trashed();
flush();
}
@@ -758,6 +738,7 @@ static void ierror_suffix(constant char *fmt, constant PARG *parg, constant char
putstr(suffix2);
putstr(suffix3);
at_exit();
screen_trashed();
flush();
need_clr = TRUE;
}
@@ -786,20 +767,18 @@ public void ixerror(constant char *fmt, constant PARG *parg)
public int query(constant char *fmt, constant PARG *parg)
{
int c;
int col = 0;
if (interactive())
clear_bot();
(void) less_printf(fmt, parg);
less_printf(fmt, parg);
c = getchr();
if (interactive())
{
lower_left();
if (col >= sc_width)
screen_trashed();
flush();
screen_trashed();
} else
{
putchr('\n');
+22 -19
View File
@@ -33,7 +33,7 @@ static int compile_pattern2(constant char *pattern, int search_type, PATTERN_TYP
{
free(comp);
if (show_error)
error("Invalid pattern", NULL_PARG);
error(LM(Invalid_pattern), NULL_PARG);
return (-1);
}
if (*comp_pattern != NULL)
@@ -49,7 +49,7 @@ static int compile_pattern2(constant char *pattern, int search_type, PATTERN_TYP
{
free(comp);
if (show_error)
error("Invalid pattern", NULL_PARG);
error(LM(Invalid_pattern), NULL_PARG);
return (-1);
}
if (*comp_pattern != NULL)
@@ -112,7 +112,7 @@ static int compile_pattern2(constant char *pattern, int search_type, PATTERN_TYP
if ((comp = regcmp(pattern, 0)) == NULL)
{
if (show_error)
error("Invalid pattern", NULL_PARG);
error(LM(Invalid_pattern), NULL_PARG);
return (-1);
}
if (comp_pattern != NULL)
@@ -343,24 +343,19 @@ static lbool match_pattern1(PATTERN_TYPE pattern, constant char *tpattern, const
int i;
int ecount;
for (ecount = RM_COUNT; ecount > 0; ecount--)
if (rm[ecount-1].rm_so >= 0)
if (RM_VALID(&rm[ecount-1]))
break;
if (ecount >= nsp)
ecount = nsp-1;
for (i = 0; i < ecount; i++)
{
if (rm[i].rm_so < 0)
if (!RM_VALID(&rm[i]))
{
*sp++ = *ep++ = line;
} else
{
#ifndef __WATCOMC__
*sp++ = line + rm[i].rm_so;
*ep++ = line + rm[i].rm_eo;
#else
*sp++ = rm[i].rm_sp;
*ep++ = rm[i].rm_ep;
#endif
*sp++ = RM_PTR(&rm[i], line);
*ep++ = RM_EPTR(&rm[i], line);
}
}
}
@@ -407,7 +402,7 @@ static lbool match_pattern1(PATTERN_TYPE pattern, constant char *tpattern, const
if (ecount > mcount) ecount = mcount;
for (i = 0; i < ecount*2; )
{
if (ovector[i] < 0 || ovector[i+1] < 0)
if (ovector[i] == PCRE2_UNSET || ovector[i+1] == PCRE2_UNSET)
{
*sp++ = *ep++ = line;
i += 2;
@@ -452,26 +447,34 @@ static lbool match_pattern1(PATTERN_TYPE pattern, constant char *tpattern, const
}
/*
* Return TRUE if the match satisfies all SUBSEARCH conditions.
* Return TRUE if the match satisfies all conditions in *subsearch.
* Update *subsearch to remove any satisfied conditions.
*/
static lbool subsearch_ok(constant char **sp, constant char **ep, int search_type)
static lbool subsearch_ok(constant char **sp, constant char **ep, int *subsearch)
{
int i;
if (*subsearch == 0)
return TRUE;
for (i = 1; i <= NUM_SEARCH_COLORS; i++)
{
if ((search_type & SRCH_SUBSEARCH(i)) && ep[i] == sp[i])
return FALSE;
if (ep[i] != sp[i]) /* i-th subpattern matched */
{
*subsearch &= ~SRCH_SUBSEARCH(i);
if (*subsearch == 0)
return TRUE;
}
}
return TRUE;
return FALSE;
}
public lbool match_pattern(PATTERN_TYPE pattern, constant char *tpattern, constant char *line, size_t line_len, size_t line_off, constant char **sp, constant char **ep, int nsp, int notbol, int search_type)
{
int subsearch = search_type & SRCH_SUBSEARCH_ALL;
for (;;)
{
size_t mlen;
lbool matched = match_pattern1(pattern, tpattern, line, line_len, line_off, sp, ep, nsp, notbol, search_type);
if (!matched || subsearch_ok(sp, ep, search_type))
if (!matched || subsearch_ok(sp, ep, &subsearch))
return matched;
/* We have a match, but it does not satisfy all SUBSEARCH conditions.
* Continue searching after this match. */
+14 -1
View File
@@ -18,7 +18,7 @@
#if HAVE_POSIX_REGCOMP
#include <regex.h>
#ifdef REG_EXTENDED
extern int less_is_more;
extern lbool less_is_more;
#define REGCOMP_FLAG (less_is_more ? 0 : REG_EXTENDED)
#else
#define REGCOMP_FLAG 0
@@ -26,6 +26,19 @@ extern int less_is_more;
#define PATTERN_TYPE regex_t *
#define SET_NULL_PATTERN(name) name = NULL
#define RE_HANDLES_CASELESS 1
#undef RM_VALID
#undef RM_PTR
#undef RM_EPTR
#ifndef __WATCOMC__
#define RM_VALID(r) ((r)->rm_so >= 0)
#define RM_PTR(r,line) ((line) + (r)->rm_so)
#define RM_EPTR(r,line) ((line) + (r)->rm_eo)
#else
#define RM_VALID(r) ((r)->rm_sp != NULL)
#define RM_PTR(r,line) ((r)->rm_sp)
#define RM_EPTR(r,line) ((r)->rm_ep)
#endif
#endif
/* ---- PCRE ---- */
+10 -1
View File
@@ -32,9 +32,18 @@
#define PCK_SHIFT_END '\x61'
#define PCK_CTL_DELETE '\x62'
#define PCK_CTL_LEFT '\x63'
#define PCK_SHIFT_PAGEDOWN '\x6f'
#define PCK_CTL_PAGEDOWN '\x70'
#define PCK_SHIFT_PAGEUP '\x71'
#define PCK_CTL_PAGEUP '\x72'
#define PCK_SHIFT_LEFT '\x73'
#define PCK_CTL_RIGHT '\x74'
#define PCK_SHIFT_UP '\x75'
#define PCK_SHIFT_DOWN '\x77'
#define PCK_CTL_UP '\x78'
#define PCK_CTL_DOWN '\x79'
#define PCK_CTL_HOME '\x7a'
#define PCK_SHIFT_DELETE '\x7b'
#define PCK_CTL_END '\x7c'
#define PCK_SHIFT_HOME '\x7d'
#define PCK_SHIFT_LEFT '\x73'
#define PCK_SHIFT_RIGHT '\x7f'
+36 -3
View File
@@ -27,7 +27,7 @@ extern int hshift;
extern int sc_width;
extern int sc_height;
extern int jump_sline;
extern int less_is_more;
extern lbool less_is_more;
extern int header_lines;
extern int utf_mode;
extern IFILE curr_ifile;
@@ -341,8 +341,23 @@ static void protochar(char c, int where)
break;
case 'g': /* Shell-escaped file name */
s = shell_quote(get_filename(curr_ifile));
ap_str(s);
free(s);
if (s == NULL)
ap_quest();
else
{
ap_str(s);
free(s);
}
break;
case 'G': /* Shell-escaped last component of file name */
s = shell_quote(last_component(get_filename(curr_ifile)));
if (s == NULL)
ap_quest();
else
{
ap_str(s);
free(s);
}
break;
case 'i': /* Index into list of files */
#if TAGS
@@ -427,6 +442,24 @@ static void protochar(char c, int where)
else
ap_quest();
break;
case 'y': /* Shell-escaped name of next file */
h = next_ifile(curr_ifile);
if (h != NULL_IFILE)
{
s = shell_quote(get_filename(h));
if (s == NULL)
ap_quest();
else
{
ap_str(s);
free(s);
}
} else
ap_quest();
break;
case '%': /* Literal percent sign */
ap_char('%');
break;
}
}
+296 -232
View File
@@ -103,6 +103,9 @@ extern int fd0;
#ifdef _OSK
#include <signal.h>
#endif
#ifdef __APPLE__
#pragma clang diagnostic ignored "-Wincompatible-pointer-types-discards-qualifiers"
#endif
#if OS2
#include <sys/signal.h>
#include "pckeys.h"
@@ -240,6 +243,7 @@ static constant char
*sc_home, /* Cursor home */
*sc_addline, /* Add line, scroll down following lines */
*sc_lower_left, /* Cursor to last line, first column */
*sc_ll, /* Raw lower-left cap (but we may use sc_move for sc_lower_left) */
*sc_return, /* Cursor to beginning of current line */
*sc_move, /* General cursor positioning */
*sc_clear, /* Clear screen */
@@ -272,6 +276,9 @@ static constant char
* and the mapping of the AT_COLOR value may include the 4 attribute bits. */
static int attrbits = 0;
static int attrcolor = -1;
static int termcap_debug;
static int no_alt_screen; /* sc_init does not switch to alt screen */
static int above_mem, below_mem; /* Memory retained above/below screen */
#endif
/* term_init has been called; terminal is ready for use by less */
@@ -289,9 +296,7 @@ public int bo_s_width, bo_e_width; /* Printing width of boldface seq */
public int ul_s_width, ul_e_width; /* Printing width of underline seq */
public int so_s_width, so_e_width; /* Printing width of standout seq */
public int bl_s_width, bl_e_width; /* Printing width of blink seq */
public int above_mem, below_mem; /* Memory retained above/below screen */
public int can_goto_line; /* Can move cursor to any line */
public int clear_bg; /* Clear fills with background color */
public lbool can_goto_line; /* Can move cursor to any line */
public lbool missing_cap = FALSE; /* Some capability is missing */
public constant char *kent = NULL; /* Keypad ENTER sequence */
public lbool kent_mapped = FALSE; /* Keypad ENTER is mapped to a command */
@@ -299,18 +304,10 @@ public lbool term_addrs = FALSE; /* "ti" has been sent to terminal */
public lbool full_screen = TRUE; /* We're using all lines of terminal */
static int attrmode = AT_NORMAL; /* current attributes (AT_* bits) */
static int termcap_debug = -1;
static int no_alt_screen; /* sc_init does not switch to alt screen */
extern int binattr;
extern lbool one_screen;
extern int shell_lines;
#if !MSDOS_COMPILER
static constant char *cheaper(constant char *t1, constant char *t2, constant char *def);
static void tmodes(constant char *inti, constant char *outti, constant char *intc, constant char *outtc, constant char **instr,
constant char **outstr, constant char *def_instr, constant char *def_outstr, char **spp);
#endif
extern int quiet; /* If VERY_QUIET, use visual bell for bell */
extern int no_vbell;
extern lbool no_back_scroll;
@@ -410,9 +407,9 @@ static void set_termio_flags(
* etc. are NOT disabled.
* 6. Input \r is not mapped to \n, nor vice versa.
*/
public void raw_mode(int on)
public void raw_mode(lbool on)
{
static int curr_on = 0;
static lbool curr_on = FALSE;
if (on == curr_on)
return;
@@ -430,7 +427,7 @@ public void raw_mode(int on)
{
struct termios s;
static struct termios save_term;
static int saved_term = 0;
static lbool saved_term = FALSE;
if (on)
{
@@ -450,7 +447,7 @@ public void raw_mode(int on)
if (!saved_term)
{
save_term = s;
saved_term = 1;
saved_term = TRUE;
}
#if HAVE_OSPEED
switch (cfgetospeed(&s))
@@ -581,7 +578,7 @@ public void raw_mode(int on)
{
struct termio s;
static struct termio save_term;
static int saved_term = 0;
static lbool saved_term = FALSE;
if (on)
{
@@ -596,7 +593,7 @@ public void raw_mode(int on)
if (!saved_term)
{
save_term = s;
saved_term = 1;
saved_term = TRUE;
}
#if HAVE_OSPEED
ospeed = s.c_cflag & CBAUD;
@@ -635,7 +632,7 @@ public void raw_mode(int on)
{
struct sgttyb s;
static struct sgttyb save_term;
static int saved_term = 0;
static lbool saved_term = FALSE;
if (on)
{
@@ -650,7 +647,7 @@ public void raw_mode(int on)
if (!saved_term)
{
save_term = s;
saved_term = 1;
saved_term = TRUE;
}
#if HAVE_OSPEED
ospeed = s.sg_ospeed;
@@ -678,7 +675,7 @@ public void raw_mode(int on)
{
struct sgbuf s;
static struct sgbuf save_term;
static int saved_term = 0;
static lbool saved_term = FALSE;
if (on)
{
@@ -693,7 +690,7 @@ public void raw_mode(int on)
if (!saved_term)
{
save_term = s;
saved_term = 1;
saved_term = TRUE;
}
erase_char = s.sg_bspch;
kill_char = s.sg_dlnch;
@@ -749,7 +746,7 @@ public void raw_mode(int on)
/*
* Some glue to prevent calling termcap functions if tgetent() failed.
*/
static int hardcopy;
static lbool hardcopy;
static constant char * ltget_env(constant char *tiname, constant char *tcname)
{
@@ -829,6 +826,7 @@ static constant char * ltgetstr(constant char *tiname, constant char *tcname, ch
if (hardcopy)
return (NULL);
#if USE_TERMINFO
(void) pp;
if (tiname == NULL)
return (NULL);
s = tigetstr(tiname);
@@ -1057,11 +1055,16 @@ public constant char * special_key_str(int key)
static char k_left[] = { '\340', PCK_LEFT, 0 };
static char k_ctl_right[] = { '\340', PCK_CTL_RIGHT, 0 };
static char k_ctl_left[] = { '\340', PCK_CTL_LEFT, 0 };
static char k_ctl_up[] = { '\340', PCK_CTL_UP, 0 };
static char k_ctl_down[] = { '\340', PCK_CTL_DOWN, 0 };
static char k_shift_right[] = { '\340', PCK_SHIFT_RIGHT, 0 };
static char k_shift_left[] = { '\340', PCK_SHIFT_LEFT, 0 };
static char k_shift_up[] = { '\340', PCK_SHIFT_UP, 0 };
static char k_shift_down[] = { '\340', PCK_SHIFT_DOWN, 0 };
static char k_insert[] = { '\340', PCK_INSERT, 0 };
static char k_delete[] = { '\340', PCK_DELETE, 0 };
static char k_ctl_delete[] = { '\340', PCK_CTL_DELETE, 0 };
static char k_shift_delete[] = { '\340', PCK_SHIFT_DELETE, 0 };
static char k_ctl_backspace[] = { '\177', 0 };
static char k_backspace[] = { '\b', 0 };
static char k_home[] = { '\340', PCK_HOME, 0 };
@@ -1070,7 +1073,11 @@ public constant char * special_key_str(int key)
static char k_down[] = { '\340', PCK_DOWN, 0 };
static char k_backtab[] = { '\340', PCK_SHIFT_TAB, 0 };
static char k_pagedown[] = { '\340', PCK_PAGEDOWN, 0 };
static char k_shift_pagedown[] = { '\340', PCK_SHIFT_PAGEDOWN, 0 };
static char k_ctl_pagedown[] = { '\340', PCK_CTL_PAGEDOWN, 0 };
static char k_pageup[] = { '\340', PCK_PAGEUP, 0 };
static char k_shift_pageup[] = { '\340', PCK_SHIFT_PAGEUP, 0 };
static char k_ctl_pageup[] = { '\340', PCK_CTL_PAGEUP, 0 };
static char k_ctl_home[] = { '\340', PCK_CTL_HOME, 0 };
static char k_ctl_end[] = { '\340', PCK_CTL_END, 0 };
static char k_shift_home[] = { '\340', PCK_SHIFT_HOME, 0 };
@@ -1141,9 +1148,21 @@ public constant char * special_key_str(int key)
case SK_PAGE_UP:
s = k_pageup;
break;
case SK_SHIFT_PAGE_UP:
s = k_shift_pageup;
break;
case SK_CTL_PAGE_UP:
s = k_ctl_pageup;
break;
case SK_PAGE_DOWN:
s = k_pagedown;
break;
case SK_SHIFT_PAGE_DOWN:
s = k_shift_pagedown;
break;
case SK_CTL_PAGE_DOWN:
s = k_ctl_pagedown;
break;
case SK_HOME:
s = k_home;
break;
@@ -1164,18 +1183,33 @@ public constant char * special_key_str(int key)
case SK_CTL_RIGHT_ARROW:
s = k_ctl_right;
break;
case SK_CTL_UP_ARROW:
s = k_ctl_up;
break;
case SK_CTL_DOWN_ARROW:
s = k_ctl_down;
break;
case SK_SHIFT_LEFT_ARROW:
s = k_shift_left;
break;
case SK_SHIFT_RIGHT_ARROW:
s = k_shift_right;
break;
case SK_SHIFT_UP_ARROW:
s = k_shift_up;
break;
case SK_SHIFT_DOWN_ARROW:
s = k_shift_down;
break;
case SK_CTL_BACKSPACE:
s = k_ctl_backspace;
break;
case SK_CTL_DELETE:
s = k_ctl_delete;
break;
case SK_SHIFT_DELETE:
s = k_shift_delete;
break;
case SK_BACKSPACE:
s = k_backspace;
break;
@@ -1213,9 +1247,21 @@ public constant char * special_key_str(int key)
case SK_PAGE_UP:
s = ltgetstr("kpp", "kP", &sp);
break;
case SK_SHIFT_PAGE_UP:
s = ltgetstr("kPRV", NULL, &sp);
break;
case SK_CTL_PAGE_UP:
s = ltgetstr("kPRV5", NULL, &sp);
break;
case SK_PAGE_DOWN:
s = ltgetstr("knp", "kN", &sp);
break;
case SK_SHIFT_PAGE_DOWN:
s = ltgetstr("kNXT", NULL, &sp);
break;
case SK_CTL_PAGE_DOWN:
s = ltgetstr("kNXT5", NULL, &sp);
break;
case SK_HOME:
s = ltgetstr("khome", "kh", &sp);
break;
@@ -1246,12 +1292,24 @@ public constant char * special_key_str(int key)
case SK_SHIFT_LEFT_ARROW:
s = ltgetstr("kLFT", NULL, &sp);
break;
case SK_SHIFT_UP_ARROW:
s = ltgetstr("kUP", NULL, &sp);
break;
case SK_SHIFT_DOWN_ARROW:
s = ltgetstr("kDN", NULL, &sp);
break;
case SK_CTL_RIGHT_ARROW:
s = ltgetstr("kRIT5", NULL, &sp);
break;
case SK_CTL_LEFT_ARROW:
s = ltgetstr("kLFT5", NULL, &sp);
break;
case SK_CTL_UP_ARROW:
s = ltgetstr("kUP5", NULL, &sp);
break;
case SK_CTL_DOWN_ARROW:
s = ltgetstr("kDN5", NULL, &sp);
break;
case SK_F1:
s = ltgetstr("kf1", "k1", &sp);
break;
@@ -1316,6 +1374,12 @@ public constant char * special_key_str(int key)
s = tbuf;
}
break;
case SK_CTL_DELETE:
s = ltgetstr("kDC5", NULL, &sp);
break;
case SK_SHIFT_DELETE:
s = ltgetstr("kDC", NULL, &sp);
break;
case SK_BACKSPACE:
s = ltgetstr("kbs", "kb", &sp);
if (s == NULL)
@@ -1371,62 +1435,74 @@ public void init_win_colors(void)
}
#endif /* MSDOS_COMPILER */
#if !MSDOS_COMPILER
/*
* Get terminal capabilities via termcap.
* Return the cost of displaying a termcap string.
* We use the trick of calling tputs, but as a char printing function
* we give it inc_costcount, which just increments "costcount".
* This tells us how many chars would be printed by using this string.
*/
public void get_term(void)
static int costcount;
/*ARGSUSED*/
static int inc_costcount(int c)
{
termcap_debug = !isnullenv(lgetenv("LESS_TERMCAP_DEBUG"));
#if MSDOS_COMPILER
auto_wrap = 1;
defer_wrap = 0;
can_goto_line = 1;
clear_bg = 1;
/*
* Set up default colors.
* The xx_s_width and xx_e_width vars are already initialized to 0.
*/
#if MSDOS_COMPILER==MSOFTC
sy_bg_color = _getbkcolor();
sy_fg_color = _gettextcolor();
get_clock();
#else
#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
{
struct text_info w;
gettextinfo(&w);
sy_bg_color = (w.attribute >> 4) & 0x0F;
sy_fg_color = (w.attribute >> 0) & 0x0F;
}
#else
#if MSDOS_COMPILER==WIN32C
{
CONSOLE_SCREEN_BUFFER_INFO scr;
costcount++;
return (c);
}
con_out_save = con_out = GetStdHandle(STD_OUTPUT_HANDLE);
/*
* Always open stdin in binary. Note this *must* be done
* before any file operations have been done on fd0.
*/
SET_BINARY(0);
GetConsoleMode(con_out, &init_console_output_mode);
GetConsoleScreenBufferInfo(con_out, &scr);
curr_attr = scr.wAttributes;
sy_bg_color = (curr_attr & BG_COLORS) >> 4; /* normalize */
sy_fg_color = curr_attr & FG_COLORS;
}
#endif
#endif
#endif
init_win_colors();
static int cost(constant char *t)
{
costcount = 0;
tputs(t, sc_height, inc_costcount);
return (costcount);
}
/*
* Get size of the screen.
*/
scrsize();
pos_init();
/*
* Return the "best" of the two given termcap strings.
* The best, if both exist, is the one with the lower
* cost (see cost() function).
*/
static constant char * cheaper(constant char *t1, constant char *t2, constant char *def)
{
if (*t1 == '\0' && *t2 == '\0')
{
missing_cap = TRUE;
return (def);
}
if (*t1 == '\0')
return (t2);
if (*t2 == '\0')
return (t1);
if (cost(t1) < cost(t2))
return (t1);
return (t2);
}
#else /* !MSDOS_COMPILER */
static void tmodes(constant char *inti, constant char *outti, constant char *intc, constant char *outtc, constant char **instr, constant char **outstr, constant char *def_instr, constant char *def_outstr, char **spp)
{
*instr = ltgetstr(inti, intc, spp);
if (*instr == NULL)
{
/* Use defaults. */
*instr = def_instr;
*outstr = def_outstr;
return;
}
*outstr = ltgetstr(outti, outtc, spp);
if (*outstr == NULL)
/* No specific out capability; use "me". */
*outstr = ltgetstr("sgr0", "me", spp);
if (*outstr == NULL)
/* Don't even have "me"; use a null string. */
*outstr = "";
}
/*
* Get terminal capabilities from termcap or terminfo.
*/
static void get_term_info(void)
{
constant char *t1;
constant char *t2;
@@ -1436,7 +1512,9 @@ public void get_term(void)
* Some termcap libraries assume termbuf is static
* (accessible after tgetent returns).
*/
#if !USE_TERMINFO
#if USE_TERMINFO
int err;
#else
static char termbuf[TERMBUF_SIZE];
#endif
static char sbuf[TERMSBUF_SIZE];
@@ -1463,30 +1541,21 @@ public void get_term(void)
*/
if ((term = lgetenv("TERM")) == NULL && (term = getenv("TERM")) == NULL)
term = DEFAULT_TERM;
hardcopy = 0;
hardcopy = FALSE;
#if USE_TERMINFO
if (cur_term != NULL)
del_curterm(cur_term);
if (setupterm(term, -1, NULL) != OK)
hardcopy = 1;
if (setupterm(term, -1, &err) != OK || err != 1)
hardcopy = TRUE;
#else
if (tgetent(termbuf, term) != TGETENT_OK)
hardcopy = 1;
hardcopy = TRUE;
#endif
if (!hardcopy && ltgetflag("hc", "hc"))
hardcopy = 1;
/*
* Get size of the screen.
*/
scrsize();
pos_init();
hardcopy = TRUE;
auto_wrap = ltgetflag("am", "am");
defer_wrap = ltgetflag("xenl", "xn");
above_mem = ltgetflag("da", "da");
below_mem = ltgetflag("db", "db");
clear_bg = ltgetflag("bce", "ut");
no_alt_screen = ltgetflag("nrrmc", "NR");
/*
@@ -1593,9 +1662,9 @@ public void get_term(void)
* We need it only if we don't have home or lower-left.
*/
sc_move = "";
can_goto_line = 0;
can_goto_line = FALSE;
} else
can_goto_line = 1;
can_goto_line = TRUE;
tmodes("smso", "rmso", "so", "se", &sc_s_in, &sc_s_out, "", "", &sp);
tmodes("smul", "rmul", "us", "ue", &sc_u_in, &sc_u_out, sc_s_in, sc_s_out, &sp);
@@ -1632,22 +1701,7 @@ public void get_term(void)
}
sc_home = cheaper(t1, t2, "|\b^");
/*
* Choose between using "ll" and "cm" ("lower left" and "cursor move")
* to move the cursor to the lower left corner of the screen.
*/
t1 = ltgetstr("ll", "ll", &sp);
if (t1 == NULL || !full_screen)
t1 = "";
if (*sc_move == '\0')
t2 = "";
else
{
strcpy(sp, ltgoto(sc_move, 0, sc_height-1));
t2 = sp;
sp += strlen(sp) + 1;
}
sc_lower_left = cheaper(t1, t2, "\r");
sc_ll = ltgetstr("ll", "ll", &sp);
/*
* Get carriage return string.
@@ -1680,75 +1734,102 @@ public void get_term(void)
no_back_scroll = TRUE;
}
}
/*
* Update terminal capabilities after screen size has changed.
*/
static void reget_term_info(void)
{
constant char *t1;
constant char *t2;
static char sbuf[64];
/*
* Choose between using "ll" and "cm" ("lower left" and "cursor move")
* to move the cursor to the lower left corner of the screen.
*/
t1 = sc_ll;
if (t1 == NULL || !full_screen)
t1 = "";
if (*sc_move == '\0')
t2 = "";
else
{
SNPRINTF1(sbuf, sizeof(sbuf), "%s", ltgoto(sc_move, 0, sc_height-1));
t2 = sbuf;
}
sc_lower_left = cheaper(t1, t2, "\r");
}
#endif /* !MSDOS_COMPILER */
/*
* Get permanent terminal characteristics.
* Called once at startup.
*/
public void get_term(void)
{
#if MSDOS_COMPILER
auto_wrap = 1;
defer_wrap = 0;
can_goto_line = TRUE;
/*
* Set up default colors.
* The xx_s_width and xx_e_width vars are already initialized to 0.
*/
#if MSDOS_COMPILER==MSOFTC
sy_bg_color = _getbkcolor();
sy_fg_color = _gettextcolor();
get_clock();
#else
#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
{
struct text_info w;
gettextinfo(&w);
sy_bg_color = (w.attribute >> 4) & 0x0F;
sy_fg_color = (w.attribute >> 0) & 0x0F;
}
#else
#if MSDOS_COMPILER==WIN32C
{
CONSOLE_SCREEN_BUFFER_INFO scr;
con_out_save = con_out = GetStdHandle(STD_OUTPUT_HANDLE);
/*
* Always open stdin in binary. Note this *must* be done
* before any file operations have been done on fd0.
*/
SET_BINARY(0);
GetConsoleMode(con_out, &init_console_output_mode);
GetConsoleScreenBufferInfo(con_out, &scr);
curr_attr = scr.wAttributes;
sy_bg_color = (curr_attr & BG_COLORS) >> 4; /* normalize */
sy_fg_color = curr_attr & FG_COLORS;
}
#endif
#endif
#endif
init_win_colors();
#else
termcap_debug = !isnullenv(lgetenv("LESS_TERMCAP_DEBUG"));
get_term_info();
#endif /* MSDOS_COMPILER */
update_term();
}
/*
* Get terminal characteristics which may change during execution (size, etc).
* May be called multiple times.
*/
public void update_term(void)
{
/* Get size of the screen. */
scrsize();
pos_init();
#if !MSDOS_COMPILER
/*
* Return the cost of displaying a termcap string.
* We use the trick of calling tputs, but as a char printing function
* we give it inc_costcount, which just increments "costcount".
* This tells us how many chars would be printed by using this string.
*/
static int costcount;
/*ARGSUSED*/
static int inc_costcount(int c)
{
costcount++;
return (c);
reget_term_info();
#endif
}
static int cost(constant char *t)
{
costcount = 0;
tputs(t, sc_height, inc_costcount);
return (costcount);
}
/*
* Return the "best" of the two given termcap strings.
* The best, if both exist, is the one with the lower
* cost (see cost() function).
*/
static constant char * cheaper(constant char *t1, constant char *t2, constant char *def)
{
if (*t1 == '\0' && *t2 == '\0')
{
missing_cap = TRUE;
return (def);
}
if (*t1 == '\0')
return (t2);
if (*t2 == '\0')
return (t1);
if (cost(t1) < cost(t2))
return (t1);
return (t2);
}
static void tmodes(constant char *inti, constant char *outti, constant char *intc, constant char *outtc, constant char **instr, constant char **outstr, constant char *def_instr, constant char *def_outstr, char **spp)
{
*instr = ltgetstr(inti, intc, spp);
if (*instr == NULL)
{
/* Use defaults. */
*instr = def_instr;
*outstr = def_outstr;
return;
}
*outstr = ltgetstr(outti, outtc, spp);
if (*outstr == NULL)
/* No specific out capability; use "me". */
*outstr = ltgetstr("sgr0", "me", spp);
if (*outstr == NULL)
/* Don't even have "me"; use a null string. */
*outstr = "";
}
#endif /* MSDOS_COMPILER */
/*
* Below are the functions which perform all the
@@ -2274,6 +2355,7 @@ static void win32_clear(void)
FillConsoleOutputAttribute(con_out, curr_attr, winsz, topleft, &nchars);
}
#if 0
/*
* Remove the n topmost lines and scroll everything below it in the
* window upward.
@@ -2338,6 +2420,7 @@ public void win32_scroll_up(int n)
SetConsoleCursorPosition(con_out, csbi.dwCursorPosition);
}
#endif
#endif
/*
* Move cursor to lower left corner of screen.
@@ -2388,32 +2471,10 @@ public void line_left(void)
/*
* Check if the console size has changed and reset internals
* (in lieu of SIGWINCH for WIN32).
* (for systems without SIGWINCH).
*/
public void check_winch(void)
{
#if MSDOS_COMPILER==WIN32C
CONSOLE_SCREEN_BUFFER_INFO scr;
COORD size;
if (con_out == INVALID_HANDLE_VALUE)
return;
flush();
GetConsoleScreenBufferInfo(con_out, &scr);
size.Y = scr.srWindow.Bottom - scr.srWindow.Top + 1;
size.X = scr.srWindow.Right - scr.srWindow.Left + 1;
if (size.Y != sc_height || size.X != sc_width)
{
sc_height = size.Y;
sc_width = size.X;
if (!no_init && con_out_ours == con_out)
SetConsoleScreenBufferSize(con_out, size);
pos_init();
screen_size_changed();
screen_trashed();
}
#endif
}
/*
@@ -2720,6 +2781,11 @@ public void deinit_bracketed_paste(void)
* Any of x,y,N,M may also be "-" to mean "unchanged".
*/
static lbool is_attr_char(char ch)
{
return (strchr("*~_&dsul", ch) != NULL);
}
/*
* Parse a 4-bit color char.
*/
@@ -2753,6 +2819,8 @@ static int parse_color4(char ch)
*/
static int parse_color6(constant char **ps)
{
if (**ps == '\0')
return CV_NOCHANGE;
if (**ps == '-')
{
(*ps)++;
@@ -2785,18 +2853,24 @@ public COLOR_TYPE parse_color(constant char *str, mutable int *p_fg, mutable int
if (*str == '+')
str++; /* ignore leading + */
fg = parse_color4(*str);
if (fg != CV_ERROR)
if (is_attr_char(*str))
{
if (str[1] == '\0' || strchr("*~_&dsul", str[1]) != NULL)
fg = bg = CV_NOCHANGE;
} else
{
fg = parse_color4(*str);
if (fg != CV_ERROR)
{
bg = CV_NOCHANGE;
str++; /* skip the fg char */
} else
{
bg = parse_color4(str[1]);
if (bg != CV_ERROR)
str += 2; /* skip both fg and bg chars */
if (str[1] == '\0' || is_attr_char(str[1]))
{
bg = CV_NOCHANGE;
str++; /* skip the fg char */
} else
{
bg = parse_color4(str[1]);
if (bg != CV_ERROR)
str += 2; /* skip both fg and bg chars */
}
}
}
if (fg != CV_ERROR && bg != CV_ERROR)
@@ -3122,12 +3196,11 @@ public int apply_at_specials(int attr)
*/
public void putbs(void)
{
#if !MSDOS_COMPILER
if (termcap_debug)
putstr("<bs>");
else
{
#if !MSDOS_COMPILER
ltputs(sc_backspace, 1, putchr);
ltputs(sc_backspace, 1, putchr);
#else
int row, col;
@@ -3156,7 +3229,6 @@ public void putbs(void)
return;
_settextposition(row, col-1);
#endif /* MSDOS_COMPILER */
}
}
#if MSDOS_COMPILER==WIN32C
@@ -3345,21 +3417,15 @@ static lbool win32_scan_code(XINPUT_RECORD *xip)
{
switch (xip->ir.Event.KeyEvent.wVirtualScanCode)
{
case PCK_RIGHT: /* right arrow */
scan = PCK_CTL_RIGHT;
break;
case PCK_LEFT: /* left arrow */
scan = PCK_CTL_LEFT;
break;
case PCK_DELETE: /* delete */
scan = PCK_CTL_DELETE;
break;
case PCK_HOME:
scan = PCK_CTL_HOME;
break;
case PCK_END:
scan = PCK_CTL_END;
break;
case PCK_RIGHT: scan = PCK_CTL_RIGHT; break;
case PCK_LEFT: scan = PCK_CTL_LEFT; break;
case PCK_UP: scan = PCK_CTL_UP; break;
case PCK_DOWN: scan = PCK_CTL_DOWN; break;
case PCK_DELETE: scan = PCK_CTL_DELETE; break;
case PCK_HOME: scan = PCK_CTL_HOME; break;
case PCK_END: scan = PCK_CTL_END; break;
case PCK_PAGEUP: scan = PCK_CTL_PAGEUP; break;
case PCK_PAGEDOWN: scan = PCK_CTL_PAGEDOWN; break;
}
} else if (xip->ir.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED)
{
@@ -3369,18 +3435,15 @@ static lbool win32_scan_code(XINPUT_RECORD *xip)
{
switch (xip->ir.Event.KeyEvent.wVirtualScanCode)
{
case PCK_RIGHT:
scan = PCK_SHIFT_RIGHT;
break;
case PCK_LEFT:
scan = PCK_SHIFT_LEFT;
break;
case PCK_HOME:
scan = PCK_SHIFT_HOME;
break;
case PCK_END:
scan = PCK_SHIFT_END;
break;
case PCK_RIGHT: scan = PCK_SHIFT_RIGHT; break;
case PCK_LEFT: scan = PCK_SHIFT_LEFT; break;
case PCK_UP: scan = PCK_SHIFT_UP; break;
case PCK_DOWN: scan = PCK_SHIFT_DOWN; break;
case PCK_DELETE: scan = PCK_SHIFT_DELETE; break;
case PCK_HOME: scan = PCK_SHIFT_HOME; break;
case PCK_END: scan = PCK_SHIFT_END; break;
case PCK_PAGEUP: scan = PCK_SHIFT_PAGEUP; break;
case PCK_PAGEDOWN: scan = PCK_SHIFT_PAGEDOWN; break;
}
}
}
@@ -3456,6 +3519,7 @@ static lbool win32_window_event(XINPUT_RECORD *xip)
{
if (xip->ir.EventType != WINDOW_BUFFER_SIZE_EVENT)
return (FALSE);
sigs |= S_WINCH;
win32_enqueue(READ_AGAIN);
return (TRUE);
}
+55 -49
View File
@@ -47,7 +47,7 @@ extern LWCHAR rscroll_char;
#if HILITE_SEARCH
extern int hilite_search;
extern lbool squished;
extern int can_goto_line;
extern lbool can_goto_line;
static lbool hide_hilite;
static POSITION prep_startpos;
static POSITION prep_endpos;
@@ -57,14 +57,14 @@ public lbool search_wrapped = FALSE;
public POSITION search_incr_start = NULL_POSITION;
#if OSC8_LINK
public POSITION osc8_linepos = NULL_POSITION;
public POSITION osc8_match_start = NULL_POSITION;
public POSITION osc8_match_end = NULL_POSITION;
public POSITION osc8_params_start = NULL_POSITION;
public POSITION osc8_params_end = NULL_POSITION;
public POSITION osc8_uri_start = NULL_POSITION;
public POSITION osc8_uri_end = NULL_POSITION;
public POSITION osc8_text_start = NULL_POSITION;
public POSITION osc8_text_end = NULL_POSITION;
static POSITION osc8_match_start = NULL_POSITION;
static POSITION osc8_match_end = NULL_POSITION;
static POSITION osc8_params_start = NULL_POSITION;
static POSITION osc8_params_end = NULL_POSITION;
static POSITION osc8_uri_start = NULL_POSITION;
static POSITION osc8_uri_end = NULL_POSITION;
static POSITION osc8_text_start = NULL_POSITION;
static POSITION osc8_text_end = NULL_POSITION;
char *osc8_uri = NULL;
constant char *osc8_search_param = NULL;
#endif
@@ -98,7 +98,7 @@ struct hilite_node
struct hilite_node *right;
struct hilite_node *prev;
struct hilite_node *next;
int red;
lbool red;
struct hilite r;
};
struct hilite_storage
@@ -187,20 +187,19 @@ static int set_pattern(struct pattern_info *info, constant char *pattern, int se
info->is_ucase_pattern = (pattern == NULL) ? FALSE : is_ucase(pattern);
is_caseless = (info->is_ucase_pattern && caseless != OPT_ONPLUS) ? 0 : caseless;
#if !NO_REGEX
if (pattern == NULL)
SET_NULL_PATTERN(info->compiled);
else if (compile_pattern(pattern, search_type, show_error, &info->compiled) < 0)
return -1;
uncompile_pattern(&info->compiled);
if (pattern != NULL)
{
if (compile_pattern(pattern, search_type, show_error, &info->compiled) < 0)
return -1;
}
#endif
/* Pattern compiled successfully; save the text too. */
if (info->text != NULL)
free(info->text);
info->text = NULL;
if (pattern != NULL)
{
info->text = (char *) ecalloc(1, strlen(pattern)+1);
strcpy(info->text, pattern);
}
info->text = save(pattern);
info->search_type = search_type;
return 0;
}
@@ -345,7 +344,7 @@ public void clear_attn(void)
POSITION old_end_attnpos;
POSITION pos;
POSITION epos;
int moved = 0;
lbool moved = FALSE;
if (hilite_target)
draw_target_attn(FALSE);
@@ -377,11 +376,11 @@ public void clear_attn(void)
goto_line(sindex);
clear_eol();
put_line(FALSE);
moved = 1;
moved = TRUE;
}
}
if (overlay_header())
moved = 1;
moved = TRUE;
if (moved)
lower_left();
#endif
@@ -404,7 +403,7 @@ public void undo_search(lbool clear)
if (has_pattern)
hide_hilite = !hide_hilite;
else if (!osc8_active)
error("No previous regular expression", NULL_PARG);
error(LM(No_previous_regular_expression), NULL_PARG);
}
repaint_hilite(TRUE);
#else
@@ -429,7 +428,7 @@ public lbool undo_osc8(void)
/*
* Clear the hilite list.
*/
public void clr_hlist(struct hilite_tree *anchor)
static void clr_hlist(struct hilite_tree *anchor)
{
struct hilite_storage *hls;
struct hilite_storage *nexthls;
@@ -472,7 +471,7 @@ static struct hilite_node* hlist_find(struct hilite_tree *anchor, POSITION pos)
if (anchor->lookaside)
{
int steps = 0;
int hit = 0;
lbool hit = FALSE;
n = anchor->lookaside;
@@ -482,13 +481,13 @@ static struct hilite_node* hlist_find(struct hilite_tree *anchor, POSITION pos)
{
if (n->prev == NULL || pos >= n->prev->r.hl_endpos)
{
hit = 1;
hit = TRUE;
break;
}
} else if (n->next == NULL)
{
n = NULL;
hit = 1;
hit = TRUE;
break;
}
@@ -684,7 +683,7 @@ public int is_hilited_attr(POSITION pos, POSITION epos, int nohide, int *p_match
#if OSC8_LINK
if (osc8_linepos != NULL_POSITION &&
pos < osc8_text_end && (epos == NULL_POSITION || epos > osc8_text_start))
return (AT_HILITE|AT_COLOR_SEARCH);
return (AT_HILITE|AT_UNDERLINE|AT_COLOR_SEARCH);
#endif
attr = hilited_range_attr(pos, epos);
@@ -919,7 +918,7 @@ static void add_hilite(struct hilite_tree *anchor, struct hilite *hl)
p->next = n;
}
n->parent = p;
n->red = 1;
n->red = TRUE;
n->r = *hl;
/*
@@ -932,7 +931,7 @@ static void add_hilite(struct hilite_tree *anchor, struct hilite *hl)
/* case 1 - current is root, root is always black */
if (n->parent == NULL)
{
n->red = 0;
n->red = FALSE;
break;
}
@@ -955,10 +954,10 @@ static void add_hilite(struct hilite_tree *anchor, struct hilite *hl)
u = n->parent->parent->right;
if (u != NULL && u->red)
{
n->parent->red = 0;
u->red = 0;
n->parent->red = FALSE;
u->red = FALSE;
n = n->parent->parent;
n->red = 1;
n->red = TRUE;
continue;
}
@@ -985,8 +984,8 @@ static void add_hilite(struct hilite_tree *anchor, struct hilite *hl)
* case 5 - parent is red but uncle is black, parent and
* grandparent on same side
*/
n->parent->red = 0;
n->parent->parent->red = 1;
n->parent->red = FALSE;
n->parent->parent->red = TRUE;
if (n == n->parent->left)
hlist_rotate_right(anchor, n->parent->parent);
else
@@ -1086,7 +1085,9 @@ static void hilite_line(POSITION linepos, constant char *line, size_t line_len,
else /* end of line */
break;
} while (match_pattern(info_compiled(&search_info), search_info.text,
line, line_len, line_off, sp, ep, nsp, 1, search_info.search_type));
line, line_len, line_off, sp, ep, nsp, 1,
search_info.search_type & ~SRCH_SUBSEARCH_ALL));
}
#endif
@@ -1316,7 +1317,7 @@ static lbool osc8_parse(constant char *line, constant char *line_end, struct osc
pop->uri_start = line;
}
break;
case OSC_END_CSI:
case OSC8_URI_CSI:
if (pop->uri_end == NULL)
pop->uri_end = oline;
break;
@@ -1352,8 +1353,8 @@ static lbool osc8_param_match(POSITION linepos, constant char *line, constant st
if (clickpos != NULL_POSITION)
{
return clickpos >= linepos + ptr_diff(op1->osc8_start, line) &&
clickpos < linepos + ptr_diff(op2->osc8_end, line);
return clickpos >= linepos + (POSITION) ptr_diff(op1->osc8_start, line) &&
clickpos < linepos + (POSITION) ptr_diff(op2->osc8_end, line);
}
if (param == NULL)
return TRUE;
@@ -1446,7 +1447,7 @@ static osc8_match osc8_search_line1(int search_type, POSITION linepos, POSITION
/* Don't set osc8 globals if we're just searching for a parameter. */
return OSC8_MATCH;
if (osc8_linepos == linepos && osc8_match_start == spos + ptr_diff(op1.osc8_start, line))
if (osc8_linepos == linepos && osc8_match_start == spos + (POSITION) ptr_diff(op1.osc8_start, line))
return OSC8_ALREADY; /* already selected */
osc8_linepos = linepos;
@@ -1819,7 +1820,7 @@ public void osc8_search(int search_type, constant char *param, int matches)
pos = search_pos(search_type);
if (pos == NULL_POSITION)
{
error("Nothing to search", NULL_PARG);
error(LM(Nothing_to_search), NULL_PARG);
return;
}
osc8_search_param = param;
@@ -1827,7 +1828,7 @@ public void osc8_search(int search_type, constant char *param, int matches)
osc8_search_param = NULL;
if (match != 0)
{
error("OSC 8 link not found", NULL_PARG);
error(LM(OSC_8_link_not_found), NULL_PARG);
return;
}
/* If new link is on screen, just highlight it without scrolling. */
@@ -1925,12 +1926,12 @@ public void osc8_open(void)
if (osc8_linepos == NULL_POSITION)
{
error("No OSC8 link selected", NULL_PARG);
error(LM(No_OSC8_link_selected), NULL_PARG);
return;
}
if (!osc8_read_selected(&op))
{
error("Cannot find OSC8 link", NULL_PARG);
error(LM(Cannot_find_OSC8_link), NULL_PARG);
return;
}
/*
@@ -1967,16 +1968,21 @@ public void osc8_open(void)
{
PARG parg;
parg.p_string = env_name + strlen(env_name_pfx); /* {{ tricky }} */
error("No handler for \"%s\" link type", &parg);
error(LM(No_handler_for_X_link_type), &parg);
return;
}
uri_q = shell_quoten(op.uri_start, uri_len);
if (uri_q == NULL)
{
error(LM(Cannot_quote_URI), NULL_PARG);
return;
}
cmd = ecalloc(strlen(handler) + strlen(uri_q) + 2, sizeof(char));
sprintf(cmd, "%s %s", handler, uri_q);
free(uri_q);
{
constant char *exec_cmd = cmd;
constant char *done_msg = "link done";
constant char *done_msg = LM(link_done);
POSITION save_osc8_linepos = osc8_linepos;
if (*exec_cmd == CONTROL('P'))
{
@@ -1998,7 +2004,7 @@ public void osc8_jump(void)
{
if (osc8_linepos == NULL_POSITION)
{
error("No OSC8 link selected", NULL_PARG);
error(LM(No_OSC8_link_selected), NULL_PARG);
return;
}
jump_loc(osc8_linepos, jump_sline);
@@ -2090,14 +2096,14 @@ public int search(int search_type, constant char *pattern, int n)
{
int r = hist_pattern(search_type);
if (r == 0)
error("No previous regular expression", NULL_PARG);
error(LM(No_previous_regular_expression), NULL_PARG);
if (r <= 0)
return (-1);
}
if ((search_type & SRCH_NO_REGEX) !=
(search_info.search_type & SRCH_NO_REGEX))
{
error("Please re-enter search pattern", NULL_PARG);
error(LM(Please_re_enter_search_pattern), NULL_PARG);
return -1;
}
#if HILITE_SEARCH
@@ -2167,7 +2173,7 @@ public int search(int search_type, constant char *pattern, int n)
if (hilite_search == OPT_ON || status_col)
repaint_hilite(TRUE);
#endif
error("Nothing to search", NULL_PARG);
error(LM(Nothing_to_search), NULL_PARG);
return (-1);
}
+5 -5
View File
@@ -34,7 +34,7 @@ extern int wscroll;
extern int quit_on_intr;
extern long jump_sline_fraction;
extern int less_is_more;
extern lbool less_is_more;
/*
* Interrupt signal handler.
@@ -170,7 +170,7 @@ static RETSIGTYPE sigusr1(int type)
/*
* Set up the signal handlers.
*/
public void init_signals(int on)
public void init_signals(lbool on)
{
if (on)
{
@@ -261,7 +261,7 @@ public void psignals(void)
clear_bot();
term_deinit();
flush();
raw_mode(0);
raw_mode(FALSE);
#ifdef SIGTTOU
LSIGNAL(SIGTTOU, SIG_DFL);
#endif
@@ -274,7 +274,7 @@ public void psignals(void)
* screen when we get back to the main command loop.
*/
LSIGNAL(SIGTSTP, stop);
raw_mode(1);
raw_mode(TRUE);
term_init();
screen_trashed();
tsignals |= S_WINCH;
@@ -289,7 +289,7 @@ public void psignals(void)
*/
old_width = sc_width;
old_height = sc_height;
get_term();
update_term();
if (sc_width != old_width || sc_height != old_height)
screen_size_changed();
screen_trashed();
+10 -10
View File
@@ -133,7 +133,7 @@ static struct tag * maketagent(constant char *file, LINENUM linenum, constant ch
/*
* Get tag mode.
*/
public int gettagtype(void)
static int gettagtype(void)
{
int f;
@@ -178,13 +178,13 @@ public void findtag(constant char *tag)
case TAG_INTR:
break;
case TAG_NOFILE:
error("No tags file", NULL_PARG);
error(LM(No_tags_file), NULL_PARG);
break;
case TAG_NOTAG:
error("No such tag in tags file", NULL_PARG);
error(LM(No_such_tag_in_tags_file), NULL_PARG);
break;
case TAG_NOTYPE:
error("unknown tag type", NULL_PARG);
error(LM(unknown_tag_type), NULL_PARG);
break;
}
}
@@ -416,12 +416,12 @@ static POSITION ctagsearch(void)
LINENUM linenum;
size_t line_len;
constant char *line;
int found;
lbool found;
pos = ch_zero();
linenum = find_linenum(pos);
for (found = 0; !found;)
for (found = FALSE; !found;)
{
/*
* Get lines until we find a matching one or
@@ -444,7 +444,7 @@ static POSITION ctagsearch(void)
/*
* We hit EOF without a match.
*/
error("Tag not found", NULL_PARG);
error(LM(Tag_not_found), NULL_PARG);
return (NULL_POSITION);
}
@@ -459,7 +459,7 @@ static POSITION ctagsearch(void)
if (ctldisp != OPT_ONPLUS)
{
if (curtag_match(line, linepos))
found = 1;
found = TRUE;
} else
{
int cvt_ops = CVT_ANSI;
@@ -468,7 +468,7 @@ static POSITION ctagsearch(void)
char *cline = (char *) ecalloc(1, cvt_len);
cvt_text(cline, line, chpos, &line_len, cvt_ops);
if (curtag_match(cline, linepos))
found = 1;
found = TRUE;
free(chpos);
free(cline);
}
@@ -543,7 +543,7 @@ static enum tag_result findgtag(constant char *tag, int type)
/* Get our data from global(1). */
qtag = shell_quote(tag);
if (qtag == NULL)
qtag = save(tag);
return TAG_NOTAG;
command = (char *) ecalloc(strlen(cmd) + strlen(flag) +
strlen(qtag) + 5, sizeof(char));
sprintf(command, "%s -x%s %s", cmd, flag, qtag);
+8
View File
@@ -216,6 +216,14 @@ public int getchr(void)
}
if (result == READ_INTR)
return (READ_INTR);
if (result == 0)
{
/*
* EOF on the tty means there is no more keyboard input.
* Don't loop forever waiting for a byte which cannot arrive.
*/
quit(QUIT_ERROR);
}
if (result < 0)
{
/*
+19 -1
View File
@@ -1111,6 +1111,24 @@ v703 5/30/26 Fix handling unsafe man options in OSC 8 link; fix unsafe
handling of unterminated OSC seq; shell-escape expansion
of % and #.
v704 5/30/26 Fix uninstall target in Makefile.
v705 6/15/26 Fix bug overriding built-in command.
v706 6/22/26 Add ^ and + modifiers for \k in lesskey file; support ctl
and shift up/down arrows; add -DO; add LESSSECURE_DISALLOW;
add LESS_SHELL_COPTION; add %G,%y,%% in prompts; underline
OSC 8 links; use separate names for lesstest executable;
add getenv cache; improve error handling for bad lesskey files
and bad OSC 8 links; remove lesskey program.
v707 7/16/26 Don't let ' with numeric arg modify the mark; add || cmd;
allow ^N to enter line number in pipe cmd; add LESSMSG.
v708 7/16/26 Merge.
v709 8/15/26 Fix --rscroll with non-ASCII char; fix exit with invalid TERM;
fix crash with :e# after :d; fix loop if invalid option in
LESS_UNSUPPORT; fix crash with initial !!; allow shell cmd
starting with '!'; add ESC-]; support shift/ctl page up/down;
fix search ^S bugs; fix display issues with less_printf.
v710 9/8/26 Fix string overrrun if input contains "\e\0"; fix memory leak
when using ${...} in lesskey file; fix status column when long
line is marked.
*/
char version[] = "704";
char version[] = "710";
-1
View File
@@ -237,7 +237,6 @@ DIRDEPS+= \
usr.bin/leave \
usr.bin/less \
usr.bin/lessecho \
usr.bin/lesskey \
usr.bin/lex/lib \
usr.bin/limits \
usr.bin/locale \
-1
View File
@@ -70,7 +70,6 @@ SUBDIR= apply \
leave \
less \
lessecho \
lesskey \
limits \
locale \
localedef \
+3 -2
View File
@@ -3,7 +3,7 @@ PROG= less
SRCS= main.c screen.c brac.c ch.c charset.c cmdbuf.c command.c cvt.c \
decode.c evar.c edit.c filename.c forwback.c help.c ifile.c input.c \
jump.c lesskey_parse.c \
line.c linenum.c lsystem.c mark.c optfunc.c option.c \
line.c linenum.c lmsg.c lsystem.c mark.c optfunc.c option.c \
opttbl.c os.c output.c pattern.c position.c prompt.c search.c \
signal.c tags.c ttyin.c version.c xbuf.c
SCRIPTS=lesspipe.sh zless.sh less-osc8-open.sh
@@ -14,8 +14,9 @@ LINKS= ${BINDIR}/less ${BINDIR}/more \
${BINDIR}/zless ${BINDIR}/xzless \
${BINDIR}/zless ${BINDIR}/lzless \
${BINDIR}/zless ${BINDIR}/zstdless
MAN= less.1 lesskey.5
MLINKS= less.1 more.1
CLEANFILES= less.1
CLEANFILES= less.1 lesskey.5
.include "Makefile.common"
.include <bsd.prog.mk>
+4 -1
View File
@@ -4,7 +4,10 @@ LSDIR= ${SRCTOP}/contrib/less
CFLAGS+=-I${SRCTOP}/usr.bin/less -I${LSDIR}
WARNS?= 1
.SUFFIXES: .nro .1
.SUFFIXES: .nro .1 .5
.nro.1:
cat ${.IMPSRC} > ${.TARGET}
.nro.5:
cat ${.IMPSRC} > ${.TARGET}
-6
View File
@@ -1,6 +0,0 @@
PROG= lesskey
SRCS= lesskey.c lesskey_parse.c version.c xbuf.c
CLEANFILES= lesskey.1
.include "${SRCTOP}/usr.bin/less/Makefile.common"
.include <bsd.prog.mk>
-15
View File
@@ -1,15 +0,0 @@
# Autogenerated - do NOT edit!
DIRDEPS = \
include \
include/xlocale \
lib/${CSU_DIR} \
lib/libc \
lib/libcompiler_rt \
.include <dirdeps.mk>
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
# local dependencies - needed for -jN in clean tree
.endif