annotate mercurial/formatter.py @ 38406:fd1dd79cff20

cmdutil: pass in parsed patch to tryimportone() (API) Previously, we parsed the patch in tryimportone(). This assumes the input is in a patch format that needs to be parsed. We want to support feeding in data from other formats. So let's let the caller handle the parsing. One wonky thing about patch parsing is that patch.extract() creates a temp file to hold the diffs and it is up to tryimportone() to unlink that temp file. I'll improve this in a subsequent commit. Differential Revision: https://phab.mercurial-scm.org/D3305
author Gregory Szorc <gregory.szorc@gmail.com>
date Thu, 12 Apr 2018 23:06:27 -0700
parents d110167610db
children 31750413f8d7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
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
31339
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
8 """Generic output formatting for Mercurial
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
9
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
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: 30719
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: 30719
diff changeset
12
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
13 - fm.write() for unconditional output
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
14 - fm.condwrite() to show some extra data conditionally in plain output
31951
16272d8c24f6 formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents: 31949
diff changeset
15 - fm.context() to provide changectx to template output
31339
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
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: 30719
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: 30719
diff changeset
18
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
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: 30719
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: 30719
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: 30719
diff changeset
22 supported by the formatter API.
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
23
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
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: 30719
diff changeset
25
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
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: 30719
diff changeset
27
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
28 fm.condwrite() vs 'if cond:':
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
29
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
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: 30719
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: 30719
diff changeset
32 fm.write().
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
33
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
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: 30719
diff changeset
35
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
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: 30719
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: 30719
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: 30719
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: 30719
diff changeset
40 "{get(foo, key)}" function.
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
41
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
42 Doctest helper:
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
43
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
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: 30719
diff changeset
45 ... import sys
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
46 ... from . import ui as uimod
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
47 ... ui = uimod.ui()
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
48 ... ui.verbose = verbose
35038
d6af8da4a3b8 py3: rewrite stdout hack of doctest by using ui.pushbuffer()
Yuya Nishihara <yuya@tcha.org>
parents: 34914
diff changeset
49 ... ui.pushbuffer()
d6af8da4a3b8 py3: rewrite stdout hack of doctest by using ui.pushbuffer()
Yuya Nishihara <yuya@tcha.org>
parents: 34914
diff changeset
50 ... try:
35039
ebe3d0095c69 py3: convert system strings to bytes in doctest of formatter.py
Yuya Nishihara <yuya@tcha.org>
parents: 35038
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: 35038
diff changeset
52 ... pycompat.byteskwargs(opts)))
35038
d6af8da4a3b8 py3: rewrite stdout hack of doctest by using ui.pushbuffer()
Yuya Nishihara <yuya@tcha.org>
parents: 34914
diff changeset
53 ... finally:
d6af8da4a3b8 py3: rewrite stdout hack of doctest by using ui.pushbuffer()
Yuya Nishihara <yuya@tcha.org>
parents: 34914
diff changeset
54 ... print(pycompat.sysstr(ui.popbuffer()), end='')
31339
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
55
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
56 Basic example:
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
57
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
58 >>> def files(ui, fm):
34914
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33873
diff changeset
59 ... files = [(b'foo', 123, (0, 0)), (b'bar', 456, (1, 0))]
31339
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
60 ... for f in files:
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
61 ... fm.startitem()
34914
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33873
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: 33873
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: 33873
diff changeset
64 ... fm.formatdate(f[2], b'%Y-%m-%d %H:%M:%S'))
31339
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
65 ... fm.data(size=f[1])
34914
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33873
diff changeset
66 ... fm.plain(b'\\n')
31339
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
67 ... fm.end()
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
68 >>> show(files)
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
69 foo
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
70 bar
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
71 >>> show(files, verbose=True)
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
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: 30719
diff changeset
73 bar 1970-01-01 00:00:01
34914
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33873
diff changeset
74 >>> show(files, template=b'json')
31339
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
75 [
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
76 {
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
77 "date": [0, 0],
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
78 "path": "foo",
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
79 "size": 123
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
80 },
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
81 {
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
82 "date": [1, 0],
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
83 "path": "bar",
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
84 "size": 456
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
85 }
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
86 ]
34914
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33873
diff changeset
87 >>> show(files, template=b'path: {path}\\ndate: {date|rfc3339date}\\n')
31339
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
88 path: foo
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
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: 30719
diff changeset
90 path: bar
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
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: 30719
diff changeset
92
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
93 Nested example:
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
94
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
95 >>> def subrepos(ui, fm):
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
96 ... fm.startitem()
36253
a33be093ec62 templater: look up symbols/resources as if they were separated (issue5699)
Yuya Nishihara <yuya@tcha.org>
parents: 36252
diff changeset
97 ... fm.write(b'reponame', b'[%s]\\n', b'baz')
38286
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37891
diff changeset
98 ... files(ui, fm.nested(b'files', tmpl=b'{reponame}'))
31339
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
99 ... fm.end()
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
100 >>> show(subrepos)
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
101 [baz]
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
102 foo
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
103 bar
36253
a33be093ec62 templater: look up symbols/resources as if they were separated (issue5699)
Yuya Nishihara <yuya@tcha.org>
parents: 36252
diff changeset
104 >>> show(subrepos, template=b'{reponame}: {join(files % "{path}", ", ")}\\n')
31339
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
105 baz: foo, bar
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
106 """
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 30719
diff changeset
107
35038
d6af8da4a3b8 py3: rewrite stdout hack of doctest by using ui.pushbuffer()
Yuya Nishihara <yuya@tcha.org>
parents: 34914
diff changeset
108 from __future__ import absolute_import, print_function
26534
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26398
diff changeset
109
33621
615ec3f14aa9 formatter: wrap (tmpl, mapfile) by named tuple
Yuya Nishihara <yuya@tcha.org>
parents: 33618
diff changeset
110 import collections
33363
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 33362
diff changeset
111 import contextlib
32586
e6eb86b154c5 templater: provide loop counter as "index" keyword
Yuya Nishihara <yuya@tcha.org>
parents: 32584
diff changeset
112 import itertools
26047
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24441
diff changeset
113 import os
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
114
26534
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26398
diff changeset
115 from .i18n import _
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26398
diff changeset
116 from .node import (
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26398
diff changeset
117 hex,
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26398
diff changeset
118 short,
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26398
diff changeset
119 )
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26398
diff changeset
120
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26398
diff changeset
121 from . import (
27227
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26999
diff changeset
122 error,
32938
0fd15522a848 py3: use pycompat.byteskwargs to converts kwargs to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32704
diff changeset
123 pycompat,
32561
654e9a1c8a6c formatter: use templatefilters.json()
Yuya Nishihara <yuya@tcha.org>
parents: 32175
diff changeset
124 templatefilters,
30437
c3a9cd78b151 formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents: 30074
diff changeset
125 templatekw,
26534
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26398
diff changeset
126 templater,
37706
6ff6e1d6b5b8 templater: move stringify() to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 37420
diff changeset
127 templateutil,
30074
b501579147f1 py3: conditionalize cPickle import by adding in util
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29707
diff changeset
128 util,
26534
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26398
diff changeset
129 )
37393
c6061cadb400 util: extract all date-related utils in utils/dateutil module
Boris Feld <boris.feld@octobus.net>
parents: 37231
diff changeset
130 from .utils import dateutil
26534
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26398
diff changeset
131
30074
b501579147f1 py3: conditionalize cPickle import by adding in util
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29707
diff changeset
132 pickle = util.pickle
b501579147f1 py3: conditionalize cPickle import by adding in util
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29707
diff changeset
133
30606
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
134 class _nullconverter(object):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
135 '''convert non-primitive data types to be processed by formatter'''
33873
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 33735
diff changeset
136
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 33735
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: 33735
diff changeset
138 storecontext = False
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 33735
diff changeset
139
30606
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
140 @staticmethod
38286
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37891
diff changeset
141 def wrapnested(data, tmpl, sep):
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37891
diff changeset
142 '''wrap nested data by appropriate type'''
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37891
diff changeset
143 return data
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37891
diff changeset
144 @staticmethod
30606
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
145 def formatdate(date, fmt):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
146 '''convert date tuple to appropriate format'''
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
147 return date
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
148 @staticmethod
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
149 def formatdict(data, key, value, fmt, sep):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
150 '''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: 30564
diff changeset
151 # 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: 30564
diff changeset
152 # serialized as a builtin dict in pickle output
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
153 return dict(data)
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
154 @staticmethod
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
155 def formatlist(data, name, fmt, sep):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
156 '''convert iterable to appropriate list format'''
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
157 return list(data)
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
158
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
159 class baseformatter(object):
30606
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
160 def __init__(self, ui, topic, opts, converter):
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
161 self._ui = ui
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
162 self._topic = topic
38383
d110167610db formatter: carry opts to file-based formatters by basefm
Yuya Nishihara <yuya@tcha.org>
parents: 38382
diff changeset
163 self._opts = opts
30606
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
164 self._converter = converter
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
165 self._item = None
22701
cb28d2b3db0b formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents: 22674
diff changeset
166 # 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
167 self.hexfunc = hex
30652
307b20e5e505 formatter: add context manager interface for convenience
Yuya Nishihara <yuya@tcha.org>
parents: 30607
diff changeset
168 def __enter__(self):
307b20e5e505 formatter: add context manager interface for convenience
Yuya Nishihara <yuya@tcha.org>
parents: 30607
diff changeset
169 return self
307b20e5e505 formatter: add context manager interface for convenience
Yuya Nishihara <yuya@tcha.org>
parents: 30607
diff changeset
170 def __exit__(self, exctype, excvalue, traceback):
307b20e5e505 formatter: add context manager interface for convenience
Yuya Nishihara <yuya@tcha.org>
parents: 30607
diff changeset
171 if exctype is None:
307b20e5e505 formatter: add context manager interface for convenience
Yuya Nishihara <yuya@tcha.org>
parents: 30607
diff changeset
172 self.end()
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
173 def _showitem(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
174 '''show a formatted item once all data is collected'''
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
175 def startitem(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
176 '''begin an item in the format list'''
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
177 if self._item is not None:
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
178 self._showitem()
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
179 self._item = {}
30606
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
180 def formatdate(self, date, fmt='%a %b %d %H:%M:%S %Y %1%2'):
30439
2f3f18ad55a2 formatter: add function to convert date tuple to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents: 30437
diff changeset
181 '''convert date tuple to appropriate format'''
30606
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
182 return self._converter.formatdate(date, fmt)
37419
034a07e60e98 templater: allow dynamically switching the default dict/list formatting
Yuya Nishihara <yuya@tcha.org>
parents: 37393
diff changeset
183 def formatdict(self, data, key='key', value='value', fmt=None, sep=' '):
30564
4891f3b93182 formatter: add function to convert dict to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents: 30439
diff changeset
184 '''convert dict or key-value pairs to appropriate dict format'''
30606
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
185 return self._converter.formatdict(data, key, value, fmt, sep)
37419
034a07e60e98 templater: allow dynamically switching the default dict/list formatting
Yuya Nishihara <yuya@tcha.org>
parents: 37393
diff changeset
186 def formatlist(self, data, name, fmt=None, sep=' '):
30437
c3a9cd78b151 formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents: 30074
diff changeset
187 '''convert iterable to appropriate list format'''
30606
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
188 # 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: 30564
diff changeset
189 # we have default template keyword, e.g. {item}
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
190 return self._converter.formatlist(data, name, fmt, sep)
31951
16272d8c24f6 formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents: 31949
diff changeset
191 def context(self, **ctxs):
16272d8c24f6 formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents: 31949
diff changeset
192 '''insert context objects to be used to render template keywords'''
33873
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 33735
diff changeset
193 ctxs = pycompat.byteskwargs(ctxs)
37770
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 37769
diff changeset
194 assert all(k in {'ctx', 'fctx'} for k in ctxs)
33873
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 33735
diff changeset
195 if self._converter.storecontext:
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 33735
diff changeset
196 self._item.update(ctxs)
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
197 def data(self, **data):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
198 '''insert data into item that's not shown in default output'''
32938
0fd15522a848 py3: use pycompat.byteskwargs to converts kwargs to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32704
diff changeset
199 data = pycompat.byteskwargs(data)
17630
ff5ed1ecd43a formatter: improve implementation of data method
David M. Carr <david@carrclan.us>
parents: 17613
diff changeset
200 self._item.update(data)
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
201 def write(self, fields, deftext, *fielddata, **opts):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
202 '''do default text output while assigning data to item'''
26998
55de800937e0 formatter: verify number of arguments passed to write functions
Yuya Nishihara <yuya@tcha.org>
parents: 26534
diff changeset
203 fieldkeys = fields.split()
55de800937e0 formatter: verify number of arguments passed to write functions
Yuya Nishihara <yuya@tcha.org>
parents: 26534
diff changeset
204 assert len(fieldkeys) == len(fielddata)
26999
aa610ffad4e8 formatter: use dict.update() to set arguments passed to write functions
Yuya Nishihara <yuya@tcha.org>
parents: 26998
diff changeset
205 self._item.update(zip(fieldkeys, fielddata))
17909
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
206 def condwrite(self, cond, fields, deftext, *fielddata, **opts):
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
207 '''do conditional write (primarily for plain formatter)'''
26998
55de800937e0 formatter: verify number of arguments passed to write functions
Yuya Nishihara <yuya@tcha.org>
parents: 26534
diff changeset
208 fieldkeys = fields.split()
55de800937e0 formatter: verify number of arguments passed to write functions
Yuya Nishihara <yuya@tcha.org>
parents: 26534
diff changeset
209 assert len(fieldkeys) == len(fielddata)
26999
aa610ffad4e8 formatter: use dict.update() to set arguments passed to write functions
Yuya Nishihara <yuya@tcha.org>
parents: 26998
diff changeset
210 self._item.update(zip(fieldkeys, fielddata))
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
211 def plain(self, text, **opts):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
212 '''show raw text for non-templated mode'''
30719
e7cacb45c4be formatter: introduce isplain() to replace (the inverse of) __nonzero__() (API)
Mathias De Maré <mathias.demare@gmail.com>
parents: 30652
diff changeset
213 def isplain(self):
e7cacb45c4be formatter: introduce isplain() to replace (the inverse of) __nonzero__() (API)
Mathias De Maré <mathias.demare@gmail.com>
parents: 30652
diff changeset
214 '''check for plain formatter usage'''
e7cacb45c4be formatter: introduce isplain() to replace (the inverse of) __nonzero__() (API)
Mathias De Maré <mathias.demare@gmail.com>
parents: 30652
diff changeset
215 return False
38286
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37891
diff changeset
216 def nested(self, field, tmpl=None, sep=''):
30607
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 30606
diff changeset
217 '''sub formatter to store nested data in the specified field'''
38286
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37891
diff changeset
218 data = []
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37891
diff changeset
219 self._item[field] = self._converter.wrapnested(data, tmpl, sep)
30607
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 30606
diff changeset
220 return _nestedformatter(self._ui, self._converter, data)
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
221 def end(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
222 '''end output for the formatter'''
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
223 if self._item is not None:
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
224 self._showitem()
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
225
38383
d110167610db formatter: carry opts to file-based formatters by basefm
Yuya Nishihara <yuya@tcha.org>
parents: 38382
diff changeset
226 def nullformatter(ui, topic, opts):
33364
e9bf3e132ea9 formatter: add nullformatter
Yuya Nishihara <yuya@tcha.org>
parents: 33363
diff changeset
227 '''formatter that prints nothing'''
38383
d110167610db formatter: carry opts to file-based formatters by basefm
Yuya Nishihara <yuya@tcha.org>
parents: 38382
diff changeset
228 return baseformatter(ui, topic, opts, converter=_nullconverter)
33364
e9bf3e132ea9 formatter: add nullformatter
Yuya Nishihara <yuya@tcha.org>
parents: 33363
diff changeset
229
30607
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 30606
diff changeset
230 class _nestedformatter(baseformatter):
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 30606
diff changeset
231 '''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: 30606
diff changeset
232 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: 30606
diff changeset
233 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: 30606
diff changeset
234 self._data = data
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 30606
diff changeset
235 def _showitem(self):
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 30606
diff changeset
236 self._data.append(self._item)
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 30606
diff changeset
237
30564
4891f3b93182 formatter: add function to convert dict to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents: 30439
diff changeset
238 def _iteritems(data):
4891f3b93182 formatter: add function to convert dict to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents: 30439
diff changeset
239 '''iterate key-value pairs in stable order'''
4891f3b93182 formatter: add function to convert dict to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents: 30439
diff changeset
240 if isinstance(data, dict):
4891f3b93182 formatter: add function to convert dict to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents: 30439
diff changeset
241 return sorted(data.iteritems())
4891f3b93182 formatter: add function to convert dict to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents: 30439
diff changeset
242 return data
4891f3b93182 formatter: add function to convert dict to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents: 30439
diff changeset
243
30606
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
244 class _plainconverter(object):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
245 '''convert non-primitive data types to text'''
33873
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 33735
diff changeset
246
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 33735
diff changeset
247 storecontext = False
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 33735
diff changeset
248
30606
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
249 @staticmethod
38286
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37891
diff changeset
250 def wrapnested(data, tmpl, sep):
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37891
diff changeset
251 raise error.ProgrammingError('plainformatter should never be nested')
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37891
diff changeset
252 @staticmethod
30606
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
253 def formatdate(date, fmt):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
254 '''stringify date tuple in the given format'''
37393
c6061cadb400 util: extract all date-related utils in utils/dateutil module
Boris Feld <boris.feld@octobus.net>
parents: 37231
diff changeset
255 return dateutil.datestr(date, fmt)
30606
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
256 @staticmethod
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
257 def formatdict(data, key, value, fmt, sep):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
258 '''stringify key-value pairs separated by sep'''
37420
cafd0586876b templater: byte-stringify dict/list values before passing to default format
Yuya Nishihara <yuya@tcha.org>
parents: 37419
diff changeset
259 prefmt = pycompat.identity
37419
034a07e60e98 templater: allow dynamically switching the default dict/list formatting
Yuya Nishihara <yuya@tcha.org>
parents: 37393
diff changeset
260 if fmt is None:
034a07e60e98 templater: allow dynamically switching the default dict/list formatting
Yuya Nishihara <yuya@tcha.org>
parents: 37393
diff changeset
261 fmt = '%s=%s'
37420
cafd0586876b templater: byte-stringify dict/list values before passing to default format
Yuya Nishihara <yuya@tcha.org>
parents: 37419
diff changeset
262 prefmt = pycompat.bytestr
cafd0586876b templater: byte-stringify dict/list values before passing to default format
Yuya Nishihara <yuya@tcha.org>
parents: 37419
diff changeset
263 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: 37419
diff changeset
264 for k, v in _iteritems(data))
30606
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
265 @staticmethod
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
266 def formatlist(data, name, fmt, sep):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
267 '''stringify iterable separated by sep'''
37420
cafd0586876b templater: byte-stringify dict/list values before passing to default format
Yuya Nishihara <yuya@tcha.org>
parents: 37419
diff changeset
268 prefmt = pycompat.identity
37419
034a07e60e98 templater: allow dynamically switching the default dict/list formatting
Yuya Nishihara <yuya@tcha.org>
parents: 37393
diff changeset
269 if fmt is None:
034a07e60e98 templater: allow dynamically switching the default dict/list formatting
Yuya Nishihara <yuya@tcha.org>
parents: 37393
diff changeset
270 fmt = '%s'
37420
cafd0586876b templater: byte-stringify dict/list values before passing to default format
Yuya Nishihara <yuya@tcha.org>
parents: 37419
diff changeset
271 prefmt = pycompat.bytestr
cafd0586876b templater: byte-stringify dict/list values before passing to default format
Yuya Nishihara <yuya@tcha.org>
parents: 37419
diff changeset
272 return sep.join(fmt % prefmt(e) for e in data)
30606
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
273
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
274 class plainformatter(baseformatter):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
275 '''the default text output scheme'''
33362
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32938
diff changeset
276 def __init__(self, ui, out, topic, opts):
30606
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
277 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
278 if ui.debugflag:
cb28d2b3db0b formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents: 22674
diff changeset
279 self.hexfunc = hex
cb28d2b3db0b formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents: 22674
diff changeset
280 else:
cb28d2b3db0b formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents: 22674
diff changeset
281 self.hexfunc = short
33362
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32938
diff changeset
282 if ui is out:
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32938
diff changeset
283 self._write = ui.write
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32938
diff changeset
284 else:
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32938
diff changeset
285 self._write = lambda s, **opts: out.write(s)
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
286 def startitem(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
287 pass
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
288 def data(self, **data):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
289 pass
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
290 def write(self, fields, deftext, *fielddata, **opts):
33362
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32938
diff changeset
291 self._write(deftext % fielddata, **opts)
17909
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
292 def condwrite(self, cond, fields, deftext, *fielddata, **opts):
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
293 '''do conditional write'''
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
294 if cond:
33362
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32938
diff changeset
295 self._write(deftext % fielddata, **opts)
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
296 def plain(self, text, **opts):
33362
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32938
diff changeset
297 self._write(text, **opts)
30719
e7cacb45c4be formatter: introduce isplain() to replace (the inverse of) __nonzero__() (API)
Mathias De Maré <mathias.demare@gmail.com>
parents: 30652
diff changeset
298 def isplain(self):
e7cacb45c4be formatter: introduce isplain() to replace (the inverse of) __nonzero__() (API)
Mathias De Maré <mathias.demare@gmail.com>
parents: 30652
diff changeset
299 return True
38286
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37891
diff changeset
300 def nested(self, field, tmpl=None, sep=''):
30607
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 30606
diff changeset
301 # 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: 30606
diff changeset
302 return self
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
303 def end(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
304 pass
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
305
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
306 class debugformatter(baseformatter):
31961
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31951
diff changeset
307 def __init__(self, ui, out, topic, opts):
30606
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
308 baseformatter.__init__(self, ui, topic, opts, _nullconverter)
31961
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31951
diff changeset
309 self._out = out
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31951
diff changeset
310 self._out.write("%s = [\n" % self._topic)
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
311 def _showitem(self):
37051
b44fac3a49fb py3: factor out byterepr() which returns an asciified value on py3
Yuya Nishihara <yuya@tcha.org>
parents: 36826
diff changeset
312 self._out.write(' %s,\n' % pycompat.byterepr(self._item))
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
313 def end(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
314 baseformatter.end(self)
31961
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31951
diff changeset
315 self._out.write("]\n")
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
316
22430
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
317 class pickleformatter(baseformatter):
31961
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31951
diff changeset
318 def __init__(self, ui, out, topic, opts):
30606
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
319 baseformatter.__init__(self, ui, topic, opts, _nullconverter)
31961
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31951
diff changeset
320 self._out = out
22430
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
321 self._data = []
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
322 def _showitem(self):
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
323 self._data.append(self._item)
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
324 def end(self):
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
325 baseformatter.end(self)
31961
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31951
diff changeset
326 self._out.write(pickle.dumps(self._data))
22430
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
327
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
328 class jsonformatter(baseformatter):
31961
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31951
diff changeset
329 def __init__(self, ui, out, topic, opts):
30606
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
330 baseformatter.__init__(self, ui, topic, opts, _nullconverter)
31961
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31951
diff changeset
331 self._out = out
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31951
diff changeset
332 self._out.write("[")
32077
59d09565ac77 formatter: set _first on formatter, not ui
Martin von Zweigbergk <martinvonz@google.com>
parents: 31961
diff changeset
333 self._first = True
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
334 def _showitem(self):
32077
59d09565ac77 formatter: set _first on formatter, not ui
Martin von Zweigbergk <martinvonz@google.com>
parents: 31961
diff changeset
335 if self._first:
59d09565ac77 formatter: set _first on formatter, not ui
Martin von Zweigbergk <martinvonz@google.com>
parents: 31961
diff changeset
336 self._first = False
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
337 else:
31961
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31951
diff changeset
338 self._out.write(",")
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
339
31961
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31951
diff changeset
340 self._out.write("\n {\n")
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
341 first = True
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
342 for k, v in sorted(self._item.items()):
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
343 if first:
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
344 first = False
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
345 else:
31961
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31951
diff changeset
346 self._out.write(",\n")
32561
654e9a1c8a6c formatter: use templatefilters.json()
Yuya Nishihara <yuya@tcha.org>
parents: 32175
diff changeset
347 u = templatefilters.json(v, paranoid=False)
654e9a1c8a6c formatter: use templatefilters.json()
Yuya Nishihara <yuya@tcha.org>
parents: 32175
diff changeset
348 self._out.write(' "%s": %s' % (k, u))
31961
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31951
diff changeset
349 self._out.write("\n }")
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
350 def end(self):
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
351 baseformatter.end(self)
31961
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31951
diff changeset
352 self._out.write("\n]\n")
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
353
30606
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
354 class _templateconverter(object):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
355 '''convert non-primitive data types to be processed by templater'''
33873
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 33735
diff changeset
356
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 33735
diff changeset
357 storecontext = True
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 33735
diff changeset
358
30606
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
359 @staticmethod
38286
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37891
diff changeset
360 def wrapnested(data, tmpl, sep):
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37891
diff changeset
361 '''wrap nested data by templatable type'''
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37891
diff changeset
362 return templateutil.mappinglist(data, tmpl=tmpl, sep=sep)
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37891
diff changeset
363 @staticmethod
30606
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
364 def formatdate(date, fmt):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
365 '''return date tuple'''
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
366 return date
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
367 @staticmethod
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
368 def formatdict(data, key, value, fmt, sep):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
369 '''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: 30564
diff changeset
370 data = util.sortdict(_iteritems(data))
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
371 def f():
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
372 yield _plainconverter.formatdict(data, key, value, fmt, sep)
37707
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 37706
diff changeset
373 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: 37706
diff changeset
374 gen=f)
30606
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
375 @staticmethod
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
376 def formatlist(data, name, fmt, sep):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
377 '''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: 30564
diff changeset
378 data = list(data)
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
379 def f():
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
380 yield _plainconverter.formatlist(data, name, fmt, sep)
37707
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 37706
diff changeset
381 return templateutil.hybridlist(data, name=name, fmt=fmt, gen=f)
30606
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
382
26049
0c6f98398f8a formatter: add template support
Matt Mackall <mpm@selenic.com>
parents: 26048
diff changeset
383 class templateformatter(baseformatter):
31961
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31951
diff changeset
384 def __init__(self, ui, out, topic, opts):
30606
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 30564
diff changeset
385 baseformatter.__init__(self, ui, topic, opts, _templateconverter)
31961
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31951
diff changeset
386 self._out = out
33616
99df35499cae formatter: inline gettemplater()
Yuya Nishihara <yuya@tcha.org>
parents: 33615
diff changeset
387 spec = lookuptemplate(ui, topic, opts.get('template', ''))
33624
883adaea9e80 formatter: render template specified by templatespec tuple
Yuya Nishihara <yuya@tcha.org>
parents: 33623
diff changeset
388 self._tref = spec.ref
36266
817a3d20dd01 templater: register keywords to defaults table
Yuya Nishihara <yuya@tcha.org>
parents: 36253
diff changeset
389 self._t = loadtemplater(ui, spec, defaults=templatekw.keywords,
817a3d20dd01 templater: register keywords to defaults table
Yuya Nishihara <yuya@tcha.org>
parents: 36253
diff changeset
390 resources=templateresources(ui),
36252
f1c54d003327 templater: move repo, ui and cache to per-engine resources
Yuya Nishihara <yuya@tcha.org>
parents: 36251
diff changeset
391 cache=templatekw.defaulttempl)
33732
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 33731
diff changeset
392 self._parts = templatepartsmap(spec, self._t,
33733
5100ce217dfa formatter: add support for separator template
Yuya Nishihara <yuya@tcha.org>
parents: 33732
diff changeset
393 ['docheader', 'docfooter', 'separator'])
32586
e6eb86b154c5 templater: provide loop counter as "index" keyword
Yuya Nishihara <yuya@tcha.org>
parents: 32584
diff changeset
394 self._counter = itertools.count()
33732
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 33731
diff changeset
395 self._renderitem('docheader', {})
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 33731
diff changeset
396
26049
0c6f98398f8a formatter: add template support
Matt Mackall <mpm@selenic.com>
parents: 26048
diff changeset
397 def _showitem(self):
33731
12a0794fa2e3 formatter: extract helper function to render template
Yuya Nishihara <yuya@tcha.org>
parents: 33680
diff changeset
398 item = self._item.copy()
33733
5100ce217dfa formatter: add support for separator template
Yuya Nishihara <yuya@tcha.org>
parents: 33732
diff changeset
399 item['index'] = index = next(self._counter)
5100ce217dfa formatter: add support for separator template
Yuya Nishihara <yuya@tcha.org>
parents: 33732
diff changeset
400 if index > 0:
5100ce217dfa formatter: add support for separator template
Yuya Nishihara <yuya@tcha.org>
parents: 33732
diff changeset
401 self._renderitem('separator', {})
33731
12a0794fa2e3 formatter: extract helper function to render template
Yuya Nishihara <yuya@tcha.org>
parents: 33680
diff changeset
402 self._renderitem(self._tref, item)
12a0794fa2e3 formatter: extract helper function to render template
Yuya Nishihara <yuya@tcha.org>
parents: 33680
diff changeset
403
33732
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 33731
diff changeset
404 def _renderitem(self, part, item):
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 33731
diff changeset
405 if part not in self._parts:
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 33731
diff changeset
406 return
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 33731
diff changeset
407 ref = self._parts[part]
37889
be3f33f5e232 templater: switch 'revcache' based on new mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37888
diff changeset
408 self._out.write(self._t.render(ref, item))
26049
0c6f98398f8a formatter: add template support
Matt Mackall <mpm@selenic.com>
parents: 26048
diff changeset
409
33732
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 33731
diff changeset
410 def end(self):
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 33731
diff changeset
411 baseformatter.end(self)
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 33731
diff changeset
412 self._renderitem('docfooter', {})
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 33731
diff changeset
413
33621
615ec3f14aa9 formatter: wrap (tmpl, mapfile) by named tuple
Yuya Nishihara <yuya@tcha.org>
parents: 33618
diff changeset
414 templatespec = collections.namedtuple(r'templatespec',
33623
57c13c0d1cde formatter: put topic in templatespec tuple
Yuya Nishihara <yuya@tcha.org>
parents: 33621
diff changeset
415 r'ref tmpl mapfile')
33621
615ec3f14aa9 formatter: wrap (tmpl, mapfile) by named tuple
Yuya Nishihara <yuya@tcha.org>
parents: 33618
diff changeset
416
26047
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24441
diff changeset
417 def lookuptemplate(ui, topic, tmpl):
33618
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 33616
diff changeset
418 """Find the template matching the given -T/--template spec 'tmpl'
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 33616
diff changeset
419
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 33616
diff changeset
420 'tmpl' can be any of the following:
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 33616
diff changeset
421
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 33616
diff changeset
422 - a literal template (e.g. '{rev}')
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 33616
diff changeset
423 - a map-file name or path (e.g. 'changelog')
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 33616
diff changeset
424 - a reference to [templates] in config file
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 33616
diff changeset
425 - a path to raw template file
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 33616
diff changeset
426
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 33616
diff changeset
427 A map file defines a stand-alone template environment. If a map file
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 33616
diff changeset
428 selected, all templates defined in the file will be loaded, and the
35498
f17a0e18c47e templater: load aliases from [templatealias] section in map file
Yuya Nishihara <yuya@tcha.org>
parents: 35208
diff changeset
429 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: 35208
diff changeset
430 loaded from user config, but from the map file.
33658
c8f2cf18b82e formatter: load templates section like a map file
Yuya Nishihara <yuya@tcha.org>
parents: 33656
diff changeset
431
c8f2cf18b82e formatter: load templates section like a map file
Yuya Nishihara <yuya@tcha.org>
parents: 33656
diff changeset
432 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: 33656
diff changeset
433 available as well as aliases in [templatealias].
33618
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 33616
diff changeset
434 """
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 33616
diff changeset
435
26047
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24441
diff changeset
436 # looks like a literal template?
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24441
diff changeset
437 if '{' in tmpl:
33658
c8f2cf18b82e formatter: load templates section like a map file
Yuya Nishihara <yuya@tcha.org>
parents: 33656
diff changeset
438 return templatespec('', tmpl, None)
26047
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24441
diff changeset
439
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24441
diff changeset
440 # perhaps a stock style?
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24441
diff changeset
441 if not os.path.split(tmpl)[0]:
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24441
diff changeset
442 mapname = (templater.templatepath('map-cmdline.' + tmpl)
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24441
diff changeset
443 or templater.templatepath(tmpl))
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24441
diff changeset
444 if mapname and os.path.isfile(mapname):
33623
57c13c0d1cde formatter: put topic in templatespec tuple
Yuya Nishihara <yuya@tcha.org>
parents: 33621
diff changeset
445 return templatespec(topic, None, mapname)
26047
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24441
diff changeset
446
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24441
diff changeset
447 # perhaps it's a reference to [templates]
33658
c8f2cf18b82e formatter: load templates section like a map file
Yuya Nishihara <yuya@tcha.org>
parents: 33656
diff changeset
448 if ui.config('templates', tmpl):
c8f2cf18b82e formatter: load templates section like a map file
Yuya Nishihara <yuya@tcha.org>
parents: 33656
diff changeset
449 return templatespec(tmpl, None, None)
26047
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24441
diff changeset
450
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24441
diff changeset
451 if tmpl == 'list':
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24441
diff changeset
452 ui.write(_("available styles: %s\n") % templater.stylelist())
27227
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26999
diff changeset
453 raise error.Abort(_("specify a template"))
26047
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24441
diff changeset
454
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24441
diff changeset
455 # 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: 24441
diff changeset
456 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: 24441
diff changeset
457 # is it a mapfile for a style?
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24441
diff changeset
458 if os.path.basename(tmpl).startswith("map-"):
33623
57c13c0d1cde formatter: put topic in templatespec tuple
Yuya Nishihara <yuya@tcha.org>
parents: 33621
diff changeset
459 return templatespec(topic, None, os.path.realpath(tmpl))
33613
470820c2418d formatter: open raw template file in posix semantics
Yuya Nishihara <yuya@tcha.org>
parents: 33612
diff changeset
460 with util.posixfile(tmpl, 'rb') as f:
33611
526f9f12f707 formatter: close raw template file explicitly
Yuya Nishihara <yuya@tcha.org>
parents: 33364
diff changeset
461 tmpl = f.read()
33658
c8f2cf18b82e formatter: load templates section like a map file
Yuya Nishihara <yuya@tcha.org>
parents: 33656
diff changeset
462 return templatespec('', tmpl, None)
26047
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24441
diff changeset
463
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24441
diff changeset
464 # constant string?
33658
c8f2cf18b82e formatter: load templates section like a map file
Yuya Nishihara <yuya@tcha.org>
parents: 33656
diff changeset
465 return templatespec('', tmpl, None)
26047
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24441
diff changeset
466
33732
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 33731
diff changeset
467 def templatepartsmap(spec, t, partnames):
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 33731
diff changeset
468 """Create a mapping of {part: ref}"""
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 33731
diff changeset
469 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: 33731
diff changeset
470 if spec.mapfile:
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 33731
diff changeset
471 partsmap.update((p, p) for p in partnames if p in t)
33735
61b60b28c381 formatter: add support for parts map of [templates] section
Yuya Nishihara <yuya@tcha.org>
parents: 33733
diff changeset
472 elif spec.ref:
61b60b28c381 formatter: add support for parts map of [templates] section
Yuya Nishihara <yuya@tcha.org>
parents: 33733
diff changeset
473 for part in partnames:
61b60b28c381 formatter: add support for parts map of [templates] section
Yuya Nishihara <yuya@tcha.org>
parents: 33733
diff changeset
474 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: 33733
diff changeset
475 if ref in t:
61b60b28c381 formatter: add support for parts map of [templates] section
Yuya Nishihara <yuya@tcha.org>
parents: 33733
diff changeset
476 partsmap[part] = ref
33732
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 33731
diff changeset
477 return partsmap
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 33731
diff changeset
478
36266
817a3d20dd01 templater: register keywords to defaults table
Yuya Nishihara <yuya@tcha.org>
parents: 36253
diff changeset
479 def loadtemplater(ui, spec, defaults=None, resources=None, cache=None):
33615
11e667a8fcba formatter: factor out function to create templater from literal or map file
Yuya Nishihara <yuya@tcha.org>
parents: 33613
diff changeset
480 """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: 33613
diff changeset
481 a map file"""
33621
615ec3f14aa9 formatter: wrap (tmpl, mapfile) by named tuple
Yuya Nishihara <yuya@tcha.org>
parents: 33618
diff changeset
482 assert not (spec.tmpl and spec.mapfile)
615ec3f14aa9 formatter: wrap (tmpl, mapfile) by named tuple
Yuya Nishihara <yuya@tcha.org>
parents: 33618
diff changeset
483 if spec.mapfile:
36251
32c278eb876f templater: keep default resources per template engine (API)
Yuya Nishihara <yuya@tcha.org>
parents: 35498
diff changeset
484 frommapfile = templater.templater.frommapfile
36266
817a3d20dd01 templater: register keywords to defaults table
Yuya Nishihara <yuya@tcha.org>
parents: 36253
diff changeset
485 return frommapfile(spec.mapfile, defaults=defaults, resources=resources,
817a3d20dd01 templater: register keywords to defaults table
Yuya Nishihara <yuya@tcha.org>
parents: 36253
diff changeset
486 cache=cache)
817a3d20dd01 templater: register keywords to defaults table
Yuya Nishihara <yuya@tcha.org>
parents: 36253
diff changeset
487 return maketemplater(ui, spec.tmpl, defaults=defaults, resources=resources,
817a3d20dd01 templater: register keywords to defaults table
Yuya Nishihara <yuya@tcha.org>
parents: 36253
diff changeset
488 cache=cache)
29705
78759f78a44e templater: factor out function that creates templater from string template
Yuya Nishihara <yuya@tcha.org>
parents: 29704
diff changeset
489
36266
817a3d20dd01 templater: register keywords to defaults table
Yuya Nishihara <yuya@tcha.org>
parents: 36253
diff changeset
490 def maketemplater(ui, tmpl, defaults=None, resources=None, cache=None):
29705
78759f78a44e templater: factor out function that creates templater from string template
Yuya Nishihara <yuya@tcha.org>
parents: 29704
diff changeset
491 """Create a templater from a string template 'tmpl'"""
29707
d813132ea361 templater: load and expand aliases by template engine (API) (issue4842)
Yuya Nishihara <yuya@tcha.org>
parents: 29705
diff changeset
492 aliases = ui.configitems('templatealias')
36266
817a3d20dd01 templater: register keywords to defaults table
Yuya Nishihara <yuya@tcha.org>
parents: 36253
diff changeset
493 t = templater.templater(defaults=defaults, resources=resources,
817a3d20dd01 templater: register keywords to defaults table
Yuya Nishihara <yuya@tcha.org>
parents: 36253
diff changeset
494 cache=cache, aliases=aliases)
33658
c8f2cf18b82e formatter: load templates section like a map file
Yuya Nishihara <yuya@tcha.org>
parents: 33656
diff changeset
495 t.cache.update((k, templater.unquotestring(v))
c8f2cf18b82e formatter: load templates section like a map file
Yuya Nishihara <yuya@tcha.org>
parents: 33656
diff changeset
496 for k, v in ui.configitems('templates'))
26048
8463433c2689 formatter: add a method to build a full templater from a -T option
Matt Mackall <mpm@selenic.com>
parents: 26047
diff changeset
497 if tmpl:
33659
8da65da039c3 formatter: always store a literal template unnamed
Yuya Nishihara <yuya@tcha.org>
parents: 33658
diff changeset
498 t.cache[''] = tmpl
26048
8463433c2689 formatter: add a method to build a full templater from a -T option
Matt Mackall <mpm@selenic.com>
parents: 26047
diff changeset
499 return t
8463433c2689 formatter: add a method to build a full templater from a -T option
Matt Mackall <mpm@selenic.com>
parents: 26047
diff changeset
500
37859
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
501 class templateresources(templater.resourcemapper):
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
502 """Resource mapper designed for the default templatekw and function"""
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
503
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
504 def __init__(self, ui, repo=None):
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
505 self._resmap = {
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
506 'cache': {}, # for templatekw/funcs to store reusable data
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
507 'repo': repo,
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
508 'ui': ui,
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
509 }
36252
f1c54d003327 templater: move repo, ui and cache to per-engine resources
Yuya Nishihara <yuya@tcha.org>
parents: 36251
diff changeset
510
37861
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37859
diff changeset
511 def availablekeys(self, context, mapping):
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37859
diff changeset
512 return {k for k, g in self._gettermap.iteritems()
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37859
diff changeset
513 if g(self, context, mapping, k) is not None}
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37859
diff changeset
514
37859
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
515 def knownkeys(self):
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
516 return self._knownkeys
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
517
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
518 def lookup(self, context, mapping, key):
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
519 get = self._gettermap.get(key)
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
520 if not get:
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
521 return None
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
522 return get(self, context, mapping, key)
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
523
37888
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37861
diff changeset
524 def populatemap(self, context, origmapping, newmapping):
37889
be3f33f5e232 templater: switch 'revcache' based on new mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37888
diff changeset
525 mapping = {}
be3f33f5e232 templater: switch 'revcache' based on new mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37888
diff changeset
526 if self._hasctx(newmapping):
be3f33f5e232 templater: switch 'revcache' based on new mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37888
diff changeset
527 mapping['revcache'] = {} # per-ctx cache
37891
e7bc0667c521 formatter: make 'originalnode' a thing in log-like templates
Yuya Nishihara <yuya@tcha.org>
parents: 37890
diff changeset
528 if (('node' in origmapping or self._hasctx(origmapping))
e7bc0667c521 formatter: make 'originalnode' a thing in log-like templates
Yuya Nishihara <yuya@tcha.org>
parents: 37890
diff changeset
529 and ('node' in newmapping or self._hasctx(newmapping))):
e7bc0667c521 formatter: make 'originalnode' a thing in log-like templates
Yuya Nishihara <yuya@tcha.org>
parents: 37890
diff changeset
530 orignode = templateutil.runsymbol(context, origmapping, 'node')
e7bc0667c521 formatter: make 'originalnode' a thing in log-like templates
Yuya Nishihara <yuya@tcha.org>
parents: 37890
diff changeset
531 mapping['originalnode'] = orignode
37889
be3f33f5e232 templater: switch 'revcache' based on new mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37888
diff changeset
532 return mapping
37888
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37861
diff changeset
533
37859
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
534 def _getsome(self, context, mapping, key):
37769
036e4483d3a1 templater: process mapping dict by resource callables
Yuya Nishihara <yuya@tcha.org>
parents: 37768
diff changeset
535 v = mapping.get(key)
036e4483d3a1 templater: process mapping dict by resource callables
Yuya Nishihara <yuya@tcha.org>
parents: 37768
diff changeset
536 if v is not None:
036e4483d3a1 templater: process mapping dict by resource callables
Yuya Nishihara <yuya@tcha.org>
parents: 37768
diff changeset
537 return v
37859
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
538 return self._resmap.get(key)
37768
255f635c3204 templater: convert resources to a table of callables for future extension
Yuya Nishihara <yuya@tcha.org>
parents: 37707
diff changeset
539
37889
be3f33f5e232 templater: switch 'revcache' based on new mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37888
diff changeset
540 def _hasctx(self, mapping):
be3f33f5e232 templater: switch 'revcache' based on new mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37888
diff changeset
541 return 'ctx' in mapping or 'fctx' in mapping
be3f33f5e232 templater: switch 'revcache' based on new mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37888
diff changeset
542
37859
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
543 def _getctx(self, context, mapping, key):
37770
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 37769
diff changeset
544 ctx = mapping.get('ctx')
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 37769
diff changeset
545 if ctx is not None:
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 37769
diff changeset
546 return ctx
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 37769
diff changeset
547 fctx = mapping.get('fctx')
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 37769
diff changeset
548 if fctx is not None:
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 37769
diff changeset
549 return fctx.changectx()
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 37769
diff changeset
550
37859
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
551 def _getrepo(self, context, mapping, key):
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
552 ctx = self._getctx(context, mapping, 'ctx')
37770
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 37769
diff changeset
553 if ctx is not None:
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 37769
diff changeset
554 return ctx.repo()
37859
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
555 return self._getsome(context, mapping, key)
37770
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 37769
diff changeset
556
37859
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
557 _gettermap = {
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
558 'cache': _getsome,
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
559 'ctx': _getctx,
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
560 'fctx': _getsome,
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
561 'repo': _getrepo,
37889
be3f33f5e232 templater: switch 'revcache' based on new mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37888
diff changeset
562 'revcache': _getsome,
37859
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
563 'ui': _getsome,
37768
255f635c3204 templater: convert resources to a table of callables for future extension
Yuya Nishihara <yuya@tcha.org>
parents: 37707
diff changeset
564 }
37859
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37775
diff changeset
565 _knownkeys = set(_gettermap.keys())
37768
255f635c3204 templater: convert resources to a table of callables for future extension
Yuya Nishihara <yuya@tcha.org>
parents: 37707
diff changeset
566
33362
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32938
diff changeset
567 def formatter(ui, out, topic, opts):
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
568 template = opts.get("template", "")
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
569 if template == "json":
33362
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32938
diff changeset
570 return jsonformatter(ui, out, topic, opts)
22430
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
571 elif template == "pickle":
33362
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32938
diff changeset
572 return pickleformatter(ui, out, topic, opts)
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
573 elif template == "debug":
33362
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32938
diff changeset
574 return debugformatter(ui, out, topic, opts)
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
575 elif template != "":
33362
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32938
diff changeset
576 return templateformatter(ui, out, topic, opts)
26398
31137258ae8b formatter: mark developer options
Matt Mackall <mpm@selenic.com>
parents: 26049
diff changeset
577 # developer config: ui.formatdebug
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
578 elif ui.configbool('ui', 'formatdebug'):
33362
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32938
diff changeset
579 return debugformatter(ui, out, topic, opts)
26398
31137258ae8b formatter: mark developer options
Matt Mackall <mpm@selenic.com>
parents: 26049
diff changeset
580 # deprecated config: ui.formatjson
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
581 elif ui.configbool('ui', 'formatjson'):
33362
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32938
diff changeset
582 return jsonformatter(ui, out, topic, opts)
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32938
diff changeset
583 return plainformatter(ui, out, topic, opts)
33363
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 33362
diff changeset
584
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 33362
diff changeset
585 @contextlib.contextmanager
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 33362
diff changeset
586 def openformatter(ui, filename, topic, opts):
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 33362
diff changeset
587 """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: 33362
diff changeset
588
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 33362
diff changeset
589 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: 33362
diff changeset
590 """
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 33362
diff changeset
591 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: 33362
diff changeset
592 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: 33362
diff changeset
593 yield fm
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 33362
diff changeset
594
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 33362
diff changeset
595 @contextlib.contextmanager
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 33362
diff changeset
596 def _neverending(fm):
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 33362
diff changeset
597 yield fm
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 33362
diff changeset
598
38383
d110167610db formatter: carry opts to file-based formatters by basefm
Yuya Nishihara <yuya@tcha.org>
parents: 38382
diff changeset
599 def maybereopen(fm, filename):
33363
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 33362
diff changeset
600 """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: 33362
diff changeset
601 the given formatter
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 33362
diff changeset
602
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 33362
diff changeset
603 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: 33362
diff changeset
604 of the given formatter.
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 33362
diff changeset
605 """
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 33362
diff changeset
606 if filename:
38383
d110167610db formatter: carry opts to file-based formatters by basefm
Yuya Nishihara <yuya@tcha.org>
parents: 38382
diff changeset
607 return openformatter(fm._ui, filename, fm._topic, fm._opts)
33363
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 33362
diff changeset
608 else:
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 33362
diff changeset
609 return _neverending(fm)