commit b4ed6ddf9920d90814860156ed32a40404ece243
parent 3895a14f2fb3bcc35ba842e259074a67adddb8a1
Author: lumidify <nobody@lumidify.org>
Date:   Fri, 14 May 2021 21:22:31 +0200
Fix positioning of cursor after deleting characters
Diffstat:
| M | buffer.c |  |  | 28 | +++++++++++++++++++--------- | 
1 file changed, 19 insertions(+), 9 deletions(-)
diff --git a/buffer.c b/buffer.c
@@ -494,15 +494,6 @@ ledit_delete_range(
 			}
 			delete_line_section(buffer, line_index1, b1, b2 - b1);
 			*new_line_ret = line_index1;
-			ledit_line *ll = ledit_get_line(buffer, line_index1);
-			/* FIXME: where should this be done? */
-			/* FIXME: also do this below in the else statement */
-			if (buffer->state->mode == NORMAL && b1 == ll->len && b1 > 0) {
-				/* FIXME: use grapheme instead of character! */
-				b1 = ll->len - 1;
-				while (b1 > 0 && ((ll->text[b1] & 0xC0) == 0x80))
-					b1--;
-			}
 			*new_byte_ret = b1;
 		} else {
 			int l1, l2, b1, b2;
@@ -531,5 +522,24 @@ ledit_delete_range(
 			*new_byte_ret = b1;
 			ledit_delete_line_entries(buffer, l1 + 1, l2);
 		}
+		/* move back one grapheme if at end of line and in normal mode */
+		ledit_line *final_line = ledit_get_line(buffer, *new_line_ret);
+		if (buffer->state->mode == NORMAL &&
+		    *new_byte_ret == final_line->len &&
+		    *new_byte_ret > 0) {
+			int nattrs;
+			const PangoLogAttr *attrs =
+			    pango_layout_get_log_attrs_readonly(final_line->layout, &nattrs);
+			int cur = nattrs - 2;
+			(*new_byte_ret)--;
+			while (*new_byte_ret > 0 && ((final_line->text[*new_byte_ret] & 0xC0) == 0x80))
+				(*new_byte_ret)--;
+			while (*new_byte_ret > 0 && cur > 0 && !attrs[cur].is_cursor_position) {
+				cur--;
+				(*new_byte_ret)--;
+				while (*new_byte_ret > 0 && ((final_line->text[*new_byte_ret] & 0xC0) == 0x80))
+					(*new_byte_ret)--;
+			}
+		}
 	}
 }