Bram,
attached patch implements undo when doing :s/.../.../gc

This has been requested recently in
https://groups.google.com/group/vim_dev/msg/9930ef0f86421814

And I think, I saw a request like this on the sf.net bug tracker, but I 
can't find it right now. Additionally, I also added using Ctrl-L for 
redrawing the screen as I found this useful.

regards,
Christian

-- 
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
diff --git a/runtime/doc/change.txt b/runtime/doc/change.txt
--- a/runtime/doc/change.txt
+++ b/runtime/doc/change.txt
@@ -628,6 +628,8 @@
 	    <Esc>   to quit substituting
 	    'a'	    to substitute this and all remaining matches {not in Vi}
 	    'q'	    to quit substituting {not in Vi}
+	    'u'     to undo the previous substitution {not in Vi}
+	    CTRL-L  redraw screen
 	    CTRL-E  to scroll the screen up {not in Vi, not available when
 			compiled without the |+insert_expand| feature}
 	    CTRL-Y  to scroll the screen down {not in Vi, not available when
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -4267,6 +4267,7 @@
 #ifdef FEAT_EVAL
     int         save_ma = 0;
 #endif
+    colnr_T     prev_col[256];		/* for placing the cursor after undoing */
 
     cmd = eap->arg;
     if (!global_busy)
@@ -4761,7 +4762,7 @@
 			    /* write message same highlighting as for
 			     * wait_return */
 			    smsg_attr(hl_attr(HLF_R),
-				    (char_u *)_("replace with %s (y/n/a/q/l/^E/^Y)?"), sub);
+				    (char_u *)_("replace with %s (y/n/a/q/l/u/^E/^Y)?"), sub);
 			    msg_no_more = FALSE;
 			    msg_scroll = i;
 			    showruler(TRUE);
@@ -4795,6 +4796,11 @@
 			}
 			if (typed == 'n')
 			    break;
+			if (typed == 'u')
+			{
+			    if (sub_nsubs)
+				break;
+			}
 			if (typed == 'y')
 			    break;
 			if (typed == 'l')
@@ -4809,6 +4815,15 @@
 			    do_ask = FALSE;
 			    break;
 			}
+			/* enable redrawing */
+			if (typed == Ctrl_L)
+			{
+			    temp = RedrawingDisabled;
+			    RedrawingDisabled = 0;
+			    update_topline();
+			    update_screen(CLEAR);
+			    RedrawingDisabled = temp;
+			}
 #ifdef FEAT_INS_EXPAND
 			if (typed == Ctrl_E)
 			    scrollup_clamp();
@@ -4823,6 +4838,33 @@
 		    if (vim_strchr(p_cpo, CPO_UNDO) != NULL)
 			--no_u_sync;
 
+		    if (typed == 'u')
+		    {
+			if (sub_nsubs)
+			{
+			    int idx = --sub_nsubs;
+			    pos_T  p = curwin->w_cursor;
+
+			    /* skip undo message */
+			    temp = global_busy;
+			    global_busy = TRUE;
+			    u_undo(1);
+			    global_busy = temp;
+
+			    sub_firstlnum = lnum = curwin->w_cursor.lnum;
+			    sub_firstline = vim_strsave(ml_get(sub_firstlnum));
+			    /* stay within the arrays bound */
+			    if (idx < 256)
+				/* move cursor to previous match */
+				matchcol = prev_col[idx];
+			    temp = searchit(curwin, curbuf, &p, BACKWARD, sub, 1L, 
+				    SEARCH_KEEP, RE_SEARCH, p.lnum, NULL);
+			    if (sub_nlines && (p.lnum < lnum || temp == FAIL))
+				sub_nlines--;
+
+			    goto skip;
+			}
+		    }
 		    if (typed == 'n')
 		    {
 			/* For a multi-line match, put matchcol at the NUL at
@@ -4940,6 +4982,8 @@
 		(void)vim_regsub_multi(&regmatch,
 				    sub_firstlnum - regmatch.startpos[0].lnum,
 					   sub, new_end, TRUE, p_magic, TRUE);
+		if (sub_nsubs < 256)
+		    prev_col[sub_nsubs] = regmatch.startpos[0].col;
 		sub_nsubs++;
 		did_sub = TRUE;
 

Raspunde prin e-mail lui