hgext/fastannotate/formatter.py
changeset 43077 687b865b95ad
parent 43076 2372284d9457
child 46114 59fa3890d40a
equal deleted inserted replaced
43076:2372284d9457 43077:687b865b95ad
    31         datefunc = util.cachefunc(datefunc)
    31         datefunc = util.cachefunc(datefunc)
    32         getctx = util.cachefunc(lambda x: repo[x[0]])
    32         getctx = util.cachefunc(lambda x: repo[x[0]])
    33         hexfunc = self._hexfunc
    33         hexfunc = self._hexfunc
    34 
    34 
    35         # special handling working copy "changeset" and "rev" functions
    35         # special handling working copy "changeset" and "rev" functions
    36         if self.opts.get('rev') == 'wdir()':
    36         if self.opts.get(b'rev') == b'wdir()':
    37             orig = hexfunc
    37             orig = hexfunc
    38             hexfunc = lambda x: None if x is None else orig(x)
    38             hexfunc = lambda x: None if x is None else orig(x)
    39             wnode = hexfunc(repo['.'].node()) + '+'
    39             wnode = hexfunc(repo[b'.'].node()) + b'+'
    40             wrev = '%d' % repo['.'].rev()
    40             wrev = b'%d' % repo[b'.'].rev()
    41             wrevpad = ''
    41             wrevpad = b''
    42             if not opts.get('changeset'):  # only show + if changeset is hidden
    42             if not opts.get(b'changeset'):  # only show + if changeset is hidden
    43                 wrev += '+'
    43                 wrev += b'+'
    44                 wrevpad = ' '
    44                 wrevpad = b' '
    45             revenc = lambda x: wrev if x is None else ('%d' % x) + wrevpad
    45             revenc = lambda x: wrev if x is None else (b'%d' % x) + wrevpad
    46 
    46 
    47             def csetenc(x):
    47             def csetenc(x):
    48                 if x is None:
    48                 if x is None:
    49                     return wnode
    49                     return wnode
    50                 return pycompat.bytestr(x) + ' '
    50                 return pycompat.bytestr(x) + b' '
    51 
    51 
    52         else:
    52         else:
    53             revenc = csetenc = pycompat.bytestr
    53             revenc = csetenc = pycompat.bytestr
    54 
    54 
    55         # opt name, separator, raw value (for json/plain), encoder (for plain)
    55         # opt name, separator, raw value (for json/plain), encoder (for plain)
    56         opmap = [
    56         opmap = [
    57             ('user', ' ', lambda x: getctx(x).user(), ui.shortuser),
    57             (b'user', b' ', lambda x: getctx(x).user(), ui.shortuser),
    58             ('number', ' ', lambda x: getctx(x).rev(), revenc),
    58             (b'number', b' ', lambda x: getctx(x).rev(), revenc),
    59             ('changeset', ' ', lambda x: hexfunc(x[0]), csetenc),
    59             (b'changeset', b' ', lambda x: hexfunc(x[0]), csetenc),
    60             ('date', ' ', lambda x: getctx(x).date(), datefunc),
    60             (b'date', b' ', lambda x: getctx(x).date(), datefunc),
    61             ('file', ' ', lambda x: x[2], pycompat.bytestr),
    61             (b'file', b' ', lambda x: x[2], pycompat.bytestr),
    62             ('line_number', ':', lambda x: x[1] + 1, pycompat.bytestr),
    62             (b'line_number', b':', lambda x: x[1] + 1, pycompat.bytestr),
    63         ]
    63         ]
    64         fieldnamemap = {'number': 'rev', 'changeset': 'node'}
    64         fieldnamemap = {b'number': b'rev', b'changeset': b'node'}
    65         funcmap = [
    65         funcmap = [
    66             (get, sep, fieldnamemap.get(op, op), enc)
    66             (get, sep, fieldnamemap.get(op, op), enc)
    67             for op, sep, get, enc in opmap
    67             for op, sep, get, enc in opmap
    68             if opts.get(op)
    68             if opts.get(op)
    69         ]
    69         ]
    70         # no separator for first column
    70         # no separator for first column
    71         funcmap[0] = list(funcmap[0])
    71         funcmap[0] = list(funcmap[0])
    72         funcmap[0][1] = ''
    72         funcmap[0][1] = b''
    73         self.funcmap = funcmap
    73         self.funcmap = funcmap
    74 
    74 
    75     def write(self, annotatedresult, lines=None, existinglines=None):
    75     def write(self, annotatedresult, lines=None, existinglines=None):
    76         """(annotateresult, [str], set([rev, linenum])) -> None. write output.
    76         """(annotateresult, [str], set([rev, linenum])) -> None. write output.
    77         annotateresult can be [(node, linenum, path)], or [(node, linenum)]
    77         annotateresult can be [(node, linenum, path)], or [(node, linenum)]
    81 
    81 
    82         # calculate padding
    82         # calculate padding
    83         for f, sep, name, enc in self.funcmap:
    83         for f, sep, name, enc in self.funcmap:
    84             l = [enc(f(x)) for x in annotatedresult]
    84             l = [enc(f(x)) for x in annotatedresult]
    85             pieces.append(l)
    85             pieces.append(l)
    86             if name in ['node', 'date']:  # node and date has fixed size
    86             if name in [b'node', b'date']:  # node and date has fixed size
    87                 l = l[:1]
    87                 l = l[:1]
    88             widths = pycompat.maplist(encoding.colwidth, set(l))
    88             widths = pycompat.maplist(encoding.colwidth, set(l))
    89             maxwidth = max(widths) if widths else 0
    89             maxwidth = max(widths) if widths else 0
    90             maxwidths.append(maxwidth)
    90             maxwidths.append(maxwidth)
    91 
    91 
    92         # buffered output
    92         # buffered output
    93         result = ''
    93         result = b''
    94         for i in pycompat.xrange(len(annotatedresult)):
    94         for i in pycompat.xrange(len(annotatedresult)):
    95             for j, p in enumerate(pieces):
    95             for j, p in enumerate(pieces):
    96                 sep = self.funcmap[j][1]
    96                 sep = self.funcmap[j][1]
    97                 padding = ' ' * (maxwidths[j] - len(p[i]))
    97                 padding = b' ' * (maxwidths[j] - len(p[i]))
    98                 result += sep + padding + p[i]
    98                 result += sep + padding + p[i]
    99             if lines:
    99             if lines:
   100                 if existinglines is None:
   100                 if existinglines is None:
   101                     result += ': ' + lines[i]
   101                     result += b': ' + lines[i]
   102                 else:  # extra formatting showing whether a line exists
   102                 else:  # extra formatting showing whether a line exists
   103                     key = (annotatedresult[i][0], annotatedresult[i][1])
   103                     key = (annotatedresult[i][0], annotatedresult[i][1])
   104                     if key in existinglines:
   104                     if key in existinglines:
   105                         result += ':  ' + lines[i]
   105                         result += b':  ' + lines[i]
   106                     else:
   106                     else:
   107                         result += ': ' + self.ui.label(
   107                         result += b': ' + self.ui.label(
   108                             '-' + lines[i], 'diff.deleted'
   108                             b'-' + lines[i], b'diff.deleted'
   109                         )
   109                         )
   110 
   110 
   111             if result[-1:] != '\n':
   111             if result[-1:] != b'\n':
   112                 result += '\n'
   112                 result += b'\n'
   113 
   113 
   114         self.ui.write(result)
   114         self.ui.write(result)
   115 
   115 
   116     @util.propertycache
   116     @util.propertycache
   117     def _hexfunc(self):
   117     def _hexfunc(self):
   118         if self.ui.debugflag or self.opts.get('long_hash'):
   118         if self.ui.debugflag or self.opts.get(b'long_hash'):
   119             return node.hex
   119             return node.hex
   120         else:
   120         else:
   121             return node.short
   121             return node.short
   122 
   122 
   123     def end(self):
   123     def end(self):
   125 
   125 
   126 
   126 
   127 class jsonformatter(defaultformatter):
   127 class jsonformatter(defaultformatter):
   128     def __init__(self, ui, repo, opts):
   128     def __init__(self, ui, repo, opts):
   129         super(jsonformatter, self).__init__(ui, repo, opts)
   129         super(jsonformatter, self).__init__(ui, repo, opts)
   130         self.ui.write('[')
   130         self.ui.write(b'[')
   131         self.needcomma = False
   131         self.needcomma = False
   132 
   132 
   133     def write(self, annotatedresult, lines=None, existinglines=None):
   133     def write(self, annotatedresult, lines=None, existinglines=None):
   134         if annotatedresult:
   134         if annotatedresult:
   135             self._writecomma()
   135             self._writecomma()
   137         pieces = [
   137         pieces = [
   138             (name, pycompat.maplist(f, annotatedresult))
   138             (name, pycompat.maplist(f, annotatedresult))
   139             for f, sep, name, enc in self.funcmap
   139             for f, sep, name, enc in self.funcmap
   140         ]
   140         ]
   141         if lines is not None:
   141         if lines is not None:
   142             pieces.append(('line', lines))
   142             pieces.append((b'line', lines))
   143         pieces.sort()
   143         pieces.sort()
   144 
   144 
   145         seps = [','] * len(pieces[:-1]) + ['']
   145         seps = [b','] * len(pieces[:-1]) + [b'']
   146 
   146 
   147         result = ''
   147         result = b''
   148         lasti = len(annotatedresult) - 1
   148         lasti = len(annotatedresult) - 1
   149         for i in pycompat.xrange(len(annotatedresult)):
   149         for i in pycompat.xrange(len(annotatedresult)):
   150             result += '\n {\n'
   150             result += b'\n {\n'
   151             for j, p in enumerate(pieces):
   151             for j, p in enumerate(pieces):
   152                 k, vs = p
   152                 k, vs = p
   153                 result += '  "%s": %s%s\n' % (
   153                 result += b'  "%s": %s%s\n' % (
   154                     k,
   154                     k,
   155                     templatefilters.json(vs[i], paranoid=False),
   155                     templatefilters.json(vs[i], paranoid=False),
   156                     seps[j],
   156                     seps[j],
   157                 )
   157                 )
   158             result += ' }%s' % ('' if i == lasti else ',')
   158             result += b' }%s' % (b'' if i == lasti else b',')
   159         if lasti >= 0:
   159         if lasti >= 0:
   160             self.needcomma = True
   160             self.needcomma = True
   161 
   161 
   162         self.ui.write(result)
   162         self.ui.write(result)
   163 
   163 
   164     def _writecomma(self):
   164     def _writecomma(self):
   165         if self.needcomma:
   165         if self.needcomma:
   166             self.ui.write(',')
   166             self.ui.write(b',')
   167             self.needcomma = False
   167             self.needcomma = False
   168 
   168 
   169     @util.propertycache
   169     @util.propertycache
   170     def _hexfunc(self):
   170     def _hexfunc(self):
   171         return node.hex
   171         return node.hex
   172 
   172 
   173     def end(self):
   173     def end(self):
   174         self.ui.write('\n]\n')
   174         self.ui.write(b'\n]\n')