]> git.mdlowis.com Git - projs/tide.git/commitdiff
use transaction logging for job processing interface
authorMichael D. Lowis <mike@mdlowis.com>
Wed, 5 Sep 2018 02:00:17 +0000 (22:00 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Wed, 5 Sep 2018 02:00:17 +0000 (22:00 -0400)
inc/edit.h
lib/buf.c
lib/job.c
lib/view.c
tide.c

index 153bbdaed230061a0c5c42e69bc01df17f92373e..78042f291d9aa23765e2c24cb12edd25a97a2765 100644 (file)
@@ -6,7 +6,7 @@ typedef struct Log {
     size_t beg;       /* beginning of affected region */
     size_t end;       /* end of affected region*/
     char* data;       /* pointer to deleted character data */
-    long transid;     /* id of transaction this item is a part of */
+    int transid;      /* id of transaction this item is a part of */
 } Log;
 
 /* cursor/selection representation */
@@ -30,7 +30,7 @@ typedef struct {
     char* gapend;     /* end of the gap */
     Log* undo;        /* undo list */
     Log* redo;        /* redo list */
-    long transid;     /* id number of the current transaction */
+    int transid;      /* id number of the current transaction */
     Sel selection;    /* the currently selected text */
 } Buf;
 
@@ -129,6 +129,7 @@ void view_bof(View* view, bool extsel);
 void view_eof(View* view, bool extsel);
 void view_undo(View* view);
 void view_redo(View* view);
+void view_paste(View* view, char* str);
 void view_putstr(View* view, char* str);
 char* view_getstr(View* view);
 char* view_getcmd(View* view);
index 169848d1b783db942d0e355140fac6ac85f76d57..df45b608b203156753005412d8af930a457bd22d 100644 (file)
--- a/lib/buf.c
+++ b/lib/buf.c
@@ -145,8 +145,9 @@ static void putb(Buf* buf, char b, Sel* p_sel) {
     buf->status = MODIFIED;
 }
 
-static Log* mklog(size_t beg, size_t end, char* data, Log* next) {
+static Log* mklog(Buf* buf, size_t beg, size_t end, char* data, Log* next) {
     Log* log = calloc(1, sizeof(Log));
+    log->transid = (buf->transid < 0 ? 0 : buf->transid);
     log->beg = beg;
     log->end = end;
     log->data = data;
@@ -168,10 +169,10 @@ static void dumplog(Buf* buf) {
 #if 0
     printf("\nUndo:\n");
     for (Log* log = buf->undo; log; log = log->next)
-        printf("    %lu-%lu '%s'\n", log->beg, log->end, log->data);
+        printf("    (%d) %lu-%lu '%s'\n", log->transid, log->beg, log->end, log->data);
     printf("Redo:\n");
     for (Log* log = buf->redo; log; log = log->next)
-        printf("    %lu-%lu '%s'\n", log->beg, log->end, log->data);
+        printf("    (%d) %lu-%lu '%s'\n", log->transid, log->beg, log->end, log->data);
 #endif
 }
 
@@ -179,8 +180,8 @@ static void log_add(Buf* buf, size_t beg, size_t end, char* data) {
     Log* prev = buf->undo;
     log_clear(&(buf->redo));
     /* decide if this is an insert or delete */
-    if (!prev || (buf->transid > 0 && buf->transid == prev->transid)) {
-        buf->undo = mklog(beg, end, data, prev);
+    if (!prev || (buf->transid > 0 && buf->transid != prev->transid)) {
+        buf->undo = mklog(buf, beg, end, data, prev);
     } else if (!data && !prev->data && prev->end == beg) {
         prev->end = end;
     } else if (prev->data && data && prev->beg == beg) {
@@ -195,7 +196,7 @@ static void log_add(Buf* buf, size_t beg, size_t end, char* data) {
         prev->data = newdata;
         prev->end = --prev->beg;
     } else {
-        buf->undo = mklog(beg, end, data, prev);
+        buf->undo = mklog(buf, beg, end, data, prev);
     }
     dumplog(buf);
 }
@@ -225,10 +226,14 @@ static void log_swap(Buf* buf, Log** src, Log** dest) {
         item->beg = sel.beg;
         item->end = sel.end;
     }
-    /* push item onto redo stack */
+    /* push item onto destination stack */
     item->next = *dest;
     *dest = item;
-    dumplog(buf);
+    /* undo recursively if this is part of a transaction */
+    if (*src && item->transid && item->transid == (*src)->transid)
+        log_swap(buf, src, dest);
+    else
+        dumplog(buf);
 }
 
 void buf_logstart(Buf* buf) {
@@ -258,8 +263,9 @@ void buf_lastins(Buf* buf) {
     if (!log) return;
     Sel sel = {.beg = log->beg, .end = log->end };
     size_t delsize = 0;
+    int transid = log->transid;
     /* try and expand the selected region to encompass related inserts */
-    for (; log; log = log->next) {
+    for (; log && (log->transid == transid); log = log->next) {
         if (!log->data) {
             size_t ibeg = log->beg, iend = log->end - delsize;
             if (iend < ibeg || ibeg > sel.beg || iend < sel.beg) break;
index 7d8f57c0309681bd1f0c2a5fecf390cf5fd0362f..aac1b34b21ad5d8278215c5ca954d601aef22919 100644 (file)
--- a/lib/job.c
+++ b/lib/job.c
@@ -27,8 +27,11 @@ static void pipe_read(Job* job) {
     long nread = read(job->fd, buffer, sizeof(buffer)-1);
     if (nread <= 0) {
         job->readfn = NULL;
+        buf_logstop(&pipedata->dest->buffer);
+        view_selprev(pipedata->dest);
     } else if (nread > 0) {
         buffer[nread] = '\0';
+        buf_logstart(&pipedata->dest->buffer);
         view_putstr(pipedata->dest, buffer);
     }
 }
index cfe0c1a21c14fad12e825a451900ddc6a0232228..13e4939c6331ee456f036114767bc7fb1eb2d653 100644 (file)
@@ -312,9 +312,15 @@ void view_redo(View* view) {
     if (!selection_visible(view)) view->sync_flags |= CENTER;
 }
 
+void view_paste(View* view, char* str) {
+    buf_logstart(BUF);
+    view_putstr(view, str);
+    buf_logstop(BUF);
+    view_selprev(view);
+}
+
 void view_putstr(View* view, char* str) {
     buf_puts(BUF, str);
-    view_selprev(view);
 }
 
 char* view_getstr(View* view) {
diff --git a/tide.c b/tide.c
index 0de92152b054df46f94d9253c7d2587c4bfcc1b0..16ea030d5b82353eaace2c63556385ecbac73c5d 100644 (file)
--- a/tide.c
+++ b/tide.c
@@ -123,7 +123,7 @@ static void delete(char* arg) {
 }
 
 static void onpaste(char* text) {
-    view_putstr(win_view(FOCUSED), text);
+    view_paste(win_view(FOCUSED), text);
 }
 
 void cut(char* arg) {