Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | import string |
2 | import re | |
3 | ||
4 | ###$ event <<expand-word>> | |
5 | ###$ win <Alt-slash> | |
6 | ###$ unix <Alt-slash> | |
7 | ||
8 | class AutoExpand: | |
9 | ||
10 | menudefs = [ | |
11 | ('edit', [ | |
12 | ('E_xpand Word', '<<expand-word>>'), | |
13 | ]), | |
14 | ] | |
15 | ||
16 | wordchars = string.ascii_letters + string.digits + "_" | |
17 | ||
18 | def __init__(self, editwin): | |
19 | self.text = editwin.text | |
20 | self.state = None | |
21 | ||
22 | def expand_word_event(self, event): | |
23 | curinsert = self.text.index("insert") | |
24 | curline = self.text.get("insert linestart", "insert lineend") | |
25 | if not self.state: | |
26 | words = self.getwords() | |
27 | index = 0 | |
28 | else: | |
29 | words, index, insert, line = self.state | |
30 | if insert != curinsert or line != curline: | |
31 | words = self.getwords() | |
32 | index = 0 | |
33 | if not words: | |
34 | self.text.bell() | |
35 | return "break" | |
36 | word = self.getprevword() | |
37 | self.text.delete("insert - %d chars" % len(word), "insert") | |
38 | newword = words[index] | |
39 | index = (index + 1) % len(words) | |
40 | if index == 0: | |
41 | self.text.bell() # Warn we cycled around | |
42 | self.text.insert("insert", newword) | |
43 | curinsert = self.text.index("insert") | |
44 | curline = self.text.get("insert linestart", "insert lineend") | |
45 | self.state = words, index, curinsert, curline | |
46 | return "break" | |
47 | ||
48 | def getwords(self): | |
49 | word = self.getprevword() | |
50 | if not word: | |
51 | return [] | |
52 | before = self.text.get("1.0", "insert wordstart") | |
53 | wbefore = re.findall(r"\b" + word + r"\w+\b", before) | |
54 | del before | |
55 | after = self.text.get("insert wordend", "end") | |
56 | wafter = re.findall(r"\b" + word + r"\w+\b", after) | |
57 | del after | |
58 | if not wbefore and not wafter: | |
59 | return [] | |
60 | words = [] | |
61 | dict = {} | |
62 | # search backwards through words before | |
63 | wbefore.reverse() | |
64 | for w in wbefore: | |
65 | if dict.get(w): | |
66 | continue | |
67 | words.append(w) | |
68 | dict[w] = w | |
69 | # search onwards through words after | |
70 | for w in wafter: | |
71 | if dict.get(w): | |
72 | continue | |
73 | words.append(w) | |
74 | dict[w] = w | |
75 | words.append(word) | |
76 | return words | |
77 | ||
78 | def getprevword(self): | |
79 | line = self.text.get("insert linestart", "insert") | |
80 | i = len(line) | |
81 | while i > 0 and line[i-1] in self.wordchars: | |
82 | i = i-1 | |
83 | return line[i:] |