summaryrefslogtreecommitdiffstats
path: root/Tools/idle/EditorWindow.py
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1998-10-10 18:48:31 (GMT)
committerGuido van Rossum <guido@python.org>1998-10-10 18:48:31 (GMT)
commit3b4ca0ddad8d1e224f71e89f4c7fbc8de5c6edc4 (patch)
tree1a66ed7c7eec87f31d61a2a083096e5cad89a39c /Tools/idle/EditorWindow.py
parentdc1adabcb86ee0813c9bae2d5cc59be5cad1ff31 (diff)
downloadcpython-3b4ca0ddad8d1e224f71e89f4c7fbc8de5c6edc4.zip
cpython-3b4ca0ddad8d1e224f71e89f4c7fbc8de5c6edc4.tar.gz
cpython-3b4ca0ddad8d1e224f71e89f4c7fbc8de5c6edc4.tar.bz2
Initial checking of Tk-based Python IDE.
Features: text editor with syntax coloring and undo; subclassed into interactive Python shell which adds history.
Diffstat (limited to 'Tools/idle/EditorWindow.py')
-rw-r--r--Tools/idle/EditorWindow.py175
1 files changed, 175 insertions, 0 deletions
diff --git a/Tools/idle/EditorWindow.py b/Tools/idle/EditorWindow.py
new file mode 100644
index 0000000..2028ed1
--- /dev/null
+++ b/Tools/idle/EditorWindow.py
@@ -0,0 +1,175 @@
+import sys
+import os
+import string
+from Tkinter import *
+
+
+class EditorWindow:
+
+ from Percolator import Percolator
+ from ColorDelegator import ColorDelegator
+ from UndoDelegator import UndoDelegator
+ from IOBinding import IOBinding
+ from SearchBinding import SearchBinding
+ from AutoIndent import AutoIndent
+ from AutoExpand import AutoExpand
+ import Bindings
+
+ def __init__(self, root, filename=None):
+ self.top = top = Toplevel(root)
+ self.vbar = vbar = Scrollbar(top, name='vbar')
+ self.text = text = Text(top, name='text')
+
+ self.Bindings.apply_bindings(text)
+
+ self.top.protocol("WM_DELETE_WINDOW", self.close)
+ self.top.bind("<<close-window>>", self.close_event)
+ self.text.bind("<<center-insert>>", self.center_insert_event)
+
+ vbar['command'] = text.yview
+ vbar.pack(side=RIGHT, fill=Y)
+
+ text['yscrollcommand'] = vbar.set
+ text['background'] = 'white'
+ if sys.platform[:3] == 'win':
+ text['font'] = ("lucida console", 8)
+ text.pack(side=LEFT, fill=BOTH, expand=1)
+ text.focus_set()
+
+ self.auto = auto = self.AutoIndent(text)
+ self.autoex = self.AutoExpand(text)
+ self.per = per = self.Percolator(text)
+ if self.ispythonsource(filename):
+ self.color = color = self.ColorDelegator(); per.insertfilter(color)
+ ##print "Initial colorizer"
+ else:
+ ##print "No initial colorizer"
+ self.color = None
+ self.undo = undo = self.UndoDelegator(); per.insertfilter(undo)
+ self.search = search = self.SearchBinding(undo)
+ self.io = io = self.IOBinding(undo)
+
+ undo.set_saved_change_hook(self.saved_change_hook)
+ io.set_filename_change_hook(self.filename_change_hook)
+
+ if filename:
+ if os.path.exists(filename):
+ io.loadfile(filename)
+ else:
+ io.set_filename(filename)
+
+ self.saved_change_hook()
+
+ def gotoline(self, lineno):
+ if lineno is not None and lineno > 0:
+ self.text.mark_set("insert", "%d.0" % lineno)
+ self.text.tag_remove("sel", "1.0", "end")
+ self.text.tag_add("sel", "insert", "insert +1l")
+ self.center()
+
+ def ispythonsource(self, filename):
+ if not filename:
+ return 1
+ if os.path.normcase(filename[-3:]) == ".py":
+ return 1
+ try:
+ f = open(filename)
+ line = f.readline()
+ f.close()
+ except IOError:
+ return 0
+ return line[:2] == '#!' and string.find(line, 'python') >= 0
+
+ close_hook = None
+
+ def set_close_hook(self, close_hook):
+ self.close_hook = close_hook
+
+ def filename_change_hook(self):
+ self.saved_change_hook()
+ if self.ispythonsource(self.io.filename):
+ self.addcolorizer()
+ else:
+ self.rmcolorizer()
+
+ def addcolorizer(self):
+ if self.color:
+ return
+ ##print "Add colorizer"
+ self.per.removefilter(self.undo)
+ self.color = self.ColorDelegator()
+ self.per.insertfilter(self.color)
+ self.per.insertfilter(self.undo)
+
+ def rmcolorizer(self):
+ if not self.color:
+ return
+ ##print "Remove colorizer"
+ self.per.removefilter(self.undo)
+ self.per.removefilter(self.color)
+ self.color = None
+ self.per.insertfilter(self.undo)
+
+ def saved_change_hook(self):
+ if self.io.filename:
+ title = self.io.filename
+ else:
+ title = "(Untitled)"
+ if not self.undo.get_saved():
+ title = title + " *"
+ self.top.wm_title(title)
+
+ def center_insert_event(self, event):
+ self.center()
+
+ def center(self, mark="insert"):
+ insert = float(self.text.index(mark + " linestart"))
+ end = float(self.text.index("end"))
+ if insert > end-insert:
+ self.text.see("1.0")
+ else:
+ self.text.see("end")
+ self.text.see(mark)
+
+ def close_event(self, event):
+ self.close()
+
+ def close(self):
+ self.top.wm_deiconify()
+ self.top.tkraise()
+ reply = self.io.maybesave()
+ if reply != "cancel":
+ if self.color and self.color.colorizing:
+ self.color.close()
+ self.top.bell()
+ return "cancel"
+ if self.close_hook:
+ self.close_hook()
+ if self.color:
+ self.color.close() # Cancel colorization
+ self.top.destroy()
+ return reply
+
+
+def fixwordbreaks(root):
+ tk = root.tk
+ tk.call('tcl_wordBreakAfter', 'a b', 0) # make sure word.tcl is loaded
+ tk.call('set', 'tcl_wordchars', '[a-zA-Z0-9_]')
+ tk.call('set', 'tcl_nonwordchars', '[^a-zA-Z0-9_]')
+
+
+def test():
+ root = Tk()
+ fixwordbreaks(root)
+ root.withdraw()
+ if sys.argv[1:]:
+ filename = sys.argv[1]
+ else:
+ filename = None
+ edit = EditorWindow(root, filename)
+ edit.set_close_hook(root.quit)
+ root.mainloop()
+ root.destroy()
+
+if __name__ == '__main__':
+ test()