Introduction
Introduction Statistics Contact Development Disclaimer Help
tAdd basic repetition and motion callback support to cursor movement keys - led…
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 3895a14f2fb3bcc35ba842e259074a67adddb8a1
parent 52cea73bf0e43483210cb94e5177989bc524a30c
Author: lumidify <[email protected]>
Date: Thu, 13 May 2021 21:54:24 +0200
Add basic repetition and motion callback support to cursor movement keys
Diffstat:
M buffer.c | 12 +++++++++---
M ledit.c | 249 ++++++++++++++++++++---------…
2 files changed, 171 insertions(+), 90 deletions(-)
---
diff --git a/buffer.c b/buffer.c
t@@ -494,10 +494,16 @@ ledit_delete_range(
}
delete_line_section(buffer, line_index1, b1, b2 - b1);
*new_line_ret = line_index1;
+ ledit_line *ll = ledit_get_line(buffer, line_index1);
+ /* FIXME: where should this be done? */
+ /* FIXME: also do this below in the else statement */
+ if (buffer->state->mode == NORMAL && b1 == ll->len && …
+ /* FIXME: use grapheme instead of character! */
+ b1 = ll->len - 1;
+ while (b1 > 0 && ((ll->text[b1] & 0xC0) == 0x8…
+ b1--;
+ }
*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) {
diff --git a/ledit.c b/ledit.c
t@@ -91,9 +91,10 @@ static void resize_window(int w, int h);
static void backspace(void);
static void delete_key(void);
-static void move_cursor(int dir);
+static void move_cursor_left_right(int dir);
static void cursor_left(void);
static void cursor_right(void);
+static void move_cursor_up_down(int dir);
static void cursor_down(void);
static void cursor_up(void);
static void cursor_to_beginning(void);
t@@ -117,6 +118,67 @@ static void key_d_cb(int line, int char_pos, enum key_typ…
static void change_keyboard(char *lang);
static void key_press(XEvent event);
+static void get_new_line_softline(
+ int cur_line, int cur_index, int movement,
+ int *new_line_ret, int *new_softline_ret
+);
+
+static void
+get_new_line_softline(
+ int cur_line, int cur_index, int movement,
+ int *new_line_ret, int *new_softline_ret) {
+ ledit_line *line = ledit_get_line(buffer, cur_line);
+ int x, softline;
+ pango_layout_index_to_line_x(line->layout, cur_index, 0, &softline, &x…
+ if (movement > 0) {
+ int softlines = pango_layout_get_line_count(line->layout);
+ if (softlines - softline > movement) {
+ *new_line_ret = cur_line;
+ *new_softline_ret = softline + movement;
+ } else {
+ movement -= (softlines - softline - 1);
+ int endline = cur_line + 1;
+ while (movement > 0 && endline < buffer->lines_num) {
+ line = ledit_get_line(buffer, endline);
+ softlines = pango_layout_get_line_count(line->…
+ movement -= softlines;
+ endline++;
+ }
+ endline--;
+ if (movement <= 0) {
+ *new_softline_ret = movement + softlines - 1;
+ } else {
+ *new_softline_ret = softlines - 1;
+ }
+ *new_line_ret = endline;
+ }
+ } else if (movement < 0) {
+ int softlines = 0;
+ if (softline + movement >= 0) {
+ *new_line_ret = cur_line;
+ *new_softline_ret = softline + movement;
+ } else {
+ movement += softline;
+ int endline = cur_line - 1;
+ while (movement < 0 && endline >= 0) {
+ line = ledit_get_line(buffer, endline);
+ softlines = pango_layout_get_line_count(line->…
+ movement += softlines;
+ endline--;
+ }
+ endline++;
+ if (movement >= 0) {
+ *new_softline_ret = movement;
+ } else {
+ *new_softline_ret = 0;
+ }
+ *new_line_ret = endline;
+ }
+ } else {
+ *new_line_ret = cur_line;
+ *new_softline_ret = softline;
+ }
+}
static void
key_d(void) {
t@@ -132,33 +194,14 @@ key_d(void) {
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…
- }
+ int new_line, new_softline;
+ get_new_line_softline(
+ buffer->cur_line, buffer->cur_index, lines - 1,
+ &new_line, &new_softline
+ );
+ ledit_line *ll = ledit_get_line(buffer, new_line);
+ PangoLayoutLine *pl = pango_layout_get_line_readonly(l…
+ e->motion_cb(new_line, pl->start_index, KEY_MOTION_LIN…
clear_key_stack();
} else if (e != NULL) {
clear_key_stack();
t@@ -175,7 +218,6 @@ key_d(void) {
/* 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,
t@@ -819,51 +861,79 @@ delete_key(void) {
ledit_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->cur_inde…
}
-/* FIXME: this comment needs to be implemented still */
-/* num is number of graphemes to move (see pango documentation) - negative
- * is left, positive is right */
static void
-move_cursor(int dir) {
+move_cursor_left_right(int dir) {
+ 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 : 0;
+ e = pop_key_stack();
+ }
+ if (e != NULL)
+ num *= (e->count > 0 ? e->count : 1);
+ }
+
/* FIXME: trailing */
- int trailing, last_index = buffer->cur_index;
+ int trailing = 0, tmp_index;
ledit_line *cur_line = ledit_get_line(buffer, buffer->cur_line);
- pango_layout_move_cursor_visually(
- cur_line->layout, TRUE,
- buffer->cur_index, 0, dir,
- &buffer->cur_index, &trailing
- );
+ int new_index = buffer->cur_index, last_index = buffer->cur_index;
+ while (num > 0) {
+ tmp_index = new_index;
+ pango_layout_move_cursor_visually(
+ cur_line->layout, TRUE,
+ new_index, trailing, dir,
+ &new_index, &trailing
+ );
+ /* for some reason, this is necessary */
+ if (new_index < 0)
+ new_index = 0;
+ else if (new_index > cur_line->len)
+ new_index = cur_line->len;
+ num--;
+ if (tmp_index != new_index)
+ last_index = tmp_index;
+ }
/* 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 */
/* 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++;
+ new_index++;
+ while (new_index < cur_line->len &&
+ ((cur_line->text[new_index] & 0xC0) == 0x80))
+ new_index++;
}
- if (buffer->cur_index < 0)
- buffer->cur_index = 0;
+ if (new_index < 0)
+ new_index = 0;
/* when in normal mode, the cursor cannot be at the very end
of the line because it's always covering a character */
- if (buffer->cur_index >= cur_line->len) {
- if (state.mode == NORMAL)
- buffer->cur_index = last_index;
- else
- buffer->cur_index = cur_line->len;
+ if (new_index >= cur_line->len) {
+ if (state.mode == NORMAL && (e == NULL || e->motion_cb == NULL…
+ new_index = last_index;
+ } else {
+ /* FIXME: I guess this is unnecessary */
+ new_index = cur_line->len;
+ }
}
- ledit_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->cur_inde…
+ if (e != NULL & e->motion_cb != NULL) {
+ e->motion_cb(buffer->cur_line, new_index, KEY_MOTION_CHAR);
+ } else {
+ buffer->cur_index = new_index;
+ ledit_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->…
+ }
+ clear_key_stack();
}
static void
cursor_left(void) {
- move_cursor(-1);
+ move_cursor_left_right(-1);
}
static void
cursor_right(void) {
- move_cursor(1);
+ move_cursor_left_right(1);
}
static void
t@@ -901,48 +971,53 @@ enter_insert(void) {
ledit_wipe_line_cursor_attrs(buffer, buffer->cur_line);
}
+/* FIXME: Check if previous key allows motion command - or is this checked aut…
static void
-cursor_down(void) {
- int lineno, x;
- ledit_line *cur_line = ledit_get_line(buffer, buffer->cur_line);
- 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);
- /* move to the next hard line */
- if (buffer->cur_line < buffer->lines_num - 1) {
- buffer->cur_line++;
- cur_line = ledit_get_line(buffer, buffer->cur_line);
- ledit_x_softline_to_pos(cur_line, x, 0, &buffer->cur_i…
+move_cursor_up_down(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 : 0;
+ e = pop_key_stack();
}
+ if (e != NULL)
+ num *= (e->count > 0 ? e->count : 1);
+ }
+ num *= dir;
+
+ get_new_line_softline(
+ buffer->cur_line, buffer->cur_index, num,
+ &new_line, &new_softline
+ );
+
+ ledit_line *cur_lline = ledit_get_line(buffer, buffer->cur_line);
+ ledit_line *new_lline = ledit_get_line(buffer, new_line);
+ if (e != NULL && e->motion_cb != NULL) {
+ PangoLayoutLine *pl = pango_layout_get_line_readonly(new_lline…
+ e->motion_cb(new_line, pl->start_index, KEY_MOTION_LINE);
} else {
- /* move to the next soft line */
- ledit_x_softline_to_pos(cur_line, x, lineno + 1, &buffer->cur_…
+ int lineno, x;
+ ledit_pos_to_x_softline(cur_lline, buffer->cur_index, &x, &lin…
+ ledit_x_softline_to_pos(new_lline, x, new_softline, &buffer->c…
+ if (buffer->cur_line != new_line)
+ ledit_wipe_line_cursor_attrs(buffer, buffer->cur_line);
+ buffer->cur_line = new_line;
+ ledit_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->…
}
- ledit_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->cur_inde…
+ clear_key_stack();
+}
+
+static void
+cursor_down(void) {
+ move_cursor_up_down(1);
}
static void
cursor_up(void) {
- int lineno, x;
- ledit_line *cur_line = ledit_get_line(buffer, buffer->cur_line);
- 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 */
- if (buffer->cur_line > 0) {
- buffer->cur_line--;
- cur_line = ledit_get_line(buffer, buffer->cur_line);
- int maxlines = pango_layout_get_line_count(cur_line->l…
- ledit_x_softline_to_pos(cur_line, x, maxlines - 1, &bu…
- }
- } else {
- /* move to the previous soft line */
- ledit_x_softline_to_pos(cur_line, x, lineno - 1, &buffer->cur_…
- }
- ledit_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->cur_inde…
+ move_cursor_up_down(-1);
}
static void
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.