aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2014-07-17 12:15:24 +0200
committerMarc André Tanner <mat@brain-dump.org>2014-07-17 12:15:24 +0200
commitfe0f10dcfda70989ea294ac6e56d842e931fdbb3 (patch)
treee320c96cf936b60e0b66d0556e34e4420c45f41a
parent392098c13c3fb4e879f795170afc35e2e3c0f2d8 (diff)
downloadvis-fe0f10dcfda70989ea294ac6e56d842e931fdbb3.tar.gz
vis-fe0f10dcfda70989ea294ac6e56d842e931fdbb3.tar.xz
Throw away redo history once a new action is performed
Keep all pieces in a global double linked list such that individual pieces can be removed.
-rw-r--r--editor.c34
1 files changed, 27 insertions, 7 deletions
diff --git a/editor.c b/editor.c
index 012f454..5b9c101 100644
--- a/editor.c
+++ b/editor.c
@@ -25,7 +25,9 @@ struct Buffer {
typedef struct Piece Piece;
struct Piece {
- Piece *prev, *next, *global_next;
+ Editor *editor;
+ Piece *prev, *next;
+ Piece *global_prev, *global_next;
char *content;
size_t len;
// size_t line_count;
@@ -179,12 +181,15 @@ static Action *action_pop(Action **stack) {
}
static Action *action_alloc(Editor *ed) {
- Action *a = calloc(1, sizeof(Action));
- if (!a)
+ Action *old, *new = calloc(1, sizeof(Action));
+ if (!new)
return NULL;
- ed->current_action = a;
- action_push(&ed->undo, a);
- return a;
+ /* throw a away all old redo operations, since we are about to perform a new one */
+ while ((old = action_pop(&ed->redo)))
+ action_free(old);
+ ed->current_action = new;
+ action_push(&ed->undo, new);
+ return new;
}
static void action_free(Action *a) {
@@ -198,16 +203,27 @@ static void action_free(Action *a) {
}
static Piece *piece_alloc(Editor *ed) {
- Piece *p = malloc(sizeof(Piece));
+ Piece *p = calloc(1, sizeof(Piece));
if (!p)
return NULL;
+ p->editor = ed;
p->index = ++ed->piece_count;
p->global_next = ed->pieces;
+ if (ed->pieces)
+ ed->pieces->global_prev = p;
ed->pieces = p;
return p;
}
static void piece_free(Piece *p) {
+ if (!p)
+ return;
+ if (p->global_prev)
+ p->global_prev->global_next = p->global_next;
+ if (p->global_next)
+ p->global_next->global_prev = p->global_prev;
+ if (p->editor->pieces == p)
+ p->editor->pieces = p->global_next;
free(p);
}
@@ -250,6 +266,10 @@ static Change *change_alloc(Editor *ed) {
}
static void change_free(Change *c) {
+ /* only free the new part of the span, the old one is still in use */
+ piece_free(c->new.start);
+ if (c->new.start != c->new.end)
+ piece_free(c->new.end);
free(c);
}