comparison mercurial/help.py @ 40291:170926caf44c

help: adding support for command categories Differential Revision: https://phab.mercurial-scm.org/D5065
author rdamazio@google.com
date Sat, 13 Oct 2018 05:03:50 -0700
parents 8cf459d8b111
children 9c6473d2038b
comparison
equal deleted inserted replaced
40290:091f9b8a1051 40291:170926caf44c
23 fancyopts, 23 fancyopts,
24 filemerge, 24 filemerge,
25 fileset, 25 fileset,
26 minirst, 26 minirst,
27 pycompat, 27 pycompat,
28 registrar,
28 revset, 29 revset,
29 templatefilters, 30 templatefilters,
30 templatefuncs, 31 templatefuncs,
31 templatekw, 32 templatekw,
32 util, 33 util,
43 _("(ADVANCED)"), 44 _("(ADVANCED)"),
44 # i18n: "(DEPRECATED)" is a keyword, must be translated consistently 45 # i18n: "(DEPRECATED)" is a keyword, must be translated consistently
45 _("(DEPRECATED)"), 46 _("(DEPRECATED)"),
46 # i18n: "(EXPERIMENTAL)" is a keyword, must be translated consistently 47 # i18n: "(EXPERIMENTAL)" is a keyword, must be translated consistently
47 _("(EXPERIMENTAL)"), 48 _("(EXPERIMENTAL)"),
49 }
50
51 # The order in which command categories will be displayed.
52 # Extensions with custom categories should insert them into this list
53 # after/before the appropriate item, rather than replacing the list or
54 # assuming absolute positions.
55 CATEGORY_ORDER = [
56 registrar.command.CATEGORY_NONE,
57 ]
58
59 # Human-readable category names. These are translated.
60 # Extensions with custom categories should add their names here.
61 CATEGORY_NAMES = {
62 registrar.command.CATEGORY_NONE: 'Uncategorized commands',
48 } 63 }
49 64
50 def listexts(header, exts, indent=1, showdeprecated=False): 65 def listexts(header, exts, indent=1, showdeprecated=False):
51 '''return a text listing of the given extensions''' 66 '''return a text listing of the given extensions'''
52 rst = [] 67 rst = []
417 rst.append(_('\n(some details hidden, use --verbose ' 432 rst.append(_('\n(some details hidden, use --verbose '
418 'to show complete help)')) 433 'to show complete help)'))
419 434
420 return rst 435 return rst
421 436
422
423 def helplist(select=None, **opts): 437 def helplist(select=None, **opts):
424 # list of commands 438 # Category -> list of commands
425 if name == "shortlist": 439 cats = {}
426 header = _('basic commands:\n\n') 440 # Command -> short description
427 elif name == "debug":
428 header = _('debug commands (internal and unsupported):\n\n')
429 else:
430 header = _('list of commands:\n\n')
431
432 h = {} 441 h = {}
433 cmds = {} 442 # Command -> string showing synonyms
443 syns = {}
434 for c, e in commands.table.iteritems(): 444 for c, e in commands.table.iteritems():
435 fs = cmdutil.parsealiases(c) 445 fs = cmdutil.parsealiases(c)
436 f = fs[0] 446 f = fs[0]
447 syns[f] = ', '.join(fs)
448 func = e[0]
437 p = '' 449 p = ''
438 if c.startswith("^"): 450 if c.startswith("^"):
439 p = '^' 451 p = '^'
440 if select and not select(p + f): 452 if select and not select(p + f):
441 continue 453 continue
442 if (not select and name != 'shortlist' and 454 if (not select and name != 'shortlist' and
443 e[0].__module__ != commands.__name__): 455 func.__module__ != commands.__name__):
444 continue 456 continue
445 if name == "shortlist" and not p: 457 if name == "shortlist" and not p:
446 continue 458 continue
447 doc = pycompat.getdoc(e[0]) 459 doc = pycompat.getdoc(func)
448 if filtercmd(ui, f, name, doc): 460 if filtercmd(ui, f, name, doc):
449 continue 461 continue
450 doc = gettext(doc) 462 doc = gettext(doc)
451 if not doc: 463 if not doc:
452 doc = _("(no help text available)") 464 doc = _("(no help text available)")
453 h[f] = doc.splitlines()[0].rstrip() 465 h[f] = doc.splitlines()[0].rstrip()
454 cmds[f] = '|'.join(fs) 466
467 cat = getattr(func, 'helpcategory', None) or (
468 registrar.command.CATEGORY_NONE)
469 cats.setdefault(cat, []).append(f)
455 470
456 rst = [] 471 rst = []
457 if not h: 472 if not h:
458 if not ui.quiet: 473 if not ui.quiet:
459 rst.append(_('no commands defined\n')) 474 rst.append(_('no commands defined\n'))
460 return rst 475 return rst
461 476
477 # Output top header.
462 if not ui.quiet: 478 if not ui.quiet:
463 rst.append(header) 479 if name == "shortlist":
464 fns = sorted(h) 480 rst.append(_('basic commands:\n\n'))
465 for f in fns: 481 elif name == "debug":
466 if ui.verbose: 482 rst.append(_('debug commands (internal and unsupported):\n\n'))
467 commacmds = cmds[f].replace("|",", ")
468 rst.append(" :%s: %s\n" % (commacmds, h[f]))
469 else: 483 else:
470 rst.append(' :%s: %s\n' % (f, h[f])) 484 rst.append(_('list of commands:\n'))
485
486 def appendcmds(cmds):
487 cmds = sorted(cmds)
488 for c in cmds:
489 if ui.verbose:
490 rst.append(" :%s: %s\n" % (syns[c], h[c]))
491 else:
492 rst.append(' :%s: %s\n' % (c, h[c]))
493
494 if name in ('shortlist', 'debug'):
495 # List without categories.
496 appendcmds(h)
497 else:
498 # Check that all categories have an order.
499 missing_order = set(cats.keys()) - set(CATEGORY_ORDER)
500 if missing_order:
501 ui.develwarn('help categories missing from CATEGORY_ORDER: %s' %
502 missing_order)
503
504 # List per category.
505 for cat in CATEGORY_ORDER:
506 catfns = cats.get(cat, [])
507 if catfns:
508 if len(cats) > 1:
509 catname = gettext(CATEGORY_NAMES[cat])
510 rst.append("\n%s:\n" % catname)
511 rst.append("\n")
512 appendcmds(catfns)
471 513
472 ex = opts.get 514 ex = opts.get
473 anyopts = (ex(r'keyword') or not (ex(r'command') or ex(r'extension'))) 515 anyopts = (ex(r'keyword') or not (ex(r'command') or ex(r'extension')))
474 if not name and anyopts: 516 if not name and anyopts:
475 exts = listexts(_('enabled extensions:'), extensions.enabled()) 517 exts = listexts(_('enabled extensions:'), extensions.enabled())
497 rst.append(_("\n(use 'hg help' for the full list of commands " 539 rst.append(_("\n(use 'hg help' for the full list of commands "
498 "or 'hg -v' for details)\n")) 540 "or 'hg -v' for details)\n"))
499 elif name and not full: 541 elif name and not full:
500 rst.append(_("\n(use 'hg help %s' to show the full help " 542 rst.append(_("\n(use 'hg help %s' to show the full help "
501 "text)\n") % name) 543 "text)\n") % name)
502 elif name and cmds and name in cmds.keys(): 544 elif name and syns and name in syns.keys():
503 rst.append(_("\n(use 'hg help -v -e %s' to show built-in " 545 rst.append(_("\n(use 'hg help -v -e %s' to show built-in "
504 "aliases and global options)\n") % name) 546 "aliases and global options)\n") % name)
505 else: 547 else:
506 rst.append(_("\n(use 'hg help -v%s' to show built-in aliases " 548 rst.append(_("\n(use 'hg help -v%s' to show built-in aliases "
507 "and global options)\n") 549 "and global options)\n")