|
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:] |