diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2014-07-16 12:02:42 +0200 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2014-07-16 12:02:42 +0200 |
| commit | 615bbd7da9c3fe634cb9c37d867a208df048d047 (patch) | |
| tree | d545a6026fcfefa32ad9a7bd637c967c4f03dc2f | |
| parent | 1df415d621191a1fb1c23fa00409b25a74a3747a (diff) | |
| download | vis-615bbd7da9c3fe634cb9c37d867a208df048d047.tar.gz vis-615bbd7da9c3fe634cb9c37d867a208df048d047.tar.xz | |
Implement deletion
| -rw-r--r-- | editor.c | 70 | ||||
| -rw-r--r-- | editor.h | 2 |
2 files changed, 70 insertions, 2 deletions
@@ -46,7 +46,7 @@ struct Change { typedef struct Action Action; struct Action { Change *change; - Action *next; //, *prev; + Action *next; time_t timestamp; }; @@ -346,6 +346,74 @@ void editor_iterate(Editor *ed, void *data, size_t pos, iterator_callback_t call } } +bool editor_delete(Editor *ed, size_t pos, size_t len) { + if (len == 0) + return true; + if (pos + len > ed->size) + return false; + Location loc = piece_get(ed, pos); + Piece *p = loc.piece; + size_t off = loc.off; + size_t cur; // how much has already been deleted + bool midway_start = false, midway_end = false; + Change *c = change_alloc(ed); + if (!c) + return false; + Piece *before, *after; // unmodified pieces before / after deletion point + Piece *start, *end; // span which is removed + if (off == p->len) { + /* deletion starts at a piece boundry */ + cur = 0; + before = p; + start = p->next; + } else { + /* deletion starts midway through a piece */ + midway_start = true; + cur = p->len - off; + start = p; + before = piece_alloc(); + } + /* skip all pieces which fall into deletion range */ + while (cur < len) { + p = p->next; + cur += p->len; + } + + if (cur == len) { + /* deletion stops at a piece boundry */ + end = p; + after = p->next; + } else { // cur > len + /* deletion stops midway through a piece */ + midway_end = true; + end = p; + after = piece_alloc(); + piece_init(after, before, p->next, p->content + p->len - (cur - len), cur - len); + } + + if (midway_start) { + /* we finally now which piece follows our newly allocated before piece */ + piece_init(before, start->prev, after, start->content, off); + } + + Piece *new_start = NULL, *new_end = NULL; + if (midway_start) { + new_start = before; + if (!midway_end) + new_end = before; + } + if (midway_end) { + if (!midway_start) + new_start = after; + new_end = after; + } + + span_init(&c->new, new_start, new_end); + span_init(&c->old, start, end); + span_swap(ed, &c->old, &c->new); + return true; +} + void editor_snapshot(Editor *ed) { ed->current_action = NULL; } @@ -11,7 +11,7 @@ typedef Iterate (*iterator_callback_t)(void *, size_t pos, const char *content, bool editor_insert(Editor*, size_t pos, char *c); -void editor_delete(Editor*, size_t start, size_t end); +bool editor_delete(Editor*, size_t pos, size_t len); bool editor_undo(Editor*); bool editor_redo(Editor*); void editor_snapshot(Editor*); |
