diff options
author | monster <monster@ydb.tech> | 2022-07-07 14:41:37 +0300 |
---|---|---|
committer | monster <monster@ydb.tech> | 2022-07-07 14:41:37 +0300 |
commit | 06e5c21a835c0e923506c4ff27929f34e00761c2 (patch) | |
tree | 75efcbc6854ef9bd476eb8bf00cc5c900da436a2 /contrib/python/prompt-toolkit/py3/prompt_toolkit/completion/fuzzy_completer.py | |
parent | 03f024c4412e3aa613bb543cf1660176320ba8f4 (diff) | |
download | ydb-06e5c21a835c0e923506c4ff27929f34e00761c2.tar.gz |
fix ya.make
Diffstat (limited to 'contrib/python/prompt-toolkit/py3/prompt_toolkit/completion/fuzzy_completer.py')
-rw-r--r-- | contrib/python/prompt-toolkit/py3/prompt_toolkit/completion/fuzzy_completer.py | 201 |
1 files changed, 0 insertions, 201 deletions
diff --git a/contrib/python/prompt-toolkit/py3/prompt_toolkit/completion/fuzzy_completer.py b/contrib/python/prompt-toolkit/py3/prompt_toolkit/completion/fuzzy_completer.py deleted file mode 100644 index 627adc8738a..00000000000 --- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/completion/fuzzy_completer.py +++ /dev/null @@ -1,201 +0,0 @@ -import re -from typing import Callable, Dict, Iterable, List, NamedTuple, Optional, Tuple, Union - -from prompt_toolkit.document import Document -from prompt_toolkit.filters import FilterOrBool, to_filter -from prompt_toolkit.formatted_text import AnyFormattedText, StyleAndTextTuples - -from .base import CompleteEvent, Completer, Completion -from .word_completer import WordCompleter - -__all__ = [ - "FuzzyCompleter", - "FuzzyWordCompleter", -] - - -class FuzzyCompleter(Completer): - """ - Fuzzy completion. - This wraps any other completer and turns it into a fuzzy completer. - - If the list of words is: ["leopard" , "gorilla", "dinosaur", "cat", "bee"] - Then trying to complete "oar" would yield "leopard" and "dinosaur", but not - the others, because they match the regular expression 'o.*a.*r'. - Similar, in another application "djm" could expand to "django_migrations". - - The results are sorted by relevance, which is defined as the start position - and the length of the match. - - Notice that this is not really a tool to work around spelling mistakes, - like what would be possible with difflib. The purpose is rather to have a - quicker or more intuitive way to filter the given completions, especially - when many completions have a common prefix. - - Fuzzy algorithm is based on this post: - https://blog.amjith.com/fuzzyfinder-in-10-lines-of-python - - :param completer: A :class:`~.Completer` instance. - :param WORD: When True, use WORD characters. - :param pattern: Regex pattern which selects the characters before the - cursor that are considered for the fuzzy matching. - :param enable_fuzzy: (bool or `Filter`) Enabled the fuzzy behavior. For - easily turning fuzzyness on or off according to a certain condition. - """ - - def __init__( - self, - completer: Completer, - WORD: bool = False, - pattern: Optional[str] = None, - enable_fuzzy: FilterOrBool = True, - ): - - assert pattern is None or pattern.startswith("^") - - self.completer = completer - self.pattern = pattern - self.WORD = WORD - self.pattern = pattern - self.enable_fuzzy = to_filter(enable_fuzzy) - - def get_completions( - self, document: Document, complete_event: CompleteEvent - ) -> Iterable[Completion]: - if self.enable_fuzzy(): - return self._get_fuzzy_completions(document, complete_event) - else: - return self.completer.get_completions(document, complete_event) - - def _get_pattern(self) -> str: - if self.pattern: - return self.pattern - if self.WORD: - return r"[^\s]+" - return "^[a-zA-Z0-9_]*" - - def _get_fuzzy_completions( - self, document: Document, complete_event: CompleteEvent - ) -> Iterable[Completion]: - - word_before_cursor = document.get_word_before_cursor( - pattern=re.compile(self._get_pattern()) - ) - - # Get completions - document2 = Document( - text=document.text[: document.cursor_position - len(word_before_cursor)], - cursor_position=document.cursor_position - len(word_before_cursor), - ) - - completions = list(self.completer.get_completions(document2, complete_event)) - - fuzzy_matches: List[_FuzzyMatch] = [] - - pat = ".*?".join(map(re.escape, word_before_cursor)) - pat = f"(?=({pat}))" # lookahead regex to manage overlapping matches - regex = re.compile(pat, re.IGNORECASE) - for compl in completions: - matches = list(regex.finditer(compl.text)) - if matches: - # Prefer the match, closest to the left, then shortest. - best = min(matches, key=lambda m: (m.start(), len(m.group(1)))) - fuzzy_matches.append( - _FuzzyMatch(len(best.group(1)), best.start(), compl) - ) - - def sort_key(fuzzy_match: "_FuzzyMatch") -> Tuple[int, int]: - "Sort by start position, then by the length of the match." - return fuzzy_match.start_pos, fuzzy_match.match_length - - fuzzy_matches = sorted(fuzzy_matches, key=sort_key) - - for match in fuzzy_matches: - # Include these completions, but set the correct `display` - # attribute and `start_position`. - yield Completion( - text=match.completion.text, - start_position=match.completion.start_position - - len(word_before_cursor), - display_meta=match.completion.display_meta, - display=self._get_display(match, word_before_cursor), - style=match.completion.style, - ) - - def _get_display( - self, fuzzy_match: "_FuzzyMatch", word_before_cursor: str - ) -> AnyFormattedText: - """ - Generate formatted text for the display label. - """ - m = fuzzy_match - word = m.completion.text - - if m.match_length == 0: - # No highlighting when we have zero length matches (no input text). - # In this case, use the original display text (which can include - # additional styling or characters). - return m.completion.display - - result: StyleAndTextTuples = [] - - # Text before match. - result.append(("class:fuzzymatch.outside", word[: m.start_pos])) - - # The match itself. - characters = list(word_before_cursor) - - for c in word[m.start_pos : m.start_pos + m.match_length]: - classname = "class:fuzzymatch.inside" - if characters and c.lower() == characters[0].lower(): - classname += ".character" - del characters[0] - - result.append((classname, c)) - - # Text after match. - result.append( - ("class:fuzzymatch.outside", word[m.start_pos + m.match_length :]) - ) - - return result - - -class FuzzyWordCompleter(Completer): - """ - Fuzzy completion on a list of words. - - (This is basically a `WordCompleter` wrapped in a `FuzzyCompleter`.) - - :param words: List of words or callable that returns a list of words. - :param meta_dict: Optional dict mapping words to their meta-information. - :param WORD: When True, use WORD characters. - """ - - def __init__( - self, - words: Union[List[str], Callable[[], List[str]]], - meta_dict: Optional[Dict[str, str]] = None, - WORD: bool = False, - ) -> None: - - self.words = words - self.meta_dict = meta_dict or {} - self.WORD = WORD - - self.word_completer = WordCompleter( - words=self.words, WORD=self.WORD, meta_dict=self.meta_dict - ) - - self.fuzzy_completer = FuzzyCompleter(self.word_completer, WORD=self.WORD) - - def get_completions( - self, document: Document, complete_event: CompleteEvent - ) -> Iterable[Completion]: - return self.fuzzy_completer.get_completions(document, complete_event) - - -class _FuzzyMatch(NamedTuple): - match_length: int - start_pos: int - completion: Completion |