diff options
Diffstat (limited to 'forwback.c')
| -rw-r--r-- | forwback.c | 163 |
1 files changed, 78 insertions, 85 deletions
diff --git a/forwback.c b/forwback.c index b0efc47f0ad6..992365749063 100644 --- a/forwback.c +++ b/forwback.c @@ -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. @@ -19,8 +19,11 @@ public lbool squished; public int no_back_scroll = 0; public int forw_prompt; -public int first_time = 1; -public lbool no_eof_bell = FALSE; +public lbool first_time = TRUE; /* We're printing the first screen of output */ +public int shell_lines = 1; +/* soft_eof is set as end-of-file when a read attempt returns EOF. This can + * differ from actual EOF (ch_length()) if & filtering is in effect. */ +public POSITION soft_eof = NULL_POSITION; extern int sigs; extern int top_scroll; @@ -35,9 +38,10 @@ extern int ignore_eoi; extern int header_lines; extern int header_cols; extern int full_screen; +extern int stop_on_form_feed; extern POSITION header_start_pos; +extern lbool getting_one_screen; #if HILITE_SEARCH -extern size_t size_linebuf; extern int hilite_search; extern int status_col; #endif @@ -50,14 +54,14 @@ extern char *tagoption; */ public void eof_bell(void) { - if (no_eof_bell) - return; #if HAVE_TIME - static time_type last_eof_bell = 0; - time_type now = get_time(); - if (now == last_eof_bell) /* max once per second */ - return; - last_eof_bell = now; + { + static time_type last_eof_bell = 0; + time_type now = get_time(); + if (now == last_eof_bell) /* max once per second */ + return; + last_eof_bell = now; + } #endif if (quiet == NOT_QUIET) bell(); @@ -68,7 +72,7 @@ public void eof_bell(void) /* * Check to see if the end of file is currently displayed. */ -public lbool eof_displayed(void) +public lbool eof_displayed(lbool offset) { POSITION pos; @@ -87,8 +91,8 @@ public lbool eof_displayed(void) * If the bottom line ends at the file length, * we must be just at EOF. */ - pos = position(BOTTOM_PLUS_ONE); - return (pos == NULL_POSITION || pos == ch_length()); + pos = position(offset ? BOTTOM_OFFSET : BOTTOM_PLUS_ONE); + return (pos == NULL_POSITION || pos == ch_length() || pos == soft_eof); } /* @@ -99,7 +103,7 @@ public lbool entire_file_displayed(void) POSITION pos; /* Make sure last line of file is displayed. */ - if (!eof_displayed()) + if (!eof_displayed(TRUE)) return (FALSE); /* Make sure first line of file is displayed. */ @@ -134,7 +138,7 @@ static POSITION forw_line_pfx(POSITION pos, int pfx, int skipeol) sc_width = pfx + line_pfx_width(); auto_wrap = 0; hshift = 0; - pos = forw_line_seg(pos, skipeol, FALSE, FALSE); + pos = forw_line_seg(pos, skipeol, FALSE, FALSE, NULL, NULL); sc_width = save_sc_width; auto_wrap = save_auto_wrap; hshift = save_hshift; @@ -169,10 +173,10 @@ public int overlay_header(void) home(); for (ln = 0; ln < header_lines; ++ln) { - pos = forw_line(pos); + pos = forw_line(pos, NULL, NULL); set_attr_header(ln); clear_eol(); - put_line(); + put_line(FALSE); } moved = TRUE; } @@ -192,7 +196,7 @@ public int overlay_header(void) /* Need skipeol for all header lines except the last one. */ pos = forw_line_pfx(pos, header_cols, ln+1 < header_lines); set_attr_header(ln); - put_line(); + put_line(FALSE); } } moved = TRUE; @@ -210,11 +214,14 @@ public int overlay_header(void) * "nblank" is the number of blank lines to draw before the first * real line. If nblank > 0, the pos must be NULL_POSITION. * The first real line after the blanks will start at ch_zero(). + * "to_newline" means count file lines rather than screen lines. */ -public void forw(int n, POSITION pos, lbool force, lbool only_last, int nblank) +public void forw(int n, POSITION pos, lbool force, lbool only_last, lbool to_newline, int nblank) { int nlines = 0; lbool do_repaint; + lbool newline; + lbool first_line = TRUE; if (pos != NULL_POSITION) pos = after_header_pos(pos); @@ -231,14 +238,6 @@ public void forw(int n, POSITION pos, lbool force, lbool only_last, int nblank) */ do_repaint = (only_last && n > sc_height-1) || (forw_scroll >= 0 && n > forw_scroll && n != sc_height-1); - -#if HILITE_SEARCH - if (pos != NULL_POSITION && (hilite_search == OPT_ONPLUS || is_filtering() || status_col)) { - prep_hilite(pos, pos + (POSITION) (4*size_linebuf), ignore_eoi ? 1 : -1); - pos = next_unfiltered(pos); - } -#endif - if (!do_repaint) { if (top_scroll && n >= sc_height - 1 && pos != ch_length()) @@ -250,7 +249,6 @@ public void forw(int n, POSITION pos, lbool force, lbool only_last, int nblank) * but we don't yet know if that will happen. }} */ pos_clear(); - add_forw_pos(pos); force = TRUE; clear(); home(); @@ -264,7 +262,6 @@ public void forw(int n, POSITION pos, lbool force, lbool only_last, int nblank) * (position table) and start a new screen. */ pos_clear(); - add_forw_pos(pos); force = TRUE; if (top_scroll) { @@ -279,6 +276,7 @@ public void forw(int n, POSITION pos, lbool force, lbool only_last, int nblank) while (--n >= 0) { + POSITION linepos = NULL_POSITION; /* * Read the next line of input. */ @@ -297,10 +295,10 @@ public void forw(int n, POSITION pos, lbool force, lbool only_last, int nblank) /* * Get the next line from the file. */ - pos = forw_line(pos); -#if HILITE_SEARCH - pos = next_unfiltered(pos); -#endif + POSITION opos = pos; + pos = forw_line(pos, &linepos, &newline); + if (to_newline && !newline) + ++n; if (pos == NULL_POSITION) { /* @@ -309,19 +307,23 @@ public void forw(int n, POSITION pos, lbool force, lbool only_last, int nblank) * Even if force is true, stop when the last * line in the file reaches the top of screen. */ - if (!force && position(TOP) != NULL_POSITION) - break; - if (!empty_lines(0, 0) && - !empty_lines(1, 1) && - empty_lines(2, sc_height-1)) + soft_eof = opos; + linepos = opos; + if (ABORT_SIGS() || + (!force && position(TOP) != NULL_POSITION) || + (!empty_lines(0, 0) && !empty_lines(1, 1) && empty_lines(2, sc_height-1))) + { + pos = opos; break; + } } } /* * Add the position of the next line to the position table. * Display the current line on the screen. */ - add_forw_pos(pos); + add_forw_pos(linepos, first_line); + first_line = FALSE; nlines++; if (do_repaint) continue; @@ -345,30 +347,13 @@ public void forw(int n, POSITION pos, lbool force, lbool only_last, int nblank) squished = TRUE; continue; } - put_line(); -#if 0 - /* {{ - * Can't call clear_eol here. The cursor might be at end of line - * on an ignaw terminal, so clear_eol would clear the last char - * of the current line instead of all of the next line. - * If we really need to do this on clear_bg terminals, we need - * to find a better way. - * }} - */ - if (clear_bg && apply_at_specials(final_attr) != AT_NORMAL) - { - /* - * Writing the last character on the last line - * of the display may have scrolled the screen. - * If we were in standout mode, clear_bg terminals - * will fill the new line with the standout color. - * Now we're in normal mode again, so clear the line. - */ - clear_eol(); - } -#endif + put_line(TRUE); + if (stop_on_form_feed && !do_repaint && line_is_ff() && position(TOP) != NULL_POSITION) + break; forw_prompt = 1; } + if (!first_line) + add_forw_pos(pos, FALSE); if (nlines == 0 && !ignore_eoi) eof_bell(); else if (do_repaint) @@ -378,34 +363,30 @@ public void forw(int n, POSITION pos, lbool force, lbool only_last, int nblank) overlay_header(); /* lower_left(); {{ considered harmful? }} */ } - first_time = 0; + first_time = FALSE; (void) currline(BOTTOM); } /* * Display n lines, scrolling backward. */ -public void back(int n, POSITION pos, lbool force, lbool only_last) +public void back(int n, POSITION pos, lbool force, lbool only_last, lbool to_newline) { int nlines = 0; lbool do_repaint; + lbool newline; squish_check(); do_repaint = (n > get_back_scroll() || (only_last && n > sc_height-1) || header_lines > 0); -#if HILITE_SEARCH - if (pos != NULL_POSITION && (hilite_search == OPT_ONPLUS || is_filtering() || status_col)) { - prep_hilite((pos < (POSITION) (3*size_linebuf)) ? 0 : pos - (POSITION) (3*size_linebuf), pos, -1); - } -#endif + while (--n >= 0) { /* * Get the previous line of input. */ -#if HILITE_SEARCH - pos = prev_unfiltered(pos); -#endif - pos = back_line(pos); + pos = back_line(pos, &newline); + if (to_newline && !newline) + ++n; if (pos == NULL_POSITION) { /* @@ -431,7 +412,9 @@ public void back(int n, POSITION pos, lbool force, lbool only_last) { home(); add_line(); - put_line(); + put_line(FALSE); + if (stop_on_form_feed && line_is_ff()) + break; } } if (nlines == 0) @@ -450,11 +433,11 @@ public void back(int n, POSITION pos, lbool force, lbool only_last) * Display n more lines, forward. * Start just after the line currently displayed at the bottom of the screen. */ -public void forward(int n, lbool force, lbool only_last) +public void forward(int n, lbool force, lbool only_last, lbool to_newline) { POSITION pos; - if (get_quit_at_eof() && eof_displayed() && !(ch_getflags() & CH_HELPFILE)) + if (get_quit_at_eof() && eof_displayed(FALSE) && !(ch_getflags() & CH_HELPFILE)) { /* * If the -e flag is set and we're trying to go @@ -481,7 +464,7 @@ public void forward(int n, lbool force, lbool only_last) { do { - back(1, position(TOP), 1, 0); + back(1, position(TOP), TRUE, FALSE, FALSE); pos = position(BOTTOM_PLUS_ONE); } while (pos == NULL_POSITION && !ABORT_SIGS()); } @@ -491,14 +474,14 @@ public void forward(int n, lbool force, lbool only_last) return; } } - forw(n, pos, force, only_last, 0); + forw(n, pos, force, only_last, to_newline, 0); } /* * Display n more lines, backward. * Start just before the line currently displayed at the top of the screen. */ -public void backward(int n, lbool force, lbool only_last) +public void backward(int n, lbool force, lbool only_last, lbool to_newline) { POSITION pos; @@ -508,7 +491,7 @@ public void backward(int n, lbool force, lbool only_last) eof_bell(); return; } - back(n, pos, force, only_last); + back(n, pos, force, only_last, to_newline); } /* @@ -531,15 +514,25 @@ public int get_back_scroll(void) /* * Will the entire file fit on one screen? */ -public int get_one_screen(void) +public lbool get_one_screen(void) { int nlines; POSITION pos = ch_zero(); + lbool ret = FALSE; - for (nlines = 0; nlines < sc_height; nlines++) + /* Disable polling until we know whether we will exit early due to -F. */ + getting_one_screen = TRUE; + for (nlines = 0; nlines + shell_lines <= sc_height; nlines++) { - pos = forw_line(pos); - if (pos == NULL_POSITION) break; + pos = forw_line(pos, NULL, NULL); + if (ABORT_SIGS()) + break; + if (pos == NULL_POSITION) + { + ret = TRUE; + break; + } } - return (nlines < sc_height); + getting_one_screen = FALSE; + return ret; } |
