ledit

Text editor (WIP)
git clone git://lumidify.org/ledit.git (fast, but not encrypted)
git clone https://lumidify.org/git/ledit.git (encrypted, but very slow)
Log | Files | Refs | README | LICENSE

commit 81ddea61d765938b662b3456b3fe80369cfbc138
parent 626c8692fa7f3dadb3c83a7c5b68b129e9e04ad5
Author: lumidify <nobody@lumidify.org>
Date:   Fri,  6 Oct 2023 11:05:17 +0200

Fix bug with undo

Sometimes, the text would get scrambled when using undo. This was
actually due to a bug in the deletion function that only became
apparent when using undo.

Diffstat:
Mbuffer.c | 8+++++++-
Mundo.c | 32+++++++++++++++++++++-----------
2 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/buffer.c b/buffer.c @@ -909,8 +909,12 @@ buffer_prev_char_pos( *byte_ret = cur_byte; } +/* The check for length == 0 in buffer_delete_line_section_base and the check for + empty range in delete_range_base shouldn't be needed, but I added them just in case. */ static void buffer_delete_line_section_base(ledit_buffer *buffer, size_t line, size_t start, size_t length) { + if (length == 0) + return; ledit_line *l = buffer_get_line(buffer, line); /* FIXME: somehow make sure this doesn't get optimized out? */ (void)add_sz(start, length); /* just check that no overflow */ @@ -928,7 +932,7 @@ buffer_delete_line_section_base(ledit_buffer *buffer, size_t line, size_t start, memmove( l->text + l->gap, l->text + l->gap + l->cap - l->len, - start - l->gap + start - l->gap - l->cap + l->len ); } l->len -= length; @@ -947,6 +951,8 @@ delete_range_base( size_t line_index1, size_t byte_index1, size_t line_index2, size_t byte_index2, txtbuf *text_ret) { + if (line_index1 == line_index2 && byte_index1 == byte_index2) + return; sort_range(&line_index1, &byte_index1, &line_index2, &byte_index2); if (line_index1 == line_index2) { if (text_ret) { diff --git a/undo.c b/undo.c @@ -101,6 +101,23 @@ undo_change_mode_group(undo_stack *undo) { undo->change_mode_group = 1; } +/* +static void +dump_undo(undo_stack *undo) { + printf("START UNDO STACK\n"); + printf("cur: %zu\n", undo->cur); + for (size_t i = 0; i < undo->len; i++) { + undo_elem *e = &undo->stack[i]; + printf( + "type %d, mode %d, group %d, mode_group %d, text '%.*s', range (%zu, %zu)\n", + e->type, e->mode, e->group, e->mode_group, (int)e->text->len, e->text->text, + e->op_range.byte1, e->op_range.byte2 + ); + } + printf("END UNDO STACK\n"); +} +*/ + static void push_undo( undo_stack *undo, txtbuf *text, @@ -123,17 +140,7 @@ push_undo( txtbuf_copy(e->text, text); else e->text = txtbuf_dup(text); - /* - printf("START UNDO STACK\n"); - for (size_t i = 0; i < undo->len; i++) { - undo_elem *e = &undo->stack[i]; - printf( - "type %d, mode %d, group %d, mode_group %d, text '%.*s'\n", - e->type, e->mode, e->group, e->mode_group, (int)e->text->len, e->text->text - ); - } - printf("END UNDO STACK\n"); - */ + /* dump_undo(undo); */ } void @@ -195,6 +202,7 @@ ledit_undo(undo_stack *undo, ledit_mode mode, void *callback_data, switch (e->type) { case UNDO_INSERT: /* FIXME: should the paste buffer also be modified? */ + /* printf("delete %zu,%zu; %zu,%zu\n", e->op_range.line1, e->op_range.byte1, e->op_range.line2, e->op_range.byte2); */ delete_cb( callback_data, e->op_range.line1, e->op_range.byte1, @@ -202,6 +210,7 @@ ledit_undo(undo_stack *undo, ledit_mode mode, void *callback_data, ); break; case UNDO_DELETE: + /* printf("delete %zu,%zu; %zu,%zu\n", e->op_range.line1, e->op_range.byte1, e->op_range.line2, e->op_range.byte2); */ insert_cb( callback_data, e->op_range.line1, e->op_range.byte1, @@ -234,6 +243,7 @@ ledit_undo(undo_stack *undo, ledit_mode mode, void *callback_data, *min_line_ret = min_line; if (mode == NORMAL || mode == VISUAL) undo_change_mode_group(undo); + /* dump_undo(undo); */ return UNDO_NORMAL; }