Skip to content

Commit 7f619ed

Browse files
Several fixes to the completion code.
- Give dictionary completions priority over path completions. - Always call non-fuzzy completer after fuzzy completer to prevent that some completions were missed out if the fuzzy completer doesn't find them.
1 parent 1246deb commit 7f619ed

File tree

3 files changed

+44
-25
lines changed

3 files changed

+44
-25
lines changed

ptpython/completer.py

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,16 @@ class PythonCompleter(Completer):
4242
"""
4343

4444
def __init__(
45-
self, get_globals, get_locals, get_enable_dictionary_completion
45+
self,
46+
get_globals: Callable[[], dict],
47+
get_locals: Callable[[], dict],
48+
enable_dictionary_completion: Callable[[], bool],
4649
) -> None:
4750
super().__init__()
4851

4952
self.get_globals = get_globals
5053
self.get_locals = get_locals
51-
self.get_enable_dictionary_completion = get_enable_dictionary_completion
54+
self.enable_dictionary_completion = enable_dictionary_completion
5255

5356
self._system_completer = SystemCompleter()
5457
self._jedi_completer = JediCompleter(get_globals, get_locals)
@@ -134,10 +137,10 @@ def _complete_python_while_typing(self, document: Document) -> bool:
134137
When `complete_while_typing` is set, only return completions when this
135138
returns `True`.
136139
"""
137-
text = document.text_before_cursor.rstrip()
140+
text = document.text_before_cursor # .rstrip()
138141
char_before_cursor = text[-1:]
139142
return bool(
140-
text and (char_before_cursor.isalnum() or char_before_cursor in "_.(,")
143+
text and (char_before_cursor.isalnum() or char_before_cursor in "_.([,")
141144
)
142145

143146
def get_completions(
@@ -156,22 +159,11 @@ def get_completions(
156159
)
157160
return
158161

159-
# Do Path completions (if there were no dictionary completions).
160-
# TODO: not if we have dictionary completions...
161-
if complete_event.completion_requested or self._complete_path_while_typing(
162-
document
163-
):
164-
yield from self._path_completer.get_completions(document, complete_event)
165-
162+
# Do dictionary key completions.
166163
if complete_event.completion_requested or self._complete_python_while_typing(
167164
document
168165
):
169-
# If we are inside a string, Don't do Python completion.
170-
if self._path_completer_grammar.match(document.text_before_cursor):
171-
return
172-
173-
# Do dictionary key completions.
174-
if self.get_enable_dictionary_completion():
166+
if self.enable_dictionary_completion():
175167
has_dict_completions = False
176168
for c in self._dictionary_completer.get_completions(
177169
document, complete_event
@@ -184,8 +176,23 @@ def get_completions(
184176
if has_dict_completions:
185177
return
186178

187-
# Do Jedi Python completions.
188-
yield from self._jedi_completer.get_completions(document, complete_event)
179+
# Do Path completions (if there were no dictionary completions).
180+
if complete_event.completion_requested or self._complete_path_while_typing(
181+
document
182+
):
183+
yield from self._path_completer.get_completions(document, complete_event)
184+
185+
# Do Jedi completions.
186+
if complete_event.completion_requested or self._complete_python_while_typing(
187+
document
188+
):
189+
# If we are inside a string, Don't do Jedi completion.
190+
if not self._path_completer_grammar.match(document.text_before_cursor):
191+
192+
# Do Jedi Python completions.
193+
yield from self._jedi_completer.get_completions(
194+
document, complete_event
195+
)
189196

190197

191198
class JediCompleter(Completer):

ptpython/python_input.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@
1818
from prompt_toolkit.buffer import Buffer
1919
from prompt_toolkit.completion import (
2020
Completer,
21+
ConditionalCompleter,
2122
DynamicCompleter,
2223
FuzzyCompleter,
2324
ThreadedCompleter,
25+
merge_completers,
2426
)
2527
from prompt_toolkit.document import Document
2628
from prompt_toolkit.enums import DEFAULT_BUFFER, EditingMode
@@ -205,9 +207,20 @@ def __init__(
205207
)
206208

207209
self._completer = HidePrivateCompleter(
208-
FuzzyCompleter(
209-
DynamicCompleter(lambda: self.completer),
210-
enable_fuzzy=Condition(lambda: self.enable_fuzzy_completion),
210+
# If fuzzy is enabled, first do fuzzy completion, but always add
211+
# the non-fuzzy completions, if somehow the fuzzy completer didn't
212+
# find them. (Due to the way the cursor position is moved in the
213+
# fuzzy completer, some completions will not always be found by the
214+
# fuzzy completer, but will be found with the normal completer.)
215+
merge_completers(
216+
[
217+
ConditionalCompleter(
218+
FuzzyCompleter(DynamicCompleter(lambda: self.completer)),
219+
Condition(lambda: self.enable_fuzzy_completion),
220+
),
221+
DynamicCompleter(lambda: self.completer),
222+
],
223+
deduplicate=True,
211224
),
212225
lambda: self.complete_private_attributes,
213226
)

setup.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,8 @@
2020
"appdirs",
2121
"importlib_metadata;python_version<'3.8'",
2222
"jedi>=0.16.0",
23-
# Use prompt_toolkit 3.0.12, because of dont_extend_width bugfix when
24-
# signature and completion dropdown are displayed together.
25-
"prompt_toolkit>=3.0.12,<3.1.0",
23+
# Use prompt_toolkit 3.0.16, because of the `DeduplicateCompleter`.
24+
"prompt_toolkit>=3.0.16,<3.1.0",
2625
"pygments",
2726
"black",
2827
],

0 commit comments

Comments
 (0)