##// END OF EJS Templates
Merge PR #668 (greedy completion)...
MinRK -
r4827:1021cbe9 merge
parent child Browse files
Show More
@@ -78,12 +78,14 b' import re'
78 import shlex
78 import shlex
79 import sys
79 import sys
80
80
81 from IPython.config.configurable import Configurable
81 from IPython.core.error import TryNext
82 from IPython.core.error import TryNext
82 from IPython.core.prefilter import ESC_MAGIC
83 from IPython.core.prefilter import ESC_MAGIC
83 from IPython.utils import generics
84 from IPython.utils import generics
84 from IPython.utils import io
85 from IPython.utils import io
85 from IPython.utils.dir2 import dir2
86 from IPython.utils.dir2 import dir2
86 from IPython.utils.process import arg_split
87 from IPython.utils.process import arg_split
88 from IPython.utils.traitlets import CBool
87
89
88 #-----------------------------------------------------------------------------
90 #-----------------------------------------------------------------------------
89 # Globals
91 # Globals
@@ -210,6 +212,8 b' def single_dir_expand(matches):'
210
212
211 class Bunch(object): pass
213 class Bunch(object): pass
212
214
215 DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
216 GREEDY_DELIMS = ' \r\n'
213
217
214 class CompletionSplitter(object):
218 class CompletionSplitter(object):
215 """An object to split an input line in a manner similar to readline.
219 """An object to split an input line in a manner similar to readline.
@@ -228,7 +232,7 b' class CompletionSplitter(object):'
228
232
229 # A string of delimiter characters. The default value makes sense for
233 # A string of delimiter characters. The default value makes sense for
230 # IPython's most typical usage patterns.
234 # IPython's most typical usage patterns.
231 _delims = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
235 _delims = DELIMS
232
236
233 # The expression (a normal string) to be compiled into a regular expression
237 # The expression (a normal string) to be compiled into a regular expression
234 # for actual splitting. We store it as an attribute mostly for ease of
238 # for actual splitting. We store it as an attribute mostly for ease of
@@ -260,11 +264,20 b' class CompletionSplitter(object):'
260 return self._delim_re.split(l)[-1]
264 return self._delim_re.split(l)[-1]
261
265
262
266
263 class Completer(object):
267 class Completer(Configurable):
264 def __init__(self, namespace=None, global_namespace=None):
268
269 greedy = CBool(False, config=True,
270 help="""Activate greedy completion
271
272 This will enable completion on elements of lists, results of function calls, etc.,
273 but can be unsafe because the code is actually evaluated on TAB.
274 """
275 )
276
277 def __init__(self, namespace=None, global_namespace=None, config=None):
265 """Create a new completer for the command line.
278 """Create a new completer for the command line.
266
279
267 Completer([namespace,global_namespace]) -> completer instance.
280 Completer(namespace=ns,global_namespace=ns2) -> completer instance.
268
281
269 If unspecified, the default namespace where completions are performed
282 If unspecified, the default namespace where completions are performed
270 is __main__ (technically, __main__.__dict__). Namespaces should be
283 is __main__ (technically, __main__.__dict__). Namespaces should be
@@ -294,6 +307,8 b' class Completer(object):'
294 self.global_namespace = {}
307 self.global_namespace = {}
295 else:
308 else:
296 self.global_namespace = global_namespace
309 self.global_namespace = global_namespace
310
311 super(Completer, self).__init__(config=config)
297
312
298 def complete(self, text, state):
313 def complete(self, text, state):
299 """Return the next possible completion for 'text'.
314 """Return the next possible completion for 'text'.
@@ -349,14 +364,20 b' class Completer(object):'
349
364
350 """
365 """
351
366
352 #print 'Completer->attr_matches, txt=%r' % text # dbg
367 #io.rprint('Completer->attr_matches, txt=%r' % text) # dbg
353 # Another option, seems to work great. Catches things like ''.<tab>
368 # Another option, seems to work great. Catches things like ''.<tab>
354 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
369 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
355
370
356 if not m:
371 if m:
372 expr, attr = m.group(1, 3)
373 elif self.greedy:
374 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
375 if not m2:
376 return []
377 expr, attr = m2.group(1,2)
378 else:
357 return []
379 return []
358
380
359 expr, attr = m.group(1, 3)
360 try:
381 try:
361 obj = eval(expr, self.namespace)
382 obj = eval(expr, self.namespace)
362 except:
383 except:
@@ -380,8 +401,19 b' class Completer(object):'
380 class IPCompleter(Completer):
401 class IPCompleter(Completer):
381 """Extension of the completer class with IPython-specific features"""
402 """Extension of the completer class with IPython-specific features"""
382
403
383 def __init__(self, shell, namespace=None, global_namespace=None,
404 def _greedy_changed(self, name, old, new):
384 omit__names=True, alias_table=None, use_readline=True):
405 """update the splitter and readline delims when greedy is changed"""
406 if new:
407 self.splitter.set_delims(GREEDY_DELIMS)
408 else:
409 self.splitter.set_delims(DELIMS)
410
411 if self.readline:
412 self.readline.set_completer_delims(self.splitter.get_delims())
413
414 def __init__(self, shell=None, namespace=None, global_namespace=None,
415 omit__names=True, alias_table=None, use_readline=True,
416 config=None):
385 """IPCompleter() -> completer
417 """IPCompleter() -> completer
386
418
387 Return a completer object suitable for use by the readline library
419 Return a completer object suitable for use by the readline library
@@ -411,8 +443,6 b' class IPCompleter(Completer):'
411 without readline, though in that case callers must provide some extra
443 without readline, though in that case callers must provide some extra
412 information on each call about the current line."""
444 information on each call about the current line."""
413
445
414 Completer.__init__(self, namespace, global_namespace)
415
416 self.magic_escape = ESC_MAGIC
446 self.magic_escape = ESC_MAGIC
417 self.splitter = CompletionSplitter()
447 self.splitter = CompletionSplitter()
418
448
@@ -424,6 +454,10 b' class IPCompleter(Completer):'
424 else:
454 else:
425 self.readline = None
455 self.readline = None
426
456
457 # _greedy_changed() depends on splitter and readline being defined:
458 Completer.__init__(self, namespace=namespace, global_namespace=global_namespace,
459 config=config)
460
427 # List where completion matches will be stored
461 # List where completion matches will be stored
428 self.matches = []
462 self.matches = []
429 self.omit__names = omit__names
463 self.omit__names = omit__names
@@ -579,7 +613,7 b' class IPCompleter(Completer):'
579 def python_matches(self,text):
613 def python_matches(self,text):
580 """Match attributes or global python names"""
614 """Match attributes or global python names"""
581
615
582 #print 'Completer->python_matches, txt=%r' % text # dbg
616 #io.rprint('Completer->python_matches, txt=%r' % text) # dbg
583 if "." in text:
617 if "." in text:
584 try:
618 try:
585 matches = self.attr_matches(text)
619 matches = self.attr_matches(text)
@@ -680,7 +714,7 b' class IPCompleter(Completer):'
680 return argMatches
714 return argMatches
681
715
682 def dispatch_custom_completer(self, text):
716 def dispatch_custom_completer(self, text):
683 #print "Custom! '%s' %s" % (text, self.custom_completers) # dbg
717 #io.rprint("Custom! '%s' %s" % (text, self.custom_completers)) # dbg
684 line = self.line_buffer
718 line = self.line_buffer
685 if not line.strip():
719 if not line.strip():
686 return None
720 return None
@@ -1771,12 +1771,14 b' class InteractiveShell(SingletonConfigurable, Magic):'
1771 from IPython.core.completerlib import (module_completer,
1771 from IPython.core.completerlib import (module_completer,
1772 magic_run_completer, cd_completer)
1772 magic_run_completer, cd_completer)
1773
1773
1774 self.Completer = IPCompleter(self,
1774 self.Completer = IPCompleter(shell=self,
1775 self.user_ns,
1775 namespace=self.user_ns,
1776 self.user_global_ns,
1776 global_namespace=self.user_global_ns,
1777 self.readline_omit__names,
1777 omit__names=self.readline_omit__names,
1778 self.alias_manager.alias_table,
1778 alias_table=self.alias_manager.alias_table,
1779 self.has_readline)
1779 use_readline=self.has_readline,
1780 config=self.config,
1781 )
1780
1782
1781 # Add custom completers to the basic ones built into IPCompleter
1783 # Add custom completers to the basic ones built into IPCompleter
1782 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1784 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
@@ -181,3 +181,14 b' def test_local_file_completions():'
181 finally:
181 finally:
182 # prevent failures from making chdir stick
182 # prevent failures from making chdir stick
183 os.chdir(cwd)
183 os.chdir(cwd)
184
185 def test_greedy_completions():
186 ip = get_ipython()
187 ip.Completer.greedy = False
188 ip.ex('a=range(5)')
189 _,c = ip.complete('.',line='a[0].')
190 nt.assert_false('a[0].real' in c, "Shouldn't have completed on a[0]: %s"%c)
191 ip.Completer.greedy = True
192 _,c = ip.complete('.',line='a[0].')
193 nt.assert_true('a[0].real' in c, "Should have completed on a[0]: %s"%c)
194
@@ -35,6 +35,7 b' from IPython.config.loader import ('
35 from IPython.config.application import boolean_flag
35 from IPython.config.application import boolean_flag
36 from IPython.core import release
36 from IPython.core import release
37 from IPython.core import usage
37 from IPython.core import usage
38 from IPython.core.completer import Completer
38 from IPython.core.crashhandler import CrashHandler
39 from IPython.core.crashhandler import CrashHandler
39 from IPython.core.formatters import PlainTextFormatter
40 from IPython.core.formatters import PlainTextFormatter
40 from IPython.core.application import (
41 from IPython.core.application import (
@@ -198,6 +199,7 b' class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):'
198 TerminalInteractiveShell,
199 TerminalInteractiveShell,
199 ProfileDir,
200 ProfileDir,
200 PlainTextFormatter,
201 PlainTextFormatter,
202 Completer,
201 ]
203 ]
202
204
203 subcommands = Dict(dict(
205 subcommands = Dict(dict(
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now