summaryrefslogtreecommitdiffstats
path: root/Demo/stdwin/python.py
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2000-05-11 14:43:52 (GMT)
committerGuido van Rossum <guido@python.org>2000-05-11 14:43:52 (GMT)
commitdab6cb8f6dacc107e9482976ca2f8e0313f05131 (patch)
tree88eef631a9c853ed763bb1be126ad3a11d6185db /Demo/stdwin/python.py
parentede8c6eea1da425960b27ed735a41bc23a72a89a (diff)
downloadcpython-dab6cb8f6dacc107e9482976ca2f8e0313f05131.zip
cpython-dab6cb8f6dacc107e9482976ca2f8e0313f05131.tar.gz
cpython-dab6cb8f6dacc107e9482976ca2f8e0313f05131.tar.bz2
removing more stdwin users
Diffstat (limited to 'Demo/stdwin/python.py')
-rwxr-xr-xDemo/stdwin/python.py449
1 files changed, 0 insertions, 449 deletions
diff --git a/Demo/stdwin/python.py b/Demo/stdwin/python.py
deleted file mode 100755
index 8a3dfce..0000000
--- a/Demo/stdwin/python.py
+++ /dev/null
@@ -1,449 +0,0 @@
-#! /usr/bin/env python
-
-# 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:
-#
-# 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.
-#
-# Although this supports multiple windows, the whole application
-# is deaf and dumb when a command is running in one window.
-#
-# Interrupt is (ab)used to signal EOF on input requests.
-#
-# On UNIX (using X11), interrupts typed in the window will not be
-# 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.)
-
-
-import sys
-import stdwin
-from stdwinevents import *
-import rand
-import mainloop
-import os
-
-
-# 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 = []
-
-
-# Exception raised when input is available
-#
-InputAvailable = 'input available for raw_input (not an error)'
-
-
-# Main program -- create the window and call the mainloop
-#
-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()
-
-
-# Create a new window
-#
-def makewindow():
- # stdwin.setdefscrollbars(0, 1) # Not in Python 0.9.1
- # stdwin.setfont('monaco') # Not on UNIX! and not Python 0.9.1
- # width, height = stdwin.textwidth('in')*40, stdwin.lineheight()*24
- # stdwin.setdefwinsize(width, height)
- win = stdwin.open('Python interpreter ready')
- win.editor = win.textcreate((0,0), win.getwinsize())
- 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
- win.setwincursor('ibeam')
- win.filename = '' # Empty if no file for this window
- 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 = []
- 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)
-
-
-# Make an 'Edit' menu
-#
-def makeeditmenu(win):
- win.editmenu = mp = win.menucreate('Edit')
- mp.callback = []
- 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)
- win.iauto = len(mp.callback)
- additem(mp, 'Autoexecute', '', do_auto)
- mp.check(win.iauto, win.auto)
- win.insertOutputNum = len(mp.callback)
- additem(mp, 'Insert Output', '', do_insertOutputOption)
- win.insertErrorNum = len(mp.callback)
- additem(mp, 'Insert Error', '', do_insertErrorOption)
- additem(mp, 'Exec', '\r', do_exec)
-
-
-# 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.
-# Some events are treated specially.
-# Most other events are passed directly to the editor.
-#
-def pdispatch(event):
- type, win, detail = event
- if not win:
- win = stdwin.getactive()
- if not win: return
- if type == WE_CLOSE:
- do_close(win)
- return
- 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:
- raise KeyboardInterrupt
- else:
- win.command = ''
- settitle(win)
- elif type == WE_MENU:
- mp, item = detail
- mp.callback[item](win)
- else:
- void = win.editor.event(event)
- if win in mainloop.windows:
- # 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())
-
-
-# Helper to set the title of the window
-#
-def settitle(win):
- if win.filename == '':
- win.settitle('Python interpreter ready')
- else:
- win.settitle(win.filename)
-
-
-# Helper to replace the text of the focus
-#
-def replace(win, text):
- win.editor.replace(text)
- # Resize the window to display the text
- win.setdocsize(0, win.editor.getrect()[1][1]) # update the size before
- win.editor.setfocus(win.editor.getfocus()) # move focus to the change
-
-
-# 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
- win.editor.replace(open(filename, 'r').read())
- win.editor.setfocus(0, 0)
- win.settitle(win.filename)
- #
- except KeyboardInterrupt:
- pass # Don't give an error on cancel
-#
-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:
- pass # Don't give an error on cancel
-
-def do_saveas(win):
- currentFilename = win.filename
- win.filename = ''
- do_save(win) # Use do_save with empty filename
- if win.filename == '': # Restore the name if do_save did not set it
- 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)
- win.close()
-#
-def do_quit(win):
- # Call win.dispatch instead of do_close because there
- # may be 'alien' windows in the list.
- for win in mainloop.windows[:]:
- mainloop.dispatch((WE_CLOSE, win, None))
- # need to catch failed close
-
-
-# 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, '')
-
-
-# These would be better in a preferences dialog:
-#
-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]:
- stdwin.message('Please complete recursive input first')
- 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.
- 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
- b = b+1
- text = alltext[a:b] + '\n'
- else:
- # Execute exactly the selected text.
- text = win.editor.getfocustext()
- if text[-1:] <> '\n': # Make sure text ends with \n
- text = text + '\n'
- while b < n and alltext[b] <> '\n': # Find end of line after b
- 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
- raise InputAvailable, text
- #
- # 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...')
- #
- # 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...)
- #
- save_stdin = sys.stdin
- save_stdout = sys.stdout
- save_stderr = sys.stderr
- try:
- sys.stdin = sys.stdout = sys.stderr = IOWindow(win)
- win.busy = 1
- try:
- exec(command, win.globals)
- except KeyboardInterrupt:
- print '[Interrupt]'
- except:
- if type(sys.exc_type) == type(''):
- msg = sys.exc_type
- else: msg = sys.exc_type.__name__
- 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
- sys.stdin = save_stdin
- settitle(win)
-
-
-# Class emulating file I/O from/to a window
-#
-class IOWindow:
- #
- def __init__(self, win):
- self.win = win
- #
- def readline(self, *unused_args):
- n = len(inputwindows)
- save_title = self.win.gettitle()
- title = n*'(' + 'Requesting input...' + ')'*n
- self.win.settitle(title)
- inputwindows.insert(0, self.win)
- try:
- try:
- mainloop.mainloop()
- 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...
- raise EOFError
- #
- def write(self, text):
- mainloop.check()
- replace(self.win, text)
- mainloop.check()
-
-
-# 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'))
-
-
-# Call the main program
-#
-main()