aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2014-07-22 14:47:17 +0200
committerMarc André Tanner <mat@brain-dump.org>2014-07-22 14:47:17 +0200
commit1000482506cc5a419a7f6be026cc1c8e8d89ce67 (patch)
tree1ddd5fb3671a48d82382275dfe968c8f4ed7d5c9
parent3e67f99d3395d2b98ea9e8de4b6b0e9eaf4711fd (diff)
downloadvis-1000482506cc5a419a7f6be026cc1c8e8d89ce67.tar.gz
vis-1000482506cc5a419a7f6be026cc1c8e8d89ce67.tar.xz
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.
-rw-r--r--editor.c35
1 files 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 */