From 380ad30a53b25644f96b3fad07ee7285537b132e Mon Sep 17 00:00:00 2001 From: David Lawrence Ramsey Date: Wed, 18 Jan 2017 20:31:33 -0600 Subject: [PATCH] softwrap: account for softwrap when checking whether current is offscreen Add the new functions current_is_above_screen() (which doesn't account for softwrapped chunks yet, but will when we can scroll edittop partially off the screen, which is forthcoming), current_is_below_screen() (which determines whether current[current_x] is past the softwrapped chunk at the bottom of the screen), and current_is_offscreen() (the union of the previous two functions). edit_redraw() and edit_refresh() now use current_is_offscreen() to check whether they should adjust the viewport, and adjust_viewport() now uses current_is_above_screen() to determine whether current is on or below the screen in FLOWING mode. --- src/proto.h | 3 +++ src/winio.c | 47 ++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/proto.h b/src/proto.h index c7eeeb93..1415af73 100644 --- a/src/proto.h +++ b/src/proto.h @@ -711,6 +711,9 @@ int go_back_chunks(int nrows, filestruct **line, size_t *leftedge); int go_forward_chunks(int nrows, filestruct **line, size_t *leftedge); bool less_than_a_screenful(size_t was_lineno, size_t was_leftedge); void edit_scroll(scroll_dir direction, int nrows); +bool current_is_above_screen(void); +bool current_is_below_screen(void); +bool current_is_offscreen(void); void edit_redraw(filestruct *old_current); void edit_refresh(void); void adjust_viewport(update_type location); diff --git a/src/winio.c b/src/winio.c index 39538644..84a7e9b0 100644 --- a/src/winio.c +++ b/src/winio.c @@ -2946,6 +2946,41 @@ void edit_scroll(scroll_dir direction, int nrows) compute_maxlines(); } +/* Return TRUE if current[current_x] is above the top of the screen, and FALSE + * otherwise. */ +bool current_is_above_screen(void) +{ + return (openfile->current->lineno < openfile->edittop->lineno); +} + +/* Return TRUE if current[current_x] is below the bottom of the screen, and + * FALSE otherwise. */ +bool current_is_below_screen(void) +{ +#ifndef NANO_TINY + if (ISSET(SOFTWRAP)) { + filestruct *line = openfile->edittop; + size_t leftedge = 0; + + /* If current[current_x] is more than a screen's worth of lines after + * edittop, it's below the screen. */ + return (go_forward_chunks(editwinrows - 1, &line, &leftedge) == 0 && + (line->lineno < openfile->current->lineno || + (line->lineno == openfile->current->lineno && + leftedge < (xplustabs() / editwincols) * editwincols))); + } else +#endif + return (openfile->current->lineno >= + openfile->edittop->lineno + editwinrows); +} + +/* Return TRUE if current[current_x] is offscreen relative to edittop, and + * FALSE otherwise. */ +bool current_is_offscreen(void) +{ + return (current_is_above_screen() || current_is_below_screen()); +} + /* Update any lines between old_current and current that need to be * updated. Use this if we've moved without changing any text. */ void edit_redraw(filestruct *old_current) @@ -2955,12 +2990,7 @@ void edit_redraw(filestruct *old_current) openfile->placewewant = xplustabs(); /* If the current line is offscreen, scroll until it's onscreen. */ - if (openfile->current->lineno >= openfile->edittop->lineno + maxlines || -#ifndef NANO_TINY - (openfile->current->lineno == openfile->edittop->lineno + maxlines - 1 && - ISSET(SOFTWRAP) && strlenpt(openfile->current->data) >= editwincols) || -#endif - openfile->current->lineno < openfile->edittop->lineno) { + if (current_is_offscreen()) { adjust_viewport((focusing || !ISSET(SMOOTH_SCROLL)) ? CENTERING : FLOWING); refresh_needed = TRUE; return; @@ -3003,8 +3033,7 @@ void edit_refresh(void) compute_maxlines(); /* If the current line is out of view, get it back on screen. */ - if (openfile->current->lineno < openfile->edittop->lineno || - openfile->current->lineno >= openfile->edittop->lineno + maxlines) { + if (current_is_offscreen()) { #ifdef DEBUG fprintf(stderr, "edit-refresh: line = %ld, edittop = %ld and maxlines = %d\n", (long)openfile->current->lineno, (long)openfile->edittop->lineno, maxlines); @@ -3055,7 +3084,7 @@ void adjust_viewport(update_type manner) if (manner == CENTERING) goal = editwinrows / 2; else if (manner == FLOWING) { - if (openfile->current->lineno >= openfile->edittop->lineno) { + if (!current_is_above_screen()) { goal = editwinrows - 1; #ifndef NANO_TINY if (ISSET(SOFTWRAP))