Compare commits
25 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
bcd5ee2e60 | ||
|
cf5bf59333 | ||
|
0d2a63001f | ||
|
3450d899d7 | ||
|
6747585322 | ||
|
9f00cb94da | ||
|
d939c9481b | ||
|
7b5055ac5d | ||
|
453b4e97c2 | ||
|
342e59727a | ||
|
b5e854521f | ||
|
8ec3ab3338 | ||
|
caa3953f2c | ||
|
b714576b08 | ||
|
6d38f80e33 | ||
|
4d2bf938b5 | ||
|
0a80cfe7e3 | ||
|
d1957a47c1 | ||
|
eda1d2bb96 | ||
|
46d94c3343 | ||
|
64959d6069 | ||
|
526b6fef24 | ||
|
fef1e7b820 | ||
|
c9674e9bf2 | ||
|
0642b909c3 |
424
Cargo.lock
generated
424
Cargo.lock
generated
@ -1,44 +1,76 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 4
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "0.7.18"
|
version = "1.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "alphanumeric-sort"
|
name = "alphanumeric-sort"
|
||||||
version = "1.4.3"
|
version = "1.5.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "20e59b2ccb4c1ffbbf45af6f493e16ac65a66981c85664f1587816c0b08cd698"
|
checksum = "d67c60c5f10f11c6ee04de72b2dd98bb9d2548cbc314d22a609bfa8bd9e87e8f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atty"
|
name = "anstream"
|
||||||
version = "0.2.14"
|
version = "0.6.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi",
|
"anstyle",
|
||||||
"libc",
|
"anstyle-parse",
|
||||||
"winapi",
|
"anstyle-query",
|
||||||
|
"anstyle-wincon",
|
||||||
|
"colorchoice",
|
||||||
|
"is_terminal_polyfill",
|
||||||
|
"utf8parse",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "anstyle"
|
||||||
version = "1.0.1"
|
version = "1.0.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "anstyle-parse"
|
||||||
version = "1.3.2"
|
version = "0.2.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
|
||||||
|
dependencies = [
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-query"
|
||||||
|
version = "1.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-wincon"
|
||||||
|
version = "3.0.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
@ -48,45 +80,79 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "3.0.10"
|
version = "4.5.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7a30c3bf9ff12dfe5dae53f0a96e0febcd18420d1c0e7fad77796d9d5c4b5375"
|
checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"clap_builder",
|
||||||
"bitflags",
|
|
||||||
"clap_derive",
|
"clap_derive",
|
||||||
"indexmap",
|
]
|
||||||
"lazy_static",
|
|
||||||
"os_str_bytes",
|
[[package]]
|
||||||
|
name = "clap_builder"
|
||||||
|
version = "4.5.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54"
|
||||||
|
dependencies = [
|
||||||
|
"anstream",
|
||||||
|
"anstyle",
|
||||||
|
"clap_lex",
|
||||||
"strsim",
|
"strsim",
|
||||||
"termcolor",
|
|
||||||
"textwrap",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_derive"
|
name = "clap_derive"
|
||||||
version = "3.0.6"
|
version = "4.5.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "517358c28fcef6607bf6f76108e02afad7e82297d132a6b846dcc1fc3efcd153"
|
checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck",
|
"heck 0.5.0",
|
||||||
"proc-macro-error",
|
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 2.0.85",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "evalexpr"
|
name = "clap_lex"
|
||||||
version = "7.0.1"
|
version = "0.7.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "90c8b61e4acbb2e4fbcf9d4c7af4d431f38c2a60b975b1d03d0276fbb032ec5d"
|
checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colorchoice"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "duct"
|
||||||
|
version = "0.13.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e4ab5718d1224b63252cd0c6f74f6480f9ffeb117438a2e0f5cf6d9a4798929c"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"once_cell",
|
||||||
|
"os_pipe",
|
||||||
|
"shared_child",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "evalexpr"
|
||||||
|
version = "7.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1d4fd7bd9e32c1205549decf6f36772d7b606a579b26afaffa335ae148151a5d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.4"
|
version = "0.2.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c"
|
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
@ -94,34 +160,30 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "heck"
|
||||||
version = "0.11.2"
|
version = "0.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
|
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.4.0"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "is_terminal_polyfill"
|
||||||
version = "0.1.19"
|
version = "1.70.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "itertools"
|
||||||
version = "1.8.0"
|
version = "0.10.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223"
|
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"either",
|
||||||
"hashbrown",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -137,7 +199,10 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"alphanumeric-sort",
|
"alphanumeric-sort",
|
||||||
"clap",
|
"clap",
|
||||||
|
"duct",
|
||||||
|
"either",
|
||||||
"evalexpr",
|
"evalexpr",
|
||||||
|
"itertools",
|
||||||
"kakplugin",
|
"kakplugin",
|
||||||
"linked-hash-map",
|
"linked-hash-map",
|
||||||
"linked_hash_set",
|
"linked_hash_set",
|
||||||
@ -147,23 +212,17 @@ dependencies = [
|
|||||||
"strum_macros",
|
"strum_macros",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lazy_static"
|
|
||||||
version = "1.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.113"
|
version = "0.2.161"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eef78b64d87775463c549fbd80e19249ef436ea3bf1de2a1eb7e717ec7fab1e9"
|
checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linked-hash-map"
|
name = "linked-hash-map"
|
||||||
version = "0.5.4"
|
version = "0.5.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
|
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linked_hash_set"
|
name = "linked_hash_set"
|
||||||
@ -176,63 +235,49 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.4.1"
|
version = "2.7.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "os_str_bytes"
|
name = "once_cell"
|
||||||
version = "6.0.0"
|
version = "1.20.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
|
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "os_pipe"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5ffd2b0a5634335b135d5728d84c5e0fd726954b87111f7506a61c502280d982"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"libc",
|
||||||
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "ppv-lite86"
|
||||||
version = "0.2.16"
|
version = "0.2.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
|
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro-error"
|
|
||||||
version = "1.0.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro-error-attr",
|
"zerocopy",
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
"version_check",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro-error-attr"
|
|
||||||
version = "1.0.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"version_check",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.36"
|
version = "1.0.89"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
|
checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.15"
|
version = "1.0.37"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
|
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
@ -260,18 +305,30 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_core"
|
name = "rand_core"
|
||||||
version = "0.6.3"
|
version = "0.6.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
|
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.5.4"
|
version = "1.11.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
|
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-automata",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.4.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
@ -280,15 +337,25 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.6.25"
|
version = "0.8.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.7"
|
version = "1.0.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a0a5f7c728f5d284929a1cccb5bc19884422bfe6ef4d6c409da2c41838983fcf"
|
checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shared_child"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09fa9338aed9a1df411814a5b2252f7cd206c55ae9bf2fa763f8de84603aa60c"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shell-words"
|
name = "shell-words"
|
||||||
@ -298,9 +365,9 @@ checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.10.0"
|
version = "0.11.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strum"
|
name = "strum"
|
||||||
@ -313,88 +380,147 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strum_macros"
|
name = "strum_macros"
|
||||||
version = "0.24.2"
|
version = "0.24.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4faebde00e8ff94316c01800f9054fd2ba77d30d9e922541913051d1d978918b"
|
checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck",
|
"heck 0.4.1",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"rustversion",
|
"rustversion",
|
||||||
"syn",
|
"syn 1.0.109",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.86"
|
version = "1.0.109"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
|
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"unicode-xid",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "termcolor"
|
name = "syn"
|
||||||
version = "1.1.2"
|
version = "2.0.85"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
|
checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi-util",
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "textwrap"
|
name = "unicode-ident"
|
||||||
version = "0.14.2"
|
version = "1.0.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80"
|
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "utf8parse"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "version_check"
|
|
||||||
version = "0.9.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.10.2+wasi-snapshot-preview1"
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "windows-sys"
|
||||||
version = "0.3.9"
|
version = "0.59.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi-i686-pc-windows-gnu",
|
"windows-targets",
|
||||||
"winapi-x86_64-pc-windows-gnu",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-i686-pc-windows-gnu"
|
name = "windows-targets"
|
||||||
version = "0.4.0"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi-util"
|
|
||||||
version = "0.1.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi",
|
"windows_aarch64_gnullvm",
|
||||||
|
"windows_aarch64_msvc",
|
||||||
|
"windows_i686_gnu",
|
||||||
|
"windows_i686_gnullvm",
|
||||||
|
"windows_i686_msvc",
|
||||||
|
"windows_x86_64_gnu",
|
||||||
|
"windows_x86_64_gnullvm",
|
||||||
|
"windows_x86_64_msvc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-x86_64-pc-windows-gnu"
|
name = "windows_aarch64_gnullvm"
|
||||||
version = "0.4.0"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||||
|
|
||||||
|
[[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_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy"
|
||||||
|
version = "0.7.35"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"zerocopy-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy-derive"
|
||||||
|
version = "0.7.35"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.85",
|
||||||
|
]
|
||||||
|
@ -32,7 +32,7 @@ image = "scratch"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
regex = "1"
|
regex = "1"
|
||||||
clap = {version = "3", features = ["derive", "env"]}
|
clap = { version = "4", features = ["derive", "env"] }
|
||||||
alphanumeric-sort = "1"
|
alphanumeric-sort = "1"
|
||||||
# shellwords = {version = "1", path = "../../../git/rust-shellwords/"}
|
# shellwords = {version = "1", path = "../../../git/rust-shellwords/"}
|
||||||
# shellwords = "1"
|
# shellwords = "1"
|
||||||
@ -43,6 +43,9 @@ linked-hash-map = "0.5.4"
|
|||||||
linked_hash_set = "0.1.4"
|
linked_hash_set = "0.1.4"
|
||||||
strum_macros = "0.24"
|
strum_macros = "0.24"
|
||||||
strum = { version = "0.24", features = ["derive"] }
|
strum = { version = "0.24", features = ["derive"] }
|
||||||
|
itertools = "0.10.5"
|
||||||
|
either = "1.8.1"
|
||||||
|
duct = "0.13.7"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = true
|
lto = true
|
||||||
@ -50,3 +53,4 @@ opt-level = "z"
|
|||||||
strip = true
|
strip = true
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
panic = "abort"
|
panic = "abort"
|
||||||
|
debug = true
|
||||||
|
21
README.adoc
21
README.adoc
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
Sort by regular expression or lexicographically, find uniqes, shuffle, or evaluate rust selections without spawning a new command for each selection.
|
Sort by regular expression or lexicographically, find uniqes, shuffle, or evaluate rust selections without spawning a new command for each selection.
|
||||||
|
|
||||||
[![asciicast](https://asciinema.org/a/dIQh9NtLRkzVEENxmij5qBaai.svg)](https://asciinema.org/a/dIQh9NtLRkzVEENxmij5qBaai)
|
image::https://asciinema.org/a/dIQh9NtLRkzVEENxmij5qBaai.svg[link="https://asciinema.org/a/dIQh9NtLRkzVEENxmij5qBaai"]
|
||||||
|
|
||||||
== Example
|
== Example
|
||||||
|
|
||||||
@ -876,12 +876,19 @@ After `uniq`:
|
|||||||
====
|
====
|
||||||
|
|
||||||
=== incr/decr
|
=== incr/decr
|
||||||
Select only unique selections
|
|
||||||
|
|
||||||
* `[AMOUNT]` - Optional increment/decrement count
|
Increment or decrement selections
|
||||||
|
|
||||||
== TODO
|
* `[AMOUNT]` - Optional increment/decrement count (default: `1`)
|
||||||
|
|
||||||
* I don't know what will happen with multiline strings and regex
|
.Example
|
||||||
* Figure out how to change the `no_skip_whitespace` option name in the source
|
[%collapsible]
|
||||||
* Get sort by selections working
|
====
|
||||||
|
Before:
|
||||||
|
++++
|
||||||
|
++++
|
||||||
|
|
||||||
|
After `incr 3`:
|
||||||
|
++++
|
||||||
|
++++
|
||||||
|
====
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::Register;
|
||||||
use std::{fmt, fmt::Display, num::ParseIntError};
|
use std::{fmt, fmt::Display, num::ParseIntError};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -22,6 +23,8 @@ pub enum KakError {
|
|||||||
CustomStatic(&'static str),
|
CustomStatic(&'static str),
|
||||||
/// The selections/selections_desc list passed was empty
|
/// The selections/selections_desc list passed was empty
|
||||||
SetEmptySelections,
|
SetEmptySelections,
|
||||||
|
/// The register register has no content
|
||||||
|
EmptyRegister(Register),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::error::Error for KakError {}
|
impl std::error::Error for KakError {}
|
||||||
@ -41,6 +44,9 @@ impl KakError {
|
|||||||
Self::SetEmptySelections => {
|
Self::SetEmptySelections => {
|
||||||
String::from("Attempted to set selections/selections_desc to empty list")
|
String::from("Attempted to set selections/selections_desc to empty list")
|
||||||
}
|
}
|
||||||
|
Self::EmptyRegister(r) => {
|
||||||
|
format!("Empty register: {r}")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,6 +68,7 @@ impl Display for KakError {
|
|||||||
f,
|
f,
|
||||||
"Attempted to set selections/selections_desc to empty list"
|
"Attempted to set selections/selections_desc to empty list"
|
||||||
),
|
),
|
||||||
|
Self::EmptyRegister(r) => write!(f, "Register {r} has no content"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,23 @@ pub fn get_selections(keys: Option<&'_ str>) -> Result<Vec<Selection>, KakError>
|
|||||||
response("%val{selections}", keys)
|
response("%val{selections}", keys)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_register_selections<R>(r: R) -> Result<Vec<Selection>, KakError>
|
||||||
|
where
|
||||||
|
R: AsRef<Register>,
|
||||||
|
{
|
||||||
|
cmd(&format!(
|
||||||
|
r#"
|
||||||
|
evaluate-commands -draft %{{
|
||||||
|
execute-keys '\"{}z';
|
||||||
|
echo -quoting shell -to-file {} -- %val{{selections}};
|
||||||
|
}}"#,
|
||||||
|
r.as_ref().kak_escaped(),
|
||||||
|
get_var("kak_response_fifo")?
|
||||||
|
))?;
|
||||||
|
let selections = shell_words::split(&fs::read_to_string(&get_var("kak_response_fifo")?)?)?;
|
||||||
|
Ok(selections)
|
||||||
|
}
|
||||||
|
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// Will return `Err` if command fifo could not be opened, read from, or written to
|
/// Will return `Err` if command fifo could not be opened, read from, or written to
|
||||||
@ -40,10 +57,7 @@ where
|
|||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// Will return `Err` if command fifo could not be opened, read from, or written to
|
/// Will return `Err` if command fifo could not be opened, read from, or written to
|
||||||
pub fn get_selections_desc_unordered<S>(keys: Option<S>) -> Result<Vec<SelectionDesc>, KakError>
|
pub fn get_selections_desc_unordered(keys: Option<&str>) -> Result<Vec<SelectionDesc>, KakError> {
|
||||||
where
|
|
||||||
S: AsRef<str>,
|
|
||||||
{
|
|
||||||
response("%val{selections_desc}", keys.as_ref())?
|
response("%val{selections_desc}", keys.as_ref())?
|
||||||
.iter()
|
.iter()
|
||||||
.map(|sd| SelectionDesc::from_str(sd))
|
.map(|sd| SelectionDesc::from_str(sd))
|
||||||
@ -144,10 +158,6 @@ where
|
|||||||
write!(f, "set-register '\"'")?;
|
write!(f, "set-register '\"'")?;
|
||||||
for i in selections_iter {
|
for i in selections_iter {
|
||||||
num_written = num_written.saturating_add(1);
|
num_written = num_written.saturating_add(1);
|
||||||
// eprintln!(
|
|
||||||
// "Got response: {:?}",
|
|
||||||
// i.map_err(Into::into)?.clone().as_ref()
|
|
||||||
// );
|
|
||||||
write!(f, " '{}'", escape(i.map_err(Into::into)?.as_ref()))?;
|
write!(f, " '{}'", escape(i.map_err(Into::into)?.as_ref()))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,13 +295,13 @@ where
|
|||||||
|
|
||||||
cmd(match keys.as_ref() {
|
cmd(match keys.as_ref() {
|
||||||
None => format!(
|
None => format!(
|
||||||
"echo -quoting shell -to-file {response_fifo} -- {}",
|
"echo -quoting shell -to-file '{response_fifo}' -- {}",
|
||||||
msg.as_ref()
|
msg.as_ref()
|
||||||
),
|
),
|
||||||
Some(keys) => format!(
|
Some(keys) => format!(
|
||||||
r#"evaluate-commands -draft %{{
|
r#"evaluate-commands -draft %{{
|
||||||
execute-keys '{}';
|
execute-keys '{}';
|
||||||
echo -quoting shell -to-file {response_fifo} -- {};
|
echo -quoting shell -to-file '{response_fifo}' -- {};
|
||||||
}}"#,
|
}}"#,
|
||||||
escape(keys.as_ref()),
|
escape(keys.as_ref()),
|
||||||
msg.as_ref()
|
msg.as_ref()
|
||||||
@ -354,5 +364,12 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn reg(register: Register, keys: Option<&'_ str>) -> Result<Vec<String>, KakError> {
|
pub fn reg(register: Register, keys: Option<&'_ str>) -> Result<Vec<String>, KakError> {
|
||||||
response(format!("%reg{{{}}}", register.kak_expanded()), keys)
|
let ret = response(format!("%reg{{{}}}", register.kak_expanded()), keys)?;
|
||||||
|
|
||||||
|
// Kak returns a single empty line
|
||||||
|
if &ret[..] == [""] {
|
||||||
|
return Err(KakError::EmptyRegister(register));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(ret)
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ pub struct SelectionWithSubselections {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, PartialOrd, Ord, Eq, Debug)]
|
#[derive(Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Debug)]
|
||||||
pub struct SelectionDesc {
|
pub struct SelectionDesc {
|
||||||
pub left: AnchorPosition,
|
pub left: AnchorPosition,
|
||||||
pub right: AnchorPosition,
|
pub right: AnchorPosition,
|
||||||
@ -86,6 +86,46 @@ impl SelectionDesc {
|
|||||||
s.right.row - s.left.row + 1
|
s.right.row - s.left.row + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the smallest selection that encompases both selections
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// let sel1 = SelectionDesc {
|
||||||
|
/// left: AnchorPosition { row: 10, col: 16 },
|
||||||
|
/// right: AnchorPosition { row: 1, col: 14 },
|
||||||
|
/// };
|
||||||
|
/// let sel2 = SelectionDesc {
|
||||||
|
/// left: AnchorPosition { row: 64, col: 10 },
|
||||||
|
/// right: AnchorPosition { row: 1, col: 100 },
|
||||||
|
/// };
|
||||||
|
/// let expected_bounding = SelectionDesc {
|
||||||
|
/// left: AnchorPosition { row: 1, col: 14 },
|
||||||
|
/// right: AnchorPosition { row: 64, col: 27 },
|
||||||
|
/// };
|
||||||
|
/// assert_eq!(sel1.rev().bounding_selection(&sel1), sel1.sort());
|
||||||
|
/// assert_eq!(sel2.bounding_selection(&sel1), expected_bounding.sort());
|
||||||
|
/// assert_eq!(sel2.rev().bounding_selection(&sel1.rev()), expected_bounding.sort());
|
||||||
|
/// assert_eq!(sel2.rev().bounding_selection(&sel1), expected_bounding.sort());
|
||||||
|
/// ```
|
||||||
|
pub fn bounding_selection<SD>(&self, other: SD) -> Self
|
||||||
|
where
|
||||||
|
SD: AsRef<Self>,
|
||||||
|
{
|
||||||
|
// So left is the minimum and right is the maximum
|
||||||
|
let (a, b) = (self.sort(), other.as_ref().sort());
|
||||||
|
|
||||||
|
Self {
|
||||||
|
left: min(a.left, b.left),
|
||||||
|
right: max(a.right, b.right),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn rev(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
left: self.right,
|
||||||
|
right: self.left,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn sort(&self) -> Self {
|
pub fn sort(&self) -> Self {
|
||||||
if self.left < self.right {
|
if self.left < self.right {
|
||||||
|
10
src/box_.rs
10
src/box_.rs
@ -2,7 +2,7 @@ use kakplugin::{
|
|||||||
get_selections_desc, set_selections_desc, AnchorPosition, KakError, SelectionDesc,
|
get_selections_desc, set_selections_desc, AnchorPosition, KakError, SelectionDesc,
|
||||||
};
|
};
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
#[derive(clap::StructOpt, Debug)]
|
#[derive(clap::Args, Debug)]
|
||||||
pub struct Options {
|
pub struct Options {
|
||||||
/// Bounding box mode, which selects the largest box to contain everything
|
/// Bounding box mode, which selects the largest box to contain everything
|
||||||
#[clap(short, long, help = "Select the bonding box of all selections")]
|
#[clap(short, long, help = "Select the bonding box of all selections")]
|
||||||
@ -70,10 +70,10 @@ fn boxed_selections(options: &Options) -> Result<Vec<SelectionDesc>, KakError> {
|
|||||||
|
|
||||||
let whole_line_selection_command = if options.no_newline {
|
let whole_line_selection_command = if options.no_newline {
|
||||||
// Select everything and only keep non-newlines
|
// Select everything and only keep non-newlines
|
||||||
"<a-x>s^[^\\n]+<ret>"
|
"xs^[^\\n]+<ret>"
|
||||||
} else {
|
} else {
|
||||||
// Select everything and split
|
// Select everything and split
|
||||||
"<a-x><a-s>"
|
"x<a-s>"
|
||||||
};
|
};
|
||||||
|
|
||||||
// Whole-row selections split on newline
|
// Whole-row selections split on newline
|
||||||
@ -128,11 +128,11 @@ fn boxed_selections(options: &Options) -> Result<Vec<SelectionDesc>, KakError> {
|
|||||||
|
|
||||||
/// Returns a vec of `selections_desc` of the intersection of the bounding box and the component rows
|
/// Returns a vec of `selections_desc` of the intersection of the bounding box and the component rows
|
||||||
///
|
///
|
||||||
/// This function takes a selection desc, and its whole-row split selections (`<a-x><a-s>`).
|
/// This function takes a selection desc, and its whole-row split selections (`x<a-s>`).
|
||||||
/// For each whole-row (col 1 to max col) selection, it finds the intersection between the min col and max col in `selection_desc`
|
/// For each whole-row (col 1 to max col) selection, it finds the intersection between the min col and max col in `selection_desc`
|
||||||
///
|
///
|
||||||
/// * `selection_desc` - The base (possibly multiline) `selection_desc`
|
/// * `selection_desc` - The base (possibly multiline) `selection_desc`
|
||||||
/// * `selections_desc_rows` - Vec of above `selection_desc` split by line (`<a-x><a-s>`)
|
/// * `selections_desc_rows` - Vec of above `selection_desc` split by line (`x<a-s>`)
|
||||||
fn to_boxed_selections<SD1, SD2>(
|
fn to_boxed_selections<SD1, SD2>(
|
||||||
selection_desc: SD1,
|
selection_desc: SD1,
|
||||||
selections_desc_rows: &[SD2],
|
selections_desc_rows: &[SD2],
|
||||||
|
@ -2,7 +2,7 @@ use evalexpr::{eval, Value};
|
|||||||
use kakplugin::{get_selections, set_selections, KakError};
|
use kakplugin::{get_selections, set_selections, KakError};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
#[derive(clap::StructOpt, Debug)]
|
#[derive(clap::Args, Debug)]
|
||||||
pub struct Options {
|
pub struct Options {
|
||||||
#[clap(index = 1, help = "Amount to increment/decrement", default_value = "1")]
|
#[clap(index = 1, help = "Amount to increment/decrement", default_value = "1")]
|
||||||
amount: isize,
|
amount: isize,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use kakplugin::{
|
use kakplugin::{
|
||||||
get_selections_desc, set_selections_desc, types::MaybeSplit, KakError, SelectionDesc,
|
get_selections_desc, set_selections_desc, types::MaybeSplit, KakError, SelectionDesc,
|
||||||
};
|
};
|
||||||
#[derive(clap::StructOpt, Debug)]
|
#[derive(clap::Args, Debug)]
|
||||||
pub struct Options {
|
pub struct Options {
|
||||||
#[clap(short, long, help = "Do not include newlines")]
|
#[clap(short, long, help = "Do not include newlines")]
|
||||||
no_newline: bool,
|
no_newline: bool,
|
||||||
@ -16,7 +16,7 @@ pub fn invert(options: &Options) -> Result<String, KakError> {
|
|||||||
// Split by multiline so subtraction is defined (see below)
|
// Split by multiline so subtraction is defined (see below)
|
||||||
// Group by row, so for a given document row, subtraction can iterate over the Vec
|
// Group by row, so for a given document row, subtraction can iterate over the Vec
|
||||||
get_selections_desc(Some("<a-s>"))?
|
get_selections_desc(Some("<a-s>"))?
|
||||||
.group_by(|a, b| a.left.row == b.left.row)
|
.chunk_by(|a, b| a.left.row == b.left.row)
|
||||||
.map(|sds| (sds[0].left.row, sds.to_vec()))
|
.map(|sds| (sds[0].left.row, sds.to_vec()))
|
||||||
.collect()
|
.collect()
|
||||||
};
|
};
|
||||||
@ -29,9 +29,9 @@ pub fn invert(options: &Options) -> Result<String, KakError> {
|
|||||||
// Select everything and split
|
// Select everything and split
|
||||||
(false, false) => "%<a-s>",
|
(false, false) => "%<a-s>",
|
||||||
// Select entire line, then remove newline
|
// Select entire line, then remove newline
|
||||||
(true, true) => "<a-x><a-s>s^[^\\n]+<ret>",
|
(true, true) => "x<a-s>s^[^\\n]+<ret>",
|
||||||
// Select entire line, including newline
|
// Select entire line, including newline
|
||||||
(true, false) => "<a-x><a-s>",
|
(true, false) => "x<a-s>",
|
||||||
};
|
};
|
||||||
|
|
||||||
let document_descs: Vec<SelectionDesc> = {
|
let document_descs: Vec<SelectionDesc> = {
|
||||||
|
14
src/join.rs
Normal file
14
src/join.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
use kakplugin::{get_selections_desc_unordered, set_selections_desc, KakError};
|
||||||
|
|
||||||
|
#[derive(clap::Args, Debug)]
|
||||||
|
pub struct Options;
|
||||||
|
|
||||||
|
pub fn join(_options: &Options) -> Result<String, KakError> {
|
||||||
|
set_selections_desc(
|
||||||
|
get_selections_desc_unordered(None)?
|
||||||
|
.into_iter()
|
||||||
|
.reduce(|acc, sd| acc.bounding_selection(sd)),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(format!("Joined all selections"))
|
||||||
|
}
|
31
src/keep_every.rs
Normal file
31
src/keep_every.rs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
use itertools::Itertools;
|
||||||
|
use kakplugin::{get_selections_desc_unordered, set_selections_desc, KakError};
|
||||||
|
|
||||||
|
#[derive(Debug, clap::Args)]
|
||||||
|
pub struct Options {
|
||||||
|
#[clap(index = 1, value_parser = clap::value_parser!(u16).range(2..))]
|
||||||
|
keep_every: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn keep_every(options: &Options) -> Result<String, KakError> {
|
||||||
|
let old_selections_desc = get_selections_desc_unordered(None)?;
|
||||||
|
|
||||||
|
let mut new_count = 0;
|
||||||
|
set_selections_desc(
|
||||||
|
old_selections_desc
|
||||||
|
.iter()
|
||||||
|
.chunks(options.keep_every.into())
|
||||||
|
.into_iter()
|
||||||
|
.flat_map(|mut it| {
|
||||||
|
// Only keep the first selection from each chunk
|
||||||
|
new_count += 1;
|
||||||
|
it.next()
|
||||||
|
}),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(format!(
|
||||||
|
"{} kept from {}",
|
||||||
|
new_count,
|
||||||
|
old_selections_desc.len()
|
||||||
|
))
|
||||||
|
}
|
13
src/main.rs
13
src/main.rs
@ -5,7 +5,6 @@
|
|||||||
// Cannot be fixed
|
// Cannot be fixed
|
||||||
#![allow(clippy::multiple_crate_versions)]
|
#![allow(clippy::multiple_crate_versions)]
|
||||||
#![allow(clippy::struct_excessive_bools)]
|
#![allow(clippy::struct_excessive_bools)]
|
||||||
#![feature(slice_group_by)]
|
|
||||||
#![feature(slice_take)]
|
#![feature(slice_take)]
|
||||||
#![feature(array_chunks)]
|
#![feature(array_chunks)]
|
||||||
|
|
||||||
@ -13,8 +12,11 @@ mod box_;
|
|||||||
mod errors;
|
mod errors;
|
||||||
mod incr;
|
mod incr;
|
||||||
mod invert;
|
mod invert;
|
||||||
|
mod join;
|
||||||
|
mod keep_every;
|
||||||
mod math_eval;
|
mod math_eval;
|
||||||
mod pad;
|
mod pad;
|
||||||
|
mod rev;
|
||||||
mod set;
|
mod set;
|
||||||
mod shuf;
|
mod shuf;
|
||||||
mod sort;
|
mod sort;
|
||||||
@ -69,6 +71,12 @@ enum Commands {
|
|||||||
Decr(incr::Options),
|
Decr(incr::Options),
|
||||||
#[clap(about = "Decrement selections")]
|
#[clap(about = "Decrement selections")]
|
||||||
Incr(incr::Options),
|
Incr(incr::Options),
|
||||||
|
#[clap(about = "Reverse selections")]
|
||||||
|
Rev(rev::Options),
|
||||||
|
#[clap(about = "Join selections")]
|
||||||
|
Join(join::Options),
|
||||||
|
#[clap(about = "Keep a subset of selections", visible_aliases = &["keep"])]
|
||||||
|
KeepEvery(keep_every::Options),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@ -119,5 +127,8 @@ fn run() -> Result<String, KakError> {
|
|||||||
Commands::Xlookup(o) => xlookup::xlookup(o),
|
Commands::Xlookup(o) => xlookup::xlookup(o),
|
||||||
Commands::Incr(o) => incr::incr(o, true),
|
Commands::Incr(o) => incr::incr(o, true),
|
||||||
Commands::Decr(o) => incr::incr(o, false),
|
Commands::Decr(o) => incr::incr(o, false),
|
||||||
|
Commands::Rev(o) => rev::rev(o),
|
||||||
|
Commands::Join(o) => join::join(o),
|
||||||
|
Commands::KeepEvery(o) => keep_every::keep_every(o),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,22 +2,35 @@ use evalexpr::{eval, Value};
|
|||||||
use kakplugin::{get_selections, set_selections, KakError};
|
use kakplugin::{get_selections, set_selections, KakError};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
#[derive(clap::StructOpt, Debug)]
|
#[derive(clap::Args, Debug)]
|
||||||
pub struct Options;
|
pub struct Options {
|
||||||
pub fn math_eval(_options: &Options) -> Result<String, KakError> {
|
/// Additional arguments to pass to the math evaluator
|
||||||
|
///
|
||||||
|
/// For example, you can run `kakutils-rs bc + 5` to add 5 to all selections
|
||||||
|
extra_math_args: Option<Vec<String>>,
|
||||||
|
}
|
||||||
|
pub fn math_eval(options: &Options) -> Result<String, KakError> {
|
||||||
let mut err_count: usize = 0;
|
let mut err_count: usize = 0;
|
||||||
|
|
||||||
let selections = get_selections(None)?;
|
let selections = get_selections(None)?;
|
||||||
|
|
||||||
set_selections(selections.iter().map(|s| match eval(s) {
|
let extra = options.extra_math_args.as_ref().map(|v| v.join(" "));
|
||||||
Ok(Value::Float(f)) => Cow::Owned(f.to_string()),
|
|
||||||
Ok(Value::Int(f)) => Cow::Owned(f.to_string()),
|
set_selections(selections.iter().map(|s| {
|
||||||
Ok(_) => Cow::Borrowed(""),
|
match eval(&if let Some(e) = &extra {
|
||||||
Err(e) => {
|
Cow::Owned(format!("{s} {e}"))
|
||||||
eprintln!("Error: {:?}", e);
|
} else {
|
||||||
err_count = err_count.saturating_add(1);
|
Cow::Borrowed(s)
|
||||||
// Set the selection to empty
|
}) {
|
||||||
Cow::Borrowed("")
|
Ok(Value::Float(f)) => Cow::Owned(f.to_string()),
|
||||||
|
Ok(Value::Int(f)) => Cow::Owned(f.to_string()),
|
||||||
|
Ok(_) => Cow::Borrowed(""),
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("Error: {:?}", e);
|
||||||
|
err_count = err_count.saturating_add(1);
|
||||||
|
// Set the selection to empty
|
||||||
|
Cow::Borrowed("")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}))?;
|
}))?;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ use crate::utils::split_newlines;
|
|||||||
use kakplugin::{get_selections, set_selections, KakError};
|
use kakplugin::{get_selections, set_selections, KakError};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
#[derive(clap::StructOpt, Debug)]
|
#[derive(clap::Args, Debug)]
|
||||||
pub struct Options {
|
pub struct Options {
|
||||||
#[clap(index = 1, help = "Pad with this char", default_value = "0")]
|
#[clap(index = 1, help = "Pad with this char", default_value = "0")]
|
||||||
fill: char,
|
fill: char,
|
||||||
|
11
src/rev.rs
Normal file
11
src/rev.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
use kakplugin::{get_selections, set_selections, KakError};
|
||||||
|
#[derive(clap::Args, Debug)]
|
||||||
|
pub struct Options;
|
||||||
|
|
||||||
|
pub fn rev(_options: &Options) -> Result<String, KakError> {
|
||||||
|
let selections = get_selections(None)?;
|
||||||
|
|
||||||
|
set_selections(selections.iter().rev())?;
|
||||||
|
|
||||||
|
Ok(format!("Reversed {} selections", selections.len()))
|
||||||
|
}
|
135
src/set.rs
135
src/set.rs
@ -1,18 +1,19 @@
|
|||||||
// use crate::utils;
|
// use crate::utils;
|
||||||
use kakplugin::{
|
use kakplugin::{
|
||||||
get_selections, get_selections_with_desc, set_selections_desc, types::Register, KakError,
|
get_register_selections, get_selections, get_selections_with_desc, set_selections_desc,
|
||||||
Selection,
|
types::Register, KakError,
|
||||||
};
|
};
|
||||||
use linked_hash_map::LinkedHashMap;
|
use linked_hash_map::LinkedHashMap;
|
||||||
use linked_hash_set::LinkedHashSet;
|
use linked_hash_set::LinkedHashSet;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::{io::Write, str::FromStr};
|
use std::{borrow::Cow, io::Write, str::FromStr};
|
||||||
|
|
||||||
#[derive(clap::StructOpt, Debug)]
|
const KAK_BUFFER_NAME: &str = "*kakplugin-set*";
|
||||||
|
|
||||||
|
#[derive(clap::Args, Debug)]
|
||||||
pub struct Options {
|
pub struct Options {
|
||||||
#[clap(
|
#[clap(
|
||||||
min_values = 1,
|
num_args = 1..=3,
|
||||||
max_values = 3,
|
|
||||||
allow_hyphen_values = true,
|
allow_hyphen_values = true,
|
||||||
help = "Register operation and operand. Empty register is current selection. Example: 'a-b' or '+b'"
|
help = "Register operation and operand. Empty register is current selection. Example: 'a-b' or '+b'"
|
||||||
)]
|
)]
|
||||||
@ -65,7 +66,7 @@ impl FromStr for Operation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set(options: &Options) -> Result<String, KakError> {
|
pub fn set<'sel>(options: &'_ Options) -> Result<String, KakError> {
|
||||||
// Get the actual operation we are performing
|
// Get the actual operation we are performing
|
||||||
let (left_register, operation, right_register) = parse_arguments(&options.args[..])?;
|
let (left_register, operation, right_register) = parse_arguments(&options.args[..])?;
|
||||||
|
|
||||||
@ -74,19 +75,19 @@ pub fn set(options: &Options) -> Result<String, KakError> {
|
|||||||
let (left_selections, right_selections) = match (&left_register, &right_register) {
|
let (left_selections, right_selections) = match (&left_register, &right_register) {
|
||||||
(Register::Underscore, r) => {
|
(Register::Underscore, r) => {
|
||||||
let l_selections = get_selections(None)?;
|
let l_selections = get_selections(None)?;
|
||||||
let r_selections = get_selections(Some(&format!("\"{r}z")))?;
|
let r_selections = get_register_selections(r)?;
|
||||||
|
|
||||||
(l_selections, r_selections)
|
(l_selections, r_selections)
|
||||||
}
|
}
|
||||||
(l, Register::Underscore) => {
|
(l, Register::Underscore) => {
|
||||||
let r_selections = get_selections(None)?;
|
let r_selections = get_selections(None)?;
|
||||||
let l_selections = get_selections(Some(&format!("\"{l}z")))?;
|
let l_selections = get_register_selections(l)?;
|
||||||
|
|
||||||
(l_selections, r_selections)
|
(l_selections, r_selections)
|
||||||
}
|
}
|
||||||
(l, r) => {
|
(l, r) => {
|
||||||
let l_selections = get_selections(Some(&format!("\"{l}z")))?;
|
let l_selections = get_register_selections(l)?;
|
||||||
let r_selections = get_selections(Some(&format!("\"{r}z")))?;
|
let r_selections = get_register_selections(r)?;
|
||||||
|
|
||||||
(l_selections, r_selections)
|
(l_selections, r_selections)
|
||||||
}
|
}
|
||||||
@ -95,63 +96,72 @@ pub fn set(options: &Options) -> Result<String, KakError> {
|
|||||||
// Get the frequency of each selection. The count does not matter as much as presence
|
// Get the frequency of each selection. The count does not matter as much as presence
|
||||||
// Count is used only for compare
|
// Count is used only for compare
|
||||||
let (left_ordered_counts, right_ordered_counts) = (
|
let (left_ordered_counts, right_ordered_counts) = (
|
||||||
to_ordered_counts(options, left_selections),
|
to_ordered_counts(
|
||||||
to_ordered_counts(options, right_selections),
|
options,
|
||||||
|
left_selections.iter().map(|s| s.as_ref()).collect(),
|
||||||
|
),
|
||||||
|
to_ordered_counts(
|
||||||
|
options,
|
||||||
|
right_selections.iter().map(|s| s.as_ref()).collect(),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Get an ordered set of every key for each register
|
// Get an ordered set of every key for each register
|
||||||
let (left_keys, right_keys) = (
|
let (left_keys, right_keys) = (
|
||||||
left_ordered_counts
|
left_ordered_counts
|
||||||
.keys()
|
.keys()
|
||||||
.collect::<LinkedHashSet<&Selection>>(),
|
.map(|k| -> &str { k.as_ref() })
|
||||||
|
.collect::<LinkedHashSet<&str>>(),
|
||||||
right_ordered_counts
|
right_ordered_counts
|
||||||
.keys()
|
.keys()
|
||||||
.collect::<LinkedHashSet<&Selection>>(),
|
.map(|k| -> &str { k.as_ref() })
|
||||||
|
.collect::<LinkedHashSet<&str>>(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Run the actual set operation
|
// Run the actual set operation
|
||||||
let result = key_set_operation(&operation, &left_keys, &right_keys);
|
let result = key_set_operation(&operation, &left_keys, &right_keys);
|
||||||
|
let num_modified = result.len();
|
||||||
|
|
||||||
match &operation {
|
match &operation {
|
||||||
Operation::Compare => compare(
|
Operation::Compare => compare(
|
||||||
left_register,
|
left_register,
|
||||||
right_register,
|
right_register,
|
||||||
&result,
|
result,
|
||||||
&left_ordered_counts,
|
&left_ordered_counts,
|
||||||
&right_ordered_counts,
|
&right_ordered_counts,
|
||||||
)?,
|
)?,
|
||||||
Operation::Union => print_result(&result)?,
|
Operation::Union => print_result(result)?,
|
||||||
// Intersect/subtract will have at most the number of elements in the current selection
|
// Intersect/subtract will have at most the number of elements in the current selection
|
||||||
// If the user operated on the current selection, and we can modify the selection descs inplace, do it
|
// If the user operated on the current selection, and we can modify the selection descs inplace, do it
|
||||||
Operation::Intersect | Operation::Subtract => {
|
Operation::Intersect | Operation::Subtract => {
|
||||||
if left_register == Register::Underscore {
|
if left_register == Register::Underscore {
|
||||||
// If the user asked for an intersection or subtraction from the current selection, we can update selection_descs only
|
// If the user asked for an intersection or subtraction from the current selection, we can update selection_descs only
|
||||||
// For example (current selection) - (contents of register a) allows us to simply deselect some selections
|
// For example (current selection) - (contents of register a) allows us to simply deselect some selections
|
||||||
reduce_selections(options, &result)?;
|
reduce_selections(options, result)?;
|
||||||
} else {
|
} else {
|
||||||
// The user asked for registers that *aren't* the current selection
|
// The user asked for registers that *aren't* the current selection
|
||||||
// This means either registers don't represent the current selection, or the current selection is on the other side
|
// This means either registers don't represent the current selection, or the current selection is on the other side
|
||||||
print_result(&result)?;
|
print_result(result)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(match &operation {
|
Ok(match &operation {
|
||||||
Operation::Compare => format!("Compared {} selections", result.len()),
|
Operation::Compare => format!("Compared {} selections", num_modified),
|
||||||
op => format!(
|
op => format!(
|
||||||
"{}{}{} returned {} selections",
|
"{}{}{} returned {} selections",
|
||||||
left_register.to_char(),
|
left_register.to_char(),
|
||||||
op.to_char(),
|
op.to_char(),
|
||||||
right_register.to_char(),
|
right_register.to_char(),
|
||||||
result.len()
|
num_modified
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reduces selections to those that are in the `key_set_operation_result`
|
/// Reduces selections to those that are in the `key_set_operation_result`
|
||||||
fn reduce_selections(
|
fn reduce_selections<'sel, 'a>(
|
||||||
options: &Options,
|
options: &Options,
|
||||||
key_set_operation_result: &LinkedHashSet<&Selection>,
|
key_set_operation_result: LinkedHashSet<&'sel str>,
|
||||||
) -> Result<(), KakError> {
|
) -> Result<(), KakError> {
|
||||||
// The registers should have been read in a draft context
|
// The registers should have been read in a draft context
|
||||||
// So the current selection will be unmodified
|
// So the current selection will be unmodified
|
||||||
@ -163,12 +173,12 @@ fn reduce_selections(
|
|||||||
// we can just use contains here
|
// we can just use contains here
|
||||||
let key = crate::utils::get_key(
|
let key = crate::utils::get_key(
|
||||||
&swd.content,
|
&swd.content,
|
||||||
options.skip_whitespace,
|
!options.skip_whitespace,
|
||||||
options.regex.as_ref(),
|
options.regex.as_ref(),
|
||||||
options.ignore_case,
|
options.ignore_case,
|
||||||
);
|
);
|
||||||
|
|
||||||
if key_set_operation_result.contains(&key) {
|
if key_set_operation_result.contains(key.as_ref()) {
|
||||||
Some(swd.desc)
|
Some(swd.desc)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -178,7 +188,8 @@ fn reduce_selections(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_result(key_set_operation_result: &LinkedHashSet<&Selection>) -> Result<(), KakError> {
|
/// Writes the result of a set operation to a new kak buffer
|
||||||
|
fn print_result(key_set_operation_result: LinkedHashSet<&str>) -> Result<(), KakError> {
|
||||||
// Manually set selections so we don't have to allocate a string
|
// Manually set selections so we don't have to allocate a string
|
||||||
let mut f = kakplugin::open_command_fifo()?;
|
let mut f = kakplugin::open_command_fifo()?;
|
||||||
|
|
||||||
@ -197,9 +208,10 @@ fn print_result(key_set_operation_result: &LinkedHashSet<&Selection>) -> Result<
|
|||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
r#";
|
r#";
|
||||||
edit -scratch '*kakplugin-set*';
|
edit -scratch '{}';
|
||||||
execute-keys '%<a-R>_';
|
execute-keys '%<a-R>_';
|
||||||
}}"#
|
}}"#,
|
||||||
|
KAK_BUFFER_NAME
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
f.flush()?;
|
f.flush()?;
|
||||||
@ -207,12 +219,19 @@ fn print_result(key_set_operation_result: &LinkedHashSet<&Selection>) -> Result<
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compare(
|
/// Writes a comparison table to a new kak buffer
|
||||||
|
///
|
||||||
|
/// * `left_register` - Register of the left side
|
||||||
|
/// * `right_register` - Register of the right side
|
||||||
|
/// * `key_set_operation_result` - Set of selections after chosen operation
|
||||||
|
/// * `left_ordered_counts` - Map of ordered counts on `get_key` to frequency on the left side
|
||||||
|
/// * `right_ordered_counts` - Map of ordered counts on `get_key` to frequency on the right side
|
||||||
|
fn compare<'sel, 'a, 'b>(
|
||||||
left_register: Register,
|
left_register: Register,
|
||||||
right_register: Register,
|
right_register: Register,
|
||||||
key_set_operation_result: &LinkedHashSet<&Selection>,
|
key_set_operation_result: LinkedHashSet<&'b str>,
|
||||||
left_ordered_counts: &LinkedHashMap<Selection, usize>,
|
left_ordered_counts: &'b LinkedHashMap<Cow<'sel, str>, usize>,
|
||||||
right_ordered_counts: &LinkedHashMap<Selection, usize>,
|
right_ordered_counts: &'b LinkedHashMap<Cow<'sel, str>, usize>,
|
||||||
) -> Result<(), KakError> {
|
) -> Result<(), KakError> {
|
||||||
// Manually set selections so we don't have to allocate a string
|
// Manually set selections so we don't have to allocate a string
|
||||||
let mut f = kakplugin::open_command_fifo()?;
|
let mut f = kakplugin::open_command_fifo()?;
|
||||||
@ -253,9 +272,10 @@ fn compare(
|
|||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
r#";
|
r#";
|
||||||
edit -scratch '*kakplugin-set*';
|
edit -scratch '{}';
|
||||||
execute-keys '%<a-R><a-;>3<a-W>L)<a-space>_vb';
|
execute-keys '%<a-R><a-;>3<a-W>L)<a-space>_vb';
|
||||||
}}"#
|
}}"#,
|
||||||
|
KAK_BUFFER_NAME
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
f.flush()?;
|
f.flush()?;
|
||||||
@ -263,13 +283,21 @@ fn compare(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_ordered_counts(options: &Options, sels: Vec<Selection>) -> LinkedHashMap<Selection, usize> {
|
/// Counts frequency of unique selection contents, while preserving document order using a `LinkedHashMap`
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
///
|
||||||
|
/// `LinkedHashMap` ordered by document order with `get_key(selection, ...)` as key and frequency of selection
|
||||||
|
fn to_ordered_counts<'sel>(
|
||||||
|
options: &Options,
|
||||||
|
selections: Vec<&'sel str>,
|
||||||
|
) -> LinkedHashMap<Cow<'sel, str>, usize> {
|
||||||
let mut ret = LinkedHashMap::new();
|
let mut ret = LinkedHashMap::new();
|
||||||
|
|
||||||
for i in sels {
|
for i in selections {
|
||||||
let key = crate::utils::get_key(
|
let key = crate::utils::get_key(
|
||||||
&i,
|
&i,
|
||||||
options.skip_whitespace,
|
!options.skip_whitespace,
|
||||||
options.regex.as_ref(),
|
options.regex.as_ref(),
|
||||||
options.ignore_case,
|
options.ignore_case,
|
||||||
);
|
);
|
||||||
@ -289,25 +317,19 @@ fn to_ordered_counts(options: &Options, sels: Vec<Selection>) -> LinkedHashMap<S
|
|||||||
/// * `operation` - The operation to perform
|
/// * `operation` - The operation to perform
|
||||||
/// * `left_keys` - The set on the left side of the operator
|
/// * `left_keys` - The set on the left side of the operator
|
||||||
/// * `right_keys` - The set on the right side of the operator
|
/// * `right_keys` - The set on the right side of the operator
|
||||||
fn key_set_operation<'a>(
|
fn key_set_operation<'sel>(
|
||||||
operation: &Operation,
|
operation: &Operation,
|
||||||
left_keys: &LinkedHashSet<&'a Selection>,
|
left_keys: &LinkedHashSet<&'sel str>,
|
||||||
right_keys: &LinkedHashSet<&'a Selection>,
|
right_keys: &LinkedHashSet<&'sel str>,
|
||||||
) -> LinkedHashSet<&'a Selection> {
|
) -> LinkedHashSet<&'sel str> {
|
||||||
match operation {
|
match operation {
|
||||||
Operation::Intersect => left_keys
|
Operation::Intersect => left_keys
|
||||||
.intersection(right_keys)
|
.intersection(right_keys)
|
||||||
// .into_iter()
|
// .into_iter()
|
||||||
.copied()
|
.copied()
|
||||||
.collect(),
|
.collect(),
|
||||||
Operation::Subtract => left_keys
|
Operation::Subtract => left_keys.difference(right_keys).copied().collect(),
|
||||||
.difference(right_keys)
|
Operation::Compare | Operation::Union => left_keys.union(right_keys).copied().collect(), // TODO: Symmetric difference?
|
||||||
.into_iter()
|
|
||||||
.copied()
|
|
||||||
.collect(),
|
|
||||||
Operation::Compare | Operation::Union => {
|
|
||||||
left_keys.union(right_keys).into_iter().copied().collect()
|
|
||||||
} // TODO: Symmetric difference?
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,9 +371,18 @@ fn parse_arguments(args: &[String]) -> Result<(Register, Operation, Register), K
|
|||||||
Register::from_str(r)?,
|
Register::from_str(r)?,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
_ => Err(KakError::Custom(
|
[middle] => {
|
||||||
"Invalid arguments to set command".to_string(),
|
// They gave us one argument like "-"
|
||||||
)),
|
// Default to (current selection)(operation)(^ register (set with Z)) => _-^
|
||||||
|
Ok((
|
||||||
|
Register::Underscore,
|
||||||
|
Operation::from_str(middle)?,
|
||||||
|
Register::Caret,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
_ => Err(KakError::Custom(format!(
|
||||||
|
"Invalid arguments to set command: {args:?}"
|
||||||
|
))),
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
if left_register == right_register {
|
if left_register == right_register {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use kakplugin::{get_selections, set_selections, KakError};
|
use kakplugin::{get_selections, set_selections, KakError};
|
||||||
use rand::{seq::SliceRandom, thread_rng};
|
use rand::{seq::SliceRandom, thread_rng};
|
||||||
#[derive(clap::StructOpt, Debug)]
|
#[derive(clap::Args, Debug)]
|
||||||
pub struct Options;
|
pub struct Options;
|
||||||
pub fn shuf(_options: &Options) -> Result<String, KakError> {
|
pub fn shuf(_options: &Options) -> Result<String, KakError> {
|
||||||
let mut selections = get_selections(None)?;
|
let mut selections = get_selections(None)?;
|
||||||
|
22
src/sort.rs
22
src/sort.rs
@ -1,9 +1,10 @@
|
|||||||
use alphanumeric_sort::compare_str;
|
use alphanumeric_sort::compare_str;
|
||||||
|
use clap::ArgAction;
|
||||||
use kakplugin::{self, get_selections_with_desc, open_command_fifo, KakError, SelectionWithDesc};
|
use kakplugin::{self, get_selections_with_desc, open_command_fifo, KakError, SelectionWithDesc};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::{borrow::Cow, cmp::Ordering, io::Write};
|
use std::{borrow::Cow, cmp::Ordering, io::Write};
|
||||||
|
|
||||||
#[derive(clap::StructOpt, Debug)]
|
#[derive(clap::Args, Debug)]
|
||||||
pub struct Options {
|
pub struct Options {
|
||||||
#[clap(index = 1, help = "Optional regex comparison key")]
|
#[clap(index = 1, help = "Optional regex comparison key")]
|
||||||
regex: Option<Regex>,
|
regex: Option<Regex>,
|
||||||
@ -14,7 +15,8 @@ pub struct Options {
|
|||||||
)]
|
)]
|
||||||
subselections_register: Option<char>,
|
subselections_register: Option<char>,
|
||||||
// TODO: Can we invert a boolean? This name is terrible
|
// TODO: Can we invert a boolean? This name is terrible
|
||||||
#[clap(short = 'S', long, parse(try_from_str = invert_bool), default_value_t, help = "Do not treat trimmed value of selections when sorting")]
|
// #[clap(short = 'S', long, value_parser = invert_bool, default_value_t, help = "Do not treat trimmed value of selections when sorting")]
|
||||||
|
#[clap(short = 'S', long, action = ArgAction::SetFalse, default_value_t, help = "Do not treat trimmed value of selections when sorting")]
|
||||||
no_skip_whitespace: bool,
|
no_skip_whitespace: bool,
|
||||||
#[clap(short = 'L', long, help = "Do not sort numbers lexicographically")]
|
#[clap(short = 'L', long, help = "Do not sort numbers lexicographically")]
|
||||||
no_lexicographic_sort: bool,
|
no_lexicographic_sort: bool,
|
||||||
@ -24,14 +26,14 @@ pub struct Options {
|
|||||||
ignore_case: bool,
|
ignore_case: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn invert_bool(s: &str) -> Result<bool, &'static str> {
|
// fn invert_bool(s: &str) -> Result<bool, &'static str> {
|
||||||
// Invert the boolean
|
// // Invert the boolean
|
||||||
match s {
|
// match s {
|
||||||
"false" => Ok(true),
|
// "false" => Ok(true),
|
||||||
"true" => Ok(false),
|
// "true" => Ok(false),
|
||||||
_ => Err("Unparsable boolean value"),
|
// _ => Err("Unparsable boolean value"),
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
struct SortableSelection<'a> {
|
struct SortableSelection<'a> {
|
||||||
/// The content of the selection
|
/// The content of the selection
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use kakplugin::{get_selections, open_command_fifo, KakError};
|
use kakplugin::{get_selections, open_command_fifo, KakError};
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
#[derive(clap::StructOpt, Debug)]
|
#[derive(clap::Args, Debug)]
|
||||||
pub struct Options {
|
pub struct Options {
|
||||||
#[clap(short, long, help = "Trim from left")]
|
#[clap(short, long, help = "Trim from left")]
|
||||||
left: bool,
|
left: bool,
|
||||||
|
@ -6,7 +6,7 @@ use kakplugin::{
|
|||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
#[derive(clap::StructOpt, Debug)]
|
#[derive(clap::Args, Debug)]
|
||||||
pub struct Options {
|
pub struct Options {
|
||||||
#[clap(index = 1, help = "Optional regex to compare unique elements")]
|
#[clap(index = 1, help = "Optional regex to compare unique elements")]
|
||||||
regex: Option<Regex>,
|
regex: Option<Regex>,
|
||||||
|
48
src/utils.rs
48
src/utils.rs
@ -1,26 +1,38 @@
|
|||||||
use kakplugin::Selection;
|
// use kakplugin::Selection;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::{
|
use std::{
|
||||||
|
borrow::Cow,
|
||||||
collections::hash_map::DefaultHasher,
|
collections::hash_map::DefaultHasher,
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn get_key(
|
/// Gets a key out of a selection
|
||||||
// TODO: Use Cow
|
///
|
||||||
selection: &Selection,
|
/// # Examples
|
||||||
skip_whitespace: bool,
|
///
|
||||||
|
/// ```
|
||||||
|
/// assert_eq!(get_key(" asdf\n", false, None, false), "asdf\n");
|
||||||
|
/// assert_eq!(get_key(" asdf\n", true, None, false), " asdf\n");
|
||||||
|
/// assert_eq!(get_key(" as1f\n", false, Some("\w+"), false), "as");
|
||||||
|
/// assert_eq!(get_key(" aS1F\n", false, Some("\w+"), true), "as1f");
|
||||||
|
/// ```
|
||||||
|
pub fn get_key<'sel>(
|
||||||
|
selection: &'sel str,
|
||||||
|
preserve_whitespace: bool,
|
||||||
regex: Option<&Regex>,
|
regex: Option<&Regex>,
|
||||||
ignore_case: bool,
|
ignore_case: bool,
|
||||||
) -> String {
|
) -> Cow<'sel, str> {
|
||||||
// Strip whitespace if requested
|
// Strip whitespace if requested
|
||||||
let mut key = if skip_whitespace {
|
let mut key = if preserve_whitespace {
|
||||||
selection.as_str()
|
// TODO: Does this need to be swapped?
|
||||||
|
selection
|
||||||
} else {
|
} else {
|
||||||
selection.trim()
|
selection.trim()
|
||||||
};
|
};
|
||||||
|
|
||||||
// If they requested a regex match, set the key to the string slice of that match
|
// If they requested a regex match, set the key to the string slice of that match
|
||||||
if let Some(regex_match) = (|| {
|
if let Some(regex_match) = (|| {
|
||||||
|
// let captures = regex.as_ref()?.captures(&key)?;
|
||||||
let captures = regex.as_ref()?.captures(key)?;
|
let captures = regex.as_ref()?.captures(key)?;
|
||||||
captures
|
captures
|
||||||
.get(1)
|
.get(1)
|
||||||
@ -28,29 +40,35 @@ pub fn get_key(
|
|||||||
.map(|m| m.as_str())
|
.map(|m| m.as_str())
|
||||||
})() {
|
})() {
|
||||||
key = regex_match;
|
key = regex_match;
|
||||||
|
// Cow::Borrowed(regex_match)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore case if requested
|
// Ignore case if requested
|
||||||
// Lowercase at the end to not mangle regex
|
|
||||||
if ignore_case {
|
if ignore_case {
|
||||||
key.to_lowercase()
|
// Lowercase at the end to not mangle regex
|
||||||
|
// TODO: Do not allocate if it is already lowercased
|
||||||
|
// Need to_lowercase(&self) -> Cow<str>
|
||||||
|
if !key.as_bytes().iter().any(u8::is_ascii_uppercase) {
|
||||||
|
Cow::Borrowed(key)
|
||||||
|
} else {
|
||||||
|
Cow::Owned(key.to_ascii_lowercase())
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO: Do not perform an allocation here
|
Cow::Borrowed(key)
|
||||||
key.to_string()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a key out of a selection based on options
|
/// Get a key out of a selection based on options
|
||||||
pub fn get_hash(
|
pub fn get_hash(
|
||||||
// TODO: Accept any Into<AsRef<Selection>>
|
// TODO: Accept any Into<AsRef<Selection>>
|
||||||
selection: &Selection,
|
selection: &str,
|
||||||
skip_whitespace: bool,
|
preserve_whitespace: bool,
|
||||||
regex: Option<&Regex>,
|
regex: Option<&Regex>,
|
||||||
ignore_case: bool,
|
ignore_case: bool,
|
||||||
) -> u64 {
|
) -> u64 {
|
||||||
let mut hasher = DefaultHasher::new();
|
let mut hasher = DefaultHasher::new();
|
||||||
|
|
||||||
get_key(selection, skip_whitespace, regex, ignore_case).hash(&mut hasher);
|
get_key(&selection, preserve_whitespace, regex, ignore_case).hash(&mut hasher);
|
||||||
|
|
||||||
hasher.finish()
|
hasher.finish()
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ use std::{
|
|||||||
io::{BufRead, BufReader, Write},
|
io::{BufRead, BufReader, Write},
|
||||||
process::{Command, Stdio},
|
process::{Command, Stdio},
|
||||||
};
|
};
|
||||||
#[derive(clap::StructOpt, Debug)]
|
#[derive(clap::Args, Debug)]
|
||||||
pub struct Options {
|
pub struct Options {
|
||||||
#[clap()]
|
#[clap()]
|
||||||
command: String,
|
command: String,
|
||||||
|
@ -8,13 +8,15 @@ use std::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(clap::StructOpt, Debug)]
|
#[derive(clap::Args, Debug)]
|
||||||
pub struct Options {
|
pub struct Options {
|
||||||
#[clap(help = "Register with the lookup table", default_value = "\"")]
|
#[clap(help = "Register with the lookup table", default_value = "^")]
|
||||||
register: Register,
|
register: Register,
|
||||||
}
|
}
|
||||||
pub fn xlookup(options: &Options) -> Result<String, KakError> {
|
pub fn xlookup(options: &Options) -> Result<String, KakError> {
|
||||||
let lookup_table = build_lookuptable(kakplugin::reg(options.register, None)?)?;
|
eprintln!("Getting registers for {options:?}");
|
||||||
|
let lookup_table = build_lookuptable(kakplugin::get_register_selections(options.register)?)?;
|
||||||
|
// let lookup_table = build_lookuptable(kakplugin::reg(options.register, None)?)?;
|
||||||
|
|
||||||
let selections = get_selections(None)?;
|
let selections = get_selections(None)?;
|
||||||
|
|
||||||
@ -22,7 +24,7 @@ pub fn xlookup(options: &Options) -> Result<String, KakError> {
|
|||||||
|
|
||||||
set_selections(selections.iter().map(|key| {
|
set_selections(selections.iter().map(|key| {
|
||||||
lookup_table
|
lookup_table
|
||||||
.get(&get_hash(key, false, None, false))
|
.get(&get_hash(&key, false, None, false))
|
||||||
.map_or_else(
|
.map_or_else(
|
||||||
|| {
|
|| {
|
||||||
eprintln!("Key '{key}' not found",);
|
eprintln!("Key '{key}' not found",);
|
||||||
@ -48,7 +50,7 @@ pub fn xlookup(options: &Options) -> Result<String, KakError> {
|
|||||||
fn build_lookuptable(mut selections: Vec<Selection>) -> Result<BTreeMap<u64, Selection>, KakError> {
|
fn build_lookuptable(mut selections: Vec<Selection>) -> Result<BTreeMap<u64, Selection>, KakError> {
|
||||||
let mut iter = selections.array_chunks_mut();
|
let mut iter = selections.array_chunks_mut();
|
||||||
let ret = iter.try_fold(BTreeMap::new(), |mut acc, [key, value]| {
|
let ret = iter.try_fold(BTreeMap::new(), |mut acc, [key, value]| {
|
||||||
match acc.entry(get_hash(key, false, None, false)) {
|
match acc.entry(get_hash(&key, false, None, false)) {
|
||||||
Occupied(_) => Err(KakError::Custom(format!("Duplicate key '{key}'"))),
|
Occupied(_) => Err(KakError::Custom(format!("Duplicate key '{key}'"))),
|
||||||
Vacant(v) => {
|
Vacant(v) => {
|
||||||
v.insert(value.clone());
|
v.insert(value.clone());
|
||||||
@ -76,7 +78,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
macro_rules! hsh {
|
macro_rules! hsh {
|
||||||
($expr:expr) => {
|
($expr:expr) => {
|
||||||
get_hash(&$expr.to_string(), false, None, false)
|
get_hash($expr, false, None, false)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
|
Loading…
Reference in New Issue
Block a user