##// END OF EJS Templates
templatekw: add helper method to generate a template keyword for a namespace...
Sean Farley -
r23609:40fcf6c0 default
parent child Browse files
Show More
@@ -1,435 +1,443 b''
1 # templatekw.py - common changeset template keywords
1 # templatekw.py - common changeset template keywords
2 #
2 #
3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
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.
6 # GNU General Public License version 2 or any later version.
7
7
8 from node import hex
8 from node import hex
9 import patch, util, error
9 import patch, util, error
10 import hbisect
10 import hbisect
11
11
12 # This helper class allows us to handle both:
12 # This helper class allows us to handle both:
13 # "{files}" (legacy command-line-specific list hack) and
13 # "{files}" (legacy command-line-specific list hack) and
14 # "{files % '{file}\n'}" (hgweb-style with inlining and function support)
14 # "{files % '{file}\n'}" (hgweb-style with inlining and function support)
15
15
16 class _hybrid(object):
16 class _hybrid(object):
17 def __init__(self, gen, values, joinfmt=None):
17 def __init__(self, gen, values, joinfmt=None):
18 self.gen = gen
18 self.gen = gen
19 self.values = values
19 self.values = values
20 if joinfmt:
20 if joinfmt:
21 self.joinfmt = joinfmt
21 self.joinfmt = joinfmt
22 else:
22 else:
23 self.joinfmt = lambda x: x.values()[0]
23 self.joinfmt = lambda x: x.values()[0]
24 def __iter__(self):
24 def __iter__(self):
25 return self.gen
25 return self.gen
26 def __call__(self):
26 def __call__(self):
27 for x in self.values:
27 for x in self.values:
28 yield x
28 yield x
29 def __len__(self):
29 def __len__(self):
30 return len(self.values)
30 return len(self.values)
31
31
32 def showlist(name, values, plural=None, element=None, **args):
32 def showlist(name, values, plural=None, element=None, **args):
33 if not element:
33 if not element:
34 element = name
34 element = name
35 f = _showlist(name, values, plural, **args)
35 f = _showlist(name, values, plural, **args)
36 return _hybrid(f, [{element: x} for x in values])
36 return _hybrid(f, [{element: x} for x in values])
37
37
38 def _showlist(name, values, plural=None, **args):
38 def _showlist(name, values, plural=None, **args):
39 '''expand set of values.
39 '''expand set of values.
40 name is name of key in template map.
40 name is name of key in template map.
41 values is list of strings or dicts.
41 values is list of strings or dicts.
42 plural is plural of name, if not simply name + 's'.
42 plural is plural of name, if not simply name + 's'.
43
43
44 expansion works like this, given name 'foo'.
44 expansion works like this, given name 'foo'.
45
45
46 if values is empty, expand 'no_foos'.
46 if values is empty, expand 'no_foos'.
47
47
48 if 'foo' not in template map, return values as a string,
48 if 'foo' not in template map, return values as a string,
49 joined by space.
49 joined by space.
50
50
51 expand 'start_foos'.
51 expand 'start_foos'.
52
52
53 for each value, expand 'foo'. if 'last_foo' in template
53 for each value, expand 'foo'. if 'last_foo' in template
54 map, expand it instead of 'foo' for last key.
54 map, expand it instead of 'foo' for last key.
55
55
56 expand 'end_foos'.
56 expand 'end_foos'.
57 '''
57 '''
58 templ = args['templ']
58 templ = args['templ']
59 if plural:
59 if plural:
60 names = plural
60 names = plural
61 else: names = name + 's'
61 else: names = name + 's'
62 if not values:
62 if not values:
63 noname = 'no_' + names
63 noname = 'no_' + names
64 if noname in templ:
64 if noname in templ:
65 yield templ(noname, **args)
65 yield templ(noname, **args)
66 return
66 return
67 if name not in templ:
67 if name not in templ:
68 if isinstance(values[0], str):
68 if isinstance(values[0], str):
69 yield ' '.join(values)
69 yield ' '.join(values)
70 else:
70 else:
71 for v in values:
71 for v in values:
72 yield dict(v, **args)
72 yield dict(v, **args)
73 return
73 return
74 startname = 'start_' + names
74 startname = 'start_' + names
75 if startname in templ:
75 if startname in templ:
76 yield templ(startname, **args)
76 yield templ(startname, **args)
77 vargs = args.copy()
77 vargs = args.copy()
78 def one(v, tag=name):
78 def one(v, tag=name):
79 try:
79 try:
80 vargs.update(v)
80 vargs.update(v)
81 except (AttributeError, ValueError):
81 except (AttributeError, ValueError):
82 try:
82 try:
83 for a, b in v:
83 for a, b in v:
84 vargs[a] = b
84 vargs[a] = b
85 except ValueError:
85 except ValueError:
86 vargs[name] = v
86 vargs[name] = v
87 return templ(tag, **vargs)
87 return templ(tag, **vargs)
88 lastname = 'last_' + name
88 lastname = 'last_' + name
89 if lastname in templ:
89 if lastname in templ:
90 last = values.pop()
90 last = values.pop()
91 else:
91 else:
92 last = None
92 last = None
93 for v in values:
93 for v in values:
94 yield one(v)
94 yield one(v)
95 if last is not None:
95 if last is not None:
96 yield one(last, tag=lastname)
96 yield one(last, tag=lastname)
97 endname = 'end_' + names
97 endname = 'end_' + names
98 if endname in templ:
98 if endname in templ:
99 yield templ(endname, **args)
99 yield templ(endname, **args)
100
100
101 def getfiles(repo, ctx, revcache):
101 def getfiles(repo, ctx, revcache):
102 if 'files' not in revcache:
102 if 'files' not in revcache:
103 revcache['files'] = repo.status(ctx.p1().node(), ctx.node())[:3]
103 revcache['files'] = repo.status(ctx.p1().node(), ctx.node())[:3]
104 return revcache['files']
104 return revcache['files']
105
105
106 def getlatesttags(repo, ctx, cache):
106 def getlatesttags(repo, ctx, cache):
107 '''return date, distance and name for the latest tag of rev'''
107 '''return date, distance and name for the latest tag of rev'''
108
108
109 if 'latesttags' not in cache:
109 if 'latesttags' not in cache:
110 # Cache mapping from rev to a tuple with tag date, tag
110 # Cache mapping from rev to a tuple with tag date, tag
111 # distance and tag name
111 # distance and tag name
112 cache['latesttags'] = {-1: (0, 0, 'null')}
112 cache['latesttags'] = {-1: (0, 0, 'null')}
113 latesttags = cache['latesttags']
113 latesttags = cache['latesttags']
114
114
115 rev = ctx.rev()
115 rev = ctx.rev()
116 todo = [rev]
116 todo = [rev]
117 while todo:
117 while todo:
118 rev = todo.pop()
118 rev = todo.pop()
119 if rev in latesttags:
119 if rev in latesttags:
120 continue
120 continue
121 ctx = repo[rev]
121 ctx = repo[rev]
122 tags = [t for t in ctx.tags()
122 tags = [t for t in ctx.tags()
123 if (repo.tagtype(t) and repo.tagtype(t) != 'local')]
123 if (repo.tagtype(t) and repo.tagtype(t) != 'local')]
124 if tags:
124 if tags:
125 latesttags[rev] = ctx.date()[0], 0, ':'.join(sorted(tags))
125 latesttags[rev] = ctx.date()[0], 0, ':'.join(sorted(tags))
126 continue
126 continue
127 try:
127 try:
128 # The tuples are laid out so the right one can be found by
128 # The tuples are laid out so the right one can be found by
129 # comparison.
129 # comparison.
130 pdate, pdist, ptag = max(
130 pdate, pdist, ptag = max(
131 latesttags[p.rev()] for p in ctx.parents())
131 latesttags[p.rev()] for p in ctx.parents())
132 except KeyError:
132 except KeyError:
133 # Cache miss - recurse
133 # Cache miss - recurse
134 todo.append(rev)
134 todo.append(rev)
135 todo.extend(p.rev() for p in ctx.parents())
135 todo.extend(p.rev() for p in ctx.parents())
136 continue
136 continue
137 latesttags[rev] = pdate, pdist + 1, ptag
137 latesttags[rev] = pdate, pdist + 1, ptag
138 return latesttags[rev]
138 return latesttags[rev]
139
139
140 def getrenamedfn(repo, endrev=None):
140 def getrenamedfn(repo, endrev=None):
141 rcache = {}
141 rcache = {}
142 if endrev is None:
142 if endrev is None:
143 endrev = len(repo)
143 endrev = len(repo)
144
144
145 def getrenamed(fn, rev):
145 def getrenamed(fn, rev):
146 '''looks up all renames for a file (up to endrev) the first
146 '''looks up all renames for a file (up to endrev) the first
147 time the file is given. It indexes on the changerev and only
147 time the file is given. It indexes on the changerev and only
148 parses the manifest if linkrev != changerev.
148 parses the manifest if linkrev != changerev.
149 Returns rename info for fn at changerev rev.'''
149 Returns rename info for fn at changerev rev.'''
150 if fn not in rcache:
150 if fn not in rcache:
151 rcache[fn] = {}
151 rcache[fn] = {}
152 fl = repo.file(fn)
152 fl = repo.file(fn)
153 for i in fl:
153 for i in fl:
154 lr = fl.linkrev(i)
154 lr = fl.linkrev(i)
155 renamed = fl.renamed(fl.node(i))
155 renamed = fl.renamed(fl.node(i))
156 rcache[fn][lr] = renamed
156 rcache[fn][lr] = renamed
157 if lr >= endrev:
157 if lr >= endrev:
158 break
158 break
159 if rev in rcache[fn]:
159 if rev in rcache[fn]:
160 return rcache[fn][rev]
160 return rcache[fn][rev]
161
161
162 # If linkrev != rev (i.e. rev not found in rcache) fallback to
162 # If linkrev != rev (i.e. rev not found in rcache) fallback to
163 # filectx logic.
163 # filectx logic.
164 try:
164 try:
165 return repo[rev][fn].renamed()
165 return repo[rev][fn].renamed()
166 except error.LookupError:
166 except error.LookupError:
167 return None
167 return None
168
168
169 return getrenamed
169 return getrenamed
170
170
171
171
172 def showauthor(repo, ctx, templ, **args):
172 def showauthor(repo, ctx, templ, **args):
173 """:author: String. The unmodified author of the changeset."""
173 """:author: String. The unmodified author of the changeset."""
174 return ctx.user()
174 return ctx.user()
175
175
176 def showbisect(repo, ctx, templ, **args):
176 def showbisect(repo, ctx, templ, **args):
177 """:bisect: String. The changeset bisection status."""
177 """:bisect: String. The changeset bisection status."""
178 return hbisect.label(repo, ctx.node())
178 return hbisect.label(repo, ctx.node())
179
179
180 def showbranch(**args):
180 def showbranch(**args):
181 """:branch: String. The name of the branch on which the changeset was
181 """:branch: String. The name of the branch on which the changeset was
182 committed.
182 committed.
183 """
183 """
184 return args['ctx'].branch()
184 return args['ctx'].branch()
185
185
186 def showbranches(**args):
186 def showbranches(**args):
187 """:branches: List of strings. The name of the branch on which the
187 """:branches: List of strings. The name of the branch on which the
188 changeset was committed. Will be empty if the branch name was
188 changeset was committed. Will be empty if the branch name was
189 default.
189 default.
190 """
190 """
191 branch = args['ctx'].branch()
191 branch = args['ctx'].branch()
192 if branch != 'default':
192 if branch != 'default':
193 return showlist('branch', [branch], plural='branches', **args)
193 return showlist('branch', [branch], plural='branches', **args)
194 return showlist('branch', [], plural='branches', **args)
194 return showlist('branch', [], plural='branches', **args)
195
195
196 def showbookmarks(**args):
196 def showbookmarks(**args):
197 """:bookmarks: List of strings. Any bookmarks associated with the
197 """:bookmarks: List of strings. Any bookmarks associated with the
198 changeset.
198 changeset.
199 """
199 """
200 repo = args['ctx']._repo
200 repo = args['ctx']._repo
201 bookmarks = args['ctx'].bookmarks()
201 bookmarks = args['ctx'].bookmarks()
202 hybrid = showlist('bookmark', bookmarks, **args)
202 hybrid = showlist('bookmark', bookmarks, **args)
203 for value in hybrid.values:
203 for value in hybrid.values:
204 value['current'] = repo._bookmarkcurrent
204 value['current'] = repo._bookmarkcurrent
205 return hybrid
205 return hybrid
206
206
207 def showchildren(**args):
207 def showchildren(**args):
208 """:children: List of strings. The children of the changeset."""
208 """:children: List of strings. The children of the changeset."""
209 ctx = args['ctx']
209 ctx = args['ctx']
210 childrevs = ['%d:%s' % (cctx, cctx) for cctx in ctx.children()]
210 childrevs = ['%d:%s' % (cctx, cctx) for cctx in ctx.children()]
211 return showlist('children', childrevs, element='child', **args)
211 return showlist('children', childrevs, element='child', **args)
212
212
213 def showcurrentbookmark(**args):
213 def showcurrentbookmark(**args):
214 """:currentbookmark: String. The active bookmark, if it is
214 """:currentbookmark: String. The active bookmark, if it is
215 associated with the changeset"""
215 associated with the changeset"""
216 import bookmarks as bookmarks # to avoid circular import issues
216 import bookmarks as bookmarks # to avoid circular import issues
217 repo = args['repo']
217 repo = args['repo']
218 if bookmarks.iscurrent(repo):
218 if bookmarks.iscurrent(repo):
219 current = repo._bookmarkcurrent
219 current = repo._bookmarkcurrent
220 if current in args['ctx'].bookmarks():
220 if current in args['ctx'].bookmarks():
221 return current
221 return current
222 return ''
222 return ''
223
223
224 def showdate(repo, ctx, templ, **args):
224 def showdate(repo, ctx, templ, **args):
225 """:date: Date information. The date when the changeset was committed."""
225 """:date: Date information. The date when the changeset was committed."""
226 return ctx.date()
226 return ctx.date()
227
227
228 def showdescription(repo, ctx, templ, **args):
228 def showdescription(repo, ctx, templ, **args):
229 """:desc: String. The text of the changeset description."""
229 """:desc: String. The text of the changeset description."""
230 return ctx.description().strip()
230 return ctx.description().strip()
231
231
232 def showdiffstat(repo, ctx, templ, **args):
232 def showdiffstat(repo, ctx, templ, **args):
233 """:diffstat: String. Statistics of changes with the following format:
233 """:diffstat: String. Statistics of changes with the following format:
234 "modified files: +added/-removed lines"
234 "modified files: +added/-removed lines"
235 """
235 """
236 stats = patch.diffstatdata(util.iterlines(ctx.diff()))
236 stats = patch.diffstatdata(util.iterlines(ctx.diff()))
237 maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats)
237 maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats)
238 return '%s: +%s/-%s' % (len(stats), adds, removes)
238 return '%s: +%s/-%s' % (len(stats), adds, removes)
239
239
240 def showextras(**args):
240 def showextras(**args):
241 """:extras: List of dicts with key, value entries of the 'extras'
241 """:extras: List of dicts with key, value entries of the 'extras'
242 field of this changeset."""
242 field of this changeset."""
243 extras = args['ctx'].extra()
243 extras = args['ctx'].extra()
244 c = [{'key': x[0], 'value': x[1]} for x in sorted(extras.items())]
244 c = [{'key': x[0], 'value': x[1]} for x in sorted(extras.items())]
245 f = _showlist('extra', c, plural='extras', **args)
245 f = _showlist('extra', c, plural='extras', **args)
246 return _hybrid(f, c, lambda x: '%s=%s' % (x['key'], x['value']))
246 return _hybrid(f, c, lambda x: '%s=%s' % (x['key'], x['value']))
247
247
248 def showfileadds(**args):
248 def showfileadds(**args):
249 """:file_adds: List of strings. Files added by this changeset."""
249 """:file_adds: List of strings. Files added by this changeset."""
250 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
250 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
251 return showlist('file_add', getfiles(repo, ctx, revcache)[1],
251 return showlist('file_add', getfiles(repo, ctx, revcache)[1],
252 element='file', **args)
252 element='file', **args)
253
253
254 def showfilecopies(**args):
254 def showfilecopies(**args):
255 """:file_copies: List of strings. Files copied in this changeset with
255 """:file_copies: List of strings. Files copied in this changeset with
256 their sources.
256 their sources.
257 """
257 """
258 cache, ctx = args['cache'], args['ctx']
258 cache, ctx = args['cache'], args['ctx']
259 copies = args['revcache'].get('copies')
259 copies = args['revcache'].get('copies')
260 if copies is None:
260 if copies is None:
261 if 'getrenamed' not in cache:
261 if 'getrenamed' not in cache:
262 cache['getrenamed'] = getrenamedfn(args['repo'])
262 cache['getrenamed'] = getrenamedfn(args['repo'])
263 copies = []
263 copies = []
264 getrenamed = cache['getrenamed']
264 getrenamed = cache['getrenamed']
265 for fn in ctx.files():
265 for fn in ctx.files():
266 rename = getrenamed(fn, ctx.rev())
266 rename = getrenamed(fn, ctx.rev())
267 if rename:
267 if rename:
268 copies.append((fn, rename[0]))
268 copies.append((fn, rename[0]))
269
269
270 c = [{'name': x[0], 'source': x[1]} for x in copies]
270 c = [{'name': x[0], 'source': x[1]} for x in copies]
271 f = _showlist('file_copy', c, plural='file_copies', **args)
271 f = _showlist('file_copy', c, plural='file_copies', **args)
272 return _hybrid(f, c, lambda x: '%s (%s)' % (x['name'], x['source']))
272 return _hybrid(f, c, lambda x: '%s (%s)' % (x['name'], x['source']))
273
273
274 # showfilecopiesswitch() displays file copies only if copy records are
274 # showfilecopiesswitch() displays file copies only if copy records are
275 # provided before calling the templater, usually with a --copies
275 # provided before calling the templater, usually with a --copies
276 # command line switch.
276 # command line switch.
277 def showfilecopiesswitch(**args):
277 def showfilecopiesswitch(**args):
278 """:file_copies_switch: List of strings. Like "file_copies" but displayed
278 """:file_copies_switch: List of strings. Like "file_copies" but displayed
279 only if the --copied switch is set.
279 only if the --copied switch is set.
280 """
280 """
281 copies = args['revcache'].get('copies') or []
281 copies = args['revcache'].get('copies') or []
282 c = [{'name': x[0], 'source': x[1]} for x in copies]
282 c = [{'name': x[0], 'source': x[1]} for x in copies]
283 f = _showlist('file_copy', c, plural='file_copies', **args)
283 f = _showlist('file_copy', c, plural='file_copies', **args)
284 return _hybrid(f, c, lambda x: '%s (%s)' % (x['name'], x['source']))
284 return _hybrid(f, c, lambda x: '%s (%s)' % (x['name'], x['source']))
285
285
286 def showfiledels(**args):
286 def showfiledels(**args):
287 """:file_dels: List of strings. Files removed by this changeset."""
287 """:file_dels: List of strings. Files removed by this changeset."""
288 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
288 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
289 return showlist('file_del', getfiles(repo, ctx, revcache)[2],
289 return showlist('file_del', getfiles(repo, ctx, revcache)[2],
290 element='file', **args)
290 element='file', **args)
291
291
292 def showfilemods(**args):
292 def showfilemods(**args):
293 """:file_mods: List of strings. Files modified by this changeset."""
293 """:file_mods: List of strings. Files modified by this changeset."""
294 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
294 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
295 return showlist('file_mod', getfiles(repo, ctx, revcache)[0],
295 return showlist('file_mod', getfiles(repo, ctx, revcache)[0],
296 element='file', **args)
296 element='file', **args)
297
297
298 def showfiles(**args):
298 def showfiles(**args):
299 """:files: List of strings. All files modified, added, or removed by this
299 """:files: List of strings. All files modified, added, or removed by this
300 changeset.
300 changeset.
301 """
301 """
302 return showlist('file', args['ctx'].files(), **args)
302 return showlist('file', args['ctx'].files(), **args)
303
303
304 def showlatesttag(repo, ctx, templ, cache, **args):
304 def showlatesttag(repo, ctx, templ, cache, **args):
305 """:latesttag: String. Most recent global tag in the ancestors of this
305 """:latesttag: String. Most recent global tag in the ancestors of this
306 changeset.
306 changeset.
307 """
307 """
308 return getlatesttags(repo, ctx, cache)[2]
308 return getlatesttags(repo, ctx, cache)[2]
309
309
310 def showlatesttagdistance(repo, ctx, templ, cache, **args):
310 def showlatesttagdistance(repo, ctx, templ, cache, **args):
311 """:latesttagdistance: Integer. Longest path to the latest tag."""
311 """:latesttagdistance: Integer. Longest path to the latest tag."""
312 return getlatesttags(repo, ctx, cache)[1]
312 return getlatesttags(repo, ctx, cache)[1]
313
313
314 def showmanifest(**args):
314 def showmanifest(**args):
315 repo, ctx, templ = args['repo'], args['ctx'], args['templ']
315 repo, ctx, templ = args['repo'], args['ctx'], args['templ']
316 args = args.copy()
316 args = args.copy()
317 args.update({'rev': repo.manifest.rev(ctx.changeset()[0]),
317 args.update({'rev': repo.manifest.rev(ctx.changeset()[0]),
318 'node': hex(ctx.changeset()[0])})
318 'node': hex(ctx.changeset()[0])})
319 return templ('manifest', **args)
319 return templ('manifest', **args)
320
320
321 def shownode(repo, ctx, templ, **args):
321 def shownode(repo, ctx, templ, **args):
322 """:node: String. The changeset identification hash, as a 40 hexadecimal
322 """:node: String. The changeset identification hash, as a 40 hexadecimal
323 digit string.
323 digit string.
324 """
324 """
325 return ctx.hex()
325 return ctx.hex()
326
326
327 def showp1rev(repo, ctx, templ, **args):
327 def showp1rev(repo, ctx, templ, **args):
328 """:p1rev: Integer. The repository-local revision number of the changeset's
328 """:p1rev: Integer. The repository-local revision number of the changeset's
329 first parent, or -1 if the changeset has no parents."""
329 first parent, or -1 if the changeset has no parents."""
330 return ctx.p1().rev()
330 return ctx.p1().rev()
331
331
332 def showp2rev(repo, ctx, templ, **args):
332 def showp2rev(repo, ctx, templ, **args):
333 """:p2rev: Integer. The repository-local revision number of the changeset's
333 """:p2rev: Integer. The repository-local revision number of the changeset's
334 second parent, or -1 if the changeset has no second parent."""
334 second parent, or -1 if the changeset has no second parent."""
335 return ctx.p2().rev()
335 return ctx.p2().rev()
336
336
337 def showp1node(repo, ctx, templ, **args):
337 def showp1node(repo, ctx, templ, **args):
338 """:p1node: String. The identification hash of the changeset's first parent,
338 """:p1node: String. The identification hash of the changeset's first parent,
339 as a 40 digit hexadecimal string. If the changeset has no parents, all
339 as a 40 digit hexadecimal string. If the changeset has no parents, all
340 digits are 0."""
340 digits are 0."""
341 return ctx.p1().hex()
341 return ctx.p1().hex()
342
342
343 def showp2node(repo, ctx, templ, **args):
343 def showp2node(repo, ctx, templ, **args):
344 """:p2node: String. The identification hash of the changeset's second
344 """:p2node: String. The identification hash of the changeset's second
345 parent, as a 40 digit hexadecimal string. If the changeset has no second
345 parent, as a 40 digit hexadecimal string. If the changeset has no second
346 parent, all digits are 0."""
346 parent, all digits are 0."""
347 return ctx.p2().hex()
347 return ctx.p2().hex()
348
348
349 def showphase(repo, ctx, templ, **args):
349 def showphase(repo, ctx, templ, **args):
350 """:phase: String. The changeset phase name."""
350 """:phase: String. The changeset phase name."""
351 return ctx.phasestr()
351 return ctx.phasestr()
352
352
353 def showphaseidx(repo, ctx, templ, **args):
353 def showphaseidx(repo, ctx, templ, **args):
354 """:phaseidx: Integer. The changeset phase index."""
354 """:phaseidx: Integer. The changeset phase index."""
355 return ctx.phase()
355 return ctx.phase()
356
356
357 def showrev(repo, ctx, templ, **args):
357 def showrev(repo, ctx, templ, **args):
358 """:rev: Integer. The repository-local changeset revision number."""
358 """:rev: Integer. The repository-local changeset revision number."""
359 return ctx.rev()
359 return ctx.rev()
360
360
361 def showsubrepos(**args):
361 def showsubrepos(**args):
362 """:subrepos: List of strings. Updated subrepositories in the changeset."""
362 """:subrepos: List of strings. Updated subrepositories in the changeset."""
363 ctx = args['ctx']
363 ctx = args['ctx']
364 substate = ctx.substate
364 substate = ctx.substate
365 if not substate:
365 if not substate:
366 return showlist('subrepo', [], **args)
366 return showlist('subrepo', [], **args)
367 psubstate = ctx.parents()[0].substate or {}
367 psubstate = ctx.parents()[0].substate or {}
368 subrepos = []
368 subrepos = []
369 for sub in substate:
369 for sub in substate:
370 if sub not in psubstate or substate[sub] != psubstate[sub]:
370 if sub not in psubstate or substate[sub] != psubstate[sub]:
371 subrepos.append(sub) # modified or newly added in ctx
371 subrepos.append(sub) # modified or newly added in ctx
372 for sub in psubstate:
372 for sub in psubstate:
373 if sub not in substate:
373 if sub not in substate:
374 subrepos.append(sub) # removed in ctx
374 subrepos.append(sub) # removed in ctx
375 return showlist('subrepo', sorted(subrepos), **args)
375 return showlist('subrepo', sorted(subrepos), **args)
376
376
377 def showtags(**args):
377 def showtags(**args):
378 """:tags: List of strings. Any tags associated with the changeset."""
378 """:tags: List of strings. Any tags associated with the changeset."""
379 return showlist('tag', args['ctx'].tags(), **args)
379 return showlist('tag', args['ctx'].tags(), **args)
380
380
381 def shownames(namespace, **args):
382 """helper method to generate a template keyword for a namespace"""
383 ctx = args['ctx']
384 repo = ctx._repo
385 names = repo.names.names(repo, namespace, ctx.node())
386 return showlist(repo.names.templatename(namespace), names,
387 plural=namespace, **args)
388
381 # keywords are callables like:
389 # keywords are callables like:
382 # fn(repo, ctx, templ, cache, revcache, **args)
390 # fn(repo, ctx, templ, cache, revcache, **args)
383 # with:
391 # with:
384 # repo - current repository instance
392 # repo - current repository instance
385 # ctx - the changectx being displayed
393 # ctx - the changectx being displayed
386 # templ - the templater instance
394 # templ - the templater instance
387 # cache - a cache dictionary for the whole templater run
395 # cache - a cache dictionary for the whole templater run
388 # revcache - a cache dictionary for the current revision
396 # revcache - a cache dictionary for the current revision
389 keywords = {
397 keywords = {
390 'author': showauthor,
398 'author': showauthor,
391 'bisect': showbisect,
399 'bisect': showbisect,
392 'branch': showbranch,
400 'branch': showbranch,
393 'branches': showbranches,
401 'branches': showbranches,
394 'bookmarks': showbookmarks,
402 'bookmarks': showbookmarks,
395 'children': showchildren,
403 'children': showchildren,
396 'currentbookmark': showcurrentbookmark,
404 'currentbookmark': showcurrentbookmark,
397 'date': showdate,
405 'date': showdate,
398 'desc': showdescription,
406 'desc': showdescription,
399 'diffstat': showdiffstat,
407 'diffstat': showdiffstat,
400 'extras': showextras,
408 'extras': showextras,
401 'file_adds': showfileadds,
409 'file_adds': showfileadds,
402 'file_copies': showfilecopies,
410 'file_copies': showfilecopies,
403 'file_copies_switch': showfilecopiesswitch,
411 'file_copies_switch': showfilecopiesswitch,
404 'file_dels': showfiledels,
412 'file_dels': showfiledels,
405 'file_mods': showfilemods,
413 'file_mods': showfilemods,
406 'files': showfiles,
414 'files': showfiles,
407 'latesttag': showlatesttag,
415 'latesttag': showlatesttag,
408 'latesttagdistance': showlatesttagdistance,
416 'latesttagdistance': showlatesttagdistance,
409 'manifest': showmanifest,
417 'manifest': showmanifest,
410 'node': shownode,
418 'node': shownode,
411 'p1rev': showp1rev,
419 'p1rev': showp1rev,
412 'p1node': showp1node,
420 'p1node': showp1node,
413 'p2rev': showp2rev,
421 'p2rev': showp2rev,
414 'p2node': showp2node,
422 'p2node': showp2node,
415 'phase': showphase,
423 'phase': showphase,
416 'phaseidx': showphaseidx,
424 'phaseidx': showphaseidx,
417 'rev': showrev,
425 'rev': showrev,
418 'subrepos': showsubrepos,
426 'subrepos': showsubrepos,
419 'tags': showtags,
427 'tags': showtags,
420 }
428 }
421
429
422 def _showparents(**args):
430 def _showparents(**args):
423 """:parents: List of strings. The parents of the changeset in "rev:node"
431 """:parents: List of strings. The parents of the changeset in "rev:node"
424 format. If the changeset has only one "natural" parent (the predecessor
432 format. If the changeset has only one "natural" parent (the predecessor
425 revision) nothing is shown."""
433 revision) nothing is shown."""
426 pass
434 pass
427
435
428 dockeywords = {
436 dockeywords = {
429 'parents': _showparents,
437 'parents': _showparents,
430 }
438 }
431 dockeywords.update(keywords)
439 dockeywords.update(keywords)
432 del dockeywords['branches']
440 del dockeywords['branches']
433
441
434 # tell hggettext to extract docstrings from these functions:
442 # tell hggettext to extract docstrings from these functions:
435 i18nfunctions = dockeywords.values()
443 i18nfunctions = dockeywords.values()
General Comments 0
You need to be logged in to leave comments. Login now