URI: 
       tImplement Ctrl-u and Ctrl-d - 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 1055b60d3977134356fbeb8f0d1abfff4d05f3f9
   DIR parent 00de6deacf3f962dbf3b3d89926fe69798ad2893
  HTML Author: lumidify <nobody@lumidify.org>
       Date:   Mon,  1 Nov 2021 09:37:26 +0100
       
       Implement Ctrl-u and Ctrl-d
       
       Diffstat:
         M keys_basic.c                        |      72 ++++++++++++++++++++++++++++---
         M keys_basic_config.h                 |       4 ++++
       
       2 files changed, 70 insertions(+), 6 deletions(-)
       ---
   DIR diff --git a/keys_basic.c b/keys_basic.c
       t@@ -26,7 +26,8 @@
        #include "keys_basic_config.h"
        
        /* this is supposed to be global for all buffers */
       -txtbuf *paste_buffer = NULL;
       +static txtbuf *paste_buffer = NULL;
       +static int last_lines_scrolled = -1;
        
        struct repetition_stack_elem {
                char *key_text;
       t@@ -347,7 +348,10 @@ delete_selection(ledit_buffer *buffer) {
           invalid was on the stack - this is for commands that just take a repeat
           count and nothing else (cursor movement keys are different because they
           can use other elements on the key stack too, for instance call a callback
       -   as is done for deletion */
       +   as is done for deletion
       +   Note that an empty stack leads to 0 being returned even though most commands
       +   use 1 as repeat then so the caller can distinguish between empty stack and
       +   a repetition count of 1 */
        static int
        get_key_repeat(void) {
                int num = 1;
       t@@ -363,12 +367,68 @@ get_key_repeat(void) {
                                   element under it on the stack -> error */
                                num = -1;
                        }
       +        } else {
       +                num = 0;
                }
                clear_key_stack();
                return num;
        }
        
        static void
       +scroll_lines(ledit_buffer *buffer, int lines, int dir) {
       +        int final_lines;
       +        int text_w, text_h;
       +        PangoRectangle strong, weak;
       +        ledit_line *ll = ledit_buffer_get_line(buffer, buffer->cur_line);
       +        pango_layout_get_cursor_pos(ll->layout, buffer->cur_index, &strong, &weak);
       +        long abs_pos = ll->y_offset + strong.y / PANGO_SCALE;
       +        ledit_window_get_textview_size(buffer->window, &text_w, &text_h);
       +        if (lines > 0)
       +                final_lines = last_lines_scrolled = lines;
       +        else if (last_lines_scrolled > 0)
       +                final_lines = last_lines_scrolled;
       +        else
       +                final_lines = text_h / (strong.height / PANGO_SCALE);
       +        ledit_buffer_wipe_line_cursor_attrs(buffer, buffer->cur_line);
       +        get_new_line_softline(
       +            buffer, buffer->cur_line, buffer->cur_index,
       +            dir < 0 ? -final_lines : final_lines,
       +            &buffer->cur_line, &buffer->cur_index
       +        );
       +        ll = ledit_buffer_get_line(buffer, buffer->cur_line);
       +        pango_layout_get_cursor_pos(ll->layout, buffer->cur_index, &strong, &weak);
       +        long new_abs_pos = ll->y_offset + strong.y / PANGO_SCALE;
       +        ledit_buffer_scroll(buffer, buffer->display_offset + (new_abs_pos - abs_pos));
       +        ledit_buffer_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->cur_index);
       +}
       +
       +static struct action
       +scroll_lines_up(ledit_buffer *buffer, char *text, int len) {
       +        (void)text;
       +        (void)len;
       +        int repeat = get_key_repeat();
       +        if (repeat >= 0)
       +                scroll_lines(buffer, repeat, -1);
       +        else
       +                ledit_window_show_message(buffer->window, "Invalid key", -1);
       +        discard_repetition_stack();
       +        return (struct action){ACTION_NONE, NULL};
       +}
       +
       +static struct action
       +scroll_lines_down(ledit_buffer *buffer, char *text, int len) {
       +        (void)text;
       +        (void)len;
       +        int repeat = get_key_repeat();
       +        if (repeat >= 0)
       +                scroll_lines(buffer, repeat, 1);
       +        else
       +                ledit_window_show_message(buffer->window, "Invalid key", -1);
       +        discard_repetition_stack();
       +        return (struct action){ACTION_NONE, NULL};
       +}
       +
       +static void
        scroll_with_cursor(ledit_buffer *buffer, int movement) {
                PangoRectangle strong, weak;
                ledit_line *ll = ledit_buffer_get_line(buffer, buffer->cur_line);
       t@@ -404,7 +464,7 @@ scroll_with_cursor_up(ledit_buffer *buffer, char *text, int len) {
                (void)len;
                int repeat = get_key_repeat();
                if (repeat >= 0)
       -                scroll_with_cursor(buffer, -repeat);
       +                scroll_with_cursor(buffer, -(repeat == 0 ? 1 : repeat));
                else
                        ledit_window_show_message(buffer->window, "Invalid key", -1);
                discard_repetition_stack();
       t@@ -417,7 +477,7 @@ scroll_with_cursor_down(ledit_buffer *buffer, char *text, int len) {
                (void)len;
                int repeat = get_key_repeat();
                if (repeat >= 0)
       -                scroll_with_cursor(buffer, repeat);
       +                scroll_with_cursor(buffer, repeat == 0 ? 1 : repeat);
                else
                        ledit_window_show_message(buffer->window, "Invalid key", -1);
                discard_repetition_stack();
       t@@ -463,7 +523,7 @@ screen_up(ledit_buffer *buffer, char *text, int len) {
                (void)len;
                int repeat = get_key_repeat();
                if (repeat >= 0)
       -                move_screen(buffer, -repeat);
       +                move_screen(buffer, -(repeat == 0 ? 1 : repeat));
                else
                        ledit_window_show_message(buffer->window, "Invalid key", -1);
                discard_repetition_stack();
       t@@ -476,7 +536,7 @@ screen_down(ledit_buffer *buffer, char *text, int len) {
                (void)len;
                int repeat = get_key_repeat();
                if (repeat >= 0)
       -                move_screen(buffer, repeat);
       +                move_screen(buffer, repeat == 0 ? 1 : repeat);
                else
                        ledit_window_show_message(buffer->window, "Invalid key", -1);
                discard_repetition_stack();
   DIR diff --git a/keys_basic_config.h b/keys_basic_config.h
       t@@ -61,6 +61,8 @@ static struct action screen_up(ledit_buffer *buffer, char *text, int len);
        static struct action screen_down(ledit_buffer *buffer, char *text, int len);
        static struct action scroll_with_cursor_up(ledit_buffer *buffer, char *text, int len);
        static struct action scroll_with_cursor_down(ledit_buffer *buffer, char *text, int len);
       +static struct action scroll_lines_up(ledit_buffer *buffer, char *text, int len);
       +static struct action scroll_lines_down(ledit_buffer *buffer, char *text, int len);
        
        /* FIXME: maybe sort these and use binary search
           -> but that would mess with the catch-all keys */
       t@@ -110,6 +112,8 @@ static struct key keys_en[] = {
                {"f",  ControlMask, 0, NORMAL, KEY_ANY, KEY_NUMBERALLOWED, &screen_down},
                {"e",  ControlMask, 0, NORMAL, KEY_ANY, KEY_NUMBERALLOWED, &scroll_with_cursor_down},
                {"y",  ControlMask, 0, NORMAL, KEY_ANY, KEY_NUMBERALLOWED, &scroll_with_cursor_up},
       +        {"d",  ControlMask, 0, NORMAL, KEY_ANY, KEY_NUMBERALLOWED, &scroll_lines_down},
       +        {"u",  ControlMask, 0, NORMAL, KEY_ANY, KEY_NUMBERALLOWED, &scroll_lines_up},
                {"", 0, 0, INSERT, KEY_ANY, KEY_ANY, &insert_mode_insert_text}
        };