чување eab2ab7503ee6a7a2981084fbda7acf5a8e950e7
родитељ 15bed42ab7abb29e4baab1bb62669a87a24c7f82
Аутор: Страхиња Радић <sr@strahinja.org>
Датум: Tue, 21 Jul 2026 15:08:20 +0000
Bugfix: cutting multiline selections didn't update line sizes properly
Diffstat:
| M | TODO | | | 7 | ------- |
| M | TODO.done | | | 9 | +++++++++ |
| M | sled.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