forked from mirrors/jj
cli: make log word-wrapping helper calculate width eagerly
Multiple graphs will be nested in "op log" output, and things would be messy if we had to calculate graph widths lazily. Let's simply make LogContentFormat track the current available width no matter if ui.log-word-wrap is off.
This commit is contained in:
parent
d9c68e08b1
commit
6154827129
5 changed files with 58 additions and 70 deletions
|
@ -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<Self, config::ConfigError> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(),
|
||||
)?;
|
||||
}
|
||||
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue