From 08a52c1dab20c8e6ee74de3fdbd97c4f6fc624dc Mon Sep 17 00:00:00 2001 From: Benno Schulenberg Date: Sat, 11 Apr 2015 15:21:08 +0000 Subject: [PATCH] Not splitting off the marked region into a separate partition, but doing the replacings in situ in the current one, to fix an undo bug. git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@5189 35c25a1d-7b9e-4130-9fde-d3aeb78583b8 --- ChangeLog | 8 ++++++++ src/search.c | 53 +++++++++++++++++++++++++++++++++------------------- 2 files changed, 42 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3e1c0557..764d3f5f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2015-04-11 Benno Schulenberg + * src/search.c (do_replace_loop): Do not split off the marked region + into a separate partition, but do the replacings in the current one, + taking good care to stay within the boundaries of the region. This + fixes an undo bug where the first part of a line would disappear if + the region started in the middle of a line. Bug was reported here: + https://lists.gnu.org/archive/html/nano-devel/2015-03/msg00077.html. + 2015-04-08 Benno Schulenberg * src/browser.c (browser_select_dirname, findnextfile): Rename 'currselected' to 'looking_at', for more contrast with 'selected', diff --git a/src/search.c b/src/search.c index 4deca0b3..5c62cbd6 100644 --- a/src/search.c +++ b/src/search.c @@ -692,25 +692,26 @@ ssize_t do_replace_loop( #endif #ifndef NANO_TINY bool old_mark_set = openfile->mark_set; - filestruct *edittop_save = openfile->edittop, *top, *bot; + filestruct *top, *bot; size_t top_x, bot_x; bool right_side_up = FALSE; /* TRUE if (mark_begin, mark_begin_x) is the top of the mark, * FALSE if (current, current_x) is. */ if (old_mark_set) { - /* If the mark is on, partition the filestruct so that it - * contains only the marked text, set edittop to the top of the - * partition, turn the mark off, and refresh the screen. */ + /* If the mark is on, frame the region, and turn the mark off. */ mark_order((const filestruct **)&top, &top_x, (const filestruct **)&bot, &bot_x, &right_side_up); - filepart = partition_filestruct(top, top_x, bot, bot_x); - openfile->edittop = openfile->fileage; openfile->mark_set = FALSE; -#ifndef DISABLE_COLOR - reset_multis(openfile->current, TRUE); -#endif - edit_refresh(); + + /* Start either at the top or the bottom of the marked region. */ + if (!ISSET(BACKWARDS_SEARCH)) { + openfile->current = top; + openfile->current_x = (top_x == 0 ? 0 : top_x - 1); + } else { + openfile->current = bot; + openfile->current_x = bot_x; + } } #endif /* !NANO_TINY */ @@ -734,6 +735,18 @@ ssize_t do_replace_loop( , real_current, *real_current_x, needle, &match_len)) { int i = 0; +#ifndef NANO_TINY + if (old_mark_set) { + /* When we've found an occurrence outside of the marked region, + * stop the fanfare. */ + if (openfile->current->lineno > bot->lineno || + openfile->current->lineno < top->lineno || + (openfile->current == bot && openfile->current_x > bot_x) || + (openfile->current == top && openfile->current_x < top_x)) + break; + } +#endif + #ifdef HAVE_REGEX_H /* If the bol_or_eol flag is set, we've found a match on the * beginning line already, and we're still on the beginning line @@ -794,7 +807,7 @@ ssize_t do_replace_loop( size_t length_change; #ifndef NANO_TINY - update_undo(REPLACE); + add_undo(REPLACE); #endif if (i == 2) replaceall = TRUE; @@ -815,6 +828,7 @@ ssize_t do_replace_loop( openfile->mark_begin_x = openfile->current_x; else openfile->mark_begin_x += length_change; + bot_x = openfile->mark_begin_x; } } @@ -828,6 +842,7 @@ ssize_t do_replace_loop( if (*real_current_x < openfile->current_x + match_len) *real_current_x = openfile->current_x + match_len; *real_current_x += length_change; + bot_x = *real_current_x; } #ifndef NANO_TINY } @@ -849,7 +864,10 @@ ssize_t do_replace_loop( openfile->current->data = copy; #ifndef DISABLE_COLOR - reset_multis(openfile->current, TRUE); + /* Reset the precalculated multiline-regex hints only when + * the first replacement has been made. */ + if (numreplaced == 0) + reset_multis(openfile->current, TRUE); #endif if (!replaceall) { @@ -869,15 +887,12 @@ ssize_t do_replace_loop( } } + if (numreplaced == -1) + not_found_msg(needle); + #ifndef NANO_TINY - if (old_mark_set) { - /* If the mark was on, unpartition the filestruct so that it - * contains all the text again, set edittop back to what it was - * before, turn the mark back on, and refresh the screen. */ - unpartition_filestruct(&filepart); - openfile->edittop = edittop_save; + if (old_mark_set) openfile->mark_set = TRUE; - } #endif /* If the NO_NEWLINES flag isn't set, and text has been added to the