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