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 60385928394de59d1104da2c69241745cbba4784
parent 32ba7c8e9dbb2f7f4327b2a989e07d02e84ee2e1
Author: lumidify <nobody@lumidify.org>
Date:   Thu, 18 Nov 2021 12:05:36 +0100

Sort of improve Ctrl-d/Ctrl-u

Diffstat:
Mkeys_basic.c | 99+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
1 file changed, 62 insertions(+), 37 deletions(-)

diff --git a/keys_basic.c b/keys_basic.c @@ -121,6 +121,7 @@ static void get_new_line_softline( 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); static void push_undo_empty_insert(ledit_buffer *buffer, int line, int index, int start_group); +static void move_half_screen(ledit_buffer *buffer, int movement); /* FIXME: move to common */ static void @@ -644,35 +645,37 @@ move_to_line(ledit_buffer *buffer, char *text, int len) { /* FIXME: should these scrolling functions change behavior when hard_line_based == 1? */ static void scroll_lines(ledit_buffer *buffer, int lines, int dir) { - int final_lines; - int text_w, text_h; - ledit_line *ll = ledit_buffer_get_line(buffer, buffer->cur_line); - int x, y, h, sli; - ledit_buffer_get_cursor_pixel_pos(buffer, buffer->cur_line, buffer->cur_index, &x, &y, &h); - /* get the middle position of char */ - ledit_pos_to_x_softline(ll, buffer->cur_index, &x, &sli); - long abs_pos = ll->y_offset + y; - ledit_window_get_textview_size(buffer->window, &text_w, &text_h); - if (lines > 0) - final_lines = last_lines_scrolled = lines; - else if (last_lines_scrolled > 0) - final_lines = last_lines_scrolled; - else - final_lines = text_h / h / 2; - ledit_buffer_wipe_line_cursor_attrs(buffer, buffer->cur_line); - get_new_line_softline( - buffer, buffer->cur_line, buffer->cur_index, - dir < 0 ? -final_lines : final_lines, - &buffer->cur_line, &sli - ); - int start, end; - ledit_buffer_get_softline_bounds(buffer, buffer->cur_line, sli, &start, &end); - ll = ledit_buffer_get_line(buffer, buffer->cur_line); - ledit_x_softline_to_pos(ll, x, sli, &buffer->cur_index); - ledit_buffer_get_cursor_pixel_pos(buffer, buffer->cur_line, buffer->cur_index, &x, &y, &h); - long new_abs_pos = ll->y_offset + y; - ledit_buffer_scroll(buffer, buffer->display_offset + (new_abs_pos - abs_pos)); - ledit_buffer_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->cur_index); + if (last_lines_scrolled <= 0 && lines <= 0) { + /* no scroll command yet - scroll half of screen */ + move_half_screen(buffer, dir); + } else { + int x, y, h, sli; + int final_lines, text_w, text_h; + ledit_line *ll = ledit_buffer_get_line(buffer, buffer->cur_line); + ledit_buffer_get_cursor_pixel_pos(buffer, buffer->cur_line, buffer->cur_index, &x, &y, &h); + /* get the middle position of char */ + ledit_pos_to_x_softline(ll, buffer->cur_index, &x, &sli); + long abs_pos = ll->y_offset + y; + ledit_window_get_textview_size(buffer->window, &text_w, &text_h); + if (lines > 0) + final_lines = last_lines_scrolled = lines; + else + final_lines = last_lines_scrolled; + ledit_buffer_wipe_line_cursor_attrs(buffer, buffer->cur_line); + get_new_line_softline( + buffer, buffer->cur_line, buffer->cur_index, + dir < 0 ? -final_lines : final_lines, + &buffer->cur_line, &sli + ); + int start, end; + ledit_buffer_get_softline_bounds(buffer, buffer->cur_line, sli, &start, &end); + ll = ledit_buffer_get_line(buffer, buffer->cur_line); + ledit_x_softline_to_pos(ll, x, sli, &buffer->cur_index); + ledit_buffer_get_cursor_pixel_pos(buffer, buffer->cur_line, buffer->cur_index, &x, &y, &h); + long new_abs_pos = ll->y_offset + y; + ledit_buffer_scroll(buffer, buffer->display_offset + (new_abs_pos - abs_pos)); + ledit_buffer_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->cur_index); + } } static struct action @@ -756,29 +759,51 @@ scroll_with_cursor_down(ledit_buffer *buffer, char *text, int len) { return (struct action){ACTION_NONE, NULL}; } -/* movement is multiplied with the window height and the result is added to the display offset +/* movement is multiplied with half the window height and the result is added to the display offset the cursor is moved to the bottom if movement is upwards, to the top otherwise + FIXME: this is slightly different now (unless the screen is already at the very top or bottom - then it is the other way around) */ +/* FIXME: this is a bit weird at the moment */ static void -move_screen(ledit_buffer *buffer, int movement) { +move_half_screen(ledit_buffer *buffer, int movement) { int w, h; ledit_window_get_textview_size(buffer->window, &w, &h); /* FIXME: overflow */ - long total = movement * (long)h; + int total = movement * h/2; + ledit_line *ll = ledit_buffer_get_line(buffer, buffer->cur_line); + int cur_x, cur_y, cur_h; + ledit_buffer_get_cursor_pixel_pos( + buffer, buffer->cur_line, buffer->cur_index, &cur_x, &cur_y, &cur_h + ); + long real_cur_y = ll->y_offset - buffer->display_offset + cur_y; /* new pixel position of cursor */ /* Note: this usually causes at least part of a line of overlap because ensure_cursor_shown scrolls back a bit if the line isn't completely shown (this behavior could be changed using ledit_buffer_get_nearest_legal_pos) */ int y = movement > 0 ? 0 : h; - if (buffer->display_offset + total < 0) + int half_screen = abs(movement) % 2 == 1; + if (half_screen) { + /* if only half screens are moved and we are at the beginning or + end, just move the cursor the movement amount instead of + moving it to the very top or bottom */ + if (buffer->display_offset + total <= 0 || + buffer->display_offset + total + h >= buffer->total_height) { + y = real_cur_y + total; + } + } else { + if (buffer->display_offset + total <= 0) + y = 0; + else if (buffer->display_offset + total + h > buffer->total_height) + y = h; + } + if (y < 0) y = 0; - else if (buffer->display_offset + total + h > buffer->total_height) + if (y > h) y = h; ledit_buffer_scroll(buffer, buffer->display_offset + total); ledit_buffer_wipe_line_cursor_attrs(buffer, buffer->cur_line); /* try to keep current x position of cursor */ - ledit_line *ll = ledit_buffer_get_line(buffer, buffer->cur_line); int x, softline; /* FIXME: properly document what uses PANGO_SCALE and what not */ ledit_pos_to_x_softline(ll, buffer->cur_index, &x, &softline); @@ -795,7 +820,7 @@ screen_up(ledit_buffer *buffer, char *text, int len) { (void)len; int repeat = get_key_repeat(); if (repeat >= 0) - move_screen(buffer, -(repeat == 0 ? 1 : repeat)); + move_half_screen(buffer, -(repeat == 0 ? 2 : repeat*2)); else ledit_window_show_message(buffer->window, "Invalid key", -1); discard_repetition_stack(); @@ -808,7 +833,7 @@ screen_down(ledit_buffer *buffer, char *text, int len) { (void)len; int repeat = get_key_repeat(); if (repeat >= 0) - move_screen(buffer, repeat == 0 ? 1 : repeat); + move_half_screen(buffer, repeat == 0 ? 2 : repeat*2); else ledit_window_show_message(buffer->window, "Invalid key", -1); discard_repetition_stack();