D360: log: add a "graphwidth" template variable

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

D360: log: add a "graphwidth" template variable

dsp (David Soria Parra)
hooper created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  Wrapping text in templates for 'hg log --graph' can't be done very well,
  because the template doesn't know how wide the graph drawing is. The edge
  drawing function needs to know the number of lines in the template output, so
  we need to also determine how wide that drawing would be before we call the
  edgefn or evaluate the template.
 
  This patch adds an optional widthfn callback alongside edgefn so that callers
  to displaygraph() can enable it to pass the computed graph width into the
  template. The new argument is added so as to avoid breaking any extensions
  calling the current displaygraph(). The stock asciiedges() gets a stock
  asciiwidth() so that we can do something like this:
 
  COLUMNS=10 hg log --graph --template "{fill(desc, termwidth - graphwidth)}"
  @  a a a a
 
  | a a a a |
  | a a a a |
  |
 
  o    a a a
 
  | \   a a a |
  |           | a a a |
  |           | a a a |
  |
 
  Using extensions to do this would be relatively complicated due to a lack of
  hooks in this area of the code.
 
  In the future it may make sense to have a more generic "textwidth" that tells
  you how many columns you can expect to fill without causing the terminal to
  wrap your output. I'm not sure there are other situations to motivate this yet,
  or if it is entirely feasible.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D360

AFFECTED FILES
  hgext/show.py
  mercurial/cmdutil.py
  mercurial/commands.py
  mercurial/graphmod.py
  mercurial/templatekw.py
  tests/test-command-template.t

CHANGE DETAILS

diff --git a/tests/test-command-template.t b/tests/test-command-template.t
--- a/tests/test-command-template.t
+++ b/tests/test-command-template.t
@@ -4319,3 +4319,155 @@
   custom
 
   $ cd ..
+
+Test 'graphwidth' in 'hg log' on various topologies. The key here is that the
+printed graphwidths 3, 5, 7, etc. should all line up in their respective
+columns. We don't care about other aspects of the graph rendering here.
+
+  $ hg init graphwidth
+  $ cd graphwidth
+
+  $ wrappabletext="a a a a a a a a a a a a"
+
+  $ printf "first\n" > file
+  $ hg add file
+  $ hg commit -m "$wrappabletext"
+
+  $ printf "first\nsecond\n" > file
+  $ hg commit -m "$wrappabletext"
+
+  $ hg checkout 0
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ printf "third\nfirst\n" > file
+  $ hg commit -m "$wrappabletext"
+  created new head
+
+  $ hg merge
+  merging file
+  0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+
+  $ hg log --graph -T "{graphwidth}"
+  @  3
+  |
+  | @  5
+  |/
+  o  3
+  
+  $ hg commit -m "$wrappabletext"
+
+  $ hg log --graph -T "{graphwidth}"
+  @    5
+  |\
+  | o  5
+  | |
+  o |  5
+  |/
+  o  3
+  
+
+  $ hg checkout 0
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ printf "third\nfirst\nsecond\n" > file
+  $ hg commit -m "$wrappabletext"
+  created new head
+
+  $ hg log --graph -T "{graphwidth}"
+  @  3
+  |
+  | o    7
+  | |\
+  +---o  7
+  | |
+  | o  5
+  |/
+  o  3
+  
+
+  $ hg log --graph -T "{graphwidth}" -r 3
+  o    5
+  |\
+  ~ ~
+
+  $ hg log --graph -T "{graphwidth}" -r 1
+  o  3
+  |
+  ~
+
+  $ hg merge
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg commit -m "$wrappabletext"
+
+  $ printf "seventh\n" >> file
+  $ hg commit -m "$wrappabletext"
+
+  $ hg log --graph -T "{graphwidth}"
+  @  3
+  |
+  o    5
+  |\
+  | o  5
+  | |
+  o |    7
+  |\ \
+  | o |  7
+  | |/
+  o /  5
+  |/
+  o  3
+  
+
+The point of graphwidth is to allow wrapping that accounts for the space taken
+by the graph.
+
+  $ COLUMNS=10 hg log --graph -T "{fill(desc, termwidth - graphwidth)}"
+  @  a a a a
+  |  a a a a
+  |  a a a a
+  o    a a a
+  |\   a a a
+  | |  a a a
+  | |  a a a
+  | o  a a a
+  | |  a a a
+  | |  a a a
+  | |  a a a
+  o |    a a
+  |\ \   a a
+  | | |  a a
+  | | |  a a
+  | | |  a a
+  | | |  a a
+  | o |  a a
+  | |/   a a
+  | |    a a
+  | |    a a
+  | |    a a
+  | |    a a
+  o |  a a a
+  |/   a a a
+  |    a a a
+  |    a a a
+  o  a a a a
+     a a a a
+     a a a a
+
+Something tricky happens when there are elided nodes; the next drawn row of
+edges can be more than one column wider, but the graph width only increases by
+one column. The remaining columns are added in between the nodes.
+
+  $ hg log --graph -T "{graphwidth}" -r "0|2|4|5"
+  o    5
+  |\
+  | \
+  | :\
+  o : :  7
+  :/ /
+  : o  5
+  :/
+  o  3
+  
+
+  $ cd ..
+
diff --git a/mercurial/templatekw.py b/mercurial/templatekw.py
--- a/mercurial/templatekw.py
+++ b/mercurial/templatekw.py
@@ -764,6 +764,13 @@
     """Integer. The width of the current terminal."""
     return repo.ui.termwidth()
 
