чување 26e7e0cddd03536129f8c155ec995640c6838b97
родитељ 03446e528209433df3f52c6f0c66f8c1f61c3128
Аутор: Страхиња Радић <contact@strahinja.org>
Датум: Sat, 10 Jul 2021 19:58:32 +0200
Added C-R/C-T = go to prev/next word, C-W = erase prev word in edit dialog and search box
Signed-off-by: Страхиња Радић <contact@strahinja.org>
Diffstat:
| M | TODO | | | 2 | +- |
| M | poe.1.in | | | 3 | +++ |
| M | poe.c | | | 196 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
измењених датотека: 3, додавања: 200(+), брисања: 1(-)
diff --git a/TODO b/TODO
@@ -2,7 +2,7 @@
====
[x] Line editing with cursor
- [ ] Previous/next word?
+ [x] Previous/next word?
[x] Enter -> F6 -> Esc -> Enter should not focus info box
diff --git a/poe.1.in b/poe.1.in
@@ -111,6 +111,9 @@ _
\fCC-E\fP or \fCEnd\fP@Go to end of line
\fCC-U\fP@Erase to start of line
\fCC-K\fP@Erase to end of line
+\fCC-R\fP@Go to previous word
+\fCC-T\fP@Go to next word
+\fCC-W\fP@Erase previous word
\fC\[ua]\fP@Go to previous line
\fC\[<-]\fP@Go to previous character
\fC\[->]\fP@Go to next character
diff --git a/poe.c b/poe.c
@@ -45,6 +45,9 @@ void erase_search_backwards(struct DrawState* state);
void erase_search_forward(struct DrawState* state);
void erase_search_to_start(struct DrawState* state);
void erase_search_to_end(struct DrawState* state);
+void move_search_prev_word(struct DrawState* state);
+void move_search_next_word(struct DrawState* state);
+void erase_search_prev_word(struct DrawState* state);
void next_match(struct DrawState* state);
void prev_match(struct DrawState* state);
void next_untranslated(struct DrawState* state);
@@ -56,6 +59,9 @@ void edit_page_down(struct DrawState* state);
void move_start(struct DrawState* state);
void move_left(struct DrawState* state);
void move_right(struct DrawState* state);
+void move_prev_word(struct DrawState* state);
+void move_next_word(struct DrawState* state);
+void erase_prev_word(struct DrawState* state);
void move_end(struct DrawState* state);
void move_list_up(struct DrawState* state);
void move_list_down(struct DrawState* state);
@@ -674,6 +680,103 @@ erase_search_to_end(struct DrawState* state)
}
void
+move_search_prev_word(struct DrawState* state)
+{
+ int i = state->search_column;
+ uint32_t* pline = state->search;
+
+ while (i > 0 && (pline[i] == ' ' || pline[i] == '\t'))
+ i--;
+ while (i > 0 && (pline[i] != ' ' && pline[i] != '\t'))
+ i--;
+
+ state->search_column = i;
+ state->search_display_column = display_length(state, state->search,
+ state->search_column);
+
+ if (state->search_column <
+ state->search_first_shown_column)
+ {
+ if (state->search_column > SEARCH_WIDTH-4)
+ state->search_first_shown_column =
+ state->search_column
+ - SEARCH_WIDTH+4;
+ else
+ state->search_first_shown_column = 0;
+ }
+ state->search_display_column = display_length(state,
+ state->search,
+ state->search_column);
+}
+
+void
+move_search_next_word(struct DrawState* state)
+{
+ int i = state->search_column;
+ uint32_t* pline = state->search;
+ size_t len = u32_strlen(state->search);
+
+ while (i < len && (pline[i] != ' ' && pline[i] != '\t'))
+ i++;
+ while (i < len && (pline[i] == ' ' || pline[i] == '\t'))
+ i++;
+ state->search_column = i;
+ state->search_display_column = display_length(state, state->search,
+ state->search_column);
+
+ if (state->search_display_column -
+ state->search_first_shown_column >
+ SEARCH_WIDTH-4)
+ {
+ state->search_first_shown_column =
+ state->search_display_column - SEARCH_WIDTH+4;
+ state->search_display_column = display_length(state,
+ state->search, state->search_column);
+ }
+}
+
+void
+erase_search_prev_word(struct DrawState* state)
+{
+ int i = state->search_column;
+ size_t len = u32_strlen(state->search);
+
+ uint32_t* pline = state->search;
+
+ while (i > 0 && (pline[i] == ' ' || pline[i] == '\t'))
+ i--;
+ while (i > 0 && (pline[i] != ' ' && pline[i] != '\t'))
+ i--;
+
+ int d = state->search_column - i;
+
+ for (int j = i; j < len-d; j++)
+ pline[j] = pline[j+d];
+
+ len -= state->search_column-i;
+ pline[len] = 0;
+ state->search_column = i;
+ state->search_display_column = display_length(state, state->search,
+ state->search_column);
+
+ if (state->search_column <
+ state->search_first_shown_column)
+ {
+ if (state->search_column > SEARCH_WIDTH-4)
+ state->search_first_shown_column =
+ state->search_column
+ - SEARCH_WIDTH+4;
+ else
+ state->search_first_shown_column = 0;
+ }
+ state->search_display_column = display_length(state,
+ state->search,
+ state->search_column);
+
+ next_match(state);
+}
+
+void
next_match(struct DrawState* state)
{
if (state->msgid_count == 0 || !state->search || !*state->search)
@@ -1054,6 +1157,83 @@ move_right(struct DrawState* state)
- EDIT_WIDTH+4;
}
+void
+move_prev_word(struct DrawState* state)
+{
+ if (state->edit_info_focused)
+ {
+ strcpy(state->error, errors[ERR_DLG_OPEN_QUIT]);
+ return;
+ }
+
+ int i = state->input_column;
+ uint32_t* pline = state->input_buffer[state->input_row].text;
+
+ while (i > 0 && (pline[i] == ' ' || pline[i] == '\t'))
+ i--;
+ while (i > 0 && (pline[i] != ' ' && pline[i] != '\t'))
+ i--;
+
+ state->input_column = i;
+ state->input_display_column = display_length(state, state->input_buffer[
+ state->input_row].text, state->input_column);
+}
+
+void
+move_next_word(struct DrawState* state)
+{
+ if (state->edit_info_focused)
+ {
+ strcpy(state->error, errors[ERR_DLG_OPEN_QUIT]);
+ return;
+ }
+
+ int i = state->input_column;
+ uint32_t* pline = state->input_buffer[state->input_row].text;
+ size_t len = state->input_buffer[state->input_row].length;
+
+ while (i < len && (pline[i] != ' ' && pline[i] != '\t'))
+ i++;
+ while (i < len && (pline[i] == ' ' || pline[i] == '\t'))
+ i++;
+ state->input_column = i;
+ state->input_display_column = display_length(state, state->input_buffer[
+ state->input_row].text, state->input_column);
+}
+
+void
+erase_prev_word(struct DrawState* state)
+{
+ if (state->edit_info_focused)
+ {
+ strcpy(state->error, errors[ERR_DLG_OPEN_QUIT]);
+ return;
+ }
+
+ int i = state->input_column;
+ size_t len = state->input_buffer[state->input_row].length;
+
+ uint32_t* pline = state->input_buffer[state->input_row].text;
+
+ while (i > 0 && (pline[i] == ' ' || pline[i] == '\t'))
+ i--;
+ while (i > 0 && (pline[i] != ' ' && pline[i] != '\t'))
+ i--;
+
+ int d = state->input_column - i;
+
+ for (int j = i; j < len-d; j++)
+ pline[j] = pline[j+d];
+
+ len -= state->input_column-i;
+ state->input_buffer[state->input_row].length = len;
+ pline[len] = 0;
+ state->input_column = i;
+ state->input_display_column = display_length(state, state->input_buffer[
+ state->input_row].text, state->input_column);
+ state->dirty = 1;
+}
+
void
move_end(struct DrawState* state)
{
@@ -1307,7 +1487,11 @@ void
erase_to_start(struct DrawState* state)
{
if (state->edit_info_focused)
+ {
+ strcpy(state->error, errors[ERR_DLG_OPEN_QUIT]);
return;
+ }
+
size_t i = state->input_column;
struct BufferLine* buffer_line = &state->input_buffer[state->input_row];
size_t len = buffer_line->length;
@@ -1454,10 +1638,16 @@ handle_editbox_key_event(struct tb_event* ev, struct DrawState* state)
prev_plural(state);
else if (ev->key == TB_KEY_CTRL_Q)
strcpy(state->error, errors[ERR_DLG_OPEN_QUIT]);
+ else if (ev->key == TB_KEY_CTRL_R)
+ move_prev_word(state);
else if (ev->key == TB_KEY_CTRL_S)
save_msgstr(state);
+ else if (ev->key == TB_KEY_CTRL_T)
+ move_next_word(state);
else if (ev->key == TB_KEY_CTRL_U)
erase_to_start(state);
+ else if (ev->key == TB_KEY_CTRL_W)
+ erase_prev_word(state);
else if (ev->key == TB_KEY_CTRL_Z)
toggle_fuzzy(state);
else if (ev->key == TB_KEY_DELETE && !state->edit_info_focused)
@@ -1655,8 +1845,14 @@ handle_search_key_event(struct tb_event* ev, struct DrawState* state)
erase_search_backwards(state);
else if (ev->key == TB_KEY_CTRL_K)
erase_search_to_end(state);
+ else if (ev->key == TB_KEY_CTRL_R)
+ move_search_prev_word(state);
+ else if (ev->key == TB_KEY_CTRL_T)
+ move_search_next_word(state);
else if (ev->key == TB_KEY_CTRL_U)
erase_search_to_start(state);
+ else if (ev->key == TB_KEY_CTRL_W)
+ erase_search_prev_word(state);
else if (ev->key == TB_KEY_DELETE)
erase_search_forward(state);
else if (ev->key == TB_KEY_END