D360: log: add a "graphwidth" template variable

2017-08-21 Thread martinvonz (Martin von Zweigbergk)
martinvonz added a comment.


  > it may make sense to have a more generic "textwidth"
  
  Good idea! That seems like what one usually wants. Can we not simply add that 
(defined as "termwidth - graphwidth")? If we had that, when would one want 
termwidth or graphwidth themselves?

REPOSITORY
  rHG Mercurial

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

To: hooper, #hg-reviewers, yuja
Cc: martinvonz, yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D360: log: add a "graphwidth" template variable

2017-08-17 Thread hooper (Danny Hooper)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG6f6c87888b22: log: add a "graphwidth" template variable 
(authored by hooper).

CHANGED PRIOR TO COMMIT
  https://phab.mercurial-scm.org/D360?vs=1009&id=1026#toc

REPOSITORY
  rHG Mercurial

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

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
+  |
+  | o7
+  | |\
+  +---o  7
+  | |
+  | o  5
+  |/
+  o  3
+  
+
+  $ hg log --graph -T "{graphwidth}" -r 3
+  o5
+  |\
+  ~ ~
+
+  $ 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
+  |
+  o5
+  |\
+  | 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
+  oa 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"
+  o5
+  |\
+  | \
+  | :\
+  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,9 +206,9 @@
 edges.append((nodeidx, nodeidx))
 ed

D360: log: add a "graphwidth" template variable

2017-08-17 Thread yuja (Yuya Nishihara)
yuja accepted this revision.
yuja added a comment.
This revision is now accepted and ready to land.


  Slightly adjusted the commit message for new version, and queued, thanks.

INLINE COMMENTS

> hooper wrote in cmdutil.py:2557
> 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.

Okay, I guess using a list would be slightly faster in common scenario, but I
have no strong opinion about this.

> graphmod.py:212
>  char = '\\'
>  lines = []
>  nodeidx += 1

Removed this `lines` in flight.

> graphmod.py:227
>  state['edges'].pop(rev, None)
> -yield (type, char, lines, (nodeidx, edges, ncols, nmorecols))
> +yield (type, char, width, (nodeidx, edges, ncols, nmorecols))
>  

Perhaps the `width` can be computed from the `coldata` afterwards, but
that wouldn't make much difference.

`width = indentation_level * 2 + 1`

  # graphmod.ascii()
  indentation_level = max(ncols, ncols + coldiff)
  for (line, logstr) in zip(lines, text):
  ln = "%-*s %s" % (2 * indentation_level, "".join(line), logstr)

REPOSITORY
  rHG Mercurial

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

To: hooper, #hg-reviewers, yuja
Cc: yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D360: log: add a "graphwidth" template variable

2017-08-16 Thread hooper (Danny Hooper)
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
+  |
+  | o7
+  | |\
+  +---o  7
+  | |
+  | o  5
+  |/
+  o  3
+  
+
+  $ hg log --graph -T "{graphwidth}" -r 3
+  o5
+  |\
+  ~ ~
+
+  $ 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
+  |
+  o5
+  |\
+  | 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
+  oa 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"
+  o5
+  |\
+  | \
+  | :\
+  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, nmorec

D360: log: add a "graphwidth" template variable

2017-08-16 Thread hooper (Danny Hooper)
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
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D360: log: add a "graphwidth" template variable

2017-08-15 Thread yuja (Yuya Nishihara)
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
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D360: log: add a "graphwidth" template variable

2017-08-15 Thread hooper (Danny Hooper)
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
+  |
+  | o7
+  | |\
+  +---o  7
+  | |
+  | o  5
+  |/
+  o  3
+  
+
+  $ hg log --graph -T "{graphwidth}" -r 3
+  o5
+  |\
+  ~ ~
+
+  $ 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
+  |
+  o5
+  |\
+  | 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
+  oa 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"
+  o5
+  |\
+  | \
+  | :\
+  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
+  

D360: log: add a "graphwidth" template variable

2017-08-15 Thread hooper (Danny Hooper)
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
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D360: log: add a "graphwidth" template variable

2017-08-15 Thread hooper (Danny Hooper)
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
+  |
+  | o7
+  | |\
+  +---o  7
+  | |
+  | o  5
+  |/
+  o  3
+  
+
+  $ hg log --graph -T "{graphwidth}" -r 3
+  o5
+  |\
+  ~ ~
+
+  $ 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
+  |
+  o5
+  |\
+  | 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
+  oa 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"
+  o5
+  |\
+  | \
+  | :\
+  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, nc

D360: log: add a "graphwidth" template variable

2017-08-14 Thread yuja (Yuya Nishihara)
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
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D360: log: add a "graphwidth" template variable

2017-08-14 Thread hooper (Danny Hooper)
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
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D360: log: add a "graphwidth" template variable

2017-08-13 Thread yuja (Yuya Nishihara)
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
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D360: log: add a "graphwidth" template variable

2017-08-11 Thread hooper (Danny Hooper)
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
+  |
+  | o7
+  | |\
+  +---o  7
+  | |
+  | o  5
+  |/
+  o  3
+  
+
+  $ hg log --graph -T "{graphwidth}" -r 3
+  o5
+  |\
+  ~ ~
+
+  $ 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
+  |
+  o5
+  |\
+  | 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
+  oa 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"
+  o5
+  |\
+  | \
+  | :\
+  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 chara

D360: log: add a "graphwidth" template variable

2017-08-11 Thread hooper (Danny Hooper)
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 |
  |
  
  oa 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
+  |
+  | o7
+  | |\
+  +---o  7
+  | |
+  | o  5
+  |/
+  o  3
+  
+
+  $ hg log --graph -T "{graphwidth}" -r 3
+  o5
+  |\
+  ~ ~
+
+  $ 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
+  |
+  o5
+  |\
+  | 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
+  oa 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"
+  o5
+  |\
+  | \
+  | :\
+  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 graphw