Add ansi-string-length.

This commit is contained in:
Dominik Pantůček 2023-03-21 22:35:55 +01:00
parent f840c18b49
commit bde3199cca
2 changed files with 35 additions and 0 deletions

View file

@ -163,6 +163,13 @@ black text.
Generic highlight of given text. Defaults to bold blue text.
(ansi-string-length str)
* ```str``` string that may contain ANSI CSI SGR sequences
Returns the string length in characters without any ANSI CSI SGR
sequences contained.
### Command Line parsing
Generic syntax-based implementation of command-line options parsing

View file

@ -82,6 +82,31 @@
(define a:muted (ansi #:black #:bold))
(define a:highlight (ansi #:blue #:bold))
;; Returns visual string length in characters skipping any ANSI CSI
;; SGR sequences.
;;
;; Internal states:
;; 0 - regular string
;; 1 - seen escape
;; 2 - CSI started
(define (ansi-string-length str)
(let loop ((lst (string->list str))
(state 0)
(len 0))
(if (null? lst)
len
(let ((ch (car lst)))
(case state
((0) (if (eq? ch #\escape)
(loop (cdr lst) 1 len)
(loop (cdr lst) 0 (add1 len))))
((1) (if (eq? ch #\[)
(loop (cdr lst) 2 len)
(loop (cdr lst) 0 len)))
((2) (if (eq? ch #\m)
(loop (cdr lst) 0 len)
(loop (cdr lst) 2 len))))))))
;; Performs ANSI module self-tests.
(define (ansi-tests!)
(run-tests
@ -89,6 +114,9 @@
(test-equal? ansi (ansi #:red) "\x1b[31m")
(test-equal? ansi (ansi #:nonsense) "")
(test-equal? ansi (ansi #:default) "\x1b[0m")
(test-eq? ansi-string-length (ansi-string-length "test") 4)
(test-eq? ansi-string-length (ansi-string-length "\x1b[1mtest") 4)
(test-eq? ansi-string-length (ansi-string-length "\x1b[30mtest\x1b[0m") 4)
))
)