feature/prod-ready #1
309
Cargo.lock
generated
309
Cargo.lock
generated
@@ -24,6 +24,12 @@ version = "2.0.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
|
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ahash"
|
||||||
|
version = "0.4.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0453232ace82dee0dd0b4c87a59bd90f7b53b314f3e0f61fe2ee7c8a16482289"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ahash"
|
name = "ahash"
|
||||||
version = "0.8.12"
|
version = "0.8.12"
|
||||||
@@ -37,6 +43,15 @@ dependencies = [
|
|||||||
"zerocopy",
|
"zerocopy",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "1.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aligned"
|
name = "aligned"
|
||||||
version = "0.4.3"
|
version = "0.4.3"
|
||||||
@@ -351,7 +366,7 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"log",
|
"log",
|
||||||
"nom",
|
"nom 8.0.0",
|
||||||
"num-rational",
|
"num-rational",
|
||||||
"v_frame",
|
"v_frame",
|
||||||
]
|
]
|
||||||
@@ -903,6 +918,15 @@ dependencies = [
|
|||||||
"libloading",
|
"libloading",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dlv-list"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "68df3f2b690c1b86e65ef7830956aededf3cb0a16f898f79b9a6f421a7b6211b"
|
||||||
|
dependencies = [
|
||||||
|
"rand 0.8.5",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "document-features"
|
name = "document-features"
|
||||||
version = "0.2.12"
|
version = "0.2.12"
|
||||||
@@ -940,7 +964,7 @@ version = "0.31.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d0dfe0859f3fb1bc6424c57d41e10e9093fe938f426b691e42272c2f336d915c"
|
checksum = "d0dfe0859f3fb1bc6424c57d41e10e9093fe938f426b691e42272c2f336d915c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash 0.8.12",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"document-features",
|
"document-features",
|
||||||
"egui",
|
"egui",
|
||||||
@@ -976,7 +1000,7 @@ version = "0.31.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "25dd34cec49ab55d85ebf70139cb1ccd29c977ef6b6ba4fe85489d6877ee9ef3"
|
checksum = "25dd34cec49ab55d85ebf70139cb1ccd29c977ef6b6ba4fe85489d6877ee9ef3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash 0.8.12",
|
||||||
"bitflags 2.11.0",
|
"bitflags 2.11.0",
|
||||||
"emath",
|
"emath",
|
||||||
"epaint",
|
"epaint",
|
||||||
@@ -991,7 +1015,7 @@ version = "0.31.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d319dfef570f699b6e9114e235e862a2ddcf75f0d1a061de9e1328d92146d820"
|
checksum = "d319dfef570f699b6e9114e235e862a2ddcf75f0d1a061de9e1328d92146d820"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash 0.8.12",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"document-features",
|
"document-features",
|
||||||
"egui",
|
"egui",
|
||||||
@@ -1011,7 +1035,7 @@ version = "0.31.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7d9dfbb78fe4eb9c3a39ad528b90ee5915c252e77bbab9d4ebc576541ab67e13"
|
checksum = "7d9dfbb78fe4eb9c3a39ad528b90ee5915c252e77bbab9d4ebc576541ab67e13"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash 0.8.12",
|
||||||
"arboard",
|
"arboard",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"egui",
|
"egui",
|
||||||
@@ -1030,7 +1054,7 @@ version = "0.31.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "910906e3f042ea6d2378ec12a6fd07698e14ddae68aed2d819ffe944a73aab9e"
|
checksum = "910906e3f042ea6d2378ec12a6fd07698e14ddae68aed2d819ffe944a73aab9e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash 0.8.12",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"egui",
|
"egui",
|
||||||
"glow",
|
"glow",
|
||||||
@@ -1091,7 +1115,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "41fcc0f5a7c613afd2dee5e4b30c3e6acafb8ad6f0edb06068811f708a67c562"
|
checksum = "41fcc0f5a7c613afd2dee5e4b30c3e6acafb8ad6f0edb06068811f708a67c562"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ab_glyph",
|
"ab_glyph",
|
||||||
"ahash",
|
"ahash 0.8.12",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"ecolor",
|
"ecolor",
|
||||||
"emath",
|
"emath",
|
||||||
@@ -1246,6 +1270,15 @@ dependencies = [
|
|||||||
"simd-adler32",
|
"simd-adler32",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "file-locker"
|
||||||
|
version = "1.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "75ae8b5984a4863d8a32109a848d038bd6d914f20f010cc141375f7a183c41cf"
|
||||||
|
dependencies = [
|
||||||
|
"nix",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "find-msvc-tools"
|
name = "find-msvc-tools"
|
||||||
version = "0.1.9"
|
version = "0.1.9"
|
||||||
@@ -1306,7 +1339,7 @@ checksum = "457e789b3d1202543297a350643cf459f836cade38934e7a4cf6a39e7cde2905"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"fontconfig-parser",
|
"fontconfig-parser",
|
||||||
"log",
|
"log",
|
||||||
"memmap2",
|
"memmap2 0.9.10",
|
||||||
"slotmap",
|
"slotmap",
|
||||||
"tinyvec",
|
"tinyvec",
|
||||||
"ttf-parser",
|
"ttf-parser",
|
||||||
@@ -1348,6 +1381,16 @@ dependencies = [
|
|||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "freedesktop_entry_parser"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "db9c27b72f19a99a895f8ca89e2d26e4ef31013376e56fdafef697627306c3e4"
|
||||||
|
dependencies = [
|
||||||
|
"nom 7.1.3",
|
||||||
|
"thiserror 1.0.69",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures"
|
name = "futures"
|
||||||
version = "0.3.32"
|
version = "0.3.32"
|
||||||
@@ -1696,6 +1739,15 @@ dependencies = [
|
|||||||
"smallvec",
|
"smallvec",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.9.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
|
||||||
|
dependencies = [
|
||||||
|
"ahash 0.4.8",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.15.5"
|
version = "0.15.5"
|
||||||
@@ -2227,6 +2279,7 @@ dependencies = [
|
|||||||
"plugin-cmd",
|
"plugin-cmd",
|
||||||
"plugin-files",
|
"plugin-files",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tracing-subscriber",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2339,6 +2392,12 @@ dependencies = [
|
|||||||
"smallvec",
|
"smallvec",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "leb128fmt"
|
name = "leb128fmt"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -2410,6 +2469,29 @@ version = "0.1.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d4a5ff6bcca6c4867b1c4fd4ef63e4db7436ef363e0ad7531d1558856bae64f4"
|
checksum = "d4a5ff6bcca6c4867b1c4fd4ef63e4db7436ef363e0ad7531d1558856bae64f4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linicon"
|
||||||
|
version = "2.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4ee8c5653188a809616c97296180a0547a61dba205bcdcbdd261dbd022a25fd9"
|
||||||
|
dependencies = [
|
||||||
|
"file-locker",
|
||||||
|
"freedesktop_entry_parser",
|
||||||
|
"linicon-theme",
|
||||||
|
"memmap2 0.5.10",
|
||||||
|
"thiserror 1.0.69",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linicon-theme"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a4f8240c33bb08c5d8b8cdea87b683b05e61037aa76ff26bef40672cc6ecbb80"
|
||||||
|
dependencies = [
|
||||||
|
"freedesktop_entry_parser",
|
||||||
|
"rust-ini",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linux-raw-sys"
|
name = "linux-raw-sys"
|
||||||
version = "0.4.15"
|
version = "0.4.15"
|
||||||
@@ -2473,6 +2555,15 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "matchers"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9"
|
||||||
|
dependencies = [
|
||||||
|
"regex-automata",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "maybe-rayon"
|
name = "maybe-rayon"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
@@ -2489,6 +2580,15 @@ version = "2.8.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memmap2"
|
||||||
|
version = "0.5.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memmap2"
|
name = "memmap2"
|
||||||
version = "0.9.10"
|
version = "0.9.10"
|
||||||
@@ -2537,6 +2637,12 @@ dependencies = [
|
|||||||
"paste",
|
"paste",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "minimal-lexical"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "miniz_oxide"
|
||||||
version = "0.8.9"
|
version = "0.8.9"
|
||||||
@@ -2692,12 +2798,34 @@ version = "1.0.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
|
checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nix"
|
||||||
|
version = "0.29.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.11.0",
|
||||||
|
"cfg-if",
|
||||||
|
"cfg_aliases",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nohash-hasher"
|
name = "nohash-hasher"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
|
checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "7.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"minimal-lexical",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nom"
|
name = "nom"
|
||||||
version = "8.0.0"
|
version = "8.0.0"
|
||||||
@@ -2713,6 +2841,25 @@ version = "0.3.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8"
|
checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nu-ansi-term"
|
||||||
|
version = "0.50.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys 0.61.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nucleo-matcher"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bf33f538733d1a5a3494b836ba913207f14d9d4a1d3cd67030c5061bdd2cac85"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"unicode-segmentation",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-bigint"
|
name = "num-bigint"
|
||||||
version = "0.4.6"
|
version = "0.4.6"
|
||||||
@@ -3185,6 +3332,16 @@ dependencies = [
|
|||||||
"num-traits",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ordered-multimap"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1c672c7ad9ec066e428c00eb917124a06f08db19e2584de982cc34b1f4c12485"
|
||||||
|
dependencies = [
|
||||||
|
"dlv-list",
|
||||||
|
"hashbrown 0.9.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ordered-stream"
|
name = "ordered-stream"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
@@ -3318,9 +3475,12 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"k-launcher-kernel",
|
"k-launcher-kernel",
|
||||||
|
"linicon",
|
||||||
|
"nucleo-matcher",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tracing",
|
||||||
"xdg",
|
"xdg",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -3540,14 +3700,35 @@ version = "6.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
|
checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"rand_chacha 0.3.1",
|
||||||
|
"rand_core 0.6.4",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand"
|
name = "rand"
|
||||||
version = "0.9.2"
|
version = "0.9.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
|
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand_chacha",
|
"rand_chacha 0.9.0",
|
||||||
"rand_core",
|
"rand_core 0.9.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_chacha"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||||
|
dependencies = [
|
||||||
|
"ppv-lite86",
|
||||||
|
"rand_core 0.6.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3557,7 +3738,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ppv-lite86",
|
"ppv-lite86",
|
||||||
"rand_core",
|
"rand_core 0.9.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.2.17",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3608,8 +3798,8 @@ dependencies = [
|
|||||||
"num-traits",
|
"num-traits",
|
||||||
"paste",
|
"paste",
|
||||||
"profiling",
|
"profiling",
|
||||||
"rand",
|
"rand 0.9.2",
|
||||||
"rand_chacha",
|
"rand_chacha 0.9.0",
|
||||||
"simd_helpers",
|
"simd_helpers",
|
||||||
"thiserror 2.0.18",
|
"thiserror 2.0.18",
|
||||||
"v_frame",
|
"v_frame",
|
||||||
@@ -3706,6 +3896,23 @@ dependencies = [
|
|||||||
"thiserror 2.0.18",
|
"thiserror 2.0.18",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.4.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.8.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "renderdoc-sys"
|
name = "renderdoc-sys"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@@ -3744,6 +3951,16 @@ version = "0.20.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97"
|
checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rust-ini"
|
||||||
|
version = "0.17.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "63471c4aa97a1cf8332a5f97709a79a4234698de6a1f5087faf66f2dae810e22"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"ordered-multimap",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-hash"
|
name = "rustc-hash"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@@ -3844,7 +4061,7 @@ checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"ab_glyph",
|
"ab_glyph",
|
||||||
"log",
|
"log",
|
||||||
"memmap2",
|
"memmap2 0.9.10",
|
||||||
"smithay-client-toolkit 0.19.2",
|
"smithay-client-toolkit 0.19.2",
|
||||||
"tiny-skia",
|
"tiny-skia",
|
||||||
]
|
]
|
||||||
@@ -3924,6 +4141,15 @@ dependencies = [
|
|||||||
"serde_core",
|
"serde_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sharded-slab"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shlex"
|
name = "shlex"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
@@ -4029,7 +4255,7 @@ dependencies = [
|
|||||||
"cursor-icon",
|
"cursor-icon",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"memmap2",
|
"memmap2 0.9.10",
|
||||||
"rustix 0.38.44",
|
"rustix 0.38.44",
|
||||||
"thiserror 1.0.69",
|
"thiserror 1.0.69",
|
||||||
"wayland-backend",
|
"wayland-backend",
|
||||||
@@ -4054,7 +4280,7 @@ dependencies = [
|
|||||||
"cursor-icon",
|
"cursor-icon",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"memmap2",
|
"memmap2 0.9.10",
|
||||||
"rustix 1.1.4",
|
"rustix 1.1.4",
|
||||||
"thiserror 2.0.18",
|
"thiserror 2.0.18",
|
||||||
"wayland-backend",
|
"wayland-backend",
|
||||||
@@ -4099,7 +4325,7 @@ dependencies = [
|
|||||||
"bytemuck",
|
"bytemuck",
|
||||||
"fastrand",
|
"fastrand",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"memmap2",
|
"memmap2 0.9.10",
|
||||||
"ndk",
|
"ndk",
|
||||||
"objc2 0.6.4",
|
"objc2 0.6.4",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
@@ -4292,6 +4518,15 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thread_local"
|
||||||
|
version = "1.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tiff"
|
name = "tiff"
|
||||||
version = "0.10.3"
|
version = "0.10.3"
|
||||||
@@ -4477,6 +4712,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
|
checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
"valuable",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-log"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"once_cell",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-subscriber"
|
||||||
|
version = "0.3.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319"
|
||||||
|
dependencies = [
|
||||||
|
"matchers",
|
||||||
|
"nu-ansi-term",
|
||||||
|
"once_cell",
|
||||||
|
"regex-automata",
|
||||||
|
"sharded-slab",
|
||||||
|
"smallvec",
|
||||||
|
"thread_local",
|
||||||
|
"tracing",
|
||||||
|
"tracing-core",
|
||||||
|
"tracing-log",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -4647,6 +4912,12 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "valuable"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version_check"
|
name = "version_check"
|
||||||
version = "0.9.5"
|
version = "0.9.5"
|
||||||
@@ -5607,7 +5878,7 @@ version = "0.30.13"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a6755fa58a9f8350bd1e472d4c3fcc25f824ec358933bba33306d0b63df5978d"
|
checksum = "a6755fa58a9f8350bd1e472d4c3fcc25f824ec358933bba33306d0b63df5978d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash 0.8.12",
|
||||||
"android-activity",
|
"android-activity",
|
||||||
"atomic-waker",
|
"atomic-waker",
|
||||||
"bitflags 2.11.0",
|
"bitflags 2.11.0",
|
||||||
@@ -5622,7 +5893,7 @@ dependencies = [
|
|||||||
"dpi",
|
"dpi",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"memmap2",
|
"memmap2 0.9.10",
|
||||||
"ndk",
|
"ndk",
|
||||||
"objc2 0.5.2",
|
"objc2 0.5.2",
|
||||||
"objc2-app-kit 0.2.2",
|
"objc2-app-kit 0.2.2",
|
||||||
|
|||||||
@@ -107,8 +107,7 @@ impl Default for PluginsCfg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn load() -> Config {
|
pub fn load() -> Config {
|
||||||
let path = dirs::config_dir()
|
let path = dirs::config_dir().map(|d| d.join("k-launcher").join("config.toml"));
|
||||||
.map(|d| d.join("k-launcher").join("config.toml"));
|
|
||||||
let Some(path) = path else {
|
let Some(path) = path else {
|
||||||
return Config::default();
|
return Config::default();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ impl ResultTitle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize)]
|
#[derive(
|
||||||
|
Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize,
|
||||||
|
)]
|
||||||
pub struct Score(u32);
|
pub struct Score(u32);
|
||||||
|
|
||||||
impl Score {
|
impl Score {
|
||||||
@@ -104,7 +106,10 @@ pub struct Kernel {
|
|||||||
|
|
||||||
impl Kernel {
|
impl Kernel {
|
||||||
pub fn new(plugins: Vec<Arc<dyn Plugin>>, max_results: usize) -> Self {
|
pub fn new(plugins: Vec<Arc<dyn Plugin>>, max_results: usize) -> Self {
|
||||||
Self { plugins, max_results }
|
Self {
|
||||||
|
plugins,
|
||||||
|
max_results,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn search(&self, query: &str) -> Vec<SearchResult> {
|
pub async fn search(&self, query: &str) -> Vec<SearchResult> {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use std::process::{Command, Stdio};
|
|
||||||
use std::os::unix::process::CommandExt;
|
use std::os::unix::process::CommandExt;
|
||||||
|
use std::process::{Command, Stdio};
|
||||||
|
|
||||||
use k_launcher_kernel::{AppLauncher, LaunchAction};
|
use k_launcher_kernel::{AppLauncher, LaunchAction};
|
||||||
|
|
||||||
@@ -77,21 +77,31 @@ impl AppLauncher for UnixAppLauncher {
|
|||||||
.stdin(Stdio::null())
|
.stdin(Stdio::null())
|
||||||
.stdout(Stdio::null())
|
.stdout(Stdio::null())
|
||||||
.stderr(Stdio::null())
|
.stderr(Stdio::null())
|
||||||
.pre_exec(|| { libc::setsid(); Ok(()) })
|
.pre_exec(|| {
|
||||||
|
libc::setsid();
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
.spawn()
|
.spawn()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LaunchAction::SpawnInTerminal(cmd) => {
|
LaunchAction::SpawnInTerminal(cmd) => {
|
||||||
let Some((term_bin, term_args)) = resolve_terminal() else { return };
|
let Some((term_bin, term_args)) = resolve_terminal() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
let _ = unsafe {
|
let _ = unsafe {
|
||||||
Command::new(&term_bin)
|
Command::new(&term_bin)
|
||||||
.args(&term_args)
|
.args(&term_args)
|
||||||
.arg("sh").arg("-c").arg(cmd)
|
.arg("sh")
|
||||||
|
.arg("-c")
|
||||||
|
.arg(cmd)
|
||||||
.stdin(Stdio::null())
|
.stdin(Stdio::null())
|
||||||
.stdout(Stdio::null())
|
.stdout(Stdio::null())
|
||||||
.stderr(Stdio::null())
|
.stderr(Stdio::null())
|
||||||
.pre_exec(|| { libc::setsid(); Ok(()) })
|
.pre_exec(|| {
|
||||||
|
libc::setsid();
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
.spawn()
|
.spawn()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ async fn do_search(
|
|||||||
io: &mut ProcessIo,
|
io: &mut ProcessIo,
|
||||||
query: &str,
|
query: &str,
|
||||||
) -> Result<Vec<ExternalResult>, Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<Vec<ExternalResult>, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let line = serde_json::to_string(&Query { query: query.to_string() })?;
|
let line = serde_json::to_string(&Query {
|
||||||
|
query: query.to_string(),
|
||||||
|
})?;
|
||||||
io.stdin.write_all(line.as_bytes()).await?;
|
io.stdin.write_all(line.as_bytes()).await?;
|
||||||
io.stdin.write_all(b"\n").await?;
|
io.stdin.write_all(b"\n").await?;
|
||||||
io.stdin.flush().await?;
|
io.stdin.flush().await?;
|
||||||
@@ -143,7 +145,9 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn query_serializes_correctly() {
|
fn query_serializes_correctly() {
|
||||||
let q = Query { query: "firefox".to_string() };
|
let q = Query {
|
||||||
|
query: "firefox".to_string(),
|
||||||
|
};
|
||||||
assert_eq!(serde_json::to_string(&q).unwrap(), r#"{"query":"firefox"}"#);
|
assert_eq!(serde_json::to_string(&q).unwrap(), r#"{"query":"firefox"}"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,21 +159,27 @@ mod tests {
|
|||||||
assert_eq!(results[0].id, "1");
|
assert_eq!(results[0].id, "1");
|
||||||
assert_eq!(results[0].title, "Firefox");
|
assert_eq!(results[0].title, "Firefox");
|
||||||
assert_eq!(results[0].score, 80);
|
assert_eq!(results[0].score, 80);
|
||||||
assert!(matches!(&results[0].action, ExternalAction::SpawnProcess { cmd } if cmd == "firefox"));
|
assert!(
|
||||||
|
matches!(&results[0].action, ExternalAction::SpawnProcess { cmd } if cmd == "firefox")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn result_parses_copy_action() {
|
fn result_parses_copy_action() {
|
||||||
let json = r#"[{"id":"c","title":"= 4","score":90,"action":{"type":"CopyToClipboard","text":"4"}}]"#;
|
let json = r#"[{"id":"c","title":"= 4","score":90,"action":{"type":"CopyToClipboard","text":"4"}}]"#;
|
||||||
let results: Vec<ExternalResult> = serde_json::from_str(json).unwrap();
|
let results: Vec<ExternalResult> = serde_json::from_str(json).unwrap();
|
||||||
assert!(matches!(&results[0].action, ExternalAction::CopyToClipboard { text } if text == "4"));
|
assert!(
|
||||||
|
matches!(&results[0].action, ExternalAction::CopyToClipboard { text } if text == "4")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn result_parses_open_path_action() {
|
fn result_parses_open_path_action() {
|
||||||
let json = r#"[{"id":"f","title":"/home/user","score":50,"action":{"type":"OpenPath","path":"/home/user"}}]"#;
|
let json = r#"[{"id":"f","title":"/home/user","score":50,"action":{"type":"OpenPath","path":"/home/user"}}]"#;
|
||||||
let results: Vec<ExternalResult> = serde_json::from_str(json).unwrap();
|
let results: Vec<ExternalResult> = serde_json::from_str(json).unwrap();
|
||||||
assert!(matches!(&results[0].action, ExternalAction::OpenPath { path } if path == "/home/user"));
|
assert!(
|
||||||
|
matches!(&results[0].action, ExternalAction::OpenPath { path } if path == "/home/user")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -182,7 +192,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn result_parses_missing_optional_fields() {
|
fn result_parses_missing_optional_fields() {
|
||||||
let json = r#"[{"id":"x","title":"X","score":10,"action":{"type":"SpawnProcess","cmd":"x"}}]"#;
|
let json =
|
||||||
|
r#"[{"id":"x","title":"X","score":10,"action":{"type":"SpawnProcess","cmd":"x"}}]"#;
|
||||||
let results: Vec<ExternalResult> = serde_json::from_str(json).unwrap();
|
let results: Vec<ExternalResult> = serde_json::from_str(json).unwrap();
|
||||||
assert!(results[0].description.is_none());
|
assert!(results[0].description.is_none());
|
||||||
assert!(results[0].icon.is_none());
|
assert!(results[0].icon.is_none());
|
||||||
|
|||||||
@@ -127,11 +127,20 @@ impl eframe::App for KLauncherApp {
|
|||||||
ui.set_width(ui.available_width());
|
ui.set_width(ui.available_width());
|
||||||
for (i, result) in self.results.iter().enumerate() {
|
for (i, result) in self.results.iter().enumerate() {
|
||||||
let is_selected = i == self.selected;
|
let is_selected = i == self.selected;
|
||||||
let bg = if is_selected { SELECTED_BG } else { Color32::TRANSPARENT };
|
let bg = if is_selected {
|
||||||
|
SELECTED_BG
|
||||||
|
} else {
|
||||||
|
Color32::TRANSPARENT
|
||||||
|
};
|
||||||
|
|
||||||
let row_frame = egui::Frame::new()
|
let row_frame = egui::Frame::new()
|
||||||
.fill(bg)
|
.fill(bg)
|
||||||
.inner_margin(egui::Margin { left: 8, right: 8, top: 6, bottom: 6 })
|
.inner_margin(egui::Margin {
|
||||||
|
left: 8,
|
||||||
|
right: 8,
|
||||||
|
top: 6,
|
||||||
|
bottom: 6,
|
||||||
|
})
|
||||||
.corner_radius(egui::CornerRadius::same(4));
|
.corner_radius(egui::CornerRadius::same(4));
|
||||||
|
|
||||||
row_frame.show(ui, |ui| {
|
row_frame.show(ui, |ui| {
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use iced::{
|
use iced::{
|
||||||
Border, Color, Element, Length, Size, Subscription, Task,
|
Border, Color, Element, Length, Size, Subscription, Task, event,
|
||||||
event,
|
|
||||||
keyboard::{Event as KeyEvent, Key, key::Named},
|
keyboard::{Event as KeyEvent, Key, key::Named},
|
||||||
widget::{column, container, image, row, scrollable, svg, text, text_input, Space},
|
widget::{Space, column, container, image, row, scrollable, svg, text, text_input},
|
||||||
window,
|
window,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -126,8 +125,13 @@ fn view(state: &KLauncherApp) -> Element<'_, Message> {
|
|||||||
.padding(12)
|
.padding(12)
|
||||||
.size(cfg.search_font_size)
|
.size(cfg.search_font_size)
|
||||||
.style(|theme, _status| {
|
.style(|theme, _status| {
|
||||||
let mut s = iced::widget::text_input::default(theme, iced::widget::text_input::Status::Active);
|
let mut s =
|
||||||
s.border = Border { color: Color::TRANSPARENT, width: 0.0, radius: 0.0.into() };
|
iced::widget::text_input::default(theme, iced::widget::text_input::Status::Active);
|
||||||
|
s.border = Border {
|
||||||
|
color: Color::TRANSPARENT,
|
||||||
|
width: 0.0,
|
||||||
|
radius: 0.0.into(),
|
||||||
|
};
|
||||||
s
|
s
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -147,26 +151,27 @@ fn view(state: &KLauncherApp) -> Element<'_, Message> {
|
|||||||
Color::from_rgba8(255, 255, 255, 0.07)
|
Color::from_rgba8(255, 255, 255, 0.07)
|
||||||
};
|
};
|
||||||
let icon_el: Element<'_, Message> = match &result.icon {
|
let icon_el: Element<'_, Message> = match &result.icon {
|
||||||
Some(p) if p.ends_with(".svg") =>
|
Some(p) if p.ends_with(".svg") => {
|
||||||
svg(svg::Handle::from_path(p)).width(24).height(24).into(),
|
svg(svg::Handle::from_path(p)).width(24).height(24).into()
|
||||||
Some(p) =>
|
}
|
||||||
image(image::Handle::from_path(p)).width(24).height(24).into(),
|
Some(p) => image(image::Handle::from_path(p))
|
||||||
|
.width(24)
|
||||||
|
.height(24)
|
||||||
|
.into(),
|
||||||
None => Space::new().width(24).height(24).into(),
|
None => Space::new().width(24).height(24).into(),
|
||||||
};
|
};
|
||||||
let title_col: Element<'_, Message> = if let Some(desc) = &result.description {
|
let title_col: Element<'_, Message> = if let Some(desc) = &result.description {
|
||||||
column![
|
column![
|
||||||
text(result.title.as_str()).size(title_size),
|
text(result.title.as_str()).size(title_size),
|
||||||
text(desc).size(desc_size).color(Color::from_rgba8(210, 215, 230, 1.0)),
|
text(desc)
|
||||||
|
.size(desc_size)
|
||||||
|
.color(Color::from_rgba8(210, 215, 230, 1.0)),
|
||||||
]
|
]
|
||||||
.into()
|
.into()
|
||||||
} else {
|
} else {
|
||||||
text(result.title.as_str()).size(title_size).into()
|
text(result.title.as_str()).size(title_size).into()
|
||||||
};
|
};
|
||||||
container(
|
container(row![icon_el, title_col].spacing(8).align_y(iced::Center))
|
||||||
row![icon_el, title_col]
|
|
||||||
.spacing(8)
|
|
||||||
.align_y(iced::Center),
|
|
||||||
)
|
|
||||||
.width(Length::Fill)
|
.width(Length::Fill)
|
||||||
.padding([6, 12])
|
.padding([6, 12])
|
||||||
.style(move |_theme| container::Style {
|
.style(move |_theme| container::Style {
|
||||||
@@ -209,7 +214,8 @@ fn view(state: &KLauncherApp) -> Element<'_, Message> {
|
|||||||
.into()
|
.into()
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut content_children: Vec<Element<'_, Message>> = vec![search_bar.into(), results_list.into()];
|
let mut content_children: Vec<Element<'_, Message>> =
|
||||||
|
vec![search_bar.into(), results_list.into()];
|
||||||
if let Some(err) = maybe_error {
|
if let Some(err) = maybe_error {
|
||||||
content_children.push(err);
|
content_children.push(err);
|
||||||
}
|
}
|
||||||
@@ -261,15 +267,15 @@ pub fn run(
|
|||||||
update,
|
update,
|
||||||
view,
|
view,
|
||||||
)
|
)
|
||||||
.title("K-Launcher")
|
.title("K-Launcher")
|
||||||
.subscription(subscription)
|
.subscription(subscription)
|
||||||
.window(window::Settings {
|
.window(window::Settings {
|
||||||
size: Size::new(wc.width, wc.height),
|
size: Size::new(wc.width, wc.height),
|
||||||
position: window::Position::Centered,
|
position: window::Position::Centered,
|
||||||
decorations: wc.decorations,
|
decorations: wc.decorations,
|
||||||
transparent: wc.transparent,
|
transparent: wc.transparent,
|
||||||
resizable: wc.resizable,
|
resizable: wc.resizable,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.run()
|
.run()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
pub fn send_show() -> Result<(), Box<dyn std::error::Error>> {
|
pub fn send_show() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let runtime_dir = std::env::var("XDG_RUNTIME_DIR")
|
let runtime_dir =
|
||||||
.unwrap_or_else(|_| "/run/user/1000".to_string());
|
std::env::var("XDG_RUNTIME_DIR").unwrap_or_else(|_| "/run/user/1000".to_string());
|
||||||
let socket_path = format!("{runtime_dir}/k-launcher.sock");
|
let socket_path = format!("{runtime_dir}/k-launcher.sock");
|
||||||
let mut stream = std::os::unix::net::UnixStream::connect(&socket_path)?;
|
let mut stream = std::os::unix::net::UnixStream::connect(&socket_path)?;
|
||||||
stream.write_all(b"show\n")?;
|
stream.write_all(b"show\n")?;
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ use std::sync::Arc;
|
|||||||
use k_launcher_kernel::Kernel;
|
use k_launcher_kernel::Kernel;
|
||||||
use k_launcher_os_bridge::UnixAppLauncher;
|
use k_launcher_os_bridge::UnixAppLauncher;
|
||||||
use k_launcher_plugin_host::ExternalPlugin;
|
use k_launcher_plugin_host::ExternalPlugin;
|
||||||
use plugin_apps::{AppsPlugin, frecency::FrecencyStore};
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
use plugin_apps::linux::FsDesktopEntrySource;
|
use plugin_apps::linux::FsDesktopEntrySource;
|
||||||
|
use plugin_apps::{AppsPlugin, frecency::FrecencyStore};
|
||||||
use plugin_calc::CalcPlugin;
|
use plugin_calc::CalcPlugin;
|
||||||
use plugin_cmd::CmdPlugin;
|
use plugin_cmd::CmdPlugin;
|
||||||
use plugin_files::FilesPlugin;
|
use plugin_files::FilesPlugin;
|
||||||
@@ -36,14 +36,27 @@ fn run_ui() -> iced::Result {
|
|||||||
let frecency = FrecencyStore::load();
|
let frecency = FrecencyStore::load();
|
||||||
|
|
||||||
let mut plugins: Vec<Arc<dyn k_launcher_kernel::Plugin>> = vec![];
|
let mut plugins: Vec<Arc<dyn k_launcher_kernel::Plugin>> = vec![];
|
||||||
if cfg.plugins.cmd { plugins.push(Arc::new(CmdPlugin::new())); }
|
if cfg.plugins.cmd {
|
||||||
if cfg.plugins.calc { plugins.push(Arc::new(CalcPlugin::new())); }
|
plugins.push(Arc::new(CmdPlugin::new()));
|
||||||
if cfg.plugins.files { plugins.push(Arc::new(FilesPlugin::new())); }
|
}
|
||||||
if cfg.plugins.apps {
|
if cfg.plugins.calc {
|
||||||
plugins.push(Arc::new(AppsPlugin::new(FsDesktopEntrySource::new(), frecency)));
|
plugins.push(Arc::new(CalcPlugin::new()));
|
||||||
|
}
|
||||||
|
if cfg.plugins.files {
|
||||||
|
plugins.push(Arc::new(FilesPlugin::new()));
|
||||||
|
}
|
||||||
|
if cfg.plugins.apps {
|
||||||
|
plugins.push(Arc::new(AppsPlugin::new(
|
||||||
|
FsDesktopEntrySource::new(),
|
||||||
|
frecency,
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
for ext in &cfg.plugins.external {
|
for ext in &cfg.plugins.external {
|
||||||
plugins.push(Arc::new(ExternalPlugin::new(&ext.name, &ext.path, ext.args.clone())));
|
plugins.push(Arc::new(ExternalPlugin::new(
|
||||||
|
&ext.name,
|
||||||
|
&ext.path,
|
||||||
|
ext.args.clone(),
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let kernel: Arc<dyn k_launcher_kernel::SearchEngine> =
|
let kernel: Arc<dyn k_launcher_kernel::SearchEngine> =
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use k_launcher_kernel::Kernel;
|
use k_launcher_kernel::Kernel;
|
||||||
use k_launcher_os_bridge::UnixAppLauncher;
|
use k_launcher_os_bridge::UnixAppLauncher;
|
||||||
use plugin_apps::{AppsPlugin, frecency::FrecencyStore};
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
use plugin_apps::linux::FsDesktopEntrySource;
|
use plugin_apps::linux::FsDesktopEntrySource;
|
||||||
|
use plugin_apps::{AppsPlugin, frecency::FrecencyStore};
|
||||||
use plugin_calc::CalcPlugin;
|
use plugin_calc::CalcPlugin;
|
||||||
use plugin_cmd::CmdPlugin;
|
use plugin_cmd::CmdPlugin;
|
||||||
use plugin_files::FilesPlugin;
|
use plugin_files::FilesPlugin;
|
||||||
@@ -12,12 +12,15 @@ use plugin_files::FilesPlugin;
|
|||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let launcher = Arc::new(UnixAppLauncher::new());
|
let launcher = Arc::new(UnixAppLauncher::new());
|
||||||
let frecency = FrecencyStore::load();
|
let frecency = FrecencyStore::load();
|
||||||
let kernel: Arc<dyn k_launcher_kernel::SearchEngine> = Arc::new(Kernel::new(vec![
|
let kernel: Arc<dyn k_launcher_kernel::SearchEngine> = Arc::new(Kernel::new(
|
||||||
Arc::new(CmdPlugin::new()),
|
vec![
|
||||||
Arc::new(CalcPlugin::new()),
|
Arc::new(CmdPlugin::new()),
|
||||||
Arc::new(FilesPlugin::new()),
|
Arc::new(CalcPlugin::new()),
|
||||||
Arc::new(AppsPlugin::new(FsDesktopEntrySource::new(), frecency)),
|
Arc::new(FilesPlugin::new()),
|
||||||
], 8));
|
Arc::new(AppsPlugin::new(FsDesktopEntrySource::new(), frecency)),
|
||||||
|
],
|
||||||
|
8,
|
||||||
|
));
|
||||||
k_launcher_ui_egui::run(kernel, launcher)?;
|
k_launcher_ui_egui::run(kernel, launcher)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,10 @@ impl FrecencyStore {
|
|||||||
.ok()
|
.ok()
|
||||||
.and_then(|s| serde_json::from_str(&s).ok())
|
.and_then(|s| serde_json::from_str(&s).ok())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
Arc::new(Self { path, data: Mutex::new(data) })
|
Arc::new(Self {
|
||||||
|
path,
|
||||||
|
data: Mutex::new(data),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -53,7 +56,10 @@ impl FrecencyStore {
|
|||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.as_secs();
|
.as_secs();
|
||||||
let mut data = self.data.lock().unwrap();
|
let mut data = self.data.lock().unwrap();
|
||||||
let entry = data.entry(id.to_string()).or_insert(Entry { count: 0, last_used: 0 });
|
let entry = data.entry(id.to_string()).or_insert(Entry {
|
||||||
|
count: 0,
|
||||||
|
last_used: 0,
|
||||||
|
});
|
||||||
entry.count += 1;
|
entry.count += 1;
|
||||||
entry.last_used = now;
|
entry.last_used = now;
|
||||||
if let Some(parent) = self.path.parent() {
|
if let Some(parent) = self.path.parent() {
|
||||||
@@ -72,7 +78,13 @@ impl FrecencyStore {
|
|||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.as_secs();
|
.as_secs();
|
||||||
let age_secs = now.saturating_sub(entry.last_used);
|
let age_secs = now.saturating_sub(entry.last_used);
|
||||||
let decay = if age_secs < 3600 { 4 } else if age_secs < 86400 { 2 } else { 1 };
|
let decay = if age_secs < 3600 {
|
||||||
|
4
|
||||||
|
} else if age_secs < 86400 {
|
||||||
|
2
|
||||||
|
} else {
|
||||||
|
1
|
||||||
|
};
|
||||||
entry.count * decay
|
entry.count * decay
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +98,13 @@ impl FrecencyStore {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|(id, entry)| {
|
.map(|(id, entry)| {
|
||||||
let age_secs = now.saturating_sub(entry.last_used);
|
let age_secs = now.saturating_sub(entry.last_used);
|
||||||
let decay = if age_secs < 3600 { 4 } else if age_secs < 86400 { 2 } else { 1 };
|
let decay = if age_secs < 3600 {
|
||||||
|
4
|
||||||
|
} else if age_secs < 86400 {
|
||||||
|
2
|
||||||
|
} else {
|
||||||
|
1
|
||||||
|
};
|
||||||
(id.clone(), entry.count * decay)
|
(id.clone(), entry.count * decay)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|||||||
@@ -91,7 +91,10 @@ impl AppsPlugin {
|
|||||||
let id = format!("app-{}", e.name.as_str());
|
let id = format!("app-{}", e.name.as_str());
|
||||||
let keywords_lc = e.keywords.iter().map(|k| k.to_lowercase()).collect();
|
let keywords_lc = e.keywords.iter().map(|k| k.to_lowercase()).collect();
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
let icon = e.icon.as_ref().and_then(|p| linux::resolve_icon_path(p.as_str()));
|
let icon = e
|
||||||
|
.icon
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|p| linux::resolve_icon_path(p.as_str()));
|
||||||
#[cfg(not(target_os = "linux"))]
|
#[cfg(not(target_os = "linux"))]
|
||||||
let icon: Option<String> = None;
|
let icon: Option<String> = None;
|
||||||
let exec = e.exec.as_str().to_string();
|
let exec = e.exec.as_str().to_string();
|
||||||
@@ -117,13 +120,16 @@ impl AppsPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn initials(name_lc: &str) -> String {
|
fn initials(name_lc: &str) -> String {
|
||||||
name_lc.split_whitespace().filter_map(|w| w.chars().next()).collect()
|
name_lc
|
||||||
|
.split_whitespace()
|
||||||
|
.filter_map(|w| w.chars().next())
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn score_match(name: &str, query: &str) -> Option<u32> {
|
fn score_match(name: &str, query: &str) -> Option<u32> {
|
||||||
use nucleo_matcher::{
|
use nucleo_matcher::{
|
||||||
pattern::{CaseMatching, Normalization, Pattern},
|
|
||||||
Config, Matcher, Utf32Str,
|
Config, Matcher, Utf32Str,
|
||||||
|
pattern::{CaseMatching, Normalization, Pattern},
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut matcher = Matcher::new(Config::DEFAULT);
|
let mut matcher = Matcher::new(Config::DEFAULT);
|
||||||
@@ -136,7 +142,11 @@ fn score_match(name: &str, query: &str) -> Option<u32> {
|
|||||||
if let Some(s) = score {
|
if let Some(s) = score {
|
||||||
let name_lc = name.to_lowercase();
|
let name_lc = name.to_lowercase();
|
||||||
let query_lc = query.to_lowercase();
|
let query_lc = query.to_lowercase();
|
||||||
let bonus: u32 = if initials(&name_lc).starts_with(&query_lc) { 20 } else { 0 };
|
let bonus: u32 = if initials(&name_lc).starts_with(&query_lc) {
|
||||||
|
20
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
};
|
||||||
Some(s.saturating_add(bonus))
|
Some(s.saturating_add(bonus))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@@ -162,7 +172,9 @@ impl Plugin for AppsPlugin {
|
|||||||
|
|
||||||
async fn search(&self, query: &str) -> Vec<SearchResult> {
|
async fn search(&self, query: &str) -> Vec<SearchResult> {
|
||||||
if query.is_empty() {
|
if query.is_empty() {
|
||||||
return self.frecency.top_ids(5)
|
return self
|
||||||
|
.frecency
|
||||||
|
.top_ids(5)
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|id| {
|
.filter_map(|id| {
|
||||||
let e = self.entries.get(id)?;
|
let e = self.entries.get(id)?;
|
||||||
@@ -185,7 +197,10 @@ impl Plugin for AppsPlugin {
|
|||||||
.values()
|
.values()
|
||||||
.filter_map(|e| {
|
.filter_map(|e| {
|
||||||
let score = score_match(e.name.as_str(), query).or_else(|| {
|
let score = score_match(e.name.as_str(), query).or_else(|| {
|
||||||
e.keywords_lc.iter().any(|k| k.contains(&query_lc)).then_some(50)
|
e.keywords_lc
|
||||||
|
.iter()
|
||||||
|
.any(|k| k.contains(&query_lc))
|
||||||
|
.then_some(50)
|
||||||
})?;
|
})?;
|
||||||
Some(SearchResult {
|
Some(SearchResult {
|
||||||
id: ResultId::new(&e.id),
|
id: ResultId::new(&e.id),
|
||||||
@@ -238,7 +253,14 @@ mod tests {
|
|||||||
Self {
|
Self {
|
||||||
entries: entries
|
entries: entries
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(n, e, kw)| (n.to_string(), e.to_string(), None, kw.into_iter().map(|s| s.to_string()).collect()))
|
.map(|(n, e, kw)| {
|
||||||
|
(
|
||||||
|
n.to_string(),
|
||||||
|
e.to_string(),
|
||||||
|
None,
|
||||||
|
kw.into_iter().map(|s| s.to_string()).collect(),
|
||||||
|
)
|
||||||
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -261,20 +283,29 @@ mod tests {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn apps_prefix_match() {
|
async fn apps_prefix_match() {
|
||||||
let p = AppsPlugin::new(MockSource::with(vec![("Firefox", "firefox")]), ephemeral_frecency());
|
let p = AppsPlugin::new(
|
||||||
|
MockSource::with(vec![("Firefox", "firefox")]),
|
||||||
|
ephemeral_frecency(),
|
||||||
|
);
|
||||||
let results = p.search("fire").await;
|
let results = p.search("fire").await;
|
||||||
assert_eq!(results[0].title.as_str(), "Firefox");
|
assert_eq!(results[0].title.as_str(), "Firefox");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn apps_no_match_returns_empty() {
|
async fn apps_no_match_returns_empty() {
|
||||||
let p = AppsPlugin::new(MockSource::with(vec![("Firefox", "firefox")]), ephemeral_frecency());
|
let p = AppsPlugin::new(
|
||||||
|
MockSource::with(vec![("Firefox", "firefox")]),
|
||||||
|
ephemeral_frecency(),
|
||||||
|
);
|
||||||
assert!(p.search("zz").await.is_empty());
|
assert!(p.search("zz").await.is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn apps_empty_query_no_frecency_returns_empty() {
|
async fn apps_empty_query_no_frecency_returns_empty() {
|
||||||
let p = AppsPlugin::new(MockSource::with(vec![("Firefox", "firefox")]), ephemeral_frecency());
|
let p = AppsPlugin::new(
|
||||||
|
MockSource::with(vec![("Firefox", "firefox")]),
|
||||||
|
ephemeral_frecency(),
|
||||||
|
);
|
||||||
assert!(p.search("").await.is_empty());
|
assert!(p.search("").await.is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,9 +353,15 @@ mod tests {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn apps_fuzzy_typo_match() {
|
async fn apps_fuzzy_typo_match() {
|
||||||
let p = AppsPlugin::new(MockSource::with(vec![("Firefox", "firefox")]), ephemeral_frecency());
|
let p = AppsPlugin::new(
|
||||||
|
MockSource::with(vec![("Firefox", "firefox")]),
|
||||||
|
ephemeral_frecency(),
|
||||||
|
);
|
||||||
let results = p.search("frefox").await;
|
let results = p.search("frefox").await;
|
||||||
assert!(!results.is_empty(), "nucleo should fuzzy-match 'frefox' to 'Firefox'");
|
assert!(
|
||||||
|
!results.is_empty(),
|
||||||
|
"nucleo should fuzzy-match 'frefox' to 'Firefox'"
|
||||||
|
);
|
||||||
assert!(results[0].score.value() > 0);
|
assert!(results[0].score.value() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use crate::{AppName, DesktopEntry, DesktopEntrySource, ExecCommand, IconPath};
|
|
||||||
use crate::humanize_category;
|
use crate::humanize_category;
|
||||||
|
use crate::{AppName, DesktopEntry, DesktopEntrySource, ExecCommand, IconPath};
|
||||||
|
|
||||||
pub struct FsDesktopEntrySource;
|
pub struct FsDesktopEntrySource;
|
||||||
|
|
||||||
@@ -154,13 +154,15 @@ fn parse_desktop_file(path: &Path) -> Option<DesktopEntry> {
|
|||||||
"Type" if !is_application => is_application = value.trim() == "Application",
|
"Type" if !is_application => is_application = value.trim() == "Application",
|
||||||
"NoDisplay" => no_display = value.trim().eq_ignore_ascii_case("true"),
|
"NoDisplay" => no_display = value.trim().eq_ignore_ascii_case("true"),
|
||||||
"Categories" if category.is_none() => {
|
"Categories" if category.is_none() => {
|
||||||
category = value.trim()
|
category = value
|
||||||
|
.trim()
|
||||||
.split(';')
|
.split(';')
|
||||||
.find(|s| !s.is_empty())
|
.find(|s| !s.is_empty())
|
||||||
.map(|s| humanize_category(s.trim()));
|
.map(|s| humanize_category(s.trim()));
|
||||||
}
|
}
|
||||||
"Keywords" if keywords.is_empty() => {
|
"Keywords" if keywords.is_empty() => {
|
||||||
keywords = value.trim()
|
keywords = value
|
||||||
|
.trim()
|
||||||
.split(';')
|
.split(';')
|
||||||
.filter(|s| !s.is_empty())
|
.filter(|s| !s.is_empty())
|
||||||
.map(|s| s.trim().to_string())
|
.map(|s| s.trim().to_string())
|
||||||
@@ -202,7 +204,10 @@ mod exec_tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn preserves_quoted_value() {
|
fn preserves_quoted_value() {
|
||||||
assert_eq!(clean_exec(r#"app --arg="value" %U"#), r#"app --arg="value""#);
|
assert_eq!(
|
||||||
|
clean_exec(r#"app --arg="value" %U"#),
|
||||||
|
r#"app --arg="value""#
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ fn strip_numeric_separators(expr: &str) -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const MATH_FNS: &[&str] = &[
|
const MATH_FNS: &[&str] = &[
|
||||||
"sqrt", "sin", "cos", "tan", "asin", "acos", "atan",
|
"sqrt", "sin", "cos", "tan", "asin", "acos", "atan", "ln", "log2", "log10", "exp", "abs",
|
||||||
"ln", "log2", "log10", "exp", "abs", "ceil", "floor", "round",
|
"ceil", "floor", "round",
|
||||||
];
|
];
|
||||||
|
|
||||||
fn should_eval(query: &str) -> bool {
|
fn should_eval(query: &str) -> bool {
|
||||||
@@ -36,8 +36,8 @@ fn should_eval(query: &str) -> bool {
|
|||||||
|| MATH_FNS.iter().any(|f| q.starts_with(f))
|
|| MATH_FNS.iter().any(|f| q.starts_with(f))
|
||||||
}
|
}
|
||||||
|
|
||||||
static MATH_CTX: LazyLock<evalexpr::HashMapContext<evalexpr::DefaultNumericTypes>> =
|
static MATH_CTX: LazyLock<evalexpr::HashMapContext<evalexpr::DefaultNumericTypes>> = LazyLock::new(
|
||||||
LazyLock::new(|| {
|
|| {
|
||||||
use evalexpr::*;
|
use evalexpr::*;
|
||||||
context_map! {
|
context_map! {
|
||||||
"pi" => float std::f64::consts::PI,
|
"pi" => float std::f64::consts::PI,
|
||||||
@@ -59,7 +59,8 @@ static MATH_CTX: LazyLock<evalexpr::HashMapContext<evalexpr::DefaultNumericTypes
|
|||||||
"round" => Function::new(|a: &Value<DefaultNumericTypes>| Ok(Value::from_float(a.as_number()?.round())))
|
"round" => Function::new(|a: &Value<DefaultNumericTypes>| Ok(Value::from_float(a.as_number()?.round())))
|
||||||
}
|
}
|
||||||
.expect("static math context must be valid")
|
.expect("static math context must be valid")
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Plugin for CalcPlugin {
|
impl Plugin for CalcPlugin {
|
||||||
|
|||||||
@@ -76,11 +76,7 @@ impl Plugin for FilesPlugin {
|
|||||||
let full_path = entry.path();
|
let full_path = entry.path();
|
||||||
let name = entry.file_name().to_string_lossy().to_string();
|
let name = entry.file_name().to_string_lossy().to_string();
|
||||||
let is_dir = full_path.is_dir();
|
let is_dir = full_path.is_dir();
|
||||||
let title = if is_dir {
|
let title = if is_dir { format!("{name}/") } else { name };
|
||||||
format!("{name}/")
|
|
||||||
} else {
|
|
||||||
name
|
|
||||||
};
|
|
||||||
let path_str = full_path.to_string_lossy().to_string();
|
let path_str = full_path.to_string_lossy().to_string();
|
||||||
SearchResult {
|
SearchResult {
|
||||||
id: ResultId::new(format!("file-{i}")),
|
id: ResultId::new(format!("file-{i}")),
|
||||||
|
|||||||
Reference in New Issue
Block a user