diff options
Diffstat (limited to 'yolk.colors.ss')
-rw-r--r-- | yolk.colors.ss | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/yolk.colors.ss b/yolk.colors.ss new file mode 100644 index 0000000..70b821b --- /dev/null +++ b/yolk.colors.ss | |||
@@ -0,0 +1,89 @@ | |||
1 | ;;; (yolk colors) --- ansi color escapes | ||
2 | |||
3 | ;; "Colors" in this context refers both to actual /colors/, and to text | ||
4 | ;; properties like bold, italic, etc. | ||
5 | |||
6 | (import (scheme base) | ||
7 | (scheme write) | ||
8 | (chicken string) | ||
9 | (matchable) ; is this something i want? | ||
10 | (yolk common)) | ||
11 | |||
12 | (define (%colors . codes) | ||
13 | (let ((codestr (string-intersperse (map ->string codes) ";"))) | ||
14 | (csi codestr "m"))) | ||
15 | |||
16 | (define %props-alist | ||
17 | '((reset . "0") | ||
18 | ;; name . (on . off) | ||
19 | (bold . ("1" . "22")) | ||
20 | (dim . ("2" . "22")) | ||
21 | (italic . ("3" . "23")) | ||
22 | (underline . ("4" . "24")) | ||
23 | (blink . ("5" . "25")) | ||
24 | (inverse . ("7" . "27")) | ||
25 | (hidden . ("8" . "28")) | ||
26 | (strikethrough . ("9" . "29")))) | ||
27 | |||
28 | (define %colors-alist | ||
29 | '((reset . "0") | ||
30 | ;; color . (fg . bg) | ||
31 | (black . ("30" . "40")) | ||
32 | (red . ("31" . "41")) | ||
33 | (green . ("32" . "42")) | ||
34 | (yellow . ("33" . "43")) | ||
35 | (blue . ("34" . "44")) | ||
36 | (magenta . ("35" . "45")) | ||
37 | (cyan . ("36" . "46")) | ||
38 | (white . ("37" . "47")) | ||
39 | (default . ("39" . "49")))) | ||
40 | |||
41 | (define (atom? x) | ||
42 | (and (not (pair? x)) | ||
43 | (not (null? x)))) | ||
44 | |||
45 | (define (colors-reset . codes) | ||
46 | (cond | ||
47 | ((null? codes) | ||
48 | (%colors 0)) | ||
49 | (else (apply string-append | ||
50 | (map (lambda (code) | ||
51 | (match code | ||
52 | ('fg (%colors (cadr (assq 'default %colors-alist)))) | ||
53 | ('bg (%colors (cddr (assq 'default %colors-alist)))) | ||
54 | (x (%colors (cddr (assq x %props-alist)))))) | ||
55 | codes))))) | ||
56 | |||
57 | (define (color? x) | ||
58 | (memq x '(default black red green yellow blue magenta cyan white))) | ||
59 | |||
60 | (define (colors codes) | ||
61 | (let loop ((codes codes) | ||
62 | (acc '())) | ||
63 | (if (null? codes) | ||
64 | (apply %colors (reverse acc)) | ||
65 | (loop (cdr codes) | ||
66 | (match (car codes) | ||
67 | ((? number? x) | ||
68 | (cons x acc)) | ||
69 | ((or `(fg ,color) | ||
70 | (? color? color)) | ||
71 | (cons (cadr (assq color %colors-alist)) | ||
72 | acc)) | ||
73 | (`(bg ,color) | ||
74 | (cons (cddr (assq color %colors-alist)) | ||
75 | acc)) | ||
76 | ((or `(set ,prop) | ||
77 | `(,prop on) | ||
78 | (? atom? prop)) | ||
79 | (cons (cadr (assq prop %props-alist)) | ||
80 | acc)) | ||
81 | ((or `(reset ,prop) | ||
82 | `(,prop off)) | ||
83 | (cons (cddr (assq prop %props-alist))))))))) | ||
84 | |||
85 | (define (with-colors codes thunk) | ||
86 | (dynamic-wind | ||
87 | (lambda () (display (colors codes))) | ||
88 | thunk | ||
89 | (lambda () (display (colors-reset))))) | ||