##// END OF EJS Templates
%cd and %run completers. try 'foo' and '%foo' completer if command line has 'foo'
vivainio -
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,94 +1,119 b''
1 """ Tab completion support for a couple of linux package managers
1 """ Tab completion support for a couple of linux package managers
2
2
3 This is also an example of how to write custom completer plugins
3 This is also an example of how to write custom completer plugins
4 or hooks.
4 or hooks.
5
5
6 Practical use:
6 Practical use:
7
7
8 [ipython]|1> import ipy_linux_package_managers
8 [ipython]|1> import ipy_linux_package_managers
9 [ipython]|2> apt-get u<<< press tab here >>>
9 [ipython]|2> apt-get u<<< press tab here >>>
10 update upgrade
10 update upgrade
11 [ipython]|2> apt-get up
11 [ipython]|2> apt-get up
12
12
13 """
13 """
14 import IPython.ipapi
14 import IPython.ipapi
15 import glob,os,shlex
15
16
16 ip = IPython.ipapi.get()
17 ip = IPython.ipapi.get()
17
18
18 def apt_completers(self, event):
19 def apt_completers(self, event):
19 """ This should return a list of strings with possible completions.
20 """ This should return a list of strings with possible completions.
20
21
21 Note that all the included strings that don't start with event.symbol
22 Note that all the included strings that don't start with event.symbol
22 are removed, in order to not confuse readline.
23 are removed, in order to not confuse readline.
23
24
24 """
25 """
25 # print event # dbg
26 # print event # dbg
26
27
27 # commands are only suggested for the 'command' part of package manager
28 # commands are only suggested for the 'command' part of package manager
28 # invocation
29 # invocation
29
30
30 cmd = (event.line + "<placeholder>").rsplit(None,1)[0]
31 cmd = (event.line + "<placeholder>").rsplit(None,1)[0]
31 # print cmd
32 # print cmd
32 if cmd.endswith('apt-get') or cmd.endswith('yum'):
33 if cmd.endswith('apt-get') or cmd.endswith('yum'):
33 return ['update', 'upgrade', 'install', 'remove']
34 return ['update', 'upgrade', 'install', 'remove']
34
35
35 # later on, add dpkg -l / whatever to get list of possible
36 # later on, add dpkg -l / whatever to get list of possible
36 # packages, add switches etc. for the rest of command line
37 # packages, add switches etc. for the rest of command line
37 # filling
38 # filling
38
39
39 raise IPython.ipapi.TryNext
40 raise IPython.ipapi.TryNext
40
41
41
42
42 # re_key specifies the regexp that triggers the specified completer
43 # re_key specifies the regexp that triggers the specified completer
43
44
44 ip.set_hook('complete_command', apt_completers, re_key = '.*apt-get')
45 ip.set_hook('complete_command', apt_completers, re_key = '.*apt-get')
45 ip.set_hook('complete_command', apt_completers, re_key = '.*yum')
46 ip.set_hook('complete_command', apt_completers, re_key = '.*yum')
46
47
47 py_std_modules = """\
48 py_std_modules = """\
48 BaseHTTPServer Bastion CGIHTTPServer ConfigParser Cookie
49 BaseHTTPServer Bastion CGIHTTPServer ConfigParser Cookie
49 DocXMLRPCServer HTMLParser MimeWriter Queue SimpleHTTPServer
50 DocXMLRPCServer HTMLParser MimeWriter Queue SimpleHTTPServer
50 SimpleXMLRPCServer SocketServer StringIO UserDict UserList UserString
51 SimpleXMLRPCServer SocketServer StringIO UserDict UserList UserString
51 _LWPCookieJar _MozillaCookieJar __future__ __phello__.foo _strptime
52 _LWPCookieJar _MozillaCookieJar __future__ __phello__.foo _strptime
52 _threading_local aifc anydbm asynchat asyncore atexit audiodev base64
53 _threading_local aifc anydbm asynchat asyncore atexit audiodev base64
53 bdb binhex bisect cProfile calendar cgi cgitb chunk cmd code codecs
54 bdb binhex bisect cProfile calendar cgi cgitb chunk cmd code codecs
54 codeop colorsys commands compileall contextlib cookielib copy copy_reg
55 codeop colorsys commands compileall contextlib cookielib copy copy_reg
55 csv dbhash decimal difflib dircache dis doctest dumbdbm dummy_thread
56 csv dbhash decimal difflib dircache dis doctest dumbdbm dummy_thread
56 dummy_threading filecmp fileinput fnmatch formatter fpformat ftplib
57 dummy_threading filecmp fileinput fnmatch formatter fpformat ftplib
57 functools getopt getpass gettext glob gopherlib gzip hashlib heapq
58 functools getopt getpass gettext glob gopherlib gzip hashlib heapq
58 hmac htmlentitydefs htmllib httplib ihooks imaplib imghdr imputil
59 hmac htmlentitydefs htmllib httplib ihooks imaplib imghdr imputil
59 inspect keyword linecache locale macpath macurl2path mailbox mailcap
60 inspect keyword linecache locale macpath macurl2path mailbox mailcap
60 markupbase md5 mhlib mimetools mimetypes mimify modulefinder multifile
61 markupbase md5 mhlib mimetools mimetypes mimify modulefinder multifile
61 mutex netrc new nntplib ntpath nturl2path opcode optparse os
62 mutex netrc new nntplib ntpath nturl2path opcode optparse os
62 os2emxpath pdb pickle pickletools pipes pkgutil platform popen2 poplib
63 os2emxpath pdb pickle pickletools pipes pkgutil platform popen2 poplib
63 posixfile posixpath pprint profile pstats pty py_compile pyclbr pydoc
64 posixfile posixpath pprint profile pstats pty py_compile pyclbr pydoc
64 quopri random re repr rexec rfc822 rlcompleter robotparser runpy sched
65 quopri random re repr rexec rfc822 rlcompleter robotparser runpy sched
65 sets sgmllib sha shelve shlex shutil site smtpd smtplib sndhdr socket
66 sets sgmllib sha shelve shlex shutil site smtpd smtplib sndhdr socket
66 sre sre_compile sre_constants sre_parse stat statvfs string stringold
67 sre sre_compile sre_constants sre_parse stat statvfs string stringold
67 stringprep struct subprocess sunau sunaudio symbol symtable tabnanny
68 stringprep struct subprocess sunau sunaudio symbol symtable tabnanny
68 tarfile telnetlib tempfile textwrap this threading timeit toaiff token
69 tarfile telnetlib tempfile textwrap this threading timeit toaiff token
69 tokenize trace traceback tty types unittest urllib urllib2 urlparse
70 tokenize trace traceback tty types unittest urllib urllib2 urlparse
70 user uu uuid warnings wave weakref webbrowser whichdb xdrlib xmllib
71 user uu uuid warnings wave weakref webbrowser whichdb xdrlib xmllib
71 xmlrpclib zipfile"""
72 xmlrpclib zipfile"""
72
73
73 def module_completer(self,event):
74 def module_completer(self,event):
74 """ Give completions after user has typed 'import' """
75 """ Give completions after user has typed 'import' """
75 return py_std_modules.split()
76 return py_std_modules.split()
76
77
77 ip.set_hook('complete_command', module_completer, str_key = 'import')
78 ip.set_hook('complete_command', module_completer, str_key = 'import')
78
79
79 svn_commands = """\
80 svn_commands = """\
80 add blame praise annotate ann cat checkout co cleanup commit ci copy
81 add blame praise annotate ann cat checkout co cleanup commit ci copy
81 cp delete del remove rm diff di export help ? h import info list ls
82 cp delete del remove rm diff di export help ? h import info list ls
82 lock log merge mkdir move mv rename ren propdel pdel pd propedit pedit
83 lock log merge mkdir move mv rename ren propdel pdel pd propedit pedit
83 pe propget pget pg proplist plist pl propset pset ps resolved revert
84 pe propget pget pg proplist plist pl propset pset ps resolved revert
84 status stat st switch sw unlock update
85 status stat st switch sw unlock update
85 """
86 """
86
87
87 def svn_completer(self,event):
88 def svn_completer(self,event):
88 if len((event.line + 'placeholder').split()) > 2:
89 if len((event.line + 'placeholder').split()) > 2:
89 # the rest are probably file names
90 # the rest are probably file names
90 return ip.IP.Completer.file_matches(event.symbol)
91 return ip.IP.Completer.file_matches(event.symbol)
91
92
92 return svn_commands.split()
93 return svn_commands.split()
93
94
94 ip.set_hook('complete_command', svn_completer, str_key = 'svn') No newline at end of file
95 ip.set_hook('complete_command', svn_completer, str_key = 'svn')
96
97 def runlistpy(self, event):
98 comps = shlex.split(event.line)
99 relpath = (len(comps) > 1 and comps[-1] or '')
100
101 print "rp",relpath
102 if relpath.startswith('~'):
103 relpath = os.path.expanduser(relpath)
104 dirs = [f.replace('\\','/') + "/" for f in glob.glob(relpath+'*') if os.path.isdir(f)]
105 pys = [f.replace('\\','/') for f in glob.glob(relpath+'*.py')]
106 return dirs + pys
107
108 ip.set_hook('complete_command', runlistpy, str_key = '%run')
109
110 def listdirs(self, event):
111 relpath = event.symbol
112 if relpath.startswith('~'):
113 relpath = os.path.expanduser(relpath).replace('\\','/')
114 found = [f.replace('\\','/')+'/' for f in glob.glob(relpath+'*') if os.path.isdir(f)]
115 if not found:
116 return [relpath]
117 return found
118
119 ip.set_hook('complete_command', listdirs, str_key = '%cd') No newline at end of file
@@ -1,616 +1,627 b''
1 """Word completion for IPython.
1 """Word completion for IPython.
2
2
3 This module is a fork of the rlcompleter module in the Python standard
3 This module is a fork of the rlcompleter module in the Python standard
4 library. The original enhancements made to rlcompleter have been sent
4 library. The original enhancements made to rlcompleter have been sent
5 upstream and were accepted as of Python 2.3, but we need a lot more
5 upstream and were accepted as of Python 2.3, but we need a lot more
6 functionality specific to IPython, so this module will continue to live as an
6 functionality specific to IPython, so this module will continue to live as an
7 IPython-specific utility.
7 IPython-specific utility.
8
8
9 ---------------------------------------------------------------------------
9 ---------------------------------------------------------------------------
10 Original rlcompleter documentation:
10 Original rlcompleter documentation:
11
11
12 This requires the latest extension to the readline module (the
12 This requires the latest extension to the readline module (the
13 completes keywords, built-ins and globals in __main__; when completing
13 completes keywords, built-ins and globals in __main__; when completing
14 NAME.NAME..., it evaluates (!) the expression up to the last dot and
14 NAME.NAME..., it evaluates (!) the expression up to the last dot and
15 completes its attributes.
15 completes its attributes.
16
16
17 It's very cool to do "import string" type "string.", hit the
17 It's very cool to do "import string" type "string.", hit the
18 completion key (twice), and see the list of names defined by the
18 completion key (twice), and see the list of names defined by the
19 string module!
19 string module!
20
20
21 Tip: to use the tab key as the completion key, call
21 Tip: to use the tab key as the completion key, call
22
22
23 readline.parse_and_bind("tab: complete")
23 readline.parse_and_bind("tab: complete")
24
24
25 Notes:
25 Notes:
26
26
27 - Exceptions raised by the completer function are *ignored* (and
27 - Exceptions raised by the completer function are *ignored* (and
28 generally cause the completion to fail). This is a feature -- since
28 generally cause the completion to fail). This is a feature -- since
29 readline sets the tty device in raw (or cbreak) mode, printing a
29 readline sets the tty device in raw (or cbreak) mode, printing a
30 traceback wouldn't work well without some complicated hoopla to save,
30 traceback wouldn't work well without some complicated hoopla to save,
31 reset and restore the tty state.
31 reset and restore the tty state.
32
32
33 - The evaluation of the NAME.NAME... form may cause arbitrary
33 - The evaluation of the NAME.NAME... form may cause arbitrary
34 application defined code to be executed if an object with a
34 application defined code to be executed if an object with a
35 __getattr__ hook is found. Since it is the responsibility of the
35 __getattr__ hook is found. Since it is the responsibility of the
36 application (or the user) to enable this feature, I consider this an
36 application (or the user) to enable this feature, I consider this an
37 acceptable risk. More complicated expressions (e.g. function calls or
37 acceptable risk. More complicated expressions (e.g. function calls or
38 indexing operations) are *not* evaluated.
38 indexing operations) are *not* evaluated.
39
39
40 - GNU readline is also used by the built-in functions input() and
40 - GNU readline is also used by the built-in functions input() and
41 raw_input(), and thus these also benefit/suffer from the completer
41 raw_input(), and thus these also benefit/suffer from the completer
42 features. Clearly an interactive application can benefit by
42 features. Clearly an interactive application can benefit by
43 specifying its own completer function and using raw_input() for all
43 specifying its own completer function and using raw_input() for all
44 its input.
44 its input.
45
45
46 - When the original stdin is not a tty device, GNU readline is never
46 - When the original stdin is not a tty device, GNU readline is never
47 used, and this module (and the readline module) are silently inactive.
47 used, and this module (and the readline module) are silently inactive.
48
48
49 """
49 """
50
50
51 #*****************************************************************************
51 #*****************************************************************************
52 #
52 #
53 # Since this file is essentially a minimally modified copy of the rlcompleter
53 # Since this file is essentially a minimally modified copy of the rlcompleter
54 # module which is part of the standard Python distribution, I assume that the
54 # module which is part of the standard Python distribution, I assume that the
55 # proper procedure is to maintain its copyright as belonging to the Python
55 # proper procedure is to maintain its copyright as belonging to the Python
56 # Software Foundation (in addition to my own, for all new code).
56 # Software Foundation (in addition to my own, for all new code).
57 #
57 #
58 # Copyright (C) 2001 Python Software Foundation, www.python.org
58 # Copyright (C) 2001 Python Software Foundation, www.python.org
59 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
59 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
60 #
60 #
61 # Distributed under the terms of the BSD License. The full license is in
61 # Distributed under the terms of the BSD License. The full license is in
62 # the file COPYING, distributed as part of this software.
62 # the file COPYING, distributed as part of this software.
63 #
63 #
64 #*****************************************************************************
64 #*****************************************************************************
65
65
66 import __builtin__
66 import __builtin__
67 import __main__
67 import __main__
68 import glob
68 import glob
69 import keyword
69 import keyword
70 import os
70 import os
71 import re
71 import re
72 import shlex
72 import shlex
73 import sys
73 import sys
74 import IPython.rlineimpl as readline
74 import IPython.rlineimpl as readline
75 import itertools
75 import itertools
76 from IPython.ipstruct import Struct
76 from IPython.ipstruct import Struct
77 from IPython import ipapi
77 from IPython import ipapi
78
78
79 import types
79 import types
80
80
81 # Python 2.4 offers sets as a builtin
81 # Python 2.4 offers sets as a builtin
82 try:
82 try:
83 set([1,2])
83 set([1,2])
84 except NameError:
84 except NameError:
85 from sets import Set as set
85 from sets import Set as set
86
86
87 from IPython.genutils import debugx
87 from IPython.genutils import debugx
88
88
89 __all__ = ['Completer','IPCompleter']
89 __all__ = ['Completer','IPCompleter']
90
90
91 def get_class_members(cls):
91 def get_class_members(cls):
92 ret = dir(cls)
92 ret = dir(cls)
93 if hasattr(cls,'__bases__'):
93 if hasattr(cls,'__bases__'):
94 for base in cls.__bases__:
94 for base in cls.__bases__:
95 ret.extend(get_class_members(base))
95 ret.extend(get_class_members(base))
96 return ret
96 return ret
97
97
98 class Completer:
98 class Completer:
99 def __init__(self,namespace=None,global_namespace=None):
99 def __init__(self,namespace=None,global_namespace=None):
100 """Create a new completer for the command line.
100 """Create a new completer for the command line.
101
101
102 Completer([namespace,global_namespace]) -> completer instance.
102 Completer([namespace,global_namespace]) -> completer instance.
103
103
104 If unspecified, the default namespace where completions are performed
104 If unspecified, the default namespace where completions are performed
105 is __main__ (technically, __main__.__dict__). Namespaces should be
105 is __main__ (technically, __main__.__dict__). Namespaces should be
106 given as dictionaries.
106 given as dictionaries.
107
107
108 An optional second namespace can be given. This allows the completer
108 An optional second namespace can be given. This allows the completer
109 to handle cases where both the local and global scopes need to be
109 to handle cases where both the local and global scopes need to be
110 distinguished.
110 distinguished.
111
111
112 Completer instances should be used as the completion mechanism of
112 Completer instances should be used as the completion mechanism of
113 readline via the set_completer() call:
113 readline via the set_completer() call:
114
114
115 readline.set_completer(Completer(my_namespace).complete)
115 readline.set_completer(Completer(my_namespace).complete)
116 """
116 """
117
117
118 # some minimal strict typechecks. For some core data structures, I
118 # some minimal strict typechecks. For some core data structures, I
119 # want actual basic python types, not just anything that looks like
119 # want actual basic python types, not just anything that looks like
120 # one. This is especially true for namespaces.
120 # one. This is especially true for namespaces.
121 for ns in (namespace,global_namespace):
121 for ns in (namespace,global_namespace):
122 if ns is not None and type(ns) != types.DictType:
122 if ns is not None and type(ns) != types.DictType:
123 raise TypeError,'namespace must be a dictionary'
123 raise TypeError,'namespace must be a dictionary'
124
124
125 # Don't bind to namespace quite yet, but flag whether the user wants a
125 # Don't bind to namespace quite yet, but flag whether the user wants a
126 # specific namespace or to use __main__.__dict__. This will allow us
126 # specific namespace or to use __main__.__dict__. This will allow us
127 # to bind to __main__.__dict__ at completion time, not now.
127 # to bind to __main__.__dict__ at completion time, not now.
128 if namespace is None:
128 if namespace is None:
129 self.use_main_ns = 1
129 self.use_main_ns = 1
130 else:
130 else:
131 self.use_main_ns = 0
131 self.use_main_ns = 0
132 self.namespace = namespace
132 self.namespace = namespace
133
133
134 # The global namespace, if given, can be bound directly
134 # The global namespace, if given, can be bound directly
135 if global_namespace is None:
135 if global_namespace is None:
136 self.global_namespace = {}
136 self.global_namespace = {}
137 else:
137 else:
138 self.global_namespace = global_namespace
138 self.global_namespace = global_namespace
139
139
140 def complete(self, text, state):
140 def complete(self, text, state):
141 """Return the next possible completion for 'text'.
141 """Return the next possible completion for 'text'.
142
142
143 This is called successively with state == 0, 1, 2, ... until it
143 This is called successively with state == 0, 1, 2, ... until it
144 returns None. The completion should begin with 'text'.
144 returns None. The completion should begin with 'text'.
145
145
146 """
146 """
147 if self.use_main_ns:
147 if self.use_main_ns:
148 self.namespace = __main__.__dict__
148 self.namespace = __main__.__dict__
149
149
150 if state == 0:
150 if state == 0:
151 if "." in text:
151 if "." in text:
152 self.matches = self.attr_matches(text)
152 self.matches = self.attr_matches(text)
153 else:
153 else:
154 self.matches = self.global_matches(text)
154 self.matches = self.global_matches(text)
155 try:
155 try:
156 return self.matches[state]
156 return self.matches[state]
157 except IndexError:
157 except IndexError:
158 return None
158 return None
159
159
160 def global_matches(self, text):
160 def global_matches(self, text):
161 """Compute matches when text is a simple name.
161 """Compute matches when text is a simple name.
162
162
163 Return a list of all keywords, built-in functions and names currently
163 Return a list of all keywords, built-in functions and names currently
164 defined in self.namespace or self.global_namespace that match.
164 defined in self.namespace or self.global_namespace that match.
165
165
166 """
166 """
167 matches = []
167 matches = []
168 match_append = matches.append
168 match_append = matches.append
169 n = len(text)
169 n = len(text)
170 for lst in [keyword.kwlist,
170 for lst in [keyword.kwlist,
171 __builtin__.__dict__.keys(),
171 __builtin__.__dict__.keys(),
172 self.namespace.keys(),
172 self.namespace.keys(),
173 self.global_namespace.keys()]:
173 self.global_namespace.keys()]:
174 for word in lst:
174 for word in lst:
175 if word[:n] == text and word != "__builtins__":
175 if word[:n] == text and word != "__builtins__":
176 match_append(word)
176 match_append(word)
177 return matches
177 return matches
178
178
179 def attr_matches(self, text):
179 def attr_matches(self, text):
180 """Compute matches when text contains a dot.
180 """Compute matches when text contains a dot.
181
181
182 Assuming the text is of the form NAME.NAME....[NAME], and is
182 Assuming the text is of the form NAME.NAME....[NAME], and is
183 evaluatable in self.namespace or self.global_namespace, it will be
183 evaluatable in self.namespace or self.global_namespace, it will be
184 evaluated and its attributes (as revealed by dir()) are used as
184 evaluated and its attributes (as revealed by dir()) are used as
185 possible completions. (For class instances, class members are are
185 possible completions. (For class instances, class members are are
186 also considered.)
186 also considered.)
187
187
188 WARNING: this can still invoke arbitrary C code, if an object
188 WARNING: this can still invoke arbitrary C code, if an object
189 with a __getattr__ hook is evaluated.
189 with a __getattr__ hook is evaluated.
190
190
191 """
191 """
192 import re
192 import re
193
193
194 # Another option, seems to work great. Catches things like ''.<tab>
194 # Another option, seems to work great. Catches things like ''.<tab>
195 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
195 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
196
196
197 if not m:
197 if not m:
198 return []
198 return []
199
199
200 expr, attr = m.group(1, 3)
200 expr, attr = m.group(1, 3)
201 try:
201 try:
202 object = eval(expr, self.namespace)
202 object = eval(expr, self.namespace)
203 except:
203 except:
204 object = eval(expr, self.global_namespace)
204 object = eval(expr, self.global_namespace)
205
205
206 # Start building the attribute list via dir(), and then complete it
206 # Start building the attribute list via dir(), and then complete it
207 # with a few extra special-purpose calls.
207 # with a few extra special-purpose calls.
208 words = dir(object)
208 words = dir(object)
209
209
210 if hasattr(object,'__class__'):
210 if hasattr(object,'__class__'):
211 words.append('__class__')
211 words.append('__class__')
212 words.extend(get_class_members(object.__class__))
212 words.extend(get_class_members(object.__class__))
213
213
214 # this is the 'dir' function for objects with Enthought's traits
214 # this is the 'dir' function for objects with Enthought's traits
215 if hasattr(object, 'trait_names'):
215 if hasattr(object, 'trait_names'):
216 try:
216 try:
217 words.extend(object.trait_names())
217 words.extend(object.trait_names())
218 # eliminate possible duplicates, as some traits may also
218 # eliminate possible duplicates, as some traits may also
219 # appear as normal attributes in the dir() call.
219 # appear as normal attributes in the dir() call.
220 words = set(words)
220 words = set(words)
221 except TypeError:
221 except TypeError:
222 # This will happen if `object` is a class and not an instance.
222 # This will happen if `object` is a class and not an instance.
223 pass
223 pass
224
224
225 # Support for PyCrust-style _getAttributeNames magic method.
225 # Support for PyCrust-style _getAttributeNames magic method.
226 if hasattr(object, '_getAttributeNames'):
226 if hasattr(object, '_getAttributeNames'):
227 try:
227 try:
228 words.extend(object._getAttributeNames())
228 words.extend(object._getAttributeNames())
229 # Eliminate duplicates.
229 # Eliminate duplicates.
230 words = set(words)
230 words = set(words)
231 except TypeError:
231 except TypeError:
232 # `object` is a class and not an instance. Ignore
232 # `object` is a class and not an instance. Ignore
233 # this error.
233 # this error.
234 pass
234 pass
235
235
236 # filter out non-string attributes which may be stuffed by dir() calls
236 # filter out non-string attributes which may be stuffed by dir() calls
237 # and poor coding in third-party modules
237 # and poor coding in third-party modules
238 words = [w for w in words
238 words = [w for w in words
239 if isinstance(w, basestring) and w != "__builtins__"]
239 if isinstance(w, basestring) and w != "__builtins__"]
240 # Build match list to return
240 # Build match list to return
241 n = len(attr)
241 n = len(attr)
242 return ["%s.%s" % (expr, w) for w in words if w[:n] == attr ]
242 return ["%s.%s" % (expr, w) for w in words if w[:n] == attr ]
243
243
244 class IPCompleter(Completer):
244 class IPCompleter(Completer):
245 """Extension of the completer class with IPython-specific features"""
245 """Extension of the completer class with IPython-specific features"""
246
246
247 def __init__(self,shell,namespace=None,global_namespace=None,
247 def __init__(self,shell,namespace=None,global_namespace=None,
248 omit__names=0,alias_table=None):
248 omit__names=0,alias_table=None):
249 """IPCompleter() -> completer
249 """IPCompleter() -> completer
250
250
251 Return a completer object suitable for use by the readline library
251 Return a completer object suitable for use by the readline library
252 via readline.set_completer().
252 via readline.set_completer().
253
253
254 Inputs:
254 Inputs:
255
255
256 - shell: a pointer to the ipython shell itself. This is needed
256 - shell: a pointer to the ipython shell itself. This is needed
257 because this completer knows about magic functions, and those can
257 because this completer knows about magic functions, and those can
258 only be accessed via the ipython instance.
258 only be accessed via the ipython instance.
259
259
260 - namespace: an optional dict where completions are performed.
260 - namespace: an optional dict where completions are performed.
261
261
262 - global_namespace: secondary optional dict for completions, to
262 - global_namespace: secondary optional dict for completions, to
263 handle cases (such as IPython embedded inside functions) where
263 handle cases (such as IPython embedded inside functions) where
264 both Python scopes are visible.
264 both Python scopes are visible.
265
265
266 - The optional omit__names parameter sets the completer to omit the
266 - The optional omit__names parameter sets the completer to omit the
267 'magic' names (__magicname__) for python objects unless the text
267 'magic' names (__magicname__) for python objects unless the text
268 to be completed explicitly starts with one or more underscores.
268 to be completed explicitly starts with one or more underscores.
269
269
270 - If alias_table is supplied, it should be a dictionary of aliases
270 - If alias_table is supplied, it should be a dictionary of aliases
271 to complete. """
271 to complete. """
272
272
273 Completer.__init__(self,namespace,global_namespace)
273 Completer.__init__(self,namespace,global_namespace)
274 self.magic_prefix = shell.name+'.magic_'
274 self.magic_prefix = shell.name+'.magic_'
275 self.magic_escape = shell.ESC_MAGIC
275 self.magic_escape = shell.ESC_MAGIC
276 self.readline = readline
276 self.readline = readline
277 delims = self.readline.get_completer_delims()
277 delims = self.readline.get_completer_delims()
278 delims = delims.replace(self.magic_escape,'')
278 delims = delims.replace(self.magic_escape,'')
279 self.readline.set_completer_delims(delims)
279 self.readline.set_completer_delims(delims)
280 self.get_line_buffer = self.readline.get_line_buffer
280 self.get_line_buffer = self.readline.get_line_buffer
281 self.omit__names = omit__names
281 self.omit__names = omit__names
282 self.merge_completions = shell.rc.readline_merge_completions
282 self.merge_completions = shell.rc.readline_merge_completions
283
283
284 if alias_table is None:
284 if alias_table is None:
285 alias_table = {}
285 alias_table = {}
286 self.alias_table = alias_table
286 self.alias_table = alias_table
287 # Regexp to split filenames with spaces in them
287 # Regexp to split filenames with spaces in them
288 self.space_name_re = re.compile(r'([^\\] )')
288 self.space_name_re = re.compile(r'([^\\] )')
289 # Hold a local ref. to glob.glob for speed
289 # Hold a local ref. to glob.glob for speed
290 self.glob = glob.glob
290 self.glob = glob.glob
291
291
292 # Determine if we are running on 'dumb' terminals, like (X)Emacs
292 # Determine if we are running on 'dumb' terminals, like (X)Emacs
293 # buffers, to avoid completion problems.
293 # buffers, to avoid completion problems.
294 term = os.environ.get('TERM','xterm')
294 term = os.environ.get('TERM','xterm')
295 self.dumb_terminal = term in ['dumb','emacs']
295 self.dumb_terminal = term in ['dumb','emacs']
296
296
297 # Special handling of backslashes needed in win32 platforms
297 # Special handling of backslashes needed in win32 platforms
298 if sys.platform == "win32":
298 if sys.platform == "win32":
299 self.clean_glob = self._clean_glob_win32
299 self.clean_glob = self._clean_glob_win32
300 else:
300 else:
301 self.clean_glob = self._clean_glob
301 self.clean_glob = self._clean_glob
302 self.matchers = [self.python_matches,
302 self.matchers = [self.python_matches,
303 self.file_matches,
303 self.file_matches,
304 self.alias_matches,
304 self.alias_matches,
305 self.python_func_kw_matches]
305 self.python_func_kw_matches]
306
306
307 # Code contributed by Alex Schmolck, for ipython/emacs integration
307 # Code contributed by Alex Schmolck, for ipython/emacs integration
308 def all_completions(self, text):
308 def all_completions(self, text):
309 """Return all possible completions for the benefit of emacs."""
309 """Return all possible completions for the benefit of emacs."""
310
310
311 completions = []
311 completions = []
312 comp_append = completions.append
312 comp_append = completions.append
313 try:
313 try:
314 for i in xrange(sys.maxint):
314 for i in xrange(sys.maxint):
315 res = self.complete(text, i)
315 res = self.complete(text, i)
316
316
317 if not res: break
317 if not res: break
318
318
319 comp_append(res)
319 comp_append(res)
320 #XXX workaround for ``notDefined.<tab>``
320 #XXX workaround for ``notDefined.<tab>``
321 except NameError:
321 except NameError:
322 pass
322 pass
323 return completions
323 return completions
324 # /end Alex Schmolck code.
324 # /end Alex Schmolck code.
325
325
326 def _clean_glob(self,text):
326 def _clean_glob(self,text):
327 return self.glob("%s*" % text)
327 return self.glob("%s*" % text)
328
328
329 def _clean_glob_win32(self,text):
329 def _clean_glob_win32(self,text):
330 return [f.replace("\\","/")
330 return [f.replace("\\","/")
331 for f in self.glob("%s*" % text)]
331 for f in self.glob("%s*" % text)]
332
332
333 def file_matches(self, text):
333 def file_matches(self, text):
334 """Match filneames, expanding ~USER type strings.
334 """Match filneames, expanding ~USER type strings.
335
335
336 Most of the seemingly convoluted logic in this completer is an
336 Most of the seemingly convoluted logic in this completer is an
337 attempt to handle filenames with spaces in them. And yet it's not
337 attempt to handle filenames with spaces in them. And yet it's not
338 quite perfect, because Python's readline doesn't expose all of the
338 quite perfect, because Python's readline doesn't expose all of the
339 GNU readline details needed for this to be done correctly.
339 GNU readline details needed for this to be done correctly.
340
340
341 For a filename with a space in it, the printed completions will be
341 For a filename with a space in it, the printed completions will be
342 only the parts after what's already been typed (instead of the
342 only the parts after what's already been typed (instead of the
343 full completions, as is normally done). I don't think with the
343 full completions, as is normally done). I don't think with the
344 current (as of Python 2.3) Python readline it's possible to do
344 current (as of Python 2.3) Python readline it's possible to do
345 better."""
345 better."""
346
346
347 # print 'Completer->file_matches: <%s>' % text # dbg
347 # print 'Completer->file_matches: <%s>' % text # dbg
348
348
349 # chars that require escaping with backslash - i.e. chars
349 # chars that require escaping with backslash - i.e. chars
350 # that readline treats incorrectly as delimiters, but we
350 # that readline treats incorrectly as delimiters, but we
351 # don't want to treat as delimiters in filename matching
351 # don't want to treat as delimiters in filename matching
352 # when escaped with backslash
352 # when escaped with backslash
353
353
354 protectables = ' ()[]{}'
354 protectables = ' ()[]{}'
355
355
356 def protect_filename(s):
356 def protect_filename(s):
357 return "".join([(ch in protectables and '\\' + ch or ch)
357 return "".join([(ch in protectables and '\\' + ch or ch)
358 for ch in s])
358 for ch in s])
359
359
360 lbuf = self.lbuf
360 lbuf = self.lbuf
361 open_quotes = 0 # track strings with open quotes
361 open_quotes = 0 # track strings with open quotes
362 try:
362 try:
363 lsplit = shlex.split(lbuf)[-1]
363 lsplit = shlex.split(lbuf)[-1]
364 except ValueError:
364 except ValueError:
365 # typically an unmatched ", or backslash without escaped char.
365 # typically an unmatched ", or backslash without escaped char.
366 if lbuf.count('"')==1:
366 if lbuf.count('"')==1:
367 open_quotes = 1
367 open_quotes = 1
368 lsplit = lbuf.split('"')[-1]
368 lsplit = lbuf.split('"')[-1]
369 elif lbuf.count("'")==1:
369 elif lbuf.count("'")==1:
370 open_quotes = 1
370 open_quotes = 1
371 lsplit = lbuf.split("'")[-1]
371 lsplit = lbuf.split("'")[-1]
372 else:
372 else:
373 return None
373 return None
374 except IndexError:
374 except IndexError:
375 # tab pressed on empty line
375 # tab pressed on empty line
376 lsplit = ""
376 lsplit = ""
377
377
378 if lsplit != protect_filename(lsplit):
378 if lsplit != protect_filename(lsplit):
379 # if protectables are found, do matching on the whole escaped
379 # if protectables are found, do matching on the whole escaped
380 # name
380 # name
381 has_protectables = 1
381 has_protectables = 1
382 text0,text = text,lsplit
382 text0,text = text,lsplit
383 else:
383 else:
384 has_protectables = 0
384 has_protectables = 0
385 text = os.path.expanduser(text)
385 text = os.path.expanduser(text)
386
386
387 if text == "":
387 if text == "":
388 return [protect_filename(f) for f in self.glob("*")]
388 return [protect_filename(f) for f in self.glob("*")]
389
389
390 m0 = self.clean_glob(text.replace('\\',''))
390 m0 = self.clean_glob(text.replace('\\',''))
391 if has_protectables:
391 if has_protectables:
392 # If we had protectables, we need to revert our changes to the
392 # If we had protectables, we need to revert our changes to the
393 # beginning of filename so that we don't double-write the part
393 # beginning of filename so that we don't double-write the part
394 # of the filename we have so far
394 # of the filename we have so far
395 len_lsplit = len(lsplit)
395 len_lsplit = len(lsplit)
396 matches = [text0 + protect_filename(f[len_lsplit:]) for f in m0]
396 matches = [text0 + protect_filename(f[len_lsplit:]) for f in m0]
397 else:
397 else:
398 if open_quotes:
398 if open_quotes:
399 # if we have a string with an open quote, we don't need to
399 # if we have a string with an open quote, we don't need to
400 # protect the names at all (and we _shouldn't_, as it
400 # protect the names at all (and we _shouldn't_, as it
401 # would cause bugs when the filesystem call is made).
401 # would cause bugs when the filesystem call is made).
402 matches = m0
402 matches = m0
403 else:
403 else:
404 matches = [protect_filename(f) for f in m0]
404 matches = [protect_filename(f) for f in m0]
405 if len(matches) == 1 and os.path.isdir(matches[0]):
405 if len(matches) == 1 and os.path.isdir(matches[0]):
406 # Takes care of links to directories also. Use '/'
406 # Takes care of links to directories also. Use '/'
407 # explicitly, even under Windows, so that name completions
407 # explicitly, even under Windows, so that name completions
408 # don't end up escaped.
408 # don't end up escaped.
409 matches[0] += '/'
409 matches[0] += '/'
410 return matches
410 return matches
411
411
412 def alias_matches(self, text):
412 def alias_matches(self, text):
413 """Match internal system aliases"""
413 """Match internal system aliases"""
414 #print 'Completer->alias_matches:',text,'lb',self.lbuf # dbg
414 #print 'Completer->alias_matches:',text,'lb',self.lbuf # dbg
415
415
416 # if we are not in the first 'item', alias matching
416 # if we are not in the first 'item', alias matching
417 # doesn't make sense
417 # doesn't make sense
418 if ' ' in self.lbuf:
418 if ' ' in self.lbuf:
419 return []
419 return []
420 text = os.path.expanduser(text)
420 text = os.path.expanduser(text)
421 aliases = self.alias_table.keys()
421 aliases = self.alias_table.keys()
422 if text == "":
422 if text == "":
423 return aliases
423 return aliases
424 else:
424 else:
425 return [alias for alias in aliases if alias.startswith(text)]
425 return [alias for alias in aliases if alias.startswith(text)]
426
426
427 def python_matches(self,text):
427 def python_matches(self,text):
428 """Match attributes or global python names"""
428 """Match attributes or global python names"""
429
429
430 #print 'Completer->python_matches, txt=<%s>' % text # dbg
430 #print 'Completer->python_matches, txt=<%s>' % text # dbg
431 if "." in text:
431 if "." in text:
432 try:
432 try:
433 matches = self.attr_matches(text)
433 matches = self.attr_matches(text)
434 if text.endswith('.') and self.omit__names:
434 if text.endswith('.') and self.omit__names:
435 if self.omit__names == 1:
435 if self.omit__names == 1:
436 # true if txt is _not_ a __ name, false otherwise:
436 # true if txt is _not_ a __ name, false otherwise:
437 no__name = (lambda txt:
437 no__name = (lambda txt:
438 re.match(r'.*\.__.*?__',txt) is None)
438 re.match(r'.*\.__.*?__',txt) is None)
439 else:
439 else:
440 # true if txt is _not_ a _ name, false otherwise:
440 # true if txt is _not_ a _ name, false otherwise:
441 no__name = (lambda txt:
441 no__name = (lambda txt:
442 re.match(r'.*\._.*?',txt) is None)
442 re.match(r'.*\._.*?',txt) is None)
443 matches = filter(no__name, matches)
443 matches = filter(no__name, matches)
444 except NameError:
444 except NameError:
445 # catches <undefined attributes>.<tab>
445 # catches <undefined attributes>.<tab>
446 matches = []
446 matches = []
447 else:
447 else:
448 matches = self.global_matches(text)
448 matches = self.global_matches(text)
449 # this is so completion finds magics when automagic is on:
449 # this is so completion finds magics when automagic is on:
450 if (matches == [] and
450 if (matches == [] and
451 not text.startswith(os.sep) and
451 not text.startswith(os.sep) and
452 not ' ' in self.lbuf):
452 not ' ' in self.lbuf):
453 matches = self.attr_matches(self.magic_prefix+text)
453 matches = self.attr_matches(self.magic_prefix+text)
454 return matches
454 return matches
455
455
456 def _default_arguments(self, obj):
456 def _default_arguments(self, obj):
457 """Return the list of default arguments of obj if it is callable,
457 """Return the list of default arguments of obj if it is callable,
458 or empty list otherwise."""
458 or empty list otherwise."""
459
459
460 if not (inspect.isfunction(obj) or inspect.ismethod(obj)):
460 if not (inspect.isfunction(obj) or inspect.ismethod(obj)):
461 # for classes, check for __init__,__new__
461 # for classes, check for __init__,__new__
462 if inspect.isclass(obj):
462 if inspect.isclass(obj):
463 obj = (getattr(obj,'__init__',None) or
463 obj = (getattr(obj,'__init__',None) or
464 getattr(obj,'__new__',None))
464 getattr(obj,'__new__',None))
465 # for all others, check if they are __call__able
465 # for all others, check if they are __call__able
466 elif hasattr(obj, '__call__'):
466 elif hasattr(obj, '__call__'):
467 obj = obj.__call__
467 obj = obj.__call__
468 # XXX: is there a way to handle the builtins ?
468 # XXX: is there a way to handle the builtins ?
469 try:
469 try:
470 args,_,_1,defaults = inspect.getargspec(obj)
470 args,_,_1,defaults = inspect.getargspec(obj)
471 if defaults:
471 if defaults:
472 return args[-len(defaults):]
472 return args[-len(defaults):]
473 except TypeError: pass
473 except TypeError: pass
474 return []
474 return []
475
475
476 def python_func_kw_matches(self,text):
476 def python_func_kw_matches(self,text):
477 """Match named parameters (kwargs) of the last open function"""
477 """Match named parameters (kwargs) of the last open function"""
478
478
479 if "." in text: # a parameter cannot be dotted
479 if "." in text: # a parameter cannot be dotted
480 return []
480 return []
481 try: regexp = self.__funcParamsRegex
481 try: regexp = self.__funcParamsRegex
482 except AttributeError:
482 except AttributeError:
483 regexp = self.__funcParamsRegex = re.compile(r'''
483 regexp = self.__funcParamsRegex = re.compile(r'''
484 '.*?' | # single quoted strings or
484 '.*?' | # single quoted strings or
485 ".*?" | # double quoted strings or
485 ".*?" | # double quoted strings or
486 \w+ | # identifier
486 \w+ | # identifier
487 \S # other characters
487 \S # other characters
488 ''', re.VERBOSE | re.DOTALL)
488 ''', re.VERBOSE | re.DOTALL)
489 # 1. find the nearest identifier that comes before an unclosed
489 # 1. find the nearest identifier that comes before an unclosed
490 # parenthesis e.g. for "foo (1+bar(x), pa", the candidate is "foo"
490 # parenthesis e.g. for "foo (1+bar(x), pa", the candidate is "foo"
491 tokens = regexp.findall(self.get_line_buffer())
491 tokens = regexp.findall(self.get_line_buffer())
492 tokens.reverse()
492 tokens.reverse()
493 iterTokens = iter(tokens); openPar = 0
493 iterTokens = iter(tokens); openPar = 0
494 for token in iterTokens:
494 for token in iterTokens:
495 if token == ')':
495 if token == ')':
496 openPar -= 1
496 openPar -= 1
497 elif token == '(':
497 elif token == '(':
498 openPar += 1
498 openPar += 1
499 if openPar > 0:
499 if openPar > 0:
500 # found the last unclosed parenthesis
500 # found the last unclosed parenthesis
501 break
501 break
502 else:
502 else:
503 return []
503 return []
504 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
504 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
505 ids = []
505 ids = []
506 isId = re.compile(r'\w+$').match
506 isId = re.compile(r'\w+$').match
507 while True:
507 while True:
508 try:
508 try:
509 ids.append(iterTokens.next())
509 ids.append(iterTokens.next())
510 if not isId(ids[-1]):
510 if not isId(ids[-1]):
511 ids.pop(); break
511 ids.pop(); break
512 if not iterTokens.next() == '.':
512 if not iterTokens.next() == '.':
513 break
513 break
514 except StopIteration:
514 except StopIteration:
515 break
515 break
516 # lookup the candidate callable matches either using global_matches
516 # lookup the candidate callable matches either using global_matches
517 # or attr_matches for dotted names
517 # or attr_matches for dotted names
518 if len(ids) == 1:
518 if len(ids) == 1:
519 callableMatches = self.global_matches(ids[0])
519 callableMatches = self.global_matches(ids[0])
520 else:
520 else:
521 callableMatches = self.attr_matches('.'.join(ids[::-1]))
521 callableMatches = self.attr_matches('.'.join(ids[::-1]))
522 argMatches = []
522 argMatches = []
523 for callableMatch in callableMatches:
523 for callableMatch in callableMatches:
524 try: namedArgs = self._default_arguments(eval(callableMatch,
524 try: namedArgs = self._default_arguments(eval(callableMatch,
525 self.namespace))
525 self.namespace))
526 except: continue
526 except: continue
527 for namedArg in namedArgs:
527 for namedArg in namedArgs:
528 if namedArg.startswith(text):
528 if namedArg.startswith(text):
529 argMatches.append("%s=" %namedArg)
529 argMatches.append("%s=" %namedArg)
530 return argMatches
530 return argMatches
531
531
532 def dispatch_custom_completer(self,text):
532 def dispatch_custom_completer(self,text):
533 # print "Custom! '%s' %s" % (text, self.custom_completers) # dbg
533 # print "Custom! '%s' %s" % (text, self.custom_completers) # dbg
534 line = self.full_lbuf
534 line = self.full_lbuf
535 if not line.strip():
535 if not line.strip():
536 return None
536 return None
537
537
538 event = Struct()
538 event = Struct()
539 event.line = line
539 event.line = line
540 event.symbol = text
540 event.symbol = text
541 cmd = line.split(None,1)[0]
541 cmd = line.split(None,1)[0]
542 event.command = cmd
542 event.command = cmd
543 #print "\ncustom:{%s]\n" % event # dbg
544
545 # for foo etc, try also to find completer for %foo
546 if not cmd.startswith(self.magic_escape):
547 try_magic = self.custom_completers.s_matches(
548 self.magic_escape + cmd)
549 else:
550 try_magic = []
551
552
543 for c in itertools.chain(
553 for c in itertools.chain(
544 self.custom_completers.s_matches(cmd),
554 self.custom_completers.s_matches(cmd),
555 try_magic,
545 self.custom_completers.flat_matches(self.lbuf)):
556 self.custom_completers.flat_matches(self.lbuf)):
546 # print "try",c # dbg
557 # print "try",c # dbg
547 try:
558 try:
548 res = c(event)
559 res = c(event)
549 return [r for r in res if r.startswith(text)]
560 return [r for r in res if r.startswith(text)]
550 except ipapi.TryNext:
561 except ipapi.TryNext:
551 pass
562 pass
552
563
553 return None
564 return None
554
565
555
566
556
567
557 def complete(self, text, state):
568 def complete(self, text, state):
558 """Return the next possible completion for 'text'.
569 """Return the next possible completion for 'text'.
559
570
560 This is called successively with state == 0, 1, 2, ... until it
571 This is called successively with state == 0, 1, 2, ... until it
561 returns None. The completion should begin with 'text'. """
572 returns None. The completion should begin with 'text'. """
562
573
563 #print '\n*** COMPLETE: <%s> (%s)' % (text,state) # dbg
574 #print '\n*** COMPLETE: <%s> (%s)' % (text,state) # dbg
564
575
565 # if there is only a tab on a line with only whitespace, instead
576 # if there is only a tab on a line with only whitespace, instead
566 # of the mostly useless 'do you want to see all million
577 # of the mostly useless 'do you want to see all million
567 # completions' message, just do the right thing and give the user
578 # completions' message, just do the right thing and give the user
568 # his tab! Incidentally, this enables pasting of tabbed text from
579 # his tab! Incidentally, this enables pasting of tabbed text from
569 # an editor (as long as autoindent is off).
580 # an editor (as long as autoindent is off).
570
581
571 # don't apply this on 'dumb' terminals, such as emacs buffers, so we
582 # don't apply this on 'dumb' terminals, such as emacs buffers, so we
572 # don't interfere with their own tab-completion mechanism.
583 # don't interfere with their own tab-completion mechanism.
573 self.full_lbuf = self.get_line_buffer()
584 self.full_lbuf = self.get_line_buffer()
574 self.lbuf = self.full_lbuf[:self.readline.get_endidx()]
585 self.lbuf = self.full_lbuf[:self.readline.get_endidx()]
575 if not (self.dumb_terminal or self.get_line_buffer().strip()):
586 if not (self.dumb_terminal or self.get_line_buffer().strip()):
576 self.readline.insert_text('\t')
587 self.readline.insert_text('\t')
577 return None
588 return None
578
589
579
590
580 magic_escape = self.magic_escape
591 magic_escape = self.magic_escape
581 magic_prefix = self.magic_prefix
592 magic_prefix = self.magic_prefix
582
593
583 try:
594 try:
584 if text.startswith(magic_escape):
595 if text.startswith(magic_escape):
585 text = text.replace(magic_escape,magic_prefix)
596 text = text.replace(magic_escape,magic_prefix)
586 elif text.startswith('~'):
597 elif text.startswith('~'):
587 text = os.path.expanduser(text)
598 text = os.path.expanduser(text)
588 if state == 0:
599 if state == 0:
589 custom_res = self.dispatch_custom_completer(text)
600 custom_res = self.dispatch_custom_completer(text)
590 if custom_res is not None:
601 if custom_res is not None:
591 # did custom completers produce something?
602 # did custom completers produce something?
592 self.matches = custom_res
603 self.matches = custom_res
593 else:
604 else:
594 # Extend the list of completions with the results of each
605 # Extend the list of completions with the results of each
595 # matcher, so we return results to the user from all
606 # matcher, so we return results to the user from all
596 # namespaces.
607 # namespaces.
597 if self.merge_completions:
608 if self.merge_completions:
598 self.matches = []
609 self.matches = []
599 for matcher in self.matchers:
610 for matcher in self.matchers:
600 self.matches.extend(matcher(text))
611 self.matches.extend(matcher(text))
601 else:
612 else:
602 for matcher in self.matchers:
613 for matcher in self.matchers:
603 self.matches = matcher(text)
614 self.matches = matcher(text)
604 if self.matches:
615 if self.matches:
605 break
616 break
606
617
607 try:
618 try:
608 return self.matches[state].replace(magic_prefix,magic_escape)
619 return self.matches[state].replace(magic_prefix,magic_escape)
609 except IndexError:
620 except IndexError:
610 return None
621 return None
611 except:
622 except:
612 from IPython.ultraTB import AutoFormattedTB; # dbg
623 from IPython.ultraTB import AutoFormattedTB; # dbg
613 tb=AutoFormattedTB('Verbose');tb() #dbg
624 tb=AutoFormattedTB('Verbose');tb() #dbg
614
625
615 # If completion fails, don't annoy the user.
626 # If completion fails, don't annoy the user.
616 return None
627 return None
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now