Introduction
Introduction Statistics Contact Development Disclaimer Help
tAdd initial support for deletion - 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 52cea73bf0e43483210cb94e5177989bc524a30c
parent 174e6af4e28e5dec7b1402de9b15174357898865
Author: lumidify <[email protected]>
Date: Wed, 12 May 2021 21:47:17 +0200
Add initial support for deletion
Diffstat:
M buffer.c | 275 +++++++++++++++++++++++++++++…
M buffer.h | 10 ++++++++++
M ledit.c | 342 ++++++++++++++++-------------…
3 files changed, 452 insertions(+), 175 deletions(-)
---
diff --git a/buffer.c b/buffer.c
t@@ -138,8 +138,9 @@ init_line(ledit_buffer *buffer, ledit_line *line) {
line->parent_buffer = buffer;
line->layout = pango_layout_new(buffer->state->context);
pango_layout_set_width(line->layout, (buffer->state->w - 10) * PANGO_S…
- pango_layout_set_font_description(line->layout, buffer->state->font);
- pango_layout_set_wrap(line->layout, PANGO_WRAP_WORD_CHAR);
+ pango_layout_set_font_description(line->layout, buffer->state->font);
+ pango_layout_set_wrap(line->layout, PANGO_WRAP_WORD_CHAR);
+ pango_layout_set_attributes(line->layout, basic_attrs);
line->text = NULL;
line->cap = line->len = 0;
line->cache_index = -1;
t@@ -185,18 +186,27 @@ ledit_append_line(ledit_buffer *buffer, int line_index, …
}
void
-ledit_delete_line_entry(ledit_buffer *buffer, int index) {
- g_object_unref(buffer->lines[index].layout);
- free(buffer->lines[index].text);
- if (index < buffer->lines_num - 1)
+ledit_delete_line_entries(ledit_buffer *buffer, int index1, int index2) {
+ for (int i = index1; i <= index2; i++) {
+ g_object_unref(buffer->lines[i].layout);
+ free(buffer->lines[i].text);
+ }
+ if (index2 < buffer->lines_num - 1) {
memmove(
- buffer->lines + index, buffer->lines + index + 1,
- (buffer->lines_num - index - 1) * sizeof(ledit_line)
+ buffer->lines + index1, buffer->lines + index2 + 1,
+ (buffer->lines_num - index2 - 1) * sizeof(ledit_line)
);
- buffer->lines_num--;
+ }
+ buffer->lines_num -= index2 - index1 + 1;
+ /* FIXME: avoid this by just subtracting the heights */
recalc_line_size_absolute(buffer);
}
+void
+ledit_delete_line_entry(ledit_buffer *buffer, int index) {
+ ledit_delete_line_entries(buffer, index, index);
+}
+
/* FIXME: use some sort of gap buffer (that would make this function
slightly more useful...) */
ledit_line *
t@@ -270,3 +280,250 @@ ledit_delete_unicode_char(ledit_buffer *buffer, int line…
recalc_single_line_size(buffer, line_index);
return new_index;
}
+
+static void
+delete_line_section(ledit_buffer *buffer, int line, int start, int length) {
+ ledit_line *l = &buffer->lines[line];
+ memmove(l->text + start, l->text + start + length, l->len - start - le…
+ l->len -= length;
+ pango_layout_set_text(l->layout, l->text, l->len);
+ recalc_single_line_size(buffer, line);
+ l->dirty = 1;
+}
+
+void
+ledit_pos_to_x_softline(ledit_line *line, int pos, int *x_ret, int *softline_r…
+ pango_layout_index_to_line_x(line->layout, pos, 0, softline_ret, x_ret…
+ /* FIXME: do these lines need to be unref'd? */
+ PangoLayoutLine *pango_line = pango_layout_get_line_readonly(line->lay…
+ /* add left margin to x position if line is aligned right */
+ if (pango_line->resolved_dir == PANGO_DIRECTION_RTL) {
+ PangoRectangle rect;
+ pango_layout_line_get_extents(pango_line, NULL, &rect);
+ *x_ret += (line->w * PANGO_SCALE - rect.width);
+ }
+ /* if in normal mode, change position to the middle of the
+ current rectangle so that moving around won't jump weirdly */
+ /* FIXME: also in visual? */
+ if (line->parent_buffer->state->mode == NORMAL) {
+ PangoRectangle rect;
+ pango_layout_index_to_pos(line->layout, pos, &rect);
+ *x_ret += rect.width / 2;
+ }
+}
+
+/* FIXME: change this to return int */
+void
+ledit_x_softline_to_pos(ledit_line *line, int x, int softline, int *pos_ret) {
+ int trailing = 0;
+ int x_relative = x;
+ PangoLayoutLine *pango_line =
+ pango_layout_get_line_readonly(line->layout, softline);
+ /* x is absolute, so the margin at the left needs to be subtracted */
+ if (pango_line->resolved_dir == PANGO_DIRECTION_RTL) {
+ PangoRectangle rect;
+ pango_layout_line_get_extents(pango_line, NULL, &rect);
+ x_relative -= (line->w * PANGO_SCALE - rect.width);
+ }
+ pango_layout_line_x_to_index(
+ pango_line, x_relative, pos_ret, &trailing
+ );
+ /* if in insert mode, snap to the nearest border between graphemes */
+ if (line->parent_buffer->state->mode == INSERT) {
+ while (trailing > 0) {
+ trailing--;
+ (*pos_ret)++;
+ /* utf8 stuff */
+ while (*pos_ret < line->len &&
+ ((line->text[*pos_ret] & 0xC0) == 0x80))
+ (*pos_ret)++;
+ }
+ }
+}
+
+/* FIXME: cursor jumps weirdly */
+/* FIXME: use at least somewhat sensible variable names */
+void
+ledit_delete_range(
+ ledit_buffer *buffer, int line_based,
+ int line_index1, int byte_index1,
+ int line_index2, int byte_index2,
+ int *new_line_ret, int *new_byte_ret) {
+ if (line_based) {
+ int x, softline1, softline2;
+ ledit_line *line1 = ledit_get_line(buffer, line_index1);
+ ledit_pos_to_x_softline(line1, byte_index1, &x, &softline1);
+ if (line_index1 == line_index2) {
+ int x_useless;
+ pango_layout_index_to_line_x(line1->layout, byte_index…
+ int l1 = softline1 < softline2 ? softline1 : softline2;
+ int l2 = softline1 < softline2 ? softline2 : softline1;
+ int softlines = pango_layout_get_line_count(line1->lay…
+ PangoLayoutLine *pl1 = pango_layout_get_line_readonly(…
+ PangoLayoutLine *pl2 = pango_layout_get_line_readonly(…
+ /* don't delete entire line of it is the last one rema…
+ if (l1 == 0 && l2 == softlines - 1 && buffer->lines_nu…
+ ledit_delete_line_entry(buffer, line_index1);
+ /* note: line_index1 is now the index of the n…
+ line since the current one was just deleted…
+ if (line_index1 < buffer->lines_num) {
+ *new_line_ret = line_index1;
+ ledit_x_softline_to_pos(
+ ledit_get_line(buffer, line_index1…
+ x, 0, new_byte_ret
+ );
+ } else {
+ /* note: logically, this must be >= 0 …
+ buffer->lines_num > 1 && line_index…
+ *new_line_ret = line_index1 - 1;
+ ledit_line *prevline = ledit_get_line(…
+ softlines = pango_layout_get_line_coun…
+ ledit_x_softline_to_pos(prevline, x, s…
+ }
+ } else {
+ /* FIXME: sanity checks that the length is act…
+ delete_line_section(
+ buffer, line_index1, pl1->start_index,
+ pl2->start_index + pl2->length - pl1->star…
+ );
+ if (l2 == softlines - 1 && line_index1 < buffe…
+ *new_line_ret = line_index1 + 1;
+ ledit_x_softline_to_pos(
+ ledit_get_line(buffer, line_index1…
+ x, 0, new_byte_ret
+ );
+ } else if (l2 < softlines - 1) {
+ *new_line_ret = line_index1;
+ ledit_x_softline_to_pos(
+ ledit_get_line(buffer, line_index1…
+ x, l1, new_byte_ret
+ );
+ } else if (l1 > 0) {
+ *new_line_ret = line_index1;
+ ledit_x_softline_to_pos(
+ ledit_get_line(buffer, line_index1…
+ x, l1 - 1, new_byte_ret
+ );
+ } else {
+ /* the line has been emptied and is th…
+ *new_line_ret = 0;
+ *new_byte_ret = 0;
+ }
+ }
+ } else {
+ int x_useless, sl1, sl2;
+ int l1, l2, b1, b2;
+ if (line_index1 < line_index2) {
+ l1 = line_index1;
+ b1 = byte_index1;
+ l2 = line_index2;
+ b2 = byte_index2;
+ } else {
+ l1 = line_index2;
+ b1 = byte_index2;
+ l2 = line_index1;
+ b2 = byte_index1;
+ }
+ ledit_line *ll1 = ledit_get_line(buffer, l1);
+ ledit_line *ll2 = ledit_get_line(buffer, l2);
+ pango_layout_index_to_line_x(ll1->layout, b1, 0, &sl1,…
+ pango_layout_index_to_line_x(ll2->layout, b2, 0, &sl2,…
+ PangoLayoutLine *pl1 = pango_layout_get_line_readonly(…
+ PangoLayoutLine *pl2 = pango_layout_get_line_readonly(…
+ int softlines = pango_layout_get_line_count(ll2->layou…
+ if (sl1 == 0 && sl2 == softlines - 1) {
+ if (l1 == 0 && l2 == buffer->lines_num - 1) {
+ delete_line_section(buffer, l1, 0, ll1…
+ ledit_delete_line_entries(buffer, l1 +…
+ *new_line_ret = 0;
+ *new_byte_ret = 0;
+ } else {
+ ledit_delete_line_entries(buffer, l1, …
+ if (l1 >= buffer->lines_num) {
+ *new_line_ret = buffer->lines_…
+ ledit_line *new_lline = ledit_…
+ int new_softlines = pango_layo…
+ ledit_x_softline_to_pos(new_ll…
+ } else {
+ *new_line_ret = l1;
+ ledit_x_softline_to_pos(
+ ledit_get_line(buffer, l1),
+ x, 0, new_byte_ret
+ );
+ }
+ }
+ } else if (sl1 == 0) {
+ delete_line_section(buffer, l2, 0, pl2->start_…
+ ledit_delete_line_entries(buffer, l1, l2 - 1);
+ *new_line_ret = l1;
+ ledit_x_softline_to_pos(ledit_get_line(buffer,…
+ } else if (sl2 == softlines - 1) {
+ delete_line_section(buffer, l1, pl1->start_ind…
+ ledit_delete_line_entries(buffer, l1 + 1, l2);
+ if (l1 + 1 >= buffer->lines_num) {
+ *new_line_ret = buffer->lines_num - 1;
+ ledit_line *new_lline = ledit_get_line…
+ int new_softlines = pango_layout_get_l…
+ ledit_x_softline_to_pos(new_lline, x, …
+ } else {
+ *new_line_ret = l1 + 1;
+ ledit_x_softline_to_pos(
+ ledit_get_line(buffer, l1 + 1),
+ x, 0, new_byte_ret
+ );
+ }
+ } else {
+ /* FIXME: should this join the two lines? */
+ delete_line_section(buffer, l1, pl1->start_ind…
+ delete_line_section(buffer, l2, 0, pl2->start_…
+ if (l2 > l1 + 1)
+ ledit_delete_line_entries(buffer, l1 +…
+ *new_line_ret = l1 + 1;
+ ledit_x_softline_to_pos(ledit_get_line(buffer,…
+ }
+ }
+ } else {
+ if (line_index1 == line_index2) {
+ int b1, b2;
+ if (byte_index1 < byte_index2) {
+ b1 = byte_index1;
+ b2 = byte_index2;
+ } else {
+ b1 = byte_index2;
+ b2 = byte_index1;
+ }
+ delete_line_section(buffer, line_index1, b1, b2 - b1);
+ *new_line_ret = line_index1;
+ *new_byte_ret = b1;
+ /* FIXME: this needs to be checked by calling code to
+ move cursor one back if in normal mode and at end
+ of line */
+ } else {
+ int l1, l2, b1, b2;
+ if (line_index1 < line_index2) {
+ l1 = line_index1;
+ b1 = byte_index1;
+ l2 = line_index2;
+ b2 = byte_index2;
+ } else {
+ l1 = line_index2;
+ b1 = byte_index2;
+ l2 = line_index1;
+ b2 = byte_index1;
+ }
+ ledit_line *line1 = ledit_get_line(buffer, l1);
+ ledit_line *line2 = ledit_get_line(buffer, l2);
+ line1->len = b1;
+ if (b2 > 0) {
+ ledit_insert_text(
+ buffer, l1, b1,
+ line2->text + b2,
+ line2->len - b2
+ );
+ }
+ *new_line_ret = l1;
+ *new_byte_ret = b1;
+ ledit_delete_line_entries(buffer, l1 + 1, l2);
+ }
+ }
+}
diff --git a/buffer.h b/buffer.h
t@@ -1,5 +1,6 @@
typedef struct ledit_buffer ledit_buffer;
+/* FIXME: size_t for len, etc. */
typedef struct {
PangoLayout *layout;
char *text;
t@@ -36,7 +37,16 @@ void ledit_wipe_line_cursor_attrs(ledit_buffer *buffer, int…
void ledit_insert_text(ledit_buffer *buffer, int line_index, int index, char *…
void ledit_render_line(ledit_buffer *buffer, int line_index);
void ledit_append_line(ledit_buffer *buffer, int line_index, int text_index);
+void ledit_delete_line_entries(ledit_buffer *buffer, int index1, int index2);
void ledit_delete_line_entry(ledit_buffer *buffer, int index);
ledit_line *ledit_get_line(ledit_buffer *buffer, int index);
int ledit_line_visible(ledit_buffer *buffer, int index);
int ledit_delete_unicode_char(ledit_buffer *buffer, int line_index, int byte_i…
+void ledit_delete_range(
+ ledit_buffer *buffer, int line_based,
+ int line_index1, int byte_index1,
+ int line_index2, int byte_index2,
+ int *new_line_ret, int *new_byte_ret
+);
+void ledit_pos_to_x_softline(ledit_line *line, int pos, int *x_ret, int *softl…
+void ledit_x_softline_to_pos(ledit_line *line, int x, int softline, int *pos_r…
diff --git a/ledit.c b/ledit.c
t@@ -31,24 +31,32 @@ enum key_type {
KEY_NONE = 0,
KEY_MISC = 1,
KEY_CHAR = 2,
- KEY_MOTION = 4,
- KEY_NUMBER = 8,
- KEY_NUMBERALLOWED = 16,
+ KEY_MOTION_CHAR = 4,
+ KEY_MOTION_LINE = 8,
+ KEY_MOTION = 4|8,
+ KEY_NUMBER = 16,
+ KEY_NUMBERALLOWED = 32,
KEY_ANY = 0xFF
};
struct key {
- char *text; /* for keys that correspond with text */
- KeySym keysym; /* for other keys, e.g. arrow keys */
- enum ledit_mode modes; /* modes in which this keybinding is functional…
+ char *text; /* for keys that correspond with text */
+ KeySym keysym; /* for other keys, e.g. arrow keys */
+ enum ledit_mode modes; /* modes in which this keybinding is function…
+ enum key_type prev_keys; /* allowed previous keys */
enum key_type key_types; /* key types - used to determine if the key i…
- void (*func)(void); /* callback function */
+ void (*func)(void); /* callback function */
};
struct key_stack_elem {
- enum key_type key; /* key type */
+ enum key_type key;
enum key_type followup; /* allowed keys to complete the keybinding */
- void (*func)(void); /* function to call if an allowed key is entered */
+ /* callback function that motion commands call to complete a command -
+ * line and char_pos already include the repetition stored in this sta…
+ * element; type is the type of motion command (used to determine if
+ * the command should operate on lines or chars) */
+ void (*motion_cb)(int line, int char_pos, enum key_type type);
+ int count; /* number of repetitions */
int data1; /* misc. data 1 */
int data2; /* misc. data 2 */
};
t@@ -63,12 +71,7 @@ static ledit_buffer *buffer;
/* TODO: protect against overflow, especially on repeating commands */
-static struct key_stack_elem *push_key_stack(
- enum key_type key,
- enum key_type followup,
- void (*func)(void),
- int data1, int data2
-);
+static struct key_stack_elem *push_key_stack(void);
static struct key_stack_elem *peek_key_stack(void);
static struct key_stack_elem *pop_key_stack(void);
void clear_key_stack(void);
t@@ -109,11 +112,81 @@ static void push_6(void);
static void push_7(void);
static void push_8(void);
static void push_9(void);
+static void key_d(void);
+static void key_d_cb(int line, int char_pos, enum key_type type);
static void change_keyboard(char *lang);
static void key_press(XEvent event);
static void
+key_d(void) {
+ int num = 0;
+ 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 may be a b…
+ 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;
+
+ ledit_line *line = ledit_get_line(buffer, buffer->cur_…
+ int x, softline;
+ pango_layout_index_to_line_x(line->layout, buffer->cur…
+ int softlines = pango_layout_get_line_count(line->layo…
+ if (softlines - softline >= lines) {
+ PangoLayoutLine *l = pango_layout_get_line_rea…
+ e->motion_cb(buffer->cur_line, l->start_index,…
+ } else {
+ lines -= (softlines - softline);
+ int endline = buffer->cur_line + 1;
+ while (lines > 0 && endline < buffer->lines_nu…
+ line = ledit_get_line(buffer, endline);
+ softlines = pango_layout_get_line_coun…
+ lines -= softlines;
+ endline++;
+ }
+ endline--;
+ int endsoftline = 0;
+ if (lines <= 0) {
+ endsoftline = lines + softlines - 1;
+ } else {
+ endsoftline = softlines - 1;
+ }
+ PangoLayoutLine *l = pango_layout_get_line_rea…
+ e->motion_cb(endline, l->start_index, KEY_MOTI…
+ }
+ clear_key_stack();
+ } else if (e != NULL) {
+ clear_key_stack();
+ }
+ }
+ if (e == NULL) {
+ e = push_key_stack();
+ e->key = KEY_MOTION; /* ? */
+ e->count = num;
+ e->motion_cb = &key_d_cb;
+ }
+}
+
+/* FIXME: should this get number of lines to remove or actual end line? */
+static void
+key_d_cb(int line, int char_pos, enum key_type type) {
+ printf("%d, %d\n", line, char_pos);
+ int line_based = type == KEY_MOTION_LINE ? 1 : 0;
+ ledit_delete_range(
+ buffer, line_based,
+ buffer->cur_line, buffer->cur_index,
+ line, char_pos,
+ &buffer->cur_line, &buffer->cur_index
+ );
+ ledit_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->cur_inde…
+}
+
+static void
key_x(void) {
struct key_stack_elem *e = pop_key_stack();
int num = 1;
t@@ -121,7 +194,7 @@ key_x(void) {
if (e && !(e->key & KEY_NUMBER))
return;
if (e)
- num = e->data1;
+ num = e->count;
if (num <= 0)
num = 1;
printf("delete %d\n", num);
t@@ -130,14 +203,16 @@ key_x(void) {
static void
push_num(int num) {
struct key_stack_elem *e = peek_key_stack();
- if (!e || !(e->key & KEY_NUMBER))
- e = push_key_stack(KEY_NUMBER, KEY_NUMBERALLOWED, NULL, 0, 0);
+ if (!e || !(e->key & KEY_NUMBER)) {
+ e = push_key_stack();
+ e->key = KEY_NUMBER;
+ e->followup = KEY_NUMBER|KEY_NUMBERALLOWED;
+ }
/* FIXME: error checking */
- e->data1 *= 10;
- e->data1 += num;
+ e->count *= 10;
+ e->count += num;
}
-/* FIXME: CHANGE BEHAVIOR TO MOVEMENT */
static void
push_0(void) {
push_num(0);
t@@ -198,11 +273,7 @@ main(int argc, char *argv[]) {
}
static struct key_stack_elem *
-push_key_stack(
- enum key_type key,
- enum key_type followup,
- void (*func)(void),
- int data1, int data2) {
+push_key_stack(void) {
struct key_stack_elem *e;
if (key_stack.len >= key_stack.alloc) {
size_t new_alloc = key_stack.alloc > 0 ? key_stack.alloc * 2 :…
t@@ -212,11 +283,12 @@ push_key_stack(
key_stack.alloc = new_alloc;
}
e = &key_stack.stack[key_stack.len];
- e->key = key;
- e->followup = followup;
- e->func = func;
- e->data1 = data1;
- e->data2 = data2;
+ e->key = KEY_NONE;
+ e->followup = KEY_NONE;
+ e->motion_cb = NULL;
+ e->count = 0;
+ e->data1 = 0;
+ e->data2 = 0;
key_stack.len++;
return &key_stack.stack[key_stack.len - 1];
}
t@@ -757,21 +829,20 @@ move_cursor(int dir) {
ledit_line *cur_line = ledit_get_line(buffer, buffer->cur_line);
pango_layout_move_cursor_visually(
cur_line->layout, TRUE,
- buffer->cur_index, buffer->trailing, dir,
- &buffer->cur_index, &buffer->trailing
+ buffer->cur_index, 0, dir,
+ &buffer->cur_index, &trailing
);
/* FIXME: Allow cursor to be at end of soft line */
/* we don't currently support a difference between the cursor being at
the end of a soft line and the beginning of the next line */
- /*
- while (buffer->trailing > 0) {
- buffer->trailing--;
+ /* FIXME: spaces at end of softlines are weird in normal mode */
+ while (trailing > 0) {
+ trailing--;
buffer->cur_index++;
while (buffer->cur_index < cur_line->len &&
((cur_line->text[buffer->cur_index] & 0xC0) == 0x80))
buffer->cur_index++;
}
- */
if (buffer->cur_index < 0)
buffer->cur_index = 0;
/* when in normal mode, the cursor cannot be at the very end
t@@ -832,23 +903,10 @@ enter_insert(void) {
static void
cursor_down(void) {
- int lineno, x, trailing = 0;
+ int lineno, x;
ledit_line *cur_line = ledit_get_line(buffer, buffer->cur_line);
- pango_layout_index_to_line_x(
- cur_line->layout, buffer->cur_index, 0, &lineno, &x
- );
- PangoLayoutLine *cur_pango_line =
- pango_layout_get_line_readonly(cur_line->layout, lineno);
- if (cur_pango_line->resolved_dir == PANGO_DIRECTION_RTL) {
- PangoRectangle rect;
- pango_layout_line_get_extents(cur_pango_line, NULL, &rect);
- x += (cur_line->w * PANGO_SCALE - rect.width);
- }
- if (state.mode == NORMAL) {
- PangoRectangle pos;
- pango_layout_index_to_pos(cur_line->layout, buffer->cur_index,…
- x += pos.width / 2;
- }
+ ledit_pos_to_x_softline(cur_line, buffer->cur_index, &x, &lineno);
+
int maxlines = pango_layout_get_line_count(cur_line->layout);
if (lineno == maxlines - 1) {
ledit_wipe_line_cursor_attrs(buffer, buffer->cur_line);
t@@ -856,59 +914,21 @@ cursor_down(void) {
if (buffer->cur_line < buffer->lines_num - 1) {
buffer->cur_line++;
cur_line = ledit_get_line(buffer, buffer->cur_line);
- PangoLayoutLine *nextline =
- pango_layout_get_line_readonly(cur_line->layout, 0…
- if (nextline->resolved_dir == PANGO_DIRECTION_RTL) {
- PangoRectangle rect;
- pango_layout_line_get_extents(nextline, NULL, …
- x -= (cur_line->w * PANGO_SCALE - rect.width);
- }
- pango_layout_line_x_to_index(
- nextline, x, &buffer->cur_index, &trailing
- );
- if (state.mode == INSERT)
- buffer->cur_index += trailing;
+ ledit_x_softline_to_pos(cur_line, x, 0, &buffer->cur_i…
}
} else {
/* move to the next soft line */
- PangoLayoutLine *nextline =
- pango_layout_get_line_readonly(cur_line->layout, lineno + …
- if (nextline->resolved_dir == PANGO_DIRECTION_RTL) {
- PangoRectangle rect;
- pango_layout_line_get_extents(nextline, NULL, &rect);
- x -= (cur_line->w * PANGO_SCALE - rect.width);
- }
- pango_layout_line_x_to_index(
- nextline, x, &buffer->cur_index, &trailing
- );
- if (state.mode == INSERT)
- buffer->cur_index += trailing;
+ ledit_x_softline_to_pos(cur_line, x, lineno + 1, &buffer->cur_…
}
ledit_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->cur_inde…
}
static void
cursor_up(void) {
- int lineno, x, trailing = 0;
+ int lineno, x;
ledit_line *cur_line = ledit_get_line(buffer, buffer->cur_line);
- pango_layout_index_to_line_x(
- cur_line->layout, buffer->cur_index, 0, &lineno, &x
- );
- PangoLayoutLine *cur_pango_line =
- pango_layout_get_line_readonly(cur_line->layout, lineno);
- /* FIXME: do these lines need to be unref'd? */
- if (cur_pango_line->resolved_dir == PANGO_DIRECTION_RTL) {
- PangoRectangle rect;
- pango_layout_line_get_extents(cur_pango_line, NULL, &rect);
- /* FIXME: don't store w in each line because it is now the sam…
- x += (cur_line->w * PANGO_SCALE - rect.width);
- }
- if (state.mode == NORMAL) {
- PangoRectangle pos;
- pango_layout_index_to_pos(cur_line->layout, buffer->cur_index,…
- x += pos.width / 2;
- }
- /* FIXME: clean this up (if and else are very similar) */
+ ledit_pos_to_x_softline(cur_line, buffer->cur_index, &x, &lineno);
+ buffer->trailing = 0;
if (lineno == 0) {
ledit_wipe_line_cursor_attrs(buffer, buffer->cur_line);
/* move to the previous hard line */
t@@ -916,34 +936,11 @@ cursor_up(void) {
buffer->cur_line--;
cur_line = ledit_get_line(buffer, buffer->cur_line);
int maxlines = pango_layout_get_line_count(cur_line->l…
- PangoLayoutLine *prevline =
- pango_layout_get_line_readonly(cur_line->layout, m…
- if (prevline->resolved_dir == PANGO_DIRECTION_RTL) {
- PangoRectangle rect;
- pango_layout_line_get_extents(prevline, NULL, …
- x -= (cur_line->w * PANGO_SCALE - rect.width);
- }
- pango_layout_line_x_to_index(
- prevline, x, &buffer->cur_index, &trailing
- );
- /* FIXME: also in visual? */
- if (state.mode == INSERT)
- buffer->cur_index += trailing;
+ ledit_x_softline_to_pos(cur_line, x, maxlines - 1, &bu…
}
} else {
/* move to the previous soft line */
- PangoLayoutLine *prevline =
- pango_layout_get_line_readonly(cur_line->layout, lineno - …
- if (prevline->resolved_dir == PANGO_DIRECTION_RTL) {
- PangoRectangle rect;
- pango_layout_line_get_extents(prevline, NULL, &rect);
- x -= (cur_line->w * PANGO_SCALE - rect.width);
- }
- pango_layout_line_x_to_index(
- prevline, x, &buffer->cur_index, &trailing
- );
- if (state.mode == INSERT)
- buffer->cur_index += trailing;
+ ledit_x_softline_to_pos(cur_line, x, lineno - 1, &buffer->cur_…
}
ledit_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->cur_inde…
}
t@@ -955,57 +952,66 @@ cursor_to_beginning(void) {
}
static struct key keys_en[] = {
- {NULL, XK_BackSpace, INSERT, KEY_ANY, &backspace},
- {NULL, XK_Left, INSERT|NORMAL, KEY_ANY, &cursor_left},
- {NULL, XK_Right, INSERT|NORMAL, KEY_ANY, &cursor_right},
- {NULL, XK_Up, INSERT|NORMAL, KEY_ANY, &cursor_up},
- {NULL, XK_Down, INSERT|NORMAL, KEY_ANY, &cursor_down},
- {NULL, XK_Return, INSERT, KEY_ANY, &return_key},
- {NULL, XK_Delete, INSERT, KEY_ANY, &delete_key},
- {NULL, XK_Escape, INSERT, KEY_ANY, &escape_key},
- {"i", 0, NORMAL, KEY_ANY, &enter_insert},
- {"h", 0, NORMAL, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_left},
- {"l", 0, NORMAL, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_right},
- {"j", 0, NORMAL, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_down},
- {"k", 0, NORMAL, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_up},
- {"0", 0, NORMAL, KEY_ANY, &cursor_to_beginning},
- {"1", 0, NORMAL, KEY_NUMBER, &push_1},
- {"2", 0, NORMAL, KEY_NUMBER, &push_2},
- {"x", 0, NORMAL, KEY_NUMBERALLOWED, &key_x}
+ {NULL, XK_BackSpace, INSERT, KEY_ANY, KEY_ANY, &backspace},
+ {NULL, XK_Left, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_left},
+ {NULL, XK_Right, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_right},
+ {NULL, XK_Up, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_up},
+ {NULL, XK_Down, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_down},
+ {NULL, XK_Return, INSERT, KEY_ANY, KEY_ANY, &return_key},
+ {NULL, XK_Delete, INSERT, KEY_ANY, KEY_ANY, &delete_key},
+ {NULL, XK_Escape, INSERT, KEY_ANY, KEY_ANY, &escape_key},
+ {"i", 0, NORMAL, KEY_ANY, KEY_ANY, &enter_insert},
+ {"h", 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_lef…
+ {"l", 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_rig…
+ {"j", 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_dow…
+ {"k", 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_up},
+ {"0", 0, NORMAL, ~KEY_NUMBER, KEY_ANY, &cursor_to_beginning},
+ {"0", 0, NORMAL, KEY_NUMBER, KEY_NUMBER, &push_0},
+ {"1", 0, NORMAL, KEY_ANY, KEY_NUMBER, &push_1},
+ {"2", 0, NORMAL, KEY_ANY, KEY_NUMBER, &push_2},
+ {"3", 0, NORMAL, KEY_ANY, KEY_NUMBER, &push_3},
+ {"4", 0, NORMAL, KEY_ANY, KEY_NUMBER, &push_4},
+ {"5", 0, NORMAL, KEY_ANY, KEY_NUMBER, &push_5},
+ {"6", 0, NORMAL, KEY_ANY, KEY_NUMBER, &push_6},
+ {"7", 0, NORMAL, KEY_ANY, KEY_NUMBER, &push_7},
+ {"8", 0, NORMAL, KEY_ANY, KEY_NUMBER, &push_8},
+ {"9", 0, NORMAL, KEY_ANY, KEY_NUMBER, &push_9},
+ {"x", 0, NORMAL, KEY_ANY, KEY_NUMBERALLOWED, &key_x},
+ {"d", 0, NORMAL, KEY_ANY, KEY_MOTION|KEY_NUMBERALLOWED, &key_d}
};
static struct key keys_ur[] = {
- {NULL, XK_BackSpace, INSERT, KEY_ANY, &backspace},
- {NULL, XK_Left, INSERT|NORMAL, KEY_ANY, &cursor_left},
- {NULL, XK_Right, INSERT|NORMAL, KEY_ANY, &cursor_right},
- {NULL, XK_Up, INSERT|NORMAL, KEY_ANY, &cursor_up},
- {NULL, XK_Down, INSERT|NORMAL, KEY_ANY, &cursor_down},
- {NULL, XK_Return, INSERT, KEY_ANY, &return_key},
- {NULL, XK_Delete, INSERT, KEY_ANY, &delete_key},
- {NULL, XK_Escape, INSERT, KEY_ANY, &escape_key},
- {"ی", 0, NORMAL, KEY_ANY, &enter_insert},
- {"ح", 0, NORMAL, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_left},
- {"ل", 0, NORMAL, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_right},
- {"ج", 0, NORMAL, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_down},
- {"ک", 0, NORMAL, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_up},
- {"0", 0, NORMAL, KEY_ANY, &cursor_to_beginning}
+ {NULL, XK_BackSpace, INSERT, KEY_ANY, KEY_ANY, &backspace},
+ {NULL, XK_Left, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_left},
+ {NULL, XK_Right, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_right},
+ {NULL, XK_Up, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_up},
+ {NULL, XK_Down, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_down},
+ {NULL, XK_Return, INSERT, KEY_ANY, KEY_ANY, &return_key},
+ {NULL, XK_Delete, INSERT, KEY_ANY, KEY_ANY, &delete_key},
+ {NULL, XK_Escape, INSERT, KEY_ANY, KEY_ANY, &escape_key},
+ {"ی", 0, NORMAL, KEY_ANY, KEY_ANY, &enter_insert},
+ {"ح", 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_le…
+ {"ل", 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_ri…
+ {"ج", 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_do…
+ {"ک", 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_up…
+ {"0", 0, NORMAL, KEY_ANY, KEY_ANY, &cursor_to_beginning}
};
static struct key keys_hi[] = {
- {NULL, XK_BackSpace, INSERT, KEY_ANY, &backspace},
- {NULL, XK_Left, INSERT|NORMAL, KEY_ANY, &cursor_left},
- {NULL, XK_Right, INSERT|NORMAL, KEY_ANY, &cursor_right},
- {NULL, XK_Up, INSERT|NORMAL, KEY_ANY, &cursor_up},
- {NULL, XK_Down, INSERT|NORMAL, KEY_ANY, &cursor_down},
- {NULL, XK_Return, INSERT, KEY_ANY, &return_key},
- {NULL, XK_Delete, INSERT, KEY_ANY, &delete_key},
- {NULL, XK_Escape, INSERT, KEY_ANY, &escape_key},
- {"ि", 0, NORMAL, KEY_ANY, &enter_insert},
- {"ह", 0, NORMAL, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_left},
- {"ल", 0, NORMAL, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_right},
- {"ज", 0, NORMAL, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_down},
- {"क", 0, NORMAL, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_up},
- {"0", 0, NORMAL, KEY_ANY, &cursor_to_beginning}
+ {NULL, XK_BackSpace, INSERT, KEY_ANY, KEY_ANY, &backspace},
+ {NULL, XK_Left, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_left},
+ {NULL, XK_Right, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_right},
+ {NULL, XK_Up, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_up},
+ {NULL, XK_Down, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_down},
+ {NULL, XK_Return, INSERT, KEY_ANY, KEY_ANY, &return_key},
+ {NULL, XK_Delete, INSERT, KEY_ANY, KEY_ANY, &delete_key},
+ {NULL, XK_Escape, INSERT, KEY_ANY, KEY_ANY, &escape_key},
+ {"ि", 0, NORMAL, KEY_ANY, KEY_ANY, &enter_insert},
+ {"ह", 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_l…
+ {"ल", 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_r…
+ {"ज", 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_d…
+ {"क", 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_u…
+ {"0", 0, NORMAL, KEY_ANY, KEY_ANY, &cursor_to_beginning}
};
#define LENGTH(X) (sizeof(X) / sizeof(X[0]))
t@@ -1044,10 +1050,12 @@ key_press(XEvent event) {
state.xic, &event.xkey, buf, sizeof(buf), &sym, NULL
);
int found = 0;
+ struct key_stack_elem *e = peek_key_stack();
for (int i = 0; i < cur_keys->num_keys; i++) {
if (cur_keys->keys[i].text) {
if (n > 0 &&
(cur_keys->keys[i].modes & state.mode) &&
+ (!e || (e->key & cur_keys->keys[i].prev_keys)) &&
!strncmp(cur_keys->keys[i].text, buf, n)) {
cur_keys->keys[i].func();
found = 1;
t@@ -1057,6 +1065,8 @@ key_press(XEvent event) {
cur_keys->keys[i].func();
found = 1;
}
+ if (found)
+ break;
}
if (state.mode == INSERT && !found && n > 0) {
ledit_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.