Mercurial > hg
annotate mercurial/formatter.py @ 32076:d7b698ae153b stable
help: explain how to access subtopics in internals
author | Matt DeVore <matvore@google.com> |
---|---|
date | Wed, 19 Apr 2017 17:04:22 -0700 |
parents | 5b2241e84982 |
children | 0fd15522a848 |
rev | line source |
---|---|
16134 | 1 # formatter.py - generic output formatting for mercurial |
2 # | |
3 # Copyright 2012 Matt Mackall <mpm@selenic.com> | |
4 # | |
5 # This software may be used and distributed according to the terms of the | |
6 # GNU General Public License version 2 or any later version. | |
7 | |
30560
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
8 """Generic output formatting for Mercurial |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
9 |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
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:
29949
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:
29949
diff
changeset
|
12 |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
13 - fm.write() for unconditional output |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
14 - fm.condwrite() to show some extra data conditionally in plain output |
31172
16272d8c24f6
formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents:
31170
diff
changeset
|
15 - fm.context() to provide changectx to template output |
30560
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
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:
29949
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:
29949
diff
changeset
|
18 |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
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:
29949
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:
29949
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:
29949
diff
changeset
|
22 supported by the formatter API. |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
23 |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
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:
29949
diff
changeset
|
25 |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
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:
29949
diff
changeset
|
27 |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
28 fm.condwrite() vs 'if cond:': |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
29 |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
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:
29949
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:
29949
diff
changeset
|
32 fm.write(). |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
33 |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
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:
29949
diff
changeset
|
35 |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
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:
29949
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:
29949
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:
29949
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:
29949
diff
changeset
|
40 "{get(foo, key)}" function. |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
41 |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
42 Doctest helper: |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
43 |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
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:
29949
diff
changeset
|
45 ... import sys |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
46 ... from . import ui as uimod |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
47 ... ui = uimod.ui() |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
48 ... ui.fout = sys.stdout # redirect to doctest |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
49 ... ui.verbose = verbose |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
50 ... return fn(ui, ui.formatter(fn.__name__, opts)) |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
51 |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
52 Basic example: |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
53 |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
54 >>> def files(ui, fm): |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
55 ... files = [('foo', 123, (0, 0)), ('bar', 456, (1, 0))] |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
56 ... for f in files: |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
57 ... fm.startitem() |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
58 ... fm.write('path', '%s', f[0]) |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
59 ... fm.condwrite(ui.verbose, 'date', ' %s', |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
60 ... fm.formatdate(f[2], '%Y-%m-%d %H:%M:%S')) |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
61 ... fm.data(size=f[1]) |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
62 ... fm.plain('\\n') |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
63 ... fm.end() |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
64 >>> show(files) |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
65 foo |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
66 bar |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
67 >>> show(files, verbose=True) |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
68 foo 1970-01-01 00:00:00 |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
69 bar 1970-01-01 00:00:01 |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
70 >>> show(files, template='json') |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
71 [ |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
72 { |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
73 "date": [0, 0], |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
74 "path": "foo", |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
75 "size": 123 |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
76 }, |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
77 { |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
78 "date": [1, 0], |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
79 "path": "bar", |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
80 "size": 456 |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
81 } |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
82 ] |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
83 >>> show(files, template='path: {path}\\ndate: {date|rfc3339date}\\n') |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
84 path: foo |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
85 date: 1970-01-01T00:00:00+00:00 |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
86 path: bar |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
87 date: 1970-01-01T00:00:01+00:00 |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
88 |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
89 Nested example: |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
90 |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
91 >>> def subrepos(ui, fm): |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
92 ... fm.startitem() |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
93 ... fm.write('repo', '[%s]\\n', 'baz') |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
94 ... files(ui, fm.nested('files')) |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
95 ... fm.end() |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
96 >>> show(subrepos) |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
97 [baz] |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
98 foo |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
99 bar |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
100 >>> show(subrepos, template='{repo}: {join(files % "{path}", ", ")}\\n') |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
101 baz: foo, bar |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
102 """ |
783016005122
formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents:
29949
diff
changeset
|
103 |
25950
175873e36d03
formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25838
diff
changeset
|
104 from __future__ import absolute_import |
175873e36d03
formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25838
diff
changeset
|
105 |
31807
e6eb86b154c5
templater: provide loop counter as "index" keyword
Yuya Nishihara <yuya@tcha.org>
parents:
31805
diff
changeset
|
106 import itertools |
25511
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
107 import os |
22428
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
108 |
25950
175873e36d03
formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25838
diff
changeset
|
109 from .i18n import _ |
175873e36d03
formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25838
diff
changeset
|
110 from .node import ( |
175873e36d03
formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25838
diff
changeset
|
111 hex, |
175873e36d03
formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25838
diff
changeset
|
112 short, |
175873e36d03
formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25838
diff
changeset
|
113 ) |
175873e36d03
formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25838
diff
changeset
|
114 |
175873e36d03
formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25838
diff
changeset
|
115 from . import ( |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
26373
diff
changeset
|
116 error, |
31782
654e9a1c8a6c
formatter: use templatefilters.json()
Yuya Nishihara <yuya@tcha.org>
parents:
31396
diff
changeset
|
117 templatefilters, |
29676
c3a9cd78b151
formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents:
29324
diff
changeset
|
118 templatekw, |
25950
175873e36d03
formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25838
diff
changeset
|
119 templater, |
29324
b501579147f1
py3: conditionalize cPickle import by adding in util
Pulkit Goyal <7895pulkit@gmail.com>
parents:
28957
diff
changeset
|
120 util, |
25950
175873e36d03
formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25838
diff
changeset
|
121 ) |
175873e36d03
formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25838
diff
changeset
|
122 |
29324
b501579147f1
py3: conditionalize cPickle import by adding in util
Pulkit Goyal <7895pulkit@gmail.com>
parents:
28957
diff
changeset
|
123 pickle = util.pickle |
b501579147f1
py3: conditionalize cPickle import by adding in util
Pulkit Goyal <7895pulkit@gmail.com>
parents:
28957
diff
changeset
|
124 |
29836
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
125 class _nullconverter(object): |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
126 '''convert non-primitive data types to be processed by formatter''' |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
127 @staticmethod |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
128 def formatdate(date, fmt): |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
129 '''convert date tuple to appropriate format''' |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
130 return date |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
131 @staticmethod |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
132 def formatdict(data, key, value, fmt, sep): |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
133 '''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:
29794
diff
changeset
|
134 # 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:
29794
diff
changeset
|
135 # serialized as a builtin dict in pickle output |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
136 return dict(data) |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
137 @staticmethod |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
138 def formatlist(data, name, fmt, sep): |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
139 '''convert iterable to appropriate list format''' |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
140 return list(data) |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
141 |
16134 | 142 class baseformatter(object): |
29836
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
143 def __init__(self, ui, topic, opts, converter): |
16134 | 144 self._ui = ui |
145 self._topic = topic | |
146 self._style = opts.get("style") | |
147 self._template = opts.get("template") | |
29836
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
148 self._converter = converter |
16134 | 149 self._item = None |
22701
cb28d2b3db0b
formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents:
22674
diff
changeset
|
150 # 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
|
151 self.hexfunc = hex |
29882
307b20e5e505
formatter: add context manager interface for convenience
Yuya Nishihara <yuya@tcha.org>
parents:
29837
diff
changeset
|
152 def __enter__(self): |
307b20e5e505
formatter: add context manager interface for convenience
Yuya Nishihara <yuya@tcha.org>
parents:
29837
diff
changeset
|
153 return self |
307b20e5e505
formatter: add context manager interface for convenience
Yuya Nishihara <yuya@tcha.org>
parents:
29837
diff
changeset
|
154 def __exit__(self, exctype, excvalue, traceback): |
307b20e5e505
formatter: add context manager interface for convenience
Yuya Nishihara <yuya@tcha.org>
parents:
29837
diff
changeset
|
155 if exctype is None: |
307b20e5e505
formatter: add context manager interface for convenience
Yuya Nishihara <yuya@tcha.org>
parents:
29837
diff
changeset
|
156 self.end() |
16134 | 157 def _showitem(self): |
158 '''show a formatted item once all data is collected''' | |
159 pass | |
160 def startitem(self): | |
161 '''begin an item in the format list''' | |
162 if self._item is not None: | |
163 self._showitem() | |
164 self._item = {} | |
29836
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
165 def formatdate(self, date, fmt='%a %b %d %H:%M:%S %Y %1%2'): |
29678
2f3f18ad55a2
formatter: add function to convert date tuple to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents:
29676
diff
changeset
|
166 '''convert date tuple to appropriate format''' |
29836
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
167 return self._converter.formatdate(date, fmt) |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
168 def formatdict(self, data, key='key', value='value', fmt='%s=%s', sep=' '): |
29794
4891f3b93182
formatter: add function to convert dict to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents:
29678
diff
changeset
|
169 '''convert dict or key-value pairs to appropriate dict format''' |
29836
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
170 return self._converter.formatdict(data, key, value, fmt, sep) |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
171 def formatlist(self, data, name, fmt='%s', sep=' '): |
29676
c3a9cd78b151
formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents:
29324
diff
changeset
|
172 '''convert iterable to appropriate list format''' |
29836
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
173 # 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:
29794
diff
changeset
|
174 # we have default template keyword, e.g. {item} |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
175 return self._converter.formatlist(data, name, fmt, sep) |
31172
16272d8c24f6
formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents:
31170
diff
changeset
|
176 def context(self, **ctxs): |
16272d8c24f6
formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents:
31170
diff
changeset
|
177 '''insert context objects to be used to render template keywords''' |
16272d8c24f6
formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents:
31170
diff
changeset
|
178 pass |
16134 | 179 def data(self, **data): |
180 '''insert data into item that's not shown in default output''' | |
17630
ff5ed1ecd43a
formatter: improve implementation of data method
David M. Carr <david@carrclan.us>
parents:
17597
diff
changeset
|
181 self._item.update(data) |
16134 | 182 def write(self, fields, deftext, *fielddata, **opts): |
183 '''do default text output while assigning data to item''' | |
26372
55de800937e0
formatter: verify number of arguments passed to write functions
Yuya Nishihara <yuya@tcha.org>
parents:
25950
diff
changeset
|
184 fieldkeys = fields.split() |
55de800937e0
formatter: verify number of arguments passed to write functions
Yuya Nishihara <yuya@tcha.org>
parents:
25950
diff
changeset
|
185 assert len(fieldkeys) == len(fielddata) |
26373
aa610ffad4e8
formatter: use dict.update() to set arguments passed to write functions
Yuya Nishihara <yuya@tcha.org>
parents:
26372
diff
changeset
|
186 self._item.update(zip(fieldkeys, fielddata)) |
17909
3326fd05eb1f
formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents:
17630
diff
changeset
|
187 def condwrite(self, cond, fields, deftext, *fielddata, **opts): |
3326fd05eb1f
formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents:
17630
diff
changeset
|
188 '''do conditional write (primarily for plain formatter)''' |
26372
55de800937e0
formatter: verify number of arguments passed to write functions
Yuya Nishihara <yuya@tcha.org>
parents:
25950
diff
changeset
|
189 fieldkeys = fields.split() |
55de800937e0
formatter: verify number of arguments passed to write functions
Yuya Nishihara <yuya@tcha.org>
parents:
25950
diff
changeset
|
190 assert len(fieldkeys) == len(fielddata) |
26373
aa610ffad4e8
formatter: use dict.update() to set arguments passed to write functions
Yuya Nishihara <yuya@tcha.org>
parents:
26372
diff
changeset
|
191 self._item.update(zip(fieldkeys, fielddata)) |
16134 | 192 def plain(self, text, **opts): |
193 '''show raw text for non-templated mode''' | |
194 pass | |
29949
e7cacb45c4be
formatter: introduce isplain() to replace (the inverse of) __nonzero__() (API)
Mathias De Maré <mathias.demare@gmail.com>
parents:
29882
diff
changeset
|
195 def isplain(self): |
e7cacb45c4be
formatter: introduce isplain() to replace (the inverse of) __nonzero__() (API)
Mathias De Maré <mathias.demare@gmail.com>
parents:
29882
diff
changeset
|
196 '''check for plain formatter usage''' |
e7cacb45c4be
formatter: introduce isplain() to replace (the inverse of) __nonzero__() (API)
Mathias De Maré <mathias.demare@gmail.com>
parents:
29882
diff
changeset
|
197 return False |
29837
5b886289a1ca
formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents:
29836
diff
changeset
|
198 def nested(self, field): |
5b886289a1ca
formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents:
29836
diff
changeset
|
199 '''sub formatter to store nested data in the specified field''' |
5b886289a1ca
formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents:
29836
diff
changeset
|
200 self._item[field] = data = [] |
5b886289a1ca
formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents:
29836
diff
changeset
|
201 return _nestedformatter(self._ui, self._converter, data) |
16134 | 202 def end(self): |
203 '''end output for the formatter''' | |
204 if self._item is not None: | |
205 self._showitem() | |
206 | |
29837
5b886289a1ca
formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents:
29836
diff
changeset
|
207 class _nestedformatter(baseformatter): |
5b886289a1ca
formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents:
29836
diff
changeset
|
208 '''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:
29836
diff
changeset
|
209 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:
29836
diff
changeset
|
210 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:
29836
diff
changeset
|
211 self._data = data |
5b886289a1ca
formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents:
29836
diff
changeset
|
212 def _showitem(self): |
5b886289a1ca
formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents:
29836
diff
changeset
|
213 self._data.append(self._item) |
5b886289a1ca
formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents:
29836
diff
changeset
|
214 |
29794
4891f3b93182
formatter: add function to convert dict to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents:
29678
diff
changeset
|
215 def _iteritems(data): |
4891f3b93182
formatter: add function to convert dict to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents:
29678
diff
changeset
|
216 '''iterate key-value pairs in stable order''' |
4891f3b93182
formatter: add function to convert dict to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents:
29678
diff
changeset
|
217 if isinstance(data, dict): |
4891f3b93182
formatter: add function to convert dict to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents:
29678
diff
changeset
|
218 return sorted(data.iteritems()) |
4891f3b93182
formatter: add function to convert dict to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents:
29678
diff
changeset
|
219 return data |
4891f3b93182
formatter: add function to convert dict to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents:
29678
diff
changeset
|
220 |
29836
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
221 class _plainconverter(object): |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
222 '''convert non-primitive data types to text''' |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
223 @staticmethod |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
224 def formatdate(date, fmt): |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
225 '''stringify date tuple in the given format''' |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
226 return util.datestr(date, fmt) |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
227 @staticmethod |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
228 def formatdict(data, key, value, fmt, sep): |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
229 '''stringify key-value pairs separated by sep''' |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
230 return sep.join(fmt % (k, v) for k, v in _iteritems(data)) |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
231 @staticmethod |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
232 def formatlist(data, name, fmt, sep): |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
233 '''stringify iterable separated by sep''' |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
234 return sep.join(fmt % e for e in data) |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
235 |
16134 | 236 class plainformatter(baseformatter): |
237 '''the default text output scheme''' | |
238 def __init__(self, ui, topic, opts): | |
29836
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
239 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
|
240 if ui.debugflag: |
cb28d2b3db0b
formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents:
22674
diff
changeset
|
241 self.hexfunc = hex |
cb28d2b3db0b
formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents:
22674
diff
changeset
|
242 else: |
cb28d2b3db0b
formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents:
22674
diff
changeset
|
243 self.hexfunc = short |
16134 | 244 def startitem(self): |
245 pass | |
246 def data(self, **data): | |
247 pass | |
248 def write(self, fields, deftext, *fielddata, **opts): | |
249 self._ui.write(deftext % fielddata, **opts) | |
17909
3326fd05eb1f
formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents:
17630
diff
changeset
|
250 def condwrite(self, cond, fields, deftext, *fielddata, **opts): |
3326fd05eb1f
formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents:
17630
diff
changeset
|
251 '''do conditional write''' |
3326fd05eb1f
formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents:
17630
diff
changeset
|
252 if cond: |
3326fd05eb1f
formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents:
17630
diff
changeset
|
253 self._ui.write(deftext % fielddata, **opts) |
16134 | 254 def plain(self, text, **opts): |
255 self._ui.write(text, **opts) | |
29949
e7cacb45c4be
formatter: introduce isplain() to replace (the inverse of) __nonzero__() (API)
Mathias De Maré <mathias.demare@gmail.com>
parents:
29882
diff
changeset
|
256 def isplain(self): |
e7cacb45c4be
formatter: introduce isplain() to replace (the inverse of) __nonzero__() (API)
Mathias De Maré <mathias.demare@gmail.com>
parents:
29882
diff
changeset
|
257 return True |
29837
5b886289a1ca
formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents:
29836
diff
changeset
|
258 def nested(self, field): |
5b886289a1ca
formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents:
29836
diff
changeset
|
259 # 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:
29836
diff
changeset
|
260 return self |
16134 | 261 def end(self): |
262 pass | |
263 | |
264 class debugformatter(baseformatter): | |
31182
5660c45ecba6
formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents:
31172
diff
changeset
|
265 def __init__(self, ui, out, topic, opts): |
29836
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
266 baseformatter.__init__(self, ui, topic, opts, _nullconverter) |
31182
5660c45ecba6
formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents:
31172
diff
changeset
|
267 self._out = out |
5660c45ecba6
formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents:
31172
diff
changeset
|
268 self._out.write("%s = [\n" % self._topic) |
16134 | 269 def _showitem(self): |
31182
5660c45ecba6
formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents:
31172
diff
changeset
|
270 self._out.write(" " + repr(self._item) + ",\n") |
16134 | 271 def end(self): |
272 baseformatter.end(self) | |
31182
5660c45ecba6
formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents:
31172
diff
changeset
|
273 self._out.write("]\n") |
16134 | 274 |
22430
968247e8f4ac
formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents:
22428
diff
changeset
|
275 class pickleformatter(baseformatter): |
31182
5660c45ecba6
formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents:
31172
diff
changeset
|
276 def __init__(self, ui, out, topic, opts): |
29836
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
277 baseformatter.__init__(self, ui, topic, opts, _nullconverter) |
31182
5660c45ecba6
formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents:
31172
diff
changeset
|
278 self._out = out |
22430
968247e8f4ac
formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents:
22428
diff
changeset
|
279 self._data = [] |
968247e8f4ac
formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents:
22428
diff
changeset
|
280 def _showitem(self): |
968247e8f4ac
formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents:
22428
diff
changeset
|
281 self._data.append(self._item) |
968247e8f4ac
formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents:
22428
diff
changeset
|
282 def end(self): |
968247e8f4ac
formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents:
22428
diff
changeset
|
283 baseformatter.end(self) |
31182
5660c45ecba6
formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents:
31172
diff
changeset
|
284 self._out.write(pickle.dumps(self._data)) |
22430
968247e8f4ac
formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents:
22428
diff
changeset
|
285 |
22428
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
286 class jsonformatter(baseformatter): |
31182
5660c45ecba6
formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents:
31172
diff
changeset
|
287 def __init__(self, ui, out, topic, opts): |
29836
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
288 baseformatter.__init__(self, ui, topic, opts, _nullconverter) |
31182
5660c45ecba6
formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents:
31172
diff
changeset
|
289 self._out = out |
5660c45ecba6
formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents:
31172
diff
changeset
|
290 self._out.write("[") |
31298
59d09565ac77
formatter: set _first on formatter, not ui
Martin von Zweigbergk <martinvonz@google.com>
parents:
31182
diff
changeset
|
291 self._first = True |
22428
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
292 def _showitem(self): |
31298
59d09565ac77
formatter: set _first on formatter, not ui
Martin von Zweigbergk <martinvonz@google.com>
parents:
31182
diff
changeset
|
293 if self._first: |
59d09565ac77
formatter: set _first on formatter, not ui
Martin von Zweigbergk <martinvonz@google.com>
parents:
31182
diff
changeset
|
294 self._first = False |
22428
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
295 else: |
31182
5660c45ecba6
formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents:
31172
diff
changeset
|
296 self._out.write(",") |
22428
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
297 |
31182
5660c45ecba6
formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents:
31172
diff
changeset
|
298 self._out.write("\n {\n") |
22428
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
299 first = True |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
300 for k, v in sorted(self._item.items()): |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
301 if first: |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
302 first = False |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
303 else: |
31182
5660c45ecba6
formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents:
31172
diff
changeset
|
304 self._out.write(",\n") |
31782
654e9a1c8a6c
formatter: use templatefilters.json()
Yuya Nishihara <yuya@tcha.org>
parents:
31396
diff
changeset
|
305 u = templatefilters.json(v, paranoid=False) |
654e9a1c8a6c
formatter: use templatefilters.json()
Yuya Nishihara <yuya@tcha.org>
parents:
31396
diff
changeset
|
306 self._out.write(' "%s": %s' % (k, u)) |
31182
5660c45ecba6
formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents:
31172
diff
changeset
|
307 self._out.write("\n }") |
22428
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
308 def end(self): |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
309 baseformatter.end(self) |
31182
5660c45ecba6
formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents:
31172
diff
changeset
|
310 self._out.write("\n]\n") |
22428
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
311 |
29836
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
312 class _templateconverter(object): |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
313 '''convert non-primitive data types to be processed by templater''' |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
314 @staticmethod |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
315 def formatdate(date, fmt): |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
316 '''return date tuple''' |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
317 return date |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
318 @staticmethod |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
319 def formatdict(data, key, value, fmt, sep): |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
320 '''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:
29794
diff
changeset
|
321 data = util.sortdict(_iteritems(data)) |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
322 def f(): |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
323 yield _plainconverter.formatdict(data, key, value, fmt, sep) |
31925
5b2241e84982
templatekw: add public function to wrap a dict by _hybrid object
Yuya Nishihara <yuya@tcha.org>
parents:
31924
diff
changeset
|
324 return templatekw.hybriddict(data, key=key, value=value, fmt=fmt, |
5b2241e84982
templatekw: add public function to wrap a dict by _hybrid object
Yuya Nishihara <yuya@tcha.org>
parents:
31924
diff
changeset
|
325 gen=f()) |
29836
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
326 @staticmethod |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
327 def formatlist(data, name, fmt, sep): |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
328 '''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:
29794
diff
changeset
|
329 data = list(data) |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
330 def f(): |
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
331 yield _plainconverter.formatlist(data, name, fmt, sep) |
31924
21f129354dd0
templatekw: add public function to wrap a list by _hybrid object
Yuya Nishihara <yuya@tcha.org>
parents:
31807
diff
changeset
|
332 return templatekw.hybridlist(data, name=name, fmt=fmt, gen=f()) |
29836
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
333 |
25513
0c6f98398f8a
formatter: add template support
Matt Mackall <mpm@selenic.com>
parents:
25512
diff
changeset
|
334 class templateformatter(baseformatter): |
31182
5660c45ecba6
formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents:
31172
diff
changeset
|
335 def __init__(self, ui, out, topic, opts): |
29836
18bac830eef3
formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents:
29794
diff
changeset
|
336 baseformatter.__init__(self, ui, topic, opts, _templateconverter) |
31182
5660c45ecba6
formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents:
31172
diff
changeset
|
337 self._out = out |
25513
0c6f98398f8a
formatter: add template support
Matt Mackall <mpm@selenic.com>
parents:
25512
diff
changeset
|
338 self._topic = topic |
31172
16272d8c24f6
formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents:
31170
diff
changeset
|
339 self._t = gettemplater(ui, topic, opts.get('template', ''), |
16272d8c24f6
formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents:
31170
diff
changeset
|
340 cache=templatekw.defaulttempl) |
31807
e6eb86b154c5
templater: provide loop counter as "index" keyword
Yuya Nishihara <yuya@tcha.org>
parents:
31805
diff
changeset
|
341 self._counter = itertools.count() |
31172
16272d8c24f6
formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents:
31170
diff
changeset
|
342 self._cache = {} # for templatekw/funcs to store reusable data |
16272d8c24f6
formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents:
31170
diff
changeset
|
343 def context(self, **ctxs): |
16272d8c24f6
formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents:
31170
diff
changeset
|
344 '''insert context objects to be used to render template keywords''' |
16272d8c24f6
formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents:
31170
diff
changeset
|
345 assert all(k == 'ctx' for k in ctxs) |
16272d8c24f6
formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents:
31170
diff
changeset
|
346 self._item.update(ctxs) |
25513
0c6f98398f8a
formatter: add template support
Matt Mackall <mpm@selenic.com>
parents:
25512
diff
changeset
|
347 def _showitem(self): |
31172
16272d8c24f6
formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents:
31170
diff
changeset
|
348 # TODO: add support for filectx. probably each template keyword or |
16272d8c24f6
formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents:
31170
diff
changeset
|
349 # function will have to declare dependent resources. e.g. |
16272d8c24f6
formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents:
31170
diff
changeset
|
350 # @templatekeyword(..., requires=('ctx',)) |
31805
dca9b6922514
formatter: reorder code that builds template mapping
Yuya Nishihara <yuya@tcha.org>
parents:
31782
diff
changeset
|
351 props = {} |
31172
16272d8c24f6
formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents:
31170
diff
changeset
|
352 if 'ctx' in self._item: |
31805
dca9b6922514
formatter: reorder code that builds template mapping
Yuya Nishihara <yuya@tcha.org>
parents:
31782
diff
changeset
|
353 props.update(templatekw.keywords) |
31807
e6eb86b154c5
templater: provide loop counter as "index" keyword
Yuya Nishihara <yuya@tcha.org>
parents:
31805
diff
changeset
|
354 props['index'] = next(self._counter) |
31805
dca9b6922514
formatter: reorder code that builds template mapping
Yuya Nishihara <yuya@tcha.org>
parents:
31782
diff
changeset
|
355 # explicitly-defined fields precede templatekw |
dca9b6922514
formatter: reorder code that builds template mapping
Yuya Nishihara <yuya@tcha.org>
parents:
31782
diff
changeset
|
356 props.update(self._item) |
dca9b6922514
formatter: reorder code that builds template mapping
Yuya Nishihara <yuya@tcha.org>
parents:
31782
diff
changeset
|
357 if 'ctx' in self._item: |
31172
16272d8c24f6
formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents:
31170
diff
changeset
|
358 # but template resources must be always available |
16272d8c24f6
formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents:
31170
diff
changeset
|
359 props['templ'] = self._t |
16272d8c24f6
formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents:
31170
diff
changeset
|
360 props['repo'] = props['ctx'].repo() |
16272d8c24f6
formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents:
31170
diff
changeset
|
361 props['revcache'] = {} |
16272d8c24f6
formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents:
31170
diff
changeset
|
362 g = self._t(self._topic, ui=self._ui, cache=self._cache, **props) |
31182
5660c45ecba6
formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents:
31172
diff
changeset
|
363 self._out.write(templater.stringify(g)) |
25513
0c6f98398f8a
formatter: add template support
Matt Mackall <mpm@selenic.com>
parents:
25512
diff
changeset
|
364 |
25511
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
365 def lookuptemplate(ui, topic, tmpl): |
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
366 # looks like a literal template? |
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
367 if '{' in tmpl: |
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
368 return tmpl, None |
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
369 |
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
370 # perhaps a stock style? |
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
371 if not os.path.split(tmpl)[0]: |
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
372 mapname = (templater.templatepath('map-cmdline.' + tmpl) |
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
373 or templater.templatepath(tmpl)) |
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
374 if mapname and os.path.isfile(mapname): |
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
375 return None, mapname |
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
376 |
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
377 # perhaps it's a reference to [templates] |
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
378 t = ui.config('templates', tmpl) |
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
379 if t: |
28630
bf35644b9f3a
templater: relax unquotestring() to fall back to bare string
Yuya Nishihara <yuya@tcha.org>
parents:
28384
diff
changeset
|
380 return templater.unquotestring(t), None |
25511
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
381 |
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
382 if tmpl == 'list': |
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
383 ui.write(_("available styles: %s\n") % templater.stylelist()) |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
26373
diff
changeset
|
384 raise error.Abort(_("specify a template")) |
25511
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
385 |
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
386 # perhaps it's a path to a map or a template |
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
387 if ('/' in tmpl or '\\' in tmpl) and os.path.isfile(tmpl): |
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
388 # is it a mapfile for a style? |
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
389 if os.path.basename(tmpl).startswith("map-"): |
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
390 return None, os.path.realpath(tmpl) |
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
391 tmpl = open(tmpl).read() |
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
392 return tmpl, None |
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
393 |
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
394 # constant string? |
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
395 return tmpl, None |
c2a4dfe2a336
formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents:
24321
diff
changeset
|
396 |
31172
16272d8c24f6
formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents:
31170
diff
changeset
|
397 def gettemplater(ui, topic, spec, cache=None): |
25512
8463433c2689
formatter: add a method to build a full templater from a -T option
Matt Mackall <mpm@selenic.com>
parents:
25511
diff
changeset
|
398 tmpl, mapfile = lookuptemplate(ui, topic, spec) |
28954
f97a0bcfd7a1
templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents:
28630
diff
changeset
|
399 assert not (tmpl and mapfile) |
f97a0bcfd7a1
templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents:
28630
diff
changeset
|
400 if mapfile: |
31172
16272d8c24f6
formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents:
31170
diff
changeset
|
401 return templater.templater.frommapfile(mapfile, cache=cache) |
16272d8c24f6
formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents:
31170
diff
changeset
|
402 return maketemplater(ui, topic, tmpl, cache=cache) |
28955
78759f78a44e
templater: factor out function that creates templater from string template
Yuya Nishihara <yuya@tcha.org>
parents:
28954
diff
changeset
|
403 |
31170
e64b70c96338
formatter: drop filters argument from maketemplater()
Yuya Nishihara <yuya@tcha.org>
parents:
30560
diff
changeset
|
404 def maketemplater(ui, topic, tmpl, cache=None): |
28955
78759f78a44e
templater: factor out function that creates templater from string template
Yuya Nishihara <yuya@tcha.org>
parents:
28954
diff
changeset
|
405 """Create a templater from a string template 'tmpl'""" |
28957
d813132ea361
templater: load and expand aliases by template engine (API) (issue4842)
Yuya Nishihara <yuya@tcha.org>
parents:
28955
diff
changeset
|
406 aliases = ui.configitems('templatealias') |
31170
e64b70c96338
formatter: drop filters argument from maketemplater()
Yuya Nishihara <yuya@tcha.org>
parents:
30560
diff
changeset
|
407 t = templater.templater(cache=cache, aliases=aliases) |
25512
8463433c2689
formatter: add a method to build a full templater from a -T option
Matt Mackall <mpm@selenic.com>
parents:
25511
diff
changeset
|
408 if tmpl: |
8463433c2689
formatter: add a method to build a full templater from a -T option
Matt Mackall <mpm@selenic.com>
parents:
25511
diff
changeset
|
409 t.cache[topic] = tmpl |
8463433c2689
formatter: add a method to build a full templater from a -T option
Matt Mackall <mpm@selenic.com>
parents:
25511
diff
changeset
|
410 return t |
8463433c2689
formatter: add a method to build a full templater from a -T option
Matt Mackall <mpm@selenic.com>
parents:
25511
diff
changeset
|
411 |
16134 | 412 def formatter(ui, topic, opts): |
22428
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
413 template = opts.get("template", "") |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
414 if template == "json": |
31182
5660c45ecba6
formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents:
31172
diff
changeset
|
415 return jsonformatter(ui, ui, topic, opts) |
22430
968247e8f4ac
formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents:
22428
diff
changeset
|
416 elif template == "pickle": |
31182
5660c45ecba6
formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents:
31172
diff
changeset
|
417 return pickleformatter(ui, ui, topic, opts) |
22428
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
418 elif template == "debug": |
31182
5660c45ecba6
formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents:
31172
diff
changeset
|
419 return debugformatter(ui, ui, topic, opts) |
22428
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
420 elif template != "": |
31182
5660c45ecba6
formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents:
31172
diff
changeset
|
421 return templateformatter(ui, ui, topic, opts) |
25838
31137258ae8b
formatter: mark developer options
Matt Mackall <mpm@selenic.com>
parents:
25513
diff
changeset
|
422 # developer config: ui.formatdebug |
22428
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
423 elif ui.configbool('ui', 'formatdebug'): |
31182
5660c45ecba6
formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents:
31172
diff
changeset
|
424 return debugformatter(ui, ui, topic, opts) |
25838
31137258ae8b
formatter: mark developer options
Matt Mackall <mpm@selenic.com>
parents:
25513
diff
changeset
|
425 # deprecated config: ui.formatjson |
22428
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
426 elif ui.configbool('ui', 'formatjson'): |
31182
5660c45ecba6
formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents:
31172
diff
changeset
|
427 return jsonformatter(ui, ui, topic, opts) |
16134 | 428 return plainformatter(ui, topic, opts) |