├── .envrc ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.md ├── flake.lock ├── flake.nix ├── nix └── default.nix └── src └── lib.rs /.envrc: -------------------------------------------------------------------------------- 1 | use flake 2 | 3 | export DATABASE_URL=${XDG_CACHE_HOME:=$HOME/.cache}/anyrun-ha-assist.sqlite3 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | result/ 3 | .direnv/ 4 | -------------------------------------------------------------------------------- /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 = "abi_stable" 7 | version = "0.11.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "467388fe07f5a809f4df42226142cadd5a7706810b76a0896fd68d156b1ea886" 10 | dependencies = [ 11 | "abi_stable_derive", 12 | "abi_stable_shared", 13 | "const_panic", 14 | "core_extensions", 15 | "crossbeam-channel", 16 | "generational-arena", 17 | "libloading", 18 | "lock_api", 19 | "parking_lot", 20 | "paste", 21 | "repr_offset", 22 | "rustc_version", 23 | "serde", 24 | "serde_derive", 25 | "serde_json", 26 | ] 27 | 28 | [[package]] 29 | name = "abi_stable_derive" 30 | version = "0.11.0" 31 | source = "registry+https://github.com/rust-lang/crates.io-index" 32 | checksum = "0aecd3efa5a5294f5c67913d45f985ccb382b3c93327581529610eeecdf4821a" 33 | dependencies = [ 34 | "abi_stable_shared", 35 | "as_derive_utils", 36 | "core_extensions", 37 | "proc-macro2", 38 | "quote", 39 | "rustc_version", 40 | "syn 1.0.109", 41 | "typed-arena", 42 | ] 43 | 44 | [[package]] 45 | name = "abi_stable_shared" 46 | version = "0.11.0" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "b2b5df7688c123e63f4d4d649cba63f2967ba7f7861b1664fca3f77d3dad2b63" 49 | dependencies = [ 50 | "core_extensions", 51 | ] 52 | 53 | [[package]] 54 | name = "aho-corasick" 55 | version = "1.0.2" 56 | source = "registry+https://github.com/rust-lang/crates.io-index" 57 | checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" 58 | dependencies = [ 59 | "memchr", 60 | ] 61 | 62 | [[package]] 63 | name = "anyrun-interface" 64 | version = "0.1.0" 65 | source = "git+https://github.com/Kirottu/anyrun#da97c9287f01f7d85ecf5e4ab8819bde3ae0e79a" 66 | dependencies = [ 67 | "abi_stable", 68 | ] 69 | 70 | [[package]] 71 | name = "anyrun-macros" 72 | version = "0.1.0" 73 | source = "git+https://github.com/Kirottu/anyrun#da97c9287f01f7d85ecf5e4ab8819bde3ae0e79a" 74 | dependencies = [ 75 | "quote", 76 | "syn 2.0.28", 77 | ] 78 | 79 | [[package]] 80 | name = "anyrun-nixos-options" 81 | version = "2.0.0" 82 | dependencies = [ 83 | "abi_stable", 84 | "anyrun-plugin", 85 | "fuzzy-matcher", 86 | "html-escape", 87 | "open", 88 | "rayon", 89 | "regex", 90 | "ron", 91 | "serde", 92 | "serde-inline-default", 93 | "serde_json", 94 | "url", 95 | ] 96 | 97 | [[package]] 98 | name = "anyrun-plugin" 99 | version = "0.1.0" 100 | source = "git+https://github.com/Kirottu/anyrun#da97c9287f01f7d85ecf5e4ab8819bde3ae0e79a" 101 | dependencies = [ 102 | "abi_stable", 103 | "anyrun-interface", 104 | "anyrun-macros", 105 | ] 106 | 107 | [[package]] 108 | name = "as_derive_utils" 109 | version = "0.11.0" 110 | source = "registry+https://github.com/rust-lang/crates.io-index" 111 | checksum = "ff3c96645900a44cf11941c111bd08a6573b0e2f9f69bc9264b179d8fae753c4" 112 | dependencies = [ 113 | "core_extensions", 114 | "proc-macro2", 115 | "quote", 116 | "syn 1.0.109", 117 | ] 118 | 119 | [[package]] 120 | name = "autocfg" 121 | version = "1.1.0" 122 | source = "registry+https://github.com/rust-lang/crates.io-index" 123 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 124 | 125 | [[package]] 126 | name = "base64" 127 | version = "0.13.1" 128 | source = "registry+https://github.com/rust-lang/crates.io-index" 129 | checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" 130 | 131 | [[package]] 132 | name = "bitflags" 133 | version = "1.3.2" 134 | source = "registry+https://github.com/rust-lang/crates.io-index" 135 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 136 | 137 | [[package]] 138 | name = "cfg-if" 139 | version = "1.0.0" 140 | source = "registry+https://github.com/rust-lang/crates.io-index" 141 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 142 | 143 | [[package]] 144 | name = "const_panic" 145 | version = "0.2.8" 146 | source = "registry+https://github.com/rust-lang/crates.io-index" 147 | checksum = "6051f239ecec86fde3410901ab7860d458d160371533842974fc61f96d15879b" 148 | 149 | [[package]] 150 | name = "core_extensions" 151 | version = "1.5.3" 152 | source = "registry+https://github.com/rust-lang/crates.io-index" 153 | checksum = "92c71dc07c9721607e7a16108336048ee978c3a8b129294534272e8bac96c0ee" 154 | dependencies = [ 155 | "core_extensions_proc_macros", 156 | ] 157 | 158 | [[package]] 159 | name = "core_extensions_proc_macros" 160 | version = "1.5.3" 161 | source = "registry+https://github.com/rust-lang/crates.io-index" 162 | checksum = "69f3b219d28b6e3b4ac87bc1fc522e0803ab22e055da177bff0068c4150c61a6" 163 | 164 | [[package]] 165 | name = "crossbeam-channel" 166 | version = "0.5.8" 167 | source = "registry+https://github.com/rust-lang/crates.io-index" 168 | checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" 169 | dependencies = [ 170 | "cfg-if", 171 | "crossbeam-utils", 172 | ] 173 | 174 | [[package]] 175 | name = "crossbeam-deque" 176 | version = "0.8.3" 177 | source = "registry+https://github.com/rust-lang/crates.io-index" 178 | checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" 179 | dependencies = [ 180 | "cfg-if", 181 | "crossbeam-epoch", 182 | "crossbeam-utils", 183 | ] 184 | 185 | [[package]] 186 | name = "crossbeam-epoch" 187 | version = "0.9.15" 188 | source = "registry+https://github.com/rust-lang/crates.io-index" 189 | checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" 190 | dependencies = [ 191 | "autocfg", 192 | "cfg-if", 193 | "crossbeam-utils", 194 | "memoffset", 195 | "scopeguard", 196 | ] 197 | 198 | [[package]] 199 | name = "crossbeam-utils" 200 | version = "0.8.16" 201 | source = "registry+https://github.com/rust-lang/crates.io-index" 202 | checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" 203 | dependencies = [ 204 | "cfg-if", 205 | ] 206 | 207 | [[package]] 208 | name = "either" 209 | version = "1.9.0" 210 | source = "registry+https://github.com/rust-lang/crates.io-index" 211 | checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" 212 | 213 | [[package]] 214 | name = "form_urlencoded" 215 | version = "1.2.0" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" 218 | dependencies = [ 219 | "percent-encoding", 220 | ] 221 | 222 | [[package]] 223 | name = "fuzzy-matcher" 224 | version = "0.3.7" 225 | source = "registry+https://github.com/rust-lang/crates.io-index" 226 | checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94" 227 | dependencies = [ 228 | "thread_local", 229 | ] 230 | 231 | [[package]] 232 | name = "generational-arena" 233 | version = "0.2.9" 234 | source = "registry+https://github.com/rust-lang/crates.io-index" 235 | checksum = "877e94aff08e743b651baaea359664321055749b398adff8740a7399af7796e7" 236 | dependencies = [ 237 | "cfg-if", 238 | ] 239 | 240 | [[package]] 241 | name = "hermit-abi" 242 | version = "0.3.2" 243 | source = "registry+https://github.com/rust-lang/crates.io-index" 244 | checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" 245 | 246 | [[package]] 247 | name = "html-escape" 248 | version = "0.2.13" 249 | source = "registry+https://github.com/rust-lang/crates.io-index" 250 | checksum = "6d1ad449764d627e22bfd7cd5e8868264fc9236e07c752972b4080cd351cb476" 251 | dependencies = [ 252 | "utf8-width", 253 | ] 254 | 255 | [[package]] 256 | name = "idna" 257 | version = "0.4.0" 258 | source = "registry+https://github.com/rust-lang/crates.io-index" 259 | checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" 260 | dependencies = [ 261 | "unicode-bidi", 262 | "unicode-normalization", 263 | ] 264 | 265 | [[package]] 266 | name = "is-docker" 267 | version = "0.2.0" 268 | source = "registry+https://github.com/rust-lang/crates.io-index" 269 | checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3" 270 | dependencies = [ 271 | "once_cell", 272 | ] 273 | 274 | [[package]] 275 | name = "is-wsl" 276 | version = "0.4.0" 277 | source = "registry+https://github.com/rust-lang/crates.io-index" 278 | checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5" 279 | dependencies = [ 280 | "is-docker", 281 | "once_cell", 282 | ] 283 | 284 | [[package]] 285 | name = "itoa" 286 | version = "1.0.9" 287 | source = "registry+https://github.com/rust-lang/crates.io-index" 288 | checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" 289 | 290 | [[package]] 291 | name = "libc" 292 | version = "0.2.147" 293 | source = "registry+https://github.com/rust-lang/crates.io-index" 294 | checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" 295 | 296 | [[package]] 297 | name = "libloading" 298 | version = "0.7.4" 299 | source = "registry+https://github.com/rust-lang/crates.io-index" 300 | checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" 301 | dependencies = [ 302 | "cfg-if", 303 | "winapi", 304 | ] 305 | 306 | [[package]] 307 | name = "lock_api" 308 | version = "0.4.10" 309 | source = "registry+https://github.com/rust-lang/crates.io-index" 310 | checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" 311 | dependencies = [ 312 | "autocfg", 313 | "scopeguard", 314 | ] 315 | 316 | [[package]] 317 | name = "memchr" 318 | version = "2.5.0" 319 | source = "registry+https://github.com/rust-lang/crates.io-index" 320 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 321 | 322 | [[package]] 323 | name = "memoffset" 324 | version = "0.9.0" 325 | source = "registry+https://github.com/rust-lang/crates.io-index" 326 | checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" 327 | dependencies = [ 328 | "autocfg", 329 | ] 330 | 331 | [[package]] 332 | name = "num_cpus" 333 | version = "1.16.0" 334 | source = "registry+https://github.com/rust-lang/crates.io-index" 335 | checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" 336 | dependencies = [ 337 | "hermit-abi", 338 | "libc", 339 | ] 340 | 341 | [[package]] 342 | name = "once_cell" 343 | version = "1.18.0" 344 | source = "registry+https://github.com/rust-lang/crates.io-index" 345 | checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" 346 | 347 | [[package]] 348 | name = "open" 349 | version = "5.0.0" 350 | source = "registry+https://github.com/rust-lang/crates.io-index" 351 | checksum = "cfabf1927dce4d6fdf563d63328a0a506101ced3ec780ca2135747336c98cef8" 352 | dependencies = [ 353 | "is-wsl", 354 | "libc", 355 | "pathdiff", 356 | ] 357 | 358 | [[package]] 359 | name = "parking_lot" 360 | version = "0.12.1" 361 | source = "registry+https://github.com/rust-lang/crates.io-index" 362 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 363 | dependencies = [ 364 | "lock_api", 365 | "parking_lot_core", 366 | ] 367 | 368 | [[package]] 369 | name = "parking_lot_core" 370 | version = "0.9.8" 371 | source = "registry+https://github.com/rust-lang/crates.io-index" 372 | checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" 373 | dependencies = [ 374 | "cfg-if", 375 | "libc", 376 | "redox_syscall", 377 | "smallvec", 378 | "windows-targets", 379 | ] 380 | 381 | [[package]] 382 | name = "paste" 383 | version = "1.0.14" 384 | source = "registry+https://github.com/rust-lang/crates.io-index" 385 | checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" 386 | 387 | [[package]] 388 | name = "pathdiff" 389 | version = "0.2.1" 390 | source = "registry+https://github.com/rust-lang/crates.io-index" 391 | checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" 392 | 393 | [[package]] 394 | name = "percent-encoding" 395 | version = "2.3.0" 396 | source = "registry+https://github.com/rust-lang/crates.io-index" 397 | checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" 398 | 399 | [[package]] 400 | name = "proc-macro2" 401 | version = "1.0.66" 402 | source = "registry+https://github.com/rust-lang/crates.io-index" 403 | checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" 404 | dependencies = [ 405 | "unicode-ident", 406 | ] 407 | 408 | [[package]] 409 | name = "quote" 410 | version = "1.0.32" 411 | source = "registry+https://github.com/rust-lang/crates.io-index" 412 | checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" 413 | dependencies = [ 414 | "proc-macro2", 415 | ] 416 | 417 | [[package]] 418 | name = "rayon" 419 | version = "1.7.0" 420 | source = "registry+https://github.com/rust-lang/crates.io-index" 421 | checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" 422 | dependencies = [ 423 | "either", 424 | "rayon-core", 425 | ] 426 | 427 | [[package]] 428 | name = "rayon-core" 429 | version = "1.11.0" 430 | source = "registry+https://github.com/rust-lang/crates.io-index" 431 | checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" 432 | dependencies = [ 433 | "crossbeam-channel", 434 | "crossbeam-deque", 435 | "crossbeam-utils", 436 | "num_cpus", 437 | ] 438 | 439 | [[package]] 440 | name = "redox_syscall" 441 | version = "0.3.5" 442 | source = "registry+https://github.com/rust-lang/crates.io-index" 443 | checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" 444 | dependencies = [ 445 | "bitflags", 446 | ] 447 | 448 | [[package]] 449 | name = "regex" 450 | version = "1.9.1" 451 | source = "registry+https://github.com/rust-lang/crates.io-index" 452 | checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" 453 | dependencies = [ 454 | "aho-corasick", 455 | "memchr", 456 | "regex-automata", 457 | "regex-syntax", 458 | ] 459 | 460 | [[package]] 461 | name = "regex-automata" 462 | version = "0.3.4" 463 | source = "registry+https://github.com/rust-lang/crates.io-index" 464 | checksum = "b7b6d6190b7594385f61bd3911cd1be99dfddcfc365a4160cc2ab5bff4aed294" 465 | dependencies = [ 466 | "aho-corasick", 467 | "memchr", 468 | "regex-syntax", 469 | ] 470 | 471 | [[package]] 472 | name = "regex-syntax" 473 | version = "0.7.4" 474 | source = "registry+https://github.com/rust-lang/crates.io-index" 475 | checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" 476 | 477 | [[package]] 478 | name = "repr_offset" 479 | version = "0.2.2" 480 | source = "registry+https://github.com/rust-lang/crates.io-index" 481 | checksum = "fb1070755bd29dffc19d0971cab794e607839ba2ef4b69a9e6fbc8733c1b72ea" 482 | dependencies = [ 483 | "tstr", 484 | ] 485 | 486 | [[package]] 487 | name = "ron" 488 | version = "0.8.0" 489 | source = "registry+https://github.com/rust-lang/crates.io-index" 490 | checksum = "300a51053b1cb55c80b7a9fde4120726ddf25ca241a1cbb926626f62fb136bff" 491 | dependencies = [ 492 | "base64", 493 | "bitflags", 494 | "serde", 495 | ] 496 | 497 | [[package]] 498 | name = "rustc_version" 499 | version = "0.4.0" 500 | source = "registry+https://github.com/rust-lang/crates.io-index" 501 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 502 | dependencies = [ 503 | "semver", 504 | ] 505 | 506 | [[package]] 507 | name = "ryu" 508 | version = "1.0.15" 509 | source = "registry+https://github.com/rust-lang/crates.io-index" 510 | checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" 511 | 512 | [[package]] 513 | name = "scopeguard" 514 | version = "1.2.0" 515 | source = "registry+https://github.com/rust-lang/crates.io-index" 516 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 517 | 518 | [[package]] 519 | name = "semver" 520 | version = "1.0.18" 521 | source = "registry+https://github.com/rust-lang/crates.io-index" 522 | checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" 523 | 524 | [[package]] 525 | name = "serde" 526 | version = "1.0.180" 527 | source = "registry+https://github.com/rust-lang/crates.io-index" 528 | checksum = "0ea67f183f058fe88a4e3ec6e2788e003840893b91bac4559cabedd00863b3ed" 529 | dependencies = [ 530 | "serde_derive", 531 | ] 532 | 533 | [[package]] 534 | name = "serde-inline-default" 535 | version = "0.1.1" 536 | source = "registry+https://github.com/rust-lang/crates.io-index" 537 | checksum = "fa824cde50b5f01ff28a955114d8152a07cd62d81f53459dad0f2610136be844" 538 | dependencies = [ 539 | "proc-macro2", 540 | "quote", 541 | "syn 1.0.109", 542 | ] 543 | 544 | [[package]] 545 | name = "serde_derive" 546 | version = "1.0.180" 547 | source = "registry+https://github.com/rust-lang/crates.io-index" 548 | checksum = "24e744d7782b686ab3b73267ef05697159cc0e5abbed3f47f9933165e5219036" 549 | dependencies = [ 550 | "proc-macro2", 551 | "quote", 552 | "syn 2.0.28", 553 | ] 554 | 555 | [[package]] 556 | name = "serde_json" 557 | version = "1.0.104" 558 | source = "registry+https://github.com/rust-lang/crates.io-index" 559 | checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" 560 | dependencies = [ 561 | "itoa", 562 | "ryu", 563 | "serde", 564 | ] 565 | 566 | [[package]] 567 | name = "smallvec" 568 | version = "1.11.0" 569 | source = "registry+https://github.com/rust-lang/crates.io-index" 570 | checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" 571 | 572 | [[package]] 573 | name = "syn" 574 | version = "1.0.109" 575 | source = "registry+https://github.com/rust-lang/crates.io-index" 576 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 577 | dependencies = [ 578 | "proc-macro2", 579 | "quote", 580 | "unicode-ident", 581 | ] 582 | 583 | [[package]] 584 | name = "syn" 585 | version = "2.0.28" 586 | source = "registry+https://github.com/rust-lang/crates.io-index" 587 | checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" 588 | dependencies = [ 589 | "proc-macro2", 590 | "quote", 591 | "unicode-ident", 592 | ] 593 | 594 | [[package]] 595 | name = "thread_local" 596 | version = "1.1.7" 597 | source = "registry+https://github.com/rust-lang/crates.io-index" 598 | checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" 599 | dependencies = [ 600 | "cfg-if", 601 | "once_cell", 602 | ] 603 | 604 | [[package]] 605 | name = "tinyvec" 606 | version = "1.6.0" 607 | source = "registry+https://github.com/rust-lang/crates.io-index" 608 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 609 | dependencies = [ 610 | "tinyvec_macros", 611 | ] 612 | 613 | [[package]] 614 | name = "tinyvec_macros" 615 | version = "0.1.1" 616 | source = "registry+https://github.com/rust-lang/crates.io-index" 617 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 618 | 619 | [[package]] 620 | name = "tstr" 621 | version = "0.2.3" 622 | source = "registry+https://github.com/rust-lang/crates.io-index" 623 | checksum = "cca3264971090dec0feef3b455a3c178f02762f7550cf4592991ac64b3be2d7e" 624 | dependencies = [ 625 | "tstr_proc_macros", 626 | ] 627 | 628 | [[package]] 629 | name = "tstr_proc_macros" 630 | version = "0.2.2" 631 | source = "registry+https://github.com/rust-lang/crates.io-index" 632 | checksum = "e78122066b0cb818b8afd08f7ed22f7fdbc3e90815035726f0840d0d26c0747a" 633 | 634 | [[package]] 635 | name = "typed-arena" 636 | version = "2.0.2" 637 | source = "registry+https://github.com/rust-lang/crates.io-index" 638 | checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" 639 | 640 | [[package]] 641 | name = "unicode-bidi" 642 | version = "0.3.13" 643 | source = "registry+https://github.com/rust-lang/crates.io-index" 644 | checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" 645 | 646 | [[package]] 647 | name = "unicode-ident" 648 | version = "1.0.11" 649 | source = "registry+https://github.com/rust-lang/crates.io-index" 650 | checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" 651 | 652 | [[package]] 653 | name = "unicode-normalization" 654 | version = "0.1.22" 655 | source = "registry+https://github.com/rust-lang/crates.io-index" 656 | checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" 657 | dependencies = [ 658 | "tinyvec", 659 | ] 660 | 661 | [[package]] 662 | name = "url" 663 | version = "2.4.1" 664 | source = "registry+https://github.com/rust-lang/crates.io-index" 665 | checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" 666 | dependencies = [ 667 | "form_urlencoded", 668 | "idna", 669 | "percent-encoding", 670 | ] 671 | 672 | [[package]] 673 | name = "utf8-width" 674 | version = "0.1.6" 675 | source = "registry+https://github.com/rust-lang/crates.io-index" 676 | checksum = "5190c9442dcdaf0ddd50f37420417d219ae5261bbf5db120d0f9bab996c9cba1" 677 | 678 | [[package]] 679 | name = "winapi" 680 | version = "0.3.9" 681 | source = "registry+https://github.com/rust-lang/crates.io-index" 682 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 683 | dependencies = [ 684 | "winapi-i686-pc-windows-gnu", 685 | "winapi-x86_64-pc-windows-gnu", 686 | ] 687 | 688 | [[package]] 689 | name = "winapi-i686-pc-windows-gnu" 690 | version = "0.4.0" 691 | source = "registry+https://github.com/rust-lang/crates.io-index" 692 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 693 | 694 | [[package]] 695 | name = "winapi-x86_64-pc-windows-gnu" 696 | version = "0.4.0" 697 | source = "registry+https://github.com/rust-lang/crates.io-index" 698 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 699 | 700 | [[package]] 701 | name = "windows-targets" 702 | version = "0.48.1" 703 | source = "registry+https://github.com/rust-lang/crates.io-index" 704 | checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" 705 | dependencies = [ 706 | "windows_aarch64_gnullvm", 707 | "windows_aarch64_msvc", 708 | "windows_i686_gnu", 709 | "windows_i686_msvc", 710 | "windows_x86_64_gnu", 711 | "windows_x86_64_gnullvm", 712 | "windows_x86_64_msvc", 713 | ] 714 | 715 | [[package]] 716 | name = "windows_aarch64_gnullvm" 717 | version = "0.48.0" 718 | source = "registry+https://github.com/rust-lang/crates.io-index" 719 | checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" 720 | 721 | [[package]] 722 | name = "windows_aarch64_msvc" 723 | version = "0.48.0" 724 | source = "registry+https://github.com/rust-lang/crates.io-index" 725 | checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" 726 | 727 | [[package]] 728 | name = "windows_i686_gnu" 729 | version = "0.48.0" 730 | source = "registry+https://github.com/rust-lang/crates.io-index" 731 | checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" 732 | 733 | [[package]] 734 | name = "windows_i686_msvc" 735 | version = "0.48.0" 736 | source = "registry+https://github.com/rust-lang/crates.io-index" 737 | checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" 738 | 739 | [[package]] 740 | name = "windows_x86_64_gnu" 741 | version = "0.48.0" 742 | source = "registry+https://github.com/rust-lang/crates.io-index" 743 | checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" 744 | 745 | [[package]] 746 | name = "windows_x86_64_gnullvm" 747 | version = "0.48.0" 748 | source = "registry+https://github.com/rust-lang/crates.io-index" 749 | checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" 750 | 751 | [[package]] 752 | name = "windows_x86_64_msvc" 753 | version = "0.48.0" 754 | source = "registry+https://github.com/rust-lang/crates.io-index" 755 | checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" 756 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "anyrun-nixos-options" 3 | version = "2.0.0" 4 | edition = "2021" 5 | description = "An anyrun plugin that lets you search NixOS options." 6 | 7 | [lib] 8 | crate-type = ["cdylib"] 9 | 10 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 11 | 12 | [dependencies] 13 | anyrun-plugin = { git = "https://github.com/Kirottu/anyrun" } 14 | abi_stable = "0.11.1" 15 | ron = "0.8.0" 16 | serde = { version = "1.0.163", features = ["derive"] } 17 | serde_json = "1.0.96" 18 | fuzzy-matcher = "0.3.7" 19 | html-escape = "0.2.13" 20 | regex = "1.9.1" 21 | open = "5.0.0" 22 | rayon = "1.7.0" 23 | serde-inline-default = "0.1.1" 24 | url = "2.4.1" 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # anyrun-nixos-options 2 | 3 | An anyrun plugin that lets you search NixOS options. 4 | 5 | # how 2 build? 6 | 7 | `nix build` 8 | ... or `cargo build` optionally :) 9 | 10 | # Configuration 11 | 12 | This plugin requires a config in your anyrun config directory called `nixos_options.ron`. 13 | The file looks like this: 14 | 15 | ```ron 16 | Config( 17 | options: {":prefix": ["/path/to/options.json"] }, // You can obtain NixOS's options.json using config.system.build.manual.optionsJSON 18 | min_score: 0, // Optional, the minimum score of entries to show. Set it to a larger value on slow machines. Default: 0 19 | nixpkgs_url: "https://github.com/NixOS/nixpkgs/blob/nixos-unstable", // Optional, URL to Nixpkgs tree. Set it to use the same branch as you're using. Defaults to the unstable url. 20 | max_entries: Some(10) // max_entries specific to this plugin. Set to None to disable 21 | ) 22 | ``` 23 | 24 | **Important: Make sure to set a `max_entries` either in your anyrun config, or in this plugin's config. Without that, the plugin will be VERY slow, since there exist over 16 thousand options to search through at the time of writing this.** 25 | **I have set mine to 10, since even that value is enough for it to go off-screen, so you shouldn't lose any data.** 26 | 27 | # Using this with NixOS? 28 | 29 | Under flakes, the following instructions will apply: 30 | 31 | 1. Use the [anyrun home-manager module](https://github.com/Kirottu/anyrun/blob/master/nix/hm-module.nix) 32 | 2. Add the plugin to your anyrun plugins list 33 | 34 | ```nix 35 | programs.anyrun.config = { 36 | # ... 37 | plugins = [ 38 | inputs.anyrun-nixos-options.packages.${pkgs.system}.default 39 | # other plugins that you might have 40 | ]; 41 | # ... 42 | }; 43 | ``` 44 | 45 | 3. Create a config file for it: 46 | 47 | ```nix 48 | # ↓ make sure osConfig is in the argument set 49 | {inputs, pkgs, osConfig, ...}: { 50 | programs.anyrun.extraConfigFiles."nixos-options.ron".text = let 51 | # ↓ home-manager refers to the nixos configuration as osConfig 52 | nixos-options = osConfig.system.build.manual.optionsJSON + "/share/doc/nixos/options.json"; 53 | # merge your options 54 | options = builtins.toJSON { 55 | ":nix" = [nixos-options]; 56 | }; 57 | # or alternatively if you wish to read any other documentation options, such as home-manager 58 | # get the docs-json package from the home-manager flake 59 | # hm-options = inputs.home-manager.packages.${pkgs.system}.docs-json + "/share/doc/home-manager/options.json"; 60 | # options = builtins.toJSON { 61 | # ":nix" = [nixos-options]; 62 | # ":hm" = [hm-options]; 63 | # ":something-else" = [some-other-option]; 64 | # ":nall" = [nixos-options hm-options some-other-option]; 65 | # }; 66 | 67 | in '' 68 | Config( 69 | // add your option paths 70 | options: ${options}, 71 | ) 72 | ''; 73 | } 74 | 75 | ``` 76 | 77 | 4. You are done. Rebuild your system and run anyrun as usual. `:nix` should bring up 78 | your NixOS (and any other configured) options 79 | 80 | Without flakes, inputs... generally should be changed to or depending on your usage. 81 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-parts": { 4 | "inputs": { 5 | "nixpkgs-lib": "nixpkgs-lib" 6 | }, 7 | "locked": { 8 | "lastModified": 1690933134, 9 | "narHash": "sha256-ab989mN63fQZBFrkk4Q8bYxQCktuHmBIBqUG1jl6/FQ=", 10 | "owner": "hercules-ci", 11 | "repo": "flake-parts", 12 | "rev": "59cf3f1447cfc75087e7273b04b31e689a8599fb", 13 | "type": "github" 14 | }, 15 | "original": { 16 | "owner": "hercules-ci", 17 | "repo": "flake-parts", 18 | "type": "github" 19 | } 20 | }, 21 | "nixpkgs": { 22 | "locked": { 23 | "lastModified": 1690031011, 24 | "narHash": "sha256-kzK0P4Smt7CL53YCdZCBbt9uBFFhE0iNvCki20etAf4=", 25 | "path": "/nix/store/gxw5rlp29swdpgz26vhaqzy21b9pxrim-source", 26 | "rev": "12303c652b881435065a98729eb7278313041e49", 27 | "type": "path" 28 | }, 29 | "original": { 30 | "id": "nixpkgs", 31 | "type": "indirect" 32 | } 33 | }, 34 | "nixpkgs-lib": { 35 | "locked": { 36 | "dir": "lib", 37 | "lastModified": 1690881714, 38 | "narHash": "sha256-h/nXluEqdiQHs1oSgkOOWF+j8gcJMWhwnZ9PFabN6q0=", 39 | "owner": "NixOS", 40 | "repo": "nixpkgs", 41 | "rev": "9e1960bc196baf6881340d53dccb203a951745a2", 42 | "type": "github" 43 | }, 44 | "original": { 45 | "dir": "lib", 46 | "owner": "NixOS", 47 | "ref": "nixos-unstable", 48 | "repo": "nixpkgs", 49 | "type": "github" 50 | } 51 | }, 52 | "root": { 53 | "inputs": { 54 | "flake-parts": "flake-parts", 55 | "nixpkgs": "nixpkgs" 56 | } 57 | } 58 | }, 59 | "root": "root", 60 | "version": 7 61 | } 62 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "An anyrun plugin that lets you search NixOS options."; 3 | 4 | inputs = { 5 | flake-parts.url = "github:hercules-ci/flake-parts"; 6 | }; 7 | 8 | outputs = inputs @ { 9 | nixpkgs, 10 | flake-parts, 11 | ... 12 | }: 13 | flake-parts.lib.mkFlake {inherit inputs;} { 14 | systems = [ 15 | "x86_64-linux" 16 | "aarch64-linux" 17 | ]; 18 | 19 | perSystem = { 20 | config, 21 | pkgs, 22 | ... 23 | }: rec { 24 | packages = rec { 25 | anyrun-nixos-options = pkgs.callPackage ./nix {}; 26 | default = anyrun-nixos-options; 27 | }; 28 | 29 | legacyPackages = packages; 30 | 31 | devShells.default = with pkgs; 32 | mkShell { 33 | buildInputs = [ 34 | cargo 35 | clippy 36 | rustc 37 | git 38 | rustfmt 39 | rust-analyzer 40 | ]; 41 | 42 | inputsFrom = [packages.default]; 43 | }; 44 | }; 45 | }; 46 | } 47 | -------------------------------------------------------------------------------- /nix/default.nix: -------------------------------------------------------------------------------- 1 | {rustPlatform}: 2 | rustPlatform.buildRustPackage { 3 | pname = "anyrun-nixos-options"; 4 | version = "0.1.0"; 5 | 6 | src = ../.; 7 | 8 | cargoLock = { 9 | lockFile = ../Cargo.lock; 10 | outputHashes."anyrun-interface-0.1.0" = "sha256-YrvbqM9WXr3/cgFVwc1EjIaQq4aI4DdrB1fhHfAW/d4="; 11 | }; 12 | } 13 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | use fuzzy_matcher::FuzzyMatcher; 2 | use serde_inline_default::serde_inline_default; 3 | use std::{ 4 | collections::HashMap, 5 | fs, 6 | sync::{Arc, Mutex}, 7 | }; 8 | 9 | use abi_stable::std_types::{ROption, RString, RVec}; 10 | use anyrun_plugin::*; 11 | use rayon::prelude::*; 12 | use serde::Deserialize; 13 | 14 | #[derive(Deserialize, Debug)] 15 | #[serde(rename = "Config")] 16 | pub struct AnyrunConfig { 17 | max_entries: Option, 18 | } 19 | 20 | #[serde_inline_default] 21 | #[derive(Deserialize, Debug)] 22 | pub struct Config { 23 | options: HashMap>, 24 | #[serde_inline_default(0)] 25 | min_score: i64, 26 | #[serde_inline_default("https://github.com/NixOS/nixpkgs/blob/nixos-unstable".to_string())] 27 | nixpkgs_url: String, 28 | max_entries: Option, 29 | } 30 | 31 | #[derive(Deserialize, Debug)] 32 | pub struct DefaultOrExample { 33 | #[serde(rename = "_type")] 34 | #[allow(unused)] 35 | r#type: String, 36 | text: String, 37 | } 38 | 39 | #[derive(Deserialize, Debug)] 40 | #[serde(untagged)] 41 | pub enum Declaration { 42 | NixOS(String), 43 | Nmd(NmdDeclaration), 44 | } 45 | 46 | #[derive(Deserialize, Debug)] 47 | pub struct NmdDeclaration { 48 | // #[serde(rename = "channelPath")] 49 | // channel_path: String, 50 | // path: String, 51 | url: String, 52 | } 53 | 54 | #[derive(Deserialize, Debug)] 55 | pub struct NixOSOption { 56 | declarations: Vec, 57 | description: Option, 58 | default: Option, 59 | example: Option, 60 | #[allow(unused)] 61 | loc: Vec, 62 | #[serde(rename = "readOnly")] 63 | #[allow(unused)] 64 | read_only: bool, 65 | r#type: String, 66 | } 67 | 68 | pub struct State { 69 | config: Config, 70 | options: HashMap>, 71 | anyrun_cfg: AnyrunConfig, 72 | } 73 | 74 | #[init] 75 | fn init(config_dir: RString) -> State { 76 | let content = 77 | fs::read_to_string(format!("{}/nixos-options.ron", config_dir)).unwrap_or_else(|why| { 78 | panic!( 79 | "Error reading anyrun-nixos-options config file ({}/nixos-options.ron).\n{}", 80 | config_dir, why 81 | ) 82 | }); 83 | 84 | let cfg: Config = ron::from_str(&content).unwrap(); 85 | 86 | let anyrun_content = fs::read_to_string(format!("{}/config.ron", config_dir)) 87 | .unwrap_or_else(|why| panic!("Error reading anyrun config file.\n{}", why)); 88 | 89 | let anyrun_cfg: AnyrunConfig = ron::from_str(&anyrun_content).unwrap(); 90 | 91 | if anyrun_cfg.max_entries.is_none() { 92 | println!("With the anyrun-nixos-options, it's recommended to set anyrun's `max_entries` to some small value."); 93 | } 94 | 95 | if let Some(max_entries) = anyrun_cfg.max_entries { 96 | if max_entries == 0 { 97 | println!("With the anyrun-nixos-options, it's recommended to set anyrun's `max_entries` to some small value."); 98 | } 99 | } 100 | 101 | let mut options: HashMap> = HashMap::new(); 102 | 103 | for option in &cfg.options { 104 | let mut hash_map: HashMap = HashMap::new(); 105 | 106 | for path in option.1 { 107 | let raw_options = fs::read_to_string(path).unwrap_or_else(|why| { 108 | panic!( 109 | "Error reading anyrun-nixos-options options file ({}).\n{}", 110 | path, why 111 | ) 112 | }); 113 | 114 | let parsed_options: HashMap = 115 | serde_json::from_str(&raw_options).unwrap(); 116 | 117 | hash_map.extend(parsed_options); 118 | } 119 | 120 | options.insert(option.0.clone(), hash_map); 121 | } 122 | 123 | State { 124 | config: cfg, 125 | options, 126 | anyrun_cfg, 127 | } 128 | } 129 | 130 | #[info] 131 | fn info() -> PluginInfo { 132 | PluginInfo { 133 | name: "NixOS Options".into(), 134 | icon: "go-home".into(), 135 | } 136 | } 137 | 138 | #[get_matches] 139 | fn get_matches(input: RString, state: &mut State) -> RVec { 140 | let results = Arc::new(Mutex::new(RVec::::new())); 141 | 142 | for option in &state.options { 143 | let prefix = option.0; 144 | 145 | let input = if let Some(input) = input.strip_prefix(prefix) { 146 | let trimmed = input.trim(); 147 | trimmed.replace(" ", ".") 148 | } else { 149 | continue; 150 | }; 151 | 152 | let matcher = fuzzy_matcher::skim::SkimMatcherV2::default().smart_case(); 153 | 154 | let mut entries = option 155 | .1 156 | .par_iter() 157 | .filter_map(|(key, query)| { 158 | let score = matcher.fuzzy_indices(&key, &input).unwrap_or((0, vec![])); 159 | 160 | if score.0 > state.config.min_score { 161 | Some((score, key, query)) 162 | } else { 163 | None 164 | } 165 | }) 166 | .collect::>(); 167 | 168 | entries.par_sort_unstable_by(|a, b| (b.0).0.cmp(&(a.0).0)); 169 | 170 | let plugin_max_entries = state.config.max_entries.unwrap_or(usize::MAX); 171 | let anyrun_max_entries = state.anyrun_cfg.max_entries.unwrap_or(usize::MAX); 172 | 173 | let max_entries = plugin_max_entries.min(anyrun_max_entries); 174 | 175 | entries.truncate(max_entries); 176 | 177 | let md_url_regex = regex::Regex::new(r#"\[([^\[]+)\](\(.*\))"#).unwrap(); 178 | let url_regex = 179 | regex::Regex::new(r#"<([^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})>"#).unwrap(); 180 | 181 | let file_regex = regex::Regex::new(r#"\{file\}`(.+?)`"#).unwrap(); 182 | let command_regex = regex::Regex::new(r#"\{command\}`(.+?)`"#).unwrap(); 183 | let option_regex = regex::Regex::new(r#"\{option\}`(.+?)`"#).unwrap(); 184 | let plain_url_regex = regex::Regex::new(r#"`(.+?)`"#).unwrap(); 185 | 186 | let res = results.clone(); 187 | 188 | entries.par_iter().for_each(move |entry| { 189 | let mut description = if let Some(desc) = &entry.2.description { 190 | let encoded_desc = html_escape::encode_text(desc); 191 | 192 | let url_parsed = url_regex.replace_all(&encoded_desc, |caps: ®ex::Captures| { 193 | format!(r#"{}"#, &caps[1]) 194 | }); 195 | 196 | let md_parsed = md_url_regex.replace_all(&url_parsed, |caps: ®ex::Captures| { 197 | format!(r#"{}"#, &caps[1]) 198 | }); 199 | 200 | let file_parsed = file_regex.replace_all(&md_parsed, |caps: ®ex::Captures| { 201 | format!(r#"{}"#, &caps[1]) 202 | }); 203 | 204 | let command_parsed = 205 | command_regex.replace_all(&file_parsed, |caps: ®ex::Captures| { 206 | format!(r#"{}"#, &caps[1]) 207 | }); 208 | 209 | let option_parsed = 210 | option_regex.replace_all(&command_parsed, |caps: ®ex::Captures| { 211 | format!( 212 | r#"{}"#, 213 | &caps[1] 214 | ) 215 | }); 216 | 217 | let plain_url_parsed = 218 | plain_url_regex.replace_all(&option_parsed, |caps: ®ex::Captures| { 219 | format!(r#"{}"#, &caps[1]) 220 | }); 221 | 222 | plain_url_parsed.trim().to_string() 223 | } else { 224 | "".to_string() 225 | }; 226 | 227 | description.push_str(&format!( 228 | "\n\nType: {}", 229 | html_escape::encode_text(&entry.2.r#type), 230 | )); 231 | 232 | if let Some(default) = &entry.2.default { 233 | description.push_str(&format!( 234 | "\nDefault:{}{}", 235 | if default.text.contains("\n") { 236 | "\n" 237 | } else { 238 | " " 239 | }, 240 | html_escape::encode_text(&default.text) 241 | )) 242 | } 243 | 244 | if let Some(example) = &entry.2.example { 245 | description.push_str(&format!( 246 | "\nExample:{}{}", 247 | if example.text.contains("\n") { 248 | "\n" 249 | } else { 250 | " " 251 | }, 252 | html_escape::encode_text(&example.text) 253 | )) 254 | } 255 | 256 | let mut title = String::new(); 257 | 258 | let mut iterator = entry.1.chars().enumerate().peekable(); 259 | 260 | let mut is_red = false; 261 | 262 | while let Some((i, char)) = iterator.next() { 263 | if entry.0 .1.contains(&i) { 264 | if !is_red { 265 | title.push_str(&format!("")); 266 | is_red = true; 267 | } 268 | 269 | title.push_str(&html_escape::encode_text(&char.to_string())); 270 | 271 | if let Some(next) = iterator.peek() { 272 | if !entry.0 .1.contains(&next.0) { 273 | title.push_str(""); 274 | is_red = false; 275 | } 276 | } 277 | } else { 278 | title.push_str(&html_escape::encode_text(&char.to_string())); 279 | } 280 | } 281 | if is_red { 282 | title.push_str(""); 283 | } 284 | 285 | res.lock().unwrap().push(Match { 286 | title: format!(r#"{}"#, title).into(), 287 | description: ROption::RSome(description.trim().into()), 288 | icon: ROption::RNone, 289 | id: ROption::RNone, 290 | use_pango: true, 291 | }) 292 | }); 293 | } 294 | 295 | Arc::try_unwrap(results) 296 | .unwrap_or_else(|_| panic!("Failed to get results")) 297 | .into_inner() 298 | .unwrap() 299 | } 300 | 301 | #[handler] 302 | fn handler(selection: Match, state: &mut State) -> HandleResult { 303 | let span_regex = 304 | regex::Regex::new(r##"(.+?)"##).unwrap(); 305 | 306 | let key = span_regex 307 | .replace_all(&selection.title, |caps: ®ex::Captures| { 308 | caps[1].to_string() 309 | }) 310 | .to_string(); 311 | 312 | let key_with_no_monospace = &key[30..key.len() - 7]; 313 | 314 | for option in &state.options { 315 | let value = option.1.get(&key_with_no_monospace.to_string()); 316 | 317 | if let Some(value) = value { 318 | for declaration in &value.declarations { 319 | let url = match declaration { 320 | Declaration::NixOS(v) => v, 321 | Declaration::Nmd(v) => &v.url, 322 | }; 323 | 324 | let parsed_url = url::Url::parse(url); 325 | 326 | let final_url = match parsed_url { 327 | Ok(_) => url.clone(), 328 | Err(_) => format!("{}/{}", state.config.nixpkgs_url.clone(), url), 329 | }; 330 | 331 | open::that(final_url).ok(); 332 | } 333 | return HandleResult::Close; 334 | } 335 | } 336 | 337 | return HandleResult::Refresh(false); 338 | } 339 | --------------------------------------------------------------------------------