Refinement, plugins, etc.

This commit is contained in:
Kirottu
2022-12-31 12:51:46 +02:00
parent 990bf12b79
commit ce4b157160
17 changed files with 36037 additions and 223 deletions

699
Cargo.lock generated
View File

@@ -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"

View File

@@ -5,5 +5,5 @@ members = [
"anyrun-interface",
"plugins/applications",
"plugins/symbols",
"plugins/web-search",
"plugins/rink",
]

5
README.md Normal file
View File

@@ -0,0 +1,5 @@
# AnyRun
A wayland native krunner-like runner, made with customizability in mind.

View File

@@ -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)]

View File

@@ -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(),
)
}
};
}

View File

@@ -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"] }

View File

@@ -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: &gtk::Application, args: Rc<RefCell<Option<Args>>>) {
fn activate(app: &gtk::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: &gtk::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: &gtk::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: &gtk::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::<&gtk::ListBoxRow>);
@@ -237,50 +292,61 @@ fn activate(app: &gtk::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::<&gtk::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: &gtk::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: &gtk::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: &gtk::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(
&gtk::Image::builder()
.icon_name(&_match.icon)
.name(style_names::MATCH)
.pixel_size(32)
.build(),
);
if let ROption::RSome(icon) = &_match.icon {
hbox.add(
&gtk::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(
&gtk::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 {
&gtk::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(
&gtk::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)
});
}
}
}

View File

@@ -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"

View File

@@ -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)>);

View File

@@ -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())
}

View File

@@ -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
View 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, ());

View File

@@ -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
View 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();
}

File diff suppressed because it is too large Load Diff

View File

@@ -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>);

View File

@@ -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);