ledit

Text editor (WIP)
git clone git://lumidify.org/ledit.git (fast, but not encrypted)
git clone https://lumidify.org/git/ledit.git (encrypted, but very slow)
Log | Files | Refs | README | LICENSE

commit 3d0707ecc637d39e0f853d036c592bbcbe7675f7
parent 335e5d61cc5d4876fb7240543fb55afb55f00cfb
Author: lumidify <nobody@lumidify.org>
Date:   Fri,  5 Nov 2021 21:04:14 +0100

Implement appending commands

Diffstat:
Mbuffer.c | 16++++++++++++++++
Mbuffer.h | 2+-
Mkeys_basic.c | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Mkeys_basic_config.h | 8++++++++
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}