204 addtopicsymbols('filesets', '.. predicatesmarker', fileset.symbols) |
205 addtopicsymbols('filesets', '.. predicatesmarker', fileset.symbols) |
205 addtopicsymbols('merge-tools', '.. internaltoolsmarker', filemerge.internals) |
206 addtopicsymbols('merge-tools', '.. internaltoolsmarker', filemerge.internals) |
206 addtopicsymbols('revsets', '.. predicatesmarker', revset.symbols) |
207 addtopicsymbols('revsets', '.. predicatesmarker', revset.symbols) |
207 addtopicsymbols('templates', '.. keywordsmarker', templatekw.dockeywords) |
208 addtopicsymbols('templates', '.. keywordsmarker', templatekw.dockeywords) |
208 addtopicsymbols('templates', '.. filtersmarker', templatefilters.filters) |
209 addtopicsymbols('templates', '.. filtersmarker', templatefilters.filters) |
|
210 |
|
211 def help_(ui, name, unknowncmd=False, full=True, **opts): |
|
212 ''' |
|
213 Generate the help for 'name' as unformatted restructured text. If |
|
214 'name' is None, describe the commands available. |
|
215 ''' |
|
216 |
|
217 import commands # avoid cycle |
|
218 |
|
219 def helpcmd(name): |
|
220 try: |
|
221 aliases, entry = cmdutil.findcmd(name, commands.table, |
|
222 strict=unknowncmd) |
|
223 except error.AmbiguousCommand, inst: |
|
224 # py3k fix: except vars can't be used outside the scope of the |
|
225 # except block, nor can be used inside a lambda. python issue4617 |
|
226 prefix = inst.args[0] |
|
227 select = lambda c: c.lstrip('^').startswith(prefix) |
|
228 rst = helplist(select) |
|
229 return rst |
|
230 |
|
231 rst = [] |
|
232 |
|
233 # check if it's an invalid alias and display its error if it is |
|
234 if getattr(entry[0], 'badalias', False): |
|
235 if not unknowncmd: |
|
236 ui.pushbuffer() |
|
237 entry[0](ui) |
|
238 rst.append(ui.popbuffer()) |
|
239 return rst |
|
240 |
|
241 # synopsis |
|
242 if len(entry) > 2: |
|
243 if entry[2].startswith('hg'): |
|
244 rst.append("%s\n" % entry[2]) |
|
245 else: |
|
246 rst.append('hg %s %s\n' % (aliases[0], entry[2])) |
|
247 else: |
|
248 rst.append('hg %s\n' % aliases[0]) |
|
249 # aliases |
|
250 if full and not ui.quiet and len(aliases) > 1: |
|
251 rst.append(_("\naliases: %s\n") % ', '.join(aliases[1:])) |
|
252 rst.append('\n') |
|
253 |
|
254 # description |
|
255 doc = gettext(entry[0].__doc__) |
|
256 if not doc: |
|
257 doc = _("(no help text available)") |
|
258 if util.safehasattr(entry[0], 'definition'): # aliased command |
|
259 if entry[0].definition.startswith('!'): # shell alias |
|
260 doc = _('shell alias for::\n\n %s') % entry[0].definition[1:] |
|
261 else: |
|
262 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc) |
|
263 doc = doc.splitlines(True) |
|
264 if ui.quiet or not full: |
|
265 rst.append(doc[0]) |
|
266 else: |
|
267 rst.extend(doc) |
|
268 rst.append('\n') |
|
269 |
|
270 # check if this command shadows a non-trivial (multi-line) |
|
271 # extension help text |
|
272 try: |
|
273 mod = extensions.find(name) |
|
274 doc = gettext(mod.__doc__) or '' |
|
275 if '\n' in doc.strip(): |
|
276 msg = _('use "hg help -e %s" to show help for ' |
|
277 'the %s extension') % (name, name) |
|
278 rst.append('\n%s\n' % msg) |
|
279 except KeyError: |
|
280 pass |
|
281 |
|
282 # options |
|
283 if not ui.quiet and entry[1]: |
|
284 rst.append('\n%s\n\n' % _("options:")) |
|
285 rst.append(optrst(entry[1], ui.verbose)) |
|
286 |
|
287 if ui.verbose: |
|
288 rst.append('\n%s\n\n' % _("global options:")) |
|
289 rst.append(optrst(commands.globalopts, ui.verbose)) |
|
290 |
|
291 if not ui.verbose: |
|
292 if not full: |
|
293 rst.append(_('\nuse "hg help %s" to show the full help text\n') |
|
294 % name) |
|
295 elif not ui.quiet: |
|
296 omitted = _('use "hg -v help %s" to show more complete' |
|
297 ' help and the global options') % name |
|
298 notomitted = _('use "hg -v help %s" to show' |
|
299 ' the global options') % name |
|
300 indicateomitted(rst, omitted, notomitted) |
|
301 |
|
302 return rst |
|
303 |
|
304 |
|
305 def helplist(select=None): |
|
306 # list of commands |
|
307 if name == "shortlist": |
|
308 header = _('basic commands:\n\n') |
|
309 else: |
|
310 header = _('list of commands:\n\n') |
|
311 |
|
312 h = {} |
|
313 cmds = {} |
|
314 for c, e in commands.table.iteritems(): |
|
315 f = c.split("|", 1)[0] |
|
316 if select and not select(f): |
|
317 continue |
|
318 if (not select and name != 'shortlist' and |
|
319 e[0].__module__ != commands.__name__): |
|
320 continue |
|
321 if name == "shortlist" and not f.startswith("^"): |
|
322 continue |
|
323 f = f.lstrip("^") |
|
324 if not ui.debugflag and f.startswith("debug"): |
|
325 continue |
|
326 doc = e[0].__doc__ |
|
327 if doc and 'DEPRECATED' in doc and not ui.verbose: |
|
328 continue |
|
329 doc = gettext(doc) |
|
330 if not doc: |
|
331 doc = _("(no help text available)") |
|
332 h[f] = doc.splitlines()[0].rstrip() |
|
333 cmds[f] = c.lstrip("^") |
|
334 |
|
335 rst = [] |
|
336 if not h: |
|
337 if not ui.quiet: |
|
338 rst.append(_('no commands defined\n')) |
|
339 return rst |
|
340 |
|
341 if not ui.quiet: |
|
342 rst.append(header) |
|
343 fns = sorted(h) |
|
344 for f in fns: |
|
345 if ui.verbose: |
|
346 commacmds = cmds[f].replace("|",", ") |
|
347 rst.append(" :%s: %s\n" % (commacmds, h[f])) |
|
348 else: |
|
349 rst.append(' :%s: %s\n' % (f, h[f])) |
|
350 |
|
351 if not name: |
|
352 exts = listexts(_('enabled extensions:'), extensions.enabled()) |
|
353 if exts: |
|
354 rst.append('\n') |
|
355 rst.extend(exts) |
|
356 |
|
357 rst.append(_("\nadditional help topics:\n\n")) |
|
358 topics = [] |
|
359 for names, header, doc in helptable: |
|
360 topics.append((names[0], header)) |
|
361 for t, desc in topics: |
|
362 rst.append(" :%s: %s\n" % (t, desc)) |
|
363 |
|
364 optlist = [] |
|
365 if not ui.quiet: |
|
366 if ui.verbose: |
|
367 optlist.append((_("global options:"), commands.globalopts)) |
|
368 if name == 'shortlist': |
|
369 optlist.append((_('use "hg help" for the full list ' |
|
370 'of commands'), ())) |
|
371 else: |
|
372 if name == 'shortlist': |
|
373 msg = _('use "hg help" for the full list of commands ' |
|
374 'or "hg -v" for details') |
|
375 elif name and not full: |
|
376 msg = _('use "hg help %s" to show the full help ' |
|
377 'text') % name |
|
378 else: |
|
379 msg = _('use "hg -v help%s" to show builtin aliases and ' |
|
380 'global options') % (name and " " + name or "") |
|
381 optlist.append((msg, ())) |
|
382 |
|
383 if optlist: |
|
384 for title, options in optlist: |
|
385 rst.append('\n%s\n' % title) |
|
386 if options: |
|
387 rst.append('\n%s\n' % optrst(options, ui.verbose)) |
|
388 return rst |
|
389 |
|
390 def helptopic(name): |
|
391 for names, header, doc in helptable: |
|
392 if name in names: |
|
393 break |
|
394 else: |
|
395 raise error.UnknownCommand(name) |
|
396 |
|
397 rst = ["%s\n\n" % header] |
|
398 # description |
|
399 if not doc: |
|
400 rst.append(" %s\n" % _("(no help text available)")) |
|
401 if util.safehasattr(doc, '__call__'): |
|
402 rst += [" %s\n" % l for l in doc().splitlines()] |
|
403 |
|
404 if not ui.verbose: |
|
405 omitted = (_('use "hg help -v %s" to show more complete help') % |
|
406 name) |
|
407 indicateomitted(rst, omitted) |
|
408 |
|
409 try: |
|
410 cmdutil.findcmd(name, commands.table) |
|
411 rst.append(_('\nuse "hg help -c %s" to see help for ' |
|
412 'the %s command\n') % (name, name)) |
|
413 except error.UnknownCommand: |
|
414 pass |
|
415 return rst |
|
416 |
|
417 def helpext(name): |
|
418 try: |
|
419 mod = extensions.find(name) |
|
420 doc = gettext(mod.__doc__) or _('no help text available') |
|
421 except KeyError: |
|
422 mod = None |
|
423 doc = extensions.disabledext(name) |
|
424 if not doc: |
|
425 raise error.UnknownCommand(name) |
|
426 |
|
427 if '\n' not in doc: |
|
428 head, tail = doc, "" |
|
429 else: |
|
430 head, tail = doc.split('\n', 1) |
|
431 rst = [_('%s extension - %s\n\n') % (name.split('.')[-1], head)] |
|
432 if tail: |
|
433 rst.extend(tail.splitlines(True)) |
|
434 rst.append('\n') |
|
435 |
|
436 if not ui.verbose: |
|
437 omitted = (_('use "hg help -v %s" to show more complete help') % |
|
438 name) |
|
439 indicateomitted(rst, omitted) |
|
440 |
|
441 if mod: |
|
442 try: |
|
443 ct = mod.cmdtable |
|
444 except AttributeError: |
|
445 ct = {} |
|
446 modcmds = set([c.split('|', 1)[0] for c in ct]) |
|
447 rst.extend(helplist(modcmds.__contains__)) |
|
448 else: |
|
449 rst.append(_('use "hg help extensions" for information on enabling ' |
|
450 'extensions\n')) |
|
451 return rst |
|
452 |
|
453 def helpextcmd(name): |
|
454 cmd, ext, mod = extensions.disabledcmd(ui, name, |
|
455 ui.configbool('ui', 'strict')) |
|
456 doc = gettext(mod.__doc__).splitlines()[0] |
|
457 |
|
458 rst = listexts(_("'%s' is provided by the following " |
|
459 "extension:") % cmd, {ext: doc}, indent=4) |
|
460 rst.append('\n') |
|
461 rst.append(_('use "hg help extensions" for information on enabling ' |
|
462 'extensions\n')) |
|
463 return rst |
|
464 |
|
465 |
|
466 rst = [] |
|
467 kw = opts.get('keyword') |
|
468 if kw: |
|
469 matches = topicmatch(kw) |
|
470 for t, title in (('topics', _('Topics')), |
|
471 ('commands', _('Commands')), |
|
472 ('extensions', _('Extensions')), |
|
473 ('extensioncommands', _('Extension Commands'))): |
|
474 if matches[t]: |
|
475 rst.append('%s:\n\n' % title) |
|
476 rst.extend(minirst.maketable(sorted(matches[t]), 1)) |
|
477 rst.append('\n') |
|
478 elif name and name != 'shortlist': |
|
479 i = None |
|
480 if unknowncmd: |
|
481 queries = (helpextcmd,) |
|
482 elif opts.get('extension'): |
|
483 queries = (helpext,) |
|
484 elif opts.get('command'): |
|
485 queries = (helpcmd,) |
|
486 else: |
|
487 queries = (helptopic, helpcmd, helpext, helpextcmd) |
|
488 for f in queries: |
|
489 try: |
|
490 rst = f(name) |
|
491 i = None |
|
492 break |
|
493 except error.UnknownCommand, inst: |
|
494 i = inst |
|
495 if i: |
|
496 raise i |
|
497 else: |
|
498 # program name |
|
499 if not ui.quiet: |
|
500 rst = [_("Mercurial Distributed SCM\n"), '\n'] |
|
501 rst.extend(helplist()) |
|
502 |
|
503 return ''.join(rst) |