nano

nano with my custom patches
git clone git://bsandro.tech/nano
Log | Files | Refs | README | LICENSE

commit b33a62af8ce8fe31a2689e896c5d64ff324c44f5
parent d729edaeda5f1bf3de395f5a13865649cd91357a
Author: Benno Schulenberg <bensberg@telfort.nl>
Date:   Sat, 25 Apr 2020 17:19:03 +0200

new feature: a position-plus-portion indicator on the righthand side

This displays a scrollbar-like thing on the right edge of the screen,
giving a rough indication where in the buffer the text that is being
shown in the viewport is located, and how large/small a portion of
the buffer this text is.

(Support for softwrapping, and an option to turn the indicator on,
will arrive in subsequent commits.)

This fulfills https://savannah.gnu.org/bugs/?57956.

Original-patch-by: Marco Diego Aurélio Mesquita <marcodiegomesquita@gmail.com>

Diffstat:
Msrc/global.c | 4++++
Msrc/help.c | 10+++++-----
Msrc/nano.c | 13++++++++++---
Msrc/proto.h | 2++
Msrc/winio.c | 43+++++++++++++++++++++++++++++++++++++++----
5 files changed, 60 insertions(+), 12 deletions(-)

diff --git a/src/global.c b/src/global.c @@ -134,7 +134,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 @@ -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 @@ -1039,7 +1039,10 @@ void regenerate_screen(void) COLS = win.ws_col; LINES = win.ws_row; #endif - editwincols = COLS - margin; + thebar = (LINES > 5 && COLS > 9) ? 1 : 0; + bardata = nrealloc(bardata, LINES * sizeof(int)); + + editwincols = COLS - margin - thebar; /* Do as the website suggests: leave and immediately reenter curses mode. */ endwin(); @@ -1246,7 +1249,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. */ @@ -2283,7 +2286,11 @@ int main(int argc, char **argv) window_init(); curs_set(0); - editwincols = COLS; +#ifndef NANO_TINY + thebar = (LINES > 5 && COLS > 9) ? 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 @@ -95,7 +95,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 @@ -2398,6 +2398,9 @@ void draw_row(int row, const char *converted, linestruct *line, size_t from_col) if (is_shorter || ISSET(SOFTWRAP)) wclrtoeol(edit); + if (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 @@ -2766,7 +2769,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); } @@ -2946,6 +2949,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) @@ -2979,6 +3000,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); @@ -3249,6 +3273,11 @@ void edit_refresh(void) if (current_is_offscreen()) adjust_viewport((focusing || ISSET(JUMPY_SCROLLING)) ? CENTERING : FLOWING); +#ifndef NANO_TINY + if (thebar) + draw_scrollbar(); +#endif + line = openfile->edittop; while (row < editwinrows && line != NULL) { @@ -3259,8 +3288,14 @@ void edit_refresh(void) line = line->next; } - while (row < editwinrows) - blank_row(edit, row++); + while (row < editwinrows) { + blank_row(edit, row); +#ifndef NANO_TINY + if (thebar) + mvwaddch(edit, row, COLS - 1, bardata[row]); +#endif + row++; + } place_the_cursor(); wnoutrefresh(edit); @@ -3407,7 +3442,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);