##// END OF EJS Templates
make Completer.greedy configurable
MinRK -
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,8 +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 _delims = ' \n\t'
233
236
234 # 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
235 # 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
@@ -261,11 +264,20 b' class CompletionSplitter(object):'
261 return self._delim_re.split(l)[-1]
264 return self._delim_re.split(l)[-1]
262
265
263
266
264 class Completer(object):
267 class Completer(Configurable):
265 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):
266 """Create a new completer for the command line.
278 """Create a new completer for the command line.
267
279
268 Completer([namespace,global_namespace]) -> completer instance.
280 Completer(namespace=ns,global_namespace=ns2) -> completer instance.
269
281
270 If unspecified, the default namespace where completions are performed
282 If unspecified, the default namespace where completions are performed
271 is __main__ (technically, __main__.__dict__). Namespaces should be
283 is __main__ (technically, __main__.__dict__). Namespaces should be
@@ -296,6 +308,8 b' class Completer(object):'
296 else:
308 else:
297 self.global_namespace = global_namespace
309 self.global_namespace = global_namespace
298
310
311 super(Completer, self).__init__(config=config)
312
299 def complete(self, text, state):
313 def complete(self, text, state):
300 """Return the next possible completion for 'text'.
314 """Return the next possible completion for 'text'.
301
315
@@ -356,11 +370,13 b' class Completer(object):'
356
370
357 if m:
371 if m:
358 expr, attr = m.group(1, 3)
372 expr, attr = m.group(1, 3)
359 else:
373 elif self.greedy:
360 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
374 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
361 if not m2:
375 if not m2:
362 return []
376 return []
363 expr, attr = m2.group(1,2)
377 expr, attr = m2.group(1,2)
378 else:
379 return []
364
380
365 try:
381 try:
366 obj = eval(expr, self.namespace)
382 obj = eval(expr, self.namespace)
@@ -385,8 +401,19 b' class Completer(object):'
385 class IPCompleter(Completer):
401 class IPCompleter(Completer):
386 """Extension of the completer class with IPython-specific features"""
402 """Extension of the completer class with IPython-specific features"""
387
403
388 def __init__(self, shell, namespace=None, global_namespace=None,
404 def _greedy_changed(self, name, old, new):
389 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):
390 """IPCompleter() -> completer
417 """IPCompleter() -> completer
391
418
392 Return a completer object suitable for use by the readline library
419 Return a completer object suitable for use by the readline library
@@ -416,8 +443,6 b' class IPCompleter(Completer):'
416 without readline, though in that case callers must provide some extra
443 without readline, though in that case callers must provide some extra
417 information on each call about the current line."""
444 information on each call about the current line."""
418
445
419 Completer.__init__(self, namespace, global_namespace)
420
421 self.magic_escape = ESC_MAGIC
446 self.magic_escape = ESC_MAGIC
422 self.splitter = CompletionSplitter()
447 self.splitter = CompletionSplitter()
423
448
@@ -429,6 +454,10 b' class IPCompleter(Completer):'
429 else:
454 else:
430 self.readline = None
455 self.readline = None
431
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
432 # List where completion matches will be stored
461 # List where completion matches will be stored
433 self.matches = []
462 self.matches = []
434 self.omit__names = omit__names
463 self.omit__names = omit__names
@@ -1749,12 +1749,14 b' class InteractiveShell(SingletonConfigurable, Magic):'
1749 from IPython.core.completerlib import (module_completer,
1749 from IPython.core.completerlib import (module_completer,
1750 magic_run_completer, cd_completer)
1750 magic_run_completer, cd_completer)
1751
1751
1752 self.Completer = IPCompleter(self,
1752 self.Completer = IPCompleter(shell=self,
1753 self.user_ns,
1753 namespace=self.user_ns,
1754 self.user_global_ns,
1754 global_namespace=self.user_global_ns,
1755 self.readline_omit__names,
1755 omit__names=self.readline_omit__names,
1756 self.alias_manager.alias_table,
1756 alias_table=self.alias_manager.alias_table,
1757 self.has_readline)
1757 use_readline=self.has_readline,
1758 config=self.config,
1759 )
1758
1760
1759 # Add custom completers to the basic ones built into IPCompleter
1761 # Add custom completers to the basic ones built into IPCompleter
1760 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1762 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(
General Comments 0
You need to be logged in to leave comments. Login now