From cb17732ac24f5ffb8fd23bbc956c24163d8c0f4c Mon Sep 17 00:00:00 2001 From: Benno Schulenberg Date: Thu, 7 Apr 2016 13:58:51 +0200 Subject: [PATCH] scrolling: don't scroll too much when having to bridge blank lines Add a third mode of scrolling, FLOWING, besides CENTERING and STATIONARY. This is used for word and paragraph jumping (and for bracket matching, but that worked correctly already), and only when focusing is FALSE. The new mode prevents the screen from scrolling too many lines when there are several blank lines at the bottom of the edit window and the next word or paragraph is out of view. This fixes https://savannah.gnu.org/bugs/?47194. --- src/move.c | 4 ++-- src/nano.c | 2 +- src/nano.h | 2 +- src/search.c | 2 +- src/text.c | 4 ++-- src/winio.c | 41 ++++++++++++++++++++++++----------------- 6 files changed, 31 insertions(+), 24 deletions(-) diff --git a/src/move.c b/src/move.c index 2061591b..75295680 100644 --- a/src/move.c +++ b/src/move.c @@ -96,7 +96,7 @@ void do_page_up(void) #endif /* Scroll the edit window up a page. */ - edit_update(NONE); + edit_update(STATIONARY); } /* Move down one page. */ @@ -136,7 +136,7 @@ void do_page_down(void) openfile->placewewant); /* Scroll the edit window down a page. */ - edit_update(NONE); + edit_update(STATIONARY); } #ifndef DISABLE_JUSTIFY diff --git a/src/nano.c b/src/nano.c index 21cb1ed6..1658b3c6 100644 --- a/src/nano.c +++ b/src/nano.c @@ -404,7 +404,7 @@ void move_to_filestruct(filestruct **file_top, filestruct **file_bot, /* If the top of the edit window was inside the old partition, put * it in range of current. */ if (edittop_inside) - edit_update(NONE); + edit_update(STATIONARY); /* Renumber starting with the beginning line of the old * partition. */ diff --git a/src/nano.h b/src/nano.h index 6de3fbde..b79f3d23 100644 --- a/src/nano.h +++ b/src/nano.h @@ -176,7 +176,7 @@ typedef enum { } scroll_dir; typedef enum { - CENTER, NONE + CENTERING, FLOWING, STATIONARY } update_type; typedef enum { diff --git a/src/search.c b/src/search.c index 6bd6b35f..1c7d3377 100644 --- a/src/search.c +++ b/src/search.c @@ -958,7 +958,7 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer, openfile->placewewant = column - 1; /* Put the top line of the edit window in range of the current line. */ - edit_update(CENTER); + edit_update(CENTERING); /* When in interactive mode, update the screen. */ if (interactive) { diff --git a/src/text.c b/src/text.c index 37388f35..2b43b798 100644 --- a/src/text.c +++ b/src/text.c @@ -2831,7 +2831,7 @@ const char *do_alt_speller(char *tempfile_name) /* Go back to the old position. */ goto_line_posx(lineno_save, current_x_save); openfile->current_y = current_y_save; - edit_update(NONE); + edit_update(STATIONARY); /* Stat the temporary file again, and mark the buffer as modified only * if this file was changed since it was written. */ @@ -3310,7 +3310,7 @@ void do_formatter(void) goto_line_posx(lineno_save, current_x_save); openfile->current_y = current_y_save; openfile->placewewant = pww_save; - edit_update(NONE); + edit_update(STATIONARY); set_modified(); diff --git a/src/winio.c b/src/winio.c index acaae86b..3f4f9a61 100644 --- a/src/winio.c +++ b/src/winio.c @@ -2963,7 +2963,7 @@ void edit_redraw(filestruct *old_current, size_t pww_save) /* If the current line is offscreen, scroll until it's onscreen. */ if (openfile->current->lineno >= openfile->edittop->lineno + maxrows || openfile->current->lineno < openfile->edittop->lineno) - edit_update((focusing || !ISSET(SMOOTH_SCROLL)) ? CENTER : NONE); + edit_update((focusing || !ISSET(SMOOTH_SCROLL)) ? CENTERING : FLOWING); #ifndef NANO_TINY /* If the mark is on, update all lines between old_current and current. */ @@ -3005,7 +3005,7 @@ void edit_refresh(void) #endif /* Make sure the current line is on the screen. */ - edit_update((focusing || !ISSET(SMOOTH_SCROLL)) ? CENTER : NONE); + edit_update((focusing || !ISSET(SMOOTH_SCROLL)) ? CENTERING : STATIONARY); } foo = openfile->edittop; @@ -3027,26 +3027,33 @@ void edit_refresh(void) wnoutrefresh(edit); } -/* Move edittop to put it in range of current, keeping current in the - * same place. location determines how we move it: if it's CENTER, we - * center current, and if it's NONE, we put current current_y lines - * below edittop. */ -void edit_update(update_type location) +/* Move edittop so that current is on the screen. manner says how it + * should be moved: CENTERING means that current should end up in the + * middle of the screen, STATIONARY means that it should stay at the + * same vertical position, and FLOWING means that it should scroll no + * more than needed to bring current into view. */ +void edit_update(update_type manner) { filestruct *foo = openfile->current; int goal; - /* If location is CENTER, we move edittop up (editwinrows / 2) - * lines. This puts current at the center of the screen. If - * location is NONE, we move edittop up current_y lines if current_y - * is in range of the screen, 0 lines if current_y is less than 0, - * or (editwinrows - 1) lines if current_y is greater than - * (editwinrows - 1). This puts current at the same place on the - * screen as before, or at the top or bottom of the screen if - * edittop is beyond either. */ - if (location == CENTER) + /* If manner is CENTERING, move edittop half the number of window + * lines back from current. If manner is STATIONARY, move edittop + * back current_y lines if current_y is in range of the screen, + * 0 lines if current_y is below zero, or (editwinrows - 1) lines + * if current_y is too big. This puts current at the same place + * on the screen as before, or at the top or bottom if current_y is + * beyond either. If manner is FLOWING, move edittop back 0 lines + * or (editwinrows - 1) lines, depending or where current has moved. + * This puts the cursor on the first or the last line. */ + if (manner == CENTERING) goal = editwinrows / 2; - else { + else if (manner == FLOWING) { + if (openfile->current->lineno < openfile->edittop->lineno) + goal = 0; + else + goal = editwinrows - 1; + } else { goal = openfile->current_y; /* Limit goal to (editwinrows - 1) lines maximum. */