Re: [PATCH] new feature: horizontal scrolling of full screen
Xylia Allegretta <[email protected]> Tue, 6 Jan 2026 23:17:55 +0000
| Newsgroups | gmane.editors.nano.devel |
|---|---|
| Message-ID | <CAE7GgQ9-M038Xf==upk6hL1jgn98HwoiApJxDbeM1Kb4aLpC4g@mail.gmail.com> |
On Tue, Jan 6, 2026 at 10:02 PM Chris Allegretta <[email protected]> wrote: > How about the following: > - By default, scroll horizontally by 1 > - If JUMPY_SCROLLING is set, scroll by some other value, 8, COLS/2, or > what have you.... Seems to me like someone who's enabled jumpy scrolling > is ok with large movements of the screen, and doesn't mind (or prefers) > recalibrating what they're looking at after a lot of the text has moved. > This would be logically consistent with that. That's a pretty easy change. I've added a check for if JUMPY_SCROLLNG is set in the scrolling update function, and eliminated a variable in winio that I realized was unnecessary. -Xylia Allegretta.
fullscrolling-4.patch
(text/x-patch, 11 KB)
From 0e0103c96699ce647d3e34923eddbce012c64974 Mon Sep 17 00:00:00 2001 From: Xylia Allegretta <[email protected]> Date: Tue, 6 Jan 2026 18:10:10 -0500 Subject: [PATCH] new feature: horizontal scrolling of full screen (patch v4) That's a pretty easy change. I've added a check for if JUMPY_SCROLLNG is set in the scrolling update function, and eliminated a variable in winio that I realized was unnecessary. Signed-off-by: Xylia Allegretta <[email protected]> --- src/cut.c | 6 ++-- src/definitions.h | 3 +- src/global.c | 3 ++ src/move.c | 8 +++-- src/nano.c | 16 +++++++-- src/prototypes.h | 3 ++ src/text.c | 8 +++++ src/winio.c | 84 ++++++++++++++++++++++++++++++++++++++++++++--- 8 files changed, 118 insertions(+), 13 deletions(-) diff --git a/src/cut.c b/src/cut.c index a2d4aecf..dc7e86e4 100644 --- a/src/cut.c +++ b/src/cut.c @@ -50,8 +50,10 @@ void expunge(undo_type action) &openfile->current->data[openfile->current_x + charlen], line_len - charlen + 1); #ifndef NANO_TINY - /* When softwrapping, a changed number of chunks requires a refresh. */ - if (ISSET(SOFTWRAP) && extra_chunks_in(openfile->current) != old_amount) + /* When softwrapping, a changed number of chunks requires a refresh. + * Alternatively, when fullscrolling, a change in scrolling requires a refresh. */ + if ((ISSET(SOFTWRAP) && extra_chunks_in(openfile->current) != old_amount) || + (ISSET(FULL_SCROLLING) && fullsc_update())) refresh_needed = TRUE; /* Adjust the mark if it is after the cursor on the current line. */ diff --git a/src/definitions.h b/src/definitions.h index dfe2106f..3262821f 100644 --- a/src/definitions.h +++ b/src/definitions.h @@ -376,7 +376,8 @@ enum { USE_MAGIC, MINIBAR, ZERO, - MODERN_BINDINGS + MODERN_BINDINGS, + FULL_SCROLLING }; /* Structure types. */ diff --git a/src/global.c b/src/global.c index 84912f17..271f6d49 100644 --- a/src/global.c +++ b/src/global.c @@ -296,6 +296,9 @@ size_t light_from_col = 0; size_t light_to_col = 0; /* Where the spotlighted text ends. */ +size_t fullsc_pos = 0; + /* The amount the screen has scrolled right when fullscrolling. */ + /* To make the functions and shortcuts lists clearer. */ #define VIEW TRUE /* Is allowed in view mode. */ #define NOVIEW FALSE diff --git a/src/move.c b/src/move.c index f79107ab..23486ca9 100644 --- a/src/move.c +++ b/src/move.c @@ -511,7 +511,9 @@ void do_home(void) /* If we changed chunk, we might be offscreen. Otherwise, * update current if the mark is on or we changed "page". */ - if (ISSET(SOFTWRAP) && moved_off_chunk) + if (ISSET(FULL_SCROLLING) && fullsc_update()) + edit_refresh(); + else 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); @@ -563,7 +565,9 @@ void do_end(void) /* If we changed chunk, we might be offscreen. Otherwise, * update current if the mark is on or we changed "page". */ - if (ISSET(SOFTWRAP) && moved_off_chunk) + if (ISSET(FULL_SCROLLING) && fullsc_update()) + edit_refresh(); + else 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); diff --git a/src/nano.c b/src/nano.c index 2b45ca76..ee3081ab 100644 --- a/src/nano.c +++ b/src/nano.c @@ -1356,6 +1356,8 @@ int process_click(void) if (ISSET(SOFTWRAP)) leftedge = leftedge_for(xplustabs(), openfile->current); + else if (ISSET(FULL_SCROLLING)) + leftedge = fullsc_pos; else #endif leftedge = get_page_start(xplustabs()); @@ -1554,10 +1556,12 @@ void inject(char *burst, size_t count) #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, - * we need a full refresh. */ - if (ISSET(SOFTWRAP) && (extra_chunks_in(openfile->current) != old_amount || + * we need a full refresh. A refresh is also necessary when fullscrolling + * is set and the scrolling changes. */ + if ((ISSET(SOFTWRAP) && (extra_chunks_in(openfile->current) != old_amount || (openfile->cursor_row == editwinrows - 1 && - chunk_for(openfile->placewewant, openfile->current) > original_row))) { + chunk_for(openfile->placewewant, openfile->current) > original_row))) || + (ISSET(FULL_SCROLLING) && fullsc_update())) { refresh_needed = TRUE; focusing = FALSE; } @@ -2642,6 +2646,12 @@ int main(int argc, char **argv) die(_("Can open just one file\n")); #endif + /* Enabled by default for testing. */ + SET(FULL_SCROLLING); + /* These options should be mutually exclusive. */ + if (ISSET(SOFTWRAP)) + UNSET(SOFTWRAP); + prepare_for_display(); #ifdef ENABLE_NANORC diff --git a/src/prototypes.h b/src/prototypes.h index c83380df..84bd2d78 100644 --- a/src/prototypes.h +++ b/src/prototypes.h @@ -197,6 +197,8 @@ extern bool spotlighted; extern size_t light_from_col; extern size_t light_to_col; +extern size_t fullsc_pos; + typedef void (*functionptrtype)(void); /* The two needed functions from browser.c. */ @@ -687,3 +689,4 @@ void flip_newbuffer(void); #endif void discard_buffer(void); void do_cancel(void); +bool fullsc_update(void); diff --git a/src/text.c b/src/text.c index 3d553447..54f8cd3c 100644 --- a/src/text.c +++ b/src/text.c @@ -665,6 +665,10 @@ void do_undo(void) openfile->totsize = u->wassize; + /* If scrolling has changed, refresh. */ + if (ISSET(FULL_SCROLLING) && fullsc_update()) + refresh_needed = TRUE; + #ifdef ENABLE_COLOR if (u->type <= REPLACE) check_the_multis(openfile->current); @@ -834,6 +838,10 @@ void do_redo(void) openfile->totsize = u->newsize; + /* If scrolling has changed, refresh. */ + if (ISSET(FULL_SCROLLING) && fullsc_update()) + refresh_needed = TRUE; + #ifdef ENABLE_COLOR if (u->type <= REPLACE) check_the_multis(openfile->current); diff --git a/src/winio.c b/src/winio.c index 277851d9..4beecdd4 100644 --- a/src/winio.c +++ b/src/winio.c @@ -81,6 +81,8 @@ static size_t macro_length = 0; /* The current length of the macro. */ static size_t milestone = 0; /* Where the last burst of recorded keystrokes started. */ +static bool fullsc_refresh_check = TRUE; + /* Whether or not to update scrolling when a refresh occurs. */ /* Add the given code to the macro buffer. */ void add_to_macrobuffer(int code) @@ -1759,6 +1761,37 @@ void set_blankdelay_to_one(void) countdown = 1; } +/* Fullscrolling helper function. Returns TRUE if a refresh is needed due to scrolling. */ +bool fullsc_update(void) +{ + size_t xtemp = xplustabs(), scroll_dist = 1; + bool lscrolled = FALSE, rscrolled = FALSE; + if (ISSET(JUMPY_SCROLLING)) + scroll_dist = 8; + /* Scroll until the cursor is on-screen. */ + while (TRUE) { + if (xtemp >= fullsc_pos + editwincols - 2) { + rscrolled = TRUE; + fullsc_pos += scroll_dist; + } + else if (xtemp < fullsc_pos + 2 && fullsc_pos >= scroll_dist) { + lscrolled = TRUE; + fullsc_pos -= scroll_dist; + } + else + break; + /* Prevent infinite loop when screen is squished. */ + if (lscrolled && rscrolled) + break; + } + + /* Don't needlessly call this function again during the next refresh. */ + if (lscrolled || rscrolled) + fullsc_refresh_check = FALSE; + + return lscrolled || rscrolled; +} + /* Convert text into a string that can be displayed on screen. The caller * wants to display text starting with the given column, and extending for * at most span columns. column is zero-based, and span is one-based, so @@ -1787,6 +1820,22 @@ char *display_string(const char *text, size_t column, size_t span, size_t beyond = column + span; /* The column number just beyond the last shown character. */ + /* If fullscrolling is enabled, cull offscreen text. */ + if (isdata && ISSET(FULL_SCROLLING)) { + /* Is text offscreen? */ + if (fullsc_pos!=0 && fullsc_pos >= breadth(text)) { + /* Create blank string. */ + /* This has the side effect of the mark highlighting the + * entire line, which could be a good or bad thing. */ + size_t i; + for (i=0; i<allocsize-1; i++) + converted[i]=' '; + converted[i]='\0'; + has_more = FALSE; + return converted; + } + } + text += start_x; #ifndef NANO_TINY @@ -2518,7 +2567,10 @@ void place_the_cursor(void) #endif { row = openfile->current->lineno - openfile->edittop->lineno; - column -= get_page_start(column); + if (ISSET(FULL_SCROLLING)) + column -= fullsc_pos; + else + column -= get_page_start(column); } if (row < editwinrows) @@ -2838,14 +2890,17 @@ 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(FULL_SCROLLING)) + from_col = fullsc_pos; + 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); draw_row(row, converted, line, from_col); free(converted); - if (from_col > 0) { + if (from_col > 0 || (ISSET(FULL_SCROLLING) && fullsc_pos)) { wattron(midwin, hilite_attribute); mvwaddch(midwin, row, margin, '<'); wattroff(midwin, hilite_attribute); @@ -3086,6 +3141,12 @@ void edit_scroll(bool direction) wscrl(midwin, (direction == BACKWARD) ? -1 : 1); scrollok(midwin, FALSE); + /* If fullscrolling, and the page changed, refresh. */ + if (ISSET(FULL_SCROLLING) && fullsc_update()) { + refresh_needed = TRUE; + return; + } + /* If we're not on the first "page" (when not softwrapping), or the mark * is on, the row next to the scrolled region needs to be redrawn too. */ if (line_needs_update(openfile->placewewant, 0) && nrows < editwinrows) @@ -3344,6 +3405,12 @@ void edit_redraw(linestruct *old_current, update_type manner) return; } + /* If fullscrolling, and the page changed, refresh. */ + if (ISSET(FULL_SCROLLING) && fullsc_update()) { + refresh_needed = TRUE; + return; + } + #ifndef NANO_TINY /* If the mark is on, update all lines between old_current and current. */ if (openfile->mark) { @@ -3358,8 +3425,10 @@ void edit_redraw(linestruct *old_current, update_type manner) } else #endif /* Otherwise, update old_current only if it differs from current - * and was horizontally scrolled. */ - if (old_current != openfile->current && get_page_start(was_pww) > 0) + * and was horizontally scrolled. When fullscrolling, there's no + * reason to do this. */ + if (old_current != openfile->current && (get_page_start(was_pww) > 0 + && !ISSET(FULL_SCROLLING))) update_line(old_current, 0); /* Update current if the mark is on or it has changed "page", or if it @@ -3396,6 +3465,11 @@ void edit_refresh(void) } #endif + /* If refresh was not caused by a manual fullsc_update() call, call now. */ + if (ISSET(FULL_SCROLLING) && fullsc_refresh_check) + fullsc_update(); + fullsc_refresh_check = TRUE; + #ifndef NANO_TINY if (sidebar) draw_scrollbar(); -- 2.52.0