##// END OF EJS Templates
help: define list of keywords that should be excluded from non-verbose output...
Yuya Nishihara -
r26369:4799b5c4 default
parent child Browse files
Show More
@@ -1,527 +1,532 b''
1 # help.py - help data for mercurial
1 # help.py - help data for mercurial
2 #
2 #
3 # Copyright 2006 Matt Mackall <mpm@selenic.com>
3 # Copyright 2006 Matt Mackall <mpm@selenic.com>
4 #
4 #
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 i18n import gettext, _
8 from i18n import gettext, _
9 import itertools, os, textwrap
9 import itertools, os, textwrap
10 import error
10 import error
11 import extensions, revset, fileset, templatekw, templatefilters, filemerge
11 import extensions, revset, fileset, templatekw, templatefilters, filemerge
12 import templater
12 import templater
13 import encoding, util, minirst
13 import encoding, util, minirst
14 import cmdutil
14 import cmdutil
15 import hgweb.webcommands as webcommands
15 import hgweb.webcommands as webcommands
16
16
17 _exclkeywords = [
18 "DEPRECATED",
19 "EXPERIMENTAL",
20 _("DEPRECATED"),
21 _("EXPERIMENTAL"),
22 ]
23
17 def listexts(header, exts, indent=1, showdeprecated=False):
24 def listexts(header, exts, indent=1, showdeprecated=False):
18 '''return a text listing of the given extensions'''
25 '''return a text listing of the given extensions'''
19 rst = []
26 rst = []
20 if exts:
27 if exts:
21 rst.append('\n%s\n\n' % header)
28 rst.append('\n%s\n\n' % header)
22 for name, desc in sorted(exts.iteritems()):
29 for name, desc in sorted(exts.iteritems()):
23 if '(DEPRECATED)' in desc and not showdeprecated:
30 if '(DEPRECATED)' in desc and not showdeprecated:
24 continue
31 continue
25 rst.append('%s:%s: %s\n' % (' ' * indent, name, desc))
32 rst.append('%s:%s: %s\n' % (' ' * indent, name, desc))
26 return rst
33 return rst
27
34
28 def extshelp():
35 def extshelp():
29 rst = loaddoc('extensions')().splitlines(True)
36 rst = loaddoc('extensions')().splitlines(True)
30 rst.extend(listexts(
37 rst.extend(listexts(
31 _('enabled extensions:'), extensions.enabled(), showdeprecated=True))
38 _('enabled extensions:'), extensions.enabled(), showdeprecated=True))
32 rst.extend(listexts(_('disabled extensions:'), extensions.disabled()))
39 rst.extend(listexts(_('disabled extensions:'), extensions.disabled()))
33 doc = ''.join(rst)
40 doc = ''.join(rst)
34 return doc
41 return doc
35
42
36 def optrst(header, options, verbose):
43 def optrst(header, options, verbose):
37 data = []
44 data = []
38 multioccur = False
45 multioccur = False
39 for option in options:
46 for option in options:
40 if len(option) == 5:
47 if len(option) == 5:
41 shortopt, longopt, default, desc, optlabel = option
48 shortopt, longopt, default, desc, optlabel = option
42 else:
49 else:
43 shortopt, longopt, default, desc = option
50 shortopt, longopt, default, desc = option
44 optlabel = _("VALUE") # default label
51 optlabel = _("VALUE") # default label
45
52
46 if not verbose and ("DEPRECATED" in desc or _("DEPRECATED") in desc or
53 if not verbose and any(w in desc for w in _exclkeywords):
47 "EXPERIMENTAL" in desc or
48 _("EXPERIMENTAL") in desc):
49 continue
54 continue
50
55
51 so = ''
56 so = ''
52 if shortopt:
57 if shortopt:
53 so = '-' + shortopt
58 so = '-' + shortopt
54 lo = '--' + longopt
59 lo = '--' + longopt
55 if default:
60 if default:
56 desc += _(" (default: %s)") % default
61 desc += _(" (default: %s)") % default
57
62
58 if isinstance(default, list):
63 if isinstance(default, list):
59 lo += " %s [+]" % optlabel
64 lo += " %s [+]" % optlabel
60 multioccur = True
65 multioccur = True
61 elif (default is not None) and not isinstance(default, bool):
66 elif (default is not None) and not isinstance(default, bool):
62 lo += " %s" % optlabel
67 lo += " %s" % optlabel
63
68
64 data.append((so, lo, desc))
69 data.append((so, lo, desc))
65
70
66 if multioccur:
71 if multioccur:
67 header += (_(" ([+] can be repeated)"))
72 header += (_(" ([+] can be repeated)"))
68
73
69 rst = ['\n%s:\n\n' % header]
74 rst = ['\n%s:\n\n' % header]
70 rst.extend(minirst.maketable(data, 1))
75 rst.extend(minirst.maketable(data, 1))
71
76
72 return ''.join(rst)
77 return ''.join(rst)
73
78
74 def indicateomitted(rst, omitted, notomitted=None):
79 def indicateomitted(rst, omitted, notomitted=None):
75 rst.append('\n\n.. container:: omitted\n\n %s\n\n' % omitted)
80 rst.append('\n\n.. container:: omitted\n\n %s\n\n' % omitted)
76 if notomitted:
81 if notomitted:
77 rst.append('\n\n.. container:: notomitted\n\n %s\n\n' % notomitted)
82 rst.append('\n\n.. container:: notomitted\n\n %s\n\n' % notomitted)
78
83
79 def topicmatch(kw):
84 def topicmatch(kw):
80 """Return help topics matching kw.
85 """Return help topics matching kw.
81
86
82 Returns {'section': [(name, summary), ...], ...} where section is
87 Returns {'section': [(name, summary), ...], ...} where section is
83 one of topics, commands, extensions, or extensioncommands.
88 one of topics, commands, extensions, or extensioncommands.
84 """
89 """
85 kw = encoding.lower(kw)
90 kw = encoding.lower(kw)
86 def lowercontains(container):
91 def lowercontains(container):
87 return kw in encoding.lower(container) # translated in helptable
92 return kw in encoding.lower(container) # translated in helptable
88 results = {'topics': [],
93 results = {'topics': [],
89 'commands': [],
94 'commands': [],
90 'extensions': [],
95 'extensions': [],
91 'extensioncommands': [],
96 'extensioncommands': [],
92 }
97 }
93 for names, header, doc in helptable:
98 for names, header, doc in helptable:
94 # Old extensions may use a str as doc.
99 # Old extensions may use a str as doc.
95 if (sum(map(lowercontains, names))
100 if (sum(map(lowercontains, names))
96 or lowercontains(header)
101 or lowercontains(header)
97 or (callable(doc) and lowercontains(doc()))):
102 or (callable(doc) and lowercontains(doc()))):
98 results['topics'].append((names[0], header))
103 results['topics'].append((names[0], header))
99 import commands # avoid cycle
104 import commands # avoid cycle
100 for cmd, entry in commands.table.iteritems():
105 for cmd, entry in commands.table.iteritems():
101 if len(entry) == 3:
106 if len(entry) == 3:
102 summary = entry[2]
107 summary = entry[2]
103 else:
108 else:
104 summary = ''
109 summary = ''
105 # translate docs *before* searching there
110 # translate docs *before* searching there
106 docs = _(getattr(entry[0], '__doc__', None)) or ''
111 docs = _(getattr(entry[0], '__doc__', None)) or ''
107 if kw in cmd or lowercontains(summary) or lowercontains(docs):
112 if kw in cmd or lowercontains(summary) or lowercontains(docs):
108 doclines = docs.splitlines()
113 doclines = docs.splitlines()
109 if doclines:
114 if doclines:
110 summary = doclines[0]
115 summary = doclines[0]
111 cmdname = cmd.split('|')[0].lstrip('^')
116 cmdname = cmd.split('|')[0].lstrip('^')
112 results['commands'].append((cmdname, summary))
117 results['commands'].append((cmdname, summary))
113 for name, docs in itertools.chain(
118 for name, docs in itertools.chain(
114 extensions.enabled(False).iteritems(),
119 extensions.enabled(False).iteritems(),
115 extensions.disabled().iteritems()):
120 extensions.disabled().iteritems()):
116 # extensions.load ignores the UI argument
121 # extensions.load ignores the UI argument
117 mod = extensions.load(None, name, '')
122 mod = extensions.load(None, name, '')
118 name = name.split('.')[-1]
123 name = name.split('.')[-1]
119 if lowercontains(name) or lowercontains(docs):
124 if lowercontains(name) or lowercontains(docs):
120 # extension docs are already translated
125 # extension docs are already translated
121 results['extensions'].append((name, docs.splitlines()[0]))
126 results['extensions'].append((name, docs.splitlines()[0]))
122 for cmd, entry in getattr(mod, 'cmdtable', {}).iteritems():
127 for cmd, entry in getattr(mod, 'cmdtable', {}).iteritems():
123 if kw in cmd or (len(entry) > 2 and lowercontains(entry[2])):
128 if kw in cmd or (len(entry) > 2 and lowercontains(entry[2])):
124 cmdname = cmd.split('|')[0].lstrip('^')
129 cmdname = cmd.split('|')[0].lstrip('^')
125 if entry[0].__doc__:
130 if entry[0].__doc__:
126 cmddoc = gettext(entry[0].__doc__).splitlines()[0]
131 cmddoc = gettext(entry[0].__doc__).splitlines()[0]
127 else:
132 else:
128 cmddoc = _('(no help text available)')
133 cmddoc = _('(no help text available)')
129 results['extensioncommands'].append((cmdname, cmddoc))
134 results['extensioncommands'].append((cmdname, cmddoc))
130 return results
135 return results
131
136
132 def loaddoc(topic):
137 def loaddoc(topic):
133 """Return a delayed loader for help/topic.txt."""
138 """Return a delayed loader for help/topic.txt."""
134
139
135 def loader():
140 def loader():
136 docdir = os.path.join(util.datapath, 'help')
141 docdir = os.path.join(util.datapath, 'help')
137 path = os.path.join(docdir, topic + ".txt")
142 path = os.path.join(docdir, topic + ".txt")
138 doc = gettext(util.readfile(path))
143 doc = gettext(util.readfile(path))
139 for rewriter in helphooks.get(topic, []):
144 for rewriter in helphooks.get(topic, []):
140 doc = rewriter(topic, doc)
145 doc = rewriter(topic, doc)
141 return doc
146 return doc
142
147
143 return loader
148 return loader
144
149
145 helptable = sorted([
150 helptable = sorted([
146 (["config", "hgrc"], _("Configuration Files"), loaddoc('config')),
151 (["config", "hgrc"], _("Configuration Files"), loaddoc('config')),
147 (["dates"], _("Date Formats"), loaddoc('dates')),
152 (["dates"], _("Date Formats"), loaddoc('dates')),
148 (["patterns"], _("File Name Patterns"), loaddoc('patterns')),
153 (["patterns"], _("File Name Patterns"), loaddoc('patterns')),
149 (['environment', 'env'], _('Environment Variables'),
154 (['environment', 'env'], _('Environment Variables'),
150 loaddoc('environment')),
155 loaddoc('environment')),
151 (['revisions', 'revs'], _('Specifying Single Revisions'),
156 (['revisions', 'revs'], _('Specifying Single Revisions'),
152 loaddoc('revisions')),
157 loaddoc('revisions')),
153 (['multirevs', 'mrevs'], _('Specifying Multiple Revisions'),
158 (['multirevs', 'mrevs'], _('Specifying Multiple Revisions'),
154 loaddoc('multirevs')),
159 loaddoc('multirevs')),
155 (['revsets', 'revset'], _("Specifying Revision Sets"), loaddoc('revsets')),
160 (['revsets', 'revset'], _("Specifying Revision Sets"), loaddoc('revsets')),
156 (['filesets', 'fileset'], _("Specifying File Sets"), loaddoc('filesets')),
161 (['filesets', 'fileset'], _("Specifying File Sets"), loaddoc('filesets')),
157 (['diffs'], _('Diff Formats'), loaddoc('diffs')),
162 (['diffs'], _('Diff Formats'), loaddoc('diffs')),
158 (['merge-tools', 'mergetools'], _('Merge Tools'), loaddoc('merge-tools')),
163 (['merge-tools', 'mergetools'], _('Merge Tools'), loaddoc('merge-tools')),
159 (['templating', 'templates', 'template', 'style'], _('Template Usage'),
164 (['templating', 'templates', 'template', 'style'], _('Template Usage'),
160 loaddoc('templates')),
165 loaddoc('templates')),
161 (['urls'], _('URL Paths'), loaddoc('urls')),
166 (['urls'], _('URL Paths'), loaddoc('urls')),
162 (["extensions"], _("Using Additional Features"), extshelp),
167 (["extensions"], _("Using Additional Features"), extshelp),
163 (["subrepos", "subrepo"], _("Subrepositories"), loaddoc('subrepos')),
168 (["subrepos", "subrepo"], _("Subrepositories"), loaddoc('subrepos')),
164 (["hgweb"], _("Configuring hgweb"), loaddoc('hgweb')),
169 (["hgweb"], _("Configuring hgweb"), loaddoc('hgweb')),
165 (["glossary"], _("Glossary"), loaddoc('glossary')),
170 (["glossary"], _("Glossary"), loaddoc('glossary')),
166 (["hgignore", "ignore"], _("Syntax for Mercurial Ignore Files"),
171 (["hgignore", "ignore"], _("Syntax for Mercurial Ignore Files"),
167 loaddoc('hgignore')),
172 loaddoc('hgignore')),
168 (["phases"], _("Working with Phases"), loaddoc('phases')),
173 (["phases"], _("Working with Phases"), loaddoc('phases')),
169 (['scripting'], _('Using Mercurial from scripts and automation'),
174 (['scripting'], _('Using Mercurial from scripts and automation'),
170 loaddoc('scripting')),
175 loaddoc('scripting')),
171 ])
176 ])
172
177
173 # Map topics to lists of callable taking the current topic help and
178 # Map topics to lists of callable taking the current topic help and
174 # returning the updated version
179 # returning the updated version
175 helphooks = {}
180 helphooks = {}
176
181
177 def addtopichook(topic, rewriter):
182 def addtopichook(topic, rewriter):
178 helphooks.setdefault(topic, []).append(rewriter)
183 helphooks.setdefault(topic, []).append(rewriter)
179
184
180 def makeitemsdoc(topic, doc, marker, items, dedent=False):
185 def makeitemsdoc(topic, doc, marker, items, dedent=False):
181 """Extract docstring from the items key to function mapping, build a
186 """Extract docstring from the items key to function mapping, build a
182 single documentation block and use it to overwrite the marker in doc.
187 single documentation block and use it to overwrite the marker in doc.
183 """
188 """
184 entries = []
189 entries = []
185 for name in sorted(items):
190 for name in sorted(items):
186 text = (items[name].__doc__ or '').rstrip()
191 text = (items[name].__doc__ or '').rstrip()
187 if not text:
192 if not text:
188 continue
193 continue
189 text = gettext(text)
194 text = gettext(text)
190 if dedent:
195 if dedent:
191 text = textwrap.dedent(text)
196 text = textwrap.dedent(text)
192 lines = text.splitlines()
197 lines = text.splitlines()
193 doclines = [(lines[0])]
198 doclines = [(lines[0])]
194 for l in lines[1:]:
199 for l in lines[1:]:
195 # Stop once we find some Python doctest
200 # Stop once we find some Python doctest
196 if l.strip().startswith('>>>'):
201 if l.strip().startswith('>>>'):
197 break
202 break
198 if dedent:
203 if dedent:
199 doclines.append(l.rstrip())
204 doclines.append(l.rstrip())
200 else:
205 else:
201 doclines.append(' ' + l.strip())
206 doclines.append(' ' + l.strip())
202 entries.append('\n'.join(doclines))
207 entries.append('\n'.join(doclines))
203 entries = '\n\n'.join(entries)
208 entries = '\n\n'.join(entries)
204 return doc.replace(marker, entries)
209 return doc.replace(marker, entries)
205
210
206 def addtopicsymbols(topic, marker, symbols, dedent=False):
211 def addtopicsymbols(topic, marker, symbols, dedent=False):
207 def add(topic, doc):
212 def add(topic, doc):
208 return makeitemsdoc(topic, doc, marker, symbols, dedent=dedent)
213 return makeitemsdoc(topic, doc, marker, symbols, dedent=dedent)
209 addtopichook(topic, add)
214 addtopichook(topic, add)
210
215
211 addtopicsymbols('filesets', '.. predicatesmarker', fileset.symbols)
216 addtopicsymbols('filesets', '.. predicatesmarker', fileset.symbols)
212 addtopicsymbols('merge-tools', '.. internaltoolsmarker',
217 addtopicsymbols('merge-tools', '.. internaltoolsmarker',
213 filemerge.internalsdoc)
218 filemerge.internalsdoc)
214 addtopicsymbols('revsets', '.. predicatesmarker', revset.symbols)
219 addtopicsymbols('revsets', '.. predicatesmarker', revset.symbols)
215 addtopicsymbols('templates', '.. keywordsmarker', templatekw.dockeywords)
220 addtopicsymbols('templates', '.. keywordsmarker', templatekw.dockeywords)
216 addtopicsymbols('templates', '.. filtersmarker', templatefilters.filters)
221 addtopicsymbols('templates', '.. filtersmarker', templatefilters.filters)
217 addtopicsymbols('templates', '.. functionsmarker', templater.funcs)
222 addtopicsymbols('templates', '.. functionsmarker', templater.funcs)
218 addtopicsymbols('hgweb', '.. webcommandsmarker', webcommands.commands,
223 addtopicsymbols('hgweb', '.. webcommandsmarker', webcommands.commands,
219 dedent=True)
224 dedent=True)
220
225
221 def help_(ui, name, unknowncmd=False, full=True, **opts):
226 def help_(ui, name, unknowncmd=False, full=True, **opts):
222 '''
227 '''
223 Generate the help for 'name' as unformatted restructured text. If
228 Generate the help for 'name' as unformatted restructured text. If
224 'name' is None, describe the commands available.
229 'name' is None, describe the commands available.
225 '''
230 '''
226
231
227 import commands # avoid cycle
232 import commands # avoid cycle
228
233
229 def helpcmd(name):
234 def helpcmd(name):
230 try:
235 try:
231 aliases, entry = cmdutil.findcmd(name, commands.table,
236 aliases, entry = cmdutil.findcmd(name, commands.table,
232 strict=unknowncmd)
237 strict=unknowncmd)
233 except error.AmbiguousCommand as inst:
238 except error.AmbiguousCommand as inst:
234 # py3k fix: except vars can't be used outside the scope of the
239 # py3k fix: except vars can't be used outside the scope of the
235 # except block, nor can be used inside a lambda. python issue4617
240 # except block, nor can be used inside a lambda. python issue4617
236 prefix = inst.args[0]
241 prefix = inst.args[0]
237 select = lambda c: c.lstrip('^').startswith(prefix)
242 select = lambda c: c.lstrip('^').startswith(prefix)
238 rst = helplist(select)
243 rst = helplist(select)
239 return rst
244 return rst
240
245
241 rst = []
246 rst = []
242
247
243 # check if it's an invalid alias and display its error if it is
248 # check if it's an invalid alias and display its error if it is
244 if getattr(entry[0], 'badalias', None):
249 if getattr(entry[0], 'badalias', None):
245 rst.append(entry[0].badalias + '\n')
250 rst.append(entry[0].badalias + '\n')
246 if entry[0].unknowncmd:
251 if entry[0].unknowncmd:
247 try:
252 try:
248 rst.extend(helpextcmd(entry[0].cmdname))
253 rst.extend(helpextcmd(entry[0].cmdname))
249 except error.UnknownCommand:
254 except error.UnknownCommand:
250 pass
255 pass
251 return rst
256 return rst
252
257
253 # synopsis
258 # synopsis
254 if len(entry) > 2:
259 if len(entry) > 2:
255 if entry[2].startswith('hg'):
260 if entry[2].startswith('hg'):
256 rst.append("%s\n" % entry[2])
261 rst.append("%s\n" % entry[2])
257 else:
262 else:
258 rst.append('hg %s %s\n' % (aliases[0], entry[2]))
263 rst.append('hg %s %s\n' % (aliases[0], entry[2]))
259 else:
264 else:
260 rst.append('hg %s\n' % aliases[0])
265 rst.append('hg %s\n' % aliases[0])
261 # aliases
266 # aliases
262 if full and not ui.quiet and len(aliases) > 1:
267 if full and not ui.quiet and len(aliases) > 1:
263 rst.append(_("\naliases: %s\n") % ', '.join(aliases[1:]))
268 rst.append(_("\naliases: %s\n") % ', '.join(aliases[1:]))
264 rst.append('\n')
269 rst.append('\n')
265
270
266 # description
271 # description
267 doc = gettext(entry[0].__doc__)
272 doc = gettext(entry[0].__doc__)
268 if not doc:
273 if not doc:
269 doc = _("(no help text available)")
274 doc = _("(no help text available)")
270 if util.safehasattr(entry[0], 'definition'): # aliased command
275 if util.safehasattr(entry[0], 'definition'): # aliased command
271 if entry[0].definition.startswith('!'): # shell alias
276 if entry[0].definition.startswith('!'): # shell alias
272 doc = _('shell alias for::\n\n %s') % entry[0].definition[1:]
277 doc = _('shell alias for::\n\n %s') % entry[0].definition[1:]
273 else:
278 else:
274 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
279 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
275 doc = doc.splitlines(True)
280 doc = doc.splitlines(True)
276 if ui.quiet or not full:
281 if ui.quiet or not full:
277 rst.append(doc[0])
282 rst.append(doc[0])
278 else:
283 else:
279 rst.extend(doc)
284 rst.extend(doc)
280 rst.append('\n')
285 rst.append('\n')
281
286
282 # check if this command shadows a non-trivial (multi-line)
287 # check if this command shadows a non-trivial (multi-line)
283 # extension help text
288 # extension help text
284 try:
289 try:
285 mod = extensions.find(name)
290 mod = extensions.find(name)
286 doc = gettext(mod.__doc__) or ''
291 doc = gettext(mod.__doc__) or ''
287 if '\n' in doc.strip():
292 if '\n' in doc.strip():
288 msg = _('(use "hg help -e %s" to show help for '
293 msg = _('(use "hg help -e %s" to show help for '
289 'the %s extension)') % (name, name)
294 'the %s extension)') % (name, name)
290 rst.append('\n%s\n' % msg)
295 rst.append('\n%s\n' % msg)
291 except KeyError:
296 except KeyError:
292 pass
297 pass
293
298
294 # options
299 # options
295 if not ui.quiet and entry[1]:
300 if not ui.quiet and entry[1]:
296 rst.append(optrst(_("options"), entry[1], ui.verbose))
301 rst.append(optrst(_("options"), entry[1], ui.verbose))
297
302
298 if ui.verbose:
303 if ui.verbose:
299 rst.append(optrst(_("global options"),
304 rst.append(optrst(_("global options"),
300 commands.globalopts, ui.verbose))
305 commands.globalopts, ui.verbose))
301
306
302 if not ui.verbose:
307 if not ui.verbose:
303 if not full:
308 if not full:
304 rst.append(_('\n(use "hg %s -h" to show more help)\n')
309 rst.append(_('\n(use "hg %s -h" to show more help)\n')
305 % name)
310 % name)
306 elif not ui.quiet:
311 elif not ui.quiet:
307 rst.append(_('\n(some details hidden, use --verbose '
312 rst.append(_('\n(some details hidden, use --verbose '
308 'to show complete help)'))
313 'to show complete help)'))
309
314
310 return rst
315 return rst
311
316
312
317
313 def helplist(select=None):
318 def helplist(select=None):
314 # list of commands
319 # list of commands
315 if name == "shortlist":
320 if name == "shortlist":
316 header = _('basic commands:\n\n')
321 header = _('basic commands:\n\n')
317 elif name == "debug":
322 elif name == "debug":
318 header = _('debug commands (internal and unsupported):\n\n')
323 header = _('debug commands (internal and unsupported):\n\n')
319 else:
324 else:
320 header = _('list of commands:\n\n')
325 header = _('list of commands:\n\n')
321
326
322 h = {}
327 h = {}
323 cmds = {}
328 cmds = {}
324 for c, e in commands.table.iteritems():
329 for c, e in commands.table.iteritems():
325 f = c.split("|", 1)[0]
330 f = c.split("|", 1)[0]
326 if select and not select(f):
331 if select and not select(f):
327 continue
332 continue
328 if (not select and name != 'shortlist' and
333 if (not select and name != 'shortlist' and
329 e[0].__module__ != commands.__name__):
334 e[0].__module__ != commands.__name__):
330 continue
335 continue
331 if name == "shortlist" and not f.startswith("^"):
336 if name == "shortlist" and not f.startswith("^"):
332 continue
337 continue
333 f = f.lstrip("^")
338 f = f.lstrip("^")
334 if not ui.debugflag and f.startswith("debug") and name != "debug":
339 if not ui.debugflag and f.startswith("debug") and name != "debug":
335 continue
340 continue
336 doc = e[0].__doc__
341 doc = e[0].__doc__
337 if doc and 'DEPRECATED' in doc and not ui.verbose:
342 if doc and 'DEPRECATED' in doc and not ui.verbose:
338 continue
343 continue
339 doc = gettext(doc)
344 doc = gettext(doc)
340 if not doc:
345 if not doc:
341 doc = _("(no help text available)")
346 doc = _("(no help text available)")
342 h[f] = doc.splitlines()[0].rstrip()
347 h[f] = doc.splitlines()[0].rstrip()
343 cmds[f] = c.lstrip("^")
348 cmds[f] = c.lstrip("^")
344
349
345 rst = []
350 rst = []
346 if not h:
351 if not h:
347 if not ui.quiet:
352 if not ui.quiet:
348 rst.append(_('no commands defined\n'))
353 rst.append(_('no commands defined\n'))
349 return rst
354 return rst
350
355
351 if not ui.quiet:
356 if not ui.quiet:
352 rst.append(header)
357 rst.append(header)
353 fns = sorted(h)
358 fns = sorted(h)
354 for f in fns:
359 for f in fns:
355 if ui.verbose:
360 if ui.verbose:
356 commacmds = cmds[f].replace("|",", ")
361 commacmds = cmds[f].replace("|",", ")
357 rst.append(" :%s: %s\n" % (commacmds, h[f]))
362 rst.append(" :%s: %s\n" % (commacmds, h[f]))
358 else:
363 else:
359 rst.append(' :%s: %s\n' % (f, h[f]))
364 rst.append(' :%s: %s\n' % (f, h[f]))
360
365
361 if not name:
366 if not name:
362 exts = listexts(_('enabled extensions:'), extensions.enabled())
367 exts = listexts(_('enabled extensions:'), extensions.enabled())
363 if exts:
368 if exts:
364 rst.append('\n')
369 rst.append('\n')
365 rst.extend(exts)
370 rst.extend(exts)
366
371
367 rst.append(_("\nadditional help topics:\n\n"))
372 rst.append(_("\nadditional help topics:\n\n"))
368 topics = []
373 topics = []
369 for names, header, doc in helptable:
374 for names, header, doc in helptable:
370 topics.append((names[0], header))
375 topics.append((names[0], header))
371 for t, desc in topics:
376 for t, desc in topics:
372 rst.append(" :%s: %s\n" % (t, desc))
377 rst.append(" :%s: %s\n" % (t, desc))
373
378
374 if ui.quiet:
379 if ui.quiet:
375 pass
380 pass
376 elif ui.verbose:
381 elif ui.verbose:
377 rst.append('\n%s\n' % optrst(_("global options"),
382 rst.append('\n%s\n' % optrst(_("global options"),
378 commands.globalopts, ui.verbose))
383 commands.globalopts, ui.verbose))
379 if name == 'shortlist':
384 if name == 'shortlist':
380 rst.append(_('\n(use "hg help" for the full list '
385 rst.append(_('\n(use "hg help" for the full list '
381 'of commands)\n'))
386 'of commands)\n'))
382 else:
387 else:
383 if name == 'shortlist':
388 if name == 'shortlist':
384 rst.append(_('\n(use "hg help" for the full list of commands '
389 rst.append(_('\n(use "hg help" for the full list of commands '
385 'or "hg -v" for details)\n'))
390 'or "hg -v" for details)\n'))
386 elif name and not full:
391 elif name and not full:
387 rst.append(_('\n(use "hg help %s" to show the full help '
392 rst.append(_('\n(use "hg help %s" to show the full help '
388 'text)\n') % name)
393 'text)\n') % name)
389 elif name and cmds and name in cmds.keys():
394 elif name and cmds and name in cmds.keys():
390 rst.append(_('\n(use "hg help -v -e %s" to show built-in '
395 rst.append(_('\n(use "hg help -v -e %s" to show built-in '
391 'aliases and global options)\n') % name)
396 'aliases and global options)\n') % name)
392 else:
397 else:
393 rst.append(_('\n(use "hg help -v%s" to show built-in aliases '
398 rst.append(_('\n(use "hg help -v%s" to show built-in aliases '
394 'and global options)\n')
399 'and global options)\n')
395 % (name and " " + name or ""))
400 % (name and " " + name or ""))
396 return rst
401 return rst
397
402
398 def helptopic(name):
403 def helptopic(name):
399 for names, header, doc in helptable:
404 for names, header, doc in helptable:
400 if name in names:
405 if name in names:
401 break
406 break
402 else:
407 else:
403 raise error.UnknownCommand(name)
408 raise error.UnknownCommand(name)
404
409
405 rst = [minirst.section(header)]
410 rst = [minirst.section(header)]
406
411
407 # description
412 # description
408 if not doc:
413 if not doc:
409 rst.append(" %s\n" % _("(no help text available)"))
414 rst.append(" %s\n" % _("(no help text available)"))
410 if callable(doc):
415 if callable(doc):
411 rst += [" %s\n" % l for l in doc().splitlines()]
416 rst += [" %s\n" % l for l in doc().splitlines()]
412
417
413 if not ui.verbose:
418 if not ui.verbose:
414 omitted = _('(some details hidden, use --verbose'
419 omitted = _('(some details hidden, use --verbose'
415 ' to show complete help)')
420 ' to show complete help)')
416 indicateomitted(rst, omitted)
421 indicateomitted(rst, omitted)
417
422
418 try:
423 try:
419 cmdutil.findcmd(name, commands.table)
424 cmdutil.findcmd(name, commands.table)
420 rst.append(_('\nuse "hg help -c %s" to see help for '
425 rst.append(_('\nuse "hg help -c %s" to see help for '
421 'the %s command\n') % (name, name))
426 'the %s command\n') % (name, name))
422 except error.UnknownCommand:
427 except error.UnknownCommand:
423 pass
428 pass
424 return rst
429 return rst
425
430
426 def helpext(name):
431 def helpext(name):
427 try:
432 try:
428 mod = extensions.find(name)
433 mod = extensions.find(name)
429 doc = gettext(mod.__doc__) or _('no help text available')
434 doc = gettext(mod.__doc__) or _('no help text available')
430 except KeyError:
435 except KeyError:
431 mod = None
436 mod = None
432 doc = extensions.disabledext(name)
437 doc = extensions.disabledext(name)
433 if not doc:
438 if not doc:
434 raise error.UnknownCommand(name)
439 raise error.UnknownCommand(name)
435
440
436 if '\n' not in doc:
441 if '\n' not in doc:
437 head, tail = doc, ""
442 head, tail = doc, ""
438 else:
443 else:
439 head, tail = doc.split('\n', 1)
444 head, tail = doc.split('\n', 1)
440 rst = [_('%s extension - %s\n\n') % (name.split('.')[-1], head)]
445 rst = [_('%s extension - %s\n\n') % (name.split('.')[-1], head)]
441 if tail:
446 if tail:
442 rst.extend(tail.splitlines(True))
447 rst.extend(tail.splitlines(True))
443 rst.append('\n')
448 rst.append('\n')
444
449
445 if not ui.verbose:
450 if not ui.verbose:
446 omitted = _('(some details hidden, use --verbose'
451 omitted = _('(some details hidden, use --verbose'
447 ' to show complete help)')
452 ' to show complete help)')
448 indicateomitted(rst, omitted)
453 indicateomitted(rst, omitted)
449
454
450 if mod:
455 if mod:
451 try:
456 try:
452 ct = mod.cmdtable
457 ct = mod.cmdtable
453 except AttributeError:
458 except AttributeError:
454 ct = {}
459 ct = {}
455 modcmds = set([c.split('|', 1)[0] for c in ct])
460 modcmds = set([c.split('|', 1)[0] for c in ct])
456 rst.extend(helplist(modcmds.__contains__))
461 rst.extend(helplist(modcmds.__contains__))
457 else:
462 else:
458 rst.append(_('(use "hg help extensions" for information on enabling'
463 rst.append(_('(use "hg help extensions" for information on enabling'
459 ' extensions)\n'))
464 ' extensions)\n'))
460 return rst
465 return rst
461
466
462 def helpextcmd(name):
467 def helpextcmd(name):
463 cmd, ext, mod = extensions.disabledcmd(ui, name,
468 cmd, ext, mod = extensions.disabledcmd(ui, name,
464 ui.configbool('ui', 'strict'))
469 ui.configbool('ui', 'strict'))
465 doc = gettext(mod.__doc__).splitlines()[0]
470 doc = gettext(mod.__doc__).splitlines()[0]
466
471
467 rst = listexts(_("'%s' is provided by the following "
472 rst = listexts(_("'%s' is provided by the following "
468 "extension:") % cmd, {ext: doc}, indent=4)
473 "extension:") % cmd, {ext: doc}, indent=4)
469 rst.append('\n')
474 rst.append('\n')
470 rst.append(_('(use "hg help extensions" for information on enabling '
475 rst.append(_('(use "hg help extensions" for information on enabling '
471 'extensions)\n'))
476 'extensions)\n'))
472 return rst
477 return rst
473
478
474
479
475 rst = []
480 rst = []
476 kw = opts.get('keyword')
481 kw = opts.get('keyword')
477 if kw:
482 if kw:
478 matches = topicmatch(name)
483 matches = topicmatch(name)
479 helpareas = []
484 helpareas = []
480 if opts.get('extension'):
485 if opts.get('extension'):
481 helpareas += [('extensions', _('Extensions'))]
486 helpareas += [('extensions', _('Extensions'))]
482 if opts.get('command'):
487 if opts.get('command'):
483 helpareas += [('commands', _('Commands'))]
488 helpareas += [('commands', _('Commands'))]
484 if not helpareas:
489 if not helpareas:
485 helpareas = [('topics', _('Topics')),
490 helpareas = [('topics', _('Topics')),
486 ('commands', _('Commands')),
491 ('commands', _('Commands')),
487 ('extensions', _('Extensions')),
492 ('extensions', _('Extensions')),
488 ('extensioncommands', _('Extension Commands'))]
493 ('extensioncommands', _('Extension Commands'))]
489 for t, title in helpareas:
494 for t, title in helpareas:
490 if matches[t]:
495 if matches[t]:
491 rst.append('%s:\n\n' % title)
496 rst.append('%s:\n\n' % title)
492 rst.extend(minirst.maketable(sorted(matches[t]), 1))
497 rst.extend(minirst.maketable(sorted(matches[t]), 1))
493 rst.append('\n')
498 rst.append('\n')
494 if not rst:
499 if not rst:
495 msg = _('no matches')
500 msg = _('no matches')
496 hint = _('try "hg help" for a list of topics')
501 hint = _('try "hg help" for a list of topics')
497 raise util.Abort(msg, hint=hint)
502 raise util.Abort(msg, hint=hint)
498 elif name and name != 'shortlist':
503 elif name and name != 'shortlist':
499 queries = []
504 queries = []
500 if unknowncmd:
505 if unknowncmd:
501 queries += [helpextcmd]
506 queries += [helpextcmd]
502 if opts.get('extension'):
507 if opts.get('extension'):
503 queries += [helpext]
508 queries += [helpext]
504 if opts.get('command'):
509 if opts.get('command'):
505 queries += [helpcmd]
510 queries += [helpcmd]
506 if not queries:
511 if not queries:
507 queries = (helptopic, helpcmd, helpext, helpextcmd)
512 queries = (helptopic, helpcmd, helpext, helpextcmd)
508 for f in queries:
513 for f in queries:
509 try:
514 try:
510 rst = f(name)
515 rst = f(name)
511 break
516 break
512 except error.UnknownCommand:
517 except error.UnknownCommand:
513 pass
518 pass
514 else:
519 else:
515 if unknowncmd:
520 if unknowncmd:
516 raise error.UnknownCommand(name)
521 raise error.UnknownCommand(name)
517 else:
522 else:
518 msg = _('no such help topic: %s') % name
523 msg = _('no such help topic: %s') % name
519 hint = _('try "hg help --keyword %s"') % name
524 hint = _('try "hg help --keyword %s"') % name
520 raise util.Abort(msg, hint=hint)
525 raise util.Abort(msg, hint=hint)
521 else:
526 else:
522 # program name
527 # program name
523 if not ui.quiet:
528 if not ui.quiet:
524 rst = [_("Mercurial Distributed SCM\n"), '\n']
529 rst = [_("Mercurial Distributed SCM\n"), '\n']
525 rst.extend(helplist())
530 rst.extend(helplist())
526
531
527 return ''.join(rst)
532 return ''.join(rst)
General Comments 0
You need to be logged in to leave comments. Login now