about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--Src/Zle/zle_utils.c27
2 files changed, 22 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index 0fe5c3668..266e7f9ed 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2012-10-09  Peter Stephenson  <pws@csr.com>
 
+	* users/17314: Src/Zle/zle_utils.c: ensure an undo change number
+	uniquely specifies a point in editing history by incrementing
+	the value returned by the variable.
+
 	* unposted: Src/builtin.c: fix trivial typo with "functions +T".
 
 2012-10-07  Peter Stephenson  <p.w.stephenson@ntlworld.com>
@@ -248,5 +252,5 @@
 
 *****************************************************
 * This is used by the shell to define $ZSH_PATCHLEVEL
-* $Revision: 1.5741 $
+* $Revision: 1.5742 $
 *****************************************************
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;
 }
-