URI: 
       tFix a few bugs - 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 e822581bc43838987d8830b54c5e2103056a1b18
   DIR parent 8c56c0d034a6e99583be2d9926946997c8fa82bb
  HTML Author: lumidify <nobody@lumidify.org>
       Date:   Thu, 23 Dec 2021 21:06:42 +0100
       
       Fix a few bugs
       
       Diffstat:
         M README                              |       2 ++
         M buffer.h                            |       2 +-
         M keys_basic.c                        |      27 ++++++++++++++++++++-------
         M ledit.1                             |       3 +++
         M view.c                              |       7 ++++---
       
       5 files changed, 30 insertions(+), 11 deletions(-)
       ---
   DIR diff --git a/README b/README
       t@@ -5,6 +5,8 @@ ledit is a vi-like text editor for people who switch between keyboard
        layouts frequently and/or work with languages that require complex text
        layout.
        
       +REQUIREMENTS: pango, xlib (extensions: xkb, xdbe)
       +
        The documentation can be viewed in ledit.1 or at the following locations:
        
        gopher://lumidify.org/0/doc/ledit/ledit-current.txt
   DIR diff --git a/buffer.h b/buffer.h
       t@@ -32,7 +32,7 @@ typedef struct {
                ledit_buffer_mark *marks;
        } ledit_buffer_marklist;
        
       -/* TODO: advisory lock on file? also check if modification date changed before writing */
       +/* TODO: advisory lock on file */
        struct ledit_buffer {
                ledit_common *common;            /* common stuff, e.g. display, etc. */
                char *filename;                  /* last opened filename */
   DIR diff --git a/keys_basic.c b/keys_basic.c
       t@@ -9,6 +9,8 @@
           and being deleted at some later time even though they're not shown anymore */
        /* FIXME: delete everything concerned with selections in insert mode since
           they are now not allowed at all */
       +/* FIXME: a lot of error checking in the individual functions may be redundant
       +   now that more checking is done beforehand for the allowed keys */
        #include <stdio.h>
        #include <stdlib.h>
        
       t@@ -479,6 +481,7 @@ delete_selection(ledit_view *view) {
                return 0;
        }
        
       +/* FIXME: should these delete characters or graphemes? */
        static struct action
        delete_chars_forwards(ledit_view *view, char *text, size_t len) {
                (void)text;
       t@@ -936,7 +939,7 @@ change(ledit_view *view, char *text, size_t len) {
                                return err_invalid_key(view);
                        } else {
                                struct key_stack_elem *e = push_key_stack();
       -                        e->key = KEY_MOTIONALLOWED;
       +                        e->key = KEY_MOTIONALLOWED|KEY_NUMBERALLOWED;
                                e->count = num;
                                e->motion_cb = &change_cb;
                        }
       t@@ -999,9 +1002,11 @@ yank(ledit_view *view, char *text, size_t len) {
                } else {
                        motion_callback cb = NULL;
                        int num = get_key_repeat_and_motion_cb(view, &cb);
       -                if (num == 0)
       -                        num = 1;
       +                if (num == -1)
       +                        return err_invalid_key(view);
                        if (cb == &yank_cb) {
       +                        if (num == 0)
       +                                num = 1;
                                size_t new_line;
                                int new_softline;
                                get_new_line_softline(
       t@@ -1014,10 +1019,11 @@ yank(ledit_view *view, char *text, size_t len) {
                                clear_key_stack();
                        } else if (cb == NULL) {
                                struct key_stack_elem *e = push_key_stack();
       -                        e->key = KEY_MOTIONALLOWED;
       +                        e->key = KEY_MOTIONALLOWED|KEY_NUMBERALLOWED;
                                e->count = num;
                                e->motion_cb = &yank_cb;
                        } else {
       +                        /* FIXME: proper error */
                                clear_key_stack();
                        }
                }
       t@@ -1120,7 +1126,7 @@ delete(ledit_view *view, char *text, size_t len) {
                                return err_invalid_key(view);
                        } else {
                                struct key_stack_elem *e = push_key_stack();
       -                        e->key = KEY_MOTIONALLOWED;
       +                        e->key = KEY_MOTIONALLOWED|KEY_NUMBERALLOWED;
                                e->count = num;
                                e->motion_cb = &delete_cb;
                        }
       t@@ -1561,6 +1567,7 @@ move_cursor_left_right(ledit_view *view, int dir, int allow_illegal_index) {
                        } else if (view->mode == NORMAL) {
                                view_set_line_cursor_attrs(view, view->cur_line, view->cur_index);
                        }
       +                view->redraw = 1;
                        discard_repetition_stack();
                }
                clear_key_stack();
       t@@ -1683,6 +1690,7 @@ move_cursor_up_down(ledit_view *view, int dir) {
                        } else if (view->mode == NORMAL) {
                                view_set_line_cursor_attrs(view, view->cur_line, view->cur_index);
                        }
       +                view->redraw = 1;
                        discard_repetition_stack();
                }
                clear_key_stack();
       t@@ -1951,6 +1959,7 @@ jump_to_mark(ledit_view *view, char *text, size_t len) {
                (void)text;
                (void)len;
                grab_char_cb = &jump_to_mark_cb;
       +        /* FIXME: should it be discarded here? */
                discard_repetition_stack();
                return (struct action){ACTION_NONE, NULL};
        }
       t@@ -2061,7 +2070,7 @@ search_str_backwards(char *haystack, size_t hlen, char *needle, size_t nlen, siz
                size_t new_index = start_index;
                for (; new_index > 0; new_index--) {
                        if (!strncmp(haystack + new_index - 1, needle, nlen)) {
       -                        *ret = new_index;
       +                        *ret = new_index - 1;
                                return 0;
                        }
                }
       t@@ -2189,6 +2198,7 @@ replace_cb(ledit_view *view, char *text, size_t len) {
                CHECK_VIEW_LOCKED(view);
                size_t start_index = view->cur_index;
                /* FIXME: replace with (key repeat) * text instead of just text */
       +        /* FIXME: cursor pos or char? */
                size_t end_index = view_next_cursor_pos(
                    view, view->cur_line, view->cur_index, 1
                );
       t@@ -2339,7 +2349,10 @@ basic_key_handler(ledit_view *view, XEvent *event, int lang_index) {
        
                if (found && (type & KEY_ENSURE_CURSOR_SHOWN))
                        view_ensure_cursor_shown(view);
       -        if (!found && n > 0)
       +        if (!found && n > 0) {
                        window_show_message(view->window, "Invalid key", -1);
       +                discard_repetition_stack();
       +                clear_key_stack();
       +        }
                return act;
        }
   DIR diff --git a/ledit.1 b/ledit.1
       t@@ -3,6 +3,9 @@
        .\" bigword, etc.
        .\" commands - no good way for mapping found
        .\" difference between unicode char and grapheme
       +.\" x, X currently delete graphemes
       +.\" everything assumed to be utf8
       +.\" marks sometimes char, sometimes line based
        .\"
        .\" WARNING: Some parts of this are stolen shamelessly from OpenBSD's
        .\" vi(1) manpage!
   DIR diff --git a/view.c b/view.c
       t@@ -1191,7 +1191,7 @@ view_delete_range_base(
                size_t new_line = 0, new_byte = 0;
                ledit_assert(line_index1 < view->lines_num);
                ledit_assert(line_index2 < view->lines_num);
       -        ledit_range cur_range = {0, 0, 0, 0};
       +        ledit_range cur_range = {view->cur_line, view->cur_index, 0, 0};
                /* FIXME: could this be simplified by just calculating the range and then using
                   the non-line-based version? */
                if (delmode == DELETE_HARDLINE) {
       t@@ -1443,8 +1443,9 @@ view_delete_range_base(
                            rgl1, rgb1, rgl2, rgb2, text_ret
                        );
                }
       -        cur_range.line1 = view->cur_line;
       -        cur_range.byte1 = view->cur_index;
       +        /* note: line1/byte1 need to be set at the top since deleting text
       +           might change the current line/byte of the view through the notify
       +           functions */
                cur_range.line2 = new_line;
                cur_range.byte2 = new_byte;
                undo_change_last_cur_range(view->buffer->undo, cur_range);