Introduction
Introduction Statistics Contact Development Disclaimer Help
tClean up commands with motion callback - 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 c5fa1b6794a0e0dc9346571a34c85d40fdbb01b5
parent b113e1224270deb100329dec7cc42e05d8aead63
Author: lumidify <[email protected]>
Date: Wed, 10 Nov 2021 21:43:56 +0100
Clean up commands with motion callback
Diffstat:
M keys_basic.c | 308 ++++++++++++++++-------------…
M keys_basic_config.h | 4 ++--
2 files changed, 160 insertions(+), 152 deletions(-)
---
diff --git a/keys_basic.c b/keys_basic.c
t@@ -111,7 +111,7 @@ void clear_key_stack(void);
static void move_cursor_left_right(ledit_buffer *buffer, int dir, int allow_il…
static void move_cursor_up_down(ledit_buffer *buffer, int dir);
static void push_num(int num);
-static void key_d_cb(ledit_buffer *buffer, int line, int char_pos, enum key_ty…
+static void delete_cb(ledit_buffer *buffer, int line, int char_pos, enum key_t…
static void yank_cb(ledit_buffer *buffer, int line, int char_pos, enum key_typ…
static void get_new_line_softline(
ledit_buffer *buffer, int cur_line, int cur_index,
t@@ -187,21 +187,74 @@ err_invalid_key(ledit_buffer *buffer) {
return (struct action){ACTION_NONE, NULL};
}
-/* FIXME: error if no motion cb and not number key */
+/*
+ * Get the number of times a command should be repeated and the motion
+ * callback, if there was one on the stack.
+ * Note that *cb_ret is set to NULL if a non-null address is given and
+ * there is no motion callback on the stack.
+ * An empty stack or a stack where the top element has a count of 0
+ * leads to 0 being returned.
+ * In case of error, -1 is returned:
+ * - When the top or second element is not a number key but also does
+ * not comtain a motion callback.
+ * - When the stack is not empty after removing the top element and
+ * possibly a second one if the top one was a number key.
+ */
static int
get_key_repeat_and_motion_cb(motion_callback *cb_ret) {
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;
+ num = e->count;
e = pop_key_stack();
+ } else if (e->count == 0) {
+ num = 0;
}
if (e != NULL)
num *= (e->count > 0 ? e->count : 1);
+ } else {
+ num = 0;
}
+ if (e != NULL && !(e->key & KEY_NUMBER) && e->motion_cb == NULL)
+ num = -1;
+ else if (!key_stack_empty())
+ num = -1;
if (cb_ret != NULL && e != NULL && e->motion_cb != NULL)
*cb_ret = e->motion_cb;
+ else if (cb_ret != NULL)
+ *cb_ret = NULL;
+ return num;
+}
+
+/*
+ * 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 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.
+ * 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;
+ 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) {
+ /* the key was not a number, or there was another
+ element under it on the stack -> error */
+ num = -1;
+ }
+ } else {
+ num = 0;
+ }
+ clear_key_stack();
return num;
}
t@@ -418,35 +471,6 @@ 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 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
- 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;
- 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) {
- /* the key was not a number, or there was another
- element under it on the stack -> error */
- num = -1;
- }
- } else {
- num = 0;
- }
- clear_key_stack();
- return num;
-}
-
static struct action
delete_chars_forwards(ledit_buffer *buffer, char *text, int len) {
(void)text;
t@@ -574,15 +598,18 @@ static struct action
move_to_line(ledit_buffer *buffer, char *text, int len) {
(void)text;
(void)len;
- int repeat = get_key_repeat();
+ motion_callback cb = NULL;
+ int repeat = get_key_repeat_and_motion_cb(&cb);
int line;
if (repeat > 0)
line = repeat > buffer->lines_num ? buffer->lines_num : repeat;
else if (repeat == 0)
line = buffer->lines_num;
else
- ledit_window_show_message(buffer->window, "Invalid key", -1);
- if (repeat >= 0) {
+ return err_invalid_key(buffer);
+ if (cb != NULL) {
+ cb(buffer, line - 1, 0, KEY_MOTION_LINE);
+ } else {
ledit_buffer_wipe_line_cursor_attrs(buffer, buffer->cur_line);
buffer->cur_line = line - 1;
buffer->cur_index = 0;
t@@ -597,8 +624,8 @@ move_to_line(ledit_buffer *buffer, char *text, int len) {
ledit_buffer_scroll(buffer, ll->y_offset - text_h / 2);
}
ledit_buffer_set_line_cursor_attrs(buffer, buffer->cur_line, b…
+ discard_repetition_stack();
}
- discard_repetition_stack();
return (struct action){ACTION_NONE, NULL};
}
t@@ -828,39 +855,31 @@ static struct action
change(ledit_buffer *buffer, char *text, int len) {
(void)text;
(void)len;
- int num = 0;
- struct key_stack_elem *e = pop_key_stack();
- if (buffer->sel.line1 != buffer->sel.line2 || buffer->sel.byte1 != buf…
+ motion_callback cb = NULL;
+ int num = get_key_repeat_and_motion_cb(&cb);
+ if (num == -1)
+ return err_invalid_key(buffer);
+ if (buffer->common->mode == VISUAL) {
ledit_buffer_set_mode(buffer, INSERT);
delete_selection(buffer);
ledit_buffer_wipe_line_cursor_attrs(buffer, buffer->cur_line);
clear_key_stack();
} else {
- if (e != NULL) {
- if (e->key & KEY_NUMBER) {
- num = e->count;
- e = pop_key_stack();
- }
- if (e != NULL && e->motion_cb == &change_cb) {
- int prevnum = e->count > 0 ? e->count : 1;
- num = num > 0 ? num : 1;
- int lines = num * prevnum;
- int new_line, new_softline;
- get_new_line_softline(
- buffer, buffer->cur_line, buffer->cur_inde…
- lines - 1, &new_line, &new_softline
- );
- ledit_line *ll = ledit_buffer_get_line(buffer,…
- PangoLayoutLine *pl = pango_layout_get_line_re…
- e->motion_cb(buffer, new_line, pl->start_index…
- clear_key_stack();
- } else if (e != NULL) {
- /* FIXME: show message? */
- clear_key_stack();
- }
- }
- if (e == NULL) {
- e = push_key_stack();
+ if (cb == &change_cb) {
+ int lines = num > 0 ? num : 1;
+ int new_line, new_softline;
+ get_new_line_softline(
+ buffer, buffer->cur_line, buffer->cur_index,
+ lines - 1, &new_line, &new_softline
+ );
+ ledit_line *ll = ledit_buffer_get_line(buffer, new_lin…
+ PangoLayoutLine *pl = pango_layout_get_line_readonly(l…
+ cb(buffer, new_line, pl->start_index, KEY_MOTION_LINE);
+ clear_key_stack();
+ } else if (cb != NULL) {
+ return err_invalid_key(buffer);
+ } else {
+ struct key_stack_elem *e = push_key_stack();
e->key = KEY_MOTION; /* ? */
e->count = num;
e->motion_cb = &change_cb;
t@@ -924,6 +943,8 @@ yank(ledit_buffer *buffer, char *text, int len) {
} else {
motion_callback cb = NULL;
int num = get_key_repeat_and_motion_cb(&cb);
+ if (num == 0)
+ num = 1;
if (cb == &yank_cb) {
int new_line, new_softline;
get_new_line_softline(
t@@ -1000,45 +1021,38 @@ yank_cb(ledit_buffer *buffer, int line, int char_pos, …
}
static struct action
-key_d(ledit_buffer *buffer, char *text, int len) {
+delete(ledit_buffer *buffer, char *text, int len) {
(void)text;
(void)len;
- int num = 0;
+ motion_callback cb = NULL;
+ int num = get_key_repeat_and_motion_cb(&cb);
+ if (num == -1)
+ return err_invalid_key(buffer);
if (delete_selection(buffer)) {
ledit_buffer_set_mode(buffer, NORMAL);
buffer->cur_index = ledit_buffer_get_legal_normal_pos(buffer, …
ledit_buffer_set_line_cursor_attrs(buffer, buffer->cur_line, b…
clear_key_stack();
} else {
- struct key_stack_elem *e = pop_key_stack();
- if (e != NULL) {
- if (e->key & KEY_NUMBER) {
- num = e->count;
- e = pop_key_stack();
- }
- /* FIXME: checking equality of the function pointer ma…
- if (e != NULL && e->motion_cb == &key_d_cb) {
- int prevnum = e->count > 0 ? e->count : 1;
- num = num > 0 ? num : 1;
- int lines = num * prevnum;
- int new_line, new_softline;
- get_new_line_softline(
- buffer, buffer->cur_line, buffer->cur_inde…
- lines - 1, &new_line, &new_softline
- );
- ledit_line *ll = ledit_buffer_get_line(buffer,…
- PangoLayoutLine *pl = pango_layout_get_line_re…
- e->motion_cb(buffer, new_line, pl->start_index…
- clear_key_stack();
- } else if (e != NULL) {
- clear_key_stack();
- }
- }
- if (e == NULL) {
- e = push_key_stack();
+ /* FIXME: checking equality of the function pointer may be a b…
+ if (cb == &delete_cb) {
+ int lines = num > 0 ? num : 1;
+ int new_line, new_softline;
+ get_new_line_softline(
+ buffer, buffer->cur_line, buffer->cur_index,
+ lines - 1, &new_line, &new_softline
+ );
+ ledit_line *ll = ledit_buffer_get_line(buffer, new_lin…
+ PangoLayoutLine *pl = pango_layout_get_line_readonly(l…
+ cb(buffer, new_line, pl->start_index, KEY_MOTION_LINE);
+ clear_key_stack();
+ } else if (cb != NULL) {
+ return err_invalid_key(buffer);
+ } else {
+ struct key_stack_elem *e = push_key_stack();
e->key = KEY_MOTION; /* ? */
e->count = num;
- e->motion_cb = &key_d_cb;
+ e->motion_cb = &delete_cb;
}
}
return (struct action){ACTION_NONE, NULL};
t@@ -1046,7 +1060,7 @@ key_d(ledit_buffer *buffer, char *text, int len) {
/* FIXME: should this get number of lines to remove or actual end line? */
static void
-key_d_cb(ledit_buffer *buffer, int line, int char_pos, enum key_type type) {
+delete_cb(ledit_buffer *buffer, int line, int char_pos, enum key_type type) {
int line_based = type == KEY_MOTION_LINE ? 1 : 0;
delete_range(
buffer, line_based, 0,
t@@ -1314,16 +1328,12 @@ 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);
- }
+ motion_callback cb;
+ int num = get_key_repeat_and_motion_cb(&cb);
+ if (num == -1)
+ return err_invalid_key(buffer);
+ if (num == 0)
+ num = 1;
ledit_buffer_wipe_line_cursor_attrs(buffer, buffer->cur_line);
int new_line, new_softline;
get_new_line_softline(
t@@ -1333,13 +1343,17 @@ move_to_eol(ledit_buffer *buffer, char *text, int len)…
ledit_line *ll = ledit_buffer_get_line(buffer, new_line);
PangoLayoutLine *sl = pango_layout_get_line_readonly(ll->layout, new_s…
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);
+ if (cb != NULL) {
+ 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, …
+ ledit_buffer_set_selection(
+ buffer,
+ buffer->sel.line1, buffer->sel.byte1,
+ new_line, end_index
+ );
} else {
/* FIXME: this is weird because the cursor is actually…
next soft line, but the alternative has too many we…
t@@ -1358,24 +1372,20 @@ static struct action …
name(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); …
- } …
+ motion_callback cb; …
+ int num = get_key_repeat_and_motion_cb(&cb); …
+ if (num == -1) …
+ return err_invalid_key(buffer); …
+ if (num == 0) …
+ num = 1; …
int new_line, new_index, new_real_index; …
func( …
buffer, …
buffer->cur_line, buffer->cur_index, num, …
&new_line, &new_index, &new_real_index …
); …
- if (e != NULL && e->motion_cb != NULL) { …
- e->motion_cb(buffer, new_line, new_real_index, KEY_MOTION_CHAR…
+ if (cb != NULL) { …
+ cb(buffer, new_line, new_real_index, KEY_MOTION_CHAR); …
} else { …
if (buffer->common->mode == VISUAL) { …
ledit_buffer_set_selection( …
t@@ -1411,16 +1421,12 @@ GEN_WORD_MOVEMENT(prev_bigword, ledit_buffer_prev_bigw…
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 : 1;
- e = pop_key_stack();
- }
- if (e != NULL)
- num *= (e->count > 0 ? e->count : 1);
- }
+ motion_callback cb;
+ int num = get_key_repeat_and_motion_cb(&cb);
+ if (num == -1)
+ (void)err_invalid_key(buffer);
+ if (num == 0)
+ num = 1;
/* FIXME: trailing */
int trailing = 0, tmp_index;
t@@ -1456,16 +1462,15 @@ move_cursor_left_right(ledit_buffer *buffer, int dir, …
of the line because it's always covering a character */
if (new_index >= cur_line->len) {
if (!allow_illegal_index &&
- buffer->common->mode == NORMAL &&
- (e == NULL || e->motion_cb == NULL)) {
+ buffer->common->mode == NORMAL && cb == NULL) {
new_index = last_index;
} else {
/* FIXME: I guess this is unnecessary */
new_index = cur_line->len;
}
}
- if (e != NULL && e->motion_cb != NULL) {
- e->motion_cb(buffer, buffer->cur_line, new_index, KEY_MOTION_C…
+ if (cb != NULL) {
+ cb(buffer, buffer->cur_line, new_index, KEY_MOTION_CHAR);
} else {
buffer->cur_index = new_index;
if (buffer->common->mode == VISUAL) {
t@@ -1578,21 +1583,17 @@ enter_insert(ledit_buffer *buffer, char *text, int len…
return (struct action){ACTION_NONE, NULL};
}
-/* FIXME: Check if previous key allows motion command - or is this checked aut…
+/* FIXME: Check if previous key allows motion command - or should this be chec…
static void
move_cursor_up_down(ledit_buffer *buffer, int dir) {
int new_line, new_softline;
- 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);
- }
+ motion_callback cb;
+ int num = get_key_repeat_and_motion_cb(&cb);
+ if (num == -1)
+ (void)err_invalid_key(buffer);
+ if (num == 0)
+ num = 1;
num *= dir;
get_new_line_softline(
t@@ -1602,9 +1603,9 @@ move_cursor_up_down(ledit_buffer *buffer, int dir) {
ledit_line *cur_lline = ledit_buffer_get_line(buffer, buffer->cur_line…
ledit_line *new_lline = ledit_buffer_get_line(buffer, new_line);
- if (e != NULL && e->motion_cb != NULL) {
+ if (cb != NULL) {
PangoLayoutLine *pl = pango_layout_get_line_readonly(new_lline…
- e->motion_cb(buffer, new_line, pl->start_index, KEY_MOTION_LIN…
+ cb(buffer, new_line, pl->start_index, KEY_MOTION_LINE);
} else {
int lineno, x;
ledit_pos_to_x_softline(cur_lline, buffer->cur_index, &x, &lin…
t@@ -1647,10 +1648,13 @@ static struct action
cursor_to_beginning(ledit_buffer *buffer, char *text, int len) {
(void)text;
(void)len;
- struct key_stack_elem *e = pop_key_stack();
- /* FIXME: error when no callback? */
- if (e != NULL && e->motion_cb != NULL) {
- e->motion_cb(buffer, buffer->cur_line, 0, KEY_MOTION_CHAR);
+ motion_callback cb;
+ int num = get_key_repeat_and_motion_cb(&cb);
+ if (num == -1)
+ return err_invalid_key(buffer);
+ /* FIXME: should anything be done with num? */
+ if (cb != NULL) {
+ cb(buffer, buffer->cur_line, 0, KEY_MOTION_CHAR);
} else {
buffer->cur_index = 0;
if (buffer->common->mode == VISUAL) {
t@@ -1888,6 +1892,10 @@ static struct action …
name##_cb(ledit_buffer *buffer, char *text, int len) { …
motion_callback cb = NULL; …
int num = get_key_repeat_and_motion_cb(&cb); …
+ if (num == -1) …
+ return err_invalid_key(buffer); …
+ if (num == 0) …
+ num = 1; …
ledit_line *ll = ledit_buffer_get_line(buffer, buffer->cur_line); …
int new_index = buffer->cur_index; …
for (int i = 0; i < num; i++) { …
diff --git a/keys_basic_config.h b/keys_basic_config.h
t@@ -41,7 +41,7 @@ static struct action push_6(ledit_buffer *buffer, char *text…
static struct action push_7(ledit_buffer *buffer, char *text, int len);
static struct action push_8(ledit_buffer *buffer, char *text, int len);
static struct action push_9(ledit_buffer *buffer, char *text, int len);
-static struct action key_d(ledit_buffer *buffer, char *text, int len);
+static struct action delete(ledit_buffer *buffer, char *text, int len);
static struct action enter_visual(ledit_buffer *buffer, char *text, int len);
static struct action switch_selection_end(ledit_buffer *buffer, char *text, in…
static struct action clipcopy(ledit_buffer *buffer, char *text, int len);
t@@ -125,7 +125,7 @@ static struct key keys_en[] = {
{"9", 0, 0, NORMAL|VISUAL, KEY_ANY, KEY_NUMBER, &push_9},
{"x", 0, 0, NORMAL, KEY_ANY, KEY_NUMBERALLOWED, &delete_chars_forward…
{"X", 0, 0, NORMAL, KEY_ANY, KEY_NUMBERALLOWED, &delete_chars_backwar…
- {"d", 0, 0, NORMAL|VISUAL, KEY_ANY, KEY_MOTION|KEY_NUMBERALLOWED, &ke…
+ {"d", 0, 0, NORMAL|VISUAL, KEY_ANY, KEY_MOTION|KEY_NUMBERALLOWED, &de…
{"y", 0, 0, NORMAL|VISUAL, KEY_ANY, KEY_MOTION|KEY_NUMBERALLOWED, &ya…
{"Y", 0, 0, NORMAL, KEY_ANY, KEY_NUMBERALLOWED, &yank_lines},
{"c", 0, 0, NORMAL|VISUAL, KEY_ANY, KEY_MOTION|KEY_NUMBERALLOWED, &ch…
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.