Skip to content

Commit f16a248

Browse files
Shawn Axsomthomasballinger
Shawn Axsom
authored andcommitted
Array item completion is working with strings.
Pressing tab works for autocompletion of array items now
1 parent 9f45c32 commit f16a248

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

bpython/autocomplete.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,44 @@ def list_attributes(self, obj):
335335
return dir(obj)
336336

337337

338+
class ArrayObjectMembersCompletion(BaseCompletionType):
339+
340+
def __init__(self, shown_before_tab=True, mode=SIMPLE):
341+
self._shown_before_tab = shown_before_tab
342+
self.completer = AttrCompletion(mode=mode)
343+
344+
def matches(self, cursor_offset, line, **kwargs):
345+
if 'locals_' not in kwargs:
346+
return None
347+
locals_ = kwargs['locals_']
348+
349+
r = self.locate(cursor_offset, line)
350+
if r is None:
351+
return None
352+
member_part = r[2]
353+
_, _, dexpr = lineparts.current_array_with_indexer(cursor_offset, line)
354+
try:
355+
locals_['temp_val_from_array'] = safe_eval(dexpr, locals_)
356+
except (EvaluationError, IndexError):
357+
return set()
358+
359+
temp_line = line.replace(member_part, 'temp_val_from_array.')
360+
361+
matches = self.completer.matches(len(temp_line), temp_line, **kwargs)
362+
matches_with_correct_name = \
363+
set(match.replace('temp_val_from_array.', member_part) for match in matches)
364+
365+
del locals_['temp_val_from_array']
366+
367+
return matches_with_correct_name
368+
369+
def locate(self, current_offset, line):
370+
return lineparts.current_array_item_member_name(current_offset, line)
371+
372+
def format(self, match):
373+
return after_last_dot(match)
374+
375+
338376
class DictKeyCompletion(BaseCompletionType):
339377

340378
def matches(self, cursor_offset, line, **kwargs):
@@ -565,6 +603,7 @@ def get_default_completer(mode=SIMPLE):
565603
MagicMethodCompletion(mode=mode),
566604
MultilineJediCompletion(mode=mode),
567605
GlobalCompletion(mode=mode),
606+
ArrayObjectMembersCompletion(mode=mode),
568607
CumulativeCompleter((AttrCompletion(mode=mode),
569608
ParameterNameCompletion(mode=mode)),
570609
mode=mode)

bpython/line.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,3 +226,27 @@ def current_string_literal_attr(cursor_offset, line):
226226
if m.start(4) <= cursor_offset and m.end(4) >= cursor_offset:
227227
return LinePart(m.start(4), m.end(4), m.group(4))
228228
return None
229+
230+
231+
current_array_with_indexer_re = LazyReCompile(
232+
r'''([\w_][\w0-9._]*\[[a-zA-Z0-9_"']+\])\.(.*)''')
233+
234+
235+
def current_array_with_indexer(cursor_offset, line):
236+
"""an array and indexer, e.g. foo[1]"""
237+
matches = current_array_with_indexer_re.finditer(line)
238+
for m in matches:
239+
if m.start(1) <= cursor_offset and m.end(1) <= cursor_offset:
240+
return LinePart(m.start(1), m.end(1), m.group(1))
241+
242+
243+
current_array_item_member_name_re = LazyReCompile(
244+
r'''([\w_][\w0-9._]*\[[a-zA-Z0-9_"']+\]\.)(.*)''')
245+
246+
247+
def current_array_item_member_name(cursor_offset, line):
248+
"""the member name after an array indexer, e.g. foo[1].bar"""
249+
matches = current_array_item_member_name_re.finditer(line)
250+
for m in matches:
251+
if m.start(2) <= cursor_offset and m.end(2) >= cursor_offset:
252+
return LinePart(m.start(1), m.end(2), m.group(1))

0 commit comments

Comments
 (0)