git.fiddlerwoaroof.com
Browse code

feat(tools): add zenburn utility

Edward Langley authored on 25/04/2023 05:38:27
Showing 3 changed files
... ...
@@ -20,3 +20,4 @@
20 20
 core
21 21
 pom.xml
22 22
 pom.xml.asc
23
+/tools/bin/zenburn
... ...
@@ -1,9 +1,17 @@
1
-all: git-pick-patch bloomutil
1
+all: bin bin/git-pick-patch bin/bloomutil bin/zenburn
2 2
 
3
-bindir:
3
+bin/zenburn: zenburn.lisp
4
+	sbcl --lose-on-corruption --disable-ldb --disable-debugger \
5
+		  --no-userinit --no-sysinit \
6
+		  --eval '(push :fw.dump *features*)' \
7
+		  --load zenburn.lisp \
8
+		  --eval '(fwoar.zenburn:dump)'
9
+	mv zenburn bin
10
+
11
+bin:
4 12
 	mkdir -p bin
5 13
 
6
-bloomutil: bloomutil.lisp
14
+bin/bloomutil: bloomutil.lisp
7 15
 	sbcl --disable-debugger \
8 16
 	     --no-userinit \
9 17
 	     --eval '(pushnew :fw.dump *features*)' \
... ...
@@ -11,7 +19,7 @@ bloomutil: bloomutil.lisp
11 19
 	     --eval '(fwoar.bloomutil::dump)'
12 20
 	mv bloomutil bin
13 21
 
14
-git-pick-patch: bindir git-pick-patch.lisp
22
+bin/git-pick-patch: git-pick-patch.lisp
15 23
 	sbcl --eval "(ql:quickload '(:alexandria :serapeum :cl-ppcre))" \
16 24
 	     --load git-pick-patch.lisp \
17 25
 	     --eval '(save-lisp-and-die "bin/git-pick-patch"'" :executable t :toplevel 'git-pick-patch::main :compression t)"
