base.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. from __future__ import unicode_literals
  2. from six import string_types
  3. from prompt_toolkit.completion import Completer, Completion
  4. __all__ = (
  5. 'WordCompleter',
  6. )
  7. class WordCompleter(Completer):
  8. """
  9. Simple autocompletion on a list of words.
  10. :param words: List of words.
  11. :param ignore_case: If True, case-insensitive completion.
  12. :param meta_dict: Optional dict mapping words to their meta-information.
  13. :param WORD: When True, use WORD characters.
  14. :param sentence: When True, don't complete by comparing the word before the
  15. cursor, but by comparing all the text before the cursor. In this case,
  16. the list of words is just a list of strings, where each string can
  17. contain spaces. (Can not be used together with the WORD option.)
  18. :param match_middle: When True, match not only the start, but also in the
  19. middle of the word.
  20. """
  21. def __init__(self, words, ignore_case=False, meta_dict=None, WORD=False,
  22. sentence=False, match_middle=False):
  23. assert not (WORD and sentence)
  24. self.words = list(words)
  25. self.ignore_case = ignore_case
  26. self.meta_dict = meta_dict or {}
  27. self.WORD = WORD
  28. self.sentence = sentence
  29. self.match_middle = match_middle
  30. assert all(isinstance(w, string_types) for w in self.words)
  31. def get_completions(self, document, complete_event):
  32. # Get word/text before cursor.
  33. if self.sentence:
  34. word_before_cursor = document.text_before_cursor
  35. else:
  36. word_before_cursor = document.get_word_before_cursor(WORD=self.WORD)
  37. if self.ignore_case:
  38. word_before_cursor = word_before_cursor.lower()
  39. def word_matches(word):
  40. """ True when the word before the cursor matches. """
  41. if self.ignore_case:
  42. word = word.lower()
  43. if self.match_middle:
  44. return word_before_cursor in word
  45. else:
  46. return word.startswith(word_before_cursor)
  47. for a in self.words:
  48. if word_matches(a):
  49. display_meta = self.meta_dict.get(a, '')
  50. yield Completion(a, -len(word_before_cursor), display_meta=display_meta)