Introduction
Introduction Statistics Contact Development Disclaimer Help
tImplement pasting (well, sort of) - 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 271d268ba17415be9808bb1da36389036b4eb95d
parent e5841801447358ed8f2f57e3dc0adc2873fb500e
Author: lumidify <[email protected]>
Date: Mon, 1 Nov 2021 13:17:15 +0100
Implement pasting (well, sort of)
Diffstat:
M keys_basic.c | 121 ++++++++++++++++++++++++-----…
M keys_basic_config.h | 2 ++
2 files changed, 97 insertions(+), 26 deletions(-)
---
diff --git a/keys_basic.c b/keys_basic.c
t@@ -25,7 +25,8 @@
#include "keys_command.h"
#include "keys_basic_config.h"
-/* this is supposed to be global for all buffers */
+/* note: this is supposed to be global for all buffers */
+int paste_buffer_line_based = 0;
static txtbuf *paste_buffer = NULL;
static int last_lines_scrolled = -1;
t@@ -91,7 +92,7 @@ static struct key_stack_elem *peek_key_stack(void);
static struct key_stack_elem *pop_key_stack(void);
void clear_key_stack(void);
-static void move_cursor_left_right(ledit_buffer *buffer, int dir);
+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…
t@@ -99,6 +100,7 @@ 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
);
+static void move_cursor_logically(ledit_buffer *buffer, int movement_dir, int …
/* FIXME: move to common */
static void
t@@ -304,7 +306,7 @@ delete_range(
}
static void
-insert_text(ledit_buffer *buffer, int line, int index, char *text, int len, in…
+insert_text(ledit_buffer *buffer, int line, int index, char *text, int len, in…
if (len < 0)
len = strlen(text);
/* FIXME: this is kind of hacky... */
t@@ -314,14 +316,22 @@ insert_text(ledit_buffer *buffer, int line, int index, c…
cur_range.byte1 = buffer->cur_index;
del_range.line1 = line;
del_range.byte1 = index;
+ int cur_line, cur_index;
ledit_buffer_insert_text_with_newlines(
buffer, line, index, text, len,
- &buffer->cur_line, &buffer->cur_index
+ &cur_line, &cur_index
);
- cur_range.line2 = buffer->cur_line;
- cur_range.byte2 = buffer->cur_index;
- del_range.line2 = buffer->cur_line;
- del_range.byte2 = buffer->cur_index;
+ /* this is mainly for pasting, where the new line and index
+ should not be at the end of the pasted text */
+ if (new_line >= 0 && new_index >= 0) {
+ cur_range.line2 = buffer->cur_line = new_line;
+ cur_range.byte2 = buffer->cur_index = new_index;
+ } else {
+ cur_range.line2 = buffer->cur_line = cur_line;
+ cur_range.byte2 = buffer->cur_index = cur_index;
+ }
+ del_range.line2 = cur_line;
+ del_range.byte2 = cur_index;
ledit_push_undo_insert(
buffer->undo, &ins_buf, del_range, cur_range, start_group, buffer-…
);
t@@ -335,6 +345,7 @@ delete_selection(ledit_buffer *buffer) {
buffer->sel.line1, buffer->sel.byte1,
buffer->sel.line2, buffer->sel.byte2
);
+ paste_buffer_line_based = 0;
/* FIXME: maybe just set this to the current cursor pos? */
buffer->sel.line1 = buffer->sel.line2 = -1;
buffer->sel.byte1 = buffer->sel.byte2 = -1;
t@@ -629,8 +640,53 @@ key_d_cb(ledit_buffer *buffer, int line, int char_pos, en…
buffer->cur_line, buffer->cur_index,
line, char_pos
);
+ paste_buffer_line_based = line_based;
+ ledit_buffer_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->c…
+ finalize_repetition_stack();
+}
+
+/* FIXME: don't use the pango functions directly so normalize_and_set_pango_te…
+ always called properly */
+static struct action
+paste_normal(ledit_buffer *buffer, char *text, int len) {
+ (void)text;
+ (void)len;
+ if (!paste_buffer) {
+ ledit_window_show_message(buffer->window, "Nothing to paste", …
+ discard_repetition_stack();
+ return (struct action){ACTION_NONE, NULL};
+ }
+ if (paste_buffer_line_based) {
+ int x, softline;
+ ledit_buffer_wipe_line_cursor_attrs(buffer, buffer->cur_line);
+ ledit_line *ll = ledit_buffer_get_line(buffer, buffer->cur_lin…
+ pango_layout_index_to_line_x(ll->layout, buffer->cur_index, 0,…
+ PangoLayoutLine *sl = pango_layout_get_line_readonly(ll->layou…
+ insert_text(
+ buffer, buffer->cur_line, sl->start_index + sl->length,
+ "\n", -1, buffer->cur_line, buffer->cur_index, 1
+ );
+ /* remove trailing newline if it exists - this may be hacky */
+ int text_len = paste_buffer->len;
+ if (paste_buffer->text[paste_buffer->len-1] == '\n') {
+ text_len--;
+ paste_buffer->text[paste_buffer->len-1] = '\0';
+ }
+ insert_text(
+ buffer, buffer->cur_line + 1, 0,
+ paste_buffer->text, text_len, buffer->cur_line + 1, 0, 0
+ );
+ } else {
+ /* must allow illegal index so text can be pasted at end of li…
+ move_cursor_logically(buffer, 1, 1);
+ insert_text(
+ buffer, buffer->cur_line, buffer->cur_index,
+ paste_buffer->text, paste_buffer->len, buffer->cur_line, b…
+ );
+ }
ledit_buffer_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->c…
finalize_repetition_stack();
+ return (struct action){ACTION_NONE, NULL};
}
static struct action
t@@ -794,7 +850,7 @@ delete_key(ledit_buffer *buffer, char *text, int len) {
}
static void
-move_cursor_left_right(ledit_buffer *buffer, int dir) {
+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) {
t@@ -839,7 +895,9 @@ move_cursor_left_right(ledit_buffer *buffer, int dir) {
/* when in normal mode, the cursor cannot be at the very end
of the line because it's always covering a character */
if (new_index >= cur_line->len) {
- if (buffer->common->mode == NORMAL && (e == NULL || e->motion_…
+ if (!allow_illegal_index &&
+ buffer->common->mode == NORMAL &&
+ (e == NULL || e->motion_cb == NULL)) {
new_index = last_index;
} else {
/* FIXME: I guess this is unnecessary */
t@@ -868,7 +926,7 @@ static struct action
cursor_left(ledit_buffer *buffer, char *text, int len) {
(void)text;
(void)len;
- move_cursor_left_right(buffer, -1);
+ move_cursor_left_right(buffer, -1, 0);
return (struct action){ACTION_NONE, NULL};
}
t@@ -876,7 +934,7 @@ static struct action
cursor_right(ledit_buffer *buffer, char *text, int len) {
(void)text;
(void)len;
- move_cursor_left_right(buffer, 1);
+ move_cursor_left_right(buffer, 1, 0);
return (struct action){ACTION_NONE, NULL};
}
t@@ -887,7 +945,7 @@ return_key(ledit_buffer *buffer, char *text, int len) {
int start_group = 1;
if (delete_selection(buffer))
start_group = 0;
- insert_text(buffer, buffer->cur_line, buffer->cur_index, "\n", -1, sta…
+ insert_text(buffer, buffer->cur_line, buffer->cur_index, "\n", -1, -1,…
/* FIXME: these aren't needed, right? This only works in insert mode
* anyways, so there's nothing to wipe */
/* ledit_buffer_wipe_line_cursor_attrs(buffer, buffer->cur_line);
t@@ -954,6 +1012,28 @@ pango_layout_get_direction(PangoLayout *layout, int inde…
}
#endif
+static void
+move_cursor_logically(ledit_buffer *buffer, int movement_dir, int allow_illega…
+ PangoDirection dir = PANGO_DIRECTION_RTL;
+ int tmp_index = buffer->cur_index;
+ ledit_line *cur_line = ledit_buffer_get_line(buffer, buffer->cur_line);
+ if (buffer->cur_index >= cur_line->len)
+ tmp_index--;
+ if (tmp_index >= 0)
+ dir = pango_layout_get_direction(cur_line->layout, tmp_index);
+ if (dir == PANGO_DIRECTION_RTL || dir == PANGO_DIRECTION_WEAK_RTL) {
+ if (movement_dir < 0)
+ move_cursor_left_right(buffer, 1, allow_illegal_index);
+ else
+ move_cursor_left_right(buffer, -1, allow_illegal_index…
+ } else {
+ if (movement_dir < 0)
+ move_cursor_left_right(buffer, -1, allow_illegal_index…
+ else
+ move_cursor_left_right(buffer, 1, allow_illegal_index);
+ }
+}
+
static struct action
escape_key(ledit_buffer *buffer, char *text, int len) {
(void)text;
t@@ -968,18 +1048,7 @@ escape_key(ledit_buffer *buffer, char *text, int len) {
} else {
ledit_buffer_set_mode(buffer, NORMAL);
clear_key_stack();
- PangoDirection dir = PANGO_DIRECTION_RTL;
- int tmp_index = buffer->cur_index;
- ledit_line *cur_line = ledit_buffer_get_line(buffer, buffer->c…
- if (buffer->cur_index >= cur_line->len)
- tmp_index--;
- if (tmp_index >= 0)
- dir = pango_layout_get_direction(cur_line->layout, tmp…
- if (dir == PANGO_DIRECTION_RTL || dir == PANGO_DIRECTION_WEAK_…
- cursor_right(buffer, NULL, 0);
- } else {
- cursor_left(buffer, NULL, 0);
- }
+ move_cursor_logically(buffer, -1, 0);
if (buffer->sel.line1 != buffer->sel.line2) {
int min = buffer->sel.line1 < buffer->sel.line2 ? buff…
int max = buffer->sel.line1 > buffer->sel.line2 ? buff…
t@@ -1217,7 +1286,7 @@ redo(ledit_buffer *buffer, char *text, int len) {
static struct action
insert_mode_insert_text(ledit_buffer *buffer, char *text, int len) {
delete_selection(buffer);
- insert_text(buffer, buffer->cur_line, buffer->cur_index, text, len, 1);
+ insert_text(buffer, buffer->cur_line, buffer->cur_index, text, len, -1…
return (struct action){ACTION_NONE, NULL};
}
diff --git a/keys_basic_config.h b/keys_basic_config.h
t@@ -64,6 +64,7 @@ static struct action scroll_with_cursor_down(ledit_buffer *b…
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 l…
static struct action move_to_line(ledit_buffer *buffer, char *text, int len);
+static struct action paste_normal(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@@ -121,6 +122,7 @@ static struct key keys_en[] = {
{"d", ControlMask, 0, NORMAL, KEY_ANY, KEY_NUMBERALLOWED, &scroll_lin…
{"u", ControlMask, 0, NORMAL, KEY_ANY, KEY_NUMBERALLOWED, &scroll_lin…
{"G", 0, 0, NORMAL, KEY_ANY, KEY_NUMBERALLOWED, &move_to_line},
+ {"p", 0, 0, NORMAL, KEY_ANY, KEY_ANY, &paste_normal},
{"", 0, 0, INSERT, KEY_ANY, KEY_ANY, &insert_mode_insert_text}
};
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.