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
|
#endif
|
||||||
|
|
||||||
/* Scroll the edit window up a page. */
|
/* Scroll the edit window up a page. */
|
||||||
edit_update(NONE);
|
edit_update(STATIONARY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move down one page. */
|
/* Move down one page. */
|
||||||
|
@ -136,7 +136,7 @@ void do_page_down(void)
|
||||||
openfile->placewewant);
|
openfile->placewewant);
|
||||||
|
|
||||||
/* Scroll the edit window down a page. */
|
/* Scroll the edit window down a page. */
|
||||||
edit_update(NONE);
|
edit_update(STATIONARY);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef DISABLE_JUSTIFY
|
#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
|
/* If the top of the edit window was inside the old partition, put
|
||||||
* it in range of current. */
|
* it in range of current. */
|
||||||
if (edittop_inside)
|
if (edittop_inside)
|
||||||
edit_update(NONE);
|
edit_update(STATIONARY);
|
||||||
|
|
||||||
/* Renumber starting with the beginning line of the old
|
/* Renumber starting with the beginning line of the old
|
||||||
* partition. */
|
* partition. */
|
||||||
|
|
|
@ -176,7 +176,7 @@ typedef enum {
|
||||||
} scroll_dir;
|
} scroll_dir;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CENTER, NONE
|
CENTERING, FLOWING, STATIONARY
|
||||||
} update_type;
|
} update_type;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
@ -958,7 +958,7 @@ void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
|
||||||
openfile->placewewant = column - 1;
|
openfile->placewewant = column - 1;
|
||||||
|
|
||||||
/* Put the top line of the edit window in range of the current line. */
|
/* 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. */
|
/* When in interactive mode, update the screen. */
|
||||||
if (interactive) {
|
if (interactive) {
|
||||||
|
|
|
@ -2831,7 +2831,7 @@ const char *do_alt_speller(char *tempfile_name)
|
||||||
/* Go back to the old position. */
|
/* Go back to the old position. */
|
||||||
goto_line_posx(lineno_save, current_x_save);
|
goto_line_posx(lineno_save, current_x_save);
|
||||||
openfile->current_y = current_y_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
|
/* Stat the temporary file again, and mark the buffer as modified only
|
||||||
* if this file was changed since it was written. */
|
* 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);
|
goto_line_posx(lineno_save, current_x_save);
|
||||||
openfile->current_y = current_y_save;
|
openfile->current_y = current_y_save;
|
||||||
openfile->placewewant = pww_save;
|
openfile->placewewant = pww_save;
|
||||||
edit_update(NONE);
|
edit_update(STATIONARY);
|
||||||
|
|
||||||
set_modified();
|
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 the current line is offscreen, scroll until it's onscreen. */
|
||||||
if (openfile->current->lineno >= openfile->edittop->lineno + maxrows ||
|
if (openfile->current->lineno >= openfile->edittop->lineno + maxrows ||
|
||||||
openfile->current->lineno < openfile->edittop->lineno)
|
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
|
#ifndef NANO_TINY
|
||||||
/* If the mark is on, update all lines between old_current and current. */
|
/* If the mark is on, update all lines between old_current and current. */
|
||||||
|
@ -3005,7 +3005,7 @@ void edit_refresh(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Make sure the current line is on the screen. */
|
/* 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;
|
foo = openfile->edittop;
|
||||||
|
@ -3027,26 +3027,33 @@ void edit_refresh(void)
|
||||||
wnoutrefresh(edit);
|
wnoutrefresh(edit);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move edittop to put it in range of current, keeping current in the
|
/* Move edittop so that current is on the screen. manner says how it
|
||||||
* same place. location determines how we move it: if it's CENTER, we
|
* should be moved: CENTERING means that current should end up in the
|
||||||
* center current, and if it's NONE, we put current current_y lines
|
* middle of the screen, STATIONARY means that it should stay at the
|
||||||
* below edittop. */
|
* same vertical position, and FLOWING means that it should scroll no
|
||||||
void edit_update(update_type location)
|
* more than needed to bring current into view. */
|
||||||
|
void edit_update(update_type manner)
|
||||||
{
|
{
|
||||||
filestruct *foo = openfile->current;
|
filestruct *foo = openfile->current;
|
||||||
int goal;
|
int goal;
|
||||||
|
|
||||||
/* If location is CENTER, we move edittop up (editwinrows / 2)
|
/* If manner is CENTERING, move edittop half the number of window
|
||||||
* lines. This puts current at the center of the screen. If
|
* lines back from current. If manner is STATIONARY, move edittop
|
||||||
* location is NONE, we move edittop up current_y lines if current_y
|
* back current_y lines if current_y is in range of the screen,
|
||||||
* is in range of the screen, 0 lines if current_y is less than 0,
|
* 0 lines if current_y is below zero, or (editwinrows - 1) lines
|
||||||
* or (editwinrows - 1) lines if current_y is greater than
|
* if current_y is too big. This puts current at the same place
|
||||||
* (editwinrows - 1). This puts current at the same place on the
|
* on the screen as before, or at the top or bottom if current_y is
|
||||||
* screen as before, or at the top or bottom of the screen if
|
* beyond either. If manner is FLOWING, move edittop back 0 lines
|
||||||
* edittop is beyond either. */
|
* or (editwinrows - 1) lines, depending or where current has moved.
|
||||||
if (location == CENTER)
|
* This puts the cursor on the first or the last line. */
|
||||||
|
if (manner == CENTERING)
|
||||||
goal = editwinrows / 2;
|
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;
|
goal = openfile->current_y;
|
||||||
|
|
||||||
/* Limit goal to (editwinrows - 1) lines maximum. */
|
/* Limit goal to (editwinrows - 1) lines maximum. */
|
||||||
|
|
Loading…
Reference in New Issue