[PATCH v2] smooth horizontal scrolling in unison (revisited)
Benno Schulenberg <[email protected]> Wed, 7 Jan 2026 16:20:25 +0100
| Newsgroups | gmane.editors.nano.devel |
|---|---|
| Message-ID | <[email protected]> |
Instead of horizontally scrolling just the current line by nearly a screen width when the cursor is about the go offscreen, now all screen lines are scrolled horizontally together by just the amount needed to keep the cursor comfortably in view. (The joint-panning option is set here by default, for testing.) Motivated-by: Xylia Allegretta <[email protected]> Original-patch-by: Mark Majeres <[email protected]> --- src/definitions.h | 3 ++- src/global.c | 2 ++ src/nano.c | 13 +++++++++++-- src/prototypes.h | 2 ++ src/search.c | 6 ++++++ src/utils.c | 11 +++++++++++ src/winio.c | 16 +++++++++++++--- 7 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/definitions.h b/src/definitions.h index dfe2106f..bc7e220c 100644 --- a/src/definitions.h +++ b/src/definitions.h @@ -376,7 +376,8 @@ enum { USE_MAGIC, MINIBAR, ZERO, - MODERN_BINDINGS + MODERN_BINDINGS, + JOINT_PANNING }; /* Structure types. */ diff --git a/src/global.c b/src/global.c index 84912f17..56680f02 100644 --- a/src/global.c +++ b/src/global.c @@ -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. */ diff --git a/src/nano.c b/src/nano.c index 2b45ca76..d16ef410 100644 --- a/src/nano.c +++ b/src/nano.c @@ -1477,6 +1477,7 @@ void inject(char *burst, size_t count) { linestruct *thisline = openfile->current; size_t datalen = strlen(thisline->data); + size_t was_pww = openfile->placewewant; #ifndef NANO_TINY size_t original_row = 0; size_t old_amount = 0; @@ -1551,6 +1552,10 @@ void inject(char *burst, size_t count) openfile->placewewant = xplustabs(); + /* When panning, check whether the viewport needs to shift. */ + if (ISSET(JOINT_PANNING) && line_needs_update(was_pww, openfile->placewewant)) + ; + #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, @@ -2642,6 +2647,8 @@ int main(int argc, char **argv) die(_("Can open just one file\n")); #endif + SET(JOINT_PANNING); + prepare_for_display(); #ifdef ENABLE_NANORC @@ -2701,9 +2708,11 @@ int main(int argc, char **argv) } #endif - if ((refresh_needed && LINES > 1) || (LINES == 1 && lastmessage <= HUSH)) + if ((refresh_needed && LINES > 1) || (LINES == 1 && lastmessage <= HUSH)) { + if (ISSET(JOINT_PANNING) && !ISSET(SOFTWRAP)) + brink = get_page_start(xplustabs()); edit_refresh(); - else + } else place_the_cursor(); #ifndef NANO_TINY diff --git a/src/prototypes.h b/src/prototypes.h index c83380df..05b5f7bb 100644 --- a/src/prototypes.h +++ b/src/prototypes.h @@ -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; diff --git a/src/search.c b/src/search.c index 254e23a5..d5187f83 100644 --- a/src/search.c +++ b/src/search.c @@ -332,6 +332,9 @@ 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 is visible too. */ + if (ISSET(JOINT_PANNING) && !ISSET(SOFTWRAP)) + brink = get_page_start(light_to_col); refresh_needed = TRUE; } #endif @@ -591,6 +594,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(JOINT_PANNING) && !ISSET(SOFTWRAP)) + brink = get_page_start(light_to_col); + /* Refresh the edit window, scrolling it if necessary. */ edit_refresh(); diff --git a/src/utils.c b/src/utils.c index 537c8cf7..e129177a 100644 --- a/src/utils.c +++ b/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(JOINT_PANNING) && !ISSET(SOFTWRAP)) { + if (column < 3) + return 0; + else if (column < brink + 3) + return column - 3; + else if (column - brink > editwincols - 4) + return column - editwincols + 4; + else + return brink; + } + if (column == 0 || column + 2 < editwincols || ISSET(SOFTWRAP)) return 0; else if (editwincols > 8) diff --git a/src/winio.c b/src/winio.c index 277851d9..e9e9fb5d 100644 --- a/src/winio.c +++ b/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(JOINT_PANNING)) + from_col = get_page_start(wideness(line->data, index)); + else + from_col = brink; /* 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(JOINT_PANNING) && !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(JOINT_PANNING) && !ISSET(SOFTWRAP)) { + refresh_needed = TRUE; + return; } #ifndef NANO_TINY -- 2.51.2