aboutsummaryrefslogtreecommitdiffstats
path: root/tagit/dialogues/autoinput.py
blob: a036ed4914380650e44dd25f523eb03812825012 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
"""This is a simple example of how to use suggestion text.

In this example you setup a word_list at the begining. In this case
'the the quick brown fox jumps over the lazy old dog'. This list along
with any new word written word in the textinput is available as a
suggestion when you are typing. You can press tab to auto complete the text.

Based on & thanks to akshayaurora:
  https://gist.github.com/akshayaurora/fa5a68980af585e355668e5adce5f98b

Part of the tagit module.
A copy of the license is provided with the project.
Modifications authored by: Matthias Baumgartner, 2022
"""
# standard imports
from bisect import bisect

# kivy imports
from kivy.uix.textinput import TextInput
import kivy.properties as kp

# exports
__all__ = ('AutoTextInput', )


## code ##

class AutoTextInput(TextInput):

    sep = kp.StringProperty(',')
    suffix = kp.StringProperty(' ')
    vocabulary = kp.ListProperty()

    def on_suggestion_text(self, wx, value):
        if not value:
            return

        super(AutoTextInput, self).on_suggestion_text(wx, value)

    def keyboard_on_key_down(self, window, keycode, text, modifiers):
        if self.suggestion_text and keycode[1] == 'tab':  # complete suggestion_text
            self.insert_text(self.suggestion_text + self.sep + self.suffix)
            self.suggestion_text = ''
            return True
        return super(AutoTextInput, self).keyboard_on_key_down(window, keycode, text, modifiers)

    def on_text(self, wx, value):
        # include all current text from textinput into the word list
        # the kind of behavior sublime text has

        # what's on the current line
        temp = value[:value.rfind(self.sep)].split(self.sep)
        temp = [s.strip() for s in temp]
        # combine with static vocabulary
        wordlist = sorted(set(self.vocabulary + temp))

        # get prefix
        prefix = value[value.rfind(self.sep)+1:].strip()
        if not prefix:
            return

        # binary search on (sorted) wordlist
        pos = bisect(wordlist, prefix)

        # check if matching string found
        if pos == len(wordlist) or not wordlist[pos].startswith(prefix):
            self.suggestion_text = ''
            return

        # fetch suffix from wordlist
        self.suggestion_text = wordlist[pos][len(prefix):]

## EOF ##