visualize tree-sitter trees and queries

init

oppi.li 80ac5c56

+1
.gitignore
··· 1 + /target
+573
Cargo.lock
··· 1 + # This file is automatically @generated by Cargo. 2 + # It is not intended for manual editing. 3 + version = 3 4 + 5 + [[package]] 6 + name = "aho-corasick" 7 + version = "1.1.3" 8 + source = "registry+https://github.com/rust-lang/crates.io-index" 9 + checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 10 + dependencies = [ 11 + "memchr", 12 + ] 13 + 14 + [[package]] 15 + name = "bitflags" 16 + version = "1.3.2" 17 + source = "registry+https://github.com/rust-lang/crates.io-index" 18 + checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 19 + 20 + [[package]] 21 + name = "cc" 22 + version = "1.0.106" 23 + source = "registry+https://github.com/rust-lang/crates.io-index" 24 + checksum = "066fce287b1d4eafef758e89e09d724a24808a9196fe9756b8ca90e86d0719a2" 25 + 26 + [[package]] 27 + name = "cfg-if" 28 + version = "1.0.0" 29 + source = "registry+https://github.com/rust-lang/crates.io-index" 30 + checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 31 + 32 + [[package]] 33 + name = "console" 34 + version = "0.15.8" 35 + source = "registry+https://github.com/rust-lang/crates.io-index" 36 + checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" 37 + dependencies = [ 38 + "encode_unicode", 39 + "lazy_static", 40 + "libc", 41 + "unicode-width", 42 + "windows-sys 0.52.0", 43 + ] 44 + 45 + [[package]] 46 + name = "encode_unicode" 47 + version = "0.3.6" 48 + source = "registry+https://github.com/rust-lang/crates.io-index" 49 + checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" 50 + 51 + [[package]] 52 + name = "filetime" 53 + version = "0.2.23" 54 + source = "registry+https://github.com/rust-lang/crates.io-index" 55 + checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" 56 + dependencies = [ 57 + "cfg-if", 58 + "libc", 59 + "redox_syscall", 60 + "windows-sys 0.52.0", 61 + ] 62 + 63 + [[package]] 64 + name = "inotify" 65 + version = "0.9.6" 66 + source = "registry+https://github.com/rust-lang/crates.io-index" 67 + checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" 68 + dependencies = [ 69 + "bitflags", 70 + "inotify-sys", 71 + "libc", 72 + ] 73 + 74 + [[package]] 75 + name = "inotify-sys" 76 + version = "0.1.5" 77 + source = "registry+https://github.com/rust-lang/crates.io-index" 78 + checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" 79 + dependencies = [ 80 + "libc", 81 + ] 82 + 83 + [[package]] 84 + name = "kqueue" 85 + version = "1.0.8" 86 + source = "registry+https://github.com/rust-lang/crates.io-index" 87 + checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c" 88 + dependencies = [ 89 + "kqueue-sys", 90 + "libc", 91 + ] 92 + 93 + [[package]] 94 + name = "kqueue-sys" 95 + version = "1.0.4" 96 + source = "registry+https://github.com/rust-lang/crates.io-index" 97 + checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" 98 + dependencies = [ 99 + "bitflags", 100 + "libc", 101 + ] 102 + 103 + [[package]] 104 + name = "lazy_static" 105 + version = "1.5.0" 106 + source = "registry+https://github.com/rust-lang/crates.io-index" 107 + checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 108 + 109 + [[package]] 110 + name = "libc" 111 + version = "0.2.155" 112 + source = "registry+https://github.com/rust-lang/crates.io-index" 113 + checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" 114 + 115 + [[package]] 116 + name = "log" 117 + version = "0.4.22" 118 + source = "registry+https://github.com/rust-lang/crates.io-index" 119 + checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" 120 + 121 + [[package]] 122 + name = "memchr" 123 + version = "2.7.4" 124 + source = "registry+https://github.com/rust-lang/crates.io-index" 125 + checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 126 + 127 + [[package]] 128 + name = "mio" 129 + version = "0.8.11" 130 + source = "registry+https://github.com/rust-lang/crates.io-index" 131 + checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" 132 + dependencies = [ 133 + "libc", 134 + "log", 135 + "wasi", 136 + "windows-sys 0.48.0", 137 + ] 138 + 139 + [[package]] 140 + name = "notify" 141 + version = "5.2.0" 142 + source = "registry+https://github.com/rust-lang/crates.io-index" 143 + checksum = "729f63e1ca555a43fe3efa4f3efdf4801c479da85b432242a7b726f353c88486" 144 + dependencies = [ 145 + "bitflags", 146 + "filetime", 147 + "inotify", 148 + "kqueue", 149 + "libc", 150 + "mio", 151 + "walkdir", 152 + "windows-sys 0.45.0", 153 + ] 154 + 155 + [[package]] 156 + name = "redox_syscall" 157 + version = "0.4.1" 158 + source = "registry+https://github.com/rust-lang/crates.io-index" 159 + checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" 160 + dependencies = [ 161 + "bitflags", 162 + ] 163 + 164 + [[package]] 165 + name = "regex" 166 + version = "1.10.5" 167 + source = "registry+https://github.com/rust-lang/crates.io-index" 168 + checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" 169 + dependencies = [ 170 + "aho-corasick", 171 + "memchr", 172 + "regex-automata", 173 + "regex-syntax", 174 + ] 175 + 176 + [[package]] 177 + name = "regex-automata" 178 + version = "0.4.7" 179 + source = "registry+https://github.com/rust-lang/crates.io-index" 180 + checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" 181 + dependencies = [ 182 + "aho-corasick", 183 + "memchr", 184 + "regex-syntax", 185 + ] 186 + 187 + [[package]] 188 + name = "regex-syntax" 189 + version = "0.8.4" 190 + source = "registry+https://github.com/rust-lang/crates.io-index" 191 + checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" 192 + 193 + [[package]] 194 + name = "same-file" 195 + version = "1.0.6" 196 + source = "registry+https://github.com/rust-lang/crates.io-index" 197 + checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 198 + dependencies = [ 199 + "winapi-util", 200 + ] 201 + 202 + [[package]] 203 + name = "tree-sitter" 204 + version = "0.20.10" 205 + source = "registry+https://github.com/rust-lang/crates.io-index" 206 + checksum = "e747b1f9b7b931ed39a548c1fae149101497de3c1fc8d9e18c62c1a66c683d3d" 207 + dependencies = [ 208 + "cc", 209 + "regex", 210 + ] 211 + 212 + [[package]] 213 + name = "tree-sitter" 214 + version = "0.21.0" 215 + source = "registry+https://github.com/rust-lang/crates.io-index" 216 + checksum = "705bf7c0958d0171dd7d3a6542f2f4f21d87ed5f1dc8db52919d3a6bed9a359a" 217 + dependencies = [ 218 + "cc", 219 + "regex", 220 + ] 221 + 222 + [[package]] 223 + name = "tree-sitter-elm" 224 + version = "5.7.0" 225 + source = "registry+https://github.com/rust-lang/crates.io-index" 226 + checksum = "1ee736eec2208cd9ea7f2bf1af505c27df03edaed8c7bac38c29f2b147c6035d" 227 + dependencies = [ 228 + "cc", 229 + "tree-sitter 0.20.10", 230 + ] 231 + 232 + [[package]] 233 + name = "tree-sitter-go" 234 + version = "0.19.1" 235 + source = "registry+https://github.com/rust-lang/crates.io-index" 236 + checksum = "71967701c8214be4aa77e0260e98361e6fd71ceec1d9d03abb37a22c9f60d0ff" 237 + dependencies = [ 238 + "cc", 239 + "tree-sitter 0.20.10", 240 + ] 241 + 242 + [[package]] 243 + name = "tree-sitter-javascript" 244 + version = "0.21.4" 245 + source = "registry+https://github.com/rust-lang/crates.io-index" 246 + checksum = "8710a71bc6779e33811a8067bdda3ed08bed1733296ff915e44faf60f8c533d7" 247 + dependencies = [ 248 + "cc", 249 + "tree-sitter 0.21.0", 250 + ] 251 + 252 + [[package]] 253 + name = "tree-sitter-json" 254 + version = "0.21.0" 255 + source = "git+https://github.com/tree-sitter/tree-sitter-json#94f5c527b2965465956c2000ed6134dd24daf2a7" 256 + dependencies = [ 257 + "cc", 258 + "tree-sitter 0.21.0", 259 + ] 260 + 261 + [[package]] 262 + name = "tree-sitter-md" 263 + version = "0.2.3" 264 + source = "registry+https://github.com/rust-lang/crates.io-index" 265 + checksum = "d9c3cfd068f2527250bbd8ff407431164e12b17863e7eafb76e311dd3f96965a" 266 + dependencies = [ 267 + "cc", 268 + "tree-sitter 0.21.0", 269 + ] 270 + 271 + [[package]] 272 + name = "tree-sitter-mdx" 273 + version = "0.0.1" 274 + source = "git+https://github.com/jlopezcur/tree-sitter-mdx#df43681bff333228fa60b69c09a1e7a6f9ed1610" 275 + dependencies = [ 276 + "cc", 277 + "tree-sitter 0.20.10", 278 + ] 279 + 280 + [[package]] 281 + name = "tree-sitter-python" 282 + version = "0.21.0" 283 + source = "registry+https://github.com/rust-lang/crates.io-index" 284 + checksum = "b4066c6cf678f962f8c2c4561f205945c84834cce73d981e71392624fdc390a9" 285 + dependencies = [ 286 + "cc", 287 + "tree-sitter 0.21.0", 288 + ] 289 + 290 + [[package]] 291 + name = "tree-sitter-ruby" 292 + version = "0.21.0" 293 + source = "registry+https://github.com/rust-lang/crates.io-index" 294 + checksum = "c0031f687c0772f2dad7b77104c43428611099a1804c81244ada21560f41f0b1" 295 + dependencies = [ 296 + "cc", 297 + "tree-sitter 0.21.0", 298 + ] 299 + 300 + [[package]] 301 + name = "tree-sitter-rust" 302 + version = "0.21.2" 303 + source = "registry+https://github.com/rust-lang/crates.io-index" 304 + checksum = "277690f420bf90741dea984f3da038ace46c4fe6047cba57a66822226cde1c93" 305 + dependencies = [ 306 + "cc", 307 + "tree-sitter 0.21.0", 308 + ] 309 + 310 + [[package]] 311 + name = "tree-sitter-typescript" 312 + version = "0.21.2" 313 + source = "registry+https://github.com/rust-lang/crates.io-index" 314 + checksum = "ecb35d98a688378e56c18c9c159824fd16f730ccbea19aacf4f206e5d5438ed9" 315 + dependencies = [ 316 + "cc", 317 + "tree-sitter 0.21.0", 318 + ] 319 + 320 + [[package]] 321 + name = "tree-viz" 322 + version = "0.1.0" 323 + dependencies = [ 324 + "console", 325 + "notify", 326 + "tree-sitter 0.21.0", 327 + "tree-sitter-elm", 328 + "tree-sitter-go", 329 + "tree-sitter-javascript", 330 + "tree-sitter-json", 331 + "tree-sitter-md", 332 + "tree-sitter-mdx", 333 + "tree-sitter-python", 334 + "tree-sitter-ruby", 335 + "tree-sitter-rust", 336 + "tree-sitter-typescript", 337 + ] 338 + 339 + [[package]] 340 + name = "unicode-width" 341 + version = "0.1.13" 342 + source = "registry+https://github.com/rust-lang/crates.io-index" 343 + checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" 344 + 345 + [[package]] 346 + name = "walkdir" 347 + version = "2.5.0" 348 + source = "registry+https://github.com/rust-lang/crates.io-index" 349 + checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" 350 + dependencies = [ 351 + "same-file", 352 + "winapi-util", 353 + ] 354 + 355 + [[package]] 356 + name = "wasi" 357 + version = "0.11.0+wasi-snapshot-preview1" 358 + source = "registry+https://github.com/rust-lang/crates.io-index" 359 + checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 360 + 361 + [[package]] 362 + name = "winapi-util" 363 + version = "0.1.8" 364 + source = "registry+https://github.com/rust-lang/crates.io-index" 365 + checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" 366 + dependencies = [ 367 + "windows-sys 0.52.0", 368 + ] 369 + 370 + [[package]] 371 + name = "windows-sys" 372 + version = "0.45.0" 373 + source = "registry+https://github.com/rust-lang/crates.io-index" 374 + checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" 375 + dependencies = [ 376 + "windows-targets 0.42.2", 377 + ] 378 + 379 + [[package]] 380 + name = "windows-sys" 381 + version = "0.48.0" 382 + source = "registry+https://github.com/rust-lang/crates.io-index" 383 + checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 384 + dependencies = [ 385 + "windows-targets 0.48.5", 386 + ] 387 + 388 + [[package]] 389 + name = "windows-sys" 390 + version = "0.52.0" 391 + source = "registry+https://github.com/rust-lang/crates.io-index" 392 + checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 393 + dependencies = [ 394 + "windows-targets 0.52.6", 395 + ] 396 + 397 + [[package]] 398 + name = "windows-targets" 399 + version = "0.42.2" 400 + source = "registry+https://github.com/rust-lang/crates.io-index" 401 + checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" 402 + dependencies = [ 403 + "windows_aarch64_gnullvm 0.42.2", 404 + "windows_aarch64_msvc 0.42.2", 405 + "windows_i686_gnu 0.42.2", 406 + "windows_i686_msvc 0.42.2", 407 + "windows_x86_64_gnu 0.42.2", 408 + "windows_x86_64_gnullvm 0.42.2", 409 + "windows_x86_64_msvc 0.42.2", 410 + ] 411 + 412 + [[package]] 413 + name = "windows-targets" 414 + version = "0.48.5" 415 + source = "registry+https://github.com/rust-lang/crates.io-index" 416 + checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 417 + dependencies = [ 418 + "windows_aarch64_gnullvm 0.48.5", 419 + "windows_aarch64_msvc 0.48.5", 420 + "windows_i686_gnu 0.48.5", 421 + "windows_i686_msvc 0.48.5", 422 + "windows_x86_64_gnu 0.48.5", 423 + "windows_x86_64_gnullvm 0.48.5", 424 + "windows_x86_64_msvc 0.48.5", 425 + ] 426 + 427 + [[package]] 428 + name = "windows-targets" 429 + version = "0.52.6" 430 + source = "registry+https://github.com/rust-lang/crates.io-index" 431 + checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 432 + dependencies = [ 433 + "windows_aarch64_gnullvm 0.52.6", 434 + "windows_aarch64_msvc 0.52.6", 435 + "windows_i686_gnu 0.52.6", 436 + "windows_i686_gnullvm", 437 + "windows_i686_msvc 0.52.6", 438 + "windows_x86_64_gnu 0.52.6", 439 + "windows_x86_64_gnullvm 0.52.6", 440 + "windows_x86_64_msvc 0.52.6", 441 + ] 442 + 443 + [[package]] 444 + name = "windows_aarch64_gnullvm" 445 + version = "0.42.2" 446 + source = "registry+https://github.com/rust-lang/crates.io-index" 447 + checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" 448 + 449 + [[package]] 450 + name = "windows_aarch64_gnullvm" 451 + version = "0.48.5" 452 + source = "registry+https://github.com/rust-lang/crates.io-index" 453 + checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 454 + 455 + [[package]] 456 + name = "windows_aarch64_gnullvm" 457 + version = "0.52.6" 458 + source = "registry+https://github.com/rust-lang/crates.io-index" 459 + checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 460 + 461 + [[package]] 462 + name = "windows_aarch64_msvc" 463 + version = "0.42.2" 464 + source = "registry+https://github.com/rust-lang/crates.io-index" 465 + checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" 466 + 467 + [[package]] 468 + name = "windows_aarch64_msvc" 469 + version = "0.48.5" 470 + source = "registry+https://github.com/rust-lang/crates.io-index" 471 + checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 472 + 473 + [[package]] 474 + name = "windows_aarch64_msvc" 475 + version = "0.52.6" 476 + source = "registry+https://github.com/rust-lang/crates.io-index" 477 + checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 478 + 479 + [[package]] 480 + name = "windows_i686_gnu" 481 + version = "0.42.2" 482 + source = "registry+https://github.com/rust-lang/crates.io-index" 483 + checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" 484 + 485 + [[package]] 486 + name = "windows_i686_gnu" 487 + version = "0.48.5" 488 + source = "registry+https://github.com/rust-lang/crates.io-index" 489 + checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 490 + 491 + [[package]] 492 + name = "windows_i686_gnu" 493 + version = "0.52.6" 494 + source = "registry+https://github.com/rust-lang/crates.io-index" 495 + checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 496 + 497 + [[package]] 498 + name = "windows_i686_gnullvm" 499 + version = "0.52.6" 500 + source = "registry+https://github.com/rust-lang/crates.io-index" 501 + checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 502 + 503 + [[package]] 504 + name = "windows_i686_msvc" 505 + version = "0.42.2" 506 + source = "registry+https://github.com/rust-lang/crates.io-index" 507 + checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" 508 + 509 + [[package]] 510 + name = "windows_i686_msvc" 511 + version = "0.48.5" 512 + source = "registry+https://github.com/rust-lang/crates.io-index" 513 + checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 514 + 515 + [[package]] 516 + name = "windows_i686_msvc" 517 + version = "0.52.6" 518 + source = "registry+https://github.com/rust-lang/crates.io-index" 519 + checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 520 + 521 + [[package]] 522 + name = "windows_x86_64_gnu" 523 + version = "0.42.2" 524 + source = "registry+https://github.com/rust-lang/crates.io-index" 525 + checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" 526 + 527 + [[package]] 528 + name = "windows_x86_64_gnu" 529 + version = "0.48.5" 530 + source = "registry+https://github.com/rust-lang/crates.io-index" 531 + checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 532 + 533 + [[package]] 534 + name = "windows_x86_64_gnu" 535 + version = "0.52.6" 536 + source = "registry+https://github.com/rust-lang/crates.io-index" 537 + checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 538 + 539 + [[package]] 540 + name = "windows_x86_64_gnullvm" 541 + version = "0.42.2" 542 + source = "registry+https://github.com/rust-lang/crates.io-index" 543 + checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" 544 + 545 + [[package]] 546 + name = "windows_x86_64_gnullvm" 547 + version = "0.48.5" 548 + source = "registry+https://github.com/rust-lang/crates.io-index" 549 + checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 550 + 551 + [[package]] 552 + name = "windows_x86_64_gnullvm" 553 + version = "0.52.6" 554 + source = "registry+https://github.com/rust-lang/crates.io-index" 555 + checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 556 + 557 + [[package]] 558 + name = "windows_x86_64_msvc" 559 + version = "0.42.2" 560 + source = "registry+https://github.com/rust-lang/crates.io-index" 561 + checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" 562 + 563 + [[package]] 564 + name = "windows_x86_64_msvc" 565 + version = "0.48.5" 566 + source = "registry+https://github.com/rust-lang/crates.io-index" 567 + checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 568 + 569 + [[package]] 570 + name = "windows_x86_64_msvc" 571 + version = "0.52.6" 572 + source = "registry+https://github.com/rust-lang/crates.io-index" 573 + checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
+25
Cargo.toml
··· 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-ruby = "0.21" 11 + tree-sitter-rust = "0.21" 12 + tree-sitter = "0.21" 13 + console = "^0.15" 14 + tree-sitter-go = "0.19.1" 15 + tree-sitter-typescript = "0.21" 16 + tree-sitter-javascript = "0.21" 17 + tree-sitter-mdx = { git = "https://github.com/jlopezcur/tree-sitter-mdx" } 18 + tree-sitter-json = { git = "https://github.com/tree-sitter/tree-sitter-json" } 19 + tree-sitter-python = "0.21" 20 + tree-sitter-md = "0.2.3" 21 + # tree-sitter-cobol = { path = "../../tree-sitter-cobol/" } 22 + 23 + [dependencies.notify] 24 + version = "5.0.0" 25 + default-features = false
+10
readme.txt
··· 1 + tree-viz -- <language> <file> [scope_query] 2 + 3 + language is one of: 4 + 5 + - typescript 6 + - javascript 7 + - python 8 + - rust 9 + - markdown 10 + - ruby
+259
src/app.rs
··· 1 + use crate::config::Config; 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 + language: tree_sitter::Language, 15 + path: PathBuf, 16 + query: Option<Query>, 17 + query_path: Option<PathBuf>, 18 + src: Vec<u8>, 19 + tree: Tree, 20 + } 21 + 22 + impl App { 23 + pub fn new<'a, P: AsRef<Path>>( 24 + src: &'a [u8], 25 + path: P, 26 + query_path: Option<P>, 27 + language: tree_sitter::Language, 28 + ) -> Self { 29 + let path = path.as_ref().to_owned(); 30 + 31 + let mut parser = Parser::new(); 32 + parser.set_language(&language).unwrap(); 33 + 34 + let tree = parser.parse(&src, None).unwrap(); 35 + let query_path = query_path.map(|q| q.as_ref().to_owned()); 36 + let query = query_path.as_ref().map(|p| { 37 + let query_src = std::fs::read_to_string(&p).expect("unable to read query"); 38 + Query::new(&language, &query_src).expect("query parse error") 39 + }); 40 + 41 + Self { 42 + config: Default::default(), 43 + path, 44 + query, 45 + query_path, 46 + src: src.to_owned(), 47 + tree, 48 + language, 49 + } 50 + } 51 + 52 + pub fn draw(&self) { 53 + let term = Term::stdout(); 54 + term.clear_screen().unwrap(); 55 + let mut done = false; 56 + let mut depth = 0; 57 + let mut in_capture: Option<Range> = None; 58 + let mut cursor = self.tree.walk(); 59 + 60 + let capture_names = self 61 + .query 62 + .as_ref() 63 + .map(|q| q.capture_names()) 64 + .unwrap_or_default(); 65 + let capture_map = self 66 + .query 67 + .as_ref() 68 + .map(|query| { 69 + QueryCursor::new() 70 + .matches(&query, self.tree.root_node(), self.src.as_slice()) 71 + .flat_map(|match_| match_.captures) 72 + .fold( 73 + HashMap::new(), 74 + |mut map: HashMap<Node, Vec<u32>>, capture| { 75 + map.entry(capture.node) 76 + .and_modify(|idxs| idxs.push(capture.index)) 77 + .or_insert_with(|| vec![capture.index]); 78 + map 79 + }, 80 + ) 81 + }) 82 + .unwrap_or_default(); 83 + 84 + while !done { 85 + let node = cursor.node(); 86 + let mut tree_string = String::new(); 87 + in_capture = match in_capture { 88 + Some(range) 89 + if !contains(&range, &node.range()) && capture_map.contains_key(&node) => 90 + { 91 + Some(node.range()) 92 + } 93 + Some(range) if !contains(&range, &node.range()) => None, 94 + None if capture_map.contains_key(&node) => Some(node.range()), 95 + i => i, 96 + }; 97 + 98 + write!( 99 + tree_string, 100 + "{}", 101 + (if in_capture.is_some() { 102 + Style::new().on_yellow().on_bright() 103 + } else { 104 + Style::new() 105 + }) 106 + .bright() 107 + .black() 108 + .apply_to( 109 + format!("{}{}", "|", " ".repeat(self.config.indent_level)) 110 + .repeat(depth as usize) 111 + ) 112 + ) 113 + .unwrap(); 114 + 115 + if self.config.show_field_name { 116 + if let Some(f) = cursor.field_name() { 117 + write!( 118 + tree_string, 119 + "{} ", 120 + if in_capture.is_some() { 121 + Style::new().on_yellow().on_bright() 122 + } else { 123 + Style::new() 124 + } 125 + .yellow() 126 + .apply_to(f) 127 + ) 128 + .unwrap() 129 + } 130 + } 131 + 132 + write!( 133 + tree_string, 134 + "{} ", 135 + if node.is_error() { 136 + Style::new().red() 137 + } else if in_capture.is_some() { 138 + Style::new().on_yellow().on_bright() 139 + } else { 140 + Style::new() 141 + } 142 + .apply_to(node.kind()), 143 + ) 144 + .unwrap(); 145 + 146 + if let Some(idxs) = capture_map.get(&node) { 147 + for index in idxs { 148 + write!( 149 + tree_string, 150 + "@{} ", 151 + style(capture_names[*index as usize]).magenta() 152 + ) 153 + .unwrap(); 154 + } 155 + } 156 + 157 + if self.config.show_ranges { 158 + let range = node.range(); 159 + write!( 160 + tree_string, 161 + " {}", 162 + style(format!("{:?}..{:?}", range.start_byte, range.end_byte,)) 163 + .bright() 164 + .black() 165 + ) 166 + .unwrap(); 167 + } 168 + 169 + if self.config.show_src { 170 + write!( 171 + tree_string, 172 + " {:.?}", 173 + style(node.utf8_text(&self.src).unwrap()).cyan() 174 + ) 175 + .unwrap(); 176 + } 177 + 178 + term.write_line(&tree_string).unwrap(); 179 + term.clear_to_end_of_screen().unwrap(); 180 + 181 + if cursor.goto_first_child() { 182 + depth += 1; 183 + continue; 184 + } 185 + if cursor.goto_next_sibling() { 186 + continue; 187 + } 188 + 189 + loop { 190 + if !cursor.goto_parent() { 191 + done = true; 192 + break; 193 + } else { 194 + depth -= 1; 195 + } 196 + 197 + if cursor.goto_next_sibling() { 198 + break; 199 + } 200 + } 201 + } 202 + 203 + // see https://github.com/console-rs/console/issues/36#issuecomment-624731432 204 + // for the reasoning behing this hackjob 205 + 206 + term.write_line("\n(>) increase indent").unwrap(); 207 + term.clear_to_end_of_screen().unwrap(); 208 + 209 + term.write_line("(<) decrease indent ").unwrap(); 210 + term.clear_to_end_of_screen().unwrap(); 211 + 212 + term.write_line("(n) toggle ranges").unwrap(); 213 + term.clear_to_end_of_screen().unwrap(); 214 + 215 + term.write_line("(s) toggle source text").unwrap(); 216 + term.clear_to_end_of_screen().unwrap(); 217 + 218 + term.write_line("(r) reload from disk").unwrap(); 219 + term.clear_to_end_of_screen().unwrap(); 220 + 221 + term.write_line("(C-c) quit").unwrap(); 222 + term.clear_to_end_of_screen().unwrap(); 223 + } 224 + 225 + pub fn increase_indent(&mut self) { 226 + self.config.indent_level = self.config.indent_level.saturating_add(1); 227 + } 228 + 229 + pub fn decrease_indent(&mut self) { 230 + self.config.indent_level = self.config.indent_level.saturating_sub(1); 231 + } 232 + 233 + pub fn toggle_ranges(&mut self) { 234 + self.config.show_ranges = !self.config.show_ranges; 235 + } 236 + 237 + pub fn toggle_source(&mut self) { 238 + self.config.show_src = !self.config.show_src; 239 + } 240 + 241 + pub fn reload(&mut self) { 242 + let src = std::fs::read_to_string(&self.path).unwrap(); 243 + let new = Self::new( 244 + src.as_bytes(), 245 + &self.path, 246 + self.query_path.as_ref(), 247 + self.language.clone(), 248 + ); 249 + *self = Self { 250 + config: self.config, 251 + ..new 252 + }; 253 + } 254 + } 255 + 256 + // does a encompass b 257 + fn contains(a: &Range, b: &Range) -> bool { 258 + a.start_byte <= b.start_byte && a.end_byte >= b.end_byte 259 + }
+26
src/config.rs
··· 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 + pub show_field_name: bool, 9 + } 10 + 11 + impl Default for Config { 12 + fn default() -> Self { 13 + Config::new() 14 + } 15 + } 16 + 17 + impl Config { 18 + fn new() -> Self { 19 + Self { 20 + indent_level: 2, 21 + show_ranges: true, 22 + show_src: true, 23 + show_field_name: true, 24 + } 25 + } 26 + }
+102
src/main.rs
··· 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 + 16 + fn main() { 17 + let mut args = env::args(); 18 + let _ = args.next(); 19 + 20 + let language = match args.next().as_ref().map(|s| s.as_str()) { 21 + Some("rust") => tree_sitter_rust::language(), 22 + Some("tsx") | Some("typescript") => tree_sitter_typescript::language_tsx(), 23 + Some("javascript") => tree_sitter_javascript::language(), 24 + Some("python") => tree_sitter_python::language(), 25 + Some("ruby") => tree_sitter_ruby::language(), 26 + Some("markdown") => tree_sitter_md::language(), 27 + Some(s) => panic!("invalid language passed: {s}"), 28 + None => panic!("no language passed"), 29 + }; 30 + let path = args.next().expect("no arg passed"); 31 + let query_path = args.next(); 32 + let src = fs::read_to_string(&path).expect("unable to read file"); 33 + 34 + let app = Arc::new(RwLock::new(App::new( 35 + src.as_bytes(), 36 + &path, 37 + query_path.as_ref(), 38 + language, 39 + ))); 40 + 41 + let watch_fn = |watcher_app: Arc<RwLock<App>>| { 42 + move |ev| { 43 + if let Ok(WatchEvent { 44 + kind: WatchEventKind::Modify(..), 45 + .. 46 + }) = ev 47 + { 48 + if let Ok(mut locked) = watcher_app.try_write() { 49 + locked.reload(); 50 + locked.draw(); 51 + }; 52 + } 53 + } 54 + }; 55 + 56 + let mut watcher1 = notify::recommended_watcher(watch_fn(Arc::clone(&app))).unwrap(); 57 + watcher1 58 + .watch(Path::new(&path), RecursiveMode::NonRecursive) 59 + .unwrap(); 60 + 61 + let mut watcher2 = notify::recommended_watcher(watch_fn(Arc::clone(&app))).unwrap(); 62 + if let Some(query_path) = query_path { 63 + watcher2 64 + .watch(Path::new(&query_path), RecursiveMode::NonRecursive) 65 + .unwrap(); 66 + } 67 + 68 + let (tx, rx) = mpsc::channel(); 69 + let tx0 = tx.clone(); 70 + thread::spawn(move || { 71 + let term = Term::stdout(); 72 + loop { 73 + if let Ok(Key::Char(ev)) = term.read_key() { 74 + tx0.send(ev).unwrap(); 75 + } 76 + } 77 + }); 78 + 79 + if let Ok(locked) = app.try_read() { 80 + locked.draw(); 81 + } 82 + 83 + loop { 84 + match rx.try_recv() { 85 + Ok(ev) => { 86 + if let Ok(mut locked) = app.try_write() { 87 + match ev { 88 + '>' => locked.increase_indent(), 89 + '<' => locked.decrease_indent(), 90 + 'n' => locked.toggle_ranges(), 91 + 's' => locked.toggle_source(), 92 + 'r' => locked.reload(), 93 + _ => (), 94 + } 95 + locked.draw(); 96 + } 97 + } 98 + _ => (), 99 + } 100 + thread::sleep(Duration::from_millis(10)); 101 + } 102 + }