comparison mercurial/graphmod.py @ 33858: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
33857:833f70277f0e 33858: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)