So much cleaner and likely faster if not the same

This commit is contained in:
Vivianne 2024-02-29 09:33:11 -05:00
parent b40011ca7c
commit 4cdd0bd08c
1 changed files with 29 additions and 50 deletions

View File

@ -3,11 +3,10 @@
#:use-module (ice-9 binary-ports)
#:export (make-ansi-port-tuple))
(define %MARKER "\x1b")
(define %MARKER-CHAR #\x1b)
(define %MARKER #\x1b)
(define %RESET "[0m")
(define %RESET-SEQ (string-append %MARKER %RESET))
(define %RESET-SEQ
(string-append (string %MARKER) %RESET))
(define (ansi-terminator? char)
(let ((c (char->integer char)))
@ -15,63 +14,40 @@
;; TODO: create helpers that allow the reflow to operate properly.
(define (make-ansi-port-tuple o-port)
;; The current ansi sequence gets built up over time
;; need to reset this after we write it out
(define sequence-port #f)
(define sequence-port-get-bv #f)
(define (reset-sequence-port!)
(define-values (p get)
(open-bytevector-output-port))
(set! sequence-port p)
(set! sequence-port-get-bv get))
(reset-sequence-port!)
;; The previous ansi sequence also gets built up
;; sequence by sequence
(define last-seq-port #f)
(define last-seq-port-get-bv #f)
(define (reset-last-seq-port!)
(define-values (p get)
(open-bytevector-output-port))
(set! last-seq-port p)
(set! last-seq-port-get-bv get)
(set! cached-sequence #f))
(reset-last-seq-port!)
;; The sequence we are currently building up, a list of characters (reversed).
(define wip-sequence-list '())
;; The current sequence, a list of strings (reversed).
;; These will be compressed into a single string upon reading.
(define current-sequence-list '())
(define in-escape-sequence? #f)
(define sequence? #f)
(define cached-sequence #f)
(define (sequence?) (not (null? current-sequence-list)))
(define-syntax-rule (cons! item lst)
(set! lst (cons item lst)))
;; rune by rune
(define (put-char c)
(cond
((equal? %MARKER-CHAR c)
((equal? %MARKER c)
(set! in-escape-sequence? #t)
(set! sequence? #t)
(display c sequence-port))
(cons! c wip-sequence-list))
(in-escape-sequence?
(display c sequence-port)
(cons! c wip-sequence-list)
(when (ansi-terminator? c)
(set! in-escape-sequence? #f)
(let* ((bv (sequence-port-get-bv))
(sequence (and bv (bytevector->string bv (native-transcoder)))))
(unless sequence
(error "Terminator found within sequence, but sequence could not be converted to string"))
(let ((sequence (reverse-list->string wip-sequence-list)))
(cond
((string-suffix? %RESET sequence)
;; Reset sequence, clear the saved sequence!
(reset-last-seq-port!)
(set! sequence? #f))
(set! current-sequence-list '()))
((equal? c #\m)
;; color code, put the sequence into the last-seq port!
(put-bytevector last-seq-port bv)
(set! cached-sequence #f)))
;; color code, add the sequence
(cons! sequence current-sequence-list)))
(display sequence o-port)
(reset-sequence-port!))))
(set! wip-sequence-list '()))))
(else
(display c o-port))))
@ -91,14 +67,17 @@
"w"))
(define (last-sequence)
(and sequence?
(or cached-sequence
(let ((seq (bytevector->string (last-seq-port-get-bv) (native-transcoder))))
(set! cached-sequence seq)
seq))))
(and
(sequence?)
(if (= 1 (length current-sequence-list))
(car current-sequence-list)
;; On read, compress the list of strings to a single string for safekeeping
(let ((str (string-concatenate-reverse/shared current-sequence-list)))
(set! current-sequence-list (list str))
str))))
(define (reset-ansi)
(when sequence?
(when (sequence?)
(display %RESET-SEQ o-port)))
(define (restore-ansi)