##// 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 78 import shlex
79 79 import sys
80 80
81 from IPython.config.configurable import Configurable
81 82 from IPython.core.error import TryNext
82 83 from IPython.core.prefilter import ESC_MAGIC
83 84 from IPython.utils import generics
84 85 from IPython.utils import io
85 86 from IPython.utils.dir2 import dir2
86 87 from IPython.utils.process import arg_split
88 from IPython.utils.traitlets import CBool
87 89
88 90 #-----------------------------------------------------------------------------
89 91 # Globals
@@ -210,6 +212,8 b' def single_dir_expand(matches):'
210 212
211 213 class Bunch(object): pass
212 214
215 DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
216 GREEDY_DELIMS = ' \r\n'
213 217
214 218 class CompletionSplitter(object):
215 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 233 # A string of delimiter characters. The default value makes sense for
230 234 # IPython's most typical usage patterns.
231 _delims = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
235 _delims = DELIMS
232 236
233 237 # The expression (a normal string) to be compiled into a regular expression
234 238 # for actual splitting. We store it as an attribute mostly for ease of
@@ -260,11 +264,20 b' class CompletionSplitter(object):'
260 264 return self._delim_re.split(l)[-1]
261 265
262 266
263 class Completer(object):
264 def __init__(self, namespace=None, global_namespace=None):
267 class Completer(Configurable):
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 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 282 If unspecified, the default namespace where completions are performed
270 283 is __main__ (technically, __main__.__dict__). Namespaces should be
@@ -294,6 +307,8 b' class Completer(object):'
294 307 self.global_namespace = {}
295 308 else:
296 309 self.global_namespace = global_namespace
310
311 super(Completer, self).__init__(config=config)
297 312
298 313 def complete(self, text, state):
299 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 368 # Another option, seems to work great. Catches things like ''.<tab>
354 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 379 return []
358
359 expr, attr = m.group(1, 3)
380
360 381 try:
361 382 obj = eval(expr, self.namespace)
362 383 except:
@@ -380,8 +401,19 b' class Completer(object):'
380 401 class IPCompleter(Completer):
381 402 """Extension of the completer class with IPython-specific features"""
382 403
383 def __init__(self, shell, namespace=None, global_namespace=None,
384 omit__names=True, alias_table=None, use_readline=True):
404 def _greedy_changed(self, name, old, new):
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 417 """IPCompleter() -> completer
386 418
387 419 Return a completer object suitable for use by the readline library
@@ -411,8 +443,6 b' class IPCompleter(Completer):'
411 443 without readline, though in that case callers must provide some extra
412 444 information on each call about the current line."""
413 445
414 Completer.__init__(self, namespace, global_namespace)
415
416 446 self.magic_escape = ESC_MAGIC
417 447 self.splitter = CompletionSplitter()
418 448
@@ -424,6 +454,10 b' class IPCompleter(Completer):'
424 454 else:
425 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 461 # List where completion matches will be stored
428 462 self.matches = []
429 463 self.omit__names = omit__names
@@ -579,7 +613,7 b' class IPCompleter(Completer):'
579 613 def python_matches(self,text):
580 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 617 if "." in text:
584 618 try:
585 619 matches = self.attr_matches(text)
@@ -680,7 +714,7 b' class IPCompleter(Completer):'
680 714 return argMatches
681 715
682 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 718 line = self.line_buffer
685 719 if not line.strip():
686 720 return None
@@ -1771,12 +1771,14 b' class InteractiveShell(SingletonConfigurable, Magic):'
1771 1771 from IPython.core.completerlib import (module_completer,
1772 1772 magic_run_completer, cd_completer)
1773 1773
1774 self.Completer = IPCompleter(self,
1775 self.user_ns,
1776 self.user_global_ns,
1777 self.readline_omit__names,
1778 self.alias_manager.alias_table,
1779 self.has_readline)
1774 self.Completer = IPCompleter(shell=self,
1775 namespace=self.user_ns,
1776 global_namespace=self.user_global_ns,
1777 omit__names=self.readline_omit__names,
1778 alias_table=self.alias_manager.alias_table,
1779 use_readline=self.has_readline,
1780 config=self.config,
1781 )
1780 1782
1781 1783 # Add custom completers to the basic ones built into IPCompleter
1782 1784 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
@@ -181,3 +181,14 b' def test_local_file_completions():'
181 181 finally:
182 182 # prevent failures from making chdir stick
183 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 35 from IPython.config.application import boolean_flag
36 36 from IPython.core import release
37 37 from IPython.core import usage
38 from IPython.core.completer import Completer
38 39 from IPython.core.crashhandler import CrashHandler
39 40 from IPython.core.formatters import PlainTextFormatter
40 41 from IPython.core.application import (
@@ -198,6 +199,7 b' class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):'
198 199 TerminalInteractiveShell,
199 200 ProfileDir,
200 201 PlainTextFormatter,
202 Completer,
201 203 ]
202 204
203 205 subcommands = Dict(dict(
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now