+@templatekeyword('graphwidth')
+def graphwidth(repo, ctx, templ, **args):
+    """Integer. The width of the graph drawn by 'log --graph' or zero."""
+    # The value args['graphwidth'] will be this function, so we use an internal
+    # name to pass the value through props into this function.
+    return args.get('_graphwidth', 0)
+
 @templatekeyword('troubles')
 def showtroubles(**args):
     """List of strings. Evolution troubles affecting the changeset.
diff --git a/mercurial/graphmod.py b/mercurial/graphmod.py
--- a/mercurial/graphmod.py
+++ b/mercurial/graphmod.py
@@ -222,6 +222,24 @@
     state['edges'].pop(rev, None)
     yield (type, char, lines, (nodeidx, edges, ncols, nmorecols))
 
+def asciiwidth(state, rev, parents):
+    """returns the width of the graph drawn by ascii() based on asciiedges()"""
+    seen = state['seen'][:]
+    if rev not in seen:
+        seen.append(rev)
+    columns = len(seen)
+
+    # We might be adding columns to handle previously unseen parents, but only
+    # one of them goes into the graph width for this rev.
+    newparents = 0
+    for ptype, parent in parents:
+        if parent != rev and parent not in seen:
+            newparents += 1
+    columns = max(columns, columns + min(2, newparents) - 1)
+
+    # Each column is 2 characters, and there's another character of padding.
+    return 1 + 2 * columns
+
 def _fixlongrightedges(edges):
     for (i, (start, end)) in enumerate(edges):
         if end > start:
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -3123,7 +3123,8 @@
         def display(other, chlist, displayer):
             revdag = cmdutil.graphrevs(other, chlist, opts)
             cmdutil.displaygraph(ui, repo, revdag, displayer,
-                                 graphmod.asciiedges)
+                                 graphmod.asciiedges,
+                                 widthfn=graphmod.asciiwidth)
 
         hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
         return 0
@@ -3572,7 +3573,8 @@
         revdag = cmdutil.graphrevs(repo, o, opts)
         ui.pager('outgoing')
         displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
-        cmdutil.displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges)
+        cmdutil.displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges,
+                             widthfn=graphmod.asciiwidth)
         cmdutil.outgoinghooks(ui, repo, other, opts, o)
         return 0
 
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -2508,7 +2508,7 @@
     return formatnode
 
 def displaygraph(ui, repo, dag, displayer, edgefn, getrenamed=None,
-                 filematcher=None):
+                 filematcher=None, widthfn=None):
     formatnode = _graphnodeformatter(ui, displayer)
     state = graphmod.asciistate()
     styles = state['styles']
@@ -2545,7 +2545,11 @@
         revmatchfn = None
         if filematcher is not None:
             revmatchfn = filematcher(ctx.rev())
-        displayer.show(ctx, copies=copies, matchfn=revmatchfn)
+        graphwidth = None
+        if widthfn:
+            graphwidth = widthfn(state, rev, parents)
+        displayer.show(ctx, copies=copies, matchfn=revmatchfn,
+                       _graphwidth=graphwidth)
         lines = displayer.hunk.pop(rev).split('\n')
         if not lines[-1]:
             del lines[-1]
@@ -2569,8 +2573,8 @@
 
     ui.pager('log')
     displayer = show_changeset(ui, repo, opts, buffered=True)
-    displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges, getrenamed,
-                 filematcher)
+    displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges,
+                 getrenamed, filematcher, widthfn=graphmod.asciiwidth)
 
 def checkunsupportedgraphflags(pats, opts):
     for op in ["newest_first"]:
diff --git a/hgext/show.py b/hgext/show.py
--- a/hgext/show.py
+++ b/hgext/show.py
@@ -397,7 +397,8 @@
     revdag = graphmod.dagwalker(repo, revs)
 
     ui.setconfig('experimental', 'graphshorten', True)
-    cmdutil.displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges)
+    cmdutil.displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges,
+                         widthfn=graphmod.asciiwidth)
 
 def extsetup(ui):
     # Alias `hg <prefix><view>` to `hg show <view>`.



To: hooper, #hg-reviewers
Cc: mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

D360: log: add a "graphwidth" template variable

dsp (David Soria Parra)
hooper updated this revision to Diff 822.
hooper edited the summary of this revision.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D360?vs=821&id=822

REVISION DETAIL
  https://phab.mercurial-scm.org/D360

AFFECTED FILES
  hgext/show.py
  mercurial/cmdutil.py
  mercurial/commands.py
  mercurial/graphmod.py
  mercurial/templatekw.py
  tests/test-command-template.t

CHANGE DETAILS

diff --git a/tests/test-command-template.t b/tests/test-command-template.t
--- a/tests/test-command-template.t
+++ b/tests/test-command-template.t
@@ -4319,3 +4319,155 @@
   custom
 
   $ cd ..
+
+Test 'graphwidth' in 'hg log' on various topologies. The key here is that the
+printed graphwidths 3, 5, 7, etc. should all line up in their respective
+columns. We don't care about other aspects of the graph rendering here.
+
+  $ hg init graphwidth
+  $ cd graphwidth
+
+  $ wrappabletext="a a a a a a a a a a a a"
+
+  $ printf "first\n" > file
+  $ hg add file
+  $ hg commit -m "$wrappabletext"
+
+  $ printf "first\nsecond\n" > file
+  $ hg commit -m "$wrappabletext"
+
+  $ hg checkout 0
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ printf "third\nfirst\n" > file
+  $ hg commit -m "$wrappabletext"
+  created new head
+
+  $ hg merge
+  merging file
+  0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+
+  $ hg log --graph -T "{graphwidth}"
+  @  3
+  |
+  | @  5
+  |/
+  o  3
+  
+  $ hg commit -m "$wrappabletext"
+
+  $ hg log --graph -T "{graphwidth}"
+  @    5
+  |\
+  | o  5
+  | |
+  o |  5
+  |/
+  o  3
+  
+
+  $ hg checkout 0
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ printf "third\nfirst\nsecond\n" > file
+  $ hg commit -m "$wrappabletext"
+  created new head
+
+  $ hg log --graph -T "{graphwidth}"
+  @  3
+  |
+  | o    7
+  | |\
+  +---o  7
+  | |
+  | o  5
+  |/
+  o  3
+  
+
+  $ hg log --graph -T "{graphwidth}" -r 3
+  o    5
+  |\
+  ~ ~
+
+  $ hg log --graph -T "{graphwidth}" -r 1
+  o  3
+  |
+  ~
+
+  $ hg merge
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg commit -m "$wrappabletext"
+
+  $ printf "seventh\n" >> file
+  $ hg commit -m "$wrappabletext"
+
+  $ hg log --graph -T "{graphwidth}"
+  @  3
+  |
+  o    5
+  |\
+  | o  5
+  | |
+  o |    7
+  |\ \
+  | o |  7
+  | |/
+  o /  5
+  |/
+  o  3
+  
+
+The point of graphwidth is to allow wrapping that accounts for the space taken
+by the graph.
+
+  $ COLUMNS=10 hg log --graph -T "{fill(desc, termwidth - graphwidth)}"
+  @  a a a a
+  |  a a a a
+  |  a a a a
+  o    a a a
+  |\   a a a
+  | |  a a a
+  | |  a a a
+  | o  a a a
+  | |  a a a
+  | |  a a a
+  | |  a a a
+  o |    a a
+  |\ \   a a
+  | | |  a a
+  | | |  a a
+  | | |  a a
+  | | |  a a
+  | o |  a a
+  | |/   a a
+  | |    a a
+  | |    a a
+  | |    a a
+  | |    a a
+  o |  a a a
+  |/   a a a
+  |    a a a
+  |    a a a
+  o  a a a a
+     a a a a
+     a a a a
+
+Something tricky happens when there are elided nodes; the next drawn row of
+edges can be more than one column wider, but the graph width only increases by
+one column. The remaining columns are added in between the nodes.
+
+  $ hg log --graph -T "{graphwidth}" -r "0|2|4|5"
+  o    5
+  |\
+  | \
+  | :\
+  o : :  7
+  :/ /
+  : o  5
+  :/
+  o  3
+  
+
+  $ cd ..
+
diff --git a/mercurial/templatekw.py b/mercurial/templatekw.py
--- a/mercurial/templatekw.py
+++ b/mercurial/templatekw.py
@@ -764,6 +764,13 @@
     """Integer. The width of the current terminal."""
     return repo.ui.termwidth()
 
+@templatekeyword('graphwidth')
+def graphwidth(repo, ctx, templ, **args):
+    """Integer. The width of the graph drawn by 'log --graph' or zero."""
+    # The value args['graphwidth'] will be this function, so we use an internal
+    # name to pass the value through props into this function.
+    return args.get('_graphwidth', 0)
+
 @templatekeyword('troubles')
 def showtroubles(**args):
     """List of strings. Evolution troubles affecting the changeset.
