aboutsummaryrefslogtreecommitdiffstats
path: root/pkgs/by-name/lf/lf-make-map
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--pkgs/by-name/lf/lf-make-map/Cargo.lock217
-rw-r--r--pkgs/by-name/lf/lf-make-map/Cargo.toml5
-rw-r--r--pkgs/by-name/lf/lf-make-map/flake.nix2
-rw-r--r--pkgs/by-name/lf/lf-make-map/src/cli.rs6
-rw-r--r--pkgs/by-name/lf/lf-make-map/src/main.rs89
-rw-r--r--pkgs/by-name/lf/lf-make-map/src/mapping/interactive.rs172
-rw-r--r--pkgs/by-name/lf/lf-make-map/src/mapping/map_key.rs41
-rw-r--r--pkgs/by-name/lf/lf-make-map/src/mapping/mod.rs1
-rwxr-xr-xpkgs/by-name/lf/lf-make-map/tests/base.sh2
-rw-r--r--pkgs/by-name/lf/lf-make-map/tests/cases/dot_dirs/output.old13
-rwxr-xr-xpkgs/by-name/lf/lf-make-map/tests/cases/dot_dirs/test.sh49
-rw-r--r--pkgs/by-name/lf/lf-make-map/tests/cases/dot_dirs_duplicates/output.old17
-rwxr-xr-xpkgs/by-name/lf/lf-make-map/tests/cases/dot_dirs_duplicates/test.sh53
-rwxr-xr-xpkgs/by-name/lf/lf-make-map/tests/cases/simple/test.sh8
-rwxr-xr-xpkgs/by-name/lf/lf-make-map/update.sh4
15 files changed, 541 insertions, 138 deletions
diff --git a/pkgs/by-name/lf/lf-make-map/Cargo.lock b/pkgs/by-name/lf/lf-make-map/Cargo.lock
index db296a8c..799f83ef 100644
--- a/pkgs/by-name/lf/lf-make-map/Cargo.lock
+++ b/pkgs/by-name/lf/lf-make-map/Cargo.lock
@@ -72,9 +72,9 @@ dependencies = [
[[package]]
name = "anyhow"
-version = "1.0.102"
+version = "1.0.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
+checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3"
[[package]]
name = "autocfg"
@@ -83,6 +83,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
[[package]]
+name = "bitflags"
+version = "2.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8"
+
+[[package]]
name = "bumpalo"
version = "3.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -90,9 +96,9 @@ checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649"
[[package]]
name = "cc"
-version = "1.2.62"
+version = "1.2.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98"
+checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96"
dependencies = [
"find-msvc-tools",
"shlex",
@@ -106,9 +112,9 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "chrono"
-version = "0.4.44"
+version = "0.4.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0"
+checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327"
dependencies = [
"iana-time-zone",
"js-sys",
@@ -170,6 +176,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
+name = "crossterm"
+version = "0.29.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b"
+dependencies = [
+ "bitflags",
+ "document-features",
+ "mio",
+ "parking_lot",
+ "rustix",
+ "signal-hook",
+ "signal-hook-mio",
+]
+
+[[package]]
+name = "document-features"
+version = "0.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61"
+dependencies = [
+ "litrs",
+]
+
+[[package]]
+name = "errno"
+version = "0.3.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
+dependencies = [
+ "libc",
+ "windows-sys",
+]
+
+[[package]]
name = "find-msvc-tools"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -254,13 +294,12 @@ checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
[[package]]
name = "js-sys"
-version = "0.3.99"
+version = "0.3.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11"
+checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102"
dependencies = [
"cfg-if",
"futures-util",
- "once_cell",
"wasm-bindgen",
]
@@ -279,6 +318,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"clap",
+ "crossterm",
"keymaps",
"log",
"stderrlog",
@@ -292,10 +332,43 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
[[package]]
+name = "linux-raw-sys"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
+
+[[package]]
+name = "litrs"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092"
+
+[[package]]
+name = "lock_api"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
+dependencies = [
+ "scopeguard",
+]
+
+[[package]]
name = "log"
-version = "0.4.30"
+version = "0.4.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "616ec5685824bcc94416c6d4a7a446eea774a31efd7062c8480ba6fd06d7a6e5"
+checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad"
+
+[[package]]
+name = "mio"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda"
+dependencies = [
+ "libc",
+ "log",
+ "wasi",
+ "windows-sys",
+]
[[package]]
name = "num-traits"
@@ -319,6 +392,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
[[package]]
+name = "parking_lot"
+version = "0.12.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
+dependencies = [
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.9.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall",
+ "smallvec",
+ "windows-link",
+]
+
+[[package]]
name = "pin-project-lite"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -335,14 +431,36 @@ dependencies = [
[[package]]
name = "quote"
-version = "1.0.45"
+version = "1.0.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
+checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368"
dependencies = [
"proc-macro2",
]
[[package]]
+name = "redox_syscall"
+version = "0.5.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
+name = "rustix"
+version = "1.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190"
+dependencies = [
+ "bitflags",
+ "errno",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys",
+]
+
+[[package]]
name = "rustversion"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -358,10 +476,47 @@ dependencies = [
]
[[package]]
+name = "scopeguard"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
+
+[[package]]
name = "shlex"
-version = "1.3.0"
+version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
+checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
+
+[[package]]
+name = "signal-hook"
+version = "0.3.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2"
+dependencies = [
+ "libc",
+ "signal-hook-registry",
+]
+
+[[package]]
+name = "signal-hook-mio"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b75a19a7a740b25bc7944bdee6172368f988763b744e3d4dfe753f6b4ece40cc"
+dependencies = [
+ "libc",
+ "mio",
+ "signal-hook",
+]
+
+[[package]]
+name = "signal-hook-registry"
+version = "1.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b"
+dependencies = [
+ "errno",
+ "libc",
+]
[[package]]
name = "slab"
@@ -370,6 +525,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
[[package]]
+name = "smallvec"
+version = "1.15.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90"
+
+[[package]]
name = "stderrlog"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -390,9 +551,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
-version = "2.0.117"
+version = "2.0.118"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
+checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
dependencies = [
"proc-macro2",
"quote",
@@ -460,10 +621,16 @@ dependencies = [
]
[[package]]
+name = "wasi"
+version = "0.11.1+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
+
+[[package]]
name = "wasm-bindgen"
-version = "0.2.122"
+version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409"
+checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4"
dependencies = [
"cfg-if",
"once_cell",
@@ -474,9 +641,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
-version = "0.2.122"
+version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6"
+checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -484,9 +651,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
-version = "0.2.122"
+version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e"
+checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e"
dependencies = [
"bumpalo",
"proc-macro2",
@@ -497,9 +664,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
-version = "0.2.122"
+version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437"
+checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24"
dependencies = [
"unicode-ident",
]
diff --git a/pkgs/by-name/lf/lf-make-map/Cargo.toml b/pkgs/by-name/lf/lf-make-map/Cargo.toml
index 94405954..8411a4b9 100644
--- a/pkgs/by-name/lf/lf-make-map/Cargo.toml
+++ b/pkgs/by-name/lf/lf-make-map/Cargo.toml
@@ -17,9 +17,10 @@ edition = "2024"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-anyhow = "1.0.102"
+anyhow = "1.0.103"
clap = { version = "4.6.1", features = ["derive", "env"] }
+crossterm = {version = "0.29.0", default-features = false, features = ["events"]}
keymaps = "1.2.0"
-log = "0.4.30"
+log = "0.4.33"
stderrlog = "0.6.0"
walkdir = "2.5.0"
diff --git a/pkgs/by-name/lf/lf-make-map/flake.nix b/pkgs/by-name/lf/lf-make-map/flake.nix
index 5e191e7b..2d1e93a2 100644
--- a/pkgs/by-name/lf/lf-make-map/flake.nix
+++ b/pkgs/by-name/lf/lf-make-map/flake.nix
@@ -16,7 +16,7 @@
system = "x86_64-linux";
sources = import ../../../../npins/full.nix {};
- pkgs = sources.load "nixpkgs";
+ pkgs = (sources.loadFlake "nixpkgs").legacyPackages."${system}";
in {
devShells."${system}".default = pkgs.mkShell {
packages = [
diff --git a/pkgs/by-name/lf/lf-make-map/src/cli.rs b/pkgs/by-name/lf/lf-make-map/src/cli.rs
index 70746984..25a5a626 100644
--- a/pkgs/by-name/lf/lf-make-map/src/cli.rs
+++ b/pkgs/by-name/lf/lf-make-map/src/cli.rs
@@ -50,6 +50,12 @@ pub enum Command {
#[command(flatten)]
options: CommandOptions,
},
+
+ /// Perform interactive selection, and then cd-there.
+ Interactive {
+ #[command(flatten)]
+ options: CommandOptions,
+ },
}
#[derive(Debug, Parser)]
diff --git a/pkgs/by-name/lf/lf-make-map/src/main.rs b/pkgs/by-name/lf/lf-make-map/src/main.rs
index d5d934e1..1576c1dd 100644
--- a/pkgs/by-name/lf/lf-make-map/src/main.rs
+++ b/pkgs/by-name/lf/lf-make-map/src/main.rs
@@ -39,6 +39,7 @@ fn main() -> anyhow::Result<()> {
let relevant_directories = match &args.command {
Command::Visualize { options } => &options.relevant_directories,
Command::Generate { options } => &options.relevant_directories,
+ Command::Interactive { options } => &options.relevant_directories,
};
for dir in relevant_directories {
@@ -99,6 +100,7 @@ fn main() -> anyhow::Result<()> {
match args.command {
Command::Visualize { .. } => println!("{}", mappings.0),
Command::Generate { .. } => println!("{}", mappings.to_lf_mappings(args.home_name)),
+ Command::Interactive { .. } => mappings.interactive_start(args.home_name)?,
}
Ok(())
@@ -144,90 +146,3 @@ because it can't be turned to a string
)
})
}
-
-// fn gen_lf_mappings(home_name: PathBuf, char_num: usize, rel_dirs: Vec<PathBuf>) {
-// let mut mappings_vec = vec![];
-// let mut index_counter = 0;
-// rel_dirs.iter().for_each(|rel_dir| {
-// mappings_vec.push(vec![Mapping::new(
-// &gen_hot_key(rel_dir, rel_dir, char_num),
-// rel_dir,
-// rel_dir,
-// None,
-// )]);
-// get_dir(rel_dir.to_owned()).iter().for_each(|path| {
-// mappings_vec[index_counter].push(Mapping::new(
-// &gen_hot_key(
-// path,
-// path.parent().expect("All paths here should have parents"),
-// char_num,
-// ),
-// path,
-// &path
-// .parent()
-// .expect("All paths here should have parents")
-// .to_owned(),
-// None,
-// ));
-// });
-// index_counter += 1;
-// });
-// print_mappings(&mappings_vec, home_name);
-// mappings_vec
-// .into_iter()
-// .for_each(|rel_dir_mapping: Vec<Mapping>| {
-// let mut hash_map = sort_mapping_by_hot_key(rel_dir_mapping.clone());
-// //dbg!(hash_map);
-// hash_map.insert("gsi".to_owned(), vec![rel_dir_mapping[0].clone()]);
-// });
-// }
-//
-// fn sort_mapping_by_hot_key(mut mappings: Vec<Mapping>) -> HashMap<String, Vec<Mapping>> {
-// mappings.sort_by_key(|mapping| mapping.hot_key.clone());
-//
-// let mut filtered_mappings: HashMap<String, Vec<Mapping>> = HashMap::new();
-// mappings.iter().for_each(|mapping| {
-// filtered_mappings.insert(mapping.hot_key.clone(), vec![]);
-// });
-// //dbg!(&mappings);
-//
-// let mut index_counter = 1;
-// mappings.iter().for_each(|mapping| {
-// if mappings.len() > index_counter {
-// let next_mapping = &mappings[index_counter];
-// let vec = filtered_mappings
-// .get_mut(&mapping.hot_key)
-// .expect("This existst as it has been initialized");
-//
-// if &next_mapping.hot_key == &mapping.hot_key {
-// vec.push(mapping.clone());
-// vec.push(next_mapping.clone());
-// } else {
-// vec.push(mapping.clone());
-// }
-//
-// let new_vec = vec.to_owned();
-// filtered_mappings.insert(mapping.hot_key.to_owned(), new_vec);
-// }
-//
-// index_counter += 1;
-// });
-// filtered_mappings
-// }
-//
-// fn print_mappings(mappings: &Vec<Vec<Mapping>>, home_name: PathBuf) {
-// for mapping in mappings {
-// mapping.iter().for_each(|map| {
-// println!(
-// "{} = \"cd {}\";",
-// map.hot_key,
-// map.path
-// .display()
-// .to_string()
-// .replace(home_name.to_str().expect("This should be UTF-8"), "~")
-// );
-// });
-//
-// println!("# -------------");
-// }
-// }
diff --git a/pkgs/by-name/lf/lf-make-map/src/mapping/interactive.rs b/pkgs/by-name/lf/lf-make-map/src/mapping/interactive.rs
new file mode 100644
index 00000000..b8ac27d2
--- /dev/null
+++ b/pkgs/by-name/lf/lf-make-map/src/mapping/interactive.rs
@@ -0,0 +1,172 @@
+// nixos-config - My current NixOS configuration
+//
+// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// This file is part of my nixos-config.
+//
+// You should have received a copy of the License along with this program.
+// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+use std::{io::stderr, path::PathBuf};
+
+use anyhow::Result;
+use crossterm::{
+ cursor::{MoveToRow, MoveUp},
+ event::{
+ Event, KeyEventKind, KeyModifiers, KeyboardEnhancementFlags, PopKeyboardEnhancementFlags,
+ PushKeyboardEnhancementFlags, read,
+ },
+ execute,
+ style::Print,
+ terminal::{self, Clear, ClearType, EnterAlternateScreen, LeaveAlternateScreen},
+};
+
+use crate::mapping::map_key::MapKey;
+
+use super::MappingsTrie;
+
+enum Status {
+ Done(PathBuf),
+ Stop,
+}
+
+impl MappingsTrie {
+ pub fn interactive_start(&self, home_path: PathBuf) -> Result<()> {
+ terminal::enable_raw_mode()?;
+ execute!(
+ stderr(),
+ EnterAlternateScreen,
+ PushKeyboardEnhancementFlags(KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES),
+ MoveToRow(0)
+ )?;
+
+ let output = self.interactive_start_inner(home_path);
+
+ execute!(stderr(), LeaveAlternateScreen, PopKeyboardEnhancementFlags)?;
+ terminal::disable_raw_mode()?;
+
+ match output? {
+ Status::Done(path_buf) => {
+ println!("{}", path_buf.display())
+ }
+ Status::Stop => (),
+ }
+
+ Ok(())
+ }
+
+ fn interactive_start_inner(&self, home_path: PathBuf) -> Result<Status> {
+ macro_rules! done {
+ ($state:ident, $last_length:ident) => {{
+ let value = match self.0.get(&$state).expect("Is some").value() {
+ Some(value) => value,
+ None => return Ok(Status::Stop),
+ };
+
+ let path = home_path.join(&value.path);
+
+ terminal::disable_raw_mode()?;
+ execute!(
+ stderr(),
+ MoveUp($last_length as u16),
+ Clear(ClearType::FromCursorDown),
+ Print(format!("{}\n", path.display()))
+ )?;
+ terminal::enable_raw_mode()?;
+
+ return Ok(Status::Done(path));
+ }};
+ }
+
+ let mut state: Vec<MapKey> = vec![];
+ let mut last_length: usize = 1;
+ while let (trie, matched) = self.0.try_get(&state)
+ && matched == state
+ {
+ if trie.value().is_some() {
+ done!(state, last_length);
+ } else {
+ if let Some(last) = state.last_mut()
+ && let Some(mlast) = matched.last()
+ {
+ last.resolution = mlast.resolution;
+ mlast.part_path.clone_into(&mut last.part_path);
+ }
+ }
+
+ {
+ terminal::disable_raw_mode()?;
+ let string = trie.to_string();
+ execute!(
+ stderr(),
+ MoveUp(last_length as u16),
+ Clear(ClearType::FromCursorDown),
+ Print(format!(
+ "Current state: {}\n",
+ self.current_progress(home_path.display().to_string(), &state)
+ )),
+ Print(&string)
+ )?;
+ last_length = string.lines().count() + 1;
+ terminal::enable_raw_mode()?;
+ }
+
+ if let Event::Key(event) = read()?
+ && event.kind == KeyEventKind::Press
+ {
+ match event.code {
+ crossterm::event::KeyCode::Backspace => {
+ state.pop();
+ }
+ crossterm::event::KeyCode::Enter => done!(state, last_length),
+ crossterm::event::KeyCode::Esc => break,
+ crossterm::event::KeyCode::Char(char) => {
+ if event.modifiers == KeyModifiers::CONTROL && char == 'c' {
+ break;
+ } else {
+ state.push(MapKey {
+ key: char,
+ resolution: 0,
+ part_path: String::new(),
+ });
+ }
+ }
+
+ crossterm::event::KeyCode::Left
+ | crossterm::event::KeyCode::Right
+ | crossterm::event::KeyCode::Up
+ | crossterm::event::KeyCode::Down
+ | crossterm::event::KeyCode::Home
+ | crossterm::event::KeyCode::End
+ | crossterm::event::KeyCode::PageUp
+ | crossterm::event::KeyCode::PageDown
+ | crossterm::event::KeyCode::Tab
+ | crossterm::event::KeyCode::BackTab
+ | crossterm::event::KeyCode::Delete
+ | crossterm::event::KeyCode::Insert
+ | crossterm::event::KeyCode::F(_)
+ | crossterm::event::KeyCode::Null
+ | crossterm::event::KeyCode::CapsLock
+ | crossterm::event::KeyCode::ScrollLock
+ | crossterm::event::KeyCode::NumLock
+ | crossterm::event::KeyCode::PrintScreen
+ | crossterm::event::KeyCode::Pause
+ | crossterm::event::KeyCode::Menu
+ | crossterm::event::KeyCode::KeypadBegin
+ | crossterm::event::KeyCode::Media(_)
+ | crossterm::event::KeyCode::Modifier(_) => (),
+ }
+ }
+ }
+
+ Ok(Status::Stop)
+ }
+
+ fn current_progress(&self, home_path: String, state: &[MapKey]) -> String {
+ state
+ .iter()
+ .map(|mk| &mk.part_path)
+ .fold(home_path, |acc, part| format!("{acc}/{part}"))
+ }
+}
diff --git a/pkgs/by-name/lf/lf-make-map/src/mapping/map_key.rs b/pkgs/by-name/lf/lf-make-map/src/mapping/map_key.rs
index 5fd046fb..6d88d5af 100644
--- a/pkgs/by-name/lf/lf-make-map/src/mapping/map_key.rs
+++ b/pkgs/by-name/lf/lf-make-map/src/mapping/map_key.rs
@@ -48,8 +48,8 @@ impl PartialOrd for MapKey {
}
impl MapKey {
- pub fn new_from_part_path(part_path: &str, resolution: usize) -> Vec<Self> {
- let key = Self::part_path_to_key(part_path, resolution);
+ pub fn new_from_part_path(part_path: &str, resolution: usize, full_path: &str) -> Vec<Self> {
+ let key = Self::path_part_to_key(part_path, resolution, Some(full_path));
key.chars()
.map(|ch| Self {
@@ -63,7 +63,7 @@ impl MapKey {
pub fn new_ones_from_path(path: &str, number_of_chars: usize) -> Vec<Self> {
let key: Vec<MapKey> = path
.split('/')
- .flat_map(|part| Self::new_from_part_path(part, number_of_chars))
+ .flat_map(|part| Self::new_from_part_path(part, number_of_chars, path))
.collect();
debug!(
@@ -80,14 +80,13 @@ impl MapKey {
// debug!("Incrementing: '{}' ('{}')", &self, &self.part_path);
let added_chars = if new_resolution < self.part_path.len() {
- MapKey::part_path_to_key(&self.part_path, new_resolution)
+ MapKey::path_part_to_key(&self.part_path, new_resolution, None)
} else {
let mut generated_chars =
- MapKey::part_path_to_key(&self.part_path, self.part_path.len());
+ MapKey::path_part_to_key(&self.part_path, self.part_path.len(), None);
generated_chars.extend(
(0..(new_resolution - self.part_path.len()))
- .into_iter()
.map(|_| self.part_path.chars().last().expect("This will exists")),
);
@@ -110,19 +109,24 @@ impl MapKey {
}
pub fn display(values: &[Self]) -> String {
- values.iter().map(|value| value.key.clone()).collect()
+ values.iter().map(|value| value.key).collect()
}
- fn part_path_to_key(part: &str, number_of_chars: usize) -> String {
- fn make(pat: char, part: &str, number_of_chars: usize) -> String {
+ fn path_part_to_key(part: &str, number_of_chars: usize, full_path: Option<&str>) -> String {
+ fn make(pat: char, part: &str, number_of_chars: usize, full_path: Option<&str>) -> String {
let mut acc = String::new();
- if !part.split(pat).all(|part| part.len() > 0) {
+ if part.split(pat).all(|split| split.is_empty()) {
panic!(
"\
-Can't turn this path '{}' to a mapping.
-This should not happen, please report the bug!",
- part
+Failed to split path part `{part}`, with pattern `{pat}`, because all resulting split parts are empty. {}
+This should not happen, please report this bug!", {
+ if let Some(full_path) = full_path {
+ format!("(Full path was: `{full_path}`)")
+ } else {
+ String::new()
+ }
+ }
)
}
@@ -149,9 +153,16 @@ This should not happen, please report the bug!",
}
let value = if part.contains('_') && !part.starts_with('_') && !part.ends_with('_') {
- make('_', part, number_of_chars)
+ make('_', part, number_of_chars, full_path)
} else if part.contains('-') && !part.starts_with('-') && !part.ends_with('-') {
- make('-', part, number_of_chars)
+ make('-', part, number_of_chars, full_path)
+ } else if part.starts_with('.') {
+ // HACK: Special case for directories like ~/.config ~/.local and so on.
+ // We just drop the starting '.' and it's easier to type. <2026-06-02>
+ part.chars()
+ .skip(1)
+ .take(number_of_chars)
+ .collect::<String>()
} else {
part.chars().take(number_of_chars).collect::<String>()
};
diff --git a/pkgs/by-name/lf/lf-make-map/src/mapping/mod.rs b/pkgs/by-name/lf/lf-make-map/src/mapping/mod.rs
index 21392388..b733990e 100644
--- a/pkgs/by-name/lf/lf-make-map/src/mapping/mod.rs
+++ b/pkgs/by-name/lf/lf-make-map/src/mapping/mod.rs
@@ -14,6 +14,7 @@ use log::{Level, debug, log_enabled, trace};
use map_key::MapKey;
pub mod lf_mapping;
+pub mod interactive;
pub mod map_key;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
diff --git a/pkgs/by-name/lf/lf-make-map/tests/base.sh b/pkgs/by-name/lf/lf-make-map/tests/base.sh
index c7694985..d860cf84 100755
--- a/pkgs/by-name/lf/lf-make-map/tests/base.sh
+++ b/pkgs/by-name/lf/lf-make-map/tests/base.sh
@@ -18,7 +18,7 @@ execute_make_maps() {
}
fd . cases --max-depth 1 --type directory | while read -r case; do
- echo "Executing '$case/test.sh'"
+ echo "Executing '${case}test.sh'"
# shellcheck source=/dev/null
LOCATION="$case/test.sh" . "$case/test.sh"
diff --git a/pkgs/by-name/lf/lf-make-map/tests/cases/dot_dirs/output.old b/pkgs/by-name/lf/lf-make-map/tests/cases/dot_dirs/output.old
new file mode 100644
index 00000000..49307bc6
--- /dev/null
+++ b/pkgs/by-name/lf/lf-make-map/tests/cases/dot_dirs/output.old
@@ -0,0 +1,13 @@
+map gc. cd "/tmp/tmp.DfcgjemfCG/.config"
+map gca. cd "/tmp/tmp.DfcgjemfCG/.config/apzu"
+map gcl. cd "/tmp/tmp.DfcgjemfCG/.config/lahmu"
+map gct. cd "/tmp/tmp.DfcgjemfCG/.config/tiamat"
+map gd. cd "/tmp/tmp.DfcgjemfCG/documents"
+map gda. cd "/tmp/tmp.DfcgjemfCG/documents/apzu"
+map gdl. cd "/tmp/tmp.DfcgjemfCG/documents/lahmu"
+map gdt. cd "/tmp/tmp.DfcgjemfCG/documents/tiamat"
+map gl. cd "/tmp/tmp.DfcgjemfCG/.local"
+map gln. cd "/tmp/tmp.DfcgjemfCG/.local/nvim"
+map glsh. cd "/tmp/tmp.DfcgjemfCG/.local/share"
+map glst. cd "/tmp/tmp.DfcgjemfCG/.local/state"
+
diff --git a/pkgs/by-name/lf/lf-make-map/tests/cases/dot_dirs/test.sh b/pkgs/by-name/lf/lf-make-map/tests/cases/dot_dirs/test.sh
new file mode 100755
index 00000000..d3df848c
--- /dev/null
+++ b/pkgs/by-name/lf/lf-make-map/tests/cases/dot_dirs/test.sh
@@ -0,0 +1,49 @@
+#! /usr/bin/env sh
+
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+mkFile() {
+ t="$1"
+
+ mkdir --parents "$(dirname "$t")"
+ echo "TEST_FILE" >"$t"
+}
+
+# We need to hard code this, so that our output matches the golden sample.
+base="/tmp/tmp.DfcgjemfCG"
+test="$(mktemp --directory -t lf_make_temp_test_XXXXX)"
+
+if [ -d "$base" ]; then
+ rm --recursive "$base"
+fi
+mkdir "$base"
+
+cleanup() {
+ rm --recursive "$base" "$test"
+}
+trap cleanup EXIT
+
+mkFile "$base/.local/share/file1.txt"
+mkFile "$base/.local/state/file1.txt"
+mkFile "$base/.local/nvim/log.LOG"
+mkFile "$base/.local/.tog/TOG.LOG"
+
+mkFile "$base/.config/apzu/file2.txt"
+mkFile "$base/.config/tiamat/file2.txt"
+mkFile "$base/.config/lahmu/file2.txt"
+
+mkFile "$base/documents/apzu/file2.txt"
+mkFile "$base/documents/tiamat/file2.txt"
+mkFile "$base/documents/lahmu/file2.txt"
+
+execute_make_maps --home-name "$base" --depth 100 generate "$base/.local" "$base/.config" "$base/documents" >"$test/output.new"
+
+diff "$test/output.new" "$(dirname "$LOCATION")/output.old"
diff --git a/pkgs/by-name/lf/lf-make-map/tests/cases/dot_dirs_duplicates/output.old b/pkgs/by-name/lf/lf-make-map/tests/cases/dot_dirs_duplicates/output.old
new file mode 100644
index 00000000..f7523ba3
--- /dev/null
+++ b/pkgs/by-name/lf/lf-make-map/tests/cases/dot_dirs_duplicates/output.old
@@ -0,0 +1,17 @@
+map gca. cd "/tmp/tmp.DfcgjemfCG/cats"
+map gcaa. cd "/tmp/tmp.DfcgjemfCG/cats/apzu"
+map gcal. cd "/tmp/tmp.DfcgjemfCG/cats/lahmu"
+map gcat. cd "/tmp/tmp.DfcgjemfCG/cats/tiamat"
+map gco. cd "/tmp/tmp.DfcgjemfCG/.config"
+map gcoa. cd "/tmp/tmp.DfcgjemfCG/.config/apzu"
+map gcol. cd "/tmp/tmp.DfcgjemfCG/.config/lahmu"
+map gcot. cd "/tmp/tmp.DfcgjemfCG/.config/tiamat"
+map gd. cd "/tmp/tmp.DfcgjemfCG/documents"
+map gda. cd "/tmp/tmp.DfcgjemfCG/documents/apzu"
+map gdl. cd "/tmp/tmp.DfcgjemfCG/documents/lahmu"
+map gdt. cd "/tmp/tmp.DfcgjemfCG/documents/tiamat"
+map gl. cd "/tmp/tmp.DfcgjemfCG/.local"
+map gln. cd "/tmp/tmp.DfcgjemfCG/.local/nvim"
+map glsh. cd "/tmp/tmp.DfcgjemfCG/.local/share"
+map glst. cd "/tmp/tmp.DfcgjemfCG/.local/state"
+
diff --git a/pkgs/by-name/lf/lf-make-map/tests/cases/dot_dirs_duplicates/test.sh b/pkgs/by-name/lf/lf-make-map/tests/cases/dot_dirs_duplicates/test.sh
new file mode 100755
index 00000000..33447e54
--- /dev/null
+++ b/pkgs/by-name/lf/lf-make-map/tests/cases/dot_dirs_duplicates/test.sh
@@ -0,0 +1,53 @@
+#! /usr/bin/env sh
+
+# nixos-config - My current NixOS configuration
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of my nixos-config.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+mkFile() {
+ t="$1"
+
+ mkdir --parents "$(dirname "$t")"
+ echo "TEST_FILE" >"$t"
+}
+
+# We need to hard code this, so that our output matches the golden sample.
+base="/tmp/tmp.DfcgjemfCG"
+test="$(mktemp --directory -t lf_make_temp_test_XXXXX)"
+
+if [ -d "$base" ]; then
+ rm --recursive "$base"
+fi
+mkdir "$base"
+
+cleanup() {
+ rm --recursive "$base" "$test"
+}
+trap cleanup EXIT
+
+mkFile "$base/.local/share/file1.txt"
+mkFile "$base/.local/state/file1.txt"
+mkFile "$base/.local/nvim/log.LOG"
+mkFile "$base/.local/.tog/TOG.LOG"
+
+mkFile "$base/.config/apzu/file2.txt"
+mkFile "$base/.config/tiamat/file2.txt"
+mkFile "$base/.config/lahmu/file2.txt"
+
+mkFile "$base/documents/apzu/file2.txt"
+mkFile "$base/documents/tiamat/file2.txt"
+mkFile "$base/documents/lahmu/file2.txt"
+
+mkFile "$base/cats/apzu/file2.txt"
+mkFile "$base/cats/tiamat/file2.txt"
+mkFile "$base/cats/lahmu/file2.txt"
+
+execute_make_maps --home-name "$base" --depth 100 generate "$base/.local" "$base/.config" "$base/documents" "$base/cats" >"$test/output.new"
+
+diff "$test/output.new" "$(dirname "$LOCATION")/output.old"
diff --git a/pkgs/by-name/lf/lf-make-map/tests/cases/simple/test.sh b/pkgs/by-name/lf/lf-make-map/tests/cases/simple/test.sh
index 22f97009..97ee0cb9 100755
--- a/pkgs/by-name/lf/lf-make-map/tests/cases/simple/test.sh
+++ b/pkgs/by-name/lf/lf-make-map/tests/cases/simple/test.sh
@@ -14,11 +14,9 @@
base="/tmp/tmp.DfcgjemfCG"
test="$(mktemp --directory -t lf_make_temp_test_XXXXX)"
-[ -d "$base" ] && {
- echo "$base already exists!"
- exit 1
-}
-
+if [ -d "$base" ]; then
+ rm --recursive "$base"
+fi
mkdir "$base"
cleanup() {
diff --git a/pkgs/by-name/lf/lf-make-map/update.sh b/pkgs/by-name/lf/lf-make-map/update.sh
index 23d90a86..188771c4 100755
--- a/pkgs/by-name/lf/lf-make-map/update.sh
+++ b/pkgs/by-name/lf/lf-make-map/update.sh
@@ -10,5 +10,5 @@
# You should have received a copy of the License along with this program.
# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
-[ "$1" = "upgrade" ] && cargo upgrade
-cargo update
+[ "$1" = "upgrade" ] && cargo upgrade --incompatible allow --pinned allow --recursive true
+cargo update --recursive