diff --git a/cli/src/cli_util.rs b/cli/src/cli_util.rs index 3d49b51d5..b995963b0 100644 --- a/cli/src/cli_util.rs +++ b/cli/src/cli_util.rs @@ -2330,47 +2330,46 @@ fn load_template_aliases( /// Helper to reformat content of log-like commands. #[derive(Clone, Debug)] -pub enum LogContentFormat { - NoWrap, - Wrap { term_width: usize }, +pub struct LogContentFormat { + width: usize, + word_wrap: bool, } impl LogContentFormat { + /// Creates new formatting helper for the terminal. pub fn new(ui: &Ui, settings: &UserSettings) -> Result { - if settings.config().get_bool("ui.log-word-wrap")? { - let term_width = ui.term_width(); - Ok(LogContentFormat::Wrap { term_width }) - } else { - Ok(LogContentFormat::NoWrap) + Ok(LogContentFormat { + width: ui.term_width(), + word_wrap: settings.config().get_bool("ui.log-word-wrap")?, + }) + } + + /// Subtracts the given `width` and returns new formatting helper. + #[must_use] + pub fn sub_width(&self, width: usize) -> Self { + LogContentFormat { + width: self.width.saturating_sub(width), + word_wrap: self.word_wrap, } } + /// Current width available to content. + pub fn width(&self) -> usize { + self.width + } + + /// Writes content which will optionally be wrapped at the current width. pub fn write( &self, formatter: &mut dyn Formatter, content_fn: impl FnOnce(&mut dyn Formatter) -> std::io::Result<()>, ) -> std::io::Result<()> { - self.write_graph_text(formatter, content_fn, || 0) - } - - pub fn write_graph_text( - &self, - formatter: &mut dyn Formatter, - content_fn: impl FnOnce(&mut dyn Formatter) -> std::io::Result<()>, - graph_width_fn: impl FnOnce() -> usize, - ) -> std::io::Result<()> { - match self { - LogContentFormat::NoWrap => content_fn(formatter), - LogContentFormat::Wrap { term_width } => { - let mut recorder = FormatRecorder::new(); - content_fn(&mut recorder)?; - text_util::write_wrapped( - formatter, - &recorder, - term_width.saturating_sub(graph_width_fn()), - )?; - Ok(()) - } + if self.word_wrap { + let mut recorder = FormatRecorder::new(); + content_fn(&mut recorder)?; + text_util::write_wrapped(formatter, &recorder, self.width) + } else { + content_fn(formatter) } } } diff --git a/cli/src/commands/evolog.rs b/cli/src/commands/evolog.rs index 59892cd6f..b60c452b4 100644 --- a/cli/src/commands/evolog.rs +++ b/cli/src/commands/evolog.rs @@ -147,27 +147,24 @@ pub(crate) fn cmd_evolog( .iter() .map(|id| Edge::Direct(id.clone())) .collect_vec(); - let graph_width = || graph.width(commit.id(), &edges); let mut buffer = vec![]; - with_content_format.write_graph_text( - ui.new_formatter(&mut buffer).as_mut(), - |formatter| template.format(&commit, formatter), - graph_width, - )?; + let within_graph = with_content_format.sub_width(graph.width(commit.id(), &edges)); + within_graph.write(ui.new_formatter(&mut buffer).as_mut(), |formatter| { + template.format(&commit, formatter) + })?; if !buffer.ends_with(b"\n") { buffer.push(b'\n'); } if let Some(renderer) = &diff_renderer { let predecessors: Vec<_> = commit.predecessors().try_collect()?; let mut formatter = ui.new_formatter(&mut buffer); - let width = usize::saturating_sub(ui.term_width(), graph_width()); renderer.show_inter_diff( ui, formatter.as_mut(), &predecessors, &commit, &EverythingMatcher, - width, + within_graph.width(), )?; } let node_symbol = format_template(ui, &Some(commit.clone()), &node_template); diff --git a/cli/src/commands/log.rs b/cli/src/commands/log.rs index f09a840b9..f7cdca960 100644 --- a/cli/src/commands/log.rs +++ b/cli/src/commands/log.rs @@ -205,24 +205,22 @@ pub(crate) fn cmd_log( let mut buffer = vec![]; let key = (commit_id, false); let commit = store.get_commit(&key.0)?; - let graph_width = || graph.width(&key, &graphlog_edges); - with_content_format.write_graph_text( - ui.new_formatter(&mut buffer).as_mut(), - |formatter| template.format(&commit, formatter), - graph_width, - )?; + let within_graph = + with_content_format.sub_width(graph.width(&key, &graphlog_edges)); + within_graph.write(ui.new_formatter(&mut buffer).as_mut(), |formatter| { + template.format(&commit, formatter) + })?; if !buffer.ends_with(b"\n") { buffer.push(b'\n'); } if let Some(renderer) = &diff_renderer { let mut formatter = ui.new_formatter(&mut buffer); - let width = usize::saturating_sub(ui.term_width(), graph_width()); renderer.show_patch( ui, formatter.as_mut(), &commit, matcher.as_ref(), - width, + within_graph.width(), )?; } @@ -238,11 +236,11 @@ pub(crate) fn cmd_log( let real_key = (elided_key.0.clone(), false); let edges = [Edge::Direct(real_key)]; let mut buffer = vec![]; - with_content_format.write_graph_text( - ui.new_formatter(&mut buffer).as_mut(), - |formatter| writeln!(formatter.labeled("elided"), "(elided revisions)"), - || graph.width(&elided_key, &edges), - )?; + let within_graph = + with_content_format.sub_width(graph.width(&elided_key, &edges)); + within_graph.write(ui.new_formatter(&mut buffer).as_mut(), |formatter| { + writeln!(formatter.labeled("elided"), "(elided revisions)") + })?; let node_symbol = format_template(ui, &None, &node_template); graph.add_node( &elided_key, diff --git a/cli/src/commands/operation/diff.rs b/cli/src/commands/operation/diff.rs index a181f67a3..daf2e6c5f 100644 --- a/cli/src/commands/operation/diff.rs +++ b/cli/src/commands/operation/diff.rs @@ -244,33 +244,28 @@ pub fn show_op_diff( .iter() .map(|edge| Edge::Direct(edge.target.clone())) .collect_vec(); - let graph_width = || graph.width(&change_id, &edges); let mut buffer = vec![]; - with_content_format.write_graph_text( - ui.new_formatter(&mut buffer).as_mut(), - |formatter| { - write_modified_change_summary( - formatter, - commit_summary_template, - &change_id, - modified_change, - ) - }, - graph_width, - )?; + let within_graph = with_content_format.sub_width(graph.width(&change_id, &edges)); + within_graph.write(ui.new_formatter(&mut buffer).as_mut(), |formatter| { + write_modified_change_summary( + formatter, + commit_summary_template, + &change_id, + modified_change, + ) + })?; if !buffer.ends_with(b"\n") { buffer.push(b'\n'); } if let Some(diff_renderer) = &diff_renderer { let mut formatter = ui.new_formatter(&mut buffer); - let width = usize::saturating_sub(ui.term_width(), graph_width()); show_change_diff( ui, formatter.as_mut(), diff_renderer, modified_change, - width, + within_graph.width(), )?; } diff --git a/cli/src/commands/operation/log.rs b/cli/src/commands/operation/log.rs index a1d47ed5b..6050d44e0 100644 --- a/cli/src/commands/operation/log.rs +++ b/cli/src/commands/operation/log.rs @@ -134,11 +134,10 @@ fn do_op_log( edges.push(Edge::Direct(id.clone())); } let mut buffer = vec![]; - with_content_format.write_graph_text( - ui.new_formatter(&mut buffer).as_mut(), - |formatter| template.format(&op, formatter), - || graph.width(op.id(), &edges), - )?; + let within_graph = with_content_format.sub_width(graph.width(op.id(), &edges)); + within_graph.write(ui.new_formatter(&mut buffer).as_mut(), |formatter| { + template.format(&op, formatter) + })?; if !buffer.ends_with(b"\n") { buffer.push(b'\n'); }