commit 1055b60d3977134356fbeb8f0d1abfff4d05f3f9
parent 00de6deacf3f962dbf3b3d89926fe69798ad2893
Author: lumidify <nobody@lumidify.org>
Date: Mon, 1 Nov 2021 09:37:26 +0100
Implement Ctrl-u and Ctrl-d
Diffstat:
2 files changed, 70 insertions(+), 6 deletions(-)
diff --git a/keys_basic.c b/keys_basic.c
@@ -26,7 +26,8 @@
#include "keys_basic_config.h"
/* this is supposed to be global for all buffers */
-txtbuf *paste_buffer = NULL;
+static txtbuf *paste_buffer = NULL;
+static int last_lines_scrolled = -1;
struct repetition_stack_elem {
char *key_text;
@@ -347,7 +348,10 @@ delete_selection(ledit_buffer *buffer) {
invalid was on the stack - this is for commands that just take a repeat
count and nothing else (cursor movement keys are different because they
can use other elements on the key stack too, for instance call a callback
- as is done for deletion */
+ as is done for deletion
+ Note that an empty stack leads to 0 being returned even though most commands
+ use 1 as repeat then so the caller can distinguish between empty stack and
+ a repetition count of 1 */
static int
get_key_repeat(void) {
int num = 1;
@@ -363,12 +367,68 @@ get_key_repeat(void) {
element under it on the stack -> error */
num = -1;
}
+ } else {
+ num = 0;
}
clear_key_stack();
return num;
}
static void
+scroll_lines(ledit_buffer *buffer, int lines, int dir) {
+ int final_lines;
+ int text_w, text_h;
+ PangoRectangle strong, weak;
+ ledit_line *ll = ledit_buffer_get_line(buffer, buffer->cur_line);
+ pango_layout_get_cursor_pos(ll->layout, buffer->cur_index, &strong, &weak);
+ long abs_pos = ll->y_offset + strong.y / PANGO_SCALE;
+ 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 / (strong.height / PANGO_SCALE);
+ 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, &buffer->cur_index
+ );
+ ll = ledit_buffer_get_line(buffer, buffer->cur_line);
+ pango_layout_get_cursor_pos(ll->layout, buffer->cur_index, &strong, &weak);
+ long new_abs_pos = ll->y_offset + strong.y / PANGO_SCALE;
+ 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
+scroll_lines_up(ledit_buffer *buffer, char *text, int len) {
+ (void)text;
+ (void)len;
+ int repeat = get_key_repeat();
+ if (repeat >= 0)
+ scroll_lines(buffer, repeat, -1);
+ else
+ ledit_window_show_message(buffer->window, "Invalid key", -1);
+ discard_repetition_stack();
+ return (struct action){ACTION_NONE, NULL};
+}
+
+static struct action
+scroll_lines_down(ledit_buffer *buffer, char *text, int len) {
+ (void)text;
+ (void)len;
+ int repeat = get_key_repeat();
+ if (repeat >= 0)
+ scroll_lines(buffer, repeat, 1);
+ else
+ ledit_window_show_message(buffer->window, "Invalid key", -1);
+ discard_repetition_stack();
+ return (struct action){ACTION_NONE, NULL};
+}
+
+static void
scroll_with_cursor(ledit_buffer *buffer, int movement) {
PangoRectangle strong, weak;
ledit_line *ll = ledit_buffer_get_line(buffer, buffer->cur_line);
@@ -404,7 +464,7 @@ scroll_with_cursor_up(ledit_buffer *buffer, char *text, int len) {
(void)len;
int repeat = get_key_repeat();
if (repeat >= 0)
- scroll_with_cursor(buffer, -repeat);
+ scroll_with_cursor(buffer, -(repeat == 0 ? 1 : repeat));
else
ledit_window_show_message(buffer->window, "Invalid key", -1);
discard_repetition_stack();
@@ -417,7 +477,7 @@ scroll_with_cursor_down(ledit_buffer *buffer, char *text, int len) {
(void)len;
int repeat = get_key_repeat();
if (repeat >= 0)
- scroll_with_cursor(buffer, repeat);
+ scroll_with_cursor(buffer, repeat == 0 ? 1 : repeat);
else
ledit_window_show_message(buffer->window, "Invalid key", -1);
discard_repetition_stack();
@@ -463,7 +523,7 @@ screen_up(ledit_buffer *buffer, char *text, int len) {
(void)len;
int repeat = get_key_repeat();
if (repeat >= 0)
- move_screen(buffer, -repeat);
+ move_screen(buffer, -(repeat == 0 ? 1 : repeat));
else
ledit_window_show_message(buffer->window, "Invalid key", -1);
discard_repetition_stack();
@@ -476,7 +536,7 @@ screen_down(ledit_buffer *buffer, char *text, int len) {
(void)len;
int repeat = get_key_repeat();
if (repeat >= 0)
- move_screen(buffer, repeat);
+ move_screen(buffer, repeat == 0 ? 1 : repeat);
else
ledit_window_show_message(buffer->window, "Invalid key", -1);
discard_repetition_stack();
diff --git a/keys_basic_config.h b/keys_basic_config.h
@@ -61,6 +61,8 @@ static struct action screen_up(ledit_buffer *buffer, char *text, int len);
static struct action screen_down(ledit_buffer *buffer, char *text, int len);
static struct action scroll_with_cursor_up(ledit_buffer *buffer, char *text, int len);
static struct action scroll_with_cursor_down(ledit_buffer *buffer, char *text, int len);
+static struct action scroll_lines_up(ledit_buffer *buffer, char *text, int len);
+static struct action scroll_lines_down(ledit_buffer *buffer, char *text, int len);
/* FIXME: maybe sort these and use binary search
-> but that would mess with the catch-all keys */
@@ -110,6 +112,8 @@ static struct key keys_en[] = {
{"f", ControlMask, 0, NORMAL, KEY_ANY, KEY_NUMBERALLOWED, &screen_down},
{"e", ControlMask, 0, NORMAL, KEY_ANY, KEY_NUMBERALLOWED, &scroll_with_cursor_down},
{"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, INSERT, KEY_ANY, KEY_ANY, &insert_mode_insert_text}
};