diff --git a/mercurial/graphmod.py b/mercurial/graphmod.py
--- a/mercurial/graphmod.py
+++ b/mercurial/graphmod.py
@@ -222,6 +222,24 @@
     state['edges'].pop(rev, None)
     yield (type, char, lines, (nodeidx, edges, ncols, nmorecols))
 
+def asciiwidth(state, rev, parents):
+    """returns the width of the graph drawn by ascii() based on asciiedges()"""
+    seen = state['seen'][:]
+    if rev not in seen:
+        seen.append(rev)
+    columns = len(seen)
+
+    # We might be adding columns to handle previously unseen parents, but only
+    # one of them goes into the graph width for this rev.
+    newparents = 0
+    for ptype, parent in parents:
+        if parent != rev and parent not in seen:
+            newparents += 1
+    columns = max(columns, columns + min(2, newparents) - 1)
+
+    # Each column is 2 characters, and there's another character of padding.
+    return 1 + 2 * columns
+
 def _fixlongrightedges(edges):
     for (i, (start, end)) in enumerate(edges):
         if end > start:
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -3123,7 +3123,8 @@
         def display(other, chlist, displayer):
             revdag = cmdutil.graphrevs(other, chlist, opts)
             cmdutil.displaygraph(ui, repo, revdag, displayer,
-                                 graphmod.asciiedges)
+                                 graphmod.asciiedges,
+                                 widthfn=graphmod.asciiwidth)
 
         hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
         return 0
@@ -3572,7 +3573,8 @@
         revdag = cmdutil.graphrevs(repo, o, opts)
         ui.pager('outgoing')
         displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
-        cmdutil.displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges)
+        cmdutil.displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges,
+                             widthfn=graphmod.asciiwidth)
         cmdutil.outgoinghooks(ui, repo, other, opts, o)
         return 0
 
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -2508,7 +2508,7 @@
     return formatnode
 
 def displaygraph(ui, repo, dag, displayer, edgefn, getrenamed=None,
-                 filematcher=None):
+                 filematcher=None, widthfn=None):
     formatnode = _graphnodeformatter(ui, displayer)
     state = graphmod.asciistate()
     styles = state['styles']
@@ -2545,7 +2545,11 @@
         revmatchfn = None
         if filematcher is not None:
             revmatchfn = filematcher(ctx.rev())
-        displayer.show(ctx, copies=copies, matchfn=revmatchfn)
+        graphwidth = 0
+        if widthfn:
+            graphwidth = widthfn(state, rev, parents)
+        displayer.show(ctx, copies=copies, matchfn=revmatchfn,
+                       _graphwidth=graphwidth)
         lines = displayer.hunk.pop(rev).split('\n')
         if not lines[-1]:
             del lines[-1]
