ed

simple ed
git clone git://git.2f30.org/ed.git
Log | Files | Refs

commit 53afdf5cd33868ac4b6bc9afc24b5a4cee0ca0ad
parent 827419fffee2a4fbf9adc1b953c1e8a362872079
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sun Dec 13 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:
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();