| 
									
										
										
										
											2000-08-15 01:13:23 +00:00
										 |  |  | import string | 
					
						
							|  |  |  | import re | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ###$ event <<expand-word>> | 
					
						
							|  |  |  | ###$ win <Alt-slash> | 
					
						
							|  |  |  | ###$ unix <Alt-slash> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class AutoExpand: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     keydefs = { | 
					
						
							|  |  |  |         '<<expand-word>>': ['<Alt-slash>'], | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     unix_keydefs = { | 
					
						
							| 
									
										
										
										
											2001-07-12 22:13:51 +00:00
										 |  |  |         '<<expand-word>>': ['<Meta-slash>', '<Alt-slash>'], | 
					
						
							| 
									
										
										
										
											2000-08-15 01:13:23 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     menudefs = [ | 
					
						
							|  |  |  |         ('edit', [ | 
					
						
							|  |  |  |             ('E_xpand word', '<<expand-word>>'), | 
					
						
							|  |  |  |          ]), | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     wordchars = string.letters + string.digits + "_" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, editwin): | 
					
						
							|  |  |  |         self.text = editwin.text | 
					
						
							|  |  |  |         self.state = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def expand_word_event(self, event): | 
					
						
							|  |  |  |         curinsert = self.text.index("insert") | 
					
						
							|  |  |  |         curline = self.text.get("insert linestart", "insert lineend") | 
					
						
							|  |  |  |         if not self.state: | 
					
						
							|  |  |  |             words = self.getwords() | 
					
						
							|  |  |  |             index = 0 | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             words, index, insert, line = self.state | 
					
						
							|  |  |  |             if insert != curinsert or line != curline: | 
					
						
							|  |  |  |                 words = self.getwords() | 
					
						
							|  |  |  |                 index = 0 | 
					
						
							|  |  |  |         if not words: | 
					
						
							|  |  |  |             self.text.bell() | 
					
						
							|  |  |  |             return "break" | 
					
						
							|  |  |  |         word = self.getprevword() | 
					
						
							|  |  |  |         self.text.delete("insert - %d chars" % len(word), "insert") | 
					
						
							|  |  |  |         newword = words[index] | 
					
						
							|  |  |  |         index = (index + 1) % len(words) | 
					
						
							|  |  |  |         if index == 0: | 
					
						
							|  |  |  |             self.text.bell()            # Warn we cycled around | 
					
						
							|  |  |  |         self.text.insert("insert", newword) | 
					
						
							|  |  |  |         curinsert = self.text.index("insert") | 
					
						
							|  |  |  |         curline = self.text.get("insert linestart", "insert lineend") | 
					
						
							|  |  |  |         self.state = words, index, curinsert, curline | 
					
						
							|  |  |  |         return "break" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def getwords(self): | 
					
						
							|  |  |  |         word = self.getprevword() | 
					
						
							|  |  |  |         if not word: | 
					
						
							|  |  |  |             return [] | 
					
						
							|  |  |  |         before = self.text.get("1.0", "insert wordstart") | 
					
						
							|  |  |  |         wbefore = re.findall(r"\b" + word + r"\w+\b", before) | 
					
						
							|  |  |  |         del before | 
					
						
							|  |  |  |         after = self.text.get("insert wordend", "end") | 
					
						
							|  |  |  |         wafter = re.findall(r"\b" + word + r"\w+\b", after) | 
					
						
							|  |  |  |         del after | 
					
						
							|  |  |  |         if not wbefore and not wafter: | 
					
						
							|  |  |  |             return [] | 
					
						
							|  |  |  |         words = [] | 
					
						
							|  |  |  |         dict = {} | 
					
						
							|  |  |  |         # search backwards through words before | 
					
						
							|  |  |  |         wbefore.reverse() | 
					
						
							|  |  |  |         for w in wbefore: | 
					
						
							|  |  |  |             if dict.get(w): | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             words.append(w) | 
					
						
							|  |  |  |             dict[w] = w | 
					
						
							|  |  |  |         # search onwards through words after | 
					
						
							|  |  |  |         for w in wafter: | 
					
						
							|  |  |  |             if dict.get(w): | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             words.append(w) | 
					
						
							|  |  |  |             dict[w] = w | 
					
						
							|  |  |  |         words.append(word) | 
					
						
							|  |  |  |         return words | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def getprevword(self): | 
					
						
							|  |  |  |         line = self.text.get("insert linestart", "insert") | 
					
						
							|  |  |  |         i = len(line) | 
					
						
							|  |  |  |         while i > 0 and line[i-1] in self.wordchars: | 
					
						
							|  |  |  |             i = i-1 | 
					
						
							|  |  |  |         return line[i:] |