mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 03:44:55 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			91 lines
		
	
	
	
		
			2.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			91 lines
		
	
	
	
		
			2.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import string
 | 
						|
import re
 | 
						|
 | 
						|
###$ event <<expand-word>>
 | 
						|
###$ win <Alt-slash>
 | 
						|
###$ unix <Alt-slash>
 | 
						|
 | 
						|
class AutoExpand:
 | 
						|
 | 
						|
    keydefs = {
 | 
						|
        '<<expand-word>>': ['<Alt-slash>'],
 | 
						|
    }
 | 
						|
 | 
						|
    unix_keydefs = {
 | 
						|
        '<<expand-word>>': ['<Meta-slash>', '<Alt-slash>'],
 | 
						|
    }
 | 
						|
 | 
						|
    menudefs = [
 | 
						|
        ('edit', [
 | 
						|
            ('E_xpand word', '<<expand-word>>'),
 | 
						|
         ]),
 | 
						|
    ]
 | 
						|
 | 
						|
    wordchars = string.ascii_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:]
 |