Compare commits

..

12 Commits

Author SHA1 Message Date
33b4f410e5 fix(scripts): fix duplicate inject deduplication in aur-local-test
dedup_inject_files() was called before its definition in the script's
execution order. Moved the call to the Main section where all functions
are already defined.
2026-04-06 02:04:24 +02:00
a7683f16bf docs: update config example and README to reflect provider field removal 2026-04-06 02:02:06 +02:00
178f81082a fix(owlry-core,owlry): preserve config on save, fix tab filtering, clean provider fields
- Config::save() now merges into existing file via toml_edit to preserve
  user comments and unknown keys instead of overwriting
- Remove 16 dead ProvidersConfig plugin-toggle fields (uuctl, ssh, clipboard,
  bookmarks, emoji, scripts, files, media, weather_*, pomodoro_*) that became
  unreachable after accept_all=true was introduced
- Wire general.tabs to ProviderFilter::new() to drive UI tab display
- Fix set_single_mode() and toggle() not clearing accept_all, making tab
  filtering a no-op in default launch mode
- Add restore_all_mode() for cycle-back-to-All path in tab cycling
- Reduce PROVIDER_TOGGLES to built-in providers only
2026-04-06 01:59:48 +02:00
7863de9971 chore(owlry): bump version to 1.0.7 2026-04-06 01:57:42 +02:00
dacc194d02 chore(owlry-core): bump version to 1.3.3 2026-04-06 01:57:39 +02:00
5871609c73 chore(aur): update owlry-rune to 1.1.3 2026-04-05 18:18:11 +02:00
e3c4988e01 chore(owlry-rune): bump version to 1.1.3 2026-04-05 18:18:05 +02:00
46b5d8518f chore(aur): update owlry-rune to 1.1.2 2026-04-05 18:05:59 +02:00
95a698225c chore(owlry-rune): bump version to 1.1.2 2026-04-05 18:05:54 +02:00
709e1b04cb chore(aur): update owlry-lua to 1.1.2 2026-04-05 18:05:31 +02:00
827bf383ea chore(owlry-lua): bump version to 1.1.2 2026-04-05 18:05:25 +02:00
b706347ec9 chore(aur): update owlry-core to 1.3.2 2026-04-05 17:59:24 +02:00
19 changed files with 252 additions and 803 deletions

491
Cargo.lock generated
View File

