blob: 887da1e244adec369558eb6b9801c6073e5a64f0 [file] [log] [blame]
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +00001#! /usr/bin/env python
2
3import os
4import sys
5import string
Guido van Rossum80d132d1998-10-16 16:12:11 +00006import getopt
Guido van Rossum5af7a721998-10-12 23:59:27 +00007import re
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +00008
9import linecache
10from code import InteractiveInterpreter
11
12from Tkinter import *
13import tkMessageBox
14
15from EditorWindow import fixwordbreaks
16from FileList import FileList, MultiEditorWindow, MultiIOBinding
17from ColorDelegator import ColorDelegator
18
Guido van Rossumcc0ade81998-10-19 02:26:16 +000019# We need to patch linecache.checkcache, because we don't want it
20# to throw away our <pyshell#...> entries.
21# Rather than repeating its code here, we save those entries,
22# then call the original function, and then restore the saved entries.
23def linecache_checkcache(orig_checkcache=linecache.checkcache):
24 cache = linecache.cache
25 save = {}
26 for filename in cache.keys():
27 if filename[:1] + filename[-1:] == '<>':
28 save[filename] = cache[filename]
29 orig_checkcache()
30 cache.update(save)
31linecache.checkcache = linecache_checkcache
32
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000033
Guido van Rossum5af7a721998-10-12 23:59:27 +000034class PyShellEditorWindow(MultiEditorWindow):
Guido van Rossumcc0ade81998-10-19 02:26:16 +000035
36 def __init__(self, *args):
37 apply(MultiEditorWindow.__init__, (self,) + args)
38 self.text.bind("<3>", self.right_menu_event)
Guido van Rossum5af7a721998-10-12 23:59:27 +000039
40 def fixedwindowsmenu(self, wmenu):
41 wmenu.add_command(label="Python Shell", command=self.flist.open_shell)
Guido van Rossum35f75421998-10-13 23:51:13 +000042 wmenu.add_separator()
Guido van Rossumcc0ade81998-10-19 02:26:16 +000043
44 menu = None
45
46 def right_menu_event(self, event):
47 self.text.mark_set("insert", "@%d,%d" % (event.x, event.y))
48 if not self.menu:
49 self.make_menu()
50 menu = self.menu
51 iswin = sys.platform[:3] == 'win'
52 if iswin:
53 self.text.config(cursor="arrow")
54 menu.tk_popup(event.x_root, event.y_root)
55 if iswin:
56 self.text.config(cursor="ibeam")
57
58 def make_menu(self):
59 self.menu = menu = Menu(self.text, tearoff=0)
60 menu.add_command(label="Set breakpoint here",
61 command=self.set_breakpoint_here)
62
63 def set_breakpoint_here(self):
64 if not self.flist.pyshell or not self.flist.pyshell.interp.debugger:
65 self.text.bell()
66 return
67 self.flist.pyshell.interp.debugger.set_breakpoint_here(self)
Guido van Rossum5af7a721998-10-12 23:59:27 +000068
69
70class PyShellFileList(FileList):
71
72 EditorWindow = PyShellEditorWindow
73
74 pyshell = None
75
76 def open_shell(self):
77 if self.pyshell:
78 self.pyshell.wakeup()
79 else:
80 self.pyshell = PyShell(self)
81 self.pyshell.begin()
82 return self.pyshell
83
84
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +000085class ModifiedIOBinding(MultiIOBinding):
86
87 def defaultfilename(self, mode="open"):
88 if self.filename:
89 return MultiIOBinding.defaultfilename(self, mode)
90 else:
91 try:
92 pwd = os.getcwd()
93 except os.error:
94 pwd = ""
95 return pwd, ""
96
97 def open(self, event):
98 # Override base class method -- don't allow reusing this window
99 filename = self.askopenfile()
100 if filename:
101 self.flist.open(filename)
102 return "break"
103
104 def maybesave(self):
105 # Override base class method -- don't ask any questions
106 if self.text.get_saved():
107 return "yes"
108 else:
109 return "no"
110
111
112class ModifiedColorDelegator(ColorDelegator):
113
114 def recolorize_main(self):
115 self.tag_remove("TODO", "1.0", "iomark")
116 self.tag_add("SYNC", "1.0", "iomark")
117 ColorDelegator.recolorize_main(self)
118
119
120class ModifiedInterpreter(InteractiveInterpreter):
121
122 def __init__(self, tkconsole):
123 self.tkconsole = tkconsole
124 InteractiveInterpreter.__init__(self)
125
126 gid = 0
127
128 def runsource(self, source):
129 # Extend base class to stuff the source in the line cache
Guido van Rossumcc0ade81998-10-19 02:26:16 +0000130 filename = "<pyshell#%d>" % self.gid
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000131 self.gid = self.gid + 1
132 lines = string.split(source, "\n")
133 linecache.cache[filename] = len(source)+1, 0, lines, filename
134 self.more = 0
135 return InteractiveInterpreter.runsource(self, source, filename)
136
137 def showsyntaxerror(self, filename=None):
138 # Extend base class to color the offending position
139 # (instead of printing it and pointing at it with a caret)
140 text = self.tkconsole.text
141 stuff = self.unpackerror()
142 if not stuff:
143 self.tkconsole.resetoutput()
144 InteractiveInterpreter.showsyntaxerror(self, filename)
145 return
146 msg, lineno, offset, line = stuff
147 if lineno == 1:
148 pos = "iomark + %d chars" % (offset-1)
149 else:
150 pos = "iomark linestart + %d lines + %d chars" % (lineno-1,
151 offset-1)
152 text.tag_add("ERROR", pos)
153 text.see(pos)
154 char = text.get(pos)
155 if char in string.letters + string.digits + "_":
156 text.tag_add("ERROR", pos + " wordstart", pos)
157 self.tkconsole.resetoutput()
158 self.write("SyntaxError: %s\n" % str(msg))
159
160 def unpackerror(self):
161 type, value, tb = sys.exc_info()
162 ok = type == SyntaxError
163 if ok:
164 try:
165 msg, (dummy_filename, lineno, offset, line) = value
166 except:
167 ok = 0
168 if ok:
169 return msg, lineno, offset, line
170 else:
171 return None
172
173 def showtraceback(self):
174 # Extend base class method to reset output properly
175 text = self.tkconsole.text
176 self.tkconsole.resetoutput()
Guido van Rossum19563521998-10-13 16:32:05 +0000177 self.checklinecache()
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000178 InteractiveInterpreter.showtraceback(self)
Guido van Rossum19563521998-10-13 16:32:05 +0000179
180 def checklinecache(self):
181 c = linecache.cache
182 for key in c.keys():
183 if key[:1] + key[-1:] != "<>":
184 del c[key]
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000185
Guido van Rossum35f75421998-10-13 23:51:13 +0000186 debugger = None
187
188 def setdebugger(self, debugger):
189 self.debugger = debugger
190
191 def getdebugger(self):
192 return self.debugger
193
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000194 def runcode(self, code):
195 # Override base class method
Guido van Rossum35f75421998-10-13 23:51:13 +0000196 debugger = self.debugger
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000197 try:
198 self.tkconsole.beginexecuting()
199 try:
Guido van Rossum35f75421998-10-13 23:51:13 +0000200 if debugger:
201 debugger.run(code, self.locals)
202 else:
203 exec code in self.locals
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000204 except SystemExit:
205 if tkMessageBox.askyesno(
206 "Exit?",
207 "Do you want to exit altogether?",
208 default="yes",
209 master=self.tkconsole.text):
210 raise
211 else:
212 self.showtraceback()
213 except:
214 self.showtraceback()
215 finally:
216 self.tkconsole.endexecuting()
217
218 def write(self, s):
219 # Override base class write
220 self.tkconsole.console.write(s)
221
222
Guido van Rossum5af7a721998-10-12 23:59:27 +0000223class PyShell(PyShellEditorWindow):
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000224
225 # Override classes
226 ColorDelegator = ModifiedColorDelegator
227 IOBinding = ModifiedIOBinding
228
Guido van Rossum5af7a721998-10-12 23:59:27 +0000229 # Override menu bar specs
230 menu_specs = PyShellEditorWindow.menu_specs[:]
231 menu_specs.insert(len(menu_specs)-1, ("debug", "Debug"))
232
Guido van Rossumcc0ade81998-10-19 02:26:16 +0000233 # New classes
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000234 from History import History
Guido van Rossumcc0ade81998-10-19 02:26:16 +0000235 from PopupMenu import PopupMenu
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000236
237 def __init__(self, flist=None):
238 self.interp = ModifiedInterpreter(self)
239 if flist is None:
240 root = Tk()
241 fixwordbreaks(root)
242 root.withdraw()
Guido van Rossum5af7a721998-10-12 23:59:27 +0000243 flist = PyShellFileList(root)
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000244
Guido van Rossum5af7a721998-10-12 23:59:27 +0000245 PyShellEditorWindow.__init__(self, flist, None, None)
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000246 self.config_colors()
247
248 import __builtin__
249 __builtin__.quit = __builtin__.exit = "To exit, type Ctrl-D."
250
251 self.auto.config(prefertabs=1)
252
253 text = self.text
254 text.bind("<<newline-and-indent>>", self.enter_callback)
255 text.bind("<<plain-newline-and-indent>>", self.linefeed_callback)
256 text.bind("<<interrupt-execution>>", self.cancel_callback)
257 text.bind("<<beginning-of-line>>", self.home_callback)
258 text.bind("<<end-of-file>>", self.eof_callback)
Guido van Rossum5af7a721998-10-12 23:59:27 +0000259 text.bind("<<goto-traceback-line>>", self.goto_traceback_line)
260 text.bind("<<open-stack-viewer>>", self.open_stack_viewer)
Guido van Rossum35f75421998-10-13 23:51:13 +0000261 text.bind("<<toggle-debugger>>", self.toggle_debugger)
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000262
263 sys.stdout = PseudoFile(self, "stdout")
Guido van Rossum3f08d401998-10-13 15:21:41 +0000264 sys.stderr = PseudoFile(self, "stderr")
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000265 sys.stdin = self
266 self.console = PseudoFile(self, "console")
267
268 self.history = self.History(self.text)
Guido van Rossumcc0ade81998-10-19 02:26:16 +0000269 self.popup = self.PopupMenu(self.text, self.flist)
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000270
271 tagdefs = {
272 ##"stdin": {"background": "yellow"},
273 "stdout": {"foreground": "blue"},
274 "stderr": {"foreground": "#007700"},
275 "console": {"foreground": "red"},
276 "ERROR": {"background": "#FF7777"},
277 None: {"foreground": "purple"}, # default
278 }
279
280 def config_colors(self):
281 for tag, cnf in self.tagdefs.items():
282 if cnf:
283 if not tag:
284 apply(self.text.configure, (), cnf)
285 else:
286 apply(self.text.tag_configure, (tag,), cnf)
Guido van Rossumcc0ade81998-10-19 02:26:16 +0000287 self.text.tag_raise("sel")
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000288
289 reading = 0
290 executing = 0
291 canceled = 0
292 endoffile = 0
Guido van Rossum35f75421998-10-13 23:51:13 +0000293
294 def toggle_debugger(self, event=None):
295 if self.executing:
296 tkMessageBox.showerror("Don't debug now",
297 "You can only toggle the debugger when idle",
298 master=self.text)
299 return "break"
300 db = self.interp.getdebugger()
301 if db:
Guido van Rossum35e55da1998-10-14 03:43:05 +0000302 self.close_debugger()
303 else:
304 self.open_debugger()
305
306 def close_debugger(self):
307 db = self.interp.getdebugger()
308 if db:
309 self.interp.setdebugger(None)
Guido van Rossum35f75421998-10-13 23:51:13 +0000310 db.close()
311 self.resetoutput()
312 self.console.write("[DEBUG OFF]\n")
313 sys.ps1 = ">>> "
314 self.showprompt()
Guido van Rossum35e55da1998-10-14 03:43:05 +0000315
316 def open_debugger(self):
317 import Debugger
318 self.interp.setdebugger(Debugger.Debugger(self))
Guido van Rossumadfe7731998-10-16 21:09:35 +0000319 sys.ps1 = "[DEBUG ON]\n>>> "
Guido van Rossum35e55da1998-10-14 03:43:05 +0000320 self.showprompt()
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000321
322 def beginexecuting(self):
323 # Helper for ModifiedInterpreter
324 self.resetoutput()
325 self.executing = 1
326 self._cancel_check = self.cancel_check
327 ##sys.settrace(self._cancel_check)
328
329 def endexecuting(self):
330 # Helper for ModifiedInterpreter
331 sys.settrace(None)
332 self.executing = 0
333 self.canceled = 0
334
335 def close(self):
336 # Extend base class method
337 if self.executing:
338 # XXX Need to ask a question here
339 if not tkMessageBox.askokcancel(
340 "Cancel?",
341 "The program is still running; do you want to cancel it?",
342 default="ok",
343 master=self.text):
344 return "cancel"
345 self.canceled = 1
346 if self.reading:
347 self.top.quit()
348 return "cancel"
Guido van Rossum5af7a721998-10-12 23:59:27 +0000349 reply = PyShellEditorWindow.close(self)
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000350 if reply != "cancel":
Guido van Rossum5af7a721998-10-12 23:59:27 +0000351 self.flist.pyshell = None
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000352 # Restore std streams
353 sys.stdout = sys.__stdout__
354 sys.stderr = sys.__stderr__
355 sys.stdin = sys.__stdin__
356 # Break cycles
357 self.interp = None
358 self.console = None
359 return reply
360
361 def ispythonsource(self, filename):
362 # Override this so EditorWindow never removes the colorizer
363 return 1
364
365 def saved_change_hook(self):
366 # Override this to get the title right
367 title = "Python Shell"
368 if self.io.filename:
369 title = title + ": " + self.io.filename
370 if not self.undo.get_saved():
371 title = title + " *"
372 self.top.wm_title(title)
373
Guido van Rossum5af7a721998-10-12 23:59:27 +0000374 def begin(self):
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000375 self.resetoutput()
376 self.write("Python %s on %s\n%s\n" %
377 (sys.version, sys.platform, sys.copyright))
378 try:
379 sys.ps1
380 except AttributeError:
381 sys.ps1 = ">>> "
382 self.showprompt()
383 import Tkinter
384 Tkinter._default_root = None
Guido van Rossum5af7a721998-10-12 23:59:27 +0000385
386 def interact(self):
387 self.begin()
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000388 self.top.mainloop()
389
390 def readline(self):
391 save = self.reading
392 try:
393 self.reading = 1
394 self.top.mainloop()
395 finally:
396 self.reading = save
397 line = self.text.get("iomark", "end-1c")
398 self.resetoutput()
399 if self.canceled:
400 self.canceled = 0
401 raise KeyboardInterrupt
402 if self.endoffile:
403 self.endoffile = 0
404 return ""
405 return line
406
407 def cancel_callback(self, event):
408 try:
409 if self.text.compare("sel.first", "!=", "sel.last"):
410 return # Active selection -- always use default binding
411 except:
412 pass
413 if not (self.executing or self.reading):
414 self.resetoutput()
415 self.write("KeyboardInterrupt\n")
416 self.showprompt()
417 return "break"
418 self.endoffile = 0
419 self.canceled = 1
420 if self.reading:
421 self.top.quit()
422 return "break"
423
424 def eof_callback(self, event):
425 if self.executing and not self.reading:
426 return # Let the default binding (delete next char) take over
427 if not (self.text.compare("iomark", "==", "insert") and
428 self.text.compare("insert", "==", "end-1c")):
429 return # Let the default binding (delete next char) take over
430 if not self.executing:
431## if not tkMessageBox.askokcancel(
432## "Exit?",
433## "Are you sure you want to exit?",
434## default="ok", master=self.text):
435## return "break"
436 self.resetoutput()
437 self.close()
438 else:
439 self.canceled = 0
440 self.endoffile = 1
441 self.top.quit()
442 return "break"
443
444 def home_callback(self, event):
445 if event.state != 0 and event.keysym == "Home":
446 return # <Modifier-Home>; fall back to class binding
447 if self.text.compare("iomark", "<=", "insert") and \
448 self.text.compare("insert linestart", "<=", "iomark"):
449 self.text.mark_set("insert", "iomark")
450 self.text.tag_remove("sel", "1.0", "end")
451 self.text.see("insert")
452 return "break"
453
454 def linefeed_callback(self, event):
455 # Insert a linefeed without entering anything (still autoindented)
456 if self.reading:
457 self.text.insert("insert", "\n")
458 self.text.see("insert")
459 else:
460 self.auto.autoindent(event)
461 return "break"
462
463 def enter_callback(self, event):
464 if self.executing and not self.reading:
465 return # Let the default binding (insert '\n') take over
466 # If some text is selected, recall the selection
Guido van Rossum4650df91998-10-13 14:41:27 +0000467 # (but only if this before the I/O mark)
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000468 try:
469 sel = self.text.get("sel.first", "sel.last")
470 if sel:
Guido van Rossum4650df91998-10-13 14:41:27 +0000471 if self.text.compare("self.last", "<=", "iomark"):
472 self.recall(sel)
473 return "break"
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000474 except:
475 pass
476 # If we're strictly before the line containing iomark, recall
477 # the current line, less a leading prompt, less leading or
478 # trailing whitespace
479 if self.text.compare("insert", "<", "iomark linestart"):
Guido van Rossum4650df91998-10-13 14:41:27 +0000480 # Check if there's a relevant stdin range -- if so, use it
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000481 prev = self.text.tag_prevrange("stdin", "insert")
482 if prev and self.text.compare("insert", "<", prev[1]):
483 self.recall(self.text.get(prev[0], prev[1]))
484 return "break"
485 next = self.text.tag_nextrange("stdin", "insert")
486 if next and self.text.compare("insert lineend", ">=", next[0]):
487 self.recall(self.text.get(next[0], next[1]))
488 return "break"
489 # No stdin mark -- just get the current line
490 self.recall(self.text.get("insert linestart", "insert lineend"))
491 return "break"
Guido van Rossum4650df91998-10-13 14:41:27 +0000492 # If we're in the current input before its last line,
493 # insert a newline right at the insert point
494 if self.text.compare("insert", "<", "end-1c linestart"):
495 self.auto.autoindent(event)
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000496 return "break"
Guido van Rossum4650df91998-10-13 14:41:27 +0000497 # We're in the last line; append a newline and submit it
498 self.text.mark_set("insert", "end-1c")
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000499 if self.reading:
500 self.text.insert("insert", "\n")
501 self.text.see("insert")
502 else:
503 self.auto.autoindent(event)
504 self.text.tag_add("stdin", "iomark", "end-1c")
505 self.text.update_idletasks()
506 if self.reading:
507 self.top.quit() # Break out of recursive mainloop() in raw_input()
508 else:
509 self.runit()
510 return "break"
511
512 def recall(self, s):
513 if self.history:
514 self.history.recall(s)
515
516 def runit(self):
517 line = self.text.get("iomark", "end-1c")
518 # Strip off last newline and surrounding whitespace.
519 # (To allow you to hit return twice to end a statement.)
520 i = len(line)
521 while i > 0 and line[i-1] in " \t":
522 i = i-1
523 if i > 0 and line[i-1] == "\n":
524 i = i-1
525 while i > 0 and line[i-1] in " \t":
526 i = i-1
527 line = line[:i]
528 more = self.interp.runsource(line)
529 if not more:
530 self.showprompt()
531
532 def cancel_check(self, frame, what, args,
533 dooneevent=tkinter.dooneevent,
534 dontwait=tkinter.DONT_WAIT):
535 # Hack -- use the debugger hooks to be able to handle events
536 # and interrupt execution at any time.
537 # This slows execution down quite a bit, so you may want to
538 # disable this (by not calling settrace() in runcode() above)
539 # for full-bore (uninterruptable) speed.
540 # XXX This should become a user option.
541 if self.canceled:
542 return
543 dooneevent(dontwait)
544 if self.canceled:
545 self.canceled = 0
546 raise KeyboardInterrupt
547 return self._cancel_check
Guido van Rossum5af7a721998-10-12 23:59:27 +0000548
549 file_line_pats = [
550 r'File "([^"]*)", line (\d+)',
551 r'([^\s]+)\((\d+)\)',
552 r'([^\s]+):\s*(\d+):',
553 ]
554
555 file_line_progs = None
556
557 def goto_traceback_line(self, event=None):
558 if self.file_line_progs is None:
559 l = []
560 for pat in self.file_line_pats:
561 l.append(re.compile(pat))
562 self.file_line_progs = l
563 # x, y = self.event.x, self.event.y
564 # self.text.mark_set("insert", "@%d,%d" % (x, y))
565 line = self.text.get("insert linestart", "insert lineend")
566 for prog in self.file_line_progs:
567 m = prog.search(line)
568 if m:
569 break
570 else:
571 tkMessageBox.showerror("No traceback line",
572 "The line you point at doesn't look "
573 "like an error message.",
574 master=self.text)
575 return
576 filename, lineno = m.group(1, 2)
577 try:
578 f = open(filename, "r")
579 f.close()
580 except IOError, msg:
581 self.text.bell()
582 return
583 edit = self.flist.open(filename)
584 try:
585 lineno = int(lineno)
586 except ValueError, msg:
587 self.text.bell()
588 return
589 edit.gotoline(lineno)
590
591 def open_stack_viewer(self, event=None):
592 try:
593 sys.last_traceback
594 except:
595 tkMessageBox.showerror("No stack trace",
596 "There is no stack trace yet.\n"
597 "(sys.last_traceback is not defined)",
598 master=self.text)
599 return
Guido van Rossum80d132d1998-10-16 16:12:11 +0000600 from StackViewer import StackBrowser
601 sv = StackBrowser(self.root, self.flist)
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000602
603 def showprompt(self):
604 self.resetoutput()
605 try:
606 s = str(sys.ps1)
607 except:
608 s = ""
609 self.console.write(s)
610 self.text.mark_set("insert", "end-1c")
611
612 def resetoutput(self):
613 source = self.text.get("iomark", "end-1c")
614 if self.history:
615 self.history.history_store(source)
616 if self.text.get("end-2c") != "\n":
617 self.text.insert("end-1c", "\n")
618 self.text.mark_set("iomark", "end-1c")
619 sys.stdout.softspace = 0
620
621 def write(self, s):
622 # Overrides base class write
623 self.console.write(s)
624
625class PseudoFile:
626
627 def __init__(self, interp, tags):
628 self.interp = interp
629 self.text = interp.text
630 self.tags = tags
631
632 def write(self, s):
633 self.text.mark_gravity("iomark", "right")
634 self.text.insert("iomark", str(s), self.tags)
635 self.text.mark_gravity("iomark", "left")
636 self.text.see("iomark")
637 self.text.update()
638 if self.interp.canceled:
639 self.interp.canceled = 0
640 raise KeyboardInterrupt
641
642 def writelines(self, l):
643 map(self.write, l)
644
645
646def main():
Guido van Rossum80d132d1998-10-16 16:12:11 +0000647 debug = 0
648 try:
649 opts, args = getopt.getopt(sys.argv[1:], "d")
650 except getopt.error, msg:
651 sys.stderr.write("Error: %s\n" % str(msg))
652 sys.exit(2)
653 for o, a in opts:
654 if o == "-d":
655 debug = 1
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000656 global flist, root
657 root = Tk()
658 fixwordbreaks(root)
659 root.withdraw()
Guido van Rossum5af7a721998-10-12 23:59:27 +0000660 flist = PyShellFileList(root)
Guido van Rossum80d132d1998-10-16 16:12:11 +0000661 if args:
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000662 for filename in sys.argv[1:]:
663 flist.open(filename)
664 t = PyShell(flist)
Guido van Rossum5af7a721998-10-12 23:59:27 +0000665 flist.pyshell = t
666 t.begin()
Guido van Rossum80d132d1998-10-16 16:12:11 +0000667 if debug:
668 t.open_debugger()
Guido van Rossum5af7a721998-10-12 23:59:27 +0000669 root.mainloop()
Guido van Rossum3b4ca0d1998-10-10 18:48:31 +0000670
671if __name__ == "__main__":
672 main()