[PATCH] smooth horizontal scrolling in unison (revisited)
Benno Schulenberg <[email protected]> Sun, 4 Jan 2026 16:15:49 +0100
| Newsgroups | gmane.editors.nano.devel |
|---|---|
| Message-ID | <[email protected]> |
This horizontally scrolls all screen lines together when the cursor is about to go offscreen to the side. It scrolls the lines by just the amount needed to keep the cursor in view. (This rough implementation redraws the entire screen when it's not needed in several cases, but the important thing is to not fail to redraw all lines when it *is* needed. Things can probably be made more efficient later.) (This patch sets the joint-panning option 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/move.c | 16 ++++++++++++---- src/nano.c | 11 +++++++++-- src/prototypes.h | 2 ++ src/utils.c | 11 +++++++++++ src/winio.c | 8 +++++++- 7 files changed, 45 insertions(+), 8 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/move.c b/src/move.c index f79107ab..7d7d9331 100644 --- a/src/move.c +++ b/src/move.c @@ -513,8 +513,12 @@ void do_home(void) * update current if the mark is on or we changed "page". */ if (ISSET(SOFTWRAP) && moved_off_chunk) edit_redraw(was_current, FLOWING); - else if (line_needs_update(was_column, openfile->placewewant)) - update_line(openfile->current, openfile->current_x); + else if (line_needs_update(was_column, openfile->placewewant)) { + if (ISSET(JOINT_PANNING) && !ISSET(SOFTWRAP)) + refresh_needed = TRUE; + else + update_line(openfile->current, openfile->current_x); + } } /* Move to the end of the current line (or softwrapped chunk). @@ -565,8 +569,12 @@ void do_end(void) * update current if the mark is on or we changed "page". */ if (ISSET(SOFTWRAP) && moved_off_chunk) edit_redraw(was_current, FLOWING); - else if (line_needs_update(was_column, openfile->placewewant)) - update_line(openfile->current, openfile->current_x); + else if (line_needs_update(was_column, openfile->placewewant)) { + if (ISSET(JOINT_PANNING) && !ISSET(SOFTWRAP)) + refresh_needed = TRUE; + else + update_line(openfile->current, openfile->current_x); + } } /* Move the cursor to the preceding line or chunk. */ diff --git a/src/nano.c b/src/nano.c index 2b45ca76..39907be1 100644 --- a/src/nano.c +++ b/src/nano.c @@ -1651,6 +1651,9 @@ void process_a_keystroke(void) cycling_aim = 0; #endif + if (ISSET(JOINT_PANNING) && !ISSET(SOFTWRAP)) + refresh_needed = TRUE; + if (!function) { pletion_line = NULL; keep_cutbuffer = FALSE; @@ -2642,6 +2645,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 +2706,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/utils.c b/src/utils.c index 537c8cf7..afff84db 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 == 0) + return 0; + else if (column <= brink) + return column - 1; + else if ((column - brink) > (COLS - 2 - sidebar)) + return column - (COLS - 2 - sidebar); + 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..f1151922 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); @@ -3342,6 +3345,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