##// END OF EJS Templates
branchmap: don't use buffer() on Python 3...
branchmap: don't use buffer() on Python 3 This is certainly slower than the Python 2 code, but it works, and we can revisit it later if it's a problem.

File last commit:

r31293:2cdb1239 default
r31347:279430ee default
Show More
help.py
660 lines | 23.0 KiB | text/x-python | PythonLexer
Matt Mackall
Add basic support for help topics and a dates topic
r3795 # help.py - help data for mercurial
#
# Copyright 2006 Matt Mackall <mpm@selenic.com>
#
Martin Geisler
updated license to be explicit about GPL version 2
r8225 # This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Matt Mackall
Add basic support for help topics and a dates topic
r3795
Gregory Szorc
help: use absolute_import
r27479 from __future__ import absolute_import
import itertools
import os
import textwrap
from .i18n import (
_,
gettext,
)
from . import (
cmdutil,
encoding,
error,
extensions,
filemerge,
fileset,
minirst,
revset,
templatefilters,
templatekw,
templater,
util,
)
from .hgweb import (
webcommands,
)
Cédric Duval
help: adding a new help topic about extensions...
r8863
Jun Wu
help: hide command line options marked as "advanced"...
r31080 _exclkeywords = set([
"(ADVANCED)",
Yuya Nishihara
help: include parens in DEPRECATED/EXPERIMENTAL keywords...
r26370 "(DEPRECATED)",
"(EXPERIMENTAL)",
Jun Wu
help: hide command line options marked as "advanced"...
r31080 # i18n: "(ADVANCED)" is a keyword, must be translated consistently
_("(ADVANCED)"),
Yuya Nishihara
help: include parens in DEPRECATED/EXPERIMENTAL keywords...
r26370 # i18n: "(DEPRECATED)" is a keyword, must be translated consistently
_("(DEPRECATED)"),
# i18n: "(EXPERIMENTAL)" is a keyword, must be translated consistently
_("(EXPERIMENTAL)"),
Jun Wu
help: hide command line options marked as "advanced"...
r31080 ])
Yuya Nishihara
help: define list of keywords that should be excluded from non-verbose output...
r26369
Augie Fackler
help: exclude deprecated extensions in the disabled part of 'help extensions'
r20582 def listexts(header, exts, indent=1, showdeprecated=False):
Cédric Duval
help: more improvements for the extensions topic...
r8879 '''return a text listing of the given extensions'''
Olav Reinert
help: format extension lists using RST...
r16852 rst = []
if exts:
for name, desc in sorted(exts.iteritems()):
Yuya Nishihara
help: unify handling of DEPRECATED/EXPERIMENTAL keywords...
r26371 if not showdeprecated and any(w in desc for w in _exclkeywords):
Augie Fackler
help: exclude deprecated extensions in the disabled part of 'help extensions'
r20582 continue
Olav Reinert
help: format extension lists using RST...
r16852 rst.append('%s:%s: %s\n' % (' ' * indent, name, desc))
timeless
help: make listexts less confusing for deprecated exts...
r27151 if rst:
rst.insert(0, '\n%s\n\n' % header)
Olav Reinert
help: format extension lists using RST...
r16852 return rst
Cédric Duval
help: refactor extensions listing, and show enabled ones in the dedicated topic
r8864
Yuya Nishihara
help: pass around ui to doc loader (API)...
r26413 def extshelp(ui):
rst = loaddoc('extensions')(ui).splitlines(True)
Augie Fackler
help: exclude deprecated extensions in the disabled part of 'help extensions'
r20582 rst.extend(listexts(
_('enabled extensions:'), extensions.enabled(), showdeprecated=True))
Olav Reinert
help: format extension lists using RST...
r16852 rst.extend(listexts(_('disabled extensions:'), extensions.disabled()))
doc = ''.join(rst)
Cédric Duval
help: adding a new help topic about extensions...
r8863 return doc
Martin Geisler
i18n: mark help strings for translation...
r7013
Matt Mackall
help: roll option list header into option formatter
r22116 def optrst(header, options, verbose):
Olav Reinert
help: move some helper functions to help.py
r16781 data = []
multioccur = False
for option in options:
if len(option) == 5:
shortopt, longopt, default, desc, optlabel = option
else:
shortopt, longopt, default, desc = option
optlabel = _("VALUE") # default label
Yuya Nishihara
help: define list of keywords that should be excluded from non-verbose output...
r26369 if not verbose and any(w in desc for w in _exclkeywords):
Olav Reinert
help: move some helper functions to help.py
r16781 continue
so = ''
if shortopt:
so = '-' + shortopt
lo = '--' + longopt
if default:
desc += _(" (default: %s)") % default
if isinstance(default, list):
lo += " %s [+]" % optlabel
multioccur = True
elif (default is not None) and not isinstance(default, bool):
lo += " %s" % optlabel
data.append((so, lo, desc))
Matt Mackall
help: fold repeatable option message into option table header...
r22117 if multioccur:
header += (_(" ([+] can be repeated)"))
Olav Reinert
help: move some helper functions to help.py
r16781
Matt Mackall
help: roll option list header into option formatter
r22116 rst = ['\n%s:\n\n' % header]
rst.extend(minirst.maketable(data, 1))
Olav Reinert
help: move some helper functions to help.py
r16781
Olav Reinert
minirst: generate tables as a list of joined lines
r16815 return ''.join(rst)
Olav Reinert
help: move some helper functions to help.py
r16781
FUJIWARA Katsunori
help: indicate help omitting if help document is not fully displayed...
r17837 def indicateomitted(rst, omitted, notomitted=None):
rst.append('\n\n.. container:: omitted\n\n %s\n\n' % omitted)
if notomitted:
rst.append('\n\n.. container:: notomitted\n\n %s\n\n' % notomitted)
timeless
help: refactor filtercmd
r27323 def filtercmd(ui, cmd, kw, doc):
if not ui.debugflag and cmd.startswith("debug") and kw != "debug":
return True
if not ui.verbose and doc and any(w in doc for w in _exclkeywords):
return True
return False
Yuya Nishihara
help: pass around ui to doc loader (API)...
r26413 def topicmatch(ui, kw):
Augie Fackler
help: introduce topicmatch for finding topics matching a keyword
r16710 """Return help topics matching kw.
Returns {'section': [(name, summary), ...], ...} where section is
one of topics, commands, extensions, or extensioncommands.
"""
kw = encoding.lower(kw)
def lowercontains(container):
Nikolaj Sjujskij
help: fix search with `-k` option in non-ASCII locales...
r16845 return kw in encoding.lower(container) # translated in helptable
Augie Fackler
help: introduce topicmatch for finding topics matching a keyword
r16710 results = {'topics': [],
'commands': [],
'extensions': [],
'extensioncommands': [],
}
for names, header, doc in helptable:
Gregory Szorc
help: only call doc() when it is callable...
r22322 # Old extensions may use a str as doc.
Augie Fackler
help: introduce topicmatch for finding topics matching a keyword
r16710 if (sum(map(lowercontains, names))
or lowercontains(header)
Yuya Nishihara
help: pass around ui to doc loader (API)...
r26413 or (callable(doc) and lowercontains(doc(ui)))):
Augie Fackler
help: introduce topicmatch for finding topics matching a keyword
r16710 results['topics'].append((names[0], header))
Gregory Szorc
help: use absolute_import
r27479 from . import commands # avoid cycle
Augie Fackler
help: introduce topicmatch for finding topics matching a keyword
r16710 for cmd, entry in commands.table.iteritems():
if len(entry) == 3:
summary = entry[2]
else:
summary = ''
Nikolaj Sjujskij
help: fix search with `-k` option in non-ASCII locales...
r16845 # translate docs *before* searching there
docs = _(getattr(entry[0], '__doc__', None)) or ''
Augie Fackler
help: introduce topicmatch for finding topics matching a keyword
r16710 if kw in cmd or lowercontains(summary) or lowercontains(docs):
Nikolaj Sjujskij
help: fix search with `-k` option in non-ASCII locales...
r16845 doclines = docs.splitlines()
Augie Fackler
help: introduce topicmatch for finding topics matching a keyword
r16710 if doclines:
summary = doclines[0]
av6
help: replace some str.split() calls by str.partition() or str.rpartition()...
r26845 cmdname = cmd.partition('|')[0].lstrip('^')
timeless
help: call filtercmd from topicmatch...
r27324 if filtercmd(ui, cmdname, kw, docs):
continue
Augie Fackler
help: introduce topicmatch for finding topics matching a keyword
r16710 results['commands'].append((cmdname, summary))
for name, docs in itertools.chain(
FUJIWARA Katsunori
help: use full name of extensions to look up them for keyword search...
r19769 extensions.enabled(False).iteritems(),
Augie Fackler
help: introduce topicmatch for finding topics matching a keyword
r16710 extensions.disabled().iteritems()):
Simon Farnsworth
help: don't crash in keyword search if an extension fails to provide docs...
r28058 if not docs:
continue
Jun Wu
mercurial: pass ui to extensions.load (issue5007)...
r27660 mod = extensions.load(ui, name, '')
av6
help: replace some str.split() calls by str.partition() or str.rpartition()...
r26845 name = name.rpartition('.')[-1]
Augie Fackler
help: introduce topicmatch for finding topics matching a keyword
r16710 if lowercontains(name) or lowercontains(docs):
Nikolaj Sjujskij
help: fix search with `-k` option in non-ASCII locales...
r16845 # extension docs are already translated
results['extensions'].append((name, docs.splitlines()[0]))
Augie Fackler
help: introduce topicmatch for finding topics matching a keyword
r16710 for cmd, entry in getattr(mod, 'cmdtable', {}).iteritems():
Augie Fackler
help: add --keyword (-k) for searching help
r16711 if kw in cmd or (len(entry) > 2 and lowercontains(entry[2])):
av6
help: replace some str.split() calls by str.partition() or str.rpartition()...
r26845 cmdname = cmd.partition('|')[0].lstrip('^')
Olav Reinert
help: fix extension commands help in keyword search...
r16942 if entry[0].__doc__:
cmddoc = gettext(entry[0].__doc__).splitlines()[0]
Thomas Arendsen Hein
help: fix 'hg help -k' matching an extension without docs...
r16884 else:
cmddoc = _('(no help text available)')
timeless
help: filter extension commands
r27387 if filtercmd(ui, cmdname, kw, cmddoc):
continue
Thomas Arendsen Hein
help: fix 'hg help -k' matching an extension without docs...
r16884 results['extensioncommands'].append((cmdname, cmddoc))
Augie Fackler
help: introduce topicmatch for finding topics matching a keyword
r16710 return results
Gregory Szorc
help: teach loaddoc to load from a different directory...
r27375 def loaddoc(topic, subdir=None):
Martin Geisler
help: move help topics from mercurial/help.py to help/*.txt...
r9539 """Return a delayed loader for help/topic.txt."""
Matt Mackall
move environment topic
r3798
Yuya Nishihara
help: pass around ui to doc loader (API)...
r26413 def loader(ui):
Mads Kiilerich
help: don't search randomly for help data - trust util.datapath...
r22637 docdir = os.path.join(util.datapath, 'help')
Gregory Szorc
help: teach loaddoc to load from a different directory...
r27375 if subdir:
docdir = os.path.join(docdir, subdir)
Martin Geisler
help: move help topics from mercurial/help.py to help/*.txt...
r9539 path = os.path.join(docdir, topic + ".txt")
Dan Villiom Podlaski Christiansen
prevent transient leaks of file handle by using new helper functions...
r14168 doc = gettext(util.readfile(path))
Patrick Mezard
help: add topic rewriting hooks...
r12820 for rewriter in helphooks.get(topic, []):
Yuya Nishihara
help: pass around ui to rewriter hooks (API)...
r26414 doc = rewriter(ui, topic, doc)
Patrick Mezard
help: add topic rewriting hooks...
r12820 return doc
Martin Geisler
help: move help topics from mercurial/help.py to help/*.txt...
r9539 return loader
Alexander Solovyov
help: add a topic about some of the templating features
r7677
Gregory Szorc
help: add "internals" topic...
r27376 internalstable = sorted([
Gregory Szorc
help: don't try to render a section on sub-topics...
r29747 (['bundles'], _('Bundles'),
Gregory Szorc
help: add "internals" topic...
r27376 loaddoc('bundles', subdir='internals')),
Augie Fackler
help: update help.internalstable for new censor docs
r31293 (['censor'], _('Censor'),
loaddoc('censor', subdir='internals')),
Gregory Szorc
help: don't try to render a section on sub-topics...
r29747 (['changegroups'], _('Changegroups'),
Gregory Szorc
help: add "internals" topic...
r27376 loaddoc('changegroups', subdir='internals')),
Gregory Szorc
help: don't try to render a section on sub-topics...
r29747 (['requirements'], _('Repository Requirements'),
Gregory Szorc
help: document requirements...
r28523 loaddoc('requirements', subdir='internals')),
Gregory Szorc
help: don't try to render a section on sub-topics...
r29747 (['revlogs'], _('Revision Logs'),
Gregory Szorc
internals: document revlog format...
r27631 loaddoc('revlogs', subdir='internals')),
Gregory Szorc
help: internals topic for wire protocol...
r29859 (['wireprotocol'], _('Wire Protocol'),
loaddoc('wireprotocol', subdir='internals')),
Gregory Szorc
help: add "internals" topic...
r27376 ])
def internalshelp(ui):
"""Generate the index for the "internals" topic."""
lines = []
for names, header, doc in internalstable:
Yuya Nishihara
help: add missed last new line to "internals" topic...
r27400 lines.append(' :%s: %s\n' % (names[0], header))
Gregory Szorc
help: add "internals" topic...
r27376
Yuya Nishihara
help: add missed last new line to "internals" topic...
r27400 return ''.join(lines)
Gregory Szorc
help: add "internals" topic...
r27376
Yun Lee
help: sort help topics to make the output more readable (issue2751)
r13888 helptable = sorted([
Pierre-Yves David
color: update the help table...
r31129 (['color'], _("Colorizing Outputs"), loaddoc('color')),
Martin Geisler
help: make "hg help hgrc" an alias for "hg help config"
r12145 (["config", "hgrc"], _("Configuration Files"), loaddoc('config')),
Martin Geisler
help: move help topics from mercurial/help.py to help/*.txt...
r9539 (["dates"], _("Date Formats"), loaddoc('dates')),
(["patterns"], _("File Name Patterns"), loaddoc('patterns')),
Matt Mackall
many, many trivial check-code fixups
r10282 (['environment', 'env'], _('Environment Variables'),
loaddoc('environment')),
Martin von Zweigbergk
help: merge revsets.txt into revisions.txt...
r30769 (['revisions', 'revs', 'revsets', 'revset', 'multirevs', 'mrevs'],
_('Specifying Revisions'), loaddoc('revisions')),
Mads Kiilerich
help: use the first topic name from helptable, not the longest alias...
r17322 (['filesets', 'fileset'], _("Specifying File Sets"), loaddoc('filesets')),
Martin Geisler
help: move help topics from mercurial/help.py to help/*.txt...
r9539 (['diffs'], _('Diff Formats'), loaddoc('diffs')),
Gregory Szorc
help: make "mergetool" an alias for "merge-tools"...
r30812 (['merge-tools', 'mergetools', 'mergetool'], _('Merge Tools'),
loaddoc('merge-tools')),
A. S. Budden
help: add reference to template help (issue3413)...
r16568 (['templating', 'templates', 'template', 'style'], _('Template Usage'),
Matt Mackall
many, many trivial check-code fixups
r10282 loaddoc('templates')),
Martin Geisler
help: move help topics from mercurial/help.py to help/*.txt...
r9539 (['urls'], _('URL Paths'), loaddoc('urls')),
Martin Geisler
help: consistently use title capitalization for help topics
r16547 (["extensions"], _("Using Additional Features"), extshelp),
Mads Kiilerich
help: use the first topic name from helptable, not the longest alias...
r17322 (["subrepos", "subrepo"], _("Subrepositories"), loaddoc('subrepos')),
Mads Kiilerich
help: fix helptable indentation
r17321 (["hgweb"], _("Configuring hgweb"), loaddoc('hgweb')),
(["glossary"], _("Glossary"), loaddoc('glossary')),
(["hgignore", "ignore"], _("Syntax for Mercurial Ignore Files"),
loaddoc('hgignore')),
(["phases"], _("Working with Phases"), loaddoc('phases')),
Gregory Szorc
help: scripting help topic...
r25881 (['scripting'], _('Using Mercurial from scripts and automation'),
loaddoc('scripting')),
Gregory Szorc
help: add "internals" topic...
r27376 (['internals'], _("Technical implementation topics"),
internalshelp),
Augie Fackler
pager: move most help to a new help topic and deprecate extension
r31061 (['pager'], _("Pager Support"), loaddoc('pager')),
Yun Lee
help: sort help topics to make the output more readable (issue2751)
r13888 ])
Patrick Mezard
help: add topic rewriting hooks...
r12820
Gregory Szorc
help: support loading sub-topics...
r27379 # Maps topics with sub-topics to a list of their sub-topics.
subtopics = {
'internals': internalstable,
}
Patrick Mezard
help: add topic rewriting hooks...
r12820 # Map topics to lists of callable taking the current topic help and
# returning the updated version
Matt Mackall
help: consolidate topic hooks in help.py...
r14318 helphooks = {}
Patrick Mezard
help: add topic rewriting hooks...
r12820
def addtopichook(topic, rewriter):
helphooks.setdefault(topic, []).append(rewriter)
Patrick Mezard
help: extract items doc generation function
r13593
Yuya Nishihara
help: pass around ui to rewriter hooks (API)...
r26414 def makeitemsdoc(ui, topic, doc, marker, items, dedent=False):
Patrick Mezard
help: extract items doc generation function
r13593 """Extract docstring from the items key to function mapping, build a
timeless@mozdev.org
help: fix makeitemsdoc English description
r26196 single documentation block and use it to overwrite the marker in doc.
Patrick Mezard
help: extract items doc generation function
r13593 """
entries = []
for name in sorted(items):
text = (items[name].__doc__ or '').rstrip()
Yuya Nishihara
help: hide deprecated filesets, revsets and template items if not verbose...
r26415 if (not text
or not ui.verbose and any(w in text for w in _exclkeywords)):
Patrick Mezard
help: extract items doc generation function
r13593 continue
text = gettext(text)
Gregory Szorc
help: teach topic symbols how to dedent...
r24098 if dedent:
text = textwrap.dedent(text)
Patrick Mezard
help: extract items doc generation function
r13593 lines = text.splitlines()
"Yann E. MORIN"
help: strip doctest from dochelp...
r16250 doclines = [(lines[0])]
for l in lines[1:]:
# Stop once we find some Python doctest
if l.strip().startswith('>>>'):
break
Gregory Szorc
help: teach topic symbols how to dedent...
r24098 if dedent:
doclines.append(l.rstrip())
else:
doclines.append(' ' + l.strip())
"Yann E. MORIN"
help: strip doctest from dochelp...
r16250 entries.append('\n'.join(doclines))
Patrick Mezard
help: extract items doc generation function
r13593 entries = '\n\n'.join(entries)
return doc.replace(marker, entries)
Matt Mackall
help: consolidate topic hooks in help.py...
r14318
Gregory Szorc
help: teach topic symbols how to dedent...
r24098 def addtopicsymbols(topic, marker, symbols, dedent=False):
Yuya Nishihara
help: pass around ui to rewriter hooks (API)...
r26414 def add(ui, topic, doc):
return makeitemsdoc(ui, topic, doc, marker, symbols, dedent=dedent)
Matt Mackall
help: consolidate topic hooks in help.py...
r14318 addtopichook(topic, add)
Matt Mackall
fileset: add a help topic...
r14686 addtopicsymbols('filesets', '.. predicatesmarker', fileset.symbols)
Gregory Szorc
help.merge-tools: do not double document merge tools...
r24099 addtopicsymbols('merge-tools', '.. internaltoolsmarker',
filemerge.internalsdoc)
Martin von Zweigbergk
help: merge revsets.txt into revisions.txt...
r30769 addtopicsymbols('revisions', '.. predicatesmarker', revset.symbols)
Yuya Nishihara
templatekw: remove dockeywords hack...
r26436 addtopicsymbols('templates', '.. keywordsmarker', templatekw.keywords)
Matt Mackall
help: consolidate topic hooks in help.py...
r14318 addtopicsymbols('templates', '.. filtersmarker', templatefilters.filters)
Gregory Szorc
help: populate template functions via docstrings...
r24587 addtopicsymbols('templates', '.. functionsmarker', templater.funcs)
Gregory Szorc
help: teach topic symbols how to dedent...
r24098 addtopicsymbols('hgweb', '.. webcommandsmarker', webcommands.commands,
dedent=True)
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746
Gregory Szorc
help: pass subtopic into help()...
r27377 def help_(ui, name, unknowncmd=False, full=True, subtopic=None, **opts):
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 '''
Generate the help for 'name' as unformatted restructured text. If
'name' is None, describe the commands available.
'''
Gregory Szorc
help: use absolute_import
r27479 from . import commands # avoid cycle
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746
Gregory Szorc
help: pass sub-topic into help query functions...
r27378 def helpcmd(name, subtopic=None):
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 try:
aliases, entry = cmdutil.findcmd(name, commands.table,
strict=unknowncmd)
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except error.AmbiguousCommand as inst:
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 # py3k fix: except vars can't be used outside the scope of the
# except block, nor can be used inside a lambda. python issue4617
prefix = inst.args[0]
select = lambda c: c.lstrip('^').startswith(prefix)
rst = helplist(select)
return rst
rst = []
# check if it's an invalid alias and display its error if it is
Yuya Nishihara
alias: keep error message in "badalias" so that help can see it...
r22160 if getattr(entry[0], 'badalias', None):
Yuya Nishihara
help: provide help of bad alias without executing aliascmd()...
r22162 rst.append(entry[0].badalias + '\n')
if entry[0].unknowncmd:
try:
rst.extend(helpextcmd(entry[0].cmdname))
except error.UnknownCommand:
pass
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 return rst
# synopsis
if len(entry) > 2:
if entry[2].startswith('hg'):
rst.append("%s\n" % entry[2])
else:
rst.append('hg %s %s\n' % (aliases[0], entry[2]))
else:
rst.append('hg %s\n' % aliases[0])
# aliases
if full and not ui.quiet and len(aliases) > 1:
rst.append(_("\naliases: %s\n") % ', '.join(aliases[1:]))
rst.append('\n')
# description
doc = gettext(entry[0].__doc__)
if not doc:
doc = _("(no help text available)")
if util.safehasattr(entry[0], 'definition'): # aliased command
timeless
help: report source of aliases
r28828 source = entry[0].source
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 if entry[0].definition.startswith('!'): # shell alias
timeless
help: report source of aliases
r28828 doc = (_('shell alias for::\n\n %s\n\ndefined by: %s\n') %
(entry[0].definition[1:], source))
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 else:
timeless
help: report source of aliases
r28828 doc = (_('alias for: hg %s\n\n%s\n\ndefined by: %s\n') %
(entry[0].definition, doc, source))
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 doc = doc.splitlines(True)
if ui.quiet or not full:
rst.append(doc[0])
else:
rst.extend(doc)
rst.append('\n')
# check if this command shadows a non-trivial (multi-line)
# extension help text
try:
mod = extensions.find(name)
doc = gettext(mod.__doc__) or ''
if '\n' in doc.strip():
timeless
help: use single quotes in use warning
r29974 msg = _("(use 'hg help -e %s' to show help for "
"the %s extension)") % (name, name)
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 rst.append('\n%s\n' % msg)
except KeyError:
pass
# options
if not ui.quiet and entry[1]:
Matt Mackall
help: roll option list header into option formatter
r22116 rst.append(optrst(_("options"), entry[1], ui.verbose))
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746
if ui.verbose:
Matt Mackall
help: roll option list header into option formatter
r22116 rst.append(optrst(_("global options"),
commands.globalopts, ui.verbose))
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746
if not ui.verbose:
if not full:
timeless
help: use single quotes in use warning
r29974 rst.append(_("\n(use 'hg %s -h' to show more help)\n")
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 % name)
elif not ui.quiet:
Matt Mackall
help: tweak --verbose command help hint...
r22110 rst.append(_('\n(some details hidden, use --verbose '
'to show complete help)'))
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746
return rst
timeless
help: fix help -c/help -e/help -k...
r27325 def helplist(select=None, **opts):
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 # list of commands
if name == "shortlist":
header = _('basic commands:\n\n')
Mads Kiilerich
help: let 'hg help debug' show the list of secret debug commands...
r20822 elif name == "debug":
header = _('debug commands (internal and unsupported):\n\n')
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 else:
header = _('list of commands:\n\n')
h = {}
cmds = {}
for c, e in commands.table.iteritems():
av6
help: replace some str.split() calls by str.partition() or str.rpartition()...
r26845 f = c.partition("|")[0]
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 if select and not select(f):
continue
if (not select and name != 'shortlist' and
e[0].__module__ != commands.__name__):
continue
if name == "shortlist" and not f.startswith("^"):
continue
f = f.lstrip("^")
doc = e[0].__doc__
timeless
help: refactor filtercmd
r27323 if filtercmd(ui, f, name, doc):
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 continue
doc = gettext(doc)
if not doc:
doc = _("(no help text available)")
h[f] = doc.splitlines()[0].rstrip()
cmds[f] = c.lstrip("^")
rst = []
if not h:
if not ui.quiet:
rst.append(_('no commands defined\n'))
return rst
if not ui.quiet:
rst.append(header)
fns = sorted(h)
for f in fns:
if ui.verbose:
commacmds = cmds[f].replace("|",", ")
rst.append(" :%s: %s\n" % (commacmds, h[f]))
else:
rst.append(' :%s: %s\n' % (f, h[f]))
timeless
help: fix help -c/help -e/help -k...
r27325 ex = opts.get
anyopts = (ex('keyword') or not (ex('command') or ex('extension')))
if not name and anyopts:
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 exts = listexts(_('enabled extensions:'), extensions.enabled())
if exts:
rst.append('\n')
rst.extend(exts)
rst.append(_("\nadditional help topics:\n\n"))
topics = []
for names, header, doc in helptable:
topics.append((names[0], header))
for t, desc in topics:
rst.append(" :%s: %s\n" % (t, desc))
Matt Mackall
help: refactor helplist optlist mess...
r22115 if ui.quiet:
pass
elif ui.verbose:
Matt Mackall
help: roll option list header into option formatter
r22116 rst.append('\n%s\n' % optrst(_("global options"),
commands.globalopts, ui.verbose))
Matt Mackall
help: refactor helplist optlist mess...
r22115 if name == 'shortlist':
timeless
help: use single quotes in use warning
r29974 rst.append(_("\n(use 'hg help' for the full list "
"of commands)\n"))
Matt Mackall
help: refactor helplist optlist mess...
r22115 else:
if name == 'shortlist':
timeless
help: use single quotes in use warning
r29974 rst.append(_("\n(use 'hg help' for the full list of commands "
"or 'hg -v' for details)\n"))
Matt Mackall
help: refactor helplist optlist mess...
r22115 elif name and not full:
timeless
help: use single quotes in use warning
r29974 rst.append(_("\n(use 'hg help %s' to show the full help "
"text)\n") % name)
Chingis Dugarzhapov
help: suggest '-v -e' to get built-in aliases for extensions (issue4461)...
r23624 elif name and cmds and name in cmds.keys():
timeless
help: use single quotes in use warning
r29974 rst.append(_("\n(use 'hg help -v -e %s' to show built-in "
"aliases and global options)\n") % name)
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 else:
timeless
help: use single quotes in use warning
r29974 rst.append(_("\n(use 'hg help -v%s' to show built-in aliases "
"and global options)\n")
Matt Mackall
help: normalize helplist hints
r22118 % (name and " " + name or ""))
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 return rst
Gregory Szorc
help: pass sub-topic into help query functions...
r27378 def helptopic(name, subtopic=None):
Gregory Szorc
help: support loading sub-topics...
r27379 # Look for sub-topic entry first.
header, doc = None, None
if subtopic and name in subtopics:
for names, header, doc in subtopics[name]:
if subtopic in names:
break
if not header:
for names, header, doc in helptable:
if name in names:
break
else:
raise error.UnknownCommand(name)
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746
Dan Villiom Podlaski Christiansen
help: use a full header for topic titles...
r18748 rst = [minirst.section(header)]
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 # description
if not doc:
rst.append(" %s\n" % _("(no help text available)"))
Augie Fackler
help: restore use of callable() since it was readded in Python 3.2
r21796 if callable(doc):
Yuya Nishihara
help: pass around ui to doc loader (API)...
r26413 rst += [" %s\n" % l for l in doc(ui).splitlines()]
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746
if not ui.verbose:
Matt Mackall
help: normalize topic and extension verbose hints
r22114 omitted = _('(some details hidden, use --verbose'
' to show complete help)')
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 indicateomitted(rst, omitted)
try:
cmdutil.findcmd(name, commands.table)
timeless
help: use single quotes in use warning
r29974 rst.append(_("\nuse 'hg help -c %s' to see help for "
"the %s command\n") % (name, name))
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 except error.UnknownCommand:
pass
return rst
Gregory Szorc
help: pass sub-topic into help query functions...
r27378 def helpext(name, subtopic=None):
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 try:
mod = extensions.find(name)
doc = gettext(mod.__doc__) or _('no help text available')
except KeyError:
mod = None
doc = extensions.disabledext(name)
if not doc:
raise error.UnknownCommand(name)
if '\n' not in doc:
head, tail = doc, ""
else:
head, tail = doc.split('\n', 1)
av6
help: replace some str.split() calls by str.partition() or str.rpartition()...
r26845 rst = [_('%s extension - %s\n\n') % (name.rpartition('.')[-1], head)]
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 if tail:
rst.extend(tail.splitlines(True))
rst.append('\n')
if not ui.verbose:
Matt Mackall
help: normalize topic and extension verbose hints
r22114 omitted = _('(some details hidden, use --verbose'
' to show complete help)')
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 indicateomitted(rst, omitted)
if mod:
try:
ct = mod.cmdtable
except AttributeError:
ct = {}
av6
help: replace some str.split() calls by str.partition() or str.rpartition()...
r26845 modcmds = set([c.partition('|')[0] for c in ct])
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 rst.extend(helplist(modcmds.__contains__))
else:
timeless
help: use single quotes in use warning
r29974 rst.append(_("(use 'hg help extensions' for information on enabling"
" extensions)\n"))
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 return rst
Gregory Szorc
help: pass sub-topic into help query functions...
r27378 def helpextcmd(name, subtopic=None):
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 cmd, ext, mod = extensions.disabledcmd(ui, name,
ui.configbool('ui', 'strict'))
doc = gettext(mod.__doc__).splitlines()[0]
rst = listexts(_("'%s' is provided by the following "
timeless
help: make help deprecated mention the extension...
r27152 "extension:") % cmd, {ext: doc}, indent=4,
showdeprecated=True)
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 rst.append('\n')
timeless
help: use single quotes in use warning
r29974 rst.append(_("(use 'hg help extensions' for information on enabling "
"extensions)\n"))
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 return rst
rst = []
kw = opts.get('keyword')
timeless
help: fix help -c/help -e/help -k...
r27325 if kw or name is None and any(opts[o] for o in opts):
matches = topicmatch(ui, name or '')
timeless@mozdev.org
help: fix help argument parsing and documentation...
r26238 helpareas = []
if opts.get('extension'):
helpareas += [('extensions', _('Extensions'))]
if opts.get('command'):
helpareas += [('commands', _('Commands'))]
if not helpareas:
helpareas = [('topics', _('Topics')),
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 ('commands', _('Commands')),
('extensions', _('Extensions')),
timeless@mozdev.org
help: fix help argument parsing and documentation...
r26238 ('extensioncommands', _('Extension Commands'))]
for t, title in helpareas:
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 if matches[t]:
rst.append('%s:\n\n' % title)
rst.extend(minirst.maketable(sorted(matches[t]), 1))
rst.append('\n')
Pierre-Yves David
help: provide a more helpful message when no keyword are matched...
r21288 if not rst:
msg = _('no matches')
timeless
help: use single quotes in use warning
r29974 hint = _("try 'hg help' for a list of topics")
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(msg, hint=hint)
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 elif name and name != 'shortlist':
timeless@mozdev.org
help: fix help argument parsing and documentation...
r26238 queries = []
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 if unknowncmd:
timeless@mozdev.org
help: fix help argument parsing and documentation...
r26238 queries += [helpextcmd]
if opts.get('extension'):
queries += [helpext]
if opts.get('command'):
queries += [helpcmd]
if not queries:
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 queries = (helptopic, helpcmd, helpext, helpextcmd)
for f in queries:
try:
Gregory Szorc
help: pass sub-topic into help query functions...
r27378 rst = f(name, subtopic)
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 break
Pierre-Yves David
help: suggest keyword search when no topic is found...
r21289 except error.UnknownCommand:
pass
else:
if unknowncmd:
raise error.UnknownCommand(name)
else:
msg = _('no such help topic: %s') % name
timeless
help: use single quotes in use warning
r29974 hint = _("try 'hg help --keyword %s'") % name
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(msg, hint=hint)
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746 else:
# program name
if not ui.quiet:
rst = [_("Mercurial Distributed SCM\n"), '\n']
timeless
help: fix help -c/help -e/help -k...
r27325 rst.extend(helplist(None, **opts))
Dan Villiom Podlaski Christiansen
help: move the majority of the help command to the help module...
r18746
return ''.join(rst)
Augie Fackler
help: move rst formatting of help documents into help.py...
r31059
def formattedhelp(ui, name, keep=None, unknowncmd=False, full=True, **opts):
"""get help for a given topic (as a dotted name) as rendered rst
Either returns the rendered help text or raises an exception.
"""
if keep is None:
keep = []
Augie Fackler
help: avoid mutating passed-in `keep` list in `formattedhelp`
r31265 else:
keep = list(keep) # make a copy so we can mutate this later
Augie Fackler
help: move rst formatting of help documents into help.py...
r31059 fullname = name
section = None
subtopic = None
if name and '.' in name:
name, remaining = name.split('.', 1)
remaining = encoding.lower(remaining)
if '.' in remaining:
subtopic, section = remaining.split('.', 1)
else:
if name in subtopics:
subtopic = remaining
else:
section = remaining
textwidth = ui.configint('ui', 'textwidth', 78)
termwidth = ui.termwidth() - 2
if textwidth <= 0 or termwidth < textwidth:
textwidth = termwidth
text = help_(ui, name,
subtopic=subtopic, unknowncmd=unknowncmd, full=full, **opts)
formatted, pruned = minirst.format(text, textwidth, keep=keep,
section=section)
# We could have been given a weird ".foo" section without a name
# to look for, or we could have simply failed to found "foo.bar"
# because bar isn't a section of foo
if section and not (formatted and name):
raise error.Abort(_("help section not found: %s") % fullname)
if 'verbose' in pruned:
keep.append('omitted')
else:
keep.append('notomitted')
formatted, pruned = minirst.format(text, textwidth, keep=keep,
section=section)
return formatted