Browse code
feat(tree-sitter): more work on highlighting with tree-sitter
Edward authored on 23/04/2021 09:10:18
Showing 1 changed files
Showing 1 changed files
... | ... |
@@ -51,10 +51,10 @@ |
51 | 51 |
tree |
52 | 52 |
:traversal :postorder)) |
53 | 53 |
|
54 |
-(defvar *current-language*) |
|
54 |
+(defvar *current-language* :tsx) |
|
55 | 55 |
(defun parse (src &optional (language *current-language*)) |
56 | 56 |
(typecase src |
57 |
- (pathname (parse language (alexandria:read-file-into-string src))) |
|
57 |
+ (pathname (parse (alexandria:read-file-into-string src) language)) |
|
58 | 58 |
(string (displace-tree (cl-tree-sitter:parse-string language src) |
59 | 59 |
src)))) |
60 | 60 |
|
... | ... |
@@ -66,9 +66,145 @@ |
66 | 66 |
(cons (if (and (tag-p (car node)) (= 3 (length node))) |
67 | 67 |
(destructuring-bind (_ op . __) (parse-thing node) |
68 | 68 |
(declare (ignore _ __)) |
69 |
- (when (eql op type) |
|
70 |
- (save node))) |
|
69 |
+ (if (fwoar.cl-multis.interface:isa? op type) |
|
70 |
+ (save node) |
|
71 |
+ node)) |
|
71 | 72 |
node)) |
72 | 73 |
(t node))) |
73 | 74 |
tree |
74 | 75 |
:traversal :postorder))) |
76 |
+ |
|
77 |
+(defun child-tagged (tag) |
|
78 |
+ (lambda (node) |
|
79 |
+ (values-list |
|
80 |
+ (remove-if-not (serapeum:op (eql tag _1)) |
|
81 |
+ (fourth (parse-thing node)) |
|
82 |
+ :key (data-lens:• 'car |
|
83 |
+ 'parse-thing))))) |
|
84 |
+ |
|
85 |
+ |
|
86 |
+#+(or) |
|
87 |
+(defvar *empty-package* (make-package (gensym) :use ())) |
|
88 |
+ |
|
89 |
+#+(or) |
|
90 |
+(defvar *ht-pprint-dispatch* (copy-pprint-dispatch *print-pprint-dispatch*)) |
|
91 |
+ |
|
92 |
+#+(or) |
|
93 |
+(set-pprint-dispatch 'hash-table |
|
94 |
+ (lambda (s o) |
|
95 |
+ (let ((*package* (make-package *empty-package*))) |
|
96 |
+ (prin1 `(alexandria:alist-hash-table |
|
97 |
+ (list |
|
98 |
+ ,@(mapcar (lambda (it) |
|
99 |
+ `(cons ,(car it) |
|
100 |
+ ,(cdr it))) |
|
101 |
+ (alexandria:hash-table-alist o)))) |
|
102 |
+ s))) |
|
103 |
+ 0 *ht-pprint-dispatch*) |
|
104 |
+ |
|
105 |
+#+(or) |
|
106 |
+(set-pprint-dispatch 'vector |
|
107 |
+ nil |
|
108 |
+ #+(or) |
|
109 |
+ (lambda (s o) |
|
110 |
+ (let ((*package* *empty-package*)) |
|
111 |
+ (typecase o |
|
112 |
+ (string (let ((*print-pretty* nil)) |
|
113 |
+ (prin1 o s))) |
|
114 |
+ (t (prin1 `(vector |
|
115 |
+ ,@(map 'list 'identity o)) |
|
116 |
+ s))))) |
|
117 |
+ 0 *ht-pprint-dispatch*) |
|
118 |
+ |
|
119 |
+(defun collect-edits (tree collector) |
|
120 |
+ (destructuring-bind (tag type source children) (parse-thing tree) |
|
121 |
+ (multiple-value-bind (_ offs) (array-displacement source) |
|
122 |
+ (declare (ignore _)) |
|
123 |
+ (let ((end (+ offs (length source)))) |
|
124 |
+ (flet ((tag (start-p) |
|
125 |
+ (format nil "<~:[~;/~]span~:*~:[ class=\"~a ~{~a~^ ~}\"~;~]>" |
|
126 |
+ start-p |
|
127 |
+ (if tag (string-downcase tag) "") |
|
128 |
+ (mapcar 'string-downcase |
|
129 |
+ (fwoar.cl-multis.interface:ancestors |
|
130 |
+ type))))) |
|
131 |
+ (funcall collector (fwoar.lisp-sandbox.ot-edit:insert offs (tag nil))) |
|
132 |
+ (funcall collector (fwoar.lisp-sandbox.ot-edit:insert end (tag t))) |
|
133 |
+ (mapcar (lambda (it) |
|
134 |
+ (collect-edits it collector)) |
|
135 |
+ children)))))) |
|
136 |
+ |
|
137 |
+#+(or) |
|
138 |
+(setf (ningle:route *a* "/2/(?<url>.*)" :regexp t) |
|
139 |
+ (lambda (_) |
|
140 |
+ (let ((*standard-output* *trace-output*)) |
|
141 |
+ (fresh-line)(princ "notice: ")(prin1 _)(terpri)) |
|
142 |
+ (let ((src (drakma:http-request (cadr (assoc :captures _))))) |
|
143 |
+ (flet ((outp () |
|
144 |
+ (spinneret:with-html |
|
145 |
+ (:div #+(or)selector-ui |
|
146 |
+ ;; :node-types ("expression" "identifier" "operator" "subscript-expression" |
|
147 |
+ ;; "member-expression" "jsx" "pair") |
|
148 |
+ (:pre |
|
149 |
+ (:code :class "language-ts" |
|
150 |
+ (:raw |
|
151 |
+ (fwoar.lisp-sandbox.ot-edit:apply-edits |
|
152 |
+ src |
|
153 |
+ (serapeum:with-collector (s) |
|
154 |
+ (loop for next = (position #\< src) |
|
155 |
+ then (position #\< src :start (1+ next)) |
|
156 |
+ while next |
|
157 |
+ do (s (fwoar.lisp-sandbox.ot-edit::replace-char next "<"))) |
|
158 |
+ (loop for next = (position #\> src) |
|
159 |
+ then (position #\> src :start (1+ next)) |
|
160 |
+ while next |
|
161 |
+ do (s (fwoar.lisp-sandbox.ot-edit::replace-char next ">"))) |
|
162 |
+ (collect-edits (parse src) |
|
163 |
+ #'s)))))) |
|
164 |
+ (:ul#w |
|
165 |
+ (:li "expression")) |
|
166 |
+ (:script |
|
167 |
+ (:raw "const ul = document.querySelector(\"#w\");" |
|
168 |
+ "const dps = new Set([]);" |
|
169 |
+ "[].map.call(document.querySelectorAll(\".syntax-element\")," |
|
170 |
+ " v=> {Array.from(v.classList).forEach(it=>dps.add(it.toLowerCase()))});" |
|
171 |
+ "function it(v) {const it=document.createElement(\"li\"); " |
|
172 |
+ "it.textContent = v; return it}" |
|
173 |
+ " const dpA = Array.from(dps);dpA.sort();" |
|
174 |
+ " dpA.forEach(cls => { if(/^[a-zA-Z-]{2,}$/.test(cls)) {ul.appendChild(it(cls))}})")))))) |
|
175 |
+ (spinneret:with-html-string |
|
176 |
+ (:style |
|
177 |
+ "input[name=expression]:checked ~ pre .expression {color: var(--zenburn-red);background-color: hsla(180,0%,0%,0.1)}" |
|
178 |
+ "input[name=jsx]:checked ~ pre .jsx {color: var(--zenburn-red);background-color: hsla(180,0%,0%,0.1)}" |
|
179 |
+ "input[name=subscript-expression]:checked ~ pre .subscript-expression {color: var(--zenburn-red);background-color: hsla(180,0%,0%,0.1)}" |
|
180 |
+ "input[name=member-expression]:checked ~ pre .member-expression {color: var(--zenburn-red);background-color: hsla(180,0%,0%,0.1)}" |
|
181 |
+ "input[name=identifier]:checked ~ pre .function .identifier {color: var(--zenburn-red)}" |
|
182 |
+ "input[name=operator]:checked ~ pre .function .operator {color: var(--zenburn-red)}" |
|
183 |
+ "input[name=pair]:checked ~ pre .pair .tag-key {color: var(--zenburn-blue)}" |
|
184 |
+ "input[name=pair]:checked ~ pre .pair .tag-value {color: var(--zenburn-green)}" |
|
185 |
+ "input[name=pair]:checked ~ pre .pair {background: var(--zenburn-fg+1)}" |
|
186 |
+ (coerce '(#\newline) 'string) |
|
187 |
+ (alexandria:read-file-into-string (truename "~/styles.css")) |
|
188 |
+ ) |
|
189 |
+ (outp)))))) |
|
190 |
+ |
|
191 |
+ |
|
192 |
+#+(or) |
|
193 |
+(mapcan (data-lens:• |
|
194 |
+ (lambda (it) |
|
195 |
+ (destructuring-bind (a c) it |
|
196 |
+ (mapcar (serapeum:op (list a _)) c))) |
|
197 |
+ (data-lens:juxt |
|
198 |
+ (data-lens:• (lambda (it) |
|
199 |
+ (substitute #\- #\_ it)) |
|
200 |
+ (lambda (it) |
|
201 |
+ (string-left-trim "_" it))) |
|
202 |
+ (data-lens:• (data-lens:over (data-lens:• (data-lens:applicable-when |
|
203 |
+ (data-lens:• (lambda (it) |
|
204 |
+ (substitute #\- #\_ it)) |
|
205 |
+ (lambda (it) |
|
206 |
+ (string-left-trim "_" it))) |
|
207 |
+ 'identity) |
|
208 |
+ (data-lens:key "name"))) |
|
209 |
+ (lambda (it) (fw.lu:dive (list "rules" it "members") tsx-grammar:+data+))))) |
|
210 |
+ (gethash "supertypes" tsx)) |