# HG changeset patch # User Dirkjan Ochtman # Date 2009-08-20 06:49:01 # Node ID 571a7acb45442992b10f43d9bea3d131242acd4d # Parent b360addfbe0e4f0eee538c7bbc559adf9455f590 graphlog: simplify ascii drawing to process one cset at a time diff --git a/hgext/graphlog.py b/hgext/graphlog.py --- a/hgext/graphlog.py +++ b/hgext/graphlog.py @@ -100,11 +100,13 @@ def get_padding_line(ni, n_columns, edge line.extend(["|", " "] * (n_columns - ni - 1)) return line -def ascii(ui, dag): +def ascii(ui, base, type, char, text, coldata): """prints an ASCII graph of the DAG - dag is a generator that emits tuples with the following elements: + takes the following arguments (one call per node in the graph): + - ui to write to + - A list we can keep the needed state in - Column of the current node in the set of ongoing edges. - Type indicator of node data == ASCIIDATA. - Payload: (char, lines): @@ -119,89 +121,86 @@ def ascii(ui, dag): 0 means no columns added or removed; 1 means one column added. """ - base = [0, 0] - for idx, type, (char, text), edges, ncols, coldiff in dag: - - assert -2 < coldiff < 2 - if coldiff == -1: - # Transform - # - # | | | | | | - # o | | into o---+ - # |X / |/ / - # | | | | - fix_long_right_edges(edges) - - # add_padding_line says whether to rewrite + idx, edges, ncols, coldiff = coldata + assert -2 < coldiff < 2 + if coldiff == -1: + # Transform # - # | | | | | | | | - # | o---+ into | o---+ - # | / / | | | # <--- padding line - # o | | | / / - # o | | - add_padding_line = (len(text) > 2 and - coldiff == -1 and - [x for (x, y) in edges if x + 1 < y]) + # | | | | | | + # o | | into o---+ + # |X / |/ / + # | | | | + fix_long_right_edges(edges) + + # add_padding_line says whether to rewrite + # + # | | | | | | | | + # | o---+ into | o---+ + # | / / | | | # <--- padding line + # o | | | / / + # o | | + add_padding_line = (len(text) > 2 and coldiff == -1 and + [x for (x, y) in edges if x + 1 < y]) - # fix_nodeline_tail says whether to rewrite - # - # | | o | | | | o | | - # | | |/ / | | |/ / - # | o | | into | o / / # <--- fixed nodeline tail - # | |/ / | |/ / - # o | | o | | - fix_nodeline_tail = len(text) <= 2 and not add_padding_line + # fix_nodeline_tail says whether to rewrite + # + # | | o | | | | o | | + # | | |/ / | | |/ / + # | o | | into | o / / # <--- fixed nodeline tail + # | |/ / | |/ / + # o | | o | | + fix_nodeline_tail = len(text) <= 2 and not add_padding_line - # nodeline is the line containing the node character (typically o) - nodeline = ["|", " "] * idx - nodeline.extend([char, " "]) + # nodeline is the line containing the node character (typically o) + nodeline = ["|", " "] * idx + nodeline.extend([char, " "]) - nodeline.extend( - get_nodeline_edges_tail(idx, base[1], ncols, coldiff, - base[0], fix_nodeline_tail)) + nodeline.extend( + get_nodeline_edges_tail(idx, base[1], ncols, coldiff, + base[0], fix_nodeline_tail)) - # shift_interline is the line containing the non-vertical - # edges between this entry and the next - shift_interline = ["|", " "] * idx - if coldiff == -1: - n_spaces = 1 - edge_ch = "/" - elif coldiff == 0: - n_spaces = 2 - edge_ch = "|" - else: - n_spaces = 3 - edge_ch = "\\" - shift_interline.extend(n_spaces * [" "]) - shift_interline.extend([edge_ch, " "] * (ncols - idx - 1)) + # shift_interline is the line containing the non-vertical + # edges between this entry and the next + shift_interline = ["|", " "] * idx + if coldiff == -1: + n_spaces = 1 + edge_ch = "/" + elif coldiff == 0: + n_spaces = 2 + edge_ch = "|" + else: + n_spaces = 3 + edge_ch = "\\" + shift_interline.extend(n_spaces * [" "]) + shift_interline.extend([edge_ch, " "] * (ncols - idx - 1)) - # draw edges from the current node to its parents - draw_edges(edges, nodeline, shift_interline) + # draw edges from the current node to its parents + draw_edges(edges, nodeline, shift_interline) - # lines is the list of all graph lines to print - lines = [nodeline] - if add_padding_line: - lines.append(get_padding_line(idx, ncols, edges)) - lines.append(shift_interline) + # lines is the list of all graph lines to print + lines = [nodeline] + if add_padding_line: + lines.append(get_padding_line(idx, ncols, edges)) + lines.append(shift_interline) - # make sure that there are as many graph lines as there are - # log strings - while len(text) < len(lines): - text.append("") - if len(lines) < len(text): - extra_interline = ["|", " "] * (ncols + coldiff) - while len(lines) < len(text): - lines.append(extra_interline) + # make sure that there are as many graph lines as there are + # log strings + while len(text) < len(lines): + text.append("") + if len(lines) < len(text): + extra_interline = ["|", " "] * (ncols + coldiff) + while len(lines) < len(text): + lines.append(extra_interline) - # print lines - indentation_level = max(ncols, ncols + coldiff) - for (line, logstr) in zip(lines, text): - ln = "%-*s %s" % (2 * indentation_level, "".join(line), logstr) - ui.write(ln.rstrip() + '\n') + # print lines + indentation_level = max(ncols, ncols + coldiff) + for (line, logstr) in zip(lines, text): + ln = "%-*s %s" % (2 * indentation_level, "".join(line), logstr) + ui.write(ln.rstrip() + '\n') - # ... and start over - base[0] = coldiff - base[1] = idx + # ... and start over + base[0] = coldiff + base[1] = idx def get_revs(repo, rev_opt): if rev_opt: @@ -217,14 +216,13 @@ def check_unsupported_flags(opts): if op in opts and opts[op]: raise util.Abort(_("--graph option is incompatible with --%s") % op) -def generate(dag, displayer, showparents, edgefn): - seen = [] +def generate(ui, dag, displayer, showparents, edgefn): + seen, base = [], [0, 0] for rev, type, ctx, parents in dag: char = ctx.node() in showparents and '@' or 'o' displayer.show(ctx) lines = displayer.hunk.pop(rev).split('\n')[:-1] - cols = edgefn(seen, rev, parents) - yield cols[0], type, (char, lines), cols[1], cols[2], cols[3] + ascii(ui, base, type, char, lines, edgefn(seen, rev, parents)) def graphlog(ui, repo, path=None, **opts): """show revision history alongside an ASCII revision graph @@ -252,8 +250,7 @@ def graphlog(ui, repo, path=None, **opts displayer = show_changeset(ui, repo, opts, buffered=True) showparents = [ctx.node() for ctx in repo[None].parents()] - gen = generate(revdag, displayer, showparents, asciiedges) - ascii(ui, gen) + generate(ui, revdag, displayer, showparents, asciiedges) def graphrevs(repo, nodes, opts): limit = cmdutil.loglimit(opts) @@ -289,8 +286,7 @@ def goutgoing(ui, repo, dest=None, **opt revdag = graphrevs(repo, o, opts) displayer = show_changeset(ui, repo, opts, buffered=True) showparents = [ctx.node() for ctx in repo[None].parents()] - gen = generate(revdag, displayer, showparents, asciiedges) - ascii(ui, gen) + generate(ui, revdag, displayer, showparents, asciiedges) def gincoming(ui, repo, source="default", **opts): """show the incoming changesets alongside an ASCII revision graph @@ -340,8 +336,7 @@ def gincoming(ui, repo, source="default" revdag = graphrevs(other, chlist, opts) displayer = show_changeset(ui, other, opts, buffered=True) showparents = [ctx.node() for ctx in repo[None].parents()] - gen = generate(revdag, displayer, showparents, asciiedges) - ascii(ui, gen) + generate(ui, revdag, displayer, showparents, asciiedges) finally: if hasattr(other, 'close'):