Patchwork [4,of,4] graphlog: make node symbol templatable by ui.graphnodetemplate option

login
register
mail settings
Submitter Yuya Nishihara
Date Dec. 3, 2015, 2:26 p.m.
Message ID <e2e5714e8ad810e73216.1449152807@mimosa>
Download mbox | patch
Permalink /patch/11787/
State Accepted
Headers show

Comments

Yuya Nishihara - Dec. 3, 2015, 2:26 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1447489543 -32400
#      Sat Nov 14 17:25:43 2015 +0900
# Node ID e2e5714e8ad810e73216599ee55aec40b98604d1
# Parent  ebe7e6a6986675c44cef7bfd442d73e29a2dda40
graphlog: make node symbol templatable by ui.graphnodetemplate option

New ui.graphnodetemplate option allows us to colorize a node symbol by phase
or branch,

  [ui]
  graphnodetemplate = {label('graphnode.{phase}', graphnode)}
  [color]
  graphnode.draft = yellow bold

or use a variety of unicode emoji characters, and so on. (You'll need less-481
to display non-BMP unicode character.)

  [ui]
  graphnodetemplate = {ifeq(obsolete, 'stable', graphnode, '\xf0\x9f\x92\xa9')}

Patch

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -2159,11 +2159,31 @@  def getlogrevs(repo, pats, opts):
 
     return revs, expr, filematcher
 
+def _graphnodeformatter(ui, displayer):
+    spec = ui.config('ui', 'graphnodetemplate')
+    if not spec:
+        return templatekw.showgraphnode  # fast path for "{graphnode}"
+
+    templ = formatter.gettemplater(ui, 'graphnode', spec)
+    cache = {}
+    if isinstance(displayer, changeset_templater):
+        cache = displayer.cache  # reuse cache of slow templates
+    props = templatekw.keywords.copy()
+    props['templ'] = templ
+    props['cache'] = cache
+    def formatnode(repo, ctx):
+        props['ctx'] = ctx
+        props['repo'] = repo
+        props['revcache'] = {}
+        return templater.stringify(templ('graphnode', **props))
+    return formatnode
+
 def displaygraph(ui, repo, dag, displayer, edgefn, getrenamed=None,
                  filematcher=None):
+    formatnode = _graphnodeformatter(ui, displayer)
     seen, state = [], graphmod.asciistate()
     for rev, type, ctx, parents in dag:
-        char = templatekw.showgraphnode(repo, ctx)
+        char = formatnode(repo, ctx)
         copies = None
         if getrenamed and ctx.rev():
             copies = []
diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt
--- a/mercurial/help/config.txt
+++ b/mercurial/help/config.txt
@@ -1454,6 +1454,10 @@  User interface controls.
     Encoding to try if it's not possible to decode the changelog using
     UTF-8. (default: ISO-8859-1)
 
+``graphnodetemplate``
+    The template used to print changeset nodes in an ASCII revision graph.
+    (default: ``{graphnode}``)
+
 ``ignore``
     A file to read per-user ignore patterns from. This file should be
     in the same format as a repository-wide .hgignore file. Filenames
diff --git a/tests/test-glog.t b/tests/test-glog.t
--- a/tests/test-glog.t
+++ b/tests/test-glog.t
@@ -2400,4 +2400,25 @@  working-directory revision
   @  3:5918b8d165d1
   |
 
+node template with changeset_printer:
+
+  $ hg log -Gqr 5:7 --config ui.graphnodetemplate='{rev}'
+  7  7:02dbb8e276b8
+  |
+  6    6:fc281d8ff18d
+  |\
+  5 |  5:99b31f1c2782
+  | |
+
+node template with changeset_templater (shared cache variable):
+
+  $ hg log -Gr 5:7 -T '{latesttag % "{rev} {tag}+{distance}"}\n' \
+  > --config ui.graphnodetemplate='{ifeq(latesttagdistance, 0, "#", graphnode)}'
+  o  7 foo-bar+1
+  |
+  #    6 foo-bar+0
+  |\
+  o |  5 null+5
+  | |
+
   $ cd ..