X Tutup
Skip to content

Commit 37906c0

Browse files
committed
Suggest full list of literal dictionary keys upon typing opening '['. Dict may be global, object attribute, etc. Method autocomplete unchanged
1 parent d16c649 commit 37906c0

File tree

2 files changed

+31
-19
lines changed

2 files changed

+31
-19
lines changed

bpython/autocomplete.py

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,26 +63,39 @@ def complete(self, text, state):
6363
if self.use_main_ns:
6464
self.namespace = __main__.__dict__
6565

66+
dictpattern = re.compile('[^\[\]]+\[$')
67+
def complete_dict(text):
68+
lastbracket_index = text.rindex('[')
69+
dexpr = text[:lastbracket_index].lstrip()
70+
obj = eval(dexpr, self.locals)
71+
if obj and isinstance(obj, type({})) and obj.keys():
72+
self.matches = [dexpr + "[{!r}]".format(k) for k in obj.keys()]
73+
else:
74+
# empty dictionary
75+
self.matches = []
76+
6677
if state == 0:
6778
if "." in text:
68-
self.matches = self.attr_matches(text)
69-
#print self.matches
70-
# MAJA TODO: what if there's a dict in an object...?
71-
elif "[" in text:
72-
expr = text[:text.rindex('[')].lstrip()
73-
obj = eval(expr, self.locals)
74-
# use type() instead of hasattr?
75-
if obj and hasattr(obj,'keys') and obj.keys():
76-
self.matches = [expr + "[%r]" % k for k in obj.keys()]
79+
if dictpattern.match(text):
80+
complete_dict(text)
7781
else:
78-
# empty dictionary
79-
self.matches = []
82+
# Examples: 'foo.b' or 'foo[bar.'
83+
for i in range(1, len(text) + 1):
84+
if text[-i] == '[':
85+
i -= 1
86+
break
87+
methodtext = text[-i:]
88+
self.matches = [''.join([text[:-i], m]) for m in
89+
self.attr_matches(methodtext)]
90+
elif dictpattern.match(text):
91+
complete_dict(text)
8092
else:
8193
self.matches = self.global_matches(text)
8294
try:
8395
return self.matches[state]
8496
except IndexError:
8597
return None
98+
8699
def attr_matches(self, text):
87100
"""Taken from rlcompleter.py and bent to my will.
88101
"""

bpython/cli.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -505,19 +505,18 @@ def cw(self):
505505
# isn't at the end of the line, but that's what this does for now.
506506
if self.cpos: return
507507

508-
# look from right to left for a bad method character
508+
# look from right to left for a bad method or dictionary character
509509
l = len(self.s)
510-
#MAJA is_method_or_dict_character, [ and \' major problem
511-
is_method_char = lambda c: c.isalnum() or c in ('.',
512-
'_', '[', '\'', ']')
510+
is_method_char = lambda c: c.isalnum() or c in ('.', '_')
511+
dict_chars = ['[']
513512

514-
if not self.s or not is_method_char(self.s[l-1]):
513+
if not self.s or not (is_method_char(self.s[-1])
514+
or self.s[-1] in dict_chars):
515515
return
516516

517-
#MAJA only dictionaries should have \' (TODO)
518-
519517
for i in range(1, l+1):
520-
if not is_method_char(self.s[-i]):
518+
c = self.s[-i]
519+
if not (is_method_char(c) or c in dict_chars):
521520
i -= 1
522521
break
523522

0 commit comments

Comments
 (0)
X Tutup