@@ -2570,7 +2574,7 @@
     ui.pager('log')
     displayer = show_changeset(ui, repo, opts, buffered=True)
     displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges, getrenamed,
-                 filematcher)
+                 filematcher, widthfn=graphmod.asciiwidth)
 
 def checkunsupportedgraphflags(pats, opts):
     for op in ["newest_first"]:
diff --git a/hgext/show.py b/hgext/show.py
--- a/hgext/show.py
+++ b/hgext/show.py
@@ -397,7 +397,8 @@
     revdag = graphmod.dagwalker(repo, revs)
 
     ui.setconfig('experimental', 'graphshorten', True)
-    cmdutil.displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges)
+    cmdutil.displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges,
+                         widthfn=graphmod.asciiwidth)
 
 def extsetup(ui):
     # Alias `hg <prefix><view>` to `hg show <view>`.



To: hooper, #hg-reviewers
Cc: mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

D360: log: add a "graphwidth" template variable

dsp (David Soria Parra)
In reply to this post by dsp (David Soria Parra)
yuja added a comment.


  > The edge
  >  drawing function needs to know the number of lines in the template output, so
  >  we need to also determine how wide that drawing would be before we call the
  >  edgefn or evaluate the template.
 
  Actually `asciiedges()` doesn't need the `lines` to be rendered, so we could do
  something as follows:
 
    edges = list(edgefn(type, char, state, rev, parents))
    graphwidth = asciiwidth(edges)
    displayer.show(...)
    lines = displayer.hunk.pop()...
    for type, char, coldata in edges:
        ascii(ui, state, type, char, lines, coldata)
        lines = []
 
  This would be better in API point of view, but I'm not sure if `asciiwidth()` could get
  simpler by this change.

INLINE COMMENTS

> templatekw.py:768
> +@templatekeyword('graphwidth')
> +def graphwidth(repo, ctx, templ, **args):
> +    """Integer. The width of the graph drawn by 'log --graph' or zero."""

s/graphwidth/showgraphwidth/, and functions should be sorted alphabetically.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D360

To: hooper, #hg-reviewers
Cc: yuja, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

D360: log: add a "graphwidth" template variable

dsp (David Soria Parra)
In reply to this post by dsp (David Soria Parra)
hooper added a comment.


  In https://phab.mercurial-scm.org/D360#5639, @yuja wrote:
 
  > > The edge
  > >  drawing function needs to know the number of lines in the template output, so
  > >  we need to also determine how wide that drawing would be before we call the
  > >  edgefn or evaluate the template.
  >
  > Actually `asciiedges()` doesn't need the `lines` to be rendered, so we could do
  >  something as follows:
  >
  >   edges = list(edgefn(type, char, state, rev, parents))
  >   graphwidth = asciiwidth(edges)
  >   displayer.show(...)
  >   lines = displayer.hunk.pop()...
  >   for type, char, coldata in edges:
  >       ascii(ui, state, type, char, lines, coldata)
  >       lines = []
  >
  >
  > This would be better in API point of view, but I'm not sure if `asciiwidth()` could get
  >  simpler by this change.
 
 
  I had avoided this change because it might break extensions with their own edgefns. Do you think that's a concern?

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D360

To: hooper, #hg-reviewers
Cc: yuja, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

D360: log: add a "graphwidth" template variable

dsp (David Soria Parra)
In reply to this post by dsp (David Soria Parra)
yuja added a comment.


  > I had avoided this change because it might break extensions with their own edgefns. Do you think that's a concern?
 
  It's probably okay to change the function interface. I don't think the current `edgefn`
  is any useful for extensions. And I heard no problem after https://phab.mercurial-scm.org/rHG97cb1aeaca7849bc72d66a8adc6081106f1c9bcf.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D360

To: hooper, #hg-reviewers
Cc: yuja, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

D360: log: add a "graphwidth" template variable

dsp (David Soria Parra)
In reply to this post by dsp (David Soria Parra)
hooper updated this revision to Diff 940.
hooper edited the summary of this revision.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D360?vs=822&id=940

REVISION DETAIL
  https://phab.mercurial-scm.org/D360

AFFECTED FILES
  mercurial/cmdutil.py
  mercurial/graphmod.py
  mercurial/templatekw.py
  tests/test-command-template.t

CHANGE DETAILS

diff --git a/tests/test-command-template.t b/tests/test-command-template.t
--- a/tests/test-command-template.t
+++ b/tests/test-command-template.t
@@ -4319,3 +4319,155 @@
   custom
 
   $ cd ..
