vis
a vi-like editor based on Plan 9's structural regular expressions
git clone https://9o.is/git/vis.git
commit a574d17054efff5971c796b8933699c2a1a5791a parent 5f334f839723ab2352a4d861527b55b46aa19c9c Author: Marc André Tanner <mat@brain-dump.org> Date: Mon, 21 Jul 2014 13:23:41 +0200 Add iterator functions to walk through text Diffstat:
| M | editor.c | | | 51 | +++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | editor.h | | | 12 | +++++++++++- |
2 files changed, 62 insertions(+), 1 deletion(-)
diff --git 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 @@ -1,6 +1,13 @@ #include <stdbool.h> 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);