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 */
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;
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);
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;
#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
}
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) {
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);
}
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) {
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;