+
+Test 'graphwidth' in 'hg log' on various topologies. The key here is that the
+printed graphwidths 3, 5, 7, etc. should all line up in their respective
+columns. We don't care about other aspects of the graph rendering here.
+
+  $ hg init graphwidth
+  $ cd graphwidth
+
+  $ wrappabletext="a a a a a a a a a a a a"
+
+  $ printf "first\n" > file
+  $ hg add file
+  $ hg commit -m "$wrappabletext"
+
+  $ printf "first\nsecond\n" > file
+  $ hg commit -m "$wrappabletext"
+
+  $ hg checkout 0
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ printf "third\nfirst\n" > file
+  $ hg commit -m "$wrappabletext"
+  created new head
+
+  $ hg merge
+  merging file
+  0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+
+  $ hg log --graph -T "{graphwidth}"
+  @  3
+  |
+  | @  5
+  |/
+  o  3
+  
+  $ hg commit -m "$wrappabletext"
+
+  $ hg log --graph -T "{graphwidth}"
+  @    5
+  |\
+  | o  5
+  | |
+  o |  5
+  |/
+  o  3
+  
+
+  $ hg checkout 0
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ printf "third\nfirst\nsecond\n" > file
+  $ hg commit -m "$wrappabletext"
+  created new head
+
+  $ hg log --graph -T "{graphwidth}"
+  @  3
+  |
+  | o    7
+  | |\
+  +---o  7
+  | |
+  | o  5
+  |/
+  o  3
+  
+
+  $ hg log --graph -T "{graphwidth}" -r 3
+  o    5
+  |\
+  ~ ~
+
+  $ hg log --graph -T "{graphwidth}" -r 1
+  o  3
+  |
+  ~
+
+  $ hg merge
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg commit -m "$wrappabletext"
+
+  $ printf "seventh\n" >> file
+  $ hg commit -m "$wrappabletext"
+
+  $ hg log --graph -T "{graphwidth}"
+  @  3
+  |
+  o    5
+  |\
+  | o  5
+  | |
+  o |    7
+  |\ \
+  | o |  7
+  | |/
+  o /  5
+  |/
+  o  3
+  
+
+The point of graphwidth is to allow wrapping that accounts for the space taken
+by the graph.
+
+  $ COLUMNS=10 hg log --graph -T "{fill(desc, termwidth - graphwidth)}"
+  @  a a a a
+  |  a a a a
+  |  a a a a
+  o    a a a
+  |\   a a a
+  | |  a a a
+  | |  a a a
+  | o  a a a
+  | |  a a a
+  | |  a a a
+  | |  a a a
+  o |    a a
+  |\ \   a a
+  | | |  a a
+  | | |  a a
+  | | |  a a
+  | | |  a a
+  | o |  a a
+  | |/   a a
+  | |    a a
+  | |    a a
+  | |    a a
+  | |    a a
+  o |  a a a
+  |/   a a a
+  |    a a a
+  |    a a a
+  o  a a a a
+     a a a a
+     a a a a
+
+Something tricky happens when there are elided nodes; the next drawn row of
+edges can be more than one column wider, but the graph width only increases by
+one column. The remaining columns are added in between the nodes.
+
+  $ hg log --graph -T "{graphwidth}" -r "0|2|4|5"
+  o    5
+  |\
+  | \
+  | :\
+  o : :  7
+  :/ /
+  : o  5
+  :/
+  o  3
+  
+
+  $ cd ..
+
diff --git a/mercurial/templatekw.py b/mercurial/templatekw.py
--- a/mercurial/templatekw.py
+++ b/mercurial/templatekw.py
@@ -764,6 +764,13 @@
     """Integer. The width of the current terminal."""
     return repo.ui.termwidth()
 
