about summary refs log tree commit diff
path: root/Src
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2012-03-29 20:31:33 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2012-03-29 20:31:33 +0000
commit13a45d74eb246894516aa9315622cf99d7f27697 (patch)
tree680a07a1d9c4215c050b41e89c9bf1d7f3491e95 /Src
parent8bb9818cd403092830896c7c7dd02e3ccd744213 (diff)
downloadzsh-13a45d74eb246894516aa9315622cf99d7f27697.tar.gz
zsh-13a45d74eb246894516aa9315622cf99d7f27697.tar.xz
zsh-13a45d74eb246894516aa9315622cf99d7f27697.zip
users/16932: implement $UNDO_CHANGE_NO and argument to undo widget
Diffstat (limited to 'Src')
-rw-r--r--Src/Zle/zle.h1
-rw-r--r--Src/Zle/zle_params.c4
-rw-r--r--Src/Zle/zle_utils.c30
3 files changed, 33 insertions, 2 deletions
diff --git a/Src/Zle/zle.h b/Src/Zle/zle.h
index bedf28f17..cf44b47d2 100644
--- a/Src/Zle/zle.h
+++ b/Src/Zle/zle.h
@@ -269,6 +269,7 @@ struct change {
     ZLE_STRING_T ins;		/* characters to insert */
     int insl;			/* no. of characters in ins */
     int old_cs, new_cs;		/* old and new cursor positions */
+    zlong changeno;             /* unique number of this change */
 };
 
 #define CH_NEXT (1<<0)   /* next structure is also part of this change */
diff --git a/Src/Zle/zle_params.c b/Src/Zle/zle_params.c
index 3fdb5f8ed..1a39df862 100644
--- a/Src/Zle/zle_params.c
+++ b/Src/Zle/zle_params.c
@@ -93,6 +93,8 @@ static const struct gsu_integer pending_gsu =
 { get_pending, NULL, zleunsetfn };
 static const struct gsu_integer region_active_gsu =
 { get_region_active, set_region_active, zleunsetfn };
+static const struct gsu_integer undo_change_no_gsu =
+{ get_undo_current_change, NULL, zleunsetfn };
 
 static const struct gsu_array killring_gsu =
 { get_killring, set_killring, unset_killring };
@@ -133,6 +135,8 @@ static struct zleparam {
     { "RBUFFER", PM_SCALAR,  GSU(rbuffer_gsu), NULL },
     { "REGION_ACTIVE", PM_INTEGER, GSU(region_active_gsu), NULL},
     { "region_highlight", PM_ARRAY, GSU(region_highlight_gsu), NULL },
+    { "UNDO_CHANGE_NO", PM_INTEGER | PM_READONLY, GSU(undo_change_no_gsu),
+      NULL },
     { "WIDGET", PM_SCALAR | PM_READONLY, GSU(widget_gsu), NULL },
     { "WIDGETFUNC", PM_SCALAR | PM_READONLY, GSU(widgetfunc_gsu), NULL },
     { "WIDGETSTYLE", PM_SCALAR | PM_READONLY, GSU(widgetstyle_gsu), NULL },
diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c
index 45e30445e..cf6787f3a 100644
--- a/Src/Zle/zle_utils.c
+++ b/Src/Zle/zle_utils.c
@@ -1359,6 +1359,10 @@ static struct change *changes, *curchange;
 
 static struct change *nextchanges, *endnextchanges;
 
+/* incremented to provide a unique change number */
+
+static zlong undo_changeno;
+
 /**/
 void
 initundo(void)
@@ -1368,6 +1372,7 @@ initundo(void)
     curchange->prev = curchange->next = NULL;
     curchange->del = curchange->ins = NULL;
     curchange->dell = curchange->insl = 0;
+    curchange->changeno = undo_changeno = 0;
     lastline = zalloc((lastlinesz = linesz) * ZLE_CHAR_SIZE);
     ZS_memcpy(lastline, zleline, (lastll = zlell));
     lastcs = zlecs;
@@ -1492,6 +1497,7 @@ mkundoent(void)
 	ch->flags = 0;
 	ch->prev = NULL;
     }
+    ch->changeno = ++undo_changeno;
     endnextchanges = ch;
 }
 
@@ -1512,8 +1518,15 @@ setlastline(void)
 
 /**/
 int
-undo(UNUSED(char **args))
+undo(char **args)
 {
+    zlong last_change = (zlong)0;
+
+    if (*args)
+    {
+	last_change = zstrtol(*args, NULL, 0);
+    }
+
     handleundo();
     do {
 	if(!curchange->prev)
@@ -1522,7 +1535,8 @@ undo(UNUSED(char **args))
 	    curchange = curchange->prev;
 	else
 	    break;
-    } while(curchange->flags & CH_PREV);
+    } while (*args ? curchange->changeno != last_change :
+	     (curchange->flags & CH_PREV));
     setlastline();
     return 0;
 }
@@ -1637,3 +1651,15 @@ zlecallhook(char *name, char *arg)
     errflag = saverrflag;
     retflag = savretflag;
 }
+
+/*
+ * Return the number corresponding to the last change made.
+ */
+
+/**/
+zlong
+get_undo_current_change(UNUSED(Param pm))
+{
+    return undo_changeno;
+}
+