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