MFV less v691

Relnotes:	yes
MFC after:	2 weeks
This commit is contained in:
Xin LI
2026-02-02 12:50:35 -08:00
49 changed files with 2654 additions and 1387 deletions
+62
View File
@@ -9,6 +9,68 @@
Report bugs, suggestions or comments at Report bugs, suggestions or comments at
https://github.com/gwsw/less/issues. https://github.com/gwsw/less/issues.
======================================================================
Major changes between "less" versions 685 and 691
* Add --autosave option (github #678).
* Add ESC-f command (github #680).
* Add column number to long prompt and = message.
* Add prompt prototype sequences %C, %W, %Q and ?Q (github #685).
* Map keypad keys, and use terminfo rather than termcap since keypad
definitions don't exist in termcap (github #650).
* Change HOME key to scroll fully left and END key to scroll fully right.
Add shift-HOME and ctrl-HOME to scroll left and jump to top, and
add shift-END and ctrl-END to scroll right and jump to end (github #658).
* Add LESSNOCONFIG environment variable.
* Add --without-termlib to configure (github #701).
* When setting line number colors (-DN), don't force bold attribute.
To set bold, you must append "d" or "*" to the color string (github #684).
* While waiting for file data, only ^C or ^X will interrupt, not any command.
This reverts to behavior that existed before less-670 (github #700).
* When --save-marks is not used, retain any marks saved in the history file
(github #662).
* Defer sending the terminal init string until the first char is read
from the input file (github #682).
* Make SIGHUP do an orderly exit like SIGTERM.
* Implement modeline handling in Windows build.
* Fix bugs and improve behavior of screen resize on Windows.
* Fix bug when entering search modifier key at start of non-empty
search string (github #668).
* Fix bug repainting screen with --form-feed (github #672).
* Fix bugs passing invalid negative values to some command line
options (github #675).
* Fix incorrect display of Lit indicator (github #670).
* Fix incorrect display when returning to a mark after resizeing window
(github #681).
* Fix bug using --pattern with --incsearch (github #696).
* Disallow mouse click to open OSC8 link in SECURE mode (github #676).
* Add SECURE_COMPILE environment variable for Windows builds.
* Update Unicode tables.
====================================================================== ======================================================================
Major changes between "less" versions 679 and 685 Major changes between "less" versions 679 and 685
+24 -36
View File
@@ -84,7 +84,7 @@ INSTALLATION (Unix & Linux systems only):
Makefile now. Take particular notice of the list of "terminal" Makefile now. Take particular notice of the list of "terminal"
libraries in the LIBS definition in the Makefile; these may need libraries in the LIBS definition in the Makefile; these may need
to be edited. The terminal libraries will be some subset of to be edited. The terminal libraries will be some subset of
-lncurses -lcurses -ltermcap -ltermlib -ltinfo -ltinfow -lxcurses -lncursesw -lncurses -lcurses -ltermcap -ltermlib
If you wish, you may edit defines.h to remove some optional features. If you wish, you may edit defines.h to remove some optional features.
If you choose not to include some features in your version, you may If you choose not to include some features in your version, you may
@@ -117,6 +117,29 @@ programmers", not "persons who attempt to circumvent computer security".)
=======================================================================
INSTALLATION (Windows-95, Windows-98 and Windows-NT systems only,
with Microsoft Visual C++, mingw, or Borland C)
1. Move the distributed source to its own directory.
2. If you wish, you may edit defines.wn to remove some optional features.
If you choose not to include some features in your version, you may
wish to edit the manual page less.man and the help page help.c
to remove the descriptions of the features which you are removing.
3. If you are using Microsoft Visual C++, run "nmake -f Makefile.wnm".
If you are using mingw, run "make -f Makefile.wng".
If you are using Borland C, run "make -f Makefile.wnb".
If the environment variable SECURE_COMPILE is to 1 during the make,
a "secure" version of less is built, with some features disabled.
4. If the make succeeds, it will generate the programs "less.exe" and
"lesskey.exe" in your current directory. Test the generated programs.
======================================================================= =======================================================================
INSTALLATION (MS-DOS systems only, INSTALLATION (MS-DOS systems only,
with Microsoft C, Borland C, or DJGPP) with Microsoft C, Borland C, or DJGPP)
@@ -156,34 +179,6 @@ INSTALLATION (MS-DOS systems only,
=======================================================================
INSTALLATION (Windows-95, Windows-98 and Windows-NT systems only,
with Borland C or Microsoft Visual C++)
1. Move the distributed source to its own directory.
2. If you are using Borland C, rename Makefile.wnb to Makefile.
If you are using Microsoft Visual C++, rename Makefile.wnm to Makefile.
3. Check the Makefile to make sure the definitions look ok.
4. If you wish, you may edit defines.wn to remove some optional features.
If you choose not to include some features in your version, you may
wish to edit the manual page less.man and the help page help.c
to remove the descriptions of the features which you are removing.
5. Type "make" and watch the fun.
6. If the make succeeds, it will generate the programs "less.exe" and
"lesskey.exe" in your current directory. Test the generated programs.
7. When satisfied that it works, if you wish to install it
in a public place, type "make install".
See step 6 of the Unix installation instructions for details
on how to change the default installation directories.
======================================================================= =======================================================================
INSTALLATION (OS/2 systems only, INSTALLATION (OS/2 systems only,
with EMX C) with EMX C)
@@ -245,10 +240,3 @@ INSTALLATION (OS-9 systems only,
See step 6 of the Unix installation instructions for details See step 6 of the Unix installation instructions for details
on how to change the default installation directories. on how to change the default installation directories.
=======================================================================
ACKNOWLEDGMENTS:
Some versions of the less distribution are packaged using
Info-ZIP's compression utility.
Info-ZIP's software is free and can be obtained as source
code or executables from various anonymous-ftp sites,
including ftp.uu.net:/pub/archiving/zip.
+6 -6
View File
@@ -22,7 +22,7 @@
typedef POSITION BLOCKNUM; typedef POSITION BLOCKNUM;
public int ignore_eoi; public lbool ignore_eoi = FALSE;
/* /*
* Pool of buffers holding the most recently used blocks of the input file. * Pool of buffers holding the most recently used blocks of the input file.
@@ -883,13 +883,13 @@ public void ch_init(int f, int flags, ssize_t nread)
*/ */
ch_fsize = (flags & CH_HELPFILE) ? size_helpdata : filesize(ch_file); ch_fsize = (flags & CH_HELPFILE) ? size_helpdata : filesize(ch_file);
/*
* This is a kludge to workaround a Linux kernel bug: files in some
* pseudo filesystems like /proc and tracefs have a size of 0 according
* to fstat() but have readable data.
*/
if (ch_fsize == 0 && nread > 0) if (ch_fsize == 0 && nread > 0)
{ {
/*
* This is a kludge to workaround a Linux kernel bug: files in some
* pseudo filesystems like /proc and tracefs have a size of 0 according
* to fstat() but have readable data.
*/
ch_flags |= CH_NOTRUSTSIZE; ch_flags |= CH_NOTRUSTSIZE;
} }
+6 -8
View File
@@ -202,20 +202,20 @@ static void ichardef_utf(constant char *s)
switch (*s++) switch (*s++)
{ {
case 'b': case 'b':
xbuf_add_data(&user_ubin_array, (unsigned char *) &range, sizeof(range)); xbuf_add_data(&user_ubin_array, &range, sizeof(range));
break; break;
case 'c': case 'c':
xbuf_add_data(&user_compose_array, (unsigned char *) &range, sizeof(range)); xbuf_add_data(&user_compose_array, &range, sizeof(range));
break; break;
case 'd': case 'd':
xbuf_add_data(&user_omit_array, (unsigned char *) &range, sizeof(range)); xbuf_add_data(&user_omit_array, &range, sizeof(range));
break; break;
case 'w': case 'w':
xbuf_add_data(&user_wide_array, (unsigned char *) &range, sizeof(range)); xbuf_add_data(&user_wide_array, &range, sizeof(range));
xbuf_add_data(&user_prt_array, (unsigned char *) &range, sizeof(range)); xbuf_add_data(&user_prt_array, &range, sizeof(range));
break; break;
case 'p': case '.': case 'p': case '.':
xbuf_add_data(&user_prt_array, (unsigned char *) &range, sizeof(range)); xbuf_add_data(&user_prt_array, &range, sizeof(range));
break; break;
case '\0': case '\0':
s--; s--;
@@ -435,7 +435,6 @@ static void set_charset(void)
#endif #endif
#endif #endif
#if HAVE_STRSTR
/* /*
* Check whether LC_ALL, LC_CTYPE or LANG look like UTF-8 is used. * Check whether LC_ALL, LC_CTYPE or LANG look like UTF-8 is used.
*/ */
@@ -448,7 +447,6 @@ static void set_charset(void)
if (icharset("utf-8", 1)) if (icharset("utf-8", 1))
return; return;
} }
#endif
#if HAVE_LOCALE #if HAVE_LOCALE
/* /*
+22
View File
@@ -86,6 +86,7 @@
#define A_OSC8_JUMP 74 #define A_OSC8_JUMP 74
#define A_START_PASTE 75 /* must not overlap EC_* */ #define A_START_PASTE 75 /* must not overlap EC_* */
#define A_END_PASTE 76 /* must not overlap EC_* */ #define A_END_PASTE 76 /* must not overlap EC_* */
#define A_F_FOREVER_BELL 77
/* These values must not conflict with any A_* or EC_* value. */ /* These values must not conflict with any A_* or EC_* value. */
#define A_INVALID 100 #define A_INVALID 100
@@ -155,4 +156,25 @@
#define SK_BACKTAB 15 #define SK_BACKTAB 15
#define SK_CTL_BACKSPACE 16 #define SK_CTL_BACKSPACE 16
#define SK_BACKSPACE 17 #define SK_BACKSPACE 17
#define SK_PAD_U 18
#define SK_PAD_D 19
#define SK_PAD_R 20
#define SK_PAD_L 21
#define SK_PAD_UR 22
#define SK_PAD_UL 23
#define SK_PAD_DR 24
#define SK_PAD_DL 25
#define SK_PAD_CENTER 26
#define SK_PAD_STAR 27
#define SK_PAD_SLASH 28
#define SK_PAD_DASH 29
#define SK_PAD_PLUS 30
#define SK_PAD_DOT 31
#define SK_PAD_COMMA 32
#define SK_PAD_ZERO 33
#define SK_SHIFT_HOME 34
#define SK_SHIFT_END 35
#define SK_CTL_HOME 36
#define SK_CTL_END 37
#define SK_CONTROL_K 40 #define SK_CONTROL_K 40
+80 -56
View File
@@ -23,7 +23,7 @@
extern int sc_width; extern int sc_width;
extern int utf_mode; extern int utf_mode;
extern int no_hist_dups; extern int no_hist_dups;
extern int marks_modified; extern lbool marks_modified;
extern int no_paste; extern int no_paste;
public lbool pasting = FALSE; public lbool pasting = FALSE;
@@ -35,6 +35,9 @@ static int cmd_offset; /* Index into cmdbuf of first displayed char */
static lbool literal; /* Next input char should not be interpreted */ static lbool literal; /* Next input char should not be interpreted */
static size_t updown_match; /* Prefix length in up/down movement */ static size_t updown_match; /* Prefix length in up/down movement */
static lbool have_updown_match = FALSE; static lbool have_updown_match = FALSE;
#if LESS_INSERT_MODE
static lbool insert_mode = TRUE;
#endif
static int cmd_complete(int action); static int cmd_complete(int action);
/* /*
@@ -189,7 +192,7 @@ public int len_cmdbuf(void)
*/ */
public lbool cmdbuf_empty(void) public lbool cmdbuf_empty(void)
{ {
return cp == cmdbuf && cmd_mbc_buf_len == 0; return cmdbuf[0] == '\0' && cmd_mbc_buf_len == 0;
} }
/* /*
@@ -454,39 +457,6 @@ static int cmd_left(void)
return (CC_OK); return (CC_OK);
} }
/*
* Insert a char into the command buffer, at the current position.
*/
static int cmd_ichar(constant char *cs, size_t clen)
{
char *s;
if (strlen(cmdbuf) + clen >= sizeof(cmdbuf)-1)
{
/* No room in the command buffer for another char. */
bell();
return (CC_ERROR);
}
/*
* Make room for the new character (shift the tail of the buffer right).
*/
for (s = &cmdbuf[strlen(cmdbuf)]; s >= cp; s--)
s[clen] = s[0];
/*
* Insert the character into the buffer.
*/
for (s = cp; s < cp + clen; s++)
*s = *cs++;
/*
* Reprint the tail of the line from the inserted char.
*/
have_updown_match = FALSE;
cmd_repaint(cp);
cmd_right();
return (CC_OK);
}
/* /*
* Backspace in the command buffer. * Backspace in the command buffer.
* Delete the char to the left of the cursor. * Delete the char to the left of the cursor.
@@ -502,7 +472,7 @@ static int cmd_erase(void)
* Backspace past beginning of the buffer: * Backspace past beginning of the buffer:
* this usually means abort the command. * this usually means abort the command.
*/ */
return (CC_QUIT); return CC_QUIT;
} }
/* /*
* Move cursor left (to the char being erased). * Move cursor left (to the char being erased).
@@ -532,7 +502,7 @@ static int cmd_erase(void)
* to abort the current command, if CF_QUIT_ON_ERASE is set. * to abort the current command, if CF_QUIT_ON_ERASE is set.
*/ */
if ((curr_cmdflags & CF_QUIT_ON_ERASE) && cp == cmdbuf && *cp == '\0') if ((curr_cmdflags & CF_QUIT_ON_ERASE) && cp == cmdbuf && *cp == '\0')
return (CC_QUIT); return CC_QUIT;
return (CC_OK); return (CC_OK);
} }
@@ -554,6 +524,43 @@ static int cmd_delete(void)
return (CC_OK); return (CC_OK);
} }
/*
* Insert a char into the command buffer, at the current position.
*/
static int cmd_ichar(constant char *cs, size_t clen)
{
char *s;
if (strlen(cmdbuf) + clen >= sizeof(cmdbuf)-1)
{
/* No room in the command buffer for another char. */
lbell();
return (CC_ERROR);
}
#if LESS_INSERT_MODE
if (!insert_mode)
cmd_delete();
#endif
/*
* Make room for the new character (shift the tail of the buffer right).
*/
for (s = &cmdbuf[strlen(cmdbuf)]; s >= cp; s--)
s[clen] = s[0];
/*
* Insert the character into the buffer.
*/
for (s = cp; s < cp + clen; s++)
*s = *cs++;
/*
* Reprint the tail of the line from the inserted char.
*/
have_updown_match = FALSE;
cmd_repaint(cp);
cmd_right();
return (CC_OK);
}
/* /*
* Delete the "word" to the left of the cursor. * Delete the "word" to the left of the cursor.
*/ */
@@ -612,7 +619,7 @@ static int cmd_kill(void)
if (cmdbuf[0] == '\0') if (cmdbuf[0] == '\0')
{ {
/* Buffer is already empty; abort the current command. */ /* Buffer is already empty; abort the current command. */
return (CC_QUIT); return CC_QUIT;
} }
cmd_offset = 0; cmd_offset = 0;
cmd_home(); cmd_home();
@@ -625,7 +632,7 @@ static int cmd_kill(void)
* to abort the current command, if CF_QUIT_ON_ERASE is set. * to abort the current command, if CF_QUIT_ON_ERASE is set.
*/ */
if (curr_cmdflags & CF_QUIT_ON_ERASE) if (curr_cmdflags & CF_QUIT_ON_ERASE)
return (CC_QUIT); return CC_QUIT;
return (CC_OK); return (CC_OK);
} }
@@ -660,7 +667,7 @@ static int cmd_updown(int action)
/* /*
* The current command has no history list. * The current command has no history list.
*/ */
bell(); lbell();
return (CC_OK); return (CC_OK);
} }
@@ -705,7 +712,7 @@ static int cmd_updown(int action)
/* /*
* We didn't find a history entry that matches. * We didn't find a history entry that matches.
*/ */
bell(); lbell();
return (CC_OK); return (CC_OK);
} }
@@ -796,6 +803,15 @@ public void cmd_addhist(struct mlist *mlist, constant char *cmd, lbool modified)
* Thus, an UPARROW will always retrieve the previous command. * Thus, an UPARROW will always retrieve the previous command.
*/ */
mlist->curr_mp = ml->next; mlist->curr_mp = ml->next;
if (modified)
{
if (mlist == &mlist_search && autosave_action('/'))
save_cmdhist();
#if SHELL_ESCAPE || PIPEC
else if (mlist == &mlist_shell && autosave_action('!'))
save_cmdhist();
#endif
}
#endif #endif
} }
@@ -904,6 +920,9 @@ static int cmd_edit(char c, lbool stay_in_completion)
return (CC_OK); return (CC_OK);
case EC_INSERT: case EC_INSERT:
not_in_completion(); not_in_completion();
#if LESS_INSERT_MODE
insert_mode = !insert_mode;
#endif
return (CC_OK); return (CC_OK);
case EC_BACKSPACE: case EC_BACKSPACE:
not_in_completion(); not_in_completion();
@@ -914,7 +933,7 @@ static int cmd_edit(char c, lbool stay_in_completion)
case EC_ABORT: case EC_ABORT:
not_in_completion(); not_in_completion();
(void) cmd_kill(); (void) cmd_kill();
return (CC_QUIT); return CC_QUIT;
case EC_W_BACKSPACE: case EC_W_BACKSPACE:
not_in_completion(); not_in_completion();
return (cmd_werase()); return (cmd_werase());
@@ -950,17 +969,23 @@ static int cmd_istr(constant char *str)
{ {
constant char *endline = str + strlen(str); constant char *endline = str + strlen(str);
constant char *s; constant char *s;
int action; int action = CC_OK;
#if LESS_INSERT_MODE
lbool save_insert_mode = insert_mode;
insert_mode = TRUE;
#endif
for (s = str; *s != '\0'; ) for (s = str; *s != '\0'; )
{ {
constant char *os = s; constant char *os = s;
step_charc(&s, +1, endline); step_charc(&s, +1, endline);
action = cmd_ichar(os, ptr_diff(s, os)); action = cmd_ichar(os, ptr_diff(s, os));
if (action != CC_OK) if (action != CC_OK)
return (action); break;
} }
return (CC_OK); #if LESS_INSERT_MODE
insert_mode = save_insert_mode;
#endif
return (action);
} }
/* /*
@@ -1171,7 +1196,7 @@ static int cmd_complete(int action)
#endif /* TAB_COMPLETE_FILENAME */ #endif /* TAB_COMPLETE_FILENAME */
if (tk_text == NULL) if (tk_text == NULL)
{ {
bell(); lbell();
return (CC_OK); return (CC_OK);
} }
if (action == EC_EXPAND) if (action == EC_EXPAND)
@@ -1239,7 +1264,7 @@ static int cmd_complete(int action)
fail: fail:
in_completion = FALSE; in_completion = FALSE;
bell(); lbell();
return (CC_OK); return (CC_OK);
} }
@@ -1281,7 +1306,7 @@ static int cmd_uchar(char c, size_t *plen)
} else } else
{ {
/* UTF8_INVALID or stray UTF8_TRAIL */ /* UTF8_INVALID or stray UTF8_TRAIL */
bell(); lbell();
return (CC_ERROR); return (CC_ERROR);
} }
} else if (IS_UTF8_TRAIL(c)) } else if (IS_UTF8_TRAIL(c))
@@ -1293,14 +1318,14 @@ static int cmd_uchar(char c, size_t *plen)
{ {
/* complete, but not well formed (non-shortest form), sequence */ /* complete, but not well formed (non-shortest form), sequence */
cmd_mbc_buf_len = 0; cmd_mbc_buf_len = 0;
bell(); lbell();
return (CC_ERROR); return (CC_ERROR);
} }
} else } else
{ {
/* Flush incomplete (truncated) sequence. */ /* Flush incomplete (truncated) sequence. */
cmd_mbc_buf_len = 0; cmd_mbc_buf_len = 0;
bell(); lbell();
/* Handle new char. */ /* Handle new char. */
goto retry; goto retry;
} }
@@ -1388,7 +1413,6 @@ public LINENUM cmd_int(mutable long *frac)
{ {
constant char *p; constant char *p;
LINENUM n = 0; LINENUM n = 0;
lbool err;
for (p = cmdbuf; *p >= '0' && *p <= '9'; p++) for (p = cmdbuf; *p >= '0' && *p <= '9'; p++)
{ {
@@ -1401,8 +1425,8 @@ public LINENUM cmd_int(mutable long *frac)
*frac = 0; *frac = 0;
if (*p++ == '.') if (*p++ == '.')
{ {
*frac = getfraction(&p, NULL, &err); /* {{ Just ignore error in fractional part. }} */
/* {{ do something if err is set? }} */ (void) getfraction(&p, frac);
} }
return (n); return (n);
} }
@@ -1447,7 +1471,7 @@ static int mlist_size(struct mlist *ml)
static char * histfile_find(lbool must_exist) static char * histfile_find(lbool must_exist)
{ {
constant char *home = lgetenv("HOME"); constant char *home = lgetenv("HOME");
char *name = NULL; char *name;
/* Try in $XDG_STATE_HOME, then in $HOME/.local/state, then in $XDG_DATA_HOME, then in $HOME. */ /* Try in $XDG_STATE_HOME, then in $HOME/.local/state, then in $XDG_DATA_HOME, then in $HOME. */
#if OS2 #if OS2
@@ -1738,7 +1762,7 @@ public void save_cmdhist(void)
int skip_shell; int skip_shell;
struct save_ctx ctx; struct save_ctx ctx;
constant char *s; constant char *s;
FILE *fout = NULL; FILE *fout;
int histsize = 0; int histsize = 0;
if (!secure_allow(SF_HISTORY) || !histfile_modified()) if (!secure_allow(SF_HISTORY) || !histfile_modified())
+45 -40
View File
@@ -32,7 +32,7 @@ extern int jump_sline;
extern lbool quitting; extern lbool quitting;
extern int wscroll; extern int wscroll;
extern int top_scroll; extern int top_scroll;
extern int ignore_eoi; extern lbool ignore_eoi;
extern int hshift; extern int hshift;
extern int bs_mode; extern int bs_mode;
extern int proc_backspace; extern int proc_backspace;
@@ -49,7 +49,6 @@ extern void *ml_examine;
extern int wheel_lines; extern int wheel_lines;
extern int def_search_type; extern int def_search_type;
extern lbool search_wrapped; extern lbool search_wrapped;
extern lbool no_poll;
extern int no_paste; extern int no_paste;
extern lbool pasting; extern lbool pasting;
extern int no_edit_warn; extern int no_edit_warn;
@@ -154,7 +153,7 @@ static void start_mca(int action, constant char *prompt, void *mlist, int cmdfla
set_mlist(mlist, cmdflags); set_mlist(mlist, cmdflags);
} }
public int in_mca(void) public lbool in_mca(void)
{ {
return (mca != 0 && mca != A_PREFIX); return (mca != 0 && mca != A_PREFIX);
} }
@@ -476,7 +475,7 @@ static int mca_opt_nonfirst_char(char c)
} }
} else if (!ambig) } else if (!ambig)
{ {
bell(); lbell();
} }
return (MCA_MORE); return (MCA_MORE);
} }
@@ -575,7 +574,10 @@ static int mca_search_char(char c)
*/ */
if (!cmdbuf_empty() || literal_char) if (!cmdbuf_empty() || literal_char)
{ {
lbool was_literal_char = literal_char;
literal_char = FALSE; literal_char = FALSE;
if (was_literal_char)
mca_search1();
return (NO_MCA); return (NO_MCA);
} }
@@ -639,6 +641,17 @@ static int mca_search_char(char c)
return (NO_MCA); return (NO_MCA);
} }
/*
* Jump back to the starting position of an incremental search.
*/
static void jump_search_incr_pos(void)
{
if (search_incr_pos.pos == NULL_POSITION)
return;
hshift = search_incr_hshift;
jump_loc(search_incr_pos.pos, search_incr_pos.ln);
}
/* /*
* Handle a character of a multi-character command. * Handle a character of a multi-character command.
*/ */
@@ -772,30 +785,21 @@ static int mca_char(char c)
if (*pattern == '\0') if (*pattern == '\0')
{ {
/* User has backspaced to an empty pattern. */ /* User has backspaced to an empty pattern. */
undo_search(1); undo_search(TRUE);
hshift = search_incr_hshift; jump_search_incr_pos();
jump_loc(search_incr_pos.pos, search_incr_pos.ln);
} else } else
{ {
/*
* Suppress tty polling while searching.
* This avoids a problem where tty input
* can cause the search to be interrupted.
*/
no_poll = TRUE;
if (search(st | SRCH_INCR, pattern, 1) != 0) if (search(st | SRCH_INCR, pattern, 1) != 0)
{ {
/* No match, invalid pattern, etc. */ /* No match, invalid pattern, etc. */
undo_search(1); undo_search(TRUE);
hshift = search_incr_hshift; jump_search_incr_pos();
jump_loc(search_incr_pos.pos, search_incr_pos.ln);
} }
no_poll = FALSE;
} }
/* Redraw the search prompt and search string. */ /* Redraw the search prompt and search string. */
if (is_screen_trashed() || !full_screen) if (is_screen_trashed() || !full_screen)
{ {
clear(); lclear();
repaint(); repaint();
} }
mca_search1(); mca_search1();
@@ -851,7 +855,7 @@ static void make_display(void)
* We need to clear and repaint screen before any change. * We need to clear and repaint screen before any change.
*/ */
if (!full_screen && !(quit_if_one_screen && one_screen)) if (!full_screen && !(quit_if_one_screen && one_screen))
clear(); lclear();
/* /*
* If nothing is displayed yet, display starting from initial_scrpos. * If nothing is displayed yet, display starting from initial_scrpos.
*/ */
@@ -864,9 +868,9 @@ static void make_display(void)
} else if (is_screen_trashed() || !full_screen) } else if (is_screen_trashed() || !full_screen)
{ {
int save_top_scroll = top_scroll; int save_top_scroll = top_scroll;
int save_ignore_eoi = ignore_eoi; lbool save_ignore_eoi = ignore_eoi;
top_scroll = 1; top_scroll = 1;
ignore_eoi = 0; ignore_eoi = FALSE;
if (is_screen_trashed() == 2) if (is_screen_trashed() == 2)
{ {
/* Special case used by ignore_eoi: re-open the input file /* Special case used by ignore_eoi: re-open the input file
@@ -1304,29 +1308,31 @@ static void multi_search(constant char *pattern, int n, int silent)
/* /*
* Forward forever, or until a highlighted line appears. * Forward forever, or until a highlighted line appears.
*/ */
static int forw_loop(int until_hilite) static int forw_loop(int action)
{ {
POSITION curr_len; POSITION prev_hilite;
if (ch_getflags() & CH_HELPFILE) if (ch_getflags() & CH_HELPFILE)
return (A_NOACTION); return (A_NOACTION);
cmd_exec(); cmd_exec();
jump_forw_buffered(); jump_forw_buffered();
curr_len = ch_length(); highest_hilite = prev_hilite = 0;
highest_hilite = until_hilite ? curr_len : NULL_POSITION; ignore_eoi = TRUE;
ignore_eoi = 1;
while (!sigs) while (!sigs)
{ {
if (until_hilite && highest_hilite > curr_len) if (action != A_F_FOREVER && highest_hilite > prev_hilite)
{ {
bell(); lbell();
break; if (action == A_F_UNTIL_HILITE)
break;
prev_hilite = highest_hilite;
} }
make_display(); make_display();
forward(1, FALSE, FALSE, FALSE); forward(1, FALSE, FALSE, FALSE);
} }
ignore_eoi = 0; highest_hilite = NULL_POSITION;
ignore_eoi = FALSE;
ch_set_eof(); ch_set_eof();
/* /*
@@ -1334,7 +1340,7 @@ static int forw_loop(int until_hilite)
* a non-abort signal (e.g. window-change). * a non-abort signal (e.g. window-change).
*/ */
if (sigs && !ABORT_SIGS()) if (sigs && !ABORT_SIGS())
return (until_hilite ? A_F_UNTIL_HILITE : A_F_FOREVER); return (action);
return (A_NOACTION); return (A_NOACTION);
} }
@@ -1401,7 +1407,6 @@ public void commands(void)
#endif #endif
search_type = SRCH_FORW; search_type = SRCH_FORW;
wscroll = (sc_height + 1) / 2;
newaction = A_NOACTION; newaction = A_NOACTION;
for (;;) for (;;)
@@ -1507,7 +1512,9 @@ public void commands(void)
* want erase_char/kill_char to be treated * want erase_char/kill_char to be treated
* as line editing characters. * as line editing characters.
*/ */
constant char tbuf[2] = { c, '\0' }; char tbuf[2];
tbuf[0] = c;
tbuf[1] = '\0';
action = fcmd_decode(tbuf, &extra); action = fcmd_decode(tbuf, &extra);
} }
/* /*
@@ -1664,6 +1671,8 @@ public void commands(void)
break; break;
case A_F_FOREVER: case A_F_FOREVER:
case A_F_FOREVER_BELL:
case A_F_UNTIL_HILITE:
/* /*
* Forward forever, ignoring EOF. * Forward forever, ignoring EOF.
*/ */
@@ -1671,11 +1680,7 @@ public void commands(void)
error("Warning: command may not work correctly when file is viewed via LESSOPEN", NULL_PARG); error("Warning: command may not work correctly when file is viewed via LESSOPEN", NULL_PARG);
if (show_attn) if (show_attn)
set_attnpos(bottompos); set_attnpos(bottompos);
newaction = forw_loop(0); newaction = forw_loop(action);
break;
case A_F_UNTIL_HILITE:
newaction = forw_loop(1);
break; break;
case A_F_SCROLL: case A_F_SCROLL:
@@ -2143,7 +2148,7 @@ public void commands(void)
cmd_exec(); cmd_exec();
if (new_ifile == NULL_IFILE) if (new_ifile == NULL_IFILE)
{ {
bell(); lbell();
break; break;
} }
if (edit_ifile(new_ifile) != 0) if (edit_ifile(new_ifile) != 0)
@@ -2353,7 +2358,7 @@ public void commands(void)
break; break;
default: default:
bell(); lbell();
break; break;
} }
} }
+11 -3
View File
@@ -1,4 +1,4 @@
/* Generated by "./mkutable -f2 Mn Me -- unicode/UnicodeData.txt" on Aug 11 0:27:25 GMT 2025 */ /* Generated by "./mkutable -f2 Mn Me -- unicode/UnicodeData.txt" on Nov 28 1:30:11 GMT 2025 */
{ 0x0300, 0x036f }, /* Mn */ { 0x0300, 0x036f }, /* Mn */
{ 0x0483, 0x0487 }, /* Mn */ { 0x0483, 0x0487 }, /* Mn */
{ 0x0488, 0x0489 }, /* Me */ { 0x0488, 0x0489 }, /* Me */
@@ -144,7 +144,8 @@
{ 0x1a7f, 0x1a7f }, /* Mn */ { 0x1a7f, 0x1a7f }, /* Mn */
{ 0x1ab0, 0x1abd }, /* Mn */ { 0x1ab0, 0x1abd }, /* Mn */
{ 0x1abe, 0x1abe }, /* Me */ { 0x1abe, 0x1abe }, /* Me */
{ 0x1abf, 0x1ace }, /* Mn */ { 0x1abf, 0x1add }, /* Mn */
{ 0x1ae0, 0x1aeb }, /* Mn */
{ 0x1b00, 0x1b03 }, /* Mn */ { 0x1b00, 0x1b03 }, /* Mn */
{ 0x1b34, 0x1b34 }, /* Mn */ { 0x1b34, 0x1b34 }, /* Mn */
{ 0x1b36, 0x1b3a }, /* Mn */ { 0x1b36, 0x1b3a }, /* Mn */
@@ -230,7 +231,7 @@
{ 0x10d24, 0x10d27 }, /* Mn */ { 0x10d24, 0x10d27 }, /* Mn */
{ 0x10d69, 0x10d6d }, /* Mn */ { 0x10d69, 0x10d6d }, /* Mn */
{ 0x10eab, 0x10eac }, /* Mn */ { 0x10eab, 0x10eac }, /* Mn */
{ 0x10efc, 0x10eff }, /* Mn */ { 0x10efa, 0x10eff }, /* Mn */
{ 0x10f46, 0x10f50 }, /* Mn */ { 0x10f46, 0x10f50 }, /* Mn */
{ 0x10f82, 0x10f85 }, /* Mn */ { 0x10f82, 0x10f85 }, /* Mn */
{ 0x11001, 0x11001 }, /* Mn */ { 0x11001, 0x11001 }, /* Mn */
@@ -305,6 +306,9 @@
{ 0x11a59, 0x11a5b }, /* Mn */ { 0x11a59, 0x11a5b }, /* Mn */
{ 0x11a8a, 0x11a96 }, /* Mn */ { 0x11a8a, 0x11a96 }, /* Mn */
{ 0x11a98, 0x11a99 }, /* Mn */ { 0x11a98, 0x11a99 }, /* Mn */
{ 0x11b60, 0x11b60 }, /* Mn */
{ 0x11b62, 0x11b64 }, /* Mn */
{ 0x11b66, 0x11b66 }, /* Mn */
{ 0x11c30, 0x11c36 }, /* Mn */ { 0x11c30, 0x11c36 }, /* Mn */
{ 0x11c38, 0x11c3d }, /* Mn */ { 0x11c38, 0x11c3d }, /* Mn */
{ 0x11c3f, 0x11c3f }, /* Mn */ { 0x11c3f, 0x11c3f }, /* Mn */
@@ -360,5 +364,9 @@
{ 0x1e2ec, 0x1e2ef }, /* Mn */ { 0x1e2ec, 0x1e2ef }, /* Mn */
{ 0x1e4ec, 0x1e4ef }, /* Mn */ { 0x1e4ec, 0x1e4ef }, /* Mn */
{ 0x1e5ee, 0x1e5ef }, /* Mn */ { 0x1e5ee, 0x1e5ef }, /* Mn */
{ 0x1e6e3, 0x1e6e3 }, /* Mn */
{ 0x1e6e6, 0x1e6e6 }, /* Mn */
{ 0x1e6ee, 0x1e6ef }, /* Mn */
{ 0x1e6f5, 0x1e6f5 }, /* Mn */
{ 0x1e8d0, 0x1e8d6 }, /* Mn */ { 0x1e8d0, 0x1e8d6 }, /* Mn */
{ 0x1e944, 0x1e94a }, /* Mn */ { 0x1e944, 0x1e94a }, /* Mn */
+94 -7
View File
@@ -36,6 +36,7 @@
extern int erase_char, erase2_char, kill_char; extern int erase_char, erase2_char, kill_char;
extern int mousecap; extern int mousecap;
extern int sc_height; extern int sc_height;
extern char *no_config;
static constant lbool allow_drag = TRUE; static constant lbool allow_drag = TRUE;
@@ -92,6 +93,7 @@ static unsigned char cmdtable[] =
ESC,'j',0, A_F_NEWLINE, ESC,'j',0, A_F_NEWLINE,
ESC,'k',0, A_B_NEWLINE, ESC,'k',0, A_B_NEWLINE,
'F',0, A_F_FOREVER, 'F',0, A_F_FOREVER,
ESC,'f',0, A_F_FOREVER_BELL,
ESC,'F',0, A_F_UNTIL_HILITE, ESC,'F',0, A_F_UNTIL_HILITE,
'R',0, A_FREPAINT, 'R',0, A_FREPAINT,
'r',0, A_REPAINT, 'r',0, A_REPAINT,
@@ -100,7 +102,12 @@ static unsigned char cmdtable[] =
ESC,'u',0, A_UNDO_SEARCH, ESC,'u',0, A_UNDO_SEARCH,
ESC,'U',0, A_CLR_SEARCH, ESC,'U',0, A_CLR_SEARCH,
'g',0, A_GOLINE, 'g',0, A_GOLINE,
SK(SK_HOME),0, A_GOLINE, SK(SK_HOME),0, A_LLSHIFT,
SK(SK_SHIFT_HOME),0, A_GOLINE|A_EXTRA, ESC,'{',0,
SK(SK_CTL_HOME),0, A_GOLINE|A_EXTRA, ESC,'{',0,
SK(SK_END),0, A_RRSHIFT,
SK(SK_SHIFT_END),0, A_GOEND|A_EXTRA, ESC,'}',0,
SK(SK_CTL_END),0, A_GOEND|A_EXTRA, ESC,'}',0,
'<',0, A_GOLINE, '<',0, A_GOLINE,
ESC,'<',0, A_GOLINE, ESC,'<',0, A_GOLINE,
'p',0, A_PERCENT, 'p',0, A_PERCENT,
@@ -125,7 +132,6 @@ static unsigned char cmdtable[] =
ESC,'G',0, A_GOEND_BUF, ESC,'G',0, A_GOEND_BUF,
ESC,'>',0, A_GOEND, ESC,'>',0, A_GOEND,
'>',0, A_GOEND, '>',0, A_GOEND,
SK(SK_END),0, A_GOEND,
'P',0, A_GOPOS, 'P',0, A_GOPOS,
'0',0, A_DIGIT, '0',0, A_DIGIT,
@@ -183,6 +189,24 @@ static unsigned char cmdtable[] =
'!',0, A_SHELL, '!',0, A_SHELL,
'#',0, A_PSHELL, '#',0, A_PSHELL,
'+',0, A_FIRSTCMD, '+',0, A_FIRSTCMD,
SK(SK_PAD_U),0, A_B_LINE,
SK(SK_PAD_D),0, A_F_LINE,
SK(SK_PAD_R),0, A_RSHIFT,
SK(SK_PAD_L),0, A_LSHIFT,
SK(SK_PAD_UR),0, A_B_SCREEN,
SK(SK_PAD_UL),0, A_LLSHIFT,
SK(SK_PAD_DR),0, A_RRSHIFT,
SK(SK_PAD_DL),0, A_GOEND,
SK(SK_PAD_STAR),0, A_NOACTION|A_EXTRA, '*',0,
SK(SK_PAD_SLASH),0, A_NOACTION|A_EXTRA, '/',0,
SK(SK_PAD_DASH),0, A_NOACTION|A_EXTRA, '-',0,
SK(SK_PAD_PLUS),0, A_NOACTION|A_EXTRA, '+',0,
SK(SK_PAD_DOT),0, A_NOACTION|A_EXTRA, '.',0,
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,
ESC,'[','2','0','0','~',0, A_START_PASTE, ESC,'[','2','0','0','~',0, A_START_PASTE,
ESC,'[','2','0','1','~',0, A_END_PASTE, ESC,'[','2','0','1','~',0, A_END_PASTE,
@@ -227,13 +251,33 @@ static unsigned char edittable[] =
ESC,SK(SK_BACKSPACE),0, EC_W_BACKSPACE, /* ESC BACKSPACE */ ESC,SK(SK_BACKSPACE),0, EC_W_BACKSPACE, /* ESC BACKSPACE */
ESC,'0',0, EC_HOME, /* ESC 0 */ ESC,'0',0, EC_HOME, /* ESC 0 */
SK(SK_HOME),0, EC_HOME, /* HOME */ SK(SK_HOME),0, EC_HOME, /* HOME */
SK(SK_SHIFT_HOME),0, EC_HOME, /* SHIFT-HOME */
SK(SK_CTL_HOME),0, EC_HOME, /* CTRL-HOME */
ESC,'$',0, EC_END, /* ESC $ */ ESC,'$',0, EC_END, /* ESC $ */
SK(SK_END),0, EC_END, /* END */ SK(SK_END),0, EC_END, /* END */
SK(SK_SHIFT_END),0, EC_END, /* SHIFT-END */
SK(SK_CTL_END),0, EC_END, /* CTRL-END */
ESC,'k',0, EC_UP, /* ESC k */ ESC,'k',0, EC_UP, /* ESC k */
SK(SK_UP_ARROW),0, EC_UP, /* UPARROW */ SK(SK_UP_ARROW),0, EC_UP, /* UPARROW */
ESC,'j',0, EC_DOWN, /* ESC j */ ESC,'j',0, EC_DOWN, /* ESC j */
SK(SK_DOWN_ARROW),0, EC_DOWN, /* DOWNARROW */ SK(SK_DOWN_ARROW),0, EC_DOWN, /* DOWNARROW */
CONTROL('G'),0, EC_ABORT, /* CTRL-G */ CONTROL('G'),0, EC_ABORT, /* CTRL-G */
SK(SK_PAD_U),0, EC_UP,
SK(SK_PAD_D),0, EC_DOWN,
SK(SK_PAD_R),0, EC_RIGHT,
SK(SK_PAD_L),0, EC_LEFT,
SK(SK_PAD_UR),0, A_NOACTION,
SK(SK_PAD_UL),0, EC_HOME,
SK(SK_PAD_DR),0, A_NOACTION,
SK(SK_PAD_DL),0, EC_END,
SK(SK_PAD_STAR),0, A_NOACTION|A_EXTRA, '*',0,
SK(SK_PAD_SLASH),0, A_NOACTION|A_EXTRA, '/',0,
SK(SK_PAD_DASH),0, A_NOACTION|A_EXTRA, '-',0,
SK(SK_PAD_PLUS),0, A_NOACTION|A_EXTRA, '+',0,
SK(SK_PAD_DOT),0, A_NOACTION|A_EXTRA, '.',0,
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,
ESC,'[','M',0, EC_X11MOUSE, /* X11 mouse report */ ESC,'[','M',0, EC_X11MOUSE, /* X11 mouse report */
ESC,'[','<',0, EC_X116MOUSE, /* X11 1006 mouse report */ ESC,'[','<',0, EC_X116MOUSE, /* X11 1006 mouse report */
ESC,'[','2','0','0','~',0, A_START_PASTE, /* open paste bracket */ ESC,'[','2','0','0','~',0, A_START_PASTE, /* open paste bracket */
@@ -549,8 +593,11 @@ static int mouse_button_left(int x, int y, lbool down, lbool drag)
} else if (!down) } else if (!down)
{ {
#if OSC8_LINK #if OSC8_LINK
if (osc8_click(y, x)) if (secure_allow(SF_OSC8_OPEN))
return (A_NOACTION); {
if (osc8_click(y, x))
return (A_NOACTION);
}
#else #else
(void) x; (void) x;
#endif /* OSC8_LINK */ #endif /* OSC8_LINK */
@@ -738,7 +785,7 @@ static int cmd_search(constant char *cmd, constant unsigned char *table, constan
while (table < endtable) while (table < endtable)
{ {
int taction; int taction;
const unsigned char *textra; constant unsigned char *textra;
size_t cmdlen; size_t cmdlen;
size_t match = cmd_match((constant char *) table, cmd); size_t match = cmd_match((constant char *) table, cmd);
table = cmd_next_entry(table, &taction, &textra, &cmdlen); table = cmd_next_entry(table, &taction, &textra, &cmdlen);
@@ -821,6 +868,44 @@ public int ecmd_decode(constant char *cmd, constant char **sp)
return (cmd_decode(list_ecmd_tables, cmd, sp)); return (cmd_decode(list_ecmd_tables, cmd, sp));
} }
/*
* Parse a comma-separated list.
* Call func repeatedly, passing each item in the list.
* Stop and return FALSE if func ever returns FALSE,
* otherwise parse the entire list and return TRUE.
*/
public lbool parse_csl(lbool (*func)(constant char *word, size_t wlen, void *arg), constant char *str, void *arg)
{
for (;;)
{
constant char *estr;
while (*str == ' ' || *str == ',') ++str; /* skip leading spaces/commas */
if (*str == '\0') break;
estr = strchr(str, ',');
if (estr == NULL) estr = str + strlen(str);
while (estr > str && estr[-1] == ' ') --estr; /* trim trailing spaces */
if (!(*func)(str, ptr_diff(estr, str), arg))
return FALSE;
str = estr;
}
return TRUE;
}
/*
* Should we ignore the setting of an environment variable?
*/
static lbool word_no_match(constant char *word, size_t wlen, void *arg)
{
constant char *var = (constant char *) arg;
return !(wlen == strlen(var) && strncmp(var, word, wlen) == 0);
}
static lbool ignore_env(constant char *var)
{
if (isnullenv(no_config))
return FALSE; /* no_config is not set; don't ignore anything */
/* no_config is set; ignore any var that does not appear in no_config */
return parse_csl(word_no_match, no_config, (void*) var);
}
/* /*
* Get the value of an environment variable. * Get the value of an environment variable.
@@ -831,6 +916,8 @@ public constant char * lgetenv(constant char *var)
int a; int a;
constant char *s; constant char *s;
if (ignore_env(var))
return (NULL);
a = cmd_decode(list_var_tables, var, &s); a = cmd_decode(list_var_tables, var, &s);
if (a == EV_OK) if (a == EV_OK)
return (s); return (s);
@@ -986,7 +1073,7 @@ public int lesskey(constant char *filename, lbool sysvar)
ssize_t n; ssize_t n;
int f; int f;
if (!secure_allow(SF_LESSKEY)) if (!secure_allow(SF_LESSKEY) || !isnullenv(no_config))
return (1); return (1);
/* /*
* Try to open the lesskey file. * Try to open the lesskey file.
@@ -1048,7 +1135,7 @@ static int lesskey_text(constant char *filename, lbool sysvar, lbool content)
int r; int r;
static struct lesskey_tables tables; static struct lesskey_tables tables;
if (!secure_allow(SF_LESSKEY)) if (!secure_allow(SF_LESSKEY) || !isnullenv(no_config))
return (1); return (1);
r = content ? parse_lesskey_content(filename, &tables) : parse_lesskey(filename, &tables); r = content ? parse_lesskey_content(filename, &tables) : parse_lesskey(filename, &tables);
if (r != 0) if (r != 0)
+6 -8
View File
@@ -77,20 +77,20 @@ public void init_textlist(struct textlist *tlist, mutable char *str)
#if SPACES_IN_FILENAMES #if SPACES_IN_FILENAMES
if (meta_quoted) if (meta_quoted)
{ {
meta_quoted = 0; meta_quoted = FALSE;
} else if (esclen > 0 && s + esclen < tlist->endstring && } else if (esclen > 0 && s + esclen < tlist->endstring &&
strncmp(s, esc, esclen) == 0) strncmp(s, esc, esclen) == 0)
{ {
meta_quoted = 1; meta_quoted = TRUE;
s += esclen - 1; s += esclen - 1;
} else if (delim_quoted) } else if (delim_quoted)
{ {
if (*s == closequote) if (*s == closequote)
delim_quoted = 0; delim_quoted = FALSE;
} else /* (!delim_quoted) */ } else /* (!delim_quoted) */
{ {
if (*s == openquote) if (*s == openquote)
delim_quoted = 1; delim_quoted = TRUE;
else if (*s == ' ') else if (*s == ' ')
*s = '\0'; *s = '\0';
} }
@@ -101,7 +101,7 @@ public void init_textlist(struct textlist *tlist, mutable char *str)
} }
} }
public constant char * forw_textlist(struct textlist *tlist, constant char *prev) public constant char * forw_textlist(constant struct textlist *tlist, constant char *prev)
{ {
constant char *s; constant char *s;
@@ -120,7 +120,7 @@ public constant char * forw_textlist(struct textlist *tlist, constant char *prev
return (s); return (s);
} }
public constant char * back_textlist(struct textlist *tlist, constant char *prev) public constant char * back_textlist(constant struct textlist *tlist, constant char *prev)
{ {
constant char *s; constant char *s;
@@ -210,7 +210,6 @@ static void modeline_options(constant char *str, char end_char)
*/ */
static void check_modeline(constant char *line) static void check_modeline(constant char *line)
{ {
#if HAVE_STRSTR
static constant char *pgms[] = { "less:", "vim:", "vi:", "ex:", NULL }; static constant char *pgms[] = { "less:", "vim:", "vi:", "ex:", NULL };
constant char **pgm; constant char **pgm;
for (pgm = pgms; *pgm != NULL; ++pgm) for (pgm = pgms; *pgm != NULL; ++pgm)
@@ -235,7 +234,6 @@ static void check_modeline(constant char *line)
pline = str; pline = str;
} }
} }
#endif /* HAVE_STRSTR */
} }
/* /*
+7 -6
View File
@@ -469,7 +469,7 @@ public char * fcomplete(constant char *s)
* be used later to compare to st_size from stat(2) to see if the file * be used later to compare to st_size from stat(2) to see if the file
* is lying about its size. * is lying about its size.
*/ */
public int bin_file(int f, ssize_t *n) public lbool bin_file(int f, ssize_t *n)
{ {
int bin_count = 0; int bin_count = 0;
char data[256]; char data[256];
@@ -477,12 +477,12 @@ public int bin_file(int f, ssize_t *n)
constant char* edata; constant char* edata;
if (!seekable(f)) if (!seekable(f))
return (0); return FALSE;
if (less_lseek(f, (less_off_t)0, SEEK_SET) == BAD_LSEEK) if (less_lseek(f, (less_off_t)0, SEEK_SET) == BAD_LSEEK)
return (0); return FALSE;
*n = read(f, data, sizeof(data)); *n = read(f, data, sizeof(data));
if (*n <= 0) if (*n <= 0)
return (0); return FALSE;
edata = &data[*n]; edata = &data[*n];
for (p = data; p < edata; ) for (p = data; p < edata; )
{ {
@@ -569,9 +569,10 @@ static FILE * shellcmd(constant char *cmd)
fd = popen(cmd, "r"); fd = popen(cmd, "r");
} else } else
{ {
size_t len = strlen(shell) + strlen(esccmd) + 5; constant char *copt = shell_coption();
size_t len = strlen(shell) + strlen(esccmd) + strlen(copt) + 3;
scmd = (char *) ecalloc(len, sizeof(char)); scmd = (char *) ecalloc(len, sizeof(char));
SNPRINTF3(scmd, len, "%s %s %s", shell, shell_coption(), esccmd); SNPRINTF3(scmd, len, "%s %s %s", shell, copt, esccmd);
free(esccmd); free(esccmd);
fd = popen(scmd, "r"); fd = popen(scmd, "r");
free(scmd); free(scmd);
+1 -1
View File
@@ -1,4 +1,4 @@
/* Generated by "./mkutable -f2 Cf -- unicode/UnicodeData.txt" on Jul 27 19:38:50 GMT 2025 */ /* Generated by "./mkutable -f2 Cf -- unicode/UnicodeData.txt" on Nov 28 1:30:12 GMT 2025 */
{ 0x0600, 0x0605 }, /* Cf */ { 0x0600, 0x0605 }, /* Cf */
{ 0x061c, 0x061c }, /* Cf */ { 0x061c, 0x061c }, /* Cf */
{ 0x06dd, 0x06dd }, /* Cf */ { 0x06dd, 0x06dd }, /* Cf */
+19 -16
View File
@@ -36,7 +36,7 @@ extern int auto_wrap;
extern lbool plusoption; extern lbool plusoption;
extern int forw_scroll; extern int forw_scroll;
extern int back_scroll; extern int back_scroll;
extern int ignore_eoi; extern lbool ignore_eoi;
extern int header_lines; extern int header_lines;
extern int header_cols; extern int header_cols;
extern int full_screen; extern int full_screen;
@@ -66,7 +66,7 @@ public void eof_bell(void)
} }
#endif #endif
if (quiet == NOT_QUIET) if (quiet == NOT_QUIET)
bell(); lbell();
else else
vbell(); vbell();
} }
@@ -218,12 +218,13 @@ public int overlay_header(void)
* The first real line after the blanks will start at ch_zero(). * The first real line after the blanks will start at ch_zero().
* "to_newline" means count file lines rather than screen lines. * "to_newline" means count file lines rather than screen lines.
*/ */
public void forw(int n, POSITION pos, lbool force, lbool only_last, lbool to_newline, int nblank) public void forw(int n, POSITION pos, lbool force, lbool only_last, lbool to_newline, lbool do_stop_on_form_feed, int nblank)
{ {
int nlines = 0; int nlines = 0;
lbool do_repaint; lbool do_repaint;
lbool newline; lbool newline;
lbool first_line = TRUE; lbool first_line = TRUE;
lbool need_home = FALSE;
if (pos != NULL_POSITION) if (pos != NULL_POSITION)
pos = after_header_pos(pos); pos = after_header_pos(pos);
@@ -252,10 +253,7 @@ public void forw(int n, POSITION pos, lbool force, lbool only_last, lbool to_new
*/ */
pos_clear(); pos_clear();
force = TRUE; force = TRUE;
if (less_is_more == 0) { need_home = (less_is_more == 0) ? TRUE : FALSE;
clear();
home();
}
} }
if (pos != position(BOTTOM_PLUS_ONE) || empty_screen()) if (pos != position(BOTTOM_PLUS_ONE) || empty_screen())
@@ -269,8 +267,7 @@ public void forw(int n, POSITION pos, lbool force, lbool only_last, lbool to_new
force = TRUE; force = TRUE;
if (top_scroll) if (top_scroll)
{ {
clear(); need_home = TRUE;
home();
} else if (!first_time && !is_filtering() && full_screen) } else if (!first_time && !is_filtering() && full_screen)
{ {
putstr("...skipping...\n"); putstr("...skipping...\n");
@@ -331,6 +328,12 @@ public void forw(int n, POSITION pos, lbool force, lbool only_last, lbool to_new
nlines++; nlines++;
if (do_repaint) if (do_repaint)
continue; continue;
if (need_home)
{
lclear();
home();
need_home = FALSE;
}
/* /*
* If this is the first screen displayed and * If this is the first screen displayed and
* we hit an early EOF (i.e. before the requested * we hit an early EOF (i.e. before the requested
@@ -353,13 +356,13 @@ public void forw(int n, POSITION pos, lbool force, lbool only_last, lbool to_new
continue; continue;
} }
put_line(TRUE); put_line(TRUE);
if (stop_on_form_feed && !do_repaint && line_is_ff() && position(TOP) != NULL_POSITION) if (do_stop_on_form_feed && !do_repaint && line_is_ff() && position(TOP) != NULL_POSITION)
break; break;
forw_prompt = 1; forw_prompt = 1;
} }
if (!first_line) if (!first_line)
add_forw_pos(pos, FALSE); add_forw_pos(pos, FALSE);
if (nlines == 0 && !ignore_eoi && !ABORT_SIGS()) if (nlines == 0 && !ignore_eoi)
eof_bell(); eof_bell();
else if (do_repaint) else if (do_repaint)
repaint(); repaint();
@@ -375,7 +378,7 @@ public void forw(int n, POSITION pos, lbool force, lbool only_last, lbool to_new
/* /*
* Display n lines, scrolling backward. * Display n lines, scrolling backward.
*/ */
public void back(int n, POSITION pos, lbool force, lbool only_last, lbool to_newline) public void back(int n, POSITION pos, lbool force, lbool only_last, lbool to_newline, lbool do_stop_on_form_feed)
{ {
int nlines = 0; int nlines = 0;
lbool do_repaint; lbool do_repaint;
@@ -418,7 +421,7 @@ public void back(int n, POSITION pos, lbool force, lbool only_last, lbool to_new
home(); home();
add_line(); add_line();
put_line(FALSE); put_line(FALSE);
if (stop_on_form_feed && line_is_ff()) if (do_stop_on_form_feed && line_is_ff())
break; break;
} }
} }
@@ -469,7 +472,7 @@ public void forward(int n, lbool force, lbool only_last, lbool to_newline)
{ {
do do
{ {
back(1, position(TOP), TRUE, FALSE, FALSE); back(1, position(TOP), TRUE, FALSE, FALSE, stop_on_form_feed);
pos = position(BOTTOM_PLUS_ONE); pos = position(BOTTOM_PLUS_ONE);
} while (pos == NULL_POSITION && !ABORT_SIGS()); } while (pos == NULL_POSITION && !ABORT_SIGS());
} }
@@ -479,7 +482,7 @@ public void forward(int n, lbool force, lbool only_last, lbool to_newline)
return; return;
} }
} }
forw(n, pos, force, only_last, to_newline, 0); forw(n, pos, force, only_last, to_newline, stop_on_form_feed, 0);
} }
/* /*
@@ -496,7 +499,7 @@ public void backward(int n, lbool force, lbool only_last, lbool to_newline)
eof_bell(); eof_bell();
return; return;
} }
back(n, pos, force, only_last, to_newline); back(n, pos, force, only_last, to_newline, stop_on_form_feed);
} }
/* /*
+40 -35
View File
@@ -8,17 +8,18 @@ public size_t sprefix(constant char *ps, constant char *s, int uppercase);
public void quit(int status); public void quit(int status);
public int secure_allow(int features); public int secure_allow(int features);
public void raw_mode(int on); public void raw_mode(int on);
public void scrsize(void);
public void screen_size_changed(void); public void screen_size_changed(void);
public constant char * special_key_str(int key); public constant char * special_key_str(int key);
public void init_win_colors(void); public void init_win_colors(void);
public void get_term(void); public void get_term();
public void init_mouse(void); public void init_mouse(void);
public void deinit_mouse(void); public void deinit_mouse(void);
public void suspend_screen(void); public void suspend_screen(void);
public void resume_screen(void); public void resume_screen(void);
public void init(void); public void term_init(void);
public void deinit(void); public void term_deinit(void);
public int interactive(void); public lbool interactive(void);
public void home(void); public void home(void);
public void dump_screen(void); public void dump_screen(void);
public void add_line(void); public void add_line(void);
@@ -29,8 +30,8 @@ public void line_left(void);
public void check_winch(void); public void check_winch(void);
public void goto_line(int sindex); public void goto_line(int sindex);
public void vbell(void); public void vbell(void);
public void bell(void); public void lbell(void);
public void clear(void); public void lclear(void);
public void clear_eol(void); public void clear_eol(void);
public void clear_bot(void); public void clear_bot(void);
public void init_bracketed_paste(void); public void init_bracketed_paste(void);
@@ -45,7 +46,7 @@ public void putbs(void);
public void WIN32ungetch(int ch); public void WIN32ungetch(int ch);
public lbool win32_kbhit2(lbool no_queued); public lbool win32_kbhit2(lbool no_queued);
public lbool win32_kbhit(void); public lbool win32_kbhit(void);
public char WIN32getch(void); public int WIN32getch(void);
public void win32_getch_clear(void); public void win32_getch_clear(void);
public void WIN32setcolors(int fg, int bg); public void WIN32setcolors(int fg, int bg);
public void WIN32textout(constant char *text, size_t len); public void WIN32textout(constant char *text, size_t len);
@@ -106,7 +107,7 @@ public constant char * cmd_lastpattern(void);
public void init_cmdhist(void); public void init_cmdhist(void);
public void save_cmdhist(void); public void save_cmdhist(void);
public void cmd_exec(void); public void cmd_exec(void);
public int in_mca(void); public lbool in_mca(void);
public int norm_search_type(int st); public int norm_search_type(int st);
public void screen_trashed_num(int trashed); public void screen_trashed_num(int trashed);
public void screen_trashed(void); public void screen_trashed(void);
@@ -134,6 +135,7 @@ public void add_uvar_table(unsigned char *buf, size_t len);
public void add_sysvar_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 fcmd_decode(constant char *cmd, constant char **sp);
public int ecmd_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 constant char * lgetenv(constant char *var); public constant char * lgetenv(constant char *var);
public constant char * lgetenv_ext(constant char *var, unsigned char *env_buf, size_t env_buf_len); public constant char * lgetenv_ext(constant char *var, unsigned char *env_buf, size_t env_buf_len);
public lbool isnullenv(constant char *s); public lbool isnullenv(constant char *s);
@@ -142,8 +144,8 @@ public int lesskey_src(constant char *filename, lbool sysvar);
public int lesskey_content(constant char *content, lbool sysvar); public int lesskey_content(constant char *content, lbool sysvar);
public int editchar(char c, int flags); public int editchar(char c, int flags);
public void init_textlist(struct textlist *tlist, mutable char *str); public void init_textlist(struct textlist *tlist, mutable char *str);
public constant char * forw_textlist(struct textlist *tlist, constant char *prev); public constant char * forw_textlist(constant struct textlist *tlist, constant char *prev);
public constant char * back_textlist(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_altpipe(IFILE ifile);
public void check_altpipe_error(void); public void check_altpipe_error(void);
public int edit(constant char *filename); public int edit(constant char *filename);
@@ -170,7 +172,7 @@ public char * dirfile(constant char *dirname, constant char *filename, int must_
public char * homefile(constant char *filename); public char * homefile(constant char *filename);
public char * fexpand(constant char *s); public char * fexpand(constant char *s);
public char * fcomplete(constant char *s); public char * fcomplete(constant char *s);
public int bin_file(int f, ssize_t *n); public lbool bin_file(int f, ssize_t *n);
public char * readfd(FILE *fd); public char * readfd(FILE *fd);
public char * lglob(constant char *afilename); public char * lglob(constant char *afilename);
public lbool is_fake_pathname(constant char *path); public lbool is_fake_pathname(constant char *path);
@@ -188,8 +190,8 @@ public lbool eof_displayed(lbool offset);
public lbool entire_file_displayed(void); public lbool entire_file_displayed(void);
public void squish_check(void); public void squish_check(void);
public int overlay_header(void); public int overlay_header(void);
public void forw(int n, POSITION pos, lbool force, lbool only_last, lbool to_newline, int nblank); public void forw(int n, POSITION pos, lbool force, lbool only_last, lbool to_newline, lbool do_stop_on_form_feed, int nblank);
public void back(int n, POSITION pos, lbool force, lbool only_last, lbool to_newline); public void back(int n, POSITION pos, lbool force, lbool only_last, lbool to_newline, lbool do_stop_on_form_feed);
public void forward(int n, lbool force, lbool only_last, lbool to_newline); public void forward(int n, lbool force, lbool only_last, lbool to_newline);
public void backward(int n, lbool force, lbool only_last, lbool to_newline); public void backward(int n, lbool force, lbool only_last, lbool to_newline);
public int get_back_scroll(void); public int get_back_scroll(void);
@@ -203,10 +205,10 @@ public IFILE get_ifile(constant char *filename, IFILE prev);
public constant char * get_filename(IFILE ifile); public constant char * get_filename(IFILE ifile);
public constant char * get_real_filename(IFILE ifile); public constant char * get_real_filename(IFILE ifile);
public int get_index(IFILE ifile); public int get_index(IFILE ifile);
public void store_pos(IFILE ifile, struct scrpos *scrpos); public void store_pos(IFILE ifile, constant struct scrpos *scrpos);
public void get_pos(IFILE ifile, struct scrpos *scrpos); public void get_pos(IFILE ifile, struct scrpos *scrpos);
public void set_open(IFILE ifile); public void set_open(IFILE ifile);
public int opened(IFILE ifile); public lbool opened(IFILE ifile);
public void hold_ifile(IFILE ifile, int incr); public void hold_ifile(IFILE ifile, int incr);
public int held_ifile(IFILE ifile); public int held_ifile(IFILE ifile);
public void * get_filestate(IFILE ifile); public void * get_filestate(IFILE ifile);
@@ -264,6 +266,7 @@ public POSITION forw_raw_line(POSITION curr_pos, constant char **linep, size_t *
public POSITION back_raw_line(POSITION curr_pos, constant char **linep, size_t *line_lenp); public POSITION back_raw_line(POSITION curr_pos, constant char **linep, size_t *line_lenp);
public int skip_columns(int cols, constant char **linep, size_t *line_lenp); public int skip_columns(int cols, constant char **linep, size_t *line_lenp);
public void load_line(constant char *str); public void load_line(constant char *str);
public int longest_line_width(void);
public int rrshift(void); public int rrshift(void);
public int set_color_map(int attr, constant char *colorstr); public int set_color_map(int attr, constant char *colorstr);
public constant char * get_color_map(int attr); public constant char * get_color_map(int attr);
@@ -278,7 +281,7 @@ public void lsystem(constant char *cmd, constant char *donemsg);
public int pipe_mark(char c, constant char *cmd); public int pipe_mark(char c, constant char *cmd);
public int pipe_data(constant char *cmd, POSITION spos, POSITION epos); public int pipe_data(constant char *cmd, POSITION spos, POSITION epos);
public void init_mark(void); public void init_mark(void);
public int badmark(char c); public lbool badmark(char c);
public void setmark(char c, int where); public void setmark(char c, int where);
public void clrmark(char c); public void clrmark(char c);
public void lastmark(void); public void lastmark(void);
@@ -303,6 +306,7 @@ public void opt_t(int type, constant char *s);
public void opt__T(int type, constant char *s); public void opt__T(int type, constant char *s);
public void opt_p(int type, constant char *s); public void opt_p(int type, constant char *s);
public void opt__P(int type, constant char *s); public void opt__P(int type, constant char *s);
public void opt_autosave(int type, constant char *s);
public void opt_b(int type, constant char *s); public void opt_b(int type, constant char *s);
public void opt_i(int type, constant char *s); public void opt_i(int type, constant char *s);
public void opt__V(int type, constant char *s); public void opt__V(int type, constant char *s);
@@ -321,7 +325,6 @@ public void opt_status_col_width(int type, constant char *s);
public void opt_filesize(int type, constant char *s); public void opt_filesize(int type, constant char *s);
public void opt_first_cmd_at_prompt(int type, constant char *s); public void opt_first_cmd_at_prompt(int type, constant char *s);
public void opt_intr(int type, constant char *s); public void opt_intr(int type, constant char *s);
public int next_cnum(constant char **sp, constant char *printopt, constant char *errmsg, lbool *errp);
public void opt_header(int type, constant char *s); public void opt_header(int type, constant char *s);
public void opt_search_type(int type, constant char *s); public void opt_search_type(int type, constant char *s);
public void opt_nosearch_headers(int type, constant char *s); public void opt_nosearch_headers(int type, constant char *s);
@@ -331,17 +334,18 @@ public void opt_no_paste(int type, constant char *s);
public void opt_ttyin_name(int type, constant char *s); public void opt_ttyin_name(int type, constant char *s);
public int chop_line(void); public int chop_line(void);
public int get_swindow(void); public int get_swindow(void);
public lbool autosave_action(char act);
public constant char * propt(char c); public constant char * propt(char c);
public void scan_option(constant char *s, lbool is_env); public void scan_option(constant char *s, lbool is_env);
public void toggle_option(struct loption *o, lbool lower, constant char *s, int how_toggle); public lbool toggle_option(struct loption *o, lbool lower, constant char *s, int how_toggle);
public int opt_has_param(struct loption *o); public lbool opt_has_param(constant struct loption *o);
public constant char * opt_prompt(struct loption *o); public constant char * opt_prompt(constant struct loption *o);
public constant char * opt_toggle_disallowed(int c); public constant char * opt_toggle_disallowed(int c);
public lbool isoptpending(void); public lbool isoptpending(void);
public void nopendopt(void); public void nopendopt(void);
public int getnumc(constant char **sp, constant char *printopt, lbool *errp); public lbool getnumc(constant char **sp, constant char *printopt, lbool neg_ok, mutable int *p_num);
public int getnum(char **sp, constant char *printopt, lbool *errp); public lbool getnum(char **sp, constant char *printopt, lbool neg_ok, mutable int *p_num);
public long getfraction(constant char **sp, constant char *printopt, lbool *errp); public lbool getfraction(constant char **sp, mutable long *p_frac);
public void init_unsupport(void); public void init_unsupport(void);
public int get_quit_at_eof(void); public int get_quit_at_eof(void);
public void init_option(void); public void init_option(void);
@@ -350,10 +354,11 @@ public struct loption * findopt_name(constant char **p_optname, constant char **
public char * findopts_name(constant char *pfx); public char * findopts_name(constant char *pfx);
public void init_poll(void); public void init_poll(void);
public lbool ttyin_ready(void); public lbool ttyin_ready(void);
public int supports_ctrl_x(void); public lbool supports_ctrl_x(void);
public ssize_t iread(int fd, unsigned char *buf, size_t len); public ssize_t iread(int fd, unsigned char *buf, size_t len);
public int iopen(constant char *filename, int flags); public int iopen(constant char *filename, int flags);
public void intio(void); public void intio(void);
public void polling_ok(void);
public time_type get_time(void); public time_type get_time(void);
public char * errno_message(constant char *filename); public char * errno_message(constant char *filename);
public constant char * signal_message(int sig); public constant char * signal_message(int sig);
@@ -364,16 +369,16 @@ public int os9_signal(int type, RETSIGTYPE (*handler)());
public void sleep_ms(int ms); public void sleep_ms(int ms);
public void put_line(lbool forw_scroll); public void put_line(lbool forw_scroll);
public void flush(void); public void flush(void);
public void set_output(int fd); public void set_output(int fd, lbool no_term_init);
public int putchr(int ch); public int putchr(int ch);
public void clear_bot_if_needed(void); public void clear_bot_if_needed(void);
public void putstr(constant char *s); public void putstr(constant char *s);
public int less_printf(constant char *fmt, PARG *parg); public int less_printf(constant char *fmt, constant PARG *parg);
public void get_return(void); public void get_return(void);
public void error(constant char *fmt, PARG *parg); public void error(constant char *fmt, constant PARG *parg);
public void ierror(constant char *fmt, PARG *parg); public void ierror(constant char *fmt, constant PARG *parg);
public void ixerror(constant char *fmt, PARG *parg); public void ixerror(constant char *fmt, constant PARG *parg);
public int query(constant char *fmt, PARG *parg); public int query(constant char *fmt, constant PARG *parg);
public int compile_pattern(constant char *pattern, int search_type, int show_error, PATTERN_TYPE *comp_pattern); public int compile_pattern(constant char *pattern, int search_type, int show_error, PATTERN_TYPE *comp_pattern);
public void uncompile_pattern(PATTERN_TYPE *pattern); public void uncompile_pattern(PATTERN_TYPE *pattern);
public int valid_pattern(char *pattern); public int valid_pattern(char *pattern);
@@ -386,8 +391,8 @@ public void add_back_pos(POSITION pos);
public void pos_clear(void); public void pos_clear(void);
public void pos_init(void); public void pos_init(void);
public int onscreen(POSITION pos); public int onscreen(POSITION pos);
public int empty_screen(void); public lbool empty_screen(void);
public int empty_lines(int s, int e); public lbool empty_lines(int s, int e);
public void get_scrpos(struct scrpos *scrpos, int where); public void get_scrpos(struct scrpos *scrpos, int where);
public int sindex_from_sline(int sline); public int sindex_from_sline(int sline);
public void pos_rehead(void); public void pos_rehead(void);
@@ -401,7 +406,7 @@ public int get_cvt_ops(int search_type);
public void repaint_hilite(lbool on); public void repaint_hilite(lbool on);
public void clear_attn(void); public void clear_attn(void);
public void undo_search(lbool clear); public void undo_search(lbool clear);
public void undo_osc8(void); public lbool undo_osc8(void);
public void clr_hlist(struct hilite_tree *anchor); public void clr_hlist(struct hilite_tree *anchor);
public void clr_hilite(void); public void clr_hilite(void);
public void clr_filter(void); public void clr_filter(void);
@@ -420,7 +425,7 @@ public int search(int search_type, constant char *pattern, int n);
public void prep_hilite(POSITION spos, POSITION epos, int maxlines); public void prep_hilite(POSITION spos, POSITION epos, int maxlines);
public void set_filter_pattern(constant char *pattern, int search_type); public void set_filter_pattern(constant char *pattern, int search_type);
public lbool is_filtering(void); public lbool is_filtering(void);
public RETSIGTYPE winch(int type); public RETSIGTYPE lwinch(int type);
public void init_signals(int on); public void init_signals(int on);
public void psignals(void); public void psignals(void);
public void cleantags(void); public void cleantags(void);
@@ -445,7 +450,7 @@ public void xbuf_deinit(struct xbuffer *xbuf);
public void xbuf_reset(struct xbuffer *xbuf); public void xbuf_reset(struct xbuffer *xbuf);
public void xbuf_add_byte(struct xbuffer *xbuf, unsigned char b); public void xbuf_add_byte(struct xbuffer *xbuf, unsigned char b);
public void xbuf_add_char(struct xbuffer *xbuf, char c); public void xbuf_add_char(struct xbuffer *xbuf, char c);
public void xbuf_add_data(struct xbuffer *xbuf, constant unsigned char *data, size_t len); public void xbuf_add_data(struct xbuffer *xbuf, constant void *vdata, size_t len);
public int xbuf_pop(struct xbuffer *buf); public int xbuf_pop(struct xbuffer *buf);
public void xbuf_set(struct xbuffer *dst, constant struct xbuffer *src); public void xbuf_set(struct xbuffer *dst, constant struct xbuffer *src);
public constant char * xbuf_char_data(constant struct xbuffer *xbuf); public constant char * xbuf_char_data(constant struct xbuffer *xbuf);
+4 -1
View File
@@ -1,4 +1,4 @@
/* This file was generated by mkhelp.pl from less.hlp at 18:02 on 2025/10/4 */ /* This file was generated by mkhelp.pl from less.hlp at 16:50 on 2026/1/10 */
#include "less.h" #include "less.h"
constant char helpdata[] = { constant char helpdata[] = {
'\n', '\n',
@@ -32,6 +32,7 @@ constant char helpdata[] = {
' ',' ','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', ' ',' ','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', ' ',' ','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',
' ',' ','E','S','C','-','F',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','L','i','k','e',' ','F',' ','b','u','t',' ','s','t','o','p',' ','w','h','e','n',' ','s','e','a','r','c','h',' ','p','a','t','t','e','r','n',' ','i','s',' ','f','o','u','n','d','.','\n', ' ',' ','E','S','C','-','F',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','L','i','k','e',' ','F',' ','b','u','t',' ','s','t','o','p',' ','w','h','e','n',' ','s','e','a','r','c','h',' ','p','a','t','t','e','r','n',' ','i','s',' ','f','o','u','n','d','.','\n',
' ',' ','E','S','C','-','f',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','L','i','k','e',' ','F',' ','b','u','t',' ','r','i','n','g',' ','t','h','e',' ','b','e','l','l',' ','w','h','e','n',' ','s','e','a','r','c','h',' ','p','a','t','t','e','r','n',' ','i','s',' ','f','o','u','n','d','.','\n',
' ',' ','r',' ',' ','^','R',' ',' ','^','L',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','p','a','i','n','t',' ','s','c','r','e','e','n','.','\n', ' ',' ','r',' ',' ','^','R',' ',' ','^','L',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','p','a','i','n','t',' ','s','c','r','e','e','n','.','\n',
' ',' ','R',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','p','a','i','n','t',' ','s','c','r','e','e','n',',',' ','d','i','s','c','a','r','d','i','n','g',' ','b','u','f','f','e','r','e','d',' ','i','n','p','u','t','.','\n', ' ',' ','R',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','p','a','i','n','t',' ','s','c','r','e','e','n',',',' ','d','i','s','c','a','r','d','i','n','g',' ','b','u','f','f','e','r','e','d',' ','i','n','p','u','t','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n', ' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
@@ -222,6 +223,8 @@ constant char helpdata[] = {
' ',' ','-','#',' ','[','_','\b','N',']',' ',' ','.','.','.','.',' ',' ','-','-','s','h','i','f','t','=','[','_','\b','N',']','\n', ' ',' ','-','#',' ','[','_','\b','N',']',' ',' ','.','.','.','.',' ',' ','-','-','s','h','i','f','t','=','[','_','\b','N',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','h','o','r','i','z','o','n','t','a','l',' ','s','c','r','o','l','l',' ','a','m','o','u','n','t',' ','(','0',' ','=',' ','o','n','e',' ','h','a','l','f',' ','s','c','r','e','e','n',' ','w','i','d','t','h',')','.','\n', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','h','o','r','i','z','o','n','t','a','l',' ','s','c','r','o','l','l',' ','a','m','o','u','n','t',' ','(','0',' ','=',' ','o','n','e',' ','h','a','l','f',' ','s','c','r','e','e','n',' ','w','i','d','t','h',')','.','\n',
'\n', '\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','a','u','t','o','s','a','v','e','=','[','_','\b','m','_','\b','/','_','\b','!','_','\b','*',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','A','c','t','i','o','n','s',' ','w','h','i','c','h',' ','c','a','u','s','e',' ','t','h','e',' ','h','i','s','t','o','r','y',' ','f','i','l','e',' ','t','o',' ','b','e',' ','s','a','v','e','d','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','e','x','i','t','-','f','o','l','l','o','w','-','o','n','-','c','l','o','s','e','\n', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','e','x','i','t','-','f','o','l','l','o','w','-','o','n','-','c','l','o','s','e','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','x','i','t',' ','F',' ','c','o','m','m','a','n','d',' ','o','n',' ','a',' ','p','i','p','e',' ','w','h','e','n',' ','w','r','i','t','e','r',' ','c','l','o','s','e','s',' ','p','i','p','e','.','\n', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','x','i','t',' ','F',' ','c','o','m','m','a','n','d',' ','o','n',' ','a',' ','p','i','p','e',' ','w','h','e','n',' ','w','r','i','t','e','r',' ','c','l','o','s','e','s',' ','p','i','p','e','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','f','i','l','e','-','s','i','z','e','\n', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','f','i','l','e','-','s','i','z','e','\n',
+5 -5
View File
@@ -31,7 +31,7 @@ struct ifile {
void *h_filestate; /* File state (used in ch.c) */ void *h_filestate; /* File state (used in ch.c) */
int h_index; /* Index within command line list */ int h_index; /* Index within command line list */
int h_hold; /* Hold count */ int h_hold; /* Hold count */
char h_opened; /* Has this ifile been opened? */ lbool h_opened; /* Has this ifile been opened? */
struct scrpos h_scrpos; /* Saved position within the file */ struct scrpos h_scrpos; /* Saved position within the file */
void *h_altpipe; /* Alt pipe */ void *h_altpipe; /* Alt pipe */
char *h_altfilename; /* Alt filename */ char *h_altfilename; /* Alt filename */
@@ -108,7 +108,7 @@ static struct ifile * new_ifile(constant char *filename, struct ifile *prev)
p->h_filename = save(filename); p->h_filename = save(filename);
p->h_rfilename = lrealpath(filename); p->h_rfilename = lrealpath(filename);
p->h_scrpos.pos = NULL_POSITION; p->h_scrpos.pos = NULL_POSITION;
p->h_opened = 0; p->h_opened = FALSE;
p->h_hold = 0; p->h_hold = 0;
p->h_filestate = NULL; p->h_filestate = NULL;
p->h_altfilename = NULL; p->h_altfilename = NULL;
@@ -269,7 +269,7 @@ public int get_index(IFILE ifile)
/* /*
* Save the file position to be associated with a given file. * Save the file position to be associated with a given file.
*/ */
public void store_pos(IFILE ifile, struct scrpos *scrpos) public void store_pos(IFILE ifile, constant struct scrpos *scrpos)
{ {
int_ifile(ifile)->h_scrpos = *scrpos; int_ifile(ifile)->h_scrpos = *scrpos;
} }
@@ -288,13 +288,13 @@ public void get_pos(IFILE ifile, struct scrpos *scrpos)
*/ */
public void set_open(IFILE ifile) public void set_open(IFILE ifile)
{ {
int_ifile(ifile)->h_opened = 1; int_ifile(ifile)->h_opened = TRUE;
} }
/* /*
* Return whether the ifile has been opened previously. * Return whether the ifile has been opened previously.
*/ */
public int opened(IFILE ifile) public lbool opened(IFILE ifile)
{ {
return (int_ifile(ifile)->h_opened); return (int_ifile(ifile)->h_opened);
} }
-1
View File
@@ -22,7 +22,6 @@
extern int squeeze; extern int squeeze;
extern int hshift; extern int hshift;
extern int quit_if_one_screen; extern int quit_if_one_screen;
extern int ignore_eoi;
extern int status_col; extern int status_col;
extern int wordwrap; extern int wordwrap;
extern POSITION start_attnpos; extern POSITION start_attnpos;
+8 -8
View File
@@ -194,7 +194,7 @@ static void after_header_message(void)
return; return;
last_msg = now; last_msg = now;
#endif #endif
bell(); lbell();
/* {{ This message displays before the file text is updated, which is not a good UX. }} */ /* {{ This message displays before the file text is updated, which is not a good UX. }} */
/** error("Cannot display text before header; use --header=- to disable header", NULL_PARG); */ /** error("Cannot display text before header; use --header=- to disable header", NULL_PARG); */
} }
@@ -243,9 +243,9 @@ public void jump_loc(POSITION pos, int sline)
*/ */
nline -= sindex; nline -= sindex;
if (nline > 0) if (nline > 0)
forw(nline, position(BOTTOM_PLUS_ONE), TRUE, FALSE, FALSE, 0); forw(nline, position(BOTTOM_PLUS_ONE), TRUE, FALSE, FALSE, FALSE, 0);
else else
back(-nline, position(TOP), TRUE, FALSE, FALSE); back(-nline, position(TOP), TRUE, FALSE, FALSE, FALSE);
#if HILITE_SEARCH #if HILITE_SEARCH
if (show_attn) if (show_attn)
repaint_hilite(TRUE); repaint_hilite(TRUE);
@@ -286,7 +286,7 @@ public void jump_loc(POSITION pos, int sline)
* close enough to the current screen * close enough to the current screen
* that we can just scroll there after all. * that we can just scroll there after all.
*/ */
forw(sc_height-sindex+nline-1, bpos, TRUE, FALSE, FALSE, 0); forw(sc_height-sindex+nline-1, bpos, TRUE, FALSE, FALSE, FALSE, 0);
#if HILITE_SEARCH #if HILITE_SEARCH
if (show_attn) if (show_attn)
repaint_hilite(TRUE); repaint_hilite(TRUE);
@@ -308,7 +308,7 @@ public void jump_loc(POSITION pos, int sline)
lastmark(); lastmark();
squished = FALSE; squished = FALSE;
screen_trashed_num(0); screen_trashed_num(0);
forw(sc_height-1, pos, TRUE, FALSE, FALSE, sindex-nline); forw(sc_height-1, pos, TRUE, FALSE, FALSE, FALSE, sindex-nline);
} else } else
{ {
/* /*
@@ -337,7 +337,7 @@ public void jump_loc(POSITION pos, int sline)
* close enough to the current screen * close enough to the current screen
* that we can just scroll there after all. * that we can just scroll there after all.
*/ */
back(nline, tpos, TRUE, FALSE, FALSE); back(nline, tpos, TRUE, FALSE, FALSE, FALSE);
#if HILITE_SEARCH #if HILITE_SEARCH
if (show_attn) if (show_attn)
repaint_hilite(TRUE); repaint_hilite(TRUE);
@@ -347,11 +347,11 @@ public void jump_loc(POSITION pos, int sline)
} }
lastmark(); lastmark();
if (!top_scroll) if (!top_scroll)
clear(); lclear();
else else
home(); home();
screen_trashed_num(0); screen_trashed_num(0);
add_back_pos(pos); add_back_pos(pos);
back(sc_height-1, pos, TRUE, FALSE, FALSE); back(sc_height-1, pos, TRUE, FALSE, FALSE, FALSE);
} }
} }
+3
View File
@@ -53,5 +53,8 @@ typedef __int64 ssize_t;
typedef __int32 ssize_t; typedef __int32 ssize_t;
#endif #endif
#endif #endif
#ifdef __BORLANDC__
typedef long ssize_t;
#endif
#endif // LESS_LANG_H_ #endif // LESS_LANG_H_
+14 -3
View File
@@ -52,9 +52,6 @@
#if HAVE_CTYPE_H #if HAVE_CTYPE_H
#include <ctype.h> #include <ctype.h>
#endif #endif
#if HAVE_WCTYPE_H
#include <wctype.h>
#endif
#if HAVE_LIMITS_H #if HAVE_LIMITS_H
#include <limits.h> #include <limits.h>
#endif #endif
@@ -266,6 +263,11 @@ typedef off_t LINENUM;
#endif #endif
#endif #endif
/* Use iread() to read tty? */
#if !MSDOS_COMPILER || MSDOS_COMPILER == DJGPPC
#define LESS_IREAD_TTY 1
#endif
/* /*
* Flags for creat() * Flags for creat()
*/ */
@@ -675,3 +677,12 @@ unsigned long lstrtoulc(constant char*, constant char**, int);
#if MSDOS_COMPILER==WIN32C #if MSDOS_COMPILER==WIN32C
int pclose(FILE*); int pclose(FILE*);
#endif #endif
#if !HAVE_STRCHR
char * strchr(char *s, char c);
#endif
#if !HAVE_MEMCPY
void * memcpy(void *dst, constant void *src, size_t len);
#endif
#if !HAVE_STRSTR
char * strstr(constant char *haystack, constant char *needle);
#endif
+3
View File
@@ -29,6 +29,7 @@
ESC-{ ^LeftArrow Left to first column. ESC-{ ^LeftArrow Left to first column.
F Forward forever; like "tail -f". F Forward forever; like "tail -f".
ESC-F Like F but stop when search pattern is found. ESC-F Like F but stop when search pattern is found.
ESC-f Like F but ring the bell when search pattern is found.
r ^R ^L Repaint screen. r ^R ^L Repaint screen.
R Repaint screen, discarding buffered input. R Repaint screen, discarding buffered input.
--------------------------------------------------- ---------------------------------------------------
@@ -219,6 +220,8 @@
-# [_N] .... --shift=[_N] -# [_N] .... --shift=[_N]
Set horizontal scroll amount (0 = one half screen width). Set horizontal scroll amount (0 = one half screen width).
--autosave=[_m_/_!_*]
Actions which cause the history file to be saved.
--exit-follow-on-close --exit-follow-on-close
Exit F command on a pipe when writer closes pipe. Exit F command on a pipe when writer closes pipe.
--file-size --file-size
+1013 -472
View File
File diff suppressed because it is too large Load Diff
+32 -5
View File
@@ -1,9 +1,33 @@
.TH LESSECHO 1 "Version 685: 04 Oct 2025" .TH LESSECHO 1 "10 Jan 2026" "less 691"
.\" 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
.SH NAME .SH NAME
lessecho \- expand metacharacters lessecho \- expand metacharacters
.SH SYNOPSIS .SH SYNOPSIS
.HP
.B lessecho .B lessecho
.I "[-ox] [-cx] [-pn] [-dn] [-mx] [-nn] [-ex] [-a] file ..." .RB [ \-a ]
.RB [ \-o\c
.IR x ]
.RB [ \-c\c
.IR x ]
.RB [ \-p\c
.IR n ]
.RB [ \-d\c
.IR n ]
.RB [ \-m\c
.IR x ]
.RB [ \-n\c
.IR n ]
.RB [ \-e\c
.IR x ]
.I file
\&.\|.\|.
.PP
.B "lessecho \-\-version"
.SH "DESCRIPTION" .SH "DESCRIPTION"
.B lessecho .B lessecho
is a program that simply echos its arguments on standard output. is a program that simply echos its arguments on standard output.
@@ -18,12 +42,12 @@ A summary of options is included below.
.TP .TP
.B \-e\fIx\fP .B \-e\fIx\fP
Specifies "\fIx\fP", rather than backslash, to be the escape char for metachars. Specifies "\fIx\fP", rather than backslash, to be the escape char for metachars.
If \fIx\fP is "-", no escape char is used and arguments containing metachars If \fIx\fP is "\-", no escape char is used and arguments containing metachars
are surrounded by quotes instead. are surrounded by quotes instead.
.TP .TP
.B \-o\fIx\fP .B \-o\fIx\fP
Specifies "\fIx\fP", rather than double-quote, to be the open quote character, Specifies "\fIx\fP", rather than double-quote, to be the open quote character,
which is used if the \-e- option is specified. which is used if the \-e\- option is specified.
.TP .TP
.B \-c\fIx\fP .B \-c\fIx\fP
Specifies "\fIx\fP" to be the close quote character. Specifies "\fIx\fP" to be the close quote character.
@@ -53,4 +77,7 @@ The default is that only arguments containing metacharacters are quoted.
This manual page was written by Thomas Schoepf <schoepf@debian.org>, This manual page was written by Thomas Schoepf <schoepf@debian.org>,
for the Debian GNU/Linux system (but may be used by others). for the Debian GNU/Linux system (but may be used by others).
.PP .PP
Report bugs at https://github.com/gwsw/less/issues. Report bugs at
.nh
https://\*:github\*:.com/\*:gwsw/\*:less/\*:issues.
.hy
+215 -142
View File
@@ -1,12 +1,31 @@
'\" t '\" t
.TH LESSKEY 1 "Version 685: 04 Oct 2025" .TH LESSKEY 1 "10 Jan 2026" "less 691"
.\" Define a string for the caret ("hat") as portably as possible.
.ie \n(.g .ds ^ \(ha
.el .ds ^ ^
.\" Define a string for the neutral apostrophe as portably as possible.
.ie \n(.g .ds ' \(aq
.el .ds ' '
.\" 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
.SH NAME .SH NAME
lesskey \- customize key bindings for less lesskey \- customize key bindings for less
.SH "SYNOPSIS (deprecated)" .SH "SYNOPSIS (deprecated)"
.B "lesskey [\-o output] [\-\-] [input]" .B lesskey
.br .RB [ \-o
.B "lesskey [\-\-output=output] [\-\-] [input]" .IR output ]
.B \-\-
.I input
.br .br
.B lesskey
.RB [ \-\-output=\c
.IR output ]
.B \-\-
.I input
.PP
.B "lesskey \-V" .B "lesskey \-V"
.br .br
.B "lesskey \-\-version" .B "lesskey \-\-version"
@@ -43,7 +62,7 @@ Each section starts with a line that identifies the type of section.
Possible sections are: Possible sections are:
.IP #command .IP #command
Customizes command key bindings. Customizes command key bindings.
.IP #line-edit .IP #line\-edit
Customizes line-editing key bindings. Customizes line-editing key bindings.
.IP #env .IP #env
Defines environment variables. Defines environment variables.
@@ -54,15 +73,15 @@ except as noted below.
. .
.SH "COMMAND SECTION" .SH "COMMAND SECTION"
The command section begins with the line The command section begins with the line
.sp .PP
#command #command
.sp .PP
If the command section is the first section in the file, If the command section is the first section in the file,
this line may be omitted. this line may be omitted.
The command section consists of lines of the form: The command section consists of lines of the form:
.sp .PP
\fIstring\fP <whitespace> \fIaction\fP <whitespace> [extra-string] <newline> \fIstring\fP <whitespace> \fIaction\fP <whitespace> [extra-string] <newline>
.sp .PP
Whitespace is any sequence of one or more spaces and/or tabs. Whitespace is any sequence of one or more spaces and/or tabs.
The \fIstring\fP is the command key(s) which invoke the action. The \fIstring\fP is the command key(s) which invoke the action.
The \fIstring\fP may be a single command key, or a sequence of up to 15 keys. The \fIstring\fP may be a single command key, or a sequence of up to 15 keys.
@@ -84,8 +103,9 @@ l l l.
\et TAB (0x09) \et TAB (0x09)
.TE .TE
.RE .RE
.sp .PP
\ek followed by a single character represents the char(s) produced when one of these keys is pressed: \ek followed by one or two characters represents the char(s) produced
when one of these keys is pressed:
.RS 5m .RS 5m
.TS .TS
l l. l l.
@@ -106,6 +126,22 @@ l l.
\ekx DELETE \ekx DELETE
\ekX ctrl-DELETE \ekX ctrl-DELETE
\ek1 F1 \ek1 F1
\ekp1 lower left key on the numeric keypad
\ekp2 lower center key on the numeric keypad
\ekp3 lower right key on the numeric keypad
\ekp4 center left key on the numeric keypad
\ekp5 center key on the numeric keypad
\ekp6 center right key on the numeric keypad
\ekp7 upper left key on the numeric keypad
\ekp8 upper center key on the numeric keypad
\ekp9 upper right key on the numeric keypad
\ekp0 0 on the numeric keypad
\ekp* * on the numeric keypad
\ekp/ / on the numeric keypad
\ekp\- \- on the numeric keypad
\ekp+ + on the numeric keypad
\ekp. . on the numeric keypad
\ekp, , on the numeric keypad
.TE .TE
.RE .RE
.PP .PP
@@ -126,11 +162,13 @@ For example, see the "{" and ":t" commands in the example below.
It can also be used to execute more than one command when a key is pressed. It can also be used to execute more than one command when a key is pressed.
For example, if this line were in a lesskey file, pressing the "B" key For example, if this line were in a lesskey file, pressing the "B" key
would first set the "b" mark and then search for the string "next": would first set the "b" mark and then search for the string "next":
.sp .PP
.EX
.nf .nf
B set-mark b/next\en B set\-mark b/next\en
.fi .fi
.sp .EE
.PP
The extra string has a special meaning for the "quit" action: The extra string has a special meaning for the "quit" action:
when when
.B less .B less
@@ -144,116 +182,131 @@ default command keys used by
Documentation on each command can be found in the Documentation on each command can be found in the
.B less .B less
man page, under the key sequence which invokes the command. man page, under the key sequence which invokes the command.
.sp .PP
.RS 5m .RS 5m
.TS .TS
l l. l l.
#command #command
\er forw-line \er forw\-line
\en forw-line \en forw\-line
e forw-line e forw\-line
j forw-line j forw\-line
\ekd forw-line \ekd forw\-line
^E forw-line \*^E forw\-line
^N forw-line \*^N forw\-line
k back-line k back\-line
y back-line y back\-line
^Y back-line \*^Y back\-line
^K back-line \*^K back\-line
^P back-line \*^P back\-line
J forw-line-force J forw\-line\-force
K back-line-force K back\-line\-force
Y back-line-force Y back\-line\-force
\eej forw-newline \eej forw\-newline
\eek back-newline \eek back\-newline
d forw-scroll d forw\-scroll
^D forw-scroll \*^D forw\-scroll
u back-scroll u back\-scroll
^U back-scroll \*^U back\-scroll
\e40 forw-screen \e40 forw\-screen
f forw-screen f forw\-screen
^F forw-screen \*^F forw\-screen
^V forw-screen \*^V forw\-screen
\ekD forw-screen \ekD forw\-screen
b back-screen b back\-screen
^B back-screen \*^B back\-screen
\eev back-screen \eev back\-screen
\ekU back-screen \ekU back\-screen
z forw-window z forw\-window
w back-window w back\-window
\ee\e40 forw-screen-force \ee\e40 forw\-screen\-force
\eeb back-screen-force \eeb back\-screen\-force
F forw-forever F forw\-forever
\eeF forw-until-hilite \eeF forw\-until\-hilite
R repaint-flush R repaint\-flush
r repaint r repaint
^R repaint \*^R repaint
^L repaint \*^L repaint
\eeu undo-hilite \eeu undo\-hilite
\eeU clear-search \eeU clear\-search
g goto-line g goto\-line
\ekh goto-line \ekh goto\-line
< goto-line < goto\-line
\ee< goto-line \ee< goto\-line
p percent p percent
% percent % percent
\ee( left-scroll \ee( left\-scroll
\ee) right-scroll \ee) right\-scroll
\ekl left-scroll \ekl left\-scroll
\ekr right-scroll \ekr right\-scroll
\ee{ no-scroll \ee{ no\-scroll
\ee} end-scroll \ee} end\-scroll
{ forw-bracket {} { forw\-bracket {}
} back-bracket {} } back\-bracket {}
( forw-bracket () ( forw\-bracket ()
) back-bracket () ) back\-bracket ()
[ forw-bracket [] [ forw\-bracket []
] back-bracket [] ] back\-bracket []
\ee^F forw-bracket \ee\*^F forw\-bracket
\ee^B back-bracket \ee\*^B back\-bracket
G goto-end G goto\-end
\ee> goto-end \ee> goto\-end
> goto-end > goto\-end
\eke goto-end \eke goto\-end
\eeG goto-end-buffered \eeG goto\-end\-buffered
\&= status \&= status
^G status \*^G status
:f status :f status
/ forw-search / forw\-search
? back-search ? back\-search
\ee/ forw-search * \ee/ forw\-search *
\ee? back-search * \ee? back\-search *
n repeat-search n repeat\-search
\een repeat-search-all \een repeat\-search\-all
N reverse-search N reverse\-search
\eeN reverse-search-all \eeN reverse\-search\-all
^O^N osc8-forw-search \*^O\*^N osc8\-forw\-search
^On osc8-forw-search \*^On osc8\-forw\-search
^O^P osc8-back-search \*^O\*^P osc8\-back\-search
^Op osc8-back-search \*^Op osc8\-back\-search
^O^O osc8-open \*^O\*^O osc8\-open
& filter & filter
m set-mark m set\-mark
M set-mark-bottom M set\-mark\-bottom
\eem clear-mark \eem clear\-mark
\&' goto-mark \&\*' goto\-mark
^X^X goto-mark \*^X\*^X goto\-mark
E examine E examine
:e examine :e examine
^X^V examine \*^X\*^V examine
:n next-file :n next\-file
:p prev-file :p prev\-file
t next-tag t next\-tag
T prev-tag T prev\-tag
:x index-file :x index\-file
:d remove-file :d remove\-file
- toggle-option \- toggle\-option
:t toggle-option t :t toggle\-option t
s toggle-option o s toggle\-option o
## Use a long option name by starting the ## Use a long option name by starting the
## extra string with ONE dash; eg: ## extra string with ONE dash; eg:
## s toggle-option -log-file\en ## s toggle\-option \-log\-file\en
\&_ display-option \&_ display\-option
\ekp1 goto\-end
\ekp2 forw\-line
\ekp3 forw\-screen
\ekp4 left\-scroll
\ekp6 right\-scroll
\ekp7 goto\-line
\ekp8 back\-line
\ekp9 back\-screen
\ekp0 noaction 0
\ekp* noaction *
\ekp/ noaction /
\ekp\- noaction \-
\ekp+ noaction +
\ekp. noaction .
\ekp, noaction ,
| pipe | pipe
v visual v visual
! shell ! shell
@@ -281,7 +334,6 @@ Q quit
ZZ quit ZZ quit
.TE .TE
.RE .RE
.sp
.SH PRECEDENCE .SH PRECEDENCE
Commands specified by Commands specified by
.B lesskey .B lesskey
@@ -296,9 +348,9 @@ will give an error beep for an "invalid" command,
but not for a "noaction" command. but not for a "noaction" command.
In addition, ALL default commands may be disabled by In addition, ALL default commands may be disabled by
adding this control line to the input file: adding this control line to the input file:
.sp .PP
#stop #stop
.sp .PP
This will cause all default commands to be ignored. This will cause all default commands to be ignored.
The #stop line should be the last line in that section of the file. The #stop line should be the last line in that section of the file.
.PP .PP
@@ -310,9 +362,11 @@ For example, failure to provide a "quit" command can lead to frustration.
. .
.SH "LINE EDITING SECTION" .SH "LINE EDITING SECTION"
The line-editing section begins with the line: The line-editing section begins with the line:
.sp .PP
#line-edit .EX
.sp #line\-edit
.EE
.PP
This section specifies new key bindings for the line editing commands, This section specifies new key bindings for the line editing commands,
in a manner similar to the way key bindings for in a manner similar to the way key bindings for
ordinary commands are specified in the #command section. ordinary commands are specified in the #command section.
@@ -323,14 +377,14 @@ one per line as in the example below.
The following input file describes the set of The following input file describes the set of
default line-editing keys used by default line-editing keys used by
.BR less : .BR less :
.sp .PP
.RS 5m .RS 5m
.TS .TS
l l. l l.
#line-edit #line\-edit
\et forw-complete \et forw\-complete
\e17 back-complete \e17 back\-complete
\ee\et back-complete \ee\et back\-complete
^L expand ^L expand
^V literal ^V literal
^A literal ^A literal
@@ -338,16 +392,16 @@ l l.
\ekr right \ekr right
\eeh left \eeh left
\ekl left \ekl left
\eeb word-left \eeb word\-left
\ee\ekl word-left \ee\ekl word\-left
\eew word-right \eew word\-right
\ee\ekr word-right \ee\ekr word\-right
\eei insert \eei insert
\eex delete \eex delete
\ekx delete \ekx delete
\eeX word-delete \eeX word\-delete
\eekx word-delete \eekx word\-delete
\ee\eb word-backspace \ee\eb word\-backspace
\ee0 home \ee0 home
\ekh home \ekh home
\ee$ end \ee$ end
@@ -356,17 +410,29 @@ l l.
\eku up \eku up
\eej down \eej down
^G abort ^G abort
\ekp1 end
\ekp2 down
\ekp4 left
\ekp6 right
\ekp7 home
\ekp8 up
\ekp0 noaction 0
\ekp* noaction *
\ekp/ noaction /
\ekp\- noaction \-
\ekp+ noaction +
\ekp. noaction .
\ekp, noaction ,
\ee[M mouse \ee[M mouse
\ee[< mouse6 \ee[< mouse6
.TE .TE
.RE .RE
.sp
. .
.SH "LESS ENVIRONMENT VARIABLES" .SH "LESS ENVIRONMENT VARIABLES"
The environment variable section begins with the line The environment variable section begins with the line
.sp .PP
#env #env
.sp .PP
Following this line is a list of environment variable assignments. Following this line is a list of environment variable assignments.
Each line consists of an environment variable name, an equals sign (=) Each line consists of an environment variable name, an equals sign (=)
and the value to be assigned to the environment variable. and the value to be assigned to the environment variable.
@@ -376,7 +442,7 @@ Variables assigned in this way are visible only to
If a variable is specified in the system environment and also in a If a variable is specified in the system environment and also in a
lesskey file, the value in the lesskey file takes precedence. lesskey file, the value in the lesskey file takes precedence.
. .
.sp .PP
If the variable name is followed by += rather than =, If the variable name is followed by += rather than =,
the string is appended to the variable's existing value. the string is appended to the variable's existing value.
This currently works only if any += lines immediately follow This currently works only if any += lines immediately follow
@@ -390,7 +456,7 @@ it should be appended to the end of the preceding line.
(It cannot be added to the beginning of the += string because space after (It cannot be added to the beginning of the += string because space after
the equals sign is ignored, as noted above.) the equals sign is ignored, as noted above.)
. .
.sp .PP
In the string after the = sign, a substring of the form ${NAME} In the string after the = sign, a substring of the form ${NAME}
is replaced with the value of the environment variable "NAME". is replaced with the value of the environment variable "NAME".
The value of the variable may come from either the system environment, The value of the variable may come from either the system environment,
@@ -417,18 +483,20 @@ the remainder of the line is parsed if and only if the running version of
matches the operator. matches the operator.
This can be helpful if a lesskey file is used by different versions of This can be helpful if a lesskey file is used by different versions of
.BR less . .BR less .
.sp .PP
For example, suppose that a new command named 'sideways-search' is added in For example, suppose that a new command named 'sideways\-search' is added in
.B less .B less
version 777. version 777.
Then the following line would assign the command to the Q key, but only in versions of Then the following line would assign the command to the Q key, but only in versions of
.B less .B less
which support it. The line would be ignored by versions earlier than 777. which support it. The line would be ignored by versions earlier than 777.
.sp .PP
.EX
.nf .nf
#version >= 777 Q sideways-search #version >= 777 Q sideways\-search
.fi .fi
.sp .EE
.PP
These six operators are supported: These six operators are supported:
.RS 5m .RS 5m
.TS .TS
@@ -441,7 +509,7 @@ l l.
!= Not equal to != Not equal to
.TE .TE
.RE .RE
.sp .PP
The #version feature is not supported in The #version feature is not supported in
.B less .B less
and and
@@ -453,14 +521,16 @@ In those older versions, all #version lines are ignored.
The following input file sets the \-i and \-S options when The following input file sets the \-i and \-S options when
.B less .B less
is run and, on version 595 and higher, adds a \-\-color option. is run and, on version 595 and higher, adds a \-\-color option.
.sp .PP
.EX
.nf .nf
#env #env
## (Note that there must be a space at the end of the next line, ## (Note that there must be a space at the end of the next line,
## to separate the --color option from the -S option.) ## to separate the \-\-color option from the \-S option.)
LESS = \-i\ \-S\ LESS = \-i\ \-S\
#version\ >=\ 595\ \ LESS\ +=\ \-\-color=Hkc #version\ >=\ 595\ \ LESS\ +=\ \-\-color=Hkc
.fi .fi
.EE
. .
.SH "SEE ALSO" .SH "SEE ALSO"
.BR less (1) .BR less (1)
@@ -496,4 +566,7 @@ See the GNU General Public License for more details.
. .
Mark Nudelman Mark Nudelman
.br .br
Report bugs at https://github.com/gwsw/less/issues. Report bugs at
.nh
https://\*:github\*:.com/\*:gwsw/\*:less/\*:issues.
.hy
+25 -1
View File
@@ -247,6 +247,7 @@ static constant char * tstr(char **pp, int xlate)
case 'k': case 'k':
if (xlate) if (xlate)
{ {
ch = 0;
switch (*++p) switch (*++p)
{ {
case 'b': ch = SK_BACKSPACE; break; case 'b': ch = SK_BACKSPACE; break;
@@ -266,7 +267,30 @@ static constant char * tstr(char **pp, int xlate)
case 'x': ch = SK_DELETE; break; case 'x': ch = SK_DELETE; break;
case 'X': ch = SK_CTL_DELETE; break; case 'X': ch = SK_CTL_DELETE; break;
case '1': ch = SK_F1; break; case '1': ch = SK_F1; break;
default: case 'p':
switch (*++p)
{
case '1': ch = SK_PAD_DL; break;
case '2': ch = SK_PAD_D; break;
case '3': ch = SK_PAD_DR; break;
case '4': ch = SK_PAD_L; break;
case '5': ch = SK_PAD_CENTER; break;
case '6': ch = SK_PAD_R; break;
case '7': ch = SK_PAD_UL; break;
case '8': ch = SK_PAD_U; break;
case '9': ch = SK_PAD_UR; break;
case '0': ch = SK_PAD_ZERO; break;
case '*': ch = SK_PAD_STAR; break;
case '/': ch = SK_PAD_SLASH; break;
case '-': ch = SK_PAD_DASH; break;
case '+': ch = SK_PAD_PLUS; break;
case '.': ch = SK_PAD_DOT; break;
case ',': ch = SK_PAD_COMMA; break;
}
break;
}
if (ch == 0)
{
parse_error("invalid escape sequence \"\\k%s\"", char_string(buf, *p, 0)); parse_error("invalid escape sequence \"\\k%s\"", char_string(buf, *p, 0));
*pp = increment_pointer(p); *pp = increment_pointer(p);
return (""); return ("");
+23 -14
View File
@@ -97,7 +97,7 @@ extern int twiddle;
extern int status_col; extern int status_col;
extern int status_col_width; extern int status_col_width;
extern int linenum_width; extern int linenum_width;
extern int auto_wrap, ignaw; extern int auto_wrap, defer_wrap;
extern int bo_s_width, bo_e_width; extern int bo_s_width, bo_e_width;
extern int ul_s_width, ul_e_width; extern int ul_s_width, ul_e_width;
extern int bl_s_width, bl_e_width; extern int bl_s_width, bl_e_width;
@@ -129,7 +129,7 @@ static struct color_map color_map[] = {
{ AT_COLOR_BIN, "kR" }, { AT_COLOR_BIN, "kR" },
{ AT_COLOR_CTRL, "kR" }, { AT_COLOR_CTRL, "kR" },
{ AT_COLOR_ERROR, "kY" }, { AT_COLOR_ERROR, "kY" },
{ AT_COLOR_LINENUM, "c" }, { AT_COLOR_LINENUM, "c*" },
{ AT_COLOR_MARK, "Wb" }, { AT_COLOR_MARK, "Wb" },
{ AT_COLOR_PROMPT, "kC" }, { AT_COLOR_PROMPT, "kC" },
{ AT_COLOR_RSCROLL, "kc" }, { AT_COLOR_RSCROLL, "kc" },
@@ -185,7 +185,7 @@ public void init_line(void)
s = skipspc(s); s = skipspc(s);
if (*s == ',') if (*s == ',')
++s; ++s;
xbuf_add_data(&xbuf, (constant void *) &num, sizeof(num)); xbuf_add_data(&xbuf, &num, sizeof(num));
++osc_ansi_allow_count; ++osc_ansi_allow_count;
} }
osc_ansi_allow = (long *) xbuf.data; osc_ansi_allow = (long *) xbuf.data;
@@ -436,7 +436,7 @@ public void plinestart(POSITION pos)
for (i = 0; i + len < (size_t) linenum_width; i++) for (i = 0; i + len < (size_t) linenum_width; i++)
add_pfx(' ', AT_NORMAL); add_pfx(' ', AT_NORMAL);
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
add_pfx(buf[i], AT_BOLD|AT_COLOR_LINENUM); add_pfx(buf[i], use_color ? AT_COLOR_LINENUM : AT_BOLD);
add_pfx(' ', AT_NORMAL); add_pfx(' ', AT_NORMAL);
} }
end_column = (int) linebuf.pfx_end; /*{{type-issue}}*/ end_column = (int) linebuf.pfx_end; /*{{type-issue}}*/
@@ -1480,14 +1480,14 @@ public void pdone(lbool endline, lbool chopped, lbool forw)
* the next line is blank. In that case the single newline output for * the next line is blank. In that case the single newline output for
* that blank line would be ignored!) * that blank line would be ignored!)
*/ */
if (end_column < sc_width + cshift || !auto_wrap || (endline && ignaw) || ctldisp == OPT_ON) if (end_column < sc_width + cshift || !auto_wrap || (endline && defer_wrap) || ctldisp == OPT_ON)
{ {
add_linebuf('\n', AT_NORMAL, 0); add_linebuf('\n', AT_NORMAL, 0);
} }
else if (ignaw && end_column >= sc_width + cshift && forw) else if (defer_wrap && end_column >= sc_width + cshift && forw)
{ {
/* /*
* Terminals with "ignaw" don't wrap until they *really* need * Terminals with "defer_wrap" don't wrap until they *really* need
* to, i.e. when the character *after* the last one to fit on a * to, i.e. when the character *after* the last one to fit on a
* line is output. But they are too hard to deal with when they * line is output. But they are too hard to deal with when they
* get in the state where a full screen width of characters * get in the state where a full screen width of characters
@@ -1509,7 +1509,7 @@ public void pdone(lbool endline, lbool chopped, lbool forw)
* colored with the last char's background color before the color * colored with the last char's background color before the color
* reset sequence is sent. Clear the line to reset the background color. * reset sequence is sent. Clear the line to reset the background color.
*/ */
if (auto_wrap && !ignaw && end_column >= sc_width + cshift) if (auto_wrap && !defer_wrap && end_column >= sc_width + cshift)
clear_after_line = TRUE; clear_after_line = TRUE;
set_linebuf(linebuf.end, '\0', AT_NORMAL); set_linebuf(linebuf.end, '\0', AT_NORMAL);
} }
@@ -1915,27 +1915,36 @@ public void load_line(constant char *str)
} }
/* /*
* Find the shift necessary to show the end of the longest displayed line. * Find the length of the longest displayed line on the screen.
*/ */
public int rrshift(void) public int longest_line_width(void)
{ {
POSITION pos; POSITION pos;
int save_width; int save_width;
int sline; int sindex;
int longest = 0; int longest = 0;
save_width = sc_width; save_width = sc_width;
sc_width = INT_MAX; /* so forw_line() won't chop */ sc_width = INT_MAX; /* so forw_line() won't chop */
for (sline = TOP; sline < sc_height; sline++) for (sindex = TOP; sindex < sc_height-1; sindex++)
if ((pos = position(sline)) != NULL_POSITION) if ((pos = position(sindex)) != NULL_POSITION)
break; break;
for (; sline < sc_height && pos != NULL_POSITION; sline++) for (; sindex < sc_height-1 && pos != NULL_POSITION; sindex++)
{ {
pos = forw_line(pos, NULL, NULL); pos = forw_line(pos, NULL, NULL);
if (end_column > longest) if (end_column > longest)
longest = end_column; longest = end_column;
} }
sc_width = save_width; sc_width = save_width;
return longest;
}
/*
* Find the shift necessary to show the end of the longest displayed line.
*/
public int rrshift(void)
{
int longest = longest_line_width();
if (longest < sc_width) if (longest < sc_width)
return 0; return 0;
return longest - sc_width; return longest - sc_width;
+10 -10
View File
@@ -32,6 +32,7 @@
#endif #endif
#endif #endif
extern int sigs;
extern IFILE curr_ifile; extern IFILE curr_ifile;
@@ -92,7 +93,7 @@ public void lsystem(constant char *cmd, constant char *donemsg)
/* /*
* De-initialize the terminal and take out of raw mode. * De-initialize the terminal and take out of raw mode.
*/ */
deinit(); term_deinit();
flush(); /* Make sure the deinit chars get out */ flush(); /* Make sure the deinit chars get out */
raw_mode(0); raw_mode(0);
#if MSDOS_COMPILER==WIN32C #if MSDOS_COMPILER==WIN32C
@@ -135,9 +136,10 @@ public void lsystem(constant char *cmd, constant char *donemsg)
char *esccmd = shell_quote(cmd); char *esccmd = shell_quote(cmd);
if (esccmd != NULL) if (esccmd != NULL)
{ {
size_t len = strlen(shell) + strlen(esccmd) + 5; constant char *copt = shell_coption();
size_t len = strlen(shell) + strlen(esccmd) + strlen(copt) + 3;
p = (char *) ecalloc(len, sizeof(char)); p = (char *) ecalloc(len, sizeof(char));
SNPRINTF3(p, len, "%s %s %s", shell, shell_coption(), esccmd); SNPRINTF3(p, len, "%s %s %s", shell, copt, esccmd);
free(esccmd); free(esccmd);
} }
} }
@@ -191,7 +193,7 @@ public void lsystem(constant char *cmd, constant char *donemsg)
putchr('\n'); putchr('\n');
flush(); flush();
} }
init(); term_init();
screen_trashed(); screen_trashed();
#if MSDOS_COMPILER && MSDOS_COMPILER!=WIN32C #if MSDOS_COMPILER && MSDOS_COMPILER!=WIN32C
@@ -220,15 +222,13 @@ public void lsystem(constant char *cmd, constant char *donemsg)
*/ */
reedit_ifile(save_ifile); reedit_ifile(save_ifile);
#if defined(SIGWINCH) || defined(SIGWIND)
/* /*
* Since we were ignoring window change signals while we executed * Since we were ignoring window change signals while we executed
* the system command, we must assume the window changed. * the system command, we must assume the window changed.
* Warning: this leaves a signal pending (in "sigs"), * Warning: this leaves a signal pending (in "sigs"),
* so psignals() should be called soon after lsystem(). * so psignals() should be called soon after lsystem().
*/ */
winch(0); sigs |= S_WINCH;
#endif
} }
#endif #endif
@@ -305,7 +305,7 @@ public int pipe_data(constant char *cmd, POSITION spos, POSITION epos)
putstr(cmd); putstr(cmd);
putstr("\n"); putstr("\n");
deinit(); term_deinit();
flush(); flush();
raw_mode(0); raw_mode(0);
init_signals(0); init_signals(0);
@@ -351,11 +351,11 @@ public int pipe_data(constant char *cmd, POSITION spos, POSITION epos)
#endif #endif
init_signals(1); init_signals(1);
raw_mode(1); raw_mode(1);
init(); term_init();
screen_trashed(); screen_trashed();
#if defined(SIGWINCH) || defined(SIGWIND) #if defined(SIGWINCH) || defined(SIGWIND)
/* {{ Probably don't need this here. }} */ /* {{ Probably don't need this here. }} */
winch(0); lwinch(0);
#endif #endif
return (0); return (0);
} }
+27 -26
View File
@@ -40,6 +40,7 @@ public constant char *progname;
public lbool quitting = FALSE; public lbool quitting = FALSE;
public int dohelp; public int dohelp;
public char * init_header = NULL; public char * init_header = NULL;
public char * no_config = NULL;
static int secure_allow_features; static int secure_allow_features;
#if LOGFILE #if LOGFILE
@@ -75,8 +76,9 @@ extern int quit_if_one_screen;
extern int no_init; extern int no_init;
extern int errmsgs; extern int errmsgs;
extern int redraw_on_quit; extern int redraw_on_quit;
extern int term_init_done; extern int term_addrs;
extern lbool first_time; extern lbool first_time;
extern lbool term_init_ever;
#if MSDOS_COMPILER==WIN32C && (defined(__MINGW32__) || defined(_MSC_VER)) #if MSDOS_COMPILER==WIN32C && (defined(__MINGW32__) || defined(_MSC_VER))
/* malloc'ed 0-terminated utf8 of 0-terminated wide ws, or null on errors */ /* malloc'ed 0-terminated utf8 of 0-terminated wide ws, or null on errors */
@@ -205,6 +207,12 @@ static int security_feature(constant char *name, size_t len)
return security_feature_error("invalid", len, name); return security_feature_error("invalid", len, name);
return features[match].sf_value; return features[match].sf_value;
} }
static lbool set_security_feature(constant char *word, size_t wlen, void *arg)
{
secure_allow_features |= security_feature(word, wlen);
return TRUE;
}
#endif /* !SECURE */ #endif /* !SECURE */
/* /*
@@ -224,19 +232,7 @@ static void init_secure(void)
str = lgetenv("LESSSECURE_ALLOW"); str = lgetenv("LESSSECURE_ALLOW");
if (!isnullenv(str)) if (!isnullenv(str))
{ parse_csl(set_security_feature, str, NULL);
for (;;)
{
constant char *estr;
while (*str == ' ' || *str == ',') ++str; /* skip leading spaces/commas */
if (*str == '\0') break;
estr = strchr(str, ',');
if (estr == NULL) estr = str + strlen(str);
while (estr > str && estr[-1] == ' ') --estr; /* trim trailing spaces */
secure_allow_features |= security_feature(str, ptr_diff(estr, str));
str = estr;
}
}
#endif #endif
} }
@@ -251,8 +247,11 @@ int main(int argc, constant char *argv[])
struct xbuffer xfiles; struct xbuffer xfiles;
constant int *files; constant int *files;
size_t num_files; size_t num_files;
size_t f;
lbool end_opts = FALSE; lbool end_opts = FALSE;
lbool posixly_correct = FALSE; lbool posixly_correct;
no_config = getenv("LESSNOCONFIG");
#if MSDOS_COMPILER==WIN32C && (defined(__MINGW32__) || defined(_MSC_VER)) #if MSDOS_COMPILER==WIN32C && (defined(__MINGW32__) || defined(_MSC_VER))
if (GetACP() != CP_UTF8) /* not using a UTF-8 manifest */ if (GetACP() != CP_UTF8) /* not using a UTF-8 manifest */
@@ -325,7 +324,7 @@ int main(int argc, constant char *argv[])
#define isoptstring(s) less_is_more ? (((s)[0] == '-') && (s)[1] != '\0') : \ #define isoptstring(s) less_is_more ? (((s)[0] == '-') && (s)[1] != '\0') : \
(((s)[0] == '-' || (s)[0] == '+') && (s)[1] != '\0') (((s)[0] == '-' || (s)[0] == '+') && (s)[1] != '\0')
xbuf_init(&xfiles); xbuf_init(&xfiles);
posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); posixly_correct = (lgetenv("POSIXLY_CORRECT") != NULL);
for (i = 0; i < argc; i++) for (i = 0; i < argc; i++)
{ {
if (strcmp(argv[i], "--") == 0) if (strcmp(argv[i], "--") == 0)
@@ -336,7 +335,7 @@ int main(int argc, constant char *argv[])
{ {
if (posixly_correct) if (posixly_correct)
end_opts = TRUE; end_opts = TRUE;
xbuf_add_data(&xfiles, (constant unsigned char *) &i, sizeof(i)); xbuf_add_data(&xfiles, &i, sizeof(i));
} }
} }
#undef isoptstring #undef isoptstring
@@ -379,7 +378,7 @@ int main(int argc, constant char *argv[])
ifile = get_ifile(FAKE_HELPFILE, ifile); ifile = get_ifile(FAKE_HELPFILE, ifile);
files = (constant int *) xfiles.data; files = (constant int *) xfiles.data;
num_files = xfiles.end / sizeof(int); num_files = xfiles.end / sizeof(int);
for (i = 0; i < num_files; i++) for (f = 0; f < num_files; f++)
{ {
#if (MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC) #if (MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC)
/* /*
@@ -393,7 +392,7 @@ int main(int argc, constant char *argv[])
char *gfilename; char *gfilename;
char *qfilename; char *qfilename;
gfilename = lglob(argv[files[i]]); gfilename = lglob(argv[files[f]]);
init_textlist(&tlist, gfilename); init_textlist(&tlist, gfilename);
filename = NULL; filename = NULL;
while ((filename = forw_textlist(&tlist, filename)) != NULL) while ((filename = forw_textlist(&tlist, filename)) != NULL)
@@ -405,7 +404,7 @@ int main(int argc, constant char *argv[])
} }
free(gfilename); free(gfilename);
#else #else
(void) get_ifile(argv[files[i]], ifile); (void) get_ifile(argv[files[f]], ifile);
ifile = prev_ifile(NULL_IFILE); ifile = prev_ifile(NULL_IFILE);
#endif #endif
} }
@@ -420,7 +419,7 @@ int main(int argc, constant char *argv[])
* Output is not a tty. * Output is not a tty.
* Just copy the input file(s) to output. * Just copy the input file(s) to output.
*/ */
set_output(1); /* write to stdout */ set_output(1, TRUE); /* write to stdout */
SET_BINARY(1); SET_BINARY(1);
if (edit_first() == 0) if (edit_first() == 0)
{ {
@@ -476,7 +475,7 @@ int main(int argc, constant char *argv[])
/* /*
* See if file fits on one screen to decide whether * See if file fits on one screen to decide whether
* to send terminal init. But don't need this * to send terminal init. But don't need this
* if -X (no_init) overrides this (see init()). * if -X (no_init) overrides this (see term_init()).
*/ */
if (quit_if_one_screen) if (quit_if_one_screen)
{ {
@@ -504,8 +503,10 @@ int main(int argc, constant char *argv[])
get_return(); get_return();
putchr('\n'); putchr('\n');
} }
set_output(1); set_output(1, FALSE);
init(); #if MSDOS_COMPILER
term_init();
#endif
commands(); commands();
quit(QUIT_OK); quit(QUIT_OK);
/*NOTREACHED*/ /*NOTREACHED*/
@@ -617,9 +618,9 @@ public void quit(int status)
check_altpipe_error(); check_altpipe_error();
if (interactive()) if (interactive())
clear_bot(); clear_bot();
deinit(); term_deinit();
flush(); flush();
if (redraw_on_quit && term_init_done) if (redraw_on_quit && term_addrs)
{ {
/* /*
* The last file text displayed might have been on an * The last file text displayed might have been on an
+106 -50
View File
@@ -27,7 +27,6 @@ struct mark
* because we don't want to create an ifile until the * because we don't want to create an ifile until the
* user explicitly requests the file (by name or mark). * user explicitly requests the file (by name or mark).
*/ */
char m_letter; /* Associated character */
IFILE m_ifile; /* Input file being marked */ IFILE m_ifile; /* Input file being marked */
char *m_filename; /* Name of the input file */ char *m_filename; /* Name of the input file */
struct scrpos m_scrpos; /* Position of the mark */ struct scrpos m_scrpos; /* Position of the mark */
@@ -39,12 +38,14 @@ struct mark
* The final one is lmark, for the "last mark"; addressed by the apostrophe. * The final one is lmark, for the "last mark"; addressed by the apostrophe.
*/ */
#define NMARKS ((2*26)+2) /* a-z, A-Z, mousemark, lastmark */ #define NMARKS ((2*26)+2) /* a-z, A-Z, mousemark, lastmark */
#define NUMARKS ((2*26)+1) /* user marks (not lastmark) */ #define NUMARKS (NMARKS-1) /* user marks (not lastmark) */
#define MOUSEMARK (NMARKS-2)
#define LASTMARK (NMARKS-1) #define LASTMARK (NMARKS-1)
#define MOUSEMARK (LASTMARK-1)
static struct mark marks[NMARKS]; static struct mark marks[NMARKS];
public int marks_modified = 0; public lbool marks_modified = FALSE;
#if CMD_HISTORY
static struct mark file_marks[NMARKS];
#endif
/* /*
* Initialize a mark struct. * Initialize a mark struct.
@@ -69,17 +70,23 @@ public void init_mark(void)
for (i = 0; i < NMARKS; i++) for (i = 0; i < NMARKS; i++)
{ {
char letter;
switch (i) {
case MOUSEMARK: letter = '#'; break;
case LASTMARK: letter = '\''; break;
default: letter = (char) ((i < 26) ? 'a'+i : 'A'+i-26); break;
}
marks[i].m_letter = letter;
cmark(&marks[i], NULL_IFILE, NULL_POSITION, -1); cmark(&marks[i], NULL_IFILE, NULL_POSITION, -1);
#if CMD_HISTORY
cmark(&file_marks[i], NULL_IFILE, NULL_POSITION, -1);
#endif
} }
} }
static void mark_clear(struct mark *m)
{
m->m_scrpos.pos = NULL_POSITION;
}
static lbool mark_is_set(struct mark *m)
{
return m->m_scrpos.pos != NULL_POSITION;
}
/* /*
* Set m_ifile and clear m_filename. * Set m_ifile and clear m_filename.
*/ */
@@ -101,23 +108,48 @@ static void mark_get_ifile(struct mark *m)
mark_set_ifile(m, get_ifile(m->m_filename, prev_ifile(NULL_IFILE))); mark_set_ifile(m, get_ifile(m->m_filename, prev_ifile(NULL_IFILE)));
} }
/*
* Return the letter associated with a mark index.
*/
static char mark_letter(int index)
{
switch (index) {
case LASTMARK: return '\'';
case MOUSEMARK: return '#';
default: return (char) ((index < 26) ? 'a'+index : 'A'+index-26);
}
}
/*
* Return the mark table index identified by a character.
*/
static int mark_index(char c)
{
if (c >= 'a' && c <= 'z')
return c-'a';
if (c >= 'A' && c <= 'Z')
return c-'A'+26;
if (c == '\'')
return LASTMARK;
if (c == '#')
return MOUSEMARK;
return -1;
}
/* /*
* Return the user mark struct identified by a character. * Return the user mark struct identified by a character.
*/ */
static struct mark * getumark(char c) static struct mark * getumark(char c)
{ {
PARG parg; int index = mark_index(c);
if (c >= 'a' && c <= 'z') if (index < 0 || index >= NUMARKS)
return (&marks[c-'a']); {
if (c >= 'A' && c <= 'Z') PARG parg;
return (&marks[c-'A'+26]); parg.p_char = (char) c;
if (c == '\'') error("Invalid mark letter %c", &parg);
return (&marks[LASTMARK]); return NULL;
if (c == '#') }
return (&marks[MOUSEMARK]); return &marks[index];
parg.p_char = (char) c;
error("Invalid mark letter %c", &parg);
return (NULL);
} }
/* /*
@@ -172,7 +204,7 @@ static struct mark * getmark(char c)
m = getumark(c); m = getumark(c);
if (m == NULL) if (m == NULL)
break; break;
if (m->m_scrpos.pos == NULL_POSITION) if (!mark_is_set(m))
{ {
error("Mark not set", NULL_PARG); error("Mark not set", NULL_PARG);
return (NULL); return (NULL);
@@ -185,7 +217,7 @@ static struct mark * getmark(char c)
/* /*
* Is a mark letter invalid? * Is a mark letter invalid?
*/ */
public int badmark(char c) public lbool badmark(char c)
{ {
return (getmark(c) == NULL); return (getmark(c) == NULL);
} }
@@ -204,11 +236,13 @@ public void setmark(char c, int where)
get_scrpos(&scrpos, where); get_scrpos(&scrpos, where);
if (scrpos.pos == NULL_POSITION) if (scrpos.pos == NULL_POSITION)
{ {
bell(); lbell();
return; return;
} }
cmark(m, curr_ifile, scrpos.pos, scrpos.ln); cmark(m, curr_ifile, scrpos.pos, scrpos.ln);
marks_modified = 1; marks_modified = TRUE;
if (perma_marks && autosave_action('m'))
save_cmdhist();
} }
/* /*
@@ -223,11 +257,13 @@ public void clrmark(char c)
return; return;
if (m->m_scrpos.pos == NULL_POSITION) if (m->m_scrpos.pos == NULL_POSITION)
{ {
bell(); lbell();
return; return;
} }
m->m_scrpos.pos = NULL_POSITION; m->m_scrpos.pos = NULL_POSITION;
marks_modified = 1; marks_modified = TRUE;
if (perma_marks && autosave_action('m'))
save_cmdhist();
} }
/* /*
@@ -243,7 +279,7 @@ public void lastmark(void)
if (scrpos.pos == NULL_POSITION) if (scrpos.pos == NULL_POSITION)
return; return;
cmark(&marks[LASTMARK], curr_ifile, scrpos.pos, scrpos.ln); cmark(&marks[LASTMARK], curr_ifile, scrpos.pos, scrpos.ln);
marks_modified = 1; marks_modified = TRUE;
} }
/* /*
@@ -264,7 +300,7 @@ public void gomark(char c)
* set it to the beginning of the current file. * set it to the beginning of the current file.
* {{ Couldn't we instead set marks[LASTMARK] in edit()? }} * {{ Couldn't we instead set marks[LASTMARK] in edit()? }}
*/ */
if (m == &marks[LASTMARK] && m->m_scrpos.pos == NULL_POSITION) if (m == &marks[LASTMARK] && !mark_is_set(m))
cmark(m, curr_ifile, ch_zero(), jump_sline); cmark(m, curr_ifile, ch_zero(), jump_sline);
mark_get_ifile(m); mark_get_ifile(m);
@@ -316,14 +352,11 @@ public char posmark(POSITION pos)
/* Only user marks */ /* Only user marks */
for (i = 0; i < NUMARKS; i++) for (i = 0; i < NUMARKS; i++)
{ {
if (marks[i].m_ifile == curr_ifile && marks[i].m_scrpos.pos == pos) struct mark *m = &marks[i];
{ if (m->m_ifile == curr_ifile && m->m_scrpos.pos == pos)
if (i < 26) return (char) ('a' + i); return mark_letter(i);
if (i < 26*2) return (char) ('A' + (i - 26));
return '#';
}
} }
return 0; return '\0';
} }
/* /*
@@ -335,7 +368,7 @@ public void unmark(IFILE ifile)
for (i = 0; i < NMARKS; i++) for (i = 0; i < NMARKS; i++)
if (marks[i].m_ifile == ifile) if (marks[i].m_ifile == ifile)
marks[i].m_scrpos.pos = NULL_POSITION; mark_clear(&marks[i]);
} }
/* /*
@@ -363,6 +396,15 @@ public void mark_check_ifile(IFILE ifile)
#if CMD_HISTORY #if CMD_HISTORY
/*
* Initialize a mark struct, including the filename.
*/
static void cmarkf(struct mark *m, IFILE ifile, POSITION pos, int ln, constant char *filename)
{
cmark(m, ifile, pos, ln);
m->m_filename = (filename == NULL) ? NULL : save(filename);
}
/* /*
* Save marks to history file. * Save marks to history file.
*/ */
@@ -370,16 +412,29 @@ public void save_marks(FILE *fout, constant char *hdr)
{ {
int i; int i;
if (!perma_marks) if (perma_marks)
return; {
/* Copy active marks to file_marks. */
for (i = 0; i < NMARKS; i++)
{
struct mark *m = &marks[i];
if (mark_is_set(m))
cmarkf(&file_marks[i], m->m_ifile, m->m_scrpos.pos, m->m_scrpos.ln, m->m_filename);
}
}
/*
* Save file_marks to the history file.
* These may have been read from the history file at startup
* (in restore_mark), or copied from the active marks above.
*/
fprintf(fout, "%s\n", hdr); fprintf(fout, "%s\n", hdr);
for (i = 0; i < NMARKS; i++) for (i = 0; i < NMARKS; i++)
{ {
constant char *filename; constant char *filename;
struct mark *m = &marks[i]; struct mark *m = &file_marks[i];
char pos_str[INT_STRLEN_BOUND(m->m_scrpos.pos) + 2]; char pos_str[INT_STRLEN_BOUND(m->m_scrpos.pos) + 2];
if (m->m_scrpos.pos == NULL_POSITION) if (!mark_is_set(m))
continue; continue;
postoa(m->m_scrpos.pos, pos_str, 10); postoa(m->m_scrpos.pos, pos_str, 10);
filename = m->m_filename; filename = m->m_filename;
@@ -387,7 +442,7 @@ public void save_marks(FILE *fout, constant char *hdr)
filename = get_real_filename(m->m_ifile); filename = get_real_filename(m->m_ifile);
if (strcmp(filename, "-") != 0) if (strcmp(filename, "-") != 0)
fprintf(fout, "m %c %d %s %s\n", fprintf(fout, "m %c %d %s %s\n",
m->m_letter, m->m_scrpos.ln, pos_str, filename); mark_letter(i), m->m_scrpos.ln, pos_str, filename);
} }
} }
@@ -396,7 +451,7 @@ public void save_marks(FILE *fout, constant char *hdr)
*/ */
public void restore_mark(constant char *line) public void restore_mark(constant char *line)
{ {
struct mark *m; int index;
int ln; int ln;
POSITION pos; POSITION pos;
@@ -404,8 +459,8 @@ public void restore_mark(constant char *line)
if (*line++ != 'm') if (*line++ != 'm')
return; return;
skip_whitespace; skip_whitespace;
m = getumark(*line++); index = mark_index(*line++);
if (m == NULL) if (index < 0)
return; return;
skip_whitespace; skip_whitespace;
ln = lstrtoic(line, &line, 10); ln = lstrtoic(line, &line, 10);
@@ -420,8 +475,9 @@ public void restore_mark(constant char *line)
if (pos < 0) if (pos < 0)
return; return;
skip_whitespace; skip_whitespace;
cmark(m, NULL_IFILE, pos, ln); /* Save in both active marks table and file_marks table. */
m->m_filename = save(line); cmarkf(&marks[index], NULL_IFILE, pos, ln, line);
cmarkf(&file_marks[index], NULL_IFILE, pos, ln, line);
} }
#endif /* CMD_HISTORY */ #endif /* CMD_HISTORY */
+1 -1
View File
@@ -1,4 +1,4 @@
/* Generated by "./mkutable -f2 Xx -- unicode/UnicodeData.txt" on Aug 19 1:16:32 GMT 2025 */ /* Generated by "./mkutable -f2 Xx -- unicode/UnicodeData.txt" on Nov 28 1:30:12 GMT 2025 */
{ 0x00ad, 0x00ad }, /* Xx */ { 0x00ad, 0x00ad }, /* Xx */
{ 0x200d, 0x200d }, /* Xx */ { 0x200d, 0x200d }, /* Xx */
{ 0xfe00, 0xfe0f }, /* Xx */ { 0xfe00, 0xfe0f }, /* Xx */
+76 -52
View File
@@ -44,6 +44,7 @@ extern char *wproto;
extern char *every_first_cmd; extern char *every_first_cmd;
extern IFILE curr_ifile; extern IFILE curr_ifile;
extern char version[]; extern char version[];
extern int jump_sline_arg;
extern int jump_sline; extern int jump_sline;
extern long jump_sline_fraction; extern long jump_sline_fraction;
extern int shift_count; extern int shift_count;
@@ -73,6 +74,7 @@ extern int nosearch_header_cols;
extern POSITION header_start_pos; extern POSITION header_start_pos;
extern char *init_header; extern char *init_header;
extern char *first_cmd_at_prompt; extern char *first_cmd_at_prompt;
extern char *autosave;
#if LOGFILE #if LOGFILE
extern char *namelogfile; extern char *namelogfile;
extern lbool force_logfile; extern lbool force_logfile;
@@ -166,36 +168,27 @@ public void opt__O(int type, constant char *s)
} }
#endif #endif
static int toggle_fraction(int *num, long *frac, constant char *s, constant char *printopt, void (*calc)(void)) static void toggle_fraction(int *num, long *frac, constant char *s, constant char *printopt, lbool neg_ok, void (*calc)(void))
{ {
lbool err;
if (s == NULL) if (s == NULL)
{ {
(*calc)();
} else if (*s == '.') } else if (*s == '.')
{ {
long tfrac;
s++; s++;
tfrac = getfraction(&s, printopt, &err); if (!getfraction(&s, frac))
if (err)
{ {
error("Invalid fraction", NULL_PARG); PARG parg;
return -1; parg.p_string = printopt;
error("Invalid fraction in %s", &parg);
return;
} }
*frac = tfrac;
(*calc)();
} else } else
{ {
int tnum = getnumc(&s, printopt, &err); if (!getnumc(&s, printopt, neg_ok, num))
if (err) return;
{
error("Invalid number", NULL_PARG);
return -1;
}
*frac = -1; *frac = -1;
*num = tnum;
} }
return 0; (*calc)();
} }
static void query_fraction(int value, long fraction, constant char *int_msg, constant char *frac_msg) static void query_fraction(int value, long fraction, constant char *int_msg, constant char *frac_msg)
@@ -229,11 +222,11 @@ public void opt_j(int type, constant char *s)
{ {
case INIT: case INIT:
case TOGGLE: case TOGGLE:
toggle_fraction(&jump_sline, &jump_sline_fraction, toggle_fraction(&jump_sline_arg, &jump_sline_fraction,
s, "j", calc_jump_sline); s, "-j", TRUE, calc_jump_sline);
break; break;
case QUERY: case QUERY:
query_fraction(jump_sline, jump_sline_fraction, query_fraction(jump_sline_arg, jump_sline_fraction,
"Position target at screen line %d", "Position target at screen position %s"); "Position target at screen line %d", "Position target at screen position %s");
break; break;
} }
@@ -241,10 +234,19 @@ public void opt_j(int type, constant char *s)
public void calc_jump_sline(void) public void calc_jump_sline(void)
{ {
jump_sline = jump_sline_arg;
/* If jump_sline_fraction is set, calculate jump_sline from it. */
if (jump_sline_fraction >= 0) if (jump_sline_fraction >= 0)
jump_sline = (int) muldiv(sc_height, jump_sline_fraction, NUM_FRAC_DENOM); jump_sline = (int) muldiv(sc_height, jump_sline_fraction, NUM_FRAC_DENOM);
/* Negative jump_sline means relative to bottom of screen. */
if (jump_sline < 0)
jump_sline += sc_height;
/* If jump_sline is obscured by header, move it after the header. */
if (jump_sline <= header_lines) if (jump_sline <= header_lines)
jump_sline = header_lines + 1; jump_sline = header_lines + 1;
/* If jump_sline is past bottom of screen, move it to the bottom. */
if (jump_sline >= sc_height)
jump_sline = sc_height - 1;
} }
/* /*
@@ -257,7 +259,7 @@ public void opt_shift(int type, constant char *s)
case INIT: case INIT:
case TOGGLE: case TOGGLE:
toggle_fraction(&shift_count, &shift_count_fraction, toggle_fraction(&shift_count, &shift_count_fraction,
s, "#", calc_shift_count); s, "-#", FALSE, calc_shift_count);
break; break;
case QUERY: case QUERY:
query_fraction(shift_count, shift_count_fraction, query_fraction(shift_count, shift_count_fraction,
@@ -472,6 +474,30 @@ public void opt__P(int type, constant char *s)
} }
} }
/*
* Handler for --autosave option.
*/
public void opt_autosave(int type, constant char *s)
{
PARG parg;
switch (type)
{
case INIT:
case TOGGLE:
if (s == NULL)
s = "-";
if (autosave != NULL)
free(autosave);
autosave = save(s);
break;
case QUERY:
parg.p_string = (autosave != NULL) ? autosave : "-";
error("Autosave actions: %s", &parg);
break;
}
}
/* /*
* Handler for the -b option. * Handler for the -b option.
*/ */
@@ -522,7 +548,7 @@ public void opt__V(int type, constant char *s)
dispversion(); dispversion();
break; break;
case INIT: case INIT:
set_output(1); /* Force output to stdout per GNU standard for --version output. */ set_output(1, TRUE); /* Force output to stdout per GNU standard for --version output. */
putstr("less "); putstr("less ");
putstr(version); putstr(version);
putstr(" ("); putstr(" (");
@@ -854,7 +880,7 @@ public void opt_match_shift(int type, constant char *s)
case INIT: case INIT:
case TOGGLE: case TOGGLE:
toggle_fraction(&match_shift, &match_shift_fraction, toggle_fraction(&match_shift, &match_shift_fraction,
s, "--match-shift", calc_match_shift); s, "--match-shift", FALSE, calc_match_shift);
break; break;
case QUERY: case QUERY:
query_fraction(match_shift, match_shift_fraction, query_fraction(match_shift, match_shift_fraction,
@@ -1019,28 +1045,24 @@ public void opt_intr(int type, constant char *s)
* Return -1 if the list entry is missing or empty. * Return -1 if the list entry is missing or empty.
* Updates *sp to point to the first char of the next number in the list. * Updates *sp to point to the first char of the next number in the list.
*/ */
public int next_cnum(constant char **sp, constant char *printopt, constant char *errmsg, lbool *errp) static lbool next_cnum(constant char **sp, constant char *printopt, mutable int *p_num)
{ {
int n;
*errp = FALSE;
if (**sp == '\0') /* at end of line */ if (**sp == '\0') /* at end of line */
return -1; {
*p_num = -1;
return TRUE;
}
if (**sp == ',') /* that's the next comma; we have an empty string */ if (**sp == ',') /* that's the next comma; we have an empty string */
{ {
++(*sp); ++(*sp);
return -1; *p_num = -1;
} return TRUE;
n = getnumc(sp, printopt, errp);
if (*errp)
{
PARG parg;
parg.p_string = errmsg;
error("invalid %s", &parg);
return -1;
} }
if (!getnumc(sp, printopt, FALSE, p_num))
return FALSE;
if (**sp == ',') if (**sp == ',')
++(*sp); ++(*sp);
return n; return TRUE;
} }
/* /*
@@ -1050,26 +1072,21 @@ public int next_cnum(constant char **sp, constant char *printopt, constant char
static lbool parse_header(constant char *s, int *lines, int *cols, POSITION *start_pos) static lbool parse_header(constant char *s, int *lines, int *cols, POSITION *start_pos)
{ {
int n; int n;
lbool err;
if (*s == '-') if (*s == '-')
s = "0,0"; s = "0,0";
if (!next_cnum(&s, "--header", &n))
n = next_cnum(&s, "header", "number of lines", &err); return FALSE;
if (err) return FALSE;
if (n >= 0) *lines = n; if (n >= 0) *lines = n;
if (!next_cnum(&s, "--header", &n))
n = next_cnum(&s, "header", "number of columns", &err); return FALSE;
if (err) return FALSE;
if (n >= 0) *cols = n; if (n >= 0) *cols = n;
if (!next_cnum(&s, "--header", &n))
n = next_cnum(&s, "header", "line number", &err); return FALSE;
if (err) return FALSE; if (n > 0)
if (n > 0)
{ {
LINENUM lnum = (LINENUM) n; if (n < 1) n = 1;
if (lnum < 1) lnum = 1; *start_pos = find_pos((LINENUM)n);
*start_pos = find_pos(lnum);
} }
return TRUE; return TRUE;
} }
@@ -1264,3 +1281,10 @@ public int get_swindow(void)
return (sc_height - header_lines + swindow); return (sc_height - header_lines + swindow);
} }
/*
* Should an action initiate an autosave?
*/
public lbool autosave_action(char act)
{
return strchr(autosave, act) != NULL || strchr(autosave, '*') != NULL;
}
+69 -67
View File
@@ -70,7 +70,6 @@ public void scan_option(constant char *s, lbool is_env)
char *str; char *str;
lbool set_default; lbool set_default;
lbool lc; lbool lc;
lbool ambig;
PARG parg; PARG parg;
if (s == NULL) if (s == NULL)
@@ -94,7 +93,7 @@ public void scan_option(constant char *s, lbool is_env)
break; break;
case O_NUMBER: case O_NUMBER:
printopt = opt_desc(pendopt); printopt = opt_desc(pendopt);
*(pendopt->ovar) = getnumc(&s, printopt, NULL); getnumc(&s, printopt, FALSE, pendopt->ovar);
break; break;
} }
} }
@@ -179,14 +178,20 @@ public void scan_option(constant char *s, lbool is_env)
* Not a special case. * Not a special case.
* Look up the option letter in the option table. * Look up the option letter in the option table.
*/ */
ambig = FALSE;
if (optname == NULL) if (optname == NULL)
{ {
printopt = propt(optc); printopt = propt(optc);
lc = ASCII_IS_LOWER(optc); lc = ASCII_IS_LOWER(optc);
o = findopt(optc); o = findopt(optc);
if (o == NULL)
{
parg.p_string = printopt;
error("There is no %s option (\"less --help\" for help)", &parg);
return;
}
} else } else
{ {
lbool ambig = FALSE;
printopt = optname; printopt = optname;
lc = ASCII_IS_LOWER(optname[0]); lc = ASCII_IS_LOWER(optname[0]);
o = findopt_name(&optname, NULL, &ambig); o = findopt_name(&optname, NULL, &ambig);
@@ -208,7 +213,7 @@ public void scan_option(constant char *s, lbool is_env)
(o->otype & OTYPE) != O_NUMBER) (o->otype & OTYPE) != O_NUMBER)
{ {
parg.p_string = printopt; parg.p_string = printopt;
error("The %s option should not be followed by =", error("The --%s option should not be followed by =",
&parg); &parg);
return; return;
} }
@@ -221,17 +226,15 @@ public void scan_option(constant char *s, lbool is_env)
*/ */
o = NULL; o = NULL;
} }
} if (o == NULL)
if (o == NULL) {
{ parg.p_string = printopt;
parg.p_string = printopt; if (ambig)
if (ambig) error("--%s is an ambiguous abbreviation (\"less --help\" for help)", &parg);
error("%s is an ambiguous abbreviation (\"less --help\" for help)", else
&parg); error("There is no --%s option (\"less --help\" for help)", &parg);
else return;
error("There is no %s option (\"less --help\" for help)", }
&parg);
return;
} }
str = NULL; str = NULL;
@@ -292,7 +295,7 @@ public void scan_option(constant char *s, lbool is_env)
} }
if (o->otype & O_UNSUPPORTED) if (o->otype & O_UNSUPPORTED)
break; break;
*(o->ovar) = getnumc(&s, printopt, NULL); getnumc(&s, printopt, FALSE, o->ovar);
break; break;
} }
/* /*
@@ -314,11 +317,9 @@ public void scan_option(constant char *s, lbool is_env)
* OPT_UNSET set to the default value * OPT_UNSET set to the default value
* OPT_SET set to the inverse of the default value * OPT_SET set to the inverse of the default value
*/ */
public void toggle_option(struct loption *o, lbool lower, constant char *s, int how_toggle) public lbool toggle_option(struct loption *o, lbool lower, constant char *s, int how_toggle)
{ {
int num;
int no_prompt; int no_prompt;
lbool err;
PARG parg; PARG parg;
no_prompt = (how_toggle & OPT_NO_PROMPT); no_prompt = (how_toggle & OPT_NO_PROMPT);
@@ -327,21 +328,21 @@ public void toggle_option(struct loption *o, lbool lower, constant char *s, int
if (o == NULL) if (o == NULL)
{ {
error("No such option", NULL_PARG); error("No such option", NULL_PARG);
return; return FALSE;
} }
if (how_toggle == OPT_TOGGLE && (o->otype & O_NO_TOGGLE)) if (how_toggle == OPT_TOGGLE && (o->otype & O_NO_TOGGLE))
{ {
parg.p_string = opt_desc(o); parg.p_string = opt_desc(o);
error("Cannot change the %s option", &parg); error("Cannot change the %s option", &parg);
return; return FALSE;
} }
if (how_toggle == OPT_NO_TOGGLE && (o->otype & O_NO_QUERY)) if (how_toggle == OPT_NO_TOGGLE && (o->otype & O_NO_QUERY))
{ {
parg.p_string = opt_desc(o); parg.p_string = opt_desc(o);
error("Cannot query the %s option", &parg); error("Cannot query the %s option", &parg);
return; return FALSE;
} }
/* /*
@@ -426,7 +427,7 @@ public void toggle_option(struct loption *o, lbool lower, constant char *s, int
case OPT_UNSET: case OPT_UNSET:
error("Cannot use \"-+\" or \"-!\" for a string option", error("Cannot use \"-+\" or \"-!\" for a string option",
NULL_PARG); NULL_PARG);
return; return FALSE;
} }
break; break;
case O_NUMBER: case O_NUMBER:
@@ -436,9 +437,8 @@ public void toggle_option(struct loption *o, lbool lower, constant char *s, int
switch (how_toggle) switch (how_toggle)
{ {
case OPT_TOGGLE: case OPT_TOGGLE:
num = getnumc(&s, NULL, &err); if (!getnumc(&s, opt_desc(o), FALSE, o->ovar))
if (!err) return FALSE;
*(o->ovar) = num;
break; break;
case OPT_UNSET: case OPT_UNSET:
*(o->ovar) = o->odefault; *(o->ovar) = o->odefault;
@@ -446,7 +446,7 @@ public void toggle_option(struct loption *o, lbool lower, constant char *s, int
case OPT_SET: case OPT_SET:
error("Can't use \"-!\" for a numeric option", error("Can't use \"-!\" for a numeric option",
NULL_PARG); NULL_PARG);
return; return FALSE;
} }
break; break;
} }
@@ -488,15 +488,15 @@ public void toggle_option(struct loption *o, lbool lower, constant char *s, int
error(o->odesc[1], &parg); error(o->odesc[1], &parg);
break; break;
case O_STRING: case O_STRING:
/* if (how_toggle != OPT_NO_TOGGLE && o->ofunc != NULL)
* Message was already printed by the handling function. (*o->ofunc)(QUERY, NULL);
*/
break; break;
} }
} }
if (how_toggle != OPT_NO_TOGGLE && (o->otype & O_REPAINT)) if (how_toggle != OPT_NO_TOGGLE && (o->otype & O_REPAINT))
screen_trashed(); screen_trashed();
return TRUE;
} }
/* /*
@@ -513,20 +513,20 @@ static int flip_triple(int val, lbool lc)
/* /*
* Determine if an option takes a parameter. * Determine if an option takes a parameter.
*/ */
public int opt_has_param(struct loption *o) public lbool opt_has_param(constant struct loption *o)
{ {
if (o == NULL) if (o == NULL)
return (0); return FALSE;
if (o->otype & (O_BOOL|O_TRIPLE|O_NOVAR|O_NO_TOGGLE)) if (o->otype & (O_BOOL|O_TRIPLE|O_NOVAR|O_NO_TOGGLE))
return (0); return FALSE;
return (1); return TRUE;
} }
/* /*
* Return the prompt to be used for a given option letter. * Return the prompt to be used for a given option letter.
* Only string and number valued options have prompts. * Only string and number valued options have prompts.
*/ */
public constant char * opt_prompt(struct loption *o) public constant char * opt_prompt(constant struct loption *o)
{ {
if (o == NULL || (o->otype & (O_STRING|O_NUMBER)) == 0) if (o == NULL || (o->otype & (O_STRING|O_NUMBER)) == 0)
return ("?"); return ("?");
@@ -653,26 +653,29 @@ static constant char * optstring(constant char *s, char **p_str, constant char *
return (p); return (p);
} }
/* typedef enum {
*/ NUM_ERR_NONE, NUM_ERR_OVERFLOW, NUM_ERR_NEG, NUM_ERR_MISSING
static int num_error(constant char *printopt, lbool *errp, lbool overflow) } num_error_type;
{
PARG parg;
if (errp != NULL) /*
{ * Display error message for invalid number.
*errp = TRUE; */
return (-1); static lbool num_error(constant char *printopt, num_error_type error_type)
} {
if (printopt != NULL) if (printopt != NULL)
{ {
constant char *msg;
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;
}
parg.p_string = printopt; parg.p_string = printopt;
error((overflow error(msg, &parg);
? "Number too large in '%s'"
: "Number is required after %s"),
&parg);
} }
return (-1); return FALSE;
} }
/* /*
@@ -680,38 +683,38 @@ static int num_error(constant char *printopt, lbool *errp, lbool overflow)
* Like atoi(), but takes a pointer to a char *, and updates * Like atoi(), but takes a pointer to a char *, and updates
* the char * to point after the translated number. * the char * to point after the translated number.
*/ */
public int getnumc(constant char **sp, constant char *printopt, lbool *errp) public lbool getnumc(constant char **sp, constant char *printopt, lbool neg_ok, mutable int *p_num)
{ {
constant char *s = *sp; constant char *s = *sp;
int n; int n;
lbool neg; lbool neg = FALSE;
s = skipspc(s); s = skipspc(s);
neg = FALSE;
if (*s == '-') if (*s == '-')
{ {
if (!neg_ok)
return num_error(printopt, NUM_ERR_NEG);
neg = TRUE; neg = TRUE;
s++; s++;
} }
if (*s < '0' || *s > '9') if (*s < '0' || *s > '9')
return (num_error(printopt, errp, FALSE)); return num_error(printopt, NUM_ERR_MISSING);
n = lstrtoic(s, sp, 10); n = lstrtoic(s, sp, 10);
if (n < 0) if (n < 0)
return (num_error(printopt, errp, TRUE)); return num_error(printopt, NUM_ERR_OVERFLOW);
if (errp != NULL)
*errp = FALSE;
if (neg) if (neg)
n = -n; n = -n;
return (n); *p_num = n;
return TRUE;
} }
public int getnum(char **sp, constant char *printopt, lbool *errp) public lbool getnum(char **sp, constant char *printopt, lbool neg_ok, mutable int *p_num)
{ {
constant char *cs = *sp; constant char *cs = *sp;
int r = getnumc(&cs, printopt, errp); if (!getnumc(&cs, printopt, neg_ok, p_num))
return FALSE;
*sp = (char *) cs; *sp = (char *) cs;
return r; return TRUE;
} }
/* /*
@@ -720,7 +723,7 @@ public int getnum(char **sp, constant char *printopt, lbool *errp)
* The value of the fraction is returned as parts per NUM_FRAC_DENOM. * The value of the fraction is returned as parts per NUM_FRAC_DENOM.
* That is, if "n" is returned, the fraction intended is n/NUM_FRAC_DENOM. * That is, if "n" is returned, the fraction intended is n/NUM_FRAC_DENOM.
*/ */
public long getfraction(constant char **sp, constant char *printopt, lbool *errp) public lbool getfraction(constant char **sp, mutable long *p_frac)
{ {
constant char *s; constant char *s;
long frac = 0; long frac = 0;
@@ -728,7 +731,7 @@ public long getfraction(constant char **sp, constant char *printopt, lbool *errp
s = skipspc(*sp); s = skipspc(*sp);
if (*s < '0' || *s > '9') if (*s < '0' || *s > '9')
return (num_error(printopt, errp, FALSE)); return FALSE;
for ( ; *s >= '0' && *s <= '9'; s++) for ( ; *s >= '0' && *s <= '9'; s++)
{ {
@@ -740,9 +743,8 @@ public long getfraction(constant char **sp, constant char *printopt, lbool *errp
while (fraclen++ < NUM_LOG_FRAC_DENOM) while (fraclen++ < NUM_LOG_FRAC_DENOM)
frac *= 10; frac *= 10;
*sp = s; *sp = s;
if (errp != NULL) *p_frac = frac;
*errp = FALSE; return TRUE;
return (frac);
} }
/* /*
+7
View File
@@ -40,6 +40,7 @@ public int ctldisp; /* Send control chars to screen untranslated */
public int force_open; /* Open the file even if not regular file */ public int force_open; /* Open the file even if not regular file */
public int swindow; /* Size of scrolling window */ public int swindow; /* Size of scrolling window */
public int jump_sline; /* Screen line of "jump target" */ public int jump_sline; /* Screen line of "jump target" */
public int jump_sline_arg;
public long jump_sline_fraction = -1; public long jump_sline_fraction = -1;
public int shift_count; /* Number of positions to shift horizontally */ public int shift_count; /* Number of positions to shift horizontally */
public long shift_count_fraction = -1; public long shift_count_fraction = -1;
@@ -87,6 +88,7 @@ public int stop_on_form_feed; /* Stop scrolling on a line starting with form f
public long match_shift_fraction = NUM_FRAC_DENOM/2; /* 1/2 of screen width */ public long match_shift_fraction = NUM_FRAC_DENOM/2; /* 1/2 of screen width */
public char intr_char = CONTROL('X'); /* Char to interrupt reads */ public char intr_char = CONTROL('X'); /* Char to interrupt reads */
public char *first_cmd_at_prompt = NULL; /* Command to exec before first prompt */ public char *first_cmd_at_prompt = NULL; /* Command to exec before first prompt */
public char *autosave; /* Actions which do autosave of history file */
#if HILITE_SEARCH #if HILITE_SEARCH
public int hilite_search; /* Highlight matched search patterns? */ public int hilite_search; /* Highlight matched search patterns? */
#endif #endif
@@ -186,6 +188,7 @@ static struct optname proc_tab_optname = { "proc-tab", NULL };
static struct optname proc_return_optname = { "proc-return", NULL }; static struct optname proc_return_optname = { "proc-return", NULL };
static struct optname match_shift_optname = { "match-shift", NULL }; static struct optname match_shift_optname = { "match-shift", NULL };
static struct optname first_cmd_at_prompt_optname = { "cmd", NULL }; static struct optname first_cmd_at_prompt_optname = { "cmd", NULL };
static struct optname autosave_optname = { "autosave", NULL };
#if LESSTEST #if LESSTEST
static struct optname ttyin_name_optname = { "tty", NULL }; static struct optname ttyin_name_optname = { "tty", NULL };
#endif /*LESSTEST*/ #endif /*LESSTEST*/
@@ -762,6 +765,10 @@ static struct loption option[] =
NULL NULL
} }
}, },
{ OLETTER_NONE, &autosave_optname,
O_STRING|O_INIT_HANDLER, 0, NULL, opt_autosave,
{ "Autosave actions: ", "s", NULL }
},
#if LESSTEST #if LESSTEST
{ OLETTER_NONE, &ttyin_name_optname, { OLETTER_NONE, &ttyin_name_optname,
O_STRING|O_NO_TOGGLE, 0, NULL, opt_ttyin_name, O_STRING|O_NO_TOGGLE, 0, NULL, opt_ttyin_name,
+44 -19
View File
@@ -82,7 +82,6 @@ static lbool opening;
public lbool waiting_for_data; public lbool waiting_for_data;
public int consecutive_nulls = 0; public int consecutive_nulls = 0;
public lbool getting_one_screen = FALSE; public lbool getting_one_screen = FALSE;
public lbool no_poll = FALSE;
/* Milliseconds to wait for data before displaying "waiting for data" message. */ /* Milliseconds to wait for data before displaying "waiting for data" message. */
static int waiting_for_data_delay = 4000; static int waiting_for_data_delay = 4000;
@@ -93,7 +92,7 @@ static JUMP_BUF read_label;
static JUMP_BUF open_label; static JUMP_BUF open_label;
extern int sigs; extern int sigs;
extern int ignore_eoi; extern lbool ignore_eoi;
extern int exit_F_on_close; extern int exit_F_on_close;
extern int follow_mode; extern int follow_mode;
extern int scanning_eof; extern int scanning_eof;
@@ -104,7 +103,7 @@ extern int one_screen;
#if HAVE_TIME #if HAVE_TIME
extern time_type less_start_time; extern time_type less_start_time;
#endif #endif
#if !MSDOS_COMPILER #if LESS_IREAD_TTY
extern int tty; extern int tty;
#endif #endif
@@ -164,8 +163,6 @@ static int check_poll(int fd, int tty)
/* Break out of "waiting for data". */ /* Break out of "waiting for data". */
return (READ_INTR); return (READ_INTR);
ungetcc_back((char) ch); ungetcc_back((char) ch);
if (!no_poll)
return (READ_INTR);
} }
} }
if (ignore_eoi && exit_F_on_close && (poller[0].revents & (POLLHUP|POLLIN)) == POLLHUP) if (ignore_eoi && exit_F_on_close && (poller[0].revents & (POLLHUP|POLLIN)) == POLLHUP)
@@ -198,6 +195,7 @@ public lbool ttyin_ready(void)
if (!use_poll) if (!use_poll)
return FALSE; return FALSE;
{ {
/* {{ assert LESS_IREAD_TTY }} */
struct pollfd poller[1] = { { tty, POLLIN, 0 } }; struct pollfd poller[1] = { { tty, POLLIN, 0 } };
poll(poller, 1, 0); poll(poller, 1, 0);
return ((poller[0].revents & POLLIN) != 0); return ((poller[0].revents & POLLIN) != 0);
@@ -209,7 +207,7 @@ public lbool ttyin_ready(void)
#endif #endif
} }
public int supports_ctrl_x(void) public lbool supports_ctrl_x(void)
{ {
#if MSDOS_COMPILER==WIN32C #if MSDOS_COMPILER==WIN32C
return (TRUE); return (TRUE);
@@ -269,7 +267,7 @@ public ssize_t iread(int fd, unsigned char *buf, size_t len)
#endif #endif
#endif #endif
#endif #endif
#if !MSDOS_COMPILER #if !MSDOS_COMPILER /* {{ LESS_IREAD_TTY? }} */
if (fd != tty && !ABORT_SIGS()) if (fd != tty && !ABORT_SIGS())
/* Non-interrupt signal like SIGWINCH. */ /* Non-interrupt signal like SIGWINCH. */
return (READ_AGAIN); return (READ_AGAIN);
@@ -316,19 +314,14 @@ public ssize_t iread(int fd, unsigned char *buf, size_t len)
#if MSDOS_COMPILER==WIN32C #if MSDOS_COMPILER==WIN32C
if (!(quit_if_one_screen && one_screen) && win32_kbhit2(TRUE)) if (!(quit_if_one_screen && one_screen) && win32_kbhit2(TRUE))
{ {
int c; int c = WIN32getch();
lbool intr; if (c == CONTROL('C') || c == intr_char)
c = WIN32getch();
intr = (c == CONTROL('C') || c == intr_char);
if (!intr)
WIN32ungetch((char) c);
if (intr || !no_poll)
{ {
sigs |= S_SWINTERRUPT; sigs |= S_SWINTERRUPT;
reading = FALSE; reading = FALSE;
return (READ_INTR); return (READ_INTR);
} }
WIN32ungetch(c);
} }
#endif #endif
#endif #endif
@@ -369,10 +362,13 @@ public ssize_t iread(int fd, unsigned char *buf, size_t len)
#endif #endif
return (READ_ERR); return (READ_ERR);
} }
#if USE_POLL #if LESS_IREAD_TTY
if (fd != tty && n > 0) if (fd != tty)
any_data = TRUE;
#endif #endif
{
if (n > 0)
polling_ok();
}
return (n); return (n);
} }
@@ -418,6 +414,16 @@ public void intio(void)
} }
} }
/*
* We can start polling the input file.
*/
public void polling_ok(void)
{
#if USE_POLL
any_data = TRUE;
#endif
}
/* /*
* Return the current time. * Return the current time.
*/ */
@@ -548,7 +554,7 @@ char * strchr(char *s, char c)
#endif #endif
#if !HAVE_MEMCPY #if !HAVE_MEMCPY
void * memcpy(void *dst, void *src, size_t len) void * memcpy(void *dst, constant void *src, size_t len)
{ {
char *dstp = (char *) dst; char *dstp = (char *) dst;
char *srcp = (char *) src; char *srcp = (char *) src;
@@ -560,6 +566,25 @@ void * memcpy(void *dst, void *src, size_t len)
} }
#endif #endif
#if !HAVE_STRSTR
char * strstr(constant char *haystack, constant char *needle)
{
if (*needle == '\0')
return (char *) haystack;
for (; *haystack; haystack++) {
constant char *h = haystack;
constant char *n = needle;
while (*h != '\0' && *n != '\0' && *h == *n) {
h++;
n++;
}
if (*n == '\0')
return (char *) haystack;
}
return NULL;
}
#endif
#ifdef _OSK_MWC32 #ifdef _OSK_MWC32
/* /*
+23 -13
View File
@@ -23,7 +23,6 @@
public int errmsgs; /* Count of messages displayed by error() */ public int errmsgs; /* Count of messages displayed by error() */
public int need_clr; public int need_clr;
public int final_attr; public int final_attr;
public int at_prompt;
extern int sigs; extern int sigs;
extern int sc_width; extern int sc_width;
@@ -32,6 +31,7 @@ extern int is_tty;
extern int oldbot; extern int oldbot;
extern int utf_mode; extern int utf_mode;
extern char intr_char; extern char intr_char;
extern lbool term_init_ever;
#if MSDOS_COMPILER==WIN32C || MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC #if MSDOS_COMPILER==WIN32C || MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
extern int ctldisp; extern int ctldisp;
@@ -84,7 +84,7 @@ public void put_line(lbool forw_scroll)
/* /*
* win_flush has at least one non-critical issue when an escape sequence * win_flush has at least one non-critical issue when an escape sequence
* begins at the last char of the buffer, and possibly more issues. * begins at the last char of the buffer, and possibly more issues.
* as a temporary measure to reduce likelyhood of encountering end-of-buffer * as a temporary measure to reduce likelihood of encountering end-of-buffer
* issues till the SGR parser is replaced, OUTBUF_SIZE is 8K on Windows. * issues till the SGR parser is replaced, OUTBUF_SIZE is 8K on Windows.
*/ */
static char obuf[OUTBUF_SIZE]; static char obuf[OUTBUF_SIZE];
@@ -435,17 +435,19 @@ public void flush(void)
#endif #endif
#endif #endif
if (write(outfd, obuf, n) != n) if (write(outfd, obuf, n) != (ssize_t) n)
screen_trashed(); screen_trashed();
} }
/* /*
* Set the output file descriptor (1=stdout or 2=stderr). * Set the output file descriptor (1=stdout or 2=stderr).
*/ */
public void set_output(int fd) public void set_output(int fd, lbool no_term_init)
{ {
flush(); flush();
outfd = fd; outfd = fd;
if (no_term_init)
term_init_ever = TRUE; /* don't init terminal in putchr */
} }
/* /*
@@ -455,8 +457,17 @@ public void set_output(int fd)
public int putchr(int ch) public int putchr(int ch)
{ {
char c = (char) ch; char c = (char) ch;
/*
* Init the terminal if this is the first byte written to stdout
* (rather than stderr), and the terminal has never been initted.
* If it has previously been initted, it will be reinitted explicitly
* as part of a term_deinit/term_init pair, so we shouldn't do it here.
*/
if (!term_init_ever && outfd == 1)
term_init();
#if 0 /* fake UTF-8 output for testing */ #if 0 /* fake UTF-8 output for testing */
extern int utf_mode;
if (utf_mode) if (utf_mode)
{ {
static char ubuf[MAX_UTF_CHAR_LEN]; static char ubuf[MAX_UTF_CHAR_LEN];
@@ -494,7 +505,6 @@ public int putchr(int ch)
if (ob >= &obuf[sizeof(obuf)-1]) if (ob >= &obuf[sizeof(obuf)-1])
flush(); flush();
*ob++ = c; *ob++ = c;
at_prompt = 0;
return (c); return (c);
} }
@@ -590,7 +600,7 @@ IPRINT_FUNC(iprint_linenum, LINENUM, linenumtoa)
* {{ This paranoia about the portability of printf dates from experiences * {{ This paranoia about the portability of printf dates from experiences
* with systems in the 1980s and is of course no longer necessary. }} * with systems in the 1980s and is of course no longer necessary. }}
*/ */
public int less_printf(constant char *fmt, PARG *parg) public int less_printf(constant char *fmt, constant PARG *parg)
{ {
constant char *s; constant char *s;
constant char *es; constant char *es;
@@ -664,7 +674,7 @@ public void get_return(void)
#if ONLY_RETURN #if ONLY_RETURN
while ((c = getchr()) != '\n' && c != '\r') while ((c = getchr()) != '\n' && c != '\r')
bell(); lbell();
#else #else
c = getchr(); c = getchr();
if (c != '\n' && c != '\r' && c != ' ' && c != READ_INTR) if (c != '\n' && c != '\r' && c != ' ' && c != READ_INTR)
@@ -676,7 +686,7 @@ public void get_return(void)
* Output a message in the lower left corner of the screen * Output a message in the lower left corner of the screen
* and wait for carriage return. * and wait for carriage return.
*/ */
public void error(constant char *fmt, PARG *parg) public void error(constant char *fmt, constant PARG *parg)
{ {
int col = 0; int col = 0;
static char return_to_continue[] = " (press RETURN)"; static char return_to_continue[] = " (press RETURN)";
@@ -722,7 +732,7 @@ public void error(constant char *fmt, PARG *parg)
* Usually used to warn that we are beginning a potentially * Usually used to warn that we are beginning a potentially
* time-consuming operation. * time-consuming operation.
*/ */
static void ierror_suffix(constant char *fmt, PARG *parg, constant char *suffix1, constant char *suffix2, constant char *suffix3) static void ierror_suffix(constant char *fmt, constant PARG *parg, constant char *suffix1, constant char *suffix2, constant char *suffix3)
{ {
at_exit(); at_exit();
clear_bot(); clear_bot();
@@ -736,12 +746,12 @@ static void ierror_suffix(constant char *fmt, PARG *parg, constant char *suffix1
need_clr = 1; need_clr = 1;
} }
public void ierror(constant char *fmt, PARG *parg) public void ierror(constant char *fmt, constant PARG *parg)
{ {
ierror_suffix(fmt, parg, "... (interrupt to abort)", "", ""); ierror_suffix(fmt, parg, "... (interrupt to abort)", "", "");
} }
public void ixerror(constant char *fmt, PARG *parg) public void ixerror(constant char *fmt, constant PARG *parg)
{ {
if (!supports_ctrl_x()) if (!supports_ctrl_x())
ierror(fmt, parg); ierror(fmt, parg);
@@ -757,7 +767,7 @@ public void ixerror(constant char *fmt, PARG *parg)
* Output a message in the lower left corner of the screen * Output a message in the lower left corner of the screen
* and return a single-character response. * and return a single-character response.
*/ */
public int query(constant char *fmt, PARG *parg) public int query(constant char *fmt, constant PARG *parg)
{ {
int c; int c;
int col = 0; int col = 0;
+23 -18
View File
@@ -13,21 +13,26 @@
* Special (non-ASCII) keys on the PC send a two-byte sequence, * Special (non-ASCII) keys on the PC send a two-byte sequence,
* where the first byte is 0 and the second is as defined below. * where the first byte is 0 and the second is as defined below.
*/ */
#define PCK_SHIFT_TAB '\017' #define PCK_SHIFT_TAB '\x0f'
#define PCK_ALT_E '\022' #define PCK_ALT_E '\x12'
#define PCK_CAPS_LOCK '\072' #define PCK_CAPS_LOCK '\x3a'
#define PCK_F1 '\073' #define PCK_F1 '\x3b'
#define PCK_NUM_LOCK '\105' #define PCK_NUM_LOCK '\x45'
#define PCK_HOME '\107' #define PCK_HOME '\x47'
#define PCK_UP '\110' #define PCK_UP '\x48'
#define PCK_PAGEUP '\111' #define PCK_PAGEUP '\x49'
#define PCK_LEFT '\113' #define PCK_LEFT '\x4b'
#define PCK_RIGHT '\115' #define PCK_RIGHT '\x4d'
#define PCK_END '\117' #define PCK_END '\x4f'
#define PCK_DOWN '\120' #define PCK_DOWN '\x50'
#define PCK_PAGEDOWN '\121' #define PCK_PAGEDOWN '\x51'
#define PCK_INSERT '\122' #define PCK_INSERT '\x52'
#define PCK_DELETE '\123' #define PCK_DELETE '\x53'
#define PCK_CTL_LEFT '\163' /* The following are nonstandard and internal to less. */
#define PCK_CTL_RIGHT '\164' #define PCK_SHIFT_END '\x61'
#define PCK_CTL_DELETE '\223' #define PCK_CTL_DELETE '\x62'
#define PCK_CTL_LEFT '\x63'
#define PCK_CTL_RIGHT '\x74'
#define PCK_CTL_HOME '\x7a'
#define PCK_CTL_END '\x7c'
#define PCK_SHIFT_HOME '\x7d'
+7 -7
View File
@@ -147,19 +147,19 @@ public int onscreen(POSITION pos)
/* /*
* See if the entire screen is empty. * See if the entire screen is empty.
*/ */
public int empty_screen(void) public lbool empty_screen(void)
{ {
return (empty_lines(0, sc_height-1)); return (empty_lines(0, sc_height-1));
} }
public int empty_lines(int s, int e) public lbool empty_lines(int s, int e)
{ {
int i; int i;
for (i = s; i <= e; i++) for (i = s; i <= e; i++)
if (table[i] != NULL_POSITION && table[i] != 0) if (table[i] != NULL_POSITION && table[i] != 0)
return (0); return FALSE;
return (1); return TRUE;
} }
/* /*
@@ -232,12 +232,12 @@ public int sindex_from_sline(int sline)
if (sline < 0) if (sline < 0)
sline += sc_height; sline += sc_height;
/* /*
* Can't be less than 1 or greater than sc_height. * Can't be less than 1 or greater than sc_height-1.
*/ */
if (sline <= 0) if (sline <= 0)
sline = 1; sline = 1;
if (sline > sc_height) if (sline >= sc_height)
sline = sc_height; sline = sc_height-1;
/* /*
* Return zero-based line number, not one-based. * Return zero-based line number, not one-based.
*/ */
+31 -5
View File
@@ -24,6 +24,7 @@ extern int pr_type;
extern lbool new_file; extern lbool new_file;
extern int linenums; extern int linenums;
extern int hshift; extern int hshift;
extern int sc_width;
extern int sc_height; extern int sc_height;
extern int jump_sline; extern int jump_sline;
extern int less_is_more; extern int less_is_more;
@@ -47,9 +48,9 @@ static constant char s_proto[] =
static constant char m_proto[] = static constant char m_proto[] =
"?n?f%f .?m(%T %i of %m) ..?e(END) ?x- Next\\: %x.:?pB%pB\\%:byte %bB?s/%s...%t"; "?n?f%f .?m(%T %i of %m) ..?e(END) ?x- Next\\: %x.:?pB%pB\\%:byte %bB?s/%s...%t";
static constant char M_proto[] = static constant char M_proto[] =
"?f%f .?n?m(%T %i of %m) ..?ltlines %lt-%lb?L/%L. :byte %bB?s/%s. .?e(END) ?x- Next\\: %x.:?pB%pB\\%..%t"; "?f%f .?n?m(%T %i of %m) ..?ltlines %lt-%lb?L/%L. :byte %bB?s/%s. .?e(END) ?x- Next\\: %x.:?pB%pB\\%..?c (column %c).%t";
static constant char e_proto[] = static constant char e_proto[] =
"?f%f .?m(%T %i of %m) .?ltlines %lt-%lb?L/%L. .byte %bB?s/%s. ?e(END) :?pB%pB\\%..%t"; "?f%f .?m(%T %i of %m) .?ltlines %lt-%lb?L/%L. .byte %bB?s/%s. ?e(END) :?pB%pB\\%..?c (column %c).%t";
static constant char h_proto[] = static constant char h_proto[] =
"HELP -- ?eEND -- Press g to see it again:Press RETURN for more., or q when done"; "HELP -- ?eEND -- Press g to see it again:Press RETURN for more., or q when done";
static constant char w_proto[] = static constant char w_proto[] =
@@ -64,6 +65,7 @@ public char constant *wproto = w_proto;
static char message[PROMPT_SIZE]; static char message[PROMPT_SIZE];
static char *mp; static char *mp;
static int longest_line;
/* /*
* Initialize the prompt prototype strings. * Initialize the prompt prototype strings.
@@ -78,6 +80,18 @@ public void init_prompt(void)
wproto = save(w_proto); wproto = save(w_proto);
} }
/*
* Get width of longest line currently on screen.
* Calling longest_line_width() is expensive, so we cache its value here
* in case it is called more than once per prompt expansion.
*/
static int pr_longest_line(void)
{
if (longest_line < 0)
longest_line = longest_line_width();
return longest_line;
}
/* /*
* Append a string to the end of the message. * Append a string to the end of the message.
* nprt means the character *may* be nonprintable * nprt means the character *may* be nonprintable
@@ -233,6 +247,8 @@ static lbool cond(char c, int where)
return (currline(where) != 0 && return (currline(where) != 0 &&
(len = ch_length()) > 0 && (len = ch_length()) > 0 &&
find_linenum(len) != 0); find_linenum(len) != 0);
case 'Q': /* Any on-screen line truncated? */
return (hshift + sc_width < pr_longest_line());
case 's': /* Size of file known? */ case 's': /* Size of file known? */
case 'B': case 'B':
return (ch_length() != NULL_POSITION); return (ch_length() != NULL_POSITION);
@@ -275,7 +291,10 @@ static void protochar(char c, int where)
ap_quest(); ap_quest();
break; break;
case 'c': case 'c':
ap_int(hshift); ap_int(hshift+1);
break;
case 'C':
ap_int(hshift + sc_width);
break; break;
case 'd': /* Current page number */ case 'd': /* Current page number */
linenum = currline(where); linenum = currline(where);
@@ -374,6 +393,9 @@ static void protochar(char c, int where)
else else
ap_int(percentage(linenum, last_linenum)); ap_int(percentage(linenum, last_linenum));
break; break;
case 'Q': /* Percent shifted horizontally */
ap_int(percentage(hshift + sc_width, pr_longest_line()));
break;
case 's': /* Size of file */ case 's': /* Size of file */
case 'B': case 'B':
len = ch_length(); len = ch_length();
@@ -395,6 +417,9 @@ static void protochar(char c, int where)
#endif #endif
ap_str("file"); ap_str("file");
break; break;
case 'W': /* Width of longest line on screen */
ap_int(pr_longest_line());
break;
case 'x': /* Name of next file */ case 'x': /* Name of next file */
h = next_ifile(curr_ifile); h = next_ifile(curr_ifile);
if (h != NULL_IFILE) if (h != NULL_IFILE)
@@ -496,11 +521,12 @@ public constant char * pr_expand(constant char *proto)
char c; char c;
int where; int where;
mp = message;
if (*proto == '\0') if (*proto == '\0')
return (""); return ("");
mp = message;
longest_line = -1;
for (p = proto; *p != '\0'; p++) for (p = proto; *p != '\0'; p++)
{ {
switch (*p) switch (*p)
+337 -149
View File
File diff suppressed because it is too large Load Diff
+13 -8
View File
@@ -354,32 +354,37 @@ public void clear_attn(void)
*/ */
public void undo_search(lbool clear) public void undo_search(lbool clear)
{ {
clear_pattern(&search_info);
undo_osc8();
#if HILITE_SEARCH #if HILITE_SEARCH
lbool osc8_active = undo_osc8();
lbool has_pattern = prev_pattern(&search_info);
if (clear) if (clear)
{ {
clear_pattern(&search_info);
clr_hilite(); clr_hilite();
} else } else
{ {
if (hilite_anchor.first == NULL) if (has_pattern)
{ hide_hilite = !hide_hilite;
else if (!osc8_active)
error("No previous regular expression", NULL_PARG); error("No previous regular expression", NULL_PARG);
return;
}
hide_hilite = !hide_hilite;
} }
repaint_hilite(TRUE); repaint_hilite(TRUE);
#else
undo_osc8();
clear_pattern(&search_info);
#endif #endif
} }
/* /*
*/ */
public void undo_osc8(void) public lbool undo_osc8(void)
{ {
lbool was_active = FALSE;
#if OSC8_LINK #if OSC8_LINK
was_active = (osc8_linepos != NULL_POSITION);
osc8_linepos = NULL_POSITION; osc8_linepos = NULL_POSITION;
#endif #endif
return was_active;
} }
#if HILITE_SEARCH #if HILITE_SEARCH
+18 -10
View File
@@ -44,7 +44,7 @@ extern int less_is_more;
static RETSIGTYPE u_interrupt(int type) static RETSIGTYPE u_interrupt(int type)
{ {
(void) type; (void) type;
bell(); lbell();
#if OS2 #if OS2
LSIGNAL(SIGINT, SIG_ACK); LSIGNAL(SIGINT, SIG_ACK);
#endif #endif
@@ -64,6 +64,7 @@ static RETSIGTYPE u_interrupt(int type)
#if HILITE_SEARCH #if HILITE_SEARCH
set_filter_pattern(NULL, 0); set_filter_pattern(NULL, 0);
#endif #endif
polling_ok();
intio(); intio();
} }
#endif #endif
@@ -96,10 +97,10 @@ static RETSIGTYPE stop(int type)
* "Window" change handler * "Window" change handler
*/ */
/* ARGSUSED*/ /* ARGSUSED*/
public RETSIGTYPE winch(int type) public RETSIGTYPE lwinch(int type)
{ {
(void) type; (void) type;
LSIGNAL(SIG_LESSWINDOW, winch); LSIGNAL(SIG_LESSWINDOW, lwinch);
#if LESSTEST #if LESSTEST
/* /*
* Ignore window changes during lesstest. * Ignore window changes during lesstest.
@@ -185,10 +186,10 @@ public void init_signals(int on)
(void) LSIGNAL(SIGTSTP, !secure_allow(SF_STOP) ? SIG_IGN : stop); (void) LSIGNAL(SIGTSTP, !secure_allow(SF_STOP) ? SIG_IGN : stop);
#endif #endif
#ifdef SIGWINCH #ifdef SIGWINCH
(void) LSIGNAL(SIGWINCH, winch); (void) LSIGNAL(SIGWINCH, lwinch);
#endif #endif
#ifdef SIGWIND #ifdef SIGWIND
(void) LSIGNAL(SIGWIND, winch); (void) LSIGNAL(SIGWIND, lwinch);
#endif #endif
#ifdef SIGQUIT #ifdef SIGQUIT
(void) LSIGNAL(SIGQUIT, SIG_IGN); (void) LSIGNAL(SIGQUIT, SIG_IGN);
@@ -196,6 +197,9 @@ public void init_signals(int on)
#ifdef SIGTERM #ifdef SIGTERM
(void) LSIGNAL(SIGTERM, terminate); (void) LSIGNAL(SIGTERM, terminate);
#endif #endif
#ifdef SIGHUP
(void) LSIGNAL(SIGHUP, terminate);
#endif
#ifdef SIGUSR1 #ifdef SIGUSR1
(void) LSIGNAL(SIGUSR1, sigusr1); (void) LSIGNAL(SIGUSR1, sigusr1);
#endif #endif
@@ -224,6 +228,9 @@ public void init_signals(int on)
#ifdef SIGTERM #ifdef SIGTERM
(void) LSIGNAL(SIGTERM, SIG_DFL); (void) LSIGNAL(SIGTERM, SIG_DFL);
#endif #endif
#ifdef SIGHUP
(void) LSIGNAL(SIGHUP, SIG_DFL);
#endif
#ifdef SIGUSR1 #ifdef SIGUSR1
(void) LSIGNAL(SIGUSR1, SIG_DFL); (void) LSIGNAL(SIGUSR1, SIG_DFL);
#endif #endif
@@ -252,7 +259,7 @@ public void psignals(void)
LSIGNAL(SIGTTOU, SIG_IGN); LSIGNAL(SIGTTOU, SIG_IGN);
#endif #endif
clear_bot(); clear_bot();
deinit(); term_deinit();
flush(); flush();
raw_mode(0); raw_mode(0);
#ifdef SIGTTOU #ifdef SIGTTOU
@@ -268,7 +275,7 @@ public void psignals(void)
*/ */
LSIGNAL(SIGTSTP, stop); LSIGNAL(SIGTSTP, stop);
raw_mode(1); raw_mode(1);
init(); term_init();
screen_trashed(); screen_trashed();
tsignals |= S_WINCH; tsignals |= S_WINCH;
} }
@@ -284,10 +291,7 @@ public void psignals(void)
old_height = sc_height; old_height = sc_height;
get_term(); get_term();
if (sc_width != old_width || sc_height != old_height) if (sc_width != old_width || sc_height != old_height)
{
wscroll = (sc_height + 1) / 2;
screen_size_changed(); screen_size_changed();
}
screen_trashed(); screen_trashed();
} }
#endif #endif
@@ -295,5 +299,9 @@ public void psignals(void)
{ {
if (quit_on_intr) if (quit_on_intr)
quit(QUIT_INTERRUPT); quit(QUIT_INTERRUPT);
getcc_clear();
#if MSDOS_COMPILER==WIN32C
win32_getch_clear();
#endif
} }
} }
+4 -3
View File
@@ -256,12 +256,12 @@ static enum tag_result findctag(constant char *tag)
char *q; char *q;
FILE *f; FILE *f;
size_t taglen; size_t taglen;
int n;
LINENUM taglinenum; LINENUM taglinenum;
char *tagfile; char *tagfile;
char *tagpattern; char *tagpattern;
lbool tagendline; lbool tagendline;
int search_char; int search_char;
lbool err;
char tline[TAGLINE_SIZE]; char tline[TAGLINE_SIZE];
struct tag *tp; struct tag *tp;
@@ -321,8 +321,9 @@ static enum tag_result findctag(constant char *tag)
* First see if it is a line number. * First see if it is a line number.
*/ */
tagendline = FALSE; tagendline = FALSE;
taglinenum = getnum(&p, 0, &err); if (getnum(&p, NULL, FALSE, &n))
if (err) taglinenum = n;
else
{ {
/* /*
* No, it must be a pattern. * No, it must be a pattern.
+2 -2
View File
@@ -192,7 +192,7 @@ public int getchr(void)
do do
{ {
flush(); flush();
#if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC #if !LESS_IREAD_TTY
/* /*
* In raw read, we don't see ^C so look here for it. * In raw read, we don't see ^C so look here for it.
*/ */
@@ -208,7 +208,7 @@ public int getchr(void)
result = 1; result = 1;
if (c == '\003') if (c == '\003')
return (READ_INTR); return (READ_INTR);
#else #else /* LESS_IREAD_TTY */
{ {
unsigned char uc; unsigned char uc;
result = iread(tty, &uc, sizeof(char)); result = iread(tty, &uc, sizeof(char));
+1 -1
View File
@@ -1,4 +1,4 @@
/* Generated by "./mkutable -f2 Cc Cs Co Zl Zp -- unicode/UnicodeData.txt" on Aug 19 1:16:32 GMT 2025 */ /* Generated by "./mkutable -f2 Cc Cs Co Zl Zp -- unicode/UnicodeData.txt" on Nov 28 1:30:13 GMT 2025 */
{ 0x0000, 0x0007 }, /* Cc */ { 0x0000, 0x0007 }, /* Cc */
{ 0x000b, 0x000b }, /* Cc */ { 0x000b, 0x000b }, /* Cc */
{ 0x000e, 0x001f }, /* Cc */ { 0x000e, 0x001f }, /* Cc */
+14 -1
View File
@@ -1061,6 +1061,19 @@ v684 9/18/25 Allow mixing of options and filenames on command line;
add LESS_TERMCAP_SUSPEND & LESS_TERMCAP_RESUME. add LESS_TERMCAP_SUSPEND & LESS_TERMCAP_RESUME.
v685 10/4/25 Make --incsearch return to same column as well as same line; v685 10/4/25 Make --incsearch return to same column as well as same line;
fix some problems reported by valgrind. fix some problems reported by valgrind.
v686 10/30/25 Map keypad keys; make HOME/END scroll horizontally;
retain saved marks even if --save-marks is not specified;
fix repaint bug with --form-feed; fix bugs passing negative
values to cmd line options.
v687 11/17/25 Disallow opening OSC8 link via mouse in secure mode;
add --autosave; make SIGHUP act like SIGTERM; add ESC-f.
v688 11/28/25 Add LESSNOCONFIG; defer "ti" until first char received;
don't auto-bold line numbers.
v689 12/27/25 Add prompt seqs %C, %W, %Q, ?Q; don't allow any command to
interrupt waiting for data; fix screen resize on Windows;
add --without-termlib.
v690 12/31/25 Cleanup.
v691 1/10/26 Fix mingw build.
*/ */
char version[] = "685"; char version[] = "691";
+12 -11
View File
@@ -1,4 +1,4 @@
/* Generated by "./mkutable -f1 W F -- unicode/EastAsianWidth.txt" on Aug 10 20:15:03 GMT 2025 */ /* Generated by "./mkutable -f1 W F -- unicode/EastAsianWidth.txt" on Nov 28 1:30:13 GMT 2025 */
{ 0x1100, 0x115f }, /* W */ { 0x1100, 0x115f }, /* W */
{ 0x231a, 0x231b }, /* W */ { 0x231a, 0x231b }, /* W */
{ 0x2329, 0x232a }, /* W */ { 0x2329, 0x232a }, /* W */
@@ -61,10 +61,10 @@
{ 0xff01, 0xff60 }, /* F */ { 0xff01, 0xff60 }, /* F */
{ 0xffe0, 0xffe6 }, /* F */ { 0xffe0, 0xffe6 }, /* F */
{ 0x16fe0, 0x16fe4 }, /* W */ { 0x16fe0, 0x16fe4 }, /* W */
{ 0x16ff0, 0x16ff1 }, /* W */ { 0x16ff0, 0x16ff6 }, /* W */
{ 0x17000, 0x187f7 }, /* W */ { 0x17000, 0x18cd5 }, /* W */
{ 0x18800, 0x18cd5 }, /* W */ { 0x18cff, 0x18d1e }, /* W */
{ 0x18cff, 0x18d08 }, /* W */ { 0x18d80, 0x18df2 }, /* W */
{ 0x1aff0, 0x1aff3 }, /* W */ { 0x1aff0, 0x1aff3 }, /* W */
{ 0x1aff5, 0x1affb }, /* W */ { 0x1aff5, 0x1affb }, /* W */
{ 0x1affd, 0x1affe }, /* W */ { 0x1affd, 0x1affe }, /* W */
@@ -107,7 +107,7 @@
{ 0x1f680, 0x1f6c5 }, /* W */ { 0x1f680, 0x1f6c5 }, /* W */
{ 0x1f6cc, 0x1f6cc }, /* W */ { 0x1f6cc, 0x1f6cc }, /* W */
{ 0x1f6d0, 0x1f6d2 }, /* W */ { 0x1f6d0, 0x1f6d2 }, /* W */
{ 0x1f6d5, 0x1f6d7 }, /* W */ { 0x1f6d5, 0x1f6d8 }, /* W */
{ 0x1f6dc, 0x1f6df }, /* W */ { 0x1f6dc, 0x1f6df }, /* W */
{ 0x1f6eb, 0x1f6ec }, /* W */ { 0x1f6eb, 0x1f6ec }, /* W */
{ 0x1f6f4, 0x1f6fc }, /* W */ { 0x1f6f4, 0x1f6fc }, /* W */
@@ -118,10 +118,11 @@
{ 0x1f947, 0x1f9af }, /* W */ { 0x1f947, 0x1f9af }, /* W */
{ 0x1f9b4, 0x1f9ff }, /* W */ { 0x1f9b4, 0x1f9ff }, /* W */
{ 0x1fa70, 0x1fa7c }, /* W */ { 0x1fa70, 0x1fa7c }, /* W */
{ 0x1fa80, 0x1fa89 }, /* W */ { 0x1fa80, 0x1fa8a }, /* W */
{ 0x1fa8f, 0x1fac6 }, /* W */ { 0x1fa8e, 0x1fac6 }, /* W */
{ 0x1face, 0x1fadc }, /* W */ { 0x1fac8, 0x1fac8 }, /* W */
{ 0x1fadf, 0x1fae9 }, /* W */ { 0x1facd, 0x1fadc }, /* W */
{ 0x1faf0, 0x1faf8 }, /* W */ { 0x1fadf, 0x1faea }, /* W */
{ 0x1faef, 0x1faf8 }, /* W */
{ 0x20000, 0x2fffd }, /* W */ { 0x20000, 0x2fffd }, /* W */
{ 0x30000, 0x3fffd }, /* W */ { 0x30000, 0x3fffd }, /* W */
+2 -1
View File
@@ -66,8 +66,9 @@ public void xbuf_add_char(struct xbuffer *xbuf, char c)
/* /*
* Add arbitrary data to an xbuf. * Add arbitrary data to an xbuf.
*/ */
public void xbuf_add_data(struct xbuffer *xbuf, constant unsigned char *data, size_t len) public void xbuf_add_data(struct xbuffer *xbuf, constant void *vdata, size_t len)
{ {
constant unsigned char *data = (constant unsigned char *) vdata;
size_t i; size_t i;
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
xbuf_add_byte(xbuf, data[i]); xbuf_add_byte(xbuf, data[i]);
+1 -1
View File
@@ -17,7 +17,7 @@ void xbuf_deinit(struct xbuffer *xbuf);
void xbuf_reset(struct xbuffer *xbuf); void xbuf_reset(struct xbuffer *xbuf);
void xbuf_add_byte(struct xbuffer *xbuf, unsigned char b); void xbuf_add_byte(struct xbuffer *xbuf, unsigned char b);
void xbuf_add_char(struct xbuffer *xbuf, char c); void xbuf_add_char(struct xbuffer *xbuf, char c);
void xbuf_add_data(struct xbuffer *xbuf, constant unsigned char *data, size_t len); void xbuf_add_data(struct xbuffer *xbuf, constant void *data, size_t len);
int xbuf_pop(struct xbuffer *xbuf); int xbuf_pop(struct xbuffer *xbuf);
constant char *xbuf_char_data(constant struct xbuffer *xbuf); constant char *xbuf_char_data(constant struct xbuffer *xbuf);
+58 -58
View File
@@ -21,91 +21,91 @@
* be safe to run by unprivileged users. * be safe to run by unprivileged users.
* SECURE_COMPILE is set by the --with-secure configure option. * SECURE_COMPILE is set by the --with-secure configure option.
*/ */
#define SECURE SECURE_COMPILE #define SECURE SECURE_COMPILE
/* /*
* SHELL_ESCAPE is 1 if you wish to allow shell escapes. * SHELL_ESCAPE is 1 if you wish to allow shell escapes.
* (This is possible only if your system supplies the system() function.) * (This is possible only if your system supplies the system() function.)
*/ */
#define SHELL_ESCAPE (!SECURE) #define SHELL_ESCAPE (!SECURE)
/* /*
* EXAMINE is 1 if you wish to allow examining files by name from within less. * EXAMINE is 1 if you wish to allow examining files by name from within less.
*/ */
#define EXAMINE (!SECURE) #define EXAMINE (!SECURE)
/* /*
* TAB_COMPLETE_FILENAME is 1 if you wish to allow the TAB key * TAB_COMPLETE_FILENAME is 1 if you wish to allow the TAB key
* to complete filenames at prompts. * to complete filenames at prompts.
*/ */
#define TAB_COMPLETE_FILENAME (!SECURE) #define TAB_COMPLETE_FILENAME (!SECURE)
/* /*
* CMD_HISTORY is 1 if you wish to allow keys to cycle through * CMD_HISTORY is 1 if you wish to allow keys to cycle through
* previous commands at prompts. * previous commands at prompts.
*/ */
#define CMD_HISTORY 1 #define CMD_HISTORY 1
/* /*
* HILITE_SEARCH is 1 if you wish to have search targets to be * HILITE_SEARCH is 1 if you wish to have search targets to be
* displayed in standout mode. * displayed in standout mode.
*/ */
#define HILITE_SEARCH 1 #define HILITE_SEARCH 1
/* /*
* EDITOR is 1 if you wish to allow editor invocation (the "v" command). * EDITOR is 1 if you wish to allow editor invocation (the "v" command).
* (This is possible only if your system supplies the system() function.) * (This is possible only if your system supplies the system() function.)
* EDIT_PGM is the name of the (default) editor to be invoked. * EDIT_PGM is the name of the (default) editor to be invoked.
*/ */
#define EDITOR (!SECURE) #define EDITOR (!SECURE)
/* /*
* TAGS is 1 if you wish to support tag files. * TAGS is 1 if you wish to support tag files.
*/ */
#define TAGS (!SECURE) #define TAGS (!SECURE)
/* /*
* USERFILE is 1 if you wish to allow a .less file to specify * USERFILE is 1 if you wish to allow a .lesskey or .less file to specify
* user-defined key bindings. * user-defined key bindings.
*/ */
#define USERFILE (!SECURE) #define USERFILE (!SECURE)
/* /*
* GLOB is 1 if you wish to have shell metacharacters expanded in filenames. * GLOB is 1 if you wish to have shell metacharacters expanded in filenames.
* This will generally work if your system provides the "popen" function * This will generally work if your system provides the "popen" function
* and the "echo" shell command. * and the "echo" shell command.
*/ */
#define GLOB (!SECURE) #define GLOB (!SECURE)
/* /*
* PIPEC is 1 if you wish to have the "|" command * PIPEC is 1 if you wish to have the "|" command
* which allows the user to pipe data into a shell command. * which allows the user to pipe data into a shell command.
*/ */
#define PIPEC (!SECURE && HAVE_POPEN) #define PIPEC (!SECURE && HAVE_POPEN)
/* /*
* LOGFILE is 1 if you wish to allow the -o option (to create log files). * LOGFILE is 1 if you wish to allow the -o option (to create log files).
*/ */
#define LOGFILE (!SECURE) #define LOGFILE (!SECURE)
/* /*
* OSC8_SEARCH is 1 if you wish to allow the ^O^O and related commands * OSC8_LINK is 1 if you wish to allow the ^O^O and related commands
* (to open OSC8 hyperlinks). * (to open OSC8 hyperlinks).
*/ */
#define OSC8_LINK 1 #define OSC8_LINK 1
/* /*
* GNU_OPTIONS is 1 if you wish to support the GNU-style command * GNU_OPTIONS is 1 if you wish to support the GNU-style command
* line options --help and --version. * line options --help and --version.
*/ */
#define GNU_OPTIONS 1 #define GNU_OPTIONS 1
/* /*
* ONLY_RETURN is 1 if you want RETURN to be the only input which * ONLY_RETURN is 1 if you want RETURN to be the only input which
* will continue past an error message. * will continue past an error message.
* Otherwise, any key will continue past an error message. * Otherwise, any key will continue past an error message.
*/ */
#define ONLY_RETURN 0 #define ONLY_RETURN 0
/* /*
* LESSKEYFILE is the filename of the default lesskey output file * LESSKEYFILE is the filename of the default lesskey output file
@@ -116,33 +116,36 @@
* LESSHISTFILE is the filename of the history file * LESSHISTFILE is the filename of the history file
* (in the HOME directory). * (in the HOME directory).
*/ */
#define LESSKEYFILE ".less" /* FreeBSD */
#define LESSKEYFILE_SYS "/etc/lesskey" #define SYSDIR "/etc"
#define DEF_LESSKEYINFILE ".lesskey"
#define LESSKEYINFILE_SYS "/etc/syslesskey" #define LESSKEYFILE ".less"
#define LESSHISTFILE ".lesshst" #define LESSKEYFILE_SYS SYSDIR "/sysless"
#define DEF_LESSKEYINFILE ".lesskey"
#define LESSKEYINFILE_SYS SYSDIR "/syslesskey"
#define LESSHISTFILE ".lesshst"
/* Autodetect mingw */ /* Autodetect mingw */
#if defined(__MINGW32__) #if defined(__MINGW32__)
/* /*
* Define MSDOS_COMPILER if compiling under Microsoft C. * Define MSDOS_COMPILER if compiling under Microsoft C.
*/ */
#define MSDOS_COMPILER WIN32C #define MSDOS_COMPILER WIN32C
/* /*
* Pathname separator character. * Pathname separator character.
*/ */
#define PATHNAME_SEP "\\" #define PATHNAME_SEP "\\"
#else #else
/* /*
* Define MSDOS_COMPILER if compiling under Microsoft C. * Define MSDOS_COMPILER if compiling under Microsoft C.
*/ */
#define MSDOS_COMPILER 0 #define MSDOS_COMPILER 0
/* /*
* Pathname separator character. * Pathname separator character.
*/ */
#define PATHNAME_SEP "/" #define PATHNAME_SEP "/"
#endif #endif
/* Settings always true on Unix. */ /* Settings always true on Unix. */
@@ -154,9 +157,9 @@
#define TGETENT_OK 1 #define TGETENT_OK 1
/* /*
* HAVE_ANSI_PROTOS is 1 if your compiler supports ANSI function prototypes. * HAVE_ANSI_PROTOS is 1 if your compiler supports ANSI function prototypes.
*/ */
#define HAVE_ANSI_PROTOS 1 #define HAVE_ANSI_PROTOS 1
/* /*
* HAVE_SYS_TYPES_H is 1 if your system has <sys/types.h>. * HAVE_SYS_TYPES_H is 1 if your system has <sys/types.h>.
@@ -172,28 +175,28 @@
* HAVE_PERROR is 1 if your system has the perror() call. * HAVE_PERROR is 1 if your system has the perror() call.
* (Actually, if it has sys_errlist, sys_nerr and errno.) * (Actually, if it has sys_errlist, sys_nerr and errno.)
*/ */
#define HAVE_PERROR 1 #define HAVE_PERROR 1
/* /*
* HAVE_TIME is 1 if your system has the time() call. * HAVE_TIME is 1 if your system has the time() call.
*/ */
#define HAVE_TIME 1 #define HAVE_TIME 1
/* /*
* HAVE_SHELL is 1 if your system supports a SHELL command interpreter. * HAVE_SHELL is 1 if your system supports a SHELL command interpreter.
*/ */
#define HAVE_SHELL 1 #define HAVE_SHELL 1
/* /*
* Default shell metacharacters and meta-escape character. * Default shell metacharacters and meta-escape character.
*/ */
#define DEF_METACHARS "; *?\t\n'\"()<>[]|&^`#\\$%=~{}," #define DEF_METACHARS "; *?\t\n'\"()<>[]|&^`#\\$%=~{},"
#define DEF_METAESCAPE "\\" #define DEF_METAESCAPE "\\"
/* /*
* HAVE_DUP is 1 if your system has the dup() call. * HAVE_DUP is 1 if your system has the dup() call.
*/ */
#define HAVE_DUP 1 #define HAVE_DUP 1
/* Define to 1 if you have the memcpy() function. */ /* Define to 1 if you have the memcpy() function. */
#define HAVE_MEMCPY 1 #define HAVE_MEMCPY 1
@@ -211,26 +214,26 @@
* Sizes of various buffers. * Sizes of various buffers.
*/ */
#if 0 /* old sizes for small memory machines */ #if 0 /* old sizes for small memory machines */
#define CMDBUF_SIZE 512 /* Buffer for multichar commands */ #define CMDBUF_SIZE 512 /* Buffer for multichar commands */
#define UNGOT_SIZE 100 /* Max chars to unget() */ #define UNGOT_SIZE 100 /* Max chars to unget() */
#define LINEBUF_SIZE 1024 /* Max size of line in input file */ #define LINEBUF_SIZE 1024 /* Max size of line in input file */
#define OUTBUF_SIZE 1024 /* Output buffer */ #define OUTBUF_SIZE 1024 /* Output buffer */
#define PROMPT_SIZE 200 /* Max size of prompt string */ #define PROMPT_SIZE 200 /* Max size of prompt string */
#define TERMBUF_SIZE 2048 /* Termcap buffer for tgetent */ #define TERMBUF_SIZE 2048 /* Termcap buffer for tgetent */
#define TERMSBUF_SIZE 1024 /* Buffer to hold termcap strings */ #define TERMSBUF_SIZE 1024 /* Buffer to hold termcap strings */
#define TAGLINE_SIZE 512 /* Max size of line in tags file */ #define TAGLINE_SIZE 512 /* Max size of line in tags file */
#define TABSTOP_MAX 32 /* Max number of custom tab stops */ #define TABSTOP_MAX 32 /* Max number of custom tab stops */
#define LINENUM_POOL 200 /* Size of line number pool */ #define LINENUM_POOL 200 /* Size of line number pool */
#else /* more reasonable sizes for modern machines */ #else /* more reasonable sizes for modern machines */
#define CMDBUF_SIZE 2048 /* Buffer for multichar commands */ #define CMDBUF_SIZE 2048 /* Buffer for multichar commands */
#define UNGOT_SIZE 200 /* Max chars to unget() */ #define UNGOT_SIZE 200 /* Max chars to unget() */
#define LINEBUF_SIZE 1024 /* Initial max size of line in input file */ #define LINEBUF_SIZE 1024 /* Initial max size of line in input file */
#define OUTBUF_SIZE 1024 /* Output buffer */ #define OUTBUF_SIZE 1024 /* Output buffer */
#define PROMPT_SIZE 2048 /* Max size of prompt string */ #define PROMPT_SIZE 2048 /* Max size of prompt string */
#define TERMBUF_SIZE 2048 /* Termcap buffer for tgetent */ #define TERMBUF_SIZE 2048 /* Termcap buffer for tgetent */
#define TERMSBUF_SIZE 1024 /* Buffer to hold termcap strings */ #define TERMSBUF_SIZE 1024 /* Buffer to hold termcap strings */
#define TAGLINE_SIZE 1024 /* Max size of line in tags file */ #define TAGLINE_SIZE 1024 /* Max size of line in tags file */
#define TABSTOP_MAX 128 /* Max number of custom tab stops */ #define TABSTOP_MAX 128 /* Max number of custom tab stops */
#define LINENUM_POOL 1024 /* Size of line number pool */ #define LINENUM_POOL 1024 /* Size of line number pool */
#endif #endif
@@ -393,6 +396,9 @@
/* Define to 1 if you have the <termcap.h> header file. */ /* Define to 1 if you have the <termcap.h> header file. */
#define HAVE_TERMCAP_H 1 #define HAVE_TERMCAP_H 1
/* Define HAVE_TERMINFO if you have the terminfo library. */
#define HAVE_TERMINFO 1
/* Define HAVE_TERMIOS_FUNCS if you have tcgetattr/tcsetattr. */ /* Define HAVE_TERMIOS_FUNCS if you have tcgetattr/tcsetattr. */
#define HAVE_TERMIOS_FUNCS 1 #define HAVE_TERMIOS_FUNCS 1
@@ -429,12 +435,6 @@
/* Define HAVE_VOID if your compiler supports the "void" type. */ /* Define HAVE_VOID if your compiler supports the "void" type. */
#define HAVE_VOID 1 #define HAVE_VOID 1
/* Define HAVE_WCTYPE if you have iswupper, iswlower, towupper, towlower. */
#define HAVE_WCTYPE 1
/* Define to 1 if you have the <wctype.h> header file. */
#define HAVE_WCTYPE_H 1
/* Define to 1 if you have the '_setjmp' function. */ /* Define to 1 if you have the '_setjmp' function. */
#define HAVE__SETJMP 1 #define HAVE__SETJMP 1