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.master
parent
d851ccdd41
commit
cb17732ac2
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -176,7 +176,7 @@ typedef enum {
|
|||
} scroll_dir;
|
||||
|
||||
typedef enum {
|
||||
CENTER, NONE
|
||||
CENTERING, FLOWING, STATIONARY
|
||||
} update_type;
|
||||
|
||||
typedef enum {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
41
src/winio.c
41
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. */
|
||||
|
|
Loading…
Reference in New Issue