commit 3d0707ecc637d39e0f853d036c592bbcbe7675f7
parent 335e5d61cc5d4876fb7240543fb55afb55f00cfb
Author: lumidify <nobody@lumidify.org>
Date: Fri, 5 Nov 2021 21:04:14 +0100
Implement appending commands
Diffstat:
4 files changed, 74 insertions(+), 1 deletion(-)
diff --git a/buffer.c b/buffer.c
@@ -901,6 +901,22 @@ line_byte_to_char(ledit_line *line, int byte) {
return c;
}
+int
+ledit_buffer_next_cursor_pos(ledit_buffer *buffer, int line, int byte) {
+ int nattrs;
+ ledit_line *ll = ledit_buffer_get_line(buffer, line);
+ int c = line_byte_to_char(ll, byte);
+ int cur_byte = ledit_line_next_utf8(ll, byte);
+ const PangoLogAttr *attrs =
+ pango_layout_get_log_attrs_readonly(ll->layout, &nattrs);
+ for (int i = c + 1; i < nattrs; i++) {
+ if (attrs[i].is_cursor_position)
+ return cur_byte;
+ cur_byte = ledit_line_next_utf8(ll, cur_byte);
+ }
+ return ll->len;
+}
+
static int
line_next_word(ledit_line *line, int byte, int char_index, int wrapped_line, int *char_ret, int *real_byte_ret) {
int c, nattrs;
diff --git a/buffer.h b/buffer.h
@@ -57,7 +57,7 @@ void ledit_pos_to_x_softline(ledit_line *line, int pos, int *x_ret, int *softlin
void ledit_x_softline_to_pos(ledit_line *line, int x, int softline, int *pos_ret);
int ledit_line_next_utf8(ledit_line *line, int index);
int ledit_line_prev_utf8(ledit_line *line, int index);
-int ledit_line_byte_to_char(ledit_line *line, int byte);
+int ledit_buffer_next_cursor_pos(ledit_buffer *buffer, int line, int byte);
void ledit_buffer_next_word(ledit_buffer *buffer, int line, int byte, int num_repeat, int *line_ret, int *byte_ret, int *real_byte_ret);
void ledit_buffer_next_word_end(ledit_buffer *buffer, int line, int byte, int num_repeat, int *line_ret, int *byte_ret, int *real_byte_ret);
diff --git a/keys_basic.c b/keys_basic.c
@@ -396,6 +396,55 @@ get_key_repeat(void) {
return num;
}
+static struct action
+append_line_above(ledit_buffer *buffer, char *text, int len) {
+ int sli, x;
+ /* do this here already so the mode group is the same for the newline insertion */
+ enter_insert(buffer, text, len);
+ ledit_line *ll = ledit_buffer_get_line(buffer, buffer->cur_line);
+ pango_layout_index_to_line_x(ll->layout, buffer->cur_index, 0, &sli, &x);
+ if (sli == 0) {
+ insert_text(buffer, buffer->cur_line, 0, "\n", -1, buffer->cur_line, 0, 1);
+ } else {
+ PangoLayoutLine *sl = pango_layout_get_line_readonly(ll->layout, sli);
+ insert_text(buffer, buffer->cur_line, sl->start_index, "\n\n", -1, buffer->cur_line + 1, 0, 1);
+ }
+ return (struct action){ACTION_NONE, NULL};
+}
+
+static struct action
+append_line_below(ledit_buffer *buffer, char *text, int len) {
+ int sli, x;
+ enter_insert(buffer, text, len);
+ ledit_line *ll = ledit_buffer_get_line(buffer, buffer->cur_line);
+ pango_layout_index_to_line_x(ll->layout, buffer->cur_index, 0, &sli, &x);
+ PangoLayoutLine *sl = pango_layout_get_line_readonly(ll->layout, sli);
+ if (sl->start_index + sl->length == ll->len) {
+ insert_text(buffer, buffer->cur_line, ll->len, "\n", -1, buffer->cur_line + 1, 0, 1);
+ } else {
+ insert_text(buffer, buffer->cur_line, sl->start_index + sl->length, "\n\n", -1, buffer->cur_line + 1, 0, 1);
+ }
+ return (struct action){ACTION_NONE, NULL};
+}
+
+static struct action
+append_after_cursor(ledit_buffer *buffer, char *text, int len) {
+ buffer->cur_index = ledit_buffer_next_cursor_pos(
+ buffer, buffer->cur_line, buffer->cur_index
+ );
+ return enter_insert(buffer, text, len);
+}
+
+static struct action
+append_after_eol(ledit_buffer *buffer, char *text, int len) {
+ int sli, x;
+ ledit_line *ll = ledit_buffer_get_line(buffer, buffer->cur_line);
+ pango_layout_index_to_line_x(ll->layout, buffer->cur_index, 0, &sli, &x);
+ PangoLayoutLine *sl = pango_layout_get_line_readonly(ll->layout, sli);
+ buffer->cur_index = sl->start_index + sl->length;
+ return enter_insert(buffer, text, len);
+}
+
/* FIXME: allow motion callback! */
static struct action
move_to_line(ledit_buffer *buffer, char *text, int len) {
diff --git a/keys_basic_config.h b/keys_basic_config.h
@@ -76,6 +76,10 @@ static struct action next_bigword(ledit_buffer *buffer, char *text, int len);
static struct action next_bigword_end(ledit_buffer *buffer, char *text, int len);
static struct action prev_word(ledit_buffer *buffer, char *text, int len);
static struct action prev_bigword(ledit_buffer *buffer, char *text, int len);
+static struct action append_after_eol(ledit_buffer *buffer, char *text, int len);
+static struct action append_after_cursor(ledit_buffer *buffer, char *text, int len);
+static struct action append_line_above(ledit_buffer *buffer, char *text, int len);
+static struct action append_line_below(ledit_buffer *buffer, char *text, int len);
/* FIXME: maybe sort these and use binary search
-> but that would mess with the catch-all keys */
@@ -143,6 +147,10 @@ static struct key keys_en[] = {
{"G", 0, 0, NORMAL, KEY_ANY, KEY_NUMBERALLOWED, &move_to_line},
{"p", 0, 0, NORMAL, KEY_ANY, KEY_ANY, &paste_normal},
{"P", 0, 0, NORMAL, KEY_ANY, KEY_ANY, &paste_normal_backwards},
+ {"A", 0, 0, NORMAL, KEY_ANY, KEY_ANY, &append_after_eol},
+ {"a", 0, 0, NORMAL, KEY_ANY, KEY_ANY, &append_after_cursor},
+ {"O", 0, 0, NORMAL, KEY_ANY, KEY_ANY, &append_line_above},
+ {"o", 0, 0, NORMAL, KEY_ANY, KEY_ANY, &append_line_below},
{"m", 0, 0, NORMAL, KEY_ANY, KEY_ANY, &mark_line},
{"'", 0, 0, NORMAL, KEY_ANY, KEY_ANY, &jump_to_mark},
{"", 0, 0, INSERT, KEY_ANY, KEY_ANY, &insert_mode_insert_text}