diff options
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | Cargo.lock | 804 | ||||
-rw-r--r-- | Cargo.toml | 6 | ||||
-rw-r--r-- | flake.lock | 87 | ||||
-rw-r--r-- | flake.nix | 68 | ||||
-rw-r--r-- | tree-viz/.gitignore | 1 | ||||
-rw-r--r-- | tree-viz/Cargo.toml | 19 | ||||
-rw-r--r-- | tree-viz/src/app.rs | 230 | ||||
-rw-r--r-- | tree-viz/src/config.rs | 24 | ||||
-rw-r--r-- | tree-viz/src/main.rs | 96 |
10 files changed, 1339 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fcdcb15 --- /dev/null +++ b/.gitignore | |||
@@ -0,0 +1,4 @@ | |||
1 | target | ||
2 | scope-viz | ||
3 | .direnv | ||
4 | test-files | ||
diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..338a791 --- /dev/null +++ b/Cargo.lock | |||
@@ -0,0 +1,804 @@ | |||
1 | # This file is automatically @generated by Cargo. | ||
2 | # It is not intended for manual editing. | ||
3 | version = 3 | ||
4 | |||
5 | [[package]] | ||
6 | name = "ahash" | ||
7 | version = "0.4.7" | ||
8 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
9 | checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e" | ||
10 | |||
11 | [[package]] | ||
12 | name = "aho-corasick" | ||
13 | version = "0.7.19" | ||
14 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
15 | checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" | ||
16 | dependencies = [ | ||
17 | "memchr", | ||
18 | ] | ||
19 | |||
20 | [[package]] | ||
21 | name = "ansi_term" | ||
22 | version = "0.12.1" | ||
23 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
24 | checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" | ||
25 | dependencies = [ | ||
26 | "winapi", | ||
27 | ] | ||
28 | |||
29 | [[package]] | ||
30 | name = "anyhow" | ||
31 | version = "1.0.65" | ||
32 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
33 | checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602" | ||
34 | |||
35 | [[package]] | ||
36 | name = "autocfg" | ||
37 | version = "1.1.0" | ||
38 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
39 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" | ||
40 | |||
41 | [[package]] | ||
42 | name = "bitflags" | ||
43 | version = "1.3.2" | ||
44 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
45 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" | ||
46 | |||
47 | [[package]] | ||
48 | name = "bitvec" | ||
49 | version = "0.22.3" | ||
50 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
51 | checksum = "5237f00a8c86130a0cc317830e558b966dd7850d48a953d998c813f01a41b527" | ||
52 | dependencies = [ | ||
53 | "funty", | ||
54 | "radium", | ||
55 | "tap", | ||
56 | "wyz", | ||
57 | ] | ||
58 | |||
59 | [[package]] | ||
60 | name = "byteorder" | ||
61 | version = "1.4.3" | ||
62 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
63 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" | ||
64 | |||
65 | [[package]] | ||
66 | name = "cc" | ||
67 | version = "1.0.73" | ||
68 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
69 | checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" | ||
70 | |||
71 | [[package]] | ||
72 | name = "cfg-if" | ||
73 | version = "1.0.0" | ||
74 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
75 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" | ||
76 | |||
77 | [[package]] | ||
78 | name = "console" | ||
79 | version = "0.15.1" | ||
80 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
81 | checksum = "89eab4d20ce20cea182308bca13088fecea9c05f6776cf287205d41a0ed3c847" | ||
82 | dependencies = [ | ||
83 | "encode_unicode", | ||
84 | "libc", | ||
85 | "once_cell", | ||
86 | "terminal_size", | ||
87 | "unicode-width", | ||
88 | "winapi", | ||
89 | ] | ||
90 | |||
91 | [[package]] | ||
92 | name = "controlled-option" | ||
93 | version = "0.4.1" | ||
94 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
95 | checksum = "95abc95db25411571f40a8b0af30a3c386f3927fe6f1460c70e1f49f01bac3ac" | ||
96 | dependencies = [ | ||
97 | "controlled-option-macros", | ||
98 | ] | ||
99 | |||
100 | [[package]] | ||
101 | name = "controlled-option-macros" | ||
102 | version = "0.2.2" | ||
103 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
104 | checksum = "305024255a6c456333e130da2559b7aedd5c2e15388f51dae69f7507517cfbfb" | ||
105 | dependencies = [ | ||
106 | "proc-macro2", | ||
107 | "quote", | ||
108 | "syn", | ||
109 | ] | ||
110 | |||
111 | [[package]] | ||
112 | name = "dirs" | ||
113 | version = "3.0.2" | ||
114 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
115 | checksum = "30baa043103c9d0c2a57cf537cc2f35623889dc0d405e6c3cccfadbc81c71309" | ||
116 | dependencies = [ | ||
117 | "dirs-sys", | ||
118 | ] | ||
119 | |||
120 | [[package]] | ||
121 | name = "dirs-sys" | ||
122 | version = "0.3.7" | ||
123 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
124 | checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" | ||
125 | dependencies = [ | ||
126 | "libc", | ||
127 | "redox_users", | ||
128 | "winapi", | ||
129 | ] | ||
130 | |||
131 | [[package]] | ||
132 | name = "either" | ||
133 | version = "1.8.0" | ||
134 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
135 | checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" | ||
136 | |||
137 | [[package]] | ||
138 | name = "encode_unicode" | ||
139 | version = "0.3.6" | ||
140 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
141 | checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" | ||
142 | |||
143 | [[package]] | ||
144 | name = "filetime" | ||
145 | version = "0.2.17" | ||
146 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
147 | checksum = "e94a7bbaa59354bc20dd75b67f23e2797b4490e9d6928203fb105c79e448c86c" | ||
148 | dependencies = [ | ||
149 | "cfg-if", | ||
150 | "libc", | ||
151 | "redox_syscall", | ||
152 | "windows-sys", | ||
153 | ] | ||
154 | |||
155 | [[package]] | ||
156 | name = "funty" | ||
157 | version = "1.2.0" | ||
158 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
159 | checksum = "1847abb9cb65d566acd5942e94aea9c8f547ad02c98e1649326fc0e8910b8b1e" | ||
160 | |||
161 | [[package]] | ||
162 | name = "fxhash" | ||
163 | version = "0.2.1" | ||
164 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
165 | checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" | ||
166 | dependencies = [ | ||
167 | "byteorder", | ||
168 | ] | ||
169 | |||
170 | [[package]] | ||
171 | name = "getrandom" | ||
172 | version = "0.2.7" | ||
173 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
174 | checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" | ||
175 | dependencies = [ | ||
176 | "cfg-if", | ||
177 | "libc", | ||
178 | "wasi", | ||
179 | ] | ||
180 | |||
181 | [[package]] | ||
182 | name = "hashbrown" | ||
183 | version = "0.9.1" | ||
184 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
185 | checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" | ||
186 | dependencies = [ | ||
187 | "ahash", | ||
188 | ] | ||
189 | |||
190 | [[package]] | ||
191 | name = "hashbrown" | ||
192 | version = "0.12.3" | ||
193 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
194 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" | ||
195 | |||
196 | [[package]] | ||
197 | name = "indexmap" | ||
198 | version = "1.9.1" | ||
199 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
200 | checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" | ||
201 | dependencies = [ | ||
202 | "autocfg", | ||
203 | "hashbrown 0.12.3", | ||
204 | ] | ||
205 | |||
206 | [[package]] | ||
207 | name = "inotify" | ||
208 | version = "0.9.6" | ||
209 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
210 | checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" | ||
211 | dependencies = [ | ||
212 | "bitflags", | ||
213 | "inotify-sys", | ||
214 | "libc", | ||
215 | ] | ||
216 | |||
217 | [[package]] | ||
218 | name = "inotify-sys" | ||
219 | version = "0.1.5" | ||
220 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
221 | checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" | ||
222 | dependencies = [ | ||
223 | "libc", | ||
224 | ] | ||
225 | |||
226 | [[package]] | ||
227 | name = "itertools" | ||
228 | version = "0.10.4" | ||
229 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
230 | checksum = "d8bf247779e67a9082a4790b45e71ac7cfd1321331a5c856a74a9faebdab78d0" | ||
231 | dependencies = [ | ||
232 | "either", | ||
233 | ] | ||
234 | |||
235 | [[package]] | ||
236 | name = "itoa" | ||
237 | version = "1.0.3" | ||
238 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
239 | checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" | ||
240 | |||
241 | [[package]] | ||
242 | name = "kqueue" | ||
243 | version = "1.0.6" | ||
244 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
245 | checksum = "4d6112e8f37b59803ac47a42d14f1f3a59bbf72fc6857ffc5be455e28a691f8e" | ||
246 | dependencies = [ | ||
247 | "kqueue-sys", | ||
248 | "libc", | ||
249 | ] | ||
250 | |||
251 | [[package]] | ||
252 | name = "kqueue-sys" | ||
253 | version = "1.0.3" | ||
254 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
255 | checksum = "8367585489f01bc55dd27404dcf56b95e6da061a256a666ab23be9ba96a2e587" | ||
256 | dependencies = [ | ||
257 | "bitflags", | ||
258 | "libc", | ||
259 | ] | ||
260 | |||
261 | [[package]] | ||
262 | name = "lazy_static" | ||
263 | version = "1.4.0" | ||
264 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
265 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" | ||
266 | |||
267 | [[package]] | ||
268 | name = "libc" | ||
269 | version = "0.2.132" | ||
270 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
271 | checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" | ||
272 | |||
273 | [[package]] | ||
274 | name = "libloading" | ||
275 | version = "0.7.3" | ||
276 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
277 | checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" | ||
278 | dependencies = [ | ||
279 | "cfg-if", | ||
280 | "winapi", | ||
281 | ] | ||
282 | |||
283 | [[package]] | ||
284 | name = "log" | ||
285 | version = "0.4.17" | ||
286 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
287 | checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" | ||
288 | dependencies = [ | ||
289 | "cfg-if", | ||
290 | ] | ||
291 | |||
292 | [[package]] | ||
293 | name = "lsp-positions" | ||
294 | version = "0.3.1" | ||
295 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
296 | checksum = "6ce95baee2c4668ed42b67ae7f931abe06169fcef8e853815ffaf53b56ac7f0c" | ||
297 | dependencies = [ | ||
298 | "memchr", | ||
299 | "tree-sitter", | ||
300 | "unicode-segmentation", | ||
301 | ] | ||
302 | |||
303 | [[package]] | ||
304 | name = "memchr" | ||
305 | version = "2.5.0" | ||
306 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
307 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" | ||
308 | |||
309 | [[package]] | ||
310 | name = "mio" | ||
311 | version = "0.8.4" | ||
312 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
313 | checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" | ||
314 | dependencies = [ | ||
315 | "libc", | ||
316 | "log", | ||
317 | "wasi", | ||
318 | "windows-sys", | ||
319 | ] | ||
320 | |||
321 | [[package]] | ||
322 | name = "notify" | ||
323 | version = "5.0.0" | ||
324 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
325 | checksum = "ed2c66da08abae1c024c01d635253e402341b4060a12e99b31c7594063bf490a" | ||
326 | dependencies = [ | ||
327 | "bitflags", | ||
328 | "filetime", | ||
329 | "inotify", | ||
330 | "kqueue", | ||
331 | "libc", | ||
332 | "mio", | ||
333 | "walkdir", | ||
334 | "winapi", | ||
335 | ] | ||
336 | |||
337 | [[package]] | ||
338 | name = "once_cell" | ||
339 | version = "1.14.0" | ||
340 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
341 | checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0" | ||
342 | |||
343 | [[package]] | ||
344 | name = "proc-macro2" | ||
345 | version = "1.0.43" | ||
346 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
347 | checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" | ||
348 | dependencies = [ | ||
349 | "unicode-ident", | ||
350 | ] | ||
351 | |||
352 | [[package]] | ||
353 | name = "quote" | ||
354 | version = "1.0.21" | ||
355 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
356 | checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" | ||
357 | dependencies = [ | ||
358 | "proc-macro2", | ||
359 | ] | ||
360 | |||
361 | [[package]] | ||
362 | name = "radium" | ||
363 | version = "0.6.2" | ||
364 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
365 | checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" | ||
366 | |||
367 | [[package]] | ||
368 | name = "redox_syscall" | ||
369 | version = "0.2.16" | ||
370 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
371 | checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" | ||
372 | dependencies = [ | ||
373 | "bitflags", | ||
374 | ] | ||
375 | |||
376 | [[package]] | ||
377 | name = "redox_users" | ||
378 | version = "0.4.3" | ||
379 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
380 | checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" | ||
381 | dependencies = [ | ||
382 | "getrandom", | ||
383 | "redox_syscall", | ||
384 | "thiserror", | ||
385 | ] | ||
386 | |||
387 | [[package]] | ||
388 | name = "regex" | ||
389 | version = "1.6.0" | ||
390 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
391 | checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" | ||
392 | dependencies = [ | ||
393 | "aho-corasick", | ||
394 | "memchr", | ||
395 | "regex-syntax", | ||
396 | ] | ||
397 | |||
398 | [[package]] | ||
399 | name = "regex-syntax" | ||
400 | version = "0.6.27" | ||
401 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
402 | checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" | ||
403 | |||
404 | [[package]] | ||
405 | name = "ryu" | ||
406 | version = "1.0.11" | ||
407 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
408 | checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" | ||
409 | |||
410 | [[package]] | ||
411 | name = "same-file" | ||
412 | version = "1.0.6" | ||
413 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
414 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" | ||
415 | dependencies = [ | ||
416 | "winapi-util", | ||
417 | ] | ||
418 | |||
419 | [[package]] | ||
420 | name = "scope-viz" | ||
421 | version = "0.1.0" | ||
422 | dependencies = [ | ||
423 | "stack-graphs", | ||
424 | "tree-sitter", | ||
425 | "tree-sitter-elm", | ||
426 | "tree-sitter-graph", | ||
427 | "tree-sitter-rust", | ||
428 | "tree-sitter-stack-graphs", | ||
429 | ] | ||
430 | |||
431 | [[package]] | ||
432 | name = "serde" | ||
433 | version = "1.0.144" | ||
434 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
435 | checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860" | ||
436 | dependencies = [ | ||
437 | "serde_derive", | ||
438 | ] | ||
439 | |||
440 | [[package]] | ||
441 | name = "serde_derive" | ||
442 | version = "1.0.144" | ||
443 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
444 | checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00" | ||
445 | dependencies = [ | ||
446 | "proc-macro2", | ||
447 | "quote", | ||
448 | "syn", | ||
449 | ] | ||
450 | |||
451 | [[package]] | ||
452 | name = "serde_json" | ||
453 | version = "1.0.85" | ||
454 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
455 | checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" | ||
456 | dependencies = [ | ||
457 | "indexmap", | ||
458 | "itoa", | ||
459 | "ryu", | ||
460 | "serde", | ||
461 | ] | ||
462 | |||
463 | [[package]] | ||
464 | name = "smallvec" | ||
465 | version = "1.9.0" | ||
466 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
467 | checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" | ||
468 | |||
469 | [[package]] | ||
470 | name = "stack-graphs" | ||
471 | version = "0.10.1" | ||
472 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
473 | checksum = "9c4fdc37ccc4f64bea4bc3ffa3f94be605342e7e8b9b928e203bbd4bfd313949" | ||
474 | dependencies = [ | ||
475 | "bitvec", | ||
476 | "controlled-option", | ||
477 | "either", | ||
478 | "fxhash", | ||
479 | "itertools", | ||
480 | "libc", | ||
481 | "lsp-positions", | ||
482 | "serde", | ||
483 | "serde_json", | ||
484 | "smallvec", | ||
485 | "thiserror", | ||
486 | ] | ||
487 | |||
488 | [[package]] | ||
489 | name = "string-interner" | ||
490 | version = "0.12.2" | ||
491 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
492 | checksum = "383196d1876517ee6f9f0864d1fc1070331b803335d3c6daaa04bbcccd823c08" | ||
493 | dependencies = [ | ||
494 | "cfg-if", | ||
495 | "hashbrown 0.9.1", | ||
496 | ] | ||
497 | |||
498 | [[package]] | ||
499 | name = "syn" | ||
500 | version = "1.0.100" | ||
501 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
502 | checksum = "52205623b1b0f064a4e71182c3b18ae902267282930c6d5462c91b859668426e" | ||
503 | dependencies = [ | ||
504 | "proc-macro2", | ||
505 | "quote", | ||
506 | "unicode-ident", | ||
507 | ] | ||
508 | |||
509 | [[package]] | ||
510 | name = "tap" | ||
511 | version = "1.0.1" | ||
512 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
513 | checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" | ||
514 | |||
515 | [[package]] | ||
516 | name = "terminal_size" | ||
517 | version = "0.1.17" | ||
518 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
519 | checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" | ||
520 | dependencies = [ | ||
521 | "libc", | ||
522 | "winapi", | ||
523 | ] | ||
524 | |||
525 | [[package]] | ||
526 | name = "thiserror" | ||
527 | version = "1.0.35" | ||
528 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
529 | checksum = "c53f98874615aea268107765aa1ed8f6116782501d18e53d08b471733bea6c85" | ||
530 | dependencies = [ | ||
531 | "thiserror-impl", | ||
532 | ] | ||
533 | |||
534 | [[package]] | ||
535 | name = "thiserror-impl" | ||
536 | version = "1.0.35" | ||
537 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
538 | checksum = "f8b463991b4eab2d801e724172285ec4195c650e8ec79b149e6c2a8e6dd3f783" | ||
539 | dependencies = [ | ||
540 | "proc-macro2", | ||
541 | "quote", | ||
542 | "syn", | ||
543 | ] | ||
544 | |||
545 | [[package]] | ||
546 | name = "tree-sitter" | ||
547 | version = "0.20.9" | ||
548 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
549 | checksum = "d4423c784fe11398ca91e505cdc71356b07b1a924fc8735cfab5333afe3e18bc" | ||
550 | dependencies = [ | ||
551 | "cc", | ||
552 | "regex", | ||
553 | ] | ||
554 | |||
555 | [[package]] | ||
556 | name = "tree-sitter-elm" | ||
557 | version = "5.6.3" | ||
558 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
559 | checksum = "22b9408ad250aa27774132baf20c4f107faad16841aa45568c6900a27895093b" | ||
560 | dependencies = [ | ||
561 | "cc", | ||
562 | "tree-sitter", | ||
563 | ] | ||
564 | |||
565 | [[package]] | ||
566 | name = "tree-sitter-go" | ||
567 | version = "0.19.1" | ||
568 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
569 | checksum = "71967701c8214be4aa77e0260e98361e6fd71ceec1d9d03abb37a22c9f60d0ff" | ||
570 | dependencies = [ | ||
571 | "cc", | ||
572 | "tree-sitter", | ||
573 | ] | ||
574 | |||
575 | [[package]] | ||
576 | name = "tree-sitter-graph" | ||
577 | version = "0.6.1" | ||
578 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
579 | checksum = "18a4875525d5bbb4a27716eac5469f91370b2acb985c6a984c359abb19732e02" | ||
580 | dependencies = [ | ||
581 | "ansi_term", | ||
582 | "log", | ||
583 | "regex", | ||
584 | "serde", | ||
585 | "serde_json", | ||
586 | "smallvec", | ||
587 | "string-interner", | ||
588 | "thiserror", | ||
589 | "tree-sitter", | ||
590 | ] | ||
591 | |||
592 | [[package]] | ||
593 | name = "tree-sitter-highlight" | ||
594 | version = "0.20.1" | ||
595 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
596 | checksum = "042342584c5a7a0b833d9fc4e2bdab3f9868ddc6c4b339a1e01451c6720868bc" | ||
597 | dependencies = [ | ||
598 | "regex", | ||
599 | "thiserror", | ||
600 | "tree-sitter", | ||
601 | ] | ||
602 | |||
603 | [[package]] | ||
604 | name = "tree-sitter-loader" | ||
605 | version = "0.20.0" | ||
606 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
607 | checksum = "d0b17eef4833c7c139abed66d562dfa23228e97e647597baf246fd56c21bbfaf" | ||
608 | dependencies = [ | ||
609 | "anyhow", | ||
610 | "cc", | ||
611 | "dirs", | ||
612 | "libloading", | ||
613 | "once_cell", | ||
614 | "regex", | ||
615 | "serde", | ||
616 | "serde_json", | ||
617 | "tree-sitter", | ||
618 | "tree-sitter-highlight", | ||
619 | "tree-sitter-tags", | ||
620 | ] | ||
621 | |||
622 | [[package]] | ||
623 | name = "tree-sitter-rust" | ||
624 | version = "0.20.1" | ||
625 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
626 | checksum = "13470fafb7327a3acf96f5bc1013b5539a899a182f01c59b5af53f6b93195717" | ||
627 | dependencies = [ | ||
628 | "cc", | ||
629 | "tree-sitter", | ||
630 | ] | ||
631 | |||
632 | [[package]] | ||
633 | name = "tree-sitter-stack-graphs" | ||
634 | version = "0.3.1" | ||
635 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
636 | checksum = "510004b313ced434bf04faa5d8e6e12e7cd80bb34231c6b132b0284966244f25" | ||
637 | dependencies = [ | ||
638 | "anyhow", | ||
639 | "controlled-option", | ||
640 | "itertools", | ||
641 | "lazy_static", | ||
642 | "log", | ||
643 | "lsp-positions", | ||
644 | "regex", | ||
645 | "stack-graphs", | ||
646 | "thiserror", | ||
647 | "tree-sitter", | ||
648 | "tree-sitter-graph", | ||
649 | "tree-sitter-loader", | ||
650 | ] | ||
651 | |||
652 | [[package]] | ||
653 | name = "tree-sitter-tags" | ||
654 | version = "0.20.2" | ||
655 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
656 | checksum = "ccb3f1376219530a37a809751ecf65aa35fd8b9c1c4ab6d4faf5f6a9eeda2c05" | ||
657 | dependencies = [ | ||
658 | "memchr", | ||
659 | "regex", | ||
660 | "thiserror", | ||
661 | "tree-sitter", | ||
662 | ] | ||
663 | |||
664 | [[package]] | ||
665 | name = "tree-sitter-typescript" | ||
666 | version = "0.20.1" | ||
667 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
668 | checksum = "4e8ed0ecb931cdff13c6a13f45ccd615156e2779d9ffb0395864e05505e6e86d" | ||
669 | dependencies = [ | ||
670 | "cc", | ||
671 | "tree-sitter", | ||
672 | ] | ||
673 | |||
674 | [[package]] | ||
675 | name = "tree-viz" | ||
676 | version = "0.1.0" | ||
677 | dependencies = [ | ||
678 | "console", | ||
679 | "notify", | ||
680 | "once_cell", | ||
681 | "tree-sitter", | ||
682 | "tree-sitter-elm", | ||
683 | "tree-sitter-go", | ||
684 | "tree-sitter-rust", | ||
685 | "tree-sitter-typescript", | ||
686 | ] | ||
687 | |||
688 | [[package]] | ||
689 | name = "unicode-ident" | ||
690 | version = "1.0.4" | ||
691 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
692 | checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd" | ||
693 | |||
694 | [[package]] | ||
695 | name = "unicode-segmentation" | ||
696 | version = "1.10.0" | ||
697 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
698 | checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a" | ||
699 | |||
700 | [[package]] | ||
701 | name = "unicode-width" | ||
702 | version = "0.1.10" | ||
703 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
704 | checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" | ||
705 | |||
706 | [[package]] | ||
707 | name = "walkdir" | ||
708 | version = "2.3.2" | ||
709 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
710 | checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" | ||
711 | dependencies = [ | ||
712 | "same-file", | ||
713 | "winapi", | ||
714 | "winapi-util", | ||
715 | ] | ||
716 | |||
717 | [[package]] | ||
718 | name = "wasi" | ||
719 | version = "0.11.0+wasi-snapshot-preview1" | ||
720 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
721 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" | ||
722 | |||
723 | [[package]] | ||
724 | name = "winapi" | ||
725 | version = "0.3.9" | ||
726 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
727 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" | ||
728 | dependencies = [ | ||
729 | "winapi-i686-pc-windows-gnu", | ||
730 | "winapi-x86_64-pc-windows-gnu", | ||
731 | ] | ||
732 | |||
733 | [[package]] | ||
734 | name = "winapi-i686-pc-windows-gnu" | ||
735 | version = "0.4.0" | ||
736 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
737 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" | ||
738 | |||
739 | [[package]] | ||
740 | name = "winapi-util" | ||
741 | version = "0.1.5" | ||
742 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
743 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" | ||
744 | dependencies = [ | ||
745 | "winapi", | ||
746 | ] | ||
747 | |||
748 | [[package]] | ||
749 | name = "winapi-x86_64-pc-windows-gnu" | ||
750 | version = "0.4.0" | ||
751 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
752 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" | ||
753 | |||
754 | [[package]] | ||
755 | name = "windows-sys" | ||
756 | version = "0.36.1" | ||
757 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
758 | checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" | ||
759 | dependencies = [ | ||
760 | "windows_aarch64_msvc", | ||
761 | "windows_i686_gnu", | ||
762 | "windows_i686_msvc", | ||
763 | "windows_x86_64_gnu", | ||
764 | "windows_x86_64_msvc", | ||
765 | ] | ||
766 | |||
767 | [[package]] | ||
768 | name = "windows_aarch64_msvc" | ||
769 | version = "0.36.1" | ||
770 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
771 | checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" | ||
772 | |||
773 | [[package]] | ||
774 | name = "windows_i686_gnu" | ||
775 | version = "0.36.1" | ||
776 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
777 | checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" | ||
778 | |||
779 | [[package]] | ||
780 | name = "windows_i686_msvc" | ||
781 | version = "0.36.1" | ||
782 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
783 | checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" | ||
784 | |||
785 | [[package]] | ||
786 | name = "windows_x86_64_gnu" | ||
787 | version = "0.36.1" | ||
788 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
789 | checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" | ||
790 | |||
791 | [[package]] | ||
792 | name = "windows_x86_64_msvc" | ||
793 | version = "0.36.1" | ||
794 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
795 | checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" | ||
796 | |||
797 | [[package]] | ||
798 | name = "wyz" | ||
799 | version = "0.4.0" | ||
800 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
801 | checksum = "129e027ad65ce1453680623c3fb5163cbf7107bfe1aa32257e7d0e63f9ced188" | ||
802 | dependencies = [ | ||
803 | "tap", | ||
804 | ] | ||
diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..b7d2e20 --- /dev/null +++ b/Cargo.toml | |||
@@ -0,0 +1,6 @@ | |||
1 | [workspace] | ||
2 | |||
3 | members = [ | ||
4 | "scope-viz", | ||
5 | "tree-viz" | ||
6 | ] | ||
diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..a7c083f --- /dev/null +++ b/flake.lock | |||
@@ -0,0 +1,87 @@ | |||
1 | { | ||
2 | "nodes": { | ||
3 | "fenix": { | ||
4 | "inputs": { | ||
5 | "nixpkgs": [ | ||
6 | "nixpkgs" | ||
7 | ], | ||
8 | "rust-analyzer-src": "rust-analyzer-src" | ||
9 | }, | ||
10 | "locked": { | ||
11 | "lastModified": 1645251813, | ||
12 | "narHash": "sha256-cQ66tGjnZclBCS3nD26mZ5fUH+3/HnysGffBiWXUSHk=", | ||
13 | "owner": "nix-community", | ||
14 | "repo": "fenix", | ||
15 | "rev": "9892337b588c38ec59466a1c89befce464aae7f8", | ||
16 | "type": "github" | ||
17 | }, | ||
18 | "original": { | ||
19 | "owner": "nix-community", | ||
20 | "repo": "fenix", | ||
21 | "type": "github" | ||
22 | } | ||
23 | }, | ||
24 | "gitignore": { | ||
25 | "inputs": { | ||
26 | "nixpkgs": [ | ||
27 | "nixpkgs" | ||
28 | ] | ||
29 | }, | ||
30 | "locked": { | ||
31 | "lastModified": 1635165013, | ||
32 | "narHash": "sha256-o/BdVjNwcB6jOmzZjOH703BesSkkS5O7ej3xhyO8hAY=", | ||
33 | "owner": "hercules-ci", | ||
34 | "repo": "gitignore.nix", | ||
35 | "rev": "5b9e0ff9d3b551234b4f3eb3983744fa354b17f1", | ||
36 | "type": "github" | ||
37 | }, | ||
38 | "original": { | ||
39 | "owner": "hercules-ci", | ||
40 | "repo": "gitignore.nix", | ||
41 | "type": "github" | ||
42 | } | ||
43 | }, | ||
44 | "nixpkgs": { | ||
45 | "locked": { | ||
46 | "lastModified": 1645013224, | ||
47 | "narHash": "sha256-b7OEC8vwzJv3rsz9pwnTX2LQDkeOWz2DbKypkVvNHXc=", | ||
48 | "owner": "nixos", | ||
49 | "repo": "nixpkgs", | ||
50 | "rev": "b66b39216b1fef2d8c33cc7a5c72d8da80b79970", | ||
51 | "type": "github" | ||
52 | }, | ||
53 | "original": { | ||
54 | "owner": "nixos", | ||
55 | "ref": "nixpkgs-unstable", | ||
56 | "repo": "nixpkgs", | ||
57 | "type": "github" | ||
58 | } | ||
59 | }, | ||
60 | "root": { | ||
61 | "inputs": { | ||
62 | "fenix": "fenix", | ||
63 | "gitignore": "gitignore", | ||
64 | "nixpkgs": "nixpkgs" | ||
65 | } | ||
66 | }, | ||
67 | "rust-analyzer-src": { | ||
68 | "flake": false, | ||
69 | "locked": { | ||
70 | "lastModified": 1645205556, | ||
71 | "narHash": "sha256-e4lZW3qRyOEJ+vLKFQP7m2Dxh5P44NrnekZYLxlucww=", | ||
72 | "owner": "rust-analyzer", | ||
73 | "repo": "rust-analyzer", | ||
74 | "rev": "acf5874b39f3dc5262317a6074d9fc7285081161", | ||
75 | "type": "github" | ||
76 | }, | ||
77 | "original": { | ||
78 | "owner": "rust-analyzer", | ||
79 | "ref": "nightly", | ||
80 | "repo": "rust-analyzer", | ||
81 | "type": "github" | ||
82 | } | ||
83 | } | ||
84 | }, | ||
85 | "root": "root", | ||
86 | "version": 7 | ||
87 | } | ||
diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..861792b --- /dev/null +++ b/flake.nix | |||
@@ -0,0 +1,68 @@ | |||
1 | { | ||
2 | inputs = { | ||
3 | |||
4 | nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; | ||
5 | |||
6 | fenix = { | ||
7 | url = "github:nix-community/fenix"; | ||
8 | inputs.nixpkgs.follows = "nixpkgs"; | ||
9 | }; | ||
10 | |||
11 | gitignore = { | ||
12 | url = "github:hercules-ci/gitignore.nix"; | ||
13 | inputs.nixpkgs.follows = "nixpkgs"; | ||
14 | }; | ||
15 | |||
16 | }; | ||
17 | |||
18 | outputs = | ||
19 | { self | ||
20 | , nixpkgs | ||
21 | , fenix | ||
22 | , gitignore | ||
23 | }: | ||
24 | let | ||
25 | inherit (gitignore.lib) gitignoreSource; | ||
26 | |||
27 | supportedSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ]; | ||
28 | forAllSystems = nixpkgs.lib.genAttrs supportedSystems; | ||
29 | nixpkgsFor = forAllSystems (system: | ||
30 | import nixpkgs { inherit system; }); | ||
31 | |||
32 | chanspec = { | ||
33 | date = "2022-09-01"; | ||
34 | channel = "nightly"; | ||
35 | sha256 = "tS2IHsewoaEMHn9x8DfcEJefShcW85iDrfBWXOZJa9c="; # set zeros after modifying channel or date | ||
36 | }; | ||
37 | rustChannel = p: (fenix.overlay p p).fenix.toolchainOf chanspec; | ||
38 | |||
39 | in | ||
40 | { | ||
41 | |||
42 | |||
43 | devShell = forAllSystems (system: | ||
44 | let | ||
45 | pkgs = nixpkgsFor."${system}"; | ||
46 | toolchain = (rustChannel pkgs).withComponents [ | ||
47 | "rustc" | ||
48 | "cargo" | ||
49 | "rust-std" | ||
50 | "rustfmt" | ||
51 | "clippy" | ||
52 | "rust-src" | ||
53 | ]; | ||
54 | inherit (fenix.packages."${system}") rust-analyzer; | ||
55 | in | ||
56 | pkgs.mkShell { | ||
57 | nativeBuildInputs = [ | ||
58 | pkgs.cargo-watch | ||
59 | pkgs.bacon | ||
60 | pkgs.cargo-insta | ||
61 | rust-analyzer | ||
62 | toolchain | ||
63 | ]; | ||
64 | RUST_LOG = "info"; | ||
65 | RUST_BACKTRACE = 1; | ||
66 | }); | ||
67 | }; | ||
68 | } | ||
diff --git a/tree-viz/.gitignore b/tree-viz/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/tree-viz/.gitignore | |||
@@ -0,0 +1 @@ | |||
/target | |||
diff --git a/tree-viz/Cargo.toml b/tree-viz/Cargo.toml new file mode 100644 index 0000000..04107d3 --- /dev/null +++ b/tree-viz/Cargo.toml | |||
@@ -0,0 +1,19 @@ | |||
1 | [package] | ||
2 | name = "tree-viz" | ||
3 | version = "0.1.0" | ||
4 | edition = "2021" | ||
5 | |||
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
7 | |||
8 | [dependencies] | ||
9 | tree-sitter-elm = "5.6.3" | ||
10 | tree-sitter-rust = "0.20.1" | ||
11 | tree-sitter = "^0.20.8" | ||
12 | console = "^0.15" | ||
13 | once_cell = "1.14.0" | ||
14 | tree-sitter-go = "0.19.1" | ||
15 | tree-sitter-typescript = "0.20.1" | ||
16 | |||
17 | [dependencies.notify] | ||
18 | version = "5.0.0" | ||
19 | default-features = false | ||
diff --git a/tree-viz/src/app.rs b/tree-viz/src/app.rs new file mode 100644 index 0000000..68d3641 --- /dev/null +++ b/tree-viz/src/app.rs | |||
@@ -0,0 +1,230 @@ | |||
1 | use crate::{config::Config, LANGUAGE}; | ||
2 | |||
3 | use std::{ | ||
4 | collections::HashMap, | ||
5 | fmt::Write, | ||
6 | path::{Path, PathBuf}, | ||
7 | }; | ||
8 | |||
9 | use console::{style, Style, Term}; | ||
10 | use tree_sitter::{Node, Parser, Query, QueryCursor, Range, Tree}; | ||
11 | |||
12 | pub struct App { | ||
13 | config: Config, | ||
14 | path: PathBuf, | ||
15 | query: Option<Query>, | ||
16 | query_path: Option<PathBuf>, | ||
17 | src: Vec<u8>, | ||
18 | tree: Tree, | ||
19 | } | ||
20 | |||
21 | impl App { | ||
22 | pub fn new<'a, P: AsRef<Path>>(src: &'a [u8], path: P, query_path: Option<P>) -> Self { | ||
23 | let path = path.as_ref().to_owned(); | ||
24 | |||
25 | let mut parser = Parser::new(); | ||
26 | parser.set_language(*LANGUAGE).unwrap(); | ||
27 | |||
28 | let tree = parser.parse(&src, None).unwrap(); | ||
29 | let query_path = query_path.map(|q| q.as_ref().to_owned()); | ||
30 | let query = query_path.as_ref().map(|p| { | ||
31 | let query_src = std::fs::read_to_string(&p).expect("unable to read query"); | ||
32 | Query::new(*LANGUAGE, &query_src).expect("query parse error") | ||
33 | }); | ||
34 | |||
35 | Self { | ||
36 | config: Default::default(), | ||
37 | path, | ||
38 | query, | ||
39 | query_path, | ||
40 | src: src.to_owned(), | ||
41 | tree, | ||
42 | } | ||
43 | } | ||
44 | |||
45 | pub fn draw(&self) { | ||
46 | let term = Term::stdout(); | ||
47 | term.clear_screen().unwrap(); | ||
48 | let mut done = false; | ||
49 | let mut depth = 0; | ||
50 | let mut in_capture: Option<Range> = None; | ||
51 | let mut cursor = self.tree.walk(); | ||
52 | |||
53 | let capture_names = self | ||
54 | .query | ||
55 | .as_ref() | ||
56 | .map(|q| q.capture_names()) | ||
57 | .unwrap_or_default(); | ||
58 | let capture_map = self | ||
59 | .query | ||
60 | .as_ref() | ||
61 | .map(|query| { | ||
62 | QueryCursor::new() | ||
63 | .matches(&query, self.tree.root_node(), self.src.as_slice()) | ||
64 | .flat_map(|match_| match_.captures) | ||
65 | .fold( | ||
66 | HashMap::new(), | ||
67 | |mut map: HashMap<Node, Vec<u32>>, capture| { | ||
68 | map.entry(capture.node) | ||
69 | .and_modify(|idxs| idxs.push(capture.index)) | ||
70 | .or_insert_with(|| vec![capture.index]); | ||
71 | map | ||
72 | }, | ||
73 | ) | ||
74 | }) | ||
75 | .unwrap_or_default(); | ||
76 | |||
77 | while !done { | ||
78 | let node = cursor.node(); | ||
79 | let mut tree_string = String::new(); | ||
80 | in_capture = match in_capture { | ||
81 | Some(range) | ||
82 | if !contains(&range, &node.range()) && capture_map.contains_key(&node) => | ||
83 | { | ||
84 | Some(node.range()) | ||
85 | } | ||
86 | Some(range) if !contains(&range, &node.range()) => None, | ||
87 | None if capture_map.contains_key(&node) => Some(node.range()), | ||
88 | i => i, | ||
89 | }; | ||
90 | |||
91 | write!( | ||
92 | tree_string, | ||
93 | "{}", | ||
94 | (if in_capture.is_some() { | ||
95 | Style::new().on_yellow().on_bright() | ||
96 | } else { | ||
97 | Style::new() | ||
98 | }) | ||
99 | .bright() | ||
100 | .black() | ||
101 | .apply_to( | ||
102 | format!("{}{}", "|", " ".repeat(self.config.indent_level)) | ||
103 | .repeat(depth as usize) | ||
104 | ) | ||
105 | ) | ||
106 | .unwrap(); | ||
107 | |||
108 | write!( | ||
109 | tree_string, | ||
110 | "{} ", | ||
111 | if node.is_error() { | ||
112 | Style::new().red() | ||
113 | } else if in_capture.is_some() { | ||
114 | Style::new().on_yellow().on_bright() | ||
115 | } else { | ||
116 | Style::new() | ||
117 | } | ||
118 | .apply_to(node.kind()), | ||
119 | ) | ||
120 | .unwrap(); | ||
121 | |||
122 | if let Some(idxs) = capture_map.get(&node) { | ||
123 | for index in idxs { | ||
124 | write!( | ||
125 | tree_string, | ||
126 | "@{} ", | ||
127 | style(capture_names[*index as usize].as_str()).magenta() | ||
128 | ) | ||
129 | .unwrap(); | ||
130 | } | ||
131 | } | ||
132 | |||
133 | if self.config.show_ranges { | ||
134 | let range = node.range(); | ||
135 | write!( | ||
136 | tree_string, | ||
137 | " {}", | ||
138 | style(format!("{:?}..{:?}", range.start_byte, range.end_byte,)) | ||
139 | .bright() | ||
140 | .black() | ||
141 | ) | ||
142 | .unwrap(); | ||
143 | } | ||
144 | |||
145 | if self.config.show_src { | ||
146 | write!( | ||
147 | tree_string, | ||
148 | " {:.?}", | ||
149 | style(node.utf8_text(&self.src).unwrap()).cyan() | ||
150 | ) | ||
151 | .unwrap(); | ||
152 | } | ||
153 | |||
154 | term.write_line(&tree_string).unwrap(); | ||
155 | term.clear_to_end_of_screen().unwrap(); | ||
156 | |||
157 | if cursor.goto_first_child() { | ||
158 | depth += 1; | ||
159 | continue; | ||
160 | } | ||
161 | if cursor.goto_next_sibling() { | ||
162 | continue; | ||
163 | } | ||
164 | |||
165 | loop { | ||
166 | if !cursor.goto_parent() { | ||
167 | done = true; | ||
168 | break; | ||
169 | } else { | ||
170 | depth -= 1; | ||
171 | } | ||
172 | |||
173 | if cursor.goto_next_sibling() { | ||
174 | break; | ||
175 | } | ||
176 | } | ||
177 | } | ||
178 | |||
179 | // see https://github.com/console-rs/console/issues/36#issuecomment-624731432 | ||
180 | // for the reasoning behing this hackjob | ||
181 | |||
182 | term.write_line("\n(>) increase indent").unwrap(); | ||
183 | term.clear_to_end_of_screen().unwrap(); | ||
184 | |||
185 | term.write_line("(<) decrease indent ").unwrap(); | ||
186 | term.clear_to_end_of_screen().unwrap(); | ||
187 | |||
188 | term.write_line("(n) toggle ranges").unwrap(); | ||
189 | term.clear_to_end_of_screen().unwrap(); | ||
190 | |||
191 | term.write_line("(s) toggle source text").unwrap(); | ||
192 | term.clear_to_end_of_screen().unwrap(); | ||
193 | |||
194 | term.write_line("(r) reload from disk").unwrap(); | ||
195 | term.clear_to_end_of_screen().unwrap(); | ||
196 | |||
197 | term.write_line("(C-c) quit").unwrap(); | ||
198 | term.clear_to_end_of_screen().unwrap(); | ||
199 | } | ||
200 | |||
201 | pub fn increase_indent(&mut self) { | ||
202 | self.config.indent_level = self.config.indent_level.saturating_add(1); | ||
203 | } | ||
204 | |||
205 | pub fn decrease_indent(&mut self) { | ||
206 | self.config.indent_level = self.config.indent_level.saturating_sub(1); | ||
207 | } | ||
208 | |||
209 | pub fn toggle_ranges(&mut self) { | ||
210 | self.config.show_ranges = !self.config.show_ranges; | ||
211 | } | ||
212 | |||
213 | pub fn toggle_source(&mut self) { | ||
214 | self.config.show_src = !self.config.show_src; | ||
215 | } | ||
216 | |||
217 | pub fn reload(&mut self) { | ||
218 | let src = std::fs::read_to_string(&self.path).unwrap(); | ||
219 | let new = Self::new(src.as_bytes(), &self.path, self.query_path.as_ref()); | ||
220 | *self = Self { | ||
221 | config: self.config, | ||
222 | ..new | ||
223 | }; | ||
224 | } | ||
225 | } | ||
226 | |||
227 | // does a encompass b | ||
228 | fn contains(a: &Range, b: &Range) -> bool { | ||
229 | a.start_byte <= b.start_byte && a.end_byte >= b.end_byte | ||
230 | } | ||
diff --git a/tree-viz/src/config.rs b/tree-viz/src/config.rs new file mode 100644 index 0000000..6f34291 --- /dev/null +++ b/tree-viz/src/config.rs | |||
@@ -0,0 +1,24 @@ | |||
1 | use std::default::Default; | ||
2 | |||
3 | #[derive(Clone, Copy)] | ||
4 | pub struct Config { | ||
5 | pub indent_level: usize, | ||
6 | pub show_ranges: bool, | ||
7 | pub show_src: bool, | ||
8 | } | ||
9 | |||
10 | impl Default for Config { | ||
11 | fn default() -> Self { | ||
12 | Config::new() | ||
13 | } | ||
14 | } | ||
15 | |||
16 | impl Config { | ||
17 | fn new() -> Self { | ||
18 | Self { | ||
19 | indent_level: 2, | ||
20 | show_ranges: true, | ||
21 | show_src: true, | ||
22 | } | ||
23 | } | ||
24 | } | ||
diff --git a/tree-viz/src/main.rs b/tree-viz/src/main.rs new file mode 100644 index 0000000..79964cb --- /dev/null +++ b/tree-viz/src/main.rs | |||
@@ -0,0 +1,96 @@ | |||
1 | mod app; | ||
2 | mod config; | ||
3 | |||
4 | use std::{ | ||
5 | env, fs, | ||
6 | path::Path, | ||
7 | sync::{mpsc, Arc, RwLock}, | ||
8 | thread, | ||
9 | time::Duration, | ||
10 | }; | ||
11 | |||
12 | use app::App; | ||
13 | use console::{Key, Term}; | ||
14 | use notify::{Event as WatchEvent, EventKind as WatchEventKind, RecursiveMode, Watcher}; | ||
15 | use once_cell::sync::Lazy; | ||
16 | use tree_sitter::Language; | ||
17 | |||
18 | //pub static LANGUAGE: Lazy<Language> = Lazy::new(tree_sitter_rust::language); | ||
19 | pub static LANGUAGE: Lazy<Language> = Lazy::new(tree_sitter_typescript::language_typescript); | ||
20 | |||
21 | fn main() { | ||
22 | let mut args = env::args(); | ||
23 | let _ = args.next(); | ||
24 | |||
25 | let path = args.next().expect("no arg passed"); | ||
26 | let query_path = args.next(); | ||
27 | let src = fs::read_to_string(&path).expect("unable to read file"); | ||
28 | |||
29 | let app = Arc::new(RwLock::new(App::new( | ||
30 | src.as_bytes(), | ||
31 | &path, | ||
32 | query_path.as_ref(), | ||
33 | ))); | ||
34 | |||
35 | let watch_fn = |watcher_app: Arc<RwLock<App>>| { | ||
36 | move |ev| { | ||
37 | if let Ok(WatchEvent { | ||
38 | kind: WatchEventKind::Modify(..), | ||
39 | .. | ||
40 | }) = ev | ||
41 | { | ||
42 | if let Ok(mut locked) = watcher_app.try_write() { | ||
43 | locked.reload(); | ||
44 | locked.draw(); | ||
45 | }; | ||
46 | } | ||
47 | } | ||
48 | }; | ||
49 | |||
50 | let mut watcher1 = notify::recommended_watcher(watch_fn(Arc::clone(&app))).unwrap(); | ||
51 | watcher1 | ||
52 | .watch(Path::new(&path), RecursiveMode::NonRecursive) | ||
53 | .unwrap(); | ||
54 | |||
55 | let mut watcher2 = notify::recommended_watcher(watch_fn(Arc::clone(&app))).unwrap(); | ||
56 | if let Some(query_path) = query_path { | ||
57 | watcher2 | ||
58 | .watch(Path::new(&query_path), RecursiveMode::NonRecursive) | ||
59 | .unwrap(); | ||
60 | } | ||
61 | |||
62 | let (tx, rx) = mpsc::channel(); | ||
63 | let tx0 = tx.clone(); | ||
64 | thread::spawn(move || { | ||
65 | let term = Term::stdout(); | ||
66 | loop { | ||
67 | if let Ok(Key::Char(ev)) = term.read_key() { | ||
68 | tx0.send(ev).unwrap(); | ||
69 | } | ||
70 | } | ||
71 | }); | ||
72 | |||
73 | if let Ok(locked) = app.try_read() { | ||
74 | locked.draw(); | ||
75 | } | ||
76 | |||
77 | loop { | ||
78 | match rx.try_recv() { | ||
79 | Ok(ev) => { | ||
80 | if let Ok(mut locked) = app.try_write() { | ||
81 | match ev { | ||
82 | '>' => locked.increase_indent(), | ||
83 | '<' => locked.decrease_indent(), | ||
84 | 'n' => locked.toggle_ranges(), | ||
85 | 's' => locked.toggle_source(), | ||
86 | 'r' => locked.reload(), | ||
87 | _ => (), | ||
88 | } | ||
89 | locked.draw(); | ||
90 | } | ||
91 | } | ||
92 | _ => (), | ||
93 | } | ||
94 | thread::sleep(Duration::from_millis(10)); | ||
95 | } | ||
96 | } | ||