From 0cc3b86ab128c05aee11c97205d5f74184f4a179 Mon Sep 17 00:00:00 2001 From: rybarczykj Date: Thu, 15 Jul 2021 16:32:25 -0500 Subject: [PATCH] Update (unfinished) PR to present day --- bpython/autocomplete.py | 17 +++++++++++++---- bpython/repl.py | 8 +++++++- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/bpython/autocomplete.py b/bpython/autocomplete.py index 975a2622..7e13314e 100644 --- a/bpython/autocomplete.py +++ b/bpython/autocomplete.py @@ -162,6 +162,8 @@ def from_string(cls, value): def after_last_dot(name): + """matches are stored as 'math.cos', 'math.sin', etc. This function returns + just 'cos' or 'sin' """ return name.rstrip(".").rsplit(".")[-1] @@ -213,7 +215,9 @@ def __init__(self, shown_before_tab=True, mode=AutocompleteModes.SIMPLE): def matches(self, cursor_offset, line, **kwargs): """Returns a list of possible matches given a line and cursor, or None - if this completion type isn't applicable. + if this completion type isn't applicable. Callable matches will end + with open close parens "()", but when they are replaced, parens are + removed. ie, import completion doesn't make sense if there cursor isn't after an import or from statement, so it ought to return None. @@ -413,7 +417,12 @@ def attr_lookup(self, obj, expr, attr): n = len(attr) for word in words: if self.method_match(word, n, attr) and word != "__builtins__": - matches.append(f"{expr}.{word}") + try: + if callable(inspection.getattr_safe(obj, word)): + word += "()" + except AttributeError: + pass + matches.append("%s.%s" % (expr, word)) return matches def list_attributes(self, obj): @@ -690,6 +699,6 @@ def get_default_completer(mode=AutocompleteModes.SIMPLE, module_gatherer=None): def _callable_postfix(value, word): """rlcompleter's _callable_postfix done right.""" - if callable(value): - word += "(" + if inspection.is_callable(value): + word += "()" return word diff --git a/bpython/repl.py b/bpython/repl.py index ba9acf4d..f896b404 100644 --- a/bpython/repl.py +++ b/bpython/repl.py @@ -254,7 +254,13 @@ def __iter__(self): def current(self): if self.index == -1: raise ValueError("No current match.") - return self.matches[self.index] + cur = self.matches[self.index] + return self.strip_parens(cur) + + def strip_parens(self, word): + if word.endswith("()"): + word = word[:-2] + return word def next(self): return self.__next__()