Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: zle: vi mode: wrong undo handling on fresh lines



2014/02/04 08:26, Oliver Kiddle <okiddle@xxxxxxxxxxx> wrote:
> Anyway with the help of your hint, perhaps this:
>  zle -C undo-complete-word .complete-word _main_complete
>  complete-word() {
>    zle split-undo
>    zle undo-complete-word
>  }
>  zle -N complete-word

Thanks. It seems this solves my second problem.

There is another problem, however:

$ bindkey -v
$ echo xxx<esc>u     # type something and then undo
$                    # this is OK
$ echo yyy           # hit 'i' and type something more
$ echo yyy<esc>u     # undo again
$                    # also OK, but if I hit 'u' again
$ echo yyy           # then the command line goes back to this

Of course the expected behavior is that the command line remains
empty because there is nothing more to undo.
A possible patch is attached below. What the patch does is to
set CH_PREV in current->flags only if current->prev exists.

# If CH_PREV is set when current->prev is NULL, undo() returns
# without calling setlastline() (zle_utils.c, line 1543).
# This means lastline remains as "echo yyy" even if zleline is
# erased to "", and next call of handleundo() will add a wrong
# undo entry.



diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c
index 68d27f8..3af8ed7 100644
--- a/Src/Zle/zle_utils.c
+++ b/Src/Zle/zle_utils.c
@@ -1649,12 +1649,12 @@ splitundo(char **args)
 void
 mergeundo(void)
 {
-    struct change *current = curchange->prev;
-    while (current && current->changeno > vistartchange+1) {
+    struct change *current;
+    for (current = curchange->prev;
+	    current && current->prev && current->changeno > vistartchange+1;
+	    current = current->prev) {
 	current->flags |= CH_PREV;
-	current = current->prev;
-	if (!current) break;
-	current->flags |= CH_NEXT;
+	current->prev->flags |= CH_NEXT;
     }
 }
 






Messages sorted by: Reverse Date, Date, Thread, Author