+@templatekeyword('graphwidth')
+def graphwidth(repo, ctx, templ, **args):
+    """Integer. The width of the graph drawn by 'log --graph' or zero."""
+    # The value args['graphwidth'] will be this function, so we use an internal
+    # name to pass the value through props into this function.
+    return args.get('_graphwidth', 0)
+
 @templatekeyword('troubles')
 def showtroubles(**args):
     """List of strings. Evolution troubles affecting the changeset.
diff --git a/mercurial/graphmod.py b/mercurial/graphmod.py
--- a/mercurial/graphmod.py
+++ b/mercurial/graphmod.py
@@ -172,7 +172,7 @@
         yield (cur, type, data, (col, color), edges)
         seen = next
 
-def asciiedges(type, char, lines, state, rev, parents):
+def asciiedges(type, char, state, rev, parents):
     """adds edge info to changelog DAG walk suitable for ascii()"""
     seen = state['seen']
     if rev not in seen:
@@ -192,6 +192,7 @@
             state['edges'][parent] = state['styles'].get(ptype, '|')
 
     ncols = len(seen)
+    width = 1 + ncols * 2
     nextseen = seen[:]
     nextseen[nodeidx:nodeidx + 1] = newparents
     edges = [(nodeidx, nextseen.index(p)) for p in knownparents]
@@ -205,7 +206,8 @@
         edges.append((nodeidx, nodeidx))
         edges.append((nodeidx, nodeidx + 1))
         nmorecols = 1
-        yield (type, char, lines, (nodeidx, edges, ncols, nmorecols))
+        width += 2
+        yield (type, char, width, (nodeidx, edges, ncols, nmorecols))
         char = '\\'
         lines = []
         nodeidx += 1
@@ -218,9 +220,11 @@
     if len(newparents) > 1:
         edges.append((nodeidx, nodeidx + 1))
     nmorecols = len(nextseen) - ncols
+    if nmorecols > 0:
+        width += 2
     # remove current node from edge characters, no longer needed
     state['edges'].pop(rev, None)
-    yield (type, char, lines, (nodeidx, edges, ncols, nmorecols))
+    yield (type, char, width, (nodeidx, edges, ncols, nmorecols))
 
 def _fixlongrightedges(edges):
     for (i, (start, end)) in enumerate(edges):
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -2545,14 +2545,17 @@
         revmatchfn = None
         if filematcher is not None:
             revmatchfn = filematcher(ctx.rev())
-        displayer.show(ctx, copies=copies, matchfn=revmatchfn)
+        edges = list(edgefn(type, char, state, rev, parents))
+        width = edges[0][2]
+        displayer.show(ctx, copies=copies, matchfn=revmatchfn,
+                       _graphwidth=width)
         lines = displayer.hunk.pop(rev).split('\n')
         if not lines[-1]:
             del lines[-1]
         displayer.flush(ctx)
-        edges = edgefn(type, char, lines, state, rev, parents)
-        for type, char, lines, coldata in edges:
+        for type, char, width, coldata in edges:
             graphmod.ascii(ui, state, type, char, lines, coldata)
+            lines = []
     displayer.close()
 
 def graphlog(ui, repo, pats, opts):



To: hooper, #hg-reviewers
Cc: yuja, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

D360: log: add a "graphwidth" template variable

dsp (David Soria Parra)
In reply to this post by dsp (David Soria Parra)
hooper added inline comments.

INLINE COMMENTS

> yuja wrote in templatekw.py:768
> s/graphwidth/showgraphwidth/, and functions should be sorted alphabetically.

Can you explain why it should be renamed? I thought it should mirror termwidth. They both return an integer for computations in templates.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D360

To: hooper, #hg-reviewers
Cc: yuja, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

D360: log: add a "graphwidth" template variable

dsp (David Soria Parra)
In reply to this post by dsp (David Soria Parra)
hooper updated this revision to Diff 941.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D360?vs=940&id=941

REVISION DETAIL
  https://phab.mercurial-scm.org/D360

AFFECTED FILES
  mercurial/cmdutil.py
  mercurial/graphmod.py
  mercurial/templatekw.py
  tests/test-command-template.t

CHANGE DETAILS

diff --git a/tests/test-command-template.t b/tests/test-command-template.t
--- a/tests/test-command-template.t
+++ b/tests/test-command-template.t
@@ -4319,3 +4319,155 @@
   custom
 
   $ cd ..
+
+Test 'graphwidth' in 'hg log' on various topologies. The key here is that the
+printed graphwidths 3, 5, 7, etc. should all line up in their respective
+columns. We don't care about other aspects of the graph rendering here.
+
+  $ hg init graphwidth
+  $ cd graphwidth
+
+  $ wrappabletext="a a a a a a a a a a a a"
+
+  $ printf "first\n" > file
+  $ hg add file
+  $ hg commit -m "$wrappabletext"
+
+  $ printf "first\nsecond\n" > file
+  $ hg commit -m "$wrappabletext"
+
+  $ hg checkout 0
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ printf "third\nfirst\n" > file
+  $ hg commit -m "$wrappabletext"
+  created new head
+
+  $ hg merge
+  merging file
+  0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+
+  $ hg log --graph -T "{graphwidth}"
+  @  3
+  |
+  | @  5
+  |/
+  o  3
+  
+  $ hg commit -m "$wrappabletext"
+
+  $ hg log --graph -T "{graphwidth}"
+  @    5
+  |\
+  | o  5
+  | |
+  o |  5
+  |/
+  o  3
+  
+
+  $ hg checkout 0
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ printf "third\nfirst\nsecond\n" > file
+  $ hg commit -m "$wrappabletext"
+  created new head
+
+  $ hg log --graph -T "{graphwidth}"
+  @  3
+  |
+  | o    7
+  | |\
+  +---o  7
+  | |
+  | o  5
+  |/
+  o  3
+  
+
+  $ hg log --graph -T "{graphwidth}" -r 3
+  o    5
+  |\
+  ~ ~
+
+  $ hg log --graph -T "{graphwidth}" -r 1
+  o  3
+  |
+  ~
+
+  $ hg merge
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg commit -m "$wrappabletext"
+
+  $ printf "seventh\n" >> file
+  $ hg commit -m "$wrappabletext"
+
+  $ hg log --graph -T "{graphwidth}"
+  @  3
+  |
+  o    5
+  |\
+  | o  5
+  | |
+  o |    7
+  |\ \
+  | o |  7
+  | |/
+  o /  5
+  |/
+  o  3
+  
+
+The point of graphwidth is to allow wrapping that accounts for the space taken
+by the graph.
+
+  $ COLUMNS=10 hg log --graph -T "{fill(desc, termwidth - graphwidth)}"
+  @  a a a a
+  |  a a a a
+  |  a a a a
+  o    a a a
+  |\   a a a
+  | |  a a a
+  | |  a a a
+  | o  a a a
+  | |  a a a
+  | |  a a a
+  | |  a a a
+  o |    a a
+  |\ \   a a
+  | | |  a a
+  | | |  a a
+  | | |  a a
+  | | |  a a
+  | o |  a a
+  | |/   a a
+  | |    a a
+  | |    a a
+  | |    a a
+  | |    a a
+  o |  a a a
+  |/   a a a
+  |    a a a
+  |    a a a
+  o  a a a a
+     a a a a
+     a a a a
+
+Something tricky happens when there are elided nodes; the next drawn row of
+edges can be more than one column wider, but the graph width only increases by
+one column. The remaining columns are added in between the nodes.
+
+  $ hg log --graph -T "{graphwidth}" -r "0|2|4|5"
+  o    5
+  |\
+  | \
+  | :\
+  o : :  7
+  :/ /
+  : o  5
+  :/
+  o  3
+  
+
+  $ cd ..
+
diff --git a/mercurial/templatekw.py b/mercurial/templatekw.py
--- a/mercurial/templatekw.py
+++ b/mercurial/templatekw.py
@@ -764,6 +764,13 @@
     """Integer. The width of the current terminal."""
     return repo.ui.termwidth()
 
+@templatekeyword('graphwidth')
+def graphwidth(repo, ctx, templ, **args):
+    """Integer. The width of the graph drawn by 'log --graph' or zero."""
+    # The value args['graphwidth'] will be this function, so we use an internal
+    # name to pass the value through props into this function.
+    return args.get('_graphwidth', 0)
+
 @templatekeyword('troubles')
 def showtroubles(**args):
     """List of strings. Evolution troubles affecting the changeset.
diff --git a/mercurial/graphmod.py b/mercurial/graphmod.py
--- a/mercurial/graphmod.py
+++ b/mercurial/graphmod.py
@@ -172,7 +172,7 @@
         yield (cur, type, data, (col, color), edges)
         seen = next
 
-def asciiedges(type, char, lines, state, rev, parents):
+def asciiedges(type, char, state, rev, parents):
     """adds edge info to changelog DAG walk suitable for ascii()"""
     seen = state['seen']
     if rev not in seen:
