aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/prompt-toolkit/py3/prompt_toolkit/completion/fuzzy_completer.py
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.ru>2022-02-10 16:44:39 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:44:39 +0300
commite9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (patch)
tree64175d5cadab313b3e7039ebaa06c5bc3295e274 /contrib/python/prompt-toolkit/py3/prompt_toolkit/completion/fuzzy_completer.py
parent2598ef1d0aee359b4b6d5fdd1758916d5907d04f (diff)
downloadydb-e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0.tar.gz
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 2 of 2.
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.py400
1 files changed, 200 insertions, 200 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
index 8f9be0f028a..4f7c3ab5d68 100644
--- a/contrib/python/prompt-toolkit/py3/prompt_toolkit/completion/fuzzy_completer.py
+++ b/contrib/python/prompt-toolkit/py3/prompt_toolkit/completion/fuzzy_completer.py
@@ -1,201 +1,201 @@
-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 = "(?=({0}))".format(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(
+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 = "(?=({0}))".format(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)
-
-
-_FuzzyMatch = NamedTuple(
- "_FuzzyMatch",
- [("match_length", int), ("start_pos", int), ("completion", Completion)],
-)
+ 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)
+
+
+_FuzzyMatch = NamedTuple(
+ "_FuzzyMatch",
+ [("match_length", int), ("start_pos", int), ("completion", Completion)],
+)