commit b7dc5c71dceb3a26368fc7d027053378a5828463
parent 7f10c769894b662194bf2fd54bc159647e012bf9
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:
5 files changed, 43 insertions(+), 29 deletions(-)
diff --git a/.buffer.c.swp b/.buffer.c.swp
Binary files differ.
diff --git a/.keys_basic.c.swp b/.keys_basic.c.swp
Binary files differ.
diff --git a/buffer.c b/buffer.c
@@ -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"
@@ -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;
@@ -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;
@@ -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;
}
@@ -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;
diff --git a/keys_basic.c b/keys_basic.c
@@ -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>
@@ -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)
@@ -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;
@@ -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);
}
diff --git a/keys_basic_config.h b/keys_basic_config.h
@@ -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},