diff --git a/hgext/beautifygraph.py b/hgext/beautifygraph.py --- a/hgext/beautifygraph.py +++ b/hgext/beautifygraph.py @@ -9,6 +9,24 @@ '''beautify log -G output by using Unicode characters (EXPERIMENTAL) A terminal with UTF-8 support and monospace narrow text are required. + + The character substitutions used in the graph can be customized with + variables in the [beautifygraph] section:: + + / ``beautifygraph.edge.diagonal1`` + \ ``beautifygraph.edge.diagonal2`` + - ``beautifygraph.edge.horizontal`` + | ``beautifygraph.edge.vertical`` + : ``beautifygraph.edge.verticaldotted`` + -+- ``beautifygraph.edge.cross`` + -+ ``beautifygraph.edge.verticalleft`` + +- ``beautifygraph.edge.verticalright`` + ~ ``beautifygraph.edge.verticalstop`` + _ ``beautifygraph.node.closesbranch`` + @ ``beautifygraph.node.current`` + x ``beautifygraph.node.obsolete`` + o ``beautifygraph.node.other`` + * ``beautifygraph.node.unstable`` ''' from __future__ import absolute_import @@ -19,6 +37,7 @@ extensions, graphmod, pycompat, + registrar, templatekw, ) @@ -28,53 +47,69 @@ # leave the attribute unspecified. testedwith = 'ships-with-hg-core' -def prettyedge(before, edge, after): - if edge == '~': - return '\xE2\x95\xA7' # U+2567 ╧ - if edge == '/': - return '\xE2\x95\xB1' # U+2571 ╱ - if edge == '-': - return '\xE2\x94\x80' # U+2500 ─ - if edge == '|': - return '\xE2\x94\x82' # U+2502 │ - if edge == ':': - return '\xE2\x94\x86' # U+2506 ┆ - if edge == '\\': - return '\xE2\x95\xB2' # U+2572 ╲ +configtable = {} +configitem = registrar.configitem(configtable) + +configitem('beautifygraph', 'edge.verticalstop', '\xE2\x95\xA7') # U+2567 ╧ +configitem('beautifygraph', 'edge.diagonalcross', '\xE2\x95\xB3') # U+2573 ╳ +configitem('beautifygraph', 'edge.diagonal1', '\xE2\x95\xB1') # U+2571 ╱ +configitem('beautifygraph', 'edge.horizontal', '\xE2\x94\x80') # U+2500 ─ +configitem('beautifygraph', 'edge.vertical', '\xE2\x94\x82') # U+2502 │ +configitem('beautifygraph', 'edge.verticaldotted', '\xE2\x94\x86') # U+2506 ┆ +configitem('beautifygraph', 'edge.diagonal2', '\xE2\x95\xB2') # U+2572 ╲ +configitem('beautifygraph', 'edge.verticalright', '\xE2\x94\x9C') # U+251C ├ +configitem('beautifygraph', 'edge.verticalleft', '\xE2\x94\xA4') # U+2524 ┤ +configitem('beautifygraph', 'edge.cross', '\xE2\x94\xBC') # U+253C ┼ +configitem('beautifygraph', 'node.other', '\xE2\x97\x8B') # U+25CB ○ +configitem('beautifygraph', 'node.current', '\xE2\x97\x8D') # U+25CD ◍ +configitem('beautifygraph', 'node.unstable', '\xE2\x88\x97') # U+2217 ∗ +configitem('beautifygraph', 'node.obsolete', '\xE2\x97\x8C') # U+25CC ◌ +configitem('beautifygraph', 'node.closesbranch', '\xE2\x95\xA4') # U+2564 ╤ + +def getsubstitutions(ui): + return { + '~': ui.config('beautifygraph', 'edge.verticalstop'), + '/': ui.config('beautifygraph', 'edge.diagonal1'), + '-': ui.config('beautifygraph', 'edge.horizontal'), + '|': ui.config('beautifygraph', 'edge.vertical'), + ':': ui.config('beautifygraph', 'edge.verticaldotted'), + '\\': ui.config('beautifygraph', 'edge.diagonal2'), + '+-': ui.config('beautifygraph', 'edge.verticalright'), + '-+': ui.config('beautifygraph', 'edge.verticalleft'), + '+': ui.config('beautifygraph', 'edge.cross'), + 'o': ui.config('beautifygraph', 'node.other'), + '@': ui.config('beautifygraph', 'node.current'), + '*': ui.config('beautifygraph', 'node.unstable'), + 'x': ui.config('beautifygraph', 'node.obsolete'), + '_': ui.config('beautifygraph', 'node.closesbranch'), + } + +def prettyedge(substitutions, before, edge, after): if edge == '+': if before == ' ' and not after == ' ': - return '\xE2\x94\x9C' # U+251C ├ + return substitutions.get('+-', edge) if after == ' ' and not before == ' ': - return '\xE2\x94\xA4' # U+2524 ┤ - return '\xE2\x94\xBC' # U+253C ┼ - return edge + return substitutions.get('-+', edge) + return substitutions.get(edge, edge) -def convertedges(line): +def convertedges(substitutions, line): line = ' %s ' % line pretty = [] for idx in pycompat.xrange(len(line) - 2): - pretty.append(prettyedge(line[idx:idx + 1], + pretty.append(prettyedge(substitutions, + line[idx:idx + 1], line[idx + 1:idx + 2], line[idx + 2:idx + 3])) return ''.join(pretty) -def getprettygraphnode(orig, *args, **kwargs): - node = orig(*args, **kwargs) - if node == 'o': - return '\xE2\x97\x8B' # U+25CB ○ - if node == '@': - return '\xE2\x97\x8D' # U+25CD ◍ - if node == '*': - return '\xE2\x88\x97' # U+2217 ∗ - if node == 'x': - return '\xE2\x97\x8C' # U+25CC ◌ - if node == '_': - return '\xE2\x95\xA4' # U+2564 ╤ - return node +def getprettygraphnode(orig, repo, *args, **kwargs): + node = orig(repo, *args, **kwargs) + return getsubstitutions(repo.ui).get(node, node) def outputprettygraph(orig, ui, graph, *args, **kwargs): + substitutions = getsubstitutions(ui) (edges, text) = zip(*graph) - graph = zip([convertedges(e) for e in edges], text) + graph = zip([convertedges(substitutions, e) for e in edges], text) return orig(ui, graph, *args, **kwargs) def extsetup(ui): diff --git a/tests/test-glog-beautifygraph.t b/tests/test-glog-beautifygraph.t --- a/tests/test-glog-beautifygraph.t +++ b/tests/test-glog-beautifygraph.t @@ -1,3 +1,29 @@ + $ hg help beautifygraph + beautifygraph extension - beautify log -G output by using Unicode characters + (EXPERIMENTAL) + + A terminal with UTF-8 support and monospace narrow text are required. + + The character substitutions used in the graph can be customized with + variables in the [beautifygraph] section: + + / ``beautifygraph.edge.diagonal1`` + \ ``beautifygraph.edge.diagonal2`` + - ``beautifygraph.edge.horizontal`` + | ``beautifygraph.edge.vertical`` + : ``beautifygraph.edge.verticaldotted`` + -+- ``beautifygraph.edge.cross`` + -+ ``beautifygraph.edge.verticalleft`` + +- ``beautifygraph.edge.verticalright`` + ~ ``beautifygraph.edge.verticalstop`` + _ ``beautifygraph.node.closesbranch`` + @ ``beautifygraph.node.current`` + x ``beautifygraph.node.obsolete`` + o ``beautifygraph.node.other`` + * ``beautifygraph.node.unstable`` + + (use 'hg help extensions' for information on enabling extensions) + @ (34) head | | o (33) head @@ -3112,3 +3138,84 @@ $ cd .. + +Construct a magical repo whose ascii graph log contains all the possible symbols. + + $ hg init configuration + $ cd configuration + + $ touch file0 + $ hg commit -Aqm revision0 + $ touch file1 + $ hg commit -Aqm revision1 + $ touch file2 + $ hg commit -Aqm revision2 + $ touch file3 + $ hg commit -Aqm revision3 + $ hg update -q null + $ touch file4 + $ hg commit -Aqm revision4 + $ hg update -q 3 + $ hg merge -q 4 + $ touch file5 + $ hg commit -Aqm revision5 + $ hg update -q null + $ touch file6 + $ hg branch -q foo + $ hg commit -Aqm revision6 + $ hg merge -q 3 + $ touch file7 + $ hg commit -Aqm revision7 --close-branch + $ hg update -q 4 + $ hg merge -q 3 + $ touch file8 + $ hg commit -Aqm revision8 + $ hg update -q 6 + $ hg merge -q 5 + $ touch file9 + $ hg commit -Aqm revision9 + $ touch file10 + $ hg commit -Aqm revision10 + $ hg debugobsolete `hg log -r 9 -T '{node}'` + obsoleted 1 changesets + 1 new orphan changesets + $ hg update -q 8 + +All symbols should be configurable. + + $ hg log -G -q -r '(1:)-2' \ + > --config beautifygraph.edge.diagonal1=a \ + > --config beautifygraph.edge.diagonal2=b \ + > --config beautifygraph.edge.cross=c \ + > --config beautifygraph.edge.horizontal=d \ + > --config beautifygraph.edge.vertical=e \ + > --config beautifygraph.edge.verticaldotted=f \ + > --config beautifygraph.edge.verticalleft=g \ + > --config beautifygraph.edge.verticalright=h \ + > --config beautifygraph.edge.verticalstop=i \ + > --config beautifygraph.node.closesbranch=j \ + > --config beautifygraph.node.current=📎 \ + > --config beautifygraph.node.obsolete=l \ + > --config beautifygraph.node.other=m \ + > --config beautifygraph.node.unstable=n + n 10:3bf4adf1e513 + e + l 9:a4d281932d8a + eb + e e 📎 8:b9029cea3597 (esc) + e e eb + e hdcdddj 7:12cd82bb4409 + e e e e + e m e e 6:11bb041c7deb + e a a + mdddg 5:0b61ae539b30 + ea a + e m 4:f2e786cf2f3d + e + m 3:561d8244024e + f + m 1:388ecb15405b + e + i + + $ cd ..