tClean up some usage of pango in keys_basic.c - 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 e80afa0ebd0f0fca40a797392db2a210ad466fa4 | |
parent 12a37bf84755943e32b70a7afca27f4928f684af | |
Author: lumidify <[email protected]> | |
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 | |
t@@ -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, softl… | |
+ *start_byte_ret = pl->start_index; | |
+ *end_byte_ret = pl->start_index + pl->length; | |
+} | |
+ | |
/* FIXME: implement */ | |
/* | |
int | |
t@@ -1323,6 +1351,9 @@ ledit_buffer_delete_unicode_char_base(ledit_buffer *buff… | |
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 techni… | |
+ 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 | |
t@@ -84,6 +84,8 @@ void ledit_buffer_next_bigword(ledit_buffer *buffer, int lin… | |
void ledit_buffer_next_bigword_end(ledit_buffer *buffer, int line, int byte, i… | |
void ledit_buffer_prev_word(ledit_buffer *buffer, int line, int byte, int num_… | |
void ledit_buffer_prev_bigword(ledit_buffer *buffer, int line, int byte, int n… | |
+void ledit_buffer_get_pos_softline_bounds(ledit_buffer *buffer, int line, int … | |
+void ledit_buffer_get_softline_bounds(ledit_buffer *buffer, int line, int soft… | |
size_t ledit_buffer_textlen(ledit_buffer *buffer, int line1, int byte1, int li… | |
void ledit_buffer_copy_text(ledit_buffer *buffer, char *dst, int line1, int by… | |
diff --git a/keys_basic.c b/keys_basic.c | |
t@@ -558,33 +558,28 @@ push_undo_empty_insert(ledit_buffer *buffer, int line, i… | |
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 … | |
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, &… | |
- if (hard_line_based || sli == 0) { | |
+ ledit_buffer_get_pos_softline_bounds(buffer, buffer->cur_line, buffer-… | |
+ if (hard_line_based || start == 0) { | |
insert_text(buffer, buffer->cur_line, 0, "\n", -1, -1, -1, buf… | |
} else { | |
- PangoLayoutLine *sl = pango_layout_get_line_readonly(ll->layou… | |
- insert_text(buffer, buffer->cur_line, sl->start_index, "\n\n",… | |
+ insert_text(buffer, buffer->cur_line, start, "\n\n", -1, -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-… | |
ledit_line *ll = ledit_buffer_get_line(buffer, buffer->cur_line); | |
- pango_layout_index_to_line_x(ll->layout, buffer->cur_index, 0, &sli, &… | |
- 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, -… | |
} else { | |
- insert_text(buffer, buffer->cur_line, sl->start_index + sl->le… | |
+ insert_text(buffer, buffer->cur_line, end, "\n\n", -1, -1, -1,… | |
} | |
return (struct action){ACTION_NONE, NULL}; | |
} | |
t@@ -602,18 +597,16 @@ append_after_cursor(ledit_buffer *buffer, char *text, in… | |
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-… | |
/* 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,… | |
- PangoLayoutLine *sl = pango_layout_get_line_readonly(ll->layou… | |
- buffer->cur_index = sl->start_index + sl->length; | |
- } | |
+ else | |
+ buffer->cur_index = end; | |
return (struct action){ACTION_NONE, NULL}; | |
} | |
t@@ -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,… | |
- PangoLayoutLine *sl = pango_layout_get_line_readonly(ll->layou… | |
- end = sl->start_index + sl->length; | |
+ ledit_buffer_get_pos_softline_bounds(buffer, buffer->cur_line,… | |
} | |
delete_range( | |
buffer, 0, 0, | |
t@@ -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,… | |
- PangoLayoutLine *sl = pango_layout_get_line_readonly(ll->layou… | |
- end = sl->start_index + sl->length; | |
+ ledit_buffer_get_pos_softline_bounds(buffer, buffer->cur_line,… | |
} | |
delete_range( | |
buffer, 0, 0, | |
t@@ -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_lin… | |
- PangoLayoutLine *pl = pango_layout_get_line_readonly(l… | |
- cb(buffer, new_line, pl->start_index, KEY_MOTION_LINE); | |
+ int start, end; | |
+ ledit_buffer_get_softline_bounds(buffer, new_line, new… | |
+ cb(buffer, new_line, start, KEY_MOTION_LINE); | |
clear_key_stack(); | |
} else if (cb != NULL) { | |
return err_invalid_key(buffer); | |
t@@ -923,16 +912,11 @@ change_cb(ledit_buffer *buffer, int line, int char_pos, … | |
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_lin… | |
- pango_layout_index_to_line_x(ll->layout, buffer->cur_index, 0,… | |
- PangoLayoutLine *sl = pango_layout_get_line_readonly(ll->layou… | |
- 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,… | |
+ ledit_buffer_get_pos_softline_bounds(buffer, line, char_pos, &… | |
} else if (line_based && hard_line_based) { | |
pos1 = 0; | |
ledit_line *ll = ledit_buffer_get_line(buffer, line); | |
t@@ -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_lin… | |
- PangoLayoutLine *pl = pango_layout_get_line_readonly(l… | |
- cb(buffer, new_line, pl->start_index, KEY_MOTION_LINE); | |
+ int start, end; | |
+ ledit_buffer_get_softline_bounds(buffer, new_line, new… | |
+ cb(buffer, new_line, start, KEY_MOTION_LINE); | |
clear_key_stack(); | |
} else if (cb == NULL) { | |
struct key_stack_elem *e = push_key_stack(); | |
t@@ -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_s… | |
- yank_cb(buffer, new_line, pl->start_index, KEY_MOTION_LINE); | |
+ int start, end; | |
+ ledit_buffer_get_softline_bounds(buffer, new_line, new_softline, &star… | |
+ 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 doe… | |
- extra newlines at the beginning and end (this doesn't really matter because… | |
- 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; | |
t@@ -1035,21 +1016,26 @@ yank_cb(ledit_buffer *buffer, int line, int char_pos, … | |
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->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); | |
+ int start1, end2, tmp; | |
+ ledit_buffer_get_pos_softline_bounds(buffer, l1, b1, &start1, … | |
+ ledit_buffer_get_pos_softline_bounds(buffer, l2, b2, &tmp, &en… | |
+ 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… | |
+ 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( | |
t@@ -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_lin… | |
- PangoLayoutLine *pl = pango_layout_get_line_readonly(l… | |
- cb(buffer, new_line, pl->start_index, KEY_MOTION_LINE); | |
+ int start, end; | |
+ ledit_buffer_get_softline_bounds(buffer, new_line, new… | |
+ cb(buffer, new_line, start, KEY_MOTION_LINE); | |
clear_key_stack(); | |
} else if (cb != NULL) { | |
return err_invalid_key(buffer); | |
t@@ -1112,8 +1098,6 @@ delete_cb(ledit_buffer *buffer, int line, int char_pos, … | |
finalize_repetition_stack(); | |
} | |
-/* FIXME: don't use the pango functions directly so normalize_and_set_pango_te… | |
- 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 tex… | |
hard lines, which may be unexpected, but the alternatives I could think of … | |
t@@ -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_lin… | |
int brk = 0; | |
if (hard_line_based) { | |
brk = ll->len; | |
} else { | |
- pango_layout_index_to_line_x(ll->layout, buffer->cur_i… | |
- PangoLayoutLine *sl = pango_layout_get_line_readonly(l… | |
- brk = sl->start_index + sl->length; | |
+ int tmp; | |
+ ledit_buffer_get_pos_softline_bounds(buffer, buffer->c… | |
} | |
insert_text( | |
buffer, buffer->cur_line, brk, | |
t@@ -1186,14 +1168,12 @@ paste_normal_backwards(ledit_buffer *buffer, char *tex… | |
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… | |
int brk = 0; | |
if (!hard_line_based) { | |
- pango_layout_index_to_line_x(ll->layout, buffer->cur_i… | |
- PangoLayoutLine *sl = pango_layout_get_line_readonly(l… | |
- brk = sl->start_index; | |
+ int tmp; | |
+ ledit_buffer_get_pos_softline_bounds(buffer, buffer->c… | |
} | |
insert_text( | |
buffer, buffer->cur_line, brk, | |
t@@ -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->layou… | |
- end_index = sl->start_index + sl->length; | |
+ int tmp; | |
+ ledit_buffer_get_softline_bounds(buffer, new_line, new_softlin… | |
} | |
if (cb != NULL) { | |
cb(buffer, new_line, end_index, KEY_MOTION_CHAR); | |
t@@ -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… | |
- cb(buffer, new_line, pl->start_index, KEY_MOTION_LINE); | |
+ int start, end; | |
+ ledit_buffer_get_softline_bounds(buffer, new_line, new_softlin… | |
+ cb(buffer, new_line, start, KEY_MOTION_LINE); | |
} else { | |
int lineno, x; | |
ledit_pos_to_x_softline(cur_lline, buffer->cur_index, &x, &lin… | |
t@@ -1752,11 +1733,8 @@ insert_at_beginning(ledit_buffer *buffer, char *text, i… | |
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_lin… | |
- pango_layout_index_to_line_x(ll->layout, buffer->cur_index, 0,… | |
- PangoLayoutLine *pl = pango_layout_get_line_readonly(ll->layou… | |
- new_index = pl->start_index; | |
+ int tmp; | |
+ ledit_buffer_get_pos_softline_bounds(buffer, buffer->cur_line,… | |
} | |
push_undo_empty_insert(buffer, buffer->cur_line, buffer->cur_index, 1); | |
buffer->cur_index = new_index; | |
t@@ -1777,14 +1755,13 @@ cursor_to_first_non_ws(ledit_buffer *buffer, char *tex… | |
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,… | |
- PangoLayoutLine *pl = pango_layout_get_line_readonly(ll->layou… | |
- new_index = ledit_line_next_non_whitespace(ll, pl->start_index… | |
+ int start, end; | |
+ ledit_buffer_get_pos_softline_bounds(buffer, buffer->cur_line,… | |
+ 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->le… | |
+ buffer, buffer->cur_line, end, 1 | |
); | |
} | |
} | |
t@@ -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) | |
t@@ -1812,10 +1788,8 @@ cursor_to_beginning(ledit_buffer *buffer, char *text, i… | |
/* 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_lin… | |
- pango_layout_index_to_line_x(ll->layout, buffer->cur_index, 0,… | |
- PangoLayoutLine *pl = pango_layout_get_line_readonly(ll->layou… | |
- start_index = pl->start_index; | |
+ int tmp; | |
+ ledit_buffer_get_pos_softline_bounds(buffer, buffer->cur_line,… | |
} | |
if (cb != NULL) { | |
cb(buffer, buffer->cur_line, start_index, KEY_MOTION_CHAR); |