]> git.mdlowis.com Git - projs/tide.git/commitdiff
added undo support for deletes
authorMichael D. Lowis <mike@mdlowis.com>
Tue, 21 Aug 2018 03:03:37 +0000 (23:03 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Tue, 21 Aug 2018 03:03:37 +0000 (23:03 -0400)
lib/buf.c

index f8dcbbc2a306a49b26cdfaa8b09a6fe2c0f5ce91..f97a23ca6bffbb0f3788d75308f5e544ce14c2b6 100644 (file)
--- a/lib/buf.c
+++ b/lib/buf.c
@@ -134,8 +134,25 @@ static Sel buf_getsel(Buf* buf) {
     return sel;
 }
 
-/* Unod/Redo Operations
+/* Undo/Redo Operations
  ******************************************************************************/
+static void putb(Buf* buf, char b, Sel* p_sel) {
+    buf_syncgap(buf, p_sel->end);
+    *(buf->gapstart++) = b;
+    p_sel->end = p_sel->end + 1u;
+    p_sel->beg = p_sel->end;
+    buf->status = MODIFIED;
+}
+
+static Log* mklog(size_t beg, size_t end, char* data, Log* next) {
+    Log* log = calloc(1, sizeof(Log));
+    log->beg = beg;
+    log->end = end;
+    log->data = data;
+    log->next = next;
+    return log;
+}
+
 static void log_clear(Log** list) {
     while (*list) {
         Log* deadite = *list;
@@ -147,6 +164,30 @@ static void log_clear(Log** list) {
 }
 
 void buf_undo(Buf* buf) {
+    if (!buf->undo) return;
+    Log* item = buf->undo;
+    buf->selection.beg = item->beg;
+    buf->selection.end = item->end;
+    if (item->data) {
+        /* reinsert deleted bytes */
+        for (char* s = item->data; s && *s; s++)
+            putb(buf, *s, &(buf->selection));
+        free(item->data);
+        item->data = NULL;
+    } else {
+        /* delete the added bytes */
+        Sel sel = buf_getsel(buf);
+        item->data = buf_gets(buf);
+        buf_syncgap(buf, sel.beg);
+        buf->gapend += (item->end - item->beg);
+        sel.end = sel.beg;
+        buf->selection = sel;
+        item->beg = sel.beg;
+        item->end = sel.end;
+    }
+    /* push item onto redo stack */
+    item->next = buf->redo;
+    buf->redo = item;
 }
 
 void buf_redo(Buf* buf) {
@@ -165,14 +206,6 @@ void buf_lastins(Buf* buf) {
 
 /* Basic Operations and Accessors
  ******************************************************************************/
-static void putb(Buf* buf, char b, Sel* p_sel) {
-    buf_syncgap(buf, p_sel->end);
-    *(buf->gapstart++) = b;
-    p_sel->end = p_sel->end + 1u;
-    p_sel->beg = p_sel->end;
-    buf->status = MODIFIED;
-}
-
 static char getb(Buf* buf, size_t off) {
     if (off >= buf_end(buf)) return '\n'; // TODO: get rid of this hack
     size_t bsz = (buf->gapstart - buf->bufstart);
@@ -225,13 +258,12 @@ void buf_del(Buf* buf) {
     size_t nbytes = sel.end - sel.beg;
     if (nbytes > 0) {
         buf->status = MODIFIED;
-        //char* str = buf_gets(buf, &sel);
+        char* str = buf_gets(buf);
         buf_syncgap(buf, sel.beg);
         buf->gapend += nbytes;
         sel.end = sel.beg;
         buf->selection = sel;
-        // update log here
-        // free(str);
+        buf->undo = mklog(sel.beg, sel.end, str, buf->undo);
     }
 }