From 1939c3590b74b88920e1037f18c8c8319d5cd738 Mon Sep 17 00:00:00 2001
From: Chris Allegretta <chrisa@asty.org>
Date: Sun, 26 Jan 2003 04:26:25 +0000
Subject: [PATCH] - search.c:do_replace_loop() - Fix various bugs having to do
 with replace string length and positioning (David Benbennick)

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1392 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
---
 ChangeLog |  4 ++++
 search.c  | 62 +++++++++++++++++++++++++++++++------------------------
 2 files changed, 39 insertions(+), 27 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 6803a3df..fe783bc6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -24,6 +24,10 @@ CVS Code -
 	- Revamp -H option message to fit in 80 column terminal.
   window_init()
 	- Fix leaking *WINDOWs (no pun intended) (David Benbennick).
+- search.c:
+  do_replace_loop()
+	- Fix various bugs having to do with replace string length
+	  and positioning (David Benbennick).
 - winio.c:
   bottombars()
 	- Change strcpy of gettext() "Up" string to strncpy of max
diff --git a/search.c b/search.c
index cd1ed793..71415649 100644
--- a/search.c
+++ b/search.c
@@ -597,6 +597,9 @@ int do_replace_loop(const char *prevanswer, const filestruct *begin,
 	}
 
 	if (*i > 0 || replaceall) {	/* Yes, replace it!!!! */
+	    long length_change;
+	    size_t match_len;
+
 	    if (*i == 2)
 		replaceall = 1;
 
@@ -607,38 +610,43 @@ int do_replace_loop(const char *prevanswer, const filestruct *begin,
 		return 0;
 	    }
 
-	    /* Cleanup */
-	    totsize -= strlen(current->data);
-	    free(current->data);
-	    current->data = copy;
-	    totsize += strlen(current->data);
-
-	    if (!ISSET(REVERSE_SEARCH)) {
-		/* Stop bug where we replace a substring of the
-		   replacement text */
-		current_x += strlen(last_replace) - 1;
+	    length_change = strlen(copy) - strlen(current->data);
 
-		/* Adjust the original cursor position - COULD BE IMPROVED */
-		if (search_last_line) {
-		    *beginx += strlen(last_replace) - strlen(last_search);
+#ifdef HAVE_REGEX_H
+	    if (ISSET(USE_REGEXP))
+		match_len = regmatches[0].rm_eo - regmatches[0].rm_so;
+	    else
+#endif
+		match_len = strlen(prevanswer);
 
-		    /* For strings that cross the search start/end boundary */
+#ifndef NANO_SMALL
+	    if (current == mark_beginbuf && mark_beginx > current_x) {
+		if (mark_beginx < current_x + match_len)
+		    mark_beginx = current_x;
+		else
+		    mark_beginx += length_change;
+	    }
+#endif
 
-		    /* Don't go outside of allocated memory */
-		    if (*beginx < 1)
-			*beginx = 1;
-		}
-	    } else {
-		if (current_x > 1)
-		    current_x--;
+	    assert(0 <= match_len + length_change);
+	    if (current == begin && current_x <= *beginx) {
+		if (*beginx < current_x + match_len)
+		    *beginx = current_x + match_len;
+		*beginx += length_change;
+	    }
 
-		if (search_last_line) {
-		    *beginx += strlen(last_replace) - strlen(last_search);
+	    /* Set the cursor at the last character of the replacement
+	     * text, so searching will resume after the replacement text.
+	     * Note that current_x might be set to -1 here. */
+#ifndef NANO_SMALL
+	    if (!ISSET(REVERSE_SEARCH))
+#endif
+		current_x += match_len + length_change - 1;
 
-		    if (*beginx > strlen(current->data))
-			*beginx = strlen(current->data);
-		}
-	    }
+	    /* Cleanup */
+	    totsize += length_change;
+	    free(current->data);
+	    current->data = copy;
 
 	    edit_refresh();
 	    set_modified();
-- 
GitLab