From dc25802acc6e9d75fa8c3a246fa8c510b0f6bca2 Mon Sep 17 00:00:00 2001 From: Benno Schulenberg Date: Mon, 27 Apr 2020 12:05:26 +0200 Subject: [PATCH 1/2] possible new feature: a position+portion indicator on the righthand side MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit V2: Use an array to remember what character plus attribute each scrollbar cell should contain. V3: Do not use A_DIM as it does not work with a light background. And remove a no-longer-needed updating of the scroll bar. [This scrollbar is optionless for the moment, for ease of testing.] [The scrollbar is suppressed in softwrap mode, because it costs too much computation to determine the total number of chunks, and the number of displayed chunks is known only after the screen is fully drawn, not while drawing it.] This fulfills https://savannah.gnu.org/bugs/?57956. Original-patch-by: Marco Diego Aurélio Mesquita --- src/global.c | 4 ++++ src/help.c | 10 +++++----- src/nano.c | 21 +++++++++++++++++---- src/proto.h | 2 ++ src/winio.c | 33 +++++++++++++++++++++++++++++++-- 5 files changed, 59 insertions(+), 11 deletions(-) diff --git a/src/global.c b/src/global.c index 84103d26..0138ee80 100644 --- a/src/global.c +++ b/src/global.c @@ -131,7 +131,11 @@ int editwincols = -1; /* The number of usable columns in the edit window: COLS - margin. */ int margin = 0; /* The amount of space reserved at the left for line numbers. */ +int thebar = 0; + /* Becomes 1 when a scrollbar is shown. */ #ifndef NANO_TINY +int *bardata = NULL; + /* An array of characters that together depict the scrollbar. */ ssize_t stripe_column = 0; /* The column at which a vertical bar will be drawn. */ #endif diff --git a/src/help.c b/src/help.c index c6fbc003..359f5fc0 100644 --- a/src/help.c +++ b/src/help.c @@ -44,7 +44,7 @@ void wrap_help_text_into_buffer(void) { size_t sum = 0; /* Avoid overtight and overwide paragraphs in the introductory text. */ - size_t wrapping_point = (COLS < 40) ? 40 : (COLS > 74) ? 74 : COLS; + size_t wrapping_point = ((COLS < 40) ? 40 : (COLS > 74) ? 74 : COLS) - thebar; const char *ptr = start_of_body; make_new_buffer(); @@ -55,7 +55,7 @@ void wrap_help_text_into_buffer(void) char *oneline; if (ptr == end_of_intro) - wrapping_point = (COLS < 40) ? 40 : COLS; + wrapping_point = ((COLS < 40) ? 40 : COLS) - thebar; if (ptr < end_of_intro || *(ptr - 1) == '\n') { length = break_line(ptr, wrapping_point, TRUE); @@ -63,7 +63,7 @@ void wrap_help_text_into_buffer(void) shim = (*(ptr + length - 1) == ' ') ? 0 : 1; snprintf(oneline, length + shim, "%s", ptr); } else { - length = break_line(ptr, (COLS < 40) ? 22 : COLS - 18, TRUE); + length = break_line(ptr, ((COLS < 40) ? 22 : COLS - 18) - thebar, TRUE); oneline = nmalloc(length + 5); snprintf(oneline, length + 5, "\t\t %s", ptr); } @@ -145,7 +145,7 @@ void show_help(void) #ifdef ENABLE_LINENUMBERS UNSET(LINE_NUMBERS); - editwincols = COLS; + editwincols = COLS - thebar; margin = 0; #endif tabsize = 8; @@ -250,7 +250,7 @@ void show_help(void) #ifdef ENABLE_LINENUMBERS margin = was_margin; - editwincols = COLS - margin; + editwincols = COLS - margin - thebar; #endif tabsize = was_tabsize; #ifdef ENABLE_COLOR diff --git a/src/nano.c b/src/nano.c index fa18d9f5..5ede45bb 100644 --- a/src/nano.c +++ b/src/nano.c @@ -1041,7 +1041,11 @@ void regenerate_screen(void) COLS = win.ws_col; LINES = win.ws_row; #endif - editwincols = COLS - margin; +#ifndef NANO_TINY + thebar = (LINES > 5 && COLS > 9 && !ISSET(SOFTWRAP)) ? 1 : 0; + bardata = nrealloc(bardata, LINES * sizeof(int)); +#endif + editwincols = COLS - margin - thebar; /* Ensure that firstcolumn is the starting column of its chunk. */ ensure_firstcolumn_is_aligned(); @@ -1082,8 +1086,13 @@ void do_toggle(int flag) signal_init(); break; case SOFTWRAP: - if (!ISSET(SOFTWRAP)) + if (!ISSET(SOFTWRAP)) { + thebar = (LINES > 5 && COLS > 9) ? 1 : 0; + bardata = nrealloc(bardata, LINES * sizeof(int)); openfile->firstcolumn = 0; + } else + thebar = 0; + editwincols = COLS - margin - thebar; refresh_needed = TRUE; break; case WHITESPACE_DISPLAY: @@ -1246,7 +1255,7 @@ void confirm_margin(void) if (needed_margin != margin) { margin = needed_margin; - editwincols = COLS - margin; + editwincols = COLS - margin - thebar; #ifndef NANO_TINY /* Ensure that firstcolumn is the starting column of its chunk. */ @@ -2279,7 +2288,11 @@ int main(int argc, char **argv) window_init(); curs_set(0); - editwincols = COLS; +#ifndef NANO_TINY + thebar = (LINES > 5 && COLS > 9 && !ISSET(SOFTWRAP)) ? 1 : 0; + bardata = nrealloc(bardata, LINES * sizeof(int)); +#endif + editwincols = COLS - thebar; /* Set up the signal handlers. */ signal_init(); diff --git a/src/proto.h b/src/proto.h index f398bfe4..fe5b40d3 100644 --- a/src/proto.h +++ b/src/proto.h @@ -93,7 +93,9 @@ extern WINDOW *bottomwin; extern int editwinrows; extern int editwincols; extern int margin; +extern int thebar; #ifndef NANO_TINY +extern int *bardata; extern ssize_t stripe_column; #endif diff --git a/src/winio.c b/src/winio.c index d792d2a6..aae1b8bd 100644 --- a/src/winio.c +++ b/src/winio.c @@ -2412,6 +2412,9 @@ void draw_row(int row, const char *converted, linestruct *line, size_t from_col) if (is_shorter || ISSET(SOFTWRAP)) wclrtoeol(edit); + if (is_shorter && thebar) + mvwaddch(edit, row, COLS - 1, bardata[row]); + #ifdef USING_OLD_NCURSES /* Tell ncurses to really redraw the line without trying to optimize * for what it thinks is already there, because it gets it wrong in @@ -2780,7 +2783,7 @@ int update_line(linestruct *line, size_t index) } if (has_more) { wattron(edit, hilite_attribute); - mvwaddch(edit, row, COLS - 1, '>'); + mvwaddch(edit, row, COLS - 1 - thebar, '>'); wattroff(edit, hilite_attribute); } @@ -2960,6 +2963,24 @@ bool less_than_a_screenful(size_t was_lineno, size_t was_leftedge) return (openfile->current->lineno - was_lineno < editwinrows); } +#ifndef NANO_TINY +/* Draw a scroll bar on the righthand side of the screen. */ +void draw_scrollbar(void) +{ + int totalrows = openfile->filebot->lineno; + int lowest = ((openfile->edittop->lineno - 1) * editwinrows) / totalrows; + int highest = lowest + (editwinrows * editwinrows) / totalrows; + + if (editwinrows > totalrows) + highest = editwinrows; + + for (int row = 0; row < editwinrows; row++) { + bardata[row] = ' '|((row >= lowest && row <= highest) ? A_REVERSE : 0); + mvwaddch(edit, row, COLS - 1, bardata[row]); + } +} +#endif + /* Scroll the edit window one row in the given direction, and * draw the relevant content on the resultant blank row. */ void edit_scroll(bool direction) @@ -2993,6 +3014,9 @@ void edit_scroll(bool direction) go_forward_chunks(editwinrows - nrows, &line, &leftedge); #ifndef NANO_TINY + if (thebar) + draw_scrollbar(); + if (ISSET(SOFTWRAP)) { /* Compensate for the earlier chunks of a softwrapped line. */ nrows += chunk_for(leftedge, line); @@ -3280,6 +3304,11 @@ void edit_refresh(void) while (row < editwinrows) blank_row(edit, row++); +#ifndef NANO_TINY + if (thebar) + draw_scrollbar(); +#endif + place_the_cursor(); wnoutrefresh(edit); @@ -3426,7 +3455,7 @@ void spotlight(size_t from_col, size_t to_col) wattron(edit, interface_color_pair[SELECTED_TEXT]); waddnstr(edit, word, actual_x(word, to_col)); if (overshoots) - mvwaddch(edit, openfile->current_y, COLS - 1, '>'); + mvwaddch(edit, openfile->current_y, COLS - 1 - thebar, '>'); wattroff(edit, interface_color_pair[SELECTED_TEXT]); free(word); -- 2.17.1