@@ -50,12 +50,6 @@ dependencies = [
"core_extensions",
]
[[package]]
name = "adler2"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
[[package]]
name = "ahash"
version = "0.8.12"
@@ -178,18 +172,6 @@ dependencies = [
"pin-project-lite",
]
[[package]]
name = "async-compression"
version = "0.4.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0f9ee0f6e02ffd7ad5816e9464499fba7b3effd01123b515c41d1697c43dad1"
dependencies = [
"compression-codecs",
"compression-core",
"pin-project-lite",
"tokio",
]
[[package]]
name = "async-executor"
version = "1.14.0"
@@ -503,23 +485,6 @@ version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
[[package]]
name = "compression-codecs"
version = "0.4.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb7b51a7d9c967fc26773061ba86150f19c50c0d65c887cb1fbe295fd16619b7"
dependencies = [
"compression-core",
"flate2",
"memchr",
]
[[package]]
name = "compression-core"
version = "0.4.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75984efb6ed102a0d42db99afb6c1948f0380d1d91808d5529916e6c08b49d8d"
[[package]]
name = "concurrent-queue"
version = "2.5.0"
@@ -569,15 +534,6 @@ version = "1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "533d38ecd2709b7608fb8e18e4504deb99e9a72879e6aa66373a76d8dc4259ea"
[[package]]
name = "crc32fast"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
dependencies = [
"cfg-if",
]
[[package]]
name = "critical-section"
version = "1.2.0"
@@ -800,16 +756,6 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
[[package]]
name = "flate2"
version = "1.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c"
dependencies = [
"crc32fast",
"miniz_oxide",
]
[[package]]
name = "fnv"
version = "1.0.7"
@@ -1053,24 +999,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
dependencies = [
"cfg-if",
"js-sys",
"libc",
"wasi",
"wasm-bindgen",
]
[[package]]
name = "getrandom"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
dependencies = [
"cfg-if",
"js-sys",
"libc",
"r-efi 5.3.0",
"wasip2",
"wasm-bindgen",
]
[[package]]
@@ -1081,7 +1011,7 @@ checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555"
dependencies = [
"cfg-if",
"libc",
"r-efi 6.0.0",
"r-efi",
"wasip2",
"wasip3",
]
@@ -1532,23 +1462,6 @@ dependencies = [
"want",
]
[[package]]
name = "hyper-rustls"
version = "0.27.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58"
dependencies = [
"http",
"hyper",
"hyper-util",
"rustls",
"rustls-pki-types",
"tokio",
"tokio-rustls",
"tower-service",
"webpki-roots",
]
[[package]]
name = "hyper-tls"
version = "0.6.0"
@@ -1952,12 +1865,6 @@ dependencies = [
"tracing-subscriber",
]
[[package]]
name = "lru-slab"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
[[package]]
name = "lua-src"
version = "550.0.0"
@@ -2032,16 +1939,6 @@ dependencies = [
"nom",
]
[[package]]
name = "miniz_oxide"
version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
dependencies = [
"adler2",
"simd-adler32",
]
[[package]]
name = "mio"
version = "1.1.1"
@@ -2119,15 +2016,6 @@ dependencies = [
"syn 2.0.117",
]
[[package]]
name = "nanorand"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3"
dependencies = [
"getrandom 0.2.17",
]
[[package]]
name = "native-tls"
version = "0.2.18"
@@ -2460,7 +2348,7 @@ dependencies = [
[[package]]
name = "owlry"
version = "1.0.6"
version = "1.0.7"
dependencies = [
"chrono",
"clap",
@@ -2481,7 +2369,7 @@ dependencies = [
[[package]]
name = "owlry-core"
version = "1.3.2"
version = "1.3.3"
dependencies = [
"chrono",
"ctrlc",
@@ -2497,18 +2385,19 @@ dependencies = [
"notify-debouncer-mini",
"notify-rust",
"owlry-plugin-api",
"reqwest 0.13.2",
"reqwest",
"semver",
"serde",
"serde_json",
"tempfile",
"thiserror 2.0.18",
"toml 0.8.23",
"toml_edit 0.22.27",
]
[[package]]
name = "owlry-lua"
version = "1.1.1"
version = "1.1.2"
dependencies = [
"abi_stable",
"chrono",
@@ -2516,7 +2405,7 @@ dependencies = [
"meval",
"mlua",
"owlry-plugin-api",
"reqwest 0.13.2",
"reqwest",
"semver",
"serde",
"serde_json",
@@ -2534,16 +2423,15 @@ dependencies = [
[[package]]
name = "owlry-rune"
version = "1.1.1"
version = "1.1.3"
dependencies = [
"chrono",
"dirs",
"env_logger",
"log",
"owlry-plugin-api",
"reqwest 0.13.2",
"reqwest",
"rune",
"rune-modules",
"semver",
"serde",
"serde_json",
@@ -2715,15 +2603,6 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]]
name = "ppv-lite86"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
dependencies = [
"zerocopy",
]
[[package]]
name = "prettyplease"
version = "0.2.37"
@@ -2761,61 +2640,6 @@ dependencies = [
"memchr",
]
[[package]]
name = "quinn"
version = "0.11.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20"
dependencies = [
"bytes",
"cfg_aliases",
"pin-project-lite",
"quinn-proto",
"quinn-udp",
"rustc-hash",
"rustls",
"socket2",
"thiserror 2.0.18",
"tokio",
"tracing",
"web-time",
]
[[package]]
name = "quinn-proto"
version = "0.11.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098"
dependencies = [
"bytes",
"getrandom 0.3.4",
"lru-slab",
"rand",
"ring",
"rustc-hash",
"rustls",
"rustls-pki-types",
"slab",
"thiserror 2.0.18",
"tinyvec",
"tracing",
"web-time",
]
[[package]]
name = "quinn-udp"
version = "0.5.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd"
dependencies = [
"cfg_aliases",
"libc",
"once_cell",
"socket2",
"tracing",
"windows-sys 0.60.2",
]
[[package]]
name = "quote"
version = "1.0.45"
@@ -2825,47 +2649,12 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "r-efi"
version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
[[package]]
name = "r-efi"
version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
[[package]]
name = "rand"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
dependencies = [
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c"
dependencies = [
"getrandom 0.3.4",
]
[[package]]
name = "redox_syscall"
version = "0.5.18"
@@ -2933,44 +2722,6 @@ dependencies = [
"tstr",
]
[[package]]
name = "reqwest"
version = "0.12.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147"
dependencies = [
"base64",
"bytes",
"futures-core",
"http",
"http-body",
"http-body-util",
"hyper",
"hyper-rustls",
"hyper-util",
"js-sys",
"log",
"percent-encoding",
"pin-project-lite",
"quinn",
"rustls",
"rustls-pki-types",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper",
"tokio",
"tokio-rustls",
"tower",
"tower-http",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"webpki-roots",
]
[[package]]
name = "reqwest"
version = "0.13.2"
@@ -3008,20 +2759,6 @@ dependencies = [
"web-sys",
]
[[package]]
name = "ring"
version = "0.17.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
dependencies = [
"cc",
"cfg-if",
"getrandom 0.2.17",
"libc",
"untrusted",
"windows-sys 0.52.0",
]
[[package]]
name = "rune"
version = "0.14.1"
@@ -3095,21 +2832,6 @@ dependencies = [
"syn 2.0.117",
]
[[package]]
name = "rune-modules"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f4ef5dc3546042989f4abc70d6b9f707a539d5cbb5cb2fb167f8fbe891e1b64"
dependencies = [
"base64",
"nanorand",
"reqwest 0.12.28",
"rune",
"serde_json",
"tokio",
"toml 0.8.23",
]
[[package]]
name = "rune-tracing"
version = "0.14.1"
@@ -3158,41 +2880,15 @@ dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "rustls"
version = "0.23.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4"
dependencies = [
"once_cell",
"ring",
"rustls-pki-types",
"rustls-webpki",
"subtle",
"zeroize",
]
[[package]]
name = "rustls-pki-types"
version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd"
dependencies = [
"web-time",
"zeroize",
]
[[package]]
name = "rustls-webpki"
version = "0.103.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef"
dependencies = [
"ring",
"rustls-pki-types",
"untrusted",
]
[[package]]
name = "rustversion"
version = "1.0.22"
@@ -3346,18 +3042,6 @@ dependencies = [
"serde_core",
]
[[package]]
name = "serde_urlencoded"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
dependencies = [
"form_urlencoded",
"itoa",
"ryu",
"serde",
]
[[package]]
name = "sharded-slab"
version = "0.1.7"
@@ -3383,12 +3067,6 @@ dependencies = [
"libc",
]
[[package]]
name = "simd-adler32"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2"
[[package]]
name = "simdutf8"
version = "0.1.5"
@@ -3429,12 +3107,6 @@ version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "subtle"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "syn"
version = "1.0.109"
@@ -3620,21 +3292,6 @@ dependencies = [
"zerovec",
]
[[package]]
name = "tinyvec"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.50.0"
@@ -3645,7 +3302,6 @@ dependencies = [
"libc",
"mio",
"pin-project-lite",
"signal-hook-registry",
"socket2",
"windows-sys 0.61.2",
]
@@ -3660,29 +3316,6 @@ dependencies = [
"tokio",
]
[[package]]
name = "tokio-rustls"
version = "0.26.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61"
dependencies = [
"rustls",
"tokio",
]
[[package]]
name = "tokio-util"
version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
"pin-project-lite",
"tokio",
]
[[package]]
name = "toml"
version = "0.8.23"
@@ -3805,18 +3438,13 @@ version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8"
dependencies = [
"async-compression",
"bitflags 2.11.0",
"bytes",
"futures-core",
"futures-util",
"http",
"http-body",
"http-body-util",
"iri-string",
"pin-project-lite",
"tokio",
"tokio-util",
"tower",
"tower-layer",
"tower-service",
@@ -3975,12 +3603,6 @@ version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
[[package]]
name = "untrusted"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "url"
version = "2.5.8"
@@ -4186,25 +3808,6 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "web-time"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "webpki-roots"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed"
dependencies = [
"rustls-pki-types",
]
[[package]]
name = "which"
version = "8.0.2"
@@ -4411,15 +4014,6 @@ dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows-sys"
version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
dependencies = [
"windows-targets 0.53.5",
]
[[package]]
name = "windows-sys"
version = "0.61.2"
@@ -4453,30 +4047,13 @@ dependencies = [
"windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.6",
"windows_i686_gnullvm 0.52.6",
"windows_i686_gnullvm",
"windows_i686_msvc 0.52.6",
"windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc 0.52.6",
]
[[package]]
name = "windows-targets"
version = "0.53.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
dependencies = [
"windows-link 0.2.1",
"windows_aarch64_gnullvm 0.53.1",
"windows_aarch64_msvc 0.53.1",
"windows_i686_gnu 0.53.1",
"windows_i686_gnullvm 0.53.1",
"windows_i686_msvc 0.53.1",
"windows_x86_64_gnu 0.53.1",
"windows_x86_64_gnullvm 0.53.1",
"windows_x86_64_msvc 0.53.1",
]
[[package]]
name = "windows-threading"
version = "0.1.0"
@@ -4507,12 +4084,6 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
@@ -4525,12 +4096,6 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_aarch64_msvc"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
@@ -4543,24 +4108,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnu"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_gnullvm"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
@@ -4573,12 +4126,6 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_i686_msvc"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
@@ -4591,12 +4138,6 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnu"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
@@ -4609,12 +4150,6 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
@@ -4627,12 +4162,6 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "windows_x86_64_msvc"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
[[package]]
name = "winnow"
version = "0.7.15"

View File

@@ -254,7 +254,7 @@ Type `:config` to browse and modify settings without editing files:
| Command | What it does |
|---------|-------------|
| `:config` | Show all setting categories |
| `:config providers` | Toggle providers on/off |
| `:config providers` | Toggle built-in providers on/off (calculator, converter, system, frecency) |
| `:config theme` | Select color theme |
| `:config engine` | Select web search engine |
| `:config frecency` | Toggle frecency, set weight |
@@ -265,6 +265,8 @@ Type `:config` to browse and modify settings without editing files:
Changes are saved to `config.toml` immediately. Some settings (theme, frecency) take effect on the next search. Others (font size, dimensions) require a restart.
> **Note:** `:config providers` only covers built-in providers. To enable or disable plugins, use `owlry plugin enable/disable <name>` or set `disabled_plugins` in `[plugins]`.
### Search Prefixes
| Prefix | Provider | Example |
@@ -332,33 +334,54 @@ Or configure from within the launcher: type `:config` to interactively change se
```toml
[general]
show_icons = true
max_results = 10
tabs = ["app", "cmd", "uuctl"]
# terminal_command = "kitty" # Auto-detected
# use_uwsm = false # Enable for systemd session integration
max_results = 100
tabs = ["app", "cmd", "uuctl"] # Provider tabs shown in the header bar
# terminal_command = "kitty" # Auto-detected; overrides $TERMINAL and xdg-terminal-exec
# use_uwsm = false # Enable for systemd session integration (uwsm app --)
[appearance]
width = 850
height = 650
font_size = 14
border_radius = 12
# theme = "owl" # Or: catppuccin-mocha, nord, dracula, etc.
# theme = "owl" # Or: catppuccin-mocha, nord, dracula, etc. (see Theming section)
[plugins]
disabled = [] # Plugin IDs to disable, e.g., ["emoji", "pomodoro"]
# Optional per-element color overrides — all fields are optional, unset inherits from theme
# [appearance.colors]
# background = "#1e1e2e"
# background_secondary = "#313244"
# border = "#45475a"
# text = "#cdd6f4"
# accent = "#cba6f7"
# badge_app = "#a6e3a1" # All badge_* keys: app, cmd, clip, ssh, emoji, file,
# badge_web = "#89dceb" # script, sys, uuctl, web, calc, bm, dmenu,
# badge_media = "#f38ba8" # media, weather, pomo
[providers]
applications = true # .desktop files
commands = true # PATH executables
calculator = true # Built-in math expressions
converter = true # Built-in unit/currency conversion
calculator = true # Built-in math expressions (= or calc trigger)
converter = true # Built-in unit/currency converter (> trigger)
system = true # Built-in shutdown/reboot/lock actions
frecency = true # Boost frequently used items
frecency_weight = 0.3 # 0.0-1.0
frecency_weight = 0.3 # 0.0 = disabled, 1.0 = strong boost
# Web search engine: google, duckduckgo, bing, startpage, brave, ecosia
# Web search engine: google, duckduckgo, bing, startpage, searxng, brave, ecosia
# Or a custom URL with a {query} placeholder: "https://example.com/search?q={query}"
search_engine = "duckduckgo"
[plugins]
# disabled_plugins = ["emoji", "pomodoro"] # Plugin IDs to disable
# enabled_plugins = [] # Empty = all discovered plugins are loaded
# registry_url = "https://..." # Custom plugin registry URL
# Sandboxing for Lua/Rune user plugins (~/.config/owlry/plugins/)
# [plugins.sandbox]
# allow_filesystem = false # Allow access outside plugin directory
# allow_network = false # Allow outbound network requests
# allow_commands = false # Allow shell command execution
# memory_limit = 67108864 # Lua memory cap in bytes (default: 64 MB)
# Profiles: named sets of modes
[profiles.dev]
modes = ["app", "cmd", "ssh"]
@@ -382,10 +405,17 @@ Add plugin IDs to the disabled list in your config:
```toml
[plugins]
disabled = ["emoji", "pomodoro"]
disabled_plugins = ["emoji", "pomodoro"]
```
Or toggle providers interactively: type `:config providers` in the launcher.
Or use the CLI:
```bash
owlry plugin disable emoji
owlry plugin enable emoji
```
> **Note:** `:config providers` in the launcher only manages built-in providers (calculator, converter, system). Use `disabled_plugins` or `owlry plugin disable` for plugins.
### Plugin Management CLI

View File

@@ -1,13 +1,14 @@
pkgbase = owlry-core
pkgdesc = Core daemon for the Owlry application launcher — manages plugins, providers, and search
pkgver = 1.3.1
pkgver = 1.3.2
pkgrel = 1
url = https://somegit.dev/Owlibou/owlry
arch = x86_64
license = GPL-3.0-or-later
makedepends = cargo
depends = gcc-libs
source = owlry-core-1.3.1.tar.gz::https://somegit.dev/Owlibou/owlry/archive/owlry-core-v1.3.1.tar.gz
b2sums = e37383fd650a3bf9a2c554eb37676037e3ae72bbc2e1aad7c316809094254173b6fcd5ac87907c2f38ce5506e9f26201ec62f82446bc789153c280373e31fc9e
depends = openssl
source = owlry-core-1.3.2.tar.gz::https://somegit.dev/Owlibou/owlry/archive/owlry-core-v1.3.2.tar.gz
b2sums = 36a1e31cadcfdbe70c0a10c13eddbcea7ae21b7dcfb0aa10a75f44a82a377d6598c4237228457c13260ca4b4b88f12d416541ad7698cf28076124b1a4d3dbbc6
pkgname = owlry-core

View File

@@ -1,6 +1,6 @@
# Maintainer: vikingowl <christian@nachtigall.dev>
pkgname=owlry-core
pkgver=1.3.1
pkgver=1.3.2
pkgrel=1
pkgdesc='Core daemon for the Owlry application launcher — manages plugins, providers, and search'
arch=('x86_64')
@@ -9,7 +9,7 @@ license=('GPL-3.0-or-later')
depends=('gcc-libs' 'openssl')
makedepends=('cargo')
source=("$pkgname-$pkgver.tar.gz::https://somegit.dev/Owlibou/owlry/archive/owlry-core-v$pkgver.tar.gz")
b2sums=('e37383fd650a3bf9a2c554eb37676037e3ae72bbc2e1aad7c316809094254173b6fcd5ac87907c2f38ce5506e9f26201ec62f82446bc789153c280373e31fc9e')
b2sums=('36a1e31cadcfdbe70c0a10c13eddbcea7ae21b7dcfb0aa10a75f44a82a377d6598c4237228457c13260ca4b4b88f12d416541ad7698cf28076124b1a4d3dbbc6')
prepare() {
cd "owlry"

View File

@@ -1,13 +1,14 @@
pkgbase = owlry-lua
pkgdesc = Lua scripting runtime for Owlry — enables user-created Lua plugins
pkgver = 1.1.1
pkgver = 1.1.2
pkgrel = 1
url = https://somegit.dev/Owlibou/owlry
arch = x86_64
license = GPL-3.0-or-later
makedepends = cargo
depends = owlry-core
source = owlry-lua-1.1.1.tar.gz::https://somegit.dev/Owlibou/owlry/archive/owlry-lua-v1.1.1.tar.gz
b2sums = a0e1fa032db8dda8e6bc24457f3c04948129d3f14c1d3e61b8e080340b24f560d43294beb133ad4b1c6eb7942d401108ea91c367b074eaeeefa284e9b2a9dbc8
depends = openssl
source = owlry-lua-1.1.2.tar.gz::https://somegit.dev/Owlibou/owlry/archive/owlry-lua-v1.1.2.tar.gz
b2sums = 42e6221e6e07c629ece1493e7f5feb1b2cb2e77632d1d7779dfbe544bd89a17d77d1839d63e50d71d4f0e0322ca8a1cc39b872101039019bdf08d9bcaeda7603
pkgname = owlry-lua

View File

@@ -1,6 +1,6 @@
# Maintainer: vikingowl <christian@nachtigall.dev>
pkgname=owlry-lua
pkgver=1.1.1
pkgver=1.1.2
pkgrel=1
pkgdesc="Lua scripting runtime for Owlry — enables user-created Lua plugins"
arch=('x86_64')
@@ -9,7 +9,7 @@ license=('GPL-3.0-or-later')
depends=('owlry-core' 'openssl')
makedepends=('cargo')
source=("$pkgname-$pkgver.tar.gz::https://somegit.dev/Owlibou/owlry/archive/owlry-lua-v$pkgver.tar.gz")
b2sums=('a0e1fa032db8dda8e6bc24457f3c04948129d3f14c1d3e61b8e080340b24f560d43294beb133ad4b1c6eb7942d401108ea91c367b074eaeeefa284e9b2a9dbc8')
b2sums=('42e6221e6e07c629ece1493e7f5feb1b2cb2e77632d1d7779dfbe544bd89a17d77d1839d63e50d71d4f0e0322ca8a1cc39b872101039019bdf08d9bcaeda7603')
_cratename=owlry-lua

View File

@@ -1,13 +1,14 @@
pkgbase = owlry-rune
pkgdesc = Rune scripting runtime for Owlry — enables user-created Rune plugins
pkgver = 1.1.1
pkgver = 1.1.3
pkgrel = 1
url = https://somegit.dev/Owlibou/owlry
arch = x86_64
license = GPL-3.0-or-later
makedepends = cargo
depends = owlry-core
source = owlry-rune-1.1.1.tar.gz::https://somegit.dev/Owlibou/owlry/archive/owlry-rune-v1.1.1.tar.gz
b2sums = a0e1fa032db8dda8e6bc24457f3c04948129d3f14c1d3e61b8e080340b24f560d43294beb133ad4b1c6eb7942d401108ea91c367b074eaeeefa284e9b2a9dbc8
depends = openssl
source = owlry-rune-1.1.3.tar.gz::https://somegit.dev/Owlibou/owlry/archive/owlry-rune-v1.1.3.tar.gz
b2sums = 3dd1db5783b0e0c814f8e6064fd5d8cb736da5bd4759d648f48ea69a476451f64d27ecd0894378f3e41e7cc85557b7d9dcb0adf80114c32e561d4688aae6bb53
pkgname = owlry-rune

View File

@@ -1,6 +1,6 @@
# Maintainer: vikingowl <christian@nachtigall.dev>
pkgname=owlry-rune
pkgver=1.1.1
pkgver=1.1.3
pkgrel=1
pkgdesc="Rune scripting runtime for Owlry — enables user-created Rune plugins"
arch=('x86_64')
@@ -9,7 +9,7 @@ license=('GPL-3.0-or-later')
depends=('owlry-core' 'openssl')
makedepends=('cargo')
source=("$pkgname-$pkgver.tar.gz::https://somegit.dev/Owlibou/owlry/archive/owlry-rune-v$pkgver.tar.gz")
b2sums=('a0e1fa032db8dda8e6bc24457f3c04948129d3f14c1d3e61b8e080340b24f560d43294beb133ad4b1c6eb7942d401108ea91c367b074eaeeefa284e9b2a9dbc8')
b2sums=('3dd1db5783b0e0c814f8e6064fd5d8cb736da5bd4759d648f48ea69a476451f64d27ecd0894378f3e41e7cc85557b7d9dcb0adf80114c32e561d4688aae6bb53')
_cratename=owlry-rune

View File

@@ -1,6 +1,6 @@
[package]
name = "owlry-core"
version = "1.3.2"
version = "1.3.3"
edition.workspace = true
rust-version.workspace = true
license.workspace = true
@@ -30,6 +30,7 @@ semver = "1"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
toml = "0.8"
toml_edit = "0.22"
chrono = { version = "0.4", features = ["serde"] }
dirs = "5"

View File

@@ -2,6 +2,7 @@ use log::{debug, info, warn};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::path::PathBuf;
use toml_edit::{DocumentMut, Item};
use crate::paths;
@@ -157,82 +158,26 @@ pub struct ProvidersConfig {
pub applications: bool,
#[serde(default = "default_true")]
pub commands: bool,
#[serde(default = "default_true")]
pub uuctl: bool,
/// Enable calculator provider (= expression or calc expression)
/// Enable built-in calculator provider (= or calc trigger)
#[serde(default = "default_true")]
pub calculator: bool,
/// Enable converter provider (> expression or auto-detect)
/// Enable built-in unit/currency converter (> trigger)
#[serde(default = "default_true")]
pub converter: bool,
/// Enable built-in system actions (shutdown, reboot, lock, etc.)
#[serde(default = "default_true")]
pub system: bool,
/// Enable frecency-based result ranking
#[serde(default = "default_true")]
pub frecency: bool,
/// Weight for frecency boost (0.0 = disabled, 1.0 = strong boost)
#[serde(default = "default_frecency_weight")]
pub frecency_weight: f64,
/// Enable web search provider (? query or web query)
#[serde(default = "default_true")]
pub websearch: bool,
/// Search engine for web search
/// Search engine for web search (used by owlry-plugin-websearch)
/// Options: google, duckduckgo, bing, startpage, searxng, brave, ecosia
/// Or custom URL with {query} placeholder
/// Or a custom URL with a {query} placeholder
#[serde(default = "default_search_engine")]
pub search_engine: String,
/// Enable system commands (shutdown, reboot, etc.)
#[serde(default = "default_true")]
pub system: bool,
/// Enable SSH connections from ~/.ssh/config
#[serde(default = "default_true")]
pub ssh: bool,
/// Enable clipboard history (requires cliphist)
#[serde(default = "default_true")]
pub clipboard: bool,
/// Enable browser bookmarks
#[serde(default = "default_true")]
pub bookmarks: bool,
/// Enable emoji picker
#[serde(default = "default_true")]
pub emoji: bool,
/// Enable custom scripts from ~/.config/owlry/scripts/
#[serde(default = "default_true")]
pub scripts: bool,
/// Enable file search (requires fd or locate)
#[serde(default = "default_true")]
pub files: bool,
// ─── Widget Providers ───────────────────────────────────────────────
/// Enable MPRIS media player widget
#[serde(default = "default_true")]
pub media: bool,
/// Enable weather widget
#[serde(default)]
pub weather: bool,
/// Weather provider: wttr.in (default), openweathermap, open-meteo
#[serde(default = "default_weather_provider")]
pub weather_provider: String,
/// API key for weather services that require it (e.g., OpenWeatherMap)
#[serde(default)]
pub weather_api_key: Option<String>,
/// Location for weather (city name or coordinates)
#[serde(default)]
pub weather_location: Option<String>,
/// Enable pomodoro timer widget
#[serde(default)]
pub pomodoro: bool,
/// Pomodoro work duration in minutes
#[serde(default = "default_pomodoro_work")]
pub pomodoro_work_mins: u32,
/// Pomodoro break duration in minutes
#[serde(default = "default_pomodoro_break")]
pub pomodoro_break_mins: u32,
}
impl Default for ProvidersConfig {
@@ -240,28 +185,12 @@ impl Default for ProvidersConfig {
Self {
applications: true,
commands: true,
uuctl: true,
calculator: true,
converter: true,
system: true,
frecency: true,
frecency_weight: 0.3,
websearch: true,
search_engine: "duckduckgo".to_string(),
system: true,
ssh: true,
clipboard: true,
bookmarks: true,
emoji: true,
scripts: true,
files: true,
media: true,
weather: false,
weather_provider: "wttr.in".to_string(),
weather_api_key: None,
weather_location: Some("Berlin".to_string()),
pomodoro: false,
pomodoro_work_mins: 25,
pomodoro_break_mins: 5,
}
}
}
@@ -399,18 +328,6 @@ fn default_frecency_weight() -> f64 {
0.3
}
fn default_weather_provider() -> String {
"wttr.in".to_string()
}
fn default_pomodoro_work() -> u32 {
25
}
fn default_pomodoro_break() -> u32 {
5
}
/// Detect the best available terminal emulator
/// Fallback chain:
/// 1. $TERMINAL env var (user's explicit preference)
@@ -539,6 +456,38 @@ fn command_exists(cmd: &str) -> bool {
// Note: Config derives Default via #[derive(Default)] - all sub-structs have impl Default
/// Merge `new` into `existing`, updating values while preserving comments and unknown keys.
///
/// Tables are recursed into so that section-level comments survive. For leaf values
/// (scalars, arrays) the item is replaced but the surrounding table structure — and
/// any keys in `existing` that are absent from `new` — are left untouched.
fn merge_toml_doc(existing: &mut DocumentMut, new: &DocumentMut) {
for (key, new_item) in new.iter() {
match existing.get_mut(key) {
Some(existing_item) => merge_item(existing_item, new_item),
None => {
existing.insert(key, new_item.clone());
}
}
}
}
fn merge_item(existing: &mut Item, new: &Item) {
match (existing.as_table_mut(), new.as_table()) {
(Some(e), Some(n)) => {
for (key, new_child) in n.iter() {
match e.get_mut(key) {
Some(existing_child) => merge_item(existing_child, new_child),
None => {
e.insert(key, new_child.clone());
}
}
}
}
_ => *existing = new.clone(),
}
}
impl Config {
pub fn config_path() -> Option<PathBuf> {
paths::config_file()
@@ -585,13 +534,34 @@ impl Config {
Ok(config)
}
#[allow(dead_code)]
pub fn save(&self) -> Result<(), Box<dyn std::error::Error>> {
let path = Self::config_path().ok_or("Could not determine config path")?;
paths::ensure_parent_dir(&path)?;
let content = toml::to_string_pretty(self)?;
let new_content = toml::to_string_pretty(self)?;
// If a config file already exists, merge into it to preserve comments and
// any keys the user has added that are not part of the Config struct.
let content = if path.exists() {
let existing = std::fs::read_to_string(&path)?;
match existing.parse::<toml_edit::DocumentMut>() {
Ok(mut doc) => {
if let Ok(new_doc) = new_content.parse::<toml_edit::DocumentMut>() {
merge_toml_doc(&mut doc, &new_doc);
}
doc.to_string()
}
Err(_) => {
// Existing file is malformed — fall back to full rewrite.
warn!("Existing config is malformed; overwriting with current settings");
new_content
}
}
} else {
new_content
};
std::fs::write(&path, content)?;
info!("Saved config to {:?}", path);
Ok(())

View File

@@ -26,11 +26,17 @@ pub struct ParsedQuery {
}
impl ProviderFilter {
/// Create filter from CLI args and config
/// Create filter from CLI args and config.
///
/// `tabs` is `general.tabs` from config and drives which provider tabs are
/// shown in the UI when no explicit CLI mode is active. It has no effect on
/// query routing: when no CLI mode is set, `accept_all=true` causes
/// `is_active()` to return `true` for every provider regardless.
pub fn new(
cli_mode: Option<ProviderType>,
cli_providers: Option<Vec<ProviderType>>,
config_providers: &ProvidersConfig,
tabs: &[String],
) -> Self {
let accept_all = cli_mode.is_none() && cli_providers.is_none();
@@ -41,50 +47,23 @@ impl ProviderFilter {
// --providers overrides config
providers.into_iter().collect()
} else {
// Use config file settings, default to apps only
let mut set = HashSet::new();
// Core providers
if config_providers.applications {
set.insert(ProviderType::Application);
}
if config_providers.commands {
set.insert(ProviderType::Command);
}
// Plugin providers - use Plugin(type_id) for all
if config_providers.uuctl {
set.insert(ProviderType::Plugin("uuctl".to_string()));
}
if config_providers.system {
set.insert(ProviderType::Plugin("system".to_string()));
}
if config_providers.ssh {
set.insert(ProviderType::Plugin("ssh".to_string()));
}
if config_providers.clipboard {
set.insert(ProviderType::Plugin("clipboard".to_string()));
}
if config_providers.bookmarks {
set.insert(ProviderType::Plugin("bookmarks".to_string()));
}
if config_providers.emoji {
set.insert(ProviderType::Plugin("emoji".to_string()));
}
if config_providers.scripts {
set.insert(ProviderType::Plugin("scripts".to_string()));
}
// Dynamic providers
if config_providers.files {
set.insert(ProviderType::Plugin("filesearch".to_string()));
}
if config_providers.calculator {
set.insert(ProviderType::Plugin("calc".to_string()));
}
if config_providers.websearch {
set.insert(ProviderType::Plugin("websearch".to_string()));
}
// Default to apps if nothing enabled
// No CLI restriction: accept_all=true, so is_active() returns true for
// everything. Build the enabled set only for UI tab display, driven by
// general.tabs. Falls back to Application + Command if tabs is empty.
let mut set: HashSet<ProviderType> = tabs
.iter()
.map(|s| Self::mode_string_to_provider_type(s))
.collect();
if set.is_empty() {
set.insert(ProviderType::Application);
if config_providers.applications {
set.insert(ProviderType::Application);
}
if config_providers.commands {
set.insert(ProviderType::Command);
}
if set.is_empty() {
set.insert(ProviderType::Application);
}
}
set
};
@@ -114,7 +93,8 @@ impl ProviderFilter {
}
}
/// Toggle a provider on/off
/// Toggle a provider on/off. Clears accept_all so the enabled set is
/// actually used for routing — use restore_all_mode() to go back to All.
pub fn toggle(&mut self, provider: ProviderType) {
if self.enabled.contains(&provider) {
self.enabled.remove(&provider);
@@ -137,6 +117,7 @@ impl ProviderFilter {
provider_debug, self.enabled
);
}
self.accept_all = false;
}
/// Enable a specific provider
@@ -156,6 +137,12 @@ impl ProviderFilter {
pub fn set_single_mode(&mut self, provider: ProviderType) {
self.enabled.clear();
self.enabled.insert(provider);
self.accept_all = false;
}
/// Restore accept-all mode (used when cycling back to the "All" tab).
pub fn restore_all_mode(&mut self) {
self.accept_all = true;
}
/// Set prefix mode (from :app, :cmd, etc.)

View File

@@ -23,24 +23,15 @@ const SEARCH_ENGINES: &[&str] = &[
const BUILTIN_THEMES: &[&str] = &["owl"];
/// Boolean provider fields that can be toggled via CONFIG:toggle:providers.*.
/// Only built-in providers are listed here; plugins are enabled/disabled via
/// [plugins] disabled_plugins in config.toml or `owlry plugin enable/disable`.
const PROVIDER_TOGGLES: &[(&str, &str)] = &[
("applications", "Applications"),
("commands", "Commands"),
("uuctl", "Systemd Units"),
("calculator", "Calculator"),
("converter", "Unit Converter"),
("frecency", "Frecency Ranking"),
("websearch", "Web Search"),
("system", "System Actions"),
("ssh", "SSH Connections"),
("clipboard", "Clipboard History"),
("bookmarks", "Bookmarks"),
("emoji", "Emoji Picker"),
("scripts", "Scripts"),
("files", "File Search"),
("media", "Media Widget"),
("weather", "Weather Widget"),
("pomodoro", "Pomodoro Widget"),
("frecency", "Frecency Ranking"),
];
/// Built-in config editor provider. Interprets query text as a navigation path
@@ -70,12 +61,8 @@ impl ConfigProvider {
false
};
if result {
if let Ok(cfg) = self.config.read() {
if let Err(e) = cfg.save() {
warn!("Failed to save config: {}", e);
}
}
if result && let Ok(cfg) = self.config.read() && let Err(e) = cfg.save() {
warn!("Failed to save config: {}", e);
}
result
@@ -98,10 +85,6 @@ impl ConfigProvider {
cfg.providers.commands = !cfg.providers.commands;
true
}
"providers.uuctl" => {
cfg.providers.uuctl = !cfg.providers.uuctl;
true
}
"providers.calculator" => {
cfg.providers.calculator = !cfg.providers.calculator;
true
@@ -110,52 +93,12 @@ impl ConfigProvider {
cfg.providers.converter = !cfg.providers.converter;
true
}
"providers.frecency" => {
cfg.providers.frecency = !cfg.providers.frecency;
true
}
"providers.websearch" => {
cfg.providers.websearch = !cfg.providers.websearch;
true
}
"providers.system" => {
cfg.providers.system = !cfg.providers.system;
true
}
"providers.ssh" => {
cfg.providers.ssh = !cfg.providers.ssh;
true
}
"providers.clipboard" => {
cfg.providers.clipboard = !cfg.providers.clipboard;
true
}
"providers.bookmarks" => {
cfg.providers.bookmarks = !cfg.providers.bookmarks;
true
}
"providers.emoji" => {
cfg.providers.emoji = !cfg.providers.emoji;
true
}
"providers.scripts" => {
cfg.providers.scripts = !cfg.providers.scripts;
true
}
"providers.files" => {
cfg.providers.files = !cfg.providers.files;
true
}
"providers.media" => {
cfg.providers.media = !cfg.providers.media;
true
}
"providers.weather" => {
cfg.providers.weather = !cfg.providers.weather;
true
}
"providers.pomodoro" => {
cfg.providers.pomodoro = !cfg.providers.pomodoro;
"providers.frecency" => {
cfg.providers.frecency = !cfg.providers.frecency;
true
}
"general.show_icons" => {
@@ -762,21 +705,10 @@ fn get_provider_bool(cfg: &Config, field: &str) -> bool {
match field {
"applications" => cfg.providers.applications,
"commands" => cfg.providers.commands,
"uuctl" => cfg.providers.uuctl,
"calculator" => cfg.providers.calculator,
"converter" => cfg.providers.converter,
"frecency" => cfg.providers.frecency,
"websearch" => cfg.providers.websearch,
"system" => cfg.providers.system,
"ssh" => cfg.providers.ssh,
"clipboard" => cfg.providers.clipboard,
"bookmarks" => cfg.providers.bookmarks,
"emoji" => cfg.providers.emoji,
"scripts" => cfg.providers.scripts,
"files" => cfg.providers.files,
"media" => cfg.providers.media,
"weather" => cfg.providers.weather,
"pomodoro" => cfg.providers.pomodoro,
"frecency" => cfg.providers.frecency,
_ => false,
}
}

View File

@@ -1,6 +1,6 @@
[package]
name = "owlry-lua"
version = "1.1.1"
version = "1.1.2"
edition.workspace = true
rust-version.workspace = true
license.workspace = true

View File

@@ -1,6 +1,6 @@
[package]
name = "owlry-rune"
version = "1.1.1"
version = "1.1.3"
edition = "2024"
rust-version = "1.90"
description = "Rune scripting runtime for owlry plugins"
@@ -15,7 +15,6 @@ owlry-plugin-api = { path = "../owlry-plugin-api" }
# Rune scripting language
rune = "0.14"
rune-modules = { version = "0.14", features = ["full"] }
# Logging
log = "0.4"

View File

@@ -1,6 +1,6 @@
[package]
name = "owlry"
version = "1.0.6"
version = "1.0.7"
edition = "2024"
rust-version = "1.90"
description = "A lightweight, owl-themed application launcher for Wayland"

View File

@@ -91,17 +91,20 @@ impl OwlryApp {
.iter()
.map(|s| ProviderFilter::mode_string_to_provider_type(s))
.collect();
let tabs = &config.borrow().general.tabs.clone();
if provider_types.len() == 1 {
ProviderFilter::new(
Some(provider_types[0].clone()),
None,
&config.borrow().providers,
tabs,
)
} else {
ProviderFilter::new(None, Some(provider_types), &config.borrow().providers)
ProviderFilter::new(None, Some(provider_types), &config.borrow().providers, tabs)
}
} else {
ProviderFilter::new(None, None, &config.borrow().providers)
let tabs = config.borrow().general.tabs.clone();
ProviderFilter::new(None, None, &config.borrow().providers, &tabs)
};
let filter = Rc::new(RefCell::new(filter));

View File

@@ -394,7 +394,9 @@ impl MainWindow {
format!("Search {}...", active.join(", "))
}
/// Build dynamic hints based on enabled providers
/// Build hints string for the status bar based on enabled built-in providers.
/// Plugin trigger hints (? web, / files, etc.) are not included here since
/// plugin availability is not tracked in ProvidersConfig.
fn build_hints(config: &owlry_core::config::ProvidersConfig) -> String {
let mut parts: Vec<String> = vec![
"Tab: cycle".to_string(),
@@ -403,38 +405,14 @@ impl MainWindow {
"Esc: close".to_string(),
];
// Add trigger hints for enabled dynamic providers
if config.calculator {
parts.push("= calc".to_string());
}
if config.websearch {
parts.push("? web".to_string());
if config.converter {
parts.push("> conv".to_string());
}
if config.files {
parts.push("/ files".to_string());
}
// Add prefix hints for static providers
let mut prefixes = Vec::new();
if config.system {
prefixes.push(":sys");
}
if config.emoji {
prefixes.push(":emoji");
}
if config.ssh {
prefixes.push(":ssh");
}
if config.clipboard {
prefixes.push(":clip");
}
if config.bookmarks {
prefixes.push(":bm");
}
// Only show first few prefixes to avoid overflow
if !prefixes.is_empty() {
parts.push(prefixes[..prefixes.len().min(4)].join(" "));
parts.push(":sys".to_string());
}
parts.join(" ")
@@ -1159,6 +1137,7 @@ impl MainWindow {
for provider in tab_order {
f.enable(provider.clone());
}
f.restore_all_mode();
}
for (_, button) in buttons.borrow().iter() {
button.set_active(true);

View File

@@ -59,8 +59,10 @@ max_results = 100
# Requires: uwsm to be installed
# use_uwsm = true
# Header tabs - providers shown as toggle buttons (Ctrl+1, Ctrl+2, etc.)
# Values: app, cmd, uuctl, bookmark, calc, clip, dmenu, emoji, file, script, ssh, sys, web
# Header tabs provider tabs shown in the UI bar (Ctrl+1..9 to toggle)
# Core values: app, cmd, dmenu
# Plugin values: uuctl, calc, clip, emoji, file, script, ssh, sys, web, bm
# Any installed plugin's type_id is valid (e.g. "weather", "media")
tabs = ["app", "cmd", "uuctl"]
# ═══════════════════════════════════════════════════════════════════════
@@ -140,55 +142,25 @@ disabled_plugins = []
# PROVIDERS
# ═══════════════════════════════════════════════════════════════════════
#
# Enable/disable providers and configure their settings.
# Core providers (applications, commands) are built into the binary.
# Plugin providers require their .so to be installed.
# Controls built-in providers only. Plugins are enabled/disabled via
# [plugins] disabled_plugins or `owlry plugin enable/disable <name>`.
[providers]
# Core providers (always available)
# Core providers
applications = true # .desktop applications from XDG dirs
commands = true # Executables from $PATH
# Frecency - boost frequently/recently used items
# Built-in providers (compiled into owlry-core)
calculator = true # Math expressions (= or calc trigger)
converter = true # Unit/currency conversion (> trigger)
system = true # System actions: shutdown, reboot, lock, etc.
# Frecency — boost frequently/recently used items
# Data stored in: ~/.local/share/owlry/frecency.json
frecency = true
frecency_weight = 0.3 # 0.0 = disabled, 1.0 = strong boost
# ─────────────────────────────────────────────────────────────────────────
# Plugin provider toggles (require corresponding plugin installed)
# ─────────────────────────────────────────────────────────────────────────
uuctl = true # systemd user units
system = true # System commands (shutdown, reboot, etc.)
ssh = true # SSH hosts from ~/.ssh/config
clipboard = true # Clipboard history (requires cliphist)
bookmarks = true # Browser bookmarks
emoji = true # Emoji picker
scripts = true # Custom scripts from ~/.local/share/owlry/scripts/
files = true # File search (requires fd or mlocate)
calculator = true # Calculator (= expression)
websearch = true # Web search (? query)
# ─────────────────────────────────────────────────────────────────────────
# Widget providers (displayed at top of results)
# ─────────────────────────────────────────────────────────────────────────
media = true # MPRIS media player controls
weather = false # Weather widget (disabled by default)
pomodoro = false # Pomodoro timer (disabled by default)
# ─────────────────────────────────────────────────────────────────────────
# Provider settings
# ─────────────────────────────────────────────────────────────────────────
# Web search engine
# Web search engine (used by owlry-plugin-websearch)
# Options: google, duckduckgo, bing, startpage, searxng, brave, ecosia
# Or custom URL: "https://search.example.com/?q={query}"
# Or a custom URL: "https://search.example.com/?q={query}"
search_engine = "duckduckgo"
# Weather settings (when weather = true)
# weather_provider = "wttr.in" # Options: wttr.in, openweathermap, open-meteo
# weather_location = "Berlin" # City name or coordinates
# weather_api_key = "" # Required for openweathermap
# Pomodoro settings (when pomodoro = true)
# pomodoro_work_mins = 25 # Work session duration
# pomodoro_break_mins = 5 # Break duration

View File

@@ -135,6 +135,45 @@ done
[[ ${#INPUT_PKGS[@]} -eq 0 ]] && usage
# ─── Inject deduplication ────────────────────────────────────────────────────
# Extract the package name from a .pkg.tar.zst filename.
# Arch package filenames follow: {pkgname}-{pkgver}-{pkgrel}-{arch}.pkg.tar.zst
# pkgver is guaranteed to have no dashes, so stripping the last three
# dash-separated segments leaves pkgname.
pkg_name_from_file() {
local base
base=$(basename "$1" .pkg.tar.zst)
base="${base%-*}" # strip arch
base="${base%-*}" # strip pkgrel
base="${base%-*}" # strip pkgver (no dashes in pkgver by Arch policy)
echo "$base"
}
# Deduplicate a list of .pkg.tar.zst paths by package name.
# When the same package name appears more than once, keep the highest version
# (determined by sort -V on the filenames) and warn about the dropped ones.
dedup_inject_files() {
[[ $# -eq 0 ]] && return 0
local -A best=()
local f name winner
for f in "$@"; do
name=$(pkg_name_from_file "$f")
if [[ -v "best[$name]" ]]; then
winner=$(printf '%s\n%s\n' "${best[$name]}" "$f" | sort -V | tail -1)
if [[ "$winner" == "$f" ]]; then
warn "Dropping duplicate inject (older): $(basename "${best[$name]}")"
best[$name]="$f"
else
warn "Dropping duplicate inject (older): $(basename "$f")"
fi
else
best[$name]="$f"
fi
done
printf '%s\n' "${best[@]}"
}
# ─── Dependency resolution ───────────────────────────────────────────────────
# Return the names of local AUR packages that PKG depends on.
@@ -296,6 +335,11 @@ build_one() {
# ─── Main ────────────────────────────────────────────────────────────────────
# Deduplicate external inject files by package name (keep highest version)
if [[ ${#EXTRA_INJECT[@]} -gt 1 ]]; then
mapfile -t EXTRA_INJECT < <(dedup_inject_files "${EXTRA_INJECT[@]}")
fi
# Validate all requested packages exist
for pkg in "${INPUT_PKGS[@]}"; do
[[ -d "$AUR_DIR/$pkg" && -f "$AUR_DIR/$pkg/PKGBUILD" ]] \