commit 53afdf5cd33868ac4b6bc9afc24b5a4cee0ca0ad
parent 827419fffee2a4fbf9adc1b953c1e8a362872079
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Sun, 13 Dec 2015 18:25:15 +0100
Add basic undo command
This is a first version of undo, which
store all the relink operations in an array
(very inefficient array) and do the inverse
operation. The array is only reseted in
undo(), which means that undo() will undo
all the operations from the beginning of
the edition session.
Diffstat:
M | ed.c | | | 41 | +++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 41 insertions(+), 0 deletions(-)
diff --git a/ed.c b/ed.c
@@ -24,6 +24,12 @@ struct hline {
int next, prev;
};
+struct editop {
+ int to1, from1;
+ int to2, from2;
+};
+
+
char *prompt = "*";
regex_t *pattern;
regmatch_t matchs[10];
@@ -50,6 +56,8 @@ size_t cmdsiz, cmdcap;
int repidx;
char *rhs;
char *lastmatch;
+struct editop *undoptr;
+int nr_undo;
static void
error(char *msg)
@@ -218,9 +226,36 @@ setglobal(int i, int v)
static void
relink(int to1, int from1, int from2, int to2)
{
+ struct editop *p;
+
+ if ((p = realloc(undoptr, sizeof(*p) * (nr_undo + 1))) == NULL)
+ error("out of memory");
+ undoptr = p;
+ p += nr_undo;
+ p->from1 = from1;
+ p->to1 = zero[from1].next;
+ p->to2 = zero[from2].prev;
+ p->from2 = from2;
+
zero[from1].next = to1;
zero[from2].prev = to2;
modflag = 1;
+ ++nr_undo;
+}
+
+static void
+undo(void)
+{
+ int i;
+ struct editop *p;
+
+ for (p = &undoptr[nr_undo]; p-- > undoptr; ) {
+ zero[p->from1].next = p->to1;
+ zero[p->from2].next = p->to2;
+ }
+ free(undoptr);
+ nr_undo = 0;
+ undoptr = NULL;
}
static void
@@ -1026,6 +1061,12 @@ repeat:
deflines(lastln, lastln);
printf("%d\n", line1);
break;
+ case 'u':
+ if (nlines > 0)
+ goto bad_address;
+ chkprint(0);
+ undo();
+ break;
case 's':
deflines(curln, curln);
c = input();