cli: let graphlog provide a default node symbol

I'm about to make the default (non-working-copy) node symbol be a
unicode symbol, but we only want that when using a unicode graph, so
users with a terminal that doesn't support unicode can get plain ASCII
output by setting e.g. `ui.graph.style = "ascii"`.
This commit is contained in:
Martin von Zweigbergk 2023-03-10 23:10:31 -08:00 committed by Martin von Zweigbergk
parent cb86efac61
commit 82101bc7e0
3 changed files with 31 additions and 9 deletions

View file

@ -1484,6 +1484,7 @@ fn cmd_log(ui: &mut Ui, command: &CommandHelper, args: &LogArgs) -> Result<(), C
if !args.no_graph { if !args.no_graph {
let mut graph = get_graphlog(command.settings(), formatter.raw()); let mut graph = get_graphlog(command.settings(), formatter.raw());
let default_node_symbol = graph.default_node_symbol().to_owned();
let iter: Box<dyn Iterator<Item = (IndexEntry, Vec<RevsetGraphEdge>)>> = let iter: Box<dyn Iterator<Item = (IndexEntry, Vec<RevsetGraphEdge>)>> =
if args.reversed { if args.reversed {
Box::new(RevsetGraphIterator::new(revset.as_ref()).reversed()) Box::new(RevsetGraphIterator::new(revset.as_ref()).reversed())
@ -1538,7 +1539,7 @@ fn cmd_log(ui: &mut Ui, command: &CommandHelper, args: &LogArgs) -> Result<(), C
let node_symbol = if Some(&commit_id) == wc_commit_id { let node_symbol = if Some(&commit_id) == wc_commit_id {
"@" "@"
} else { } else {
"o" &default_node_symbol
}; };
graph.add_node( graph.add_node(
@ -1624,6 +1625,7 @@ fn cmd_obslog(ui: &mut Ui, command: &CommandHelper, args: &ObslogArgs) -> Result
); );
if !args.no_graph { if !args.no_graph {
let mut graph = get_graphlog(command.settings(), formatter.raw()); let mut graph = get_graphlog(command.settings(), formatter.raw());
let default_node_symbol = graph.default_node_symbol().to_owned();
for commit in commits { for commit in commits {
let mut edges = vec![]; let mut edges = vec![];
for predecessor in &commit.predecessors() { for predecessor in &commit.predecessors() {
@ -1650,7 +1652,7 @@ fn cmd_obslog(ui: &mut Ui, command: &CommandHelper, args: &ObslogArgs) -> Result
let node_symbol = if Some(commit.id()) == wc_commit_id { let node_symbol = if Some(commit.id()) == wc_commit_id {
"@" "@"
} else { } else {
"o" &default_node_symbol
}; };
graph.add_node( graph.add_node(
commit.id(), commit.id(),

View file

@ -69,6 +69,7 @@ fn cmd_op_log(
let mut formatter = ui.stdout_formatter(); let mut formatter = ui.stdout_formatter();
let formatter = formatter.as_mut(); let formatter = formatter.as_mut();
let mut graph = get_graphlog(command.settings(), formatter.raw()); let mut graph = get_graphlog(command.settings(), formatter.raw());
let default_node_symbol = graph.default_node_symbol().to_owned();
for op in topo_order_reverse( for op in topo_order_reverse(
vec![head_op], vec![head_op],
Box::new(|op: &Operation| op.id().clone()), Box::new(|op: &Operation| op.id().clone()),
@ -88,7 +89,11 @@ fn cmd_op_log(
if !buffer.ends_with(b"\n") { if !buffer.ends_with(b"\n") {
buffer.push(b'\n'); buffer.push(b'\n');
} }
let node_symbol = if is_head_op { "@" } else { "o" }; let node_symbol = if is_head_op {
"@"
} else {
&default_node_symbol
};
graph.add_node( graph.add_node(
op.id(), op.id(),
&edges, &edges,

View file

@ -56,12 +56,15 @@ pub trait GraphLog<K: Clone + Eq + Hash> {
text: &str, text: &str,
) -> io::Result<()>; ) -> io::Result<()>;
fn default_node_symbol(&self) -> &str;
fn width(&self, id: &K, edges: &[Edge<K>]) -> usize; fn width(&self, id: &K, edges: &[Edge<K>]) -> usize;
} }
pub struct SaplingGraphLog<'writer, R> { pub struct SaplingGraphLog<'writer, R> {
renderer: R, renderer: R,
writer: &'writer mut dyn Write, writer: &'writer mut dyn Write,
default_node_symbol: String,
} }
impl<K: Clone> From<&Edge<K>> for Ancestor<K> { impl<K: Clone> From<&Edge<K>> for Ancestor<K> {
@ -99,6 +102,10 @@ where
write!(self.writer, "{row}") write!(self.writer, "{row}")
} }
fn default_node_symbol(&self) -> &str {
&self.default_node_symbol
}
fn width(&self, id: &K, edges: &[Edge<K>]) -> usize { fn width(&self, id: &K, edges: &[Edge<K>]) -> usize {
let parents = edges.iter().map_into().collect(); let parents = edges.iter().map_into().collect();
let w: u64 = self.renderer.width(Some(id), Some(&parents)); let w: u64 = self.renderer.width(Some(id), Some(&parents));
@ -110,6 +117,7 @@ impl<'writer, R> SaplingGraphLog<'writer, R> {
pub fn create<K>( pub fn create<K>(
renderer: R, renderer: R,
formatter: &'writer mut dyn Write, formatter: &'writer mut dyn Write,
default_node_symbol: &str,
) -> Box<dyn GraphLog<K> + 'writer> ) -> Box<dyn GraphLog<K> + 'writer>
where where
K: Clone + Eq + Hash + 'writer, K: Clone + Eq + Hash + 'writer,
@ -118,6 +126,7 @@ impl<'writer, R> SaplingGraphLog<'writer, R> {
Box::new(SaplingGraphLog { Box::new(SaplingGraphLog {
renderer, renderer,
writer: formatter, writer: formatter,
default_node_symbol: default_node_symbol.to_owned(),
}) })
} }
} }
@ -129,12 +138,14 @@ pub fn get_graphlog<'a, K: Clone + Eq + Hash + 'a>(
let builder = GraphRowRenderer::new().output().with_min_row_height(0); let builder = GraphRowRenderer::new().output().with_min_row_height(0);
match settings.graph_style().as_str() { match settings.graph_style().as_str() {
"curved" => SaplingGraphLog::create(builder.build_box_drawing(), formatter), "curved" => SaplingGraphLog::create(builder.build_box_drawing(), formatter, "o"),
"square" => { "square" => SaplingGraphLog::create(
SaplingGraphLog::create(builder.build_box_drawing().with_square_glyphs(), formatter) builder.build_box_drawing().with_square_glyphs(),
} formatter,
"ascii" => SaplingGraphLog::create(builder.build_ascii(), formatter), "o",
"ascii-large" => SaplingGraphLog::create(builder.build_ascii_large(), formatter), ),
"ascii" => SaplingGraphLog::create(builder.build_ascii(), formatter, "o"),
"ascii-large" => SaplingGraphLog::create(builder.build_ascii_large(), formatter, "o"),
_ => Box::new(AsciiGraphDrawer::new(formatter)), _ => Box::new(AsciiGraphDrawer::new(formatter)),
} }
} }
@ -290,6 +301,10 @@ impl<'writer, K: Clone + Eq + Hash> GraphLog<K> for AsciiGraphDrawer<'writer, K>
Ok(()) Ok(())
} }
fn default_node_symbol(&self) -> &str {
"o"
}
fn width(&self, id: &K, edges: &[Edge<K>]) -> usize { fn width(&self, id: &K, edges: &[Edge<K>]) -> usize {
let orig = self.edges.len() - usize::from(self.index_by_target(id).is_some()); let orig = self.edges.len() - usize::from(self.index_by_target(id).is_some());
let added = cmp::max(edges.len(), 1); let added = cmp::max(edges.len(), 1);