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>
master
Benno Schulenberg 2020-04-25 17:19:03 +02:00
parent d729edaeda
commit b33a62af8c
5 changed files with 60 additions and 12 deletions

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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);