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(®match,
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;