From da3d898cd41ef5c60f90a50dc3dd0ea520035a8e Mon Sep 17 00:00:00 2001 From: Mark Thomas Date: Mon, 6 Jan 2020 14:55:54 -0800 Subject: [PATCH] cmdutil: add Rust rendering of graphs Summary: Allow rendering of graphs using renderdag by setting `experimental.graph.renderer` to `ascii`, `ascii-large` or `lines`. The minimum height of each row can be set using `experimental.graph.min-row-height`. Reviewed By: quark-zju Differential Revision: D19272580 fbshipit-source-id: ac5eff8446bd3c09d07624a193195b4224055ffc --- eden/scm/edenscm/mercurial/cmdutil.py | 63 +++++++++++++++++++++++ eden/scm/edenscm/mercurial/configitems.py | 2 + 2 files changed, 65 insertions(+) diff --git a/eden/scm/edenscm/mercurial/cmdutil.py b/eden/scm/edenscm/mercurial/cmdutil.py index 8f6deb992c..a005ddb8d5 100644 --- a/eden/scm/edenscm/mercurial/cmdutil.py +++ b/eden/scm/edenscm/mercurial/cmdutil.py @@ -19,6 +19,9 @@ import re import stat import tempfile +# pyre-fixme[21]: Could not find `bindings`. +from bindings import renderdag + from . import ( bookmarks, changelog, @@ -3026,6 +3029,10 @@ def _graphnodeformatter(ui, displayer): def displaygraph( ui, repo, dag, displayer, edgefn, getrenamed=None, filematcher=None, props=None ): + if ui.config("experimental", "graph.renderer") != "legacy": + rustdisplaygraph(ui, repo, dag, displayer, getrenamed, filematcher, props) + return + props = props or {} formatnode = _graphnodeformatter(ui, displayer) state = graphmod.asciistate() @@ -3082,6 +3089,62 @@ def displaygraph( displayer.close() +def rustdisplaygraph( + ui, + repo, + dag, + displayer, + getrenamed=None, + filematcher=None, + props=None, + reserved=None, +): + props = props or {} + formatnode = _graphnodeformatter(ui, displayer) + renderers = { + "ascii": (renderdag.ascii, 2), + "ascii-large": (renderdag.asciilarge, 2), + "lines": (renderdag.boxdrawing, 2), + } + renderer, minheight = renderers.get( + ui.config("experimental", "graph.renderer"), (renderdag.ascii, 2) + ) + if ui.configbool("experimental", "graphshorten"): + minheight = 1 + minheight = ui.configint("experimental", "graph.min-row-height", minheight) + renderer = renderer(minheight) + + if reserved: + for rev in reserved: + renderer.reserve(rev) + + for (rev, _type, ctx, parents) in dag: + char = formatnode(repo, ctx) + copies = None + if getrenamed and ctx.rev(): + copies = [] + for fn in ctx.files(): + rename = getrenamed(fn, ctx.rev()) + if rename: + copies.append((fn, rename[0])) + revmatchfn = None + if filematcher is not None: + revmatchfn = filematcher(ctx.rev()) + width = renderer.width(rev, parents) + displayer.show( + ctx, + copies=copies, + matchfn=revmatchfn, + _graphwidth=width, + **pycompat.strkwargs(props) + ) + msg = displayer.hunk.pop(rev) + ui.write(renderer.nextrow(rev, parents, char, msg).encode("utf-8")) + displayer.flush(ctx) + + displayer.close() + + def graphlog(ui, repo, pats, opts): # Parameters are identical to log command ones revs, expr, filematcher = getgraphlogrevs(repo, pats, opts) diff --git a/eden/scm/edenscm/mercurial/configitems.py b/eden/scm/edenscm/mercurial/configitems.py index df1e27041c..8610dcef61 100644 --- a/eden/scm/edenscm/mercurial/configitems.py +++ b/eden/scm/edenscm/mercurial/configitems.py @@ -273,6 +273,8 @@ coreconfigitem("experimental", "exportableenviron", default=list) coreconfigitem("experimental", "extendedheader.index", default=None) coreconfigitem("experimental", "extendedheader.similarity", default=False) coreconfigitem("experimental", "format.compression", default="zlib") +coreconfigitem("experimental", "graph.renderer", default="legacy") +coreconfigitem("experimental", "graph.min-row-height", default=dynamicdefault) coreconfigitem("experimental", "graphshorten", default=False) coreconfigitem("experimental", "graphstyle.parent", default=dynamicdefault) coreconfigitem("experimental", "graphstyle.missing", default=dynamicdefault)