Commit: patch 9.2.0981: substitute: wrong text after undo of a confirmed \r

Christian Brabandt <[email protected]>
Newsgroups gmane.editors.vim.devel
Message-ID <[email protected]>
patch 9.2.0981: substitute: wrong text after undo of a confirmed 

Commit: https://github.com/vim/vim/commit/9647ccc020d0dee86b4b8cfcaf32ee7a36b17d6b
Author: Hirohito Higashi <[email protected]>
Date:   Wed Aug 19 20:21:57 2026 +0000

    patch 9.2.0981: substitute: wrong text after undo of a confirmed 
    
    Problem:  When a substitution is confirmed with the "c" flag and the
              replacement contains "
", undo restores the whole original line
              while the lines already produced by earlier replacements stay,
              duplicating text (Masato Nishihata).
    Solution: Replace the line before the next confirmation prompt, so that the
              line split and the replacement it belongs to end up in the same
              undo block (Hirohito Higashi).
    
    fixes:  #4798
    closes: #21092
    
    Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
    Signed-off-by: Hirohito Higashi <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index 6a1715a6b..20fcfb221 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -4417,6 +4417,7 @@ ex_substitute(exarg_T *eap)
 	    int		do_again;	// do it again after joining lines
 	    int		skip_match = FALSE;
 	    linenr_T	sub_firstlnum;	// nr of first sub line
+	    bool	did_split = false;	// "
" split the line
 #ifdef FEAT_PROP_POPUP
 	    int		apc_flags = APC_SAVE_FOR_UNDO | APC_SUBSTITUTE;
 	    colnr_T	total_added =  0;
@@ -5124,6 +5125,7 @@ ex_substitute(exarg_T *eap)
 			    ++sub_firstlnum;
 			    ++lnum;
 			    ++line2;
+			    did_split = true;
 			    // move the cursor to the new line, like Vi
 			    ++curwin->w_cursor.lnum;
 			    // copy the rest
@@ -5166,9 +5168,12 @@ skip:
 		 * match, otherwise "\@<=" won't work.
 		 * When the match starts below where we start searching also
 		 * need to replace the line first (using \zs after 
).
+		 * When asking, undo is synced at every match, so a line split
+		 * by "
" must be replaced in the same undo block.
 		 */
 		if (lastone
 			|| nmatch_tl > 0
+			|| (subflags.do_ask && did_split)
 			|| (nmatch = vim_regexec_multi(&regmatch, curwin,
 							curbuf, sub_firstlnum,
 						    matchcol, NULL)) == 0
@@ -5247,6 +5252,7 @@ skip:
 			prev_matchcol = (colnr_T)(sub_firstline.length
 							      - prev_matchcol);
 			copycol = 0;
+			did_split = false;
 		    }
 		    if (nmatch == -1 && !lastone)
 			nmatch = vim_regexec_multi(&regmatch, curwin, curbuf,
diff --git a/src/testdir/test_substitute.vim b/src/testdir/test_substitute.vim
index 710814386..eb60513bd 100644
--- a/src/testdir/test_substitute.vim
+++ b/src/testdir/test_substitute.vim
@@ -1526,4 +1526,27 @@ func Test_substitute_expr_cpo()
   delfunc XSubExpr
 endfunc
 
+" Test that undo after a confirmed substitution restores the state right
+" before the confirmed match, also when "
" splits the line (issue #4798)
+func Test_sub_undo_after_confirm()
+  new
+  call setline(1, 'foofoo')
+  call feedkeys(":s/foo/bar\r/gc\<CR>yy", 'xt')
+  call assert_equal(['bar', 'bar', ''], getline(1, '$'))
+  call feedkeys('u', 'xt')
+  call assert_equal(['bar', 'foo'], getline(1, '$'))
+  call feedkeys('u', 'xt')
+  call assert_equal(['foofoo'], getline(1, '$'))
+  bwipe!
+
+  " Without "
" all the matches in one line are still undone at once.
+  new
+  call setline(1, 'aXbXcXd')
+  call feedkeys(":s/X/-/gc\<CR>yyy", 'xt')
+  call assert_equal(['a-b-c-d'], getline(1, '$'))
+  call feedkeys('u', 'xt')
+  call assert_equal(['aXbXcXd'], getline(1, '$'))
+  bwipe!
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index e5ab4cc8a..b0a5d0718 100644
--- a/src/version.c
+++ b/src/version.c
@@ -763,6 +763,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    981,
 /**/
     980,
 /**/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups "vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To view this discussion visit https://groups.google.com/d/msgid/vim_dev/E1wwmvE-00CPJy-BB%40256bit.org.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.