blob: 40d39f3f42618a0a30226d34e8d801fc68d81f97 [file] [log] [blame]
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +00001import string
2import re
3
Guido van Rossum504b0bf1999-01-02 21:28:54 +00004###$ event <<expand-word>>
5###$ win <Alt-slash>
6###$ unix <Alt-slash>
7
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +00008class AutoExpand:
Guido van Rossum504b0bf1999-01-02 21:28:54 +00009
10 keydefs = {
11 '<<expand-word>>': ['<Alt-slash>'],
12 }
13
Guido van Rossum16b91f81999-01-04 16:32:21 +000014 unix_keydefs = {
Guido van Rossumb19f1e32001-01-02 18:28:52 +000015 '<<expand-word>>': ['<Meta-slash>', '<Alt-slash>'],
Guido van Rossum16b91f81999-01-04 16:32:21 +000016 }
17
Guido van Rossum504b0bf1999-01-02 21:28:54 +000018 menudefs = [
19 ('edit', [
20 ('E_xpand word', '<<expand-word>>'),
21 ]),
22 ]
23
Fred Drake79e75e12001-07-20 19:05:50 +000024 wordchars = string.ascii_letters + string.digits + "_"
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000025
Guido van Rossum504b0bf1999-01-02 21:28:54 +000026 def __init__(self, editwin):
27 self.text = editwin.text
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000028 self.state = None
Guido van Rossum504b0bf1999-01-02 21:28:54 +000029
30 def expand_word_event(self, event):
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000031 curinsert = self.text.index("insert")
32 curline = self.text.get("insert linestart", "insert lineend")
33 if not self.state:
34 words = self.getwords()
35 index = 0
36 else:
37 words, index, insert, line = self.state
38 if insert != curinsert or line != curline:
39 words = self.getwords()
40 index = 0
41 if not words:
42 self.text.bell()
43 return "break"
44 word = self.getprevword()
45 self.text.delete("insert - %d chars" % len(word), "insert")
46 newword = words[index]
47 index = (index + 1) % len(words)
48 if index == 0:
49 self.text.bell() # Warn we cycled around
50 self.text.insert("insert", newword)
51 curinsert = self.text.index("insert")
52 curline = self.text.get("insert linestart", "insert lineend")
53 self.state = words, index, curinsert, curline
54 return "break"
Guido van Rossum504b0bf1999-01-02 21:28:54 +000055
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000056 def getwords(self):
57 word = self.getprevword()
58 if not word:
59 return []
60 before = self.text.get("1.0", "insert wordstart")
61 wbefore = re.findall(r"\b" + word + r"\w+\b", before)
62 del before
63 after = self.text.get("insert wordend", "end")
64 wafter = re.findall(r"\b" + word + r"\w+\b", after)
65 del after
66 if not wbefore and not wafter:
67 return []
68 words = []
69 dict = {}
70 # search backwards through words before
71 wbefore.reverse()
72 for w in wbefore:
73 if dict.get(w):
74 continue
75 words.append(w)
76 dict[w] = w
77 # search onwards through words after
78 for w in wafter:
79 if dict.get(w):
80 continue
81 words.append(w)
82 dict[w] = w
83 words.append(word)
84 return words
Guido van Rossum504b0bf1999-01-02 21:28:54 +000085
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000086 def getprevword(self):
87 line = self.text.get("insert linestart", "insert")
88 i = len(line)
89 while i > 0 and line[i-1] in self.wordchars:
90 i = i-1
91 return line[i:]