diff options
| author | Xin LI <delphij@FreeBSD.org> | 2025-05-19 05:51:42 +0000 |
|---|---|---|
| committer | Xin LI <delphij@FreeBSD.org> | 2025-05-19 05:51:42 +0000 |
| commit | 48b0a08b8724e7d5671dac2abf17ddb6d4e2a8f8 (patch) | |
| tree | 1b948df937500aa7672f42e2eb1b2a6d743aa51f /search.c | |
| parent | 8c9fd1007159a1cfe994ccf7021688a679a0a39c (diff) | |
Diffstat (limited to 'search.c')
| -rw-r--r-- | search.c | 184 |
1 files changed, 71 insertions, 113 deletions
@@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2024 Mark Nudelman + * Copyright (C) 1984-2025 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. @@ -44,10 +44,8 @@ extern int header_cols; extern LWCHAR rscroll_char; #if HILITE_SEARCH extern int hilite_search; -extern size_t size_linebuf; extern lbool squished; extern int can_goto_line; -extern lbool no_eof_bell; static lbool hide_hilite; static POSITION prep_startpos; static POSITION prep_endpos; @@ -245,7 +243,7 @@ public int get_cvt_ops(int search_type) /* * Is there a previous (remembered) search pattern? */ -static int prev_pattern(struct pattern_info *info) +static lbool prev_pattern(struct pattern_info *info) { #if !NO_REGEX if ((info->search_type & SRCH_NO_REGEX) == 0) @@ -289,10 +287,10 @@ public void repaint_hilite(lbool on) pos = position(sindex); if (pos == NULL_POSITION) continue; - (void) forw_line(pos); + (void) forw_line(pos, NULL, NULL); goto_line(sindex); clear_eol(); - put_line(); + put_line(FALSE); } overlay_header(); lower_left(); @@ -336,10 +334,10 @@ public void clear_attn(void) if (pos <= old_end_attnpos && (epos == NULL_POSITION || epos > old_start_attnpos)) { - (void) forw_line(pos); + (void) forw_line(pos, NULL, NULL); goto_line(sindex); clear_eol(); - put_line(); + put_line(FALSE); moved = 1; } } @@ -356,9 +354,7 @@ public void clear_attn(void) public void undo_search(lbool clear) { clear_pattern(&search_info); -#if OSC8_LINK - osc8_linepos = NULL_POSITION; -#endif + undo_osc8(); #if HILITE_SEARCH if (clear) { @@ -376,6 +372,15 @@ public void undo_search(lbool clear) #endif } +/* + */ +public void undo_osc8(void) +{ +#if OSC8_LINK + osc8_linepos = NULL_POSITION; +#endif +} + #if HILITE_SEARCH /* * Clear the hilite list. @@ -537,7 +542,7 @@ public void set_header(POSITION pos) /* * Is a position within the header lines? */ -static int pos_in_header(POSITION pos) +static lbool pos_in_header(POSITION pos) { return (header_start_pos != NULL_POSITION && pos >= header_start_pos && pos < header_end_pos); @@ -550,11 +555,10 @@ public lbool is_filtered(POSITION pos) { struct hilite_node *n; - if (ch_getflags() & CH_HELPFILE) + if (!is_filtering()) return (FALSE); if (pos_in_header(pos)) return (FALSE); - n = hlist_find(&filter_anchor, pos); return (n != NULL && pos >= n->r.hl_startpos); } @@ -565,45 +569,19 @@ public lbool is_filtered(POSITION pos) */ public POSITION next_unfiltered(POSITION pos) { - struct hilite_node *n; - - if (ch_getflags() & CH_HELPFILE) + if (!is_filtering()) return (pos); if (pos_in_header(pos)) return (pos); - - n = hlist_find(&filter_anchor, pos); - while (n != NULL && pos >= n->r.hl_startpos) + flush(); + while (pos != NULL_POSITION) { - pos = n->r.hl_endpos; - n = n->next; - } - return (pos); -} - -/* - * If pos is hidden, return the previous position which isn't or 0 if - * we're filtered right to the beginning, otherwise just return pos. - */ -public POSITION prev_unfiltered(POSITION pos) -{ - struct hilite_node *n; - - if (ch_getflags() & CH_HELPFILE) - return (pos); - if (pos_in_header(pos)) - return (pos); - - n = hlist_find(&filter_anchor, pos); - while (n != NULL && pos >= n->r.hl_startpos) - { - pos = n->r.hl_startpos; - if (pos == 0) + prep_hilite(pos, NULL_POSITION, 1); + if (!is_filtered(pos)) break; - pos--; - n = n->prev; + pos = forw_raw_line(pos, NULL, NULL); } - return (pos); + return pos; } /* @@ -661,7 +639,7 @@ public int is_hilited_attr(POSITION pos, POSITION epos, int nohide, int *p_match #if OSC8_LINK if (osc8_linepos != NULL_POSITION && - pos <= osc8_text_end && (epos == NULL_POSITION || epos > osc8_text_start)) + pos < osc8_text_end && (epos == NULL_POSITION || epos > osc8_text_start)) return (AT_HILITE|AT_COLOR_SEARCH); #endif @@ -1017,8 +995,7 @@ static void create_hilites(POSITION linepos, constant char *line, constant char */ static void hilite_line(POSITION linepos, constant char *line, size_t line_len, int *chpos, constant char **sp, constant char **ep, int nsp) { - constant char *searchp; - constant char *line_end = line + line_len; + size_t line_off = 0; /* * sp[0] and ep[0] delimit the first match in the line. @@ -1032,7 +1009,6 @@ static void hilite_line(POSITION linepos, constant char *line, size_t line_len, * sp[i] and ep[i] for i>0 delimit subpattern matches. * Color each of them with its unique color. */ - searchp = line; do { constant char *lep = sp[0]; int i; @@ -1059,14 +1035,14 @@ static void hilite_line(POSITION linepos, constant char *line, size_t line_len, * move to the first char after the string we matched. * If we matched zero, just move to the next char. */ - if (ep[0] > searchp) - searchp = ep[0]; - else if (searchp != line_end) - searchp++; + if (ep[0] > &line[line_off]) + line_off = ptr_diff(ep[0], line); + else if (line_off != line_len) + line_off++; else /* end of line */ break; } while (match_pattern(info_compiled(&search_info), search_info.text, - searchp, ptr_diff(line_end, searchp), sp, ep, nsp, 1, search_info.search_type)); + line, line_len, line_off, sp, ep, nsp, 1, search_info.search_type)); } #endif @@ -1200,14 +1176,14 @@ static POSITION search_pos(int search_type) * If so, add an entry to the filter list. */ #if HILITE_SEARCH -static int matches_filters(POSITION pos, char *cline, size_t line_len, int *chpos, POSITION linepos, constant char **sp, constant char **ep, int nsp) +static lbool matches_filters(POSITION pos, char *cline, size_t line_len, int *chpos, POSITION linepos, constant char **sp, constant char **ep, int nsp) { struct pattern_info *filter; for (filter = filter_infos; filter != NULL; filter = filter->next) { - int line_filter = match_pattern(info_compiled(filter), filter->text, - cline, line_len, sp, ep, nsp, 0, filter->search_type); + lbool line_filter = match_pattern(info_compiled(filter), filter->text, + cline, line_len, 0, sp, ep, nsp, 0, filter->search_type); if (line_filter) { struct hilite hl; @@ -1216,10 +1192,10 @@ static int matches_filters(POSITION pos, char *cline, size_t line_len, int *chpo add_hilite(&filter_anchor, &hl); free(cline); free(chpos); - return (1); + return (TRUE); } } - return (0); + return (FALSE); } #endif @@ -1231,9 +1207,10 @@ static POSITION get_lastlinepos(POSITION pos, POSITION tpos, int sheight) { int nlines; + flush(); for (nlines = 0;; nlines++) { - POSITION npos = forw_line(pos); + POSITION npos = forw_line(pos, NULL, NULL); if (npos > tpos) { if (nlines < sheight) @@ -1264,12 +1241,14 @@ struct osc8_parse_info { static lbool osc8_parse(constant char *line, constant char *line_end, struct osc8_parse_info *pop) { constant char *oline; - pop->osc8_start = pop->osc8_end = pop->uri_start = pop->uri_end = pop->params_start = pop->params_end = NULL; + LWCHAR ch; + struct ansi_state *pansi; + pop->osc8_start = pop->osc8_end = pop->uri_start = pop->uri_end = pop->params_start = pop->params_end = NULL; oline = line; - LWCHAR ch = step_charc(&line, +1, line_end); + ch = step_charc(&line, +1, line_end); /* oline points to character ch, line points to the one after it. */ - struct ansi_state *pansi = ansi_start(ch); + pansi = ansi_start(ch); if (pansi == NULL) return FALSE; pop->osc8_start = oline; /* start at the ESC */ @@ -1292,12 +1271,14 @@ static lbool osc8_parse(constant char *line, constant char *line_end, struct osc pop->uri_start = line; } break; - case OSC8_ST_ESC: + case OSC_END_CSI: if (pop->uri_end == NULL) pop->uri_end = oline; break; - case OSC8_END: + case OSC_END: ansi_done(pansi); + if (pop->params_start == NULL || pop->uri_start == NULL) + return FALSE; pop->osc8_end = line; if (pop->uri_end == NULL) /* happens when ST is "\7" */ pop->uri_end = oline; @@ -1503,7 +1484,7 @@ static int search_range(POSITION pos, POSITION endpos, int search_type, int matc #define NSP (NUM_SEARCH_COLORS+2) constant char *sp[NSP]; constant char *ep[NSP]; - int line_match; + lbool line_match; int cvt_ops; size_t cvt_len; int *chpos; @@ -1524,6 +1505,7 @@ static int search_range(POSITION pos, POSITION endpos, int search_type, int matc /* When the search wraps around, end at starting position. */ if ((search_type & SRCH_WRAP) && endpos == NULL_POSITION) endpos = pos; + flush(); for (;;) { /* @@ -1677,7 +1659,7 @@ static int search_range(POSITION pos, POSITION endpos, int search_type, int matc if (prev_pattern(&search_info)) { line_match = match_pattern(info_compiled(&search_info), search_info.text, - cline, line_len, sp, ep, NSP, 0, search_type); + cline, line_len, 0, sp, ep, NSP, 0, search_type); if (line_match) { /* @@ -1761,8 +1743,9 @@ public void osc8_search(int search_type, constant char *param, int matches) { POSITION pos; int match; + int curr_sindex = -1; - if (osc8_linepos != NULL_POSITION) + if (osc8_linepos != NULL_POSITION && (curr_sindex = onscreen(osc8_linepos)) >= 0) { /* Continue search in same line as current match. */ constant char *line; @@ -1772,9 +1755,6 @@ public void osc8_search(int search_type, constant char *param, int matches) { if (osc8_search_line(search_type, osc8_linepos, line, line_len, param, NULL_POSITION, &matches) != OSC8_NO_MATCH) { - no_eof_bell = TRUE; - jump_loc(osc8_linepos, jump_sline); - no_eof_bell = FALSE; osc8_shift_visible(); #if HILITE_SEARCH repaint_hilite(TRUE); @@ -1784,7 +1764,14 @@ public void osc8_search(int search_type, constant char *param, int matches) } search_type |= SRCH_AFTER_TARGET; } - pos = search_pos(search_type); + /* + * If the current OSC 8 link is on screen, start searching after it. + * Otherwise, start searching at the -j line like a normal search. + */ + if (curr_sindex >= 0) + pos = osc8_linepos; + else + pos = search_pos(search_type); if (pos == NULL_POSITION) { error("Nothing to search", NULL_PARG); @@ -1798,7 +1785,9 @@ public void osc8_search(int search_type, constant char *param, int matches) error("OSC 8 link not found", NULL_PARG); return; } - jump_loc(pos, jump_sline); + /* If new link is on screen, just highlight it without scrolling. */ + if (onscreen(pos) < 0) + jump_loc(pos, jump_sline); #if HILITE_SEARCH repaint_hilite(TRUE); #endif @@ -1843,7 +1832,7 @@ public lbool osc8_click(int sindex, int col) /* * Return the length of the scheme prefix in a URI. */ -static int scheme_length(constant char *uri, size_t uri_len) +static size_t scheme_length(constant char *uri, size_t uri_len) { size_t plen; for (plen = 0; plen < uri_len; plen++) @@ -1930,13 +1919,13 @@ public void osc8_open(void) #if HAVE_POPEN if (bad_uri(op.uri_start, uri_len)) { - error("Cannot open link containing dangerous characters", NULL_PARG); + error("Cannot open link containing quote characters", NULL_PARG); return; } SNPRINTF3(env_name, sizeof(env_name), "%s%.*s", env_name_pfx, (int) scheme_len, op.uri_start); handler = lgetenv(env_name); if (isnullenv(handler) || strcmp(handler, "-") == 0) - handler = lgetenv("LESS_OSC8_ANY"); + handler = lgetenv("LESS_OSC8_ANY"); if (isnullenv(handler)) { PARG parg; @@ -2212,12 +2201,6 @@ public void prep_hilite(POSITION spos, POSITION epos, int maxlines) int result; int i; - /* - * Search beyond where we're asked to search, so the prep region covers - * more than we need. Do one big search instead of a bunch of small ones. - */ - POSITION SEARCH_MORE = (POSITION) (3*size_linebuf); - if (!prev_pattern(&search_info) && !is_filtering()) return; @@ -2239,6 +2222,8 @@ public void prep_hilite(POSITION spos, POSITION epos, int maxlines) for (i = 0; i < maxlines; i++) max_epos = forw_raw_line(max_epos, NULL, NULL); } + if (epos == NULL_POSITION || (max_epos != NULL_POSITION && epos > max_epos)) + epos = max_epos; /* * Find two ranges: @@ -2256,28 +2241,13 @@ public void prep_hilite(POSITION spos, POSITION epos, int maxlines) */ clr_hilite(); clr_filter(); - if (epos != NULL_POSITION) - epos += SEARCH_MORE; nprep_startpos = spos; } else { /* * New range partially or completely overlaps old prep region. */ - if (epos == NULL_POSITION) - { - /* - * New range goes to end of file. - */ - ; - } else if (epos > prep_endpos) - { - /* - * New range ends after old prep region. - * Extend prep region to end at end of new range. - */ - epos += SEARCH_MORE; - } else /* (epos <= prep_endpos) */ + if (epos != NULL_POSITION && epos <= prep_endpos) { /* * New range ends within old prep region. @@ -2285,7 +2255,6 @@ public void prep_hilite(POSITION spos, POSITION epos, int maxlines) */ epos = prep_startpos; } - if (spos < prep_startpos) { /* @@ -2293,10 +2262,6 @@ public void prep_hilite(POSITION spos, POSITION epos, int maxlines) * Extend old prep region backwards to start at * start of new range. */ - if (spos < SEARCH_MORE) - spos = 0; - else - spos -= SEARCH_MORE; nprep_startpos = spos; } else /* (spos >= prep_startpos) */ { @@ -2308,17 +2273,10 @@ public void prep_hilite(POSITION spos, POSITION epos, int maxlines) } } - if (epos != NULL_POSITION && max_epos != NULL_POSITION && - epos > max_epos) - /* - * Don't go past the max position we're allowed. - */ - epos = max_epos; - if (epos == NULL_POSITION || epos > spos) { int search_type = SRCH_FORW | SRCH_FIND_ALL; - search_type |= (search_info.search_type & (SRCH_NO_REGEX|SRCH_SUBSEARCH_ALL)); + search_type |= (search_info.search_type & SRCH_NO_REGEX); for (;;) { result = search_range(spos, epos, search_type, 0, maxlines, (POSITION*)NULL, &new_epos, (POSITION*)NULL); |
