URI: 
       tFix bug with undo - ledit - Text editor (WIP)
  HTML git clone git://lumidify.org/ledit.git (fast, but not encrypted)
  HTML git clone https://lumidify.org/git/ledit.git (encrypted, but very slow)
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 81ddea61d765938b662b3456b3fe80369cfbc138
   DIR parent 626c8692fa7f3dadb3c83a7c5b68b129e9e04ad5
  HTML 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:
         M buffer.c                            |       8 +++++++-
         M undo.c                              |      32 ++++++++++++++++++++-----------
       
       2 files changed, 28 insertions(+), 12 deletions(-)
       ---
   DIR diff --git a/buffer.c b/buffer.c
       t@@ -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 */
       t@@ -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;
       t@@ -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) {
   DIR diff --git a/undo.c b/undo.c
       t@@ -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,
       t@@ -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
       t@@ -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,
       t@@ -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,
       t@@ -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;
        }