Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/graphmod.py @ 33879:6f6c87888b22
log: add a "graphwidth" template variable
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 makes edgefn compute the graph width and pass it into the template
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.
Differential Revision: https://phab.mercurial-scm.org/D360
author | Danny Hooper <hooper@google.com> |
---|---|
date | Tue, 15 Aug 2017 10:15:31 -0700 |
parents | 27932a76a88d |
children | 5e1d4ccab455 |
comparison
equal
deleted
inserted
replaced
33878:833f70277f0e | 33879:6f6c87888b22 |
---|---|
170 | 170 |
171 # Yield and move on | 171 # Yield and move on |
172 yield (cur, type, data, (col, color), edges) | 172 yield (cur, type, data, (col, color), edges) |
173 seen = next | 173 seen = next |
174 | 174 |
175 def asciiedges(type, char, lines, state, rev, parents): | 175 def asciiedges(type, char, state, rev, parents): |
176 """adds edge info to changelog DAG walk suitable for ascii()""" | 176 """adds edge info to changelog DAG walk suitable for ascii()""" |
177 seen = state['seen'] | 177 seen = state['seen'] |
178 if rev not in seen: | 178 if rev not in seen: |
179 seen.append(rev) | 179 seen.append(rev) |
180 nodeidx = seen.index(rev) | 180 nodeidx = seen.index(rev) |
190 else: | 190 else: |
191 newparents.append(parent) | 191 newparents.append(parent) |
192 state['edges'][parent] = state['styles'].get(ptype, '|') | 192 state['edges'][parent] = state['styles'].get(ptype, '|') |
193 | 193 |
194 ncols = len(seen) | 194 ncols = len(seen) |
195 width = 1 + ncols * 2 | |
195 nextseen = seen[:] | 196 nextseen = seen[:] |
196 nextseen[nodeidx:nodeidx + 1] = newparents | 197 nextseen[nodeidx:nodeidx + 1] = newparents |
197 edges = [(nodeidx, nextseen.index(p)) for p in knownparents] | 198 edges = [(nodeidx, nextseen.index(p)) for p in knownparents] |
198 | 199 |
199 seen[:] = nextseen | 200 seen[:] = nextseen |
203 # introduce intermediate expansion lines to grow the active node list | 204 # introduce intermediate expansion lines to grow the active node list |
204 # slowly. | 205 # slowly. |
205 edges.append((nodeidx, nodeidx)) | 206 edges.append((nodeidx, nodeidx)) |
206 edges.append((nodeidx, nodeidx + 1)) | 207 edges.append((nodeidx, nodeidx + 1)) |
207 nmorecols = 1 | 208 nmorecols = 1 |
208 yield (type, char, lines, (nodeidx, edges, ncols, nmorecols)) | 209 width += 2 |
210 yield (type, char, width, (nodeidx, edges, ncols, nmorecols)) | |
209 char = '\\' | 211 char = '\\' |
210 lines = [] | |
211 nodeidx += 1 | 212 nodeidx += 1 |
212 ncols += 1 | 213 ncols += 1 |
213 edges = [] | 214 edges = [] |
214 del newparents[0] | 215 del newparents[0] |
215 | 216 |
216 if len(newparents) > 0: | 217 if len(newparents) > 0: |
217 edges.append((nodeidx, nodeidx)) | 218 edges.append((nodeidx, nodeidx)) |
218 if len(newparents) > 1: | 219 if len(newparents) > 1: |
219 edges.append((nodeidx, nodeidx + 1)) | 220 edges.append((nodeidx, nodeidx + 1)) |
220 nmorecols = len(nextseen) - ncols | 221 nmorecols = len(nextseen) - ncols |
222 if nmorecols > 0: | |
223 width += 2 | |
221 # remove current node from edge characters, no longer needed | 224 # remove current node from edge characters, no longer needed |
222 state['edges'].pop(rev, None) | 225 state['edges'].pop(rev, None) |
223 yield (type, char, lines, (nodeidx, edges, ncols, nmorecols)) | 226 yield (type, char, width, (nodeidx, edges, ncols, nmorecols)) |
224 | 227 |
225 def _fixlongrightedges(edges): | 228 def _fixlongrightedges(edges): |
226 for (i, (start, end)) in enumerate(edges): | 229 for (i, (start, end)) in enumerate(edges): |
227 if end > start: | 230 if end > start: |
228 edges[i] = (start, end + 1) | 231 edges[i] = (start, end + 1) |