diff options
| author | Albert Cervin <albert@acervin.com> | 2023-02-11 23:03:39 +0100 |
|---|---|---|
| committer | Albert Cervin <albert@acervin.com> | 2023-02-15 23:41:35 +0100 |
| commit | e45499816eab8abadbdd5bb6dd79b526a4ed6648 (patch) | |
| tree | 3cdcb0238aaae8ed1b3578e4ad71883f0702de3c /src/text.c | |
| parent | c2976cea9bbca465712534b7e523783e2ccc6c6e (diff) | |
| download | dged-e45499816eab8abadbdd5bb6dd79b526a4ed6648.tar.gz dged-e45499816eab8abadbdd5bb6dd79b526a4ed6648.tar.xz dged-e45499816eab8abadbdd5bb6dd79b526a4ed6648.zip | |
Implement undo
This also fixes a bunch of valgrind errors
Diffstat (limited to 'src/text.c')
| -rw-r--r-- | src/text.c | 37 |
1 files changed, 32 insertions, 5 deletions
@@ -46,10 +46,14 @@ void text_destroy(struct text *text) { } free(text->lines); + + free(text); } void text_clear(struct text *text) { for (uint32_t li = 0; li < text->nlines; ++li) { + free(text->lines[li].data); + text->lines[li].data = NULL; text->lines[li].flags = 0; text->lines[li].nbytes = 0; text->lines[li].nchars = 0; @@ -237,6 +241,7 @@ void delete_line(struct text *text, uint32_t line) { } --text->nlines; + free(text->lines[text->nlines].data); text->lines[text->nlines].data = NULL; text->lines[text->nlines].nbytes = 0; text->lines[text->nlines].nchars = 0; @@ -264,7 +269,8 @@ void text_insert_at(struct text *text, uint32_t line, uint32_t col, insert_at(text, line, col, line_data, linelen, nchars); - if (linelen == 0) { + col += nchars; + if (linelen == 0 || col < text_line_length(text, line)) { new_line_at(text, line, col); } @@ -290,17 +296,38 @@ void text_insert_at(struct text *text, uint32_t line, uint32_t col, void text_delete(struct text *text, uint32_t start_line, uint32_t start_col, uint32_t end_line, uint32_t end_col) { + uint32_t maxline = text->nlines > 0 ? text->nlines - 1 : 0; + + // make sure we stay inside + if (start_line > maxline) { + start_line = maxline; + start_col = text->lines[start_line].nchars > 0 + ? text->lines[start_line].nchars - 1 + : 0; + } + + if (end_line > maxline) { + end_line = maxline; + end_col = text->lines[end_line].nchars; + } + struct line *firstline = &text->lines[start_line]; struct line *lastline = &text->lines[end_line]; + + // clamp column if (start_col > firstline->nchars) { - return; + start_col = firstline->nchars > 0 ? firstline->nchars - 1 : 0; } // handle deletion of newlines if (end_col > lastline->nchars) { - ++end_line; - end_col = 0; - lastline = &text->lines[end_line]; + if (end_line + 1 < text->nlines) { + end_col = 0; + ++end_line; + lastline = &text->lines[end_line]; + } else { + end_col = lastline->nchars; + } } uint32_t bytei = utf8_nbytes(lastline->data, lastline->nbytes, end_col); |
