diff --git a/src/lib.rs b/src/lib.rs index 884e616731..cfc3fd6873 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -70,6 +70,7 @@ pub(crate) use { lexer::Lexer, line::Line, list::List, + list_entry::ListEntry, list_feature::ListFeature, list_operator::ListOperator, load_dotenv::load_dotenv, @@ -153,7 +154,7 @@ pub(crate) use { sha2::{Digest, Sha256}, snafu::{ResultExt, Snafu}, std::{ - borrow::{Borrow, Cow}, + borrow::Borrow, cmp::Ordering, collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map}, env::{self, VarError}, @@ -182,7 +183,10 @@ pub(crate) use { }; #[cfg(test)] -pub(crate) use crate::{node::Node, tree::Tree}; +pub(crate) use { + crate::{node::Node, tree::Tree}, + std::borrow::Cow, +}; pub use crate::run::run; @@ -288,6 +292,7 @@ mod layer; mod lexer; mod line; mod list; +mod list_entry; mod list_feature; mod list_operator; mod load_dotenv; diff --git a/src/list_entry.rs b/src/list_entry.rs new file mode 100644 index 0000000000..d922ba670d --- /dev/null +++ b/src/list_entry.rs @@ -0,0 +1,9 @@ +use super::*; + +#[derive(Clone)] +pub(crate) struct ListEntry<'a> { + pub(crate) aliases: &'a [&'a str], + pub(crate) comment: Option, + pub(crate) name: &'a str, + pub(crate) recipe: &'a Recipe<'a>, +} diff --git a/src/subcommand.rs b/src/subcommand.rs index 98a8faae2c..e8190b18d6 100644 --- a/src/subcommand.rs +++ b/src/subcommand.rs @@ -766,19 +766,47 @@ impl Subcommand { print!("{}", config.list_heading); } - let recipe_groups = { - let mut recipe_groups = BTreeMap::, Vec<&Recipe>>::new(); + let entry_groups = { + let mut entry_groups = BTreeMap::, Vec>::new(); + for recipe in module.public_recipes(config) { - let recipe_groups_list = recipe.groups(); - if recipe_groups_list.is_empty() { - recipe_groups.entry(None).or_default().push(recipe); + let recipe_aliases = aliases + .get(recipe.name()) + .map(Vec::as_slice) + .unwrap_or_default(); + + let mut entries = vec![ListEntry { + aliases: recipe_aliases, + comment: recipe.doc().map(Into::into), + name: recipe.name(), + recipe, + }]; + + if config.alias_style == AliasStyle::Separate { + for name in recipe_aliases { + entries.push(ListEntry { + aliases: recipe_aliases, + comment: Some(format!("alias for `{}`", recipe.name)), + name, + recipe, + }); + } + } + + let groups = recipe.groups(); + if groups.is_empty() { + entry_groups.entry(None).or_default().extend(entries); } else { - for group in recipe_groups_list { - recipe_groups.entry(Some(group)).or_default().push(recipe); + for group in groups { + entry_groups + .entry(Some(group)) + .or_default() + .extend(entries.clone()); } } } - recipe_groups + + entry_groups }; let submodule_groups = { @@ -814,7 +842,7 @@ impl Subcommand { }; if groups.is_empty() - && (recipe_groups.contains_key(&None) || submodule_groups.contains_key(&None)) + && (entry_groups.contains_key(&None) || submodule_groups.contains_key(&None)) { ordered_groups.insert(0, None); } @@ -836,56 +864,43 @@ impl Subcommand { ); } - if let Some(recipes) = recipe_groups.get(&group) { - for recipe in recipes { - let recipe_alias_entries = if config.alias_style == AliasStyle::Separate { - aliases.get(recipe.name()) - } else { - None - }; + if let Some(entries) = entry_groups.get(&group) { + for entry in entries { + let inline_comment = signature_widths[entry.name] <= MAX_WIDTH + && entry + .comment + .as_ref() + .is_none_or(|doc| doc.lines().count() <= 1); - for (i, name) in iter::once(&recipe.name()) - .chain(recipe_alias_entries.unwrap_or(&Vec::new())) - .enumerate() + if let Some(comment) = &entry.comment + && !inline_comment { - let doc = if i == 0 { - recipe.doc().map(Cow::Borrowed) - } else { - Some(Cow::Owned(format!("alias for `{}`", recipe.name))) - }; - - let inline_doc = signature_widths[name] <= MAX_WIDTH - && doc.as_ref().is_none_or(|doc| doc.lines().count() <= 1); - - if let Some(doc) = &doc - && !inline_doc - { - for line in doc.lines() { - println!( - "{list_prefix}{} {}", - config.color.stdout().doc().paint("#"), - config.color.stdout().doc().paint(line), - ); - } + for line in comment.lines() { + println!( + "{list_prefix}{} {}", + config.color.stdout().doc().paint("#"), + config.color.stdout().doc().paint(line), + ); } + } - print!( - "{list_prefix}{}", - RecipeSignature { name, recipe }.color_display(config.color.stdout()) - ); + print!( + "{list_prefix}{}", + RecipeSignature { + name: entry.name, + recipe: entry.recipe + } + .color_display(config.color.stdout()) + ); - print_doc_and_aliases( - config, - name, - doc.filter(|_| inline_doc).as_deref(), - aliases - .get(recipe.name()) - .map(Vec::as_slice) - .unwrap_or_default(), - max_signature_width, - &signature_widths, - ); - } + print_doc_and_aliases( + config, + entry.name, + entry.comment.as_deref().filter(|_| inline_comment), + entry.aliases, + max_signature_width, + &signature_widths, + ); } }