comparison CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/lib/python3.8/idlelib/autoexpand.py @ 68:5028fdace37b

planemo upload commit 2e9511a184a1ca667c7be0c6321a36dc4e3d116d
author jpayne
date Tue, 18 Mar 2025 16:23:26 -0400
parents
children
comparison
equal deleted inserted replaced
67:0e9998148a16 68:5028fdace37b
1 '''Complete the current word before the cursor with words in the editor.
2
3 Each menu selection or shortcut key selection replaces the word with a
4 different word with the same prefix. The search for matches begins
5 before the target and moves toward the top of the editor. It then starts
6 after the cursor and moves down. It then returns to the original word and
7 the cycle starts again.
8
9 Changing the current text line or leaving the cursor in a different
10 place before requesting the next selection causes AutoExpand to reset
11 its state.
12
13 There is only one instance of Autoexpand.
14 '''
15 import re
16 import string
17
18
19 class AutoExpand:
20 wordchars = string.ascii_letters + string.digits + "_"
21
22 def __init__(self, editwin):
23 self.text = editwin.text
24 self.bell = self.text.bell
25 self.state = None
26
27 def expand_word_event(self, event):
28 "Replace the current word with the next expansion."
29 curinsert = self.text.index("insert")
30 curline = self.text.get("insert linestart", "insert lineend")
31 if not self.state:
32 words = self.getwords()
33 index = 0
34 else:
35 words, index, insert, line = self.state
36 if insert != curinsert or line != curline:
37 words = self.getwords()
38 index = 0
39 if not words:
40 self.bell()
41 return "break"
42 word = self.getprevword()
43 self.text.delete("insert - %d chars" % len(word), "insert")
44 newword = words[index]
45 index = (index + 1) % len(words)
46 if index == 0:
47 self.bell() # Warn we cycled around
48 self.text.insert("insert", newword)
49 curinsert = self.text.index("insert")
50 curline = self.text.get("insert linestart", "insert lineend")
51 self.state = words, index, curinsert, curline
52 return "break"
53
54 def getwords(self):
55 "Return a list of words that match the prefix before the cursor."
56 word = self.getprevword()
57 if not word:
58 return []
59 before = self.text.get("1.0", "insert wordstart")
60 wbefore = re.findall(r"\b" + word + r"\w+\b", before)
61 del before
62 after = self.text.get("insert wordend", "end")
63 wafter = re.findall(r"\b" + word + r"\w+\b", after)
64 del after
65 if not wbefore and not wafter:
66 return []
67 words = []
68 dict = {}
69 # search backwards through words before
70 wbefore.reverse()
71 for w in wbefore:
72 if dict.get(w):
73 continue
74 words.append(w)
75 dict[w] = w
76 # search onwards through words after
77 for w in wafter:
78 if dict.get(w):
79 continue
80 words.append(w)
81 dict[w] = w
82 words.append(word)
83 return words
84
85 def getprevword(self):
86 "Return the word prefix before the cursor."
87 line = self.text.get("insert linestart", "insert")
88 i = len(line)
89 while i > 0 and line[i-1] in self.wordchars:
90 i = i-1
91 return line[i:]
92
93
94 if __name__ == '__main__':
95 from unittest import main
96 main('idlelib.idle_test.test_autoexpand', verbosity=2)