summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEkaitz Zarraga <ekaitz@elenq.tech>2024-01-23 15:29:23 +0100
committerEkaitz Zarraga <ekaitz@elenq.tech>2024-01-23 15:29:23 +0100
commit26892394d6999fca9be6975b0910158fdf8a9fff (patch)
tree9fa2a691d8ba7de5d925e532c1b83e148db011af
parent73e28d46fd5aeb71677eec8e785029b26f6385ef (diff)
par: piece-table: add for-each
-rw-r--r--par/piece-table.scm29
-rw-r--r--par/piece-table.sld3
-rw-r--r--tests/piece-table.scm13
3 files changed, 44 insertions, 1 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))
diff --git a/par/piece-table.sld b/par/piece-table.sld
index f867612..427b389 100644
--- a/par/piece-table.sld
+++ b/par/piece-table.sld
@@ -10,5 +10,6 @@
piece-table-substring
string->piece-table
add-buffer-length
- piece-table-line)
+ piece-table-line
+ piece-table-for-each)
(include "piece-table.scm"))
diff --git a/tests/piece-table.scm b/tests/piece-table.scm
index 19bd107..453229e 100644
--- a/tests/piece-table.scm
+++ b/tests/piece-table.scm
@@ -47,3 +47,16 @@
(piece-table-delete! table 12 1)
(test-equal "OLASOY EKAIT" (piece-table->string table))
(test-end "delete")
+
+(test-begin "for-each")
+ (define table (make-piece-table "12346890"))
+ (piece-table-insert! table 4 "5" 'normal)
+ (test-equal "123456890" (piece-table->string table))
+ (piece-table-insert! table 6 "7" 'normal)
+ (test-equal "1234567890" (piece-table->string table))
+ (piece-table-for-each table
+ (lambda (c i p)
+ (test-equal c (string-ref "1234567890" i)))
+ 0
+ 10)
+(test-end)