Skip to content

Commit 51ecedb

Browse files
Add autocompletion of attributes of simple expressions
there's now duplication in completers
1 parent 488d5e6 commit 51ecedb

File tree

1 file changed

+40
-3
lines changed

1 file changed

+40
-3
lines changed

bpython/autocomplete.py

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@
4343
from bpython.line import LinePart
4444
from bpython._py3compat import py3, try_decode
4545
from bpython.lazyre import LazyReCompile
46-
from bpython.simpleeval import safe_eval, EvaluationError
46+
from bpython.simpleeval import (safe_eval, evaluate_current_expression,
47+
EvaluationError)
4748

4849
if not py3:
4950
from types import InstanceType, ClassType
@@ -241,7 +242,7 @@ def matches(self, cursor_offset, line, **kwargs):
241242
if r is None:
242243
return None
243244

244-
if locals_ is None:
245+
if locals_ is None: # TODO add a note about why
245246
locals_ = __main__.__dict__
246247

247248
assert '.' in r.word
@@ -524,6 +525,41 @@ def locate(self, current_offset, line):
524525
return lineparts.current_string_literal_attr(current_offset, line)
525526

526527

528+
class ExpressionAttributeCompletion(AttrCompletion):
529+
# could replace ArrayItemMember completion and attr completion
530+
# as a more general case
531+
def locate(self, current_offset, line):
532+
return lineparts.current_expression_attribute(current_offset, line)
533+
534+
def matches(self, cursor_offset, line, **kwargs):
535+
if 'locals_' not in kwargs:
536+
return None
537+
locals_ = kwargs['locals_']
538+
539+
if locals_ is None:
540+
locals_ = __main__.__dict__
541+
542+
attr = self.locate(cursor_offset, line)
543+
544+
try:
545+
obj = evaluate_current_expression(cursor_offset, line, locals_)
546+
except EvaluationError:
547+
return set()
548+
with inspection.AttrCleaner(obj):
549+
# strips leading dot
550+
matches = [m[1:] for m in self.attr_lookup(obj, '', attr.word)]
551+
552+
if attr.word.startswith('__'):
553+
pass
554+
elif attr.word.startswith('_'):
555+
matches = set(match for match in matches
556+
if not match.startswith('__'))
557+
else:
558+
matches = set(match for match in matches
559+
if not match.split('.')[-1].startswith('_'))
560+
return matches
561+
562+
527563
try:
528564
import jedi
529565
except ImportError:
@@ -638,8 +674,9 @@ def get_default_completer(mode=SIMPLE):
638674
CumulativeCompleter((GlobalCompletion(mode=mode),
639675
ParameterNameCompletion(mode=mode)),
640676
mode=mode),
641-
ArrayItemMembersCompletion(mode=mode),
642677
AttrCompletion(mode=mode),
678+
ExpressionAttributeCompletion(mode=mode),
679+
ArrayItemMembersCompletion(mode=mode),
643680
)
644681

645682

0 commit comments

Comments
 (0)