##// END OF EJS Templates
Merge pull request #9375 from liukelly/jedi_completion...
Matthias Bussonnier -
r22297:730393a7 merge
parent child Browse files
Show More
@@ -1,1272 +1,1332 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """Word completion for IPython.
2 """Word completion for IPython.
3
3
4 This module is a fork of the rlcompleter module in the Python standard
4 This module is a fork of the rlcompleter module in the Python standard
5 library. The original enhancements made to rlcompleter have been sent
5 library. The original enhancements made to rlcompleter have been sent
6 upstream and were accepted as of Python 2.3, but we need a lot more
6 upstream and were accepted as of Python 2.3, but we need a lot more
7 functionality specific to IPython, so this module will continue to live as an
7 functionality specific to IPython, so this module will continue to live as an
8 IPython-specific utility.
8 IPython-specific utility.
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 # Copyright (c) IPython Development Team.
50 # Copyright (c) IPython Development Team.
51 # Distributed under the terms of the Modified BSD License.
51 # Distributed under the terms of the Modified BSD License.
52 #
52 #
53 # Some of this code originated from rlcompleter in the Python standard library
53 # Some of this code originated from rlcompleter in the Python standard library
54 # Copyright (C) 2001 Python Software Foundation, www.python.org
54 # Copyright (C) 2001 Python Software Foundation, www.python.org
55
55
56 from __future__ import print_function
57
56 import __main__
58 import __main__
57 import glob
59 import glob
58 import inspect
60 import inspect
59 import itertools
61 import itertools
60 import keyword
62 import keyword
61 import os
63 import os
62 import re
64 import re
63 import sys
65 import sys
64 import unicodedata
66 import unicodedata
65 import string
67 import string
66
68
67 from traitlets.config.configurable import Configurable
69 from traitlets.config.configurable import Configurable
68 from IPython.core.error import TryNext
70 from IPython.core.error import TryNext
69 from IPython.core.inputsplitter import ESC_MAGIC
71 from IPython.core.inputsplitter import ESC_MAGIC
70 from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol
72 from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol
71 from IPython.utils import generics
73 from IPython.utils import generics
72 from IPython.utils.decorators import undoc
74 from IPython.utils.decorators import undoc
73 from IPython.utils.dir2 import dir2, get_real_method
75 from IPython.utils.dir2 import dir2, get_real_method
74 from IPython.utils.process import arg_split
76 from IPython.utils.process import arg_split
75 from IPython.utils.py3compat import builtin_mod, string_types, PY3, cast_unicode_py2
77 from IPython.utils.py3compat import builtin_mod, string_types, PY3, cast_unicode_py2
76 from traitlets import CBool, Enum
78 from traitlets import CBool, Enum
77
79
80 try:
81 import jedi
82 import jedi.api.helpers
83 import jedi.parser.user_context
84 JEDI_INSTALLED = True
85 except ImportError:
86 JEDI_INSTALLED = False
87
78 #-----------------------------------------------------------------------------
88 #-----------------------------------------------------------------------------
79 # Globals
89 # Globals
80 #-----------------------------------------------------------------------------
90 #-----------------------------------------------------------------------------
81
91
82 # Public API
92 # Public API
83 __all__ = ['Completer','IPCompleter']
93 __all__ = ['Completer','IPCompleter']
84
94
85 if sys.platform == 'win32':
95 if sys.platform == 'win32':
86 PROTECTABLES = ' '
96 PROTECTABLES = ' '
87 else:
97 else:
88 PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
98 PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
89
99
90
100
91 #-----------------------------------------------------------------------------
101 #-----------------------------------------------------------------------------
92 # Main functions and classes
102 # Main functions and classes
93 #-----------------------------------------------------------------------------
103 #-----------------------------------------------------------------------------
94
104
95 def has_open_quotes(s):
105 def has_open_quotes(s):
96 """Return whether a string has open quotes.
106 """Return whether a string has open quotes.
97
107
98 This simply counts whether the number of quote characters of either type in
108 This simply counts whether the number of quote characters of either type in
99 the string is odd.
109 the string is odd.
100
110
101 Returns
111 Returns
102 -------
112 -------
103 If there is an open quote, the quote character is returned. Else, return
113 If there is an open quote, the quote character is returned. Else, return
104 False.
114 False.
105 """
115 """
106 # We check " first, then ', so complex cases with nested quotes will get
116 # We check " first, then ', so complex cases with nested quotes will get
107 # the " to take precedence.
117 # the " to take precedence.
108 if s.count('"') % 2:
118 if s.count('"') % 2:
109 return '"'
119 return '"'
110 elif s.count("'") % 2:
120 elif s.count("'") % 2:
111 return "'"
121 return "'"
112 else:
122 else:
113 return False
123 return False
114
124
115
125
116 def protect_filename(s):
126 def protect_filename(s):
117 """Escape a string to protect certain characters."""
127 """Escape a string to protect certain characters."""
118
128
119 return "".join([(ch in PROTECTABLES and '\\' + ch or ch)
129 return "".join([(ch in PROTECTABLES and '\\' + ch or ch)
120 for ch in s])
130 for ch in s])
121
131
122 def expand_user(path):
132 def expand_user(path):
123 """Expand '~'-style usernames in strings.
133 """Expand '~'-style usernames in strings.
124
134
125 This is similar to :func:`os.path.expanduser`, but it computes and returns
135 This is similar to :func:`os.path.expanduser`, but it computes and returns
126 extra information that will be useful if the input was being used in
136 extra information that will be useful if the input was being used in
127 computing completions, and you wish to return the completions with the
137 computing completions, and you wish to return the completions with the
128 original '~' instead of its expanded value.
138 original '~' instead of its expanded value.
129
139
130 Parameters
140 Parameters
131 ----------
141 ----------
132 path : str
142 path : str
133 String to be expanded. If no ~ is present, the output is the same as the
143 String to be expanded. If no ~ is present, the output is the same as the
134 input.
144 input.
135
145
136 Returns
146 Returns
137 -------
147 -------
138 newpath : str
148 newpath : str
139 Result of ~ expansion in the input path.
149 Result of ~ expansion in the input path.
140 tilde_expand : bool
150 tilde_expand : bool
141 Whether any expansion was performed or not.
151 Whether any expansion was performed or not.
142 tilde_val : str
152 tilde_val : str
143 The value that ~ was replaced with.
153 The value that ~ was replaced with.
144 """
154 """
145 # Default values
155 # Default values
146 tilde_expand = False
156 tilde_expand = False
147 tilde_val = ''
157 tilde_val = ''
148 newpath = path
158 newpath = path
149
159
150 if path.startswith('~'):
160 if path.startswith('~'):
151 tilde_expand = True
161 tilde_expand = True
152 rest = len(path)-1
162 rest = len(path)-1
153 newpath = os.path.expanduser(path)
163 newpath = os.path.expanduser(path)
154 if rest:
164 if rest:
155 tilde_val = newpath[:-rest]
165 tilde_val = newpath[:-rest]
156 else:
166 else:
157 tilde_val = newpath
167 tilde_val = newpath
158
168
159 return newpath, tilde_expand, tilde_val
169 return newpath, tilde_expand, tilde_val
160
170
161
171
162 def compress_user(path, tilde_expand, tilde_val):
172 def compress_user(path, tilde_expand, tilde_val):
163 """Does the opposite of expand_user, with its outputs.
173 """Does the opposite of expand_user, with its outputs.
164 """
174 """
165 if tilde_expand:
175 if tilde_expand:
166 return path.replace(tilde_val, '~')
176 return path.replace(tilde_val, '~')
167 else:
177 else:
168 return path
178 return path
169
179
170
180
171
181
172 def completions_sorting_key(word):
182 def completions_sorting_key(word):
173 """key for sorting completions
183 """key for sorting completions
174
184
175 This does several things:
185 This does several things:
176
186
177 - Lowercase all completions, so they are sorted alphabetically with
187 - Lowercase all completions, so they are sorted alphabetically with
178 upper and lower case words mingled
188 upper and lower case words mingled
179 - Demote any completions starting with underscores to the end
189 - Demote any completions starting with underscores to the end
180 - Insert any %magic and %%cellmagic completions in the alphabetical order
190 - Insert any %magic and %%cellmagic completions in the alphabetical order
181 by their name
191 by their name
182 """
192 """
183 # Case insensitive sort
193 # Case insensitive sort
184 word = word.lower()
194 word = word.lower()
185
195
186 prio1, prio2 = 0, 0
196 prio1, prio2 = 0, 0
187
197
188 if word.startswith('__'):
198 if word.startswith('__'):
189 prio1 = 2
199 prio1 = 2
190 elif word.startswith('_'):
200 elif word.startswith('_'):
191 prio1 = 1
201 prio1 = 1
192
202
193 if word.endswith('='):
203 if word.endswith('='):
194 prio1 = -1
204 prio1 = -1
195
205
196 if word.startswith('%%'):
206 if word.startswith('%%'):
197 # If there's another % in there, this is something else, so leave it alone
207 # If there's another % in there, this is something else, so leave it alone
198 if not "%" in word[2:]:
208 if not "%" in word[2:]:
199 word = word[2:]
209 word = word[2:]
200 prio2 = 2
210 prio2 = 2
201 elif word.startswith('%'):
211 elif word.startswith('%'):
202 if not "%" in word[1:]:
212 if not "%" in word[1:]:
203 word = word[1:]
213 word = word[1:]
204 prio2 = 1
214 prio2 = 1
205
215
206 return prio1, word, prio2
216 return prio1, word, prio2
207
217
208
218
209 @undoc
219 @undoc
210 class Bunch(object): pass
220 class Bunch(object): pass
211
221
212
222
213 DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
223 DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
214 GREEDY_DELIMS = ' =\r\n'
224 GREEDY_DELIMS = ' =\r\n'
215
225
216
226
217 class CompletionSplitter(object):
227 class CompletionSplitter(object):
218 """An object to split an input line in a manner similar to readline.
228 """An object to split an input line in a manner similar to readline.
219
229
220 By having our own implementation, we can expose readline-like completion in
230 By having our own implementation, we can expose readline-like completion in
221 a uniform manner to all frontends. This object only needs to be given the
231 a uniform manner to all frontends. This object only needs to be given the
222 line of text to be split and the cursor position on said line, and it
232 line of text to be split and the cursor position on said line, and it
223 returns the 'word' to be completed on at the cursor after splitting the
233 returns the 'word' to be completed on at the cursor after splitting the
224 entire line.
234 entire line.
225
235
226 What characters are used as splitting delimiters can be controlled by
236 What characters are used as splitting delimiters can be controlled by
227 setting the `delims` attribute (this is a property that internally
237 setting the `delims` attribute (this is a property that internally
228 automatically builds the necessary regular expression)"""
238 automatically builds the necessary regular expression)"""
229
239
230 # Private interface
240 # Private interface
231
241
232 # A string of delimiter characters. The default value makes sense for
242 # A string of delimiter characters. The default value makes sense for
233 # IPython's most typical usage patterns.
243 # IPython's most typical usage patterns.
234 _delims = DELIMS
244 _delims = DELIMS
235
245
236 # The expression (a normal string) to be compiled into a regular expression
246 # The expression (a normal string) to be compiled into a regular expression
237 # for actual splitting. We store it as an attribute mostly for ease of
247 # for actual splitting. We store it as an attribute mostly for ease of
238 # debugging, since this type of code can be so tricky to debug.
248 # debugging, since this type of code can be so tricky to debug.
239 _delim_expr = None
249 _delim_expr = None
240
250
241 # The regular expression that does the actual splitting
251 # The regular expression that does the actual splitting
242 _delim_re = None
252 _delim_re = None
243
253
244 def __init__(self, delims=None):
254 def __init__(self, delims=None):
245 delims = CompletionSplitter._delims if delims is None else delims
255 delims = CompletionSplitter._delims if delims is None else delims
246 self.delims = delims
256 self.delims = delims
247
257
248 @property
258 @property
249 def delims(self):
259 def delims(self):
250 """Return the string of delimiter characters."""
260 """Return the string of delimiter characters."""
251 return self._delims
261 return self._delims
252
262
253 @delims.setter
263 @delims.setter
254 def delims(self, delims):
264 def delims(self, delims):
255 """Set the delimiters for line splitting."""
265 """Set the delimiters for line splitting."""
256 expr = '[' + ''.join('\\'+ c for c in delims) + ']'
266 expr = '[' + ''.join('\\'+ c for c in delims) + ']'
257 self._delim_re = re.compile(expr)
267 self._delim_re = re.compile(expr)
258 self._delims = delims
268 self._delims = delims
259 self._delim_expr = expr
269 self._delim_expr = expr
260
270
261 def split_line(self, line, cursor_pos=None):
271 def split_line(self, line, cursor_pos=None):
262 """Split a line of text with a cursor at the given position.
272 """Split a line of text with a cursor at the given position.
263 """
273 """
264 l = line if cursor_pos is None else line[:cursor_pos]
274 l = line if cursor_pos is None else line[:cursor_pos]
265 return self._delim_re.split(l)[-1]
275 return self._delim_re.split(l)[-1]
266
276
267
277
268 class Completer(Configurable):
278 class Completer(Configurable):
269
279
270 greedy = CBool(False, config=True,
280 greedy = CBool(False, config=True,
271 help="""Activate greedy completion
281 help="""Activate greedy completion
282 PENDING DEPRECTION. this is now mostly taken care of with Jedi.
272
283
273 This will enable completion on elements of lists, results of function calls, etc.,
284 This will enable completion on elements of lists, results of function calls, etc.,
274 but can be unsafe because the code is actually evaluated on TAB.
285 but can be unsafe because the code is actually evaluated on TAB.
275 """
286 """
276 )
287 )
277
288
278
289
279 def __init__(self, namespace=None, global_namespace=None, **kwargs):
290 def __init__(self, namespace=None, global_namespace=None, **kwargs):
280 """Create a new completer for the command line.
291 """Create a new completer for the command line.
281
292
282 Completer(namespace=ns,global_namespace=ns2) -> completer instance.
293 Completer(namespace=ns, global_namespace=ns2) -> completer instance.
283
294
284 If unspecified, the default namespace where completions are performed
295 If unspecified, the default namespace where completions are performed
285 is __main__ (technically, __main__.__dict__). Namespaces should be
296 is __main__ (technically, __main__.__dict__). Namespaces should be
286 given as dictionaries.
297 given as dictionaries.
287
298
288 An optional second namespace can be given. This allows the completer
299 An optional second namespace can be given. This allows the completer
289 to handle cases where both the local and global scopes need to be
300 to handle cases where both the local and global scopes need to be
290 distinguished.
301 distinguished.
291
302
292 Completer instances should be used as the completion mechanism of
303 Completer instances should be used as the completion mechanism of
293 readline via the set_completer() call:
304 readline via the set_completer() call:
294
305
295 readline.set_completer(Completer(my_namespace).complete)
306 readline.set_completer(Completer(my_namespace).complete)
296 """
307 """
297
308
298 # Don't bind to namespace quite yet, but flag whether the user wants a
309 # Don't bind to namespace quite yet, but flag whether the user wants a
299 # specific namespace or to use __main__.__dict__. This will allow us
310 # specific namespace or to use __main__.__dict__. This will allow us
300 # to bind to __main__.__dict__ at completion time, not now.
311 # to bind to __main__.__dict__ at completion time, not now.
301 if namespace is None:
312 if namespace is None:
302 self.use_main_ns = 1
313 self.use_main_ns = 1
303 else:
314 else:
304 self.use_main_ns = 0
315 self.use_main_ns = 0
305 self.namespace = namespace
316 self.namespace = namespace
306
317
307 # The global namespace, if given, can be bound directly
318 # The global namespace, if given, can be bound directly
308 if global_namespace is None:
319 if global_namespace is None:
309 self.global_namespace = {}
320 self.global_namespace = {}
310 else:
321 else:
311 self.global_namespace = global_namespace
322 self.global_namespace = global_namespace
312
323
313 super(Completer, self).__init__(**kwargs)
324 super(Completer, self).__init__(**kwargs)
314
325
315 def complete(self, text, state):
326 def complete(self, text, state):
316 """Return the next possible completion for 'text'.
327 """Return the next possible completion for 'text'.
317
328
318 This is called successively with state == 0, 1, 2, ... until it
329 This is called successively with state == 0, 1, 2, ... until it
319 returns None. The completion should begin with 'text'.
330 returns None. The completion should begin with 'text'.
320
331
321 """
332 """
322 if self.use_main_ns:
333 if self.use_main_ns:
323 self.namespace = __main__.__dict__
334 self.namespace = __main__.__dict__
324
335
325 if state == 0:
336 if state == 0:
326 if "." in text:
337 if "." in text:
327 self.matches = self.attr_matches(text)
338 self.matches = self.attr_matches(text)
328 else:
339 else:
329 self.matches = self.global_matches(text)
340 self.matches = self.global_matches(text)
330 try:
341 try:
331 return self.matches[state]
342 return self.matches[state]
332 except IndexError:
343 except IndexError:
333 return None
344 return None
334
345
335 def global_matches(self, text):
346 def global_matches(self, text):
336 """Compute matches when text is a simple name.
347 """Compute matches when text is a simple name.
337
348
338 Return a list of all keywords, built-in functions and names currently
349 Return a list of all keywords, built-in functions and names currently
339 defined in self.namespace or self.global_namespace that match.
350 defined in self.namespace or self.global_namespace that match.
340
351
341 """
352 """
342 #print 'Completer->global_matches, txt=%r' % text # dbg
343 matches = []
353 matches = []
344 match_append = matches.append
354 match_append = matches.append
345 n = len(text)
355 n = len(text)
346 for lst in [keyword.kwlist,
356 for lst in [keyword.kwlist,
347 builtin_mod.__dict__.keys(),
357 builtin_mod.__dict__.keys(),
348 self.namespace.keys(),
358 self.namespace.keys(),
349 self.global_namespace.keys()]:
359 self.global_namespace.keys()]:
350 for word in lst:
360 for word in lst:
351 if word[:n] == text and word != "__builtins__":
361 if word[:n] == text and word != "__builtins__":
352 match_append(word)
362 match_append(word)
353 return [cast_unicode_py2(m) for m in matches]
363 return [cast_unicode_py2(m) for m in matches]
354
364
355 def attr_matches(self, text):
365 def attr_matches(self, text):
356 """Compute matches when text contains a dot.
366 """Compute matches when text contains a dot.
357
367
358 Assuming the text is of the form NAME.NAME....[NAME], and is
368 Assuming the text is of the form NAME.NAME....[NAME], and is
359 evaluatable in self.namespace or self.global_namespace, it will be
369 evaluatable in self.namespace or self.global_namespace, it will be
360 evaluated and its attributes (as revealed by dir()) are used as
370 evaluated and its attributes (as revealed by dir()) are used as
361 possible completions. (For class instances, class members are are
371 possible completions. (For class instances, class members are are
362 also considered.)
372 also considered.)
363
373
364 WARNING: this can still invoke arbitrary C code, if an object
374 WARNING: this can still invoke arbitrary C code, if an object
365 with a __getattr__ hook is evaluated.
375 with a __getattr__ hook is evaluated.
366
376
367 """
377 """
368
378
369 #io.rprint('Completer->attr_matches, txt=%r' % text) # dbg
370 # Another option, seems to work great. Catches things like ''.<tab>
379 # Another option, seems to work great. Catches things like ''.<tab>
371 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
380 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
372
381
373 if m:
382 if m:
374 expr, attr = m.group(1, 3)
383 expr, attr = m.group(1, 3)
375 elif self.greedy:
384 elif self.greedy:
376 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
385 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
377 if not m2:
386 if not m2:
378 return []
387 return []
379 expr, attr = m2.group(1,2)
388 expr, attr = m2.group(1,2)
380 else:
389 else:
381 return []
390 return []
382
391
383 try:
392 try:
384 obj = eval(expr, self.namespace)
393 obj = eval(expr, self.namespace)
385 except:
394 except:
386 try:
395 try:
387 obj = eval(expr, self.global_namespace)
396 obj = eval(expr, self.global_namespace)
388 except:
397 except:
389 return []
398 return []
390
399
391 if self.limit_to__all__ and hasattr(obj, '__all__'):
400 if self.limit_to__all__ and hasattr(obj, '__all__'):
392 words = get__all__entries(obj)
401 words = get__all__entries(obj)
393 else:
402 else:
394 words = dir2(obj)
403 words = dir2(obj)
395
404
396 try:
405 try:
397 words = generics.complete_object(obj, words)
406 words = generics.complete_object(obj, words)
398 except TryNext:
407 except TryNext:
399 pass
408 pass
400 except Exception:
409 except Exception:
401 # Silence errors from completion function
410 # Silence errors from completion function
402 #raise # dbg
411 #raise # dbg
403 pass
412 pass
404 # Build match list to return
413 # Build match list to return
405 n = len(attr)
414 n = len(attr)
406 return [u"%s.%s" % (expr, w) for w in words if w[:n] == attr ]
415 return [u"%s.%s" % (expr, w) for w in words if w[:n] == attr ]
407
416
408
417
409 def get__all__entries(obj):
418 def get__all__entries(obj):
410 """returns the strings in the __all__ attribute"""
419 """returns the strings in the __all__ attribute"""
411 try:
420 try:
412 words = getattr(obj, '__all__')
421 words = getattr(obj, '__all__')
413 except:
422 except:
414 return []
423 return []
415
424
416 return [cast_unicode_py2(w) for w in words if isinstance(w, string_types)]
425 return [cast_unicode_py2(w) for w in words if isinstance(w, string_types)]
417
426
418
427
419 def match_dict_keys(keys, prefix, delims):
428 def match_dict_keys(keys, prefix, delims):
420 """Used by dict_key_matches, matching the prefix to a list of keys"""
429 """Used by dict_key_matches, matching the prefix to a list of keys"""
421 if not prefix:
430 if not prefix:
422 return None, 0, [repr(k) for k in keys
431 return None, 0, [repr(k) for k in keys
423 if isinstance(k, (string_types, bytes))]
432 if isinstance(k, (string_types, bytes))]
424 quote_match = re.search('["\']', prefix)
433 quote_match = re.search('["\']', prefix)
425 quote = quote_match.group()
434 quote = quote_match.group()
426 try:
435 try:
427 prefix_str = eval(prefix + quote, {})
436 prefix_str = eval(prefix + quote, {})
428 except Exception:
437 except Exception:
429 return None, 0, []
438 return None, 0, []
430
439
431 pattern = '[^' + ''.join('\\' + c for c in delims) + ']*$'
440 pattern = '[^' + ''.join('\\' + c for c in delims) + ']*$'
432 token_match = re.search(pattern, prefix, re.UNICODE)
441 token_match = re.search(pattern, prefix, re.UNICODE)
433 token_start = token_match.start()
442 token_start = token_match.start()
434 token_prefix = token_match.group()
443 token_prefix = token_match.group()
435
444
436 # TODO: support bytes in Py3k
445 # TODO: support bytes in Py3k
437 matched = []
446 matched = []
438 for key in keys:
447 for key in keys:
439 try:
448 try:
440 if not key.startswith(prefix_str):
449 if not key.startswith(prefix_str):
441 continue
450 continue
442 except (AttributeError, TypeError, UnicodeError):
451 except (AttributeError, TypeError, UnicodeError):
443 # Python 3+ TypeError on b'a'.startswith('a') or vice-versa
452 # Python 3+ TypeError on b'a'.startswith('a') or vice-versa
444 continue
453 continue
445
454
446 # reformat remainder of key to begin with prefix
455 # reformat remainder of key to begin with prefix
447 rem = key[len(prefix_str):]
456 rem = key[len(prefix_str):]
448 # force repr wrapped in '
457 # force repr wrapped in '
449 rem_repr = repr(rem + '"')
458 rem_repr = repr(rem + '"')
450 if rem_repr.startswith('u') and prefix[0] not in 'uU':
459 if rem_repr.startswith('u') and prefix[0] not in 'uU':
451 # Found key is unicode, but prefix is Py2 string.
460 # Found key is unicode, but prefix is Py2 string.
452 # Therefore attempt to interpret key as string.
461 # Therefore attempt to interpret key as string.
453 try:
462 try:
454 rem_repr = repr(rem.encode('ascii') + '"')
463 rem_repr = repr(rem.encode('ascii') + '"')
455 except UnicodeEncodeError:
464 except UnicodeEncodeError:
456 continue
465 continue
457
466
458 rem_repr = rem_repr[1 + rem_repr.index("'"):-2]
467 rem_repr = rem_repr[1 + rem_repr.index("'"):-2]
459 if quote == '"':
468 if quote == '"':
460 # The entered prefix is quoted with ",
469 # The entered prefix is quoted with ",
461 # but the match is quoted with '.
470 # but the match is quoted with '.
462 # A contained " hence needs escaping for comparison:
471 # A contained " hence needs escaping for comparison:
463 rem_repr = rem_repr.replace('"', '\\"')
472 rem_repr = rem_repr.replace('"', '\\"')
464
473
465 # then reinsert prefix from start of token
474 # then reinsert prefix from start of token
466 matched.append('%s%s' % (token_prefix, rem_repr))
475 matched.append('%s%s' % (token_prefix, rem_repr))
467 return quote, token_start, matched
476 return quote, token_start, matched
468
477
469
478
470 def _safe_isinstance(obj, module, class_name):
479 def _safe_isinstance(obj, module, class_name):
471 """Checks if obj is an instance of module.class_name if loaded
480 """Checks if obj is an instance of module.class_name if loaded
472 """
481 """
473 return (module in sys.modules and
482 return (module in sys.modules and
474 isinstance(obj, getattr(__import__(module), class_name)))
483 isinstance(obj, getattr(__import__(module), class_name)))
475
484
476
485
477 def back_unicode_name_matches(text):
486 def back_unicode_name_matches(text):
478 u"""Match unicode characters back to unicode name
487 u"""Match unicode characters back to unicode name
479
488
480 This does β˜ƒ -> \\snowman
489 This does β˜ƒ -> \\snowman
481
490
482 Note that snowman is not a valid python3 combining character but will be expanded.
491 Note that snowman is not a valid python3 combining character but will be expanded.
483 Though it will not recombine back to the snowman character by the completion machinery.
492 Though it will not recombine back to the snowman character by the completion machinery.
484
493
485 This will not either back-complete standard sequences like \\n, \\b ...
494 This will not either back-complete standard sequences like \\n, \\b ...
486
495
487 Used on Python 3 only.
496 Used on Python 3 only.
488 """
497 """
489 if len(text)<2:
498 if len(text)<2:
490 return u'', ()
499 return u'', ()
491 maybe_slash = text[-2]
500 maybe_slash = text[-2]
492 if maybe_slash != '\\':
501 if maybe_slash != '\\':
493 return u'', ()
502 return u'', ()
494
503
495 char = text[-1]
504 char = text[-1]
496 # no expand on quote for completion in strings.
505 # no expand on quote for completion in strings.
497 # nor backcomplete standard ascii keys
506 # nor backcomplete standard ascii keys
498 if char in string.ascii_letters or char in ['"',"'"]:
507 if char in string.ascii_letters or char in ['"',"'"]:
499 return u'', ()
508 return u'', ()
500 try :
509 try :
501 unic = unicodedata.name(char)
510 unic = unicodedata.name(char)
502 return '\\'+char,['\\'+unic]
511 return '\\'+char,['\\'+unic]
503 except KeyError as e:
512 except KeyError as e:
504 pass
513 pass
505 return u'', ()
514 return u'', ()
506
515
507 def back_latex_name_matches(text):
516 def back_latex_name_matches(text):
508 u"""Match latex characters back to unicode name
517 u"""Match latex characters back to unicode name
509
518
510 This does ->\\sqrt
519 This does ->\\sqrt
511
520
512 Used on Python 3 only.
521 Used on Python 3 only.
513 """
522 """
514 if len(text)<2:
523 if len(text)<2:
515 return u'', ()
524 return u'', ()
516 maybe_slash = text[-2]
525 maybe_slash = text[-2]
517 if maybe_slash != '\\':
526 if maybe_slash != '\\':
518 return u'', ()
527 return u'', ()
519
528
520
529
521 char = text[-1]
530 char = text[-1]
522 # no expand on quote for completion in strings.
531 # no expand on quote for completion in strings.
523 # nor backcomplete standard ascii keys
532 # nor backcomplete standard ascii keys
524 if char in string.ascii_letters or char in ['"',"'"]:
533 if char in string.ascii_letters or char in ['"',"'"]:
525 return u'', ()
534 return u'', ()
526 try :
535 try :
527 latex = reverse_latex_symbol[char]
536 latex = reverse_latex_symbol[char]
528 # '\\' replace the \ as well
537 # '\\' replace the \ as well
529 return '\\'+char,[latex]
538 return '\\'+char,[latex]
530 except KeyError as e:
539 except KeyError as e:
531 pass
540 pass
532 return u'', ()
541 return u'', ()
533
542
534
543
535 class IPCompleter(Completer):
544 class IPCompleter(Completer):
536 """Extension of the completer class with IPython-specific features"""
545 """Extension of the completer class with IPython-specific features"""
537
546
538 def _greedy_changed(self, name, old, new):
547 def _greedy_changed(self, name, old, new):
539 """update the splitter and readline delims when greedy is changed"""
548 """update the splitter and readline delims when greedy is changed"""
540 if new:
549 if new:
541 self.splitter.delims = GREEDY_DELIMS
550 self.splitter.delims = GREEDY_DELIMS
542 else:
551 else:
543 self.splitter.delims = DELIMS
552 self.splitter.delims = DELIMS
544
553
545 if self.readline:
554 if self.readline:
546 self.readline.set_completer_delims(self.splitter.delims)
555 self.readline.set_completer_delims(self.splitter.delims)
547
556
548 merge_completions = CBool(True, config=True,
557 merge_completions = CBool(True, config=True,
549 help="""Whether to merge completion results into a single list
558 help="""Whether to merge completion results into a single list
550
559
551 If False, only the completion results from the first non-empty
560 If False, only the completion results from the first non-empty
552 completer will be returned.
561 completer will be returned.
553 """
562 """
554 )
563 )
555 omit__names = Enum((0,1,2), default_value=2, config=True,
564 omit__names = Enum((0,1,2), default_value=2, config=True,
556 help="""Instruct the completer to omit private method names
565 help="""Instruct the completer to omit private method names
557
566
558 Specifically, when completing on ``object.<tab>``.
567 Specifically, when completing on ``object.<tab>``.
559
568
560 When 2 [default]: all names that start with '_' will be excluded.
569 When 2 [default]: all names that start with '_' will be excluded.
561
570
562 When 1: all 'magic' names (``__foo__``) will be excluded.
571 When 1: all 'magic' names (``__foo__``) will be excluded.
563
572
564 When 0: nothing will be excluded.
573 When 0: nothing will be excluded.
565 """
574 """
566 )
575 )
567 limit_to__all__ = CBool(default_value=False, config=True,
576 limit_to__all__ = CBool(default_value=False, config=True,
568 help="""Instruct the completer to use __all__ for the completion
577 help="""
578 DEPRECATED as of version 5.0.
579
580 Instruct the completer to use __all__ for the completion
569
581
570 Specifically, when completing on ``object.<tab>``.
582 Specifically, when completing on ``object.<tab>``.
571
583
572 When True: only those names in obj.__all__ will be included.
584 When True: only those names in obj.__all__ will be included.
573
585
574 When False [default]: the __all__ attribute is ignored
586 When False [default]: the __all__ attribute is ignored
575 """
587 """
576 )
588 )
589 use_jedi_completions = CBool(default_value=JEDI_INSTALLED, config=True,
590 help="""Use Jedi to generate autocompletions.
591 """)
577
592
578 def __init__(self, shell=None, namespace=None, global_namespace=None,
593 def __init__(self, shell=None, namespace=None, global_namespace=None,
579 use_readline=True, config=None, **kwargs):
594 use_readline=True, config=None, **kwargs):
580 """IPCompleter() -> completer
595 """IPCompleter() -> completer
581
596
582 Return a completer object suitable for use by the readline library
597 Return a completer object suitable for use by the readline library
583 via readline.set_completer().
598 via readline.set_completer().
584
599
585 Inputs:
600 Inputs:
586
601
587 - shell: a pointer to the ipython shell itself. This is needed
602 - shell: a pointer to the ipython shell itself. This is needed
588 because this completer knows about magic functions, and those can
603 because this completer knows about magic functions, and those can
589 only be accessed via the ipython instance.
604 only be accessed via the ipython instance.
590
605
591 - namespace: an optional dict where completions are performed.
606 - namespace: an optional dict where completions are performed.
592
607
593 - global_namespace: secondary optional dict for completions, to
608 - global_namespace: secondary optional dict for completions, to
594 handle cases (such as IPython embedded inside functions) where
609 handle cases (such as IPython embedded inside functions) where
595 both Python scopes are visible.
610 both Python scopes are visible.
596
611
597 use_readline : bool, optional
612 use_readline : bool, optional
598 If true, use the readline library. This completer can still function
613 If true, use the readline library. This completer can still function
599 without readline, though in that case callers must provide some extra
614 without readline, though in that case callers must provide some extra
600 information on each call about the current line."""
615 information on each call about the current line."""
601
616
602 self.magic_escape = ESC_MAGIC
617 self.magic_escape = ESC_MAGIC
603 self.splitter = CompletionSplitter()
618 self.splitter = CompletionSplitter()
604
619
605 # Readline configuration, only used by the rlcompleter method.
620 # Readline configuration, only used by the rlcompleter method.
606 if use_readline:
621 if use_readline:
607 # We store the right version of readline so that later code
622 # We store the right version of readline so that later code
608 import IPython.utils.rlineimpl as readline
623 import IPython.utils.rlineimpl as readline
609 self.readline = readline
624 self.readline = readline
610 else:
625 else:
611 self.readline = None
626 self.readline = None
612
627
613 # _greedy_changed() depends on splitter and readline being defined:
628 # _greedy_changed() depends on splitter and readline being defined:
614 Completer.__init__(self, namespace=namespace, global_namespace=global_namespace,
629 Completer.__init__(self, namespace=namespace, global_namespace=global_namespace,
615 config=config, **kwargs)
630 config=config, **kwargs)
616
631
617 # List where completion matches will be stored
632 # List where completion matches will be stored
618 self.matches = []
633 self.matches = []
619 self.shell = shell
634 self.shell = shell
620 # Regexp to split filenames with spaces in them
635 # Regexp to split filenames with spaces in them
621 self.space_name_re = re.compile(r'([^\\] )')
636 self.space_name_re = re.compile(r'([^\\] )')
622 # Hold a local ref. to glob.glob for speed
637 # Hold a local ref. to glob.glob for speed
623 self.glob = glob.glob
638 self.glob = glob.glob
624
639
625 # Determine if we are running on 'dumb' terminals, like (X)Emacs
640 # Determine if we are running on 'dumb' terminals, like (X)Emacs
626 # buffers, to avoid completion problems.
641 # buffers, to avoid completion problems.
627 term = os.environ.get('TERM','xterm')
642 term = os.environ.get('TERM','xterm')
628 self.dumb_terminal = term in ['dumb','emacs']
643 self.dumb_terminal = term in ['dumb','emacs']
629
644
630 # Special handling of backslashes needed in win32 platforms
645 # Special handling of backslashes needed in win32 platforms
631 if sys.platform == "win32":
646 if sys.platform == "win32":
632 self.clean_glob = self._clean_glob_win32
647 self.clean_glob = self._clean_glob_win32
633 else:
648 else:
634 self.clean_glob = self._clean_glob
649 self.clean_glob = self._clean_glob
635
650
636 #regexp to parse docstring for function signature
651 #regexp to parse docstring for function signature
637 self.docstring_sig_re = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
652 self.docstring_sig_re = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
638 self.docstring_kwd_re = re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
653 self.docstring_kwd_re = re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
639 #use this if positional argument name is also needed
654 #use this if positional argument name is also needed
640 #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)')
655 #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)')
641
656
642 # All active matcher routines for completion
657 # All active matcher routines for completion
643 self.matchers = [self.python_matches,
658 self.matchers = [
644 self.file_matches,
659 self.file_matches,
645 self.magic_matches,
660 self.magic_matches,
646 self.python_func_kw_matches,
661 self.python_func_kw_matches,
647 self.dict_key_matches,
662 self.dict_key_matches,
648 ]
663 ]
649
664
650 def all_completions(self, text):
665 def all_completions(self, text):
651 """
666 """
652 Wrapper around the complete method for the benefit of emacs
667 Wrapper around the complete method for the benefit of emacs
653 and pydb.
668 and pydb.
654 """
669 """
655 return self.complete(text)[1]
670 return self.complete(text)[1]
656
671
657 def _clean_glob(self,text):
672 def _clean_glob(self, text):
658 return self.glob("%s*" % text)
673 return self.glob("%s*" % text)
659
674
660 def _clean_glob_win32(self,text):
675 def _clean_glob_win32(self,text):
661 return [f.replace("\\","/")
676 return [f.replace("\\","/")
662 for f in self.glob("%s*" % text)]
677 for f in self.glob("%s*" % text)]
663
678
664 def file_matches(self, text):
679 def file_matches(self, text):
665 """Match filenames, expanding ~USER type strings.
680 """Match filenames, expanding ~USER type strings.
666
681
667 Most of the seemingly convoluted logic in this completer is an
682 Most of the seemingly convoluted logic in this completer is an
668 attempt to handle filenames with spaces in them. And yet it's not
683 attempt to handle filenames with spaces in them. And yet it's not
669 quite perfect, because Python's readline doesn't expose all of the
684 quite perfect, because Python's readline doesn't expose all of the
670 GNU readline details needed for this to be done correctly.
685 GNU readline details needed for this to be done correctly.
671
686
672 For a filename with a space in it, the printed completions will be
687 For a filename with a space in it, the printed completions will be
673 only the parts after what's already been typed (instead of the
688 only the parts after what's already been typed (instead of the
674 full completions, as is normally done). I don't think with the
689 full completions, as is normally done). I don't think with the
675 current (as of Python 2.3) Python readline it's possible to do
690 current (as of Python 2.3) Python readline it's possible to do
676 better."""
691 better."""
677
692
678 #io.rprint('Completer->file_matches: <%r>' % text) # dbg
679
680 # chars that require escaping with backslash - i.e. chars
693 # chars that require escaping with backslash - i.e. chars
681 # that readline treats incorrectly as delimiters, but we
694 # that readline treats incorrectly as delimiters, but we
682 # don't want to treat as delimiters in filename matching
695 # don't want to treat as delimiters in filename matching
683 # when escaped with backslash
696 # when escaped with backslash
684 if text.startswith('!'):
697 if text.startswith('!'):
685 text = text[1:]
698 text = text[1:]
686 text_prefix = u'!'
699 text_prefix = u'!'
687 else:
700 else:
688 text_prefix = u''
701 text_prefix = u''
689
702
690 text_until_cursor = self.text_until_cursor
703 text_until_cursor = self.text_until_cursor
691 # track strings with open quotes
704 # track strings with open quotes
692 open_quotes = has_open_quotes(text_until_cursor)
705 open_quotes = has_open_quotes(text_until_cursor)
693
706
694 if '(' in text_until_cursor or '[' in text_until_cursor:
707 if '(' in text_until_cursor or '[' in text_until_cursor:
695 lsplit = text
708 lsplit = text
696 else:
709 else:
697 try:
710 try:
698 # arg_split ~ shlex.split, but with unicode bugs fixed by us
711 # arg_split ~ shlex.split, but with unicode bugs fixed by us
699 lsplit = arg_split(text_until_cursor)[-1]
712 lsplit = arg_split(text_until_cursor)[-1]
700 except ValueError:
713 except ValueError:
701 # typically an unmatched ", or backslash without escaped char.
714 # typically an unmatched ", or backslash without escaped char.
702 if open_quotes:
715 if open_quotes:
703 lsplit = text_until_cursor.split(open_quotes)[-1]
716 lsplit = text_until_cursor.split(open_quotes)[-1]
704 else:
717 else:
705 return []
718 return []
706 except IndexError:
719 except IndexError:
707 # tab pressed on empty line
720 # tab pressed on empty line
708 lsplit = ""
721 lsplit = ""
709
722
710 if not open_quotes and lsplit != protect_filename(lsplit):
723 if not open_quotes and lsplit != protect_filename(lsplit):
711 # if protectables are found, do matching on the whole escaped name
724 # if protectables are found, do matching on the whole escaped name
712 has_protectables = True
725 has_protectables = True
713 text0,text = text,lsplit
726 text0,text = text,lsplit
714 else:
727 else:
715 has_protectables = False
728 has_protectables = False
716 text = os.path.expanduser(text)
729 text = os.path.expanduser(text)
717
730
718 if text == "":
731 if text == "":
719 return [text_prefix + cast_unicode_py2(protect_filename(f)) for f in self.glob("*")]
732 return [text_prefix + cast_unicode_py2(protect_filename(f)) for f in self.glob("*")]
720
733
721 # Compute the matches from the filesystem
734 # Compute the matches from the filesystem
722 m0 = self.clean_glob(text.replace('\\',''))
735 m0 = self.clean_glob(text.replace('\\',''))
723
736
724 if has_protectables:
737 if has_protectables:
725 # If we had protectables, we need to revert our changes to the
738 # If we had protectables, we need to revert our changes to the
726 # beginning of filename so that we don't double-write the part
739 # beginning of filename so that we don't double-write the part
727 # of the filename we have so far
740 # of the filename we have so far
728 len_lsplit = len(lsplit)
741 len_lsplit = len(lsplit)
729 matches = [text_prefix + text0 +
742 matches = [text_prefix + text0 +
730 protect_filename(f[len_lsplit:]) for f in m0]
743 protect_filename(f[len_lsplit:]) for f in m0]
731 else:
744 else:
732 if open_quotes:
745 if open_quotes:
733 # if we have a string with an open quote, we don't need to
746 # if we have a string with an open quote, we don't need to
734 # protect the names at all (and we _shouldn't_, as it
747 # protect the names at all (and we _shouldn't_, as it
735 # would cause bugs when the filesystem call is made).
748 # would cause bugs when the filesystem call is made).
736 matches = m0
749 matches = m0
737 else:
750 else:
738 matches = [text_prefix +
751 matches = [text_prefix +
739 protect_filename(f) for f in m0]
752 protect_filename(f) for f in m0]
740
753
741 # Mark directories in input list by appending '/' to their names.
754 # Mark directories in input list by appending '/' to their names.
742 return [cast_unicode_py2(x+'/') if os.path.isdir(x) else x for x in matches]
755 return [cast_unicode_py2(x+'/') if os.path.isdir(x) else x for x in matches]
743
756
744 def magic_matches(self, text):
757 def magic_matches(self, text):
745 """Match magics"""
758 """Match magics"""
746 #print 'Completer->magic_matches:',text,'lb',self.text_until_cursor # dbg
747 # Get all shell magics now rather than statically, so magics loaded at
759 # Get all shell magics now rather than statically, so magics loaded at
748 # runtime show up too.
760 # runtime show up too.
749 lsm = self.shell.magics_manager.lsmagic()
761 lsm = self.shell.magics_manager.lsmagic()
750 line_magics = lsm['line']
762 line_magics = lsm['line']
751 cell_magics = lsm['cell']
763 cell_magics = lsm['cell']
752 pre = self.magic_escape
764 pre = self.magic_escape
753 pre2 = pre+pre
765 pre2 = pre+pre
754
766
755 # Completion logic:
767 # Completion logic:
756 # - user gives %%: only do cell magics
768 # - user gives %%: only do cell magics
757 # - user gives %: do both line and cell magics
769 # - user gives %: do both line and cell magics
758 # - no prefix: do both
770 # - no prefix: do both
759 # In other words, line magics are skipped if the user gives %% explicitly
771 # In other words, line magics are skipped if the user gives %% explicitly
760 bare_text = text.lstrip(pre)
772 bare_text = text.lstrip(pre)
761 comp = [ pre2+m for m in cell_magics if m.startswith(bare_text)]
773 comp = [ pre2+m for m in cell_magics if m.startswith(bare_text)]
762 if not text.startswith(pre2):
774 if not text.startswith(pre2):
763 comp += [ pre+m for m in line_magics if m.startswith(bare_text)]
775 comp += [ pre+m for m in line_magics if m.startswith(bare_text)]
764 return [cast_unicode_py2(c) for c in comp]
776 return [cast_unicode_py2(c) for c in comp]
765
777
778 def python_jedi_matches(self, text, line_buffer, cursor_pos):
779 """Match attributes or global Python names using Jedi."""
780 if line_buffer.startswith('aimport ') or line_buffer.startswith('%aimport '):
781 return ()
782 namespaces = []
783 if self.namespace is None:
784 import __main__
785 namespaces.append(__main__.__dict__)
786 else:
787 namespaces.append(self.namespace)
788 if self.global_namespace is not None:
789 namespaces.append(self.global_namespace)
790
791 # cursor_pos is an it, jedi wants line and column
792
793 interpreter = jedi.Interpreter(line_buffer, namespaces, column=cursor_pos)
794 path = jedi.parser.user_context.UserContext(line_buffer, \
795 (1, len(line_buffer))).get_path_until_cursor()
796 path, dot, like = jedi.api.helpers.completion_parts(path)
797 if text.startswith('.'):
798 # text will be `.` on completions like `a[0].<tab>`
799 before = dot
800 else:
801 before = line_buffer[:len(line_buffer) - len(like)]
802
803
804 def trim_start(completion):
805 """completions need to start with `text`, trim the beginning until it does"""
806 if text in completion and not (completion.startswith(text)):
807 start_index = completion.index(text)
808 if cursor_pos:
809 assert start_index < cursor_pos
810 return completion[start_index:]
811 return completion
812
813 completions = interpreter.completions()
814
815 completion_text = [c.name_with_symbols for c in completions]
816
817 if self.omit__names:
818 if self.omit__names == 1:
819 # true if txt is _not_ a __ name, false otherwise:
820 no__name = lambda txt: not txt.startswith('__')
821 else:
822 # true if txt is _not_ a _ name, false otherwise:
823 no__name = lambda txt: not txt.startswith('_')
824 completion_text = filter(no__name, completion_text)
825
826
827 return [trim_start(before + c_text) for c_text in completion_text]
828
829
766 def python_matches(self, text):
830 def python_matches(self, text):
767 """Match attributes or global python names"""
831 """Match attributes or global python names"""
768
832 # Jedi completion
769 #io.rprint('Completer->python_matches, txt=%r' % text) # dbg
833
770 if "." in text:
834 if "." in text:
771 try:
835 try:
772 matches = self.attr_matches(text)
836 matches = self.attr_matches(text)
773 if text.endswith('.') and self.omit__names:
837 if text.endswith('.') and self.omit__names:
774 if self.omit__names == 1:
838 if self.omit__names == 1:
775 # true if txt is _not_ a __ name, false otherwise:
839 # true if txt is _not_ a __ name, false otherwise:
776 no__name = (lambda txt:
840 no__name = (lambda txt:
777 re.match(r'.*\.__.*?__',txt) is None)
841 re.match(r'.*\.__.*?__',txt) is None)
778 else:
842 else:
779 # true if txt is _not_ a _ name, false otherwise:
843 # true if txt is _not_ a _ name, false otherwise:
780 no__name = (lambda txt:
844 no__name = (lambda txt:
781 re.match(r'\._.*?',txt[txt.rindex('.'):]) is None)
845 re.match(r'\._.*?',txt[txt.rindex('.'):]) is None)
782 matches = filter(no__name, matches)
846 matches = filter(no__name, matches)
783 except NameError:
847 except NameError:
784 # catches <undefined attributes>.<tab>
848 # catches <undefined attributes>.<tab>
785 matches = []
849 matches = []
786 else:
850 else:
787 matches = self.global_matches(text)
851 matches = self.global_matches(text)
788 return matches
852 return matches
789
853
790 def _default_arguments_from_docstring(self, doc):
854 def _default_arguments_from_docstring(self, doc):
791 """Parse the first line of docstring for call signature.
855 """Parse the first line of docstring for call signature.
792
856
793 Docstring should be of the form 'min(iterable[, key=func])\n'.
857 Docstring should be of the form 'min(iterable[, key=func])\n'.
794 It can also parse cython docstring of the form
858 It can also parse cython docstring of the form
795 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'.
859 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'.
796 """
860 """
797 if doc is None:
861 if doc is None:
798 return []
862 return []
799
863
800 #care only the firstline
864 #care only the firstline
801 line = doc.lstrip().splitlines()[0]
865 line = doc.lstrip().splitlines()[0]
802
866
803 #p = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
867 #p = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
804 #'min(iterable[, key=func])\n' -> 'iterable[, key=func]'
868 #'min(iterable[, key=func])\n' -> 'iterable[, key=func]'
805 sig = self.docstring_sig_re.search(line)
869 sig = self.docstring_sig_re.search(line)
806 if sig is None:
870 if sig is None:
807 return []
871 return []
808 # iterable[, key=func]' -> ['iterable[' ,' key=func]']
872 # iterable[, key=func]' -> ['iterable[' ,' key=func]']
809 sig = sig.groups()[0].split(',')
873 sig = sig.groups()[0].split(',')
810 ret = []
874 ret = []
811 for s in sig:
875 for s in sig:
812 #re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
876 #re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
813 ret += self.docstring_kwd_re.findall(s)
877 ret += self.docstring_kwd_re.findall(s)
814 return ret
878 return ret
815
879
816 def _default_arguments(self, obj):
880 def _default_arguments(self, obj):
817 """Return the list of default arguments of obj if it is callable,
881 """Return the list of default arguments of obj if it is callable,
818 or empty list otherwise."""
882 or empty list otherwise."""
819 call_obj = obj
883 call_obj = obj
820 ret = []
884 ret = []
821 if inspect.isbuiltin(obj):
885 if inspect.isbuiltin(obj):
822 pass
886 pass
823 elif not (inspect.isfunction(obj) or inspect.ismethod(obj)):
887 elif not (inspect.isfunction(obj) or inspect.ismethod(obj)):
824 if inspect.isclass(obj):
888 if inspect.isclass(obj):
825 #for cython embededsignature=True the constructor docstring
889 #for cython embededsignature=True the constructor docstring
826 #belongs to the object itself not __init__
890 #belongs to the object itself not __init__
827 ret += self._default_arguments_from_docstring(
891 ret += self._default_arguments_from_docstring(
828 getattr(obj, '__doc__', ''))
892 getattr(obj, '__doc__', ''))
829 # for classes, check for __init__,__new__
893 # for classes, check for __init__,__new__
830 call_obj = (getattr(obj, '__init__', None) or
894 call_obj = (getattr(obj, '__init__', None) or
831 getattr(obj, '__new__', None))
895 getattr(obj, '__new__', None))
832 # for all others, check if they are __call__able
896 # for all others, check if they are __call__able
833 elif hasattr(obj, '__call__'):
897 elif hasattr(obj, '__call__'):
834 call_obj = obj.__call__
898 call_obj = obj.__call__
835 ret += self._default_arguments_from_docstring(
899 ret += self._default_arguments_from_docstring(
836 getattr(call_obj, '__doc__', ''))
900 getattr(call_obj, '__doc__', ''))
837
901
838 if PY3:
902 if PY3:
839 _keeps = (inspect.Parameter.KEYWORD_ONLY,
903 _keeps = (inspect.Parameter.KEYWORD_ONLY,
840 inspect.Parameter.POSITIONAL_OR_KEYWORD)
904 inspect.Parameter.POSITIONAL_OR_KEYWORD)
841 signature = inspect.signature
905 signature = inspect.signature
842 else:
906 else:
843 import IPython.utils.signatures
907 import IPython.utils.signatures
844 _keeps = (IPython.utils.signatures.Parameter.KEYWORD_ONLY,
908 _keeps = (IPython.utils.signatures.Parameter.KEYWORD_ONLY,
845 IPython.utils.signatures.Parameter.POSITIONAL_OR_KEYWORD)
909 IPython.utils.signatures.Parameter.POSITIONAL_OR_KEYWORD)
846 signature = IPython.utils.signatures.signature
910 signature = IPython.utils.signatures.signature
847
911
848 try:
912 try:
849 sig = signature(call_obj)
913 sig = signature(call_obj)
850 ret.extend(k for k, v in sig.parameters.items() if
914 ret.extend(k for k, v in sig.parameters.items() if
851 v.kind in _keeps)
915 v.kind in _keeps)
852 except ValueError:
916 except ValueError:
853 pass
917 pass
854
918
855 return list(set(ret))
919 return list(set(ret))
856
920
857 def python_func_kw_matches(self,text):
921 def python_func_kw_matches(self,text):
858 """Match named parameters (kwargs) of the last open function"""
922 """Match named parameters (kwargs) of the last open function"""
859
923
860 if "." in text: # a parameter cannot be dotted
924 if "." in text: # a parameter cannot be dotted
861 return []
925 return []
862 try: regexp = self.__funcParamsRegex
926 try: regexp = self.__funcParamsRegex
863 except AttributeError:
927 except AttributeError:
864 regexp = self.__funcParamsRegex = re.compile(r'''
928 regexp = self.__funcParamsRegex = re.compile(r'''
865 '.*?(?<!\\)' | # single quoted strings or
929 '.*?(?<!\\)' | # single quoted strings or
866 ".*?(?<!\\)" | # double quoted strings or
930 ".*?(?<!\\)" | # double quoted strings or
867 \w+ | # identifier
931 \w+ | # identifier
868 \S # other characters
932 \S # other characters
869 ''', re.VERBOSE | re.DOTALL)
933 ''', re.VERBOSE | re.DOTALL)
870 # 1. find the nearest identifier that comes before an unclosed
934 # 1. find the nearest identifier that comes before an unclosed
871 # parenthesis before the cursor
935 # parenthesis before the cursor
872 # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
936 # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
873 tokens = regexp.findall(self.text_until_cursor)
937 tokens = regexp.findall(self.text_until_cursor)
874 tokens.reverse()
938 tokens.reverse()
875 iterTokens = iter(tokens); openPar = 0
939 iterTokens = iter(tokens); openPar = 0
876
940
877 for token in iterTokens:
941 for token in iterTokens:
878 if token == ')':
942 if token == ')':
879 openPar -= 1
943 openPar -= 1
880 elif token == '(':
944 elif token == '(':
881 openPar += 1
945 openPar += 1
882 if openPar > 0:
946 if openPar > 0:
883 # found the last unclosed parenthesis
947 # found the last unclosed parenthesis
884 break
948 break
885 else:
949 else:
886 return []
950 return []
887 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
951 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
888 ids = []
952 ids = []
889 isId = re.compile(r'\w+$').match
953 isId = re.compile(r'\w+$').match
890
954
891 while True:
955 while True:
892 try:
956 try:
893 ids.append(next(iterTokens))
957 ids.append(next(iterTokens))
894 if not isId(ids[-1]):
958 if not isId(ids[-1]):
895 ids.pop(); break
959 ids.pop(); break
896 if not next(iterTokens) == '.':
960 if not next(iterTokens) == '.':
897 break
961 break
898 except StopIteration:
962 except StopIteration:
899 break
963 break
900 # lookup the candidate callable matches either using global_matches
964 # lookup the candidate callable matches either using global_matches
901 # or attr_matches for dotted names
965 # or attr_matches for dotted names
902 if len(ids) == 1:
966 if len(ids) == 1:
903 callableMatches = self.global_matches(ids[0])
967 callableMatches = self.global_matches(ids[0])
904 else:
968 else:
905 callableMatches = self.attr_matches('.'.join(ids[::-1]))
969 callableMatches = self.attr_matches('.'.join(ids[::-1]))
906 argMatches = []
970 argMatches = []
907 for callableMatch in callableMatches:
971 for callableMatch in callableMatches:
908 try:
972 try:
909 namedArgs = self._default_arguments(eval(callableMatch,
973 namedArgs = self._default_arguments(eval(callableMatch,
910 self.namespace))
974 self.namespace))
911 except:
975 except:
912 continue
976 continue
913
977
914 for namedArg in namedArgs:
978 for namedArg in namedArgs:
915 if namedArg.startswith(text):
979 if namedArg.startswith(text):
916 argMatches.append(u"%s=" %namedArg)
980 argMatches.append(u"%s=" %namedArg)
917 return argMatches
981 return argMatches
918
982
919 def dict_key_matches(self, text):
983 def dict_key_matches(self, text):
920 "Match string keys in a dictionary, after e.g. 'foo[' "
984 "Match string keys in a dictionary, after e.g. 'foo[' "
921 def get_keys(obj):
985 def get_keys(obj):
922 # Objects can define their own completions by defining an
986 # Objects can define their own completions by defining an
923 # _ipy_key_completions_() method.
987 # _ipy_key_completions_() method.
924 method = get_real_method(obj, '_ipython_key_completions_')
988 method = get_real_method(obj, '_ipython_key_completions_')
925 if method is not None:
989 if method is not None:
926 return method()
990 return method()
927
991
928 # Special case some common in-memory dict-like types
992 # Special case some common in-memory dict-like types
929 if isinstance(obj, dict) or\
993 if isinstance(obj, dict) or\
930 _safe_isinstance(obj, 'pandas', 'DataFrame'):
994 _safe_isinstance(obj, 'pandas', 'DataFrame'):
931 try:
995 try:
932 return list(obj.keys())
996 return list(obj.keys())
933 except Exception:
997 except Exception:
934 return []
998 return []
935 elif _safe_isinstance(obj, 'numpy', 'ndarray') or\
999 elif _safe_isinstance(obj, 'numpy', 'ndarray') or\
936 _safe_isinstance(obj, 'numpy', 'void'):
1000 _safe_isinstance(obj, 'numpy', 'void'):
937 return obj.dtype.names or []
1001 return obj.dtype.names or []
938 return []
1002 return []
939
1003
940 try:
1004 try:
941 regexps = self.__dict_key_regexps
1005 regexps = self.__dict_key_regexps
942 except AttributeError:
1006 except AttributeError:
943 dict_key_re_fmt = r'''(?x)
1007 dict_key_re_fmt = r'''(?x)
944 ( # match dict-referring expression wrt greedy setting
1008 ( # match dict-referring expression wrt greedy setting
945 %s
1009 %s
946 )
1010 )
947 \[ # open bracket
1011 \[ # open bracket
948 \s* # and optional whitespace
1012 \s* # and optional whitespace
949 ([uUbB]? # string prefix (r not handled)
1013 ([uUbB]? # string prefix (r not handled)
950 (?: # unclosed string
1014 (?: # unclosed string
951 '(?:[^']|(?<!\\)\\')*
1015 '(?:[^']|(?<!\\)\\')*
952 |
1016 |
953 "(?:[^"]|(?<!\\)\\")*
1017 "(?:[^"]|(?<!\\)\\")*
954 )
1018 )
955 )?
1019 )?
956 $
1020 $
957 '''
1021 '''
958 regexps = self.__dict_key_regexps = {
1022 regexps = self.__dict_key_regexps = {
959 False: re.compile(dict_key_re_fmt % '''
1023 False: re.compile(dict_key_re_fmt % '''
960 # identifiers separated by .
1024 # identifiers separated by .
961 (?!\d)\w+
1025 (?!\d)\w+
962 (?:\.(?!\d)\w+)*
1026 (?:\.(?!\d)\w+)*
963 '''),
1027 '''),
964 True: re.compile(dict_key_re_fmt % '''
1028 True: re.compile(dict_key_re_fmt % '''
965 .+
1029 .+
966 ''')
1030 ''')
967 }
1031 }
968
1032
969 match = regexps[self.greedy].search(self.text_until_cursor)
1033 match = regexps[self.greedy].search(self.text_until_cursor)
970 if match is None:
1034 if match is None:
971 return []
1035 return []
972
1036
973 expr, prefix = match.groups()
1037 expr, prefix = match.groups()
974 try:
1038 try:
975 obj = eval(expr, self.namespace)
1039 obj = eval(expr, self.namespace)
976 except Exception:
1040 except Exception:
977 try:
1041 try:
978 obj = eval(expr, self.global_namespace)
1042 obj = eval(expr, self.global_namespace)
979 except Exception:
1043 except Exception:
980 return []
1044 return []
981
1045
982 keys = get_keys(obj)
1046 keys = get_keys(obj)
983 if not keys:
1047 if not keys:
984 return keys
1048 return keys
985 closing_quote, token_offset, matches = match_dict_keys(keys, prefix, self.splitter.delims)
1049 closing_quote, token_offset, matches = match_dict_keys(keys, prefix, self.splitter.delims)
986 if not matches:
1050 if not matches:
987 return matches
1051 return matches
988
1052
989 # get the cursor position of
1053 # get the cursor position of
990 # - the text being completed
1054 # - the text being completed
991 # - the start of the key text
1055 # - the start of the key text
992 # - the start of the completion
1056 # - the start of the completion
993 text_start = len(self.text_until_cursor) - len(text)
1057 text_start = len(self.text_until_cursor) - len(text)
994 if prefix:
1058 if prefix:
995 key_start = match.start(2)
1059 key_start = match.start(2)
996 completion_start = key_start + token_offset
1060 completion_start = key_start + token_offset
997 else:
1061 else:
998 key_start = completion_start = match.end()
1062 key_start = completion_start = match.end()
999
1063
1000 # grab the leading prefix, to make sure all completions start with `text`
1064 # grab the leading prefix, to make sure all completions start with `text`
1001 if text_start > key_start:
1065 if text_start > key_start:
1002 leading = ''
1066 leading = ''
1003 else:
1067 else:
1004 leading = text[text_start:completion_start]
1068 leading = text[text_start:completion_start]
1005
1069
1006 # the index of the `[` character
1070 # the index of the `[` character
1007 bracket_idx = match.end(1)
1071 bracket_idx = match.end(1)
1008
1072
1009 # append closing quote and bracket as appropriate
1073 # append closing quote and bracket as appropriate
1010 # this is *not* appropriate if the opening quote or bracket is outside
1074 # this is *not* appropriate if the opening quote or bracket is outside
1011 # the text given to this method
1075 # the text given to this method
1012 suf = ''
1076 suf = ''
1013 continuation = self.line_buffer[len(self.text_until_cursor):]
1077 continuation = self.line_buffer[len(self.text_until_cursor):]
1014 if key_start > text_start and closing_quote:
1078 if key_start > text_start and closing_quote:
1015 # quotes were opened inside text, maybe close them
1079 # quotes were opened inside text, maybe close them
1016 if continuation.startswith(closing_quote):
1080 if continuation.startswith(closing_quote):
1017 continuation = continuation[len(closing_quote):]
1081 continuation = continuation[len(closing_quote):]
1018 else:
1082 else:
1019 suf += closing_quote
1083 suf += closing_quote
1020 if bracket_idx > text_start:
1084 if bracket_idx > text_start:
1021 # brackets were opened inside text, maybe close them
1085 # brackets were opened inside text, maybe close them
1022 if not continuation.startswith(']'):
1086 if not continuation.startswith(']'):
1023 suf += ']'
1087 suf += ']'
1024
1088
1025 return [leading + k + suf for k in matches]
1089 return [leading + k + suf for k in matches]
1026
1090
1027 def unicode_name_matches(self, text):
1091 def unicode_name_matches(self, text):
1028 u"""Match Latex-like syntax for unicode characters base
1092 u"""Match Latex-like syntax for unicode characters base
1029 on the name of the character.
1093 on the name of the character.
1030
1094
1031 This does \\GREEK SMALL LETTER ETA -> Ξ·
1095 This does \\GREEK SMALL LETTER ETA -> Ξ·
1032
1096
1033 Works only on valid python 3 identifier, or on combining characters that
1097 Works only on valid python 3 identifier, or on combining characters that
1034 will combine to form a valid identifier.
1098 will combine to form a valid identifier.
1035
1099
1036 Used on Python 3 only.
1100 Used on Python 3 only.
1037 """
1101 """
1038 slashpos = text.rfind('\\')
1102 slashpos = text.rfind('\\')
1039 if slashpos > -1:
1103 if slashpos > -1:
1040 s = text[slashpos+1:]
1104 s = text[slashpos+1:]
1041 try :
1105 try :
1042 unic = unicodedata.lookup(s)
1106 unic = unicodedata.lookup(s)
1043 # allow combining chars
1107 # allow combining chars
1044 if ('a'+unic).isidentifier():
1108 if ('a'+unic).isidentifier():
1045 return '\\'+s,[unic]
1109 return '\\'+s,[unic]
1046 except KeyError as e:
1110 except KeyError as e:
1047 pass
1111 pass
1048 return u'', []
1112 return u'', []
1049
1113
1050
1114
1051
1115
1052
1116
1053 def latex_matches(self, text):
1117 def latex_matches(self, text):
1054 u"""Match Latex syntax for unicode characters.
1118 u"""Match Latex syntax for unicode characters.
1055
1119
1056 This does both \\alp -> \\alpha and \\alpha -> Ξ±
1120 This does both \\alp -> \\alpha and \\alpha -> Ξ±
1057
1121
1058 Used on Python 3 only.
1122 Used on Python 3 only.
1059 """
1123 """
1060 slashpos = text.rfind('\\')
1124 slashpos = text.rfind('\\')
1061 if slashpos > -1:
1125 if slashpos > -1:
1062 s = text[slashpos:]
1126 s = text[slashpos:]
1063 if s in latex_symbols:
1127 if s in latex_symbols:
1064 # Try to complete a full latex symbol to unicode
1128 # Try to complete a full latex symbol to unicode
1065 # \\alpha -> Ξ±
1129 # \\alpha -> Ξ±
1066 return s, [latex_symbols[s]]
1130 return s, [latex_symbols[s]]
1067 else:
1131 else:
1068 # If a user has partially typed a latex symbol, give them
1132 # If a user has partially typed a latex symbol, give them
1069 # a full list of options \al -> [\aleph, \alpha]
1133 # a full list of options \al -> [\aleph, \alpha]
1070 matches = [k for k in latex_symbols if k.startswith(s)]
1134 matches = [k for k in latex_symbols if k.startswith(s)]
1071 return s, matches
1135 return s, matches
1072 return u'', []
1136 return u'', []
1073
1137
1074 def dispatch_custom_completer(self, text):
1138 def dispatch_custom_completer(self, text):
1075 line = self.line_buffer
1139 line = self.line_buffer
1076 if not line.strip():
1140 if not line.strip():
1077 return None
1141 return None
1078
1142
1079 # Create a little structure to pass all the relevant information about
1143 # Create a little structure to pass all the relevant information about
1080 # the current completion to any custom completer.
1144 # the current completion to any custom completer.
1081 event = Bunch()
1145 event = Bunch()
1082 event.line = line
1146 event.line = line
1083 event.symbol = text
1147 event.symbol = text
1084 cmd = line.split(None,1)[0]
1148 cmd = line.split(None,1)[0]
1085 event.command = cmd
1149 event.command = cmd
1086 event.text_until_cursor = self.text_until_cursor
1150 event.text_until_cursor = self.text_until_cursor
1087
1151
1088 #print "\ncustom:{%s]\n" % event # dbg
1089
1090 # for foo etc, try also to find completer for %foo
1152 # for foo etc, try also to find completer for %foo
1091 if not cmd.startswith(self.magic_escape):
1153 if not cmd.startswith(self.magic_escape):
1092 try_magic = self.custom_completers.s_matches(
1154 try_magic = self.custom_completers.s_matches(
1093 self.magic_escape + cmd)
1155 self.magic_escape + cmd)
1094 else:
1156 else:
1095 try_magic = []
1157 try_magic = []
1096
1158
1097 for c in itertools.chain(self.custom_completers.s_matches(cmd),
1159 for c in itertools.chain(self.custom_completers.s_matches(cmd),
1098 try_magic,
1160 try_magic,
1099 self.custom_completers.flat_matches(self.text_until_cursor)):
1161 self.custom_completers.flat_matches(self.text_until_cursor)):
1100 try:
1162 try:
1101 res = c(event)
1163 res = c(event)
1102 if res:
1164 if res:
1103 # first, try case sensitive match
1165 # first, try case sensitive match
1104 withcase = [cast_unicode_py2(r) for r in res if r.startswith(text)]
1166 withcase = [cast_unicode_py2(r) for r in res if r.startswith(text)]
1105 if withcase:
1167 if withcase:
1106 return withcase
1168 return withcase
1107 # if none, then case insensitive ones are ok too
1169 # if none, then case insensitive ones are ok too
1108 text_low = text.lower()
1170 text_low = text.lower()
1109 return [cast_unicode_py2(r) for r in res if r.lower().startswith(text_low)]
1171 return [cast_unicode_py2(r) for r in res if r.lower().startswith(text_low)]
1110 except TryNext:
1172 except TryNext:
1111 pass
1173 pass
1112
1174
1113 return None
1175 return None
1114
1176
1115 def complete(self, text=None, line_buffer=None, cursor_pos=None):
1177 def complete(self, text=None, line_buffer=None, cursor_pos=None):
1116 """Find completions for the given text and line context.
1178 """Find completions for the given text and line context.
1117
1179
1118 Note that both the text and the line_buffer are optional, but at least
1180 Note that both the text and the line_buffer are optional, but at least
1119 one of them must be given.
1181 one of them must be given.
1120
1182
1121 Parameters
1183 Parameters
1122 ----------
1184 ----------
1123 text : string, optional
1185 text : string, optional
1124 Text to perform the completion on. If not given, the line buffer
1186 Text to perform the completion on. If not given, the line buffer
1125 is split using the instance's CompletionSplitter object.
1187 is split using the instance's CompletionSplitter object.
1126
1188
1127 line_buffer : string, optional
1189 line_buffer : string, optional
1128 If not given, the completer attempts to obtain the current line
1190 If not given, the completer attempts to obtain the current line
1129 buffer via readline. This keyword allows clients which are
1191 buffer via readline. This keyword allows clients which are
1130 requesting for text completions in non-readline contexts to inform
1192 requesting for text completions in non-readline contexts to inform
1131 the completer of the entire text.
1193 the completer of the entire text.
1132
1194
1133 cursor_pos : int, optional
1195 cursor_pos : int, optional
1134 Index of the cursor in the full line buffer. Should be provided by
1196 Index of the cursor in the full line buffer. Should be provided by
1135 remote frontends where kernel has no access to frontend state.
1197 remote frontends where kernel has no access to frontend state.
1136
1198
1137 Returns
1199 Returns
1138 -------
1200 -------
1139 text : str
1201 text : str
1140 Text that was actually used in the completion.
1202 Text that was actually used in the completion.
1141
1203
1142 matches : list
1204 matches : list
1143 A list of completion matches.
1205 A list of completion matches.
1144 """
1206 """
1145 # io.rprint('\nCOMP1 %r %r %r' % (text, line_buffer, cursor_pos)) # dbg
1146
1147 # if the cursor position isn't given, the only sane assumption we can
1207 # if the cursor position isn't given, the only sane assumption we can
1148 # make is that it's at the end of the line (the common case)
1208 # make is that it's at the end of the line (the common case)
1149 if cursor_pos is None:
1209 if cursor_pos is None:
1150 cursor_pos = len(line_buffer) if text is None else len(text)
1210 cursor_pos = len(line_buffer) if text is None else len(text)
1151
1211
1152 if PY3:
1212 if PY3:
1153
1213
1154 base_text = text if not line_buffer else line_buffer[:cursor_pos]
1214 base_text = text if not line_buffer else line_buffer[:cursor_pos]
1155 latex_text, latex_matches = self.latex_matches(base_text)
1215 latex_text, latex_matches = self.latex_matches(base_text)
1156 if latex_matches:
1216 if latex_matches:
1157 return latex_text, latex_matches
1217 return latex_text, latex_matches
1158 name_text = ''
1218 name_text = ''
1159 name_matches = []
1219 name_matches = []
1160 for meth in (self.unicode_name_matches, back_latex_name_matches, back_unicode_name_matches):
1220 for meth in (self.unicode_name_matches, back_latex_name_matches, back_unicode_name_matches):
1161 name_text, name_matches = meth(base_text)
1221 name_text, name_matches = meth(base_text)
1162 if name_text:
1222 if name_text:
1163 return name_text, name_matches
1223 return name_text, name_matches
1164
1224
1165 # if text is either None or an empty string, rely on the line buffer
1225 # if text is either None or an empty string, rely on the line buffer
1166 if not text:
1226 if not text:
1167 text = self.splitter.split_line(line_buffer, cursor_pos)
1227 text = self.splitter.split_line(line_buffer, cursor_pos)
1168
1228
1169 # If no line buffer is given, assume the input text is all there was
1229 # If no line buffer is given, assume the input text is all there was
1170 if line_buffer is None:
1230 if line_buffer is None:
1171 line_buffer = text
1231 line_buffer = text
1172
1232
1173 self.line_buffer = line_buffer
1233 self.line_buffer = line_buffer
1174 self.text_until_cursor = self.line_buffer[:cursor_pos]
1234 self.text_until_cursor = self.line_buffer[:cursor_pos]
1175 # io.rprint('COMP2 %r %r %r' % (text, line_buffer, cursor_pos)) # dbg
1176
1235
1177 # Start with a clean slate of completions
1236 # Start with a clean slate of completions
1178 self.matches[:] = []
1237 self.matches[:] = []
1179 custom_res = self.dispatch_custom_completer(text)
1238 custom_res = self.dispatch_custom_completer(text)
1180 if custom_res is not None:
1239 if custom_res is not None:
1181 # did custom completers produce something?
1240 # did custom completers produce something?
1182 self.matches = custom_res
1241 self.matches = custom_res
1183 else:
1242 else:
1184 # Extend the list of completions with the results of each
1243 # Extend the list of completions with the results of each
1185 # matcher, so we return results to the user from all
1244 # matcher, so we return results to the user from all
1186 # namespaces.
1245 # namespaces.
1187 if self.merge_completions:
1246 if self.merge_completions:
1188 self.matches = []
1247 self.matches = []
1189 for matcher in self.matchers:
1248 for matcher in self.matchers:
1190 try:
1249 try:
1191 self.matches.extend(matcher(text))
1250 self.matches.extend(matcher(text))
1192 except:
1251 except:
1193 # Show the ugly traceback if the matcher causes an
1252 # Show the ugly traceback if the matcher causes an
1194 # exception, but do NOT crash the kernel!
1253 # exception, but do NOT crash the kernel!
1195 sys.excepthook(*sys.exc_info())
1254 sys.excepthook(*sys.exc_info())
1196 else:
1255 else:
1197 for matcher in self.matchers:
1256 for matcher in self.matchers:
1198 self.matches = matcher(text)
1257 self.matches = matcher(text)
1199 if self.matches:
1258 if self.matches:
1200 break
1259 break
1201 # FIXME: we should extend our api to return a dict with completions for
1260 # FIXME: we should extend our api to return a dict with completions for
1202 # different types of objects. The rlcomplete() method could then
1261 # different types of objects. The rlcomplete() method could then
1203 # simply collapse the dict into a list for readline, but we'd have
1262 # simply collapse the dict into a list for readline, but we'd have
1204 # richer completion semantics in other evironments.
1263 # richer completion semantics in other evironments.
1264 if self.use_jedi_completions:
1265 self.matches.extend(self.python_jedi_matches(text, line_buffer, cursor_pos))
1205
1266
1206 self.matches = sorted(set(self.matches), key=completions_sorting_key)
1267 self.matches = sorted(set(self.matches), key=completions_sorting_key)
1207
1268
1208 #io.rprint('COMP TEXT, MATCHES: %r, %r' % (text, self.matches)) # dbg
1209 return text, self.matches
1269 return text, self.matches
1210
1270
1211 def rlcomplete(self, text, state):
1271 def rlcomplete(self, text, state):
1212 """Return the state-th possible completion for 'text'.
1272 """Return the state-th possible completion for 'text'.
1213
1273
1214 This is called successively with state == 0, 1, 2, ... until it
1274 This is called successively with state == 0, 1, 2, ... until it
1215 returns None. The completion should begin with 'text'.
1275 returns None. The completion should begin with 'text'.
1216
1276
1217 Parameters
1277 Parameters
1218 ----------
1278 ----------
1219 text : string
1279 text : string
1220 Text to perform the completion on.
1280 Text to perform the completion on.
1221
1281
1222 state : int
1282 state : int
1223 Counter used by readline.
1283 Counter used by readline.
1224 """
1284 """
1225 if state==0:
1285 if state==0:
1226
1286
1227 self.line_buffer = line_buffer = self.readline.get_line_buffer()
1287 self.line_buffer = line_buffer = self.readline.get_line_buffer()
1228 cursor_pos = self.readline.get_endidx()
1288 cursor_pos = self.readline.get_endidx()
1229
1289
1230 #io.rprint("\nRLCOMPLETE: %r %r %r" %
1290 #io.rprint("\nRLCOMPLETE: %r %r %r" %
1231 # (text, line_buffer, cursor_pos) ) # dbg
1291 # (text, line_buffer, cursor_pos) ) # dbg
1232
1292
1233 # if there is only a tab on a line with only whitespace, instead of
1293 # if there is only a tab on a line with only whitespace, instead of
1234 # the mostly useless 'do you want to see all million completions'
1294 # the mostly useless 'do you want to see all million completions'
1235 # message, just do the right thing and give the user his tab!
1295 # message, just do the right thing and give the user his tab!
1236 # Incidentally, this enables pasting of tabbed text from an editor
1296 # Incidentally, this enables pasting of tabbed text from an editor
1237 # (as long as autoindent is off).
1297 # (as long as autoindent is off).
1238
1298
1239 # It should be noted that at least pyreadline still shows file
1299 # It should be noted that at least pyreadline still shows file
1240 # completions - is there a way around it?
1300 # completions - is there a way around it?
1241
1301
1242 # don't apply this on 'dumb' terminals, such as emacs buffers, so
1302 # don't apply this on 'dumb' terminals, such as emacs buffers, so
1243 # we don't interfere with their own tab-completion mechanism.
1303 # we don't interfere with their own tab-completion mechanism.
1244 if not (self.dumb_terminal or line_buffer.strip()):
1304 if not (self.dumb_terminal or line_buffer.strip()):
1245 self.readline.insert_text('\t')
1305 self.readline.insert_text('\t')
1246 sys.stdout.flush()
1306 sys.stdout.flush()
1247 return None
1307 return None
1248
1308
1249 # Note: debugging exceptions that may occur in completion is very
1309 # Note: debugging exceptions that may occur in completion is very
1250 # tricky, because readline unconditionally silences them. So if
1310 # tricky, because readline unconditionally silences them. So if
1251 # during development you suspect a bug in the completion code, turn
1311 # during development you suspect a bug in the completion code, turn
1252 # this flag on temporarily by uncommenting the second form (don't
1312 # this flag on temporarily by uncommenting the second form (don't
1253 # flip the value in the first line, as the '# dbg' marker can be
1313 # flip the value in the first line, as the '# dbg' marker can be
1254 # automatically detected and is used elsewhere).
1314 # automatically detected and is used elsewhere).
1255 DEBUG = False
1315 DEBUG = False
1256 #DEBUG = True # dbg
1316 #DEBUG = True # dbg
1257 if DEBUG:
1317 if DEBUG:
1258 try:
1318 try:
1259 self.complete(text, line_buffer, cursor_pos)
1319 self.complete(text, line_buffer, cursor_pos)
1260 except:
1320 except:
1261 import traceback; traceback.print_exc()
1321 import traceback; traceback.print_exc()
1262 else:
1322 else:
1263 # The normal production version is here
1323 # The normal production version is here
1264
1324
1265 # This method computes the self.matches array
1325 # This method computes the self.matches array
1266 self.complete(text, line_buffer, cursor_pos)
1326 self.complete(text, line_buffer, cursor_pos)
1267
1327
1268 try:
1328 try:
1269 return self.matches[state]
1329 return self.matches[state]
1270 except IndexError:
1330 except IndexError:
1271 return None
1331 return None
1272
1332
@@ -1,803 +1,805 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """Tests for the IPython tab-completion machinery."""
2 """Tests for the IPython tab-completion machinery."""
3
3
4 # Copyright (c) IPython Development Team.
4 # Copyright (c) IPython Development Team.
5 # Distributed under the terms of the Modified BSD License.
5 # Distributed under the terms of the Modified BSD License.
6
6
7 import os
7 import os
8 import sys
8 import sys
9 import unittest
9 import unittest
10
10
11 from contextlib import contextmanager
11 from contextlib import contextmanager
12
12
13 import nose.tools as nt
13 import nose.tools as nt
14
14
15 from traitlets.config.loader import Config
15 from traitlets.config.loader import Config
16 from IPython import get_ipython
16 from IPython import get_ipython
17 from IPython.core import completer
17 from IPython.core import completer
18 from IPython.external.decorators import knownfailureif
18 from IPython.external.decorators import knownfailureif
19 from IPython.utils.tempdir import TemporaryDirectory, TemporaryWorkingDirectory
19 from IPython.utils.tempdir import TemporaryDirectory, TemporaryWorkingDirectory
20 from IPython.utils.generics import complete_object
20 from IPython.utils.generics import complete_object
21 from IPython.utils.py3compat import string_types, unicode_type
21 from IPython.utils.py3compat import string_types, unicode_type
22 from IPython.testing import decorators as dec
22 from IPython.testing import decorators as dec
23
23
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25 # Test functions
25 # Test functions
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27
27
28 @contextmanager
28 @contextmanager
29 def greedy_completion():
29 def greedy_completion():
30 ip = get_ipython()
30 ip = get_ipython()
31 greedy_original = ip.Completer.greedy
31 greedy_original = ip.Completer.greedy
32 try:
32 try:
33 ip.Completer.greedy = True
33 ip.Completer.greedy = True
34 yield
34 yield
35 finally:
35 finally:
36 ip.Completer.greedy = greedy_original
36 ip.Completer.greedy = greedy_original
37
37
38 def test_protect_filename():
38 def test_protect_filename():
39 pairs = [ ('abc','abc'),
39 pairs = [ ('abc','abc'),
40 (' abc',r'\ abc'),
40 (' abc',r'\ abc'),
41 ('a bc',r'a\ bc'),
41 ('a bc',r'a\ bc'),
42 ('a bc',r'a\ \ bc'),
42 ('a bc',r'a\ \ bc'),
43 (' bc',r'\ \ bc'),
43 (' bc',r'\ \ bc'),
44 ]
44 ]
45 # On posix, we also protect parens and other special characters
45 # On posix, we also protect parens and other special characters
46 if sys.platform != 'win32':
46 if sys.platform != 'win32':
47 pairs.extend( [('a(bc',r'a\(bc'),
47 pairs.extend( [('a(bc',r'a\(bc'),
48 ('a)bc',r'a\)bc'),
48 ('a)bc',r'a\)bc'),
49 ('a( )bc',r'a\(\ \)bc'),
49 ('a( )bc',r'a\(\ \)bc'),
50 ('a[1]bc', r'a\[1\]bc'),
50 ('a[1]bc', r'a\[1\]bc'),
51 ('a{1}bc', r'a\{1\}bc'),
51 ('a{1}bc', r'a\{1\}bc'),
52 ('a#bc', r'a\#bc'),
52 ('a#bc', r'a\#bc'),
53 ('a?bc', r'a\?bc'),
53 ('a?bc', r'a\?bc'),
54 ('a=bc', r'a\=bc'),
54 ('a=bc', r'a\=bc'),
55 ('a\\bc', r'a\\bc'),
55 ('a\\bc', r'a\\bc'),
56 ('a|bc', r'a\|bc'),
56 ('a|bc', r'a\|bc'),
57 ('a;bc', r'a\;bc'),
57 ('a;bc', r'a\;bc'),
58 ('a:bc', r'a\:bc'),
58 ('a:bc', r'a\:bc'),
59 ("a'bc", r"a\'bc"),
59 ("a'bc", r"a\'bc"),
60 ('a*bc', r'a\*bc'),
60 ('a*bc', r'a\*bc'),
61 ('a"bc', r'a\"bc'),
61 ('a"bc', r'a\"bc'),
62 ('a^bc', r'a\^bc'),
62 ('a^bc', r'a\^bc'),
63 ('a&bc', r'a\&bc'),
63 ('a&bc', r'a\&bc'),
64 ] )
64 ] )
65 # run the actual tests
65 # run the actual tests
66 for s1, s2 in pairs:
66 for s1, s2 in pairs:
67 s1p = completer.protect_filename(s1)
67 s1p = completer.protect_filename(s1)
68 nt.assert_equal(s1p, s2)
68 nt.assert_equal(s1p, s2)
69
69
70
70
71 def check_line_split(splitter, test_specs):
71 def check_line_split(splitter, test_specs):
72 for part1, part2, split in test_specs:
72 for part1, part2, split in test_specs:
73 cursor_pos = len(part1)
73 cursor_pos = len(part1)
74 line = part1+part2
74 line = part1+part2
75 out = splitter.split_line(line, cursor_pos)
75 out = splitter.split_line(line, cursor_pos)
76 nt.assert_equal(out, split)
76 nt.assert_equal(out, split)
77
77
78
78
79 def test_line_split():
79 def test_line_split():
80 """Basic line splitter test with default specs."""
80 """Basic line splitter test with default specs."""
81 sp = completer.CompletionSplitter()
81 sp = completer.CompletionSplitter()
82 # The format of the test specs is: part1, part2, expected answer. Parts 1
82 # The format of the test specs is: part1, part2, expected answer. Parts 1
83 # and 2 are joined into the 'line' sent to the splitter, as if the cursor
83 # and 2 are joined into the 'line' sent to the splitter, as if the cursor
84 # was at the end of part1. So an empty part2 represents someone hitting
84 # was at the end of part1. So an empty part2 represents someone hitting
85 # tab at the end of the line, the most common case.
85 # tab at the end of the line, the most common case.
86 t = [('run some/scrip', '', 'some/scrip'),
86 t = [('run some/scrip', '', 'some/scrip'),
87 ('run scripts/er', 'ror.py foo', 'scripts/er'),
87 ('run scripts/er', 'ror.py foo', 'scripts/er'),
88 ('echo $HOM', '', 'HOM'),
88 ('echo $HOM', '', 'HOM'),
89 ('print sys.pa', '', 'sys.pa'),
89 ('print sys.pa', '', 'sys.pa'),
90 ('print(sys.pa', '', 'sys.pa'),
90 ('print(sys.pa', '', 'sys.pa'),
91 ("execfile('scripts/er", '', 'scripts/er'),
91 ("execfile('scripts/er", '', 'scripts/er'),
92 ('a[x.', '', 'x.'),
92 ('a[x.', '', 'x.'),
93 ('a[x.', 'y', 'x.'),
93 ('a[x.', 'y', 'x.'),
94 ('cd "some_file/', '', 'some_file/'),
94 ('cd "some_file/', '', 'some_file/'),
95 ]
95 ]
96 check_line_split(sp, t)
96 check_line_split(sp, t)
97 # Ensure splitting works OK with unicode by re-running the tests with
97 # Ensure splitting works OK with unicode by re-running the tests with
98 # all inputs turned into unicode
98 # all inputs turned into unicode
99 check_line_split(sp, [ map(unicode_type, p) for p in t] )
99 check_line_split(sp, [ map(unicode_type, p) for p in t] )
100
100
101
101
102 def test_custom_completion_error():
102 def test_custom_completion_error():
103 """Test that errors from custom attribute completers are silenced."""
103 """Test that errors from custom attribute completers are silenced."""
104 ip = get_ipython()
104 ip = get_ipython()
105 class A(object): pass
105 class A(object): pass
106 ip.user_ns['a'] = A()
106 ip.user_ns['a'] = A()
107
107
108 @complete_object.when_type(A)
108 @complete_object.when_type(A)
109 def complete_A(a, existing_completions):
109 def complete_A(a, existing_completions):
110 raise TypeError("this should be silenced")
110 raise TypeError("this should be silenced")
111
111
112 ip.complete("a.")
112 ip.complete("a.")
113
113
114
114
115 def test_unicode_completions():
115 def test_unicode_completions():
116 ip = get_ipython()
116 ip = get_ipython()
117 # Some strings that trigger different types of completion. Check them both
117 # Some strings that trigger different types of completion. Check them both
118 # in str and unicode forms
118 # in str and unicode forms
119 s = ['ru', '%ru', 'cd /', 'floa', 'float(x)/']
119 s = ['ru', '%ru', 'cd /', 'floa', 'float(x)/']
120 for t in s + list(map(unicode_type, s)):
120 for t in s + list(map(unicode_type, s)):
121 # We don't need to check exact completion values (they may change
121 # We don't need to check exact completion values (they may change
122 # depending on the state of the namespace, but at least no exceptions
122 # depending on the state of the namespace, but at least no exceptions
123 # should be thrown and the return value should be a pair of text, list
123 # should be thrown and the return value should be a pair of text, list
124 # values.
124 # values.
125 text, matches = ip.complete(t)
125 text, matches = ip.complete(t)
126 nt.assert_true(isinstance(text, string_types))
126 nt.assert_true(isinstance(text, string_types))
127 nt.assert_true(isinstance(matches, list))
127 nt.assert_true(isinstance(matches, list))
128
128
129 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
129 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
130 def test_latex_completions():
130 def test_latex_completions():
131 from IPython.core.latex_symbols import latex_symbols
131 from IPython.core.latex_symbols import latex_symbols
132 import random
132 import random
133 ip = get_ipython()
133 ip = get_ipython()
134 # Test some random unicode symbols
134 # Test some random unicode symbols
135 keys = random.sample(latex_symbols.keys(), 10)
135 keys = random.sample(latex_symbols.keys(), 10)
136 for k in keys:
136 for k in keys:
137 text, matches = ip.complete(k)
137 text, matches = ip.complete(k)
138 nt.assert_equal(len(matches),1)
138 nt.assert_equal(len(matches),1)
139 nt.assert_equal(text, k)
139 nt.assert_equal(text, k)
140 nt.assert_equal(matches[0], latex_symbols[k])
140 nt.assert_equal(matches[0], latex_symbols[k])
141 # Test a more complex line
141 # Test a more complex line
142 text, matches = ip.complete(u'print(\\alpha')
142 text, matches = ip.complete(u'print(\\alpha')
143 nt.assert_equals(text, u'\\alpha')
143 nt.assert_equals(text, u'\\alpha')
144 nt.assert_equals(matches[0], latex_symbols['\\alpha'])
144 nt.assert_equals(matches[0], latex_symbols['\\alpha'])
145 # Test multiple matching latex symbols
145 # Test multiple matching latex symbols
146 text, matches = ip.complete(u'\\al')
146 text, matches = ip.complete(u'\\al')
147 nt.assert_in('\\alpha', matches)
147 nt.assert_in('\\alpha', matches)
148 nt.assert_in('\\aleph', matches)
148 nt.assert_in('\\aleph', matches)
149
149
150
150
151
151
152
152
153 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
153 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
154 def test_back_latex_completion():
154 def test_back_latex_completion():
155 ip = get_ipython()
155 ip = get_ipython()
156
156
157 # do not return more than 1 matches fro \beta, only the latex one.
157 # do not return more than 1 matches fro \beta, only the latex one.
158 name, matches = ip.complete('\\Ξ²')
158 name, matches = ip.complete('\\Ξ²')
159 nt.assert_equal(len(matches), 1)
159 nt.assert_equal(len(matches), 1)
160 nt.assert_equal(matches[0], '\\beta')
160 nt.assert_equal(matches[0], '\\beta')
161
161
162 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
162 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
163 def test_back_unicode_completion():
163 def test_back_unicode_completion():
164 ip = get_ipython()
164 ip = get_ipython()
165
165
166 name, matches = ip.complete('\\β…€')
166 name, matches = ip.complete('\\β…€')
167 nt.assert_equal(len(matches), 1)
167 nt.assert_equal(len(matches), 1)
168 nt.assert_equal(matches[0], '\\ROMAN NUMERAL FIVE')
168 nt.assert_equal(matches[0], '\\ROMAN NUMERAL FIVE')
169
169
170
170
171 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
171 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
172 def test_forward_unicode_completion():
172 def test_forward_unicode_completion():
173 ip = get_ipython()
173 ip = get_ipython()
174
174
175 name, matches = ip.complete('\\ROMAN NUMERAL FIVE')
175 name, matches = ip.complete('\\ROMAN NUMERAL FIVE')
176 nt.assert_equal(len(matches), 1)
176 nt.assert_equal(len(matches), 1)
177 nt.assert_equal(matches[0], 'β…€')
177 nt.assert_equal(matches[0], 'β…€')
178
178
179 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
179 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
180 def test_no_ascii_back_completion():
180 def test_no_ascii_back_completion():
181 ip = get_ipython()
181 ip = get_ipython()
182 with TemporaryWorkingDirectory(): # Avoid any filename completions
182 with TemporaryWorkingDirectory(): # Avoid any filename completions
183 # single ascii letter that don't have yet completions
183 # single ascii letter that don't have yet completions
184 for letter in 'fjqyJMQVWY' :
184 for letter in 'jJ' :
185 name, matches = ip.complete('\\'+letter)
185 name, matches = ip.complete('\\'+letter)
186 nt.assert_equal(matches, [])
186 nt.assert_equal(matches, [])
187
187
188
188
189
189
190
190
191 class CompletionSplitterTestCase(unittest.TestCase):
191 class CompletionSplitterTestCase(unittest.TestCase):
192 def setUp(self):
192 def setUp(self):
193 self.sp = completer.CompletionSplitter()
193 self.sp = completer.CompletionSplitter()
194
194
195 def test_delim_setting(self):
195 def test_delim_setting(self):
196 self.sp.delims = ' '
196 self.sp.delims = ' '
197 nt.assert_equal(self.sp.delims, ' ')
197 nt.assert_equal(self.sp.delims, ' ')
198 nt.assert_equal(self.sp._delim_expr, '[\ ]')
198 nt.assert_equal(self.sp._delim_expr, '[\ ]')
199
199
200 def test_spaces(self):
200 def test_spaces(self):
201 """Test with only spaces as split chars."""
201 """Test with only spaces as split chars."""
202 self.sp.delims = ' '
202 self.sp.delims = ' '
203 t = [('foo', '', 'foo'),
203 t = [('foo', '', 'foo'),
204 ('run foo', '', 'foo'),
204 ('run foo', '', 'foo'),
205 ('run foo', 'bar', 'foo'),
205 ('run foo', 'bar', 'foo'),
206 ]
206 ]
207 check_line_split(self.sp, t)
207 check_line_split(self.sp, t)
208
208
209
209
210 def test_has_open_quotes1():
210 def test_has_open_quotes1():
211 for s in ["'", "'''", "'hi' '"]:
211 for s in ["'", "'''", "'hi' '"]:
212 nt.assert_equal(completer.has_open_quotes(s), "'")
212 nt.assert_equal(completer.has_open_quotes(s), "'")
213
213
214
214
215 def test_has_open_quotes2():
215 def test_has_open_quotes2():
216 for s in ['"', '"""', '"hi" "']:
216 for s in ['"', '"""', '"hi" "']:
217 nt.assert_equal(completer.has_open_quotes(s), '"')
217 nt.assert_equal(completer.has_open_quotes(s), '"')
218
218
219
219
220 def test_has_open_quotes3():
220 def test_has_open_quotes3():
221 for s in ["''", "''' '''", "'hi' 'ipython'"]:
221 for s in ["''", "''' '''", "'hi' 'ipython'"]:
222 nt.assert_false(completer.has_open_quotes(s))
222 nt.assert_false(completer.has_open_quotes(s))
223
223
224
224
225 def test_has_open_quotes4():
225 def test_has_open_quotes4():
226 for s in ['""', '""" """', '"hi" "ipython"']:
226 for s in ['""', '""" """', '"hi" "ipython"']:
227 nt.assert_false(completer.has_open_quotes(s))
227 nt.assert_false(completer.has_open_quotes(s))
228
228
229
229
230 @knownfailureif(sys.platform == 'win32', "abspath completions fail on Windows")
230 @knownfailureif(sys.platform == 'win32', "abspath completions fail on Windows")
231 def test_abspath_file_completions():
231 def test_abspath_file_completions():
232 ip = get_ipython()
232 ip = get_ipython()
233 with TemporaryDirectory() as tmpdir:
233 with TemporaryDirectory() as tmpdir:
234 prefix = os.path.join(tmpdir, 'foo')
234 prefix = os.path.join(tmpdir, 'foo')
235 suffixes = ['1', '2']
235 suffixes = ['1', '2']
236 names = [prefix+s for s in suffixes]
236 names = [prefix+s for s in suffixes]
237 for n in names:
237 for n in names:
238 open(n, 'w').close()
238 open(n, 'w').close()
239
239
240 # Check simple completion
240 # Check simple completion
241 c = ip.complete(prefix)[1]
241 c = ip.complete(prefix)[1]
242 nt.assert_equal(c, names)
242 nt.assert_equal(c, names)
243
243
244 # Now check with a function call
244 # Now check with a function call
245 cmd = 'a = f("%s' % prefix
245 cmd = 'a = f("%s' % prefix
246 c = ip.complete(prefix, cmd)[1]
246 c = ip.complete(prefix, cmd)[1]
247 comp = [prefix+s for s in suffixes]
247 comp = [prefix+s for s in suffixes]
248 nt.assert_equal(c, comp)
248 nt.assert_equal(c, comp)
249
249
250
250
251 def test_local_file_completions():
251 def test_local_file_completions():
252 ip = get_ipython()
252 ip = get_ipython()
253 with TemporaryWorkingDirectory():
253 with TemporaryWorkingDirectory():
254 prefix = './foo'
254 prefix = './foo'
255 suffixes = ['1', '2']
255 suffixes = ['1', '2']
256 names = [prefix+s for s in suffixes]
256 names = [prefix+s for s in suffixes]
257 for n in names:
257 for n in names:
258 open(n, 'w').close()
258 open(n, 'w').close()
259
259
260 # Check simple completion
260 # Check simple completion
261 c = ip.complete(prefix)[1]
261 c = ip.complete(prefix)[1]
262 nt.assert_equal(c, names)
262 nt.assert_equal(c, names)
263
263
264 # Now check with a function call
264 # Now check with a function call
265 cmd = 'a = f("%s' % prefix
265 cmd = 'a = f("%s' % prefix
266 c = ip.complete(prefix, cmd)[1]
266 c = ip.complete(prefix, cmd)[1]
267 comp = [prefix+s for s in suffixes]
267 comp = set(prefix+s for s in suffixes)
268 nt.assert_equal(c, comp)
268 nt.assert_true(comp.issubset(set(c)))
269
269
270
270
271 def test_greedy_completions():
271 def test_greedy_completions():
272 ip = get_ipython()
272 ip = get_ipython()
273 ip.ex('a=list(range(5))')
273 ip.ex('a=list(range(5))')
274 _,c = ip.complete('.',line='a[0].')
274 _,c = ip.complete('.',line='a[0].')
275 nt.assert_false('a[0].real' in c,
275 nt.assert_false('.real' in c,
276 "Shouldn't have completed on a[0]: %s"%c)
276 "Shouldn't have completed on a[0]: %s"%c)
277 with greedy_completion():
277 with greedy_completion():
278 _,c = ip.complete('.',line='a[0].')
278 def _(line, cursor_pos, expect, message):
279 nt.assert_true('a[0].real' in c, "Should have completed on a[0]: %s"%c)
279 _,c = ip.complete('.', line=line, cursor_pos=cursor_pos)
280 nt.assert_in(expect, c, message%c)
281
282 yield _, 'a[0].', 5, '.real', "Should have completed on a[0].: %s"
283 yield _, 'a[0].r', 6, '.real', "Should have completed on a[0].r: %s"
284
285 if sys.version_info > (3,4):
286 yield _, 'a[0].from_', 10, '.from_bytes', "Should have completed on a[0].from_: %s"
287
288
289 def _2():
290 # jedi bug, this will be empty, makeitfail for now,
291 # once jedi is fixed, switch to assert_in
292 # https://github.com/davidhalter/jedi/issues/718
293 _,c = ip.complete('.',line='a[0].from', cursor_pos=9)
294 nt.assert_not_in('.from_bytes', c, "Should not have completed on a[0].from (jedi bug), if fails, update test to assert_in: %s"%c)
295 yield _2
296
280
297
281
298
282 def test_omit__names():
299 def test_omit__names():
283 # also happens to test IPCompleter as a configurable
300 # also happens to test IPCompleter as a configurable
284 ip = get_ipython()
301 ip = get_ipython()
285 ip._hidden_attr = 1
302 ip._hidden_attr = 1
286 ip._x = {}
303 ip._x = {}
287 c = ip.Completer
304 c = ip.Completer
288 ip.ex('ip=get_ipython()')
305 ip.ex('ip=get_ipython()')
289 cfg = Config()
306 cfg = Config()
290 cfg.IPCompleter.omit__names = 0
307 cfg.IPCompleter.omit__names = 0
291 c.update_config(cfg)
308 c.update_config(cfg)
292 s,matches = c.complete('ip.')
309 s,matches = c.complete('ip.')
293 nt.assert_in('ip.__str__', matches)
310 nt.assert_in('ip.__str__', matches)
294 nt.assert_in('ip._hidden_attr', matches)
311 nt.assert_in('ip._hidden_attr', matches)
295 cfg = Config()
312 cfg = Config()
296 cfg.IPCompleter.omit__names = 1
313 cfg.IPCompleter.omit__names = 1
297 c.update_config(cfg)
314 c.update_config(cfg)
298 s,matches = c.complete('ip.')
315 s,matches = c.complete('ip.')
299 nt.assert_not_in('ip.__str__', matches)
316 nt.assert_not_in('ip.__str__', matches)
300 nt.assert_in('ip._hidden_attr', matches)
317 nt.assert_in('ip._hidden_attr', matches)
301 cfg = Config()
318 cfg = Config()
302 cfg.IPCompleter.omit__names = 2
319 cfg.IPCompleter.omit__names = 2
303 c.update_config(cfg)
320 c.update_config(cfg)
304 s,matches = c.complete('ip.')
321 s,matches = c.complete('ip.')
305 nt.assert_not_in('ip.__str__', matches)
322 nt.assert_not_in('ip.__str__', matches)
306 nt.assert_not_in('ip._hidden_attr', matches)
323 nt.assert_not_in('ip._hidden_attr', matches)
307 s,matches = c.complete('ip._x.')
324 s,matches = c.complete('ip._x.')
308 nt.assert_in('ip._x.keys', matches)
325 nt.assert_in('ip._x.keys', matches)
309 del ip._hidden_attr
326 del ip._hidden_attr
310
327
311
328
312 def test_limit_to__all__False_ok():
329 def test_limit_to__all__False_ok():
313 ip = get_ipython()
330 ip = get_ipython()
314 c = ip.Completer
331 c = ip.Completer
315 ip.ex('class D: x=24')
332 ip.ex('class D: x=24')
316 ip.ex('d=D()')
333 ip.ex('d=D()')
317 cfg = Config()
334 cfg = Config()
318 cfg.IPCompleter.limit_to__all__ = False
335 cfg.IPCompleter.limit_to__all__ = False
319 c.update_config(cfg)
336 c.update_config(cfg)
320 s, matches = c.complete('d.')
337 s, matches = c.complete('d.')
321 nt.assert_in('d.x', matches)
338 nt.assert_in('d.x', matches)
322
339
323
340
324 def test_limit_to__all__True_ok():
325 ip = get_ipython()
326 c = ip.Completer
327 ip.ex('class D: x=24')
328 ip.ex('d=D()')
329 ip.ex("d.__all__=['z']")
330 cfg = Config()
331 cfg.IPCompleter.limit_to__all__ = True
332 c.update_config(cfg)
333 s, matches = c.complete('d.')
334 nt.assert_in('d.z', matches)
335 nt.assert_not_in('d.x', matches)
336
337
338 def test_get__all__entries_ok():
341 def test_get__all__entries_ok():
339 class A(object):
342 class A(object):
340 __all__ = ['x', 1]
343 __all__ = ['x', 1]
341 words = completer.get__all__entries(A())
344 words = completer.get__all__entries(A())
342 nt.assert_equal(words, ['x'])
345 nt.assert_equal(words, ['x'])
343
346
344
347
345 def test_get__all__entries_no__all__ok():
348 def test_get__all__entries_no__all__ok():
346 class A(object):
349 class A(object):
347 pass
350 pass
348 words = completer.get__all__entries(A())
351 words = completer.get__all__entries(A())
349 nt.assert_equal(words, [])
352 nt.assert_equal(words, [])
350
353
351
354
352 def test_func_kw_completions():
355 def test_func_kw_completions():
353 ip = get_ipython()
356 ip = get_ipython()
354 c = ip.Completer
357 c = ip.Completer
355 ip.ex('def myfunc(a=1,b=2): return a+b')
358 ip.ex('def myfunc(a=1,b=2): return a+b')
356 s, matches = c.complete(None, 'myfunc(1,b')
359 s, matches = c.complete(None, 'myfunc(1,b')
357 nt.assert_in('b=', matches)
360 nt.assert_in('b=', matches)
358 # Simulate completing with cursor right after b (pos==10):
361 # Simulate completing with cursor right after b (pos==10):
359 s, matches = c.complete(None, 'myfunc(1,b)', 10)
362 s, matches = c.complete(None, 'myfunc(1,b)', 10)
360 nt.assert_in('b=', matches)
363 nt.assert_in('b=', matches)
361 s, matches = c.complete(None, 'myfunc(a="escaped\\")string",b')
364 s, matches = c.complete(None, 'myfunc(a="escaped\\")string",b')
362 nt.assert_in('b=', matches)
365 nt.assert_in('b=', matches)
363 #builtin function
366 #builtin function
364 s, matches = c.complete(None, 'min(k, k')
367 s, matches = c.complete(None, 'min(k, k')
365 nt.assert_in('key=', matches)
368 nt.assert_in('key=', matches)
366
369
367
370
368 def test_default_arguments_from_docstring():
371 def test_default_arguments_from_docstring():
369 doc = min.__doc__
370 ip = get_ipython()
372 ip = get_ipython()
371 c = ip.Completer
373 c = ip.Completer
372 kwd = c._default_arguments_from_docstring(
374 kwd = c._default_arguments_from_docstring(
373 'min(iterable[, key=func]) -> value')
375 'min(iterable[, key=func]) -> value')
374 nt.assert_equal(kwd, ['key'])
376 nt.assert_equal(kwd, ['key'])
375 #with cython type etc
377 #with cython type etc
376 kwd = c._default_arguments_from_docstring(
378 kwd = c._default_arguments_from_docstring(
377 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
379 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
378 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
380 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
379 #white spaces
381 #white spaces
380 kwd = c._default_arguments_from_docstring(
382 kwd = c._default_arguments_from_docstring(
381 '\n Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
383 '\n Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
382 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
384 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
383
385
384 def test_line_magics():
386 def test_line_magics():
385 ip = get_ipython()
387 ip = get_ipython()
386 c = ip.Completer
388 c = ip.Completer
387 s, matches = c.complete(None, 'lsmag')
389 s, matches = c.complete(None, 'lsmag')
388 nt.assert_in('%lsmagic', matches)
390 nt.assert_in('%lsmagic', matches)
389 s, matches = c.complete(None, '%lsmag')
391 s, matches = c.complete(None, '%lsmag')
390 nt.assert_in('%lsmagic', matches)
392 nt.assert_in('%lsmagic', matches)
391
393
392
394
393 def test_cell_magics():
395 def test_cell_magics():
394 from IPython.core.magic import register_cell_magic
396 from IPython.core.magic import register_cell_magic
395
397
396 @register_cell_magic
398 @register_cell_magic
397 def _foo_cellm(line, cell):
399 def _foo_cellm(line, cell):
398 pass
400 pass
399
401
400 ip = get_ipython()
402 ip = get_ipython()
401 c = ip.Completer
403 c = ip.Completer
402
404
403 s, matches = c.complete(None, '_foo_ce')
405 s, matches = c.complete(None, '_foo_ce')
404 nt.assert_in('%%_foo_cellm', matches)
406 nt.assert_in('%%_foo_cellm', matches)
405 s, matches = c.complete(None, '%%_foo_ce')
407 s, matches = c.complete(None, '%%_foo_ce')
406 nt.assert_in('%%_foo_cellm', matches)
408 nt.assert_in('%%_foo_cellm', matches)
407
409
408
410
409 def test_line_cell_magics():
411 def test_line_cell_magics():
410 from IPython.core.magic import register_line_cell_magic
412 from IPython.core.magic import register_line_cell_magic
411
413
412 @register_line_cell_magic
414 @register_line_cell_magic
413 def _bar_cellm(line, cell):
415 def _bar_cellm(line, cell):
414 pass
416 pass
415
417
416 ip = get_ipython()
418 ip = get_ipython()
417 c = ip.Completer
419 c = ip.Completer
418
420
419 # The policy here is trickier, see comments in completion code. The
421 # The policy here is trickier, see comments in completion code. The
420 # returned values depend on whether the user passes %% or not explicitly,
422 # returned values depend on whether the user passes %% or not explicitly,
421 # and this will show a difference if the same name is both a line and cell
423 # and this will show a difference if the same name is both a line and cell
422 # magic.
424 # magic.
423 s, matches = c.complete(None, '_bar_ce')
425 s, matches = c.complete(None, '_bar_ce')
424 nt.assert_in('%_bar_cellm', matches)
426 nt.assert_in('%_bar_cellm', matches)
425 nt.assert_in('%%_bar_cellm', matches)
427 nt.assert_in('%%_bar_cellm', matches)
426 s, matches = c.complete(None, '%_bar_ce')
428 s, matches = c.complete(None, '%_bar_ce')
427 nt.assert_in('%_bar_cellm', matches)
429 nt.assert_in('%_bar_cellm', matches)
428 nt.assert_in('%%_bar_cellm', matches)
430 nt.assert_in('%%_bar_cellm', matches)
429 s, matches = c.complete(None, '%%_bar_ce')
431 s, matches = c.complete(None, '%%_bar_ce')
430 nt.assert_not_in('%_bar_cellm', matches)
432 nt.assert_not_in('%_bar_cellm', matches)
431 nt.assert_in('%%_bar_cellm', matches)
433 nt.assert_in('%%_bar_cellm', matches)
432
434
433
435
434 def test_magic_completion_order():
436 def test_magic_completion_order():
435
437
436 ip = get_ipython()
438 ip = get_ipython()
437 c = ip.Completer
439 c = ip.Completer
438
440
439 # Test ordering of magics and non-magics with the same name
441 # Test ordering of magics and non-magics with the same name
440 # We want the non-magic first
442 # We want the non-magic first
441
443
442 # Before importing matplotlib, there should only be one option:
444 # Before importing matplotlib, there should only be one option:
443
445
444 text, matches = c.complete('mat')
446 text, matches = c.complete('mat')
445 nt.assert_equal(matches, ["%matplotlib"])
447 nt.assert_equal(matches, ["%matplotlib"])
446
448
447
449
448 ip.run_cell("matplotlib = 1") # introduce name into namespace
450 ip.run_cell("matplotlib = 1") # introduce name into namespace
449
451
450 # After the import, there should be two options, ordered like this:
452 # After the import, there should be two options, ordered like this:
451 text, matches = c.complete('mat')
453 text, matches = c.complete('mat')
452 nt.assert_equal(matches, ["matplotlib", "%matplotlib"])
454 nt.assert_equal(matches, ["matplotlib", "%matplotlib"])
453
455
454
456
455 ip.run_cell("timeit = 1") # define a user variable called 'timeit'
457 ip.run_cell("timeit = 1") # define a user variable called 'timeit'
456
458
457 # Order of user variable and line and cell magics with same name:
459 # Order of user variable and line and cell magics with same name:
458 text, matches = c.complete('timeit')
460 text, matches = c.complete('timeit')
459 nt.assert_equal(matches, ["timeit", "%timeit","%%timeit"])
461 nt.assert_equal(matches, ["timeit", "%timeit","%%timeit"])
460
462
461
463
462 def test_dict_key_completion_string():
464 def test_dict_key_completion_string():
463 """Test dictionary key completion for string keys"""
465 """Test dictionary key completion for string keys"""
464 ip = get_ipython()
466 ip = get_ipython()
465 complete = ip.Completer.complete
467 complete = ip.Completer.complete
466
468
467 ip.user_ns['d'] = {'abc': None}
469 ip.user_ns['d'] = {'abc': None}
468
470
469 # check completion at different stages
471 # check completion at different stages
470 _, matches = complete(line_buffer="d[")
472 _, matches = complete(line_buffer="d[")
471 nt.assert_in("'abc'", matches)
473 nt.assert_in("'abc'", matches)
472 nt.assert_not_in("'abc']", matches)
474 nt.assert_not_in("'abc']", matches)
473
475
474 _, matches = complete(line_buffer="d['")
476 _, matches = complete(line_buffer="d['")
475 nt.assert_in("abc", matches)
477 nt.assert_in("abc", matches)
476 nt.assert_not_in("abc']", matches)
478 nt.assert_not_in("abc']", matches)
477
479
478 _, matches = complete(line_buffer="d['a")
480 _, matches = complete(line_buffer="d['a")
479 nt.assert_in("abc", matches)
481 nt.assert_in("abc", matches)
480 nt.assert_not_in("abc']", matches)
482 nt.assert_not_in("abc']", matches)
481
483
482 # check use of different quoting
484 # check use of different quoting
483 _, matches = complete(line_buffer="d[\"")
485 _, matches = complete(line_buffer="d[\"")
484 nt.assert_in("abc", matches)
486 nt.assert_in("abc", matches)
485 nt.assert_not_in('abc\"]', matches)
487 nt.assert_not_in('abc\"]', matches)
486
488
487 _, matches = complete(line_buffer="d[\"a")
489 _, matches = complete(line_buffer="d[\"a")
488 nt.assert_in("abc", matches)
490 nt.assert_in("abc", matches)
489 nt.assert_not_in('abc\"]', matches)
491 nt.assert_not_in('abc\"]', matches)
490
492
491 # check sensitivity to following context
493 # check sensitivity to following context
492 _, matches = complete(line_buffer="d[]", cursor_pos=2)
494 _, matches = complete(line_buffer="d[]", cursor_pos=2)
493 nt.assert_in("'abc'", matches)
495 nt.assert_in("'abc'", matches)
494
496
495 _, matches = complete(line_buffer="d['']", cursor_pos=3)
497 _, matches = complete(line_buffer="d['']", cursor_pos=3)
496 nt.assert_in("abc", matches)
498 nt.assert_in("abc", matches)
497 nt.assert_not_in("abc'", matches)
499 nt.assert_not_in("abc'", matches)
498 nt.assert_not_in("abc']", matches)
500 nt.assert_not_in("abc']", matches)
499
501
500 # check multiple solutions are correctly returned and that noise is not
502 # check multiple solutions are correctly returned and that noise is not
501 ip.user_ns['d'] = {'abc': None, 'abd': None, 'bad': None, object(): None,
503 ip.user_ns['d'] = {'abc': None, 'abd': None, 'bad': None, object(): None,
502 5: None}
504 5: None}
503
505
504 _, matches = complete(line_buffer="d['a")
506 _, matches = complete(line_buffer="d['a")
505 nt.assert_in("abc", matches)
507 nt.assert_in("abc", matches)
506 nt.assert_in("abd", matches)
508 nt.assert_in("abd", matches)
507 nt.assert_not_in("bad", matches)
509 nt.assert_not_in("bad", matches)
508 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
510 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
509
511
510 # check escaping and whitespace
512 # check escaping and whitespace
511 ip.user_ns['d'] = {'a\nb': None, 'a\'b': None, 'a"b': None, 'a word': None}
513 ip.user_ns['d'] = {'a\nb': None, 'a\'b': None, 'a"b': None, 'a word': None}
512 _, matches = complete(line_buffer="d['a")
514 _, matches = complete(line_buffer="d['a")
513 nt.assert_in("a\\nb", matches)
515 nt.assert_in("a\\nb", matches)
514 nt.assert_in("a\\'b", matches)
516 nt.assert_in("a\\'b", matches)
515 nt.assert_in("a\"b", matches)
517 nt.assert_in("a\"b", matches)
516 nt.assert_in("a word", matches)
518 nt.assert_in("a word", matches)
517 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
519 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
518
520
519 # - can complete on non-initial word of the string
521 # - can complete on non-initial word of the string
520 _, matches = complete(line_buffer="d['a w")
522 _, matches = complete(line_buffer="d['a w")
521 nt.assert_in("word", matches)
523 nt.assert_in("word", matches)
522
524
523 # - understands quote escaping
525 # - understands quote escaping
524 _, matches = complete(line_buffer="d['a\\'")
526 _, matches = complete(line_buffer="d['a\\'")
525 nt.assert_in("b", matches)
527 nt.assert_in("b", matches)
526
528
527 # - default quoting should work like repr
529 # - default quoting should work like repr
528 _, matches = complete(line_buffer="d[")
530 _, matches = complete(line_buffer="d[")
529 nt.assert_in("\"a'b\"", matches)
531 nt.assert_in("\"a'b\"", matches)
530
532
531 # - when opening quote with ", possible to match with unescaped apostrophe
533 # - when opening quote with ", possible to match with unescaped apostrophe
532 _, matches = complete(line_buffer="d[\"a'")
534 _, matches = complete(line_buffer="d[\"a'")
533 nt.assert_in("b", matches)
535 nt.assert_in("b", matches)
534
536
535 # need to not split at delims that readline won't split at
537 # need to not split at delims that readline won't split at
536 if '-' not in ip.Completer.splitter.delims:
538 if '-' not in ip.Completer.splitter.delims:
537 ip.user_ns['d'] = {'before-after': None}
539 ip.user_ns['d'] = {'before-after': None}
538 _, matches = complete(line_buffer="d['before-af")
540 _, matches = complete(line_buffer="d['before-af")
539 nt.assert_in('before-after', matches)
541 nt.assert_in('before-after', matches)
540
542
541 def test_dict_key_completion_contexts():
543 def test_dict_key_completion_contexts():
542 """Test expression contexts in which dict key completion occurs"""
544 """Test expression contexts in which dict key completion occurs"""
543 ip = get_ipython()
545 ip = get_ipython()
544 complete = ip.Completer.complete
546 complete = ip.Completer.complete
545 d = {'abc': None}
547 d = {'abc': None}
546 ip.user_ns['d'] = d
548 ip.user_ns['d'] = d
547
549
548 class C:
550 class C:
549 data = d
551 data = d
550 ip.user_ns['C'] = C
552 ip.user_ns['C'] = C
551 ip.user_ns['get'] = lambda: d
553 ip.user_ns['get'] = lambda: d
552
554
553 def assert_no_completion(**kwargs):
555 def assert_no_completion(**kwargs):
554 _, matches = complete(**kwargs)
556 _, matches = complete(**kwargs)
555 nt.assert_not_in('abc', matches)
557 nt.assert_not_in('abc', matches)
556 nt.assert_not_in('abc\'', matches)
558 nt.assert_not_in('abc\'', matches)
557 nt.assert_not_in('abc\']', matches)
559 nt.assert_not_in('abc\']', matches)
558 nt.assert_not_in('\'abc\'', matches)
560 nt.assert_not_in('\'abc\'', matches)
559 nt.assert_not_in('\'abc\']', matches)
561 nt.assert_not_in('\'abc\']', matches)
560
562
561 def assert_completion(**kwargs):
563 def assert_completion(**kwargs):
562 _, matches = complete(**kwargs)
564 _, matches = complete(**kwargs)
563 nt.assert_in("'abc'", matches)
565 nt.assert_in("'abc'", matches)
564 nt.assert_not_in("'abc']", matches)
566 nt.assert_not_in("'abc']", matches)
565
567
566 # no completion after string closed, even if reopened
568 # no completion after string closed, even if reopened
567 assert_no_completion(line_buffer="d['a'")
569 assert_no_completion(line_buffer="d['a'")
568 assert_no_completion(line_buffer="d[\"a\"")
570 assert_no_completion(line_buffer="d[\"a\"")
569 assert_no_completion(line_buffer="d['a' + ")
571 assert_no_completion(line_buffer="d['a' + ")
570 assert_no_completion(line_buffer="d['a' + '")
572 assert_no_completion(line_buffer="d['a' + '")
571
573
572 # completion in non-trivial expressions
574 # completion in non-trivial expressions
573 assert_completion(line_buffer="+ d[")
575 assert_completion(line_buffer="+ d[")
574 assert_completion(line_buffer="(d[")
576 assert_completion(line_buffer="(d[")
575 assert_completion(line_buffer="C.data[")
577 assert_completion(line_buffer="C.data[")
576
578
577 # greedy flag
579 # greedy flag
578 def assert_completion(**kwargs):
580 def assert_completion(**kwargs):
579 _, matches = complete(**kwargs)
581 _, matches = complete(**kwargs)
580 nt.assert_in("get()['abc']", matches)
582 nt.assert_in("get()['abc']", matches)
581
583
582 assert_no_completion(line_buffer="get()[")
584 assert_no_completion(line_buffer="get()[")
583 with greedy_completion():
585 with greedy_completion():
584 assert_completion(line_buffer="get()[")
586 assert_completion(line_buffer="get()[")
585 assert_completion(line_buffer="get()['")
587 assert_completion(line_buffer="get()['")
586 assert_completion(line_buffer="get()['a")
588 assert_completion(line_buffer="get()['a")
587 assert_completion(line_buffer="get()['ab")
589 assert_completion(line_buffer="get()['ab")
588 assert_completion(line_buffer="get()['abc")
590 assert_completion(line_buffer="get()['abc")
589
591
590
592
591
593
592 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
594 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
593 def test_dict_key_completion_bytes():
595 def test_dict_key_completion_bytes():
594 """Test handling of bytes in dict key completion"""
596 """Test handling of bytes in dict key completion"""
595 ip = get_ipython()
597 ip = get_ipython()
596 complete = ip.Completer.complete
598 complete = ip.Completer.complete
597
599
598 ip.user_ns['d'] = {'abc': None, b'abd': None}
600 ip.user_ns['d'] = {'abc': None, b'abd': None}
599
601
600 _, matches = complete(line_buffer="d[")
602 _, matches = complete(line_buffer="d[")
601 nt.assert_in("'abc'", matches)
603 nt.assert_in("'abc'", matches)
602 nt.assert_in("b'abd'", matches)
604 nt.assert_in("b'abd'", matches)
603
605
604 if False: # not currently implemented
606 if False: # not currently implemented
605 _, matches = complete(line_buffer="d[b")
607 _, matches = complete(line_buffer="d[b")
606 nt.assert_in("b'abd'", matches)
608 nt.assert_in("b'abd'", matches)
607 nt.assert_not_in("b'abc'", matches)
609 nt.assert_not_in("b'abc'", matches)
608
610
609 _, matches = complete(line_buffer="d[b'")
611 _, matches = complete(line_buffer="d[b'")
610 nt.assert_in("abd", matches)
612 nt.assert_in("abd", matches)
611 nt.assert_not_in("abc", matches)
613 nt.assert_not_in("abc", matches)
612
614
613 _, matches = complete(line_buffer="d[B'")
615 _, matches = complete(line_buffer="d[B'")
614 nt.assert_in("abd", matches)
616 nt.assert_in("abd", matches)
615 nt.assert_not_in("abc", matches)
617 nt.assert_not_in("abc", matches)
616
618
617 _, matches = complete(line_buffer="d['")
619 _, matches = complete(line_buffer="d['")
618 nt.assert_in("abc", matches)
620 nt.assert_in("abc", matches)
619 nt.assert_not_in("abd", matches)
621 nt.assert_not_in("abd", matches)
620
622
621
623
622 @dec.onlyif(sys.version_info[0] < 3, 'This test only applies in Py<3')
624 @dec.onlyif(sys.version_info[0] < 3, 'This test only applies in Py<3')
623 def test_dict_key_completion_unicode_py2():
625 def test_dict_key_completion_unicode_py2():
624 """Test handling of unicode in dict key completion"""
626 """Test handling of unicode in dict key completion"""
625 ip = get_ipython()
627 ip = get_ipython()
626 complete = ip.Completer.complete
628 complete = ip.Completer.complete
627
629
628 ip.user_ns['d'] = {u'abc': None,
630 ip.user_ns['d'] = {u'abc': None,
629 u'a\u05d0b': None}
631 u'a\u05d0b': None}
630
632
631 _, matches = complete(line_buffer="d[")
633 _, matches = complete(line_buffer="d[")
632 nt.assert_in("u'abc'", matches)
634 nt.assert_in("u'abc'", matches)
633 nt.assert_in("u'a\\u05d0b'", matches)
635 nt.assert_in("u'a\\u05d0b'", matches)
634
636
635 _, matches = complete(line_buffer="d['a")
637 _, matches = complete(line_buffer="d['a")
636 nt.assert_in("abc", matches)
638 nt.assert_in("abc", matches)
637 nt.assert_not_in("a\\u05d0b", matches)
639 nt.assert_not_in("a\\u05d0b", matches)
638
640
639 _, matches = complete(line_buffer="d[u'a")
641 _, matches = complete(line_buffer="d[u'a")
640 nt.assert_in("abc", matches)
642 nt.assert_in("abc", matches)
641 nt.assert_in("a\\u05d0b", matches)
643 nt.assert_in("a\\u05d0b", matches)
642
644
643 _, matches = complete(line_buffer="d[U'a")
645 _, matches = complete(line_buffer="d[U'a")
644 nt.assert_in("abc", matches)
646 nt.assert_in("abc", matches)
645 nt.assert_in("a\\u05d0b", matches)
647 nt.assert_in("a\\u05d0b", matches)
646
648
647 # query using escape
649 # query using escape
648 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
650 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
649 nt.assert_in("u05d0b", matches) # tokenized after \\
651 nt.assert_in("u05d0b", matches) # tokenized after \\
650
652
651 # query using character
653 # query using character
652 _, matches = complete(line_buffer=u"d[u'a\u05d0")
654 _, matches = complete(line_buffer=u"d[u'a\u05d0")
653 nt.assert_in(u"a\u05d0b", matches)
655 nt.assert_in(u"a\u05d0b", matches)
654
656
655 with greedy_completion():
657 with greedy_completion():
656 _, matches = complete(line_buffer="d[")
658 _, matches = complete(line_buffer="d[")
657 nt.assert_in("d[u'abc']", matches)
659 nt.assert_in("d[u'abc']", matches)
658 nt.assert_in("d[u'a\\u05d0b']", matches)
660 nt.assert_in("d[u'a\\u05d0b']", matches)
659
661
660 _, matches = complete(line_buffer="d['a")
662 _, matches = complete(line_buffer="d['a")
661 nt.assert_in("d['abc']", matches)
663 nt.assert_in("d['abc']", matches)
662 nt.assert_not_in("d[u'a\\u05d0b']", matches)
664 nt.assert_not_in("d[u'a\\u05d0b']", matches)
663
665
664 _, matches = complete(line_buffer="d[u'a")
666 _, matches = complete(line_buffer="d[u'a")
665 nt.assert_in("d[u'abc']", matches)
667 nt.assert_in("d[u'abc']", matches)
666 nt.assert_in("d[u'a\\u05d0b']", matches)
668 nt.assert_in("d[u'a\\u05d0b']", matches)
667
669
668 _, matches = complete(line_buffer="d[U'a")
670 _, matches = complete(line_buffer="d[U'a")
669 nt.assert_in("d[U'abc']", matches)
671 nt.assert_in("d[U'abc']", matches)
670 nt.assert_in("d[U'a\\u05d0b']", matches)
672 nt.assert_in("d[U'a\\u05d0b']", matches)
671
673
672 # query using escape
674 # query using escape
673 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
675 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
674 nt.assert_in("d[u'a\\u05d0b']", matches) # tokenized after \\
676 nt.assert_in("d[u'a\\u05d0b']", matches) # tokenized after \\
675
677
676 # query using character
678 # query using character
677 _, matches = complete(line_buffer=u"d[u'a\u05d0")
679 _, matches = complete(line_buffer=u"d[u'a\u05d0")
678 nt.assert_in(u"d[u'a\u05d0b']", matches)
680 nt.assert_in(u"d[u'a\u05d0b']", matches)
679
681
680
682
681 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
683 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
682 def test_dict_key_completion_unicode_py3():
684 def test_dict_key_completion_unicode_py3():
683 """Test handling of unicode in dict key completion"""
685 """Test handling of unicode in dict key completion"""
684 ip = get_ipython()
686 ip = get_ipython()
685 complete = ip.Completer.complete
687 complete = ip.Completer.complete
686
688
687 ip.user_ns['d'] = {u'a\u05d0': None}
689 ip.user_ns['d'] = {u'a\u05d0': None}
688
690
689 # query using escape
691 # query using escape
690 _, matches = complete(line_buffer="d['a\\u05d0")
692 _, matches = complete(line_buffer="d['a\\u05d0")
691 nt.assert_in("u05d0", matches) # tokenized after \\
693 nt.assert_in("u05d0", matches) # tokenized after \\
692
694
693 # query using character
695 # query using character
694 _, matches = complete(line_buffer="d['a\u05d0")
696 _, matches = complete(line_buffer="d['a\u05d0")
695 nt.assert_in(u"a\u05d0", matches)
697 nt.assert_in(u"a\u05d0", matches)
696
698
697 with greedy_completion():
699 with greedy_completion():
698 # query using escape
700 # query using escape
699 _, matches = complete(line_buffer="d['a\\u05d0")
701 _, matches = complete(line_buffer="d['a\\u05d0")
700 nt.assert_in("d['a\\u05d0']", matches) # tokenized after \\
702 nt.assert_in("d['a\\u05d0']", matches) # tokenized after \\
701
703
702 # query using character
704 # query using character
703 _, matches = complete(line_buffer="d['a\u05d0")
705 _, matches = complete(line_buffer="d['a\u05d0")
704 nt.assert_in(u"d['a\u05d0']", matches)
706 nt.assert_in(u"d['a\u05d0']", matches)
705
707
706
708
707
709
708 @dec.skip_without('numpy')
710 @dec.skip_without('numpy')
709 def test_struct_array_key_completion():
711 def test_struct_array_key_completion():
710 """Test dict key completion applies to numpy struct arrays"""
712 """Test dict key completion applies to numpy struct arrays"""
711 import numpy
713 import numpy
712 ip = get_ipython()
714 ip = get_ipython()
713 complete = ip.Completer.complete
715 complete = ip.Completer.complete
714 ip.user_ns['d'] = numpy.array([], dtype=[('hello', 'f'), ('world', 'f')])
716 ip.user_ns['d'] = numpy.array([], dtype=[('hello', 'f'), ('world', 'f')])
715 _, matches = complete(line_buffer="d['")
717 _, matches = complete(line_buffer="d['")
716 nt.assert_in("hello", matches)
718 nt.assert_in("hello", matches)
717 nt.assert_in("world", matches)
719 nt.assert_in("world", matches)
718 # complete on the numpy struct itself
720 # complete on the numpy struct itself
719 dt = numpy.dtype([('my_head', [('my_dt', '>u4'), ('my_df', '>u4')]),
721 dt = numpy.dtype([('my_head', [('my_dt', '>u4'), ('my_df', '>u4')]),
720 ('my_data', '>f4', 5)])
722 ('my_data', '>f4', 5)])
721 x = numpy.zeros(2, dtype=dt)
723 x = numpy.zeros(2, dtype=dt)
722 ip.user_ns['d'] = x[1]
724 ip.user_ns['d'] = x[1]
723 _, matches = complete(line_buffer="d['")
725 _, matches = complete(line_buffer="d['")
724 nt.assert_in("my_head", matches)
726 nt.assert_in("my_head", matches)
725 nt.assert_in("my_data", matches)
727 nt.assert_in("my_data", matches)
726 # complete on a nested level
728 # complete on a nested level
727 with greedy_completion():
729 with greedy_completion():
728 ip.user_ns['d'] = numpy.zeros(2, dtype=dt)
730 ip.user_ns['d'] = numpy.zeros(2, dtype=dt)
729 _, matches = complete(line_buffer="d[1]['my_head']['")
731 _, matches = complete(line_buffer="d[1]['my_head']['")
730 nt.assert_true(any(["my_dt" in m for m in matches]))
732 nt.assert_true(any(["my_dt" in m for m in matches]))
731 nt.assert_true(any(["my_df" in m for m in matches]))
733 nt.assert_true(any(["my_df" in m for m in matches]))
732
734
733
735
734 @dec.skip_without('pandas')
736 @dec.skip_without('pandas')
735 def test_dataframe_key_completion():
737 def test_dataframe_key_completion():
736 """Test dict key completion applies to pandas DataFrames"""
738 """Test dict key completion applies to pandas DataFrames"""
737 import pandas
739 import pandas
738 ip = get_ipython()
740 ip = get_ipython()
739 complete = ip.Completer.complete
741 complete = ip.Completer.complete
740 ip.user_ns['d'] = pandas.DataFrame({'hello': [1], 'world': [2]})
742 ip.user_ns['d'] = pandas.DataFrame({'hello': [1], 'world': [2]})
741 _, matches = complete(line_buffer="d['")
743 _, matches = complete(line_buffer="d['")
742 nt.assert_in("hello", matches)
744 nt.assert_in("hello", matches)
743 nt.assert_in("world", matches)
745 nt.assert_in("world", matches)
744
746
745
747
746 def test_dict_key_completion_invalids():
748 def test_dict_key_completion_invalids():
747 """Smoke test cases dict key completion can't handle"""
749 """Smoke test cases dict key completion can't handle"""
748 ip = get_ipython()
750 ip = get_ipython()
749 complete = ip.Completer.complete
751 complete = ip.Completer.complete
750
752
751 ip.user_ns['no_getitem'] = None
753 ip.user_ns['no_getitem'] = None
752 ip.user_ns['no_keys'] = []
754 ip.user_ns['no_keys'] = []
753 ip.user_ns['cant_call_keys'] = dict
755 ip.user_ns['cant_call_keys'] = dict
754 ip.user_ns['empty'] = {}
756 ip.user_ns['empty'] = {}
755 ip.user_ns['d'] = {'abc': 5}
757 ip.user_ns['d'] = {'abc': 5}
756
758
757 _, matches = complete(line_buffer="no_getitem['")
759 _, matches = complete(line_buffer="no_getitem['")
758 _, matches = complete(line_buffer="no_keys['")
760 _, matches = complete(line_buffer="no_keys['")
759 _, matches = complete(line_buffer="cant_call_keys['")
761 _, matches = complete(line_buffer="cant_call_keys['")
760 _, matches = complete(line_buffer="empty['")
762 _, matches = complete(line_buffer="empty['")
761 _, matches = complete(line_buffer="name_error['")
763 _, matches = complete(line_buffer="name_error['")
762 _, matches = complete(line_buffer="d['\\") # incomplete escape
764 _, matches = complete(line_buffer="d['\\") # incomplete escape
763
765
764 class KeyCompletable(object):
766 class KeyCompletable(object):
765 def __init__(self, things=()):
767 def __init__(self, things=()):
766 self.things = things
768 self.things = things
767
769
768 def _ipython_key_completions_(self):
770 def _ipython_key_completions_(self):
769 return list(self.things)
771 return list(self.things)
770
772
771 def test_object_key_completion():
773 def test_object_key_completion():
772 ip = get_ipython()
774 ip = get_ipython()
773 ip.user_ns['key_completable'] = KeyCompletable(['qwerty', 'qwick'])
775 ip.user_ns['key_completable'] = KeyCompletable(['qwerty', 'qwick'])
774
776
775 _, matches = ip.Completer.complete(line_buffer="key_completable['qw")
777 _, matches = ip.Completer.complete(line_buffer="key_completable['qw")
776 nt.assert_in('qwerty', matches)
778 nt.assert_in('qwerty', matches)
777 nt.assert_in('qwick', matches)
779 nt.assert_in('qwick', matches)
778
780
779
781
780 def test_aimport_module_completer():
782 def test_aimport_module_completer():
781 ip = get_ipython()
783 ip = get_ipython()
782 _, matches = ip.complete('i', '%aimport i')
784 _, matches = ip.complete('i', '%aimport i')
783 nt.assert_in('io', matches)
785 nt.assert_in('io', matches)
784 nt.assert_not_in('int', matches)
786 nt.assert_not_in('int', matches)
785
787
786 def test_nested_import_module_completer():
788 def test_nested_import_module_completer():
787 ip = get_ipython()
789 ip = get_ipython()
788 _, matches = ip.complete(None, 'import IPython.co', 17)
790 _, matches = ip.complete(None, 'import IPython.co', 17)
789 nt.assert_in('IPython.core', matches)
791 nt.assert_in('IPython.core', matches)
790 nt.assert_not_in('import IPython.core', matches)
792 nt.assert_not_in('import IPython.core', matches)
791 nt.assert_not_in('IPython.display', matches)
793 nt.assert_not_in('IPython.display', matches)
792
794
793 def test_import_module_completer():
795 def test_import_module_completer():
794 ip = get_ipython()
796 ip = get_ipython()
795 _, matches = ip.complete('i', 'import i')
797 _, matches = ip.complete('i', 'import i')
796 nt.assert_in('io', matches)
798 nt.assert_in('io', matches)
797 nt.assert_not_in('int', matches)
799 nt.assert_not_in('int', matches)
798
800
799 def test_from_module_completer():
801 def test_from_module_completer():
800 ip = get_ipython()
802 ip = get_ipython()
801 _, matches = ip.complete('B', 'from io import B')
803 _, matches = ip.complete('B', 'from io import B')
802 nt.assert_in('BytesIO', matches)
804 nt.assert_in('BytesIO', matches)
803 nt.assert_not_in('BaseException', matches)
805 nt.assert_not_in('BaseException', matches)
@@ -1,451 +1,455 b''
1 """IPython terminal interface using prompt_toolkit in place of readline"""
1 """IPython terminal interface using prompt_toolkit in place of readline"""
2 from __future__ import print_function
2 from __future__ import print_function
3
3
4 import os
4 import os
5 import sys
5 import sys
6 import signal
6 import signal
7 import unicodedata
7 import unicodedata
8 from warnings import warn
8 from warnings import warn
9 from wcwidth import wcwidth
9 from wcwidth import wcwidth
10
10
11 from IPython.core.error import TryNext
11 from IPython.core.error import TryNext
12 from IPython.core.interactiveshell import InteractiveShell
12 from IPython.core.interactiveshell import InteractiveShell
13 from IPython.utils.py3compat import PY3, cast_unicode_py2, input
13 from IPython.utils.py3compat import PY3, cast_unicode_py2, input
14 from IPython.utils.terminal import toggle_set_term_title, set_term_title
14 from IPython.utils.terminal import toggle_set_term_title, set_term_title
15 from IPython.utils.process import abbrev_cwd
15 from IPython.utils.process import abbrev_cwd
16 from traitlets import Bool, CBool, Unicode, Dict, Integer
16 from traitlets import Bool, CBool, Unicode, Dict, Integer
17
17
18 from prompt_toolkit.completion import Completer, Completion
18 from prompt_toolkit.completion import Completer, Completion
19 from prompt_toolkit.enums import DEFAULT_BUFFER, SEARCH_BUFFER
19 from prompt_toolkit.enums import DEFAULT_BUFFER, SEARCH_BUFFER
20 from prompt_toolkit.filters import HasFocus, HasSelection, Condition
20 from prompt_toolkit.filters import HasFocus, HasSelection, Condition
21 from prompt_toolkit.history import InMemoryHistory
21 from prompt_toolkit.history import InMemoryHistory
22 from prompt_toolkit.shortcuts import create_prompt_application, create_eventloop, create_prompt_layout
22 from prompt_toolkit.shortcuts import create_prompt_application, create_eventloop, create_prompt_layout
23 from prompt_toolkit.interface import CommandLineInterface
23 from prompt_toolkit.interface import CommandLineInterface
24 from prompt_toolkit.key_binding.manager import KeyBindingManager
24 from prompt_toolkit.key_binding.manager import KeyBindingManager
25 from prompt_toolkit.key_binding.vi_state import InputMode
25 from prompt_toolkit.key_binding.vi_state import InputMode
26 from prompt_toolkit.key_binding.bindings.vi import ViStateFilter
26 from prompt_toolkit.key_binding.bindings.vi import ViStateFilter
27 from prompt_toolkit.keys import Keys
27 from prompt_toolkit.keys import Keys
28 from prompt_toolkit.layout.lexers import Lexer
28 from prompt_toolkit.layout.lexers import Lexer
29 from prompt_toolkit.layout.lexers import PygmentsLexer
29 from prompt_toolkit.layout.lexers import PygmentsLexer
30 from prompt_toolkit.styles import PygmentsStyle, DynamicStyle
30 from prompt_toolkit.styles import PygmentsStyle, DynamicStyle
31
31
32 from pygments.styles import get_style_by_name, get_all_styles
32 from pygments.styles import get_style_by_name, get_all_styles
33 from pygments.lexers import Python3Lexer, BashLexer, PythonLexer
33 from pygments.lexers import Python3Lexer, BashLexer, PythonLexer
34 from pygments.token import Token
34 from pygments.token import Token
35
35
36 from .pt_inputhooks import get_inputhook_func
36 from .pt_inputhooks import get_inputhook_func
37 from .interactiveshell import get_default_editor, TerminalMagics
37 from .interactiveshell import get_default_editor, TerminalMagics
38
38
39
39
40 class IPythonPTCompleter(Completer):
40 class IPythonPTCompleter(Completer):
41 """Adaptor to provide IPython completions to prompt_toolkit"""
41 """Adaptor to provide IPython completions to prompt_toolkit"""
42 def __init__(self, ipy_completer):
42 def __init__(self, ipy_completer):
43 self.ipy_completer = ipy_completer
43 self.ipy_completer = ipy_completer
44
44
45 def get_completions(self, document, complete_event):
45 def get_completions(self, document, complete_event):
46 if not document.current_line.strip():
46 if not document.current_line.strip():
47 return
47 return
48
48
49 used, matches = self.ipy_completer.complete(
49 used, matches = self.ipy_completer.complete(
50 line_buffer=document.current_line,
50 line_buffer=document.current_line,
51 cursor_pos=document.cursor_position_col
51 cursor_pos=document.cursor_position_col
52 )
52 )
53 start_pos = -len(used)
53 start_pos = -len(used)
54 for m in matches:
54 for m in matches:
55 m = unicodedata.normalize('NFC', m)
55 m = unicodedata.normalize('NFC', m)
56
56
57 # When the first character of the completion has a zero length,
57 # When the first character of the completion has a zero length,
58 # then it's probably a decomposed unicode character. E.g. caused by
58 # then it's probably a decomposed unicode character. E.g. caused by
59 # the "\dot" completion. Try to compose again with the previous
59 # the "\dot" completion. Try to compose again with the previous
60 # character.
60 # character.
61 if wcwidth(m[0]) == 0:
61 if wcwidth(m[0]) == 0:
62 if document.cursor_position + start_pos > 0:
62 if document.cursor_position + start_pos > 0:
63 char_before = document.text[document.cursor_position + start_pos - 1]
63 char_before = document.text[document.cursor_position + start_pos - 1]
64 m = unicodedata.normalize('NFC', char_before + m)
64 m = unicodedata.normalize('NFC', char_before + m)
65
65
66 # Yield the modified completion instead, if this worked.
66 # Yield the modified completion instead, if this worked.
67 if wcwidth(m[0:1]) == 1:
67 if wcwidth(m[0:1]) == 1:
68 yield Completion(m, start_position=start_pos - 1)
68 yield Completion(m, start_position=start_pos - 1)
69 continue
69 continue
70
70
71 # TODO: Use Jedi to determine meta_text
72 # (Jedi currently has a bug that results in incorrect information.)
73 # meta_text = ''
74 # yield Completion(m, start_position=start_pos,
75 # display_meta=meta_text)
71 yield Completion(m, start_position=start_pos)
76 yield Completion(m, start_position=start_pos)
72
77
73
74 class IPythonPTLexer(Lexer):
78 class IPythonPTLexer(Lexer):
75 """
79 """
76 Wrapper around PythonLexer and BashLexer.
80 Wrapper around PythonLexer and BashLexer.
77 """
81 """
78 def __init__(self):
82 def __init__(self):
79 self.python_lexer = PygmentsLexer(Python3Lexer if PY3 else PythonLexer)
83 self.python_lexer = PygmentsLexer(Python3Lexer if PY3 else PythonLexer)
80 self.shell_lexer = PygmentsLexer(BashLexer)
84 self.shell_lexer = PygmentsLexer(BashLexer)
81
85
82 def lex_document(self, cli, document):
86 def lex_document(self, cli, document):
83 if document.text.startswith('!'):
87 if document.text.startswith('!'):
84 return self.shell_lexer.lex_document(cli, document)
88 return self.shell_lexer.lex_document(cli, document)
85 else:
89 else:
86 return self.python_lexer.lex_document(cli, document)
90 return self.python_lexer.lex_document(cli, document)
87
91
88
92
89 class TerminalInteractiveShell(InteractiveShell):
93 class TerminalInteractiveShell(InteractiveShell):
90 colors_force = True
94 colors_force = True
91
95
92 space_for_menu = Integer(6, config=True, help='Number of line at the bottom of the screen '
96 space_for_menu = Integer(6, config=True, help='Number of line at the bottom of the screen '
93 'to reserve for the completion menu')
97 'to reserve for the completion menu')
94
98
95 def _space_for_menu_changed(self, old, new):
99 def _space_for_menu_changed(self, old, new):
96 self._update_layout()
100 self._update_layout()
97
101
98 pt_cli = None
102 pt_cli = None
99
103
100 autoedit_syntax = CBool(False, config=True,
104 autoedit_syntax = CBool(False, config=True,
101 help="auto editing of files with syntax errors.")
105 help="auto editing of files with syntax errors.")
102
106
103 confirm_exit = CBool(True, config=True,
107 confirm_exit = CBool(True, config=True,
104 help="""
108 help="""
105 Set to confirm when you try to exit IPython with an EOF (Control-D
109 Set to confirm when you try to exit IPython with an EOF (Control-D
106 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
110 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
107 you can force a direct exit without any confirmation.""",
111 you can force a direct exit without any confirmation.""",
108 )
112 )
109 vi_mode = Bool(False, config=True,
113 vi_mode = Bool(False, config=True,
110 help="Use vi style keybindings at the prompt",
114 help="Use vi style keybindings at the prompt",
111 )
115 )
112
116
113 mouse_support = Bool(False, config=True,
117 mouse_support = Bool(False, config=True,
114 help="Enable mouse support in the prompt"
118 help="Enable mouse support in the prompt"
115 )
119 )
116
120
117 highlighting_style = Unicode('default', config=True,
121 highlighting_style = Unicode('default', config=True,
118 help="The name of a Pygments style to use for syntax highlighting: \n %s" % ', '.join(get_all_styles())
122 help="The name of a Pygments style to use for syntax highlighting: \n %s" % ', '.join(get_all_styles())
119 )
123 )
120
124
121 def _highlighting_style_changed(self, old, new):
125 def _highlighting_style_changed(self, old, new):
122 self._style = self._make_style_from_name(self.highlighting_style)
126 self._style = self._make_style_from_name(self.highlighting_style)
123
127
124 highlighting_style_overrides = Dict(config=True,
128 highlighting_style_overrides = Dict(config=True,
125 help="Override highlighting format for specific tokens"
129 help="Override highlighting format for specific tokens"
126 )
130 )
127
131
128 editor = Unicode(get_default_editor(), config=True,
132 editor = Unicode(get_default_editor(), config=True,
129 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
133 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
130 )
134 )
131
135
132 term_title = Bool(True, config=True,
136 term_title = Bool(True, config=True,
133 help="Automatically set the terminal title"
137 help="Automatically set the terminal title"
134 )
138 )
135 def _term_title_changed(self, name, new_value):
139 def _term_title_changed(self, name, new_value):
136 self.init_term_title()
140 self.init_term_title()
137
141
138 def init_term_title(self):
142 def init_term_title(self):
139 # Enable or disable the terminal title.
143 # Enable or disable the terminal title.
140 if self.term_title:
144 if self.term_title:
141 toggle_set_term_title(True)
145 toggle_set_term_title(True)
142 set_term_title('IPython: ' + abbrev_cwd())
146 set_term_title('IPython: ' + abbrev_cwd())
143 else:
147 else:
144 toggle_set_term_title(False)
148 toggle_set_term_title(False)
145
149
146 def get_prompt_tokens(self, cli):
150 def get_prompt_tokens(self, cli):
147 return [
151 return [
148 (Token.Prompt, 'In ['),
152 (Token.Prompt, 'In ['),
149 (Token.PromptNum, str(self.execution_count)),
153 (Token.PromptNum, str(self.execution_count)),
150 (Token.Prompt, ']: '),
154 (Token.Prompt, ']: '),
151 ]
155 ]
152
156
153 def get_continuation_tokens(self, cli, width):
157 def get_continuation_tokens(self, cli, width):
154 return [
158 return [
155 (Token.Prompt, (' ' * (width - 5)) + '...: '),
159 (Token.Prompt, (' ' * (width - 5)) + '...: '),
156 ]
160 ]
157
161
158 def init_prompt_toolkit_cli(self):
162 def init_prompt_toolkit_cli(self):
159 if ('IPY_TEST_SIMPLE_PROMPT' in os.environ) or not sys.stdin.isatty():
163 if ('IPY_TEST_SIMPLE_PROMPT' in os.environ) or not sys.stdin.isatty():
160 # Fall back to plain non-interactive output for tests.
164 # Fall back to plain non-interactive output for tests.
161 # This is very limited, and only accepts a single line.
165 # This is very limited, and only accepts a single line.
162 def prompt():
166 def prompt():
163 return cast_unicode_py2(input('In [%d]: ' % self.execution_count))
167 return cast_unicode_py2(input('In [%d]: ' % self.execution_count))
164 self.prompt_for_code = prompt
168 self.prompt_for_code = prompt
165 return
169 return
166
170
167 kbmanager = KeyBindingManager.for_prompt(enable_vi_mode=self.vi_mode)
171 kbmanager = KeyBindingManager.for_prompt(enable_vi_mode=self.vi_mode)
168 insert_mode = ViStateFilter(kbmanager.get_vi_state, InputMode.INSERT)
172 insert_mode = ViStateFilter(kbmanager.get_vi_state, InputMode.INSERT)
169 # Ctrl+J == Enter, seemingly
173 # Ctrl+J == Enter, seemingly
170 @kbmanager.registry.add_binding(Keys.ControlJ,
174 @kbmanager.registry.add_binding(Keys.ControlJ,
171 filter=(HasFocus(DEFAULT_BUFFER)
175 filter=(HasFocus(DEFAULT_BUFFER)
172 & ~HasSelection()
176 & ~HasSelection()
173 & insert_mode
177 & insert_mode
174 ))
178 ))
175 def _(event):
179 def _(event):
176 b = event.current_buffer
180 b = event.current_buffer
177 d = b.document
181 d = b.document
178 if not (d.on_last_line or d.cursor_position_row >= d.line_count
182 if not (d.on_last_line or d.cursor_position_row >= d.line_count
179 - d.empty_line_count_at_the_end()):
183 - d.empty_line_count_at_the_end()):
180 b.newline()
184 b.newline()
181 return
185 return
182
186
183 status, indent = self.input_splitter.check_complete(d.text)
187 status, indent = self.input_splitter.check_complete(d.text)
184
188
185 if (status != 'incomplete') and b.accept_action.is_returnable:
189 if (status != 'incomplete') and b.accept_action.is_returnable:
186 b.accept_action.validate_and_handle(event.cli, b)
190 b.accept_action.validate_and_handle(event.cli, b)
187 else:
191 else:
188 b.insert_text('\n' + (' ' * (indent or 0)))
192 b.insert_text('\n' + (' ' * (indent or 0)))
189
193
190 @kbmanager.registry.add_binding(Keys.ControlC, filter=HasFocus(DEFAULT_BUFFER))
194 @kbmanager.registry.add_binding(Keys.ControlC, filter=HasFocus(DEFAULT_BUFFER))
191 def _(event):
195 def _(event):
192 event.current_buffer.reset()
196 event.current_buffer.reset()
193
197
194 @kbmanager.registry.add_binding(Keys.ControlC, filter=HasFocus(SEARCH_BUFFER))
198 @kbmanager.registry.add_binding(Keys.ControlC, filter=HasFocus(SEARCH_BUFFER))
195 def _(event):
199 def _(event):
196 if event.current_buffer.document.text:
200 if event.current_buffer.document.text:
197 event.current_buffer.reset()
201 event.current_buffer.reset()
198 else:
202 else:
199 event.cli.push_focus(DEFAULT_BUFFER)
203 event.cli.push_focus(DEFAULT_BUFFER)
200
204
201 supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP'))
205 supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP'))
202
206
203 @kbmanager.registry.add_binding(Keys.ControlZ, filter=supports_suspend)
207 @kbmanager.registry.add_binding(Keys.ControlZ, filter=supports_suspend)
204 def _(event):
208 def _(event):
205 event.cli.suspend_to_background()
209 event.cli.suspend_to_background()
206
210
207 @Condition
211 @Condition
208 def cursor_in_leading_ws(cli):
212 def cursor_in_leading_ws(cli):
209 before = cli.application.buffer.document.current_line_before_cursor
213 before = cli.application.buffer.document.current_line_before_cursor
210 return (not before) or before.isspace()
214 return (not before) or before.isspace()
211
215
212 # Ctrl+I == Tab
216 # Ctrl+I == Tab
213 @kbmanager.registry.add_binding(Keys.ControlI,
217 @kbmanager.registry.add_binding(Keys.ControlI,
214 filter=(HasFocus(DEFAULT_BUFFER)
218 filter=(HasFocus(DEFAULT_BUFFER)
215 & ~HasSelection()
219 & ~HasSelection()
216 & insert_mode
220 & insert_mode
217 & cursor_in_leading_ws
221 & cursor_in_leading_ws
218 ))
222 ))
219 def _(event):
223 def _(event):
220 event.current_buffer.insert_text(' ' * 4)
224 event.current_buffer.insert_text(' ' * 4)
221
225
222 # Pre-populate history from IPython's history database
226 # Pre-populate history from IPython's history database
223 history = InMemoryHistory()
227 history = InMemoryHistory()
224 last_cell = u""
228 last_cell = u""
225 for _, _, cell in self.history_manager.get_tail(self.history_load_length,
229 for _, _, cell in self.history_manager.get_tail(self.history_load_length,
226 include_latest=True):
230 include_latest=True):
227 # Ignore blank lines and consecutive duplicates
231 # Ignore blank lines and consecutive duplicates
228 cell = cell.rstrip()
232 cell = cell.rstrip()
229 if cell and (cell != last_cell):
233 if cell and (cell != last_cell):
230 history.append(cell)
234 history.append(cell)
231
235
232 self._style = self._make_style_from_name(self.highlighting_style)
236 self._style = self._make_style_from_name(self.highlighting_style)
233 style = DynamicStyle(lambda: self._style)
237 style = DynamicStyle(lambda: self._style)
234
238
235 self._app = create_prompt_application(
239 self._app = create_prompt_application(
236 key_bindings_registry=kbmanager.registry,
240 key_bindings_registry=kbmanager.registry,
237 history=history,
241 history=history,
238 completer=IPythonPTCompleter(self.Completer),
242 completer=IPythonPTCompleter(self.Completer),
239 enable_history_search=True,
243 enable_history_search=True,
240 style=style,
244 style=style,
241 mouse_support=self.mouse_support,
245 mouse_support=self.mouse_support,
242 **self._layout_options()
246 **self._layout_options()
243 )
247 )
244 self.pt_cli = CommandLineInterface(self._app,
248 self.pt_cli = CommandLineInterface(self._app,
245 eventloop=create_eventloop(self.inputhook))
249 eventloop=create_eventloop(self.inputhook))
246
250
247 def _make_style_from_name(self, name):
251 def _make_style_from_name(self, name):
248 """
252 """
249 Small wrapper that make an IPython compatible style from a style name
253 Small wrapper that make an IPython compatible style from a style name
250
254
251 We need that to add style for prompt ... etc.
255 We need that to add style for prompt ... etc.
252 """
256 """
253 style_cls = get_style_by_name(name)
257 style_cls = get_style_by_name(name)
254 style_overrides = {
258 style_overrides = {
255 Token.Prompt: '#009900',
259 Token.Prompt: '#009900',
256 Token.PromptNum: '#00ff00 bold',
260 Token.PromptNum: '#00ff00 bold',
257 }
261 }
258 if name is 'default':
262 if name is 'default':
259 style_cls = get_style_by_name('default')
263 style_cls = get_style_by_name('default')
260 # The default theme needs to be visible on both a dark background
264 # The default theme needs to be visible on both a dark background
261 # and a light background, because we can't tell what the terminal
265 # and a light background, because we can't tell what the terminal
262 # looks like. These tweaks to the default theme help with that.
266 # looks like. These tweaks to the default theme help with that.
263 style_overrides.update({
267 style_overrides.update({
264 Token.Number: '#007700',
268 Token.Number: '#007700',
265 Token.Operator: 'noinherit',
269 Token.Operator: 'noinherit',
266 Token.String: '#BB6622',
270 Token.String: '#BB6622',
267 Token.Name.Function: '#2080D0',
271 Token.Name.Function: '#2080D0',
268 Token.Name.Class: 'bold #2080D0',
272 Token.Name.Class: 'bold #2080D0',
269 Token.Name.Namespace: 'bold #2080D0',
273 Token.Name.Namespace: 'bold #2080D0',
270 })
274 })
271 style_overrides.update(self.highlighting_style_overrides)
275 style_overrides.update(self.highlighting_style_overrides)
272 style = PygmentsStyle.from_defaults(pygments_style_cls=style_cls,
276 style = PygmentsStyle.from_defaults(pygments_style_cls=style_cls,
273 style_dict=style_overrides)
277 style_dict=style_overrides)
274
278
275 return style
279 return style
276
280
277 def _layout_options(self):
281 def _layout_options(self):
278 """
282 """
279 Return the current layout option for the current Terminal InteractiveShell
283 Return the current layout option for the current Terminal InteractiveShell
280 """
284 """
281 return {
285 return {
282 'lexer':IPythonPTLexer(),
286 'lexer':IPythonPTLexer(),
283 'reserve_space_for_menu':self.space_for_menu,
287 'reserve_space_for_menu':self.space_for_menu,
284 'get_prompt_tokens':self.get_prompt_tokens,
288 'get_prompt_tokens':self.get_prompt_tokens,
285 'get_continuation_tokens':self.get_continuation_tokens,
289 'get_continuation_tokens':self.get_continuation_tokens,
286 'multiline':True,
290 'multiline':True,
287 }
291 }
288
292
289
293
290 def _update_layout(self):
294 def _update_layout(self):
291 """
295 """
292 Ask for a re computation of the application layout, if for example ,
296 Ask for a re computation of the application layout, if for example ,
293 some configuration options have changed.
297 some configuration options have changed.
294 """
298 """
295 self._app.layout = create_prompt_layout(**self._layout_options())
299 self._app.layout = create_prompt_layout(**self._layout_options())
296
300
297 def prompt_for_code(self):
301 def prompt_for_code(self):
298 document = self.pt_cli.run(pre_run=self.pre_prompt)
302 document = self.pt_cli.run(pre_run=self.pre_prompt)
299 return document.text
303 return document.text
300
304
301 def init_io(self):
305 def init_io(self):
302 if sys.platform not in {'win32', 'cli'}:
306 if sys.platform not in {'win32', 'cli'}:
303 return
307 return
304
308
305 import colorama
309 import colorama
306 colorama.init()
310 colorama.init()
307
311
308 # For some reason we make these wrappers around stdout/stderr.
312 # For some reason we make these wrappers around stdout/stderr.
309 # For now, we need to reset them so all output gets coloured.
313 # For now, we need to reset them so all output gets coloured.
310 # https://github.com/ipython/ipython/issues/8669
314 # https://github.com/ipython/ipython/issues/8669
311 from IPython.utils import io
315 from IPython.utils import io
312 io.stdout = io.IOStream(sys.stdout)
316 io.stdout = io.IOStream(sys.stdout)
313 io.stderr = io.IOStream(sys.stderr)
317 io.stderr = io.IOStream(sys.stderr)
314
318
315 def init_magics(self):
319 def init_magics(self):
316 super(TerminalInteractiveShell, self).init_magics()
320 super(TerminalInteractiveShell, self).init_magics()
317 self.register_magics(TerminalMagics)
321 self.register_magics(TerminalMagics)
318
322
319 def init_alias(self):
323 def init_alias(self):
320 # The parent class defines aliases that can be safely used with any
324 # The parent class defines aliases that can be safely used with any
321 # frontend.
325 # frontend.
322 super(TerminalInteractiveShell, self).init_alias()
326 super(TerminalInteractiveShell, self).init_alias()
323
327
324 # Now define aliases that only make sense on the terminal, because they
328 # Now define aliases that only make sense on the terminal, because they
325 # need direct access to the console in a way that we can't emulate in
329 # need direct access to the console in a way that we can't emulate in
326 # GUI or web frontend
330 # GUI or web frontend
327 if os.name == 'posix':
331 if os.name == 'posix':
328 for cmd in ['clear', 'more', 'less', 'man']:
332 for cmd in ['clear', 'more', 'less', 'man']:
329 self.alias_manager.soft_define_alias(cmd, cmd)
333 self.alias_manager.soft_define_alias(cmd, cmd)
330
334
331
335
332 def __init__(self, *args, **kwargs):
336 def __init__(self, *args, **kwargs):
333 super(TerminalInteractiveShell, self).__init__(*args, **kwargs)
337 super(TerminalInteractiveShell, self).__init__(*args, **kwargs)
334 self.init_prompt_toolkit_cli()
338 self.init_prompt_toolkit_cli()
335 self.init_term_title()
339 self.init_term_title()
336 self.keep_running = True
340 self.keep_running = True
337
341
338 def ask_exit(self):
342 def ask_exit(self):
339 self.keep_running = False
343 self.keep_running = False
340
344
341 rl_next_input = None
345 rl_next_input = None
342
346
343 def pre_prompt(self):
347 def pre_prompt(self):
344 if self.rl_next_input:
348 if self.rl_next_input:
345 self.pt_cli.application.buffer.text = cast_unicode_py2(self.rl_next_input)
349 self.pt_cli.application.buffer.text = cast_unicode_py2(self.rl_next_input)
346 self.rl_next_input = None
350 self.rl_next_input = None
347
351
348 def interact(self):
352 def interact(self):
349 while self.keep_running:
353 while self.keep_running:
350 print(self.separate_in, end='')
354 print(self.separate_in, end='')
351
355
352 try:
356 try:
353 code = self.prompt_for_code()
357 code = self.prompt_for_code()
354 except EOFError:
358 except EOFError:
355 if (not self.confirm_exit) \
359 if (not self.confirm_exit) \
356 or self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'):
360 or self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'):
357 self.ask_exit()
361 self.ask_exit()
358
362
359 else:
363 else:
360 if code:
364 if code:
361 self.run_cell(code, store_history=True)
365 self.run_cell(code, store_history=True)
362 if self.autoedit_syntax and self.SyntaxTB.last_syntax_error:
366 if self.autoedit_syntax and self.SyntaxTB.last_syntax_error:
363 self.edit_syntax_error()
367 self.edit_syntax_error()
364
368
365 def mainloop(self):
369 def mainloop(self):
366 # An extra layer of protection in case someone mashing Ctrl-C breaks
370 # An extra layer of protection in case someone mashing Ctrl-C breaks
367 # out of our internal code.
371 # out of our internal code.
368 while True:
372 while True:
369 try:
373 try:
370 self.interact()
374 self.interact()
371 break
375 break
372 except KeyboardInterrupt:
376 except KeyboardInterrupt:
373 print("\nKeyboardInterrupt escaped interact()\n")
377 print("\nKeyboardInterrupt escaped interact()\n")
374
378
375 _inputhook = None
379 _inputhook = None
376 def inputhook(self, context):
380 def inputhook(self, context):
377 if self._inputhook is not None:
381 if self._inputhook is not None:
378 self._inputhook(context)
382 self._inputhook(context)
379
383
380 def enable_gui(self, gui=None):
384 def enable_gui(self, gui=None):
381 if gui:
385 if gui:
382 self._inputhook = get_inputhook_func(gui)
386 self._inputhook = get_inputhook_func(gui)
383 else:
387 else:
384 self._inputhook = None
388 self._inputhook = None
385
389
386 # Methods to support auto-editing of SyntaxErrors:
390 # Methods to support auto-editing of SyntaxErrors:
387
391
388 def edit_syntax_error(self):
392 def edit_syntax_error(self):
389 """The bottom half of the syntax error handler called in the main loop.
393 """The bottom half of the syntax error handler called in the main loop.
390
394
391 Loop until syntax error is fixed or user cancels.
395 Loop until syntax error is fixed or user cancels.
392 """
396 """
393
397
394 while self.SyntaxTB.last_syntax_error:
398 while self.SyntaxTB.last_syntax_error:
395 # copy and clear last_syntax_error
399 # copy and clear last_syntax_error
396 err = self.SyntaxTB.clear_err_state()
400 err = self.SyntaxTB.clear_err_state()
397 if not self._should_recompile(err):
401 if not self._should_recompile(err):
398 return
402 return
399 try:
403 try:
400 # may set last_syntax_error again if a SyntaxError is raised
404 # may set last_syntax_error again if a SyntaxError is raised
401 self.safe_execfile(err.filename, self.user_ns)
405 self.safe_execfile(err.filename, self.user_ns)
402 except:
406 except:
403 self.showtraceback()
407 self.showtraceback()
404 else:
408 else:
405 try:
409 try:
406 with open(err.filename) as f:
410 with open(err.filename) as f:
407 # This should be inside a display_trap block and I
411 # This should be inside a display_trap block and I
408 # think it is.
412 # think it is.
409 sys.displayhook(f.read())
413 sys.displayhook(f.read())
410 except:
414 except:
411 self.showtraceback()
415 self.showtraceback()
412
416
413 def _should_recompile(self, e):
417 def _should_recompile(self, e):
414 """Utility routine for edit_syntax_error"""
418 """Utility routine for edit_syntax_error"""
415
419
416 if e.filename in ('<ipython console>', '<input>', '<string>',
420 if e.filename in ('<ipython console>', '<input>', '<string>',
417 '<console>', '<BackgroundJob compilation>',
421 '<console>', '<BackgroundJob compilation>',
418 None):
422 None):
419 return False
423 return False
420 try:
424 try:
421 if (self.autoedit_syntax and
425 if (self.autoedit_syntax and
422 not self.ask_yes_no(
426 not self.ask_yes_no(
423 'Return to editor to correct syntax error? '
427 'Return to editor to correct syntax error? '
424 '[Y/n] ', 'y')):
428 '[Y/n] ', 'y')):
425 return False
429 return False
426 except EOFError:
430 except EOFError:
427 return False
431 return False
428
432
429 def int0(x):
433 def int0(x):
430 try:
434 try:
431 return int(x)
435 return int(x)
432 except TypeError:
436 except TypeError:
433 return 0
437 return 0
434
438
435 # always pass integer line and offset values to editor hook
439 # always pass integer line and offset values to editor hook
436 try:
440 try:
437 self.hooks.fix_error_editor(e.filename,
441 self.hooks.fix_error_editor(e.filename,
438 int0(e.lineno), int0(e.offset),
442 int0(e.lineno), int0(e.offset),
439 e.msg)
443 e.msg)
440 except TryNext:
444 except TryNext:
441 warn('Could not open editor')
445 warn('Could not open editor')
442 return False
446 return False
443 return True
447 return True
444
448
445 # Run !system commands directly, not through pipes, so terminal programs
449 # Run !system commands directly, not through pipes, so terminal programs
446 # work correctly.
450 # work correctly.
447 system = InteractiveShell.system_raw
451 system = InteractiveShell.system_raw
448
452
449
453
450 if __name__ == '__main__':
454 if __name__ == '__main__':
451 TerminalInteractiveShell.instance().interact()
455 TerminalInteractiveShell.instance().interact()
@@ -1,299 +1,300 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
2 # -*- coding: utf-8 -*-
3 """Setup script for IPython.
3 """Setup script for IPython.
4
4
5 Under Posix environments it works like a typical setup.py script.
5 Under Posix environments it works like a typical setup.py script.
6 Under Windows, the command sdist is not supported, since IPython
6 Under Windows, the command sdist is not supported, since IPython
7 requires utilities which are not available under Windows."""
7 requires utilities which are not available under Windows."""
8
8
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10 # Copyright (c) 2008-2011, IPython Development Team.
10 # Copyright (c) 2008-2011, IPython Development Team.
11 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
11 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
12 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
12 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
13 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
13 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
14 #
14 #
15 # Distributed under the terms of the Modified BSD License.
15 # Distributed under the terms of the Modified BSD License.
16 #
16 #
17 # The full license is in the file COPYING.rst, distributed with this software.
17 # The full license is in the file COPYING.rst, distributed with this software.
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19
19
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21 # Minimal Python version sanity check
21 # Minimal Python version sanity check
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 from __future__ import print_function
23 from __future__ import print_function
24
24
25 import sys
25 import sys
26
26
27 # This check is also made in IPython/__init__, don't forget to update both when
27 # This check is also made in IPython/__init__, don't forget to update both when
28 # changing Python version requirements.
28 # changing Python version requirements.
29 v = sys.version_info
29 v = sys.version_info
30 if v[:2] < (2,7) or (v[0] >= 3 and v[:2] < (3,3)):
30 if v[:2] < (2,7) or (v[0] >= 3 and v[:2] < (3,3)):
31 error = "ERROR: IPython requires Python version 2.7 or 3.3 or above."
31 error = "ERROR: IPython requires Python version 2.7 or 3.3 or above."
32 print(error, file=sys.stderr)
32 print(error, file=sys.stderr)
33 sys.exit(1)
33 sys.exit(1)
34
34
35 PY3 = (sys.version_info[0] >= 3)
35 PY3 = (sys.version_info[0] >= 3)
36
36
37 # At least we're on the python version we need, move on.
37 # At least we're on the python version we need, move on.
38
38
39 #-------------------------------------------------------------------------------
39 #-------------------------------------------------------------------------------
40 # Imports
40 # Imports
41 #-------------------------------------------------------------------------------
41 #-------------------------------------------------------------------------------
42
42
43 # Stdlib imports
43 # Stdlib imports
44 import os
44 import os
45
45
46 from glob import glob
46 from glob import glob
47
47
48 # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
48 # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
49 # update it when the contents of directories change.
49 # update it when the contents of directories change.
50 if os.path.exists('MANIFEST'): os.remove('MANIFEST')
50 if os.path.exists('MANIFEST'): os.remove('MANIFEST')
51
51
52 from distutils.core import setup
52 from distutils.core import setup
53
53
54 # Our own imports
54 # Our own imports
55 from setupbase import target_update
55 from setupbase import target_update
56
56
57 from setupbase import (
57 from setupbase import (
58 setup_args,
58 setup_args,
59 find_packages,
59 find_packages,
60 find_package_data,
60 find_package_data,
61 check_package_data_first,
61 check_package_data_first,
62 find_entry_points,
62 find_entry_points,
63 build_scripts_entrypt,
63 build_scripts_entrypt,
64 find_data_files,
64 find_data_files,
65 git_prebuild,
65 git_prebuild,
66 install_symlinked,
66 install_symlinked,
67 install_lib_symlink,
67 install_lib_symlink,
68 install_scripts_for_symlink,
68 install_scripts_for_symlink,
69 unsymlink,
69 unsymlink,
70 )
70 )
71
71
72 isfile = os.path.isfile
72 isfile = os.path.isfile
73 pjoin = os.path.join
73 pjoin = os.path.join
74
74
75 #-------------------------------------------------------------------------------
75 #-------------------------------------------------------------------------------
76 # Handle OS specific things
76 # Handle OS specific things
77 #-------------------------------------------------------------------------------
77 #-------------------------------------------------------------------------------
78
78
79 if os.name in ('nt','dos'):
79 if os.name in ('nt','dos'):
80 os_name = 'windows'
80 os_name = 'windows'
81 else:
81 else:
82 os_name = os.name
82 os_name = os.name
83
83
84 # Under Windows, 'sdist' has not been supported. Now that the docs build with
84 # Under Windows, 'sdist' has not been supported. Now that the docs build with
85 # Sphinx it might work, but let's not turn it on until someone confirms that it
85 # Sphinx it might work, but let's not turn it on until someone confirms that it
86 # actually works.
86 # actually works.
87 if os_name == 'windows' and 'sdist' in sys.argv:
87 if os_name == 'windows' and 'sdist' in sys.argv:
88 print('The sdist command is not available under Windows. Exiting.')
88 print('The sdist command is not available under Windows. Exiting.')
89 sys.exit(1)
89 sys.exit(1)
90
90
91
91
92 #-------------------------------------------------------------------------------
92 #-------------------------------------------------------------------------------
93 # Things related to the IPython documentation
93 # Things related to the IPython documentation
94 #-------------------------------------------------------------------------------
94 #-------------------------------------------------------------------------------
95
95
96 # update the manuals when building a source dist
96 # update the manuals when building a source dist
97 if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
97 if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
98
98
99 # List of things to be updated. Each entry is a triplet of args for
99 # List of things to be updated. Each entry is a triplet of args for
100 # target_update()
100 # target_update()
101 to_update = [
101 to_update = [
102 ('docs/man/ipython.1.gz',
102 ('docs/man/ipython.1.gz',
103 ['docs/man/ipython.1'],
103 ['docs/man/ipython.1'],
104 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz'),
104 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz'),
105 ]
105 ]
106
106
107
107
108 [ target_update(*t) for t in to_update ]
108 [ target_update(*t) for t in to_update ]
109
109
110 #---------------------------------------------------------------------------
110 #---------------------------------------------------------------------------
111 # Find all the packages, package data, and data_files
111 # Find all the packages, package data, and data_files
112 #---------------------------------------------------------------------------
112 #---------------------------------------------------------------------------
113
113
114 packages = find_packages()
114 packages = find_packages()
115 package_data = find_package_data()
115 package_data = find_package_data()
116
116
117 data_files = find_data_files()
117 data_files = find_data_files()
118
118
119 setup_args['packages'] = packages
119 setup_args['packages'] = packages
120 setup_args['package_data'] = package_data
120 setup_args['package_data'] = package_data
121 setup_args['data_files'] = data_files
121 setup_args['data_files'] = data_files
122
122
123 #---------------------------------------------------------------------------
123 #---------------------------------------------------------------------------
124 # custom distutils commands
124 # custom distutils commands
125 #---------------------------------------------------------------------------
125 #---------------------------------------------------------------------------
126 # imports here, so they are after setuptools import if there was one
126 # imports here, so they are after setuptools import if there was one
127 from distutils.command.sdist import sdist
127 from distutils.command.sdist import sdist
128 from distutils.command.upload import upload
128 from distutils.command.upload import upload
129
129
130 class UploadWindowsInstallers(upload):
130 class UploadWindowsInstallers(upload):
131
131
132 description = "Upload Windows installers to PyPI (only used from tools/release_windows.py)"
132 description = "Upload Windows installers to PyPI (only used from tools/release_windows.py)"
133 user_options = upload.user_options + [
133 user_options = upload.user_options + [
134 ('files=', 'f', 'exe file (or glob) to upload')
134 ('files=', 'f', 'exe file (or glob) to upload')
135 ]
135 ]
136 def initialize_options(self):
136 def initialize_options(self):
137 upload.initialize_options(self)
137 upload.initialize_options(self)
138 meta = self.distribution.metadata
138 meta = self.distribution.metadata
139 base = '{name}-{version}'.format(
139 base = '{name}-{version}'.format(
140 name=meta.get_name(),
140 name=meta.get_name(),
141 version=meta.get_version()
141 version=meta.get_version()
142 )
142 )
143 self.files = os.path.join('dist', '%s.*.exe' % base)
143 self.files = os.path.join('dist', '%s.*.exe' % base)
144
144
145 def run(self):
145 def run(self):
146 for dist_file in glob(self.files):
146 for dist_file in glob(self.files):
147 self.upload_file('bdist_wininst', 'any', dist_file)
147 self.upload_file('bdist_wininst', 'any', dist_file)
148
148
149 setup_args['cmdclass'] = {
149 setup_args['cmdclass'] = {
150 'build_py': \
150 'build_py': \
151 check_package_data_first(git_prebuild('IPython')),
151 check_package_data_first(git_prebuild('IPython')),
152 'sdist' : git_prebuild('IPython', sdist),
152 'sdist' : git_prebuild('IPython', sdist),
153 'upload_wininst' : UploadWindowsInstallers,
153 'upload_wininst' : UploadWindowsInstallers,
154 'symlink': install_symlinked,
154 'symlink': install_symlinked,
155 'install_lib_symlink': install_lib_symlink,
155 'install_lib_symlink': install_lib_symlink,
156 'install_scripts_sym': install_scripts_for_symlink,
156 'install_scripts_sym': install_scripts_for_symlink,
157 'unsymlink': unsymlink,
157 'unsymlink': unsymlink,
158 }
158 }
159
159
160
160
161 #---------------------------------------------------------------------------
161 #---------------------------------------------------------------------------
162 # Handle scripts, dependencies, and setuptools specific things
162 # Handle scripts, dependencies, and setuptools specific things
163 #---------------------------------------------------------------------------
163 #---------------------------------------------------------------------------
164
164
165 # For some commands, use setuptools. Note that we do NOT list install here!
165 # For some commands, use setuptools. Note that we do NOT list install here!
166 # If you want a setuptools-enhanced install, just run 'setupegg.py install'
166 # If you want a setuptools-enhanced install, just run 'setupegg.py install'
167 needs_setuptools = set(('develop', 'release', 'bdist_egg', 'bdist_rpm',
167 needs_setuptools = set(('develop', 'release', 'bdist_egg', 'bdist_rpm',
168 'bdist', 'bdist_dumb', 'bdist_wininst', 'bdist_wheel',
168 'bdist', 'bdist_dumb', 'bdist_wininst', 'bdist_wheel',
169 'egg_info', 'easy_install', 'upload', 'install_egg_info',
169 'egg_info', 'easy_install', 'upload', 'install_egg_info',
170 ))
170 ))
171
171
172 if len(needs_setuptools.intersection(sys.argv)) > 0:
172 if len(needs_setuptools.intersection(sys.argv)) > 0:
173 import setuptools
173 import setuptools
174
174
175 # This dict is used for passing extra arguments that are setuptools
175 # This dict is used for passing extra arguments that are setuptools
176 # specific to setup
176 # specific to setup
177 setuptools_extra_args = {}
177 setuptools_extra_args = {}
178
178
179 # setuptools requirements
179 # setuptools requirements
180
180
181 extras_require = dict(
181 extras_require = dict(
182 parallel = ['ipyparallel'],
182 parallel = ['ipyparallel'],
183 qtconsole = ['qtconsole'],
183 qtconsole = ['qtconsole'],
184 doc = ['Sphinx>=1.3'],
184 doc = ['Sphinx>=1.3'],
185 test = ['nose>=0.10.1', 'requests', 'testpath', 'pygments'],
185 test = ['nose>=0.10.1', 'requests', 'testpath', 'pygments', 'path.py'],
186 terminal = [],
186 terminal = [],
187 kernel = ['ipykernel'],
187 kernel = ['ipykernel'],
188 nbformat = ['nbformat'],
188 nbformat = ['nbformat'],
189 notebook = ['notebook', 'ipywidgets'],
189 notebook = ['notebook', 'ipywidgets'],
190 nbconvert = ['nbconvert'],
190 nbconvert = ['nbconvert'],
191 )
191 )
192 install_requires = [
192 install_requires = [
193 'setuptools>=18.5',
193 'setuptools>=18.5',
194 'jedi',
194 'decorator',
195 'decorator',
195 'pickleshare',
196 'pickleshare',
196 'simplegeneric>0.8',
197 'simplegeneric>0.8',
197 'traitlets',
198 'traitlets',
198 'prompt_toolkit>=0.60',
199 'prompt_toolkit>=0.60',
199 'pygments',
200 'pygments',
200 ]
201 ]
201
202
202 # Platform-specific dependencies:
203 # Platform-specific dependencies:
203 # This is the correct way to specify these,
204 # This is the correct way to specify these,
204 # but requires pip >= 6. pip < 6 ignores these.
205 # but requires pip >= 6. pip < 6 ignores these.
205
206
206 extras_require.update({
207 extras_require.update({
207 ':python_version == "2.7"': ['backports.shutil_get_terminal_size'],
208 ':python_version == "2.7"': ['backports.shutil_get_terminal_size'],
208 ':python_version == "2.7" or python_version == "3.3"': ['pathlib2'],
209 ':python_version == "2.7" or python_version == "3.3"': ['pathlib2'],
209 ':sys_platform != "win32"': ['pexpect'],
210 ':sys_platform != "win32"': ['pexpect'],
210 ':sys_platform == "darwin"': ['appnope'],
211 ':sys_platform == "darwin"': ['appnope'],
211 ':sys_platform == "win32"': ['colorama'],
212 ':sys_platform == "win32"': ['colorama'],
212 'test:python_version == "2.7"': ['mock'],
213 'test:python_version == "2.7"': ['mock'],
213 })
214 })
214 # FIXME: re-specify above platform dependencies for pip < 6
215 # FIXME: re-specify above platform dependencies for pip < 6
215 # These would result in non-portable bdists.
216 # These would result in non-portable bdists.
216 if not any(arg.startswith('bdist') for arg in sys.argv):
217 if not any(arg.startswith('bdist') for arg in sys.argv):
217 if sys.version_info < (3, 3):
218 if sys.version_info < (3, 3):
218 extras_require['test'].append('mock')
219 extras_require['test'].append('mock')
219
220
220 if sys.platform == 'darwin':
221 if sys.platform == 'darwin':
221 install_requires.extend(['appnope'])
222 install_requires.extend(['appnope'])
222 have_readline = False
223 have_readline = False
223 try:
224 try:
224 import readline
225 import readline
225 except ImportError:
226 except ImportError:
226 pass
227 pass
227 else:
228 else:
228 if 'libedit' not in readline.__doc__:
229 if 'libedit' not in readline.__doc__:
229 have_readline = True
230 have_readline = True
230 if not have_readline:
231 if not have_readline:
231 install_requires.extend(['gnureadline'])
232 install_requires.extend(['gnureadline'])
232
233
233 if sys.platform.startswith('win'):
234 if sys.platform.startswith('win'):
234 extras_require['terminal'].append('pyreadline>=2.0')
235 extras_require['terminal'].append('pyreadline>=2.0')
235 else:
236 else:
236 install_requires.append('pexpect')
237 install_requires.append('pexpect')
237
238
238 # workaround pypa/setuptools#147, where setuptools misspells
239 # workaround pypa/setuptools#147, where setuptools misspells
239 # platform_python_implementation as python_implementation
240 # platform_python_implementation as python_implementation
240 if 'setuptools' in sys.modules:
241 if 'setuptools' in sys.modules:
241 for key in list(extras_require):
242 for key in list(extras_require):
242 if 'platform_python_implementation' in key:
243 if 'platform_python_implementation' in key:
243 new_key = key.replace('platform_python_implementation', 'python_implementation')
244 new_key = key.replace('platform_python_implementation', 'python_implementation')
244 extras_require[new_key] = extras_require.pop(key)
245 extras_require[new_key] = extras_require.pop(key)
245
246
246 everything = set()
247 everything = set()
247 for key, deps in extras_require.items():
248 for key, deps in extras_require.items():
248 if ':' not in key:
249 if ':' not in key:
249 everything.update(deps)
250 everything.update(deps)
250 extras_require['all'] = everything
251 extras_require['all'] = everything
251
252
252 if 'setuptools' in sys.modules:
253 if 'setuptools' in sys.modules:
253 setuptools_extra_args['zip_safe'] = False
254 setuptools_extra_args['zip_safe'] = False
254 setuptools_extra_args['entry_points'] = {
255 setuptools_extra_args['entry_points'] = {
255 'console_scripts': find_entry_points(),
256 'console_scripts': find_entry_points(),
256 'pygments.lexers': [
257 'pygments.lexers': [
257 'ipythonconsole = IPython.lib.lexers:IPythonConsoleLexer',
258 'ipythonconsole = IPython.lib.lexers:IPythonConsoleLexer',
258 'ipython = IPython.lib.lexers:IPythonLexer',
259 'ipython = IPython.lib.lexers:IPythonLexer',
259 'ipython3 = IPython.lib.lexers:IPython3Lexer',
260 'ipython3 = IPython.lib.lexers:IPython3Lexer',
260 ],
261 ],
261 }
262 }
262 setup_args['extras_require'] = extras_require
263 setup_args['extras_require'] = extras_require
263 requires = setup_args['install_requires'] = install_requires
264 requires = setup_args['install_requires'] = install_requires
264
265
265 # Script to be run by the windows binary installer after the default setup
266 # Script to be run by the windows binary installer after the default setup
266 # routine, to add shortcuts and similar windows-only things. Windows
267 # routine, to add shortcuts and similar windows-only things. Windows
267 # post-install scripts MUST reside in the scripts/ dir, otherwise distutils
268 # post-install scripts MUST reside in the scripts/ dir, otherwise distutils
268 # doesn't find them.
269 # doesn't find them.
269 if 'bdist_wininst' in sys.argv:
270 if 'bdist_wininst' in sys.argv:
270 if len(sys.argv) > 2 and \
271 if len(sys.argv) > 2 and \
271 ('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
272 ('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
272 print("ERROR: bdist_wininst must be run alone. Exiting.", file=sys.stderr)
273 print("ERROR: bdist_wininst must be run alone. Exiting.", file=sys.stderr)
273 sys.exit(1)
274 sys.exit(1)
274 setup_args['data_files'].append(
275 setup_args['data_files'].append(
275 ['Scripts', ('scripts/ipython.ico', 'scripts/ipython_nb.ico')])
276 ['Scripts', ('scripts/ipython.ico', 'scripts/ipython_nb.ico')])
276 setup_args['scripts'] = [pjoin('scripts','ipython_win_post_install.py')]
277 setup_args['scripts'] = [pjoin('scripts','ipython_win_post_install.py')]
277 setup_args['options'] = {"bdist_wininst":
278 setup_args['options'] = {"bdist_wininst":
278 {"install_script":
279 {"install_script":
279 "ipython_win_post_install.py"}}
280 "ipython_win_post_install.py"}}
280
281
281 else:
282 else:
282 # scripts has to be a non-empty list, or install_scripts isn't called
283 # scripts has to be a non-empty list, or install_scripts isn't called
283 setup_args['scripts'] = [e.split('=')[0].strip() for e in find_entry_points()]
284 setup_args['scripts'] = [e.split('=')[0].strip() for e in find_entry_points()]
284
285
285 setup_args['cmdclass']['build_scripts'] = build_scripts_entrypt
286 setup_args['cmdclass']['build_scripts'] = build_scripts_entrypt
286
287
287 #---------------------------------------------------------------------------
288 #---------------------------------------------------------------------------
288 # Do the actual setup now
289 # Do the actual setup now
289 #---------------------------------------------------------------------------
290 #---------------------------------------------------------------------------
290
291
291 setup_args.update(setuptools_extra_args)
292 setup_args.update(setuptools_extra_args)
292
293
293
294
294
295
295 def main():
296 def main():
296 setup(**setup_args)
297 setup(**setup_args)
297
298
298 if __name__ == '__main__':
299 if __name__ == '__main__':
299 main()
300 main()
General Comments 0
You need to be logged in to leave comments. Login now