sled

Једноставни уређивач текста
Дневник | Датотеке | Референце | ПРОЧИТАЈМЕ | ЛИЦЕНЦА

чување 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:
Msled.c | 169++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
Mutil.c | 22++++++++++++++++++++++
Mutil.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);