From 39f545e518d22b8f9e792902675e69e7592b806a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= Date: Mon, 21 Jul 2014 13:23:41 +0200 Subject: Add iterator functions to walk through text --- editor.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ editor.h | 12 +++++++++++- 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/editor.c b/editor.c index 567a1e8..1485432 100644 --- a/editor.c +++ b/editor.c @@ -272,6 +272,24 @@ static Location piece_get(Editor *ed, size_t pos) { return loc; } +static Location piece_get_public(Editor *ed, size_t pos) { + Location loc = {}; + // TODO: handle position at end of file: pos+1 + size_t cur = 0; + for (Piece *p = ed->begin.next; p->next; p = p->next) { + if (cur <= pos && pos <= cur + p->len) { + loc.piece = p; + loc.off = pos - cur; + return loc; + } + cur += p->len; + } + + return loc; +} + + + static Change *change_alloc(Editor *ed) { Action *a = ed->current_action; if (!a) { @@ -640,3 +658,36 @@ void editor_free(Editor *ed) { bool editor_modified(Editor *ed) { return ed->saved_action != ed->undo; } + +Iterator editor_iterator_get(Editor *ed, size_t pos) { + Location loc = piece_get_public(ed, pos); + Piece *p = loc.piece; + return (Iterator){ + .piece = p, + .text = p ? p->content + loc.off : NULL, + .len = p ? p->len - loc.off : 0, + }; +} + +void editor_iterator_next(Iterator *it) { + Piece *p = it->piece ? it->piece->next : NULL; + *it = (Iterator){ + .piece = p, + .text = p ? p->content : NULL, + .len = p ? p->len : 0, + }; +} + +void editor_iterator_prev(Iterator *it) { + Piece *p = it->piece ? it->piece->prev : NULL; + *it = (Iterator){ + .piece = p, + .text = p ? p->content : NULL, + .len = p ? p->len : 0, + }; +} + +bool editor_iterator_valid(const Iterator *it) { + /* filter out sentinel nodes */ + return it->piece && it->piece->editor; +} diff --git a/editor.h b/editor.h index 1273d6f..bde4da9 100644 --- a/editor.h +++ b/editor.h @@ -1,6 +1,13 @@ #include typedef struct Editor Editor; +typedef struct Piece Piece; + +typedef struct { + const char const *text; + /* const */ size_t len; + const Piece const *piece; +} Iterator; typedef bool (*iterator_callback_t)(void *, size_t pos, const char *content, size_t len); @@ -11,7 +18,10 @@ bool editor_replace(Editor*, size_t pos, char *c); void editor_snapshot(Editor*); bool editor_undo(Editor*); bool editor_redo(Editor*); -//char *editor_get(Editor*, size_t pos, size_t len); +Iterator editor_iterator_get(Editor*, size_t pos); +bool editor_iterator_valid(const Iterator*); +void editor_iterator_next(Iterator*); +void editor_iterator_prev(Iterator*); void editor_iterate(Editor*, void *, size_t pos, iterator_callback_t); bool editor_modified(Editor*); int editor_save(Editor*, const char *file); -- cgit v1.2.3