sled

Једноставни уређивач текста
git clone https://git.sr.ht/~strahinja/sled
Дневник | Датотеке | Референце | ПРОЧИТАЈМЕ | ЛИЦЕНЦА

чување eab2ab7503ee6a7a2981084fbda7acf5a8e950e7
родитељ 15bed42ab7abb29e4baab1bb62669a87a24c7f82
Аутор: Страхиња Радић <sr@strahinja.org>
Датум:   Tue, 21 Jul 2026 15:08:20 +0000

Bugfix: cutting multiline selections didn't update line sizes properly

Diffstat:
MTODO | 7-------
MTODO.done | 9+++++++++
Msled.c | 72++++++++++++++++++++++++++++++++++++++++++++----------------------------
измењених датотека: 3, додавања: 53(+), брисања: 35(-)

diff --git a/TODO b/TODO @@ -3,13 +3,6 @@ TODO [~] Code optimization (struct coord...) -[ ] Investigate: cut/paste multi-line selections, like - - xxxx xxxx xxxxxx [xxxxxx xxxxx xxxxx xx - xxxxxxx xxxxxxxxxxxx]. xxxxxxxxx xx xxxxx - - (Text loss again?) - [ ] Implement proper drawing of wide characters covering dialogs, now that termbox has a function for getting characters from the display buffer diff --git a/TODO.done b/TODO.done @@ -1,6 +1,15 @@ Done or canceled todos ====================== +[x] Investigate: cut/paste multi-line selections, like + + xxxx xxxx xxxxxx [xxxxxx xxxxx xxxxx xx + xxxxxxx xxxxxxxxxxxx]. xxxxxxxxx xx xxxxx + + (Text loss again?) + - Seems to be related to cutting text specifically (erase_selection?) + - Yes; fixed. + [x] Add changes from table(1) regarding the drawing of invalid UTF-8. That would perhaps also make open_binary obsolete. - Add -O/-o parameters diff --git a/sled.c b/sled.c @@ -489,49 +489,65 @@ erase_selection(struct DrawState* state) int ssr = 0; int ssc = 0; /* Selection end row/col */ - int ser = 0; - int sec = 0; + int ser = 0; + int sec = 0; + int ser_len = 0; ssize_t bufsize; + get_selection(&ssr, &ssc, &ser, &sec, state); + assert(ser < state->buffer_size); - bufsize = state->buffer[ser].size; + ser_len = state->buffer[ser].length; + bufsize = ssc + ser_len - sec + 1; buf = calloc(bufsize, sizeof(uint32_t)); if (!buf) exit(print_error(ENOMEM, "Memory allocation failed")); - get_selection(&ssr, &ssc, &ser, &sec, state); - - U32_MEMCCPY(buf, state->buffer[ser].text + sec, bufsize - sec, - temp); + U32_MEMCCPY(buf, state->buffer[ser].text + sec, bufsize, temp); + ENSURE_SIZE(state->buffer[ssr].text, temp, + state->buffer[ssr].size, bufsize, bufsize, + erase_selection_alloc_error, uint32_t); + U32_MEMCCPY((state->buffer[ssr].text + ssc), buf, bufsize, temp); - U32_MEMCCPY((state->buffer[ssr].text + ssc), buf, bufsize - ssc, - temp); - state->buffer[ssr].length = u32_strlen(state->buffer[ssr].text); + state->buffer[ssr].size = MAX(bufsize, state->buffer[ssr].size); + state->buffer[ssr].length = ssc + ser_len - sec; - if (ssr != ser) + if (ssr == ser) + goto erase_selection_same_line; + for (ssize_t row = 0; ser + row + 1 < state->rows_count; row++) { - for (ssize_t row = 0; ser + row + 1 < state->rows_count; - row++) - { - U32_MEMCCPY(state->buffer[ssr + row + 1].text, - state->buffer[ser + row + 1].text, - bufsize, temp); - state->buffer[ssr + row + 1].length - = state->buffer[ser + row + 1].length; - } - for (ssize_t row = state->rows_count - (ser - ssr); - row < state->rows_count; row++) - { - *state->buffer[row].text = 0; - state->buffer[row].length = 0; - } - state->rows_count -= ser - ssr; - recalculate_line_numbers(state); + ENSURE_SIZE(state->buffer[ssr + row + 1].text, temp, + state->buffer[ssr + row + 1].size, + state->buffer[ser + row + 1].size, + state->buffer[ser + row + 1].size, + erase_selection_alloc_error, uint32_t); + U32_MEMCCPY(state->buffer[ssr + row + 1].text, + state->buffer[ser + row + 1].text, + state->buffer[ser + row + 1].size, temp); + state->buffer[ssr + row + 1].size + = MAX(state->buffer[ssr + row + 1].size, + state->buffer[ser + row + 1].size); + state->buffer[ssr + row + 1].length + = state->buffer[ser + row + 1].length; + } + for (ssize_t row = state->rows_count - (ser - ssr); + row < state->rows_count; row++) + { + *state->buffer[row].text = 0; + state->buffer[row].length = 0; } + state->rows_count -= ser - ssr; + recalculate_line_numbers(state); + + erase_selection_same_line: free(buf); state->dirty = 1; } return 0; + +erase_selection_alloc_error: + state->running = 0; + return 1; } static int