comparison mercurial/templatekw.py @ 13585:2e80d495592a

templates: generate keyword help dynamically
author Patrick Mezard <pmezard@gmail.com>
date Sat, 12 Mar 2011 12:46:31 +0100
parents f78bc5ddbe4f
children ad2ee188f4a5
comparison
equal deleted inserted replaced
13584:02f507ce61f2 13585:2e80d495592a
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 encoding, patch, util, error 9 import encoding, patch, util, error
10 from i18n import gettext
10 11
11 def showlist(name, values, plural=None, **args): 12 def showlist(name, values, plural=None, **args):
12 '''expand set of values. 13 '''expand set of values.
13 name is name of key in template map. 14 name is name of key in template map.
14 values is list of strings or dicts. 15 values is list of strings or dicts.
141 142
142 return getrenamed 143 return getrenamed
143 144
144 145
145 def showauthor(repo, ctx, templ, **args): 146 def showauthor(repo, ctx, templ, **args):
147 """:author: String. The unmodified author of the changeset."""
146 return ctx.user() 148 return ctx.user()
147 149
148 def showbranch(**args): 150 def showbranch(**args):
151 """:branch: String. The name of the branch on which the changeset was
152 committed.
153 """
149 return args['ctx'].branch() 154 return args['ctx'].branch()
150 155
151 def showbranches(**args): 156 def showbranches(**args):
157 """:branches: List of strings. The name of the branch on which the
158 changeset was committed. Will be empty if the branch name was
159 default.
160 """
152 branch = args['ctx'].branch() 161 branch = args['ctx'].branch()
153 if branch != 'default': 162 if branch != 'default':
154 return showlist('branch', [branch], plural='branches', **args) 163 return showlist('branch', [branch], plural='branches', **args)
155 164
156 def showbookmarks(**args): 165 def showbookmarks(**args):
157 bookmarks = args['ctx'].bookmarks() 166 bookmarks = args['ctx'].bookmarks()
158 return showlist('bookmark', bookmarks, **args) 167 return showlist('bookmark', bookmarks, **args)
159 168
160 def showchildren(**args): 169 def showchildren(**args):
170 """:children: List of strings. The children of the changeset."""
161 ctx = args['ctx'] 171 ctx = args['ctx']
162 childrevs = ['%d:%s' % (cctx, cctx) for cctx in ctx.children()] 172 childrevs = ['%d:%s' % (cctx, cctx) for cctx in ctx.children()]
163 return showlist('children', childrevs, **args) 173 return showlist('children', childrevs, **args)
164 174
165 def showdate(repo, ctx, templ, **args): 175 def showdate(repo, ctx, templ, **args):
176 """:date: Date information. The date when the changeset was committed."""
166 return ctx.date() 177 return ctx.date()
167 178
168 def showdescription(repo, ctx, templ, **args): 179 def showdescription(repo, ctx, templ, **args):
180 """:desc: String. The text of the changeset description."""
169 return ctx.description().strip() 181 return ctx.description().strip()
170 182
171 def showdiffstat(repo, ctx, templ, **args): 183 def showdiffstat(repo, ctx, templ, **args):
184 """:diffstat: String. Statistics of changes with the following format:
185 "modified files: +added/-removed lines"
186 """
172 files, adds, removes = 0, 0, 0 187 files, adds, removes = 0, 0, 0
173 for i in patch.diffstatdata(util.iterlines(ctx.diff())): 188 for i in patch.diffstatdata(util.iterlines(ctx.diff())):
174 files += 1 189 files += 1
175 adds += i[1] 190 adds += i[1]
176 removes += i[2] 191 removes += i[2]
182 args = args.copy() 197 args = args.copy()
183 args.update(dict(key=key, value=value)) 198 args.update(dict(key=key, value=value))
184 yield templ('extra', **args) 199 yield templ('extra', **args)
185 200
186 def showfileadds(**args): 201 def showfileadds(**args):
202 """:file_adds: List of strings. Files added by this changeset."""
187 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache'] 203 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
188 return showlist('file_add', getfiles(repo, ctx, revcache)[1], **args) 204 return showlist('file_add', getfiles(repo, ctx, revcache)[1], **args)
189 205
190 def showfilecopies(**args): 206 def showfilecopies(**args):
207 """:file_copies: List of strings. Files copied in this changeset with
208 their sources.
209 """
191 cache, ctx = args['cache'], args['ctx'] 210 cache, ctx = args['cache'], args['ctx']
192 copies = args['revcache'].get('copies') 211 copies = args['revcache'].get('copies')
193 if copies is None: 212 if copies is None:
194 if 'getrenamed' not in cache: 213 if 'getrenamed' not in cache:
195 cache['getrenamed'] = getrenamedfn(args['repo']) 214 cache['getrenamed'] = getrenamedfn(args['repo'])
205 224
206 # showfilecopiesswitch() displays file copies only if copy records are 225 # showfilecopiesswitch() displays file copies only if copy records are
207 # provided before calling the templater, usually with a --copies 226 # provided before calling the templater, usually with a --copies
208 # command line switch. 227 # command line switch.
209 def showfilecopiesswitch(**args): 228 def showfilecopiesswitch(**args):
229 """:file_copies_switch: List of strings. Like "file_copies" but displayed
230 only if the --copied switch is set.
231 """
210 copies = args['revcache'].get('copies') or [] 232 copies = args['revcache'].get('copies') or []
211 c = [{'name': x[0], 'source': x[1]} for x in copies] 233 c = [{'name': x[0], 'source': x[1]} for x in copies]
212 return showlist('file_copy', c, plural='file_copies', **args) 234 return showlist('file_copy', c, plural='file_copies', **args)
213 235
214 def showfiledels(**args): 236 def showfiledels(**args):
237 """:file_dels: List of strings. Files removed by this changeset."""
215 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache'] 238 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
216 return showlist('file_del', getfiles(repo, ctx, revcache)[2], **args) 239 return showlist('file_del', getfiles(repo, ctx, revcache)[2], **args)
217 240
218 def showfilemods(**args): 241 def showfilemods(**args):
242 """:file_mods: List of strings. Files modified by this changeset."""
219 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache'] 243 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
220 return showlist('file_mod', getfiles(repo, ctx, revcache)[0], **args) 244 return showlist('file_mod', getfiles(repo, ctx, revcache)[0], **args)
221 245
222 def showfiles(**args): 246 def showfiles(**args):
247 """:files: List of strings. All files modified, added, or removed by this
248 changeset.
249 """
223 return showlist('file', args['ctx'].files(), **args) 250 return showlist('file', args['ctx'].files(), **args)
224 251
225 def showlatesttag(repo, ctx, templ, cache, **args): 252 def showlatesttag(repo, ctx, templ, cache, **args):
253 """:latesttag: String. Most recent global tag in the ancestors of this
254 changeset.
255 """
226 return getlatesttags(repo, ctx, cache)[2] 256 return getlatesttags(repo, ctx, cache)[2]
227 257
228 def showlatesttagdistance(repo, ctx, templ, cache, **args): 258 def showlatesttagdistance(repo, ctx, templ, cache, **args):
259 """:latesttagdistance: Integer. Longest path to the latest tag."""
229 return getlatesttags(repo, ctx, cache)[1] 260 return getlatesttags(repo, ctx, cache)[1]
230 261
231 def showmanifest(**args): 262 def showmanifest(**args):
232 repo, ctx, templ = args['repo'], args['ctx'], args['templ'] 263 repo, ctx, templ = args['repo'], args['ctx'], args['templ']
233 args = args.copy() 264 args = args.copy()
234 args.update(dict(rev=repo.manifest.rev(ctx.changeset()[0]), 265 args.update(dict(rev=repo.manifest.rev(ctx.changeset()[0]),
235 node=hex(ctx.changeset()[0]))) 266 node=hex(ctx.changeset()[0])))
236 return templ('manifest', **args) 267 return templ('manifest', **args)
237 268
238 def shownode(repo, ctx, templ, **args): 269 def shownode(repo, ctx, templ, **args):
270 """:node: String. The changeset identification hash, as a 40 hexadecimal
271 digit string.
272 """
239 return ctx.hex() 273 return ctx.hex()
240 274
241 def showrev(repo, ctx, templ, **args): 275 def showrev(repo, ctx, templ, **args):
276 """:rev: Integer. The repository-local changeset revision number."""
242 return ctx.rev() 277 return ctx.rev()
243 278
244 def showtags(**args): 279 def showtags(**args):
280 """:tags: List of strings. Any tags associated with the changeset."""
245 return showlist('tag', args['ctx'].tags(), **args) 281 return showlist('tag', args['ctx'].tags(), **args)
246 282
247 # keywords are callables like: 283 # keywords are callables like:
248 # fn(repo, ctx, templ, cache, revcache, **args) 284 # fn(repo, ctx, templ, cache, revcache, **args)
249 # with: 285 # with:
274 'node': shownode, 310 'node': shownode,
275 'rev': showrev, 311 'rev': showrev,
276 'tags': showtags, 312 'tags': showtags,
277 } 313 }
278 314
315 def makedoc(topic, doc):
316 """Generate and include keyword help in templating topic."""
317 kw = []
318 for name in sorted(keywords):
319 text = (keywords[name].__doc__ or '').rstrip()
320 if not text:
321 continue
322 text = gettext(text)
323 lines = text.splitlines()
324 lines[1:] = [(' ' + l.strip()) for l in lines[1:]]
325 kw.append('\n'.join(lines))
326 kw = '\n\n'.join(kw)
327 doc = doc.replace('.. keywordsmarker', kw)
328 return doc
329
330 # tell hggettext to extract docstrings from these functions:
331 i18nfunctions = keywords.values()