You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
68 lines
2.4 KiB
68 lines
2.4 KiB
6 years ago
|
from __future__ import unicode_literals
|
||
|
|
||
|
from six import string_types
|
||
|
from prompt_toolkit.completion import Completer, Completion
|
||
|
|
||
|
__all__ = [
|
||
|
'WordCompleter',
|
||
|
]
|
||
|
|
||
|
|
||
|
class WordCompleter(Completer):
|
||
|
"""
|
||
|
Simple autocompletion on a list of words.
|
||
|
|
||
|
:param words: List of words or callable that returns a list of words.
|
||
|
:param ignore_case: If True, case-insensitive completion.
|
||
|
:param meta_dict: Optional dict mapping words to their meta-text. (This
|
||
|
should map strings to strings or formatted text.)
|
||
|
:param WORD: When True, use WORD characters.
|
||
|
:param sentence: When True, don't complete by comparing the word before the
|
||
|
cursor, but by comparing all the text before the cursor. In this case,
|
||
|
the list of words is just a list of strings, where each string can
|
||
|
contain spaces. (Can not be used together with the WORD option.)
|
||
|
:param match_middle: When True, match not only the start, but also in the
|
||
|
middle of the word.
|
||
|
"""
|
||
|
def __init__(self, words, ignore_case=False, meta_dict=None, WORD=False,
|
||
|
sentence=False, match_middle=False):
|
||
|
assert not (WORD and sentence)
|
||
|
assert callable(words) or all(isinstance(w, string_types) for w in words)
|
||
|
|
||
|
self.words = words
|
||
|
self.ignore_case = ignore_case
|
||
|
self.meta_dict = meta_dict or {}
|
||
|
self.WORD = WORD
|
||
|
self.sentence = sentence
|
||
|
self.match_middle = match_middle
|
||
|
|
||
|
def get_completions(self, document, complete_event):
|
||
|
# Get list of words.
|
||
|
words = self.words
|
||
|
if callable(words):
|
||
|
words = words()
|
||
|
|
||
|
# Get word/text before cursor.
|
||
|
if self.sentence:
|
||
|
word_before_cursor = document.text_before_cursor
|
||
|
else:
|
||
|
word_before_cursor = document.get_word_before_cursor(WORD=self.WORD)
|
||
|
|
||
|
if self.ignore_case:
|
||
|
word_before_cursor = word_before_cursor.lower()
|
||
|
|
||
|
def word_matches(word):
|
||
|
""" True when the word before the cursor matches. """
|
||
|
if self.ignore_case:
|
||
|
word = word.lower()
|
||
|
|
||
|
if self.match_middle:
|
||
|
return word_before_cursor in word
|
||
|
else:
|
||
|
return word.startswith(word_before_cursor)
|
||
|
|
||
|
for a in words:
|
||
|
if word_matches(a):
|
||
|
display_meta = self.meta_dict.get(a, '')
|
||
|
yield Completion(a, -len(word_before_cursor), display_meta=display_meta)
|