summaryrefslogtreecommitdiff
path: root/forwback.c
diff options
context:
space:
mode:
Diffstat (limited to 'forwback.c')
-rw-r--r--forwback.c163
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;
}