about summary refs log tree commit diff stats
path: root/pkgs/sources/lf-make-map/src/main.rs
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2024-05-20 16:10:21 +0200
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2024-05-20 16:14:26 +0200
commit368cb6b0d25db2ae23be42ad51584de059997e51 (patch)
tree3282e45d3ebced63c8498a47e83a255c35de620b /pkgs/sources/lf-make-map/src/main.rs
parentrefactor(hm): Rename to `modules/home` (diff)
downloadnixos-config-368cb6b0d25db2ae23be42ad51584de059997e51.tar.gz
nixos-config-368cb6b0d25db2ae23be42ad51584de059997e51.zip
refactor(sys): Modularize and move to `modules/system` or `pkgs`
Diffstat (limited to 'pkgs/sources/lf-make-map/src/main.rs')
-rw-r--r--pkgs/sources/lf-make-map/src/main.rs229
1 files changed, 229 insertions, 0 deletions
diff --git a/pkgs/sources/lf-make-map/src/main.rs b/pkgs/sources/lf-make-map/src/main.rs
new file mode 100644
index 00000000..aaf79b20
--- /dev/null
+++ b/pkgs/sources/lf-make-map/src/main.rs
@@ -0,0 +1,229 @@
+use std::path::{Path, PathBuf};
+
+use anyhow::{Context, Result};
+use clap::Parser;
+use cli::{Args, Command};
+use log::trace;
+use mapping::map_tree::MappingTree;
+use walkdir::{DirEntry, WalkDir};
+
+use crate::mapping::MapKey;
+
+mod cli;
+mod mapping;
+
+fn main() -> anyhow::Result<()> {
+    let args = Args::parse();
+
+    stderrlog::new()
+        .module(module_path!())
+        .quiet(args.quiet)
+        .show_module_names(false)
+        .color(stderrlog::ColorChoice::Auto)
+        .verbosity(args.verbosity as usize)
+        .timestamp(stderrlog::Timestamp::Off)
+        .init()?;
+
+    let mut mappings = MappingTree::new();
+
+    let relevant_directories = match &args.command {
+        Command::Visualize { options } => &options.relevant_directories,
+        Command::Generate { options } => &options.relevant_directories,
+    };
+
+    for dir in relevant_directories {
+        trace!("Processing '{}'..", dir.display());
+        let path = strip_path(&dir, &args.home_name)?;
+
+        mappings
+            .include(path_to_str(path)?)
+            .with_context(|| format!("Failed to include path: '{}'", path.display()))?;
+    }
+
+    let home = path_to_str(&args.home_name)?.to_owned();
+
+    let mut current_depth = 1;
+    while current_depth != args.depth {
+        for (key, value) in mappings.iter(false) {
+            trace!(
+                "Adding to child ('{}' -> '{}')",
+                MapKey::display(&key),
+                value
+            );
+
+            let mut local_mappings = MappingTree::new();
+            for dir in WalkDir::new(extend(&home, &value)?)
+                .min_depth(1)
+                .max_depth(1)
+                .into_iter()
+                .filter_entry(|e| is_dir(e) && !is_hidden(e))
+            {
+                let directory = dir
+                    .with_context(|| format!("Failed to read dir ('{}')", home.clone() + &value))?;
+                let path_to_strip = &PathBuf::from(extend(&home, &value)?);
+                let path = strip_path(&directory.path(), &path_to_strip)?;
+                trace!(
+                    "Including: '{}' (after stripping '{}' from '{}' -> '{}' + '/' + '{}')",
+                    path.display(),
+                    directory.path().display(),
+                    path_to_strip.display(),
+                    home,
+                    value
+                );
+
+                let gen_key = MapKey::new_ones_from_path(path_to_str(path)?, 1);
+                local_mappings
+                    .insert(
+                        &gen_key,
+                        path_to_str(strip_path(&directory.path(), &PathBuf::from(&home))?)?,
+                    )
+                    .with_context(|| format!("Failed to include path: '{}'", path.display()))?;
+            }
+
+            trace!("{}", local_mappings);
+
+            trace!(
+                "'{}' -> '{:#?}'",
+                MapKey::display(&key),
+                local_mappings.root_node()
+            );
+            mappings.interleave(&key, local_mappings.root_node().to_owned())?;
+        }
+        current_depth += 1;
+    }
+
+    match args.command {
+        Command::Visualize { .. } => println!("{}", mappings),
+        Command::Generate { .. } => println!("{}", mappings.to_lf_mappings(args.home_name)),
+    }
+
+    Ok(())
+}
+
+fn extend(base: &str, value: &str) -> Result<String> {
+    let base_path = PathBuf::from(base);
+    let value_path = PathBuf::from(value);
+
+    Ok(path_to_str(&base_path.join(&value_path))?.to_owned())
+}
+
+fn is_hidden(entry: &DirEntry) -> bool {
+    entry
+        .file_name()
+        .to_str()
+        .map(|s| s.starts_with("."))
+        .unwrap_or(false)
+}
+
+fn is_dir(entry: &DirEntry) -> bool {
+    entry.file_type().is_dir()
+}
+
+fn strip_path<'a>(path: &'a Path, to_strip: &Path) -> Result<&'a Path> {
+    path.strip_prefix(&to_strip).with_context(|| {
+        format!(
+            "'{}' is not under the specified home path ('{}')!",
+            path.display(),
+            to_strip.display()
+        )
+    })
+}
+
+fn path_to_str(path: &Path) -> Result<&str> {
+    path.to_str().with_context(|| {
+        format!(
+            "\
+Can't derive a keymapping from path: '{}' \
+because it can't be turned to a string
+",
+            path.display()
+        )
+    })
+}
+
+// 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!("# -------------");
+//     }
+// }