Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / devtools / v9 / lib / python2.4 / idlelib / ColorDelegator.py
CommitLineData
920dae64
AT
1import time
2import re
3import keyword
4import __builtin__
5from Tkinter import *
6from Delegator import Delegator
7from configHandler import idleConf
8
9DEBUG = False
10
11def any(name, list):
12 return "(?P<%s>" % name + "|".join(list) + ")"
13
14def make_pat():
15 kw = r"\b" + any("KEYWORD", keyword.kwlist) + r"\b"
16 builtinlist = [str(name) for name in dir(__builtin__)
17 if not name.startswith('_')]
18 # self.file = file("file") :
19 # 1st 'file' colorized normal, 2nd as builtin, 3rd as comment
20 builtin = r"([^.'\"\\]\b|^)" + any("BUILTIN", builtinlist) + r"\b"
21 comment = any("COMMENT", [r"#[^\n]*"])
22 sqstring = r"(\b[rR])?'[^'\\\n]*(\\.[^'\\\n]*)*'?"
23 dqstring = r'(\b[rR])?"[^"\\\n]*(\\.[^"\\\n]*)*"?'
24 sq3string = r"(\b[rR])?'''[^'\\]*((\\.|'(?!''))[^'\\]*)*(''')?"
25 dq3string = r'(\b[rR])?"""[^"\\]*((\\.|"(?!""))[^"\\]*)*(""")?'
26 string = any("STRING", [sq3string, dq3string, sqstring, dqstring])
27 return kw + "|" + builtin + "|" + comment + "|" + string +\
28 "|" + any("SYNC", [r"\n"])
29
30prog = re.compile(make_pat(), re.S)
31idprog = re.compile(r"\s+(\w+)", re.S)
32asprog = re.compile(r".*?\b(as)\b", re.S)
33
34class ColorDelegator(Delegator):
35
36 def __init__(self):
37 Delegator.__init__(self)
38 self.prog = prog
39 self.idprog = idprog
40 self.asprog = asprog
41 self.LoadTagDefs()
42
43 def setdelegate(self, delegate):
44 if self.delegate is not None:
45 self.unbind("<<toggle-auto-coloring>>")
46 Delegator.setdelegate(self, delegate)
47 if delegate is not None:
48 self.config_colors()
49 self.bind("<<toggle-auto-coloring>>", self.toggle_colorize_event)
50 self.notify_range("1.0", "end")
51
52 def config_colors(self):
53 for tag, cnf in self.tagdefs.items():
54 if cnf:
55 self.tag_configure(tag, **cnf)
56 self.tag_raise('sel')
57
58 def LoadTagDefs(self):
59 theme = idleConf.GetOption('main','Theme','name')
60 self.tagdefs = {
61 "COMMENT": idleConf.GetHighlight(theme, "comment"),
62 "KEYWORD": idleConf.GetHighlight(theme, "keyword"),
63 "BUILTIN": idleConf.GetHighlight(theme, "builtin"),
64 "STRING": idleConf.GetHighlight(theme, "string"),
65 "DEFINITION": idleConf.GetHighlight(theme, "definition"),
66 "SYNC": {'background':None,'foreground':None},
67 "TODO": {'background':None,'foreground':None},
68 "BREAK": idleConf.GetHighlight(theme, "break"),
69 "ERROR": idleConf.GetHighlight(theme, "error"),
70 # The following is used by ReplaceDialog:
71 "hit": idleConf.GetHighlight(theme, "hit"),
72 }
73
74 if DEBUG: print 'tagdefs',self.tagdefs
75
76 def insert(self, index, chars, tags=None):
77 index = self.index(index)
78 self.delegate.insert(index, chars, tags)
79 self.notify_range(index, index + "+%dc" % len(chars))
80
81 def delete(self, index1, index2=None):
82 index1 = self.index(index1)
83 self.delegate.delete(index1, index2)
84 self.notify_range(index1)
85
86 after_id = None
87 allow_colorizing = True
88 colorizing = False
89
90 def notify_range(self, index1, index2=None):
91 self.tag_add("TODO", index1, index2)
92 if self.after_id:
93 if DEBUG: print "colorizing already scheduled"
94 return
95 if self.colorizing:
96 self.stop_colorizing = True
97 if DEBUG: print "stop colorizing"
98 if self.allow_colorizing:
99 if DEBUG: print "schedule colorizing"
100 self.after_id = self.after(1, self.recolorize)
101
102 close_when_done = None # Window to be closed when done colorizing
103
104 def close(self, close_when_done=None):
105 if self.after_id:
106 after_id = self.after_id
107 self.after_id = None
108 if DEBUG: print "cancel scheduled recolorizer"
109 self.after_cancel(after_id)
110 self.allow_colorizing = False
111 self.stop_colorizing = True
112 if close_when_done:
113 if not self.colorizing:
114 close_when_done.destroy()
115 else:
116 self.close_when_done = close_when_done
117
118 def toggle_colorize_event(self, event):
119 if self.after_id:
120 after_id = self.after_id
121 self.after_id = None
122 if DEBUG: print "cancel scheduled recolorizer"
123 self.after_cancel(after_id)
124 if self.allow_colorizing and self.colorizing:
125 if DEBUG: print "stop colorizing"
126 self.stop_colorizing = True
127 self.allow_colorizing = not self.allow_colorizing
128 if self.allow_colorizing and not self.colorizing:
129 self.after_id = self.after(1, self.recolorize)
130 if DEBUG:
131 print "auto colorizing turned",\
132 self.allow_colorizing and "on" or "off"
133 return "break"
134
135 def recolorize(self):
136 self.after_id = None
137 if not self.delegate:
138 if DEBUG: print "no delegate"
139 return
140 if not self.allow_colorizing:
141 if DEBUG: print "auto colorizing is off"
142 return
143 if self.colorizing:
144 if DEBUG: print "already colorizing"
145 return
146 try:
147 self.stop_colorizing = False
148 self.colorizing = True
149 if DEBUG: print "colorizing..."
150 t0 = time.clock()
151 self.recolorize_main()
152 t1 = time.clock()
153 if DEBUG: print "%.3f seconds" % (t1-t0)
154 finally:
155 self.colorizing = False
156 if self.allow_colorizing and self.tag_nextrange("TODO", "1.0"):
157 if DEBUG: print "reschedule colorizing"
158 self.after_id = self.after(1, self.recolorize)
159 if self.close_when_done:
160 top = self.close_when_done
161 self.close_when_done = None
162 top.destroy()
163
164 def recolorize_main(self):
165 next = "1.0"
166 while True:
167 item = self.tag_nextrange("TODO", next)
168 if not item:
169 break
170 head, tail = item
171 self.tag_remove("SYNC", head, tail)
172 item = self.tag_prevrange("SYNC", head)
173 if item:
174 head = item[1]
175 else:
176 head = "1.0"
177
178 chars = ""
179 next = head
180 lines_to_get = 1
181 ok = False
182 while not ok:
183 mark = next
184 next = self.index(mark + "+%d lines linestart" %
185 lines_to_get)
186 lines_to_get = min(lines_to_get * 2, 100)
187 ok = "SYNC" in self.tag_names(next + "-1c")
188 line = self.get(mark, next)
189 ##print head, "get", mark, next, "->", repr(line)
190 if not line:
191 return
192 for tag in self.tagdefs.keys():
193 self.tag_remove(tag, mark, next)
194 chars = chars + line
195 m = self.prog.search(chars)
196 while m:
197 for key, value in m.groupdict().items():
198 if value:
199 a, b = m.span(key)
200 self.tag_add(key,
201 head + "+%dc" % a,
202 head + "+%dc" % b)
203 if value in ("def", "class"):
204 m1 = self.idprog.match(chars, b)
205 if m1:
206 a, b = m1.span(1)
207 self.tag_add("DEFINITION",
208 head + "+%dc" % a,
209 head + "+%dc" % b)
210 elif value == "import":
211 # color all the "as" words on same line;
212 # cheap approximation to the truth
213 while True:
214 m1 = self.asprog.match(chars, b)
215 if not m1:
216 break
217 a, b = m1.span(1)
218 self.tag_add("KEYWORD",
219 head + "+%dc" % a,
220 head + "+%dc" % b)
221 m = self.prog.search(chars, m.end())
222 if "SYNC" in self.tag_names(next + "-1c"):
223 head = next
224 chars = ""
225 else:
226 ok = False
227 if not ok:
228 # We're in an inconsistent state, and the call to
229 # update may tell us to stop. It may also change
230 # the correct value for "next" (since this is a
231 # line.col string, not a true mark). So leave a
232 # crumb telling the next invocation to resume here
233 # in case update tells us to leave.
234 self.tag_add("TODO", next)
235 self.update()
236 if self.stop_colorizing:
237 if DEBUG: print "colorizing stopped"
238 return
239
240
241def main():
242 from Percolator import Percolator
243 root = Tk()
244 root.wm_protocol("WM_DELETE_WINDOW", root.quit)
245 text = Text(background="white")
246 text.pack(expand=1, fill="both")
247 text.focus_set()
248 p = Percolator(text)
249 d = ColorDelegator()
250 p.insertfilter(d)
251 root.mainloop()
252
253if __name__ == "__main__":
254 main()