@@ -192,6 +192,7 @@
             state['edges'][parent] = state['styles'].get(ptype, '|')
 
     ncols = len(seen)
+    width = 1 + ncols * 2
     nextseen = seen[:]
     nextseen[nodeidx:nodeidx + 1] = newparents
     edges = [(nodeidx, nextseen.index(p)) for p in knownparents]
@@ -205,7 +206,8 @@
         edges.append((nodeidx, nodeidx))
         edges.append((nodeidx, nodeidx + 1))
         nmorecols = 1
-        yield (type, char, lines, (nodeidx, edges, ncols, nmorecols))
+        width += 2
+        yield (type, char, width, (nodeidx, edges, ncols, nmorecols))
         char = '\\'
         lines = []
         nodeidx += 1
@@ -218,9 +220,11 @@
     if len(newparents) > 1:
         edges.append((nodeidx, nodeidx + 1))
     nmorecols = len(nextseen) - ncols
+    if nmorecols > 0:
+        width += 2
     # remove current node from edge characters, no longer needed
     state['edges'].pop(rev, None)
-    yield (type, char, lines, (nodeidx, edges, ncols, nmorecols))
+    yield (type, char, width, (nodeidx, edges, ncols, nmorecols))
 
 def _fixlongrightedges(edges):
     for (i, (start, end)) in enumerate(edges):
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -2545,14 +2545,18 @@
         revmatchfn = None
         if filematcher is not None:
             revmatchfn = filematcher(ctx.rev())
-        displayer.show(ctx, copies=copies, matchfn=revmatchfn)
+        edges = edgefn(type, char, state, rev, parents)
+        firstedge = next(edges)
+        width = firstedge[2]
+        displayer.show(ctx, copies=copies, matchfn=revmatchfn,
+                       _graphwidth=width)
         lines = displayer.hunk.pop(rev).split('\n')
         if not lines[-1]:
             del lines[-1]
         displayer.flush(ctx)
-        edges = edgefn(type, char, lines, state, rev, parents)
-        for type, char, lines, coldata in edges:
+        for type, char, width, coldata in itertools.chain([firstedge], edges):
             graphmod.ascii(ui, state, type, char, lines, coldata)
+            lines = []
     displayer.close()
 
 def graphlog(ui, repo, pats, opts):



To: hooper, #hg-reviewers
Cc: yuja, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

D360: log: add a "graphwidth" template variable

dsp (David Soria Parra)
In reply to this post by dsp (David Soria Parra)
yuja added inline comments.

INLINE COMMENTS

> cmdutil.py:2557
>          displayer.flush(ctx)
> -        edges = edgefn(type, char, lines, state, rev, parents)
> -        for type, char, lines, coldata in edges:
> +        for type, char, width, coldata in itertools.chain([firstedge], edges):
>              graphmod.ascii(ui, state, type, char, lines, coldata)

Just a nit. Is there any practical benefit to compute edges lazy?
I think `edges` can be simply converted to a list.

> hooper wrote in templatekw.py:768
> Can you explain why it should be renamed? I thought it should mirror termwidth. They both return an integer for computations in templates.

That's just a convention of templatekw. `termwidth` should be renamed too.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D360

To: hooper, #hg-reviewers
Cc: yuja, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

D360: log: add a "graphwidth" template variable

dsp (David Soria Parra)
In reply to this post by dsp (David Soria Parra)
hooper marked 2 inline comments as done.
hooper added inline comments.

INLINE COMMENTS

> yuja wrote in cmdutil.py:2557
> Just a nit. Is there any practical benefit to compute edges lazy?
> I think `edges` can be simply converted to a list.

There can be many of them.  E.g. in the hg repo it looks like a couple hundred with "hg log --graph -r 'tag()'". It just seems easy enough to hedge against it being expensive, though you might argue premature optimization.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D360

To: hooper, #hg-reviewers
Cc: yuja, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

D360: log: add a "graphwidth" template variable

dsp (David Soria Parra)
In reply to this post by dsp (David Soria Parra)
hooper updated this revision to Diff 1009.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D360?vs=941&id=1009

REVISION DETAIL
  https://phab.mercurial-scm.org/D360

AFFECTED FILES
  mercurial/cmdutil.py
  mercurial/graphmod.py
  mercurial/templatekw.py
  tests/test-command-template.t

CHANGE DETAILS

diff --git a/tests/test-command-template.t b/tests/test-command-template.t
--- a/tests/test-command-template.t
+++ b/tests/test-command-template.t
@@ -4319,3 +4319,155 @@
   custom
 
   $ cd ..
