about summary refs log tree commit diff
path: root/Src/Zle
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Zle')
-rw-r--r--Src/Zle/zle_utils.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c
index cf6787f3a..55fd2ffd2 100644
--- a/Src/Zle/zle_utils.c
+++ b/Src/Zle/zle_utils.c
@@ -1520,23 +1520,25 @@ setlastline(void)
 int
 undo(char **args)
 {
-    zlong last_change = (zlong)0;
+    zlong last_change;
 
     if (*args)
-    {
 	last_change = zstrtol(*args, NULL, 0);
-    }
+    else
+	last_change = (zlong)-1;
 
     handleundo();
     do {
-	if(!curchange->prev)
+	struct change *prev = curchange->prev;
+	if(!prev)
 	    return 1;
-	if (unapplychange(curchange->prev))
-	    curchange = curchange->prev;
+	if (prev->changeno < last_change)
+	    break;
+	if (unapplychange(prev))
+	    curchange = prev;
 	else
 	    break;
-    } while (*args ? curchange->changeno != last_change :
-	     (curchange->flags & CH_PREV));
+    } while (last_change >= (zlong)0 || (curchange->flags & CH_PREV));
     setlastline();
     return 0;
 }
@@ -1660,6 +1662,11 @@ zlecallhook(char *name, char *arg)
 zlong
 get_undo_current_change(UNUSED(Param pm))
 {
-    return undo_changeno;
+    /*
+     * Increment the number in case a change is in progress;
+     * we don't want to back off what's already been done when
+     * we return to this change number.  This eliminates any
+     * problem about the point where a change is numbered.
+     */
+    return ++undo_changeno;
 }
-