3636from bpython import line as lineparts
3737from bpython ._py3compat import py3
3838
39+
3940# Autocomplete modes
4041SIMPLE = 'simple'
4142SUBSTRING = 'substring'
@@ -70,11 +71,13 @@ def matches(self, cursor_offset, line, **kwargs):
7071 an import or from statement, so it ought to return None.
7172
7273 Completion types are used to:
73- * `locate(cur, line)` their initial target word to replace given a line and cursor
74+ * `locate(cur, line)` their initial target word to replace given a
75+ line and cursor
7476 * find `matches(cur, line)` that might replace that word
7577 * `format(match)` matches to be displayed to the user
7678 * determine whether suggestions should be `shown_before_tab`
77- * `substitute(cur, line, match)` in a match for what's found with `target`
79+ * `substitute(cur, line, match)` in a match for what's found with
80+ `target`
7881 """
7982 raise NotImplementedError
8083
@@ -98,12 +101,14 @@ def shown_before_tab(self):
98101 once that has happened."""
99102 return self ._shown_before_tab
100103
104+
101105class CumulativeCompleter (BaseCompletionType ):
102106 """Returns combined matches from several completers"""
103107
104108 def __init__ (self , completers ):
105109 if not completers :
106- raise ValueError ("CumulativeCompleter requires at least one completer" )
110+ raise ValueError (
111+ "CumulativeCompleter requires at least one completer" )
107112 self ._completers = completers
108113
109114 super (CumulativeCompleter , self ).__init__ (True )
@@ -114,22 +119,18 @@ def locate(self, current_offset, line):
114119 def format (self , word ):
115120 return self ._completers [0 ].format (word )
116121
117- def matches (self , cursor_offset , line , locals_ , argspec , current_block , complete_magic_methods , history ):
122+ def matches (self , cursor_offset , line , ** kwargs ):
118123 all_matches = set ()
119124 for completer in self ._completers :
120125 # these have to be explicitely listed to deal with the different
121126 # signatures of various matches() methods of completers
122127 matches = completer .matches (cursor_offset = cursor_offset ,
123128 line = line ,
124- locals_ = locals_ ,
125- argspec = argspec ,
126- current_block = current_block ,
127- complete_magic_methods = complete_magic_methods ,
128- history = history )
129+ ** kwargs )
129130 if matches is not None :
130131 all_matches .update (matches )
131132
132- return sorted ( all_matches )
133+ return all_matches
133134
134135
135136class ImportCompletion (BaseCompletionType ):
@@ -143,6 +144,7 @@ def locate(self, current_offset, line):
143144 def format (self , word ):
144145 return after_last_dot (word )
145146
147+
146148class FilenameCompletion (BaseCompletionType ):
147149
148150 def __init__ (self ):
@@ -174,9 +176,14 @@ def format(self, filename):
174176 else :
175177 return filename
176178
179+
177180class AttrCompletion (BaseCompletionType ):
178181
179- def matches (self , cursor_offset , line , locals_ , ** kwargs ):
182+ def matches (self , cursor_offset , line , ** kwargs ):
183+ if 'locals_' not in kwargs :
184+ return None
185+ locals_ = kwargs ['locals_' ]
186+
180187 r = self .locate (cursor_offset , line )
181188 if r is None :
182189 return None
@@ -195,8 +202,9 @@ def matches(self, cursor_offset, line, locals_, **kwargs):
195202 matches = set ('' .join ([text [:- i ], m ])
196203 for m in attr_matches (methodtext , locals_ ))
197204
198- #TODO add open paren for methods via _callable_prefix (or decide not to)
199- # unless the first character is a _ filter out all attributes starting with a _
205+ # TODO add open paren for methods via _callable_prefix (or decide not
206+ # to) unless the first character is a _ filter out all attributes
207+ # starting with a _
200208 if not text .split ('.' )[- 1 ].startswith ('_' ):
201209 matches = set (match for match in matches
202210 if not match .split ('.' )[- 1 ].startswith ('_' ))
@@ -208,9 +216,14 @@ def locate(self, current_offset, line):
208216 def format (self , word ):
209217 return after_last_dot (word )
210218
219+
211220class DictKeyCompletion (BaseCompletionType ):
212221
213- def matches (self , cursor_offset , line , locals_ , ** kwargs ):
222+ def matches (self , cursor_offset , line , ** kwargs ):
223+ if 'locals_' not in kwargs :
224+ return None
225+ locals_ = kwargs ['locals_' ]
226+
214227 r = self .locate (cursor_offset , line )
215228 if r is None :
216229 return None
@@ -232,9 +245,14 @@ def locate(self, current_offset, line):
232245 def format (self , match ):
233246 return match [:- 1 ]
234247
248+
235249class MagicMethodCompletion (BaseCompletionType ):
236250
237- def matches (self , cursor_offset , line , current_block , ** kwargs ):
251+ def matches (self , cursor_offset , line , ** kwargs ):
252+ if 'current_block' not in kwargs :
253+ return None
254+ current_block = kwargs ['current_block' ]
255+
238256 r = self .locate (cursor_offset , line )
239257 if r is None :
240258 return None
@@ -246,13 +264,18 @@ def matches(self, cursor_offset, line, current_block, **kwargs):
246264 def locate (self , current_offset , line ):
247265 return lineparts .current_method_definition_name (current_offset , line )
248266
267+
249268class GlobalCompletion (BaseCompletionType ):
250269
251- def matches (self , cursor_offset , line , locals_ , ** kwargs ):
270+ def matches (self , cursor_offset , line , ** kwargs ):
252271 """Compute matches when text is a simple name.
253272 Return a list of all keywords, built-in functions and names currently
254273 defined in self.namespace that match.
255274 """
275+ if 'locals_' not in kwargs :
276+ return None
277+ locals_ = kwargs ['locals_' ]
278+
256279 r = self .locate (cursor_offset , line )
257280 if r is None :
258281 return None
@@ -272,9 +295,14 @@ def matches(self, cursor_offset, line, locals_, **kwargs):
272295 def locate (self , current_offset , line ):
273296 return lineparts .current_single_word (current_offset , line )
274297
298+
275299class ParameterNameCompletion (BaseCompletionType ):
276300
277- def matches (self , cursor_offset , line , argspec , ** kwargs ):
301+ def matches (self , cursor_offset , line , ** kwargs ):
302+ if 'argspec' not in kwargs :
303+ return None
304+ argspec = kwargs ['argspec' ]
305+
278306 if not argspec :
279307 return None
280308 r = self .locate (cursor_offset , line )
@@ -293,6 +321,7 @@ def matches(self, cursor_offset, line, argspec, **kwargs):
293321 def locate (self , current_offset , line ):
294322 return lineparts .current_word (current_offset , line )
295323
324+
296325class StringLiteralAttrCompletion (BaseCompletionType ):
297326
298327 def matches (self , cursor_offset , line , ** kwargs ):
@@ -309,6 +338,7 @@ def matches(self, cursor_offset, line, **kwargs):
309338 def locate (self , current_offset , line ):
310339 return lineparts .current_string_literal_attr (current_offset , line )
311340
341+
312342try :
313343 import jedi
314344except ImportError :
@@ -317,14 +347,20 @@ def matches(self, cursor_offset, line, **kwargs):
317347 return None
318348else :
319349 class JediCompletion (BaseCompletionType ):
320- def matches (self , cursor_offset , line , history , ** kwargs ):
350+ def matches (self , cursor_offset , line , ** kwargs ):
351+ if 'history' not in kwargs :
352+ return None
353+ history = kwargs ['history' ]
354+
321355 if not lineparts .current_word (cursor_offset , line ):
322356 return None
323357 history = '\n ' .join (history ) + '\n ' + line
324- script = jedi .Script (history , len (history .splitlines ()), cursor_offset , 'fake.py' )
358+ script = jedi .Script (history , len (history .splitlines ()),
359+ cursor_offset , 'fake.py' )
325360 completions = script .completions ()
326361 if completions :
327- self ._orig_start = cursor_offset - (len (completions [0 ].name ) - len (completions [0 ].complete ))
362+ diff = len (completions [0 ].name ) - len (completions [0 ].complete )
363+ self ._orig_start = cursor_offset - diff
328364 else :
329365 self ._orig_start = None
330366 return None
@@ -333,22 +369,31 @@ def matches(self, cursor_offset, line, history, **kwargs):
333369
334370 matches = [c .name for c in completions ]
335371 if any (not m .lower ().startswith (matches [0 ][0 ].lower ()) for m in matches ):
336- return None # Too general - giving completions starting with multiple letters
372+ # Too general - giving completions starting with multiple
373+ # letters
374+ return None
337375 else :
338376 # case-sensitive matches only
339- return set ([ m for m in matches if m .startswith (first_letter )] )
377+ return set (m for m in matches if m .startswith (first_letter ))
340378
341379 def locate (self , cursor_offset , line ):
342380 start = self ._orig_start
343381 end = cursor_offset
344382 return start , end , line [start :end ]
345383
346-
347384 class MultilineJediCompletion (JediCompletion ):
348- def matches (self , cursor_offset , line , current_block , history , ** kwargs ):
385+ def matches (self , cursor_offset , line , ** kwargs ):
386+ if 'current_block' not in kwargs or 'history' not in kwargs :
387+ return None
388+ current_block = kwargs ['current_block' ]
389+ history = kwargs ['history' ]
390+
349391 if '\n ' in current_block :
350- assert cursor_offset <= len (line ), "%r %r" % (cursor_offset , line )
351- results = JediCompletion .matches (self , cursor_offset , line , history )
392+ assert cursor_offset <= len (line ), "%r %r" % (cursor_offset ,
393+ line )
394+ results = super (MultilineJediCompletion ,
395+ self ).matches (cursor_offset , line ,
396+ history = history )
352397 return results
353398 else :
354399 return None
@@ -359,9 +404,9 @@ def get_completer(completers, cursor_offset, line, **kwargs):
359404
360405 If no matches available, returns a tuple of an empty list and None
361406
362- kwargs (all required):
363- cursor_offset is the current cursor column
364- line is a string of the current line
407+ cursor_offset is the current cursor column
408+ line is a string of the current line
409+ kwargs (all optional):
365410 locals_ is a dictionary of the environment
366411 argspec is an inspect.ArgSpec instance for the current function where
367412 the cursor is
@@ -372,11 +417,13 @@ def get_completer(completers, cursor_offset, line, **kwargs):
372417 """
373418
374419 for completer in completers :
375- matches = completer .matches (cursor_offset , line , ** kwargs )
420+ matches = completer .matches (
421+ cursor_offset , line , ** kwargs )
376422 if matches is not None :
377423 return sorted (matches ), (completer if matches else None )
378424 return [], None
379425
426+
380427BPYTHON_COMPLETER = (
381428 DictKeyCompletion (),
382429 StringLiteralAttrCompletion (),
@@ -388,10 +435,10 @@ def get_completer(completers, cursor_offset, line, **kwargs):
388435 CumulativeCompleter ((AttrCompletion (), ParameterNameCompletion ()))
389436)
390437
391- def get_completer_bpython (** kwargs ):
438+
439+ def get_completer_bpython (cursor_offset , line , ** kwargs ):
392440 """"""
393- return get_completer (BPYTHON_COMPLETER ,
394- ** kwargs )
441+ return get_completer (BPYTHON_COMPLETER , cursor_offset , line , ** kwargs )
395442
396443
397444class EvaluationError (Exception ):
@@ -434,6 +481,7 @@ def attr_matches(text, namespace):
434481 matches = attr_lookup (obj , expr , attr )
435482 return matches
436483
484+
437485def attr_lookup (obj , expr , attr ):
438486 """Second half of original attr_matches method factored out so it can
439487 be wrapped in a safe try/finally block in case anything bad happens to
@@ -455,12 +503,14 @@ def attr_lookup(obj, expr, attr):
455503 matches .append ("%s.%s" % (expr , word ))
456504 return matches
457505
506+
458507def _callable_postfix (value , word ):
459508 """rlcompleter's _callable_postfix done right."""
460509 with inspection .AttrCleaner (value ):
461510 if inspection .is_callable (value ):
462511 word += '('
463512 return word
464513
514+
465515def method_match (word , size , text ):
466516 return word [:size ] == text
0 commit comments