+
+Test 'graphwidth' in 'hg log' on various topologies. The key here is that the
+printed graphwidths 3, 5, 7, etc. should all line up in their respective
+columns. We don't care about other aspects of the graph rendering here.
+
+  $ hg init graphwidth
+  $ cd graphwidth
+
+  $ wrappabletext="a a a a a a a a a a a a"
+
+  $ printf "first\n" > file
+  $ hg add file
+  $ hg commit -m "$wrappabletext"
+
+  $ printf "first\nsecond\n" > file
+  $ hg commit -m "$wrappabletext"
+
+  $ hg checkout 0
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ printf "third\nfirst\n" > file
+  $ hg commit -m "$wrappabletext"
+  created new head
+
+  $ hg merge
+  merging file
+  0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+
+  $ hg log --graph -T "{graphwidth}"
+  @  3
+  |
+  | @  5
+  |/
+  o  3
+  
+  $ hg commit -m "$wrappabletext"
+
+  $ hg log --graph -T "{graphwidth}"
+  @    5
+  |\
+  | o  5
+  | |
+  o |  5
+  |/
+  o  3
+  
+
+  $ hg checkout 0
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ printf "third\nfirst\nsecond\n" > file
+  $ hg commit -m "$wrappabletext"
+  created new head
+
+  $ hg log --graph -T "{graphwidth}"
+  @  3
+  |
+  | o    7
+  | |\
+  +---o  7
+  | |
+  | o  5
+  |/
+  o  3
+  
+
+  $ hg log --graph -T "{graphwidth}" -r 3
+  o    5
+  |\
+  ~ ~
+
+  $ hg log --graph -T "{graphwidth}" -r 1
+  o  3
+  |
+  ~
+
+  $ hg merge
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg commit -m "$wrappabletext"
+
+  $ printf "seventh\n" >> file
+  $ hg commit -m "$wrappabletext"
+
+  $ hg log --graph -T "{graphwidth}"
+  @  3
+  |
+  o    5
+  |\
+  | o  5
+  | |
+  o |    7
+  |\ \
+  | o |  7
+  | |/
+  o /  5
+  |/
+  o  3
+  
+
+The point of graphwidth is to allow wrapping that accounts for the space taken
+by the graph.
+
+  $ COLUMNS=10 hg log --graph -T "{fill(desc, termwidth - graphwidth)}"
+  @  a a a a
+  |  a a a a
+  |  a a a a
+  o    a a a
+  |\   a a a
+  | |  a a a
+  | |  a a a
+  | o  a a a
+  | |  a a a
+  | |  a a a
+  | |  a a a
+  o |    a a
+  |\ \   a a
+  | | |  a a
+  | | |  a a
+  | | |  a a
+  | | |  a a
+  | o |  a a
+  | |/   a a
+  | |    a a
+  | |    a a
+  | |    a a
+  | |    a a
+  o |  a a a
+  |/   a a a
+  |    a a a
+  |    a a a
+  o  a a a a
+     a a a a
+     a a a a
+
+Something tricky happens when there are elided nodes; the next drawn row of
+edges can be more than one column wider, but the graph width only increases by
+one column. The remaining columns are added in between the nodes.
+
+  $ hg log --graph -T "{graphwidth}" -r "0|2|4|5"
+  o    5
+  |\
+  | \
+  | :\
+  o : :  7
+  :/ /
+  : o  5
+  :/
+  o  3
+  
+
+  $ cd ..
+
diff --git a/mercurial/templatekw.py b/mercurial/templatekw.py
--- a/mercurial/templatekw.py
+++ b/mercurial/templatekw.py
@@ -469,6 +469,13 @@
     else:
         return 'o'
 
+@templatekeyword('graphwidth')
+def showgraphwidth(repo, ctx, templ, **args):
+    """Integer. The width of the graph drawn by 'log --graph' or zero."""
+    # The value args['graphwidth'] will be this function, so we use an internal
+    # name to pass the value through props into this function.
+    return args.get('_graphwidth', 0)
+
 @templatekeyword('index')
 def showindex(**args):
     """Integer. The current iteration of the loop. (0 indexed)"""
diff --git a/mercurial/graphmod.py b/mercurial/graphmod.py
--- a/mercurial/graphmod.py
+++ b/mercurial/graphmod.py
@@ -172,7 +172,7 @@
         yield (cur, type, data, (col, color), edges)
         seen = next
 
-def asciiedges(type, char, lines, state, rev, parents):
+def asciiedges(type, char, state, rev, parents):
     """adds edge info to changelog DAG walk suitable for ascii()"""
     seen = state['seen']
     if rev not in seen:
@@ -192,6 +192,7 @@
             state['edges'][parent] = state['styles'].get(ptype, '|')
 
     ncols = len(seen)
+    width = 1 + ncols * 2
     nextseen = seen[:]
     nextseen[nodeidx:nodeidx + 1] = newparents
     edges = [(nodeidx, nextseen.index(p)) for p in knownparents]
@@ -205,7 +206,8 @@
         edges.append((nodeidx, nodeidx))
         edges.append((nodeidx, nodeidx + 1))
         nmorecols = 1
-        yield (type, char, lines, (nodeidx, edges, ncols, nmorecols))
+        width += 2
+        yield (type, char, width, (nodeidx, edges, ncols, nmorecols))
         char = '\\'
         lines = []
         nodeidx += 1
@@ -218,9 +220,11 @@
     if len(newparents) > 1:
         edges.append((nodeidx, nodeidx + 1))
     nmorecols = len(nextseen) - ncols
+    if nmorecols > 0:
+        width += 2
     # remove current node from edge characters, no longer needed
     state['edges'].pop(rev, None)
-    yield (type, char, lines, (nodeidx, edges, ncols, nmorecols))
+    yield (type, char, width, (nodeidx, edges, ncols, nmorecols))
 
 def _fixlongrightedges(edges):
     for (i, (start, end)) in enumerate(edges):
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -2545,14 +2545,18 @@
         revmatchfn = None
         if filematcher is not None:
             revmatchfn = filematcher(ctx.rev())
-        displayer.show(ctx, copies=copies, matchfn=revmatchfn)
+        edges = edgefn(type, char, state, rev, parents)
+        firstedge = next(edges)
+        width = firstedge[2]
+        displayer.show(ctx, copies=copies, matchfn=revmatchfn,
+                       _graphwidth=width)
         lines = displayer.hunk.pop(rev).split('\n')
         if not lines[-1]:
             del lines[-1]
         displayer.flush(ctx)
-        edges = edgefn(type, char, lines, state, rev, parents)
-        for type, char, lines, coldata in edges:
+        for type, char, width, coldata in itertools.chain([firstedge], edges):
             graphmod.ascii(ui, state, type, char, lines, coldata)
+            lines = []
     displayer.close()
 
 def graphlog(ui, repo, pats, opts):



To: hooper, #hg-reviewers
Cc: yuja, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Loading...