new default feature: smooth whole-window sideways scrolling
Instead of horizontally scrolling just the current line by nearly a screen width when the cursor is about to go offscreen, now all screen lines are scrolled horizontally together by just the amount needed to keep the cursor comfortably in view. References: https://lists.gnu.org/archive/html/nano-devel/2026-01/msg00000.html https://lists.gnu.org/archive/html/nano-devel/2026-01/msg00003.html https://lists.gnu.org/archive/html/nano-devel/2014-05/msg00025.html https://lists.gnu.org/archive/html/nano-devel/2014-06/msg00152.html Nano could have acquired this feature nearly twelve years ago, but... somehow that old patch fell through the cracks and was forgotten. :| Motivated-by: Xylia Allegretta <xylia.allegretta@gmail.com> Original-patch-by: Mark Majeres <mark@engine12.com>
This commit is contained in:
@@ -53,6 +53,9 @@ void expunge(undo_type action)
|
||||
/* When softwrapping, a changed number of chunks requires a refresh. */
|
||||
if (ISSET(SOFTWRAP) && extra_chunks_in(openfile->current) != old_amount)
|
||||
refresh_needed = TRUE;
|
||||
/* When panning, and we have come near edge of the viewport... */
|
||||
else if (!ISSET(SOLO_SIDESCROLL) && openfile->placewewant < brink + CUSHION)
|
||||
refresh_needed = TRUE;
|
||||
|
||||
/* Adjust the mark if it is after the cursor on the current line. */
|
||||
if (openfile->mark == openfile->current &&
|
||||
|
||||
@@ -143,6 +143,9 @@
|
||||
/* The default number of columns from end of line where wrapping occurs. */
|
||||
#define COLUMNS_FROM_EOL 8
|
||||
|
||||
/* The number of columns the cursor should stay away from the edge. */
|
||||
#define CUSHION 3
|
||||
|
||||
/* The default comment character when a syntax does not specify any. */
|
||||
#define GENERAL_COMMENT_CHARACTER "#"
|
||||
|
||||
@@ -376,7 +379,8 @@ enum {
|
||||
USE_MAGIC,
|
||||
MINIBAR,
|
||||
ZERO,
|
||||
MODERN_BINDINGS
|
||||
MODERN_BINDINGS,
|
||||
SOLO_SIDESCROLL
|
||||
};
|
||||
|
||||
/* Structure types. */
|
||||
|
||||
@@ -73,6 +73,8 @@ char *title = NULL;
|
||||
bool refresh_needed = FALSE;
|
||||
/* Did a command mangle enough of the buffer that we should
|
||||
* repaint the screen? */
|
||||
size_t brink = 0;
|
||||
/* From which column the edit window is drawn (when panning). */
|
||||
bool focusing = TRUE;
|
||||
/* Whether an update of the edit window should center the cursor. */
|
||||
|
||||
|
||||
@@ -1551,6 +1551,10 @@ void inject(char *burst, size_t count)
|
||||
|
||||
openfile->placewewant = xplustabs();
|
||||
|
||||
/* When panning, and we have come near the edge of the viewport... */
|
||||
if (!ISSET(SOLO_SIDESCROLL) && openfile->placewewant > brink + editwincols - CUSHION - 1 )
|
||||
refresh_needed = TRUE;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* When softwrapping and the number of chunks in the current line changed,
|
||||
* or we were on the last row of the edit window and moved to a new chunk,
|
||||
|
||||
@@ -47,6 +47,8 @@ extern int final_status;
|
||||
extern bool inhelp;
|
||||
extern char *title;
|
||||
|
||||
extern size_t brink;
|
||||
|
||||
extern bool focusing;
|
||||
|
||||
extern bool as_an_at;
|
||||
|
||||
@@ -332,6 +332,11 @@ int findnextstr(const char *needle, bool whole_word_only, int modus,
|
||||
spotlighted = TRUE;
|
||||
light_from_col = xplustabs();
|
||||
light_to_col = wideness(line->data, found_x + found_len);
|
||||
|
||||
/* When panning, ensure the end of the match will be visible too. */
|
||||
if (!ISSET(SOLO_SIDESCROLL) && !ISSET(SOFTWRAP))
|
||||
brink = get_page_start(light_to_col);
|
||||
|
||||
refresh_needed = TRUE;
|
||||
}
|
||||
#endif
|
||||
@@ -591,6 +596,9 @@ ssize_t do_replace_loop(const char *needle, bool whole_word_only,
|
||||
light_to_col = wideness(openfile->current->data,
|
||||
openfile->current_x + match_len);
|
||||
|
||||
if (!ISSET(SOLO_SIDESCROLL) && !ISSET(SOFTWRAP))
|
||||
brink = get_page_start(light_to_col);
|
||||
|
||||
/* Refresh the edit window, scrolling it if necessary. */
|
||||
edit_refresh();
|
||||
|
||||
|
||||
11
src/utils.c
11
src/utils.c
@@ -343,6 +343,17 @@ char *free_and_assign(char *dest, char *src)
|
||||
* displayed in the edit window when the cursor is at the given column. */
|
||||
size_t get_page_start(size_t column)
|
||||
{
|
||||
if (!ISSET(SOLO_SIDESCROLL) && !ISSET(SOFTWRAP)) {
|
||||
if (column < CUSHION)
|
||||
return 0;
|
||||
else if (column < brink + CUSHION)
|
||||
return column - CUSHION;
|
||||
else if (column > brink + editwincols - CUSHION - 1)
|
||||
return column - editwincols + CUSHION + 1;
|
||||
else
|
||||
return brink;
|
||||
}
|
||||
|
||||
if (column == 0 || column + 2 < editwincols || ISSET(SOFTWRAP))
|
||||
return 0;
|
||||
else if (editwincols > 8)
|
||||
|
||||
20
src/winio.c
20
src/winio.c
@@ -2838,7 +2838,10 @@ int update_line(linestruct *line, size_t index)
|
||||
#endif
|
||||
|
||||
row = line->lineno - openfile->edittop->lineno;
|
||||
from_col = get_page_start(wideness(line->data, index));
|
||||
if (!ISSET(SOLO_SIDESCROLL))
|
||||
from_col = brink;
|
||||
else
|
||||
from_col = get_page_start(wideness(line->data, index));
|
||||
|
||||
/* Expand the piece to be drawn to its representable form, and draw it. */
|
||||
converted = display_string(line->data, from_col, editwincols, TRUE, FALSE);
|
||||
@@ -2931,9 +2934,13 @@ bool line_needs_update(const size_t old_column, const size_t new_column)
|
||||
#ifndef NANO_TINY
|
||||
if (openfile->mark)
|
||||
return TRUE;
|
||||
else
|
||||
#endif
|
||||
return (get_page_start(old_column) != get_page_start(new_column));
|
||||
if (get_page_start(old_column) == get_page_start(new_column))
|
||||
return FALSE;
|
||||
if (!ISSET(SOLO_SIDESCROLL) && !ISSET(SOFTWRAP))
|
||||
refresh_needed = TRUE;
|
||||
|
||||
return !refresh_needed;
|
||||
}
|
||||
|
||||
/* Try to move up nrows softwrapped chunks from the given line and the
|
||||
@@ -3342,6 +3349,9 @@ void edit_redraw(linestruct *old_current, update_type manner)
|
||||
adjust_viewport(ISSET(JUMPY_SCROLLING) ? CENTERING : manner);
|
||||
refresh_needed = TRUE;
|
||||
return;
|
||||
} else if (!ISSET(SOLO_SIDESCROLL) && !ISSET(SOFTWRAP)) {
|
||||
refresh_needed = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
@@ -3381,6 +3391,10 @@ void edit_refresh(void)
|
||||
if (current_is_offscreen())
|
||||
adjust_viewport((focusing || ISSET(JUMPY_SCROLLING)) ? CENTERING : FLOWING);
|
||||
|
||||
/* When panning, ensure the cursor will be within the viewport. */
|
||||
if (!ISSET(SOLO_SIDESCROLL) && !ISSET(SOFTWRAP))
|
||||
brink = get_page_start(xplustabs());
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
/* When needed and useful, initialize the colors for the current syntax. */
|
||||
if (openfile->syntax && !have_palette && !ISSET(NO_SYNTAX) && has_colors())
|
||||
|
||||
Reference in New Issue
Block a user