# HG changeset patch # User Steve Losh # Date 1286585136 14400 # Node ID f5aa9bd91d3021aae74912ef0c473f42598f7e9e # Parent 715b023f84bfd753d6149a75e1415c790ad31293 Moar. diff -r 715b023f84bf -r f5aa9bd91d30 plugin/gundo.vim --- a/plugin/gundo.vim Fri Oct 08 19:24:25 2010 -0400 +++ b/plugin/gundo.vim Fri Oct 08 20:45:36 2010 -0400 @@ -3,6 +3,8 @@ " Description: vim global plugin to visualizer your undo tree " Maintainer: Steve Losh " License: GPLv2+ -- look it up. +" Notes: Much of this code was thiefed from Mercurial, and the rest was +" heavily inspired by scratch.vim. " " ============================================================================ " @@ -68,46 +70,38 @@ function! s:GundoRender() python << ENDPYTHON import vim +import itertools, time normal = lambda s: vim.command('normal %s' % s) ut = vim.eval('undotree()') tip = ut['seq_last'] -current = ut['seq_cur'] entries = ut['entries'] class Buffer(object): def __init__(self): self.b = '' + def write(self, s): self.b += s class Node(object): - def __init__(self, n, parent): + def __init__(self, n, parent, time, curhead): self.n = int(n) self.parent = parent self.children = [] + self.curhead = curhead + self.time = time - def pprint(self, indent=0): - print '%sn%d -> %s, %s\n' % ( - ' ' * indent, - self.n, - self.parent.n if self.parent else 'n/a', - [c.n for c in self.children]), - for c in self.children: - c.pprint(indent+1) - - def __str__(self): - return 'Node: %s' % str(self.n) - -root = Node(0, None) +root = Node(0, None, False, 0) nodes = [] def make_nodes(alts, parent=None): p = parent for alt in alts: - node = Node(n=alt['seq'], parent=p) + curhead = True if 'curhead' in alt else False + node = Node(n=alt['seq'], parent=p, time=alt['time'], curhead=curhead) nodes.append(node) if alt.get('alt'): make_nodes(alt['alt'], parent=p) @@ -121,6 +115,38 @@ tips = [node for node in nodes if not node.children] +agescales = [("year", 3600 * 24 * 365), + ("month", 3600 * 24 * 30), + ("week", 3600 * 24 * 7), + ("day", 3600 * 24), + ("hour", 3600), + ("minute", 60), + ("second", 1)] + +def age(ts): + '''turn a timestamp into an age string.''' + + def plural(t, c): + if c == 1: + return t + return t + "s" + def fmt(t, c): + return "%d %s" % (c, plural(t, c)) + + now = time.time() + then = ts + if then > now: + return 'in the future' + + delta = max(1, int(now - then)) + if delta > agescales[0][1] * 2: + return time.strftime('%Y-%m-%d', time.gmtime(float(ts))) + + for t, s in agescales: + n = delta // s + if n >= 2 or s == 1: + return '%s ago' % fmt(t, n) + def walk_nodes(nodes): for node in nodes: @@ -390,16 +416,24 @@ state[0] = coldiff state[1] = idx -def generate(dag, edgefn): +def generate(dag, edgefn, current): seen, state = [], [0, 0] buf = Buffer() for node, parents in list(dag)[:-1]: - char = '@' if node.n == int(current) else 'o' - ascii(buf, state, 'C', char, ['[%s]' % str(node.n)], edgefn(seen, node, parents)) + line = '[%s] %s' % (node.n, age(int(node.time))) + char = '@' if node.n == current else 'o' + ascii(buf, state, 'C', char, [line], edgefn(seen, node, parents)) return buf.b dag = sorted(nodes, key=lambda n: int(n.n), reverse=True) + [root] -result = generate(walk_nodes(dag), asciiedges).splitlines() + +_curhead_l = list(itertools.dropwhile(lambda n: not n.curhead, dag)) +if _curhead_l: + current = _curhead_l[0].parent.n +else: + current = int(vim.eval('changenr()')) + +result = generate(walk_nodes(dag), asciiedges, current).splitlines() vim.command('GundoOpenBuffer') vim.command('setlocal modifiable')