changeset 43076 | 2372284d9457 |
parent 42466 | 9d31581cc44e |
child 43077 | 687b865b95ad |
43075:57875cf423c9 | 43076:2372284d9457 |
---|---|
32 templatefuncs, |
32 templatefuncs, |
33 templatekw, |
33 templatekw, |
34 ui as uimod, |
34 ui as uimod, |
35 util, |
35 util, |
36 ) |
36 ) |
37 from .hgweb import ( |
37 from .hgweb import webcommands |
38 webcommands, |
38 from .utils import compression |
39 ) |
|
40 from .utils import ( |
|
41 compression, |
|
42 ) |
|
43 |
39 |
44 _exclkeywords = { |
40 _exclkeywords = { |
45 "(ADVANCED)", |
41 "(ADVANCED)", |
46 "(DEPRECATED)", |
42 "(DEPRECATED)", |
47 "(EXPERIMENTAL)", |
43 "(EXPERIMENTAL)", |
62 registrar.command.CATEGORY_REMOTE_REPO_MANAGEMENT, |
58 registrar.command.CATEGORY_REMOTE_REPO_MANAGEMENT, |
63 registrar.command.CATEGORY_COMMITTING, |
59 registrar.command.CATEGORY_COMMITTING, |
64 registrar.command.CATEGORY_CHANGE_MANAGEMENT, |
60 registrar.command.CATEGORY_CHANGE_MANAGEMENT, |
65 registrar.command.CATEGORY_CHANGE_ORGANIZATION, |
61 registrar.command.CATEGORY_CHANGE_ORGANIZATION, |
66 registrar.command.CATEGORY_FILE_CONTENTS, |
62 registrar.command.CATEGORY_FILE_CONTENTS, |
67 registrar.command.CATEGORY_CHANGE_NAVIGATION , |
63 registrar.command.CATEGORY_CHANGE_NAVIGATION, |
68 registrar.command.CATEGORY_WORKING_DIRECTORY, |
64 registrar.command.CATEGORY_WORKING_DIRECTORY, |
69 registrar.command.CATEGORY_IMPORT_EXPORT, |
65 registrar.command.CATEGORY_IMPORT_EXPORT, |
70 registrar.command.CATEGORY_MAINTENANCE, |
66 registrar.command.CATEGORY_MAINTENANCE, |
71 registrar.command.CATEGORY_HELP, |
67 registrar.command.CATEGORY_HELP, |
72 registrar.command.CATEGORY_MISC, |
68 registrar.command.CATEGORY_MISC, |
75 |
71 |
76 # Human-readable category names. These are translated. |
72 # Human-readable category names. These are translated. |
77 # Extensions with custom categories should add their names here. |
73 # Extensions with custom categories should add their names here. |
78 CATEGORY_NAMES = { |
74 CATEGORY_NAMES = { |
79 registrar.command.CATEGORY_REPO_CREATION: 'Repository creation', |
75 registrar.command.CATEGORY_REPO_CREATION: 'Repository creation', |
80 registrar.command.CATEGORY_REMOTE_REPO_MANAGEMENT: |
76 registrar.command.CATEGORY_REMOTE_REPO_MANAGEMENT: 'Remote repository management', |
81 'Remote repository management', |
|
82 registrar.command.CATEGORY_COMMITTING: 'Change creation', |
77 registrar.command.CATEGORY_COMMITTING: 'Change creation', |
83 registrar.command.CATEGORY_CHANGE_NAVIGATION: 'Change navigation', |
78 registrar.command.CATEGORY_CHANGE_NAVIGATION: 'Change navigation', |
84 registrar.command.CATEGORY_CHANGE_MANAGEMENT: 'Change manipulation', |
79 registrar.command.CATEGORY_CHANGE_MANAGEMENT: 'Change manipulation', |
85 registrar.command.CATEGORY_CHANGE_ORGANIZATION: 'Change organization', |
80 registrar.command.CATEGORY_CHANGE_ORGANIZATION: 'Change organization', |
86 registrar.command.CATEGORY_WORKING_DIRECTORY: |
81 registrar.command.CATEGORY_WORKING_DIRECTORY: 'Working directory management', |
87 'Working directory management', |
|
88 registrar.command.CATEGORY_FILE_CONTENTS: 'File content management', |
82 registrar.command.CATEGORY_FILE_CONTENTS: 'File content management', |
89 registrar.command.CATEGORY_IMPORT_EXPORT: 'Change import/export', |
83 registrar.command.CATEGORY_IMPORT_EXPORT: 'Change import/export', |
90 registrar.command.CATEGORY_MAINTENANCE: 'Repository maintenance', |
84 registrar.command.CATEGORY_MAINTENANCE: 'Repository maintenance', |
91 registrar.command.CATEGORY_HELP: 'Help', |
85 registrar.command.CATEGORY_HELP: 'Help', |
92 registrar.command.CATEGORY_MISC: 'Miscellaneous commands', |
86 registrar.command.CATEGORY_MISC: 'Miscellaneous commands', |
122 TOPIC_CATEGORY_CONCEPTS: 'Concepts', |
116 TOPIC_CATEGORY_CONCEPTS: 'Concepts', |
123 TOPIC_CATEGORY_MISC: 'Miscellaneous', |
117 TOPIC_CATEGORY_MISC: 'Miscellaneous', |
124 TOPIC_CATEGORY_NONE: 'Uncategorized topics', |
118 TOPIC_CATEGORY_NONE: 'Uncategorized topics', |
125 } |
119 } |
126 |
120 |
121 |
|
127 def listexts(header, exts, indent=1, showdeprecated=False): |
122 def listexts(header, exts, indent=1, showdeprecated=False): |
128 '''return a text listing of the given extensions''' |
123 '''return a text listing of the given extensions''' |
129 rst = [] |
124 rst = [] |
130 if exts: |
125 if exts: |
131 for name, desc in sorted(exts.iteritems()): |
126 for name, desc in sorted(exts.iteritems()): |
134 rst.append('%s:%s: %s\n' % (' ' * indent, name, desc)) |
129 rst.append('%s:%s: %s\n' % (' ' * indent, name, desc)) |
135 if rst: |
130 if rst: |
136 rst.insert(0, '\n%s\n\n' % header) |
131 rst.insert(0, '\n%s\n\n' % header) |
137 return rst |
132 return rst |
138 |
133 |
134 |
|
139 def extshelp(ui): |
135 def extshelp(ui): |
140 rst = loaddoc('extensions')(ui).splitlines(True) |
136 rst = loaddoc('extensions')(ui).splitlines(True) |
141 rst.extend(listexts( |
137 rst.extend( |
142 _('enabled extensions:'), extensions.enabled(), showdeprecated=True)) |
138 listexts( |
143 rst.extend(listexts(_('disabled extensions:'), extensions.disabled(), |
139 _('enabled extensions:'), extensions.enabled(), showdeprecated=True |
144 showdeprecated=ui.verbose)) |
140 ) |
141 ) |
|
142 rst.extend( |
|
143 listexts( |
|
144 _('disabled extensions:'), |
|
145 extensions.disabled(), |
|
146 showdeprecated=ui.verbose, |
|
147 ) |
|
148 ) |
|
145 doc = ''.join(rst) |
149 doc = ''.join(rst) |
146 return doc |
150 return doc |
151 |
|
147 |
152 |
148 def optrst(header, options, verbose): |
153 def optrst(header, options, verbose): |
149 data = [] |
154 data = [] |
150 multioccur = False |
155 multioccur = False |
151 for option in options: |
156 for option in options: |
152 if len(option) == 5: |
157 if len(option) == 5: |
153 shortopt, longopt, default, desc, optlabel = option |
158 shortopt, longopt, default, desc, optlabel = option |
154 else: |
159 else: |
155 shortopt, longopt, default, desc = option |
160 shortopt, longopt, default, desc = option |
156 optlabel = _("VALUE") # default label |
161 optlabel = _("VALUE") # default label |
157 |
162 |
158 if not verbose and any(w in desc for w in _exclkeywords): |
163 if not verbose and any(w in desc for w in _exclkeywords): |
159 continue |
164 continue |
160 |
165 |
161 so = '' |
166 so = '' |
184 lo += " %s" % optlabel |
189 lo += " %s" % optlabel |
185 |
190 |
186 data.append((so, lo, desc)) |
191 data.append((so, lo, desc)) |
187 |
192 |
188 if multioccur: |
193 if multioccur: |
189 header += (_(" ([+] can be repeated)")) |
194 header += _(" ([+] can be repeated)") |
190 |
195 |
191 rst = ['\n%s:\n\n' % header] |
196 rst = ['\n%s:\n\n' % header] |
192 rst.extend(minirst.maketable(data, 1)) |
197 rst.extend(minirst.maketable(data, 1)) |
193 |
198 |
194 return ''.join(rst) |
199 return ''.join(rst) |
200 |
|
195 |
201 |
196 def indicateomitted(rst, omitted, notomitted=None): |
202 def indicateomitted(rst, omitted, notomitted=None): |
197 rst.append('\n\n.. container:: omitted\n\n %s\n\n' % omitted) |
203 rst.append('\n\n.. container:: omitted\n\n %s\n\n' % omitted) |
198 if notomitted: |
204 if notomitted: |
199 rst.append('\n\n.. container:: notomitted\n\n %s\n\n' % notomitted) |
205 rst.append('\n\n.. container:: notomitted\n\n %s\n\n' % notomitted) |
206 |
|
200 |
207 |
201 def filtercmd(ui, cmd, func, kw, doc): |
208 def filtercmd(ui, cmd, func, kw, doc): |
202 if not ui.debugflag and cmd.startswith("debug") and kw != "debug": |
209 if not ui.debugflag and cmd.startswith("debug") and kw != "debug": |
203 # Debug command, and user is not looking for those. |
210 # Debug command, and user is not looking for those. |
204 return True |
211 return True |
218 if ui.configbool('help', 'hidden-command.%s' % cmd): |
225 if ui.configbool('help', 'hidden-command.%s' % cmd): |
219 # Configuration explicitly hides the command. |
226 # Configuration explicitly hides the command. |
220 return True |
227 return True |
221 return False |
228 return False |
222 |
229 |
230 |
|
223 def filtertopic(ui, topic): |
231 def filtertopic(ui, topic): |
224 return ui.configbool('help', 'hidden-topic.%s' % topic, False) |
232 return ui.configbool('help', 'hidden-topic.%s' % topic, False) |
233 |
|
225 |
234 |
226 def topicmatch(ui, commands, kw): |
235 def topicmatch(ui, commands, kw): |
227 """Return help topics matching kw. |
236 """Return help topics matching kw. |
228 |
237 |
229 Returns {'section': [(name, summary), ...], ...} where section is |
238 Returns {'section': [(name, summary), ...], ...} where section is |
230 one of topics, commands, extensions, or extensioncommands. |
239 one of topics, commands, extensions, or extensioncommands. |
231 """ |
240 """ |
232 kw = encoding.lower(kw) |
241 kw = encoding.lower(kw) |
242 |
|
233 def lowercontains(container): |
243 def lowercontains(container): |
234 return kw in encoding.lower(container) # translated in helptable |
244 return kw in encoding.lower(container) # translated in helptable |
235 results = {'topics': [], |
245 |
236 'commands': [], |
246 results = { |
237 'extensions': [], |
247 'topics': [], |
238 'extensioncommands': [], |
248 'commands': [], |
239 } |
249 'extensions': [], |
250 'extensioncommands': [], |
|
251 } |
|
240 for topic in helptable: |
252 for topic in helptable: |
241 names, header, doc = topic[0:3] |
253 names, header, doc = topic[0:3] |
242 # Old extensions may use a str as doc. |
254 # Old extensions may use a str as doc. |
243 if (sum(map(lowercontains, names)) |
255 if ( |
256 sum(map(lowercontains, names)) |
|
244 or lowercontains(header) |
257 or lowercontains(header) |
245 or (callable(doc) and lowercontains(doc(ui)))): |
258 or (callable(doc) and lowercontains(doc(ui))) |
259 ): |
|
246 name = names[0] |
260 name = names[0] |
247 if not filtertopic(ui, name): |
261 if not filtertopic(ui, name): |
248 results['topics'].append((names[0], header)) |
262 results['topics'].append((names[0], header)) |
249 for cmd, entry in commands.table.iteritems(): |
263 for cmd, entry in commands.table.iteritems(): |
250 if len(entry) == 3: |
264 if len(entry) == 3: |
261 cmdname = cmdutil.parsealiases(cmd)[0] |
275 cmdname = cmdutil.parsealiases(cmd)[0] |
262 if filtercmd(ui, cmdname, func, kw, docs): |
276 if filtercmd(ui, cmdname, func, kw, docs): |
263 continue |
277 continue |
264 results['commands'].append((cmdname, summary)) |
278 results['commands'].append((cmdname, summary)) |
265 for name, docs in itertools.chain( |
279 for name, docs in itertools.chain( |
266 extensions.enabled(False).iteritems(), |
280 extensions.enabled(False).iteritems(), extensions.disabled().iteritems() |
267 extensions.disabled().iteritems()): |
281 ): |
268 if not docs: |
282 if not docs: |
269 continue |
283 continue |
270 name = name.rpartition('.')[-1] |
284 name = name.rpartition('.')[-1] |
271 if lowercontains(name) or lowercontains(docs): |
285 if lowercontains(name) or lowercontains(docs): |
272 # extension docs are already translated |
286 # extension docs are already translated |
288 if filtercmd(ui, cmdname, func, kw, cmddoc): |
302 if filtercmd(ui, cmdname, func, kw, cmddoc): |
289 continue |
303 continue |
290 results['extensioncommands'].append((cmdname, cmddoc)) |
304 results['extensioncommands'].append((cmdname, cmddoc)) |
291 return results |
305 return results |
292 |
306 |
307 |
|
293 def loaddoc(topic, subdir=None): |
308 def loaddoc(topic, subdir=None): |
294 """Return a delayed loader for help/topic.txt.""" |
309 """Return a delayed loader for help/topic.txt.""" |
295 |
310 |
296 def loader(ui): |
311 def loader(ui): |
297 docdir = os.path.join(util.datapath, 'help') |
312 docdir = os.path.join(util.datapath, 'help') |
303 doc = rewriter(ui, topic, doc) |
318 doc = rewriter(ui, topic, doc) |
304 return doc |
319 return doc |
305 |
320 |
306 return loader |
321 return loader |
307 |
322 |
308 internalstable = sorted([ |
323 |
309 (['bundle2'], _('Bundle2'), |
324 internalstable = sorted( |
310 loaddoc('bundle2', subdir='internals')), |
325 [ |
311 (['bundles'], _('Bundles'), |
326 (['bundle2'], _('Bundle2'), loaddoc('bundle2', subdir='internals')), |
312 loaddoc('bundles', subdir='internals')), |
327 (['bundles'], _('Bundles'), loaddoc('bundles', subdir='internals')), |
313 (['cbor'], _('CBOR'), |
328 (['cbor'], _('CBOR'), loaddoc('cbor', subdir='internals')), |
314 loaddoc('cbor', subdir='internals')), |
329 (['censor'], _('Censor'), loaddoc('censor', subdir='internals')), |
315 (['censor'], _('Censor'), |
330 ( |
316 loaddoc('censor', subdir='internals')), |
331 ['changegroups'], |
317 (['changegroups'], _('Changegroups'), |
332 _('Changegroups'), |
318 loaddoc('changegroups', subdir='internals')), |
333 loaddoc('changegroups', subdir='internals'), |
319 (['config'], _('Config Registrar'), |
334 ), |
320 loaddoc('config', subdir='internals')), |
335 ( |
321 (['extensions', 'extension'], _('Extension API'), |
336 ['config'], |
322 loaddoc('extensions', subdir='internals')), |
337 _('Config Registrar'), |
323 (['mergestate'], _('Mergestate'), |
338 loaddoc('config', subdir='internals'), |
324 loaddoc('mergestate', subdir='internals')), |
339 ), |
325 (['requirements'], _('Repository Requirements'), |
340 ( |
326 loaddoc('requirements', subdir='internals')), |
341 ['extensions', 'extension'], |
327 (['revlogs'], _('Revision Logs'), |
342 _('Extension API'), |
328 loaddoc('revlogs', subdir='internals')), |
343 loaddoc('extensions', subdir='internals'), |
329 (['wireprotocol'], _('Wire Protocol'), |
344 ), |
330 loaddoc('wireprotocol', subdir='internals')), |
345 ( |
331 (['wireprotocolrpc'], _('Wire Protocol RPC'), |
346 ['mergestate'], |
332 loaddoc('wireprotocolrpc', subdir='internals')), |
347 _('Mergestate'), |
333 (['wireprotocolv2'], _('Wire Protocol Version 2'), |
348 loaddoc('mergestate', subdir='internals'), |
334 loaddoc('wireprotocolv2', subdir='internals')), |
349 ), |
335 ]) |
350 ( |
351 ['requirements'], |
|
352 _('Repository Requirements'), |
|
353 loaddoc('requirements', subdir='internals'), |
|
354 ), |
|
355 ( |
|
356 ['revlogs'], |
|
357 _('Revision Logs'), |
|
358 loaddoc('revlogs', subdir='internals'), |
|
359 ), |
|
360 ( |
|
361 ['wireprotocol'], |
|
362 _('Wire Protocol'), |
|
363 loaddoc('wireprotocol', subdir='internals'), |
|
364 ), |
|
365 ( |
|
366 ['wireprotocolrpc'], |
|
367 _('Wire Protocol RPC'), |
|
368 loaddoc('wireprotocolrpc', subdir='internals'), |
|
369 ), |
|
370 ( |
|
371 ['wireprotocolv2'], |
|
372 _('Wire Protocol Version 2'), |
|
373 loaddoc('wireprotocolv2', subdir='internals'), |
|
374 ), |
|
375 ] |
|
376 ) |
|
377 |
|
336 |
378 |
337 def internalshelp(ui): |
379 def internalshelp(ui): |
338 """Generate the index for the "internals" topic.""" |
380 """Generate the index for the "internals" topic.""" |
339 lines = ['To access a subtopic, use "hg help internals.{subtopic-name}"\n', |
381 lines = [ |
340 '\n'] |
382 'To access a subtopic, use "hg help internals.{subtopic-name}"\n', |
383 '\n', |
|
384 ] |
|
341 for names, header, doc in internalstable: |
385 for names, header, doc in internalstable: |
342 lines.append(' :%s: %s\n' % (names[0], header)) |
386 lines.append(' :%s: %s\n' % (names[0], header)) |
343 |
387 |
344 return ''.join(lines) |
388 return ''.join(lines) |
345 |
389 |
346 helptable = sorted([ |
390 |
347 (['bundlespec'], _("Bundle File Formats"), loaddoc('bundlespec'), |
391 helptable = sorted( |
348 TOPIC_CATEGORY_CONCEPTS), |
392 [ |
349 (['color'], _("Colorizing Outputs"), loaddoc('color'), |
393 ( |
350 TOPIC_CATEGORY_OUTPUT), |
394 ['bundlespec'], |
351 (["config", "hgrc"], _("Configuration Files"), loaddoc('config'), |
395 _("Bundle File Formats"), |
352 TOPIC_CATEGORY_CONFIG), |
396 loaddoc('bundlespec'), |
353 (['deprecated'], _("Deprecated Features"), loaddoc('deprecated'), |
397 TOPIC_CATEGORY_CONCEPTS, |
354 TOPIC_CATEGORY_MISC), |
398 ), |
355 (["dates"], _("Date Formats"), loaddoc('dates'), TOPIC_CATEGORY_OUTPUT), |
399 ( |
356 (["flags"], _("Command-line flags"), loaddoc('flags'), |
400 ['color'], |
357 TOPIC_CATEGORY_CONFIG), |
401 _("Colorizing Outputs"), |
358 (["patterns"], _("File Name Patterns"), loaddoc('patterns'), |
402 loaddoc('color'), |
359 TOPIC_CATEGORY_IDS), |
403 TOPIC_CATEGORY_OUTPUT, |
360 (['environment', 'env'], _('Environment Variables'), |
404 ), |
361 loaddoc('environment'), TOPIC_CATEGORY_CONFIG), |
405 ( |
362 (['revisions', 'revs', 'revsets', 'revset', 'multirevs', 'mrevs'], |
406 ["config", "hgrc"], |
363 _('Specifying Revisions'), loaddoc('revisions'), TOPIC_CATEGORY_IDS), |
407 _("Configuration Files"), |
364 (['filesets', 'fileset'], _("Specifying File Sets"), loaddoc('filesets'), |
408 loaddoc('config'), |
365 TOPIC_CATEGORY_IDS), |
409 TOPIC_CATEGORY_CONFIG, |
366 (['diffs'], _('Diff Formats'), loaddoc('diffs'), TOPIC_CATEGORY_OUTPUT), |
410 ), |
367 (['merge-tools', 'mergetools', 'mergetool'], _('Merge Tools'), |
411 ( |
368 loaddoc('merge-tools'), TOPIC_CATEGORY_CONFIG), |
412 ['deprecated'], |
369 (['templating', 'templates', 'template', 'style'], _('Template Usage'), |
413 _("Deprecated Features"), |
370 loaddoc('templates'), TOPIC_CATEGORY_OUTPUT), |
414 loaddoc('deprecated'), |
371 (['urls'], _('URL Paths'), loaddoc('urls'), TOPIC_CATEGORY_IDS), |
415 TOPIC_CATEGORY_MISC, |
372 (["extensions"], _("Using Additional Features"), extshelp, |
416 ), |
373 TOPIC_CATEGORY_CONFIG), |
417 (["dates"], _("Date Formats"), loaddoc('dates'), TOPIC_CATEGORY_OUTPUT), |
374 (["subrepos", "subrepo"], _("Subrepositories"), loaddoc('subrepos'), |
418 ( |
375 TOPIC_CATEGORY_CONCEPTS), |
419 ["flags"], |
376 (["hgweb"], _("Configuring hgweb"), loaddoc('hgweb'), |
420 _("Command-line flags"), |
377 TOPIC_CATEGORY_CONFIG), |
421 loaddoc('flags'), |
378 (["glossary"], _("Glossary"), loaddoc('glossary'), TOPIC_CATEGORY_CONCEPTS), |
422 TOPIC_CATEGORY_CONFIG, |
379 (["hgignore", "ignore"], _("Syntax for Mercurial Ignore Files"), |
423 ), |
380 loaddoc('hgignore'), TOPIC_CATEGORY_IDS), |
424 ( |
381 (["phases"], _("Working with Phases"), loaddoc('phases'), |
425 ["patterns"], |
382 TOPIC_CATEGORY_CONCEPTS), |
426 _("File Name Patterns"), |
383 (['scripting'], _('Using Mercurial from scripts and automation'), |
427 loaddoc('patterns'), |
384 loaddoc('scripting'), TOPIC_CATEGORY_MISC), |
428 TOPIC_CATEGORY_IDS, |
385 (['internals'], _("Technical implementation topics"), internalshelp, |
429 ), |
386 TOPIC_CATEGORY_MISC), |
430 ( |
387 (['pager'], _("Pager Support"), loaddoc('pager'), TOPIC_CATEGORY_CONFIG), |
431 ['environment', 'env'], |
388 ]) |
432 _('Environment Variables'), |
433 loaddoc('environment'), |
|
434 TOPIC_CATEGORY_CONFIG, |
|
435 ), |
|
436 ( |
|
437 ['revisions', 'revs', 'revsets', 'revset', 'multirevs', 'mrevs'], |
|
438 _('Specifying Revisions'), |
|
439 loaddoc('revisions'), |
|
440 TOPIC_CATEGORY_IDS, |
|
441 ), |
|
442 ( |
|
443 ['filesets', 'fileset'], |
|
444 _("Specifying File Sets"), |
|
445 loaddoc('filesets'), |
|
446 TOPIC_CATEGORY_IDS, |
|
447 ), |
|
448 (['diffs'], _('Diff Formats'), loaddoc('diffs'), TOPIC_CATEGORY_OUTPUT), |
|
449 ( |
|
450 ['merge-tools', 'mergetools', 'mergetool'], |
|
451 _('Merge Tools'), |
|
452 loaddoc('merge-tools'), |
|
453 TOPIC_CATEGORY_CONFIG, |
|
454 ), |
|
455 ( |
|
456 ['templating', 'templates', 'template', 'style'], |
|
457 _('Template Usage'), |
|
458 loaddoc('templates'), |
|
459 TOPIC_CATEGORY_OUTPUT, |
|
460 ), |
|
461 (['urls'], _('URL Paths'), loaddoc('urls'), TOPIC_CATEGORY_IDS), |
|
462 ( |
|
463 ["extensions"], |
|
464 _("Using Additional Features"), |
|
465 extshelp, |
|
466 TOPIC_CATEGORY_CONFIG, |
|
467 ), |
|
468 ( |
|
469 ["subrepos", "subrepo"], |
|
470 _("Subrepositories"), |
|
471 loaddoc('subrepos'), |
|
472 TOPIC_CATEGORY_CONCEPTS, |
|
473 ), |
|
474 ( |
|
475 ["hgweb"], |
|
476 _("Configuring hgweb"), |
|
477 loaddoc('hgweb'), |
|
478 TOPIC_CATEGORY_CONFIG, |
|
479 ), |
|
480 ( |
|
481 ["glossary"], |
|
482 _("Glossary"), |
|
483 loaddoc('glossary'), |
|
484 TOPIC_CATEGORY_CONCEPTS, |
|
485 ), |
|
486 ( |
|
487 ["hgignore", "ignore"], |
|
488 _("Syntax for Mercurial Ignore Files"), |
|
489 loaddoc('hgignore'), |
|
490 TOPIC_CATEGORY_IDS, |
|
491 ), |
|
492 ( |
|
493 ["phases"], |
|
494 _("Working with Phases"), |
|
495 loaddoc('phases'), |
|
496 TOPIC_CATEGORY_CONCEPTS, |
|
497 ), |
|
498 ( |
|
499 ['scripting'], |
|
500 _('Using Mercurial from scripts and automation'), |
|
501 loaddoc('scripting'), |
|
502 TOPIC_CATEGORY_MISC, |
|
503 ), |
|
504 ( |
|
505 ['internals'], |
|
506 _("Technical implementation topics"), |
|
507 internalshelp, |
|
508 TOPIC_CATEGORY_MISC, |
|
509 ), |
|
510 ( |
|
511 ['pager'], |
|
512 _("Pager Support"), |
|
513 loaddoc('pager'), |
|
514 TOPIC_CATEGORY_CONFIG, |
|
515 ), |
|
516 ] |
|
517 ) |
|
389 |
518 |
390 # Maps topics with sub-topics to a list of their sub-topics. |
519 # Maps topics with sub-topics to a list of their sub-topics. |
391 subtopics = { |
520 subtopics = { |
392 'internals': internalstable, |
521 'internals': internalstable, |
393 } |
522 } |
394 |
523 |
395 # Map topics to lists of callable taking the current topic help and |
524 # Map topics to lists of callable taking the current topic help and |
396 # returning the updated version |
525 # returning the updated version |
397 helphooks = {} |
526 helphooks = {} |
398 |
527 |
528 |
|
399 def addtopichook(topic, rewriter): |
529 def addtopichook(topic, rewriter): |
400 helphooks.setdefault(topic, []).append(rewriter) |
530 helphooks.setdefault(topic, []).append(rewriter) |
531 |
|
401 |
532 |
402 def makeitemsdoc(ui, topic, doc, marker, items, dedent=False): |
533 def makeitemsdoc(ui, topic, doc, marker, items, dedent=False): |
403 """Extract docstring from the items key to function mapping, build a |
534 """Extract docstring from the items key to function mapping, build a |
404 single documentation block and use it to overwrite the marker in doc. |
535 single documentation block and use it to overwrite the marker in doc. |
405 """ |
536 """ |
406 entries = [] |
537 entries = [] |
407 for name in sorted(items): |
538 for name in sorted(items): |
408 text = (pycompat.getdoc(items[name]) or '').rstrip() |
539 text = (pycompat.getdoc(items[name]) or '').rstrip() |
409 if (not text |
540 if not text or not ui.verbose and any(w in text for w in _exclkeywords): |
410 or not ui.verbose and any(w in text for w in _exclkeywords)): |
|
411 continue |
541 continue |
412 text = gettext(text) |
542 text = gettext(text) |
413 if dedent: |
543 if dedent: |
414 # Abuse latin1 to use textwrap.dedent() on bytes. |
544 # Abuse latin1 to use textwrap.dedent() on bytes. |
415 text = textwrap.dedent(text.decode('latin1')).encode('latin1') |
545 text = textwrap.dedent(text.decode('latin1')).encode('latin1') |
425 doclines.append(' ' + l.strip()) |
555 doclines.append(' ' + l.strip()) |
426 entries.append('\n'.join(doclines)) |
556 entries.append('\n'.join(doclines)) |
427 entries = '\n\n'.join(entries) |
557 entries = '\n\n'.join(entries) |
428 return doc.replace(marker, entries) |
558 return doc.replace(marker, entries) |
429 |
559 |
560 |
|
430 def addtopicsymbols(topic, marker, symbols, dedent=False): |
561 def addtopicsymbols(topic, marker, symbols, dedent=False): |
431 def add(ui, topic, doc): |
562 def add(ui, topic, doc): |
432 return makeitemsdoc(ui, topic, doc, marker, symbols, dedent=dedent) |
563 return makeitemsdoc(ui, topic, doc, marker, symbols, dedent=dedent) |
564 |
|
433 addtopichook(topic, add) |
565 addtopichook(topic, add) |
434 |
566 |
435 addtopicsymbols('bundlespec', '.. bundlecompressionmarker', |
567 |
436 compression.bundlecompressiontopics()) |
568 addtopicsymbols( |
569 'bundlespec', |
|
570 '.. bundlecompressionmarker', |
|
571 compression.bundlecompressiontopics(), |
|
572 ) |
|
437 addtopicsymbols('filesets', '.. predicatesmarker', fileset.symbols) |
573 addtopicsymbols('filesets', '.. predicatesmarker', fileset.symbols) |
438 addtopicsymbols('merge-tools', '.. internaltoolsmarker', |
574 addtopicsymbols('merge-tools', '.. internaltoolsmarker', filemerge.internalsdoc) |
439 filemerge.internalsdoc) |
|
440 addtopicsymbols('revisions', '.. predicatesmarker', revset.symbols) |
575 addtopicsymbols('revisions', '.. predicatesmarker', revset.symbols) |
441 addtopicsymbols('templates', '.. keywordsmarker', templatekw.keywords) |
576 addtopicsymbols('templates', '.. keywordsmarker', templatekw.keywords) |
442 addtopicsymbols('templates', '.. filtersmarker', templatefilters.filters) |
577 addtopicsymbols('templates', '.. filtersmarker', templatefilters.filters) |
443 addtopicsymbols('templates', '.. functionsmarker', templatefuncs.funcs) |
578 addtopicsymbols('templates', '.. functionsmarker', templatefuncs.funcs) |
444 addtopicsymbols('hgweb', '.. webcommandsmarker', webcommands.commands, |
579 addtopicsymbols( |
445 dedent=True) |
580 'hgweb', '.. webcommandsmarker', webcommands.commands, dedent=True |
581 ) |
|
582 |
|
446 |
583 |
447 def inserttweakrc(ui, topic, doc): |
584 def inserttweakrc(ui, topic, doc): |
448 marker = '.. tweakdefaultsmarker' |
585 marker = '.. tweakdefaultsmarker' |
449 repl = uimod.tweakrc |
586 repl = uimod.tweakrc |
587 |
|
450 def sub(m): |
588 def sub(m): |
451 lines = [m.group(1) + s for s in repl.splitlines()] |
589 lines = [m.group(1) + s for s in repl.splitlines()] |
452 return '\n'.join(lines) |
590 return '\n'.join(lines) |
591 |
|
453 return re.sub(br'( *)%s' % re.escape(marker), sub, doc) |
592 return re.sub(br'( *)%s' % re.escape(marker), sub, doc) |
454 |
593 |
594 |
|
455 addtopichook('config', inserttweakrc) |
595 addtopichook('config', inserttweakrc) |
456 |
596 |
457 def help_(ui, commands, name, unknowncmd=False, full=True, subtopic=None, |
597 |
458 fullname=None, **opts): |
598 def help_( |
599 ui, |
|
600 commands, |
|
601 name, |
|
602 unknowncmd=False, |
|
603 full=True, |
|
604 subtopic=None, |
|
605 fullname=None, |
|
606 **opts |
|
607 ): |
|
459 ''' |
608 ''' |
460 Generate the help for 'name' as unformatted restructured text. If |
609 Generate the help for 'name' as unformatted restructured text. If |
461 'name' is None, describe the commands available. |
610 'name' is None, describe the commands available. |
462 ''' |
611 ''' |
463 |
612 |
464 opts = pycompat.byteskwargs(opts) |
613 opts = pycompat.byteskwargs(opts) |
465 |
614 |
466 def helpcmd(name, subtopic=None): |
615 def helpcmd(name, subtopic=None): |
467 try: |
616 try: |
468 aliases, entry = cmdutil.findcmd(name, commands.table, |
617 aliases, entry = cmdutil.findcmd( |
469 strict=unknowncmd) |
618 name, commands.table, strict=unknowncmd |
619 ) |
|
470 except error.AmbiguousCommand as inst: |
620 except error.AmbiguousCommand as inst: |
471 # py3 fix: except vars can't be used outside the scope of the |
621 # py3 fix: except vars can't be used outside the scope of the |
472 # except block, nor can be used inside a lambda. python issue4617 |
622 # except block, nor can be used inside a lambda. python issue4617 |
473 prefix = inst.args[0] |
623 prefix = inst.args[0] |
474 select = lambda c: cmdutil.parsealiases(c)[0].startswith(prefix) |
624 select = lambda c: cmdutil.parsealiases(c)[0].startswith(prefix) |
505 if not doc: |
655 if not doc: |
506 doc = _("(no help text available)") |
656 doc = _("(no help text available)") |
507 if util.safehasattr(entry[0], 'definition'): # aliased command |
657 if util.safehasattr(entry[0], 'definition'): # aliased command |
508 source = entry[0].source |
658 source = entry[0].source |
509 if entry[0].definition.startswith('!'): # shell alias |
659 if entry[0].definition.startswith('!'): # shell alias |
510 doc = (_('shell alias for: %s\n\n%s\n\ndefined by: %s\n') % |
660 doc = _('shell alias for: %s\n\n%s\n\ndefined by: %s\n') % ( |
511 (entry[0].definition[1:], doc, source)) |
661 entry[0].definition[1:], |
662 doc, |
|
663 source, |
|
664 ) |
|
512 else: |
665 else: |
513 doc = (_('alias for: hg %s\n\n%s\n\ndefined by: %s\n') % |
666 doc = _('alias for: hg %s\n\n%s\n\ndefined by: %s\n') % ( |
514 (entry[0].definition, doc, source)) |
667 entry[0].definition, |
668 doc, |
|
669 source, |
|
670 ) |
|
515 doc = doc.splitlines(True) |
671 doc = doc.splitlines(True) |
516 if ui.quiet or not full: |
672 if ui.quiet or not full: |
517 rst.append(doc[0]) |
673 rst.append(doc[0]) |
518 else: |
674 else: |
519 rst.extend(doc) |
675 rst.extend(doc) |
523 # extension help text |
679 # extension help text |
524 try: |
680 try: |
525 mod = extensions.find(name) |
681 mod = extensions.find(name) |
526 doc = gettext(pycompat.getdoc(mod)) or '' |
682 doc = gettext(pycompat.getdoc(mod)) or '' |
527 if '\n' in doc.strip(): |
683 if '\n' in doc.strip(): |
528 msg = _("(use 'hg help -e %s' to show help for " |
684 msg = _( |
529 "the %s extension)") % (name, name) |
685 "(use 'hg help -e %s' to show help for " "the %s extension)" |
686 ) % (name, name) |
|
530 rst.append('\n%s\n' % msg) |
687 rst.append('\n%s\n' % msg) |
531 except KeyError: |
688 except KeyError: |
532 pass |
689 pass |
533 |
690 |
534 # options |
691 # options |
535 if not ui.quiet and entry[1]: |
692 if not ui.quiet and entry[1]: |
536 rst.append(optrst(_("options"), entry[1], ui.verbose)) |
693 rst.append(optrst(_("options"), entry[1], ui.verbose)) |
537 |
694 |
538 if ui.verbose: |
695 if ui.verbose: |
539 rst.append(optrst(_("global options"), |
696 rst.append( |
540 commands.globalopts, ui.verbose)) |
697 optrst(_("global options"), commands.globalopts, ui.verbose) |
698 ) |
|
541 |
699 |
542 if not ui.verbose: |
700 if not ui.verbose: |
543 if not full: |
701 if not full: |
544 rst.append(_("\n(use 'hg %s -h' to show more help)\n") |
702 rst.append(_("\n(use 'hg %s -h' to show more help)\n") % name) |
545 % name) |
|
546 elif not ui.quiet: |
703 elif not ui.quiet: |
547 rst.append(_('\n(some details hidden, use --verbose ' |
704 rst.append( |
548 'to show complete help)')) |
705 _( |
706 '\n(some details hidden, use --verbose ' |
|
707 'to show complete help)' |
|
708 ) |
|
709 ) |
|
549 |
710 |
550 return rst |
711 return rst |
551 |
712 |
552 def helplist(select=None, **opts): |
713 def helplist(select=None, **opts): |
553 # Category -> list of commands |
714 # Category -> list of commands |
570 if not doc: |
731 if not doc: |
571 doc = _("(no help text available)") |
732 doc = _("(no help text available)") |
572 h[f] = doc.splitlines()[0].rstrip() |
733 h[f] = doc.splitlines()[0].rstrip() |
573 |
734 |
574 cat = getattr(func, 'helpcategory', None) or ( |
735 cat = getattr(func, 'helpcategory', None) or ( |
575 registrar.command.CATEGORY_NONE) |
736 registrar.command.CATEGORY_NONE |
737 ) |
|
576 cats.setdefault(cat, []).append(f) |
738 cats.setdefault(cat, []).append(f) |
577 |
739 |
578 rst = [] |
740 rst = [] |
579 if not h: |
741 if not h: |
580 if not ui.quiet: |
742 if not ui.quiet: |
603 appendcmds(h) |
765 appendcmds(h) |
604 else: |
766 else: |
605 # Check that all categories have an order. |
767 # Check that all categories have an order. |
606 missing_order = set(cats.keys()) - set(CATEGORY_ORDER) |
768 missing_order = set(cats.keys()) - set(CATEGORY_ORDER) |
607 if missing_order: |
769 if missing_order: |
608 ui.develwarn('help categories missing from CATEGORY_ORDER: %s' % |
770 ui.develwarn( |
609 missing_order) |
771 'help categories missing from CATEGORY_ORDER: %s' |
772 % missing_order |
|
773 ) |
|
610 |
774 |
611 # List per category. |
775 # List per category. |
612 for cat in CATEGORY_ORDER: |
776 for cat in CATEGORY_ORDER: |
613 catfns = cats.get(cat, []) |
777 catfns = cats.get(cat, []) |
614 if catfns: |
778 if catfns: |
617 rst.append("\n%s:\n" % catname) |
781 rst.append("\n%s:\n" % catname) |
618 rst.append("\n") |
782 rst.append("\n") |
619 appendcmds(catfns) |
783 appendcmds(catfns) |
620 |
784 |
621 ex = opts.get |
785 ex = opts.get |
622 anyopts = (ex(r'keyword') or not (ex(r'command') or ex(r'extension'))) |
786 anyopts = ex(r'keyword') or not (ex(r'command') or ex(r'extension')) |
623 if not name and anyopts: |
787 if not name and anyopts: |
624 exts = listexts(_('enabled extensions:'), extensions.enabled(), |
788 exts = listexts( |
625 showdeprecated=ui.verbose) |
789 _('enabled extensions:'), |
790 extensions.enabled(), |
|
791 showdeprecated=ui.verbose, |
|
792 ) |
|
626 if exts: |
793 if exts: |
627 rst.append('\n') |
794 rst.append('\n') |
628 rst.extend(exts) |
795 rst.extend(exts) |
629 |
796 |
630 rst.append(_("\nadditional help topics:\n")) |
797 rst.append(_("\nadditional help topics:\n")) |
638 category = TOPIC_CATEGORY_NONE |
805 category = TOPIC_CATEGORY_NONE |
639 |
806 |
640 topicname = names[0] |
807 topicname = names[0] |
641 if not filtertopic(ui, topicname): |
808 if not filtertopic(ui, topicname): |
642 topiccats.setdefault(category, []).append( |
809 topiccats.setdefault(category, []).append( |
643 (topicname, header)) |
810 (topicname, header) |
811 ) |
|
644 |
812 |
645 # Check that all categories have an order. |
813 # Check that all categories have an order. |
646 missing_order = set(topiccats.keys()) - set(TOPIC_CATEGORY_ORDER) |
814 missing_order = set(topiccats.keys()) - set(TOPIC_CATEGORY_ORDER) |
647 if missing_order: |
815 if missing_order: |
648 ui.develwarn( |
816 ui.develwarn( |
649 'help categories missing from TOPIC_CATEGORY_ORDER: %s' % |
817 'help categories missing from TOPIC_CATEGORY_ORDER: %s' |
650 missing_order) |
818 % missing_order |
819 ) |
|
651 |
820 |
652 # Output topics per category. |
821 # Output topics per category. |
653 for cat in TOPIC_CATEGORY_ORDER: |
822 for cat in TOPIC_CATEGORY_ORDER: |
654 topics = topiccats.get(cat, []) |
823 topics = topiccats.get(cat, []) |
655 if topics: |
824 if topics: |
661 rst.append(" :%s: %s\n" % (t, desc)) |
830 rst.append(" :%s: %s\n" % (t, desc)) |
662 |
831 |
663 if ui.quiet: |
832 if ui.quiet: |
664 pass |
833 pass |
665 elif ui.verbose: |
834 elif ui.verbose: |
666 rst.append('\n%s\n' % optrst(_("global options"), |
835 rst.append( |
667 commands.globalopts, ui.verbose)) |
836 '\n%s\n' |
837 % optrst(_("global options"), commands.globalopts, ui.verbose) |
|
838 ) |
|
668 if name == 'shortlist': |
839 if name == 'shortlist': |
669 rst.append(_("\n(use 'hg help' for the full list " |
840 rst.append( |
670 "of commands)\n")) |
841 _("\n(use 'hg help' for the full list " "of commands)\n") |
842 ) |
|
671 else: |
843 else: |
672 if name == 'shortlist': |
844 if name == 'shortlist': |
673 rst.append(_("\n(use 'hg help' for the full list of commands " |
845 rst.append( |
674 "or 'hg -v' for details)\n")) |
846 _( |
847 "\n(use 'hg help' for the full list of commands " |
|
848 "or 'hg -v' for details)\n" |
|
849 ) |
|
850 ) |
|
675 elif name and not full: |
851 elif name and not full: |
676 rst.append(_("\n(use 'hg help %s' to show the full help " |
852 rst.append( |
677 "text)\n") % name) |
853 _("\n(use 'hg help %s' to show the full help " "text)\n") |
854 % name |
|
855 ) |
|
678 elif name and syns and name in syns.keys(): |
856 elif name and syns and name in syns.keys(): |
679 rst.append(_("\n(use 'hg help -v -e %s' to show built-in " |
857 rst.append( |
680 "aliases and global options)\n") % name) |
858 _( |
859 "\n(use 'hg help -v -e %s' to show built-in " |
|
860 "aliases and global options)\n" |
|
861 ) |
|
862 % name |
|
863 ) |
|
681 else: |
864 else: |
682 rst.append(_("\n(use 'hg help -v%s' to show built-in aliases " |
865 rst.append( |
683 "and global options)\n") |
866 _( |
684 % (name and " " + name or "")) |
867 "\n(use 'hg help -v%s' to show built-in aliases " |
868 "and global options)\n" |
|
869 ) |
|
870 % (name and " " + name or "") |
|
871 ) |
|
685 return rst |
872 return rst |
686 |
873 |
687 def helptopic(name, subtopic=None): |
874 def helptopic(name, subtopic=None): |
688 # Look for sub-topic entry first. |
875 # Look for sub-topic entry first. |
689 header, doc = None, None |
876 header, doc = None, None |
709 rst.append(" %s\n" % _("(no help text available)")) |
896 rst.append(" %s\n" % _("(no help text available)")) |
710 if callable(doc): |
897 if callable(doc): |
711 rst += [" %s\n" % l for l in doc(ui).splitlines()] |
898 rst += [" %s\n" % l for l in doc(ui).splitlines()] |
712 |
899 |
713 if not ui.verbose: |
900 if not ui.verbose: |
714 omitted = _('(some details hidden, use --verbose' |
901 omitted = _( |
715 ' to show complete help)') |
902 '(some details hidden, use --verbose' ' to show complete help)' |
903 ) |
|
716 indicateomitted(rst, omitted) |
904 indicateomitted(rst, omitted) |
717 |
905 |
718 try: |
906 try: |
719 cmdutil.findcmd(name, commands.table) |
907 cmdutil.findcmd(name, commands.table) |
720 rst.append(_("\nuse 'hg help -c %s' to see help for " |
908 rst.append( |
721 "the %s command\n") % (name, name)) |
909 _("\nuse 'hg help -c %s' to see help for " "the %s command\n") |
910 % (name, name) |
|
911 ) |
|
722 except error.UnknownCommand: |
912 except error.UnknownCommand: |
723 pass |
913 pass |
724 return rst |
914 return rst |
725 |
915 |
726 def helpext(name, subtopic=None): |
916 def helpext(name, subtopic=None): |
741 if tail: |
931 if tail: |
742 rst.extend(tail.splitlines(True)) |
932 rst.extend(tail.splitlines(True)) |
743 rst.append('\n') |
933 rst.append('\n') |
744 |
934 |
745 if not ui.verbose: |
935 if not ui.verbose: |
746 omitted = _('(some details hidden, use --verbose' |
936 omitted = _( |
747 ' to show complete help)') |
937 '(some details hidden, use --verbose' ' to show complete help)' |
938 ) |
|
748 indicateomitted(rst, omitted) |
939 indicateomitted(rst, omitted) |
749 |
940 |
750 if mod: |
941 if mod: |
751 try: |
942 try: |
752 ct = mod.cmdtable |
943 ct = mod.cmdtable |
753 except AttributeError: |
944 except AttributeError: |
754 ct = {} |
945 ct = {} |
755 modcmds = {c.partition('|')[0] for c in ct} |
946 modcmds = {c.partition('|')[0] for c in ct} |
756 rst.extend(helplist(modcmds.__contains__)) |
947 rst.extend(helplist(modcmds.__contains__)) |
757 else: |
948 else: |
758 rst.append(_("(use 'hg help extensions' for information on enabling" |
949 rst.append( |
759 " extensions)\n")) |
950 _( |
951 "(use 'hg help extensions' for information on enabling" |
|
952 " extensions)\n" |
|
953 ) |
|
954 ) |
|
760 return rst |
955 return rst |
761 |
956 |
762 def helpextcmd(name, subtopic=None): |
957 def helpextcmd(name, subtopic=None): |
763 cmd, ext, doc = extensions.disabledcmd(ui, name, |
958 cmd, ext, doc = extensions.disabledcmd( |
764 ui.configbool('ui', 'strict')) |
959 ui, name, ui.configbool('ui', 'strict') |
960 ) |
|
765 doc = doc.splitlines()[0] |
961 doc = doc.splitlines()[0] |
766 |
962 |
767 rst = listexts(_("'%s' is provided by the following " |
963 rst = listexts( |
768 "extension:") % cmd, {ext: doc}, indent=4, |
964 _("'%s' is provided by the following " "extension:") % cmd, |
769 showdeprecated=True) |
965 {ext: doc}, |
966 indent=4, |
|
967 showdeprecated=True, |
|
968 ) |
|
770 rst.append('\n') |
969 rst.append('\n') |
771 rst.append(_("(use 'hg help extensions' for information on enabling " |
970 rst.append( |
772 "extensions)\n")) |
971 _( |
972 "(use 'hg help extensions' for information on enabling " |
|
973 "extensions)\n" |
|
974 ) |
|
975 ) |
|
773 return rst |
976 return rst |
774 |
|
775 |
977 |
776 rst = [] |
978 rst = [] |
777 kw = opts.get('keyword') |
979 kw = opts.get('keyword') |
778 if kw or name is None and any(opts[o] for o in opts): |
980 if kw or name is None and any(opts[o] for o in opts): |
779 matches = topicmatch(ui, commands, name or '') |
981 matches = topicmatch(ui, commands, name or '') |
781 if opts.get('extension'): |
983 if opts.get('extension'): |
782 helpareas += [('extensions', _('Extensions'))] |
984 helpareas += [('extensions', _('Extensions'))] |
783 if opts.get('command'): |
985 if opts.get('command'): |
784 helpareas += [('commands', _('Commands'))] |
986 helpareas += [('commands', _('Commands'))] |
785 if not helpareas: |
987 if not helpareas: |
786 helpareas = [('topics', _('Topics')), |
988 helpareas = [ |
787 ('commands', _('Commands')), |
989 ('topics', _('Topics')), |
788 ('extensions', _('Extensions')), |
990 ('commands', _('Commands')), |
789 ('extensioncommands', _('Extension Commands'))] |
991 ('extensions', _('Extensions')), |
992 ('extensioncommands', _('Extension Commands')), |
|
993 ] |
|
790 for t, title in helpareas: |
994 for t, title in helpareas: |
791 if matches[t]: |
995 if matches[t]: |
792 rst.append('%s:\n\n' % title) |
996 rst.append('%s:\n\n' % title) |
793 rst.extend(minirst.maketable(sorted(matches[t]), 1)) |
997 rst.extend(minirst.maketable(sorted(matches[t]), 1)) |
794 rst.append('\n') |
998 rst.append('\n') |
833 rst = [_("Mercurial Distributed SCM\n"), '\n'] |
1037 rst = [_("Mercurial Distributed SCM\n"), '\n'] |
834 rst.extend(helplist(None, **pycompat.strkwargs(opts))) |
1038 rst.extend(helplist(None, **pycompat.strkwargs(opts))) |
835 |
1039 |
836 return ''.join(rst) |
1040 return ''.join(rst) |
837 |
1041 |
838 def formattedhelp(ui, commands, fullname, keep=None, unknowncmd=False, |
1042 |
839 full=True, **opts): |
1043 def formattedhelp( |
1044 ui, commands, fullname, keep=None, unknowncmd=False, full=True, **opts |
|
1045 ): |
|
840 """get help for a given topic (as a dotted name) as rendered rst |
1046 """get help for a given topic (as a dotted name) as rendered rst |
841 |
1047 |
842 Either returns the rendered help text or raises an exception. |
1048 Either returns the rendered help text or raises an exception. |
843 """ |
1049 """ |
844 if keep is None: |
1050 if keep is None: |
845 keep = [] |
1051 keep = [] |
846 else: |
1052 else: |
847 keep = list(keep) # make a copy so we can mutate this later |
1053 keep = list(keep) # make a copy so we can mutate this later |
848 |
1054 |
849 # <fullname> := <name>[.<subtopic][.<section>] |
1055 # <fullname> := <name>[.<subtopic][.<section>] |
850 name = subtopic = section = None |
1056 name = subtopic = section = None |
851 if fullname is not None: |
1057 if fullname is not None: |
852 nameparts = fullname.split('.') |
1058 nameparts = fullname.split('.') |
858 |
1064 |
859 textwidth = ui.configint('ui', 'textwidth') |
1065 textwidth = ui.configint('ui', 'textwidth') |
860 termwidth = ui.termwidth() - 2 |
1066 termwidth = ui.termwidth() - 2 |
861 if textwidth <= 0 or termwidth < textwidth: |
1067 if textwidth <= 0 or termwidth < textwidth: |
862 textwidth = termwidth |
1068 textwidth = termwidth |
863 text = help_(ui, commands, name, fullname=fullname, |
1069 text = help_( |
864 subtopic=subtopic, unknowncmd=unknowncmd, full=full, **opts) |
1070 ui, |
1071 commands, |
|
1072 name, |
|
1073 fullname=fullname, |
|
1074 subtopic=subtopic, |
|
1075 unknowncmd=unknowncmd, |
|
1076 full=full, |
|
1077 **opts |
|
1078 ) |
|
865 |
1079 |
866 blocks, pruned = minirst.parse(text, keep=keep) |
1080 blocks, pruned = minirst.parse(text, keep=keep) |
867 if 'verbose' in pruned: |
1081 if 'verbose' in pruned: |
868 keep.append('omitted') |
1082 keep.append('omitted') |
869 else: |
1083 else: |