##// END OF EJS Templates
help: add 'mergetools' alias for the 'merge-tools' help topic...
Mads Kiilerich -
r17323:2be2a070 stable
parent child Browse files
Show More
@@ -1,203 +1,203
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, sys, os
9 import itertools, sys, os
10 import extensions, revset, fileset, templatekw, templatefilters, filemerge
10 import extensions, revset, fileset, templatekw, templatefilters, filemerge
11 import encoding, util, minirst
11 import encoding, util, minirst
12
12
13 def listexts(header, exts, indent=1):
13 def listexts(header, exts, indent=1):
14 '''return a text listing of the given extensions'''
14 '''return a text listing of the given extensions'''
15 rst = []
15 rst = []
16 if exts:
16 if exts:
17 rst.append('\n%s\n\n' % header)
17 rst.append('\n%s\n\n' % header)
18 for name, desc in sorted(exts.iteritems()):
18 for name, desc in sorted(exts.iteritems()):
19 rst.append('%s:%s: %s\n' % (' ' * indent, name, desc))
19 rst.append('%s:%s: %s\n' % (' ' * indent, name, desc))
20 return rst
20 return rst
21
21
22 def extshelp():
22 def extshelp():
23 rst = loaddoc('extensions')().splitlines(True)
23 rst = loaddoc('extensions')().splitlines(True)
24 rst.extend(listexts(_('enabled extensions:'), extensions.enabled()))
24 rst.extend(listexts(_('enabled extensions:'), extensions.enabled()))
25 rst.extend(listexts(_('disabled extensions:'), extensions.disabled()))
25 rst.extend(listexts(_('disabled extensions:'), extensions.disabled()))
26 doc = ''.join(rst)
26 doc = ''.join(rst)
27 return doc
27 return doc
28
28
29 def optrst(options, verbose):
29 def optrst(options, verbose):
30 data = []
30 data = []
31 multioccur = False
31 multioccur = False
32 for option in options:
32 for option in options:
33 if len(option) == 5:
33 if len(option) == 5:
34 shortopt, longopt, default, desc, optlabel = option
34 shortopt, longopt, default, desc, optlabel = option
35 else:
35 else:
36 shortopt, longopt, default, desc = option
36 shortopt, longopt, default, desc = option
37 optlabel = _("VALUE") # default label
37 optlabel = _("VALUE") # default label
38
38
39 if _("DEPRECATED") in desc and not verbose:
39 if _("DEPRECATED") in desc and not verbose:
40 continue
40 continue
41
41
42 so = ''
42 so = ''
43 if shortopt:
43 if shortopt:
44 so = '-' + shortopt
44 so = '-' + shortopt
45 lo = '--' + longopt
45 lo = '--' + longopt
46 if default:
46 if default:
47 desc += _(" (default: %s)") % default
47 desc += _(" (default: %s)") % default
48
48
49 if isinstance(default, list):
49 if isinstance(default, list):
50 lo += " %s [+]" % optlabel
50 lo += " %s [+]" % optlabel
51 multioccur = True
51 multioccur = True
52 elif (default is not None) and not isinstance(default, bool):
52 elif (default is not None) and not isinstance(default, bool):
53 lo += " %s" % optlabel
53 lo += " %s" % optlabel
54
54
55 data.append((so, lo, desc))
55 data.append((so, lo, desc))
56
56
57 rst = minirst.maketable(data, 1)
57 rst = minirst.maketable(data, 1)
58
58
59 if multioccur:
59 if multioccur:
60 rst.append(_("\n[+] marked option can be specified multiple times\n"))
60 rst.append(_("\n[+] marked option can be specified multiple times\n"))
61
61
62 return ''.join(rst)
62 return ''.join(rst)
63
63
64 def topicmatch(kw):
64 def topicmatch(kw):
65 """Return help topics matching kw.
65 """Return help topics matching kw.
66
66
67 Returns {'section': [(name, summary), ...], ...} where section is
67 Returns {'section': [(name, summary), ...], ...} where section is
68 one of topics, commands, extensions, or extensioncommands.
68 one of topics, commands, extensions, or extensioncommands.
69 """
69 """
70 kw = encoding.lower(kw)
70 kw = encoding.lower(kw)
71 def lowercontains(container):
71 def lowercontains(container):
72 return kw in encoding.lower(container) # translated in helptable
72 return kw in encoding.lower(container) # translated in helptable
73 results = {'topics': [],
73 results = {'topics': [],
74 'commands': [],
74 'commands': [],
75 'extensions': [],
75 'extensions': [],
76 'extensioncommands': [],
76 'extensioncommands': [],
77 }
77 }
78 for names, header, doc in helptable:
78 for names, header, doc in helptable:
79 if (sum(map(lowercontains, names))
79 if (sum(map(lowercontains, names))
80 or lowercontains(header)
80 or lowercontains(header)
81 or lowercontains(doc())):
81 or lowercontains(doc())):
82 results['topics'].append((names[0], header))
82 results['topics'].append((names[0], header))
83 import commands # avoid cycle
83 import commands # avoid cycle
84 for cmd, entry in commands.table.iteritems():
84 for cmd, entry in commands.table.iteritems():
85 if cmd.startswith('debug'):
85 if cmd.startswith('debug'):
86 continue
86 continue
87 if len(entry) == 3:
87 if len(entry) == 3:
88 summary = entry[2]
88 summary = entry[2]
89 else:
89 else:
90 summary = ''
90 summary = ''
91 # translate docs *before* searching there
91 # translate docs *before* searching there
92 docs = _(getattr(entry[0], '__doc__', None)) or ''
92 docs = _(getattr(entry[0], '__doc__', None)) or ''
93 if kw in cmd or lowercontains(summary) or lowercontains(docs):
93 if kw in cmd or lowercontains(summary) or lowercontains(docs):
94 doclines = docs.splitlines()
94 doclines = docs.splitlines()
95 if doclines:
95 if doclines:
96 summary = doclines[0]
96 summary = doclines[0]
97 cmdname = cmd.split('|')[0].lstrip('^')
97 cmdname = cmd.split('|')[0].lstrip('^')
98 results['commands'].append((cmdname, summary))
98 results['commands'].append((cmdname, summary))
99 for name, docs in itertools.chain(
99 for name, docs in itertools.chain(
100 extensions.enabled().iteritems(),
100 extensions.enabled().iteritems(),
101 extensions.disabled().iteritems()):
101 extensions.disabled().iteritems()):
102 # extensions.load ignores the UI argument
102 # extensions.load ignores the UI argument
103 mod = extensions.load(None, name, '')
103 mod = extensions.load(None, name, '')
104 if lowercontains(name) or lowercontains(docs):
104 if lowercontains(name) or lowercontains(docs):
105 # extension docs are already translated
105 # extension docs are already translated
106 results['extensions'].append((name, docs.splitlines()[0]))
106 results['extensions'].append((name, docs.splitlines()[0]))
107 for cmd, entry in getattr(mod, 'cmdtable', {}).iteritems():
107 for cmd, entry in getattr(mod, 'cmdtable', {}).iteritems():
108 if kw in cmd or (len(entry) > 2 and lowercontains(entry[2])):
108 if kw in cmd or (len(entry) > 2 and lowercontains(entry[2])):
109 cmdname = cmd.split('|')[0].lstrip('^')
109 cmdname = cmd.split('|')[0].lstrip('^')
110 if entry[0].__doc__:
110 if entry[0].__doc__:
111 cmddoc = gettext(entry[0].__doc__).splitlines()[0]
111 cmddoc = gettext(entry[0].__doc__).splitlines()[0]
112 else:
112 else:
113 cmddoc = _('(no help text available)')
113 cmddoc = _('(no help text available)')
114 results['extensioncommands'].append((cmdname, cmddoc))
114 results['extensioncommands'].append((cmdname, cmddoc))
115 return results
115 return results
116
116
117 def loaddoc(topic):
117 def loaddoc(topic):
118 """Return a delayed loader for help/topic.txt."""
118 """Return a delayed loader for help/topic.txt."""
119
119
120 def loader():
120 def loader():
121 if util.mainfrozen():
121 if util.mainfrozen():
122 module = sys.executable
122 module = sys.executable
123 else:
123 else:
124 module = __file__
124 module = __file__
125 base = os.path.dirname(module)
125 base = os.path.dirname(module)
126
126
127 for dir in ('.', '..'):
127 for dir in ('.', '..'):
128 docdir = os.path.join(base, dir, 'help')
128 docdir = os.path.join(base, dir, 'help')
129 if os.path.isdir(docdir):
129 if os.path.isdir(docdir):
130 break
130 break
131
131
132 path = os.path.join(docdir, topic + ".txt")
132 path = os.path.join(docdir, topic + ".txt")
133 doc = gettext(util.readfile(path))
133 doc = gettext(util.readfile(path))
134 for rewriter in helphooks.get(topic, []):
134 for rewriter in helphooks.get(topic, []):
135 doc = rewriter(topic, doc)
135 doc = rewriter(topic, doc)
136 return doc
136 return doc
137
137
138 return loader
138 return loader
139
139
140 helptable = sorted([
140 helptable = sorted([
141 (["config", "hgrc"], _("Configuration Files"), loaddoc('config')),
141 (["config", "hgrc"], _("Configuration Files"), loaddoc('config')),
142 (["dates"], _("Date Formats"), loaddoc('dates')),
142 (["dates"], _("Date Formats"), loaddoc('dates')),
143 (["patterns"], _("File Name Patterns"), loaddoc('patterns')),
143 (["patterns"], _("File Name Patterns"), loaddoc('patterns')),
144 (['environment', 'env'], _('Environment Variables'),
144 (['environment', 'env'], _('Environment Variables'),
145 loaddoc('environment')),
145 loaddoc('environment')),
146 (['revisions', 'revs'], _('Specifying Single Revisions'),
146 (['revisions', 'revs'], _('Specifying Single Revisions'),
147 loaddoc('revisions')),
147 loaddoc('revisions')),
148 (['multirevs', 'mrevs'], _('Specifying Multiple Revisions'),
148 (['multirevs', 'mrevs'], _('Specifying Multiple Revisions'),
149 loaddoc('multirevs')),
149 loaddoc('multirevs')),
150 (['revsets', 'revset'], _("Specifying Revision Sets"), loaddoc('revsets')),
150 (['revsets', 'revset'], _("Specifying Revision Sets"), loaddoc('revsets')),
151 (['filesets', 'fileset'], _("Specifying File Sets"), loaddoc('filesets')),
151 (['filesets', 'fileset'], _("Specifying File Sets"), loaddoc('filesets')),
152 (['diffs'], _('Diff Formats'), loaddoc('diffs')),
152 (['diffs'], _('Diff Formats'), loaddoc('diffs')),
153 (['merge-tools'], _('Merge Tools'), loaddoc('merge-tools')),
153 (['merge-tools', 'mergetools'], _('Merge Tools'), loaddoc('merge-tools')),
154 (['templating', 'templates', 'template', 'style'], _('Template Usage'),
154 (['templating', 'templates', 'template', 'style'], _('Template Usage'),
155 loaddoc('templates')),
155 loaddoc('templates')),
156 (['urls'], _('URL Paths'), loaddoc('urls')),
156 (['urls'], _('URL Paths'), loaddoc('urls')),
157 (["extensions"], _("Using Additional Features"), extshelp),
157 (["extensions"], _("Using Additional Features"), extshelp),
158 (["subrepos", "subrepo"], _("Subrepositories"), loaddoc('subrepos')),
158 (["subrepos", "subrepo"], _("Subrepositories"), loaddoc('subrepos')),
159 (["hgweb"], _("Configuring hgweb"), loaddoc('hgweb')),
159 (["hgweb"], _("Configuring hgweb"), loaddoc('hgweb')),
160 (["glossary"], _("Glossary"), loaddoc('glossary')),
160 (["glossary"], _("Glossary"), loaddoc('glossary')),
161 (["hgignore", "ignore"], _("Syntax for Mercurial Ignore Files"),
161 (["hgignore", "ignore"], _("Syntax for Mercurial Ignore Files"),
162 loaddoc('hgignore')),
162 loaddoc('hgignore')),
163 (["phases"], _("Working with Phases"), loaddoc('phases')),
163 (["phases"], _("Working with Phases"), loaddoc('phases')),
164 ])
164 ])
165
165
166 # Map topics to lists of callable taking the current topic help and
166 # Map topics to lists of callable taking the current topic help and
167 # returning the updated version
167 # returning the updated version
168 helphooks = {}
168 helphooks = {}
169
169
170 def addtopichook(topic, rewriter):
170 def addtopichook(topic, rewriter):
171 helphooks.setdefault(topic, []).append(rewriter)
171 helphooks.setdefault(topic, []).append(rewriter)
172
172
173 def makeitemsdoc(topic, doc, marker, items):
173 def makeitemsdoc(topic, doc, marker, items):
174 """Extract docstring from the items key to function mapping, build a
174 """Extract docstring from the items key to function mapping, build a
175 .single documentation block and use it to overwrite the marker in doc
175 .single documentation block and use it to overwrite the marker in doc
176 """
176 """
177 entries = []
177 entries = []
178 for name in sorted(items):
178 for name in sorted(items):
179 text = (items[name].__doc__ or '').rstrip()
179 text = (items[name].__doc__ or '').rstrip()
180 if not text:
180 if not text:
181 continue
181 continue
182 text = gettext(text)
182 text = gettext(text)
183 lines = text.splitlines()
183 lines = text.splitlines()
184 doclines = [(lines[0])]
184 doclines = [(lines[0])]
185 for l in lines[1:]:
185 for l in lines[1:]:
186 # Stop once we find some Python doctest
186 # Stop once we find some Python doctest
187 if l.strip().startswith('>>>'):
187 if l.strip().startswith('>>>'):
188 break
188 break
189 doclines.append(' ' + l.strip())
189 doclines.append(' ' + l.strip())
190 entries.append('\n'.join(doclines))
190 entries.append('\n'.join(doclines))
191 entries = '\n\n'.join(entries)
191 entries = '\n\n'.join(entries)
192 return doc.replace(marker, entries)
192 return doc.replace(marker, entries)
193
193
194 def addtopicsymbols(topic, marker, symbols):
194 def addtopicsymbols(topic, marker, symbols):
195 def add(topic, doc):
195 def add(topic, doc):
196 return makeitemsdoc(topic, doc, marker, symbols)
196 return makeitemsdoc(topic, doc, marker, symbols)
197 addtopichook(topic, add)
197 addtopichook(topic, add)
198
198
199 addtopicsymbols('filesets', '.. predicatesmarker', fileset.symbols)
199 addtopicsymbols('filesets', '.. predicatesmarker', fileset.symbols)
200 addtopicsymbols('merge-tools', '.. internaltoolsmarker', filemerge.internals)
200 addtopicsymbols('merge-tools', '.. internaltoolsmarker', filemerge.internals)
201 addtopicsymbols('revsets', '.. predicatesmarker', revset.symbols)
201 addtopicsymbols('revsets', '.. predicatesmarker', revset.symbols)
202 addtopicsymbols('templates', '.. keywordsmarker', templatekw.dockeywords)
202 addtopicsymbols('templates', '.. keywordsmarker', templatekw.dockeywords)
203 addtopicsymbols('templates', '.. filtersmarker', templatefilters.filters)
203 addtopicsymbols('templates', '.. filtersmarker', templatefilters.filters)
General Comments 0
You need to be logged in to leave comments. Login now