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, incorporated herein by reference. |
6 # GNU General Public License version 2, incorporated herein by reference. |
7 |
7 |
8 from i18n import _ |
8 import os, sys |
|
9 from i18n import _, gettext |
|
10 import extensions |
|
11 |
|
12 |
|
13 # borrowed from pydoc |
|
14 def pathdirs(): |
|
15 '''Convert sys.path into a list of absolute, existing, unique paths.''' |
|
16 dirs = [] |
|
17 normdirs = [] |
|
18 for dir in sys.path: |
|
19 dir = os.path.abspath(dir or '.') |
|
20 normdir = os.path.normcase(dir) |
|
21 if normdir not in normdirs and os.path.isdir(dir): |
|
22 dirs.append(dir) |
|
23 normdirs.append(normdir) |
|
24 return dirs |
|
25 |
|
26 # loosely inspired by pydoc.source_synopsis() |
|
27 # rewritten to handle ''' as well as """ |
|
28 # and to return the whole text instead of just the synopsis |
|
29 def moduledoc(file): |
|
30 '''Return the top python documentation for the given file''' |
|
31 result = [] |
|
32 |
|
33 line = file.readline() |
|
34 while line[:1] == '#' or not line.strip(): |
|
35 line = file.readline() |
|
36 if not line: break |
|
37 |
|
38 start = line[:3] |
|
39 if start == '"""' or start == "'''": |
|
40 line = line[3:] |
|
41 while line: |
|
42 if line.rstrip().endswith(start): |
|
43 line = line.split(start)[0] |
|
44 if line: |
|
45 result.append(line) |
|
46 break |
|
47 elif not line: |
|
48 return None # unmatched delimiter |
|
49 result.append(line) |
|
50 line = file.readline() |
|
51 else: |
|
52 return None |
|
53 |
|
54 return ''.join(result) |
|
55 |
|
56 def additionalextensions(): |
|
57 '''Find the extensions shipped with Mercurial but not enabled |
|
58 |
|
59 Returns extensions names and descriptions, and the max name length |
|
60 ''' |
|
61 exts = {} |
|
62 maxlength = 0 |
|
63 |
|
64 for dir in filter(os.path.isdir, |
|
65 (os.path.join(pd, 'hgext') for pd in pathdirs())): |
|
66 for e in os.listdir(dir): |
|
67 if e.endswith('.py'): |
|
68 name = e.rsplit('.', 1)[0] |
|
69 path = os.path.join(dir, e) |
|
70 else: |
|
71 name = e |
|
72 path = os.path.join(dir, e, '__init__.py') |
|
73 |
|
74 if name in exts or name == '__init__' or not os.path.exists(path): |
|
75 continue |
|
76 |
|
77 try: |
|
78 extensions.find(name) |
|
79 except KeyError: |
|
80 pass |
|
81 else: |
|
82 continue # enabled extension |
|
83 |
|
84 try: |
|
85 file = open(path) |
|
86 except IOError: |
|
87 continue |
|
88 else: |
|
89 doc = moduledoc(file) |
|
90 file.close() |
|
91 |
|
92 if doc: # extracting localized synopsis |
|
93 exts[name] = gettext(doc).splitlines()[0] |
|
94 else: |
|
95 exts[name] = _('(no help text available)') |
|
96 if len(name) > maxlength: |
|
97 maxlength = len(name) |
|
98 |
|
99 return exts, maxlength |
|
100 |
|
101 def topicextensions(): |
|
102 doc = _(r''' |
|
103 Mercurial has an extension mechanism for adding new features. |
|
104 |
|
105 To enable an extension "foo" bundled with Mercurial, create an |
|
106 entry for it your hgrc, like this: |
|
107 |
|
108 [extensions] |
|
109 foo = |
|
110 ''') |
|
111 |
|
112 exts, maxlength = additionalextensions() |
|
113 if exts: |
|
114 doc += _('\nnon-enabled extensions:\n\n') |
|
115 for name, desc in sorted(exts.iteritems()): |
|
116 doc += ' %s %s\n' % (name.ljust(maxlength), desc) |
|
117 |
|
118 return doc |
9 |
119 |
10 helptable = ( |
120 helptable = ( |
11 (["dates"], _("Date Formats"), |
121 (["dates"], _("Date Formats"), |
12 _(r''' |
122 _(r''' |
13 Some commands allow the user to specify a date, e.g.: |
123 Some commands allow the user to specify a date, e.g.: |