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