commit e80afa0ebd0f0fca40a797392db2a210ad466fa4
parent 12a37bf84755943e32b70a7afca27f4928f684af
Author: lumidify <nobody@lumidify.org>
Date: Wed, 17 Nov 2021 11:19:06 +0100
Clean up some usage of pango in keys_basic.c
Diffstat:
M | buffer.c | | | 31 | +++++++++++++++++++++++++++++++ |
M | buffer.h | | | 2 | ++ |
M | keys_basic.c | | | 158 | +++++++++++++++++++++++++++++++++---------------------------------------------- |
3 files changed, 99 insertions(+), 92 deletions(-)
diff --git a/buffer.c b/buffer.c
@@ -1256,6 +1256,34 @@ GEN_NEXT_WORD(bigword_end, line_next_bigword_end)
GEN_PREV_WORD(word, line_prev_word)
GEN_PREV_WORD(bigword, line_prev_bigword)
+void
+ledit_buffer_get_pos_softline_bounds(
+ ledit_buffer *buffer, int line, int pos,
+ int *start_byte_ret, int *end_byte_ret) {
+ assert(line >= 0 && line < buffer->lines_num);
+ ledit_line *ll = ledit_buffer_get_line(buffer, line);
+ normalize_and_set_pango_text(ll);
+ assert(pos >= 0 && pos <= ll->len);
+ int x, sli;
+ pango_layout_index_to_line_x(ll->layout, pos, 0, &sli, &x);
+ PangoLayoutLine *pl = pango_layout_get_line_readonly(ll->layout, sli);
+ *start_byte_ret = pl->start_index;
+ *end_byte_ret = pl->start_index + pl->length;
+}
+
+void
+ledit_buffer_get_softline_bounds(
+ ledit_buffer *buffer, int line, int softline,
+ int *start_byte_ret, int *end_byte_ret) {
+ assert(line >= 0 && line < buffer->lines_num);
+ ledit_line *ll = ledit_buffer_get_line(buffer, line);
+ normalize_and_set_pango_text(ll);
+ assert(softline < pango_layout_get_line_count(ll->layout));
+ PangoLayoutLine *pl = pango_layout_get_line_readonly(ll->layout, softline);
+ *start_byte_ret = pl->start_index;
+ *end_byte_ret = pl->start_index + pl->length;
+}
+
/* FIXME: implement */
/*
int
@@ -1323,6 +1351,9 @@ ledit_buffer_delete_unicode_char_base(ledit_buffer *buffer, int line_index, int
return new_index;
}
+/* FIXME: normalize_line will generally be called whenever it is not normalized
+ since text_dirty should be set then, but the naming of this function technically
+ isn't very good */
static void
normalize_and_set_pango_text(ledit_line *line) {
if (line->text_dirty) {
diff --git a/buffer.h b/buffer.h
@@ -84,6 +84,8 @@ void ledit_buffer_next_bigword(ledit_buffer *buffer, int line, int byte, int num
void ledit_buffer_next_bigword_end(ledit_buffer *buffer, int line, int byte, int num_repeat, int *line_ret, int *byte_ret, int *real_byte_ret);
void ledit_buffer_prev_word(ledit_buffer *buffer, int line, int byte, int num_repeat, int *line_ret, int *byte_ret, int *real_byte_ret);
void ledit_buffer_prev_bigword(ledit_buffer *buffer, int line, int byte, int num_repeat, int *line_ret, int *byte_ret, int *real_byte_ret);
+void ledit_buffer_get_pos_softline_bounds(ledit_buffer *buffer, int line, int pos, int *start_byte_ret, int *end_byte_ret);
+void ledit_buffer_get_softline_bounds(ledit_buffer *buffer, int line, int softline, int *start_byte_ret, int *end_byte_ret);
size_t ledit_buffer_textlen(ledit_buffer *buffer, int line1, int byte1, int line2, int byte2);
void ledit_buffer_copy_text(ledit_buffer *buffer, char *dst, int line1, int byte1, int line2, int byte2);
diff --git a/keys_basic.c b/keys_basic.c
@@ -558,33 +558,28 @@ push_undo_empty_insert(ledit_buffer *buffer, int line, int index, int start_grou
static struct action
append_line_above(ledit_buffer *buffer, char *text, int len) {
- int sli, x;
+ int start, end;
/* do this here already so the mode group is the same for the newline insertion */
enter_insert(buffer, text, len);
- ledit_line *ll = ledit_buffer_get_line(buffer, buffer->cur_line);
- /* FIXME: this is more "elegant", but inefficient because this doesn't
- actually need to be called when hard_line_based == 1 */
- pango_layout_index_to_line_x(ll->layout, buffer->cur_index, 0, &sli, &x);
- if (hard_line_based || sli == 0) {
+ ledit_buffer_get_pos_softline_bounds(buffer, buffer->cur_line, buffer->cur_index, &start, &end);
+ if (hard_line_based || start == 0) {
insert_text(buffer, buffer->cur_line, 0, "\n", -1, -1, -1, buffer->cur_line, 0, 1);
} else {
- PangoLayoutLine *sl = pango_layout_get_line_readonly(ll->layout, sli);
- insert_text(buffer, buffer->cur_line, sl->start_index, "\n\n", -1, -1, -1, buffer->cur_line + 1, 0, 1);
+ insert_text(buffer, buffer->cur_line, start, "\n\n", -1, -1, -1, buffer->cur_line + 1, 0, 1);
}
return (struct action){ACTION_NONE, NULL};
}
static struct action
append_line_below(ledit_buffer *buffer, char *text, int len) {
- int sli, x;
+ int start, end;
enter_insert(buffer, text, len);
+ ledit_buffer_get_pos_softline_bounds(buffer, buffer->cur_line, buffer->cur_index, &start, &end);
ledit_line *ll = ledit_buffer_get_line(buffer, buffer->cur_line);
- pango_layout_index_to_line_x(ll->layout, buffer->cur_index, 0, &sli, &x);
- PangoLayoutLine *sl = pango_layout_get_line_readonly(ll->layout, sli);
- if (hard_line_based || sl->start_index + sl->length == ll->len) {
+ if (hard_line_based || end == ll->len) {
insert_text(buffer, buffer->cur_line, ll->len, "\n", -1, -1, -1, buffer->cur_line + 1, 0, 1);
} else {
- insert_text(buffer, buffer->cur_line, sl->start_index + sl->length, "\n\n", -1, -1, -1, buffer->cur_line + 1, 0, 1);
+ insert_text(buffer, buffer->cur_line, end, "\n\n", -1, -1, -1, buffer->cur_line + 1, 0, 1);
}
return (struct action){ACTION_NONE, NULL};
}
@@ -602,18 +597,16 @@ append_after_cursor(ledit_buffer *buffer, char *text, int len) {
static struct action
append_after_eol(ledit_buffer *buffer, char *text, int len) {
- int sli, x;
+ int start, end;
enter_insert(buffer, text, len);
+ ledit_buffer_get_pos_softline_bounds(buffer, buffer->cur_line, buffer->cur_index, &start, &end);
/* make cursor jump back to original position on undo */
push_undo_empty_insert(buffer, buffer->cur_line, buffer->cur_index, 1);
ledit_line *ll = ledit_buffer_get_line(buffer, buffer->cur_line);
- if (hard_line_based) {
+ if (hard_line_based)
buffer->cur_index = ll->len;
- } else {
- pango_layout_index_to_line_x(ll->layout, buffer->cur_index, 0, &sli, &x);
- PangoLayoutLine *sl = pango_layout_get_line_readonly(ll->layout, sli);
- buffer->cur_index = sl->start_index + sl->length;
- }
+ else
+ buffer->cur_index = end;
return (struct action){ACTION_NONE, NULL};
}
@@ -829,14 +822,12 @@ delete_to_eol(ledit_buffer *buffer, char *text, int len) {
(void)len;
if (!key_stack_empty())
return err_invalid_key(buffer);
- int end, x, sli;
+ int start, end;
ledit_line *ll = ledit_buffer_get_line(buffer, buffer->cur_line);
if (hard_line_based) {
end = ll->len;
} else {
- pango_layout_index_to_line_x(ll->layout, buffer->cur_index, 0, &sli, &x);
- PangoLayoutLine *sl = pango_layout_get_line_readonly(ll->layout, sli);
- end = sl->start_index + sl->length;
+ ledit_buffer_get_pos_softline_bounds(buffer, buffer->cur_line, buffer->cur_index, &start, &end);
}
delete_range(
buffer, 0, 0,
@@ -858,14 +849,12 @@ change_to_eol(ledit_buffer *buffer, char *text, int len) {
if (!key_stack_empty())
return err_invalid_key(buffer);
ledit_buffer_set_mode(buffer, INSERT);
- int end, x, sli;
+ int start, end;
ledit_line *ll = ledit_buffer_get_line(buffer, buffer->cur_line);
if (hard_line_based) {
end = ll->len;
} else {
- pango_layout_index_to_line_x(ll->layout, buffer->cur_index, 0, &sli, &x);
- PangoLayoutLine *sl = pango_layout_get_line_readonly(ll->layout, sli);
- end = sl->start_index + sl->length;
+ ledit_buffer_get_pos_softline_bounds(buffer, buffer->cur_line, buffer->cur_index, &start, &end);
}
delete_range(
buffer, 0, 0,
@@ -900,9 +889,9 @@ change(ledit_buffer *buffer, char *text, int len) {
buffer, buffer->cur_line, buffer->cur_index,
lines - 1, &new_line, &new_softline
);
- ledit_line *ll = ledit_buffer_get_line(buffer, new_line);
- PangoLayoutLine *pl = pango_layout_get_line_readonly(ll->layout, new_softline);
- cb(buffer, new_line, pl->start_index, KEY_MOTION_LINE);
+ int start, end;
+ ledit_buffer_get_softline_bounds(buffer, new_line, new_softline, &start, &end);
+ cb(buffer, new_line, start, KEY_MOTION_LINE);
clear_key_stack();
} else if (cb != NULL) {
return err_invalid_key(buffer);
@@ -923,16 +912,11 @@ change_cb(ledit_buffer *buffer, int line, int char_pos, enum key_type type) {
int line_based = type == KEY_MOTION_LINE ? 1 : 0;
/* this hackery is needed to avoid deleting the entire last line and
instead leave an empty line - this should be made nicer (FIXME) */
- int pos1 = buffer->cur_index, pos2 = char_pos, x, sli;
+ int pos1 = buffer->cur_index, pos2 = char_pos;
if (line_based && !hard_line_based) {
- ledit_line *ll = ledit_buffer_get_line(buffer, buffer->cur_line);
- pango_layout_index_to_line_x(ll->layout, buffer->cur_index, 0, &sli, &x);
- PangoLayoutLine *sl = pango_layout_get_line_readonly(ll->layout, sli);
- pos1 = sl->start_index;
- ll = ledit_buffer_get_line(buffer, line);
- pango_layout_index_to_line_x(ll->layout, char_pos, 0, &sli, &x);
- sl = pango_layout_get_line_readonly(ll->layout, sli);
- pos2 = sl->start_index + sl->length;
+ int pos1, pos2, tmp;
+ ledit_buffer_get_pos_softline_bounds(buffer, buffer->cur_line, buffer->cur_index, &pos1, &tmp);
+ ledit_buffer_get_pos_softline_bounds(buffer, line, char_pos, &tmp, &pos2);
} else if (line_based && hard_line_based) {
pos1 = 0;
ledit_line *ll = ledit_buffer_get_line(buffer, line);
@@ -983,9 +967,9 @@ yank(ledit_buffer *buffer, char *text, int len) {
buffer, buffer->cur_line, buffer->cur_index,
num - 1, &new_line, &new_softline
);
- ledit_line *ll = ledit_buffer_get_line(buffer, new_line);
- PangoLayoutLine *pl = pango_layout_get_line_readonly(ll->layout, new_softline);
- cb(buffer, new_line, pl->start_index, KEY_MOTION_LINE);
+ int start, end;
+ ledit_buffer_get_softline_bounds(buffer, new_line, new_softline, &start, &end);
+ cb(buffer, new_line, start, KEY_MOTION_LINE);
clear_key_stack();
} else if (cb == NULL) {
struct key_stack_elem *e = push_key_stack();
@@ -1014,16 +998,13 @@ yank_lines(ledit_buffer *buffer, char *text, int len) {
buffer, buffer->cur_line, buffer->cur_index,
num - 1, &new_line, &new_softline
);
- ledit_line *ll = ledit_buffer_get_line(buffer, new_line);
- PangoLayoutLine *pl = pango_layout_get_line_readonly(ll->layout, new_softline);
- yank_cb(buffer, new_line, pl->start_index, KEY_MOTION_LINE);
+ int start, end;
+ ledit_buffer_get_softline_bounds(buffer, new_line, new_softline, &start, &end);
+ yank_cb(buffer, new_line, start, KEY_MOTION_LINE);
clear_key_stack();
return (struct action){ACTION_NONE, NULL};
}
-/* FIXME: delete_range and yank put different things in past_buffer - yank doesn't include
- extra newlines at the beginning and end (this doesn't really matter because paste
- ignores them anyways, but it is a bit weird) */
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;
@@ -1035,21 +1016,26 @@ yank_cb(ledit_buffer *buffer, int line, int char_pos, enum key_type type) {
swap(&b1, &b2);
}
if (line_based && !hard_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->layout, sl1);
- 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->layout, sl2);
- assert(pl1 != NULL && pl2 != NULL);
+ int start1, end2, tmp;
+ ledit_buffer_get_pos_softline_bounds(buffer, l1, b1, &start1, &tmp);
+ ledit_buffer_get_pos_softline_bounds(buffer, l2, b2, &tmp, &end2);
+ ledit_line *ll = ledit_buffer_get_line(buffer, l2);
+ if (end2 == ll->len && l2 < buffer->lines_num - 1) {
+ l2++;
+ end2 = 0;
+ }
ledit_buffer_copy_text_to_txtbuf(
- buffer, paste_buffer, l1, pl1->start_index, l2, pl2->start_index + pl2->length
+ buffer, paste_buffer, l1, start1, l2, end2
);
} else if (line_based && hard_line_based) {
ledit_line *ll = ledit_buffer_get_line(buffer, l2);
+ int end = ll->len;
+ if (l2 < buffer->lines_num - 1) {
+ l2++;
+ end = 0;
+ }
ledit_buffer_copy_text_to_txtbuf(
- buffer, paste_buffer, l1, 0, l2, ll->len
+ buffer, paste_buffer, l1, 0, l2, end
);
} else {
ledit_buffer_copy_text_to_txtbuf(
@@ -1082,9 +1068,9 @@ delete(ledit_buffer *buffer, char *text, int len) {
buffer, buffer->cur_line, buffer->cur_index,
lines - 1, &new_line, &new_softline
);
- ledit_line *ll = ledit_buffer_get_line(buffer, new_line);
- PangoLayoutLine *pl = pango_layout_get_line_readonly(ll->layout, new_softline);
- cb(buffer, new_line, pl->start_index, KEY_MOTION_LINE);
+ int start, end;
+ ledit_buffer_get_softline_bounds(buffer, new_line, new_softline, &start, &end);
+ cb(buffer, new_line, start, KEY_MOTION_LINE);
clear_key_stack();
} else if (cb != NULL) {
return err_invalid_key(buffer);
@@ -1112,8 +1098,6 @@ delete_cb(ledit_buffer *buffer, int line, int char_pos, enum key_type type) {
finalize_repetition_stack();
}
-/* FIXME: don't use the pango functions directly so normalize_and_set_pango_text is
- always called properly */
/* Note that these paste functions are a bit weird when working with softlines -
they always make sure the pasted text is separated from the surrounding text by
hard lines, which may be unexpected, but the alternatives I could think of are
@@ -1128,16 +1112,14 @@ paste_normal(ledit_buffer *buffer, char *text, int len) {
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_line);
int brk = 0;
if (hard_line_based) {
brk = ll->len;
} else {
- pango_layout_index_to_line_x(ll->layout, buffer->cur_index, 0, &softline, &x);
- PangoLayoutLine *sl = pango_layout_get_line_readonly(ll->layout, softline);
- brk = sl->start_index + sl->length;
+ int tmp;
+ ledit_buffer_get_pos_softline_bounds(buffer, buffer->cur_line, buffer->cur_index, &tmp, &brk);
}
insert_text(
buffer, buffer->cur_line, brk,
@@ -1186,14 +1168,12 @@ paste_normal_backwards(ledit_buffer *buffer, char *text, int len) {
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_line);
int brk = 0;
if (!hard_line_based) {
- pango_layout_index_to_line_x(ll->layout, buffer->cur_index, 0, &softline, &x);
- PangoLayoutLine *sl = pango_layout_get_line_readonly(ll->layout, softline);
- brk = sl->start_index;
+ int tmp;
+ ledit_buffer_get_pos_softline_bounds(buffer, buffer->cur_line, buffer->cur_index, &brk, &tmp);
}
insert_text(
buffer, buffer->cur_line, brk,
@@ -1393,8 +1373,8 @@ move_to_eol(ledit_buffer *buffer, char *text, int len) {
ledit_line *ll = ledit_buffer_get_line(buffer, new_line);
int end_index = ll->len;
if (!hard_line_based) {
- PangoLayoutLine *sl = pango_layout_get_line_readonly(ll->layout, new_softline);
- end_index = sl->start_index + sl->length;
+ int tmp;
+ ledit_buffer_get_softline_bounds(buffer, new_line, new_softline, &tmp, &end_index);
}
if (cb != NULL) {
cb(buffer, new_line, end_index, KEY_MOTION_CHAR);
@@ -1657,8 +1637,9 @@ move_cursor_up_down(ledit_buffer *buffer, int dir) {
ledit_line *cur_lline = ledit_buffer_get_line(buffer, buffer->cur_line);
ledit_line *new_lline = ledit_buffer_get_line(buffer, new_line);
if (cb != NULL) {
- PangoLayoutLine *pl = pango_layout_get_line_readonly(new_lline->layout, new_softline);
- cb(buffer, new_line, pl->start_index, KEY_MOTION_LINE);
+ int start, end;
+ ledit_buffer_get_softline_bounds(buffer, new_line, new_softline, &start, &end);
+ cb(buffer, new_line, start, KEY_MOTION_LINE);
} else {
int lineno, x;
ledit_pos_to_x_softline(cur_lline, buffer->cur_index, &x, &lineno);
@@ -1752,11 +1733,8 @@ insert_at_beginning(ledit_buffer *buffer, char *text, int len) {
enter_insert(buffer, text, len);
int new_index = 0;
if (!hard_line_based) {
- int x, sli;
- ledit_line *ll = ledit_buffer_get_line(buffer, buffer->cur_line);
- pango_layout_index_to_line_x(ll->layout, buffer->cur_index, 0, &sli, &x);
- PangoLayoutLine *pl = pango_layout_get_line_readonly(ll->layout, sli);
- new_index = pl->start_index;
+ int tmp;
+ ledit_buffer_get_pos_softline_bounds(buffer, buffer->cur_line, buffer->cur_index, &new_index, &tmp);
}
push_undo_empty_insert(buffer, buffer->cur_line, buffer->cur_index, 1);
buffer->cur_index = new_index;
@@ -1777,14 +1755,13 @@ cursor_to_first_non_ws(ledit_buffer *buffer, char *text, int len) {
if (hard_line_based) {
new_index = ledit_line_next_non_whitespace(ll, 0);
} else {
- int x, sli;
- pango_layout_index_to_line_x(ll->layout, buffer->cur_index, 0, &sli, &x);
- PangoLayoutLine *pl = pango_layout_get_line_readonly(ll->layout, sli);
- new_index = ledit_line_next_non_whitespace(ll, pl->start_index);
+ int start, end;
+ ledit_buffer_get_pos_softline_bounds(buffer, buffer->cur_line, buffer->cur_index, &start, &end);
+ new_index = ledit_line_next_non_whitespace(ll, start);
/* next non-whitespace might be on next softline */
- if (new_index >= pl->start_index + pl->length) {
+ if (new_index >= end) {
new_index = ledit_buffer_prev_cursor_pos(
- buffer, buffer->cur_line, pl->start_index + pl->length, 1
+ buffer, buffer->cur_line, end, 1
);
}
}
@@ -1804,7 +1781,6 @@ static struct action
cursor_to_beginning(ledit_buffer *buffer, char *text, int len) {
(void)text;
(void)len;
- int x, sli;
motion_callback cb;
int num = get_key_repeat_and_motion_cb(&cb);
if (num != 0)
@@ -1812,10 +1788,8 @@ cursor_to_beginning(ledit_buffer *buffer, char *text, int len) {
/* FIXME: should anything be done with num? */
int start_index = 0;
if (!hard_line_based) {
- ledit_line *ll = ledit_buffer_get_line(buffer, buffer->cur_line);
- pango_layout_index_to_line_x(ll->layout, buffer->cur_index, 0, &sli, &x);
- PangoLayoutLine *pl = pango_layout_get_line_readonly(ll->layout, sli);
- start_index = pl->start_index;
+ int tmp;
+ ledit_buffer_get_pos_softline_bounds(buffer, buffer->cur_line, buffer->cur_index, &start_index, &tmp);
}
if (cb != NULL) {
cb(buffer, buffer->cur_line, start_index, KEY_MOTION_CHAR);