Introduction
Introduction Statistics Contact Development Disclaimer Help
tImplement switching between hard line and soft line mode - ledit - Text editor…
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 f9064673e6ced9b9d8a2c1461c108170c15a96bc
parent f46f28e4d372daa0353489d65a29078e69fe0376
Author: lumidify <[email protected]>
Date: Sun, 14 Nov 2021 21:50:14 +0100
Implement switching between hard line and soft line mode
But it's all really ugly and buggy.
Diffstat:
M buffer.c | 85 +++++++++++++++++++++++++++++…
M buffer.h | 10 ++++++++--
M keys_basic.c | 291 ++++++++++++++++++++---------…
M keys_basic.h | 1 +
M keys_basic_config.h | 3 +++
M ledit.c | 1 +
M memory.c | 17 +++++++++++++++++
M memory.h | 1 +
M window.c | 21 +++++++++++++++++----
M window.h | 2 ++
10 files changed, 322 insertions(+), 110 deletions(-)
---
diff --git a/buffer.c b/buffer.c
t@@ -1,5 +1,6 @@
/* FIXME: shrink buffers when text length less than a fourth of the size */
/* FIXME: also cache PangoLayouts since keeping them around isn't really of mu…
+/* FIXME: handle all undo within buffer to keep it consistent */
#include <stdio.h>
#include <errno.h>
t@@ -1404,13 +1405,13 @@ ledit_buffer_get_legal_normal_pos(ledit_buffer *buffer…
void
ledit_buffer_delete_range(
- ledit_buffer *buffer, int line_based,
+ ledit_buffer *buffer, enum delete_mode delmode,
int line_index1, int byte_index1,
int line_index2, int byte_index2,
int *new_line_ret, int *new_byte_ret,
ledit_range *final_range_ret, txtbuf *text_ret) {
ledit_buffer_delete_range_base(
- buffer, line_based,
+ buffer, delmode,
line_index1, byte_index1,
line_index2, byte_index2,
new_line_ret, new_byte_ret,
t@@ -1423,10 +1424,15 @@ ledit_buffer_delete_range(
}
/* Note: line_index* and byte_index* don't need to be sorted */
+/* line_index1, byte_index1 are used as the cursor position in order
+ to determine the new cursor position */
/* FIXME: use at least somewhat sensible variable names */
+/* FIXME: I once noticed a bug where using 'dG' to delete to the end of
+ the file caused a line index way larger than buffer->lines_num to be
+ given, but I couldn't reproduce this bug */
void
ledit_buffer_delete_range_base(
- ledit_buffer *buffer, int line_based,
+ ledit_buffer *buffer, enum delete_mode delmode,
int line_index1, int byte_index1,
int line_index2, int byte_index2,
int *new_line_ret, int *new_byte_ret,
t@@ -1435,9 +1441,80 @@ ledit_buffer_delete_range_base(
/* range line x, range byte x */
int rgl1 = 0, rgb1 = 0, rgl2 = 0, rgb2 = 0;
int new_line = 0, new_byte = 0;
+ assert(line_index1 >= 0);
+ assert(line_index2 >= 0);
+ assert(line_index1 < buffer->lines_num);
+ assert(line_index2 < buffer->lines_num);
/* FIXME: could this be simplified by just calculating the range and t…
the non-line-based version? */
- if (line_based) {
+ if (delmode == DELETE_HARDLINE) {
+ int x, sl_useless;
+ int l1 = line_index1, l2 = line_index2;
+ if (line_index1 > line_index2) {
+ l1 = line_index2;
+ l2 = line_index1;
+ }
+ int dell1 = l1, dell2 = l2;
+ ledit_line *ll = ledit_buffer_get_line(buffer, line_index1);
+ ledit_pos_to_x_softline(ll, byte_index1, &x, &sl_useless);
+ if (l1 > 0 && l2 < buffer->lines_num - 1) {
+ rgl1 = l1;
+ rgb1 = 0;
+ rgl2 = l2 + 1;
+ rgb2 = 0;
+ } else if (l1 > 0) {
+ rgl1 = l1 - 1;
+ ll = ledit_buffer_get_line(buffer, rgl1);
+ rgb1 = ll->len;
+ rgl2 = l2;
+ ll = ledit_buffer_get_line(buffer, rgl2);
+ rgb2 = ll->len;
+ } else if (l2 < buffer->lines_num - 1) {
+ rgl1 = l1;
+ rgb1 = 0;
+ rgl2 = l2 + 1;
+ rgb2 = 0;
+ } else {
+ rgl1 = l1;
+ rgb1 = 0;
+ rgl2 = l2;
+ ll = ledit_buffer_get_line(buffer, rgl2);
+ rgb2 = ll->len;
+ }
+ if (text_ret) {
+ ledit_buffer_copy_text_to_txtbuf(
+ buffer, text_ret,
+ rgl1, rgb1, rgl2, rgb2
+ );
+ }
+ /* default is dell1 = l1, dell2 = l2 */
+ if (l2 < buffer->lines_num - 1) {
+ new_line = l1;
+ ledit_x_softline_to_pos(
+ ledit_buffer_get_line(buffer, l2 + 1),
+ x, 0, &new_byte
+ );
+ } else if (l1 > 0) {
+ new_line = l1 - 1;
+ ledit_x_softline_to_pos(
+ ledit_buffer_get_line(buffer, l1 - 1),
+ x, 0, &new_byte
+ );
+ } else {
+ dell1 = l1 + 1;
+ dell2 = l2;
+ new_line = l1;
+ new_byte = 0;
+ /* happens when all lines are deleted, so one line has…
+ ll = ledit_buffer_get_line(buffer, l1);
+ delete_line_section_base(
+ buffer, l1, 0, ll->len
+ );
+ }
+ if (dell1 <= dell2) {
+ ledit_buffer_delete_line_entries_base(buffer, dell1, d…
+ }
+ } else if (delmode == DELETE_SOFTLINE) {
int x, softline1, softline2;
ledit_line *line1 = ledit_buffer_get_line(buffer, line_index1);
normalize_and_set_pango_text(line1);
diff --git a/buffer.h b/buffer.h
t@@ -53,6 +53,12 @@ struct ledit_buffer {
ledit_buffer_marklist *marklist;
};
+enum delete_mode {
+ DELETE_CHAR,
+ DELETE_SOFTLINE,
+ DELETE_HARDLINE
+};
+
ledit_buffer *ledit_buffer_create(ledit_common *common, ledit_theme *theme, le…
int ledit_buffer_load_file(ledit_buffer *buffer, char *filename, int line, cha…
int ledit_buffer_write_to_file(ledit_buffer *buffer, char *filename, char **er…
t@@ -110,7 +116,7 @@ void ledit_buffer_delete_line_entries_base(ledit_buffer *b…
void ledit_buffer_delete_line_entry_base(ledit_buffer *buffer, int index);
int ledit_buffer_delete_unicode_char_base(ledit_buffer *buffer, int line_index…
void ledit_buffer_delete_range_base(
- ledit_buffer *buffer, int line_based,
+ ledit_buffer *buffer, enum delete_mode delmode,
int line_index1, int byte_index1,
int line_index2, int byte_index2,
int *new_line_ret, int *new_byte_ret,
t@@ -135,7 +141,7 @@ void ledit_buffer_delete_line_entries(ledit_buffer *buffer…
void ledit_buffer_delete_line_entry(ledit_buffer *buffer, int index);
int ledit_buffer_delete_unicode_char(ledit_buffer *buffer, int line_index, int…
void ledit_buffer_delete_range(
- ledit_buffer *buffer, int line_based,
+ ledit_buffer *buffer, enum delete_mode delmode,
int line_index1, int byte_index1,
int line_index2, int byte_index2,
int *new_line_ret, int *new_byte_ret,
diff --git a/keys_basic.c b/keys_basic.c
t@@ -78,6 +78,7 @@ static struct {
} key_stack = {0, 0, NULL};
static struct action (*grab_char_cb)(ledit_buffer *buffer, char *text, int len…
+static int hard_line_based = 1;
void
basic_key_cleanup(void) {
t@@ -322,62 +323,72 @@ finalize_repetition_stack(void) {
repetition_stack.tmp_stack = tmpstack;
}
-/* get the new line and softline when moving 'movement' softlines up or
+/* get the new line and softline when moving 'movement' softlines
+ (or hardlines if hard_line_based is set) up or
down (negative means up, positive means down) */
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) {
- ledit_line *line = ledit_buffer_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_buffer_get_line(buffer, endline);
- softlines = pango_layout_get_line_count(line->…
- movement -= softlines;
- endline++;
- }
- endline--;
- if (movement <= 0) {
- *new_softline_ret = movement + softlines - 1;
+ if (hard_line_based) {
+ *new_line_ret = cur_line + movement;
+ if (*new_line_ret < 0)
+ *new_line_ret = 0;
+ else if (*new_line_ret >= buffer->lines_num)
+ *new_line_ret = buffer->lines_num - 1;
+ *new_softline_ret = 0;
+ } else {
+ ledit_line *line = ledit_buffer_get_line(buffer, cur_line);
+ int x, softline;
+ pango_layout_index_to_line_x(line->layout, cur_index, 0, &soft…
+ if (movement > 0) {
+ int softlines = pango_layout_get_line_count(line->layo…
+ if (softlines - softline > movement) {
+ *new_line_ret = cur_line;
+ *new_softline_ret = softline + movement;
} 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_buffer_get_line(buffer, endline);
- softlines = pango_layout_get_line_count(line->…
- movement += softlines;
+ movement -= (softlines - softline - 1);
+ int endline = cur_line + 1;
+ while (movement > 0 && endline < buffer->lines…
+ line = ledit_buffer_get_line(buffer, e…
+ softlines = pango_layout_get_line_coun…
+ movement -= softlines;
+ endline++;
+ }
endline--;
+ if (movement <= 0) {
+ *new_softline_ret = movement + softlin…
+ } else {
+ *new_softline_ret = softlines - 1;
+ }
+ *new_line_ret = endline;
}
- endline++;
- if (movement >= 0) {
- *new_softline_ret = movement;
+ } else if (movement < 0) {
+ int softlines = 0;
+ if (softline + movement >= 0) {
+ *new_line_ret = cur_line;
+ *new_softline_ret = softline + movement;
} else {
- *new_softline_ret = 0;
+ movement += softline;
+ int endline = cur_line - 1;
+ while (movement < 0 && endline >= 0) {
+ line = ledit_buffer_get_line(buffer, e…
+ softlines = pango_layout_get_line_coun…
+ movement += softlines;
+ endline--;
+ }
+ endline++;
+ if (movement >= 0) {
+ *new_softline_ret = movement;
+ } else {
+ *new_softline_ret = 0;
+ }
+ *new_line_ret = endline;
}
- *new_line_ret = endline;
+ } else {
+ *new_line_ret = cur_line;
+ *new_softline_ret = softline;
}
- } else {
- *new_line_ret = cur_line;
- *new_softline_ret = softline;
}
}
t@@ -396,8 +407,15 @@ delete_range(
ledit_range cur_range, del_range;
cur_range.line1 = buffer->cur_line;
cur_range.byte1 = buffer->cur_index;
+ enum delete_mode delmode = DELETE_CHAR;
+ if (line_based) {
+ if (hard_line_based)
+ delmode = DELETE_HARDLINE;
+ else
+ delmode = DELETE_SOFTLINE;
+ }
ledit_buffer_delete_range(
- buffer, line_based,
+ buffer, delmode,
line_index1, byte_index1,
line_index2, byte_index2,
&buffer->cur_line, &buffer->cur_index,
t@@ -544,8 +562,10 @@ append_line_above(ledit_buffer *buffer, char *text, int l…
/* 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 (sli == 0) {
+ if (hard_line_based || sli == 0) {
insert_text(buffer, buffer->cur_line, 0, "\n", -1, -1, -1, buf…
} else {
PangoLayoutLine *sl = pango_layout_get_line_readonly(ll->layou…
t@@ -561,7 +581,7 @@ append_line_below(ledit_buffer *buffer, char *text, int le…
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 (sl->start_index + sl->length == ll->len) {
+ if (hard_line_based || sl->start_index + sl->length == 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…
t@@ -587,9 +607,13 @@ append_after_eol(ledit_buffer *buffer, char *text, int le…
/* 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);
- pango_layout_index_to_line_x(ll->layout, buffer->cur_index, 0, &sli, &…
- PangoLayoutLine *sl = pango_layout_get_line_readonly(ll->layout, sli);
- buffer->cur_index = sl->start_index + sl->length;
+ 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;
+ }
return (struct action){ACTION_NONE, NULL};
}
t@@ -629,6 +653,7 @@ move_to_line(ledit_buffer *buffer, char *text, int len) {
return (struct action){ACTION_NONE, NULL};
}
+/* FIXME: should these scrolling functions change behavior when hard_line_base…
static void
scroll_lines(ledit_buffer *buffer, int lines, int dir) {
int final_lines;
t@@ -802,20 +827,21 @@ static struct action
delete_to_eol(ledit_buffer *buffer, char *text, int len) {
(void)text;
(void)len;
- /* FIXME: move to separate function */
- if (!key_stack_empty()) {
- clear_key_stack();
- ledit_window_show_message(buffer->window, "Invalid key", -1);
- return (struct action){ACTION_NONE, NULL};
- }
- int x, sli;
+ if (!key_stack_empty())
+ return err_invalid_key(buffer);
+ int end, 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, &…
- PangoLayoutLine *sl = pango_layout_get_line_readonly(ll->layout, sli);
+ 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;
+ }
delete_range(
buffer, 0, 0,
buffer->cur_line, buffer->cur_index,
- buffer->cur_line, sl->start_index + sl->length, 1
+ buffer->cur_line, end, 1
);
paste_buffer_line_based = 0;
buffer->cur_index = ledit_buffer_get_legal_normal_pos(
t@@ -829,20 +855,22 @@ static struct action
change_to_eol(ledit_buffer *buffer, char *text, int len) {
(void)text;
(void)len;
- if (!key_stack_empty()) {
- clear_key_stack();
- ledit_window_show_message(buffer->window, "Invalid key", -1);
- return (struct action){ACTION_NONE, NULL};
- }
+ if (!key_stack_empty())
+ return err_invalid_key(buffer);
ledit_buffer_set_mode(buffer, INSERT);
- int x, sli;
+ int end, 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, &…
- PangoLayoutLine *sl = pango_layout_get_line_readonly(ll->layout, sli);
+ 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;
+ }
delete_range(
buffer, 0, 0,
buffer->cur_line, buffer->cur_index,
- buffer->cur_line, sl->start_index + sl->length, 1
+ buffer->cur_line, end, 1
);
paste_buffer_line_based = 0;
ledit_buffer_wipe_line_cursor_attrs(buffer, buffer->cur_line);
t@@ -896,7 +924,7 @@ change_cb(ledit_buffer *buffer, int line, int char_pos, en…
/* 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;
- if (line_based) {
+ 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…
t@@ -905,6 +933,10 @@ change_cb(ledit_buffer *buffer, int line, int char_pos, e…
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;
+ } else if (line_based && hard_line_based) {
+ pos1 = 0;
+ ledit_line *ll = ledit_buffer_get_line(buffer, line);
+ pos2 = ll->len;
}
/* force line_based to 0 (see comment about hackery above) */
delete_range(
t@@ -989,6 +1021,9 @@ yank_lines(ledit_buffer *buffer, char *text, int len) {
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@@ -999,7 +1034,7 @@ yank_cb(ledit_buffer *buffer, int line, int char_pos, enu…
swap(&l1, &l2);
swap(&b1, &b2);
}
- if (line_based) {
+ 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);
t@@ -1011,6 +1046,11 @@ yank_cb(ledit_buffer *buffer, int line, int char_pos, e…
ledit_buffer_copy_text_to_txtbuf(
buffer, paste_buffer, l1, pl1->start_index, l2, pl2->start…
);
+ } else if (line_based && hard_line_based) {
+ ledit_line *ll = ledit_buffer_get_line(buffer, l2);
+ ledit_buffer_copy_text_to_txtbuf(
+ buffer, paste_buffer, l1, 0, l2, ll->len
+ );
} else {
ledit_buffer_copy_text_to_txtbuf(
buffer, paste_buffer, l1, b1, l2, b2
t@@ -1091,10 +1131,16 @@ paste_normal(ledit_buffer *buffer, char *text, int len…
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…
+ 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;
+ }
insert_text(
- buffer, buffer->cur_line, sl->start_index + sl->length,
+ buffer, buffer->cur_line, brk,
"\n", -1, -1, -1, buffer->cur_line, buffer->cur_index, 1
);
int text_len = paste_buffer->len;
t@@ -1143,10 +1189,14 @@ paste_normal_backwards(ledit_buffer *buffer, char *tex…
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…
+ 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;
+ }
insert_text(
- buffer, buffer->cur_line, sl->start_index,
+ buffer, buffer->cur_line, brk,
"\n", -1, -1, -1, buffer->cur_line, buffer->cur_index, 1
);
int text_len = paste_buffer->len;
t@@ -1341,8 +1391,11 @@ move_to_eol(ledit_buffer *buffer, char *text, int len) {
&new_line, &new_softline
);
ledit_line *ll = ledit_buffer_get_line(buffer, new_line);
- PangoLayoutLine *sl = pango_layout_get_line_readonly(ll->layout, new_s…
- int end_index = sl->start_index + sl->length;
+ 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;
+ }
if (cb != NULL) {
cb(buffer, new_line, end_index, KEY_MOTION_CHAR);
} else {
t@@ -1671,7 +1724,7 @@ join_lines(ledit_buffer *buffer, char *text, int len) {
oldlen = ll1->len;
/* FIXME: truncate whitespace to one space */
ledit_buffer_delete_range(
- buffer, 0,
+ buffer, DELETE_CHAR,
cur_line, ll1->len, cur_line + 1, 0,
NULL, NULL, &del_range, buf
);
t@@ -1697,12 +1750,16 @@ insert_at_beginning(ledit_buffer *buffer, char *text, …
if (!key_stack_empty())
return err_invalid_key(buffer);
enter_insert(buffer, text, len);
- 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, &…
- PangoLayoutLine *pl = pango_layout_get_line_readonly(ll->layout, sli);
+ 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;
+ }
push_undo_empty_insert(buffer, buffer->cur_line, buffer->cur_index, 1);
- buffer->cur_index = pl->start_index;
+ buffer->cur_index = new_index;
ledit_buffer_wipe_line_cursor_attrs(buffer, buffer->cur_line);
return (struct action){ACTION_NONE, NULL};
}
t@@ -1711,20 +1768,25 @@ static struct action
cursor_to_first_non_ws(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)
return err_invalid_key(buffer);
+ int new_index = 0;
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 *pl = pango_layout_get_line_readonly(ll->layout, sli);
- int new_index = ledit_line_next_non_whitespace(ll, pl->start_index);
- /* next non-whitespace might be on next softline */
- if (new_index >= pl->start_index + pl->length) {
- new_index = ledit_buffer_prev_cursor_pos(
- buffer, buffer->cur_line, pl->start_index + pl->length, 1
- );
+ 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…
+ /* next non-whitespace might be on next softline */
+ if (new_index >= pl->start_index + pl->length) {
+ new_index = ledit_buffer_prev_cursor_pos(
+ buffer, buffer->cur_line, pl->start_index + pl->le…
+ );
+ }
}
if (cb != NULL) {
cb(buffer, buffer->cur_line, new_index, KEY_MOTION_CHAR);
t@@ -1748,13 +1810,17 @@ cursor_to_beginning(ledit_buffer *buffer, char *text, …
if (num != 0)
return err_invalid_key(buffer);
/* FIXME: should anything be done with num? */
- 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 *pl = pango_layout_get_line_readonly(ll->layout, sli);
+ 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;
+ }
if (cb != NULL) {
- cb(buffer, buffer->cur_line, pl->start_index, KEY_MOTION_CHAR);
+ cb(buffer, buffer->cur_line, start_index, KEY_MOTION_CHAR);
} else {
- buffer->cur_index = pl->start_index;
+ buffer->cur_index = start_index;
if (buffer->common->mode == VISUAL) {
ledit_buffer_set_selection(
buffer,
t@@ -2166,6 +2232,31 @@ replace(ledit_buffer *buffer, char *text, int len) {
return (struct action){ACTION_NONE, NULL};
}
+static void
+set_hard_line_based(ledit_buffer *buffer, int hl) {
+ hard_line_based = hl;
+ char *text = hl ? "|HL" : "|SL";
+ ledit_window_set_mode_extra_text(buffer->window, text);
+}
+
+static struct action
+toggle_hard_line_based(ledit_buffer *buffer, char *text, int len) {
+ (void)buffer;
+ (void)text;
+ (void)len;
+ int num = get_key_repeat();
+ if (num != 0)
+ return err_invalid_key(buffer);
+ set_hard_line_based(buffer, !hard_line_based);
+ return (struct action){ACTION_NONE, NULL};
+}
+
+/* FIXME: this is sort of all over the place and ugly */
+void
+keys_basic_init(ledit_buffer *buffer) {
+ set_hard_line_based(buffer, 1);
+}
+
static struct action
handle_key(ledit_buffer *buffer, char *key_text, int len, KeySym sym, unsigned…
struct key *cur_keys = keys[lang_index].keys;
diff --git a/keys_basic.h b/keys_basic.h
t@@ -1,2 +1,3 @@
+void keys_basic_init(ledit_buffer *buffer);
void basic_key_cleanup(void);
struct action basic_key_handler(ledit_buffer *buffer, XEvent *event, int lang_…
diff --git a/keys_basic_config.h b/keys_basic_config.h
t@@ -1,3 +1,4 @@
+/* FIXME: these aren't really used properly */
enum key_type {
KEY_NONE = 0,
KEY_MISC = 1,
t@@ -93,6 +94,7 @@ static struct action replace(ledit_buffer *buffer, char *tex…
static struct action cursor_to_first_non_ws(ledit_buffer *buffer, char *text, …
static struct action join_lines(ledit_buffer *buffer, char *text, int len);
static struct action insert_at_beginning(ledit_buffer *buffer, char *text, int…
+static struct action toggle_hard_line_based(ledit_buffer *buffer, char *text, …
/* FIXME: maybe sort these and use binary search
-> but that would mess with the catch-all keys */
t@@ -111,6 +113,7 @@ static struct key keys_en[] = {
{"j", 0, 0, NORMAL|VISUAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &…
{"k", 0, 0, NORMAL|VISUAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &…
{"h", ControlMask, 0, NORMAL|VISUAL, KEY_ANY, KEY_MOTION | KEY_NUMBER…
+ {"t", ControlMask, 0, NORMAL|VISUAL, KEY_ANY, KEY_ANY, &toggle_hard_l…
{NULL, 0, XK_space, NORMAL|VISUAL, KEY_ANY, KEY_MOTION | KEY_NUMBERAL…
{"j", ControlMask, 0, NORMAL|VISUAL, KEY_ANY, KEY_MOTION | KEY_NUMBER…
{"n", ControlMask, 0, NORMAL|VISUAL, KEY_ANY, KEY_MOTION | KEY_NUMBER…
diff --git a/ledit.c b/ledit.c
t@@ -292,6 +292,7 @@ setup(int argc, char *argv[]) {
}
ledit_buffer_set_mode(buffer, NORMAL);
ledit_buffer_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->c…
+ keys_basic_init(buffer);
redraw();
}
diff --git a/memory.c b/memory.c
t@@ -47,3 +47,20 @@ ledit_realloc(void *ptr, size_t size) {
fatal_err("Out of memory.\n");
return new_ptr;
}
+
+/* Concatenate the two given strings and return the result.
+ This allocates new memory for the result string, unlike
+ the actual strcat. Aborts program on error */
+char *
+ledit_strcat(const char *str1, const char *str2) {
+ int len1, len2;
+ char *ret;
+
+ len1 = strlen(str1);
+ len2 = strlen(str2);
+ ret = ledit_malloc(len1 + len2 + 1);
+ strcpy(ret, str1);
+ strcpy(ret + len1, str2);
+
+ return ret;
+}
diff --git a/memory.h b/memory.h
t@@ -3,3 +3,4 @@ char *ledit_strndup(const char *s, size_t n);
void *ledit_malloc(size_t size);
void *ledit_calloc(size_t nmemb, size_t size);
void *ledit_realloc(void *ptr, size_t size);
+char *ledit_strcat(const char *str1, const char *str2);
diff --git a/window.c b/window.c
t@@ -240,20 +240,24 @@ ledit_window_hide_message(ledit_window *window) {
void
ledit_window_set_mode(ledit_window *window, enum ledit_mode mode) {
+ char *text;
switch (mode) {
case NORMAL:
- pango_layout_set_text(window->bb->mode, "Normal", -1);
+ text = "Normal";
break;
case VISUAL:
- pango_layout_set_text(window->bb->mode, "Visual", -1);
+ text = "Visual";
break;
case INSERT:
- pango_layout_set_text(window->bb->mode, "Insert", -1);
+ text = "Insert";
break;
default:
- pango_layout_set_text(window->bb->mode, "ledit is bugg…
+ text = "ledit is buggy";
break;
}
+ char *final_text = ledit_strcat(text, window->mode_extra_text ? window…
+ pango_layout_set_text(window->bb->mode, final_text, -1);
+ free(final_text);
pango_layout_get_pixel_size(window->bb->mode, &window->bb->mode_w, &wi…
ledit_draw_grow(window, window->bb->mode_draw, window->bb->mode_w, win…
XftDrawRect(window->bb->mode_draw->xftdraw, &window->theme->text_bg, 0…
t@@ -261,6 +265,12 @@ ledit_window_set_mode(ledit_window *window, enum ledit_mo…
recalc_text_size(window);
}
+void
+ledit_window_set_mode_extra_text(ledit_window *window, char *text) {
+ window->mode_extra_text = ledit_strdup(text);
+ ledit_window_set_mode(window, window->common->mode);
+}
+
/* FIXME: give these functions more sensible names */
static void
get_scroll_pos_height(ledit_window *window, double *pos, double *height) {
t@@ -411,6 +421,7 @@ ledit_window_create(ledit_common *common, ledit_theme *the…
window->scroll_grab_handle = 0;
window->w = 500;
window->h = 500;
+ window->mode_extra_text = NULL;
memset(&window->wattrs, 0, sizeof(attrs));
window->wattrs.background_pixel = BlackPixel(common->dpy, common->scre…
t@@ -516,6 +527,8 @@ ledit_window_destroy(ledit_window *window) {
g_object_unref(window->bb->line);
ledit_draw_destroy(window, window->bb->mode_draw);
ledit_draw_destroy(window, window->bb->line_draw);
+ if (window->mode_extra_text)
+ free(window->mode_extra_text);
free(window->bb->line_text);
free(window->bb);
free(window);
diff --git a/window.h b/window.h
t@@ -38,6 +38,7 @@ typedef struct {
void *paste_cb_data;
void *scroll_cb_data;
void *button_cb_data;
+ char *mode_extra_text;
} ledit_window;
ledit_window *ledit_window_create(ledit_common *common, ledit_theme *theme);
t@@ -62,6 +63,7 @@ void ledit_window_show_message(ledit_window *window, char *t…
void ledit_window_hide_message(ledit_window *window);
int ledit_window_message_shown(ledit_window *window);
void ledit_window_set_mode(ledit_window *window, enum ledit_mode mode);
+void ledit_window_set_mode_extra_text(ledit_window *window, char *text);
void ledit_window_set_scroll_max(ledit_window *window, long max);
void ledit_window_set_scroll_pos(ledit_window *window, long pos);
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.