[curses] fancier graph highlighting for current/working changeset (closes #79263)

The goal is to highlight only the node in the graph instead of the whole graph line. The ID is also highlighted to help identify the node.

note:2 color style names has been modified for conveniance.
authorAlain Leufroy <alain.leufroyATgmailMYDOTcom>
changesetf2cc8e2ff806
branchdefault
phasepublic
hiddenno
parent revision#c50ff1cdc2c8 fix ImportError if the interface is not available (closes #77984)
child revision#655120b1239b [application] do not fail when started outside a repository with ``bin/hgview``(closes #79255)
files modified by this revision
hgviewlib/curses/application.py
hgviewlib/curses/graphlog.py
# HG changeset patch
# User Alain Leufroy <alain.leufroyATgmailMYDOTcom>
# Date 1318081744 -7200
# Sat Oct 08 15:49:04 2011 +0200
# Node ID f2cc8e2ff806a21b498ef0a98d4789ea72b0bd47
# Parent c50ff1cdc2c8920ada1f39a999bb53dec96e394d
[curses] fancier graph highlighting for current/working changeset (closes #79263)

The goal is to highlight only the node in the graph instead of the whole graph
line. The *ID* is also highlighted to help identify the node.

:note: 2 color style names has been modified for conveniance.

diff --git a/hgviewlib/curses/application.py b/hgviewlib/curses/application.py
@@ -286,18 +286,18 @@
1 
2      # graphlog
3      ('ID', 'brown', 'default', 'standout'),
4      ('Log', 'default', 'default'),
5      ('GraphLog', 'default', 'default', 'bold'),
6 +    ('GraphLog.working', 'black', 'dark red', 'bold'),
7 +    ('GraphLog.current', 'black', 'dark green', 'bold'),
8      ('Author', 'dark blue', 'default', 'bold'),
9      ('Date', 'dark green', 'default', 'bold'),
10      ('Tags', 'yellow', 'dark red', 'bold'),
11      ('Branch', 'yellow', 'default', 'bold'),
12      ('Filename', 'white', 'default', 'bold'),
13      ('Unapplied', 'light cyan', 'black'),
14 -    ('Current', 'black', 'dark green'),
15 -    ('Modified', 'black', 'dark red'),
16 
17      # filelist
18      ('+', 'dark green', 'default'),
19      ('-', 'dark red', 'default'),
20      ('=', 'default', 'default'),
diff --git a/hgviewlib/curses/graphlog.py b/hgviewlib/curses/graphlog.py
@@ -179,11 +179,11 @@
21          # prepare the last columns content
22          txts = []
23          for graph, fields in zzip(self.graphlog(gnode, ctx), self._allfields):
24              graph = graph or ''
25              fields = fields or ()
26 -            txts.append(('GraphLog', graph.ljust(GRAPH_MIN_WIDTH)))
27 +            txts.append(graph)
28              txts.append(' ')
29              for field in fields:
30                  if field not in self._columns:
31                      continue
32                  txt = _COLUMNMAP[field](self.walker, ctx, gnode)
@@ -203,36 +203,39 @@
33                     if col in self._columns]
34          columns.append(SelectableText(txts, wrap='clip'))
35          # normal style: use special styles for woking directory and tip
36          style = None
37          if gnode.rev is None:
38 -            style = 'Modified' # pending changes
39 +            style = 'GraphLog.working' # pending changes
40          elif gnode.rev in self.walker.wd_revs:
41 -            style = 'Current'
42 -        spec_style = style and dict.fromkeys(['GraphLog'], style) or {}
43 +            style = 'GraphLog.current'
44 +        spec_style = {'ID':style} if style else {}
45          # focused style: use special stles for working directory and tip
46 -        style = style or 'focus'
47 -        foc_style = dict.fromkeys(self._columns + ('GraphLog', None),
48 -                                  style)
49 +        foc_style = dict.fromkeys(self._columns + ('GraphLog', None,),
50 +                                  style or 'focus')
51          # wrap widget with style modified
52          widget = AttrMap(Columns(columns, 1), spec_style, foc_style)
53          widget = AppliedItem(widget, gnode, ctx)
54          return widget
55 
56      def graphlog(self, gnode, ctx):
57          """Return a generator that get lines of graph log for the node
58          """
59          # define node symbol
60          char = 'o'
61 +        style = 'GraphLog'
62          if gnode.rev is None:
63 -            char = '!' # pending changes
64 -        elif len(ctx.parents()) > 1:
65 +            style, char = 'GraphLog.working', '!' # pending changes
66 +        elif gnode.rev in self.walker.wd_revs:
67 +            style, char = 'GraphLog.current', '@'
68 +
69 +        if len(ctx.parents()) > 1:
70              char = 'M' # merge
71          elif set(ctx.tags()).intersection(self.walker.mqueues):
72              char = '*' # applied patch from mq
73 -        elif gnode.rev in self.walker.wd_revs:
74 -            char = '@'
75 +        item = (style, char)
76 +
77          # build the column data for the graphlogger from data given by hgview
78          curcol = gnode.x
79          curedges = [(start, end) for start, end, _ in gnode.bottomlines
80                      if start == curcol]
81          try:
@@ -240,11 +243,11 @@
82              prv, nxt = len(set(prv)), len(set(nxt))
83          except ValueError: # last
84              prv, nxt = 1, 0
85          coldata = (curcol, curedges, prv, nxt - prv)
86          self.asciistate = self.asciistate or [0, 0]
87 -        return hgview_ascii(self.asciistate, char, len(self._allfields),
88 +        return hgview_ascii(self.asciistate, item, len(self._allfields),
89                              coldata)
90 
91      def get_focus(self):
92          """Get focused widget"""
93          try:
@@ -372,12 +375,14 @@
94          while len(lines) < height:
95              lines.append(extra_interline)
96      # print lines
97      indentation_level = max(ncols, ncols + coldiff)
98      for line in lines:
99 -        out = "%-*s" % (2 * indentation_level, "".join(line))
100 -        yield out
101 +        # justify to GRAPH_MIN_WIDTH for conveniance
102 +        if len(line) < GRAPH_MIN_WIDTH:
103 +            line.append(' ' * (GRAPH_MIN_WIDTH - len(line)))
104 +        yield [('GraphLog', item) if isinstance(item, basestring) else item for item in line]
105      # ... and start over
106      state[0] = coldiff
107      state[1] = idx
108 
109