From 2ed225f78d94856f183512d03b42da7c2de8b797 Mon Sep 17 00:00:00 2001 From: David Lawrence Ramsey Date: Fri, 28 May 2004 20:44:09 +0000 Subject: [PATCH] overhaul the routines for movement and related things to eliminate unneeded screen redraws git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1774 35c25a1d-7b9e-4130-9fde-d3aeb78583b8 --- ChangeLog | 16 ++++++ src/global.c | 4 +- src/move.c | 155 +++++++++++++++++++++++++++++++++------------------ src/nano.c | 72 ++++++++++++++++-------- src/nano.h | 4 ++ src/proto.h | 10 +++- src/search.c | 32 +++++++---- src/winio.c | 134 +++++++++++++++++++++++++++++++++++++++++++- 8 files changed, 332 insertions(+), 95 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5273868e..83795fd8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -76,6 +76,21 @@ CVS code - to do_verbatim_input(), handle_sigwinch(), get_kbinput(), get_ascii_kbinput(), get_escape_seq_kbinput(), and get_verbatim_kbinput(). (DLR) + - Overhaul all the movement functions in order to avoid + redundant screen redraws (and regexec()s when color support is + available) whenever possible during ordinary cursor movement + when the text doesn't change. Do the same for moving in + do_char(), do_delete(), do_next_word(), do_prev_word(), + do_search(), do_research(), and do_replace_loop. Changes to + do_first_line(), do_last_line(), do_home(), do_end(), + do_page_up(), do_page_down(), do_up(), do_down(), do_left(), + do_right(), do_delete(), do_backspace(), do_search(), + do_research(), do_replace_loop(), do_find_bracket(), and + edit_refresh(). New functions do_left_void(), + do_right_void(), need_horizontal_update(), + need_vertical_update(), edit_scroll(), and edit_redraw(). + Also rename the int refresh in do_delete() and do_backspace() + to do_refresh so as not to conflict with refresh(). (DLR) - files.c: add_open_file() - Rearrange the NANO_SMALL #ifdef so that the code to set the @@ -196,6 +211,7 @@ CVS code - - Since REGEXP_COMPILED is only used in search.c, convert it from a flag to a static int there. (DLR) - Add justbegend enum, used in do_para_search(). (DLR) + - Add updown enum, used in edit_scroll(). (DLR) - proto.h: - Remove unused xpt() and add_marked_sameline() prototypes. (DLR) diff --git a/src/global.c b/src/global.c index 445b87d8..fbe3e823 100644 --- a/src/global.c +++ b/src/global.c @@ -557,11 +557,11 @@ void shortcut_init(int unjustify) sc_init_one(&main_list, NANO_FORWARD_KEY, _("Forward"), IFHELP(nano_forward_msg, NANO_NO_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, do_right); + NANO_NO_KEY, VIEW, do_right_void); sc_init_one(&main_list, NANO_BACK_KEY, _("Back"), IFHELP(nano_back_msg, NANO_NO_KEY), NANO_NO_KEY, - NANO_NO_KEY, VIEW, do_left); + NANO_NO_KEY, VIEW, do_left_void); sc_init_one(&main_list, NANO_HOME_KEY, _("Home"), IFHELP(nano_home_msg, NANO_NO_KEY), NANO_NO_KEY, diff --git a/src/move.c b/src/move.c index ac1e7a7a..77365b18 100644 --- a/src/move.c +++ b/src/move.c @@ -30,24 +30,30 @@ int do_first_line(void) { + int old_pww = placewewant; current = fileage; placewewant = 0; current_x = 0; - edit_update(current, TOP); + if (edittop != fileage || need_vertical_update(old_pww)) + edit_update(current, TOP); return 1; } int do_last_line(void) { + int old_pww = placewewant; current = filebot; placewewant = 0; current_x = 0; - edit_update(current, CENTER); + if (edittop->lineno + (editwinrows / 2) != filebot->lineno || + need_vertical_update(old_pww)) + edit_update(current, CENTER); return 1; } int do_home(void) { + int old_pww = placewewant; #ifndef NANO_SMALL if (ISSET(SMART_HOME)) { int old_current_x = current_x; @@ -68,58 +74,66 @@ int do_home(void) } #endif check_statblank(); - update_line(current, current_x); + if (need_horizontal_update(old_pww)) + update_line(current, current_x); return 1; } int do_end(void) { + int old_pww = placewewant; current_x = strlen(current->data); placewewant = xplustabs(); check_statblank(); - update_line(current, current_x); + if (need_horizontal_update(old_pww)) + update_line(current, current_x); return 1; } int do_page_up(void) { - int i; - + int new_pww = placewewant; + const filestruct *old_current = current; #ifndef DISABLE_WRAPPING wrap_reset(); #endif - /* If edittop is the first line of the file, move current up there + /* If the first line of the file is onscreen, move current up there * and put the cursor at the beginning of the line. */ if (edittop == fileage) { current = fileage; - placewewant = 0; + new_pww = 0; } else { - /* Move the top line of the edit window up a page. */ - for (i = 0; i < editwinrows - 2 && edittop->prev != NULL; i++) - edittop = edittop->prev; + edit_scroll(UP, editwinrows - 2); + #ifndef NANO_SMALL - /* If we're in smooth scrolling mode and there was at least one + /* If we're in smooth scrolling mode and there's at least one * page of text left, move the current line of the edit window * up a page. */ - if (ISSET(SMOOTHSCROLL) && current->lineno > editwinrows - 2) + if (ISSET(SMOOTHSCROLL) && current->lineno > editwinrows - 2) { + int i; for (i = 0; i < editwinrows - 2; i++) current = current->prev; - /* If we're not in smooth scrolling mode and there was at least + } + /* If we're not in smooth scrolling mode or there isn't at least * one page of text left, put the cursor at the beginning of the * top line of the edit window, as Pico does. */ else { #endif current = edittop; - placewewant = 0; + new_pww = 0; #ifndef NANO_SMALL } #endif } + /* Get the equivalent x-coordinate of the new line. */ - current_x = actual_x(current->data, placewewant); + current_x = actual_x(current->data, new_pww); - edit_refresh(); + /* Update all the lines that need to be updated, and then set + * placewewant, so that the update will work properly. */ + edit_redraw(old_current); + placewewant = new_pww; check_statblank(); return 1; @@ -127,8 +141,8 @@ int do_page_up(void) int do_page_down(void) { - int i; - + int new_pww = placewewant; + const filestruct *old_current = current; #ifndef DISABLE_WRAPPING wrap_reset(); #endif @@ -137,33 +151,39 @@ int do_page_down(void) * there and put the cursor at the beginning of the line. */ if (edittop->lineno + editwinrows > filebot->lineno) { current = filebot; - placewewant = 0; + new_pww = 0; } else { - /* Move the top line of the edit window down a page. */ - for (i = 0; i < editwinrows - 2; i++) - edittop = edittop->next; + edit_scroll(DOWN, editwinrows - 2); + #ifndef NANO_SMALL - /* If we're in smooth scrolling mode and there was at least one + /* If we're in smooth scrolling mode and there's at least one * page of text left, move the current line of the edit window * down a page. */ - if (ISSET(SMOOTHSCROLL) && current->lineno + editwinrows - 2 <= filebot->lineno) + if (ISSET(SMOOTHSCROLL) && current->lineno + editwinrows - 2 <= + filebot->lineno) { + int i; for (i = 0; i < editwinrows - 2; i++) current = current->next; - /* If we're not in smooth scrolling mode and there was at least + } + /* If we're not in smooth scrolling mode or there isn't at least * one page of text left, put the cursor at the beginning of the * top line of the edit window, as Pico does. */ else { #endif current = edittop; - placewewant = 0; + new_pww = 0; #ifndef NANO_SMALL } #endif } + /* Get the equivalent x-coordinate of the new line. */ - current_x = actual_x(current->data, placewewant); + current_x = actual_x(current->data, new_pww); - edit_refresh(); + /* Update all the lines that need to be updated, and then set + * placewewant, so that the update will work properly. */ + edit_redraw(old_current); + placewewant = new_pww; check_statblank(); return 1; @@ -182,18 +202,25 @@ int do_up(void) assert(current_y == current->lineno - edittop->lineno); current = current->prev; current_x = actual_x(current->data, placewewant); - if (current_y > 0) { - update_line(current->next, 0); - /* It was necessary to change current first, so that the - * mark display will change! */ - update_line(current, current_x); - } else + + /* If we're on the first row of the edit window, scroll up one line + * if we're in smooth scrolling mode, or up half a page if we're + * not. */ + if (current_y == 0) + edit_scroll(UP, #ifndef NANO_SMALL - if (ISSET(SMOOTHSCROLL)) - edit_update(current, TOP); - else + ISSET(SMOOTHSCROLL) ? 1 : #endif - edit_update(current, CENTER); + editwinrows / 2); + + /* Update the lines left alone by edit_scroll(): the line we were on + * before and the line we're on now. The former needs to be redrawn + * if we're not on the first page, and the latter needs to be + * drawn. */ + if (need_vertical_update(0)) + update_line(current->next, 0); + update_line(current, current_x); + return 1; } @@ -213,25 +240,30 @@ int do_down(void) current = current->next; current_x = actual_x(current->data, placewewant); - /* Note that current_y is zero-based. This test checks for the - * cursor's being not on the last row of the edit window. */ - if (current_y != editwinrows - 1) { - update_line(current->prev, 0); - update_line(current, current_x); - } else + /* If we're on the last row of the edit window, scroll down one line + * if we're in smooth scrolling mode, or down half a page if we're + * not. */ + if (current_y == editwinrows - 1) + edit_scroll(DOWN, #ifndef NANO_SMALL - if (ISSET(SMOOTHSCROLL)) - /* In this case current_y does not change. The cursor remains - * at the bottom of the edit window. */ - edit_update(edittop->next, TOP); - else + ISSET(SMOOTHSCROLL) ? 1 : #endif - edit_update(current, CENTER); + editwinrows / 2); + + /* Update the lines left alone by edit_scroll(): the line we were on + * before and the line we're on now. The former needs to be redrawn + * if we're not on the first page, and the latter needs to be + * drawn. */ + if (need_vertical_update(0)) + update_line(current->prev, 0); + update_line(current, current_x); + return 1; } -int do_left(void) +int do_left(int allow_update) { + int old_pww = placewewant; if (current_x > 0) current_x--; else if (current != fileage) { @@ -240,12 +272,19 @@ int do_left(void) } placewewant = xplustabs(); check_statblank(); - update_line(current, current_x); + if (allow_update && need_horizontal_update(old_pww)) + update_line(current, current_x); return 1; } -int do_right(void) +int do_left_void(void) +{ + return do_left(TRUE); +} + +int do_right(int allow_update) { + int old_pww = placewewant; assert(current_x <= strlen(current->data)); if (current->data[current_x] != '\0') @@ -256,6 +295,12 @@ int do_right(void) } placewewant = xplustabs(); check_statblank(); - update_line(current, current_x); + if (allow_update && need_horizontal_update(old_pww)) + update_line(current, current_x); return 1; } + +int do_right_void(void) +{ + return do_right(TRUE); +} diff --git a/src/nano.c b/src/nano.c index 6e084bd9..1362890e 100644 --- a/src/nano.c +++ b/src/nano.c @@ -928,8 +928,8 @@ void do_char(char ch) { size_t current_len = strlen(current->data); #if !defined(DISABLE_WRAPPING) || defined(ENABLE_COLOR) - int refresh = FALSE; - /* Do we have to run edit_refresh(), or can we get away with + int do_refresh = FALSE; + /* Do we have to call edit_refresh(), or can we get away with * update_line()? */ #endif @@ -962,22 +962,27 @@ void do_char(char ch) mark_beginx++; #endif - do_right(); + do_right(FALSE); #ifndef DISABLE_WRAPPING + /* If we're wrapping text, we need to call edit_refresh(). */ if (!ISSET(NO_WRAP) && ch != '\t') - refresh = do_wrap(current); + do_refresh = do_wrap(current); #endif #ifdef ENABLE_COLOR + /* If color syntaxes are turned on, we need to call + * edit_refresh(). */ if (ISSET(COLOR_SYNTAX)) - refresh = TRUE; + do_refresh = TRUE; #endif #if !defined(DISABLE_WRAPPING) || defined(ENABLE_COLOR) - if (refresh) + if (do_refresh) edit_refresh(); + else #endif + update_line(current, current_x); } int do_verbatim_input(void) @@ -1006,7 +1011,7 @@ int do_verbatim_input(void) int do_backspace(void) { if (current != fileage || current_x > 0) { - do_left(); + do_left(FALSE); do_delete(); } return 1; @@ -1014,6 +1019,10 @@ int do_backspace(void) int do_delete(void) { + int do_refresh = FALSE; + /* Do we have to call edit_refresh(), or can we get away with + * update_line()? */ + assert(current != NULL && current->data != NULL && current_x <= strlen(current->data)); @@ -1040,6 +1049,12 @@ int do_delete(void) filestruct *foo = current->next; assert(current_x == strlen(current->data)); + + /* If we're deleting at the end of a line, we need to call + * edit_refresh(). */ + if (current->data[current_x] == '\0') + do_refresh = TRUE; + current->data = charealloc(current->data, current_x + strlen(foo->data) + 1); strcpy(current->data + current_x, foo->data); @@ -1062,7 +1077,19 @@ int do_delete(void) totsize--; set_modified(); - edit_refresh(); + +#ifdef ENABLE_COLOR + /* If color syntaxes are turned on, we need to call + * edit_refresh(). */ + if (ISSET(COLOR_SYNTAX)) + do_refresh = TRUE; +#endif + + if (do_refresh) + edit_refresh(); + else + update_line(current, current_x); + return 1; } @@ -1136,6 +1163,7 @@ int do_enter(void) #ifndef NANO_SMALL int do_next_word(void) { + const filestruct *current_save = current; assert(current != NULL && current->data != NULL); /* Skip letters in this word first. */ @@ -1160,7 +1188,7 @@ int do_next_word(void) /* Refresh the screen. If current has run off the bottom, this * call puts it at the center line. */ - edit_refresh(); + edit_redraw(current_save); return 0; } @@ -1168,6 +1196,7 @@ int do_next_word(void) /* The same thing for backwards. */ int do_prev_word(void) { + const filestruct *current_save = current; assert(current != NULL && current->data != NULL); /* Skip letters in this word first. */ @@ -1197,7 +1226,7 @@ int do_prev_word(void) /* Refresh the screen. If current has run off the top, this call * puts it at the center line. */ - edit_refresh(); + edit_redraw(current_save); return 0; } @@ -1429,8 +1458,8 @@ int do_int_spell_fix(const char *word) { char *save_search; char *save_replace; - filestruct *current_save = current; size_t current_x_save = current_x; + filestruct *current_save = current; filestruct *edittop_save = edittop; /* Save where we are. */ int i = 0; @@ -2131,19 +2160,16 @@ int break_line(const char *line, int goal, int force) int do_para_search(justbegend search_type, size_t *quote, size_t *par, size_t *indent, int do_refresh) { + const filestruct *current_save = current; size_t quote_len; /* Length of the initial quotation of the paragraph we * search. */ size_t par_len; /* Number of lines in that paragraph. */ - - /* We save this global variable to see if we're where we started - * when searching for the beginning of the paragraph. */ - filestruct *current_save = current; - - size_t indent_len; /* Generic indentation length. */ - filestruct *line; /* Generic line of text. */ - + size_t indent_len; + /* Generic indentation length. */ + filestruct *line; + /* Generic line of text. */ static int do_restart = 1; /* Whether we're restarting when searching for the beginning * line of the paragraph. */ @@ -2209,7 +2235,7 @@ int do_para_search(justbegend search_type, size_t *quote, size_t *par, if (current->prev == NULL) { placewewant = 0; if (do_refresh) - edit_refresh(); + edit_redraw(current_save); #ifdef HAVE_REGEX_H if (!do_restart) regfree(&qreg); @@ -2230,7 +2256,7 @@ int do_para_search(justbegend search_type, size_t *quote, size_t *par, if (current->next == NULL) { placewewant = 0; if (do_refresh) - edit_refresh(); + edit_redraw(current_save); #ifdef HAVE_REGEX_H regfree(&qreg); #endif @@ -2321,7 +2347,7 @@ int do_para_search(justbegend search_type, size_t *quote, size_t *par, /* Refresh the screen if needed. */ if (do_refresh) - edit_refresh(); + edit_redraw(current_save); /* Save the values of quote_len, par_len, and indent_len if * needed. */ @@ -2368,9 +2394,9 @@ int do_justify(int full_justify) * unjustifies. Note we don't need to save totlines. */ int current_x_save = current_x; int current_y_save = current_y; - filestruct *current_save = current; int flags_save = flags; long totsize_save = totsize; + filestruct *current_save = current; filestruct *edittop_save = edittop; #ifndef NANO_SMALL filestruct *mark_beginbuf_save = mark_beginbuf; diff --git a/src/nano.h b/src/nano.h index 096bdb95..f727ab71 100644 --- a/src/nano.h +++ b/src/nano.h @@ -463,6 +463,10 @@ typedef enum { JUSTIFY, BEGIN, END } justbegend; +typedef enum { + UP, DOWN +} updown; + typedef enum { TOP, CENTER, NONE } topmidnone; diff --git a/src/proto.h b/src/proto.h index 1c7b8fe4..f6cf80af 100644 --- a/src/proto.h +++ b/src/proto.h @@ -240,8 +240,10 @@ int do_page_up(void); int do_page_down(void); int do_up(void); int do_down(void); -int do_left(void); -int do_right(void); +int do_left(int allow_update); +int do_left_void(void); +int do_right(int allow_update); +int do_right_void(void); /* Public functions in nano.c */ void finish(void); @@ -528,6 +530,10 @@ void reset_cursor(void); void edit_add(const filestruct *fileptr, const char *converted, int yval, size_t start); void update_line(const filestruct *fileptr, size_t index); +int need_horizontal_update(int old_placewewant); +int need_vertical_update(int old_placewewant); +void edit_scroll(updown direction, int nlines); +void edit_redraw(const filestruct *old_current); void edit_refresh(void); void edit_update(filestruct *fileptr, topmidnone location); int statusq(int allowtabs, const shortcut *s, const char *def, diff --git a/src/search.c b/src/search.c index f0d187f4..15341fd7 100644 --- a/src/search.c +++ b/src/search.c @@ -354,9 +354,8 @@ int findnextstr(int can_display_wrap, int wholeword, const filestruct /* Search for a string. */ int do_search(void) { - int i; + int i, fileptr_x = current_x, didfind; filestruct *fileptr = current; - int fileptr_x = current_x, didfind; #ifndef DISABLE_WRAPPING wrap_reset(); @@ -391,8 +390,6 @@ int do_search(void) search_last_line = FALSE; didfind = findnextstr(TRUE, FALSE, current, current_x, answer, FALSE); - edit_refresh(); - placewewant = xplustabs(); /* Check to see if there's only one occurrence of the string and * we're on it now. */ @@ -415,6 +412,8 @@ int do_search(void) #endif } + edit_redraw(fileptr); + placewewant = xplustabs(); search_abort(); return 1; @@ -424,8 +423,8 @@ int do_search(void) /* Search for the next string without prompting. */ int do_research(void) { - filestruct *fileptr = current; int fileptr_x = current_x, didfind; + filestruct *fileptr = current; #ifndef DISABLE_WRAPPING wrap_reset(); @@ -442,8 +441,6 @@ int do_research(void) search_last_line = FALSE; didfind = findnextstr(TRUE, FALSE, current, current_x, last_search, FALSE); - edit_refresh(); - placewewant = xplustabs(); /* Check to see if there's only one occurrence of the string and * we're on it now. */ @@ -468,6 +465,8 @@ int do_research(void) } else statusbar(_("No current search pattern")); + edit_redraw(fileptr); + placewewant = xplustabs(); search_abort(); return 1; @@ -582,8 +581,8 @@ int do_replace_loop(const char *needle, const filestruct *real_current, size_t *real_current_x, int wholewords) { int replaceall = 0, numreplaced = -1; - const filestruct *current_save = current; size_t current_x_save = current_x; + const filestruct *current_save = current; #ifdef HAVE_REGEX_H /* The starting-line match and bol/eol regex flags. */ int begin_line = FALSE, bol_or_eol = FALSE; @@ -628,7 +627,8 @@ int do_replace_loop(const char *needle, const filestruct *real_current, } #endif - edit_refresh(); + if (!replaceall) + edit_redraw(current_save); #ifdef HAVE_REGEX_H if (ISSET(USE_REGEXP)) @@ -709,7 +709,15 @@ int do_replace_loop(const char *needle, const filestruct *real_current, free(current->data); current->data = copy; - edit_refresh(); + if (!replaceall) { +#ifdef ENABLE_COLOR + if (ISSET(COLOR_SYNTAX)) + edit_refresh(); + else +#endif + update_line(current, current_x); + } + set_modified(); numreplaced++; } @@ -890,7 +898,7 @@ int do_find_bracket(void) char ch_under_cursor, wanted_ch; const char *pos, *brackets = "([{<>}])"; char regexp_pat[] = "[ ]"; - int flagsave, current_x_save, count = 1; + int current_x_save, flagsave, count = 1; filestruct *current_save; ch_under_cursor = current->data[current_x]; @@ -934,7 +942,7 @@ int do_find_bracket(void) count++; /* Found complementary bracket. */ else if (--count == 0) { - edit_refresh(); + edit_redraw(current_save); placewewant = xplustabs(); break; } diff --git a/src/winio.c b/src/winio.c index 76cbc39d..ab0d0dd1 100644 --- a/src/winio.c +++ b/src/winio.c @@ -2483,6 +2483,138 @@ void update_line(const filestruct *fileptr, size_t index) mvwaddch(edit, line, COLS - 1, '$'); } +/* Return a nonzero value if we need an update after moving + * horizontally. We need one if the mark is on or if old_pww and + * placewewant are on different pages. Assume none of the text has + * changed since the last update. */ +int need_horizontal_update(int old_pww) +{ + return +#ifndef NANO_SMALL + ISSET(MARK_ISSET) || +#endif + get_page_start(old_pww) != get_page_start(placewewant); +} + +/* Return a nonzero value if we need an update after moving vertically. + * We need one if the mark is on or if old_pww and placewewant + * are on different pages. Assume none of the text has changed since + * the last update. */ +int need_vertical_update(int old_pww) +{ + return +#ifndef NANO_SMALL + ISSET(MARK_ISSET) || +#endif + get_page_start(old_pww) != get_page_start(placewewant); +} + +/* Scroll the edit window in the given direction and the given number + * of lines, and draw new lines on the blank lines left after the + * scrolling. direction is the direction to scroll, either UP or DOWN, + * and nlines is the number of lines to scroll. Don't redraw the old + * topmost or bottommost line (where we assume current is) before + * scrolling or draw the new topmost or bottommost line after scrolling + * (where we assume current will be), since we don't know where we are + * on the page or whether we'll stay there. Assume none of the text has + * changed since the last update. */ +void edit_scroll(updown direction, int nlines) +{ + filestruct *foo; + int i, scroll_rows = 0; + + /* Scrolling less than one line or more than editwinrows lines is + * redundant, so don't allow it. */ + if (nlines < 1 || nlines > editwinrows) + return; + + /* Move the top line of the edit window up or down (depending on the + * value of direction) nlines lines. If there are fewer lines of + * text than that left, move it to the top or bottom line of the + * file (depending on the value of direction). Keep track of + * how many lines we moved in scroll_rows. */ + for (i = nlines; i > 0; i--) { + if (direction == UP) { + if (edittop->prev == NULL) + break; + edittop = edittop->prev; + scroll_rows--; + } else { + if (edittop->next == NULL) + break; + edittop = edittop->next; + scroll_rows++; + } + } + + /* Scroll the text on the screen up or down scroll_rows lines, + * depending on the value of direction. */ + scrollok(edit, TRUE); + wscrl(edit, scroll_rows); + scrollok(edit, FALSE); + + foo = edittop; + if (direction != UP) { + int slines = editwinrows - nlines; + for (; slines > 0 && foo != NULL; slines--) + foo = foo->next; + } + + /* And draw new lines on the blank top or bottom lines of the edit + * window, depending on the value of direction. Don't draw the new + * topmost or new bottommost line. */ + while (scroll_rows != 0 && foo != NULL) { + if (foo->next != NULL) + update_line(foo, 0); + if (direction == UP) + scroll_rows++; + else + scroll_rows--; + foo = foo->next; + } +} + +/* Update any lines between old_current and current that need to be + * updated. Note that we use placewewant to determine whether we need + * updates and current_x to update current, so if placewewant needs to + * be changed, it should be changed after calling this, and if current_x + * needs to be changed, it should be changed before calling this. + * Assume none of the text has changed since the last update. */ +void edit_redraw(const filestruct *old_current) +{ + int do_refresh = need_vertical_update(0); + const filestruct *foo; + + /* If either old_current or current is offscreen, refresh the screen + * and get out. */ + if (old_current->lineno < edittop->lineno || old_current->lineno >= + edittop->lineno + editwinrows || current->lineno < + edittop->lineno || current->lineno >= edittop->lineno + + editwinrows) { + edit_refresh(); + return; + } + + /* Update old_current and current if we're not on the first page. + * If the mark is on, update all the lines between old_current and + * current too. */ + foo = old_current; + while (foo != current) { + if (do_refresh) + update_line(foo, 0); +#ifndef NANO_SMALL + if (!ISSET(MARK_ISSET)) +#endif + break; + if (foo->lineno > current->lineno) + foo = foo->prev; + else + foo = foo->next; + } + if (do_refresh) + update_line(current, current_x); +} + /* Refresh the screen without changing the position of lines. */ void edit_refresh(void) { @@ -2510,7 +2642,7 @@ void edit_refresh(void) #endif while (nlines < editwinrows) { - update_line(foo, current_x); + update_line(foo, (foo == current) ? current_x : 0); nlines++; if (foo->next == NULL) break; -- 2.39.5