blob: 0d57be4205b43f83ec5164eb62dfe5e4579c7599 [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 = {
15 '<<expand-word>>': ['<Meta-slash>'],
16 }
17
Guido van Rossum504b0bf1999-01-02 21:28:54 +000018 menudefs = [
19 ('edit', [
20 ('E_xpand word', '<<expand-word>>'),
21 ]),
22 ]
23
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000024 wordchars = string.letters + string.digits + "_"
25
Guido van Rossum504b0bf1999-01-02 21:28:54 +000026 def __init__(self, editwin):
27 self.text = editwin.text
28 self.text.wordlist = None # XXX what is this?
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000029 self.state = None
Guido van Rossum504b0bf1999-01-02 21:28:54 +000030
31 def expand_word_event(self, event):
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000032 curinsert = self.text.index("insert")
33 curline = self.text.get("insert linestart", "insert lineend")
34 if not self.state:
35 words = self.getwords()
36 index = 0
37 else:
38 words, index, insert, line = self.state
39 if insert != curinsert or line != curline:
40 words = self.getwords()
41 index = 0
42 if not words:
43 self.text.bell()
44 return "break"
45 word = self.getprevword()
46 self.text.delete("insert - %d chars" % len(word), "insert")
47 newword = words[index]
48 index = (index + 1) % len(words)
49 if index == 0:
50 self.text.bell() # Warn we cycled around
51 self.text.insert("insert", newword)
52 curinsert = self.text.index("insert")
53 curline = self.text.get("insert linestart", "insert lineend")
54 self.state = words, index, curinsert, curline
55 return "break"
Guido van Rossum504b0bf1999-01-02 21:28:54 +000056
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000057 def getwords(self):
58 word = self.getprevword()
59 if not word:
60 return []
61 before = self.text.get("1.0", "insert wordstart")
62 wbefore = re.findall(r"\b" + word + r"\w+\b", before)
63 del before
64 after = self.text.get("insert wordend", "end")
65 wafter = re.findall(r"\b" + word + r"\w+\b", after)
66 del after
67 if not wbefore and not wafter:
68 return []
69 words = []
70 dict = {}
71 # search backwards through words before
72 wbefore.reverse()
73 for w in wbefore:
74 if dict.get(w):
75 continue
76 words.append(w)
77 dict[w] = w
78 # search onwards through words after
79 for w in wafter:
80 if dict.get(w):
81 continue
82 words.append(w)
83 dict[w] = w
84 words.append(word)
85 return words
Guido van Rossum504b0bf1999-01-02 21:28:54 +000086
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000087 def getprevword(self):
88 line = self.text.get("insert linestart", "insert")
89 i = len(line)
90 while i > 0 and line[i-1] in self.wordchars:
91 i = i-1
92 return line[i:]