From: Michael D. Lowis Date: Wed, 5 Sep 2018 02:00:17 +0000 (-0400) Subject: use transaction logging for job processing interface X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=313a8b5c461be3ecf7dc819f29438cbea1bbc707;p=projs%2Ftide.git use transaction logging for job processing interface --- diff --git a/inc/edit.h b/inc/edit.h index 153bbda..78042f2 100644 --- a/inc/edit.h +++ b/inc/edit.h @@ -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); diff --git a/lib/buf.c b/lib/buf.c index 169848d..df45b60 100644 --- 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; diff --git a/lib/job.c b/lib/job.c index 7d8f57c..aac1b34 100644 --- 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); } } diff --git a/lib/view.c b/lib/view.c index cfe0c1a..13e4939 100644 --- a/lib/view.c +++ b/lib/view.c @@ -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 0de9215..16ea030 100644 --- 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) {