18 26
new file mode 100644
... ...
@@ -0,0 +1,149 @@
1
+#+fw.dump
2
+(eval-when (:compile-toplevel :load-toplevel :execute)
3
+  (load "~/quicklisp/setup.lisp")
4
+  (require :uiop))
5
+
6
+#+fw.dump
7
+(ql:quickload '(:net.didierverna.clon))
8
+
9
+(defpackage :fwoar.zenburn
10
+  (:use :cl )
11
+  (:export dump))
12
+(in-package :fwoar.zenburn)
13
+
14
+(defun 256-color-text (fg bg format &rest args)
15
+  (cond ((and fg bg)
16
+         (destructuring-bind (fg-r fg-g fg-b) fg
17
+           (destructuring-bind (bg-r bg-g bg-b) bg
18
+             (format T "~c[38;2;~d;~d;~d;48;2;~d;~d;~dm~?~@*~c[39m~:*~c[49m"
19
+                     #\Esc
20
+                     fg-r fg-g fg-b
21
+                     bg-r bg-g bg-b
22
+                     format
23
+                     args))))
24
+        (fg
25
+         (destructuring-bind (fg-r fg-g fg-b) fg
26
+           (format T "~c[38;2;~d;~d;~dm~?~@*~c[39m~:*~c[49m"
27
+                   #\Esc
28
+                   fg-r fg-g fg-b
29
+                   format
30
+                   args)))
31
+        (bg
32
+         (destructuring-bind (bg-r bg-g bg-b) bg
33
+           (format T "~c[48;2;~d;~d;~dm~?~@*~c[39m~:*~c[49m"
34
+                   #\Esc
35
+                   bg-r bg-g bg-b
36
+                   format
37
+                   args)))
38
+        (t (error "must specify either fg or bg for a color"))))
39
+
40
+(defparameter color-alist
41
+  '((fg+2     . (#xFF #xFF #xEF))
42
+    (fg+1     . (#xF5 #xF5 #xD6))
43
+    (fg       . (#xDC #xDC #xCC))
44
+    (fg-1     . (#xA6 #xA6 #x89))
45
+    (fg-2     . (#x65 #x65 #x55))
46
+    (black    . (#x00 #x00 #x00))
47
+    (bg-2     . (#x00 #x00 #x00))
48
+    (bg-1     . (#x11 #x11 #x12))
49
+    (bg-05    . (#x38 #x38 #x38))
50
+    (bg       . (#x2A #x2B #x2E))
51
+    (bg+05    . (#x49 #x49 #x49))
52
+    (bg+1     . (#x4F #x4F #x4F))
53
+    (bg+2     . (#x5F #x5F #x5F))
54
+    (bg+3     . (#x6F #x6F #x6F))
55
+    (red+2    . (#xEC #xB3 #xB3))
56
+    (red+1    . (#xDC #xA3 #xA3))
57
+    (red      . (#xCC #x93 #x93))
58
+    (red-1    . (#xBC #x83 #x83))
59
+    (red-2    . (#xAC #x73 #x73))
60
+    (red-3    . (#x9C #x63 #x63))
61
+    (red-4    . (#x8C #x53 #x53))
62
+    (red-5    . (#x7C #x43 #x43))
63
+    (red-6    . (#x6C #x33 #x33))
64
+    (orange   . (#xDF #xAF #x8F))
65
+    (yellow   . (#xF0 #xDF #xAF))
66
+    (yellow-1 . (#xE0 #xCF #x9F))
67
+    (yellow-2 . (#xD0 #xBF #x8F))
68
+    (green-5  . (#x2F #x4F #x2F))
69
+    (green-4  . (#x3F #x5F #x3F))
70
+    (green-3  . (#x4F #x6F #x4F))
71
+    (green-2  . (#x5F #x7F #x5F))
72
+    (green-1  . (#x6F #x8F #x6F))
73
+    (green    . (#x7F #x9F #x7F))
74
+    (green+1  . (#x8F #xB2 #x8F))
75
+    (green+2  . (#x9F #xC5 #x9F))
76
+    (green+3  . (#xAF #xD8 #xAF))
77
+    (green+4  . (#xBF #xEB #xBF))
78
+    (cyan     . (#x93 #xE0 #xE3))
79
+    (blue+3   . (#xBD #xE0 #xF3))
80
+    (blue+2   . (#xAC #xE0 #xE3))
81
+    (blue+1   . (#x94 #xBF #xF3))
82
+    (blue     . (#x8C #xD0 #xD3))
83
+    (blue-1   . (#x7C #xB8 #xBB))
84
+    (blue-2   . (#x6C #xA0 #xA3))
85
+    (blue-3   . (#x5C #x88 #x8B))
86
+    (blue-4   . (#x4C #x70 #x73))
87
+    (blue-5   . (#x36 #x60 #x60))
88
+    (magenta  . (#xDC #x8C #xC3))))
89
+
90
+(defun zenburn-text (fg bg text &rest format-args)
91
+  (let ((fgcolor (when fg (cdr (assoc fg color-alist :test 'equal))))
92
+        (bgcolor (when bg (cdr (assoc bg color-alist :test 'equal)))))
93
+    (apply #'256-color-text fgcolor bgcolor text format-args)))
94
+
95
+(defun summary ()
96
+  (loop for (color . values) in color-alist
97
+        do
98
+           (zenburn-text () color (make-string 32 :initial-element #\space))
99
+           (format t "  ~8<~a~> (~{~2x~^, ~}) ~:* (~{~3d~^, ~})~%" color values)))
100
+
101
+(defvar *synopsis*
102
+  (net.didierverna.clon:defsynopsis (:postfix "[TEXT...]" :make-default nil)
103
+    (flag :short-name "h" :long-name "help")
104
+    (enum :short-name "f" :long-name "fg" :enum (mapcar 'car color-alist)
105
+          :description "Set the text's foreground color")
106
+    (enum :short-name "b" :long-name "bg" :enum (mapcar 'car color-alist)
107
+          :description "Set the text's background color")
108
+    (enum :long-name "html"  :enum (mapcar 'car color-alist)
109
+          :description "Show COLOR as an HTML RGB literal")
110
+    (enum :long-name "css"  :enum (mapcar 'car color-alist)
111
+          :description "Show COLOR as an CSS RGB literal")))
112
+
113
+(defun main ()
114
+  (let* ((context (net.didierverna.clon:make-context :synopsis *synopsis*))
115
+         (net.didierverna.clon:*context* context)
116
+         (foreground (net.didierverna.clon:getopt :context context
117
+                                                  :long-name "fg"))
118
+         (background (net.didierverna.clon:getopt :context context
119
+                                                  :long-name "bg"))
120
+         (remainder (net.didierverna.clon:remainder :context context))
121
+         (css (net.didierverna.clon:getopt :context context
122
+                                           :long-name "css"))
123
+         (html (net.didierverna.clon:getopt :context context
124
+                                            :long-name "html")))
125
+    (cond ((net.didierverna.clon:getopt :context context
126
+                                        :long-name "help")
127
+           (net.didierverna.clon:help))
128
+          ((and html css)
129
+           (format *error-output* "Can't use HTML and CSS options together~%")
130
+           (net.didierverna.clon:help))
131
+          (css
132
+           (let ((values (cdr (assoc css color-alist))))
133
+             (format t "rgb(~{~d~^, ~})~%" values)))
134
+          (html
135
+           (let ((values (cdr (assoc html color-alist))))
136
+             (format t "#~{~2,'0x~}~%" values)))
137
+          ((null remainder)
138
+           (summary))
139
+          ((or foreground background)
140
+           (zenburn-text foreground background "~{~a~^ ~}" remainder))
141
+          (t
142
+           (net.didierverna.clon:help)))))
143
+
144
+
145
+(defun dump ()
146
+  (setf net.didierverna.clon:*context* nil
147
+        *features* (remove :fw.dump *features*)
148
+        *print-case* :downcase)
149
+  (net.didierverna.clon:dump "zenburn" main))