Introduction
Introduction Statistics Contact Development Disclaimer Help
tAdd Ctrl-f and Ctrl-b for scrolling whole screens at a time - ledit - Text edi…
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 1619b579fa72a45217ceeab062cd5dc6c9961a37
parent bf406bf2c7ad5025890a061780823576b65a67d7
Author: lumidify <[email protected]>
Date: Fri, 29 Oct 2021 21:03:27 +0200
Add Ctrl-f and Ctrl-b for scrolling whole screens at a time
Diffstat:
M buffer.c | 33 +++++++++++++++++++++--------…
M buffer.h | 6 +++++-
M keys_basic.c | 74 +++++++++++++++++++++++++++++…
M keys_basic_config.h | 4 ++++
M window.c | 2 ++
5 files changed, 107 insertions(+), 12 deletions(-)
---
diff --git a/buffer.c b/buffer.c
t@@ -1363,16 +1363,25 @@ ledit_buffer_resize_textview(ledit_buffer *buffer) {
}
ledit_window_set_scroll_max(buffer->window, buffer->total_height);
if (buffer->display_offset > 0 &&
- buffer->display_offset + text_h >= buffer->total_height) {
- buffer->display_offset = buffer->total_height - text_h;
- if (buffer->display_offset < 0)
- buffer->display_offset = 0;
- ledit_window_set_scroll_pos(buffer->window, buffer->display_of…
+ buffer->display_offset + text_h > buffer->total_height) {
+ ledit_buffer_scroll(buffer, buffer->total_height - text_h);
}
}
void
-ledit_xy_to_line_byte(ledit_buffer *buffer, int x, int y, int *line_ret, int *…
+ledit_buffer_scroll(ledit_buffer *buffer, long new_offset) {
+ int text_w, text_h;
+ ledit_window_get_textview_size(buffer->window, &text_w, &text_h);
+ if (new_offset + text_h > buffer->total_height)
+ new_offset = buffer->total_height - text_h;
+ if (new_offset < 0)
+ new_offset = 0;
+ buffer->display_offset = new_offset;
+ ledit_window_set_scroll_pos(buffer->window, buffer->display_offset);
+}
+
+void
+ledit_xy_to_line_byte(ledit_buffer *buffer, int x, int y, int snap_to_nearest,…
/* FIXME: store current line offset to speed this up */
/* FIXME: use y_offset in lines */
long h = 0;
t@@ -1386,9 +1395,11 @@ ledit_xy_to_line_byte(ledit_buffer *buffer, int x, int …
x * PANGO_SCALE, (int)(pos - h) * PANGO_SCALE,
&index, &trailing
);
- while (trailing > 0) {
- trailing--;
- index = ledit_line_next_utf8(line, index);
+ if (snap_to_nearest) {
+ while (trailing > 0) {
+ trailing--;
+ index = ledit_line_next_utf8(line, ind…
+ }
}
*line_ret = i;
*byte_ret = index;
t@@ -1509,7 +1520,7 @@ ledit_buffer_button_handler(void *data, XEvent *event) {
int y = event->xbutton.y;
switch (event->type) {
case ButtonPress:
- ledit_xy_to_line_byte(buffer, x, y, &l, &b);
+ ledit_xy_to_line_byte(buffer, x, y, 1, &l, &b);
ledit_buffer_set_selection(buffer, l, b, l, b);
if (buffer->common->mode == NORMAL) {
ledit_buffer_wipe_line_cursor_attrs(buffer, buffer->cu…
t@@ -1528,7 +1539,7 @@ ledit_buffer_button_handler(void *data, XEvent *event) {
case MotionNotify:
if (buffer->selecting) {
y = y >= 0 ? y : 0;
- ledit_xy_to_line_byte(buffer, x, y, &l, &b);
+ ledit_xy_to_line_byte(buffer, x, y, 1, &l, &b);
ledit_buffer_set_selection(buffer, buffer->sel.line1, …
buffer->cur_line = l;
buffer->cur_index = b;
diff --git a/buffer.h b/buffer.h
t@@ -128,7 +128,10 @@ void ledit_buffer_insert_text_from_line(
);
void ledit_buffer_resize_width(ledit_buffer *buffer, int width);
-void ledit_xy_to_line_byte(ledit_buffer *buffer, int x, int y, int *line_ret, …
+/* x and y are in pixels, if snap_to_nearest is nonzero, the returned byte
+ is at the nearest grapheme boundary, if it is zero, the byte is always
+ the beginning of the grapheme under the position */
+void ledit_xy_to_line_byte(ledit_buffer *buffer, int x, int y, int snap_to_nea…
void ledit_buffer_ensure_cursor_shown(ledit_buffer *buffer);
void ledit_buffer_scroll_handler(void *buffer, long pos);
void ledit_buffer_button_handler(void *data, XEvent *event);
t@@ -140,3 +143,4 @@ void ledit_buffer_set_mode(ledit_buffer *buffer, enum ledi…
void ledit_buffer_paste_clipboard(ledit_buffer *buffer);
void ledit_buffer_paste_primary(ledit_buffer *buffer);
void ledit_buffer_resize_textview(ledit_buffer *buffer);
+void ledit_buffer_scroll(ledit_buffer *buffer, long new_offset);
diff --git a/keys_basic.c b/keys_basic.c
t@@ -343,6 +343,79 @@ delete_selection(ledit_buffer *buffer) {
return 0;
}
+/* get the number of times a command should be repeated, or -1 if anything
+ invalid was on the stack - this is for commands that just take a repeat
+ count and nothin else (cursor movement keys are different because they
+ can use other elements on the key stack to, for instance, call a callback
+ as is done for deletion */
+static int
+get_key_repeat(void) {
+ int num = 1;
+ 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;
+ e = pop_key_stack();
+ }
+ if (e != NULL) {
+ /* the key was not a number, or there was another
+ element under it on the stack -> error */
+ num = -1;
+ }
+ }
+ clear_key_stack();
+ return num;
+}
+
+/* movement is multiplied to the window height and added to the display offset
+ the cursor is moved to the top if movement is upwards, to the bottom otherw…
+static void
+move_screen(ledit_buffer *buffer, int movement) {
+ int w, h;
+ ledit_window_get_textview_size(buffer->window, &w, &h);
+ long total = movement * (long)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);
+ /* if movement is up, move cursor to top, else to bottom of current sc…
+ ledit_xy_to_line_byte(
+ buffer, x / PANGO_SCALE, movement < 0 ? 0 : h, 0,
+ &buffer->cur_line, &buffer->cur_index
+ );
+ ledit_buffer_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->c…
+}
+
+static struct action
+screen_up(ledit_buffer *buffer, char *text, int len) {
+ (void)text;
+ (void)len;
+ int repeat = get_key_repeat();
+ if (repeat >= 0)
+ move_screen(buffer, -repeat);
+ else
+ ledit_window_show_message(buffer->window, "Invalid key", -1);
+ discard_repetition_stack();
+ return (struct action){ACTION_NONE, NULL};
+}
+
+static struct action
+screen_down(ledit_buffer *buffer, char *text, int len) {
+ (void)text;
+ (void)len;
+ int repeat = get_key_repeat();
+ if (repeat >= 0)
+ move_screen(buffer, repeat);
+ else
+ ledit_window_show_message(buffer->window, "Invalid key", -1);
+ discard_repetition_stack();
+ return (struct action){ACTION_NONE, NULL};
+}
+
static struct action
key_d(ledit_buffer *buffer, char *text, int len) {
(void)text;
t@@ -665,6 +738,7 @@ return_key(ledit_buffer *buffer, char *text, int len) {
return (struct action){ACTION_NONE, NULL};
}
+/* FIXME: Is this illegal due to different licenses? */
/* FIXME: Check earliest version of other used functions to get minimum pango …
for ledit as a whole */
/* FIXME: This is just copied from the newer version of pango. It *seems* like
diff --git a/keys_basic_config.h b/keys_basic_config.h
t@@ -57,6 +57,8 @@ static struct action undo(ledit_buffer *buffer, char *text, …
static struct action redo(ledit_buffer *buffer, char *text, int len);
static struct action insert_mode_insert_text(ledit_buffer *buffer, char *text,…
static struct action repeat_command(ledit_buffer *buffer, char *text, int len);
+static struct action screen_up(ledit_buffer *buffer, char *text, int len);
+static struct action screen_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 */
t@@ -102,6 +104,8 @@ static struct key keys_en[] = {
{".", 0, 0, NORMAL, KEY_ANY, KEY_ANY, &repeat_command}, /* FIXME: onl…
{"z", ControlMask, 0, INSERT, KEY_ANY, KEY_ANY, &undo},
{"y", ControlMask, 0, INSERT, KEY_ANY, KEY_ANY, &redo},
+ {"b", ControlMask, 0, NORMAL, KEY_ANY, KEY_NUMBERALLOWED, &screen_up},
+ {"f", ControlMask, 0, NORMAL, KEY_ANY, KEY_NUMBERALLOWED, &screen_dow…
{"", 0, 0, INSERT, KEY_ANY, KEY_ANY, &insert_mode_insert_text}
};
diff --git a/window.c b/window.c
t@@ -415,6 +415,8 @@ ledit_window_create(ledit_common *common, ledit_theme *the…
void
ledit_window_destroy(ledit_window *window) {
/* FIXME: cleanup everything else */
+ /* FIXME: This doesn't seem to be correct - g_object_unref sometimes
+ causes segfault */
pango_font_description_free(window->font);
g_object_unref(window->fontmap);
g_object_unref(window->context);
You are viewing proxied material from lumidify.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.