commit 91a730677ac95f922d6e5bca531f9cf0811e0fd6
parent 61c47698d180e2e9e81df98c5ac9d7304594a95b
Author: lumidify <nobody@lumidify.org>
Date: Thu, 11 Nov 2021 00:02:36 +0100
Make marks work with selections and motion callbacks
Diffstat:
7 files changed, 131 insertions(+), 93 deletions(-)
diff --git a/buffer.c b/buffer.c
@@ -52,6 +52,47 @@ ledit_buffer_set_mode(ledit_buffer *buffer, enum ledit_mode mode) {
ledit_change_mode_group(buffer->undo);
}
+static void
+marklist_destroy(ledit_buffer_marklist *marklist) {
+ for (size_t i = 0; i < marklist->len; i++) {
+ free(marklist->marks[i].text);
+ }
+ free(marklist->marks);
+ free(marklist);
+}
+
+void
+ledit_buffer_insert_mark(ledit_buffer *buffer, char *mark, int len, int line, int byte) {
+ ledit_buffer_marklist *marklist = buffer->marklist;
+ for (size_t i = 0; i < marklist->len; i++) {
+ if (!strncmp(mark, marklist->marks[i].text, len)) {
+ marklist->marks[i].line = line;
+ marklist->marks[i].byte = byte;
+ return;
+ }
+ }
+ if (marklist->len == marklist->alloc) {
+ size_t new_alloc = marklist->alloc > 0 ? marklist->alloc * 2 : 4;
+ marklist->marks = ledit_realloc(
+ marklist->marks, new_alloc * sizeof(ledit_buffer_mark)
+ );
+ marklist->alloc = new_alloc;
+ }
+ ledit_buffer_mark *m = &marklist->marks[marklist->len];
+ m->text = ledit_strndup(mark, len);
+ m->line = line;
+ m->byte = byte;
+ marklist->len++;
+}
+
+static ledit_buffer_marklist *
+marklist_create(void) {
+ ledit_buffer_marklist *marklist = ledit_malloc(sizeof(ledit_buffer_marklist));
+ marklist->len = marklist->alloc = 0;
+ marklist->marks = NULL;
+ return marklist;
+}
+
ledit_buffer *
ledit_buffer_create(ledit_common *common, ledit_theme *theme, ledit_window *window) {
if (basic_attrs == NULL) {
@@ -85,6 +126,7 @@ ledit_buffer_create(ledit_common *common, ledit_theme *theme, ledit_window *wind
buffer->cache = ledit_cache_create(common);
buffer->undo = ledit_undo_stack_create();
buffer->theme = theme;
+ buffer->marklist = marklist_create();
ledit_window_set_scroll_callback(window, &ledit_buffer_scroll_handler, buffer);
ledit_window_set_button_callback(window, &ledit_buffer_button_handler, buffer);
@@ -182,6 +224,7 @@ ledit_buffer_destroy(ledit_buffer *buffer) {
free(buffer->lines);
if (buffer->filename)
free(buffer->filename);
+ marklist_destroy(buffer->marklist);
free(buffer);
}
diff --git a/buffer.h b/buffer.h
@@ -18,6 +18,17 @@ typedef struct {
char h_dirty; /* whether height needs to be recalculated still */
} ledit_line;
+typedef struct {
+ char *text;
+ int line;
+ int byte;
+} ledit_buffer_mark;
+
+typedef struct {
+ size_t len, alloc;
+ ledit_buffer_mark *marks;
+} ledit_buffer_marklist;
+
/* TODO: advisory lock on file? also check if modification date changed before writing */
struct ledit_buffer {
ledit_common *common; /* common stuff, e.g. display, window, etc. */
@@ -39,6 +50,7 @@ struct ledit_buffer {
ledit_cache *cache;
ledit_undo_stack *undo;
ledit_window *window;
+ ledit_buffer_marklist *marklist;
};
ledit_buffer *ledit_buffer_create(ledit_common *common, ledit_theme *theme, ledit_window *window);
@@ -159,3 +171,4 @@ void ledit_buffer_scroll_to_pos_bottom(ledit_buffer *buffer, int line, int byte)
/* FIXME: just make generic sort range */
void ledit_buffer_sort_selection(int *line1, int *byte1, int *line2, int *byte2);
int ledit_line_next_non_whitespace(ledit_line *line, int byte);
+void ledit_buffer_insert_mark(ledit_buffer *buffer, char *mark, int len, int line, int byte);
diff --git a/keys_basic.c b/keys_basic.c
@@ -1836,14 +1836,80 @@ enter_searchedit_backward(ledit_buffer *buffer, char *text, int len) {
return (struct action){ACTION_GRABKEY, &ledit_command_key_handler};
}
+/* FIXME: differentiate between jumping to line and index like nvi */
+static struct action
+mark_line_cb(ledit_buffer *buffer, char *text, int len) {
+ grab_char_cb = NULL;
+ ledit_buffer_insert_mark(
+ buffer, text, len, buffer->cur_line, buffer->cur_index
+ );
+ return (struct action){ACTION_NONE, NULL};
+}
+
+/* FIXME: check that byte is actually in at grapheme boundary */
+static struct action
+jump_to_mark_cb(ledit_buffer *buffer, char *text, int len) {
+ grab_char_cb = NULL;
+ ledit_buffer_marklist *marklist = buffer->marklist;
+ motion_callback cb;
+ int num = get_key_repeat_and_motion_cb(&cb);
+ if (num > 0)
+ return err_invalid_key(buffer);
+ int line = -1, index = -1;
+ for (size_t i = 0; i < marklist->len; i++) {
+ if (!strncmp(text, marklist->marks[i].text, len)) {
+ ledit_line *ll;
+ ledit_buffer_mark *m = &marklist->marks[i];
+ if (m->line >= buffer->lines_num) {
+ line = buffer->lines_num - 1;
+ ll = ledit_buffer_get_line(buffer, line);
+ index = ll->len;
+ } else {
+ line = m->line;
+ ll = ledit_buffer_get_line(buffer, m->line);
+ if (m->byte >= ll->len)
+ index = ll->len;
+ else
+ index = m->byte;
+ }
+ break;
+ }
+ }
+ if (line == -1)
+ return err_invalid_key(buffer);
+ if (buffer->common->mode == VISUAL) {
+ ledit_buffer_set_selection(
+ buffer, buffer->sel.line1, buffer->sel.byte1, line, index
+ );
+ buffer->cur_line = line;
+ buffer->cur_index = index;
+ } else {
+ if (cb) {
+ cb(buffer, line, index, KEY_MOTION_LINE);
+ } else {
+ ledit_buffer_wipe_line_cursor_attrs(buffer, buffer->cur_line);
+ buffer->cur_line = line;
+ buffer->cur_index = index;
+ buffer->cur_index = ledit_buffer_get_legal_normal_pos(
+ buffer, buffer->cur_line, buffer->cur_index
+ );
+ ledit_buffer_set_line_cursor_attrs(
+ buffer, buffer->cur_line, buffer->cur_index
+ );
+ discard_repetition_stack();
+ }
+ }
+ return (struct action){ACTION_NONE, NULL};
+}
+
static struct action
mark_line(ledit_buffer *buffer, char *text, int len) {
(void)buffer;
(void)text;
(void)len;
- ledit_command_set_type(CMD_MARKLINE);
+ grab_char_cb = &mark_line_cb;
discard_repetition_stack();
- return (struct action){ACTION_GRABKEY, &ledit_command_key_handler};
+ return (struct action){ACTION_NONE, NULL};
}
static struct action
@@ -1851,9 +1917,9 @@ jump_to_mark(ledit_buffer *buffer, char *text, int len) {
(void)buffer;
(void)text;
(void)len;
- ledit_command_set_type(CMD_JUMPTOMARK);
+ grab_char_cb = &jump_to_mark_cb;
discard_repetition_stack();
- return (struct action){ACTION_GRABKEY, &ledit_command_key_handler};
+ return (struct action){ACTION_NONE, NULL};
}
/* FIXME: support visual mode, i.e. change selection to new place? */
diff --git a/keys_basic_config.h b/keys_basic_config.h
@@ -169,8 +169,8 @@ static struct key keys_en[] = {
{"a", 0, 0, NORMAL, KEY_ANY, KEY_ANY, &append_after_cursor},
{"O", 0, 0, NORMAL, KEY_ANY, KEY_ANY, &append_line_above},
{"o", 0, 0, NORMAL, KEY_ANY, KEY_ANY, &append_line_below},
- {"m", 0, 0, NORMAL, KEY_ANY, KEY_ANY, &mark_line},
- {"'", 0, 0, NORMAL, KEY_ANY, KEY_ANY, &jump_to_mark},
+ {"m", 0, 0, NORMAL|VISUAL, KEY_ANY, KEY_ANY, &mark_line},
+ {"'", 0, 0, NORMAL|VISUAL, KEY_ANY, KEY_ANY, &jump_to_mark},
{"C", 0, 0, NORMAL, KEY_ANY, KEY_ANY, &change_to_eol},
{"D", 0, 0, NORMAL, KEY_ANY, KEY_ANY, &delete_to_eol},
{"r", 0, 0, NORMAL, KEY_ANY, KEY_ANY, &replace},
diff --git a/keys_command.c b/keys_command.c
@@ -30,87 +30,9 @@
/* this must first be set by caller before jumping to key handler */
static enum ledit_command_type cur_type;
-struct mark {
- char *text;
- int line;
- int byte;
-};
-
-/* FIXME: this should be part of buffer! */
-struct {
- size_t len, alloc;
- struct mark *marks;
-} marklist = {0, 0, NULL};
-
void
command_key_cleanup(void) {
- for (size_t i = 0; i < marklist.len; i++) {
- free(marklist.marks[i].text);
- }
- free(marklist.marks);
-}
-
-static void
-insert_mark(char *mark, int len, int line, int byte) {
- for (size_t i = 0; i < marklist.len; i++) {
- if (!strncmp(mark, marklist.marks[i].text, len)) {
- marklist.marks[i].line = line;
- marklist.marks[i].byte = byte;
- return;
- }
- }
- if (marklist.len == marklist.alloc) {
- size_t new_alloc = marklist.alloc > 0 ? marklist.alloc * 2 : 4;
- marklist.marks = ledit_realloc(
- marklist.marks, new_alloc * sizeof(struct mark)
- );
- marklist.alloc = new_alloc;
- }
- struct mark *m = &marklist.marks[marklist.len];
- m->text = ledit_strndup(mark, len);
- m->line = line;
- m->byte = byte;
- marklist.len++;
-}
-
-/* FIXME: differentiate between jumping to line and index like nvi */
-static int
-mark_line(ledit_buffer *buffer, char *key_text, int len) {
- insert_mark(key_text, len, buffer->cur_line, buffer->cur_index);
- return 0;
-}
-
-/* FIXME: check that byte is actually in at grapheme boundary */
-/* FIXME: make this work with selections! */
-static int
-jump_to_mark(ledit_buffer *buffer, char *key_text, int len) {
- ledit_buffer_wipe_line_cursor_attrs(buffer, buffer->cur_line);
- for (size_t i = 0; i < marklist.len; i++) {
- if (!strncmp(key_text, marklist.marks[i].text, len)) {
- ledit_line *ll;
- struct mark *m = &marklist.marks[i];
- if (m->line >= buffer->lines_num) {
- buffer->cur_line = buffer->lines_num - 1;
- ll = ledit_buffer_get_line(buffer, buffer->cur_line);
- buffer->cur_index = ll->len;
- } else {
- buffer->cur_line = m->line;
- ll = ledit_buffer_get_line(buffer, m->line);
- if (m->byte >= ll->len)
- buffer->cur_index = ll->len;
- else
- buffer->cur_index = m->byte;
- }
- break;
- }
- }
- if (buffer->common->mode == NORMAL) {
- buffer->cur_index = ledit_buffer_get_legal_normal_pos(
- buffer, buffer->cur_line, buffer->cur_index
- );
- }
- ledit_buffer_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->cur_index);
- return 0;
+ /* nothing right now */
}
void
diff --git a/keys_command.h b/keys_command.h
@@ -4,9 +4,7 @@ enum ledit_command_type {
CMD_EDITSEARCHB,
CMD_SEARCH,
CMD_SEARCHB,
- CMD_SUBSTITUTE,
- CMD_MARKLINE,
- CMD_JUMPTOMARK
+ CMD_SUBSTITUTE
};
/* these are only here so they can also be used by keys_basic */
diff --git a/keys_command_config.h b/keys_command_config.h
@@ -6,8 +6,6 @@ static int edit_insert_text(ledit_buffer *buffer, char *key_text, int len);
static int edit_submit(ledit_buffer *buffer, char *key_text, int len);
static int editsearch_submit(ledit_buffer *buffer, char *key_text, int len);
static int editsearchb_submit(ledit_buffer *buffer, char *key_text, int len);
-static int mark_line(ledit_buffer *buffer, char *key_text, int len);
-static int jump_to_mark(ledit_buffer *buffer, char *key_text, int len);
struct key {
char *text; /* for keys that correspond with text */
@@ -28,9 +26,7 @@ static struct key keys_en[] = {
{NULL, 0, XK_Return, CMD_EDITSEARCHB, &editsearchb_submit},
{"", 0, 0, CMD_EDIT, &edit_insert_text},
{"", 0, 0, CMD_EDITSEARCH, &edit_insert_text},
- {"", 0, 0, CMD_EDITSEARCHB, &edit_insert_text},
- {"", 0, 0, CMD_MARKLINE, &mark_line},
- {"", 0, 0, CMD_JUMPTOMARK, &jump_to_mark}
+ {"", 0, 0, CMD_EDITSEARCHB, &edit_insert_text}
};
static struct key keys_de[] = {