diff --git a/.gitignore b/.gitignore index 3e533d9..9c954c4 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ # direnv cache (should not be committed) .direnv/ waycast_cache +waycast.toml diff --git a/Cargo.lock b/Cargo.lock index ca87e3d..16a9188 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,23 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +[[package]] +name = "arraydeque" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "autocfg" version = "1.5.0" @@ -38,6 +55,12 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + [[package]] name = "bincode" version = "1.3.3" @@ -69,9 +92,21 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.9.3" +version = "2.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34efbcccd345379ca2868b2b2c9d3782e9cc58ba87bc7d79d5b53d9c9ae6f25d" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" +dependencies = [ + "serde", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] [[package]] name = "cairo-rs" @@ -112,6 +147,90 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" +[[package]] +name = "config" +version = "0.15.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0faa974509d38b33ff89282db9c3295707ccf031727c0de9772038ec526852ba" +dependencies = [ + "async-trait", + "convert_case", + "json5", + "pathdiff", + "ron", + "rust-ini", + "serde", + "serde-untagged", + "serde_json", + "toml 0.9.5", + "winnow", + "yaml-rust2", +] + +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom 0.2.16", + "once_cell", + "tiny-keccak", +] + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + [[package]] name = "directories" version = "6.0.0" @@ -130,7 +249,25 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.60.2", + "windows-sys 0.61.0", +] + +[[package]] +name = "dlv-list" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f" +dependencies = [ + "const-random", +] + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", ] [[package]] @@ -139,6 +276,16 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +[[package]] +name = "erased-serde" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7" +dependencies = [ + "serde", + "typeid", +] + [[package]] name = "errno" version = "0.3.13" @@ -165,6 +312,12 @@ dependencies = [ "rustc_version", ] +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + [[package]] name = "futures-channel" version = "0.3.31" @@ -286,6 +439,16 @@ dependencies = [ "system-deps", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "getrandom" version = "0.2.16" @@ -497,9 +660,9 @@ dependencies = [ [[package]] name = "gtk4-layer-shell" -version = "0.6.1" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f448a3a5593fb2ba018a946474beec09366c01f40ec788fc4a879981d16c91" +checksum = "17d5ba7dda5e307469217249a980136e393d13063d4d97dd34ef30ebe1955dd2" dependencies = [ "bitflags", "gdk4", @@ -554,11 +717,29 @@ dependencies = [ "system-deps", ] +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + [[package]] name = "hashbrown" version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash", +] + +[[package]] +name = "hashlink" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +dependencies = [ + "hashbrown 0.15.5", +] [[package]] name = "heck" @@ -573,7 +754,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.15.5", ] [[package]] @@ -587,6 +768,23 @@ dependencies = [ "libc", ] +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + [[package]] name = "khronos_api" version = "3.1.0" @@ -617,9 +815,9 @@ checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" [[package]] name = "log" -version = "0.4.27" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "memchr" @@ -677,6 +875,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "ordered-multimap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79" +dependencies = [ + "dlv-list", + "hashbrown 0.14.5", +] + [[package]] name = "pango" version = "0.21.1" @@ -701,6 +909,56 @@ dependencies = [ "system-deps", ] +[[package]] +name = "pathdiff" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" + +[[package]] +name = "pest" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1db05f56d34358a8b1066f67cbb203ee3e7ed2ba674a6263a1d5ec6db2204323" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb056d9e8ea77922845ec74a1c4e8fb17e7c218cc4fc11a15c5d25e189aa40bc" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e404e638f781eb3202dc82db6760c8ae8a1eeef7fb3fa8264b2ef280504966" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pest_meta" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd1101f170f5903fde0914f899bb503d9ff5271d7ba76bbb70bea63690cc0d5" +dependencies = [ + "pest", + "sha2", +] + [[package]] name = "pin-project-lite" version = "0.2.16" @@ -772,6 +1030,28 @@ dependencies = [ "thiserror", ] +[[package]] +name = "ron" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" +dependencies = [ + "base64", + "bitflags", + "serde", + "serde_derive", +] + +[[package]] +name = "rust-ini" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "796e8d2b6696392a43bea58116b667fb4c29727dc5abd27d6acf338bb4f688c7" +dependencies = [ + "cfg-if", + "ordered-multimap", +] + [[package]] name = "rustc-demangle" version = "0.1.26" @@ -800,6 +1080,12 @@ dependencies = [ "windows-sys 0.60.2", ] +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + [[package]] name = "same-file" version = "1.0.6" @@ -824,6 +1110,17 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-untagged" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34836a629bcbc6f1afdf0907a744870039b1e14c0561cb26094fa683b158eff3" +dependencies = [ + "erased-serde", + "serde", + "typeid", +] + [[package]] name = "serde_derive" version = "1.0.219" @@ -835,6 +1132,18 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_json" +version = "1.0.143" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + [[package]] name = "serde_spanned" version = "0.6.9" @@ -844,6 +1153,32 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_toml" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e68184169792863bfb6d8b5de8e15456ebf4302f28236f0ff1136591eb66541" + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "slab" version = "0.4.11" @@ -876,7 +1211,7 @@ dependencies = [ "cfg-expr", "heck", "pkg-config", - "toml", + "toml 0.8.23", "version-compare", ] @@ -919,6 +1254,15 @@ dependencies = [ "syn", ] +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + [[package]] name = "tokio" version = "1.47.1" @@ -952,11 +1296,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", - "serde_spanned", - "toml_datetime", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", "toml_edit", ] +[[package]] +name = "toml" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75129e1dc5000bfbaa9fee9d1b21f974f9fbad9daec557a521ee6e080825f6e8" +dependencies = [ + "indexmap", + "serde", + "serde_spanned 1.0.0", + "toml_datetime 0.7.0", + "toml_parser", + "toml_writer", + "winnow", +] + [[package]] name = "toml_datetime" version = "0.6.11" @@ -966,6 +1325,15 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_datetime" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3" +dependencies = [ + "serde", +] + [[package]] name = "toml_edit" version = "0.22.27" @@ -974,17 +1342,56 @@ checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ "indexmap", "serde", - "serde_spanned", - "toml_datetime", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", "winnow", ] +[[package]] +name = "toml_parser" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b551886f449aa90d4fe2bdaa9f4a2577ad2dde302c61ecf262d80b116db95c10" +dependencies = [ + "winnow", +] + +[[package]] +name = "toml_writer" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc842091f2def52017664b53082ecbbeb5c7731092bad69d2c63050401dfd64" + +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + [[package]] name = "unicode-ident" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + [[package]] name = "unty" version = "0.0.4" @@ -997,6 +1404,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + [[package]] name = "virtue" version = "0.0.18" @@ -1028,6 +1441,17 @@ dependencies = [ "wit-bindgen", ] +[[package]] +name = "waycast-config" +version = "0.1.0" +dependencies = [ + "config", + "directories", + "serde", + "serde_toml", + "toml 0.9.5", +] + [[package]] name = "waycast-core" version = "0.1.0" @@ -1071,6 +1495,7 @@ dependencies = [ "glib", "tokio", "walkdir", + "waycast-config", "waycast-core", "waycast-macros", ] @@ -1090,6 +1515,12 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +[[package]] +name = "windows-link" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" + [[package]] name = "windows-sys" version = "0.59.0" @@ -1108,6 +1539,15 @@ dependencies = [ "windows-targets 0.53.3", ] +[[package]] +name = "windows-sys" +version = "0.61.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa" +dependencies = [ + "windows-link 0.2.0", +] + [[package]] name = "windows-targets" version = "0.52.6" @@ -1130,7 +1570,7 @@ version = "0.53.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" dependencies = [ - "windows-link", + "windows-link 0.1.3", "windows_aarch64_gnullvm 0.53.0", "windows_aarch64_msvc 0.53.0", "windows_i686_gnu 0.53.0", @@ -1257,3 +1697,14 @@ name = "xml-rs" version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fd8403733700263c6eb89f192880191f1b83e332f7a20371ddcf421c4a337c7" + +[[package]] +name = "yaml-rust2" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ce2a4ff45552406d02501cea6c18d8a7e50228e7736a872951fe2fe75c91be7" +dependencies = [ + "arraydeque", + "encoding_rs", + "hashlink", +] diff --git a/Cargo.toml b/Cargo.toml index e31de28..ead5d76 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,8 @@ members = [ "waycast-core", "waycast-macros", - "waycast-plugins", - "waycast-gtk" + "waycast-plugins", + "waycast-gtk", + "waycast-config", ] resolver = "2" diff --git a/waycast-config/Cargo.toml b/waycast-config/Cargo.toml new file mode 100644 index 0000000..418d373 --- /dev/null +++ b/waycast-config/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "waycast-config" +version = "0.1.0" +edition = "2024" + +[dependencies] +config = { version = "0.15.15", features = ["toml"] } +directories = "6.0.0" +serde = { version = "1.0.219", features = ["derive"] } +serde_toml = "0.0.1" +toml = "0.9.5" diff --git a/waycast-config/src/lib.rs b/waycast-config/src/lib.rs new file mode 100644 index 0000000..1a24ebb --- /dev/null +++ b/waycast-config/src/lib.rs @@ -0,0 +1,31 @@ +use config::Config; +use directories::ProjectDirs; +use serde::de::DeserializeOwned; +use serde::{Deserialize, Serialize}; +use std::path::Path; +use std::sync::OnceLock; +use std::{fs::File, path::PathBuf}; + +#[derive(Debug, Deserialize, Serialize)] +pub struct WaycastConfig {} +static CONFIG_SINGLETON: OnceLock = OnceLock::new(); + +pub fn project_dirs() -> Option { + ProjectDirs::from("dev.thegrind", "The Grind", "waycast") +} + +pub fn config_file() -> &'static Config { + CONFIG_SINGLETON.get_or_init(|| init()) +} + +pub fn get(key: &str) -> Result { + config_file().get::(key) +} + +fn init() -> Config { + Config::builder() + .add_source(config::File::with_name("waycast.toml")) + .add_source(config::Environment::with_prefix("WAYCAST")) + .build() + .unwrap() +} diff --git a/waycast-config/src/main.rs b/waycast-config/src/main.rs new file mode 100644 index 0000000..ee84a6b --- /dev/null +++ b/waycast-config/src/main.rs @@ -0,0 +1,42 @@ +use std::collections::HashMap; + +use config::Config; +use directories::ProjectDirs; +pub fn main() { + // if let Some(dirs) = ProjectDirs::from("dev.thegrind", "The Grind", "waycast") { + // let config_dir = dirs.config_dir(); + // let cache_dir = dirs.cache_dir(); + // let data_dir = dirs.data_dir(); + + // println!("Config: {}", config_dir.display()); + // println!("Cache: {}", cache_dir.display()); + // println!("Data: {}", data_dir.display()); + // } + + // let settings = Config::builder() + // .add_source(config::File::with_name("waycast.toml")) + // .add_source(config::Environment::with_prefix("WAYCAST")) + // .build() + // .unwrap(); + + println!( + "{:?}", + waycast_config::config_file() + .get::("plugins.projects.open_command") + .expect("Could not deserialize") + ); + + // // Start with defaults + // let mut config = WaycastConfig::default(); + + // config.plugins.file_search.ignore_dirs = + // vec!["vendor".into(), "pycache".into(), "node_modules".into()]; + + // // Serialize to TOML + // let toml_str = toml::to_string_pretty(&config).expect("Failed"); + // println!("Serialized TOML:\n{}", toml_str); + + // // Deserialize back + // let parsed: WaycastConfig = toml::from_str(&toml_str).expect("Fuck"); + // println!("Deserialized struct:\n{:#?}", parsed); +} diff --git a/waycast-gtk/src/main.rs b/waycast-gtk/src/main.rs index 2cbbca0..4afb404 100644 --- a/waycast-gtk/src/main.rs +++ b/waycast-gtk/src/main.rs @@ -12,22 +12,11 @@ fn main() { .build(); app.connect_activate(|app| { - let mut file_search_plugin = waycast_plugins::file_search::new(); - - if let Err(e) = file_search_plugin.add_search_path("/home/javi/working-files/DJ Music/") { - eprintln!("{}", e) - } - - let mut project_plugin = waycast_plugins::projects::new(); - if let Err(e) = project_plugin.add_search_path("/home/javi/projects") { - eprintln!("{}", e) - } - // Create the core launcher let launcher = WaycastLauncher::new() .add_plugin(Box::new(waycast_plugins::drun::new())) - .add_plugin(Box::new(file_search_plugin)) - .add_plugin(Box::new(project_plugin)) + .add_plugin(Box::new(waycast_plugins::file_search::new())) + .add_plugin(Box::new(waycast_plugins::projects::new())) .init(); // Create and show the GTK UI diff --git a/waycast-plugins/Cargo.toml b/waycast-plugins/Cargo.toml index 4cd6d3d..2560204 100644 --- a/waycast-plugins/Cargo.toml +++ b/waycast-plugins/Cargo.toml @@ -6,11 +6,18 @@ edition = "2021" [dependencies] waycast-core = { path = "../waycast-core" } waycast-macros = { path = "../waycast-macros" } +waycast-config = { path = "../waycast-config" } directories = "6.0.0" gio = "0.21.1" glib = "0.21.1" -tokio = { version = "1.0", features = ["rt", "rt-multi-thread", "time", "macros", "sync"] } +tokio = { version = "1.0", features = [ + "rt", + "rt-multi-thread", + "time", + "macros", + "sync", +] } walkdir = "2.5.0" [lints.rust] -unexpected_cfgs = { level = "warn", check-cfg = ['cfg(rust_analyzer)'] } \ No newline at end of file +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(rust_analyzer)'] } diff --git a/waycast-plugins/src/file_search.rs b/waycast-plugins/src/file_search.rs index fedadb1..7b1e446 100644 --- a/waycast-plugins/src/file_search.rs +++ b/waycast-plugins/src/file_search.rs @@ -1,13 +1,14 @@ use directories::UserDirs; use gio::prelude::FileExt; use glib::object::Cast; +use std::collections::HashSet; use std::path::{Path, PathBuf}; use std::process::Command; use std::sync::Arc; use std::time::Duration; use tokio::sync::Mutex; use walkdir::{DirEntry, WalkDir}; -use waycast_macros::{plugin, launcher_entry}; +use waycast_macros::{launcher_entry, plugin}; use waycast_core::{LaunchError, LauncherListItem, LauncherPlugin}; @@ -72,9 +73,9 @@ impl LauncherListItem for FileEntry { } } -pub fn default_search_list() -> Vec { +pub fn default_search_list() -> HashSet { if let Some(ud) = UserDirs::new() { - let mut paths: Vec = Vec::new(); + let mut paths: HashSet = HashSet::new(); let user_dirs = [ ud.document_dir(), ud.picture_dir(), @@ -83,18 +84,27 @@ pub fn default_search_list() -> Vec { ]; for path in user_dirs.into_iter().flatten() { - paths.push(path.to_path_buf()); + paths.insert(path.to_path_buf()); } return paths; } - Vec::new() + HashSet::new() +} + +pub fn default_skip_list() -> HashSet { + HashSet::from([ + String::from("vendor"), + String::from("node_modules"), + String::from("cache"), + String::from("zig-cache"), + ]) } pub struct FileSearchPlugin { - search_paths: Vec, - skip_dirs: Vec, + search_paths: HashSet, + skip_dirs: HashSet, // Running list of files in memory files: Arc>>, } @@ -107,14 +117,24 @@ impl Default for FileSearchPlugin { impl FileSearchPlugin { pub fn new() -> Self { + let mut search_paths = default_search_list(); + let mut skip_dirs = default_skip_list(); + + if let Ok(paths) = + waycast_config::config_file().get::>("plugins.file_search.search_paths") + { + search_paths.extend(paths); + } + + if let Ok(paths) = + waycast_config::config_file().get::>("plugins.file_search.ignore_dirs") + { + skip_dirs.extend(paths); + } + FileSearchPlugin { - search_paths: default_search_list(), - skip_dirs: vec![ - String::from("vendor"), - String::from("node_modules"), - String::from("cache"), - String::from("zig-cache"), - ], + search_paths, + skip_dirs, files: Arc::new(Mutex::new(Vec::new())), } } @@ -130,12 +150,12 @@ impl FileSearchPlugin { return Err(format!("Path is not a directory: {}", p.display())); } - self.search_paths.push(p.to_path_buf()); + self.search_paths.insert(p.to_path_buf()); Ok(()) } pub fn add_skip_dir(&mut self, directory_name: String) -> Result<(), String> { - self.skip_dirs.push(directory_name); + self.skip_dirs.insert(directory_name); Ok(()) } @@ -143,13 +163,27 @@ impl FileSearchPlugin { let files_clone = Arc::clone(&self.files); let skip_dirs_clone = self.skip_dirs.clone(); + println!("File search"); + println!("---Scanning directories---"); + for p in &self.search_paths { + println!("{}", p.display()); + } + + println!("---Skipping directories---"); + for p in &self.skip_dirs { + println!("{}", p); + } + let scan_task = async move { let mut local_files = Vec::new(); for path in &self.search_paths { let walker = WalkDir::new(path).into_iter(); for entry in walker - .filter_entry(|e| !skip_hidden(e) && !skip_dir(e, &skip_dirs_clone)) + .filter_entry(|e| { + !skip_hidden(e) + && skip_dirs_clone.contains(e.file_name().to_string_lossy().as_ref()) + }) .filter_map(|e| e.ok()) { if entry.path().is_file() { @@ -183,14 +217,6 @@ fn skip_hidden(entry: &DirEntry) -> bool { .unwrap_or(false) } -fn skip_dir(entry: &DirEntry, dirs: &Vec) -> bool { - entry - .file_name() - .to_str() - .map(|n| dirs.contains(&String::from(n))) - .unwrap_or(false) -} - impl LauncherPlugin for FileSearchPlugin { plugin! { name: "Files", @@ -198,7 +224,7 @@ impl LauncherPlugin for FileSearchPlugin { description: "Search and open files", prefix: "f" } - + fn init(&self) { // Start async file scanning with 2000ms timeout let self_clone = FileSearchPlugin { @@ -240,9 +266,6 @@ impl LauncherPlugin for FileSearchPlugin { } } - - - pub fn new() -> FileSearchPlugin { FileSearchPlugin::new() -} \ No newline at end of file +} diff --git a/waycast-plugins/src/projects.rs b/waycast-plugins/src/projects.rs index 6727066..044c29c 100644 --- a/waycast-plugins/src/projects.rs +++ b/waycast-plugins/src/projects.rs @@ -7,6 +7,7 @@ // and I'll just regex in the path. // TODO: Project type detection and icon use std::{ + collections::HashSet, fs, path::{Path, PathBuf}, process::Command, @@ -20,6 +21,7 @@ use waycast_macros::{launcher_entry, plugin}; #[derive(Clone)] pub struct ProjectEntry { path: PathBuf, + exec_command: String, } impl LauncherListItem for ProjectEntry { @@ -44,8 +46,9 @@ impl LauncherListItem for ProjectEntry { } pub struct ProjectsPlugin { - search_paths: Vec, - skip_dirs: Vec, + search_paths: HashSet, + skip_dirs: HashSet, + open_command: String, // Running list of files in memory files: Arc>>, } @@ -62,20 +65,16 @@ impl ProjectsPlugin { return Err(format!("Path is not a directory: {}", p.display())); } - self.search_paths.push(p.to_path_buf()); + self.search_paths.insert(p.to_path_buf()); Ok(()) } pub fn add_skip_dir(&mut self, directory_name: String) -> Result<(), String> { - self.skip_dirs.push(directory_name); + self.skip_dirs.insert(directory_name); Ok(()) } } -fn should_skip_dir(dir_name: &str, skip_dirs: &[String]) -> bool { - skip_dirs.iter().any(|skip| skip == dir_name) -} - impl LauncherPlugin for ProjectsPlugin { plugin! { name: "Projects", @@ -88,6 +87,7 @@ impl LauncherPlugin for ProjectsPlugin { let files_clone = Arc::clone(&self.files); let search_paths = self.search_paths.clone(); let skip_dirs = self.skip_dirs.clone(); + let exec_command = self.open_command.clone(); std::thread::spawn(move || { let rt = tokio::runtime::Runtime::new().unwrap(); @@ -110,11 +110,14 @@ impl LauncherPlugin for ProjectsPlugin { } // Skip directories in skip list - if should_skip_dir(name_str, &skip_dirs) { + if skip_dirs.contains(name_str) { continue; } - project_entries.push(ProjectEntry { path }); + project_entries.push(ProjectEntry { + path, + exec_command: exec_command.clone(), + }); } } } @@ -155,17 +158,31 @@ impl LauncherPlugin for ProjectsPlugin { } } +// fn get_config_value(key: &str) -> Result { +// waycast_config::config_file().get::(format!("plugins.projects.{}", key)) +// } + pub fn new() -> ProjectsPlugin { + let search_paths = + match waycast_config::get::>("plugins.projects.search_paths") { + Ok(paths) => paths, + Err(_) => HashSet::new(), + }; + + let skip_dirs = match waycast_config::get::>("plugins.projects.skip_dirs") { + Ok(paths) => paths, + Err(_) => HashSet::new(), + }; + + let open_command = match waycast_config::get::("plugins.projects.open_command") { + Ok(cmd) => cmd, + Err(_) => String::from("code -n {path}"), + }; + ProjectsPlugin { - search_paths: Vec::new(), - skip_dirs: vec![ - String::from("vendor"), - String::from("node_modules"), - String::from("cache"), - String::from("zig-cache"), - String::from(".git"), - String::from(".svn"), - ], + search_paths, + skip_dirs, + open_command, files: Arc::new(Mutex::new(Vec::new())), } }