| 
									
										
										
										
											1992-12-14 14:10:53 +00:00
										 |  |  | #! /usr/local/bin/python | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | # A STDWIN-based front end for the Python interpreter. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # This is useful if you want to avoid console I/O and instead | 
					
						
							|  |  |  | # use text windows to issue commands to the interpreter. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # It supports multiple interpreter windows, each with its own context. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # BUGS AND CAVEATS: | 
					
						
							|  |  |  | # | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | # This was written long ago as a demonstration, and slightly hacked to | 
					
						
							|  |  |  | # keep it up-to-date, but never as an industry-strength alternative | 
					
						
							|  |  |  | # interface to Python.  It should be rewritten using more classes, and | 
					
						
							|  |  |  | # merged with something like wdb. | 
					
						
							| 
									
										
										
										
											1992-12-14 14:10:53 +00:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | # Although this supports multiple windows, the whole application | 
					
						
							|  |  |  | # is deaf and dumb when a command is running in one window. | 
					
						
							|  |  |  | # | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | # Interrupt is (ab)used to signal EOF on input requests. | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | # | 
					
						
							|  |  |  | # On UNIX (using X11), interrupts typed in the window will not be | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | # seen until the next input or output operation.  When you are stuck | 
					
						
							|  |  |  | # in an infinite loop, try typing ^C in the shell window where you | 
					
						
							|  |  |  | # started this interpreter.  (On the Mac, interrupts work normally.) | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | import stdwin | 
					
						
							|  |  |  | from stdwinevents import * | 
					
						
							|  |  |  | import rand | 
					
						
							|  |  |  | import mainloop | 
					
						
							| 
									
										
										
										
											1992-03-30 11:01:26 +00:00
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Stack of windows waiting for [raw_]input(). | 
					
						
							|  |  |  | # Element [0] is the top. | 
					
						
							|  |  |  | # If there are multiple windows waiting for input, only the | 
					
						
							|  |  |  | # one on top of the stack can accept input, because the way | 
					
						
							|  |  |  | # raw_input() is implemented (using recursive mainloop() calls). | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | inputwindows = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | # Exception raised when input is available | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | # | 
					
						
							|  |  |  | InputAvailable = 'input available for raw_input (not an error)' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | # Main program -- create the window and call the mainloop | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | # | 
					
						
							|  |  |  | def main(): | 
					
						
							|  |  |  | 	# Hack so 'import python' won't load another copy | 
					
						
							|  |  |  | 	# of this if we were loaded though 'python python.py'. | 
					
						
							|  |  |  | 	# (Should really look at sys.argv[0]...) | 
					
						
							|  |  |  | 	if 'inputwindows' in dir(sys.modules['__main__']) and \ | 
					
						
							|  |  |  | 			sys.modules['__main__'].inputwindows is inputwindows: | 
					
						
							|  |  |  | 		sys.modules['python'] = sys.modules['__main__'] | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	win = makewindow() | 
					
						
							|  |  |  | 	mainloop.mainloop() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | # Create a new window | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | # | 
					
						
							|  |  |  | def makewindow(): | 
					
						
							|  |  |  | 	# stdwin.setdefscrollbars(0, 1) # Not in Python 0.9.1 | 
					
						
							|  |  |  | 	# stdwin.setfont('monaco') # Not on UNIX! and not Python 0.9.1 | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 	# width, height = stdwin.textwidth('in')*40, stdwin.lineheight()*24 | 
					
						
							|  |  |  | 	# stdwin.setdefwinsize(width, height) | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 	win = stdwin.open('Python interpreter ready') | 
					
						
							|  |  |  | 	win.editor = win.textcreate((0,0), win.getwinsize()) | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 	win.globals = {}		# Dictionary for user's globals | 
					
						
							|  |  |  | 	win.command = ''		# Partially read command | 
					
						
							|  |  |  | 	win.busy = 0			# Ready to accept a command | 
					
						
							|  |  |  | 	win.auto = 1			# [CR] executes command | 
					
						
							|  |  |  | 	win.insertOutput = 1		# Insert output at focus | 
					
						
							|  |  |  | 	win.insertError = 1		# Insert error output at focus | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 	win.setwincursor('ibeam') | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 	win.filename = ''		# Empty if no file for this window | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 	makefilemenu(win) | 
					
						
							|  |  |  | 	makeeditmenu(win) | 
					
						
							|  |  |  | 	win.dispatch = pdispatch	# Event dispatch function | 
					
						
							|  |  |  | 	mainloop.register(win) | 
					
						
							|  |  |  | 	return win | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Make a 'File' menu | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | def makefilemenu(win): | 
					
						
							|  |  |  | 	win.filemenu = mp = win.menucreate('File') | 
					
						
							|  |  |  | 	mp.callback = [] | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 	additem(mp, 'New', 'N', do_new) | 
					
						
							|  |  |  | 	additem(mp, 'Open...', 'O', do_open) | 
					
						
							|  |  |  | 	additem(mp, '', '',  None) | 
					
						
							|  |  |  | 	additem(mp, 'Close', 'W', do_close) | 
					
						
							|  |  |  | 	additem(mp, 'Save', 'S', do_save) | 
					
						
							|  |  |  | 	additem(mp, 'Save as...', '', do_saveas) | 
					
						
							|  |  |  | 	additem(mp, '', '', None) | 
					
						
							|  |  |  | 	additem(mp, 'Quit', 'Q', do_quit) | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Make an 'Edit' menu | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | def makeeditmenu(win): | 
					
						
							|  |  |  | 	win.editmenu = mp = win.menucreate('Edit') | 
					
						
							|  |  |  | 	mp.callback = [] | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 	additem(mp, 'Cut', 'X', do_cut) | 
					
						
							|  |  |  | 	additem(mp, 'Copy', 'C', do_copy) | 
					
						
							|  |  |  | 	additem(mp, 'Paste', 'V', do_paste) | 
					
						
							|  |  |  | 	additem(mp, 'Clear', '',  do_clear) | 
					
						
							|  |  |  | 	additem(mp, '', '', None) | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 	win.iauto = len(mp.callback) | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 	additem(mp, 'Autoexecute', '', do_auto) | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 	mp.check(win.iauto, win.auto) | 
					
						
							|  |  |  | 	win.insertOutputNum = len(mp.callback) | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 	additem(mp, 'Insert Output', '', do_insertOutputOption) | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 	win.insertErrorNum = len(mp.callback) | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 	additem(mp, 'Insert Error', '', do_insertErrorOption) | 
					
						
							|  |  |  | 	additem(mp, 'Exec', '\r', do_exec) | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Helper to add a menu item and callback function | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | def additem(mp, text, shortcut, handler): | 
					
						
							|  |  |  | 	if shortcut: | 
					
						
							|  |  |  | 		mp.additem(text, shortcut) | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		mp.additem(text) | 
					
						
							|  |  |  | 	mp.callback.append(handler) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Dispatch a single event to the interpreter. | 
					
						
							|  |  |  | # Resize events cause a resize of the editor. | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | # Some events are treated specially. | 
					
						
							|  |  |  | # Most other events are passed directly to the editor. | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | # | 
					
						
							|  |  |  | def pdispatch(event): | 
					
						
							|  |  |  | 	type, win, detail = event | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 	if not win: | 
					
						
							|  |  |  | 		win = stdwin.getactive() | 
					
						
							|  |  |  | 		if not win: return | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 	if type == WE_CLOSE: | 
					
						
							|  |  |  | 		do_close(win) | 
					
						
							| 
									
										
										
										
											1992-12-14 14:10:53 +00:00
										 |  |  | 		return | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 	elif type == WE_SIZE: | 
					
						
							|  |  |  | 		win.editor.move((0, 0), win.getwinsize()) | 
					
						
							|  |  |  | 	elif type == WE_COMMAND and detail == WC_RETURN: | 
					
						
							|  |  |  | 		if win.auto: | 
					
						
							|  |  |  | 			do_exec(win) | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			void = win.editor.event(event) | 
					
						
							|  |  |  | 	elif type == WE_COMMAND and detail == WC_CANCEL: | 
					
						
							|  |  |  | 		if win.busy: | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 			raise KeyboardInterrupt | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 		else: | 
					
						
							|  |  |  | 			win.command = '' | 
					
						
							|  |  |  | 			settitle(win) | 
					
						
							|  |  |  | 	elif type == WE_MENU: | 
					
						
							|  |  |  | 		mp, item = detail | 
					
						
							|  |  |  | 		mp.callback[item](win) | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		void = win.editor.event(event) | 
					
						
							| 
									
										
										
										
											1992-12-14 14:10:53 +00:00
										 |  |  | 	if win in mainloop.windows: | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 		# May have been deleted by close... | 
					
						
							|  |  |  | 		win.setdocsize(0, win.editor.getrect()[1][1]) | 
					
						
							|  |  |  | 		if type in (WE_CHAR, WE_COMMAND): | 
					
						
							|  |  |  | 			win.editor.setfocus(win.editor.getfocus()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | # Helper to set the title of the window | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | # | 
					
						
							|  |  |  | def settitle(win): | 
					
						
							|  |  |  | 	if win.filename == '': | 
					
						
							|  |  |  | 		win.settitle('Python interpreter ready') | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		win.settitle(win.filename) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | # Helper to replace the text of the focus | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | # | 
					
						
							|  |  |  | def replace(win, text): | 
					
						
							|  |  |  | 	win.editor.replace(text) | 
					
						
							|  |  |  | 	# Resize the window to display the text | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 	win.setdocsize(0, win.editor.getrect()[1][1]) # update the size before | 
					
						
							|  |  |  | 	win.editor.setfocus(win.editor.getfocus()) # move focus to the change | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # File menu handlers | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | def do_new(win): | 
					
						
							|  |  |  | 	win = makewindow() | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | def do_open(win): | 
					
						
							|  |  |  | 	try: | 
					
						
							|  |  |  | 		filename = stdwin.askfile('Open file', '', 0) | 
					
						
							|  |  |  | 		win = makewindow() | 
					
						
							|  |  |  | 		win.filename = filename | 
					
						
							| 
									
										
										
										
											1992-03-30 11:01:26 +00:00
										 |  |  | 		win.editor.replace(open(filename, 'r').read()) | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 		win.editor.setfocus(0, 0) | 
					
						
							|  |  |  | 		win.settitle(win.filename) | 
					
						
							|  |  |  | 		# | 
					
						
							|  |  |  | 	except KeyboardInterrupt: | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 		pass			# Don't give an error on cancel | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | # | 
					
						
							|  |  |  | def do_save(win): | 
					
						
							|  |  |  | 	try: | 
					
						
							|  |  |  | 		if win.filename == '': | 
					
						
							|  |  |  | 			win.filename = stdwin.askfile('Open file', '', 1) | 
					
						
							|  |  |  | 		f = open(win.filename, 'w') | 
					
						
							|  |  |  | 		f.write(win.editor.gettext()) | 
					
						
							|  |  |  | 		# | 
					
						
							|  |  |  | 	except KeyboardInterrupt: | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 		pass			# Don't give an error on cancel | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | def do_saveas(win): | 
					
						
							|  |  |  | 	currentFilename = win.filename | 
					
						
							|  |  |  | 	win.filename = '' | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 	do_save(win)		# Use do_save with empty filename | 
					
						
							|  |  |  | 	if win.filename == '':	# Restore the name if do_save did not set it | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 		win.filename = currentFilename | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | def do_close(win): | 
					
						
							|  |  |  | 	if win.busy: | 
					
						
							|  |  |  | 		stdwin.message('Can\'t close busy window') | 
					
						
							|  |  |  | 		return		# need to fail if quitting?? | 
					
						
							|  |  |  | 	win.editor = None # Break circular reference | 
					
						
							|  |  |  | 	#del win.editmenu	# What about the filemenu?? | 
					
						
							|  |  |  | 	mainloop.unregister(win) | 
					
						
							| 
									
										
										
										
											1992-12-14 14:10:53 +00:00
										 |  |  | 	win.close() | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | # | 
					
						
							|  |  |  | def do_quit(win): | 
					
						
							|  |  |  | 	# Call win.dispatch instead of do_close because there | 
					
						
							|  |  |  | 	# may be 'alien' windows in the list. | 
					
						
							| 
									
										
										
										
											1992-12-14 14:10:53 +00:00
										 |  |  | 	for win in mainloop.windows[:]: | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 		mainloop.dispatch((WE_CLOSE, win, None)) | 
					
						
							|  |  |  | 		# need to catch failed close | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Edit menu handlers | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | def do_cut(win): | 
					
						
							|  |  |  | 	text = win.editor.getfocustext() | 
					
						
							|  |  |  | 	if not text: | 
					
						
							|  |  |  | 		stdwin.fleep() | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	stdwin.setcutbuffer(0, text) | 
					
						
							|  |  |  | 	replace(win, '') | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | def do_copy(win): | 
					
						
							|  |  |  | 	text = win.editor.getfocustext() | 
					
						
							|  |  |  | 	if not text: | 
					
						
							|  |  |  | 		stdwin.fleep() | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	stdwin.setcutbuffer(0, text) | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | def do_paste(win): | 
					
						
							|  |  |  | 	text = stdwin.getcutbuffer(0) | 
					
						
							|  |  |  | 	if not text: | 
					
						
							|  |  |  | 		stdwin.fleep() | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	replace(win, text) | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | def do_clear(win): | 
					
						
							|  |  |  | 	replace(win, '') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | # These would be better in a preferences dialog: | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | def do_auto(win): | 
					
						
							|  |  |  | 	win.auto = (not win.auto) | 
					
						
							|  |  |  | 	win.editmenu.check(win.iauto, win.auto) | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | def do_insertOutputOption(win): | 
					
						
							|  |  |  | 	win.insertOutput = (not win.insertOutput) | 
					
						
							|  |  |  | 	title = ['Append Output', 'Insert Output'][win.insertOutput] | 
					
						
							|  |  |  | 	win.editmenu.setitem(win.insertOutputNum, title) | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | def do_insertErrorOption(win): | 
					
						
							|  |  |  | 	win.insertError = (not win.insertError) | 
					
						
							|  |  |  | 	title = ['Error Dialog', 'Insert Error'][win.insertError] | 
					
						
							|  |  |  | 	win.editmenu.setitem(win.insertErrorNum, title) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Extract a command from the editor and execute it, or pass input to | 
					
						
							|  |  |  | # an interpreter waiting for it. | 
					
						
							|  |  |  | # Incomplete commands are merely placed in the window's command buffer. | 
					
						
							|  |  |  | # All exceptions occurring during the execution are caught and reported. | 
					
						
							|  |  |  | # (Tracebacks are currently not possible, as the interpreter does not | 
					
						
							|  |  |  | # save the traceback pointer until it reaches its outermost level.) | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | def do_exec(win): | 
					
						
							|  |  |  | 	if win.busy: | 
					
						
							|  |  |  | 		if win not in inputwindows: | 
					
						
							|  |  |  | 			stdwin.message('Can\'t run recursive commands') | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		if win <> inputwindows[0]: | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 			stdwin.message('Please complete recursive input first') | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 			return | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	# Set text to the string to execute. | 
					
						
							|  |  |  | 	a, b = win.editor.getfocus() | 
					
						
							|  |  |  | 	alltext = win.editor.gettext() | 
					
						
							|  |  |  | 	n = len(alltext) | 
					
						
							|  |  |  | 	if a == b: | 
					
						
							|  |  |  | 		# There is no selected text, just an insert point; | 
					
						
							|  |  |  | 		# so execute the current line. | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 		while 0 < a and alltext[a-1] <> '\n': # Find beginning of line | 
					
						
							|  |  |  | 			a = a-1 | 
					
						
							|  |  |  | 		while b < n and alltext[b] <> '\n': # Find end of line after b | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 			b = b+1 | 
					
						
							|  |  |  | 		text = alltext[a:b] + '\n' | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		# Execute exactly the selected text. | 
					
						
							|  |  |  | 		text = win.editor.getfocustext() | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 		if text[-1:] <> '\n': # Make sure text ends with \n | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 			text = text + '\n' | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 		while b < n and alltext[b] <> '\n': # Find end of line after b | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 			b = b+1 | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	# Set the focus to expect the output, since there is always something. | 
					
						
							|  |  |  | 	# Output will be inserted at end of line after current focus, | 
					
						
							|  |  |  | 	# or appended to the end of the text. | 
					
						
							|  |  |  | 	b = [n, b][win.insertOutput] | 
					
						
							|  |  |  | 	win.editor.setfocus(b, b) | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	# Make sure there is a preceeding newline. | 
					
						
							|  |  |  | 	if alltext[b-1:b] <> '\n': | 
					
						
							|  |  |  | 		win.editor.replace('\n') | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	if win.busy: | 
					
						
							|  |  |  | 		# Send it to raw_input() below | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 		raise InputAvailable, text | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	# Like the real Python interpreter, we want to execute | 
					
						
							|  |  |  | 	# single-line commands immediately, but save multi-line | 
					
						
							|  |  |  | 	# commands until they are terminated by a blank line. | 
					
						
							|  |  |  | 	# Unlike the real Python interpreter, we don't do any syntax | 
					
						
							|  |  |  | 	# checking while saving up parts of a multi-line command. | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	# The current heuristic to determine whether a command is | 
					
						
							|  |  |  | 	# the first line of a multi-line command simply checks whether | 
					
						
							|  |  |  | 	# the command ends in a colon (followed by a newline). | 
					
						
							|  |  |  | 	# This is not very robust (comments and continuations will | 
					
						
							|  |  |  | 	# confuse it), but it is usable, and simple to implement. | 
					
						
							|  |  |  | 	# (It even has the advantage that single-line loops etc. | 
					
						
							|  |  |  | 	# don't need te be terminated by a blank line.) | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	if win.command: | 
					
						
							|  |  |  | 		# Already continuing | 
					
						
							|  |  |  | 		win.command = win.command + text | 
					
						
							|  |  |  | 		if win.command[-2:] <> '\n\n': | 
					
						
							|  |  |  | 			win.settitle('Unfinished command...') | 
					
						
							|  |  |  | 			return # Need more... | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		# New command | 
					
						
							|  |  |  | 		win.command = text | 
					
						
							|  |  |  | 		if text[-2:] == ':\n': | 
					
						
							|  |  |  | 			win.settitle('Unfinished command...') | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 	command = win.command | 
					
						
							|  |  |  | 	win.command = '' | 
					
						
							|  |  |  | 	win.settitle('Executing command...') | 
					
						
							|  |  |  | 	# | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 	# Some hacks: | 
					
						
							|  |  |  | 	# - The standard files are replaced by an IOWindow instance. | 
					
						
							|  |  |  | 	# - A 2nd argument to exec() is used to specify the directory | 
					
						
							|  |  |  | 	#   holding the user's global variables.  (If this wasn't done, | 
					
						
							|  |  |  | 	#   the exec would be executed in the current local environment, | 
					
						
							|  |  |  | 	#   and the user's assignments to globals would be lost...) | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 	# | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 	save_stdin = sys.stdin | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 	save_stdout = sys.stdout | 
					
						
							|  |  |  | 	save_stderr = sys.stderr | 
					
						
							|  |  |  | 	try: | 
					
						
							| 
									
										
										
										
											1993-12-17 14:39:12 +00:00
										 |  |  | 		sys.stdin = sys.stdout = sys.stderr = IOWindow(win) | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 		win.busy = 1 | 
					
						
							|  |  |  | 		try: | 
					
						
							|  |  |  | 			exec(command, win.globals) | 
					
						
							|  |  |  | 		except KeyboardInterrupt: | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 			print '[Interrupt]' | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 		except: | 
					
						
							| 
									
										
										
										
											1995-03-22 12:17:10 +00:00
										 |  |  | 			if type(sys.exc_type) == type(''): | 
					
						
							|  |  |  | 				msg = sys.exc_type | 
					
						
							|  |  |  | 			else: msg = sys.exc_type.__name__ | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 			if sys.exc_value <> None: | 
					
						
							|  |  |  | 				msg = msg + ': ' + `sys.exc_value` | 
					
						
							|  |  |  | 			if win.insertError: | 
					
						
							|  |  |  | 				stdwin.fleep() | 
					
						
							|  |  |  | 				replace(win, msg + '\n') | 
					
						
							|  |  |  | 			else: | 
					
						
							|  |  |  | 				win.settitle('Unhandled exception') | 
					
						
							|  |  |  | 				stdwin.message(msg) | 
					
						
							|  |  |  | 	finally: | 
					
						
							|  |  |  | 		# Restore redirected I/O in *all* cases | 
					
						
							|  |  |  | 		win.busy = 0 | 
					
						
							|  |  |  | 		sys.stderr = save_stderr | 
					
						
							|  |  |  | 		sys.stdout = save_stdout | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 		sys.stdin = save_stdin | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 		settitle(win) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | # Class emulating file I/O from/to a window | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | class IOWindow: | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 	# | 
					
						
							| 
									
										
										
										
											1993-12-17 14:39:12 +00:00
										 |  |  | 	def __init__(self, win): | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 		self.win = win | 
					
						
							|  |  |  | 	# | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 	def readline(self, *unused_args): | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 		n = len(inputwindows) | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 		save_title = self.win.gettitle() | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 		title = n*'(' + 'Requesting input...' + ')'*n | 
					
						
							|  |  |  | 		self.win.settitle(title) | 
					
						
							|  |  |  | 		inputwindows.insert(0, self.win) | 
					
						
							|  |  |  | 		try: | 
					
						
							| 
									
										
										
										
											1992-05-15 15:40:30 +00:00
										 |  |  | 			try: | 
					
						
							|  |  |  | 				mainloop.mainloop() | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 			finally: | 
					
						
							|  |  |  | 				del inputwindows[0] | 
					
						
							|  |  |  | 				self.win.settitle(save_title) | 
					
						
							|  |  |  | 		except InputAvailable, val: # See do_exec above | 
					
						
							|  |  |  | 			return val | 
					
						
							|  |  |  | 		except KeyboardInterrupt: | 
					
						
							|  |  |  | 			raise EOFError # Until we have a "send EOF" key | 
					
						
							|  |  |  | 		# If we didn't catch InputAvailable, something's wrong... | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 		raise EOFError | 
					
						
							|  |  |  | 	# | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | 	def write(self, text): | 
					
						
							|  |  |  | 		mainloop.check() | 
					
						
							|  |  |  | 		replace(self.win, text) | 
					
						
							|  |  |  | 		mainloop.check() | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Currently unused function to test a command's syntax without executing it | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | def testsyntax(s): | 
					
						
							|  |  |  | 	import string | 
					
						
							|  |  |  | 	lines = string.splitfields(s, '\n') | 
					
						
							|  |  |  | 	for i in range(len(lines)): lines[i] = '\t' + lines[i] | 
					
						
							|  |  |  | 	lines.insert(0, 'if 0:') | 
					
						
							|  |  |  | 	lines.append('') | 
					
						
							|  |  |  | 	exec(string.joinfields(lines, '\n')) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-12-22 14:34:43 +00:00
										 |  |  | # Call the main program | 
					
						
							| 
									
										
										
										
											1992-03-30 10:54:51 +00:00
										 |  |  | # | 
					
						
							|  |  |  | main() |