From 0e1363d4b4d3bd4b8b66f7f7c64053cf77ed8125 Mon Sep 17 00:00:00 2001 From: Dlurak <84224239+Dlurak@users.noreply.github.com> Date: Wed, 21 Aug 2024 19:02:30 +0200 Subject: [PATCH] Add a global list command --- src/cli/list.rs | 13 +++++++++++++ src/cli/mod.rs | 10 ++++++---- src/commands/directory.rs | 36 ++++++++++++++++-------------------- src/commands/list.rs | 20 ++++++++++++++++++++ src/commands/mod.rs | 1 + src/directories.rs | 19 ++++++------------- src/helpers.rs | 7 +++++++ src/main.rs | 1 + 8 files changed, 70 insertions(+), 37 deletions(-) create mode 100644 src/cli/list.rs create mode 100644 src/commands/list.rs diff --git a/src/cli/list.rs b/src/cli/list.rs new file mode 100644 index 0000000..c668a78 --- /dev/null +++ b/src/cli/list.rs @@ -0,0 +1,13 @@ +use clap::Parser; + +#[derive(Parser, Debug)] +pub struct ListCli { + #[arg(long = "format-project", short = 'p', alias = "fmt-proj")] + pub format_project: Option, + + #[arg(long = "format-template", short = 't', alias = "fmt-temp")] + pub format_template: Option, + + #[arg(long = "format-directory", short = 'd', alias = "fmt-dir")] + pub format_directory: Option, +} diff --git a/src/cli/mod.rs b/src/cli/mod.rs index f364847..147b673 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -1,8 +1,8 @@ pub mod directory; +pub mod list; pub mod project; pub mod template; -use self::{directory::DirectoryCli, project::ProjectCli, template::TemplateCli}; use clap::{Parser, Subcommand}; /// A CLI for tmux session management @@ -23,13 +23,15 @@ pub enum Commands { /// /// This command provides functionalities to interact with tmux sessions based on directories. #[command(alias = "dir", alias = "dirs", alias = "directories")] - Directory(DirectoryCli), + Directory(directory::DirectoryCli), /// Manage templates in the context of muxmate and tmux /// /// This command provides functionalities to interact with tmux sessions based on templates #[command(alias = "temp", alias = "templ")] - Template(TemplateCli), + Template(template::TemplateCli), #[command(alias = "proj", alias = "projects")] - Project(ProjectCli), + Project(project::ProjectCli), + + List(list::ListCli), } diff --git a/src/commands/directory.rs b/src/commands/directory.rs index 985ac91..3a90dc7 100644 --- a/src/commands/directory.rs +++ b/src/commands/directory.rs @@ -4,9 +4,9 @@ use crate::{ directories::{self, Directory}, helpers::{absolute_path, dir_name, Exit}, tmux::{attach, session_exists}, - widgets::{heading::Heading, table::Table}, + widgets::table::Table, }; -use std::{collections::HashMap, path::PathBuf}; +use std::path::PathBuf; use tmux_interface::{NewSession, Tmux}; pub fn directory_handler(args: DirectoryCli) { @@ -17,31 +17,28 @@ pub fn directory_handler(args: DirectoryCli) { } fn list_handler(args: ListDirectoryArgs) { - let config = directories::parse_directory_config(); - let categories = config.categories; + let dirs = directories::parse_directory_config(); if args.minimal { - println!("{}", format_categories_minimal(&categories)); + println!("{}", format_dirs_minimal(dirs)); return; } - for (key, value) in categories { - println!("{}", Heading(key)); - println!("{}", Table::from_iter(value.iter())); - } + let tables = dirs.into_iter().map(Table::from); + let table: Table<_, _> = tables.collect(); + println!("{}", table); } -fn format_categories_minimal(categories: &HashMap>) -> String { - let categories_formatted: Vec<_> = categories - .iter() - .map(move |(key, dirs)| { - let dirs_formatted: Vec<_> = dirs.iter().map(|x| x.to_string()).collect(); - let dirs = dirs_formatted.join("\n"); - format!("{}\n{}", key, dirs) +fn format_dirs_minimal(dirs: Vec) -> String { + let dirs_formatted: Vec<_> = dirs + .into_iter() + .map(|dir| { + let name = dir.name.unwrap_or("No name".to_string()); + format!("\"{}\" {}", name, dir.path.display()) }) .collect(); - categories_formatted.join("\n\n") + dirs_formatted.join("\n") } fn start_handler(args: StartDirectoryArgs) { @@ -66,9 +63,8 @@ fn start_handler(args: StartDirectoryArgs) { } fn resolve_dir_path(cli_args: &StartDirectoryArgs) -> (String, PathBuf) { - let config = directories::parse_directory_config(); - let dirs: Vec<_> = config.categories.values().flatten().collect(); - let dir = dirs.iter().find(|&&d| d.get_name() == cli_args.directory); + let dirs = directories::parse_directory_config(); + let dir = dirs.iter().find(|d| d.get_name() == cli_args.directory); let user_name = cli_args.name.clone(); match dir { diff --git a/src/commands/list.rs b/src/commands/list.rs new file mode 100644 index 0000000..a3acc1b --- /dev/null +++ b/src/commands/list.rs @@ -0,0 +1,20 @@ +use crate::{cli::list::ListCli, directories, helpers::format_name, projects, templates}; + +pub fn list_handler(args: ListCli) { + let projects = projects::parse_project_config(); + let templates = templates::parse_template_config(); + let dirs = directories::parse_directory_config(); + + for i in projects { + println!("{}", format_name(&args.format_project, &i.name)); + } + for i in templates.into_iter().filter(|x| !x.hidden.unwrap_or(false)) { + println!("{}", format_name(&args.format_template, &i.name)); + } + + for i in dirs { + if let Some(name) = &i.name { + println!("{}", format_name(&args.format_directory, name)); + } + } +} diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 91b9a7c..17e0f6f 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -1,4 +1,5 @@ pub mod directory; pub mod init; +pub mod list; pub mod project; pub mod template; diff --git a/src/directories.rs b/src/directories.rs index b166451..178e24b 100644 --- a/src/directories.rs +++ b/src/directories.rs @@ -3,7 +3,7 @@ use crate::{ widgets::table::Table, }; use serde::Deserialize; -use std::{collections::HashMap, fmt, fs}; +use std::{fmt, fs}; #[derive(Debug, Deserialize)] pub struct Directory { @@ -34,8 +34,8 @@ impl fmt::Display for Directory { } } -impl From<&Directory> for Table { - fn from(value: &Directory) -> Self { +impl From for Table { + fn from(value: Directory) -> Self { let first_col = match (&value.icon, &value.name) { (Some(icon), Some(name)) => format!("{} {}", icon, name), (Some(icon), None) => icon.clone(), @@ -47,17 +47,10 @@ impl From<&Directory> for Table { } } -#[derive(Debug, Deserialize)] -pub struct Categories { - #[serde(flatten)] - pub categories: HashMap>, -} - -pub fn parse_directory_config() -> Categories { +pub fn parse_directory_config() -> Vec { let yaml_content = fs::read_to_string(get_config_dir().join("directories.yaml")) .exit(1, "Can't read directories config"); - let categories: Categories = serde_yaml::from_str(&yaml_content) - .exit(1, "Can't parse the directories config, please correct it"); - categories + serde_yaml::from_str(&yaml_content) + .exit(1, "Can't parse the directories config, please correct it") } diff --git a/src/helpers.rs b/src/helpers.rs index d8069e5..25fecda 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -64,6 +64,13 @@ pub fn dir_name(path: &Path) -> String { .unwrap_or("".to_string()) } +pub fn format_name(user_fmt: &Option, name: &str) -> String { + match user_fmt { + Some(fmt) => fmt.replace("{}", name), + None => name.to_string(), + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/main.rs b/src/main.rs index a810b9d..dd15825 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,5 +19,6 @@ fn main() { cli::Commands::Directory(args) => commands::directory::directory_handler(args), cli::Commands::Template(args) => commands::template::template_handler(args), cli::Commands::Project(args) => commands::project::project_handler(args), + cli::Commands::List(args) => commands::list::list_handler(args), } }