diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2015-09-21 20:54:27 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2015-09-21 20:54:27 -0700 |
commit | 515b0cdcc0b4c61c2636444b08d3868e902d380d (patch) | |
tree | 55b55bbce5cc83a846ab565a402e34918eff3b5f /linenoise/linenoise.c | |
parent | 0b0cfc846c30bb56d0f46949ecd1223028f65bb1 (diff) | |
download | txr-515b0cdcc0b4c61c2636444b08d3868e902d380d.tar.gz txr-515b0cdcc0b4c61c2636444b08d3868e902d380d.tar.bz2 txr-515b0cdcc0b4c61c2636444b08d3868e902d380d.zip |
linenoise: squelch some useless undo items.
Sometimes edits don't do anything, and so the undo item
recorded for them is superfluous. When undo is used
nothing appears to happen for a turn.
We use two strategies: detect the noop change
and avoid recording the undo (or doing anything),
or else detecting the noop undo afterward and
removing it from the undo stack.
* linenoise/linenoise.c (remove_noop_undo): New static
function.
(edit_delete, edit_backspace): Remove noop undo.
(edit_delete_prev_word): Don't record undo, move
memory or update vars if there is no word to delete.
(edit_in_editor): Remove noop undo.
(edit): For Ctrl-T, don't record undo or do anything
other than clear the selection if the cursor
is leftmost already.
Diffstat (limited to 'linenoise/linenoise.c')
-rw-r--r-- | linenoise/linenoise.c | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/linenoise/linenoise.c b/linenoise/linenoise.c index 9dd43306..18106463 100644 --- a/linenoise/linenoise.c +++ b/linenoise/linenoise.c @@ -357,6 +357,18 @@ static void record_triv_undo(lino_t *l) l->undo_stack->triv = 1; } +static void remove_noop_undo(lino_t *l) +{ + struct lino_undo *top = l->undo_stack; + + if (top != 0 && + (top->hist_index == INT_MAX || top->hist_index == l->history_index) && + strcmp(l->data, top->data) == 0) + { + delete_undo(&l->undo_stack); + } +} + static void restore_undo(lino_t *l) { struct lino_undo **ptop = &l->undo_stack; @@ -1253,6 +1265,7 @@ static void edit_delete(lino_t *l) { l->data[l->dlen] = '\0'; l->need_refresh = 1; } + remove_noop_undo(l); } /* Backspace implementation. */ @@ -1273,6 +1286,8 @@ static void edit_backspace(lino_t *l) { l->data[l->dlen] = '\0'; l->need_refresh = 1; } + + remove_noop_undo(l); } /* Delete all characters to left of cursor. */ @@ -1292,7 +1307,6 @@ static void edit_delete_prev_all(lino_t *l) static void edit_delete_prev_word(lino_t *l) { size_t odpos, diff; - record_undo(l); delete_sel(l); odpos = l->dpos; @@ -1301,9 +1315,12 @@ static void edit_delete_prev_word(lino_t *l) { while (l->dpos > 0 && strchr(SPACE, l->data[l->dpos - 1]) == 0) l->dpos--; diff = odpos - l->dpos; - memmove(l->data + l->dpos, l->data + odpos, l->dlen - odpos + 1); - l->dlen -= diff; - l->need_refresh = 1; + if (diff != 0) { + record_undo(l); + memmove(l->data + l->dpos, l->data + odpos, l->dlen - odpos + 1); + l->dlen -= diff; + l->need_refresh = 1; + } } static void tr(char *s, int find, int rep) @@ -1367,6 +1384,7 @@ static void edit_in_editor(lino_t *l) { l->dpos = l->dlen = nread; tr(l->data, '\n', '\r'); l->need_refresh = 1; + remove_noop_undo(l); } } @@ -1607,10 +1625,11 @@ static int edit(lino_t *l, const char *prompt) } break; case CTL('T'): /* swaps current character with previous. */ - record_undo(l); clear_sel(l); if (l->dpos > 0 && l->dpos < l->dlen) { int aux = l->data[l->dpos - 1]; + + record_undo(l); l->data[l->dpos-1] = l->data[l->dpos]; l->data[l->dpos] = aux; if (l->dpos != l->dlen - 1) l->dpos++; |