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 f12812ad75c528b59aaf96791c48e3940c9e888c
parent 67de119de536bb598da9aba39ecfdde09562a8d3
Author: lumidify <nobody@lumidify.org>
Date:   Mon,  1 Nov 2021 21:29:42 +0100

Add buggy implementation of '$'

Diffstat:
Mbuffer.c | 23+++++++++++++++++------
Mkeys_basic.c | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Mkeys_basic_config.h | 2++
3 files changed, 88 insertions(+), 10 deletions(-)

diff --git a/buffer.c b/buffer.c @@ -1723,12 +1723,23 @@ ledit_buffer_redraw(ledit_buffer *buffer) { /* FIXME: long, int, etc. */ int cursor_y = strong.y / PANGO_SCALE + cur_line_y; if (cursor_displayed && cursor_y >= 0) { - if (buffer->common->mode == NORMAL && buffer->cur_index == cur_line->len) { - XFillRectangle( - buffer->common->dpy, buffer->window->drawable, buffer->window->gc, - strong.x / PANGO_SCALE, cursor_y, - 10, strong.height / PANGO_SCALE - ); + if (buffer->common->mode == NORMAL) { + /* FIXME: figure out if there's a better way to do this */ + /* Seriously, which of the pango folks though it would be a good idea to + not highlight spaces at the end of soft lines? That is an utterly + horrible idea. Or am I just too stupid to use it properly? */ + int x, sli; + pango_layout_index_to_line_x(cur_line->layout, buffer->cur_index, 0, &sli, &x); + PangoLayoutLine *sl = pango_layout_get_line_readonly(cur_line->layout, sli); + if (buffer->cur_index == cur_line->len || + (cur_line->text[buffer->cur_index] == ' ' && + buffer->cur_index == sl->start_index + sl->length - 1)) { + XFillRectangle( + buffer->common->dpy, buffer->window->drawable, buffer->window->gc, + strong.x / PANGO_SCALE, cursor_y, + 10, strong.height / PANGO_SCALE + ); + } } else if (buffer->common->mode == INSERT || buffer->common->mode == VISUAL) { XDrawLine( buffer->common->dpy, buffer->window->drawable, buffer->window->gc, diff --git a/keys_basic.c b/keys_basic.c @@ -1,4 +1,8 @@ /* FIXME: cursor isn't shown on spaces at end of softlines */ +/* FIXME: selection is sometimes not reset when it is "clicked away" */ +/* 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 */ #include <stdio.h> #include <stdlib.h> @@ -101,6 +105,7 @@ static void get_new_line_softline( ledit_buffer *buffer, int cur_line, int cur_index, int movement, int *new_line_ret, int *new_softline_ret ); +static void move_cursor_in_line_dir(ledit_buffer *buffer, int dir, int allow_illegal_index); static void move_cursor_logically(ledit_buffer *buffer, int movement_dir, int allow_illegal_index); static void change_cb(ledit_buffer *buffer, int line, int char_pos, enum key_type type); @@ -371,8 +376,7 @@ get_key_repeat(void) { struct key_stack_elem *e = pop_key_stack(); if (e != NULL) { if (e->key & KEY_NUMBER) { - /* FIXME: why did I do this? */ - num = e->count > 0 ? e->count : 0; + num = e->count > 0 ? e->count : 1; e = pop_key_stack(); } if (e != NULL) { @@ -589,6 +593,7 @@ screen_down(ledit_buffer *buffer, char *text, int len) { } /* FIXME: clear selection on most commands */ +/* FIXME: don't include escape when repeating change with '.'? */ static struct action change(ledit_buffer *buffer, char *text, int len) { (void)text; @@ -986,13 +991,52 @@ delete_key(ledit_buffer *buffer, char *text, int len) { return (struct action){ACTION_NONE, NULL}; } +static struct action +move_to_eol(ledit_buffer *buffer, char *text, int len) { + (void)text; + (void)len; + int num = 1; + struct key_stack_elem *e = pop_key_stack(); + if (e != NULL) { + if (e->key & KEY_NUMBER) { + num = e->count > 0 ? e->count : 1; + e = pop_key_stack(); + } + if (e != NULL) + num *= (e->count > 0 ? e->count : 1); + } + ledit_buffer_wipe_line_cursor_attrs(buffer, buffer->cur_line); + int new_line, new_softline; + get_new_line_softline( + buffer, buffer->cur_line, buffer->cur_index, num - 1, + &new_line, &new_softline + ); + ledit_line *ll = ledit_buffer_get_line(buffer, new_line); + PangoLayoutLine *sl = pango_layout_get_line_readonly(ll->layout, new_softline); + int end_index = sl->start_index + sl->length; + if (e != NULL && e->motion_cb != NULL) { + e->motion_cb(buffer, new_line, end_index, KEY_MOTION_CHAR); + } else { + buffer->cur_line = new_line; + buffer->cur_index = end_index; + if (buffer->common->mode == VISUAL) { + ledit_buffer_set_selection(buffer, buffer->sel.line1, buffer->sel.byte1, new_line, end_index); + } else { + /* FIXME: this is still kind of weird with mixed bidi text */ + move_cursor_in_line_dir(buffer, -1, 0); + } + } + ledit_buffer_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->cur_index); + return (struct action){ACTION_NONE, NULL}; +} + static void move_cursor_left_right(ledit_buffer *buffer, int dir, int allow_illegal_index) { int num = 1; struct key_stack_elem *e = pop_key_stack(); if (e != NULL) { if (e->key & KEY_NUMBER) { - num = e->count > 0 ? e->count : 0; + num = e->count > 0 ? e->count : 1; e = pop_key_stack(); } if (e != NULL) @@ -1150,6 +1194,27 @@ pango_layout_get_direction(PangoLayout *layout, int index) { #endif static void +move_cursor_in_line_dir(ledit_buffer *buffer, int movement_dir, int allow_illegal_index) { + PangoDirection dir; + int x, sli; + ledit_line *cur_line = ledit_buffer_get_line(buffer, buffer->cur_line); + pango_layout_index_to_line_x(cur_line->layout, buffer->cur_index, 0, &sli, &x); + PangoLayoutLine *sl = pango_layout_get_line_readonly(cur_line->layout, sli); + dir = sl->resolved_dir; + if (dir == PANGO_DIRECTION_RTL || dir == PANGO_DIRECTION_WEAK_RTL) { + if (movement_dir < 0) + move_cursor_left_right(buffer, 1, allow_illegal_index); + else + move_cursor_left_right(buffer, -1, allow_illegal_index); + } else { + if (movement_dir < 0) + move_cursor_left_right(buffer, -1, allow_illegal_index); + else + move_cursor_left_right(buffer, 1, allow_illegal_index); + } +} + +static void move_cursor_logically(ledit_buffer *buffer, int movement_dir, int allow_illegal_index) { PangoDirection dir = PANGO_DIRECTION_RTL; int tmp_index = buffer->cur_index; @@ -1219,7 +1284,7 @@ move_cursor_up_down(ledit_buffer *buffer, int dir) { struct key_stack_elem *e = pop_key_stack(); if (e != NULL) { if (e->key & KEY_NUMBER) { - num = e->count > 0 ? e->count : 0; + num = e->count > 0 ? e->count : 1; e = pop_key_stack(); } if (e != NULL) diff --git a/keys_basic_config.h b/keys_basic_config.h @@ -67,6 +67,7 @@ static struct action move_to_line(ledit_buffer *buffer, char *text, int len); static struct action paste_normal(ledit_buffer *buffer, char *text, int len); static struct action paste_normal_backwards(ledit_buffer *buffer, char *text, int len); static struct action change(ledit_buffer *buffer, char *text, int len); +static struct action move_to_eol(ledit_buffer *buffer, char *text, int len); /* FIXME: maybe sort these and use binary search -> but that would mess with the catch-all keys */ @@ -124,6 +125,7 @@ static struct key keys_en[] = { {"y", ControlMask, 0, NORMAL, KEY_ANY, KEY_NUMBERALLOWED, &scroll_with_cursor_up}, {"d", ControlMask, 0, NORMAL, KEY_ANY, KEY_NUMBERALLOWED, &scroll_lines_down}, {"u", ControlMask, 0, NORMAL, KEY_ANY, KEY_NUMBERALLOWED, &scroll_lines_up}, + {"$", 0, 0, NORMAL|VISUAL, KEY_ANY, KEY_NUMBERALLOWED, &move_to_eol}, {"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},