mercurial/formatter.py
author Yuya Nishihara <yuya@tcha.org>
Fri, 16 Mar 2018 22:36:40 +0900
changeset 37070 04aafcec00b9
parent 36992 de117f579431
child 37076 44757e6dad93
permissions -rw-r--r--
templater: add context.preload(t) to test if the specified template exists I'm going to remove 'templ' from the resources dict because it is the only resource that the caller can't provide. This also implies that putting 'templ' into the resources dict creates a reference cycle. context.preload(t) will be used in place of templater.__contains__().
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     1
# formatter.py - generic output formatting for mercurial
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
#
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     3
# Copyright 2012 Matt Mackall <mpm@selenic.com>
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
#
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
30565
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
     8
"""Generic output formatting for Mercurial
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
     9
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    10
The formatter provides API to show data in various ways. The following
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    11
functions should be used in place of ui.write():
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    12
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    13
- fm.write() for unconditional output
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    14
- fm.condwrite() to show some extra data conditionally in plain output
31182
16272d8c24f6 formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents: 31180
diff changeset
    15
- fm.context() to provide changectx to template output
30565
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    16
- fm.data() to provide extra data to JSON or template output
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    17
- fm.plain() to show raw text that isn't provided to JSON or template output
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    18
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    19
To show structured data (e.g. date tuples, dicts, lists), apply fm.format*()
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    20
beforehand so the data is converted to the appropriate data type. Use
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    21
fm.isplain() if you need to convert or format data conditionally which isn't
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    22
supported by the formatter API.
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    23
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    24
To build nested structure (i.e. a list of dicts), use fm.nested().
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    25
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    26
See also https://www.mercurial-scm.org/wiki/GenericTemplatingPlan
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    27
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    28
fm.condwrite() vs 'if cond:':
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    29
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    30
In most cases, use fm.condwrite() so users can selectively show the data
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    31
in template output. If it's costly to build data, use plain 'if cond:' with
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    32
fm.write().
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    33
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    34
fm.nested() vs fm.formatdict() (or fm.formatlist()):
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    35
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    36
fm.nested() should be used to form a tree structure (a list of dicts of
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    37
lists of dicts...) which can be accessed through template keywords, e.g.
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    38
"{foo % "{bar % {...}} {baz % {...}}"}". On the other hand, fm.formatdict()
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    39
exports a dict-type object to template, which can be accessed by e.g.
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    40
"{get(foo, key)}" function.
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    41
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    42
Doctest helper:
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    43
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    44
>>> def show(fn, verbose=False, **opts):
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    45
...     import sys
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    46
...     from . import ui as uimod
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    47
...     ui = uimod.ui()
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    48
...     ui.verbose = verbose
34262
d6af8da4a3b8 py3: rewrite stdout hack of doctest by using ui.pushbuffer()
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
    49
...     ui.pushbuffer()
d6af8da4a3b8 py3: rewrite stdout hack of doctest by using ui.pushbuffer()
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
    50
...     try:
34263
ebe3d0095c69 py3: convert system strings to bytes in doctest of formatter.py
Yuya Nishihara <yuya@tcha.org>
parents: 34262
diff changeset
    51
...         return fn(ui, ui.formatter(pycompat.sysbytes(fn.__name__),
ebe3d0095c69 py3: convert system strings to bytes in doctest of formatter.py
Yuya Nishihara <yuya@tcha.org>
parents: 34262
diff changeset
    52
...                   pycompat.byteskwargs(opts)))
34262
d6af8da4a3b8 py3: rewrite stdout hack of doctest by using ui.pushbuffer()
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
    53
...     finally:
d6af8da4a3b8 py3: rewrite stdout hack of doctest by using ui.pushbuffer()
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
    54
...         print(pycompat.sysstr(ui.popbuffer()), end='')
30565
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    55
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    56
Basic example:
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    57
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    58
>>> def files(ui, fm):
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33102
diff changeset
    59
...     files = [(b'foo', 123, (0, 0)), (b'bar', 456, (1, 0))]
30565
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    60
...     for f in files:
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    61
...         fm.startitem()
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33102
diff changeset
    62
...         fm.write(b'path', b'%s', f[0])
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33102
diff changeset
    63
...         fm.condwrite(ui.verbose, b'date', b'  %s',
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33102
diff changeset
    64
...                      fm.formatdate(f[2], b'%Y-%m-%d %H:%M:%S'))
30565
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    65
...         fm.data(size=f[1])
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33102
diff changeset
    66
...         fm.plain(b'\\n')
30565
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    67
...     fm.end()
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    68
>>> show(files)
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    69
foo
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    70
bar
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    71
>>> show(files, verbose=True)
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    72
foo  1970-01-01 00:00:00
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    73
bar  1970-01-01 00:00:01
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33102
diff changeset
    74
>>> show(files, template=b'json')
30565
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    75
[
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    76
 {
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    77
  "date": [0, 0],
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    78
  "path": "foo",
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    79
  "size": 123
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    80
 },
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    81
 {
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    82
  "date": [1, 0],
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    83
  "path": "bar",
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    84
  "size": 456
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    85
 }
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    86
]
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33102
diff changeset
    87
>>> show(files, template=b'path: {path}\\ndate: {date|rfc3339date}\\n')
30565
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    88
path: foo
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    89
date: 1970-01-01T00:00:00+00:00
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    90
path: bar
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    91
date: 1970-01-01T00:00:01+00:00
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    92
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    93
Nested example:
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    94
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    95
>>> def subrepos(ui, fm):
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    96
...     fm.startitem()
35474
a33be093ec62 templater: look up symbols/resources as if they were separated (issue5699)
Yuya Nishihara <yuya@tcha.org>
parents: 35473
diff changeset
    97
...     fm.write(b'reponame', b'[%s]\\n', b'baz')
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33102
diff changeset
    98
...     files(ui, fm.nested(b'files'))
30565
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
    99
...     fm.end()
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
   100
>>> show(subrepos)
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
   101
[baz]
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
   102
foo
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
   103
bar
35474
a33be093ec62 templater: look up symbols/resources as if they were separated (issue5699)
Yuya Nishihara <yuya@tcha.org>
parents: 35473
diff changeset
   104
>>> show(subrepos, template=b'{reponame}: {join(files % "{path}", ", ")}\\n')
30565
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
   105
baz: foo, bar
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
   106
"""
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29953
diff changeset
   107
34262
d6af8da4a3b8 py3: rewrite stdout hack of doctest by using ui.pushbuffer()
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
   108
