чување 8f53b28ad2d2bcdac2f1a9b6660dfe6ba827d6e6
родитељ 0953ecfcef6999c77c99420c67f55daf2bf6e0eb
Аутор: Страхиња Радић <contact@strahinja.org>
Датум: Thu, 17 Feb 2022 15:53:54 +0100
Add selection replacing; needs polish
Signed-off-by: Страхиња Радић <contact@strahinja.org>
Diffstat:
| M | sled.c | | | 169 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------- |
| M | util.c | | | 22 | ++++++++++++++++++++++ |
| M | util.h | | | 1 | + |
измењених датотека: 3, додавања: 161(+), брисања: 31(-)
diff --git a/sled.c b/sled.c
@@ -19,6 +19,10 @@
#include "draw.h"
#include "config.h"
+#define SEL_NOT_EMPTY(state) \
+ ((state->sel_start_row != state->sel_end_row) \
+ || (state->sel_start_col != state->sel_end_col))
+
enum {
LOAD_ERR_NONE = 0,
LOAD_ERR_CANT_ALLOC = 1,
@@ -61,6 +65,8 @@ struct DrawState* join_lines(struct DrawState* state, size_t first_line,
int forward);
int toggle_selection(struct DrawState* state);
int clear_selection(struct DrawState* state);
+int position_to_selection_start(struct DrawState* state);
+int erase_selection(struct DrawState* state);
void handle_editbox_key_event(struct tb_event* ev, struct DrawState* state);
void handle_key_event(struct tb_event* ev, struct DrawState* state);
void handle_search_key_event(struct tb_event* ev, struct DrawState* state);
@@ -503,20 +509,13 @@ move_next_word(struct DrawState* state)
return 0;
}
-void
+int
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;
+ int i = state->column;
+ size_t len = state->buffer[state->row].length;
- uint32_t* pline = state->input_buffer[state->input_row].text;
+ uint32_t* pline = state->buffer[state->row].text;
if (i > 0 && u32_is_word_boundary(pline[i - 1], 0))
i--;
@@ -526,20 +525,19 @@ erase_prev_word(struct DrawState* state)
&& !u32_is_word_boundary(pline[i - 1], 0))
i--;
- int d = state->input_column - i;
+ int d = state->column - i;
for (int j = i; j < len - d; j++)
pline[j] = pline[j + d];
len -= d;
- 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;
- */
+ state->buffer[state->row].length = len;
+ pline[len] = 0;
+ state->column = i;
+ state->display_column = display_length(state,
+ state->buffer[state->row].text, state->column);
+ state->dirty = 1;
+ return 0;
}
int
@@ -627,6 +625,10 @@ insert_char(struct DrawState* state, uint32_t ch)
{
size_t i = len + 1;
int add_null = buffer_line->text[state->column] == 0;
+
+ position_to_selection_start(state);
+ erase_selection(state);
+ clear_selection(state);
while (i < MAXBUFLINE - 2 && i > state->column)
{
buffer_line->text[i] = buffer_line->text[i - 1];
@@ -656,16 +658,12 @@ insert_char(struct DrawState* state, uint32_t ch)
int
insert_space(struct DrawState* state)
{
- // TODO: Replace selection
- clear_selection(state);
return insert_char(state, ' ');
}
int
insert_tab(struct DrawState* state)
{
- // TODO: Replace selection
- clear_selection(state);
return insert_char(state, '\t');
}
@@ -674,6 +672,14 @@ erase_backwards(struct DrawState* state)
{
struct BufferLine* buffer_line = &state->buffer[state->row];
+ if (SEL_NOT_EMPTY(state))
+ {
+ position_to_selection_start(state);
+ erase_selection(state);
+ clear_selection(state);
+ return 0;
+ }
+
if (state->column > 0)
{
size_t i = state->column;
@@ -714,6 +720,14 @@ erase_forward(struct DrawState* state)
{
struct BufferLine* buffer_line = &state->buffer[state->row];
+ if (SEL_NOT_EMPTY(state))
+ {
+ position_to_selection_start(state);
+ erase_selection(state);
+ clear_selection(state);
+ return 0;
+ }
+
if (buffer_line->text[state->column])
{
size_t i = state->column;
@@ -743,6 +757,15 @@ erase_to_start(struct DrawState* state)
size_t i = state->column;
struct BufferLine* buffer_line = &state->buffer[state->row];
size_t len = buffer_line->length;
+
+ if (SEL_NOT_EMPTY(state))
+ {
+ position_to_selection_start(state);
+ erase_selection(state);
+ clear_selection(state);
+ return 0;
+ }
+
do
{
buffer_line->text[i - state->column] = buffer_line->text[i];
@@ -758,7 +781,16 @@ erase_to_start(struct DrawState* state)
int
erase_to_end(struct DrawState* state)
{
- struct BufferLine* buffer_line = &state->buffer[state->row];
+ struct BufferLine* buffer_line = &state->buffer[state->row];
+
+ if (SEL_NOT_EMPTY(state))
+ {
+ position_to_selection_start(state);
+ erase_selection(state);
+ clear_selection(state);
+ return 0;
+ }
+
buffer_line->text[state->column] = 0;
buffer_line->length = state->column;
move_end(state);
@@ -848,8 +880,7 @@ cancel_close(struct DrawState* state)
if (!*state->error && !state->in_prompt && !state->show_help)
{
- if ((state->sel_start_row != state->sel_end_row)
- || state->sel_start_col != state->sel_end_col)
+ if (SEL_NOT_EMPTY(state))
clear_selection(state);
else
strcpy(state->error, errors[ERR_EXIT_KEY]);
@@ -938,6 +969,84 @@ clear_selection(struct DrawState* state)
return 0;
}
+int
+position_to_selection_start(struct DrawState* state)
+{
+ if (SEL_NOT_EMPTY(state))
+ {
+ state->row = state->sel_start_row;
+ state->column = state->sel_start_col;
+ state->display_column = display_length(state,
+ state->buffer[state->row].text, state->column - 1);
+ state->saved_column = state->display_column;
+
+ if (state->first_shown_row > state->row)
+ state->first_shown_row = state->row;
+ else if (state->first_shown_row + (state->maxy - 2) < state->row)
+ state->first_shown_row = state->row - (state->maxy - 2);
+
+ if (state->display_column < state->first_shown_column)
+ state->first_shown_column = state->display_column;
+ else if (state->display_column - state->first_shown_column
+ > state->maxx - 1)
+ state->first_shown_column
+ = state->display_column - state->maxx + 1;
+ }
+ return 0;
+}
+
+int
+erase_selection(struct DrawState* state)
+{
+ if (SEL_NOT_EMPTY(state))
+ {
+ /* Selection start row/col */
+ size_t ssr = 0;
+ size_t ssc = 0;
+ /* Selection end row/col */
+ size_t ser = 0;
+ size_t sec = 0;
+ uint32_t* buf = NULL;
+ if (state->sel_start_row < state->sel_end_row)
+ {
+ ssr = state->sel_start_row;
+ ssc = state->sel_start_col;
+ ser = state->sel_end_row;
+ sec = state->sel_end_col;
+ }
+ else /* Swap */
+ {
+ ssr = state->sel_end_row;
+ ssc = state->sel_end_col;
+ ser = state->sel_start_row;
+ sec = state->sel_start_col;
+ }
+
+ buf = calloc(state->buffer[ssr].length, sizeof(uint32_t));
+ if (!buf)
+ exit(print_error(ENOMEM, "Memory allocation failed"));
+ u32_strcpy(buf, state->buffer[ser].text + sec);
+
+ *(state->buffer[ssr].text + ssc) = 0;
+ u32_strcat(state->buffer[ssr].text, buf);
+ state->buffer[ssr].length = u32_strlen(state->buffer[ssr].text);
+
+ if (ssr != ser)
+ {
+ for (size_t row = 0; row < state->rows_count - ser - 1;
+ row++)
+ {
+ u32_strcpy(state->buffer[ssr + row + 1].text,
+ state->buffer[ser + row + 1].text);
+ state->buffer[ssr + row + 1].length
+ = state->buffer[ser + row + 1].length;
+ }
+ }
+ free(buf);
+ }
+ return 0;
+}
+
void
handle_editbox_key_event(struct tb_event* ev, struct DrawState* state)
{
@@ -1078,8 +1187,6 @@ handle_key_event(struct tb_event* ev, struct DrawState* state)
}
if (ev->ch)
{
- // TODO: Replace selection
- clear_selection(state);
insert_char(state, ev->ch);
return;
}
@@ -1256,8 +1363,8 @@ main(int argc, char** argv)
}
tb_init();
- *error = 0;
- state.maxx = 0;
+ *error = 0;
+ state.maxx = 0;
while (state.running)
{
diff --git a/util.c b/util.c
@@ -111,6 +111,28 @@ u32_strncpy(uint32_t* to, const uint32_t* from, size_t max)
/*
* to - u32 string to concatenate to
+ * from - u32 string to concatenate */
+size_t
+u32_strcat(uint32_t* to, const uint32_t* from)
+{
+ const uint32_t* pfrom = from;
+ size_t copied = 0;
+ while (*to)
+ {
+ to++;
+ copied++;
+ }
+ while (*pfrom)
+ {
+ *to++ = *pfrom++;
+ copied++;
+ }
+ *to = 0;
+ return copied;
+}
+
+/*
+ * to - u32 string to concatenate to
* from - u32 string to concatenate
* max - total combined string size */
size_t
diff --git a/util.h b/util.h
@@ -44,6 +44,7 @@ size_t u32_strlen(const uint32_t* s);
uint32_t* u32_strchr(uint32_t* haystack, const uint32_t needle);
size_t u32_strcpy(uint32_t* to, const uint32_t* from);
size_t u32_strncpy(uint32_t* to, const uint32_t* from, size_t max);
+size_t u32_strcat(uint32_t* to, const uint32_t* from);
size_t u32_strncat(uint32_t* to, const uint32_t* from, size_t max);
size_t u32_u8_strcpy(uint32_t* to, const char* from);
int u32_is_word_boundary(const uint32_t ch, const int strictly_whitespace);