aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2014-07-16 12:02:42 +0200
committerMarc André Tanner <mat@brain-dump.org>2014-07-16 12:02:42 +0200
commit615bbd7da9c3fe634cb9c37d867a208df048d047 (patch)
treed545a6026fcfefa32ad9a7bd637c967c4f03dc2f
parent1df415d621191a1fb1c23fa00409b25a74a3747a (diff)
downloadvis-615bbd7da9c3fe634cb9c37d867a208df048d047.tar.gz
vis-615bbd7da9c3fe634cb9c37d867a208df048d047.tar.xz
Implement deletion
-rw-r--r--editor.c70
-rw-r--r--editor.h2
2 files changed, 70 insertions, 2 deletions
diff --git a/editor.c b/editor.c
index b39ebee..f3e1197 100644
--- a/editor.c
+++ b/editor.c
@@ -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;
}
diff --git a/editor.h b/editor.h
index ff750a9..3704d37 100644
--- a/editor.h
+++ b/editor.h
@@ -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*);