from __future__ import absolute_import, print_function
25950
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
   109
32856
615ec3f14aa9 formatter: wrap (tmpl, mapfile) by named tuple
Yuya Nishihara <yuya@tcha.org>
parents: 32853
diff changeset
   110
import collections
32606
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32605
diff changeset
   111
import contextlib
31807
e6eb86b154c5 templater: provide loop counter as "index" keyword
Yuya Nishihara <yuya@tcha.org>
parents: 31805
diff changeset
   112
import itertools
25511
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   113
import os
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   114
25950
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
   115
from .i18n import _
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
   116
from .node import (
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
   117
    hex,
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
   118
    short,
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
   119
)
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
   120
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
   121
from . import (
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26373
diff changeset
   122
    error,
32208
0fd15522a848 py3: use pycompat.byteskwargs to converts kwargs to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31925
diff changeset
   123
    pycompat,
31785
654e9a1c8a6c formatter: use templatefilters.json()
Yuya Nishihara <yuya@tcha.org>
parents: 31405
diff changeset
   124
    templatefilters,
29690
c3a9cd78b151 formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents: 29324
diff changeset
   125
    templatekw,
25950
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
   126
    templater,
36926
6ff6e1d6b5b8 templater: move stringify() to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36663
diff changeset
   127
    templateutil,
29324
b501579147f1 py3: conditionalize cPickle import by adding in util
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28957
diff changeset
   128
    util,
25950
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
   129
)
36636
c6061cadb400 util: extract all date-related utils in utils/dateutil module
Boris Feld <boris.feld@octobus.net>
parents: 36475
diff changeset
   130
from .utils import dateutil
25950
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
   131
29324
b501579147f1 py3: conditionalize cPickle import by adding in util
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28957
diff changeset
   132
pickle = util.pickle
b501579147f1 py3: conditionalize cPickle import by adding in util
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28957
diff changeset
   133
29847
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   134
class _nullconverter(object):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   135
    '''convert non-primitive data types to be processed by formatter'''
33102
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 32970
diff changeset
   136
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 32970
diff changeset
   137
    # set to True if context object should be stored as item
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 32970
diff changeset
   138
    storecontext = False
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 32970
diff changeset
   139
29847
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   140
    @staticmethod
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   141
    def formatdate(date, fmt):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   142
        '''convert date tuple to appropriate format'''
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   143
        return date
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   144
    @staticmethod
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   145
    def formatdict(data, key, value, fmt, sep):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   146
        '''convert dict or key-value pairs to appropriate dict format'''
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   147
        # use plain dict instead of util.sortdict so that data can be
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   148
        # serialized as a builtin dict in pickle output
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   149
        return dict(data)
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   150
    @staticmethod
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   151
    def formatlist(data, name, fmt, sep):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   152
        '''convert iterable to appropriate list format'''
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   153
        return list(data)
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   154
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   155
class baseformatter(object):
29847
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   156
    def __init__(self, ui, topic, opts, converter):
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   157
        self._ui = ui
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   158
        self._topic = topic
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   159
        self._style = opts.get("style")
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   160
        self._template = opts.get("template")
29847
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   161
        self._converter = converter
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   162
        self._item = None
22701
cb28d2b3db0b formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents: 22674
diff changeset
   163
        # function to convert node to string suitable for this output
cb28d2b3db0b formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents: 22674
diff changeset
   164
        self.hexfunc = hex
29886
307b20e5e505 formatter: add context manager interface for convenience
Yuya Nishihara <yuya@tcha.org>
parents: 29848
diff changeset
   165
    def __enter__(self):
307b20e5e505 formatter: add context manager interface for convenience
Yuya Nishihara <yuya@tcha.org>
parents: 29848
diff changeset
   166
        return self
307b20e5e505 formatter: add context manager interface for convenience
Yuya Nishihara <yuya@tcha.org>
parents: 29848
diff changeset
   167
    def __exit__(self, exctype, excvalue, traceback):
307b20e5e505 formatter: add context manager interface for convenience
Yuya Nishihara <yuya@tcha.org>
parents: 29848
diff changeset
   168
        if exctype is None:
