##// END OF EJS Templates
help: adding support for command categories...
rdamazio@google.com -
r40327:170926ca default
parent child Browse files
Show More
@@ -149,7 +149,8 b' def showtopic(ui, topic):'
149 helpprinter(ui, helptable + extrahelptable, None, include=[topic])
149 helpprinter(ui, helptable + extrahelptable, None, include=[topic])
150
150
151 def helpprinter(ui, helptable, sectionfunc, include=[], exclude=[]):
151 def helpprinter(ui, helptable, sectionfunc, include=[], exclude=[]):
152 for names, sec, doc in helptable:
152 for h in helptable:
153 names, sec, doc = h[0:3]
153 if exclude and names[0] in exclude:
154 if exclude and names[0] in exclude:
154 continue
155 continue
155 if include and names[0] not in include:
156 if include and names[0] not in include:
@@ -25,6 +25,7 b' from . import ('
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,
@@ -47,6 +48,20 b' from .hgweb import ('
47 _("(EXPERIMENTAL)"),
48 _("(EXPERIMENTAL)"),
48 }
49 }
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',
63 }
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 = []
@@ -419,39 +434,39 b' def help_(ui, commands, name, unknowncmd'
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:
@@ -459,15 +474,42 b' def help_(ui, commands, name, unknowncmd'
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')))
@@ -499,7 +541,7 b' def help_(ui, commands, name, unknowncmd'
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:
@@ -146,6 +146,10 b' class command(_funcregistrarbase):'
146 to prevent the command from running if the requested intent could not be
146 to prevent the command from running if the requested intent could not be
147 fulfilled.
147 fulfilled.
148
148
149 If `helpcategory` is set (usually to one of the constants in the help
150 module), the command will be displayed under that category in the help's
151 list of commands.
152
149 The following intents are defined:
153 The following intents are defined:
150
154
151 readonly
155 readonly
@@ -164,14 +168,17 b' class command(_funcregistrarbase):'
164 descriptions and examples.
168 descriptions and examples.
165 """
169 """
166
170
171 # Command categories for grouping them in help output.
172 CATEGORY_NONE = 'none'
173
167 def _doregister(self, func, name, options=(), synopsis=None,
174 def _doregister(self, func, name, options=(), synopsis=None,
168 norepo=False, optionalrepo=False, inferrepo=False,
175 norepo=False, optionalrepo=False, inferrepo=False,
169 intents=None):
176 intents=None, helpcategory=None):
170
171 func.norepo = norepo
177 func.norepo = norepo
172 func.optionalrepo = optionalrepo
178 func.optionalrepo = optionalrepo
173 func.inferrepo = inferrepo
179 func.inferrepo = inferrepo
174 func.intents = intents or set()
180 func.intents = intents or set()
181 func.helpcategory = helpcategory
175 if synopsis:
182 if synopsis:
176 self._table[name] = func, list(options), synopsis
183 self._table[name] = func, list(options), synopsis
177 else:
184 else:
General Comments 0
You need to be logged in to leave comments. Login now