summaryrefslogtreecommitdiff
path: root/par/piece-table.scm
diff options
context:
space:
mode:
Diffstat (limited to 'par/piece-table.scm')
-rw-r--r--par/piece-table.scm29
1 files changed, 29 insertions, 0 deletions
diff --git a/par/piece-table.scm b/par/piece-table.scm
index 24608e3..21661e7 100644
--- a/par/piece-table.scm
+++ b/par/piece-table.scm
@@ -185,6 +185,35 @@
(define (piece-table-text-length piece-table)
(reduce + 0 (map piece-length (piece-table-pieces piece-table))))
+(define (piece-table-for-each piece-table f from to)
+ ;; TODO: default from and to
+ "Calls `f` through the characters of the piece-table, like `string-for-each`
+ would do, but the `f` call also includes the piece (to expose extra data) and
+ the index of the character"
+ (let loop ((idx 0)
+ (start 0)
+ (pieces (piece-table-pieces piece-table)))
+ (let* ((piece (car pieces))
+ (len (piece-length piece))
+ (end (+ start len))
+ (more? (not (null? (cdr pieces)))))
+ (when (< idx to) ;; Skip tail
+ (if (or (= idx end) (<= end from))
+ ;; Current piece doesn't contain the section we need or finished
+ ;; Jump to next piece
+ (when more? (loop end end (cdr pieces)))
+ ;; Current piece contains part of the section we need, go char by
+ ;; char
+ (begin
+ (when (<= from idx)
+ (f
+ (string-ref (buffer->string (piece-buffer piece))
+ (+ (piece-start piece) (- idx start)))
+ idx
+ piece))
+ ;; There are chars to process in this piece
+ (loop (+ idx 1) start pieces)))))))
+
(define (piece-table-find-line-break piece-table idx)
(let loop ((idx 0)
(ps (piece-table-pieces piece-table))