From 66f046063d6784b9f447e5d99a51bcbe23a62f7e Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 26 Sep 2024 11:29:44 +0200 Subject: [PATCH] cli: Introduce write_labeled! template formatter macro --- cli/src/cli_util.rs | 1 + cli/src/command_error.rs | 7 ++++--- cli/src/commands/operation/diff.rs | 5 +++-- cli/src/commands/status.rs | 3 ++- cli/src/commit_templater.rs | 9 +++++---- cli/src/diff_util.rs | 7 ++++--- cli/src/formatter.rs | 4 +++- cli/src/git_util.rs | 5 +++-- cli/src/templater.rs | 16 +++++++++++++--- 9 files changed, 38 insertions(+), 19 deletions(-) diff --git a/cli/src/cli_util.rs b/cli/src/cli_util.rs index c49af6b773..ebe2d61465 100644 --- a/cli/src/cli_util.rs +++ b/cli/src/cli_util.rs @@ -167,6 +167,7 @@ use crate::template_builder; use crate::template_builder::TemplateLanguage; use crate::template_parser::TemplateAliasesMap; use crate::template_parser::TemplateDiagnostics; +use crate::templater::write_labeled; use crate::templater::PropertyPlaceholder; use crate::templater::TemplateRenderer; use crate::text_util; diff --git a/cli/src/command_error.rs b/cli/src/command_error.rs index 489ad8db93..cc0bce7a61 100644 --- a/cli/src/command_error.rs +++ b/cli/src/command_error.rs @@ -65,6 +65,7 @@ use crate::merge_tools::MergeToolConfigError; use crate::revset_util::UserRevsetEvaluationError; use crate::template_parser::TemplateParseError; use crate::template_parser::TemplateParseErrorKind; +use crate::templater::write_labeled; use crate::ui::Ui; #[derive(Clone, Copy, Debug, Eq, PartialEq)] @@ -775,12 +776,12 @@ fn print_error_sources(ui: &Ui, source: Option<&dyn error::Error>) -> io::Result ui.stderr_formatter() .with_label("error_source", |formatter| { if err.source().is_none() { - write!(formatter.labeled("heading"), "Caused by: ")?; + write_labeled!(formatter, "heading", "Caused by: ")?; writeln!(formatter, "{err}")?; } else { writeln!(formatter.labeled("heading"), "Caused by:")?; for (i, err) in iter::successors(Some(err), |err| err.source()).enumerate() { - write!(formatter.labeled("heading"), "{}: ", i + 1)?; + write_labeled!(formatter, "heading", "{}: ", i + 1)?; writeln!(formatter, "{err}")?; } } @@ -791,7 +792,7 @@ fn print_error_sources(ui: &Ui, source: Option<&dyn error::Error>) -> io::Result fn print_error_hints(ui: &Ui, hints: &[ErrorHint]) -> io::Result<()> { for hint in hints { ui.stderr_formatter().with_label("hint", |formatter| { - write!(formatter.labeled("heading"), "Hint: ")?; + write_labeled!(formatter, "heading", "Hint: ")?; match hint { ErrorHint::PlainText(message) => { writeln!(formatter, "{message}")?; diff --git a/cli/src/commands/operation/diff.rs b/cli/src/commands/operation/diff.rs index 84642bfcac..ad5181b2f8 100644 --- a/cli/src/commands/operation/diff.rs +++ b/cli/src/commands/operation/diff.rs @@ -47,6 +47,7 @@ use crate::formatter::Formatter; use crate::graphlog::get_graphlog; use crate::graphlog::Edge; use crate::graphlog::GraphStyle; +use crate::templater::write_labeled; use crate::templater::TemplateRenderer; use crate::ui::Ui; @@ -384,14 +385,14 @@ fn write_modified_change_summary( ) -> Result<(), std::io::Error> { writeln!(formatter, "Change {}", short_change_hash(change_id))?; for commit in modified_change.added_commits.iter() { - formatter.with_label("diff", |formatter| write!(formatter.labeled("added"), "+"))?; + formatter.with_label("diff", |formatter| write_labeled!(formatter, "added", "+"))?; write!(formatter, " ")?; commit_summary_template.format(commit, formatter)?; writeln!(formatter)?; } for commit in modified_change.removed_commits.iter() { formatter.with_label("diff", |formatter| { - write!(formatter.labeled("removed"), "-") + write_labeled!(formatter, "removed", "-") })?; write!(formatter, " ")?; commit_summary_template.format(commit, formatter)?; diff --git a/cli/src/commands/status.rs b/cli/src/commands/status.rs index 7945294b53..bd6f57bad9 100644 --- a/cli/src/commands/status.rs +++ b/cli/src/commands/status.rs @@ -24,6 +24,7 @@ use crate::cli_util::CommandHelper; use crate::command_error::CommandError; use crate::diff_util::get_copy_records; use crate::diff_util::DiffFormat; +use crate::templater::write_labeled; use crate::ui::Ui; /// Show high-level repo status @@ -158,7 +159,7 @@ pub(crate) fn cmd_status( )?; for bookmark_name in conflicted_local_bookmarks { write!(formatter, " ")?; - write!(formatter.labeled("bookmark"), "{bookmark_name}")?; + write_labeled!(formatter, "bookmark", "{bookmark_name}")?; writeln!(formatter)?; } writeln!( diff --git a/cli/src/commit_templater.rs b/cli/src/commit_templater.rs index d52dbcd0ce..6ab3048466 100644 --- a/cli/src/commit_templater.rs +++ b/cli/src/commit_templater.rs @@ -68,6 +68,7 @@ use crate::template_parser::TemplateDiagnostics; use crate::template_parser::TemplateParseError; use crate::template_parser::TemplateParseResult; use crate::templater; +use crate::templater::write_labeled; use crate::templater::PlainTextFormattedProperty; use crate::templater::SizeHint; use crate::templater::Template; @@ -1043,10 +1044,10 @@ impl RefName { // If wrapping with Rc becomes common, add generic impl for Rc. impl Template for Rc { fn format(&self, formatter: &mut TemplateFormatter) -> io::Result<()> { - write!(formatter.labeled("name"), "{}", self.name)?; + write_labeled!(formatter, "name", "{}", self.name)?; if let Some(remote) = &self.remote { write!(formatter, "@")?; - write!(formatter.labeled("remote"), "{remote}")?; + write_labeled!(formatter, "remote", "{remote}")?; } // Don't show both conflict and unsynced sigils as conflicted ref wouldn't // be pushed. @@ -1357,8 +1358,8 @@ pub struct ShortestIdPrefix { impl Template for ShortestIdPrefix { fn format(&self, formatter: &mut TemplateFormatter) -> io::Result<()> { - write!(formatter.labeled("prefix"), "{}", self.prefix)?; - write!(formatter.labeled("rest"), "{}", self.rest)?; + write_labeled!(formatter, "prefix", "{}", self.prefix)?; + write_labeled!(formatter, "rest", "{}", self.rest)?; Ok(()) } } diff --git a/cli/src/diff_util.rs b/cli/src/diff_util.rs index 8fcae42d29..1eaa687076 100644 --- a/cli/src/diff_util.rs +++ b/cli/src/diff_util.rs @@ -69,6 +69,7 @@ use crate::merge_tools::new_utf8_temp_dir; use crate::merge_tools::DiffGenerateError; use crate::merge_tools::DiffToolMode; use crate::merge_tools::ExternalMergeTool; +use crate::templater::write_labeled; use crate::text_util; use crate::ui::Ui; @@ -584,7 +585,7 @@ fn show_color_words_line_number( ) -> io::Result<()> { if let Some(line_number) = left_line_number { formatter.with_label("removed", |formatter| { - write!(formatter.labeled("line_number"), "{line_number:>4}") + write_labeled!(formatter, "line_number", "{line_number:>4}") })?; write!(formatter, " ")?; } else { @@ -592,7 +593,7 @@ fn show_color_words_line_number( } if let Some(line_number) = right_line_number { formatter.with_label("added", |formatter| { - write!(formatter.labeled("line_number"), "{line_number:>4}",) + write_labeled!(formatter, "line_number", "{line_number:>4}",) })?; write!(formatter, ": ")?; } else { @@ -1527,7 +1528,7 @@ pub fn show_diff_stat( stat.added + stat.removed, if bar_added + bar_removed > 0 { " " } else { "" }, )?; - write!(formatter.labeled("added"), "{}", "+".repeat(bar_added))?; + write_labeled!(formatter, "added", "{}", "+".repeat(bar_added))?; writeln!(formatter.labeled("removed"), "{}", "-".repeat(bar_removed))?; } writeln!( diff --git a/cli/src/formatter.rs b/cli/src/formatter.rs index f487df84da..d54537f2f3 100644 --- a/cli/src/formatter.rs +++ b/cli/src/formatter.rs @@ -30,6 +30,8 @@ use crossterm::style::SetBackgroundColor; use crossterm::style::SetForegroundColor; use itertools::Itertools; +use crate::templater::write_labeled; + // Lets the caller label strings and translates the labels to colors pub trait Formatter: Write { /// Returns the backing `Write`. This is useful for writing data that is @@ -125,7 +127,7 @@ where pub fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> io::Result<()> { self.writer.with_labeled(|formatter| { if let Some(heading) = self.heading.take() { - write!(formatter.labeled("heading"), "{heading}")?; + write_labeled!(formatter, "heading", "{heading}")?; } formatter.write_fmt(args) }) diff --git a/cli/src/git_util.rs b/cli/src/git_util.rs index 1c98c6f5d8..0f872674fd 100644 --- a/cli/src/git_util.rs +++ b/cli/src/git_util.rs @@ -42,6 +42,7 @@ use crate::command_error::user_error; use crate::command_error::CommandError; use crate::formatter::Formatter; use crate::progress::Progress; +use crate::templater::write_labeled; use crate::ui::Ui; pub fn get_git_repo(store: &Store) -> Result { @@ -381,7 +382,7 @@ impl RefStatus { }; write!(out, "{ref_kind}")?; - write!(out.labeled("bookmark"), "{padded_ref_name}")?; + write_labeled!(out, "bookmark", "{padded_ref_name}")?; writeln!(out, " [{import_status}] {tracking_status}") } } @@ -412,7 +413,7 @@ pub fn print_failed_git_export( let mut formatter = ui.stderr_formatter(); for FailedRefExport { name, reason } in failed_refs { write!(formatter, " ")?; - write!(formatter.labeled("bookmark"), "{name}")?; + write_labeled!(formatter, "bookmark", "{name}")?; for err in iter::successors(Some(reason as &dyn error::Error), |err| err.source()) { write!(formatter, ": {err}")?; } diff --git a/cli/src/templater.rs b/cli/src/templater.rs index a8332fd9ae..4edae59a1c 100644 --- a/cli/src/templater.rs +++ b/cli/src/templater.rs @@ -28,6 +28,16 @@ use crate::formatter::LabeledWriter; use crate::formatter::PlainTextFormatter; use crate::time_util; +macro_rules! write_labeled_ { + ($formatter:expr, $label:expr, $($arg:tt)*) => { + write!( + $formatter.labeled($label), + $($arg)* + ) + }; +} +pub(crate) use write_labeled_ as write_labeled; + /// Represents printable type or compiled template containing placeholder value. pub trait Template { fn format(&self, formatter: &mut TemplateFormatter) -> io::Result<()>; @@ -68,13 +78,13 @@ impl Template for Option { impl Template for Signature { fn format(&self, formatter: &mut TemplateFormatter) -> io::Result<()> { - write!(formatter.labeled("name"), "{}", self.name)?; + write_labeled!(formatter, "name", "{}", self.name)?; if !self.name.is_empty() && !self.email.is_empty() { write!(formatter, " ")?; } if !self.email.is_empty() { write!(formatter, "<")?; - write!(formatter.labeled("email"), "{}", self.email)?; + write_labeled!(formatter, "email", "{}", self.email)?; write!(formatter, ">")?; } Ok(()) @@ -797,7 +807,7 @@ fn format_property_error_inline( let TemplatePropertyError(err) = &err; formatter.with_label("error", |formatter| { write!(formatter, "<")?; - write!(formatter.labeled("heading"), "Error: ")?; + write_labeled!(formatter, "heading", "Error: ")?; write!(formatter, "{err}")?; for err in iter::successors(err.source(), |err| err.source()) { write!(formatter, ": {err}")?;