diff --git a/Makefile.aut b/Makefile.aut index 8eb9f8af..eb5acca1 100644 --- a/Makefile.aut +++ b/Makefile.aut @@ -22,7 +22,7 @@ SRC = \ help.c ifile.c input.c jump.c line.c linenum.c \ lsystem.c mark.c optfunc.c option.c opttbl.c os.c \ output.c pattern.c position.c prompt.c search.c signal.c \ - tags.c ttyin.c version.c + tags.c ttyin.c version.c xbuf.c DISTFILES_W = \ defines.ds Makefile.dsb Makefile.dsg Makefile.dsu \ defines.o2 Makefile.o2e \ @@ -36,7 +36,7 @@ DISTFILES = \ COPYING INSTALL LICENSE Makefile.in Makefile.aut NEWS README \ configure.ac lesskey.c lesskey_parse.c lessecho.c scrsize.c \ charset.h cmd.h funcs.h lglob.h less.h lesskey.h option.h \ - pckeys.h pattern.h position.h \ + pckeys.h pattern.h position.h xbuf.h \ install.sh defines.h.in mkinstalldirs \ less.nro less.man lesskey.nro lesskey.man lessecho.nro lessecho.man \ less.hlp \ diff --git a/Makefile.in b/Makefile.in index 9133fe0d..d087e9e0 100644 --- a/Makefile.in +++ b/Makefile.in @@ -50,7 +50,7 @@ OBJ = \ line.${O} linenum.${O} \ lsystem.${O} mark.${O} optfunc.${O} option.${O} opttbl.${O} os.${O} \ output.${O} pattern.${O} position.${O} prompt.${O} search.${O} signal.${O} \ - tags.${O} ttyin.${O} version.${O} @REGEX_O@ + tags.${O} ttyin.${O} version.${O} xbuf.${O} @REGEX_O@ ifneq (@SECURE_COMPILE@,1) OBJ += lesskey_parse.${O} @@ -61,8 +61,8 @@ all: less$(EXEEXT) lesskey$(EXEEXT) lessecho$(EXEEXT) less$(EXEEXT): ${OBJ} ${CC} ${LDFLAGS} -o $@ ${OBJ} ${LIBS} -lesskey$(EXEEXT): lesskey.${O} lesskey_parse.${O} version.${O} - ${CC} ${LDFLAGS} -o $@ lesskey.${O} lesskey_parse.${O} version.${O} +lesskey$(EXEEXT): lesskey.${O} lesskey_parse.${O} xbuf.${O} version.${O} + ${CC} ${LDFLAGS} -o $@ lesskey.${O} lesskey_parse.${O} xbuf.${O} version.${O} lessecho$(EXEEXT): lessecho.${O} version.${O} ${CC} ${LDFLAGS} -o $@ lessecho.${O} version.${O} diff --git a/NEWS b/NEWS index e86db8e3..97988cf9 100644 --- a/NEWS +++ b/NEWS @@ -25,6 +25,8 @@ * Add the --file-size option. +* With -F, if screen is resized to make file fit on one screen, don't exit. + * Fix bug which could leave terminal in mouse-reporting mode after exiting less. diff --git a/command.c b/command.c index cf691a79..88a2f8b3 100644 --- a/command.c +++ b/command.c @@ -791,6 +791,7 @@ prompt(VOID_PARAM) entire_file_displayed() && !(ch_getflags() & CH_HELPFILE) && next_ifile(curr_ifile) == NULL_IFILE) quit(QUIT_OK); + quit_if_one_screen = FALSE; /* only get one chance at this */ #if MSDOS_COMPILER==WIN32C /* diff --git a/less.h b/less.h index 4751976b..83e31514 100644 --- a/less.h +++ b/less.h @@ -571,6 +571,7 @@ struct loption; struct hilite_tree; struct ansi_state; #include "pattern.h" +#include "xbuf.h" #include "funcs.h" /* Functions not included in funcs.h */ diff --git a/lesskey.h b/lesskey.h index f50e2d81..1e70a7fe 100644 --- a/lesskey.h +++ b/lesskey.h @@ -7,6 +7,7 @@ * For more information, see the README file. */ +#include "xbuf.h" /* * Format of a lesskey file: @@ -38,13 +39,6 @@ /* */ #define KRADIX 64 -struct xbuffer -{ - char *data; - int end; - int size; -}; - struct lesskey_cmdname { char *cn_name; diff --git a/lesskey_parse.c b/lesskey_parse.c index 74d3e6e8..18cdf375 100644 --- a/lesskey_parse.c +++ b/lesskey_parse.c @@ -12,6 +12,7 @@ #include #include "lesskey.h" #include "cmd.h" +#include "xbuf.h" #include "defines.h" #define CONTROL(c) ((c)&037) @@ -133,38 +134,6 @@ parse_error(s1, s2) lesskey_parse_error(buf); } -/* - * Initialize an expandable text buffer. - */ - static void -xbuf_init(xbuf) - struct xbuffer *xbuf; -{ - xbuf->size = 16; - xbuf->data = ecalloc(xbuf->size, sizeof(char)); - xbuf->end = 0; -} - -/* - * Add a char to an expandable text buffer. - */ - static void -xbuf_add(xbuf, ch) - struct xbuffer *xbuf; - char ch; -{ - if (xbuf->end >= xbuf->size) - { - char *data; - xbuf->size = xbuf->size * 2; - data = ecalloc(xbuf->size, sizeof(char)); - memcpy(data, xbuf->data, xbuf->end); - free(xbuf->data); - xbuf->data = data; - } - xbuf->data[xbuf->end++] = ch; -} - /* * Initialize lesskey_tables. */ diff --git a/line.c b/line.c index 657111b4..b8f609e9 100644 --- a/line.c +++ b/line.c @@ -33,11 +33,8 @@ static struct { int pfx_end; /* Number of chars in pfx */ } linebuf; -static struct { - char *buf; - int size; - int end; -} shifted_ansi; +struct xbuffer shifted_ansi; +struct xbuffer last_ansi; public int size_linebuf = 0; /* Size of line buffer (and attr buffer) */ static struct ansi_state *line_ansi = NULL; @@ -58,6 +55,7 @@ static LWCHAR pendc; static POSITION pendpos; static char *end_ansi_chars; static char *mid_ansi_chars; +static int in_hilite; static int attr_swidth LESSPARAMS ((int a)); static int attr_ewidth LESSPARAMS ((int a)); @@ -131,8 +129,8 @@ init_line(VOID_PARAM) linebuf.buf = (char *) ecalloc(LINEBUF_SIZE, sizeof(char)); linebuf.attr = (int *) ecalloc(LINEBUF_SIZE, sizeof(int)); size_linebuf = LINEBUF_SIZE; - shifted_ansi.buf = NULL; - shifted_ansi.size = 0; + xbuf_init(&shifted_ansi); + xbuf_init(&last_ansi); } /* @@ -222,7 +220,9 @@ prewind(VOID_PARAM) mbc_buf_len = 0; is_null_line = 0; pendc = '\0'; - shifted_ansi.end = 0; + in_hilite = 0; + xbuf_reset(&shifted_ansi); + xbuf_reset(&last_ansi); } /* @@ -354,26 +354,6 @@ line_pfx_width(VOID_PARAM) return width; } -/* - * Add char to the shifted_ansi buffer. - */ - static void -add_ansi(ch) - char ch; -{ - if (shifted_ansi.end == shifted_ansi.size) - { - /* Expand shifted_ansi buffer. */ - int size = (shifted_ansi.size == 0) ? 8 : shifted_ansi.size * 2; - char *buf = (char *) ecalloc(size, sizeof(char)); - memcpy(buf, shifted_ansi.buf, shifted_ansi.size); - if (shifted_ansi.buf != NULL) free(shifted_ansi.buf); - shifted_ansi.buf = buf; - shifted_ansi.size = size; - } - shifted_ansi.buf[shifted_ansi.end++] = ch; -} - /* * Shift line left so that the last char is just to the left * of the first visible column. @@ -384,7 +364,7 @@ pshift_all(VOID_PARAM) int i; for (i = linebuf.print; i < linebuf.end; i++) if (linebuf.attr[i] == AT_ANSI) - add_ansi(linebuf.buf[i]); + xbuf_add(&shifted_ansi, linebuf.buf[i]); linebuf.end = linebuf.print; end_column = linebuf.pfx_end; } @@ -676,6 +656,7 @@ store_char(ch, a, rep, pos) #if HILITE_SEARCH { int matches; + int resend_last = 0; int hl_attr = is_hilited_attr(pos, pos+1, 0, &matches); if (hl_attr) { @@ -689,6 +670,23 @@ store_char(ch, a, rep, pos) highest_hilite = pos; a |= hl_attr; } + in_hilite = 1; + } else + { + if (in_hilite) + { + /* + * This is the first non-hilited char after a hilite. + * Resend the last ANSI seq to restore color. + */ + resend_last = 1; + } + in_hilite = 0; + } + if (resend_last) + { + for (i = 0; i < last_ansi.end; i++) + STORE_CHAR(last_ansi.data[i], AT_ANSI, NULL, pos); } } #endif @@ -731,8 +729,8 @@ store_char(ch, a, rep, pos) { /* Copy shifted ANSI sequences to beginning of line. */ for (i = 0; i < shifted_ansi.end; i++) - add_linebuf(shifted_ansi.buf[i], AT_ANSI, 0); - shifted_ansi.end = 0; + add_linebuf(shifted_ansi.data[i], AT_ANSI, 0); + xbuf_reset(&shifted_ansi); } /* Add the char to the buf, even if we will left-shift it next. */ inc_end_column(w); @@ -743,7 +741,7 @@ store_char(ch, a, rep, pos) { /* We haven't left-shifted enough yet. */ if (a == AT_ANSI) - add_ansi(ch); /* Save ANSI attributes */ + xbuf_add(&shifted_ansi, ch); /* Save ANSI attributes */ if (linebuf.end > linebuf.print) { /* Shift left enough to put last byte of this char at print-1. */ @@ -958,16 +956,18 @@ store_ansi(ch, rep, pos) switch (ansi_step(line_ansi, ch)) { case ANSI_MID: - STORE_CHAR(ch, AT_ANSI, rep, pos); + if (!in_hilite) + STORE_CHAR(ch, AT_ANSI, rep, pos); break; case ANSI_END: - STORE_CHAR(ch, AT_ANSI, rep, pos); + if (!in_hilite) + STORE_CHAR(ch, AT_ANSI, rep, pos); ansi_done(line_ansi); line_ansi = NULL; break; case ANSI_ERR: { /* Remove whole unrecognized sequence. */ - char *start = (cshift < hshift) ? shifted_ansi.buf : linebuf.buf; + char *start = (cshift < hshift) ? shifted_ansi.data : linebuf.buf; int *end = (cshift < hshift) ? &shifted_ansi.end : &linebuf.end; char *p = start + *end; LWCHAR bch; @@ -1010,10 +1010,17 @@ do_append(ch, rep, pos) int a = AT_NORMAL; if (ctldisp == OPT_ONPLUS && line_ansi == NULL) + { line_ansi = ansi_start(ch); + if (line_ansi != NULL) + xbuf_reset(&last_ansi); + } if (line_ansi != NULL) + { + xbuf_add(&last_ansi, ch); return store_ansi(ch, rep, pos); + } if (ch == '\b') return store_bs(ch, rep, pos); diff --git a/version.c b/version.c index 37c07838..0232421e 100644 --- a/version.c +++ b/version.c @@ -925,7 +925,10 @@ v583 4/21/21 Use XDG_CONFIG_HOME and XDG_DATA_HOME to find files. v584 4/30/21 Add --file-size option. v585 5/2/21 Allow color desc W per man page. v586 5/7/21 Doc changes. -v587 Fix --with-secure; fix --file-size message on Windows; fix memcpy usage. +v587 5/27/21 Fix --with-secure; fix --file-size message on Windows; + fix colored search hilite in colored text; don't exit + if -F and screen is resized; fix memcpy usage. +v588 5/27/21 Fix release. */ -char version[] = "587x"; +char version[] = "588"; diff --git a/xbuf.c b/xbuf.c new file mode 100644 index 00000000..f20dfae1 --- /dev/null +++ b/xbuf.c @@ -0,0 +1,52 @@ +#include "less.h" +#include "xbuf.h" + +/* + * Initialize an expandable text buffer. + */ + public void +xbuf_init(xbuf) + struct xbuffer *xbuf; +{ + xbuf->data = NULL; + xbuf->size = xbuf->end = 0; +} + + public void +xbuf_deinit(xbuf) + struct xbuffer *xbuf; +{ + if (xbuf->data != NULL) + free(xbuf->data); + xbuf_init(xbuf); +} + + public void +xbuf_reset(xbuf) + struct xbuffer *xbuf; +{ + xbuf->end = 0; +} + +/* + * Add a char to an expandable text buffer. + */ + public void +xbuf_add(xbuf, ch) + struct xbuffer *xbuf; + char ch; +{ + if (xbuf->end >= xbuf->size) + { + char *data; + xbuf->size = (xbuf->size == 0) ? 16 : xbuf->size * 2; + data = (char *) ecalloc(xbuf->size, sizeof(char)); + if (xbuf->data != NULL) + { + memcpy(data, xbuf->data, xbuf->end); + free(xbuf->data); + } + xbuf->data = data; + } + xbuf->data[xbuf->end++] = ch; +} diff --git a/xbuf.h b/xbuf.h new file mode 100644 index 00000000..ba62ef17 --- /dev/null +++ b/xbuf.h @@ -0,0 +1,15 @@ +#ifndef XBUF_H_ +#define XBUF_H_ + +struct xbuffer +{ + char *data; + int end; + int size; +}; + +void xbuf_init(struct xbuffer *xbuf); +void xbuf_reset(struct xbuffer *xbuf); +void xbuf_add(struct xbuffer *xbuf, char ch); + +#endif