Refinement, plugins, etc.
This commit is contained in:
699
Cargo.lock
generated
699
Cargo.lock
generated
@@ -50,6 +50,15 @@ dependencies = [
|
||||
"core_extensions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.68"
|
||||
@@ -64,8 +73,10 @@ dependencies = [
|
||||
"anyrun-interface",
|
||||
"gtk",
|
||||
"gtk-layer-shell",
|
||||
"nix 0.26.1",
|
||||
"ron",
|
||||
"serde",
|
||||
"wl-clipboard-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -89,6 +100,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"abi_stable",
|
||||
"anyrun-plugin",
|
||||
"fuzzy-matcher",
|
||||
"sublime_fuzzy",
|
||||
]
|
||||
|
||||
@@ -146,6 +158,18 @@ version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
|
||||
|
||||
[[package]]
|
||||
name = "bytecount"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c"
|
||||
|
||||
[[package]]
|
||||
name = "cairo-rs"
|
||||
version = "0.16.7"
|
||||
@@ -171,6 +195,12 @@ dependencies = [
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-expr"
|
||||
version = "0.11.0"
|
||||
@@ -192,12 +222,62 @@ version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f"
|
||||
dependencies = [
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"time",
|
||||
"wasm-bindgen",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "chrono-humanize"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8164ae3089baf04ff71f32aeb70213283dcd236dce8bc976d00b17a458f5f71c"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "chrono-tz"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2554a3155fec064362507487171dcc4edc3df60cb10f3a1fb10ed8094822b120"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"parse-zoneinfo",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codespan-reporting"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
|
||||
dependencies = [
|
||||
"termcolor",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const_panic"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58baae561b85ca19b3122a9ddd35c8ec40c3bcd14fe89921824eae73f7baffbf"
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
|
||||
|
||||
[[package]]
|
||||
name = "core_extensions"
|
||||
version = "1.5.3"
|
||||
@@ -232,6 +312,76 @@ dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cxx"
|
||||
version = "1.0.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5add3fc1717409d029b20c5b6903fc0c0b02fa6741d820054f4a2efa5e5816fd"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cxxbridge-flags",
|
||||
"cxxbridge-macro",
|
||||
"link-cplusplus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cxx-build"
|
||||
version = "1.0.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4c87959ba14bc6fbc61df77c3fcfe180fc32b93538c4f1031dd802ccb5f2ff0"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"codespan-reporting",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"scratch",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cxxbridge-flags"
|
||||
version = "1.0.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69a3e162fde4e594ed2b07d0f83c6c67b745e7f28ce58c6df5e6b6bef99dfb59"
|
||||
|
||||
[[package]]
|
||||
name = "cxxbridge-macro"
|
||||
version = "1.0.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e7e2adeb6a0d4a282e581096b06e1791532b7d576dcde5ccd9382acf55db8e6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive-new"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3418329ca0ad70234b9735dc4ceed10af4df60eff9c8e7b06cb5e520d92c3535"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "downcast-rs"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499"
|
||||
dependencies = [
|
||||
"instant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "field-offset"
|
||||
version = "0.3.4"
|
||||
@@ -242,6 +392,18 @@ dependencies = [
|
||||
"rustc_version 0.3.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fixedbitset"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.25"
|
||||
@@ -305,6 +467,15 @@ dependencies = [
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuzzy-matcher"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94"
|
||||
dependencies = [
|
||||
"thread_local",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gdk"
|
||||
version = "0.16.2"
|
||||
@@ -547,18 +718,82 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.53"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone-haiku"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca"
|
||||
dependencies = [
|
||||
"cxx",
|
||||
"cxx-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.139"
|
||||
@@ -575,6 +810,15 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "link-cplusplus"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.9"
|
||||
@@ -585,6 +829,21 @@ dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.5"
|
||||
@@ -594,12 +853,141 @@ dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.24.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"memoffset",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.26.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46a58d1d356c6597d08cde02c2f09d785b09e28711837b1ed667dc652c08a694"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-complex",
|
||||
"num-integer",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ae39348c8bc5fbd7f40c727a9925f03517afd2ab27d46702108b6a7e5414c19"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-bigint",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
|
||||
|
||||
[[package]]
|
||||
name = "os_pipe"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6a252f1f8c11e84b3ab59d7a488e48e4478a93937e027076638c49536204639"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pango"
|
||||
version = "0.16.5"
|
||||
@@ -649,6 +1037,15 @@ dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parse-zoneinfo"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41"
|
||||
dependencies = [
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.11"
|
||||
@@ -665,6 +1062,16 @@ dependencies = [
|
||||
"ucd-trie",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "petgraph"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143"
|
||||
dependencies = [
|
||||
"fixedbitset",
|
||||
"indexmap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.9"
|
||||
@@ -745,6 +1152,30 @@ dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a"
|
||||
dependencies = [
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
|
||||
|
||||
[[package]]
|
||||
name = "remove_dir_all"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "repr_offset"
|
||||
version = "0.2.1"
|
||||
@@ -754,6 +1185,30 @@ dependencies = [
|
||||
"tstr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rink"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"abi_stable",
|
||||
"anyrun-plugin",
|
||||
"rink-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rink-core"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f583576891114abaf8e057cc86f4f59a1835e1511877a96c3b4a2e0719f60b9"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"chrono-humanize",
|
||||
"chrono-tz",
|
||||
"num",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"strsim",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ron"
|
||||
version = "0.8.0"
|
||||
@@ -795,6 +1250,12 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "scratch"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.11.0"
|
||||
@@ -821,18 +1282,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.151"
|
||||
version = "1.0.152"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97fed41fc1a24994d044e6db6935e69511a1153b52c15eb42493b26fa87feba0"
|
||||
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.151"
|
||||
version = "1.0.152"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "255abe9a125a985c05190d687b320c12f9b1f0b99445e608c21ba0782c719ad8"
|
||||
checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -865,6 +1326,18 @@ version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "sublime_fuzzy"
|
||||
version = "0.7.0"
|
||||
@@ -877,6 +1350,9 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"abi_stable",
|
||||
"anyrun-plugin",
|
||||
"fuzzy-matcher",
|
||||
"ron",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -903,6 +1379,29 @@ dependencies = [
|
||||
"version-compare",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"fastrand",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"remove_dir_all",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.38"
|
||||
@@ -923,6 +1422,26 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.10"
|
||||
@@ -932,6 +1451,20 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree_magic_mini"
|
||||
version = "3.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91adfd0607cacf6e4babdb870e9bec4037c1c4b151cfd279ccefc5e0c7feaa6d"
|
||||
dependencies = [
|
||||
"bytecount",
|
||||
"fnv",
|
||||
"lazy_static",
|
||||
"nom",
|
||||
"once_cell",
|
||||
"petgraph",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tstr"
|
||||
version = "0.2.3"
|
||||
@@ -965,6 +1498,12 @@ version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||
|
||||
[[package]]
|
||||
name = "version-compare"
|
||||
version = "0.1.1"
|
||||
@@ -978,11 +1517,122 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "web-search"
|
||||
version = "0.1.0"
|
||||
name = "wasi"
|
||||
version = "0.10.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
|
||||
dependencies = [
|
||||
"abi_stable",
|
||||
"anyrun-plugin",
|
||||
"cfg-if 1.0.0",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
|
||||
|
||||
[[package]]
|
||||
name = "wayland-client"
|
||||
version = "0.29.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"downcast-rs",
|
||||
"libc",
|
||||
"nix 0.24.3",
|
||||
"wayland-commons",
|
||||
"wayland-scanner",
|
||||
"wayland-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-commons"
|
||||
version = "0.29.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902"
|
||||
dependencies = [
|
||||
"nix 0.24.3",
|
||||
"once_cell",
|
||||
"smallvec",
|
||||
"wayland-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-protocols"
|
||||
version = "0.29.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"wayland-client",
|
||||
"wayland-commons",
|
||||
"wayland-scanner",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-scanner"
|
||||
version = "0.29.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"xml-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-sys"
|
||||
version = "0.29.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be12ce1a3c39ec7dba25594b97b42cb3195d54953ddb9d3d95a7c3902bc6e9d4"
|
||||
dependencies = [
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1001,6 +1651,15 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
@@ -1063,3 +1722,27 @@ name = "windows_x86_64_msvc"
|
||||
version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
|
||||
|
||||
[[package]]
|
||||
name = "wl-clipboard-rs"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "981a303dfbb75d659f6612d05a14b2e363c103d24f676a2d44a00d18507a1ad9"
|
||||
dependencies = [
|
||||
"derive-new",
|
||||
"libc",
|
||||
"log",
|
||||
"nix 0.24.3",
|
||||
"os_pipe",
|
||||
"tempfile",
|
||||
"thiserror",
|
||||
"tree_magic_mini",
|
||||
"wayland-client",
|
||||
"wayland-protocols",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xml-rs"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3"
|
||||
|
@@ -5,5 +5,5 @@ members = [
|
||||
"anyrun-interface",
|
||||
"plugins/applications",
|
||||
"plugins/symbols",
|
||||
"plugins/web-search",
|
||||
"plugins/rink",
|
||||
]
|
5
README.md
Normal file
5
README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# AnyRun
|
||||
|
||||
A wayland native krunner-like runner, made with customizability in mind.
|
||||
|
||||
|
@@ -29,15 +29,18 @@ pub struct PluginInfo {
|
||||
}
|
||||
|
||||
/// Represents a match from a plugin
|
||||
///
|
||||
/// The `title` and `description` support pango markup.
|
||||
/// Refer to [Pango Markup](https://docs.gtk.org/Pango/pango_markup.html) for how to use pango markup.
|
||||
#[repr(C)]
|
||||
#[derive(StableAbi, Clone)]
|
||||
pub struct Match {
|
||||
pub title: RString,
|
||||
pub description: ROption<RString>,
|
||||
/// The icon name from the icon theme in use
|
||||
pub icon: RString,
|
||||
/// For runners to differentiate between the matches.
|
||||
pub id: u64,
|
||||
pub icon: ROption<RString>,
|
||||
/// For runners to differentiate between the matches. Not required.
|
||||
pub id: ROption<u64>,
|
||||
}
|
||||
|
||||
/// For determining how anyrun should proceed after the plugin has handled a match selection
|
||||
@@ -48,6 +51,8 @@ pub enum HandleResult {
|
||||
Close,
|
||||
/// Refresh the items. Useful if the runner wants to alter results in place.
|
||||
Refresh,
|
||||
/// Copy the content, due to how copying works it must be done like this.
|
||||
Copy(RVec<u8>),
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
@@ -6,9 +6,8 @@ for integrating with `stable_abi`.
|
||||
|
||||
# Arguments
|
||||
|
||||
* `$init`: Function that takes an `RString` as the only argument, which points to the anyrun config directory. It returns nothing.
|
||||
The path is used for plugin specific config files.
|
||||
**NOTE**: Should not block or block for a long time. If this blocks the main thread will too.
|
||||
* `$init`: Function that takes an `RString` as the only argument, which points to the anyrun config directory. Returns the data
|
||||
the plugin operates on.
|
||||
|
||||
* `$info`: Function that returns the plugin info as a `PluginInfo` object. Takes no arguments.
|
||||
|
||||
@@ -17,85 +16,100 @@ This is run asynchronously automatically.
|
||||
|
||||
* `$handler`: The function to handle the selection of an item. Takes a `Match` as it's only argument and returns a `HandleResult` with
|
||||
the appropriate action.
|
||||
|
||||
* `$type`: The type of the shared data to be provided to various functions.
|
||||
**/
|
||||
#[macro_export]
|
||||
macro_rules! plugin {
|
||||
($init:ident, $info:ident, $get_matches:ident, $handler:ident) => {
|
||||
mod anyrun_plugin_internal {
|
||||
static THREAD: ::std::sync::Mutex<
|
||||
Option<(
|
||||
::std::thread::JoinHandle<
|
||||
::abi_stable::std_types::RVec<::anyrun_plugin::anyrun_interface::Match>,
|
||||
>,
|
||||
u64,
|
||||
)>,
|
||||
> = ::std::sync::Mutex::new(None);
|
||||
static ID_COUNTER: ::std::sync::atomic::AtomicU64 =
|
||||
::std::sync::atomic::AtomicU64::new(0);
|
||||
($init:ident, $info:ident, $get_matches:ident, $handler:ident, $type:ty) => {
|
||||
static ANYRUN_INTERNAL_THREAD: ::std::sync::Mutex<
|
||||
Option<(
|
||||
::std::thread::JoinHandle<
|
||||
::abi_stable::std_types::RVec<::anyrun_plugin::anyrun_interface::Match>,
|
||||
>,
|
||||
u64,
|
||||
)>,
|
||||
> = ::std::sync::Mutex::new(None);
|
||||
static ANYRUN_INTERNAL_ID_COUNTER: ::std::sync::atomic::AtomicU64 =
|
||||
::std::sync::atomic::AtomicU64::new(0);
|
||||
static ANYRUN_INTERNAL_DATA: ::std::sync::Mutex<Option<$type>> =
|
||||
::std::sync::Mutex::new(None);
|
||||
|
||||
#[::abi_stable::export_root_module]
|
||||
fn init_root_module() -> ::anyrun_plugin::anyrun_interface::PluginRef {
|
||||
use ::abi_stable::prefix_type::PrefixTypeTrait;
|
||||
::anyrun_plugin::anyrun_interface::Plugin {
|
||||
init,
|
||||
info,
|
||||
get_matches,
|
||||
poll_matches,
|
||||
handle_selection,
|
||||
#[::abi_stable::export_root_module]
|
||||
fn anyrun_internal_init_root_module() -> ::anyrun_plugin::anyrun_interface::PluginRef {
|
||||
use ::abi_stable::prefix_type::PrefixTypeTrait;
|
||||
::anyrun_plugin::anyrun_interface::Plugin {
|
||||
init: anyrun_internal_init,
|
||||
info: anyrun_internal_info,
|
||||
get_matches: anyrun_internal_get_matches,
|
||||
poll_matches: anyrun_internal_poll_matches,
|
||||
handle_selection: anyrun_internal_handle_selection,
|
||||
}
|
||||
.leak_into_prefix()
|
||||
}
|
||||
|
||||
#[::abi_stable::sabi_extern_fn]
|
||||
fn anyrun_internal_init(config_dir: ::abi_stable::std_types::RString) {
|
||||
::std::thread::spawn(|| {
|
||||
*ANYRUN_INTERNAL_DATA.lock().unwrap() = Some($init(config_dir));
|
||||
});
|
||||
}
|
||||
|
||||
#[::abi_stable::sabi_extern_fn]
|
||||
fn anyrun_internal_info() -> ::anyrun_plugin::anyrun_interface::PluginInfo {
|
||||
$info()
|
||||
}
|
||||
|
||||
#[::abi_stable::sabi_extern_fn]
|
||||
fn anyrun_internal_get_matches(input: ::abi_stable::std_types::RString) -> u64 {
|
||||
let current_id =
|
||||
ANYRUN_INTERNAL_ID_COUNTER.load(::std::sync::atomic::Ordering::Relaxed);
|
||||
ANYRUN_INTERNAL_ID_COUNTER
|
||||
.store(current_id + 1, ::std::sync::atomic::Ordering::Relaxed);
|
||||
|
||||
let handle = ::std::thread::spawn(move || {
|
||||
if let Some(data) = ANYRUN_INTERNAL_DATA.lock().unwrap().as_mut() {
|
||||
$get_matches(input, data)
|
||||
} else {
|
||||
::abi_stable::std_types::RVec::new()
|
||||
}
|
||||
.leak_into_prefix()
|
||||
}
|
||||
});
|
||||
|
||||
#[::abi_stable::sabi_extern_fn]
|
||||
fn init(config_dir: ::abi_stable::std_types::RString) {
|
||||
super::$init(config_dir);
|
||||
}
|
||||
*ANYRUN_INTERNAL_THREAD.lock().unwrap() = Some((handle, current_id));
|
||||
|
||||
#[::abi_stable::sabi_extern_fn]
|
||||
fn info() -> ::anyrun_plugin::anyrun_interface::PluginInfo {
|
||||
super::$info()
|
||||
}
|
||||
current_id
|
||||
}
|
||||
|
||||
#[::abi_stable::sabi_extern_fn]
|
||||
fn get_matches(input: ::abi_stable::std_types::RString) -> u64 {
|
||||
let current_id = ID_COUNTER.load(::std::sync::atomic::Ordering::Relaxed);
|
||||
ID_COUNTER.store(current_id + 1, ::std::sync::atomic::Ordering::Relaxed);
|
||||
|
||||
let handle = ::std::thread::spawn(move || super::$get_matches(input));
|
||||
|
||||
*THREAD.lock().unwrap() = Some((handle, current_id));
|
||||
|
||||
current_id
|
||||
}
|
||||
|
||||
#[::abi_stable::sabi_extern_fn]
|
||||
fn poll_matches(id: u64) -> ::anyrun_plugin::anyrun_interface::PollResult {
|
||||
match THREAD.try_lock() {
|
||||
Ok(thread) => match thread.as_ref() {
|
||||
Some((thread, task_id)) => {
|
||||
if *task_id == id {
|
||||
if !thread.is_finished() {
|
||||
return ::anyrun_plugin::anyrun_interface::PollResult::Pending;
|
||||
}
|
||||
} else {
|
||||
return ::anyrun_plugin::anyrun_interface::PollResult::Cancelled;
|
||||
#[::abi_stable::sabi_extern_fn]
|
||||
fn anyrun_internal_poll_matches(id: u64) -> ::anyrun_plugin::anyrun_interface::PollResult {
|
||||
match ANYRUN_INTERNAL_THREAD.try_lock() {
|
||||
Ok(thread) => match thread.as_ref() {
|
||||
Some((thread, task_id)) => {
|
||||
if *task_id == id {
|
||||
if !thread.is_finished() {
|
||||
return ::anyrun_plugin::anyrun_interface::PollResult::Pending;
|
||||
}
|
||||
} else {
|
||||
return ::anyrun_plugin::anyrun_interface::PollResult::Cancelled;
|
||||
}
|
||||
None => return ::anyrun_plugin::anyrun_interface::PollResult::Cancelled,
|
||||
},
|
||||
Err(_) => return ::anyrun_plugin::anyrun_interface::PollResult::Pending,
|
||||
}
|
||||
|
||||
let (thread, _) = THREAD.lock().unwrap().take().unwrap();
|
||||
::anyrun_plugin::anyrun_interface::PollResult::Ready(thread.join().unwrap())
|
||||
}
|
||||
None => return ::anyrun_plugin::anyrun_interface::PollResult::Cancelled,
|
||||
},
|
||||
Err(_) => return ::anyrun_plugin::anyrun_interface::PollResult::Pending,
|
||||
}
|
||||
|
||||
#[::abi_stable::sabi_extern_fn]
|
||||
fn handle_selection(
|
||||
selection: ::anyrun_plugin::anyrun_interface::Match,
|
||||
) -> ::anyrun_plugin::anyrun_interface::HandleResult {
|
||||
super::$handler(selection)
|
||||
}
|
||||
let (thread, _) = ANYRUN_INTERNAL_THREAD.lock().unwrap().take().unwrap();
|
||||
::anyrun_plugin::anyrun_interface::PollResult::Ready(thread.join().unwrap())
|
||||
}
|
||||
|
||||
#[::abi_stable::sabi_extern_fn]
|
||||
fn anyrun_internal_handle_selection(
|
||||
selection: ::anyrun_plugin::anyrun_interface::Match,
|
||||
) -> ::anyrun_plugin::anyrun_interface::HandleResult {
|
||||
$handler(
|
||||
selection,
|
||||
ANYRUN_INTERNAL_DATA.lock().unwrap().as_mut().unwrap(),
|
||||
)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@@ -12,3 +12,5 @@ gtk-layer-shell = { version = "0.5.0", features = ["v0_6"] }
|
||||
ron = "0.8.0"
|
||||
serde = { version = "1.0.151", features = ["derive"] }
|
||||
anyrun-interface = { path = "../anyrun-interface" }
|
||||
wl-clipboard-rs = "0.7.0"
|
||||
nix = { version = "0.26.1", default-features = false, features = ["process"] }
|
||||
|
@@ -1,15 +1,11 @@
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
env, fs,
|
||||
path::{Path, PathBuf},
|
||||
rc::Rc,
|
||||
time::Duration,
|
||||
};
|
||||
use std::{cell::RefCell, env, fs, path::PathBuf, rc::Rc, time::Duration};
|
||||
|
||||
use abi_stable::std_types::{ROption, RVec};
|
||||
use gtk::{gdk, glib, prelude::*};
|
||||
use serde::Deserialize;
|
||||
use anyrun_interface::{HandleResult, Match, PluginInfo, PluginRef, PollResult};
|
||||
use gtk::{gdk, glib, prelude::*};
|
||||
use nix::unistd;
|
||||
use serde::Deserialize;
|
||||
use wl_clipboard_rs::copy;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct Config {
|
||||
@@ -17,6 +13,7 @@ struct Config {
|
||||
plugins: Vec<PathBuf>,
|
||||
}
|
||||
|
||||
/// A "view" of plugin's info and matches
|
||||
#[derive(Clone)]
|
||||
struct PluginView {
|
||||
plugin: PluginRef,
|
||||
@@ -29,11 +26,32 @@ struct Args {
|
||||
config_dir: Option<String>,
|
||||
}
|
||||
|
||||
/// Actions to run after GTK has finished
|
||||
enum PostRunAction {
|
||||
Copy(Vec<u8>),
|
||||
None,
|
||||
}
|
||||
|
||||
/// Some data that needs to be shared between various parts
|
||||
struct RuntimeData {
|
||||
args: Args,
|
||||
post_run_action: PostRunAction,
|
||||
}
|
||||
|
||||
/// The naming scheme for CSS styling
|
||||
///
|
||||
/// Refer to [GTK 3.0 CSS Overview](https://docs.gtk.org/gtk3/css-overview.html)
|
||||
/// and [GTK 3.0 CSS Properties](https://docs.gtk.org/gtk3/css-properties.html) for how to style.
|
||||
mod style_names {
|
||||
/// The text entry box
|
||||
pub const ENTRY: &str = "entry";
|
||||
/// "Main" widgets (main GtkListBox, main GtkBox)
|
||||
pub const MAIN: &str = "main";
|
||||
/// The window
|
||||
pub const WINDOW: &str = "window";
|
||||
/// Widgets related to the whole plugin. Including the info box
|
||||
pub const PLUGIN: &str = "plugin";
|
||||
/// Widgets for the specific match `MATCH_*` names are for more specific parts.
|
||||
pub const MATCH: &str = "match";
|
||||
|
||||
pub const MATCH_TITLE: &str = "match-title";
|
||||
@@ -43,8 +61,9 @@ mod style_names {
|
||||
|
||||
fn main() {
|
||||
let app = gtk::Application::new(Some("com.kirottu.anyrun"), Default::default());
|
||||
let args: Rc<RefCell<Option<Args>>> = Rc::new(RefCell::new(None));
|
||||
let runtime_data: Rc<RefCell<Option<RuntimeData>>> = Rc::new(RefCell::new(None));
|
||||
|
||||
// Add the launch options to the GTK Application
|
||||
app.add_main_option(
|
||||
"override-plugins",
|
||||
glib::Char('o' as i8),
|
||||
@@ -62,30 +81,60 @@ fn main() {
|
||||
None,
|
||||
);
|
||||
|
||||
let args_clone = args.clone();
|
||||
let runtime_data_clone = runtime_data.clone();
|
||||
app.connect_handle_local_options(move |_app, dict| {
|
||||
let override_plugins = dict.lookup::<Vec<String>>("override-plugins").unwrap();
|
||||
let config_dir = dict.lookup::<String>("config-dir").unwrap();
|
||||
|
||||
*args_clone.borrow_mut() = Some(Args {
|
||||
override_plugins,
|
||||
config_dir,
|
||||
*runtime_data_clone.borrow_mut() = Some(RuntimeData {
|
||||
args: Args {
|
||||
override_plugins,
|
||||
config_dir,
|
||||
},
|
||||
post_run_action: PostRunAction::None,
|
||||
});
|
||||
-1 // Magic GTK number to continue running
|
||||
});
|
||||
|
||||
let args_clone = args.clone();
|
||||
app.connect_activate(move |app| activate(app, args_clone.clone()));
|
||||
let runtime_data_clone = runtime_data.clone();
|
||||
app.connect_activate(move |app| activate(app, runtime_data_clone.clone()));
|
||||
|
||||
app.run();
|
||||
|
||||
let runtime_data = runtime_data.borrow_mut().take().unwrap();
|
||||
|
||||
// Perform a post run action if one is set
|
||||
match runtime_data.post_run_action {
|
||||
PostRunAction::Copy(bytes) => match unsafe { unistd::fork() } {
|
||||
// The parent process just exits and prints that out
|
||||
Ok(unistd::ForkResult::Parent { .. }) => {
|
||||
println!("Child spawned to serve copy requests.");
|
||||
}
|
||||
// Child process starts serving copy requests
|
||||
Ok(unistd::ForkResult::Child) => {
|
||||
let mut opts = copy::Options::new();
|
||||
opts.foreground(true);
|
||||
opts.copy(
|
||||
copy::Source::Bytes(bytes.into_boxed_slice()),
|
||||
copy::MimeType::Autodetect,
|
||||
)
|
||||
.expect("Failed to serve copy bytes");
|
||||
}
|
||||
Err(why) => {
|
||||
println!("Failed to fork for copy sharing: {}", why);
|
||||
}
|
||||
},
|
||||
PostRunAction::None => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn activate(app: >k::Application, args: Rc<RefCell<Option<Args>>>) {
|
||||
fn activate(app: >k::Application, runtime_data: Rc<RefCell<Option<RuntimeData>>>) {
|
||||
// Figure out the config dir
|
||||
let config_dir = args
|
||||
let config_dir = runtime_data
|
||||
.borrow()
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.args
|
||||
.config_dir
|
||||
.clone()
|
||||
.unwrap_or(format!(
|
||||
@@ -127,13 +176,19 @@ fn activate(app: >k::Application, args: Rc<RefCell<Option<Args>>>) {
|
||||
);
|
||||
|
||||
// Use the plugins in the config file, or the plugins specified with the override
|
||||
let plugins = match &args.borrow().as_ref().unwrap().override_plugins {
|
||||
Some(plugins) => plugins.iter().map(|path| PathBuf::from(path)).collect(),
|
||||
let plugins = match &runtime_data
|
||||
.borrow()
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.args
|
||||
.override_plugins
|
||||
{
|
||||
Some(plugins) => plugins.iter().map(PathBuf::from).collect(),
|
||||
None => config.plugins,
|
||||
};
|
||||
|
||||
// Make sure at least one plugin is specified
|
||||
if plugins.len() == 0 {
|
||||
if plugins.is_empty() {
|
||||
println!("At least one plugin needs to be enabled!");
|
||||
app.quit();
|
||||
}
|
||||
@@ -199,10 +254,10 @@ fn activate(app: >k::Application, args: Rc<RefCell<Option<Args>>>) {
|
||||
for plugin_view in plugins.iter() {
|
||||
let plugins_clone = plugins.clone();
|
||||
plugin_view.list.connect_row_selected(move |list, row| {
|
||||
if let Some(_) = row {
|
||||
if row.is_some() {
|
||||
let combined_matches = plugins_clone
|
||||
.iter()
|
||||
.map(|view| {
|
||||
.flat_map(|view| {
|
||||
view.list.children().into_iter().map(|child| {
|
||||
(
|
||||
child.dynamic_cast::<gtk::ListBoxRow>().unwrap(),
|
||||
@@ -210,9 +265,9 @@ fn activate(app: >k::Application, args: Rc<RefCell<Option<Args>>>) {
|
||||
)
|
||||
})
|
||||
})
|
||||
.flatten()
|
||||
.collect::<Vec<(gtk::ListBoxRow, gtk::ListBox)>>();
|
||||
|
||||
// Unselect everything except the new selection
|
||||
for (_, _list) in combined_matches {
|
||||
if _list != *list {
|
||||
_list.select_row(None::<>k::ListBoxRow>);
|
||||
@@ -237,50 +292,61 @@ fn activate(app: >k::Application, args: Rc<RefCell<Option<Args>>>) {
|
||||
|
||||
// Handle other key presses for selection control and all other things that may be needed
|
||||
let entry_clone = entry.clone();
|
||||
let plugins_clone = plugins.clone();
|
||||
window.connect_key_press_event(move |window, event| {
|
||||
use gdk::keys::constants;
|
||||
match event.keyval() {
|
||||
// Close window on escape
|
||||
constants::Escape => {
|
||||
window.close();
|
||||
Inhibit(true)
|
||||
}
|
||||
// Handle selections
|
||||
constants::Down | constants::Tab | constants::Up => {
|
||||
let combined_matches = plugins_clone
|
||||
// Combine all of the matches into a `Vec` to allow for easier handling of the selection
|
||||
let combined_matches = plugins
|
||||
.iter()
|
||||
.map(|view| {
|
||||
.flat_map(|view| {
|
||||
view.list.children().into_iter().map(|child| {
|
||||
(
|
||||
// All children of lists are GtkListBoxRow widgets
|
||||
child.dynamic_cast::<gtk::ListBoxRow>().unwrap(),
|
||||
view.list.clone(),
|
||||
)
|
||||
})
|
||||
})
|
||||
.flatten()
|
||||
.collect::<Vec<(gtk::ListBoxRow, gtk::ListBox)>>();
|
||||
|
||||
let (selected_match, selected_list) = match plugins_clone
|
||||
// Get the selected match
|
||||
let (selected_match, selected_list) = match plugins
|
||||
.iter()
|
||||
.find_map(|view| view.list.selected_row().map(|row| (row, view.list.clone())))
|
||||
{
|
||||
Some(selected) => selected,
|
||||
None => {
|
||||
if event.keyval() != constants::Up {
|
||||
combined_matches[0]
|
||||
// If nothing is selected select either the top or bottom match based on the input
|
||||
match event.keyval() {
|
||||
constants::Down | constants::Tab => combined_matches[0]
|
||||
.1
|
||||
.select_row(Some(&combined_matches[0].0));
|
||||
.select_row(Some(&combined_matches[0].0)),
|
||||
constants::Up => combined_matches[combined_matches.len() - 1]
|
||||
.1
|
||||
.select_row(Some(&combined_matches[combined_matches.len() - 1].0)),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
return Inhibit(true);
|
||||
}
|
||||
};
|
||||
|
||||
// Clear the previous selection
|
||||
selected_list.select_row(None::<>k::ListBoxRow>);
|
||||
|
||||
// Get the index of the current selection
|
||||
let index = combined_matches
|
||||
.iter()
|
||||
.position(|(row, _)| *row == selected_match)
|
||||
.unwrap();
|
||||
|
||||
// Move the selection based on the input, loops from top to bottom and vice versa
|
||||
match event.keyval() {
|
||||
constants::Down | constants::Tab => {
|
||||
if index < combined_matches.len() - 1 {
|
||||
@@ -309,18 +375,19 @@ fn activate(app: >k::Application, args: Rc<RefCell<Option<Args>>>) {
|
||||
|
||||
Inhibit(true)
|
||||
}
|
||||
// Handle when the selected match is "activated"
|
||||
constants::Return => {
|
||||
let (selected_match, plugin) = match plugins_clone.iter().find_map(|view| {
|
||||
view.list
|
||||
.selected_row()
|
||||
.map(|row| (row, view.plugin.clone()))
|
||||
}) {
|
||||
let (selected_match, plugin) = match plugins
|
||||
.iter()
|
||||
.find_map(|view| view.list.selected_row().map(|row| (row, view.plugin)))
|
||||
{
|
||||
Some(selected) => selected,
|
||||
None => {
|
||||
return Inhibit(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Perform actions based on the result of handling the selection
|
||||
match plugin.handle_selection()(unsafe {
|
||||
(*selected_match.data::<Match>("match").unwrap().as_ptr()).clone()
|
||||
}) {
|
||||
@@ -329,16 +396,25 @@ fn activate(app: >k::Application, args: Rc<RefCell<Option<Args>>>) {
|
||||
Inhibit(true)
|
||||
}
|
||||
HandleResult::Refresh => {
|
||||
refresh_matches(entry_clone.text().to_string(), plugins_clone.clone());
|
||||
refresh_matches(entry_clone.text().to_string(), plugins.clone());
|
||||
Inhibit(false)
|
||||
}
|
||||
HandleResult::Copy(bytes) => {
|
||||
runtime_data.borrow_mut().as_mut().unwrap().post_run_action =
|
||||
PostRunAction::Copy(bytes.into());
|
||||
window.close();
|
||||
Inhibit(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => Inhibit(false),
|
||||
}
|
||||
});
|
||||
|
||||
let main_vbox = gtk::Box::new(gtk::Orientation::Vertical, 10);
|
||||
let main_vbox = gtk::Box::builder()
|
||||
.orientation(gtk::Orientation::Vertical)
|
||||
.name(style_names::MAIN)
|
||||
.build();
|
||||
main_vbox.add(&entry);
|
||||
window.add(&main_vbox);
|
||||
window.show_all();
|
||||
@@ -348,11 +424,13 @@ fn activate(app: >k::Application, args: Rc<RefCell<Option<Args>>>) {
|
||||
}
|
||||
|
||||
fn handle_matches(matches: RVec<Match>, plugin_view: PluginView) {
|
||||
// Clear out the old matches from the list
|
||||
for widget in plugin_view.list.children() {
|
||||
plugin_view.list.remove(&widget);
|
||||
}
|
||||
|
||||
if matches.len() == 0 {
|
||||
// If there are no matches, hide the plugin's results
|
||||
if matches.is_empty() {
|
||||
plugin_view.row.hide();
|
||||
return;
|
||||
}
|
||||
@@ -364,17 +442,22 @@ fn handle_matches(matches: RVec<Match>, plugin_view: PluginView) {
|
||||
.name(style_names::MATCH)
|
||||
.hexpand(true)
|
||||
.build();
|
||||
hbox.add(
|
||||
>k::Image::builder()
|
||||
.icon_name(&_match.icon)
|
||||
.name(style_names::MATCH)
|
||||
.pixel_size(32)
|
||||
.build(),
|
||||
);
|
||||
if let ROption::RSome(icon) = &_match.icon {
|
||||
hbox.add(
|
||||
>k::Image::builder()
|
||||
.icon_name(icon)
|
||||
.name(style_names::MATCH)
|
||||
.pixel_size(32)
|
||||
.build(),
|
||||
);
|
||||
}
|
||||
let title = gtk::Label::builder()
|
||||
.name(style_names::MATCH_TITLE)
|
||||
.wrap(true)
|
||||
.use_markup(true) // Allow pango markup
|
||||
.halign(gtk::Align::Start)
|
||||
.valign(gtk::Align::Center)
|
||||
.vexpand(true)
|
||||
.label(&_match.title)
|
||||
.build();
|
||||
|
||||
@@ -391,6 +474,8 @@ fn handle_matches(matches: RVec<Match>, plugin_view: PluginView) {
|
||||
title_desc_box.add(
|
||||
>k::Label::builder()
|
||||
.name(style_names::MATCH_DESC)
|
||||
.wrap(true)
|
||||
.use_markup(true) // Allow pango markup
|
||||
.halign(gtk::Align::Start)
|
||||
.valign(gtk::Align::Center)
|
||||
.label(desc)
|
||||
@@ -402,7 +487,10 @@ fn handle_matches(matches: RVec<Match>, plugin_view: PluginView) {
|
||||
hbox.add(&title);
|
||||
}
|
||||
}
|
||||
let row = gtk::ListBoxRow::builder().name(style_names::MATCH).build();
|
||||
let row = gtk::ListBoxRow::builder()
|
||||
.name(style_names::MATCH)
|
||||
.height_request(32)
|
||||
.build();
|
||||
row.add(&hbox);
|
||||
// GTK data setting is not type checked, so it is unsafe.
|
||||
// Only `Match` objects are stored though.
|
||||
@@ -416,11 +504,13 @@ fn handle_matches(matches: RVec<Match>, plugin_view: PluginView) {
|
||||
plugin_view.row.show_all();
|
||||
}
|
||||
|
||||
/// Create the info box for the plugin
|
||||
fn create_info_box(info: &PluginInfo) -> gtk::Box {
|
||||
let info_box = gtk::Box::builder()
|
||||
.orientation(gtk::Orientation::Horizontal)
|
||||
.name(style_names::PLUGIN)
|
||||
.width_request(200)
|
||||
.height_request(32)
|
||||
.expand(false)
|
||||
.spacing(10)
|
||||
.build();
|
||||
@@ -428,7 +518,7 @@ fn create_info_box(info: &PluginInfo) -> gtk::Box {
|
||||
>k::Image::builder()
|
||||
.icon_name(&info.icon)
|
||||
.name(style_names::PLUGIN)
|
||||
.pixel_size(48)
|
||||
.pixel_size(32)
|
||||
.halign(gtk::Align::Start)
|
||||
.valign(gtk::Align::Start)
|
||||
.build(),
|
||||
@@ -438,11 +528,23 @@ fn create_info_box(info: &PluginInfo) -> gtk::Box {
|
||||
.label(&info.name)
|
||||
.name(style_names::PLUGIN)
|
||||
.halign(gtk::Align::End)
|
||||
.valign(gtk::Align::Start)
|
||||
.valign(gtk::Align::Center)
|
||||
.hexpand(true)
|
||||
.build(),
|
||||
);
|
||||
info_box
|
||||
// This is so that we can align the plugin name with the icon. GTK would not let it be properly aligned otherwise.
|
||||
let main_box = gtk::Box::builder()
|
||||
.orientation(gtk::Orientation::Vertical)
|
||||
.name(style_names::PLUGIN)
|
||||
.build();
|
||||
main_box.add(&info_box);
|
||||
main_box.add(
|
||||
>k::Box::builder()
|
||||
.orientation(gtk::Orientation::Horizontal)
|
||||
.name(style_names::PLUGIN)
|
||||
.build(),
|
||||
);
|
||||
main_box
|
||||
}
|
||||
|
||||
/// Refresh the matches from the plugins
|
||||
@@ -450,9 +552,14 @@ fn refresh_matches(input: String, plugins: Rc<Vec<PluginView>>) {
|
||||
for plugin_view in plugins.iter() {
|
||||
let id = plugin_view.plugin.get_matches()(input.clone().into());
|
||||
let plugin_view = plugin_view.clone();
|
||||
glib::timeout_add_local(Duration::from_micros(1000), move || {
|
||||
async_match(plugin_view.clone(), id)
|
||||
});
|
||||
// If the input is empty, skip getting matches and just clear everything out.
|
||||
if input.is_empty() {
|
||||
handle_matches(RVec::new(), plugin_view);
|
||||
} else {
|
||||
glib::timeout_add_local(Duration::from_micros(1000), move || {
|
||||
async_match(plugin_view.clone(), id)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -12,3 +12,4 @@ crate-type = ["cdylib"]
|
||||
anyrun-plugin = { path = "../../anyrun-plugin" }
|
||||
abi_stable = "0.11.1"
|
||||
sublime_fuzzy = "0.7.0"
|
||||
fuzzy-matcher = "0.3.7"
|
||||
|
@@ -1,18 +1,16 @@
|
||||
use abi_stable::std_types::{ROption, RString, RVec};
|
||||
use scrubber::DesktopEntry;
|
||||
use std::{process::Command, sync::RwLock, thread};
|
||||
use anyrun_plugin::{anyrun_interface::HandleResult, *};
|
||||
use fuzzy_matcher::FuzzyMatcher;
|
||||
use scrubber::DesktopEntry;
|
||||
use std::process::Command;
|
||||
|
||||
mod scrubber;
|
||||
|
||||
static ENTRIES: RwLock<Vec<(DesktopEntry, u64)>> = RwLock::new(Vec::new());
|
||||
|
||||
pub fn handler(selection: Match) -> HandleResult {
|
||||
let entries = ENTRIES.read().unwrap();
|
||||
pub fn handler(selection: Match, entries: &mut Vec<(DesktopEntry, u64)>) -> HandleResult {
|
||||
let entry = entries
|
||||
.iter()
|
||||
.find_map(|(entry, id)| {
|
||||
if *id == selection.id {
|
||||
if *id == selection.id.unwrap() {
|
||||
Some(entry)
|
||||
} else {
|
||||
None
|
||||
@@ -27,46 +25,32 @@ pub fn handler(selection: Match) -> HandleResult {
|
||||
HandleResult::Close
|
||||
}
|
||||
|
||||
pub fn init(_config_dir: RString) {
|
||||
thread::spawn(|| {
|
||||
*ENTRIES.write().unwrap() = match scrubber::scrubber() {
|
||||
Ok(results) => results,
|
||||
Err(why) => {
|
||||
println!("Error reading desktop entries: {}", why);
|
||||
return;
|
||||
}
|
||||
};
|
||||
});
|
||||
pub fn init(_config_dir: RString) -> Vec<(DesktopEntry, u64)> {
|
||||
scrubber::scrubber().expect("Failed to load desktop entries!")
|
||||
}
|
||||
|
||||
pub fn get_matches(input: RString) -> RVec<Match> {
|
||||
if input.len() == 0 {
|
||||
return RVec::new();
|
||||
}
|
||||
|
||||
let mut entries = ENTRIES
|
||||
.read()
|
||||
.unwrap()
|
||||
pub fn get_matches(input: RString, entries: &mut Vec<(DesktopEntry, u64)>) -> RVec<Match> {
|
||||
let matcher = fuzzy_matcher::skim::SkimMatcherV2::default().smart_case();
|
||||
let mut entries = entries
|
||||
.clone()
|
||||
.into_iter()
|
||||
.filter_map(|(entry, id)| {
|
||||
match sublime_fuzzy::best_match(&input.to_lowercase(), &entry.name.to_lowercase()) {
|
||||
Some(val) => Some((entry, id, val.score())),
|
||||
None => None,
|
||||
}
|
||||
matcher
|
||||
.fuzzy_match(&entry.name, &input)
|
||||
.map(|val| (entry, id, val))
|
||||
})
|
||||
.collect::<Vec<(DesktopEntry, u64, isize)>>();
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
entries.sort_by(|a, b| b.1.cmp(&a.1));
|
||||
entries.sort_by(|a, b| b.2.cmp(&a.2));
|
||||
|
||||
entries.truncate(5);
|
||||
entries
|
||||
.into_iter()
|
||||
.map(|(entry, id, _)| Match {
|
||||
title: entry.name.into(),
|
||||
icon: entry.icon.into(),
|
||||
icon: ROption::RSome(entry.icon.into()),
|
||||
description: ROption::RNone,
|
||||
id,
|
||||
id: ROption::RSome(id),
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
@@ -78,4 +62,4 @@ pub fn info() -> PluginInfo {
|
||||
}
|
||||
}
|
||||
|
||||
plugin!(init, info, get_matches, handler);
|
||||
plugin!(init, info, get_matches, handler, Vec<(DesktopEntry, u64)>);
|
||||
|
@@ -115,7 +115,7 @@ pub fn scrubber() -> Result<Vec<(DesktopEntry, u64)>, Box<dyn std::error::Error>
|
||||
Ok(entry) => entry,
|
||||
Err(_why) => return None,
|
||||
};
|
||||
DesktopEntry::from_dir_entry(&entry).map(|val| (val, id))
|
||||
DesktopEntry::from_dir_entry(entry).map(|val| (val, id))
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "web-search"
|
||||
name = "rink"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
@@ -11,3 +11,4 @@ crate-type = ["cdylib"]
|
||||
[dependencies]
|
||||
anyrun-plugin = { path = "../../anyrun-plugin" }
|
||||
abi_stable = "0.11.1"
|
||||
rink-core = "0.6"
|
31
plugins/rink/src/lib.rs
Normal file
31
plugins/rink/src/lib.rs
Normal file
@@ -0,0 +1,31 @@
|
||||
use abi_stable::std_types::{ROption, RString, RVec};
|
||||
use anyrun_plugin::{anyrun_interface::HandleResult, plugin, Match, PluginInfo};
|
||||
|
||||
fn init(_config_dir: RString) {}
|
||||
|
||||
fn info() -> PluginInfo {
|
||||
PluginInfo {
|
||||
name: "Rink".into(),
|
||||
icon: "accessories-calculator".into(),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_matches(input: RString, _: &mut ()) -> RVec<Match> {
|
||||
let mut ctx = rink_core::simple_context().unwrap();
|
||||
match rink_core::one_line(&mut ctx, &input) {
|
||||
Ok(result) => vec![Match {
|
||||
title: result.into(),
|
||||
icon: ROption::RNone,
|
||||
description: ROption::RNone,
|
||||
id: ROption::RNone,
|
||||
}]
|
||||
.into(),
|
||||
Err(_) => RVec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn handler(selection: Match, _: &mut ()) -> HandleResult {
|
||||
HandleResult::Copy(selection.title.into_bytes())
|
||||
}
|
||||
|
||||
plugin!(init, info, get_matches, handler, ());
|
@@ -11,3 +11,6 @@ crate-type = ["cdylib"]
|
||||
[dependencies]
|
||||
anyrun-plugin = { path = "../../anyrun-plugin" }
|
||||
abi_stable = "0.11.1"
|
||||
ron = "0.8.0"
|
||||
serde = { version = "1.0.152", features = ["derive"] }
|
||||
fuzzy-matcher = "0.3.7"
|
||||
|
28
plugins/symbols/build.rs
Normal file
28
plugins/symbols/build.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
use std::{
|
||||
env,
|
||||
fs::{self, File},
|
||||
io::Write,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
let string = fs::read_to_string("res/UnicodeData.txt").expect("Failed to load unicode data!");
|
||||
let mut file = File::create(format!("{}/unicode.rs", env::var("OUT_DIR").unwrap()))
|
||||
.expect("Unable to create unicode output file!");
|
||||
|
||||
file.write_all(b"#[allow(text_direction_codepoint_in_literal)]\nconst UNICODE_CHARS: &[(&str, &str)] = &[\n")
|
||||
.unwrap();
|
||||
string.lines().for_each(|line| {
|
||||
let fields = line.split(';').collect::<Vec<_>>();
|
||||
let chr = match char::from_u32(u32::from_str_radix(fields[0], 16).unwrap()) {
|
||||
Some(char) => char,
|
||||
None => return,
|
||||
};
|
||||
|
||||
if fields[1] != "<control>" {
|
||||
file.write_all(format!("(r#\"{}\"#, r#\"{}\"#),\n", fields[1], chr).as_bytes())
|
||||
.unwrap();
|
||||
}
|
||||
});
|
||||
|
||||
file.write_all(b"];\n").unwrap();
|
||||
}
|
34924
plugins/symbols/res/UnicodeData.txt
Normal file
34924
plugins/symbols/res/UnicodeData.txt
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,27 +1,88 @@
|
||||
use std::{collections::HashMap, fs};
|
||||
|
||||
use abi_stable::std_types::{ROption, RString, RVec};
|
||||
use anyrun_plugin::{plugin, anyrun_interface::HandleResult, Match, PluginInfo};
|
||||
use anyrun_plugin::{anyrun_interface::HandleResult, plugin, Match, PluginInfo};
|
||||
use fuzzy_matcher::FuzzyMatcher;
|
||||
use serde::Deserialize;
|
||||
|
||||
pub fn init(_config_dir: RString) {}
|
||||
include!(concat!(env!("OUT_DIR"), "/unicode.rs"));
|
||||
|
||||
pub fn info() -> PluginInfo {
|
||||
#[derive(Clone, Debug)]
|
||||
struct Symbol {
|
||||
chr: String,
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct Config {
|
||||
symbols: HashMap<String, String>,
|
||||
}
|
||||
|
||||
fn init(config_dir: RString) -> Vec<Symbol> {
|
||||
// Try to load the config file, if it does not exist only use the static unicode characters
|
||||
if let Ok(content) = fs::read_to_string(format!("{}/symbols.ron", config_dir)) {
|
||||
match ron::from_str::<Config>(&content) {
|
||||
Ok(config) => {
|
||||
let symbols = UNICODE_CHARS
|
||||
.iter()
|
||||
.map(|(name, chr)| (name.to_string(), chr.to_string()))
|
||||
.chain(config.symbols.into_iter())
|
||||
.map(|(name, chr)| Symbol { chr, name })
|
||||
.collect();
|
||||
return symbols;
|
||||
}
|
||||
Err(why) => {
|
||||
println!("Error parsing symbols config file: {}", why);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UNICODE_CHARS
|
||||
.iter()
|
||||
.map(|(name, chr)| Symbol {
|
||||
chr: chr.to_string(),
|
||||
name: name.to_string(),
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn info() -> PluginInfo {
|
||||
PluginInfo {
|
||||
name: "Symbols".into(),
|
||||
icon: "emblem-mail".into(),
|
||||
icon: "accessories-character-map".into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_matches(input: RString) -> RVec<Match> {
|
||||
vec![Match {
|
||||
title: "Test".into(),
|
||||
description: ROption::RNone,
|
||||
icon: "dialog-warning".into(),
|
||||
id: 0,
|
||||
}]
|
||||
.into()
|
||||
fn get_matches(input: RString, symbols: &mut Vec<Symbol>) -> RVec<Match> {
|
||||
let matcher = fuzzy_matcher::skim::SkimMatcherV2::default().ignore_case();
|
||||
let mut symbols = symbols
|
||||
.clone()
|
||||
.into_iter()
|
||||
.filter_map(|symbol| {
|
||||
matcher
|
||||
.fuzzy_match(&symbol.name, &input)
|
||||
.map(|score| (symbol, score))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Sort the symbol list according to the score
|
||||
symbols.sort_by(|a, b| b.1.cmp(&a.1));
|
||||
|
||||
symbols.truncate(3);
|
||||
|
||||
symbols
|
||||
.into_iter()
|
||||
.map(|(symbol, _)| Match {
|
||||
title: symbol.chr.into(),
|
||||
description: ROption::RSome(symbol.name.into()),
|
||||
icon: ROption::RNone,
|
||||
id: ROption::RNone,
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn handler(selection: Match) -> HandleResult {
|
||||
HandleResult::Close
|
||||
fn handler(selection: Match, _symbols: &mut Vec<Symbol>) -> HandleResult {
|
||||
HandleResult::Copy(selection.title.into_bytes())
|
||||
}
|
||||
|
||||
plugin!(init, info, get_matches, handler);
|
||||
plugin!(init, info, get_matches, handler, Vec<Symbol>);
|
||||
|
@@ -1,35 +0,0 @@
|
||||
use abi_stable::std_types::{ROption, RString, RVec};
|
||||
use anyrun_plugin::{plugin, anyrun_interface::HandleResult, Match, PluginInfo};
|
||||
|
||||
pub fn init(_config_dir: RString) {}
|
||||
|
||||
pub fn info() -> PluginInfo {
|
||||
PluginInfo {
|
||||
name: "Web search".into(),
|
||||
icon: "system-search".into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_matches(input: RString) -> RVec<Match> {
|
||||
vec![
|
||||
Match {
|
||||
title: "DDG it!".into(),
|
||||
description: ROption::RSome(format!(r#"Look up "{}" with DuckDuckGo"#, input).into()),
|
||||
icon: "emblem-web".into(),
|
||||
id: 0,
|
||||
},
|
||||
Match {
|
||||
title: "Startpage it!".into(),
|
||||
description: ROption::RSome(format!(r#"Look up "{}" with Startpage"#, input).into()),
|
||||
icon: "emblem-web".into(),
|
||||
id: 0,
|
||||
},
|
||||
]
|
||||
.into()
|
||||
}
|
||||
|
||||
pub fn handler(selection: Match) -> HandleResult {
|
||||
HandleResult::Close
|
||||
}
|
||||
|
||||
plugin!(init, info, get_matches, handler);
|
Reference in New Issue
Block a user