From 1000482506cc5a419a7f6be026cc1c8e8d89ce67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= Date: Tue, 22 Jul 2014 14:47:17 +0200 Subject: Fix bugs in caching layer Thw lenght of the whole text (ed->size) also has to be updated. Also do not allocate changes if the operations are performed in the cache. --- editor.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/editor.c b/editor.c index e7163b5..a96cc28 100644 --- a/editor.c +++ b/editor.c @@ -194,11 +194,26 @@ static void cache_piece(Editor *ed, Piece *p) { /* check whether the given piece was the most recently modified one */ static bool cache_contains(Editor *ed, Piece *p) { Buffer *buf = ed->buffers; - return buf && ed->cache && ed->cache == p && p->content + p->len == buf->content + buf->pos; + Action *a = ed->current_action; + if (!buf || !ed->cache || ed->cache != p || !a || !a->change) + return false; + + Piece *start = a->change->new.start; + Piece *end = a->change->new.start; + bool found = false; + for (Piece *cur = start; !found; cur = cur->next) { + if (cur == p) + found = true; + if (cur == end) + break; + } + + return found && p->content + p->len == buf->content + buf->pos; } /* try to insert a junk of data at a given piece offset. the insertion is only - * performed if the piece is the most recenetly changed one. */ + * performed if the piece is the most recenetly changed one. the legnth of the + * piece, the span containing it and the whole text is adjusted accordingly */ static bool cache_insert(Editor *ed, Piece *p, size_t off, char *text, size_t len) { if (!cache_contains(ed, p)) return false; @@ -206,14 +221,16 @@ static bool cache_insert(Editor *ed, Piece *p, size_t off, char *text, size_t le size_t bufpos = p->content + off - buf->content; if (!buffer_insert(buf, bufpos, text, len)) return false; - ed->current_action->change->new.len += len; p->len += len; + ed->current_action->change->new.len += len; + ed->size += len; return true; } /* try to delete a junk of data at a given piece offset. the deletion is only * performed if the piece is the most recenetly changed one and the whole - * affected range lies within it. */ + * affected range lies within it. the legnth of the piece, the span containing it + * and the whole text is adjusted accordingly */ static bool cache_delete(Editor *ed, Piece *p, size_t off, size_t len) { if (!cache_contains(ed, p)) return false; @@ -221,8 +238,9 @@ static bool cache_delete(Editor *ed, Piece *p, size_t off, size_t len) { size_t bufpos = p->content + off - buf->content; if (off + len > p->len || !buffer_delete(buf, bufpos, len)) return false; - ed->current_action->change->new.len -= len; p->len -= len; + ed->current_action->change->new.len -= len; + ed->size -= len; return true; } @@ -438,9 +456,6 @@ static Piece* editor_insert_empty(Editor *ed, char *content, size_t len) { */ bool editor_insert(Editor *ed, size_t pos, char *text) { - Change *c = change_alloc(ed); - if (!c) - return false; size_t len = strlen(text); // TODO Location loc = piece_get(ed, pos); @@ -449,6 +464,10 @@ bool editor_insert(Editor *ed, size_t pos, char *text) { if (cache_insert(ed, p, off, text, len)) return true; + Change *c = change_alloc(ed); + if (!c) + return false; + if (!(text = buffer_store(ed, text, len))) return false; /* special case for an empty document */ -- cgit v1.2.3