Show More
@@ -1,198 +1,199 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 | """Word completion for GNU readline 2.0. |
|
2 | """Word completion for GNU readline 2.0. | |
3 |
|
3 | |||
4 | --------------------------------------------------------------------------- |
|
4 | --------------------------------------------------------------------------- | |
5 | NOTE: This version is a re-implementation of rlcompleter with selectable |
|
5 | NOTE: This version is a re-implementation of rlcompleter with selectable | |
6 | namespace. |
|
6 | namespace. | |
7 |
|
7 | |||
8 | The problem with rlcompleter is that it's hardwired to work with |
|
8 | The problem with rlcompleter is that it's hardwired to work with | |
9 | __main__.__dict__, and in some cases one may have 'sandboxed' namespaces. So |
|
9 | __main__.__dict__, and in some cases one may have 'sandboxed' namespaces. So | |
10 | this class is a ripoff of rlcompleter, with the namespace to work in as an |
|
10 | this class is a ripoff of rlcompleter, with the namespace to work in as an | |
11 | optional parameter. |
|
11 | optional parameter. | |
12 |
|
12 | |||
13 | This class can be used just like rlcompleter, but the Completer class now has |
|
13 | This class can be used just like rlcompleter, but the Completer class now has | |
14 | a constructor with the optional 'namespace' parameter. |
|
14 | a constructor with the optional 'namespace' parameter. | |
15 |
|
15 | |||
16 | A patch has been submitted to Python@sourceforge for these changes to go in |
|
16 | A patch has been submitted to Python@sourceforge for these changes to go in | |
17 | the standard Python distribution. |
|
17 | the standard Python distribution. | |
18 |
|
18 | |||
19 | The patch went in for Python 2.3. Once IPython drops support for Python 2.2, |
|
19 | The patch went in for Python 2.3. Once IPython drops support for Python 2.2, | |
20 | this file can be significantly reduced. |
|
20 | this file can be significantly reduced. | |
21 | --------------------------------------------------------------------------- |
|
21 | --------------------------------------------------------------------------- | |
22 |
|
22 | |||
23 | Original rlcompleter documentation: |
|
23 | Original rlcompleter documentation: | |
24 |
|
24 | |||
25 | This requires the latest extension to the readline module (the |
|
25 | This requires the latest extension to the readline module (the | |
26 | completes keywords, built-ins and globals in __main__; when completing |
|
26 | completes keywords, built-ins and globals in __main__; when completing | |
27 | NAME.NAME..., it evaluates (!) the expression up to the last dot and |
|
27 | NAME.NAME..., it evaluates (!) the expression up to the last dot and | |
28 | completes its attributes. |
|
28 | completes its attributes. | |
29 |
|
29 | |||
30 | It's very cool to do "import string" type "string.", hit the |
|
30 | It's very cool to do "import string" type "string.", hit the | |
31 | completion key (twice), and see the list of names defined by the |
|
31 | completion key (twice), and see the list of names defined by the | |
32 | string module! |
|
32 | string module! | |
33 |
|
33 | |||
34 | Tip: to use the tab key as the completion key, call |
|
34 | Tip: to use the tab key as the completion key, call | |
35 |
|
35 | |||
36 | readline.parse_and_bind("tab: complete") |
|
36 | readline.parse_and_bind("tab: complete") | |
37 |
|
37 | |||
38 | Notes: |
|
38 | Notes: | |
39 |
|
39 | |||
40 | - Exceptions raised by the completer function are *ignored* (and |
|
40 | - Exceptions raised by the completer function are *ignored* (and | |
41 | generally cause the completion to fail). This is a feature -- since |
|
41 | generally cause the completion to fail). This is a feature -- since | |
42 | readline sets the tty device in raw (or cbreak) mode, printing a |
|
42 | readline sets the tty device in raw (or cbreak) mode, printing a | |
43 | traceback wouldn't work well without some complicated hoopla to save, |
|
43 | traceback wouldn't work well without some complicated hoopla to save, | |
44 | reset and restore the tty state. |
|
44 | reset and restore the tty state. | |
45 |
|
45 | |||
46 | - The evaluation of the NAME.NAME... form may cause arbitrary |
|
46 | - The evaluation of the NAME.NAME... form may cause arbitrary | |
47 | application defined code to be executed if an object with a |
|
47 | application defined code to be executed if an object with a | |
48 | __getattr__ hook is found. Since it is the responsibility of the |
|
48 | __getattr__ hook is found. Since it is the responsibility of the | |
49 | application (or the user) to enable this feature, I consider this an |
|
49 | application (or the user) to enable this feature, I consider this an | |
50 | acceptable risk. More complicated expressions (e.g. function calls or |
|
50 | acceptable risk. More complicated expressions (e.g. function calls or | |
51 | indexing operations) are *not* evaluated. |
|
51 | indexing operations) are *not* evaluated. | |
52 |
|
52 | |||
53 | - GNU readline is also used by the built-in functions input() and |
|
53 | - GNU readline is also used by the built-in functions input() and | |
54 | raw_input(), and thus these also benefit/suffer from the completer |
|
54 | raw_input(), and thus these also benefit/suffer from the completer | |
55 | features. Clearly an interactive application can benefit by |
|
55 | features. Clearly an interactive application can benefit by | |
56 | specifying its own completer function and using raw_input() for all |
|
56 | specifying its own completer function and using raw_input() for all | |
57 | its input. |
|
57 | its input. | |
58 |
|
58 | |||
59 | - When the original stdin is not a tty device, GNU readline is never |
|
59 | - When the original stdin is not a tty device, GNU readline is never | |
60 | used, and this module (and the readline module) are silently inactive. |
|
60 | used, and this module (and the readline module) are silently inactive. | |
61 |
|
61 | |||
62 | """ |
|
62 | """ | |
63 |
|
63 | |||
64 | #***************************************************************************** |
|
64 | #***************************************************************************** | |
65 | # |
|
65 | # | |
66 | # Since this file is essentially a minimally modified copy of the rlcompleter |
|
66 | # Since this file is essentially a minimally modified copy of the rlcompleter | |
67 | # module which is part of the standard Python distribution, I assume that the |
|
67 | # module which is part of the standard Python distribution, I assume that the | |
68 | # proper procedure is to maintain its copyright as belonging to the Python |
|
68 | # proper procedure is to maintain its copyright as belonging to the Python | |
69 | # Software Foundation: |
|
69 | # Software Foundation: | |
70 | # |
|
70 | # | |
71 | # Copyright (C) 2001 Python Software Foundation, www.python.org |
|
71 | # Copyright (C) 2001 Python Software Foundation, www.python.org | |
72 | # |
|
72 | # | |
73 | # Distributed under the terms of the Python Software Foundation license. |
|
73 | # Distributed under the terms of the Python Software Foundation license. | |
74 | # |
|
74 | # | |
75 | # Full text available at: |
|
75 | # Full text available at: | |
76 | # |
|
76 | # | |
77 | # http://www.python.org/2.1/license.html |
|
77 | # http://www.python.org/2.1/license.html | |
78 | # |
|
78 | # | |
79 | #***************************************************************************** |
|
79 | #***************************************************************************** | |
80 |
|
80 | |||
81 | import readline |
|
81 | import readline | |
82 | import __builtin__ |
|
82 | import __builtin__ | |
83 | import __main__ |
|
83 | import __main__ | |
84 |
|
84 | |||
85 | __all__ = ["Completer"] |
|
85 | __all__ = ["Completer"] | |
86 |
|
86 | |||
|
87 | # declares Python 2.2 compatibility symbols: | |||
|
88 | try: | |||
|
89 | basestring | |||
|
90 | except NameError: | |||
|
91 | import types | |||
|
92 | basestring = (types.StringType, types.UnicodeType) | |||
|
93 | ||||
87 | class Completer: |
|
94 | class Completer: | |
88 | def __init__(self, namespace = None): |
|
95 | def __init__(self, namespace = None): | |
89 | """Create a new completer for the command line. |
|
96 | """Create a new completer for the command line. | |
90 |
|
97 | |||
91 | Completer([namespace]) -> completer instance. |
|
98 | Completer([namespace]) -> completer instance. | |
92 |
|
99 | |||
93 | If unspecified, the default namespace where completions are performed |
|
100 | If unspecified, the default namespace where completions are performed | |
94 | is __main__ (technically, __main__.__dict__). Namespaces should be |
|
101 | is __main__ (technically, __main__.__dict__). Namespaces should be | |
95 | given as dictionaries. |
|
102 | given as dictionaries. | |
96 |
|
103 | |||
97 | Completer instances should be used as the completion mechanism of |
|
104 | Completer instances should be used as the completion mechanism of | |
98 | readline via the set_completer() call: |
|
105 | readline via the set_completer() call: | |
99 |
|
106 | |||
100 | readline.set_completer(Completer(my_namespace).complete) |
|
107 | readline.set_completer(Completer(my_namespace).complete) | |
101 | """ |
|
108 | """ | |
102 |
|
109 | |||
103 | if namespace and type(namespace) != type({}): |
|
110 | if namespace and type(namespace) != type({}): | |
104 | raise TypeError,'namespace must be a dictionary' |
|
111 | raise TypeError,'namespace must be a dictionary' | |
105 |
|
112 | |||
106 | # Don't bind to namespace quite yet, but flag whether the user wants a |
|
113 | # Don't bind to namespace quite yet, but flag whether the user wants a | |
107 | # specific namespace or to use __main__.__dict__. This will allow us |
|
114 | # specific namespace or to use __main__.__dict__. This will allow us | |
108 | # to bind to __main__.__dict__ at completion time, not now. |
|
115 | # to bind to __main__.__dict__ at completion time, not now. | |
109 | if namespace is None: |
|
116 | if namespace is None: | |
110 | self.use_main_ns = 1 |
|
117 | self.use_main_ns = 1 | |
111 | else: |
|
118 | else: | |
112 | self.use_main_ns = 0 |
|
119 | self.use_main_ns = 0 | |
113 | self.namespace = namespace |
|
120 | self.namespace = namespace | |
114 |
|
121 | |||
115 | def complete(self, text, state): |
|
122 | def complete(self, text, state): | |
116 | """Return the next possible completion for 'text'. |
|
123 | """Return the next possible completion for 'text'. | |
117 |
|
124 | |||
118 | This is called successively with state == 0, 1, 2, ... until it |
|
125 | This is called successively with state == 0, 1, 2, ... until it | |
119 | returns None. The completion should begin with 'text'. |
|
126 | returns None. The completion should begin with 'text'. | |
120 |
|
127 | |||
121 | """ |
|
128 | """ | |
122 | if self.use_main_ns: |
|
129 | if self.use_main_ns: | |
123 | self.namespace = __main__.__dict__ |
|
130 | self.namespace = __main__.__dict__ | |
124 |
|
131 | |||
125 | if state == 0: |
|
132 | if state == 0: | |
126 | if "." in text: |
|
133 | if "." in text: | |
127 | self.matches = self.attr_matches(text) |
|
134 | self.matches = self.attr_matches(text) | |
128 | else: |
|
135 | else: | |
129 | self.matches = self.global_matches(text) |
|
136 | self.matches = self.global_matches(text) | |
130 | try: |
|
137 | try: | |
131 | return self.matches[state] |
|
138 | return self.matches[state] | |
132 | except IndexError: |
|
139 | except IndexError: | |
133 | return None |
|
140 | return None | |
134 |
|
141 | |||
135 | def global_matches(self, text): |
|
142 | def global_matches(self, text): | |
136 | """Compute matches when text is a simple name. |
|
143 | """Compute matches when text is a simple name. | |
137 |
|
144 | |||
138 | Return a list of all keywords, built-in functions and names currently |
|
145 | Return a list of all keywords, built-in functions and names currently | |
139 | defined in self.namespace that match. |
|
146 | defined in self.namespace that match. | |
140 |
|
147 | |||
141 | """ |
|
148 | """ | |
142 | import keyword |
|
149 | import keyword | |
143 | matches = [] |
|
150 | matches = [] | |
144 | n = len(text) |
|
151 | n = len(text) | |
145 | for list in [keyword.kwlist, |
|
152 | for list in [keyword.kwlist, | |
146 | __builtin__.__dict__.keys(), |
|
153 | __builtin__.__dict__.keys(), | |
147 | self.namespace.keys()]: |
|
154 | self.namespace.keys()]: | |
148 | for word in list: |
|
155 | for word in list: | |
149 | if word[:n] == text and word != "__builtins__": |
|
156 | if word[:n] == text and word != "__builtins__": | |
150 | matches.append(word) |
|
157 | matches.append(word) | |
151 | return matches |
|
158 | return matches | |
152 |
|
159 | |||
153 | def attr_matches(self, text): |
|
160 | def attr_matches(self, text): | |
154 | """Compute matches when text contains a dot. |
|
161 | """Compute matches when text contains a dot. | |
155 |
|
162 | |||
156 | Assuming the text is of the form NAME.NAME....[NAME], and is |
|
163 | Assuming the text is of the form NAME.NAME....[NAME], and is | |
157 | evaluatable in self.namespace, it will be evaluated and its attributes |
|
164 | evaluatable in self.namespace, it will be evaluated and its attributes | |
158 | (as revealed by dir()) are used as possible completions. (For class |
|
165 | (as revealed by dir()) are used as possible completions. (For class | |
159 | instances, class members are are also considered.) |
|
166 | instances, class members are are also considered.) | |
160 |
|
167 | |||
161 | WARNING: this can still invoke arbitrary C code, if an object |
|
168 | WARNING: this can still invoke arbitrary C code, if an object | |
162 | with a __getattr__ hook is evaluated. |
|
169 | with a __getattr__ hook is evaluated. | |
163 |
|
170 | |||
164 | """ |
|
171 | """ | |
165 | import re |
|
172 | import re | |
166 |
|
173 | |||
167 | # Another option, seems to work great. Catches things like ''.<tab> |
|
174 | # Another option, seems to work great. Catches things like ''.<tab> | |
168 | m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text) |
|
175 | m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text) | |
169 |
|
176 | |||
170 | if not m: |
|
177 | if not m: | |
171 | return [] |
|
178 | return [] | |
172 | expr, attr = m.group(1, 3) |
|
179 | expr, attr = m.group(1, 3) | |
173 | object = eval(expr, self.namespace) |
|
180 | object = eval(expr, self.namespace) | |
174 | words = dir(object) |
|
181 | words = [w for w in dir(object) if isinstance(w, basestring)] | |
175 | if hasattr(object,'__class__'): |
|
182 | if hasattr(object,'__class__'): | |
176 | words.append('__class__') |
|
183 | words.append('__class__') | |
177 | words.extend(get_class_members(object.__class__)) |
|
184 | words.extend(get_class_members(object.__class__)) | |
178 | n = len(attr) |
|
185 | n = len(attr) | |
179 | matches = [] |
|
186 | matches = [] | |
180 | for word in words: |
|
187 | for word in words: | |
181 | try: |
|
|||
182 |
|
|
188 | if word[:n] == attr and word != "__builtins__": | |
183 |
|
|
189 | matches.append("%s.%s" % (expr, word)) | |
184 | except: |
|
|||
185 | # some badly behaved objects pollute dir() with non-strings, |
|
|||
186 | # which cause the completion to fail. This way we skip the |
|
|||
187 | # bad entries and can still continue processing the others. |
|
|||
188 | pass |
|
|||
189 | return matches |
|
190 | return matches | |
190 |
|
191 | |||
191 | def get_class_members(klass): |
|
192 | def get_class_members(klass): | |
192 | ret = dir(klass) |
|
193 | ret = dir(klass) | |
193 | if hasattr(klass,'__bases__'): |
|
194 | if hasattr(klass,'__bases__'): | |
194 | for base in klass.__bases__: |
|
195 | for base in klass.__bases__: | |
195 | ret.extend(get_class_members(base)) |
|
196 | ret.extend(get_class_members(base)) | |
196 | return ret |
|
197 | return ret | |
197 |
|
198 | |||
198 | readline.set_completer(Completer().complete) |
|
199 | readline.set_completer(Completer().complete) |
General Comments 0
You need to be logged in to leave comments.
Login now