Home | History | Annotate | Download | only in idlelib
      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