Subject: Re: Bug in undo/redo handling in conjunction with history-beginning-search-backward
From: Oliver Kiddle <[email-masked]>
To: zsh workers <[email-masked]>
Date: Wed, 25 May 2016 03:02:56 +0200
List-Id: Zsh Workers List <zsh-workers.zsh.org>

On 20 May, Mikael Magnusson wrote:
> % bindkey -e
> % bindkey '^U' undo
> % bindkey '^Y' redo
> % bindkey '^[C' history-beginning-search-backward
> at this point, type in "bin" and invoke the
> history-beginning-search-backward widget, type a space, then undo and
> redo fully a few times, you'll notice the point where the extra "n"
> starts popping into the command line.

On first attempt, I couldn't reproduce this. I do get the effect with
repeated undos and no redos, however.

The way history line changes are stored in the undo code differs
markedly from other changes. So the code has ended up with special logic
to handle the history changes.

36131 was when I last touched this and I wasn't really happy with the
state of things then but that was just before a two week holiday. At the
time, I said:
  It might be better to create full undo entries for history changes
  though that would need hacks to ensure that multiple history changes
  are undone in a single step.

If this patch doesn't do the job then that might be a better approach
than playing whack-a-mole with further issues.

Oliver

diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c
index 68794c6..80219a4 100644
--- a/Src/Zle/zle_utils.c
+++ b/Src/Zle/zle_utils.c
@@ -1589,9 +1589,14 @@ undo(char **args)
 	    break;
 	if (prev->changeno <= undo_limitno && !*args)
 	    return 1;
-	if (!unapplychange(prev) && last_change >= 0)
-	    unapplychange(prev);
-	curchange = prev;
+	if (!unapplychange(prev)) {
+	    if (last_change >= 0) {
+		unapplychange(prev);
+		curchange = prev;
+	    }
+	} else {
+	    curchange = prev;
+	}
     } while (last_change >= (zlong)0 || (curchange->flags & CH_PREV));
     setlastline();
     return 0;