Rework the code to have only the GvR RPC. Output from execution of user

code is directed to the Shell.
This commit is contained in:
Kurt B. Kaiser 2002-06-12 03:28:57 +00:00
parent 9f709bf9a1
commit 969de458aa
11 changed files with 168 additions and 1187 deletions

View file

@ -1,64 +1,19 @@
# changes by dscherer@cmu.edu
# - OutputWindow and OnDemandOutputWindow have been hastily
# extended to provide readline() support, an "iomark" separate
# from the "insert" cursor, and scrolling to clear the window.
# These changes are used by the ExecBinding module to provide
# standard input and output for user programs. Many of the new
# features are very similar to features of PyShell, which is a
# subclass of OutputWindow. Someone should make some sense of
# this.
from Tkinter import *
from EditorWindow import EditorWindow
import re
import tkMessageBox
from UndoDelegator import UndoDelegator
class OutputUndoDelegator(UndoDelegator):
reading = 0
# Forbid insert/delete before the I/O mark, in the blank lines after
# the output, or *anywhere* if we are not presently doing user input
def insert(self, index, chars, tags=None):
try:
if (self.delegate.compare(index, "<", "iomark") or
self.delegate.compare(index, ">", "endmark") or
(index!="iomark" and not self.reading)):
self.delegate.bell()
return
except TclError:
pass
UndoDelegator.insert(self, index, chars, tags)
def delete(self, index1, index2=None):
try:
if (self.delegate.compare(index1, "<", "iomark") or
self.delegate.compare(index1, ">", "endmark") or
(index2 and self.delegate.compare(index2, ">=", "endmark")) or
not self.reading):
self.delegate.bell()
return
except TclError:
pass
UndoDelegator.delete(self, index1, index2)
class OutputWindow(EditorWindow):
"""An editor window that can serve as an input and output file.
The input support has been rather hastily hacked in, and should
not be trusted.
"""An editor window that can serve as an output file.
Also the future base class for the Python shell window.
This class has no input facilities.
"""
UndoDelegator = OutputUndoDelegator
source_window = None
def __init__(self, *args, **keywords):
if keywords.has_key('source_window'):
self.source_window = keywords['source_window']
def __init__(self, *args):
apply(EditorWindow.__init__, (self,) + args)
self.text.bind("<<goto-file-line>>", self.goto_file_line)
self.text.bind("<<newline-and-indent>>", self.enter_callback)
self.text.mark_set("iomark","1.0")
self.text.mark_gravity("iomark", LEFT)
self.text.mark_set("endmark","1.0")
# Customize EditorWindow
@ -69,9 +24,6 @@ class OutputWindow(EditorWindow):
def short_title(self):
return "Output"
def long_title(self):
return ""
def maybesave(self):
# Override base class method -- don't ask any questions
if self.get_saved():
@ -79,63 +31,10 @@ class OutputWindow(EditorWindow):
else:
return "no"
# Act as input file - incomplete
def set_line_and_column(self, event=None):
index = self.text.index(INSERT)
if (self.text.compare(index, ">", "endmark")):
self.text.mark_set("insert", "endmark")
self.text.see("insert")
EditorWindow.set_line_and_column(self)
reading = 0
canceled = 0
endoffile = 0
def readline(self):
save = self.reading
try:
self.reading = self.undo.reading = 1
self.text.mark_set("insert", "iomark")
self.text.see("insert")
self.top.mainloop()
finally:
self.reading = self.undo.reading = save
line = self.text.get("input", "iomark")
if self.canceled:
self.canceled = 0
raise KeyboardInterrupt
if self.endoffile:
self.endoffile = 0
return ""
return line or '\n'
def close(self):
self.interrupt()
return EditorWindow.close(self)
def interrupt(self):
if self.reading:
self.endoffile = 1
self.top.quit()
def enter_callback(self, event):
if self.reading and self.text.compare("insert", ">=", "iomark"):
self.text.mark_set("input", "iomark")
self.text.mark_set("iomark", "insert")
self.write('\n',"iomark")
self.text.tag_add("stdin", "input", "iomark")
self.text.update_idletasks()
self.top.quit() # Break out of recursive mainloop() in raw_input()
return "break"
# Act as output file
def write(self, s, tags=(), mark="iomark"):
self.text.mark_gravity(mark, RIGHT)
self.text.insert(mark, s, tags)
self.text.mark_gravity(mark, LEFT)
def write(self, s, tags=(), mark="insert"):
self.text.insert(mark, str(s), tags)
self.text.see(mark)
self.text.update()
@ -183,14 +82,8 @@ class OutputWindow(EditorWindow):
master=self.text)
return
filename, lineno = result
edit = self.untitled(filename) or self.flist.open(filename)
edit = self.flist.open(filename)
edit.gotoline(lineno)
edit.wakeup()
def untitled(self, filename):
if filename!='Untitled' or not self.source_window or self.source_window.io.filename:
return None
return self.source_window
def _file_line_helper(self, line):
for prog in self.file_line_progs:
@ -200,80 +93,63 @@ class OutputWindow(EditorWindow):
else:
return None
filename, lineno = m.group(1, 2)
if not self.untitled(filename):
try:
f = open(filename, "r")
f.close()
except IOError:
return None
try:
f = open(filename, "r")
f.close()
except IOError:
return None
try:
return filename, int(lineno)
except TypeError:
return None
# This classes now used by ExecBinding.py:
# These classes are currently not used but might come in handy
class OnDemandOutputWindow:
source_window = None
tagdefs = {
# XXX Should use IdlePrefs.ColorPrefs
"stdin": {"foreground": "black"},
"stdout": {"foreground": "blue"},
"stderr": {"foreground": "red"},
}
"stderr": {"foreground": "#007700"},
}
def __init__(self, flist):
self.flist = flist
self.owin = None
self.title = "Output"
self.close_hook = None
self.old_close = None
def owclose(self):
if self.close_hook:
self.close_hook()
if self.old_close:
self.old_close()
def set_title(self, title):
self.title = title
if self.owin and self.owin.text:
self.owin.saved_change_hook()
def write(self, s, tags=(), mark="iomark"):
if not self.owin or not self.owin.text:
def write(self, s, tags, mark):
if not self.owin:
self.setup()
self.owin.write(s, tags, mark)
def readline(self):
if not self.owin or not self.owin.text:
self.setup()
return self.owin.readline()
def scroll_clear(self):
if self.owin and self.owin.text:
lineno = self.owin.getlineno("endmark")
self.owin.text.mark_set("insert","endmark")
self.owin.text.yview(float(lineno))
self.owin.wakeup()
def setup(self):
self.owin = owin = OutputWindow(self.flist, source_window = self.source_window)
owin.short_title = lambda self=self: self.title
self.owin = owin = OutputWindow(self.flist)
text = owin.text
self.old_close = owin.close_hook
owin.close_hook = self.owclose
# xxx Bad hack: 50 blank lines at the bottom so that
# we can scroll the top of the window to the output
# cursor in scroll_clear(). There must be a better way...
owin.text.mark_gravity('endmark', LEFT)
owin.text.insert('iomark', '\n'*50)
owin.text.mark_gravity('endmark', RIGHT)
for tag, cnf in self.tagdefs.items():
if cnf:
apply(text.tag_configure, (tag,), cnf)
text.tag_raise('sel')
self.write = self.owin.write
#class PseudoFile:
#
# def __init__(self, owin, tags, mark="end"):
# self.owin = owin
# self.tags = tags
# self.mark = mark
# def write(self, s):
# self.owin.write(s, self.tags, self.mark)
# def writelines(self, l):
# map(self.write, l)
# def flush(self):
# pass