Mercurial > public > mercurial-scm > hg
comparison mercurial/commands.py @ 18746:c0087d48ec3a
help: move the majority of the help command to the help module
We move the logic for generating the unformatted ReST source to the
help module, in order to eventually avoid calling commands.help_()
from hgweb.
No functionality change.
author | Dan Villiom Podlaski Christiansen <danchr@gmail.com> |
---|---|
date | Sat, 09 Feb 2013 21:51:21 +0000 |
parents | 6b786dc88612 |
children | 56dd55da2f7d 87441497ecaa |
comparison
equal
deleted
inserted
replaced
18745:3c7c25fa58e0 | 18746:c0087d48ec3a |
---|---|
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, bin, nullid, nullrev, short | 8 from node import hex, bin, nullid, nullrev, short |
9 from lock import release | 9 from lock import release |
10 from i18n import _, gettext | 10 from i18n import _ |
11 import os, re, difflib, time, tempfile, errno | 11 import os, re, difflib, time, tempfile, errno |
12 import hg, scmutil, util, revlog, extensions, copies, error, bookmarks | 12 import hg, scmutil, util, revlog, copies, error, bookmarks |
13 import patch, help, encoding, templatekw, discovery | 13 import patch, help, encoding, templatekw, discovery |
14 import archival, changegroup, cmdutil, hbisect | 14 import archival, changegroup, cmdutil, hbisect |
15 import sshserver, hgweb, hgweb.server, commandserver | 15 import sshserver, hgweb, hgweb.server, commandserver |
16 import merge as mergemod | 16 import merge as mergemod |
17 import minirst, revset, fileset | 17 import minirst, revset, fileset |
3212 [('e', 'extension', None, _('show only help for extensions')), | 3212 [('e', 'extension', None, _('show only help for extensions')), |
3213 ('c', 'command', None, _('show only help for commands')), | 3213 ('c', 'command', None, _('show only help for commands')), |
3214 ('k', 'keyword', '', _('show topics matching keyword')), | 3214 ('k', 'keyword', '', _('show topics matching keyword')), |
3215 ], | 3215 ], |
3216 _('[-ec] [TOPIC]')) | 3216 _('[-ec] [TOPIC]')) |
3217 def help_(ui, name=None, unknowncmd=False, full=True, **opts): | 3217 def help_(ui, name=None, **opts): |
3218 """show help for a given topic or a help overview | 3218 """show help for a given topic or a help overview |
3219 | 3219 |
3220 With no arguments, print a list of commands with short help messages. | 3220 With no arguments, print a list of commands with short help messages. |
3221 | 3221 |
3222 Given a topic, extension, or command name, print help for that | 3222 Given a topic, extension, or command name, print help for that |
3225 Returns 0 if successful. | 3225 Returns 0 if successful. |
3226 """ | 3226 """ |
3227 | 3227 |
3228 textwidth = min(ui.termwidth(), 80) - 2 | 3228 textwidth = min(ui.termwidth(), 80) - 2 |
3229 | 3229 |
3230 def helpcmd(name): | |
3231 try: | |
3232 aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd) | |
3233 except error.AmbiguousCommand, inst: | |
3234 # py3k fix: except vars can't be used outside the scope of the | |
3235 # except block, nor can be used inside a lambda. python issue4617 | |
3236 prefix = inst.args[0] | |
3237 select = lambda c: c.lstrip('^').startswith(prefix) | |
3238 rst = helplist(select) | |
3239 return rst | |
3240 | |
3241 rst = [] | |
3242 | |
3243 # check if it's an invalid alias and display its error if it is | |
3244 if getattr(entry[0], 'badalias', False): | |
3245 if not unknowncmd: | |
3246 ui.pushbuffer() | |
3247 entry[0](ui) | |
3248 rst.append(ui.popbuffer()) | |
3249 return rst | |
3250 | |
3251 # synopsis | |
3252 if len(entry) > 2: | |
3253 if entry[2].startswith('hg'): | |
3254 rst.append("%s\n" % entry[2]) | |
3255 else: | |
3256 rst.append('hg %s %s\n' % (aliases[0], entry[2])) | |
3257 else: | |
3258 rst.append('hg %s\n' % aliases[0]) | |
3259 # aliases | |
3260 if full and not ui.quiet and len(aliases) > 1: | |
3261 rst.append(_("\naliases: %s\n") % ', '.join(aliases[1:])) | |
3262 rst.append('\n') | |
3263 | |
3264 # description | |
3265 doc = gettext(entry[0].__doc__) | |
3266 if not doc: | |
3267 doc = _("(no help text available)") | |
3268 if util.safehasattr(entry[0], 'definition'): # aliased command | |
3269 if entry[0].definition.startswith('!'): # shell alias | |
3270 doc = _('shell alias for::\n\n %s') % entry[0].definition[1:] | |
3271 else: | |
3272 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc) | |
3273 doc = doc.splitlines(True) | |
3274 if ui.quiet or not full: | |
3275 rst.append(doc[0]) | |
3276 else: | |
3277 rst.extend(doc) | |
3278 rst.append('\n') | |
3279 | |
3280 # check if this command shadows a non-trivial (multi-line) | |
3281 # extension help text | |
3282 try: | |
3283 mod = extensions.find(name) | |
3284 doc = gettext(mod.__doc__) or '' | |
3285 if '\n' in doc.strip(): | |
3286 msg = _('use "hg help -e %s" to show help for ' | |
3287 'the %s extension') % (name, name) | |
3288 rst.append('\n%s\n' % msg) | |
3289 except KeyError: | |
3290 pass | |
3291 | |
3292 # options | |
3293 if not ui.quiet and entry[1]: | |
3294 rst.append('\n%s\n\n' % _("options:")) | |
3295 rst.append(help.optrst(entry[1], ui.verbose)) | |
3296 | |
3297 if ui.verbose: | |
3298 rst.append('\n%s\n\n' % _("global options:")) | |
3299 rst.append(help.optrst(globalopts, ui.verbose)) | |
3300 | |
3301 if not ui.verbose: | |
3302 if not full: | |
3303 rst.append(_('\nuse "hg help %s" to show the full help text\n') | |
3304 % name) | |
3305 elif not ui.quiet: | |
3306 omitted = _('use "hg -v help %s" to show more complete' | |
3307 ' help and the global options') % name | |
3308 notomitted = _('use "hg -v help %s" to show' | |
3309 ' the global options') % name | |
3310 help.indicateomitted(rst, omitted, notomitted) | |
3311 | |
3312 return rst | |
3313 | |
3314 | |
3315 def helplist(select=None): | |
3316 # list of commands | |
3317 if name == "shortlist": | |
3318 header = _('basic commands:\n\n') | |
3319 else: | |
3320 header = _('list of commands:\n\n') | |
3321 | |
3322 h = {} | |
3323 cmds = {} | |
3324 for c, e in table.iteritems(): | |
3325 f = c.split("|", 1)[0] | |
3326 if select and not select(f): | |
3327 continue | |
3328 if (not select and name != 'shortlist' and | |
3329 e[0].__module__ != __name__): | |
3330 continue | |
3331 if name == "shortlist" and not f.startswith("^"): | |
3332 continue | |
3333 f = f.lstrip("^") | |
3334 if not ui.debugflag and f.startswith("debug"): | |
3335 continue | |
3336 doc = e[0].__doc__ | |
3337 if doc and 'DEPRECATED' in doc and not ui.verbose: | |
3338 continue | |
3339 doc = gettext(doc) | |
3340 if not doc: | |
3341 doc = _("(no help text available)") | |
3342 h[f] = doc.splitlines()[0].rstrip() | |
3343 cmds[f] = c.lstrip("^") | |
3344 | |
3345 rst = [] | |
3346 if not h: | |
3347 if not ui.quiet: | |
3348 rst.append(_('no commands defined\n')) | |
3349 return rst | |
3350 | |
3351 if not ui.quiet: | |
3352 rst.append(header) | |
3353 fns = sorted(h) | |
3354 for f in fns: | |
3355 if ui.verbose: | |
3356 commands = cmds[f].replace("|",", ") | |
3357 rst.append(" :%s: %s\n" % (commands, h[f])) | |
3358 else: | |
3359 rst.append(' :%s: %s\n' % (f, h[f])) | |
3360 | |
3361 if not name: | |
3362 exts = help.listexts(_('enabled extensions:'), extensions.enabled()) | |
3363 if exts: | |
3364 rst.append('\n') | |
3365 rst.extend(exts) | |
3366 | |
3367 rst.append(_("\nadditional help topics:\n\n")) | |
3368 topics = [] | |
3369 for names, header, doc in help.helptable: | |
3370 topics.append((names[0], header)) | |
3371 for t, desc in topics: | |
3372 rst.append(" :%s: %s\n" % (t, desc)) | |
3373 | |
3374 optlist = [] | |
3375 if not ui.quiet: | |
3376 if ui.verbose: | |
3377 optlist.append((_("global options:"), globalopts)) | |
3378 if name == 'shortlist': | |
3379 optlist.append((_('use "hg help" for the full list ' | |
3380 'of commands'), ())) | |
3381 else: | |
3382 if name == 'shortlist': | |
3383 msg = _('use "hg help" for the full list of commands ' | |
3384 'or "hg -v" for details') | |
3385 elif name and not full: | |
3386 msg = _('use "hg help %s" to show the full help ' | |
3387 'text') % name | |
3388 else: | |
3389 msg = _('use "hg -v help%s" to show builtin aliases and ' | |
3390 'global options') % (name and " " + name or "") | |
3391 optlist.append((msg, ())) | |
3392 | |
3393 if optlist: | |
3394 for title, options in optlist: | |
3395 rst.append('\n%s\n' % title) | |
3396 if options: | |
3397 rst.append('\n%s\n' % help.optrst(options, ui.verbose)) | |
3398 return rst | |
3399 | |
3400 def helptopic(name): | |
3401 for names, header, doc in help.helptable: | |
3402 if name in names: | |
3403 break | |
3404 else: | |
3405 raise error.UnknownCommand(name) | |
3406 | |
3407 rst = ["%s\n\n" % header] | |
3408 # description | |
3409 if not doc: | |
3410 rst.append(" %s\n" % _("(no help text available)")) | |
3411 if util.safehasattr(doc, '__call__'): | |
3412 rst += [" %s\n" % l for l in doc().splitlines()] | |
3413 | |
3414 if not ui.verbose: | |
3415 omitted = (_('use "hg help -v %s" to show more complete help') % | |
3416 name) | |
3417 help.indicateomitted(rst, omitted) | |
3418 | |
3419 try: | |
3420 cmdutil.findcmd(name, table) | |
3421 rst.append(_('\nuse "hg help -c %s" to see help for ' | |
3422 'the %s command\n') % (name, name)) | |
3423 except error.UnknownCommand: | |
3424 pass | |
3425 return rst | |
3426 | |
3427 def helpext(name): | |
3428 try: | |
3429 mod = extensions.find(name) | |
3430 doc = gettext(mod.__doc__) or _('no help text available') | |
3431 except KeyError: | |
3432 mod = None | |
3433 doc = extensions.disabledext(name) | |
3434 if not doc: | |
3435 raise error.UnknownCommand(name) | |
3436 | |
3437 if '\n' not in doc: | |
3438 head, tail = doc, "" | |
3439 else: | |
3440 head, tail = doc.split('\n', 1) | |
3441 rst = [_('%s extension - %s\n\n') % (name.split('.')[-1], head)] | |
3442 if tail: | |
3443 rst.extend(tail.splitlines(True)) | |
3444 rst.append('\n') | |
3445 | |
3446 if not ui.verbose: | |
3447 omitted = (_('use "hg help -v %s" to show more complete help') % | |
3448 name) | |
3449 help.indicateomitted(rst, omitted) | |
3450 | |
3451 if mod: | |
3452 try: | |
3453 ct = mod.cmdtable | |
3454 except AttributeError: | |
3455 ct = {} | |
3456 modcmds = set([c.split('|', 1)[0] for c in ct]) | |
3457 rst.extend(helplist(modcmds.__contains__)) | |
3458 else: | |
3459 rst.append(_('use "hg help extensions" for information on enabling ' | |
3460 'extensions\n')) | |
3461 return rst | |
3462 | |
3463 def helpextcmd(name): | |
3464 cmd, ext, mod = extensions.disabledcmd(ui, name, | |
3465 ui.configbool('ui', 'strict')) | |
3466 doc = gettext(mod.__doc__).splitlines()[0] | |
3467 | |
3468 rst = help.listexts(_("'%s' is provided by the following " | |
3469 "extension:") % cmd, {ext: doc}, indent=4) | |
3470 rst.append('\n') | |
3471 rst.append(_('use "hg help extensions" for information on enabling ' | |
3472 'extensions\n')) | |
3473 return rst | |
3474 | |
3475 | |
3476 rst = [] | |
3477 kw = opts.get('keyword') | |
3478 if kw: | |
3479 matches = help.topicmatch(kw) | |
3480 for t, title in (('topics', _('Topics')), | |
3481 ('commands', _('Commands')), | |
3482 ('extensions', _('Extensions')), | |
3483 ('extensioncommands', _('Extension Commands'))): | |
3484 if matches[t]: | |
3485 rst.append('%s:\n\n' % title) | |
3486 rst.extend(minirst.maketable(sorted(matches[t]), 1)) | |
3487 rst.append('\n') | |
3488 elif name and name != 'shortlist': | |
3489 i = None | |
3490 if unknowncmd: | |
3491 queries = (helpextcmd,) | |
3492 elif opts.get('extension'): | |
3493 queries = (helpext,) | |
3494 elif opts.get('command'): | |
3495 queries = (helpcmd,) | |
3496 else: | |
3497 queries = (helptopic, helpcmd, helpext, helpextcmd) | |
3498 for f in queries: | |
3499 try: | |
3500 rst = f(name) | |
3501 i = None | |
3502 break | |
3503 except error.UnknownCommand, inst: | |
3504 i = inst | |
3505 if i: | |
3506 raise i | |
3507 else: | |
3508 # program name | |
3509 if not ui.quiet: | |
3510 rst = [_("Mercurial Distributed SCM\n"), '\n'] | |
3511 rst.extend(helplist()) | |
3512 | |
3513 keep = ui.verbose and ['verbose'] or [] | 3230 keep = ui.verbose and ['verbose'] or [] |
3514 text = ''.join(rst) | 3231 text = help.help_(ui, name, **opts) |
3232 | |
3515 formatted, pruned = minirst.format(text, textwidth, keep=keep) | 3233 formatted, pruned = minirst.format(text, textwidth, keep=keep) |
3516 if 'verbose' in pruned: | 3234 if 'verbose' in pruned: |
3517 keep.append('omitted') | 3235 keep.append('omitted') |
3518 else: | 3236 else: |
3519 keep.append('notomitted') | 3237 keep.append('notomitted') |