URI: 
       tFix various issues with selection; fix escape key in normal mode - 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 b7dc5c71dceb3a26368fc7d027053378a5828463
   DIR parent 7f10c769894b662194bf2fd54bc159647e012bf9
  HTML Author: lumidify <nobody@lumidify.org>
       Date:   Tue,  2 Nov 2021 11:05:18 +0100
       
       Fix various issues with selection; fix escape key in normal mode
       
       Diffstat:
         D .buffer.c.swp                       |       0 
         D .keys_basic.c.swp                   |       0 
         M buffer.c                            |      57 ++++++++++++++++++-------------
         M keys_basic.c                        |      13 +++++++++----
         M keys_basic_config.h                 |       2 +-
       
       5 files changed, 43 insertions(+), 29 deletions(-)
       ---
   DIR diff --git a/.buffer.c.swp b/.buffer.c.swp
       Binary files differ.
   DIR diff --git a/.keys_basic.c.swp b/.keys_basic.c.swp
       Binary files differ.
   DIR diff --git a/buffer.c b/buffer.c
       t@@ -13,6 +13,7 @@
        #include <pango/pangoxft.h>
        #include <X11/extensions/Xdbe.h>
        
       +#include "pango-compat.h"
        #include "memory.h"
        #include "common.h"
        #include "txtbuf.h"
       t@@ -1608,21 +1609,24 @@ ledit_buffer_set_selection(ledit_buffer *buffer, int line1, int byte1, int line2
                                        ledit_buffer_wipe_line_cursor_attrs(buffer, i);
                                }
                        }
       -                if (l1_new == l2_new) {
       -                        ledit_buffer_set_line_selection(buffer, l1_new, b1_new, b2_new);
       -                } else {
       -                        ledit_line *ll1 = ledit_buffer_get_line(buffer, l1_new);
       -                        ledit_buffer_set_line_selection(buffer, l1_new, b1_new, ll1->len);
       -                        ledit_buffer_set_line_selection(buffer, l2_new, 0, b2_new);
       -                        /* FIXME: optimize this */
       -                        for (int i = l1_new + 1; i < l2_new; i++) {
       -                                if (i <= buffer->sel.line1 || i >= buffer->sel.line2) {
       -                                        ledit_line *llx = ledit_buffer_get_line(buffer, i);
       -                                        ledit_buffer_set_line_selection(buffer, i, 0, llx->len);
       +                if (l1_new >= 0 && l2_new >= 0) {
       +                        if (l1_new == l2_new) {
       +                                ledit_buffer_set_line_selection(buffer, l1_new, b1_new, b2_new);
       +                        } else {
       +                                ledit_line *ll1 = ledit_buffer_get_line(buffer, l1_new);
       +                                ledit_buffer_set_line_selection(buffer, l1_new, b1_new, ll1->len);
       +                                ledit_buffer_set_line_selection(buffer, l2_new, 0, b2_new);
       +                                /* FIXME: optimize this */
       +                                for (int i = l1_new + 1; i < l2_new; i++) {
       +                                        if (i <= buffer->sel.line1 || i >= buffer->sel.line2) {
       +                                                ledit_line *llx = ledit_buffer_get_line(buffer, i);
       +                                                ledit_buffer_set_line_selection(buffer, i, 0, llx->len);
       +                                        }
                                        }
                                }
       +                        if (l1_new != l2_new || b1_new != b2_new)
       +                                copy_selection_to_x_primary(buffer, l1_new, b1_new, l2_new, b2_new);
                        }
       -                copy_selection_to_x_primary(buffer, l1_new, b1_new, l2_new, b2_new);
                }
                buffer->sel.line1 = line1;
                buffer->sel.byte1 = byte1;
       t@@ -1643,18 +1647,13 @@ ledit_buffer_button_handler(void *data, XEvent *event) {
                int y = event->xbutton.y;
                switch (event->type) {
                case ButtonPress:
       -                ledit_xy_to_line_byte(buffer, x, y, 1, &l, &b);
       -                ledit_buffer_set_selection(buffer, l, b, l, b);
       -                if (buffer->common->mode == NORMAL) {
       -                        ledit_buffer_wipe_line_cursor_attrs(buffer, buffer->cur_line);
       -                        /* FIXME: only set mode after dragging/when something is selected? */
       -                        /* -> return to old mode afterwards? */
       -                        /* should change_mode_group even be called here? */
       -                        ledit_buffer_set_mode(buffer, VISUAL);
       -                }
       +                ledit_xy_to_line_byte(buffer, x, y, 0,  &l, &b);
       +                buffer->selecting = 1;
                        buffer->cur_line = l;
                        buffer->cur_index = b;
       -                buffer->selecting = 1;
       +                ledit_buffer_set_selection(buffer, -1, -1, -1, -1);
       +                if (buffer->common->mode == NORMAL)
       +                        ledit_buffer_set_line_cursor_attrs(buffer, l, b);
                        break;
                case ButtonRelease:
                        buffer->selecting = 0;
       t@@ -1663,7 +1662,17 @@ ledit_buffer_button_handler(void *data, XEvent *event) {
                        if (buffer->selecting) {
                                y = y >= 0 ? y : 0;
                                ledit_xy_to_line_byte(buffer, x, y, 1, &l, &b);
       -                        ledit_buffer_set_selection(buffer, buffer->sel.line1, buffer->sel.byte1, l, b);
       +                        if (buffer->sel.line1 < 0 || buffer->sel.byte1 < 0) {
       +                                ledit_buffer_set_selection(buffer, l, b, l, b);
       +                        } else {
       +                                ledit_buffer_set_selection(buffer, buffer->sel.line1, buffer->sel.byte1, l, b);
       +                        }
       +                        if (buffer->common->mode == NORMAL) {
       +                                ledit_buffer_wipe_line_cursor_attrs(buffer, buffer->cur_line);
       +                                /* FIXME: return to old mode afterwards? */
       +                                /* should change_mode_group even be called here? */
       +                                ledit_buffer_set_mode(buffer, VISUAL);
       +                        }
                                buffer->cur_line = l;
                                buffer->cur_index = b;
                        }
       t@@ -1733,7 +1742,7 @@ ledit_buffer_redraw(ledit_buffer *buffer) {
                                int box_x = strong.x / PANGO_SCALE;
                                int box_w = 10;
                                /* determine where the box should be drawn */
       -                        PangoDirection dir = PANGO_DIRECTION_RTL;
       +                        PangoDirection dir = PANGO_DIRECTION_LTR;
                                int tmp_index = buffer->cur_index;
                                if (buffer->cur_index >= cur_line->len)
                                        tmp_index = cur_line->len - 1;
   DIR diff --git a/keys_basic.c b/keys_basic.c
       t@@ -3,6 +3,10 @@
        /* FIXME: use weak cursor */
        /* FIXME: spaces at end of soft line are weird in bidi text
           -> space is hidden when e.g. ltr text left and rtl text on right is wrapped */
       +/* FIXME: some weird things still happen with selections staying as "ghosts"
       +   and being deleted at some later time even though they're not shown anymore */
       +/* FIXME: there seem to be some issues with undo, but I couldn't reproduce
       +   them reliably yet */
        #include <stdio.h>
        #include <stdlib.h>
        
       t@@ -1164,7 +1168,7 @@ move_cursor_in_line_dir(ledit_buffer *buffer, int movement_dir, int allow_illega
        
        static void
        move_cursor_logically(ledit_buffer *buffer, int movement_dir, int allow_illegal_index) {
       -        PangoDirection dir = PANGO_DIRECTION_RTL;
       +        PangoDirection dir = PANGO_DIRECTION_LTR;
                int tmp_index = buffer->cur_index;
                ledit_line *cur_line = ledit_buffer_get_line(buffer, buffer->cur_line);
                if (buffer->cur_index >= cur_line->len)
       t@@ -1188,16 +1192,15 @@ static struct action
        escape_key(ledit_buffer *buffer, char *text, int len) {
                (void)text;
                (void)len;
       -        clear_key_stack(); /* just in case... */
       +        clear_key_stack();
                if (buffer->common->mode == INSERT)
                        finalize_repetition_stack();
                if (buffer->common->mode == INSERT &&
                    (buffer->sel.line1 != buffer->sel.line2 ||
                     buffer->sel.byte1 != buffer->sel.byte2)) {
                        ledit_buffer_set_mode(buffer, VISUAL);
       -        } else {
       +        } else if (buffer->common->mode != NORMAL) {
                        ledit_buffer_set_mode(buffer, NORMAL);
       -                clear_key_stack();
                        move_cursor_logically(buffer, -1, 0);
                        if (buffer->sel.line1 != buffer->sel.line2) {
                                int min = buffer->sel.line1 < buffer->sel.line2 ? buffer->sel.line1 : buffer->sel.line2;
       t@@ -1206,6 +1209,8 @@ escape_key(ledit_buffer *buffer, char *text, int len) {
                                        ledit_buffer_wipe_line_cursor_attrs(buffer, i);
                                }
                        }
       +                buffer->sel.line1 = buffer->sel.line2 = -1;
       +                buffer->sel.byte1 = buffer->sel.byte2 = -1;
                        /* FIXME: optimize this to avoid first wiping and then setting the attrs */
                        ledit_buffer_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->cur_index);
                }
   DIR diff --git a/keys_basic_config.h b/keys_basic_config.h
       t@@ -79,7 +79,7 @@ static struct key keys_en[] = {
                {NULL, 0, XK_Down, VISUAL|INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_down},
                {NULL, 0, XK_Return, INSERT, KEY_ANY, KEY_ANY, &return_key},
                {NULL, 0, XK_Delete, INSERT, KEY_ANY, KEY_ANY, &delete_key},
       -        {NULL, 0, XK_Escape, VISUAL|INSERT, KEY_ANY, KEY_ANY, &escape_key},
       +        {NULL, 0, XK_Escape, NORMAL|VISUAL|INSERT, KEY_ANY, KEY_ANY, &escape_key},
                {"i",  0, 0, NORMAL|VISUAL, KEY_ANY, KEY_ANY, &enter_insert},
                {"h",  0, 0, NORMAL|VISUAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_left},
                {"l",  0, 0, NORMAL|VISUAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_right},