From f19284f30d808e305953424ff2d52b02d0e9ba72 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Tue, 20 Dec 2016 22:13:51 -0500 Subject: [PATCH] undo/redo now select the re-inserted text --- TODO.md | 8 +++----- inc/edit.h | 4 ++-- libedit/buf.c | 26 +++++++++++--------------- libedit/view.c | 4 ++-- xedit.c | 1 - 5 files changed, 18 insertions(+), 25 deletions(-) diff --git a/TODO.md b/TODO.md index 75150f6..ca6e2db 100644 --- a/TODO.md +++ b/TODO.md @@ -13,20 +13,18 @@ Nice to haves: -* Undo/Redo should set selection to inserted text. * focus should follow mouse between regions * Expand tabs setting should be disabled if opened file contains tabs * Add a tools dir to namespace utility scripts only useful inside the editor * shift+click to extend selection +* implement command diffing logic to optimize the undo/redo log +* add command line flags to toggle options (Tabs, Indent, etc..) +* check for file changes when window regains focus Need to reproduce: * drag with middle and right mouse buttons causes infinite loops * off by one error on scrolling up with wrapped lines -* Implement minimal regex search (per Kernighan article) -* check for file changes when window regains focus -* add command line flags to toggle options (Tabs, Indent, etc..) -* implement command diffing logic to optimize the undo/redo log # Auxillary Programs diff --git a/inc/edit.h b/inc/edit.h index 678a376..5006c78 100644 --- a/inc/edit.h +++ b/inc/edit.h @@ -65,8 +65,8 @@ unsigned buf_insert(Buf* buf, bool indent, unsigned off, Rune rune); unsigned buf_delete(Buf* buf, unsigned beg, unsigned end); unsigned buf_change(Buf* buf, unsigned beg, unsigned end); -unsigned buf_undo(Buf* buf, unsigned pos); -unsigned buf_redo(Buf* buf, unsigned pos); +void buf_undo(Buf* buf, Sel* sel); +void buf_redo(Buf* buf, Sel* sel); void buf_loglock(Buf* buf); bool buf_iseol(Buf* buf, unsigned pos); diff --git a/libedit/buf.c b/libedit/buf.c index 59e06f1..6f0d228 100644 --- a/libedit/buf.c +++ b/libedit/buf.c @@ -146,15 +146,16 @@ static int rune_match(Buf* buf, unsigned mbeg, unsigned mend, Rune* runes) { return 0; } -static unsigned swaplog(Buf* buf, Log** from, Log** to, unsigned pos) { +static void swaplog(Buf* buf, Log** from, Log** to, Sel* sel) { /* pop the last action */ Log* log = *from; - if (!log) return pos; + if (!log) return; *from = log->next; /* invert the log type and move it to the destination */ Log* newlog = (Log*)calloc(sizeof(Log), 1); newlog->transid = log->transid; if (log->insert) { + sel->beg = sel->end = log->data.ins.beg; newlog->insert = false; size_t n = (log->data.ins.end - log->data.ins.beg); newlog->data.del.off = log->data.ins.beg; @@ -164,20 +165,17 @@ static unsigned swaplog(Buf* buf, Log** from, Log** to, unsigned pos) { newlog->data.del.runes[i] = buf_get(buf, log->data.ins.beg); delete(buf, log->data.ins.beg); } - pos = newlog->data.del.off; } else { newlog->insert = true; - newlog->data.ins.beg = log->data.del.off; + sel->beg = newlog->data.ins.beg = log->data.del.off; newlog->data.ins.end = newlog->data.ins.beg; - //newlog->data.ins.end = log->data.del.off + log->data.del.len; for (size_t i = log->data.del.len; i > 0; i--) { newlog->data.ins.end += insert(buf, newlog->data.ins.beg, log->data.del.runes[i-1]); } - pos = newlog->data.ins.end; + sel->end = newlog->data.ins.end; } newlog->next = *to; *to = newlog; - return pos; } /*****************************************************************************/ @@ -320,20 +318,18 @@ unsigned buf_change(Buf* buf, unsigned beg, unsigned end) { /*****************************************************************************/ -unsigned buf_undo(Buf* buf, unsigned pos) { - if (!buf->undo) return pos; +void buf_undo(Buf* buf, Sel* sel) { + if (!buf->undo) return; uint transid = buf->undo->transid; while (buf->undo && (buf->undo->transid == transid)) - pos = swaplog(buf, &(buf->undo), &(buf->redo), pos); - return pos; + swaplog(buf, &(buf->undo), &(buf->redo), sel); } -unsigned buf_redo(Buf* buf, unsigned pos) { - if (!buf->redo) return pos; +void buf_redo(Buf* buf, Sel* sel) { + if (!buf->redo) return; uint transid = buf->redo->transid; while (buf->redo && (buf->redo->transid == transid)) - pos = swaplog(buf, &(buf->redo), &(buf->undo), pos); - return pos; + swaplog(buf, &(buf->redo), &(buf->undo), sel); } void buf_loglock(Buf* buf) { diff --git a/libedit/view.c b/libedit/view.c index fa9e471..0c43c07 100644 --- a/libedit/view.c +++ b/libedit/view.c @@ -482,13 +482,13 @@ void view_eof(View* view, bool extsel) { } void view_undo(View* view) { - view->selection.beg = view->selection.end = buf_undo(&(view->buffer), view->selection.end); + buf_undo(&(view->buffer), &(view->selection)); view->selection.col = buf_getcol(&(view->buffer), view->selection.end); view->sync_needed = true; } void view_redo(View* view) { - view->selection.beg = view->selection.end = buf_redo(&(view->buffer), view->selection.end); + buf_redo(&(view->buffer), &(view->selection)); view->selection.col = buf_getcol(&(view->buffer), view->selection.end); view->sync_needed = true; } diff --git a/xedit.c b/xedit.c index 2c0aafd..1871a9b 100644 --- a/xedit.c +++ b/xedit.c @@ -618,7 +618,6 @@ static void add_indent(void) { static void eol_mode(void) { int crlf = getbuf(EDIT)->crlf; - printf("%d %d\n", crlf, !crlf); getbuf(EDIT)->crlf = !crlf; getbuf(TAGS)->crlf = !crlf; exec(crlf ? "|dos2unix" : "|unix2dos"); -- 2.49.0