hackerbase/ansi.scm

94 lines
2.3 KiB
Scheme

;;
;; ansi.scm
;;
;; ANSI terminal support.
;;
;; ISC License
;;
;; Copyright 2023 Brmlab, z.s.
;; Dominik Pantůček <dominik.pantucek@trustica.cz>
;;
;; Permission to use, copy, modify, and/or distribute this software
;; for any purpose with or without fee is hereby granted, provided
;; that the above copyright notice and this permission notice appear
;; in all copies.
;;
;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
;; WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
;; WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
;; AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
;; CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
;; OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
;; NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
;; CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
;;
(declare (unit ansi))
(module
ansi
(
ansi
a:error
a:warning
a:success
a:neutral
a:default
a:muted
a:highlight
ansi-tests!
)
(import scheme
(chicken base)
(chicken string)
testing
utils)
;; Only basic ANSI colors and bold attribute support.
(define colors
'((#:black . 30)
(#:red . 31)
(#:green . 32)
(#:yellow . 33)
(#:blue . 34)
(#:magenta . 35)
(#:cyan . 36)
(#:white . 37)
(#:default . 0)
(#:bold . 1)))
;; Returns ANSI sequence changing color and/or bold attribute.
(define (ansi . args)
(let ((argsl
(map
(lambda (key-color)
(number->string (cdr key-color)))
(filter
identity
(map (lambda (arg) (assq arg colors)) args)))))
(if (null? argsl)
""
(string-append "\x1b["
(string-intersperse argsl ";")
"m"))))
;; Nice styles to be used everywhere for consistency
(define a:error (ansi #:red #:bold))
(define a:warning (ansi #:default #:yellow))
(define a:success (ansi #:green #:bold))
(define a:neutral (ansi #:default #:white))
(define a:default (ansi #:default))
(define a:muted (ansi #:black #:bold))
(define a:highlight (ansi #:blue #:bold))
;; Performs ANSI module self-tests.
(define (ansi-tests!)
(run-tests
ansi
(test-equal? ansi (ansi #:red) "\x1b[31m")
(test-equal? ansi (ansi #:nonsense) "")
(test-equal? ansi (ansi #:default) "\x1b[0m")
))
)