diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2014-07-17 12:15:24 +0200 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2014-07-17 12:15:24 +0200 |
| commit | fe0f10dcfda70989ea294ac6e56d842e931fdbb3 (patch) | |
| tree | e320c96cf936b60e0b66d0556e34e4420c45f41a /editor.c | |
| parent | 392098c13c3fb4e879f795170afc35e2e3c0f2d8 (diff) | |
| download | vis-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.
Diffstat (limited to 'editor.c')
| -rw-r--r-- | editor.c | 34 |
1 files changed, 27 insertions, 7 deletions
@@ -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); } |