307b20e5e505 formatter: add context manager interface for convenience
Yuya Nishihara <yuya@tcha.org>
parents: 29848
diff changeset
   169
            self.end()
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   170
    def _showitem(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   171
        '''show a formatted item once all data is collected'''
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   172
    def startitem(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   173
        '''begin an item in the format list'''
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   174
        if self._item is not None:
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   175
            self._showitem()
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   176
        self._item = {}
29847
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   177
    def formatdate(self, date, fmt='%a %b %d %H:%M:%S %Y %1%2'):
29692
2f3f18ad55a2 formatter: add function to convert date tuple to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents: 29690
diff changeset
   178
        '''convert date tuple to appropriate format'''
29847
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   179
        return self._converter.formatdate(date, fmt)
36662
034a07e60e98 templater: allow dynamically switching the default dict/list formatting
Yuya Nishihara <yuya@tcha.org>
parents: 36636
diff changeset
   180
    def formatdict(self, data, key='key', value='value', fmt=None, sep=' '):
29805
4891f3b93182 formatter: add function to convert dict to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents: 29692
diff changeset
   181
        '''convert dict or key-value pairs to appropriate dict format'''
29847
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   182
        return self._converter.formatdict(data, key, value, fmt, sep)
36662
034a07e60e98 templater: allow dynamically switching the default dict/list formatting
Yuya Nishihara <yuya@tcha.org>
parents: 36636
diff changeset
   183
    def formatlist(self, data, name, fmt=None, sep=' '):
29690
c3a9cd78b151 formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents: 29324
diff changeset
   184
        '''convert iterable to appropriate list format'''
29847
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   185
        # name is mandatory argument for now, but it could be optional if
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   186
        # we have default template keyword, e.g. {item}
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   187
        return self._converter.formatlist(data, name, fmt, sep)
31182
16272d8c24f6 formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents: 31180
diff changeset
   188
    def context(self, **ctxs):
16272d8c24f6 formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents: 31180
diff changeset
   189
        '''insert context objects to be used to render template keywords'''
33102
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 32970
diff changeset
   190
        ctxs = pycompat.byteskwargs(ctxs)
36987
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 36986
diff changeset
   191
        assert all(k in {'ctx', 'fctx'} for k in ctxs)
33102
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 32970
diff changeset
   192
        if self._converter.storecontext:
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 32970
diff changeset
   193
            self._item.update(ctxs)
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   194
    def data(self, **data):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   195
        '''insert data into item that's not shown in default output'''
32208
0fd15522a848 py3: use pycompat.byteskwargs to converts kwargs to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31925
diff changeset
   196
        data = pycompat.byteskwargs(data)
17630
ff5ed1ecd43a formatter: improve implementation of data method
David M. Carr <david@carrclan.us>
parents: 17597
diff changeset
   197
        self._item.update(data)
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   198
    def write(self, fields, deftext, *fielddata, **opts):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   199
        '''do default text output while assigning data to item'''
26372
55de800937e0 formatter: verify number of arguments passed to write functions
Yuya Nishihara <yuya@tcha.org>
parents: 25950
diff changeset
   200
        fieldkeys = fields.split()
55de800937e0 formatter: verify number of arguments passed to write functions
Yuya Nishihara <yuya@tcha.org>
parents: 25950
diff changeset
   201
        assert len(fieldkeys) == len(fielddata)
26373
aa610ffad4e8 formatter: use dict.update() to set arguments passed to write functions
Yuya Nishihara <yuya@tcha.org>
parents: 26372
diff changeset
   202
        self._item.update(zip(fieldkeys, fielddata))
17909
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
   203
    def condwrite(self, cond, fields, deftext, *fielddata, **opts):
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
   204
        '''do conditional write (primarily for plain formatter)'''
26372
55de800937e0 formatter: verify number of arguments passed to write functions
Yuya Nishihara <yuya@tcha.org>
parents: 25950
diff changeset
   205
        fieldkeys = fields.split()
55de800937e0 formatter: verify number of arguments passed to write functions
Yuya Nishihara <yuya@tcha.org>
parents: 25950
diff changeset
   206
        assert len(fieldkeys) == len(fielddata)
26373
aa610ffad4e8 formatter: use dict.update() to set arguments passed to write functions
Yuya Nishihara <yuya@tcha.org>
parents: 26372
diff changeset
   207
        self._item.update(zip(fieldkeys, fielddata))
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   208
    def plain(self, text, **opts):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   209
        '''show raw text for non-templated mode'''
29953
e7cacb45c4be formatter: introduce isplain() to replace (the inverse of) __nonzero__() (API)
Mathias De Maré <mathias.demare@gmail.com>
parents: 29886
diff changeset
   210
    def isplain(self):
e7cacb45c4be formatter: introduce isplain() to replace (the inverse of) __nonzero__() (API)
Mathias De Maré <mathias.demare@gmail.com>
parents: 29886
diff changeset
   211
        '''check for plain formatter usage'''
e7cacb45c4be formatter: introduce isplain() to replace (the inverse of) __nonzero__() (API)
Mathias De Maré <mathias.demare@gmail.com>
parents: 29886
diff changeset
   212
        return False
29848
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 29847
diff changeset
   213
    def nested(self, field):
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 29847
diff changeset
   214
        '''sub formatter to store nested data in the specified field'''
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 29847
diff changeset
   215
        self._item[field] = data = []
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 29847
diff changeset
   216
        return _nestedformatter(self._ui, self._converter, data)
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   217
    def end(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   218
        '''end output for the formatter'''
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   219
        if self._item is not None:
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   220
            self._showitem()
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   221
32607
e9bf3e132ea9 formatter: add nullformatter
Yuya Nishihara <yuya@tcha.org>
parents: 32606
diff changeset
   222
def nullformatter(ui, topic):
e9bf3e132ea9 formatter: add nullformatter
Yuya Nishihara <yuya@tcha.org>
parents: 32606
diff changeset
   223
    '''formatter that prints nothing'''
e9bf3e132ea9 formatter: add nullformatter
Yuya Nishihara <yuya@tcha.org>
parents: 32606
diff changeset
   224
    return baseformatter(ui, topic, opts={}, converter=_nullconverter)
e9bf3e132ea9 formatter: add nullformatter
Yuya Nishihara <yuya@tcha.org>
parents: 32606
diff changeset
   225
29848
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 29847
diff changeset
   226
class _nestedformatter(baseformatter):
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 29847
diff changeset
   227
    '''build sub items and store them in the parent formatter'''
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 29847
diff changeset
   228
    def __init__(self, ui, converter, data):
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 29847
diff changeset
   229
        baseformatter.__init__(self, ui, topic='', opts={}, converter=converter)
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 29847
diff changeset
   230
        self._data = data
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 29847
diff changeset
   231
    def _showitem(self):
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 29847
diff changeset
   232
        self._data.append(self._item)
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 29847
diff changeset
   233
29805
4891f3b93182 formatter: add function to convert dict to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents: 29692
diff changeset
   234
def _iteritems(data):
4891f3b93182 formatter: add function to convert dict to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents: 29692
diff changeset
   235
    '''iterate key-value pairs in stable order'''
4891f3b93182 formatter: add function to convert dict to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents: 29692
diff changeset
   236
    if isinstance(data, dict):
4891f3b93182 formatter: add function to convert dict to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents: 29692
diff changeset
   237
        return sorted(data.iteritems())
4891f3b93182 formatter: add function to convert dict to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents: 29692
diff changeset
   238
    return data
4891f3b93182 formatter: add function to convert dict to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents: 29692
diff changeset
   239
29847
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   240
class _plainconverter(object):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   241
    '''convert non-primitive data types to text'''
33102
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 32970
diff changeset
   242
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 32970
diff changeset
   243
    storecontext = False
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 32970
diff changeset
   244
29847
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   245
    @staticmethod
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   246
    def formatdate(date, fmt):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   247
        '''stringify date tuple in the given format'''
36636
c6061cadb400 util: extract all date-related utils in utils/dateutil module
Boris Feld <boris.feld@octobus.net>
parents: 36475
diff changeset
   248
        return dateutil.datestr(date, fmt)
29847
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   249
    @staticmethod
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   250
    def formatdict(data, key, value, fmt, sep):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   251
        '''stringify key-value pairs separated by sep'''
36663
cafd0586876b templater: byte-stringify dict/list values before passing to default format
Yuya Nishihara <yuya@tcha.org>
parents: 36662
diff changeset
   252
        prefmt = pycompat.identity
36662
034a07e60e98 templater: allow dynamically switching the default dict/list formatting
Yuya Nishihara <yuya@tcha.org>
parents: 36636
diff changeset
   253
        if fmt is None:
034a07e60e98 templater: allow dynamically switching the default dict/list formatting
Yuya Nishihara <yuya@tcha.org>
parents: 36636
diff changeset
   254
            fmt = '%s=%s'
36663
cafd0586876b templater: byte-stringify dict/list values before passing to default format
Yuya Nishihara <yuya@tcha.org>
parents: 36662
diff changeset
   255
            prefmt = pycompat.bytestr
cafd0586876b templater: byte-stringify dict/list values before passing to default format
Yuya Nishihara <yuya@tcha.org>
parents: 36662
diff changeset
   256
        return sep.join(fmt % (prefmt(k), prefmt(v))
cafd0586876b templater: byte-stringify dict/list values before passing to default format
Yuya Nishihara <yuya@tcha.org>
parents: 36662
diff changeset
   257
                        for k, v in _iteritems(data))
29847
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   258
    @staticmethod
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   259
    def formatlist(data, name, fmt, sep):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   260
        '''stringify iterable separated by sep'''
36663
cafd0586876b templater: byte-stringify dict/list values before passing to default format
Yuya Nishihara <yuya@tcha.org>
parents: 36662
diff changeset
   261
        prefmt = pycompat.identity
36662
034a07e60e98 templater: allow dynamically switching the default dict/list formatting
Yuya Nishihara <yuya@tcha.org>
parents: 36636
diff changeset
   262
        if fmt is None:
034a07e60e98 templater: allow dynamically switching the default dict/list formatting
Yuya Nishihara <yuya@tcha.org>
parents: 36636
diff changeset
   263
            fmt = '%s'
36663
cafd0586876b templater: byte-stringify dict/list values before passing to default format
Yuya Nishihara <yuya@tcha.org>
parents: 36662
diff changeset
   264
            prefmt = pycompat.bytestr
cafd0586876b templater: byte-stringify dict/list values before passing to default format
Yuya Nishihara <yuya@tcha.org>
parents: 36662
diff changeset
   265
        return sep.join(fmt % prefmt(e) for e in data)
29847
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   266
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   267
class plainformatter(baseformatter):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   268
    '''the default text output scheme'''
32605
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32208
diff changeset
   269
    def __init__(self, ui, out, topic, opts):
29847
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   270
        baseformatter.__init__(self, ui, topic, opts, _plainconverter)
22701
cb28d2b3db0b formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents: 22674
diff changeset
   271
        if ui.debugflag:
cb28d2b3db0b formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents: 22674
diff changeset
   272
            self.hexfunc = hex
cb28d2b3db0b formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents: 22674
diff changeset
   273
        else:
cb28d2b3db0b formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents: 22674
diff changeset
   274
            self.hexfunc = short
32605
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32208
diff changeset
   275
        if ui is out:
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32208
diff changeset
   276
            self._write = ui.write
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32208
diff changeset
   277
        else:
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32208
diff changeset
   278
            self._write = lambda s, **opts: out.write(s)
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   279
    def startitem(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   280
        pass
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   281
    def data(self, **data):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   282
        pass
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   283
    def write(self, fields, deftext, *fielddata, **opts):
32605
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32208
diff changeset
   284
        self._write(deftext % fielddata, **opts)
17909
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
   285
    def condwrite(self, cond, fields, deftext, *fielddata, **opts):
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
   286
        '''do conditional write'''
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
   287
        if cond:
32605
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32208
diff changeset
   288
            self._write(deftext % fielddata, **opts)
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   289
    def plain(self, text, **opts):
32605
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32208
diff changeset
   290
        self._write(text, **opts)
29953
e7cacb45c4be formatter: introduce isplain() to replace (the inverse of) __nonzero__() (API)
Mathias De Maré <mathias.demare@gmail.com>
parents: 29886
diff changeset
   291
    def isplain(self):
e7cacb45c4be formatter: introduce isplain() to replace (the inverse of) __nonzero__() (API)
Mathias De Maré <mathias.demare@gmail.com>
parents: 29886
diff changeset
   292
        return True
29848
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 29847
diff changeset
   293
    def nested(self, field):
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 29847
diff changeset
   294
        # nested data will be directly written to ui
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 29847
diff changeset
   295
        return self
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   296
    def end(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   297
        pass
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   298
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   299
class debugformatter(baseformatter):
31192
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31182
diff changeset
   300
    def __init__(self, ui, out, topic, opts):
29847
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   301
        baseformatter.__init__(self, ui, topic, opts, _nullconverter)
31192
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31182
diff changeset
   302
        self._out = out
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31182
diff changeset
   303
        self._out.write("%s = [\n" % self._topic)
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   304
    def _showitem(self):
36298
b44fac3a49fb py3: factor out byterepr() which returns an asciified value on py3
Yuya Nishihara <yuya@tcha.org>
parents: 36078
diff changeset
   305
        self._out.write('    %s,\n' % pycompat.byterepr(self._item))
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   306
    def end(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   307
        baseformatter.end(self)
31192
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31182
diff changeset
   308
        self._out.write("]\n")
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   309
22430
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
   310
class pickleformatter(baseformatter):
31192
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31182
diff changeset
   311
    def __init__(self, ui, out, topic, opts):
29847
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   312
        baseformatter.__init__(self, ui, topic, opts, _nullconverter)
31192
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31182
diff changeset
   313
        self._out = out
22430
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
   314
        self._data = []
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
   315
    def _showitem(self):
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
   316
        self._data.append(self._item)
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
   317
    def end(self):
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
   318
        baseformatter.end(self)
31192
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31182
diff changeset
   319
        self._out.write(pickle.dumps(self._data))
22430
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
   320
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   321
class jsonformatter(baseformatter):
31192
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31182
diff changeset
   322
    def __init__(self, ui, out, topic, opts):
29847
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   323
        baseformatter.__init__(self, ui, topic, opts, _nullconverter)
31192
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31182
diff changeset
   324
        self._out = out
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31182
diff changeset
   325
        self._out.write("[")
31307
59d09565ac77 formatter: set _first on formatter, not ui
Martin von Zweigbergk <martinvonz@google.com>
parents: 31192
diff changeset
   326
        self._first = True
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   327
    def _showitem(self):
31307
59d09565ac77 formatter: set _first on formatter, not ui
Martin von Zweigbergk <martinvonz@google.com>
parents: 31192
diff changeset
   328
        if self._first:
59d09565ac77 formatter: set _first on formatter, not ui
Martin von Zweigbergk <martinvonz@google.com>
parents: 31192
diff changeset
   329
            self._first = False
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   330
        else:
31192
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31182
diff changeset
   331
            self._out.write(",")
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   332
31192
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31182
diff changeset
   333
        self._out.write("\n {\n")
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   334
        first = True
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   335
        for k, v in sorted(self._item.items()):
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   336
            if first:
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   337
                first = False
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   338
            else:
31192
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31182
diff changeset
   339
                self._out.write(",\n")
31785
654e9a1c8a6c formatter: use templatefilters.json()
Yuya Nishihara <yuya@tcha.org>
parents: 31405
diff changeset
   340
            u = templatefilters.json(v, paranoid=False)
654e9a1c8a6c formatter: use templatefilters.json()
Yuya Nishihara <yuya@tcha.org>
parents: 31405
diff changeset
   341
            self._out.write('  "%s": %s' % (k, u))
31192
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31182
diff changeset
   342
        self._out.write("\n }")
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   343
    def end(self):
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   344
        baseformatter.end(self)
31192
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31182
diff changeset
   345
        self._out.write("\n]\n")
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   346
29847
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   347
class _templateconverter(object):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   348
    '''convert non-primitive data types to be processed by templater'''
33102
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 32970
diff changeset
   349
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 32970
diff changeset
   350
    storecontext = True
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 32970
diff changeset
   351
29847
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   352
    @staticmethod
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   353
    def formatdate(date, fmt):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   354
        '''return date tuple'''
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   355
        return date
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   356
    @staticmethod
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   357
    def formatdict(data, key, value, fmt, sep):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   358
        '''build object that can be evaluated as either plain string or dict'''
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   359
        data = util.sortdict(_iteritems(data))
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   360
        def f():
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   361
            yield _plainconverter.formatdict(data, key, value, fmt, sep)
36927
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36926
diff changeset
   362
        return templateutil.hybriddict(data, key=key, value=value, fmt=fmt,
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36926
diff changeset
   363
                                       gen=f)
29847
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   364
    @staticmethod
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   365
    def formatlist(data, name, fmt, sep):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   366
        '''build object that can be evaluated as either plain string or list'''
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   367
        data = list(data)
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   368
        def f():
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   369
            yield _plainconverter.formatlist(data, name, fmt, sep)
36927
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36926
diff changeset
   370
        return templateutil.hybridlist(data, name=name, fmt=fmt, gen=f)
29847
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   371
25513
0c6f98398f8a formatter: add template support
Matt Mackall <mpm@selenic.com>
parents: 25512
diff changeset
   372
class templateformatter(baseformatter):
31192
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31182
diff changeset
   373
    def __init__(self, ui, out, topic, opts):
29847
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29805
diff changeset
   374
        baseformatter.__init__(self, ui, topic, opts, _templateconverter)
31192
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31182
diff changeset
   375
        self._out = out
32851
99df35499cae formatter: inline gettemplater()
Yuya Nishihara <yuya@tcha.org>
parents: 32850
diff changeset
   376
        spec = lookuptemplate(ui, topic, opts.get('template', ''))
32859
883adaea9e80 formatter: render template specified by templatespec tuple
Yuya Nishihara <yuya@tcha.org>
parents: 32858
diff changeset
   377
        self._tref = spec.ref
35487
817a3d20dd01 templater: register keywords to defaults table
Yuya Nishihara <yuya@tcha.org>
parents: 35474
diff changeset
   378
        self._t = loadtemplater(ui, spec, defaults=templatekw.keywords,
817a3d20dd01 templater: register keywords to defaults table
Yuya Nishihara <yuya@tcha.org>
parents: 35474
diff changeset
   379
                                resources=templateresources(ui),
35473
f1c54d003327 templater: move repo, ui and cache to per-engine resources
Yuya Nishihara <yuya@tcha.org>
parents: 35472
diff changeset
   380
                                cache=templatekw.defaulttempl)
32967
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32966
diff changeset
   381
        self._parts = templatepartsmap(spec, self._t,
32968
5100ce217dfa formatter: add support for separator template
Yuya Nishihara <yuya@tcha.org>
parents: 32967
diff changeset
   382
                                       ['docheader', 'docfooter', 'separator'])
31807
e6eb86b154c5 templater: provide loop counter as "index" keyword
Yuya Nishihara <yuya@tcha.org>
parents: 31805
diff changeset
   383
        self._counter = itertools.count()
32967
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32966
diff changeset
   384
        self._renderitem('docheader', {})
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32966
diff changeset
   385
25513
0c6f98398f8a formatter: add template support
Matt Mackall <mpm@selenic.com>
parents: 25512
diff changeset
   386
    def _showitem(self):
32966
12a0794fa2e3 formatter: extract helper function to render template
Yuya Nishihara <yuya@tcha.org>
parents: 32915
diff changeset
   387
        item = self._item.copy()
32968
5100ce217dfa formatter: add support for separator template
Yuya Nishihara <yuya@tcha.org>
parents: 32967
diff changeset
   388
        item['index'] = index = next(self._counter)
5100ce217dfa formatter: add support for separator template
Yuya Nishihara <yuya@tcha.org>
parents: 32967
diff changeset
   389
        if index > 0:
5100ce217dfa formatter: add support for separator template
Yuya Nishihara <yuya@tcha.org>
parents: 32967
diff changeset
   390
            self._renderitem('separator', {})
32966
12a0794fa2e3 formatter: extract helper function to render template
Yuya Nishihara <yuya@tcha.org>
parents: 32915
diff changeset
   391
        self._renderitem(self._tref, item)
12a0794fa2e3 formatter: extract helper function to render template
Yuya Nishihara <yuya@tcha.org>
parents: 32915
diff changeset
   392
32967
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32966
diff changeset
   393
    def _renderitem(self, part, item):
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32966
diff changeset
   394
        if part not in self._parts:
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32966
diff changeset
   395
            return
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32966
diff changeset
   396
        ref = self._parts[part]
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32966
diff changeset
   397
31805
dca9b6922514 formatter: reorder code that builds template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 31785
diff changeset
   398
        props = {}
dca9b6922514 formatter: reorder code that builds template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 31785
diff changeset
   399
        # explicitly-defined fields precede templatekw
32966
12a0794fa2e3 formatter: extract helper function to render template
Yuya Nishihara <yuya@tcha.org>
parents: 32915
diff changeset
   400
        props.update(item)
36987
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 36986
diff changeset
   401
        if 'ctx' in item or 'fctx' in item:
31182
16272d8c24f6 formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents: 31180
diff changeset
   402
            # but template resources must be always available
16272d8c24f6 formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents: 31180
diff changeset
   403
            props['revcache'] = {}
36992
de117f579431 templater: factor out helper that renders named template as string
Yuya Nishihara <yuya@tcha.org>
parents: 36987
diff changeset
   404
        self._out.write(self._t.render(ref, props))
25513
0c6f98398f8a formatter: add template support
Matt Mackall <mpm@selenic.com>
parents: 25512
diff changeset
   405
32967
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32966
diff changeset
   406
    def end(self):
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32966
diff changeset
   407
        baseformatter.end(self)
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32966
diff changeset
   408
        self._renderitem('docfooter', {})
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32966
diff changeset
   409
32856
615ec3f14aa9 formatter: wrap (tmpl, mapfile) by named tuple
Yuya Nishihara <yuya@tcha.org>
parents: 32853
diff changeset
   410
templatespec = collections.namedtuple(r'templatespec',
32858
57c13c0d1cde formatter: put topic in templatespec tuple
Yuya Nishihara <yuya@tcha.org>
parents: 32856
diff changeset
   411
                                      r'ref tmpl mapfile')
32856
615ec3f14aa9 formatter: wrap (tmpl, mapfile) by named tuple
Yuya Nishihara <yuya@tcha.org>
parents: 32853
diff changeset
   412
25511
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   413
def lookuptemplate(ui, topic, tmpl):
32853
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 32851
diff changeset
   414
    """Find the template matching the given -T/--template spec 'tmpl'
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 32851
diff changeset
   415
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 32851
diff changeset
   416
    'tmpl' can be any of the following:
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 32851
diff changeset
   417
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 32851
diff changeset
   418
     - a literal template (e.g. '{rev}')
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 32851
diff changeset
   419
     - a map-file name or path (e.g. 'changelog')
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 32851
diff changeset
   420
     - a reference to [templates] in config file
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 32851
diff changeset
   421
     - a path to raw template file
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 32851
diff changeset
   422
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 32851
diff changeset
   423
    A map file defines a stand-alone template environment. If a map file
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 32851
diff changeset
   424
    selected, all templates defined in the file will be loaded, and the
34715
f17a0e18c47e templater: load aliases from [templatealias] section in map file
Yuya Nishihara <yuya@tcha.org>
parents: 34426
diff changeset
   425
    template matching the given topic will be rendered. Aliases won't be
f17a0e18c47e templater: load aliases from [templatealias] section in map file
Yuya Nishihara <yuya@tcha.org>
parents: 34426
diff changeset
   426
    loaded from user config, but from the map file.
32893
c8f2cf18b82e formatter: load templates section like a map file
Yuya Nishihara <yuya@tcha.org>
parents: 32891
diff changeset
   427
c8f2cf18b82e formatter: load templates section like a map file
Yuya Nishihara <yuya@tcha.org>
parents: 32891
diff changeset
   428
    If no map file selected, all templates in [templates] section will be
c8f2cf18b82e formatter: load templates section like a map file
Yuya Nishihara <yuya@tcha.org>
parents: 32891
diff changeset
   429
    available as well as aliases in [templatealias].
32853
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 32851
diff changeset
   430
    """
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 32851
diff changeset
   431
25511
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   432
    # looks like a literal template?
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   433
    if '{' in tmpl:
32893
c8f2cf18b82e formatter: load templates section like a map file
Yuya Nishihara <yuya@tcha.org>
parents: 32891
diff changeset
   434
        return templatespec('', tmpl, None)
25511
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   435
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   436
    # perhaps a stock style?
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   437
    if not os.path.split(tmpl)[0]:
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   438
        mapname = (templater.templatepath('map-cmdline.' + tmpl)
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   439
                   or templater.templatepath(tmpl))
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   440
        if mapname and os.path.isfile(mapname):
32858
57c13c0d1cde formatter: put topic in templatespec tuple
Yuya Nishihara <yuya@tcha.org>
parents: 32856
diff changeset
   441
            return templatespec(topic, None, mapname)
25511
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   442
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   443
    # perhaps it's a reference to [templates]
32893
c8f2cf18b82e formatter: load templates section like a map file
Yuya Nishihara <yuya@tcha.org>
parents: 32891
diff changeset
   444
    if ui.config('templates', tmpl):
c8f2cf18b82e formatter: load templates section like a map file
Yuya Nishihara <yuya@tcha.org>
parents: 32891
diff changeset
   445
        return templatespec(tmpl, None, None)
25511
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   446
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   447
    if tmpl == 'list':
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   448
        ui.write(_("available styles: %s\n") % templater.stylelist())
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26373
diff changeset
   449
        raise error.Abort(_("specify a template"))
25511
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   450
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   451
    # perhaps it's a path to a map or a template
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   452
    if ('/' in tmpl or '\\' in tmpl) and os.path.isfile(tmpl):
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   453
        # is it a mapfile for a style?
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   454
        if os.path.basename(tmpl).startswith("map-"):
32858
57c13c0d1cde formatter: put topic in templatespec tuple
Yuya Nishihara <yuya@tcha.org>
parents: 32856
diff changeset
   455
            return templatespec(topic, None, os.path.realpath(tmpl))
32848
470820c2418d formatter: open raw template file in posix semantics
Yuya Nishihara <yuya@tcha.org>
parents: 32847
diff changeset
   456
        with util.posixfile(tmpl, 'rb') as f:
32846
526f9f12f707 formatter: close raw template file explicitly
Yuya Nishihara <yuya@tcha.org>
parents: 32607
diff changeset
   457
            tmpl = f.read()
32893
c8f2cf18b82e formatter: load templates section like a map file
Yuya Nishihara <yuya@tcha.org>
parents: 32891
diff changeset
   458
        return templatespec('', tmpl, None)
25511
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   459
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   460
    # constant string?
32893
c8f2cf18b82e formatter: load templates section like a map file
Yuya Nishihara <yuya@tcha.org>
parents: 32891
diff changeset
   461
    return templatespec('', tmpl, None)
25511
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   462
32967
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32966
diff changeset
   463
def templatepartsmap(spec, t, partnames):
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32966
diff changeset
   464
    """Create a mapping of {part: ref}"""
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32966
diff changeset
   465
    partsmap = {spec.ref: spec.ref}  # initial ref must exist in t
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32966
diff changeset
   466
    if spec.mapfile:
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32966
diff changeset
   467
        partsmap.update((p, p) for p in partnames if p in t)
32970
61b60b28c381 formatter: add support for parts map of [templates] section
Yuya Nishihara <yuya@tcha.org>
parents: 32968
diff changeset
   468
    elif spec.ref:
61b60b28c381 formatter: add support for parts map of [templates] section
Yuya Nishihara <yuya@tcha.org>
parents: 32968
diff changeset
   469
        for part in partnames:
61b60b28c381 formatter: add support for parts map of [templates] section
Yuya Nishihara <yuya@tcha.org>
parents: 32968
diff changeset
   470
            ref = '%s:%s' % (spec.ref, part)  # select config sub-section
61b60b28c381 formatter: add support for parts map of [templates] section
Yuya Nishihara <yuya@tcha.org>
parents: 32968
diff changeset
   471
            if ref in t:
61b60b28c381 formatter: add support for parts map of [templates] section
Yuya Nishihara <yuya@tcha.org>
parents: 32968
diff changeset
   472
                partsmap[part] = ref
32967
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32966
diff changeset
   473
    return partsmap
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32966
diff changeset
   474
35487
817a3d20dd01 templater: register keywords to defaults table
Yuya Nishihara <yuya@tcha.org>
parents: 35474
diff changeset
   475
def loadtemplater(ui, spec, defaults=None, resources=None, cache=None):
32850
11e667a8fcba formatter: factor out function to create templater from literal or map file
Yuya Nishihara <yuya@tcha.org>
parents: 32848
diff changeset
   476
    """Create a templater from either a literal template or loading from
11e667a8fcba formatter: factor out function to create templater from literal or map file
Yuya Nishihara <yuya@tcha.org>
parents: 32848
diff changeset
   477
    a map file"""
32856
615ec3f14aa9 formatter: wrap (tmpl, mapfile) by named tuple
Yuya Nishihara <yuya@tcha.org>
parents: 32853
diff changeset
   478
    assert not (spec.tmpl and spec.mapfile)
615ec3f14aa9 formatter: wrap (tmpl, mapfile) by named tuple
Yuya Nishihara <yuya@tcha.org>
parents: 32853
diff changeset
   479
    if spec.mapfile:
35472
32c278eb876f templater: keep default resources per template engine (API)
Yuya Nishihara <yuya@tcha.org>
parents: 34715
diff changeset
   480
        frommapfile = templater.templater.frommapfile
35487
817a3d20dd01 templater: register keywords to defaults table
Yuya Nishihara <yuya@tcha.org>
parents: 35474
diff changeset
   481
        return frommapfile(spec.mapfile, defaults=defaults, resources=resources,
817a3d20dd01 templater: register keywords to defaults table
Yuya Nishihara <yuya@tcha.org>
parents: 35474
diff changeset
   482
                           cache=cache)
817a3d20dd01 templater: register keywords to defaults table
Yuya Nishihara <yuya@tcha.org>
parents: 35474
diff changeset
   483
    return maketemplater(ui, spec.tmpl, defaults=defaults, resources=resources,
817a3d20dd01 templater: register keywords to defaults table
Yuya Nishihara <yuya@tcha.org>
parents: 35474
diff changeset
   484
                         cache=cache)
28955
78759f78a44e templater: factor out function that creates templater from string template
Yuya Nishihara <yuya@tcha.org>
parents: 28954
diff changeset
   485
35487
817a3d20dd01 templater: register keywords to defaults table
Yuya Nishihara <yuya@tcha.org>
parents: 35474
diff changeset
   486
def maketemplater(ui, tmpl, defaults=None, resources=None, cache=None):
28955
78759f78a44e templater: factor out function that creates templater from string template
Yuya Nishihara <yuya@tcha.org>
parents: 28954
diff changeset
   487
    """Create a templater from a string template 'tmpl'"""
28957
d813132ea361 templater: load and expand aliases by template engine (API) (issue4842)
Yuya Nishihara <yuya@tcha.org>
parents: 28955
diff changeset
   488
    aliases = ui.configitems('templatealias')
35487
817a3d20dd01 templater: register keywords to defaults table
Yuya Nishihara <yuya@tcha.org>
parents: 35474
diff changeset
   489
    t = templater.templater(defaults=defaults, resources=resources,
817a3d20dd01 templater: register keywords to defaults table
Yuya Nishihara <yuya@tcha.org>
parents: 35474
diff changeset
   490
                            cache=cache, aliases=aliases)
32893
c8f2cf18b82e formatter: load templates section like a map file
Yuya Nishihara <yuya@tcha.org>
parents: 32891
diff changeset
   491
    t.cache.update((k, templater.unquotestring(v))
c8f2cf18b82e formatter: load templates section like a map file
Yuya Nishihara <yuya@tcha.org>
parents: 32891
diff changeset
   492
                   for k, v in ui.configitems('templates'))
25512
8463433c2689 formatter: add a method to build a full templater from a -T option
Matt Mackall <mpm@selenic.com>
parents: 25511
diff changeset
   493
    if tmpl:
32894
8da65da039c3 formatter: always store a literal template unnamed
Yuya Nishihara <yuya@tcha.org>
parents: 32893
diff changeset
   494
        t.cache[''] = tmpl
25512
8463433c2689 formatter: add a method to build a full templater from a -T option
Matt Mackall <mpm@selenic.com>
parents: 25511
diff changeset
   495
    return t
8463433c2689 formatter: add a method to build a full templater from a -T option
Matt Mackall <mpm@selenic.com>
parents: 25511
diff changeset
   496
35473
f1c54d003327 templater: move repo, ui and cache to per-engine resources
Yuya Nishihara <yuya@tcha.org>
parents: 35472
diff changeset
   497
def templateresources(ui, repo=None):
f1c54d003327 templater: move repo, ui and cache to per-engine resources
Yuya Nishihara <yuya@tcha.org>
parents: 35472
diff changeset
   498
    """Create a dict of template resources designed for the default templatekw
f1c54d003327 templater: move repo, ui and cache to per-engine resources
Yuya Nishihara <yuya@tcha.org>
parents: 35472
diff changeset
   499
    and function"""
36985
255f635c3204 templater: convert resources to a table of callables for future extension
Yuya Nishihara <yuya@tcha.org>
parents: 36927
diff changeset
   500
    resmap = {
35473
f1c54d003327 templater: move repo, ui and cache to per-engine resources
Yuya Nishihara <yuya@tcha.org>
parents: 35472
diff changeset
   501
        'cache': {},  # for templatekw/funcs to store reusable data
f1c54d003327 templater: move repo, ui and cache to per-engine resources
Yuya Nishihara <yuya@tcha.org>
parents: 35472
diff changeset
   502
        'repo': repo,
f1c54d003327 templater: move repo, ui and cache to per-engine resources
Yuya Nishihara <yuya@tcha.org>
parents: 35472
diff changeset
   503
        'ui': ui,
f1c54d003327 templater: move repo, ui and cache to per-engine resources
Yuya Nishihara <yuya@tcha.org>
parents: 35472
diff changeset
   504
    }
f1c54d003327 templater: move repo, ui and cache to per-engine resources
Yuya Nishihara <yuya@tcha.org>
parents: 35472
diff changeset
   505
36985
255f635c3204 templater: convert resources to a table of callables for future extension
Yuya Nishihara <yuya@tcha.org>
parents: 36927
diff changeset
   506
    def getsome(context, mapping, key):
36986
036e4483d3a1 templater: process mapping dict by resource callables
Yuya Nishihara <yuya@tcha.org>
parents: 36985
diff changeset
   507
        v = mapping.get(key)
036e4483d3a1 templater: process mapping dict by resource callables
Yuya Nishihara <yuya@tcha.org>
parents: 36985
diff changeset
   508
        if v is not None:
036e4483d3a1 templater: process mapping dict by resource callables
Yuya Nishihara <yuya@tcha.org>
parents: 36985
diff changeset
   509
            return v
36985
255f635c3204 templater: convert resources to a table of callables for future extension
Yuya Nishihara <yuya@tcha.org>
parents: 36927
diff changeset
   510
        return resmap.get(key)
255f635c3204 templater: convert resources to a table of callables for future extension
Yuya Nishihara <yuya@tcha.org>
parents: 36927
diff changeset
   511
36987
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 36986
diff changeset
   512
    def getctx(context, mapping, key):
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 36986
diff changeset
   513
        ctx = mapping.get('ctx')
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 36986
diff changeset
   514
        if ctx is not None:
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 36986
diff changeset
   515
            return ctx
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 36986
diff changeset
   516
        fctx = mapping.get('fctx')
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 36986
diff changeset
   517
        if fctx is not None:
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 36986
diff changeset
   518
            return fctx.changectx()
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 36986
diff changeset
   519
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 36986
diff changeset
   520
    def getrepo(context, mapping, key):
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 36986
diff changeset
   521
        ctx = getctx(context, mapping, 'ctx')
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 36986
diff changeset
   522
        if ctx is not None:
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 36986
diff changeset
   523
            return ctx.repo()
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 36986
diff changeset
   524
        return getsome(context, mapping, key)
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 36986
diff changeset
   525
36985
255f635c3204 templater: convert resources to a table of callables for future extension
Yuya Nishihara <yuya@tcha.org>
parents: 36927
diff changeset
   526
    return {
255f635c3204 templater: convert resources to a table of callables for future extension
Yuya Nishihara <yuya@tcha.org>
parents: 36927
diff changeset
   527
        'cache': getsome,
36987
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 36986
diff changeset
   528
        'ctx': getctx,
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 36986
diff changeset
   529
        'fctx': getsome,
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 36986
diff changeset
   530
        'repo': getrepo,
36985
255f635c3204 templater: convert resources to a table of callables for future extension
Yuya Nishihara <yuya@tcha.org>
parents: 36927
diff changeset
   531
        'revcache': getsome,  # per-ctx cache; set later
255f635c3204 templater: convert resources to a table of callables for future extension
Yuya Nishihara <yuya@tcha.org>
parents: 36927
diff changeset
   532
        'ui': getsome,
255f635c3204 templater: convert resources to a table of callables for future extension
Yuya Nishihara <yuya@tcha.org>
parents: 36927
diff changeset
   533
    }
255f635c3204 templater: convert resources to a table of callables for future extension
Yuya Nishihara <yuya@tcha.org>
parents: 36927
diff changeset
   534
32605
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32208
diff changeset
   535
def formatter(ui, out, topic, opts):
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   536
    template = opts.get("template", "")
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   537
    if template == "json":
32605
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32208
diff changeset
   538
        return jsonformatter(ui, out, topic, opts)
22430
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
   539
    elif template == "pickle":
32605
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32208
diff changeset
   540
        return pickleformatter(ui, out, topic, opts)
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   541
    elif template == "debug":
32605
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32208
diff changeset
   542
        return debugformatter(ui, out, topic, opts)
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   543
    elif template != "":
32605
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32208
diff changeset
   544
        return templateformatter(ui, out, topic, opts)
25838
31137258ae8b formatter: mark developer options
Matt Mackall <mpm@selenic.com>
parents: 25513
diff changeset
   545
    # developer config: ui.formatdebug
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   546
    elif ui.configbool('ui', 'formatdebug'):
32605
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32208
diff changeset
   547
        return debugformatter(ui, out, topic, opts)
25838
31137258ae8b formatter: mark developer options
Matt Mackall <mpm@selenic.com>
parents: 25513
diff changeset
   548
    # deprecated config: ui.formatjson
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   549
    elif ui.configbool('ui', 'formatjson'):
32605
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32208
diff changeset
   550
        return jsonformatter(ui, out, topic, opts)
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32208
diff changeset
   551
    return plainformatter(ui, out, topic, opts)
32606
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32605
diff changeset
   552
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32605
diff changeset
   553
@contextlib.contextmanager
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32605
diff changeset
   554
def openformatter(ui, filename, topic, opts):
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32605
diff changeset
   555
    """Create a formatter that writes outputs to the specified file
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32605
diff changeset
   556
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32605
diff changeset
   557
    Must be invoked using the 'with' statement.
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32605
diff changeset
   558
    """
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32605
diff changeset
   559
    with util.posixfile(filename, 'wb') as out:
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32605
diff changeset
   560
        with formatter(ui, out, topic, opts) as fm:
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32605
diff changeset
   561
            yield fm
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32605
diff changeset
   562
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32605
diff changeset
   563
@contextlib.contextmanager
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32605
diff changeset
   564
def _neverending(fm):
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32605
diff changeset
   565
    yield fm
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32605
diff changeset
   566
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32605
diff changeset
   567
def maybereopen(fm, filename, opts):
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32605
diff changeset
   568
    """Create a formatter backed by file if filename specified, else return
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32605
diff changeset
   569
    the given formatter
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32605
diff changeset
   570
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32605
diff changeset
   571
    Must be invoked using the 'with' statement. This will never call fm.end()
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32605
diff changeset
   572
    of the given formatter.
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32605
diff changeset
   573
    """
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32605
diff changeset
   574
    if filename:
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32605
diff changeset
   575
        return openformatter(fm._ui, filename, fm._topic, opts)
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32605
diff changeset
   576
    else:
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32605
diff changeset
   577
        return _neverending(fm)