summaryrefslogtreecommitdiffstats
path: root/src/prompt_toolkit/contrib/regular_languages/completion.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/prompt_toolkit/contrib/regular_languages/completion.py')
-rw-r--r--src/prompt_toolkit/contrib/regular_languages/completion.py24
1 files changed, 15 insertions, 9 deletions
diff --git a/src/prompt_toolkit/contrib/regular_languages/completion.py b/src/prompt_toolkit/contrib/regular_languages/completion.py
index 2e353e8..19ebaad 100644
--- a/src/prompt_toolkit/contrib/regular_languages/completion.py
+++ b/src/prompt_toolkit/contrib/regular_languages/completion.py
@@ -1,6 +1,7 @@
"""
Completer for a regular grammar.
"""
+
from __future__ import annotations
from typing import Iterable
@@ -37,12 +38,10 @@ class GrammarCompleter(Completer):
m = self.compiled_grammar.match_prefix(document.text_before_cursor)
if m:
- completions = self._remove_duplicates(
+ yield from self._remove_duplicates(
self._get_completions_for_match(m, complete_event)
)
- yield from completions
-
def _get_completions_for_match(
self, match: Match, complete_event: CompleteEvent
) -> Iterable[Completion]:
@@ -81,14 +80,21 @@ class GrammarCompleter(Completer):
display_meta=completion.display_meta,
)
- def _remove_duplicates(self, items: Iterable[Completion]) -> list[Completion]:
+ def _remove_duplicates(self, items: Iterable[Completion]) -> Iterable[Completion]:
"""
Remove duplicates, while keeping the order.
(Sometimes we have duplicates, because the there several matches of the
same grammar, each yielding similar completions.)
"""
- result: list[Completion] = []
- for i in items:
- if i not in result:
- result.append(i)
- return result
+
+ def hash_completion(completion: Completion) -> tuple[str, int]:
+ return completion.text, completion.start_position
+
+ yielded_so_far: set[tuple[str, int]] = set()
+
+ for completion in items:
+ hash_value = hash_completion(completion)
+
+ if hash_value not in yielded_so_far:
+ yielded_so_far.add(hash_value)
+ yield completion