Introduction
Introduction Statistics Contact Development Disclaimer Help
tImplement yanking - 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 2e039562f045bbcb2a7b29bd39031f0597953460
parent 42118fa8413ad5bd8be9d6d9b54b3b233a68df5f
Author: lumidify <[email protected]>
Date: Wed, 10 Nov 2021 11:27:29 +0100
Implement yanking
Diffstat:
M buffer.c | 10 +++++-----
M buffer.h | 2 ++
M keys_basic.c | 118 ++++++++++++++++++++++++++---…
M keys_basic_config.h | 2 ++
4 files changed, 110 insertions(+), 22 deletions(-)
---
diff --git a/buffer.c b/buffer.c
t@@ -43,7 +43,6 @@ static void init_line(ledit_buffer *buffer, ledit_line *line…
static void delete_line_section_base(ledit_buffer *buffer, int line, int start…
static void normalize_and_set_pango_text(ledit_line *line);
static void swap(int *a, int *b);
-static void sort_selection(int *line1, int *byte1, int *line2, int *byte2);
static void copy_selection_to_x_primary(ledit_buffer *buffer, int line1, int b…
void
t@@ -704,6 +703,7 @@ ledit_buffer_delete_line_entry_base(ledit_buffer *buffer, …
/* FIXME: use some sort of gap buffer (that would make this function
slightly more useful...) */
+/* FIXME: error checking, assert? */
ledit_line *
ledit_buffer_get_line(ledit_buffer *buffer, int index) {
return &buffer->lines[index];
t@@ -1886,8 +1886,8 @@ swap(int *a, int *b) {
*b = tmp;
}
-static void
-sort_selection(int *line1, int *byte1, int *line2, int *byte2) {
+void
+ledit_buffer_sort_selection(int *line1, int *byte1, int *line2, int *byte2) {
if (*line1 > *line2) {
swap(line1, line2);
swap(byte1, byte2);
t@@ -1921,8 +1921,8 @@ ledit_buffer_set_selection(ledit_buffer *buffer, int lin…
if (buffer->sel.line1 >= 0) {
int l1_new = line1, l2_new = line2;
int b1_new = byte1, b2_new = byte2;
- sort_selection(&buffer->sel.line1, &buffer->sel.byte1, &buffer…
- sort_selection(&l1_new, &b1_new, &l2_new, &b2_new);
+ ledit_buffer_sort_selection(&buffer->sel.line1, &buffer->sel.b…
+ ledit_buffer_sort_selection(&l1_new, &b1_new, &l2_new, &b2_new…
if (buffer->sel.line1 > l2_new || buffer->sel.line2 < l1_new) {
for (int i = buffer->sel.line1; i <= buffer->sel.line2…
ledit_buffer_wipe_line_cursor_attrs(buffer, i);
diff --git a/buffer.h b/buffer.h
t@@ -156,3 +156,5 @@ void ledit_buffer_resize_textview(ledit_buffer *buffer);
void ledit_buffer_scroll(ledit_buffer *buffer, long new_offset);
void ledit_buffer_scroll_to_pos_top(ledit_buffer *buffer, int line, int byte);
void ledit_buffer_scroll_to_pos_bottom(ledit_buffer *buffer, int line, int byt…
+/* FIXME: just make generic sort range */
+void ledit_buffer_sort_selection(int *line1, int *byte1, int *line2, int *byte…
diff --git a/keys_basic.c b/keys_basic.c
t@@ -9,6 +9,7 @@
them reliably yet */
#include <stdio.h>
#include <stdlib.h>
+#include <assert.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
t@@ -111,6 +112,7 @@ static void move_cursor_left_right(ledit_buffer *buffer, i…
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 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,
int movement, int *new_line_ret, int *new_softline_ret
t@@ -177,6 +179,24 @@ clear_key_stack(void) {
key_stack.len = 0;
}
+/* FIXME: error if no motion cb and not 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;
+ e = pop_key_stack();
+ }
+ if (e != NULL)
+ num *= (e->count > 0 ? e->count : 1);
+ }
+ if (cb_ret != NULL && e != NULL && e->motion_cb != NULL)
+ *cb_ret = e->motion_cb;
+ return num;
+}
+
static struct repetition_stack_elem *
push_repetition_stack(void) {
struct repetition_stack_elem *e;
t@@ -867,6 +887,87 @@ change_cb(ledit_buffer *buffer, int line, int char_pos, e…
}
static struct action
+yank(ledit_buffer *buffer, char *text, int len) {
+ (void)text;
+ (void)len;
+ if (!paste_buffer)
+ paste_buffer = txtbuf_new();
+ if (buffer->common->mode == VISUAL) {
+ ledit_buffer_sort_selection(
+ &buffer->sel.line1, &buffer->sel.byte1, &buffer->sel.line2…
+ );
+ ledit_buffer_copy_text_to_txtbuf(
+ buffer, paste_buffer,
+ buffer->sel.line1, buffer->sel.byte1, buffer->sel.line2, b…
+ );
+ paste_buffer_line_based = 0;
+ buffer->cur_line = buffer->sel.line1;
+ buffer->cur_index = buffer->sel.byte1;
+ ledit_buffer_set_selection(buffer, -1, -1, -1, -1);
+ ledit_buffer_set_mode(buffer, 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, b…
+ clear_key_stack();
+ } else {
+ motion_callback cb = NULL;
+ int num = get_key_repeat_and_motion_cb(&cb);
+ if (cb == &yank_cb) {
+ int new_line, new_softline;
+ get_new_line_softline(
+ buffer, buffer->cur_line, buffer->cur_index,
+ num - 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) {
+ struct key_stack_elem *e = push_key_stack();
+ e->key = KEY_MOTION;
+ e->count = num;
+ e->motion_cb = &yank_cb;
+ } else {
+ clear_key_stack();
+ }
+ }
+ discard_repetition_stack();
+ return (struct action){ACTION_NONE, NULL};
+}
+
+static void
+yank_cb(ledit_buffer *buffer, int line, int char_pos, enum key_type type) {
+ int line_based = type == KEY_MOTION_LINE ? 1 : 0;
+ int l1 = buffer->cur_line, l2 = line, b1 = buffer->cur_index, b2 = cha…
+ if (!paste_buffer)
+ paste_buffer = txtbuf_new();
+ if (l2 < l1 || (l1 == l2 && b2 < b1)) {
+ swap(&l1, &l2);
+ swap(&b1, &b2);
+ }
+ if (line_based) {
+ int x, sl1, sl2;
+ ledit_line *ll1 = ledit_buffer_get_line(buffer, l1);
+ pango_layout_index_to_line_x(ll1->layout, b1, 0, &sl1, &x);
+ PangoLayoutLine *pl1 = pango_layout_get_line_readonly(ll1->lay…
+ ledit_line *ll2 = ledit_buffer_get_line(buffer, l2);
+ pango_layout_index_to_line_x(ll2->layout, b2, 0, &sl2, &x);
+ PangoLayoutLine *pl2 = pango_layout_get_line_readonly(ll2->lay…
+ assert(pl1 != NULL && pl2 != NULL);
+ ledit_buffer_copy_text_to_txtbuf(
+ buffer, paste_buffer, l1, pl1->start_index, l2, pl2->start…
+ );
+ } else {
+ ledit_buffer_copy_text_to_txtbuf(
+ buffer, paste_buffer, l1, b1, l2, b2
+ );
+ }
+ paste_buffer_line_based = line_based;
+ discard_repetition_stack();
+}
+
+static struct action
key_d(ledit_buffer *buffer, char *text, int len) {
(void)text;
(void)len;
t@@ -1700,23 +1801,6 @@ clippaste(ledit_buffer *buffer, char *text, int len) {
return (struct action){ACTION_NONE, NULL};
}
-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;
- e = pop_key_stack();
- }
- if (e != NULL)
- num *= (e->count > 0 ? e->count : 1);
- }
- if (cb_ret != NULL && e != NULL && e->motion_cb != NULL)
- *cb_ret = e->motion_cb;
- return num;
-}
-
/* FIXME: make sure the found position is valid cursor position? */
static int
search_str_backwards(char *haystack, int hlen, char *needle, int nlen, int sta…
diff --git a/keys_basic_config.h b/keys_basic_config.h
t@@ -87,6 +87,7 @@ static struct action change_to_eol(ledit_buffer *buffer, cha…
static struct action delete_to_eol(ledit_buffer *buffer, char *text, int len);
static struct action delete_chars_forwards(ledit_buffer *buffer, char *text, i…
static struct action delete_chars_backwards(ledit_buffer *buffer, char *text, …
+static struct action yank(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@@ -123,6 +124,7 @@ static struct key keys_en[] = {
{"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…
+ {"y", 0, 0, NORMAL|VISUAL, KEY_ANY, KEY_MOTION|KEY_NUMBERALLOWED, &ya…
{"c", 0, 0, NORMAL|VISUAL, KEY_ANY, KEY_MOTION|KEY_NUMBERALLOWED, &ch…
{"v", 0, 0, NORMAL, KEY_ANY, KEY_ANY, &enter_visual},
{"o", 0, 0, VISUAL, KEY_ANY, KEY_ANY, &switch_selection_end},
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.