From 3b401e770eb33c6b02dfc90637cf2eb8c89999c1 Mon Sep 17 00:00:00 2001 From: Kyle Isom Date: Sat, 29 Nov 2025 13:05:12 -0800 Subject: [PATCH] working on undo --- abuf.c | 17 +++++++++++++++ undo.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++------- undo.h | 12 +++++++---- 3 files changed, 83 insertions(+), 12 deletions(-) diff --git a/abuf.c b/abuf.c index c302cb0..b877c6a 100644 --- a/abuf.c +++ b/abuf.c @@ -74,6 +74,11 @@ ab_append(abuf *buf, const char *s, size_t len) void ab_append_ab(abuf *buf, const abuf *other) { + assert(buf != NULL); + if (other == NULL) { + return; + } + ab_append(buf, other->b, other->size); } @@ -104,6 +109,18 @@ ab_prepend(abuf *buf, const char *s, const size_t len) } +void +ab_prepend_ab(abuf *buf, const abuf *other) +{ + assert(buf != NULL); + if (other == NULL) { + return; + } + + ab_prepend(buf, other->b, other->size); +} + + void ab_free(abuf *buf) { diff --git a/undo.c b/undo.c index fa07057..f5bea5a 100644 --- a/undo.c +++ b/undo.c @@ -1,6 +1,7 @@ #include #include #include "abuf.h" +#include "buffer.h" #include "undo.h" @@ -18,7 +19,7 @@ undo_node_new(undo_kind kind) ab_init(&node->text); node->next = NULL; - node->parent = NULL; + node->next = NULL; return node; } @@ -101,7 +102,7 @@ undo_prepend(undo_tree *tree, abuf *buf) assert(tree != NULL); assert(tree->pending != NULL); - ab_prepend_ab(tree->pending->text, buf); + ab_prepend_ab(&tree->pending->text, buf); } @@ -111,7 +112,7 @@ undo_append(undo_tree *tree, abuf *buf) assert(tree != NULL); assert(tree->pending != NULL); - ab_append_ab(tree->pending->text, buf); + ab_append_ab(&tree->pending->text, buf); } @@ -121,7 +122,7 @@ undo_prependch(undo_tree *tree, char c) assert(tree != NULL); assert(tree->pending != NULL); - ab_prependch(tree->pending->text, c); + ab_prependch(&tree->pending->text, c); } @@ -131,7 +132,7 @@ undo_appendch(undo_tree *tree, char c) assert(tree != NULL); assert(tree->pending != NULL); - ab_appendch(tree->pending->text, c); + ab_appendch(&tree->pending->text, c); } @@ -144,10 +145,59 @@ undo_commit(undo_tree *tree) return; } + if (tree->root == NULL) { + assert(tree->current == NULL); + tree->root = tree->pending; + tree->current = tree->pending; + tree->pending = NULL; + + return; + } + + assert(tree->current != NULL); + if (tree->current->next != NULL) { + undo_node_free_all(tree->current->next); + } + + tree->pending->prev = tree->current; + tree->current->next = tree->pending; + tree->current = tree->pending; + tree->pending = NULL; } -void undo_apply(struct buffer *buf); -void editor_undo(struct buffer *buf); -void editor_redo(struct buffer *buf); +int +undo_apply(struct buffer *buf, int direction) +{ + (void)buf; + (void)direction; + + return 0; +} + + +int +editor_undo(struct buffer *buf) +{ + if (buf == NULL) { + return 0; + } + + undo_commit(&buf->tree); + return undo_apply(buf, UNDO_DIR_UNDO); + +} + + +int +editor_redo(struct buffer *buf) +{ + if (buf == NULL) { + return 0; + } + + undo_commit(&buf->tree); + return undo_apply(buf, UNDO_DIR_REDO); +} + diff --git a/undo.h b/undo.h index 198e47e..d0a1e7a 100644 --- a/undo.h +++ b/undo.h @@ -10,6 +10,10 @@ struct buffer; +#define UNDO_DIR_UNDO -1 +#define UNDO_DIR_REDO 1 + + typedef enum undo_kind { UNDO_INSERT = 1 << 0, UNDO_UNKNOWN = 1 << 1, @@ -22,7 +26,7 @@ typedef struct undo_node { abuf text; struct undo_node *next; - struct undo_node *parent; + struct undo_node *prev; } undo_node; @@ -44,9 +48,9 @@ void undo_append(undo_tree *tree, abuf *buf); void undo_prependch(undo_tree *tree, char c); void undo_appendch(undo_tree *tree, char c); void undo_commit(undo_tree *tree); -void undo_apply(struct buffer *buf); -void editor_undo(struct buffer *buf); -void editor_redo(struct buffer *buf); +int undo_apply(struct buffer *buf, int direction); +int editor_undo(struct buffer *buf); +int editor_redo(struct buffer *buf); #endif