summaryrefslogtreecommitdiff
path: root/sys/lib/python/idlelib
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2021-06-14 00:00:37 +0000
committerOri Bernstein <ori@eigenstate.org>2021-06-14 00:00:37 +0000
commita73a964e51247ed169d322c725a3a18859f109a3 (patch)
tree3f752d117274d444bda44e85609aeac1acf313f3 /sys/lib/python/idlelib
parente64efe273fcb921a61bf27d33b230c4e64fcd425 (diff)
python, hg: tow outside the environment.
they've served us well, and can ride off into the sunset.
Diffstat (limited to 'sys/lib/python/idlelib')
-rw-r--r--sys/lib/python/idlelib/AutoComplete.py226
-rw-r--r--sys/lib/python/idlelib/AutoCompleteWindow.py393
-rw-r--r--sys/lib/python/idlelib/AutoExpand.py83
-rw-r--r--sys/lib/python/idlelib/Bindings.py111
-rw-r--r--sys/lib/python/idlelib/CREDITS.txt36
-rw-r--r--sys/lib/python/idlelib/CallTipWindow.py171
-rw-r--r--sys/lib/python/idlelib/CallTips.py212
-rw-r--r--sys/lib/python/idlelib/ChangeLog1591
-rw-r--r--sys/lib/python/idlelib/ClassBrowser.py221
-rw-r--r--sys/lib/python/idlelib/CodeContext.py167
-rw-r--r--sys/lib/python/idlelib/ColorDelegator.py263
-rw-r--r--sys/lib/python/idlelib/Debugger.py481
-rw-r--r--sys/lib/python/idlelib/Delegator.py33
-rw-r--r--sys/lib/python/idlelib/EditorWindow.py1511
-rw-r--r--sys/lib/python/idlelib/FileList.py124
-rw-r--r--sys/lib/python/idlelib/FormatParagraph.py148
-rw-r--r--sys/lib/python/idlelib/GrepDialog.py133
-rw-r--r--sys/lib/python/idlelib/HISTORY.txt296
-rw-r--r--sys/lib/python/idlelib/HyperParser.py241
-rw-r--r--sys/lib/python/idlelib/IOBinding.py584
-rw-r--r--sys/lib/python/idlelib/Icons/folder.gifbin120 -> 0 bytes
-rw-r--r--sys/lib/python/idlelib/Icons/idle.icnsbin57435 -> 0 bytes
-rw-r--r--sys/lib/python/idlelib/Icons/minusnode.gifbin96 -> 0 bytes
-rw-r--r--sys/lib/python/idlelib/Icons/openfolder.gifbin125 -> 0 bytes
-rw-r--r--sys/lib/python/idlelib/Icons/plusnode.gifbin79 -> 0 bytes
-rw-r--r--sys/lib/python/idlelib/Icons/python.gifbin125 -> 0 bytes
-rw-r--r--sys/lib/python/idlelib/Icons/tk.gifbin85 -> 0 bytes
-rw-r--r--sys/lib/python/idlelib/IdleHistory.py88
-rw-r--r--sys/lib/python/idlelib/MultiCall.py406
-rw-r--r--sys/lib/python/idlelib/MultiStatusBar.py32
-rw-r--r--sys/lib/python/idlelib/NEWS.txt613
-rw-r--r--sys/lib/python/idlelib/ObjectBrowser.py151
-rw-r--r--sys/lib/python/idlelib/OutputWindow.py157
-rw-r--r--sys/lib/python/idlelib/ParenMatch.py172
-rw-r--r--sys/lib/python/idlelib/PathBrowser.py95
-rw-r--r--sys/lib/python/idlelib/Percolator.py85
-rw-r--r--sys/lib/python/idlelib/PyParse.py594
-rw-r--r--sys/lib/python/idlelib/PyShell.py1441
-rw-r--r--sys/lib/python/idlelib/README.txt63
-rw-r--r--sys/lib/python/idlelib/RemoteDebugger.py381
-rw-r--r--sys/lib/python/idlelib/RemoteObjectBrowser.py36
-rw-r--r--sys/lib/python/idlelib/ReplaceDialog.py167
-rw-r--r--sys/lib/python/idlelib/ScriptBinding.py210
-rw-r--r--sys/lib/python/idlelib/ScrolledList.py139
-rw-r--r--sys/lib/python/idlelib/SearchDialog.py68
-rw-r--r--sys/lib/python/idlelib/SearchDialogBase.py140
-rw-r--r--sys/lib/python/idlelib/SearchEngine.py220
-rw-r--r--sys/lib/python/idlelib/StackViewer.py137
-rw-r--r--sys/lib/python/idlelib/TODO.txt210
-rw-r--r--sys/lib/python/idlelib/ToolTip.py89
-rw-r--r--sys/lib/python/idlelib/TreeWidget.py478
-rw-r--r--sys/lib/python/idlelib/UndoDelegator.py352
-rw-r--r--sys/lib/python/idlelib/WidgetRedirector.py92
-rw-r--r--sys/lib/python/idlelib/WindowList.py90
-rw-r--r--sys/lib/python/idlelib/ZoomHeight.py50
-rw-r--r--sys/lib/python/idlelib/__init__.py1
-rw-r--r--sys/lib/python/idlelib/aboutDialog.py163
-rw-r--r--sys/lib/python/idlelib/config-extensions.def88
-rw-r--r--sys/lib/python/idlelib/config-highlight.def64
-rw-r--r--sys/lib/python/idlelib/config-keys.def214
-rw-r--r--sys/lib/python/idlelib/config-main.def79
-rw-r--r--sys/lib/python/idlelib/configDialog.py1147
-rw-r--r--sys/lib/python/idlelib/configHandler.py696
-rw-r--r--sys/lib/python/idlelib/configHelpSourceEdit.py169
-rw-r--r--sys/lib/python/idlelib/configSectionNameDialog.py97
-rw-r--r--sys/lib/python/idlelib/dynOptionMenuWidget.py35
-rw-r--r--sys/lib/python/idlelib/extend.txt83
-rw-r--r--sys/lib/python/idlelib/help.txt213
-rwxr-xr-xsys/lib/python/idlelib/idle.bat3
-rw-r--r--sys/lib/python/idlelib/idle.py21
-rw-r--r--sys/lib/python/idlelib/idle.pyw21
-rw-r--r--sys/lib/python/idlelib/idlever.py1
-rw-r--r--sys/lib/python/idlelib/keybindingDialog.py268
-rw-r--r--sys/lib/python/idlelib/macosxSupport.py112
-rw-r--r--sys/lib/python/idlelib/rpc.py602
-rw-r--r--sys/lib/python/idlelib/run.py327
-rw-r--r--sys/lib/python/idlelib/tabpage.py113
-rw-r--r--sys/lib/python/idlelib/testcode.py31
-rw-r--r--sys/lib/python/idlelib/textView.py78
79 files changed, 0 insertions, 18407 deletions
diff --git a/sys/lib/python/idlelib/AutoComplete.py b/sys/lib/python/idlelib/AutoComplete.py
deleted file mode 100644
index 708538662..000000000
--- a/sys/lib/python/idlelib/AutoComplete.py
+++ /dev/null
@@ -1,226 +0,0 @@
-"""AutoComplete.py - An IDLE extension for automatically completing names.
-
-This extension can complete either attribute names of file names. It can pop
-a window with all available names, for the user to select from.
-"""
-import os
-import sys
-import string
-
-from configHandler import idleConf
-
-import AutoCompleteWindow
-from HyperParser import HyperParser
-
-import __main__
-
-# This string includes all chars that may be in a file name (without a path
-# separator)
-FILENAME_CHARS = string.ascii_letters + string.digits + os.curdir + "._~#$:-"
-# This string includes all chars that may be in an identifier
-ID_CHARS = string.ascii_letters + string.digits + "_"
-
-# These constants represent the two different types of completions
-COMPLETE_ATTRIBUTES, COMPLETE_FILES = range(1, 2+1)
-
-class AutoComplete:
-
- menudefs = [
- ('edit', [
- ("Show completions", "<<force-open-completions>>"),
- ])
- ]
-
- popupwait = idleConf.GetOption("extensions", "AutoComplete",
- "popupwait", type="int", default=0)
-
- def __init__(self, editwin=None):
- if editwin == None: # subprocess and test
- self.editwin = None
- return
- self.editwin = editwin
- self.text = editwin.text
- self.autocompletewindow = None
-
- # id of delayed call, and the index of the text insert when the delayed
- # call was issued. If _delayed_completion_id is None, there is no
- # delayed call.
- self._delayed_completion_id = None
- self._delayed_completion_index = None
-
- def _make_autocomplete_window(self):
- return AutoCompleteWindow.AutoCompleteWindow(self.text)
-
- def _remove_autocomplete_window(self, event=None):
- if self.autocompletewindow:
- self.autocompletewindow.hide_window()
- self.autocompletewindow = None
-
- def force_open_completions_event(self, event):
- """Happens when the user really wants to open a completion list, even
- if a function call is needed.
- """
- self.open_completions(True, False, True)
-
- def try_open_completions_event(self, event):
- """Happens when it would be nice to open a completion list, but not
- really neccesary, for example after an dot, so function
- calls won't be made.
- """
- lastchar = self.text.get("insert-1c")
- if lastchar == ".":
- self._open_completions_later(False, False, False,
- COMPLETE_ATTRIBUTES)
- elif lastchar == os.sep:
- self._open_completions_later(False, False, False,
- COMPLETE_FILES)
-
- def autocomplete_event(self, event):
- """Happens when the user wants to complete his word, and if neccesary,
- open a completion list after that (if there is more than one
- completion)
- """
- if hasattr(event, "mc_state") and event.mc_state:
- # A modifier was pressed along with the tab, continue as usual.
- return
- if self.autocompletewindow and self.autocompletewindow.is_active():
- self.autocompletewindow.complete()
- return "break"
- else:
- opened = self.open_completions(False, True, True)
- if opened:
- return "break"
-
- def _open_completions_later(self, *args):
- self._delayed_completion_index = self.text.index("insert")
- if self._delayed_completion_id is not None:
- self.text.after_cancel(self._delayed_completion_id)
- self._delayed_completion_id = \
- self.text.after(self.popupwait, self._delayed_open_completions,
- *args)
-
- def _delayed_open_completions(self, *args):
- self._delayed_completion_id = None
- if self.text.index("insert") != self._delayed_completion_index:
- return
- self.open_completions(*args)
-
- def open_completions(self, evalfuncs, complete, userWantsWin, mode=None):
- """Find the completions and create the AutoCompleteWindow.
- Return True if successful (no syntax error or so found).
- if complete is True, then if there's nothing to complete and no
- start of completion, won't open completions and return False.
- If mode is given, will open a completion list only in this mode.
- """
- # Cancel another delayed call, if it exists.
- if self._delayed_completion_id is not None:
- self.text.after_cancel(self._delayed_completion_id)
- self._delayed_completion_id = None
-
- hp = HyperParser(self.editwin, "insert")
- curline = self.text.get("insert linestart", "insert")
- i = j = len(curline)
- if hp.is_in_string() and (not mode or mode==COMPLETE_FILES):
- self._remove_autocomplete_window()
- mode = COMPLETE_FILES
- while i and curline[i-1] in FILENAME_CHARS:
- i -= 1
- comp_start = curline[i:j]
- j = i
- while i and curline[i-1] in FILENAME_CHARS+os.sep:
- i -= 1
- comp_what = curline[i:j]
- elif hp.is_in_code() and (not mode or mode==COMPLETE_ATTRIBUTES):
- self._remove_autocomplete_window()
- mode = COMPLETE_ATTRIBUTES
- while i and curline[i-1] in ID_CHARS:
- i -= 1
- comp_start = curline[i:j]
- if i and curline[i-1] == '.':
- hp.set_index("insert-%dc" % (len(curline)-(i-1)))
- comp_what = hp.get_expression()
- if not comp_what or \
- (not evalfuncs and comp_what.find('(') != -1):
- return
- else:
- comp_what = ""
- else:
- return
-
- if complete and not comp_what and not comp_start:
- return
- comp_lists = self.fetch_completions(comp_what, mode)
- if not comp_lists[0]:
- return
- self.autocompletewindow = self._make_autocomplete_window()
- self.autocompletewindow.show_window(comp_lists,
- "insert-%dc" % len(comp_start),
- complete,
- mode,
- userWantsWin)
- return True
-
- def fetch_completions(self, what, mode):
- """Return a pair of lists of completions for something. The first list
- is a sublist of the second. Both are sorted.
-
- If there is a Python subprocess, get the comp. list there. Otherwise,
- either fetch_completions() is running in the subprocess itself or it
- was called in an IDLE EditorWindow before any script had been run.
-
- The subprocess environment is that of the most recently run script. If
- two unrelated modules are being edited some calltips in the current
- module may be inoperative if the module was not the last to run.
- """
- try:
- rpcclt = self.editwin.flist.pyshell.interp.rpcclt
- except:
- rpcclt = None
- if rpcclt:
- return rpcclt.remotecall("exec", "get_the_completion_list",
- (what, mode), {})
- else:
- if mode == COMPLETE_ATTRIBUTES:
- if what == "":
- namespace = __main__.__dict__.copy()
- namespace.update(__main__.__builtins__.__dict__)
- bigl = eval("dir()", namespace)
- bigl.sort()
- if "__all__" in bigl:
- smalll = eval("__all__", namespace)
- smalll.sort()
- else:
- smalll = filter(lambda s: s[:1] != '_', bigl)
- else:
- try:
- entity = self.get_entity(what)
- bigl = dir(entity)
- bigl.sort()
- if "__all__" in bigl:
- smalll = entity.__all__
- smalll.sort()
- else:
- smalll = filter(lambda s: s[:1] != '_', bigl)
- except:
- return [], []
-
- elif mode == COMPLETE_FILES:
- if what == "":
- what = "."
- try:
- expandedpath = os.path.expanduser(what)
- bigl = os.listdir(expandedpath)
- bigl.sort()
- smalll = filter(lambda s: s[:1] != '.', bigl)
- except OSError:
- return [], []
-
- if not smalll:
- smalll = bigl
- return smalll, bigl
-
- def get_entity(self, name):
- """Lookup name in a namespace spanning sys.modules and __main.dict__"""
- namespace = sys.modules.copy()
- namespace.update(__main__.__dict__)
- return eval(name, namespace)
diff --git a/sys/lib/python/idlelib/AutoCompleteWindow.py b/sys/lib/python/idlelib/AutoCompleteWindow.py
deleted file mode 100644
index d8bbff4a1..000000000
--- a/sys/lib/python/idlelib/AutoCompleteWindow.py
+++ /dev/null
@@ -1,393 +0,0 @@
-"""
-An auto-completion window for IDLE, used by the AutoComplete extension
-"""
-from Tkinter import *
-from MultiCall import MC_SHIFT
-import AutoComplete
-
-HIDE_VIRTUAL_EVENT_NAME = "<<autocompletewindow-hide>>"
-HIDE_SEQUENCES = ("<FocusOut>", "<ButtonPress>")
-KEYPRESS_VIRTUAL_EVENT_NAME = "<<autocompletewindow-keypress>>"
-# We need to bind event beyond <Key> so that the function will be called
-# before the default specific IDLE function
-KEYPRESS_SEQUENCES = ("<Key>", "<Key-BackSpace>", "<Key-Return>",
- "<Key-Up>", "<Key-Down>", "<Key-Home>", "<Key-End>")
-KEYRELEASE_VIRTUAL_EVENT_NAME = "<<autocompletewindow-keyrelease>>"
-KEYRELEASE_SEQUENCE = "<KeyRelease>"
-LISTUPDATE_SEQUENCE = "<ButtonRelease>"
-WINCONFIG_SEQUENCE = "<Configure>"
-DOUBLECLICK_SEQUENCE = "<Double-ButtonRelease>"
-
-class AutoCompleteWindow:
-
- def __init__(self, widget):
- # The widget (Text) on which we place the AutoCompleteWindow
- self.widget = widget
- # The widgets we create
- self.autocompletewindow = self.listbox = self.scrollbar = None
- # The default foreground and background of a selection. Saved because
- # they are changed to the regular colors of list items when the
- # completion start is not a prefix of the selected completion
- self.origselforeground = self.origselbackground = None
- # The list of completions
- self.completions = None
- # A list with more completions, or None
- self.morecompletions = None
- # The completion mode. Either AutoComplete.COMPLETE_ATTRIBUTES or
- # AutoComplete.COMPLETE_FILES
- self.mode = None
- # The current completion start, on the text box (a string)
- self.start = None
- # The index of the start of the completion
- self.startindex = None
- # The last typed start, used so that when the selection changes,
- # the new start will be as close as possible to the last typed one.
- self.lasttypedstart = None
- # Do we have an indication that the user wants the completion window
- # (for example, he clicked the list)
- self.userwantswindow = None
- # event ids
- self.hideid = self.keypressid = self.listupdateid = self.winconfigid \
- = self.keyreleaseid = self.doubleclickid = None
-
- def _change_start(self, newstart):
- i = 0
- while i < len(self.start) and i < len(newstart) and \
- self.start[i] == newstart[i]:
- i += 1
- if i < len(self.start):
- self.widget.delete("%s+%dc" % (self.startindex, i),
- "%s+%dc" % (self.startindex, len(self.start)))
- if i < len(newstart):
- self.widget.insert("%s+%dc" % (self.startindex, i),
- newstart[i:])
- self.start = newstart
-
- def _binary_search(self, s):
- """Find the first index in self.completions where completions[i] is
- greater or equal to s, or the last index if there is no such
- one."""
- i = 0; j = len(self.completions)
- while j > i:
- m = (i + j) // 2
- if self.completions[m] >= s:
- j = m
- else:
- i = m + 1
- return min(i, len(self.completions)-1)
-
- def _complete_string(self, s):
- """Assuming that s is the prefix of a string in self.completions,
- return the longest string which is a prefix of all the strings which
- s is a prefix of them. If s is not a prefix of a string, return s."""
- first = self._binary_search(s)
- if self.completions[first][:len(s)] != s:
- # There is not even one completion which s is a prefix of.
- return s
- # Find the end of the range of completions where s is a prefix of.
- i = first + 1
- j = len(self.completions)
- while j > i:
- m = (i + j) // 2
- if self.completions[m][:len(s)] != s:
- j = m
- else:
- i = m + 1
- last = i-1
-
- # We should return the maximum prefix of first and last
- i = len(s)
- while len(self.completions[first]) > i and \
- len(self.completions[last]) > i and \
- self.completions[first][i] == self.completions[last][i]:
- i += 1
- return self.completions[first][:i]
-
- def _selection_changed(self):
- """Should be called when the selection of the Listbox has changed.
- Updates the Listbox display and calls _change_start."""
- cursel = int(self.listbox.curselection()[0])
-
- self.listbox.see(cursel)
-
- lts = self.lasttypedstart
- selstart = self.completions[cursel]
- if self._binary_search(lts) == cursel:
- newstart = lts
- else:
- i = 0
- while i < len(lts) and i < len(selstart) and lts[i] == selstart[i]:
- i += 1
- while cursel > 0 and selstart[:i] <= self.completions[cursel-1]:
- i += 1
- newstart = selstart[:i]
- self._change_start(newstart)
-
- if self.completions[cursel][:len(self.start)] == self.start:
- # start is a prefix of the selected completion
- self.listbox.configure(selectbackground=self.origselbackground,
- selectforeground=self.origselforeground)
- else:
- self.listbox.configure(selectbackground=self.listbox.cget("bg"),
- selectforeground=self.listbox.cget("fg"))
- # If there are more completions, show them, and call me again.
- if self.morecompletions:
- self.completions = self.morecompletions
- self.morecompletions = None
- self.listbox.delete(0, END)
- for item in self.completions:
- self.listbox.insert(END, item)
- self.listbox.select_set(self._binary_search(self.start))
- self._selection_changed()
-
- def show_window(self, comp_lists, index, complete, mode, userWantsWin):
- """Show the autocomplete list, bind events.
- If complete is True, complete the text, and if there is exactly one
- matching completion, don't open a list."""
- # Handle the start we already have
- self.completions, self.morecompletions = comp_lists
- self.mode = mode
- self.startindex = self.widget.index(index)
- self.start = self.widget.get(self.startindex, "insert")
- if complete:
- completed = self._complete_string(self.start)
- self._change_start(completed)
- i = self._binary_search(completed)
- if self.completions[i] == completed and \
- (i == len(self.completions)-1 or
- self.completions[i+1][:len(completed)] != completed):
- # There is exactly one matching completion
- return
- self.userwantswindow = userWantsWin
- self.lasttypedstart = self.start
-
- # Put widgets in place
- self.autocompletewindow = acw = Toplevel(self.widget)
- # Put it in a position so that it is not seen.
- acw.wm_geometry("+10000+10000")
- # Make it float
- acw.wm_overrideredirect(1)
- try:
- # This command is only needed and available on Tk >= 8.4.0 for OSX
- # Without it, call tips intrude on the typing process by grabbing
- # the focus.
- acw.tk.call("::tk::unsupported::MacWindowStyle", "style", acw._w,
- "help", "noActivates")
- except TclError:
- pass
- self.scrollbar = scrollbar = Scrollbar(acw, orient=VERTICAL)
- self.listbox = listbox = Listbox(acw, yscrollcommand=scrollbar.set,
- exportselection=False, bg="white")
- for item in self.completions:
- listbox.insert(END, item)
- self.origselforeground = listbox.cget("selectforeground")
- self.origselbackground = listbox.cget("selectbackground")
- scrollbar.config(command=listbox.yview)
- scrollbar.pack(side=RIGHT, fill=Y)
- listbox.pack(side=LEFT, fill=BOTH, expand=True)
-
- # Initialize the listbox selection
- self.listbox.select_set(self._binary_search(self.start))
- self._selection_changed()
-
- # bind events
- self.hideid = self.widget.bind(HIDE_VIRTUAL_EVENT_NAME,
- self.hide_event)
- for seq in HIDE_SEQUENCES:
- self.widget.event_add(HIDE_VIRTUAL_EVENT_NAME, seq)
- self.keypressid = self.widget.bind(KEYPRESS_VIRTUAL_EVENT_NAME,
- self.keypress_event)
- for seq in KEYPRESS_SEQUENCES:
- self.widget.event_add(KEYPRESS_VIRTUAL_EVENT_NAME, seq)
- self.keyreleaseid = self.widget.bind(KEYRELEASE_VIRTUAL_EVENT_NAME,
- self.keyrelease_event)
- self.widget.event_add(KEYRELEASE_VIRTUAL_EVENT_NAME,KEYRELEASE_SEQUENCE)
- self.listupdateid = listbox.bind(LISTUPDATE_SEQUENCE,
- self.listupdate_event)
- self.winconfigid = acw.bind(WINCONFIG_SEQUENCE, self.winconfig_event)
- self.doubleclickid = listbox.bind(DOUBLECLICK_SEQUENCE,
- self.doubleclick_event)
-
- def winconfig_event(self, event):
- if not self.is_active():
- return
- # Position the completion list window
- acw = self.autocompletewindow
- self.widget.see(self.startindex)
- x, y, cx, cy = self.widget.bbox(self.startindex)
- acw.wm_geometry("+%d+%d" % (x + self.widget.winfo_rootx(),
- y + self.widget.winfo_rooty() \
- -acw.winfo_height()))
-
-
- def hide_event(self, event):
- if not self.is_active():
- return
- self.hide_window()
-
- def listupdate_event(self, event):
- if not self.is_active():
- return
- self.userwantswindow = True
- self._selection_changed()
-
- def doubleclick_event(self, event):
- # Put the selected completion in the text, and close the list
- cursel = int(self.listbox.curselection()[0])
- self._change_start(self.completions[cursel])
- self.hide_window()
-
- def keypress_event(self, event):
- if not self.is_active():
- return
- keysym = event.keysym
- if hasattr(event, "mc_state"):
- state = event.mc_state
- else:
- state = 0
-
- if (len(keysym) == 1 or keysym in ("underscore", "BackSpace")
- or (self.mode==AutoComplete.COMPLETE_FILES and keysym in
- ("period", "minus"))) \
- and not (state & ~MC_SHIFT):
- # Normal editing of text
- if len(keysym) == 1:
- self._change_start(self.start + keysym)
- elif keysym == "underscore":
- self._change_start(self.start + '_')
- elif keysym == "period":
- self._change_start(self.start + '.')
- elif keysym == "minus":
- self._change_start(self.start + '-')
- else:
- # keysym == "BackSpace"
- if len(self.start) == 0:
- self.hide_window()
- return
- self._change_start(self.start[:-1])
- self.lasttypedstart = self.start
- self.listbox.select_clear(0, int(self.listbox.curselection()[0]))
- self.listbox.select_set(self._binary_search(self.start))
- self._selection_changed()
- return "break"
-
- elif keysym == "Return" and not state:
- # If start is a prefix of the selection, or there was an indication
- # that the user used the completion window, put the selected
- # completion in the text, and close the list.
- # Otherwise, close the window and let the event through.
- cursel = int(self.listbox.curselection()[0])
- if self.completions[cursel][:len(self.start)] == self.start or \
- self.userwantswindow:
- self._change_start(self.completions[cursel])
- self.hide_window()
- return "break"
- else:
- self.hide_window()
- return
-
- elif (self.mode == AutoComplete.COMPLETE_ATTRIBUTES and keysym in
- ("period", "space", "parenleft", "parenright", "bracketleft",
- "bracketright")) or \
- (self.mode == AutoComplete.COMPLETE_FILES and keysym in
- ("slash", "backslash", "quotedbl", "apostrophe")) \
- and not (state & ~MC_SHIFT):
- # If start is a prefix of the selection, but is not '' when
- # completing file names, put the whole
- # selected completion. Anyway, close the list.
- cursel = int(self.listbox.curselection()[0])
- if self.completions[cursel][:len(self.start)] == self.start \
- and (self.mode==AutoComplete.COMPLETE_ATTRIBUTES or self.start):
- self._change_start(self.completions[cursel])
- self.hide_window()
- return
-
- elif keysym in ("Home", "End", "Prior", "Next", "Up", "Down") and \
- not state:
- # Move the selection in the listbox
- self.userwantswindow = True
- cursel = int(self.listbox.curselection()[0])
- if keysym == "Home":
- newsel = 0
- elif keysym == "End":
- newsel = len(self.completions)-1
- elif keysym in ("Prior", "Next"):
- jump = self.listbox.nearest(self.listbox.winfo_height()) - \
- self.listbox.nearest(0)
- if keysym == "Prior":
- newsel = max(0, cursel-jump)
- else:
- assert keysym == "Next"
- newsel = min(len(self.completions)-1, cursel+jump)
- elif keysym == "Up":
- newsel = max(0, cursel-1)
- else:
- assert keysym == "Down"
- newsel = min(len(self.completions)-1, cursel+1)
- self.listbox.select_clear(cursel)
- self.listbox.select_set(newsel)
- self._selection_changed()
- return "break"
-
- elif (keysym == "Tab" and not state):
- # The user wants a completion, but it is handled by AutoComplete
- # (not AutoCompleteWindow), so ignore.
- self.userwantswindow = True
- return
-
- elif reduce(lambda x, y: x or y,
- [keysym.find(s) != -1 for s in ("Shift", "Control", "Alt",
- "Meta", "Command", "Option")
- ]):
- # A modifier key, so ignore
- return
-
- else:
- # Unknown event, close the window and let it through.
- self.hide_window()
- return
-
- def keyrelease_event(self, event):
- if not self.is_active():
- return
- if self.widget.index("insert") != \
- self.widget.index("%s+%dc" % (self.startindex, len(self.start))):
- # If we didn't catch an event which moved the insert, close window
- self.hide_window()
-
- def is_active(self):
- return self.autocompletewindow is not None
-
- def complete(self):
- self._change_start(self._complete_string(self.start))
- # The selection doesn't change.
-
- def hide_window(self):
- if not self.is_active():
- return
-
- # unbind events
- for seq in HIDE_SEQUENCES:
- self.widget.event_delete(HIDE_VIRTUAL_EVENT_NAME, seq)
- self.widget.unbind(HIDE_VIRTUAL_EVENT_NAME, self.hideid)
- self.hideid = None
- for seq in KEYPRESS_SEQUENCES:
- self.widget.event_delete(KEYPRESS_VIRTUAL_EVENT_NAME, seq)
- self.widget.unbind(KEYPRESS_VIRTUAL_EVENT_NAME, self.keypressid)
- self.keypressid = None
- self.widget.event_delete(KEYRELEASE_VIRTUAL_EVENT_NAME,
- KEYRELEASE_SEQUENCE)
- self.widget.unbind(KEYRELEASE_VIRTUAL_EVENT_NAME, self.keyreleaseid)
- self.keyreleaseid = None
- self.listbox.unbind(LISTUPDATE_SEQUENCE, self.listupdateid)
- self.listupdateid = None
- self.autocompletewindow.unbind(WINCONFIG_SEQUENCE, self.winconfigid)
- self.winconfigid = None
-
- # destroy widgets
- self.scrollbar.destroy()
- self.scrollbar = None
- self.listbox.destroy()
- self.listbox = None
- self.autocompletewindow.destroy()
- self.autocompletewindow = None
diff --git a/sys/lib/python/idlelib/AutoExpand.py b/sys/lib/python/idlelib/AutoExpand.py
deleted file mode 100644
index 9e93d57d6..000000000
--- a/sys/lib/python/idlelib/AutoExpand.py
+++ /dev/null
@@ -1,83 +0,0 @@
-import string
-import re
-
-###$ event <<expand-word>>
-###$ win <Alt-slash>
-###$ unix <Alt-slash>
-
-class AutoExpand:
-
- menudefs = [
- ('edit', [
- ('E_xpand Word', '<<expand-word>>'),
- ]),
- ]
-
- wordchars = string.ascii_letters + string.digits + "_"
-
- def __init__(self, editwin):
- self.text = editwin.text
- self.state = None
-
- def expand_word_event(self, event):
- curinsert = self.text.index("insert")
- curline = self.text.get("insert linestart", "insert lineend")
- if not self.state:
- words = self.getwords()
- index = 0
- else:
- words, index, insert, line = self.state
- if insert != curinsert or line != curline:
- words = self.getwords()
- index = 0
- if not words:
- self.text.bell()
- return "break"
- word = self.getprevword()
- self.text.delete("insert - %d chars" % len(word), "insert")
- newword = words[index]
- index = (index + 1) % len(words)
- if index == 0:
- self.text.bell() # Warn we cycled around
- self.text.insert("insert", newword)
- curinsert = self.text.index("insert")
- curline = self.text.get("insert linestart", "insert lineend")
- self.state = words, index, curinsert, curline
- return "break"
-
- def getwords(self):
- word = self.getprevword()
- if not word:
- return []
- before = self.text.get("1.0", "insert wordstart")
- wbefore = re.findall(r"\b" + word + r"\w+\b", before)
- del before
- after = self.text.get("insert wordend", "end")
- wafter = re.findall(r"\b" + word + r"\w+\b", after)
- del after
- if not wbefore and not wafter:
- return []
- words = []
- dict = {}
- # search backwards through words before
- wbefore.reverse()
- for w in wbefore:
- if dict.get(w):
- continue
- words.append(w)
- dict[w] = w
- # search onwards through words after
- for w in wafter:
- if dict.get(w):
- continue
- words.append(w)
- dict[w] = w
- words.append(word)
- return words
-
- def getprevword(self):
- line = self.text.get("insert linestart", "insert")
- i = len(line)
- while i > 0 and line[i-1] in self.wordchars:
- i = i-1
- return line[i:]
diff --git a/sys/lib/python/idlelib/Bindings.py b/sys/lib/python/idlelib/Bindings.py
deleted file mode 100644
index a3c9fc45f..000000000
--- a/sys/lib/python/idlelib/Bindings.py
+++ /dev/null
@@ -1,111 +0,0 @@
-"""Define the menu contents, hotkeys, and event bindings.
-
-There is additional configuration information in the EditorWindow class (and
-subclasses): the menus are created there based on the menu_specs (class)
-variable, and menus not created are silently skipped in the code here. This
-makes it possible, for example, to define a Debug menu which is only present in
-the PythonShell window, and a Format menu which is only present in the Editor
-windows.
-
-"""
-import sys
-from configHandler import idleConf
-
-menudefs = [
- # underscore prefixes character to underscore
- ('file', [
- ('_New Window', '<<open-new-window>>'),
- ('_Open...', '<<open-window-from-file>>'),
- ('Open _Module...', '<<open-module>>'),
- ('Class _Browser', '<<open-class-browser>>'),
- ('_Path Browser', '<<open-path-browser>>'),
- None,
- ('_Save', '<<save-window>>'),
- ('Save _As...', '<<save-window-as-file>>'),
- ('Save Cop_y As...', '<<save-copy-of-window-as-file>>'),
- None,
- ('Prin_t Window', '<<print-window>>'),
- None,
- ('_Close', '<<close-window>>'),
- ('E_xit', '<<close-all-windows>>'),
- ]),
- ('edit', [
- ('_Undo', '<<undo>>'),
- ('_Redo', '<<redo>>'),
- None,
- ('Cu_t', '<<cut>>'),
- ('_Copy', '<<copy>>'),
- ('_Paste', '<<paste>>'),
- ('Select _All', '<<select-all>>'),
- None,
- ('_Find...', '<<find>>'),
- ('Find A_gain', '<<find-again>>'),
- ('Find _Selection', '<<find-selection>>'),
- ('Find in Files...', '<<find-in-files>>'),
- ('R_eplace...', '<<replace>>'),
- ('Go to _Line', '<<goto-line>>'),
- ]),
-('format', [
- ('_Indent Region', '<<indent-region>>'),
- ('_Dedent Region', '<<dedent-region>>'),
- ('Comment _Out Region', '<<comment-region>>'),
- ('U_ncomment Region', '<<uncomment-region>>'),
- ('Tabify Region', '<<tabify-region>>'),
- ('Untabify Region', '<<untabify-region>>'),
- ('Toggle Tabs', '<<toggle-tabs>>'),
- ('New Indent Width', '<<change-indentwidth>>'),
- ]),
- ('run', [
- ('Python Shell', '<<open-python-shell>>'),
- ]),
- ('shell', [
- ('_View Last Restart', '<<view-restart>>'),
- ('_Restart Shell', '<<restart-shell>>'),
- ]),
- ('debug', [
- ('_Go to File/Line', '<<goto-file-line>>'),
- ('!_Debugger', '<<toggle-debugger>>'),
- ('_Stack Viewer', '<<open-stack-viewer>>'),
- ('!_Auto-open Stack Viewer', '<<toggle-jit-stack-viewer>>'),
- ]),
- ('options', [
- ('_Configure IDLE...', '<<open-config-dialog>>'),
- None,
- ]),
- ('help', [
- ('_About IDLE', '<<about-idle>>'),
- None,
- ('_IDLE Help', '<<help>>'),
- ('Python _Docs', '<<python-docs>>'),
- ]),
-]
-
-import sys
-if sys.platform == 'darwin' and '.app' in sys.executable:
- # Running as a proper MacOS application bundle. This block restructures
- # the menus a little to make them conform better to the HIG.
-
- quitItem = menudefs[0][1][-1]
- closeItem = menudefs[0][1][-2]
-
- # Remove the last 3 items of the file menu: a separator, close window and
- # quit. Close window will be reinserted just above the save item, where
- # it should be according to the HIG. Quit is in the application menu.
- del menudefs[0][1][-3:]
- menudefs[0][1].insert(6, closeItem)
-
- # Remove the 'About' entry from the help menu, it is in the application
- # menu
- del menudefs[-1][1][0:2]
-
- menudefs.insert(0,
- ('application', [
- ('About IDLE', '<<about-idle>>'),
- None,
- ('_Preferences....', '<<open-config-dialog>>'),
- ]))
-
-
-default_keydefs = idleConf.GetCurrentKeySet()
-
-del sys
diff --git a/sys/lib/python/idlelib/CREDITS.txt b/sys/lib/python/idlelib/CREDITS.txt
deleted file mode 100644
index 30561a9ea..000000000
--- a/sys/lib/python/idlelib/CREDITS.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-Guido van Rossum, as well as being the creator of the Python language, is the
-original creator of IDLE. Other contributors prior to Version 0.8 include
-Mark Hammond, Jeremy Hylton, Tim Peters, and Moshe Zadka.
-
-IDLE's recent development has been carried out in the IDLEfork project.
-The objective was to develop a version of IDLE which had an execution
-environment which could be initialized prior to each run of user code.
-
-The IDLEfork project was initiated by David Scherer, with some help from Peter
-Schneider-Kamp and Nicholas Riley. David wrote the first version of the RPC
-code and designed a fast turn-around environment for VPython. Guido developed
-the RPC code and Remote Debugger currently integrated in IDLE. Bruce Sherwood
-contributed considerable time testing and suggesting improvements.
-
-Besides David and Guido, the main developers who have been active on IDLEfork
-are Stephen M. Gava, who implemented the configuration GUI, the new
-configuration system, and the About dialog, and Kurt B. Kaiser, who completed
-the integration of the RPC and remote debugger, implemented the threaded
-subprocess, and made a number of usability enhancements.
-
-Other contributors include Raymond Hettinger, Tony Lownds (Mac integration),
-Neal Norwitz (code check and clean-up), Ronald Oussoren (Mac integration),
-Noam Raphael (Code Context, Call Tips, many other patches), and Chui Tey (RPC
-integration, debugger integration and persistent breakpoints).
-
-Scott David Daniels, Tal Einat, Hernan Foffani, Christos Georgiou,
-Jim Jewett, Martin v. Löwis, Jason Orendorff, Josh Robb, Nigel Rowe,
-Bruce Sherwood, and Jeff Shute have submitted useful patches. Thanks, guys!
-
-For additional details refer to NEWS.txt and Changelog.
-
-Please contact the IDLE maintainer (kbk@shore.net) to have yourself included
-here if you are one of those we missed!
-
-
-
diff --git a/sys/lib/python/idlelib/CallTipWindow.py b/sys/lib/python/idlelib/CallTipWindow.py
deleted file mode 100644
index 22238855c..000000000
--- a/sys/lib/python/idlelib/CallTipWindow.py
+++ /dev/null
@@ -1,171 +0,0 @@
-"""A CallTip window class for Tkinter/IDLE.
-
-After ToolTip.py, which uses ideas gleaned from PySol
-Used by the CallTips IDLE extension.
-
-"""
-from Tkinter import *
-
-HIDE_VIRTUAL_EVENT_NAME = "<<calltipwindow-hide>>"
-HIDE_SEQUENCES = ("<Key-Escape>", "<FocusOut>")
-CHECKHIDE_VIRTUAL_EVENT_NAME = "<<calltipwindow-checkhide>>"
-CHECKHIDE_SEQUENCES = ("<KeyRelease>", "<ButtonRelease>")
-CHECKHIDE_TIME = 100 # miliseconds
-
-MARK_RIGHT = "calltipwindowregion_right"
-
-class CallTip:
-
- def __init__(self, widget):
- self.widget = widget
- self.tipwindow = self.label = None
- self.parenline = self.parencol = None
- self.lastline = None
- self.hideid = self.checkhideid = None
-
- def position_window(self):
- """Check if needs to reposition the window, and if so - do it."""
- curline = int(self.widget.index("insert").split('.')[0])
- if curline == self.lastline:
- return
- self.lastline = curline
- self.widget.see("insert")
- if curline == self.parenline:
- box = self.widget.bbox("%d.%d" % (self.parenline,
- self.parencol))
- else:
- box = self.widget.bbox("%d.0" % curline)
- if not box:
- box = list(self.widget.bbox("insert"))
- # align to left of window
- box[0] = 0
- box[2] = 0
- x = box[0] + self.widget.winfo_rootx() + 2
- y = box[1] + box[3] + self.widget.winfo_rooty()
- self.tipwindow.wm_geometry("+%d+%d" % (x, y))
-
- def showtip(self, text, parenleft, parenright):
- """Show the calltip, bind events which will close it and reposition it.
- """
- # truncate overly long calltip
- if len(text) >= 79:
- textlines = text.splitlines()
- for i, line in enumerate(textlines):
- if len(line) > 79:
- textlines[i] = line[:75] + ' ...'
- text = '\n'.join(textlines)
- self.text = text
- if self.tipwindow or not self.text:
- return
-
- self.widget.mark_set(MARK_RIGHT, parenright)
- self.parenline, self.parencol = map(
- int, self.widget.index(parenleft).split("."))
-
- self.tipwindow = tw = Toplevel(self.widget)
- self.position_window()
- # remove border on calltip window
- tw.wm_overrideredirect(1)
- try:
- # This command is only needed and available on Tk >= 8.4.0 for OSX
- # Without it, call tips intrude on the typing process by grabbing
- # the focus.
- tw.tk.call("::tk::unsupported::MacWindowStyle", "style", tw._w,
- "help", "noActivates")
- except TclError:
- pass
- self.label = Label(tw, text=self.text, justify=LEFT,
- background="#ffffe0", relief=SOLID, borderwidth=1,
- font = self.widget['font'])
- self.label.pack()
-
- self.checkhideid = self.widget.bind(CHECKHIDE_VIRTUAL_EVENT_NAME,
- self.checkhide_event)
- for seq in CHECKHIDE_SEQUENCES:
- self.widget.event_add(CHECKHIDE_VIRTUAL_EVENT_NAME, seq)
- self.widget.after(CHECKHIDE_TIME, self.checkhide_event)
- self.hideid = self.widget.bind(HIDE_VIRTUAL_EVENT_NAME,
- self.hide_event)
- for seq in HIDE_SEQUENCES:
- self.widget.event_add(HIDE_VIRTUAL_EVENT_NAME, seq)
-
- def checkhide_event(self, event=None):
- if not self.tipwindow:
- # If the event was triggered by the same event that unbinded
- # this function, the function will be called nevertheless,
- # so do nothing in this case.
- return
- curline, curcol = map(int, self.widget.index("insert").split('.'))
- if curline < self.parenline or \
- (curline == self.parenline and curcol <= self.parencol) or \
- self.widget.compare("insert", ">", MARK_RIGHT):
- self.hidetip()
- else:
- self.position_window()
- self.widget.after(CHECKHIDE_TIME, self.checkhide_event)
-
- def hide_event(self, event):
- if not self.tipwindow:
- # See the explanation in checkhide_event.
- return
- self.hidetip()
-
- def hidetip(self):
- if not self.tipwindow:
- return
-
- for seq in CHECKHIDE_SEQUENCES:
- self.widget.event_delete(CHECKHIDE_VIRTUAL_EVENT_NAME, seq)
- self.widget.unbind(CHECKHIDE_VIRTUAL_EVENT_NAME, self.checkhideid)
- self.checkhideid = None
- for seq in HIDE_SEQUENCES:
- self.widget.event_delete(HIDE_VIRTUAL_EVENT_NAME, seq)
- self.widget.unbind(HIDE_VIRTUAL_EVENT_NAME, self.hideid)
- self.hideid = None
-
- self.label.destroy()
- self.label = None
- self.tipwindow.destroy()
- self.tipwindow = None
-
- self.widget.mark_unset(MARK_RIGHT)
- self.parenline = self.parencol = self.lastline = None
-
- def is_active(self):
- return bool(self.tipwindow)
-
-
-
-###############################
-#
-# Test Code
-#
-class container: # Conceptually an editor_window
- def __init__(self):
- root = Tk()
- text = self.text = Text(root)
- text.pack(side=LEFT, fill=BOTH, expand=1)
- text.insert("insert", "string.split")
- root.update()
- self.calltip = CallTip(text)
-
- text.event_add("<<calltip-show>>", "(")
- text.event_add("<<calltip-hide>>", ")")
- text.bind("<<calltip-show>>", self.calltip_show)
- text.bind("<<calltip-hide>>", self.calltip_hide)
-
- text.focus_set()
- root.mainloop()
-
- def calltip_show(self, event):
- self.calltip.showtip("Hello world")
-
- def calltip_hide(self, event):
- self.calltip.hidetip()
-
-def main():
- # Test code
- c=container()
-
-if __name__=='__main__':
- main()
diff --git a/sys/lib/python/idlelib/CallTips.py b/sys/lib/python/idlelib/CallTips.py
deleted file mode 100644
index 997eb13a0..000000000
--- a/sys/lib/python/idlelib/CallTips.py
+++ /dev/null
@@ -1,212 +0,0 @@
-"""CallTips.py - An IDLE Extension to Jog Your Memory
-
-Call Tips are floating windows which display function, class, and method
-parameter and docstring information when you type an opening parenthesis, and
-which disappear when you type a closing parenthesis.
-"""
-import sys
-import types
-
-import CallTipWindow
-from HyperParser import HyperParser
-
-import __main__
-
-class CallTips:
-
- menudefs = [
- ('edit', [
- ("Show call tip", "<<force-open-calltip>>"),
- ])
- ]
-
- def __init__(self, editwin=None):
- if editwin is None: # subprocess and test
- self.editwin = None
- return
- self.editwin = editwin
- self.text = editwin.text
- self.calltip = None
- self._make_calltip_window = self._make_tk_calltip_window
-
- def close(self):
- self._make_calltip_window = None
-
- def _make_tk_calltip_window(self):
- # See __init__ for usage
- return CallTipWindow.CallTip(self.text)
-
- def _remove_calltip_window(self, event=None):
- if self.calltip:
- self.calltip.hidetip()
- self.calltip = None
-
- def force_open_calltip_event(self, event):
- """Happens when the user really wants to open a CallTip, even if a
- function call is needed.
- """
- self.open_calltip(True)
-
- def try_open_calltip_event(self, event):
- """Happens when it would be nice to open a CallTip, but not really
- neccesary, for example after an opening bracket, so function calls
- won't be made.
- """
- self.open_calltip(False)
-
- def refresh_calltip_event(self, event):
- """If there is already a calltip window, check if it is still needed,
- and if so, reload it.
- """
- if self.calltip and self.calltip.is_active():
- self.open_calltip(False)
-
- def open_calltip(self, evalfuncs):
- self._remove_calltip_window()
-
- hp = HyperParser(self.editwin, "insert")
- sur_paren = hp.get_surrounding_brackets('(')
- if not sur_paren:
- return
- hp.set_index(sur_paren[0])
- name = hp.get_expression()
- if not name or (not evalfuncs and name.find('(') != -1):
- return
- arg_text = self.fetch_tip(name)
- if not arg_text:
- return
- self.calltip = self._make_calltip_window()
- self.calltip.showtip(arg_text, sur_paren[0], sur_paren[1])
-
- def fetch_tip(self, name):
- """Return the argument list and docstring of a function or class
-
- If there is a Python subprocess, get the calltip there. Otherwise,
- either fetch_tip() is running in the subprocess itself or it was called
- in an IDLE EditorWindow before any script had been run.
-
- The subprocess environment is that of the most recently run script. If
- two unrelated modules are being edited some calltips in the current
- module may be inoperative if the module was not the last to run.
-
- """
- try:
- rpcclt = self.editwin.flist.pyshell.interp.rpcclt
- except:
- rpcclt = None
- if rpcclt:
- return rpcclt.remotecall("exec", "get_the_calltip",
- (name,), {})
- else:
- entity = self.get_entity(name)
- return get_arg_text(entity)
-
- def get_entity(self, name):
- "Lookup name in a namespace spanning sys.modules and __main.dict__"
- if name:
- namespace = sys.modules.copy()
- namespace.update(__main__.__dict__)
- try:
- return eval(name, namespace)
- except:
- return None
-
-def _find_constructor(class_ob):
- # Given a class object, return a function object used for the
- # constructor (ie, __init__() ) or None if we can't find one.
- try:
- return class_ob.__init__.im_func
- except AttributeError:
- for base in class_ob.__bases__:
- rc = _find_constructor(base)
- if rc is not None: return rc
- return None
-
-def get_arg_text(ob):
- """Get a string describing the arguments for the given object"""
- argText = ""
- if ob is not None:
- argOffset = 0
- if type(ob) in (types.ClassType, types.TypeType):
- # Look for the highest __init__ in the class chain.
- fob = _find_constructor(ob)
- if fob is None:
- fob = lambda: None
- else:
- argOffset = 1
- elif type(ob)==types.MethodType:
- # bit of a hack for methods - turn it into a function
- # but we drop the "self" param.
- fob = ob.im_func
- argOffset = 1
- else:
- fob = ob
- # Try and build one for Python defined functions
- if type(fob) in [types.FunctionType, types.LambdaType]:
- try:
- realArgs = fob.func_code.co_varnames[argOffset:fob.func_code.co_argcount]
- defaults = fob.func_defaults or []
- defaults = list(map(lambda name: "=%s" % repr(name), defaults))
- defaults = [""] * (len(realArgs)-len(defaults)) + defaults
- items = map(lambda arg, dflt: arg+dflt, realArgs, defaults)
- if fob.func_code.co_flags & 0x4:
- items.append("...")
- if fob.func_code.co_flags & 0x8:
- items.append("***")
- argText = ", ".join(items)
- argText = "(%s)" % argText
- except:
- pass
- # See if we can use the docstring
- doc = getattr(ob, "__doc__", "")
- if doc:
- doc = doc.lstrip()
- pos = doc.find("\n")
- if pos < 0 or pos > 70:
- pos = 70
- if argText:
- argText += "\n"
- argText += doc[:pos]
- return argText
-
-#################################################
-#
-# Test code
-#
-if __name__=='__main__':
-
- def t1(): "()"
- def t2(a, b=None): "(a, b=None)"
- def t3(a, *args): "(a, ...)"
- def t4(*args): "(...)"
- def t5(a, *args): "(a, ...)"
- def t6(a, b=None, *args, **kw): "(a, b=None, ..., ***)"
-
- class TC:
- "(a=None, ...)"
- def __init__(self, a=None, *b): "(a=None, ...)"
- def t1(self): "()"
- def t2(self, a, b=None): "(a, b=None)"
- def t3(self, a, *args): "(a, ...)"
- def t4(self, *args): "(...)"
- def t5(self, a, *args): "(a, ...)"
- def t6(self, a, b=None, *args, **kw): "(a, b=None, ..., ***)"
-
- def test(tests):
- ct = CallTips()
- failed=[]
- for t in tests:
- expected = t.__doc__ + "\n" + t.__doc__
- name = t.__name__
- arg_text = ct.fetch_tip(name)
- if arg_text != expected:
- failed.append(t)
- print "%s - expected %s, but got %s" % (t, expected,
- get_arg_text(entity))
- print "%d of %d tests failed" % (len(failed), len(tests))
-
- tc = TC()
- tests = (t1, t2, t3, t4, t5, t6,
- TC, tc.t1, tc.t2, tc.t3, tc.t4, tc.t5, tc.t6)
-
- test(tests)
diff --git a/sys/lib/python/idlelib/ChangeLog b/sys/lib/python/idlelib/ChangeLog
deleted file mode 100644
index 985871bee..000000000
--- a/sys/lib/python/idlelib/ChangeLog
+++ /dev/null
@@ -1,1591 +0,0 @@
-Please refer to the IDLEfork and IDLE CVS repositories for
-change details subsequent to the 0.8.1 release.
-
-
-IDLEfork ChangeLog
-==================
-
-2001-07-20 11:35 elguavas
-
- * README.txt, NEWS.txt: bring up to date for 0.8.1 release
-
-2001-07-19 16:40 elguavas
-
- * IDLEFORK.html: replaced by IDLEFORK-index.html
-
-2001-07-19 16:39 elguavas
-
- * IDLEFORK-index.html: updated placeholder idlefork homepage
-
-2001-07-19 14:49 elguavas
-
- * ChangeLog, EditorWindow.py, INSTALLATION, NEWS.txt, README.txt,
- TODO.txt, idlever.py:
- minor tidy-ups ready for 0.8.1 alpha tarball release
-
-2001-07-17 15:12 kbk
-
- * INSTALLATION, setup.py: INSTALLATION: Remove the coexist.patch
- instructions
-
- **************** setup.py:
-
- Remove the idles script, add some words on IDLE Fork to the
- long_description, and clean up some line spacing.
-
-2001-07-17 15:01 kbk
-
- * coexist.patch: Put this in the attic, at least for now...
-
-2001-07-17 14:59 kbk
-
- * PyShell.py, idle, idles: Implement idle command interface as
- suggested by GvR [idle-dev] 16 July **************** PyShell: Added
- functionality:
-
- usage: idle.py [-c command] [-d] [-i] [-r script] [-s] [-t title]
- [arg] ...
-
- idle file(s) (without options) edit the file(s)
-
- -c cmd run the command in a shell -d enable the
- debugger -i open an interactive shell -i file(s) open a
- shell and also an editor window for each file -r script run a file
- as a script in a shell -s run $IDLESTARTUP or
- $PYTHONSTARTUP before anything else -t title set title of shell
- window
-
- Remaining arguments are applied to the command (-c) or script (-r).
-
- ****************** idles: Removed the idles script, not needed
-
- ****************** idle: Removed the IdleConf references, not
- required anymore
-
-2001-07-16 17:08 kbk
-
- * INSTALLATION, coexist.patch: Added installation instructions.
-
- Added a patch which modifies idlefork so that it can co-exist with
- "official" IDLE in the site-packages directory. This patch is not
- necessary if only idlefork IDLE is installed. See INSTALLATION for
- further details.
-
-2001-07-16 15:50 kbk
-
- * idles: Add a script "idles" which opens a Python Shell window.
-
- The default behaviour of idlefork idle is to open an editor window
- instead of a shell. Complex expressions may be run in a fresh
- environment by selecting "run". There are times, however, when a
- shell is desired. Though one can be started by "idle -t 'foo'",
- this script is more convenient. In addition, a shell and an editor
- window can be started in parallel by "idles -e foo.py".
-
-2001-07-16 15:25 kbk
-
- * PyShell.py: Call out IDLE Fork in startup message.
-
-2001-07-16 14:00 kbk
-
- * PyShell.py, setup.py: Add a script "idles" which opens a Python
- Shell window.
-
- The default behaviour of idlefork idle is to open an editor window
- instead of a shell. Complex expressions may be run in a fresh
- environment by selecting "run". There are times, however, when a
- shell is desired. Though one can be started by "idle -t 'foo'",
- this script is more convenient. In addition, a shell and an editor
- window can be started in parallel by "idles -e foo.py".
-
-2001-07-15 03:06 kbk
-
- * pyclbr.py, tabnanny.py: tabnanny and pyclbr are now found in /Lib
-
-2001-07-15 02:29 kbk
-
- * BrowserControl.py: Remove, was retained for 1.5.2 support
-
-2001-07-14 15:48 kbk
-
- * setup.py: Installing Idle to site-packages via Distutils does not
- copy the Idle help.txt file.
-
- Ref SF Python Patch 422471
-
-2001-07-14 15:26 kbk
-
- * keydefs.py: py-cvs-2001_07_13 (Rev 1.3) merge
-
- "Make copy, cut and paste events case insensitive. Reported by
- Patrick K. O'Brien on idle-dev. (Should other bindings follow
- suit?)" --GvR
-
-2001-07-14 15:21 kbk
-
- * idle.py: py-cvs-2001_07_13 (Rev 1.4) merge
-
- "Move the action of loading the configuration to the IdleConf
- module rather than the idle.py script. This has advantages and
- disadvantages; the biggest advantage being that we can more easily
- have an alternative main program." --GvR
-
-2001-07-14 15:18 kbk
-
- * extend.txt: py-cvs-2001_07_13 (Rev 1.4) merge
-
- "Quick update to the extension mechanism (extend.py is gone, long
- live config.txt)" --GvR
-
-2001-07-14 15:15 kbk
-
- * StackViewer.py: py-cvs-2001_07_13 (Rev 1.16) merge
-
- "Refactored, with some future plans in mind. This now uses the new
- gotofileline() method defined in FileList.py" --GvR
-
-2001-07-14 15:10 kbk
-
- * PyShell.py: py-cvs-2001_07_13 (Rev 1.34) merge
-
- "Amazing. A very subtle change in policy in descr-branch actually
- found a bug here. Here's the deal: Class PyShell derives from
- class OutputWindow. Method PyShell.close() wants to invoke its
- parent method, but because PyShell long ago was inherited from
- class PyShellEditorWindow, it invokes
- PyShelEditorWindow.close(self). Now, class PyShellEditorWindow
- itself derives from class OutputWindow, and inherits the close()
- method from there without overriding it. Under the old rules,
- PyShellEditorWindow.close would return an unbound method restricted
- to the class that defined the implementation of close(), which was
- OutputWindow.close. Under the new rules, the unbound method is
- restricted to the class whose method was requested, that is
- PyShellEditorWindow, and this was correctly trapped as an error."
- --GvR
-
-2001-07-14 14:59 kbk
-
- * PyParse.py: py-cvs-2001_07_13 (Rel 1.9) merge
-
- "Taught IDLE's autoident parser that "yield" is a keyword that
- begins a stmt. Along w/ the preceding change to keyword.py, making
- all this work w/ a future-stmt just looks harder and harder."
- --tim_one
-
- (From Rel 1.8: "Hack to make this still work with Python 1.5.2.
- ;-( " --fdrake)
-
-2001-07-14 14:51 kbk
-
- * IdleConf.py: py-cvs-2001_07_13 (Rel 1.7) merge
-
- "Move the action of loading the configuration to the IdleConf
- module rather than the idle.py script. This has advantages and
- disadvantages; the biggest advantage being that we can more easily
- have an alternative main program." --GvR
-
-2001-07-14 14:45 kbk
-
- * FileList.py: py-cvs-2000_07_13 (Rev 1.9) merge
-
- "Delete goodname() method, which is unused. Add gotofileline(), a
- convenience method which I intend to use in a variant. Rename
- test() to _test()." --GvR
-
- This was an interesting merge. The join completely missed removing
- goodname(), which was adjacent, but outside of, a small conflict.
- I only caught it by comparing the 1.1.3.2/1.1.3.3 diff. CVS ain't
- infallible.
-
-2001-07-14 13:58 kbk
-
- * EditorWindow.py: py-cvs-2000_07_13 (Rev 1.38) merge "Remove
- legacy support for the BrowserControl module; the webbrowser module
- has been included since Python 2.0, and that is the preferred
- interface." --fdrake
-
-2001-07-14 13:32 kbk
-
- * EditorWindow.py, FileList.py, IdleConf.py, PyParse.py,
- PyShell.py, StackViewer.py, extend.txt, idle.py, keydefs.py: Import
- the 2001 July 13 23:59 GMT version of Python CVS IDLE on the
- existing 1.1.3 vendor branch named py-cvs-vendor-branch. Release
- tag is py-cvs-2001_07_13.
-
-2001-07-14 12:02 kbk
-
- * Icons/python.gif: py-cvs-rel2_1 (Rev 1.2) merge Copied py-cvs rev
- 1.2 changed file to idlefork MAIN
-
-2001-07-14 11:58 kbk
-
- * Icons/minusnode.gif: py-cvs-rel2_1 (Rev 1.2) merge Copied py-cvs
- 1.2 changed file to idlefork MAIN
-
-2001-07-14 11:23 kbk
-
- * ScrolledList.py: py-cvs-rel2_1 (rev 1.5) merge - whitespace
- normalization
-
-2001-07-14 11:20 kbk
-
- * Separator.py: py-cvs-rel2_1 (Rev 1.3) merge - whitespace
- normalization
-
-2001-07-14 11:16 kbk
-
- * StackViewer.py: py-cvs-rel2_1 (Rev 1.15) merge - whitespace
- normalization
-
-2001-07-14 11:14 kbk
-
- * ToolTip.py: py-cvs-rel2_1 (Rev 1.2) merge - whitespace
- normalization
-
-2001-07-14 10:13 kbk
-
- * PyShell.py: cvs-py-rel2_1 (Rev 1.29 - 1.33) merge
-
- Merged the following py-cvs revs without conflict: 1.29 Reduce
- copyright text output at startup 1.30 Delay setting sys.args until
- Tkinter is fully initialized 1.31 Whitespace normalization 1.32
- Turn syntax warning into error when interactive 1.33 Fix warning
- initialization bug
-
- Note that module is extensively modified wrt py-cvs
-
-2001-07-14 06:33 kbk
-
- * PyParse.py: py-cvs-rel2_1 (Rev 1.6 - 1.8) merge Fix autoindent
- bug and deflect Unicode from text.get()
-
-2001-07-14 06:00 kbk
-
- * Percolator.py: py-cvs-rel2_1 (Rev 1.3) "move "from Tkinter import
- *" to module level" --jhylton
-
-2001-07-14 05:57 kbk
-
- * PathBrowser.py: py-cvs-rel2_1 (Rev 1.6) merge - whitespace
- normalization
-
-2001-07-14 05:49 kbk
-
- * ParenMatch.py: cvs-py-rel2_1 (Rev 1.5) merge - whitespace
- normalization
-
-2001-07-14 03:57 kbk
-
- * ObjectBrowser.py: py-cvs-rel2_1 (Rev 1.3) merge "Make the test
- program work outside IDLE." -- GvR
-
-2001-07-14 03:52 kbk
-
- * MultiStatusBar.py: py-cvs-rel2_1 (Rev 1.2) merge - whitespace
- normalization
-
-2001-07-14 03:44 kbk
-
- * MultiScrolledLists.py: py-cvs-rel2_1 (Rev 1.2) merge - whitespace
- normalization
-
-2001-07-14 03:40 kbk
-
- * IdleHistory.py: py-cvs-rel2_1 (Rev 1.4) merge - whitespace
- normalization
-
-2001-07-14 03:38 kbk
-
- * IdleConf.py: py-cvs-rel2_1 (Rev 1.6) merge - whitespace
- normalization
-
-2001-07-13 14:18 kbk
-
- * IOBinding.py: py-cvs-rel2_1 (Rev 1.4) merge - move "import *" to
- module level
-
-2001-07-13 14:12 kbk
-
- * FormatParagraph.py: py-cvs-rel2_1 (Rev 1.9) merge - whitespace
- normalization
-
-2001-07-13 14:07 kbk
-
- * FileList.py: py-cvs-rel2_1 (Rev 1.8) merge - whitespace
- normalization
-
-2001-07-13 13:35 kbk
-
- * EditorWindow.py: py-cvs-rel2_1 (Rev 1.33 - 1.37) merge
-
- VP IDLE version depended on VP's ExecBinding.py and spawn.py to get
- the path to the Windows Doc directory (relative to python.exe).
- Removed this conflicting code in favor of py-cvs updates which on
- Windows use a hard coded path relative to the location of this
- module. py-cvs updates include support for webbrowser.py. Module
- still has BrowserControl.py for 1.5.2 support.
-
- At this point, the differences wrt py-cvs relate to menu
- functionality.
-
-2001-07-13 11:30 kbk
-
- * ConfigParser.py: py-cvs-rel2_1 merge - Remove, lives in /Lib
-
-2001-07-13 10:10 kbk
-
- * Delegator.py: py-cvs-rel2_1 (Rev 1.3) merge - whitespace
- normalization
-
-2001-07-13 10:07 kbk
-
- * Debugger.py: py-cvs-rel2_1 (Rev 1.15) merge - whitespace
- normalization
-
-2001-07-13 10:04 kbk
-
- * ColorDelegator.py: py-cvs-rel2_1 (Rev 1.11 and 1.12) merge
- Colorize "as" after "import" / use DEBUG instead of __debug__
-
-2001-07-13 09:54 kbk
-
- * ClassBrowser.py: py-cvs-rel2_1 (Rev 1.12) merge - whitespace
- normalization
-
-2001-07-13 09:41 kbk
-
- * BrowserControl.py: py-cvs-rel2_1 (Rev 1.1) merge - New File -
- Force HEAD to trunk with -f Note: browser.py was renamed
- BrowserControl.py 10 May 2000. It provides a collection of classes
- and convenience functions to control external browsers "for 1.5.2
- support". It was removed from py-cvs 18 April 2001.
-
-2001-07-13 09:10 kbk
-
- * CallTips.py: py-cvs-rel2_1 (Rev 1.8) merge - whitespace
- normalization
-
-2001-07-13 08:26 kbk
-
- * CallTipWindow.py: py-cvs-rel2_1 (Rev 1.3) merge - whitespace
- normalization
-
-2001-07-13 08:13 kbk
-
- * AutoExpand.py: py-cvs-rel1_2 (Rev 1.4) merge, "Add Alt-slash to
- Unix keydefs (I somehow need it on RH 6.2). Get rid of assignment
- to unused self.text.wordlist." --GvR
-
-2001-07-12 16:54 elguavas
-
- * ReplaceDialog.py: py-cvs merge, python 1.5.2 compatibility
-
-2001-07-12 16:46 elguavas
-
- * ScriptBinding.py: py-cvs merge, better error dialog
-
-2001-07-12 16:38 elguavas
-
- * TODO.txt: py-cvs merge, additions
-
-2001-07-12 15:35 elguavas
-
- * WindowList.py: py-cvs merge, correct indentation
-
-2001-07-12 15:24 elguavas
-
- * config.txt: py-cvs merge, correct typo
-
-2001-07-12 15:21 elguavas
-
- * help.txt: py-cvs merge, update colour changing info
-
-2001-07-12 14:51 elguavas
-
- * idle.py: py-cvs merge, idle_dir loading changed
-
-2001-07-12 14:44 elguavas
-
- * idlever.py: py-cvs merge, version update
-
-2001-07-11 12:53 kbk
-
- * BrowserControl.py: Initial revision
-
-2001-07-11 12:53 kbk
-
- * AutoExpand.py, BrowserControl.py, CallTipWindow.py, CallTips.py,
- ClassBrowser.py, ColorDelegator.py, Debugger.py, Delegator.py,
- EditorWindow.py, FileList.py, FormatParagraph.py, IOBinding.py,
- IdleConf.py, IdleHistory.py, MultiScrolledLists.py,
- MultiStatusBar.py, ObjectBrowser.py, OutputWindow.py,
- ParenMatch.py, PathBrowser.py, Percolator.py, PyParse.py,
- PyShell.py, RemoteInterp.py, ReplaceDialog.py, ScriptBinding.py,
- ScrolledList.py, Separator.py, StackViewer.py, TODO.txt,
- ToolTip.py, WindowList.py, config.txt, help.txt, idle, idle.bat,
- idle.py, idlever.py, setup.py, Icons/minusnode.gif,
- Icons/python.gif: Import the release 2.1 version of Python CVS IDLE
- on the existing 1.1.3 vendor branch named py-cvs-vendor-branch,
- with release tag py-cvs-rel2_1.
-
-2001-07-11 12:34 kbk
-
- * AutoExpand.py, AutoIndent.py, Bindings.py, CallTipWindow.py,
- CallTips.py, ChangeLog, ClassBrowser.py, ColorDelegator.py,
- Debugger.py, Delegator.py, EditorWindow.py, FileList.py,
- FormatParagraph.py, FrameViewer.py, GrepDialog.py, IOBinding.py,
- IdleConf.py, IdleHistory.py, MultiScrolledLists.py,
- MultiStatusBar.py, NEWS.txt, ObjectBrowser.py, OldStackViewer.py,
- OutputWindow.py, ParenMatch.py, PathBrowser.py, Percolator.py,
- PyParse.py, PyShell.py, README.txt, RemoteInterp.py,
- ReplaceDialog.py, ScriptBinding.py, ScrolledList.py,
- SearchBinding.py, SearchDialog.py, SearchDialogBase.py,
- SearchEngine.py, Separator.py, StackViewer.py, TODO.txt,
- ToolTip.py, TreeWidget.py, UndoDelegator.py, WidgetRedirector.py,
- WindowList.py, ZoomHeight.py, __init__.py, config-unix.txt,
- config-win.txt, config.txt, eventparse.py, extend.txt, help.txt,
- idle.bat, idle.py, idle.pyw, idlever.py, keydefs.py, pyclbr.py,
- tabnanny.py, testcode.py, Icons/folder.gif, Icons/minusnode.gif,
- Icons/openfolder.gif, Icons/plusnode.gif, Icons/python.gif,
- Icons/tk.gif: Import the 9 March 2000 version of Python CVS IDLE as
- 1.1.3 vendor branch named py-cvs-vendor-branch.
-
-2001-07-04 13:43 kbk
-
- * Icons/: folder.gif, minusnode.gif, openfolder.gif, plusnode.gif,
- python.gif, tk.gif: Null commit with -f option to force an uprev
- and put HEADs firmly on the trunk.
-
-2001-07-04 13:15 kbk
-
- * AutoExpand.py, AutoIndent.py, Bindings.py, CallTipWindow.py,
- CallTips.py, ChangeLog, ClassBrowser.py, ColorDelegator.py,
- ConfigParser.py, Debugger.py, Delegator.py, EditorWindow.py,
- ExecBinding.py, FileList.py, FormatParagraph.py, FrameViewer.py,
- GrepDialog.py, IDLEFORK.html, IOBinding.py, IdleConf.py,
- IdleHistory.py, MultiScrolledLists.py, MultiStatusBar.py, NEWS.txt,
- ObjectBrowser.py, OldStackViewer.py, OutputWindow.py,
- ParenMatch.py, PathBrowser.py, Percolator.py, PyParse.py,
- PyShell.py, README.txt, Remote.py, RemoteInterp.py,
- ReplaceDialog.py, ScriptBinding.py, ScrolledList.py,
- SearchBinding.py, SearchDialog.py, SearchDialogBase.py,
- SearchEngine.py, Separator.py, StackViewer.py, TODO.txt,
- ToolTip.py, TreeWidget.py, UndoDelegator.py, WidgetRedirector.py,
- WindowList.py, ZoomHeight.py, __init__.py, config-unix.txt,
- config-win.txt, config.txt, eventparse.py, extend.txt, help.txt,
- idle, idle.bat, idle.py, idle.pyw, idlever.py, keydefs.py,
- loader.py, protocol.py, pyclbr.py, setup.py, spawn.py, tabnanny.py,
- testcode.py: Null commit with -f option to force an uprev and put
- HEADs firmly on the trunk.
-
-2001-06-27 10:24 elguavas
-
- * IDLEFORK.html: updated contact details
-
-2001-06-25 17:23 elguavas
-
- * idle, RemoteInterp.py, setup.py: Initial revision
-
-2001-06-25 17:23 elguavas
-
- * idle, RemoteInterp.py, setup.py: import current python cvs idle
- as a vendor branch
-
-2001-06-24 15:10 elguavas
-
- * IDLEFORK.html: tiny change to test new syncmail setup
-
-2001-06-24 14:41 elguavas
-
- * IDLEFORK.html: change to new developer contact, also a test
- commit for new syncmail setup
-
-2001-06-23 18:15 elguavas
-
- * IDLEFORK.html: tiny test update for revitalised idle-fork
-
-2000-09-24 17:29 nriley
-
- * protocol.py: Fixes for Python 1.6 compatibility - socket bind and
- connect get a tuple instead two arguments.
-
-2000-09-24 17:28 nriley
-
- * spawn.py: Change for Python 1.6 compatibility - UNIX's 'os'
- module defines 'spawnv' now, so we check for 'fork' first.
-
-2000-08-15 22:51 nowonder
-
- * IDLEFORK.html:
- corrected email address
-
-2000-08-15 22:47 nowonder
-
- * IDLEFORK.html:
- added .html file for http://idlefork.sourceforge.net
-
-2000-08-15 11:13 dscherer
-
- * AutoExpand.py, AutoIndent.py, Bindings.py, CallTipWindow.py,
- CallTips.py, __init__.py, ChangeLog, ClassBrowser.py,
- ColorDelegator.py, ConfigParser.py, Debugger.py, Delegator.py,
- FileList.py, FormatParagraph.py, FrameViewer.py, GrepDialog.py,
- IOBinding.py, IdleConf.py, IdleHistory.py, MultiScrolledLists.py,
- MultiStatusBar.py, NEWS.txt, ObjectBrowser.py, OldStackViewer.py,
- OutputWindow.py, ParenMatch.py, PathBrowser.py, Percolator.py,
- PyParse.py, PyShell.py, README.txt, ReplaceDialog.py,
- ScriptBinding.py, ScrolledList.py, SearchBinding.py,
- SearchDialog.py, SearchDialogBase.py, SearchEngine.py,
- Separator.py, StackViewer.py, TODO.txt, ToolTip.py, TreeWidget.py,
- UndoDelegator.py, WidgetRedirector.py, WindowList.py, help.txt,
- ZoomHeight.py, config-unix.txt, config-win.txt, config.txt,
- eventparse.py, extend.txt, idle.bat, idle.py, idle.pyw, idlever.py,
- keydefs.py, loader.py, pyclbr.py, tabnanny.py, testcode.py,
- EditorWindow.py, ExecBinding.py, Remote.py, protocol.py, spawn.py,
- Icons/folder.gif, Icons/minusnode.gif, Icons/openfolder.gif,
- Icons/plusnode.gif, Icons/python.gif, Icons/tk.gif: Initial
- revision
-
-2000-08-15 11:13 dscherer
-
- * AutoExpand.py, AutoIndent.py, Bindings.py, CallTipWindow.py,
- CallTips.py, __init__.py, ChangeLog, ClassBrowser.py,
- ColorDelegator.py, ConfigParser.py, Debugger.py, Delegator.py,
- FileList.py, FormatParagraph.py, FrameViewer.py, GrepDialog.py,
- IOBinding.py, IdleConf.py, IdleHistory.py, MultiScrolledLists.py,
- MultiStatusBar.py, NEWS.txt, ObjectBrowser.py, OldStackViewer.py,
- OutputWindow.py, ParenMatch.py, PathBrowser.py, Percolator.py,
- PyParse.py, PyShell.py, README.txt, ReplaceDialog.py,
- ScriptBinding.py, ScrolledList.py, SearchBinding.py,
- SearchDialog.py, SearchDialogBase.py, SearchEngine.py,
- Separator.py, StackViewer.py, TODO.txt, ToolTip.py, TreeWidget.py,
- UndoDelegator.py, WidgetRedirector.py, WindowList.py, help.txt,
- ZoomHeight.py, config-unix.txt, config-win.txt, config.txt,
- eventparse.py, extend.txt, idle.bat, idle.py, idle.pyw, idlever.py,
- keydefs.py, loader.py, pyclbr.py, tabnanny.py, testcode.py,
- EditorWindow.py, ExecBinding.py, Remote.py, protocol.py, spawn.py,
- Icons/folder.gif, Icons/minusnode.gif, Icons/openfolder.gif,
- Icons/plusnode.gif, Icons/python.gif, Icons/tk.gif: Modified IDLE
- from VPython 0.2
-
-
-original IDLE ChangeLog:
-========================
-
-Tue Feb 15 18:08:19 2000 Guido van Rossum <guido@cnri.reston.va.us>
-
- * NEWS.txt: Notice status bar and stack viewer.
-
- * EditorWindow.py: Support for Moshe's status bar.
-
- * MultiStatusBar.py: Status bar code -- by Moshe Zadka.
-
- * OldStackViewer.py:
- Adding the old stack viewer implementation back, for the debugger.
-
- * StackViewer.py: New stack viewer, uses a tree widget.
- (XXX: the debugger doesn't yet use this.)
-
- * WindowList.py:
- Correct a typo and remove an unqualified except that was hiding the error.
-
- * ClassBrowser.py: Add an XXX comment about the ClassBrowser AIP.
-
- * ChangeLog: Updated change log.
-
- * NEWS.txt: News update. Probably incomplete; what else is new?
-
- * README.txt:
- Updated for pending IDLE 0.5 release (still very rough -- just getting
- it out in a more convenient format than CVS).
-
- * TODO.txt: Tiny addition.
-
-Thu Sep 9 14:16:02 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * TODO.txt: A few new TODO entries.
-
-Thu Aug 26 23:06:22 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * Bindings.py: Add Python Documentation entry to Help menu.
-
- * EditorWindow.py:
- Find the help.txt file relative to __file__ or ".", not in sys.path.
- (Suggested by Moshe Zadka, but implemented differently.)
-
- Add <<python-docs>> event which, on Unix, brings up Netscape pointing
- to http://www.python.doc/current/ (a local copy would be nice but its
- location can't be predicted). Windows solution TBD.
-
-Wed Aug 11 14:55:43 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * TreeWidget.py:
- Moshe noticed an inconsistency in his comment, so I'm rephrasing it to
- be clearer.
-
- * TreeWidget.py:
- Patch inspired by Moshe Zadka to search for the Icons directory in the
- same directory as __file__, rather than searching for it along sys.path.
- This works better when idle is a package.
-
-Thu Jul 15 13:11:02 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * TODO.txt: New wishes.
-
-Sat Jul 10 13:17:35 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * IdlePrefs.py:
- Make the color for stderr red (i.e. the standard warning/danger/stop
- color) rather than green. Suggested by Sam Schulenburg.
-
-Fri Jun 25 17:26:34 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * PyShell.py: Close debugger when closing. This may break a cycle.
-
- * Debugger.py: Break cycle on close.
-
- * ClassBrowser.py: Destroy the tree when closing.
-
- * TreeWidget.py: Add destroy() method to recursively destroy a tree.
-
- * PyShell.py: Extend _close() to break cycles.
- Break some other cycles too (and destroy the root when done).
-
- * EditorWindow.py:
- Add _close() method that does the actual cleanup (close() asks the
- user what they want first if there's unsaved stuff, and may cancel).
- It closes more than before.
-
- Add unload_extensions() method to unload all extensions; called from
- _close(). It calls an extension's close() method if it has one.
-
- * Percolator.py: Add close() method that breaks cycles.
-
- * WidgetRedirector.py: Add unregister() method.
- Unregister everything at closing.
- Don't call close() in __del__, rely on explicit call to close().
-
- * IOBinding.py, FormatParagraph.py, CallTips.py:
- Add close() method that breaks a cycle.
-
-Fri Jun 11 15:03:00 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * AutoIndent.py, EditorWindow.py, FormatParagraph.py:
- Tim Peters smart.patch:
-
- EditorWindow.py:
-
- + Added get_tabwidth & set_tabwidth "virtual text" methods, that get/set the
- widget's view of what a tab means.
-
- + Moved TK_TABWIDTH_DEFAULT here from AutoIndent.
-
- + Renamed Mark's get_selection_index to get_selection_indices (sorry, Mark,
- but the name was plain wrong <wink>).
-
- FormatParagraph.py: renamed use of get_selection_index.
-
- AutoIndent.py:
-
- + Moved TK_TABWIDTH_DEFAULT to EditorWindow.
-
- + Rewrote set_indentation_params to use new VTW get/set_tabwidth methods.
-
- + Changed smart_backspace_event to delete whitespace back to closest
- preceding virtual tab stop or real character (note that this may require
- inserting characters if backspacing over a tab!).
-
- + Nuked almost references to the selection tag, in favor of using
- get_selection_indices. The sole exception is in set_region, for which no
- "set_selection" abstraction has yet been agreed upon.
-
- + Had too much fun using the spiffy new features of the format-paragraph
- cmd.
-
-Thu Jun 10 17:48:02 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * FormatParagraph.py:
- Code by Mark Hammond to format paragraphs embedded in comments.
- Read the comments (which I reformatted using the new feature :-)
- for some limitations.
-
- * EditorWindow.py:
- Added abstraction get_selection_index() (Mark Hammond). Also
- reformatted some comment blocks to show off a cool feature I'm about
- to check in next.
-
- * ClassBrowser.py:
- Adapt to the new pyclbr's support of listing top-level functions. If
- this functionality is not present (e.g. when used with a vintage
- Python 1.5.2 installation) top-level functions are not listed.
-
- (Hmm... Any distribution of IDLE 0.5 should probably include a copy
- of the new pyclbr.py!)
-
- * AutoIndent.py:
- Fix off-by-one error in Tim's recent change to comment_region(): the
- list of lines returned by get_region() contains an empty line at the
- end representing the start of the next line, and this shouldn't be
- commented out!
-
- * CallTips.py:
- Mark Hammond writes: Here is another change that allows it to work for
- class creation - tries to locate an __init__ function. Also updated
- the test code to reflect your new "***" change.
-
- * CallTipWindow.py:
- Mark Hammond writes: Tim's suggestion of copying the font for the
- CallTipWindow from the text control makes sense, and actually makes
- the control look better IMO.
-
-Wed Jun 9 20:34:57 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * CallTips.py:
- Append "..." if the appropriate flag (for varargs) in co_flags is set.
- Ditto "***" for kwargs.
-
-Tue Jun 8 13:06:07 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * ReplaceDialog.py:
- Hmm... Tim didn't turn "replace all" into a single undo block.
- I think I like it better if it os, so here.
-
- * ReplaceDialog.py: Tim Peters: made replacement atomic for undo/redo.
-
- * AutoIndent.py: Tim Peters:
-
- + Set usetabs=1. Editing pyclbr.py was driving me nuts <0.6 wink>.
- usetabs=1 is the Emacs pymode default too, and thanks to indentwidth !=
- tabwidth magical usetabs disabling, new files are still created with tabs
- turned off. The only implication is that if you open a file whose first
- indent is a single tab, IDLE will now magically use tabs for that file (and
- set indentwidth to 8). Note that the whole scheme doesn't work right for
- PythonWin, though, since Windows users typically set tabwidth to 4; Mark
- probably has to hide the IDLE algorithm from them (which he already knows).
-
- + Changed comment_region_event to stick "##" in front of every line. The
- "holes" previously left on blank lines were visually confusing (made it
- needlessly hard to figure out what to uncomment later).
-
-Mon Jun 7 15:38:40 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * TreeWidget.py, ObjectBrowser.py:
- Remove unnecessary reference to pyclbr from test() code.
-
- * PyParse.py: Tim Peters:
-
- Smarter logic for finding a parse synch point.
-
- Does a half to a fifth the work in normal cases; don't notice the speedup,
- but makes more breathing room for other extensions.
-
- Speeds terrible cases by at least a factor of 10. "Terrible" == e.g. you put
- """ at the start of Tkinter.py, undo it, zoom to the bottom, and start
- typing in code. Used to take about 8 seconds for ENTER to respond, now some
- large fraction of a second. The new code gets indented correctly, despite
- that it all remains "string colored" until the colorizer catches up (after
- which, ENTER appears instantaneous again).
-
-Fri Jun 4 19:21:19 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * extend.py: Might as well enable CallTips by default.
- If there are too many complaints I'll remove it again or fix it.
-
-Thu Jun 3 14:32:16 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * AutoIndent.py, EditorWindow.py, PyParse.py:
- New offerings by Tim Peters; he writes:
-
- IDLE is now the first Python editor in the Universe not confused by my
- doctest.py <wink>.
-
- As threatened, this defines IDLE's is_char_in_string function as a
- method of EditorWindow. You just need to define one similarly in
- whatever it is you pass as editwin to AutoIndent; looking at the
- EditorWindow.py part of the patch should make this clear.
-
- * GrepDialog.py: Enclose pattern in quotes in status message.
-
- * CallTips.py:
- Mark Hammond fixed some comments and improved the way the tip text is
- constructed.
-
-Wed Jun 2 18:18:57 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * CallTips.py:
- My fix to Mark's code: restore the universal check on <KeyRelease>.
- Always cancel on <Key-Escape> or <ButtonPress>.
-
- * CallTips.py:
- A version that Mark Hammond posted to the newsgroup. Has some newer
- stuff for getting the tip. Had to fix the Key-( and Key-) events
- for Unix. Will have to re-apply my patch for catching KeyRelease and
- ButtonRelease events.
-
- * CallTipWindow.py, CallTips.py:
- Call tips by Mark Hammond (plus tiny fix by me.)
-
- * IdleHistory.py:
- Changes by Mark Hammond: (1) support optional output_sep argument to
- the constructor so he can eliminate the sys.ps2 that PythonWin leaves
- in the source; (2) remove duplicate history items.
-
- * AutoIndent.py:
- Changes by Mark Hammond to allow using IDLE extensions in PythonWin as
- well: make three dialog routines instance variables.
-
- * EditorWindow.py:
- Change by Mark Hammond to allow using IDLE extensions in PythonWin as
- well: make three dialog routines instance variables.
-
-Tue Jun 1 20:06:44 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * AutoIndent.py: Hah! A fix of my own to Tim's code!
- Unix bindings for <<toggle-tabs>> and <<change-indentwidth>> were
- missing, and somehow that meant the events were never generated,
- even though they were in the menu. The new Unix bindings are now
- the same as the Windows bindings (M-t and M-u).
-
- * AutoIndent.py, PyParse.py, PyShell.py: Tim Peters again:
-
- The new version (attached) is fast enough all the time in every real module
- I have <whew!>. You can make it slow by, e.g., creating an open list with
- 5,000 90-character identifiers (+ trailing comma) each on its own line, then
- adding an item to the end -- but that still consumes less than a second on
- my P5-166. Response time in real code appears instantaneous.
-
- Fixed some bugs.
-
- New feature: when hitting ENTER and the cursor is beyond the line's leading
- indentation, whitespace is removed on both sides of the cursor; before
- whitespace was removed only on the left; e.g., assuming the cursor is
- between the comma and the space:
-
- def something(arg1, arg2):
- ^ cursor to the left of here, and hit ENTER
- arg2): # new line used to end up here
- arg2): # but now lines up the way you expect
-
- New hack: AutoIndent has grown a context_use_ps1 Boolean config option,
- defaulting to 0 (false) and set to 1 (only) by PyShell. Reason: handling
- the fancy stuff requires looking backward for a parsing synch point; ps1
- lines are the only sensible thing to look for in a shell window, but are a
- bad thing to look for in a file window (ps1 lines show up in my module
- docstrings often). PythonWin's shell should set this true too.
-
- Persistent problem: strings containing def/class can still screw things up
- completely. No improvement. Simplest workaround is on the user's head, and
- consists of inserting e.g.
-
- def _(): pass
-
- (or any other def/class) after the end of the multiline string that's
- screwing them up. This is especially irksome because IDLE's syntax coloring
- is *not* confused, so when this happens the colors don't match the
- indentation behavior they see.
-
- * AutoIndent.py: Tim Peters again:
-
- [Tim, after adding some bracket smarts to AutoIndent.py]
- > ...
- > What it can't possibly do without reparsing large gobs of text is
- > suggest a reasonable indent level after you've *closed* a bracket
- > left open on some previous line.
- > ...
-
- The attached can, and actually fast enough to use -- most of the time. The
- code is tricky beyond belief to achieve that, but it works so far; e.g.,
-
- return len(string.expandtabs(str[self.stmt_start :
- ^ indents to caret
- i],
- ^ indents to caret
- self.tabwidth)) + 1
- ^ indents to caret
-
- It's about as smart as pymode now, wrt both bracket and backslash
- continuation rules. It does require reparsing large gobs of text, and if it
- happens to find something that looks like a "def" or "class" or sys.ps1
- buried in a multiline string, but didn't suck up enough preceding text to
- see the start of the string, it's completely hosed. I can't repair that --
- it's just too slow to reparse from the start of the file all the time.
-
- AutoIndent has grown a new num_context_lines tuple attribute that controls
- how far to look back, and-- like other params --this could/should be made
- user-overridable at startup and per-file on the fly.
-
- * PyParse.py: New file by Tim Peters:
-
- One new file in the attached, PyParse.py. The LineStudier (whatever it was
- called <wink>) class was removed from AutoIndent; PyParse subsumes its
- functionality.
-
- * AutoIndent.py: Tim Peters keeps revising this module (more to come):
-
- Removed "New tabwidth" menu binding.
-
- Added "a tab means how many spaces?" dialog to block tabify and untabify. I
- think prompting for this is good now: they're usually at-most-once-per-file
- commands, and IDLE can't let them change tabwidth from the Tk default
- anymore, so IDLE can no longer presume to have any idea what a tab means.
-
- Irony: for the purpose of keeping comments aligned via tabs, Tk's
- non-default approach is much nicer than the Emacs/Notepad/Codewright/vi/etc
- approach.
-
- * EditorWindow.py:
- 1. Catch NameError on import (could be raised by case mismatch on Windows).
- 2. No longer need to reset pyclbr cache and show watch cursor when calling
- ClassBrowser -- the ClassBrowser takes care of pyclbr and the TreeWidget
- takes care of the watch cursor.
- 3. Reset the focus to the current window after error message about class
- browser on buffer without filename.
-
- * Icons/minusnode.gif, Icons/plusnode.gif: Missed a few.
-
- * ClassBrowser.py, PathBrowser.py: Rewritten based on TreeWidget.py
-
- * ObjectBrowser.py: Object browser, based on TreeWidget.py.
-
- * TreeWidget.py: Tree widget done right.
-
- * ToolTip.py: As yet unused code for tool tips.
-
- * ScriptBinding.py:
- Ensure sys.argv[0] is the script name on Run Script.
-
- * ZoomHeight.py: Move zoom height functionality to separate function.
-
- * Icons/folder.gif, Icons/openfolder.gif, Icons/python.gif, Icons/tk.gif:
- A few icons used by ../TreeWidget.py and its callers.
-
- * AutoIndent.py: New version by Tim Peters improves block opening test.
-
-Fri May 21 04:46:17 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * Attic/History.py, PyShell.py: Rename History to IdleHistory.
- Add isatty() to pseudo files.
-
- * StackViewer.py: Make initial stack viewer wider
-
- * TODO.txt: New wishes
-
- * AutoIndent.py, EditorWindow.py, PyShell.py:
- Much improved autoindent and handling of tabs,
- by Tim Peters.
-
-Mon May 3 15:49:52 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * AutoIndent.py, EditorWindow.py, FormatParagraph.py, UndoDelegator.py:
- Tim Peters writes:
-
- I'm still unsure, but couldn't stand the virtual event trickery so tried a
- different sin (adding undo_block_start/stop methods to the Text instance in
- EditorWindow.py). Like it or not, it's efficient and works <wink>. Better
- idea?
-
- Give the attached a whirl. Even if you hate the implementation, I think
- you'll like the results. Think I caught all the "block edit" cmds,
- including Format Paragraph, plus subtler ones involving smart indents and
- backspacing.
-
- * WidgetRedirector.py: Tim Peters writes:
-
- [W]hile trying to dope out how redirection works, stumbled into two
- possible glitches. In the first, it doesn't appear to make sense to try to
- rename a command that's already been destroyed; in the second, the name
- "previous" doesn't really bring to mind "ignore the previous value" <wink>.
-
-Fri Apr 30 19:39:25 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * __init__.py: Support for using idle as a package.
-
- * PathBrowser.py:
- Avoid listing files more than once (e.g. foomodule.so has two hits:
- once for foo + module.so, once for foomodule + .so).
-
-Mon Apr 26 22:20:38 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * ChangeLog, ColorDelegator.py, PyShell.py: Tim Peters strikes again:
-
- Ho ho ho -- that's trickier than it sounded! The colorizer is working with
- "line.col" strings instead of Text marks, and the absolute coordinates of
- the point of interest can change across the self.update call (voice of
- baffled experience, when two quick backspaces no longer fooled it, but a
- backspace followed by a quick ENTER did <wink>).
-
- Anyway, the attached appears to do the trick. CPU usage goes way up when
- typing quickly into a long triple-quoted string, but the latency is fine for
- me (a relatively fast typist on a relatively slow machine). Most of the
- changes here are left over from reducing the # of vrbl names to help me
- reason about the logic better; I hope the code is a *little* easier to
-
-Fri Apr 23 14:01:25 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * EditorWindow.py:
- Provide full arguments to __import__ so it works in packagized IDLE.
-
-Thu Apr 22 23:20:17 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * help.txt:
- Bunch of updates necessary due to recent changes; added docs for File
- menu, command line and color preferences.
-
- * Bindings.py: Remove obsolete 'script' menu.
-
- * TODO.txt: Several wishes fulfilled.
-
- * OutputWindow.py:
- Moved classes OnDemandOutputWindow and PseudoFile here,
- from ScriptBinding.py where they are no longer needed.
-
- * ScriptBinding.py:
- Mostly rewritten. Instead of the old Run module and Debug module,
- there are two new commands:
-
- Import module (F5) imports or reloads the module and also adds its
- name to the __main__ namespace. This gets executed in the PyShell
- window under control of its debug settings.
-
- Run script (Control-F5) is similar but executes the contents of the
- file directly in the __main__ namespace.
-
- * PyShell.py: Nits: document use of $IDLESTARTUP; display idle version
-
- * idlever.py: New version to celebrate new command line
-
- * OutputWindow.py: Added flush(), for completeness.
-
- * PyShell.py:
- A lot of changes to make the command line more useful. You can now do:
- idle.py -e file ... -- to edit files
- idle.py script arg ... -- to run a script
- idle.py -c cmd arg ... -- to run a command
- Other options, see also the usage message (also new!) for more details:
- -d -- enable debugger
- -s -- run $IDLESTARTUP or $PYTHONSTARTUP
- -t title -- set Python Shell window's title
- sys.argv is set accordingly, unless -e is used.
- sys.path is absolutized, and all relevant paths are inserted into it.
-
- Other changes:
- - the environment in which commands are executed is now the
- __main__ module
- - explicitly save sys.stdout etc., don't restore from sys.__stdout__
- - new interpreter methods execsource(), execfile(), stuffsource()
- - a few small nits
-
- * TODO.txt:
- Some more TODO items. Made up my mind about command line args,
- Run/Import, __main__.
-
- * ColorDelegator.py:
- Super-elegant patch by Tim Peters that speeds up colorization
- dramatically (up to 15 times he claims). Works by reading more than
- one line at a time, up to 100-line chunks (starting with one line and
- then doubling up to the limit). On a typical machine (e.g. Tim's
- P5-166) this doesn't reduce interactive responsiveness in a noticeable
- way.
-
-Wed Apr 21 15:49:34 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * ColorDelegator.py:
- Patch by Tim Peters to speed up colorizing of big multiline strings.
-
-Tue Apr 20 17:32:52 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * extend.txt:
- For an event 'foo-bar', the corresponding method must be called
- foo_bar_event(). Therefore, fix the references to zoom_height() in
- the example.
-
- * IdlePrefs.py: Restored the original IDLE color scheme.
-
- * PyShell.py, IdlePrefs.py, ColorDelegator.py, EditorWindow.py:
- Color preferences code by Loren Luke (massaged by me somewhat)
-
- * SearchEngine.py:
- Patch by Mark Favas: it fixes the search engine behaviour where an
- unsuccessful search wraps around and re-searches that part of the file
- between the start of the search and the end of the file - only really
- an issue for very large files, but... (also removes a redundant
- m.span() call).
-
-Mon Apr 19 16:26:02 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * TODO.txt: A few wishes are now fulfilled.
-
- * AutoIndent.py: Tim Peters implements some of my wishes:
-
- o Makes the tab key intelligently insert spaces when appropriate
- (see Help list banter twixt David Ascher and me; idea stolen from
- every other editor on earth <wink>).
-
- o newline_and_indent_event trims trailing whitespace on the old
- line (pymode and Codewright).
-
- o newline_and_indent_event no longer fooled by trailing whitespace or
- comment after ":" (pymode, PTUI).
-
- o newline_and_indent_event now reduces the new line's indentation after
- return, break, continue, raise and pass stmts (pymode).
-
- The last two are easy to fool in the presence of strings &
- continuations, but pymode requires Emacs's high-powered C parsing
- functions to avoid that in finite time.
-
-======================================================================
- Python release 1.5.2c1, IDLE version 0.4
-======================================================================
-
-Wed Apr 7 18:41:59 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * README.txt, NEWS.txt: New version.
-
- * idlever.py: Version bump awaiting impending new release.
- (Not much has changed :-( )
-
-Mon Mar 29 14:52:28 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * ScriptBinding.py, PyShell.py:
- At Tim Peters' recommendation, add a dummy flush() method to
- PseudoFile.
-
-Thu Mar 11 23:21:23 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * PathBrowser.py: Don't crash when sys.path contains an empty string.
-
- * Attic/Outline.py: This file was never supposed to be part of IDLE.
-
- * PathBrowser.py:
- - Don't crash in the case where a superclass is a string instead of a
- pyclbr.Class object; this can happen when the superclass is
- unrecognizable (to pyclbr), e.g. when module renaming is used.
-
- - Show a watch cursor when calling pyclbr (since it may take a while
- recursively parsing imported modules!).
-
-Wed Mar 10 05:18:02 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * EditorWindow.py, Bindings.py: Add PathBrowser to File module
-
- * PathBrowser.py: "Path browser" - 4 scrolled lists displaying:
- directories on sys.path
- modules in selected directory
- classes in selected module
- methods of selected class
-
- Sinlge clicking in a directory, module or class item updates the next
- column with info about the selected item. Double clicking in a
- module, class or method item opens the file (and selects the clicked
- item if it is a class or method).
-
- I guess eventually I should be using a tree widget for this, but the
- ones I've seen don't work well enough, so for now I use the old
- Smalltalk or NeXT style multi-column hierarchical browser.
-
- * MultiScrolledLists.py:
- New utility: multiple scrolled lists in parallel
-
- * ScrolledList.py: - White background.
- - Display "(None)" (or text of your choosing) when empty.
- - Don't set the focus.
-
-======================================================================
- Python release 1.5.2b2, IDLE version 0.3
-======================================================================
-
-Wed Feb 17 22:47:41 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * NEWS.txt: News in 0.3.
-
- * README.txt, idlever.py: Bump version to 0.3.
-
- * EditorWindow.py:
- After all, we don't need to call the callbacks ourselves!
-
- * WindowList.py:
- When deleting, call the callbacks *after* deleting the window from our list!
-
- * EditorWindow.py:
- Fix up the Windows menu via the new callback mechanism instead of
- depending on menu post commands (which don't work when the menu is
- torn off).
-
- * WindowList.py:
- Support callbacks to patch up Windows menus everywhere.
-
- * ChangeLog: Oh, why not. Checking in the Emacs-generated change log.
-
-Tue Feb 16 22:34:17 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * ScriptBinding.py:
- Only pop up the stack viewer when requested in the Debug menu.
-
-Mon Feb 8 22:27:49 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * WindowList.py: Don't crash if a window no longer exists.
-
- * TODO.txt: Restructured a bit.
-
-Mon Feb 1 23:06:17 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * PyShell.py: Add current dir or paths of file args to sys.path.
-
- * Debugger.py: Add canonic() function -- for brand new bdb.py feature.
-
- * StackViewer.py: Protect against accessing an empty stack.
-
-Fri Jan 29 20:44:45 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * ZoomHeight.py:
- Use only the height to decide whether to zoom in or out.
-
-Thu Jan 28 22:24:30 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * EditorWindow.py, FileList.py:
- Make sure the Tcl variables are shared between windows.
-
- * PyShell.py, EditorWindow.py, Bindings.py:
- Move menu/key binding code from Bindings.py to EditorWindow.py,
- with changed APIs -- it makes much more sense there.
- Also add a new feature: if the first character of a menu label is
- a '!', it gets a checkbox. Checkboxes are bound to Boolean Tcl variables
- that can be accessed through the new getvar/setvar/getrawvar API;
- the variable is named after the event to which the menu is bound.
-
- * Debugger.py: Add Quit button to the debugger window.
-
- * SearchDialog.py:
- When find_again() finds exactly the current selection, it's a failure.
-
- * idle.py, Attic/idle: Rename idle -> idle.py
-
-Mon Jan 18 15:18:57 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * EditorWindow.py, WindowList.py: Only deiconify when iconic.
-
- * TODO.txt: Misc
-
-Tue Jan 12 22:14:34 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * testcode.py, Attic/test.py:
- Renamed test.py to testcode.py so one can import Python's
- test package from inside IDLE. (Suggested by Jack Jansen.)
-
- * EditorWindow.py, ColorDelegator.py:
- Hack to close a window that is colorizing.
-
- * Separator.py: Vladimir Marangozov's patch:
- The separator dances too much and seems to jump by arbitrary amounts
- in arbitrary directions when I try to move it for resizing the frames.
- This patch makes it more quiet.
-
-Mon Jan 11 14:52:40 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * TODO.txt: Some requests have been fulfilled.
-
- * EditorWindow.py:
- Set the cursor to a watch when opening the class browser (which may
- take quite a while, browsing multiple files).
-
- Newer, better center() -- but assumes no wrapping.
-
- * SearchBinding.py:
- Got rid of debug print statement in goto_line_event().
-
- * ScriptBinding.py:
- I think I like it better if it prints the traceback even when it displays
- the stack viewer.
-
- * Debugger.py: Bind ESC to close-window.
-
- * ClassBrowser.py: Use a HSeparator between the classes and the items.
- Make the list of classes wider by default (40 chars).
- Bind ESC to close-window.
-
- * Separator.py:
- Separator classes (draggable divider between two panes).
-
-Sat Jan 9 22:01:33 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * WindowList.py:
- Don't traceback when wakeup() is called when the window has been destroyed.
- This can happen when a torn-of Windows menu references closed windows.
- And Tim Peters claims that the Windows menu is his favorite to tear off...
-
- * EditorWindow.py: Allow tearing off of the Windows menu.
-
- * StackViewer.py: Close on ESC.
-
- * help.txt: Updated a bunch of things (it was mostly still 0.1!)
-
- * extend.py: Added ScriptBinding to standard bindings.
-
- * ScriptBinding.py:
- This now actually works. See doc string. It can run a module (i.e.
- import or reload) or debug it (same with debugger control). Output
- goes to a fresh output window, only created when needed.
-
-======================================================================
- Python release 1.5.2b1, IDLE version 0.2
-======================================================================
-
-Fri Jan 8 17:26:02 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * README.txt, NEWS.txt: What's new in this release.
-
- * Bindings.py, PyShell.py:
- Paul Prescod's patches to allow the stack viewer to pop up when a
- traceback is printed.
-
-Thu Jan 7 00:12:15 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * FormatParagraph.py:
- Change paragraph width limit to 70 (like Emacs M-Q).
-
- * README.txt:
- Separating TODO from README. Slight reformulation of features. No
- exact release date.
-
- * TODO.txt: Separating TODO from README.
-
-Mon Jan 4 21:19:09 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * FormatParagraph.py:
- Hm. There was a boundary condition error at the end of the file too.
-
- * SearchBinding.py: Hm. Add Unix binding for replace, too.
-
- * keydefs.py: Ran eventparse.py again.
-
- * FormatParagraph.py: Added Unix Meta-q key binding;
- fix find_paragraph when at start of file.
-
- * AutoExpand.py: Added Meta-/ binding for Unix as alt for Alt-/.
-
- * SearchBinding.py:
- Add unix binding for grep (otherwise the menu entry doesn't work!)
-
- * ZoomHeight.py: Adjusted Unix height to work with fvwm96. :=(
-
- * GrepDialog.py: Need to import sys!
-
- * help.txt, extend.txt, README.txt: Formatted some paragraphs
-
- * extend.py, FormatParagraph.py:
- Add new extension to reformat a (text) paragraph.
-
- * ZoomHeight.py: Typo in Win specific height setting.
-
-Sun Jan 3 00:47:35 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * AutoIndent.py: Added something like Tim Peters' backspace patch.
-
- * ZoomHeight.py: Adapted to Unix (i.e., more hardcoded constants).
-
-Sat Jan 2 21:28:54 1999 Guido van Rossum <guido@cnri.reston.va.us>
-
- * keydefs.py, idlever.py, idle.pyw, idle.bat, help.txt, extend.txt, extend.py, eventparse.py, ZoomHeight.py, WindowList.py, UndoDelegator.py, StackViewer.py, SearchEngine.py, SearchDialogBase.py, SearchDialog.py, ScrolledList.py, SearchBinding.py, ScriptBinding.py, ReplaceDialog.py, Attic/README, README.txt, PyShell.py, Attic/PopupMenu.py, OutputWindow.py, IOBinding.py, Attic/HelpWindow.py, History.py, GrepDialog.py, FileList.py, FrameViewer.py, EditorWindow.py, Debugger.py, Delegator.py, ColorDelegator.py, Bindings.py, ClassBrowser.py, AutoExpand.py, AutoIndent.py:
- Checking in IDLE 0.2.
-
- Much has changed -- too much, in fact, to write down.
- The big news is that there's a standard way to write IDLE extensions;
- see extend.txt. Some sample extensions have been provided, and
- some existing code has been converted to extensions. Probably the
- biggest new user feature is a new search dialog with more options,
- search and replace, and even search in files (grep).
-
- This is exactly as downloaded from my laptop after returning
- from the holidays -- it hasn't even been tested on Unix yet.
-
-Fri Dec 18 15:52:54 1998 Guido van Rossum <guido@cnri.reston.va.us>
-
- * FileList.py, ClassBrowser.py:
- Fix the class browser to work even when the file is not on sys.path.
-
-Tue Dec 8 20:39:36 1998 Guido van Rossum <guido@cnri.reston.va.us>
-
- * Attic/turtle.py: Moved to Python 1.5.2/Lib
-
-Fri Nov 27 03:19:20 1998 Guido van Rossum <guido@cnri.reston.va.us>
-
- * help.txt: Typo
-
- * EditorWindow.py, FileList.py: Support underlining of menu labels
-
- * Bindings.py:
- New approach, separate tables for menus (platform-independent) and key
- definitions (platform-specific), and generating accelerator strings
- automatically from the key definitions.
-
-Mon Nov 16 18:37:42 1998 Guido van Rossum <guido@cnri.reston.va.us>
-
- * Attic/README: Clarify portability and main program.
-
- * Attic/README: Added intro for 0.1 release and append Grail notes.
-
-Mon Oct 26 18:49:00 1998 Guido van Rossum <guido@cnri.reston.va.us>
-
- * Attic/turtle.py: root is now a global called _root
-
-Sat Oct 24 16:38:38 1998 Guido van Rossum <guido@cnri.reston.va.us>
-
- * Attic/turtle.py: Raise the root window on reset().
- Different action on WM_DELETE_WINDOW is more likely to do the right thing,
- allowing us to destroy old windows.
-
- * Attic/turtle.py:
- Split the goto() function in two: _goto() is the internal one,
- using Canvas coordinates, and goto() uses turtle coordinates
- and accepts variable argument lists.
-
- * Attic/turtle.py: Cope with destruction of the window
-
- * Attic/turtle.py: Turtle graphics
-
- * Debugger.py: Use of Breakpoint class should be bdb.Breakpoint.
-
-Mon Oct 19 03:33:40 1998 Guido van Rossum <guido@cnri.reston.va.us>
-
- * SearchBinding.py:
- Speed up the search a bit -- don't drag a mark around...
-
- * PyShell.py:
- Change our special entries from <console#N> to <pyshell#N>.
- Patch linecache.checkcache() to keep our special entries alive.
- Add popup menu to all editor windows to set a breakpoint.
-
- * Debugger.py:
- Use and pass through the 'force' flag to set_dict() where appropriate.
- Default source and globals checkboxes to false.
- Don't interact in user_return().
- Add primitive set_breakpoint() method.
-
- * ColorDelegator.py:
- Raise priority of 'sel' tag so its foreground (on Windows) will take
- priority over text colorization (which on Windows is almost the
- same color as the selection background).
-
- Define a tag and color for breakpoints ("BREAK").
-
- * Attic/PopupMenu.py: Disable "Open stack viewer" and "help" commands.
-
- * StackViewer.py:
- Add optional 'force' argument (default 0) to load_dict().
- If set, redo the display even if it's the same dict.
-
-Fri Oct 16 21:10:12 1998 Guido van Rossum <guido@cnri.reston.va.us>
-
- * StackViewer.py: Do nothing when loading the same dict as before.
-
- * PyShell.py: Details for debugger interface.
-
- * Debugger.py:
- Restructured and more consistent. Save checkboxes across instantiations.
-
- * EditorWindow.py, Attic/README, Bindings.py:
- Get rid of conflicting ^X binding. Use ^W.
-
- * Debugger.py, StackViewer.py:
- Debugger can now show local and global variables.
-
- * Debugger.py: Oops
-
- * Debugger.py, PyShell.py: Better debugger support (show stack etc).
-
- * Attic/PopupMenu.py: Follow renames in StackViewer module
-
- * StackViewer.py:
- Rename classes to StackViewer (the widget) and StackBrowser (the toplevel).
-
- * ScrolledList.py: Add close() method
-
- * EditorWindow.py: Clarify 'Open Module' dialog text
-
- * StackViewer.py: Restructured into a browser and a widget.
-
-Thu Oct 15 23:27:08 1998 Guido van Rossum <guido@cnri.reston.va.us>
-
- * ClassBrowser.py, ScrolledList.py:
- Generalized the scrolled list which is the base for the class and
- method browser into a separate class in its own module.
-
- * Attic/test.py: Cosmetic change
-
- * Debugger.py: Don't show function name if there is none
-
-Wed Oct 14 03:43:05 1998 Guido van Rossum <guido@cnri.reston.va.us>
-
- * Debugger.py, PyShell.py: Polish the Debugger GUI a bit.
- Closing it now also does the right thing.
-
-Tue Oct 13 23:51:13 1998 Guido van Rossum <guido@cnri.reston.va.us>
-
- * Debugger.py, PyShell.py, Bindings.py:
- Ad primitive debugger interface (so far it will step and show you the
- source, but it doesn't yet show the stack).
-
- * Attic/README: Misc
-
- * StackViewer.py: Whoops -- referenced self.top before it was set.
-
- * help.txt: Added history and completion commands.
-
- * help.txt: Updated
-
- * FileList.py: Add class browser functionality.
-
- * StackViewer.py:
- Add a close() method and bind to WM_DELETE_WINDOW protocol
-
- * PyShell.py: Clear the linecache before printing a traceback
-
- * Bindings.py: Added class browser binding.
-
- * ClassBrowser.py: Much improved, much left to do.
-
- * PyShell.py: Make the return key do what I mean more often.
-
- * ClassBrowser.py:
- Adding the beginnings of a Class browser. Incomplete, yet.
-
- * EditorWindow.py, Bindings.py:
- Add new command, "Open module". You select or type a module name,
- and it opens the source.
-
-Mon Oct 12 23:59:27 1998 Guido van Rossum <guido@cnri.reston.va.us>
-
- * PyShell.py: Subsume functionality from Popup menu in Debug menu.
- Other stuff so the PyShell window can be resurrected from the Windows menu.
-
- * FileList.py: Get rid of PopUp menu.
- Create a simple Windows menu. (Imperfect when Untitled windows exist.)
- Add wakeup() method: deiconify, raise, focus.
-
- * EditorWindow.py: Generalize menu creation.
-
- * Bindings.py: Add Debug and Help menu items.
-
- * EditorWindow.py: Added a menu bar to every window.
-
- * Bindings.py: Add menu configuration to the event configuration.
-
- * Attic/PopupMenu.py: Pass a root to the help window.
-
- * SearchBinding.py:
- Add parent argument to 'to to line number' dialog box.
-
-Sat Oct 10 19:15:32 1998 Guido van Rossum <guido@cnri.reston.va.us>
-
- * StackViewer.py:
- Add a label at the top showing (very basic) help for the stack viewer.
- Add a label at the bottom showing the exception info.
-
- * Attic/test.py, Attic/idle: Add Unix main script and test program.
-
- * idle.pyw, help.txt, WidgetRedirector.py, UndoDelegator.py, StackViewer.py, SearchBinding.py, Attic/README, PyShell.py, Attic/PopupMenu.py, Percolator.py, Outline.py, IOBinding.py, History.py, Attic/HelpWindow.py, FrameViewer.py, FileList.py, EditorWindow.py, Delegator.py, ColorDelegator.py, Bindings.py, AutoIndent.py, AutoExpand.py:
- Initial checking of Tk-based Python IDE.
- Features: text editor with syntax coloring and undo;
- subclassed into interactive Python shell which adds history.
-
diff --git a/sys/lib/python/idlelib/ClassBrowser.py b/sys/lib/python/idlelib/ClassBrowser.py
deleted file mode 100644
index e5a60a513..000000000
--- a/sys/lib/python/idlelib/ClassBrowser.py
+++ /dev/null
@@ -1,221 +0,0 @@
-"""Class browser.
-
-XXX TO DO:
-
-- reparse when source changed (maybe just a button would be OK?)
- (or recheck on window popup)
-- add popup menu with more options (e.g. doc strings, base classes, imports)
-- show function argument list? (have to do pattern matching on source)
-- should the classes and methods lists also be in the module's menu bar?
-- add base classes to class browser tree
-"""
-
-import os
-import sys
-import pyclbr
-
-import PyShell
-from WindowList import ListedToplevel
-from TreeWidget import TreeNode, TreeItem, ScrolledCanvas
-from configHandler import idleConf
-
-class ClassBrowser:
-
- def __init__(self, flist, name, path):
- # XXX This API should change, if the file doesn't end in ".py"
- # XXX the code here is bogus!
- self.name = name
- self.file = os.path.join(path[0], self.name + ".py")
- self.init(flist)
-
- def close(self, event=None):
- self.top.destroy()
- self.node.destroy()
-
- def init(self, flist):
- self.flist = flist
- # reset pyclbr
- pyclbr._modules.clear()
- # create top
- self.top = top = ListedToplevel(flist.root)
- top.protocol("WM_DELETE_WINDOW", self.close)
- top.bind("<Escape>", self.close)
- self.settitle()
- top.focus_set()
- # create scrolled canvas
- theme = idleConf.GetOption('main','Theme','name')
- background = idleConf.GetHighlight(theme, 'normal')['background']
- sc = ScrolledCanvas(top, bg=background, highlightthickness=0, takefocus=1)
- sc.frame.pack(expand=1, fill="both")
- item = self.rootnode()
- self.node = node = TreeNode(sc.canvas, None, item)
- node.update()
- node.expand()
-
- def settitle(self):
- self.top.wm_title("Class Browser - " + self.name)
- self.top.wm_iconname("Class Browser")
-
- def rootnode(self):
- return ModuleBrowserTreeItem(self.file)
-
-class ModuleBrowserTreeItem(TreeItem):
-
- def __init__(self, file):
- self.file = file
-
- def GetText(self):
- return os.path.basename(self.file)
-
- def GetIconName(self):
- return "python"
-
- def GetSubList(self):
- sublist = []
- for name in self.listclasses():
- item = ClassBrowserTreeItem(name, self.classes, self.file)
- sublist.append(item)
- return sublist
-
- def OnDoubleClick(self):
- if os.path.normcase(self.file[-3:]) != ".py":
- return
- if not os.path.exists(self.file):
- return
- PyShell.flist.open(self.file)
-
- def IsExpandable(self):
- return os.path.normcase(self.file[-3:]) == ".py"
-
- def listclasses(self):
- dir, file = os.path.split(self.file)
- name, ext = os.path.splitext(file)
- if os.path.normcase(ext) != ".py":
- return []
- try:
- dict = pyclbr.readmodule_ex(name, [dir] + sys.path)
- except ImportError, msg:
- return []
- items = []
- self.classes = {}
- for key, cl in dict.items():
- if cl.module == name:
- s = key
- if hasattr(cl, 'super') and cl.super:
- supers = []
- for sup in cl.super:
- if type(sup) is type(''):
- sname = sup
- else:
- sname = sup.name
- if sup.module != cl.module:
- sname = "%s.%s" % (sup.module, sname)
- supers.append(sname)
- s = s + "(%s)" % ", ".join(supers)
- items.append((cl.lineno, s))
- self.classes[s] = cl
- items.sort()
- list = []
- for item, s in items:
- list.append(s)
- return list
-
-class ClassBrowserTreeItem(TreeItem):
-
- def __init__(self, name, classes, file):
- self.name = name
- self.classes = classes
- self.file = file
- try:
- self.cl = self.classes[self.name]
- except (IndexError, KeyError):
- self.cl = None
- self.isfunction = isinstance(self.cl, pyclbr.Function)
-
- def GetText(self):
- if self.isfunction:
- return "def " + self.name + "(...)"
- else:
- return "class " + self.name
-
- def GetIconName(self):
- if self.isfunction:
- return "python"
- else:
- return "folder"
-
- def IsExpandable(self):
- if self.cl:
- try:
- return not not self.cl.methods
- except AttributeError:
- return False
-
- def GetSubList(self):
- if not self.cl:
- return []
- sublist = []
- for name in self.listmethods():
- item = MethodBrowserTreeItem(name, self.cl, self.file)
- sublist.append(item)
- return sublist
-
- def OnDoubleClick(self):
- if not os.path.exists(self.file):
- return
- edit = PyShell.flist.open(self.file)
- if hasattr(self.cl, 'lineno'):
- lineno = self.cl.lineno
- edit.gotoline(lineno)
-
- def listmethods(self):
- if not self.cl:
- return []
- items = []
- for name, lineno in self.cl.methods.items():
- items.append((lineno, name))
- items.sort()
- list = []
- for item, name in items:
- list.append(name)
- return list
-
-class MethodBrowserTreeItem(TreeItem):
-
- def __init__(self, name, cl, file):
- self.name = name
- self.cl = cl
- self.file = file
-
- def GetText(self):
- return "def " + self.name + "(...)"
-
- def GetIconName(self):
- return "python" # XXX
-
- def IsExpandable(self):
- return 0
-
- def OnDoubleClick(self):
- if not os.path.exists(self.file):
- return
- edit = PyShell.flist.open(self.file)
- edit.gotoline(self.cl.methods[self.name])
-
-def main():
- try:
- file = __file__
- except NameError:
- file = sys.argv[0]
- if sys.argv[1:]:
- file = sys.argv[1]
- else:
- file = sys.argv[0]
- dir, file = os.path.split(file)
- name = os.path.splitext(file)[0]
- ClassBrowser(PyShell.flist, name, [dir])
- if sys.stdin is sys.__stdin__:
- mainloop()
-
-if __name__ == "__main__":
- main()
diff --git a/sys/lib/python/idlelib/CodeContext.py b/sys/lib/python/idlelib/CodeContext.py
deleted file mode 100644
index 74d5b7024..000000000
--- a/sys/lib/python/idlelib/CodeContext.py
+++ /dev/null
@@ -1,167 +0,0 @@
-"""CodeContext - Extension to display the block context above the edit window
-
-Once code has scrolled off the top of a window, it can be difficult to
-determine which block you are in. This extension implements a pane at the top
-of each IDLE edit window which provides block structure hints. These hints are
-the lines which contain the block opening keywords, e.g. 'if', for the
-enclosing block. The number of hint lines is determined by the numlines
-variable in the CodeContext section of config-extensions.def. Lines which do
-not open blocks are not shown in the context hints pane.
-
-"""
-import Tkinter
-from configHandler import idleConf
-import re
-from sys import maxint as INFINITY
-
-BLOCKOPENERS = set(["class", "def", "elif", "else", "except", "finally", "for",
- "if", "try", "while", "with"])
-UPDATEINTERVAL = 100 # millisec
-FONTUPDATEINTERVAL = 1000 # millisec
-
-getspacesfirstword =\
- lambda s, c=re.compile(r"^(\s*)(\w*)"): c.match(s).groups()
-
-class CodeContext:
- menudefs = [('options', [('!Code Conte_xt', '<<toggle-code-context>>')])]
-
- context_depth = idleConf.GetOption("extensions", "CodeContext",
- "numlines", type="int", default=3)
- bgcolor = idleConf.GetOption("extensions", "CodeContext",
- "bgcolor", type="str", default="LightGray")
- fgcolor = idleConf.GetOption("extensions", "CodeContext",
- "fgcolor", type="str", default="Black")
- def __init__(self, editwin):
- self.editwin = editwin
- self.text = editwin.text
- self.textfont = self.text["font"]
- self.label = None
- # self.info is a list of (line number, indent level, line text, block
- # keyword) tuples providing the block structure associated with
- # self.topvisible (the linenumber of the line displayed at the top of
- # the edit window). self.info[0] is initialized as a 'dummy' line which
- # starts the toplevel 'block' of the module.
- self.info = [(0, -1, "", False)]
- self.topvisible = 1
- visible = idleConf.GetOption("extensions", "CodeContext",
- "visible", type="bool", default=False)
- if visible:
- self.toggle_code_context_event()
- self.editwin.setvar('<<toggle-code-context>>', True)
- # Start two update cycles, one for context lines, one for font changes.
- self.text.after(UPDATEINTERVAL, self.timer_event)
- self.text.after(FONTUPDATEINTERVAL, self.font_timer_event)
-
- def toggle_code_context_event(self, event=None):
- if not self.label:
- self.pad_frame = Tkinter.Frame(self.editwin.top,
- bg=self.bgcolor, border=2,
- relief="sunken")
- self.label = Tkinter.Label(self.pad_frame,
- text="\n" * (self.context_depth - 1),
- anchor="w", justify="left",
- font=self.textfont,
- bg=self.bgcolor, fg=self.fgcolor,
- border=0,
- width=1, # Don't request more than we get
- )
- self.label.pack(side="top", fill="x", expand=True,
- padx=4, pady=0)
- self.pad_frame.pack(side="top", fill="x", expand=False,
- padx=0, pady=0,
- after=self.editwin.status_bar)
- else:
- self.label.destroy()
- self.pad_frame.destroy()
- self.label = None
- idleConf.SetOption("extensions", "CodeContext", "visible",
- str(self.label is not None))
- idleConf.SaveUserCfgFiles()
-
- def get_line_info(self, linenum):
- """Get the line indent value, text, and any block start keyword
-
- If the line does not start a block, the keyword value is False.
- The indentation of empty lines (or comment lines) is INFINITY.
-
- """
- text = self.text.get("%d.0" % linenum, "%d.end" % linenum)
- spaces, firstword = getspacesfirstword(text)
- opener = firstword in BLOCKOPENERS and firstword
- if len(text) == len(spaces) or text[len(spaces)] == '#':
- indent = INFINITY
- else:
- indent = len(spaces)
- return indent, text, opener
-
- def get_context(self, new_topvisible, stopline=1, stopindent=0):
- """Get context lines, starting at new_topvisible and working backwards.
-
- Stop when stopline or stopindent is reached. Return a tuple of context
- data and the indent level at the top of the region inspected.
-
- """
- assert stopline > 0
- lines = []
- # The indentation level we are currently in:
- lastindent = INFINITY
- # For a line to be interesting, it must begin with a block opening
- # keyword, and have less indentation than lastindent.
- for linenum in xrange(new_topvisible, stopline-1, -1):
- indent, text, opener = self.get_line_info(linenum)
- if indent < lastindent:
- lastindent = indent
- if opener in ("else", "elif"):
- # We also show the if statement
- lastindent += 1
- if opener and linenum < new_topvisible and indent >= stopindent:
- lines.append((linenum, indent, text, opener))
- if lastindent <= stopindent:
- break
- lines.reverse()
- return lines, lastindent
-
- def update_code_context(self):
- """Update context information and lines visible in the context pane.
-
- """
- new_topvisible = int(self.text.index("@0,0").split('.')[0])
- if self.topvisible == new_topvisible: # haven't scrolled
- return
- if self.topvisible < new_topvisible: # scroll down
- lines, lastindent = self.get_context(new_topvisible,
- self.topvisible)
- # retain only context info applicable to the region
- # between topvisible and new_topvisible:
- while self.info[-1][1] >= lastindent:
- del self.info[-1]
- elif self.topvisible > new_topvisible: # scroll up
- stopindent = self.info[-1][1] + 1
- # retain only context info associated
- # with lines above new_topvisible:
- while self.info[-1][0] >= new_topvisible:
- stopindent = self.info[-1][1]
- del self.info[-1]
- lines, lastindent = self.get_context(new_topvisible,
- self.info[-1][0]+1,
- stopindent)
- self.info.extend(lines)
- self.topvisible = new_topvisible
-
- # empty lines in context pane:
- context_strings = [""] * max(0, self.context_depth - len(self.info))
- # followed by the context hint lines:
- context_strings += [x[2] for x in self.info[-self.context_depth:]]
- self.label["text"] = '\n'.join(context_strings)
-
- def timer_event(self):
- if self.label:
- self.update_code_context()
- self.text.after(UPDATEINTERVAL, self.timer_event)
-
- def font_timer_event(self):
- newtextfont = self.text["font"]
- if self.label and newtextfont != self.textfont:
- self.textfont = newtextfont
- self.label["font"] = self.textfont
- self.text.after(FONTUPDATEINTERVAL, self.font_timer_event)
diff --git a/sys/lib/python/idlelib/ColorDelegator.py b/sys/lib/python/idlelib/ColorDelegator.py
deleted file mode 100644
index e55f9e6b7..000000000
--- a/sys/lib/python/idlelib/ColorDelegator.py
+++ /dev/null
@@ -1,263 +0,0 @@
-import time
-import re
-import keyword
-import __builtin__
-from Tkinter import *
-from Delegator import Delegator
-from configHandler import idleConf
-
-DEBUG = False
-
-def any(name, alternates):
- "Return a named group pattern matching list of alternates."
- return "(?P<%s>" % name + "|".join(alternates) + ")"
-
-def make_pat():
- kw = r"\b" + any("KEYWORD", keyword.kwlist) + r"\b"
- builtinlist = [str(name) for name in dir(__builtin__)
- if not name.startswith('_')]
- # self.file = file("file") :
- # 1st 'file' colorized normal, 2nd as builtin, 3rd as string
- builtin = r"([^.'\"\\#]\b|^)" + any("BUILTIN", builtinlist) + r"\b"
- comment = any("COMMENT", [r"#[^\n]*"])
- sqstring = r"(\b[rRuU])?'[^'\\\n]*(\\.[^'\\\n]*)*'?"
- dqstring = r'(\b[rRuU])?"[^"\\\n]*(\\.[^"\\\n]*)*"?'
- sq3string = r"(\b[rRuU])?'''[^'\\]*((\\.|'(?!''))[^'\\]*)*(''')?"
- dq3string = r'(\b[rRuU])?"""[^"\\]*((\\.|"(?!""))[^"\\]*)*(""")?'
- string = any("STRING", [sq3string, dq3string, sqstring, dqstring])
- return kw + "|" + builtin + "|" + comment + "|" + string +\
- "|" + any("SYNC", [r"\n"])
-
-prog = re.compile(make_pat(), re.S)
-idprog = re.compile(r"\s+(\w+)", re.S)
-asprog = re.compile(r".*?\b(as)\b")
-
-class ColorDelegator(Delegator):
-
- def __init__(self):
- Delegator.__init__(self)
- self.prog = prog
- self.idprog = idprog
- self.asprog = asprog
- self.LoadTagDefs()
-
- def setdelegate(self, delegate):
- if self.delegate is not None:
- self.unbind("<<toggle-auto-coloring>>")
- Delegator.setdelegate(self, delegate)
- if delegate is not None:
- self.config_colors()
- self.bind("<<toggle-auto-coloring>>", self.toggle_colorize_event)
- self.notify_range("1.0", "end")
-
- def config_colors(self):
- for tag, cnf in self.tagdefs.items():
- if cnf:
- self.tag_configure(tag, **cnf)
- self.tag_raise('sel')
-
- def LoadTagDefs(self):
- theme = idleConf.GetOption('main','Theme','name')
- self.tagdefs = {
- "COMMENT": idleConf.GetHighlight(theme, "comment"),
- "KEYWORD": idleConf.GetHighlight(theme, "keyword"),
- "BUILTIN": idleConf.GetHighlight(theme, "builtin"),
- "STRING": idleConf.GetHighlight(theme, "string"),
- "DEFINITION": idleConf.GetHighlight(theme, "definition"),
- "SYNC": {'background':None,'foreground':None},
- "TODO": {'background':None,'foreground':None},
- "BREAK": idleConf.GetHighlight(theme, "break"),
- "ERROR": idleConf.GetHighlight(theme, "error"),
- # The following is used by ReplaceDialog:
- "hit": idleConf.GetHighlight(theme, "hit"),
- }
-
- if DEBUG: print 'tagdefs',self.tagdefs
-
- def insert(self, index, chars, tags=None):
- index = self.index(index)
- self.delegate.insert(index, chars, tags)
- self.notify_range(index, index + "+%dc" % len(chars))
-
- def delete(self, index1, index2=None):
- index1 = self.index(index1)
- self.delegate.delete(index1, index2)
- self.notify_range(index1)
-
- after_id = None
- allow_colorizing = True
- colorizing = False
-
- def notify_range(self, index1, index2=None):
- self.tag_add("TODO", index1, index2)
- if self.after_id:
- if DEBUG: print "colorizing already scheduled"
- return
- if self.colorizing:
- self.stop_colorizing = True
- if DEBUG: print "stop colorizing"
- if self.allow_colorizing:
- if DEBUG: print "schedule colorizing"
- self.after_id = self.after(1, self.recolorize)
-
- close_when_done = None # Window to be closed when done colorizing
-
- def close(self, close_when_done=None):
- if self.after_id:
- after_id = self.after_id
- self.after_id = None
- if DEBUG: print "cancel scheduled recolorizer"
- self.after_cancel(after_id)
- self.allow_colorizing = False
- self.stop_colorizing = True
- if close_when_done:
- if not self.colorizing:
- close_when_done.destroy()
- else:
- self.close_when_done = close_when_done
-
- def toggle_colorize_event(self, event):
- if self.after_id:
- after_id = self.after_id
- self.after_id = None
- if DEBUG: print "cancel scheduled recolorizer"
- self.after_cancel(after_id)
- if self.allow_colorizing and self.colorizing:
- if DEBUG: print "stop colorizing"
- self.stop_colorizing = True
- self.allow_colorizing = not self.allow_colorizing
- if self.allow_colorizing and not self.colorizing:
- self.after_id = self.after(1, self.recolorize)
- if DEBUG:
- print "auto colorizing turned",\
- self.allow_colorizing and "on" or "off"
- return "break"
-
- def recolorize(self):
- self.after_id = None
- if not self.delegate:
- if DEBUG: print "no delegate"
- return
- if not self.allow_colorizing:
- if DEBUG: print "auto colorizing is off"
- return
- if self.colorizing:
- if DEBUG: print "already colorizing"
- return
- try:
- self.stop_colorizing = False
- self.colorizing = True
- if DEBUG: print "colorizing..."
- t0 = time.clock()
- self.recolorize_main()
- t1 = time.clock()
- if DEBUG: print "%.3f seconds" % (t1-t0)
- finally:
- self.colorizing = False
- if self.allow_colorizing and self.tag_nextrange("TODO", "1.0"):
- if DEBUG: print "reschedule colorizing"
- self.after_id = self.after(1, self.recolorize)
- if self.close_when_done:
- top = self.close_when_done
- self.close_when_done = None
- top.destroy()
-
- def recolorize_main(self):
- next = "1.0"
- while True:
- item = self.tag_nextrange("TODO", next)
- if not item:
- break
- head, tail = item
- self.tag_remove("SYNC", head, tail)
- item = self.tag_prevrange("SYNC", head)
- if item:
- head = item[1]
- else:
- head = "1.0"
-
- chars = ""
- next = head
- lines_to_get = 1
- ok = False
- while not ok:
- mark = next
- next = self.index(mark + "+%d lines linestart" %
- lines_to_get)
- lines_to_get = min(lines_to_get * 2, 100)
- ok = "SYNC" in self.tag_names(next + "-1c")
- line = self.get(mark, next)
- ##print head, "get", mark, next, "->", repr(line)
- if not line:
- return
- for tag in self.tagdefs.keys():
- self.tag_remove(tag, mark, next)
- chars = chars + line
- m = self.prog.search(chars)
- while m:
- for key, value in m.groupdict().items():
- if value:
- a, b = m.span(key)
- self.tag_add(key,
- head + "+%dc" % a,
- head + "+%dc" % b)
- if value in ("def", "class"):
- m1 = self.idprog.match(chars, b)
- if m1:
- a, b = m1.span(1)
- self.tag_add("DEFINITION",
- head + "+%dc" % a,
- head + "+%dc" % b)
- elif value == "import":
- # color all the "as" words on same line, except
- # if in a comment; cheap approximation to the
- # truth
- if '#' in chars:
- endpos = chars.index('#')
- else:
- endpos = len(chars)
- while True:
- m1 = self.asprog.match(chars, b, endpos)
- if not m1:
- break
- a, b = m1.span(1)
- self.tag_add("KEYWORD",
- head + "+%dc" % a,
- head + "+%dc" % b)
- m = self.prog.search(chars, m.end())
- if "SYNC" in self.tag_names(next + "-1c"):
- head = next
- chars = ""
- else:
- ok = False
- if not ok:
- # We're in an inconsistent state, and the call to
- # update may tell us to stop. It may also change
- # the correct value for "next" (since this is a
- # line.col string, not a true mark). So leave a
- # crumb telling the next invocation to resume here
- # in case update tells us to leave.
- self.tag_add("TODO", next)
- self.update()
- if self.stop_colorizing:
- if DEBUG: print "colorizing stopped"
- return
-
- def removecolors(self):
- for tag in self.tagdefs.keys():
- self.tag_remove(tag, "1.0", "end")
-
-def main():
- from Percolator import Percolator
- root = Tk()
- root.wm_protocol("WM_DELETE_WINDOW", root.quit)
- text = Text(background="white")
- text.pack(expand=1, fill="both")
- text.focus_set()
- p = Percolator(text)
- d = ColorDelegator()
- p.insertfilter(d)
- root.mainloop()
-
-if __name__ == "__main__":
- main()
diff --git a/sys/lib/python/idlelib/Debugger.py b/sys/lib/python/idlelib/Debugger.py
deleted file mode 100644
index f56460aad..000000000
--- a/sys/lib/python/idlelib/Debugger.py
+++ /dev/null
@@ -1,481 +0,0 @@
-import os
-import bdb
-import types
-from Tkinter import *
-from WindowList import ListedToplevel
-from ScrolledList import ScrolledList
-import macosxSupport
-
-
-class Idb(bdb.Bdb):
-
- def __init__(self, gui):
- self.gui = gui
- bdb.Bdb.__init__(self)
-
- def user_line(self, frame):
- if self.in_rpc_code(frame):
- self.set_step()
- return
- message = self.__frame2message(frame)
- self.gui.interaction(message, frame)
-
- def user_exception(self, frame, info):
- if self.in_rpc_code(frame):
- self.set_step()
- return
- message = self.__frame2message(frame)
- self.gui.interaction(message, frame, info)
-
- def in_rpc_code(self, frame):
- if frame.f_code.co_filename.count('rpc.py'):
- return True
- else:
- prev_frame = frame.f_back
- if prev_frame.f_code.co_filename.count('Debugger.py'):
- # (that test will catch both Debugger.py and RemoteDebugger.py)
- return False
- return self.in_rpc_code(prev_frame)
-
- def __frame2message(self, frame):
- code = frame.f_code
- filename = code.co_filename
- lineno = frame.f_lineno
- basename = os.path.basename(filename)
- message = "%s:%s" % (basename, lineno)
- if code.co_name != "?":
- message = "%s: %s()" % (message, code.co_name)
- return message
-
-
-class Debugger:
-
- vstack = vsource = vlocals = vglobals = None
-
- def __init__(self, pyshell, idb=None):
- if idb is None:
- idb = Idb(self)
- self.pyshell = pyshell
- self.idb = idb
- self.frame = None
- self.make_gui()
- self.interacting = 0
-
- def run(self, *args):
- try:
- self.interacting = 1
- return self.idb.run(*args)
- finally:
- self.interacting = 0
-
- def close(self, event=None):
- if self.interacting:
- self.top.bell()
- return
- if self.stackviewer:
- self.stackviewer.close(); self.stackviewer = None
- # Clean up pyshell if user clicked debugger control close widget.
- # (Causes a harmless extra cycle through close_debugger() if user
- # toggled debugger from pyshell Debug menu)
- self.pyshell.close_debugger()
- # Now close the debugger control window....
- self.top.destroy()
-
- def make_gui(self):
- pyshell = self.pyshell
- self.flist = pyshell.flist
- self.root = root = pyshell.root
- self.top = top = ListedToplevel(root)
- self.top.wm_title("Debug Control")
- self.top.wm_iconname("Debug")
- top.wm_protocol("WM_DELETE_WINDOW", self.close)
- self.top.bind("<Escape>", self.close)
- #
- self.bframe = bframe = Frame(top)
- self.bframe.pack(anchor="w")
- self.buttons = bl = []
- #
- self.bcont = b = Button(bframe, text="Go", command=self.cont)
- bl.append(b)
- self.bstep = b = Button(bframe, text="Step", command=self.step)
- bl.append(b)
- self.bnext = b = Button(bframe, text="Over", command=self.next)
- bl.append(b)
- self.bret = b = Button(bframe, text="Out", command=self.ret)
- bl.append(b)
- self.bret = b = Button(bframe, text="Quit", command=self.quit)
- bl.append(b)
- #
- for b in bl:
- b.configure(state="disabled")
- b.pack(side="left")
- #
- self.cframe = cframe = Frame(bframe)
- self.cframe.pack(side="left")
- #
- if not self.vstack:
- self.__class__.vstack = BooleanVar(top)
- self.vstack.set(1)
- self.bstack = Checkbutton(cframe,
- text="Stack", command=self.show_stack, variable=self.vstack)
- self.bstack.grid(row=0, column=0)
- if not self.vsource:
- self.__class__.vsource = BooleanVar(top)
- self.bsource = Checkbutton(cframe,
- text="Source", command=self.show_source, variable=self.vsource)
- self.bsource.grid(row=0, column=1)
- if not self.vlocals:
- self.__class__.vlocals = BooleanVar(top)
- self.vlocals.set(1)
- self.blocals = Checkbutton(cframe,
- text="Locals", command=self.show_locals, variable=self.vlocals)
- self.blocals.grid(row=1, column=0)
- if not self.vglobals:
- self.__class__.vglobals = BooleanVar(top)
- self.bglobals = Checkbutton(cframe,
- text="Globals", command=self.show_globals, variable=self.vglobals)
- self.bglobals.grid(row=1, column=1)
- #
- self.status = Label(top, anchor="w")
- self.status.pack(anchor="w")
- self.error = Label(top, anchor="w")
- self.error.pack(anchor="w", fill="x")
- self.errorbg = self.error.cget("background")
- #
- self.fstack = Frame(top, height=1)
- self.fstack.pack(expand=1, fill="both")
- self.flocals = Frame(top)
- self.flocals.pack(expand=1, fill="both")
- self.fglobals = Frame(top, height=1)
- self.fglobals.pack(expand=1, fill="both")
- #
- if self.vstack.get():
- self.show_stack()
- if self.vlocals.get():
- self.show_locals()
- if self.vglobals.get():
- self.show_globals()
-
- def interaction(self, message, frame, info=None):
- self.frame = frame
- self.status.configure(text=message)
- #
- if info:
- type, value, tb = info
- try:
- m1 = type.__name__
- except AttributeError:
- m1 = "%s" % str(type)
- if value is not None:
- try:
- m1 = "%s: %s" % (m1, str(value))
- except:
- pass
- bg = "yellow"
- else:
- m1 = ""
- tb = None
- bg = self.errorbg
- self.error.configure(text=m1, background=bg)
- #
- sv = self.stackviewer
- if sv:
- stack, i = self.idb.get_stack(self.frame, tb)
- sv.load_stack(stack, i)
- #
- self.show_variables(1)
- #
- if self.vsource.get():
- self.sync_source_line()
- #
- for b in self.buttons:
- b.configure(state="normal")
- #
- self.top.wakeup()
- self.root.mainloop()
- #
- for b in self.buttons:
- b.configure(state="disabled")
- self.status.configure(text="")
- self.error.configure(text="", background=self.errorbg)
- self.frame = None
-
- def sync_source_line(self):
- frame = self.frame
- if not frame:
- return
- filename, lineno = self.__frame2fileline(frame)
- if filename[:1] + filename[-1:] != "<>" and os.path.exists(filename):
- self.flist.gotofileline(filename, lineno)
-
- def __frame2fileline(self, frame):
- code = frame.f_code
- filename = code.co_filename
- lineno = frame.f_lineno
- return filename, lineno
-
- def cont(self):
- self.idb.set_continue()
- self.root.quit()
-
- def step(self):
- self.idb.set_step()
- self.root.quit()
-
- def next(self):
- self.idb.set_next(self.frame)
- self.root.quit()
-
- def ret(self):
- self.idb.set_return(self.frame)
- self.root.quit()
-
- def quit(self):
- self.idb.set_quit()
- self.root.quit()
-
- stackviewer = None
-
- def show_stack(self):
- if not self.stackviewer and self.vstack.get():
- self.stackviewer = sv = StackViewer(self.fstack, self.flist, self)
- if self.frame:
- stack, i = self.idb.get_stack(self.frame, None)
- sv.load_stack(stack, i)
- else:
- sv = self.stackviewer
- if sv and not self.vstack.get():
- self.stackviewer = None
- sv.close()
- self.fstack['height'] = 1
-
- def show_source(self):
- if self.vsource.get():
- self.sync_source_line()
-
- def show_frame(self, (frame, lineno)):
- self.frame = frame
- self.show_variables()
-
- localsviewer = None
- globalsviewer = None
-
- def show_locals(self):
- lv = self.localsviewer
- if self.vlocals.get():
- if not lv:
- self.localsviewer = NamespaceViewer(self.flocals, "Locals")
- else:
- if lv:
- self.localsviewer = None
- lv.close()
- self.flocals['height'] = 1
- self.show_variables()
-
- def show_globals(self):
- gv = self.globalsviewer
- if self.vglobals.get():
- if not gv:
- self.globalsviewer = NamespaceViewer(self.fglobals, "Globals")
- else:
- if gv:
- self.globalsviewer = None
- gv.close()
- self.fglobals['height'] = 1
- self.show_variables()
-
- def show_variables(self, force=0):
- lv = self.localsviewer
- gv = self.globalsviewer
- frame = self.frame
- if not frame:
- ldict = gdict = None
- else:
- ldict = frame.f_locals
- gdict = frame.f_globals
- if lv and gv and ldict is gdict:
- ldict = None
- if lv:
- lv.load_dict(ldict, force, self.pyshell.interp.rpcclt)
- if gv:
- gv.load_dict(gdict, force, self.pyshell.interp.rpcclt)
-
- def set_breakpoint_here(self, filename, lineno):
- self.idb.set_break(filename, lineno)
-
- def clear_breakpoint_here(self, filename, lineno):
- self.idb.clear_break(filename, lineno)
-
- def clear_file_breaks(self, filename):
- self.idb.clear_all_file_breaks(filename)
-
- def load_breakpoints(self):
- "Load PyShellEditorWindow breakpoints into subprocess debugger"
- pyshell_edit_windows = self.pyshell.flist.inversedict.keys()
- for editwin in pyshell_edit_windows:
- filename = editwin.io.filename
- try:
- for lineno in editwin.breakpoints:
- self.set_breakpoint_here(filename, lineno)
- except AttributeError:
- continue
-
-class StackViewer(ScrolledList):
-
- def __init__(self, master, flist, gui):
- if macosxSupport.runningAsOSXApp():
- # At least on with the stock AquaTk version on OSX 10.4 you'll
- # get an shaking GUI that eventually kills IDLE if the width
- # argument is specified.
- ScrolledList.__init__(self, master)
- else:
- ScrolledList.__init__(self, master, width=80)
- self.flist = flist
- self.gui = gui
- self.stack = []
-
- def load_stack(self, stack, index=None):
- self.stack = stack
- self.clear()
- for i in range(len(stack)):
- frame, lineno = stack[i]
- try:
- modname = frame.f_globals["__name__"]
- except:
- modname = "?"
- code = frame.f_code
- filename = code.co_filename
- funcname = code.co_name
- import linecache
- sourceline = linecache.getline(filename, lineno)
- import string
- sourceline = string.strip(sourceline)
- if funcname in ("?", "", None):
- item = "%s, line %d: %s" % (modname, lineno, sourceline)
- else:
- item = "%s.%s(), line %d: %s" % (modname, funcname,
- lineno, sourceline)
- if i == index:
- item = "> " + item
- self.append(item)
- if index is not None:
- self.select(index)
-
- def popup_event(self, event):
- "override base method"
- if self.stack:
- return ScrolledList.popup_event(self, event)
-
- def fill_menu(self):
- "override base method"
- menu = self.menu
- menu.add_command(label="Go to source line",
- command=self.goto_source_line)
- menu.add_command(label="Show stack frame",
- command=self.show_stack_frame)
-
- def on_select(self, index):
- "override base method"
- if 0 <= index < len(self.stack):
- self.gui.show_frame(self.stack[index])
-
- def on_double(self, index):
- "override base method"
- self.show_source(index)
-
- def goto_source_line(self):
- index = self.listbox.index("active")
- self.show_source(index)
-
- def show_stack_frame(self):
- index = self.listbox.index("active")
- if 0 <= index < len(self.stack):
- self.gui.show_frame(self.stack[index])
-
- def show_source(self, index):
- if not (0 <= index < len(self.stack)):
- return
- frame, lineno = self.stack[index]
- code = frame.f_code
- filename = code.co_filename
- if os.path.isfile(filename):
- edit = self.flist.open(filename)
- if edit:
- edit.gotoline(lineno)
-
-
-class NamespaceViewer:
-
- def __init__(self, master, title, dict=None):
- width = 0
- height = 40
- if dict:
- height = 20*len(dict) # XXX 20 == observed height of Entry widget
- self.master = master
- self.title = title
- import repr
- self.repr = repr.Repr()
- self.repr.maxstring = 60
- self.repr.maxother = 60
- self.frame = frame = Frame(master)
- self.frame.pack(expand=1, fill="both")
- self.label = Label(frame, text=title, borderwidth=2, relief="groove")
- self.label.pack(fill="x")
- self.vbar = vbar = Scrollbar(frame, name="vbar")
- vbar.pack(side="right", fill="y")
- self.canvas = canvas = Canvas(frame,
- height=min(300, max(40, height)),
- scrollregion=(0, 0, width, height))
- canvas.pack(side="left", fill="both", expand=1)
- vbar["command"] = canvas.yview
- canvas["yscrollcommand"] = vbar.set
- self.subframe = subframe = Frame(canvas)
- self.sfid = canvas.create_window(0, 0, window=subframe, anchor="nw")
- self.load_dict(dict)
-
- dict = -1
-
- def load_dict(self, dict, force=0, rpc_client=None):
- if dict is self.dict and not force:
- return
- subframe = self.subframe
- frame = self.frame
- for c in subframe.children.values():
- c.destroy()
- self.dict = None
- if not dict:
- l = Label(subframe, text="None")
- l.grid(row=0, column=0)
- else:
- names = dict.keys()
- names.sort()
- row = 0
- for name in names:
- value = dict[name]
- svalue = self.repr.repr(value) # repr(value)
- # Strip extra quotes caused by calling repr on the (already)
- # repr'd value sent across the RPC interface:
- if rpc_client:
- svalue = svalue[1:-1]
- l = Label(subframe, text=name)
- l.grid(row=row, column=0, sticky="nw")
- l = Entry(subframe, width=0, borderwidth=0)
- l.insert(0, svalue)
- l.grid(row=row, column=1, sticky="nw")
- row = row+1
- self.dict = dict
- # XXX Could we use a <Configure> callback for the following?
- subframe.update_idletasks() # Alas!
- width = subframe.winfo_reqwidth()
- height = subframe.winfo_reqheight()
- canvas = self.canvas
- self.canvas["scrollregion"] = (0, 0, width, height)
- if height > 300:
- canvas["height"] = 300
- frame.pack(expand=1)
- else:
- canvas["height"] = height
- frame.pack(expand=0)
-
- def close(self):
- self.frame.destroy()
diff --git a/sys/lib/python/idlelib/Delegator.py b/sys/lib/python/idlelib/Delegator.py
deleted file mode 100644
index 6125591fe..000000000
--- a/sys/lib/python/idlelib/Delegator.py
+++ /dev/null
@@ -1,33 +0,0 @@
-class Delegator:
-
- # The cache is only used to be able to change delegates!
-
- def __init__(self, delegate=None):
- self.delegate = delegate
- self.__cache = {}
-
- def __getattr__(self, name):
- attr = getattr(self.delegate, name) # May raise AttributeError
- setattr(self, name, attr)
- self.__cache[name] = attr
- return attr
-
- def resetcache(self):
- for key in self.__cache.keys():
- try:
- delattr(self, key)
- except AttributeError:
- pass
- self.__cache.clear()
-
- def cachereport(self):
- keys = self.__cache.keys()
- keys.sort()
- print keys
-
- def setdelegate(self, delegate):
- self.resetcache()
- self.delegate = delegate
-
- def getdelegate(self):
- return self.delegate
diff --git a/sys/lib/python/idlelib/EditorWindow.py b/sys/lib/python/idlelib/EditorWindow.py
deleted file mode 100644
index 259c7f340..000000000
--- a/sys/lib/python/idlelib/EditorWindow.py
+++ /dev/null
@@ -1,1511 +0,0 @@
-import sys
-import os
-import re
-import imp
-from itertools import count
-from Tkinter import *
-import tkSimpleDialog
-import tkMessageBox
-from MultiCall import MultiCallCreator
-
-import webbrowser
-import idlever
-import WindowList
-import SearchDialog
-import GrepDialog
-import ReplaceDialog
-import PyParse
-from configHandler import idleConf
-import aboutDialog, textView, configDialog
-import macosxSupport
-
-# The default tab setting for a Text widget, in average-width characters.
-TK_TABWIDTH_DEFAULT = 8
-
-def _find_module(fullname, path=None):
- """Version of imp.find_module() that handles hierarchical module names"""
-
- file = None
- for tgt in fullname.split('.'):
- if file is not None:
- file.close() # close intermediate files
- (file, filename, descr) = imp.find_module(tgt, path)
- if descr[2] == imp.PY_SOURCE:
- break # find but not load the source file
- module = imp.load_module(tgt, file, filename, descr)
- try:
- path = module.__path__
- except AttributeError:
- raise ImportError, 'No source for module ' + module.__name__
- return file, filename, descr
-
-class EditorWindow(object):
- from Percolator import Percolator
- from ColorDelegator import ColorDelegator
- from UndoDelegator import UndoDelegator
- from IOBinding import IOBinding, filesystemencoding, encoding
- import Bindings
- from Tkinter import Toplevel
- from MultiStatusBar import MultiStatusBar
-
- help_url = None
-
- def __init__(self, flist=None, filename=None, key=None, root=None):
- if EditorWindow.help_url is None:
- dochome = os.path.join(sys.prefix, 'Doc', 'index.html')
- if sys.platform.count('linux'):
- # look for html docs in a couple of standard places
- pyver = 'python-docs-' + '%s.%s.%s' % sys.version_info[:3]
- if os.path.isdir('/var/www/html/python/'): # "python2" rpm
- dochome = '/var/www/html/python/index.html'
- else:
- basepath = '/usr/share/doc/' # standard location
- dochome = os.path.join(basepath, pyver,
- 'Doc', 'index.html')
- elif sys.platform[:3] == 'win':
- chmfile = os.path.join(sys.prefix, 'Doc',
- 'Python%d%d.chm' % sys.version_info[:2])
- if os.path.isfile(chmfile):
- dochome = chmfile
-
- elif macosxSupport.runningAsOSXApp():
- # documentation is stored inside the python framework
- dochome = os.path.join(sys.prefix,
- 'Resources/English.lproj/Documentation/index.html')
-
- dochome = os.path.normpath(dochome)
- if os.path.isfile(dochome):
- EditorWindow.help_url = dochome
- if sys.platform == 'darwin':
- # Safari requires real file:-URLs
- EditorWindow.help_url = 'file://' + EditorWindow.help_url
- else:
- EditorWindow.help_url = "http://www.python.org/doc/current"
- currentTheme=idleConf.CurrentTheme()
- self.flist = flist
- root = root or flist.root
- self.root = root
- try:
- sys.ps1
- except AttributeError:
- sys.ps1 = '>>> '
- self.menubar = Menu(root)
- self.top = top = WindowList.ListedToplevel(root, menu=self.menubar)
- if flist:
- self.tkinter_vars = flist.vars
- #self.top.instance_dict makes flist.inversedict avalable to
- #configDialog.py so it can access all EditorWindow instaces
- self.top.instance_dict = flist.inversedict
- else:
- self.tkinter_vars = {} # keys: Tkinter event names
- # values: Tkinter variable instances
- self.top.instance_dict = {}
- self.recent_files_path = os.path.join(idleConf.GetUserCfgDir(),
- 'recent-files.lst')
- self.vbar = vbar = Scrollbar(top, name='vbar')
- self.text_frame = text_frame = Frame(top)
- self.width = idleConf.GetOption('main','EditorWindow','width')
- self.text = text = MultiCallCreator(Text)(
- text_frame, name='text', padx=5, wrap='none',
- foreground=idleConf.GetHighlight(currentTheme,
- 'normal',fgBg='fg'),
- background=idleConf.GetHighlight(currentTheme,
- 'normal',fgBg='bg'),
- highlightcolor=idleConf.GetHighlight(currentTheme,
- 'hilite',fgBg='fg'),
- highlightbackground=idleConf.GetHighlight(currentTheme,
- 'hilite',fgBg='bg'),
- insertbackground=idleConf.GetHighlight(currentTheme,
- 'cursor',fgBg='fg'),
- width=self.width,
- height=idleConf.GetOption('main','EditorWindow','height') )
- self.top.focused_widget = self.text
-
- self.createmenubar()
- self.apply_bindings()
-
- self.top.protocol("WM_DELETE_WINDOW", self.close)
- self.top.bind("<<close-window>>", self.close_event)
- if macosxSupport.runningAsOSXApp():
- # Command-W on editorwindows doesn't work without this.
- text.bind('<<close-window>>', self.close_event)
- text.bind("<<cut>>", self.cut)
- text.bind("<<copy>>", self.copy)
- text.bind("<<paste>>", self.paste)
- text.bind("<<center-insert>>", self.center_insert_event)
- text.bind("<<help>>", self.help_dialog)
- text.bind("<<python-docs>>", self.python_docs)
- text.bind("<<about-idle>>", self.about_dialog)
- text.bind("<<open-config-dialog>>", self.config_dialog)
- text.bind("<<open-module>>", self.open_module)
- text.bind("<<do-nothing>>", lambda event: "break")
- text.bind("<<select-all>>", self.select_all)
- text.bind("<<remove-selection>>", self.remove_selection)
- text.bind("<<find>>", self.find_event)
- text.bind("<<find-again>>", self.find_again_event)
- text.bind("<<find-in-files>>", self.find_in_files_event)
- text.bind("<<find-selection>>", self.find_selection_event)
- text.bind("<<replace>>", self.replace_event)
- text.bind("<<goto-line>>", self.goto_line_event)
- text.bind("<3>", self.right_menu_event)
- text.bind("<<smart-backspace>>",self.smart_backspace_event)
- text.bind("<<newline-and-indent>>",self.newline_and_indent_event)
- text.bind("<<smart-indent>>",self.smart_indent_event)
- text.bind("<<indent-region>>",self.indent_region_event)
- text.bind("<<dedent-region>>",self.dedent_region_event)
- text.bind("<<comment-region>>",self.comment_region_event)
- text.bind("<<uncomment-region>>",self.uncomment_region_event)
- text.bind("<<tabify-region>>",self.tabify_region_event)
- text.bind("<<untabify-region>>",self.untabify_region_event)
- text.bind("<<toggle-tabs>>",self.toggle_tabs_event)
- text.bind("<<change-indentwidth>>",self.change_indentwidth_event)
- text.bind("<Left>", self.move_at_edge_if_selection(0))
- text.bind("<Right>", self.move_at_edge_if_selection(1))
- text.bind("<<del-word-left>>", self.del_word_left)
- text.bind("<<del-word-right>>", self.del_word_right)
-
- if flist:
- flist.inversedict[self] = key
- if key:
- flist.dict[key] = self
- text.bind("<<open-new-window>>", self.new_callback)
- text.bind("<<close-all-windows>>", self.flist.close_all_callback)
- text.bind("<<open-class-browser>>", self.open_class_browser)
- text.bind("<<open-path-browser>>", self.open_path_browser)
-
- self.set_status_bar()
- vbar['command'] = text.yview
- vbar.pack(side=RIGHT, fill=Y)
- text['yscrollcommand'] = vbar.set
- fontWeight = 'normal'
- if idleConf.GetOption('main', 'EditorWindow', 'font-bold', type='bool'):
- fontWeight='bold'
- text.config(font=(idleConf.GetOption('main', 'EditorWindow', 'font'),
- idleConf.GetOption('main', 'EditorWindow', 'font-size'),
- fontWeight))
- text_frame.pack(side=LEFT, fill=BOTH, expand=1)
- text.pack(side=TOP, fill=BOTH, expand=1)
- text.focus_set()
-
- # usetabs true -> literal tab characters are used by indent and
- # dedent cmds, possibly mixed with spaces if
- # indentwidth is not a multiple of tabwidth,
- # which will cause Tabnanny to nag!
- # false -> tab characters are converted to spaces by indent
- # and dedent cmds, and ditto TAB keystrokes
- # Although use-spaces=0 can be configured manually in config-main.def,
- # configuration of tabs v. spaces is not supported in the configuration
- # dialog. IDLE promotes the preferred Python indentation: use spaces!
- usespaces = idleConf.GetOption('main', 'Indent', 'use-spaces', type='bool')
- self.usetabs = not usespaces
-
- # tabwidth is the display width of a literal tab character.
- # CAUTION: telling Tk to use anything other than its default
- # tab setting causes it to use an entirely different tabbing algorithm,
- # treating tab stops as fixed distances from the left margin.
- # Nobody expects this, so for now tabwidth should never be changed.
- self.tabwidth = 8 # must remain 8 until Tk is fixed.
-
- # indentwidth is the number of screen characters per indent level.
- # The recommended Python indentation is four spaces.
- self.indentwidth = self.tabwidth
- self.set_notabs_indentwidth()
-
- # If context_use_ps1 is true, parsing searches back for a ps1 line;
- # else searches for a popular (if, def, ...) Python stmt.
- self.context_use_ps1 = False
-
- # When searching backwards for a reliable place to begin parsing,
- # first start num_context_lines[0] lines back, then
- # num_context_lines[1] lines back if that didn't work, and so on.
- # The last value should be huge (larger than the # of lines in a
- # conceivable file).
- # Making the initial values larger slows things down more often.
- self.num_context_lines = 50, 500, 5000000
-
- self.per = per = self.Percolator(text)
- if self.ispythonsource(filename):
- self.color = color = self.ColorDelegator()
- per.insertfilter(color)
- else:
- self.color = None
-
- self.undo = undo = self.UndoDelegator()
- per.insertfilter(undo)
- text.undo_block_start = undo.undo_block_start
- text.undo_block_stop = undo.undo_block_stop
- undo.set_saved_change_hook(self.saved_change_hook)
-
- # IOBinding implements file I/O and printing functionality
- self.io = io = self.IOBinding(self)
- io.set_filename_change_hook(self.filename_change_hook)
-
- # Create the recent files submenu
- self.recent_files_menu = Menu(self.menubar)
- self.menudict['file'].insert_cascade(3, label='Recent Files',
- underline=0,
- menu=self.recent_files_menu)
- self.update_recent_files_list()
-
- if filename:
- if os.path.exists(filename) and not os.path.isdir(filename):
- io.loadfile(filename)
- else:
- io.set_filename(filename)
- self.saved_change_hook()
-
- self.set_indentation_params(self.ispythonsource(filename))
-
- self.load_extensions()
-
- menu = self.menudict.get('windows')
- if menu:
- end = menu.index("end")
- if end is None:
- end = -1
- if end >= 0:
- menu.add_separator()
- end = end + 1
- self.wmenu_end = end
- WindowList.register_callback(self.postwindowsmenu)
-
- # Some abstractions so IDLE extensions are cross-IDE
- self.askyesno = tkMessageBox.askyesno
- self.askinteger = tkSimpleDialog.askinteger
- self.showerror = tkMessageBox.showerror
-
- def _filename_to_unicode(self, filename):
- """convert filename to unicode in order to display it in Tk"""
- if isinstance(filename, unicode) or not filename:
- return filename
- else:
- try:
- return filename.decode(self.filesystemencoding)
- except UnicodeDecodeError:
- # XXX
- try:
- return filename.decode(self.encoding)
- except UnicodeDecodeError:
- # byte-to-byte conversion
- return filename.decode('iso8859-1')
-
- def new_callback(self, event):
- dirname, basename = self.io.defaultfilename()
- self.flist.new(dirname)
- return "break"
-
- def set_status_bar(self):
- self.status_bar = self.MultiStatusBar(self.top)
- if macosxSupport.runningAsOSXApp():
- # Insert some padding to avoid obscuring some of the statusbar
- # by the resize widget.
- self.status_bar.set_label('_padding1', ' ', side=RIGHT)
- self.status_bar.set_label('column', 'Col: ?', side=RIGHT)
- self.status_bar.set_label('line', 'Ln: ?', side=RIGHT)
- self.status_bar.pack(side=BOTTOM, fill=X)
- self.text.bind("<<set-line-and-column>>", self.set_line_and_column)
- self.text.event_add("<<set-line-and-column>>",
- "<KeyRelease>", "<ButtonRelease>")
- self.text.after_idle(self.set_line_and_column)
-
- def set_line_and_column(self, event=None):
- line, column = self.text.index(INSERT).split('.')
- self.status_bar.set_label('column', 'Col: %s' % column)
- self.status_bar.set_label('line', 'Ln: %s' % line)
-
- menu_specs = [
- ("file", "_File"),
- ("edit", "_Edit"),
- ("format", "F_ormat"),
- ("run", "_Run"),
- ("options", "_Options"),
- ("windows", "_Windows"),
- ("help", "_Help"),
- ]
-
- if macosxSupport.runningAsOSXApp():
- del menu_specs[-3]
- menu_specs[-2] = ("windows", "_Window")
-
-
- def createmenubar(self):
- mbar = self.menubar
- self.menudict = menudict = {}
- for name, label in self.menu_specs:
- underline, label = prepstr(label)
- menudict[name] = menu = Menu(mbar, name=name)
- mbar.add_cascade(label=label, menu=menu, underline=underline)
-
- if sys.platform == 'darwin' and '.framework' in sys.executable:
- # Insert the application menu
- menudict['application'] = menu = Menu(mbar, name='apple')
- mbar.add_cascade(label='IDLE', menu=menu)
-
- self.fill_menus()
- self.base_helpmenu_length = self.menudict['help'].index(END)
- self.reset_help_menu_entries()
-
- def postwindowsmenu(self):
- # Only called when Windows menu exists
- menu = self.menudict['windows']
- end = menu.index("end")
- if end is None:
- end = -1
- if end > self.wmenu_end:
- menu.delete(self.wmenu_end+1, end)
- WindowList.add_windows_to_menu(menu)
-
- rmenu = None
-
- def right_menu_event(self, event):
- self.text.tag_remove("sel", "1.0", "end")
- self.text.mark_set("insert", "@%d,%d" % (event.x, event.y))
- if not self.rmenu:
- self.make_rmenu()
- rmenu = self.rmenu
- self.event = event
- iswin = sys.platform[:3] == 'win'
- if iswin:
- self.text.config(cursor="arrow")
- rmenu.tk_popup(event.x_root, event.y_root)
- if iswin:
- self.text.config(cursor="ibeam")
-
- rmenu_specs = [
- # ("Label", "<<virtual-event>>"), ...
- ("Close", "<<close-window>>"), # Example
- ]
-
- def make_rmenu(self):
- rmenu = Menu(self.text, tearoff=0)
- for label, eventname in self.rmenu_specs:
- def command(text=self.text, eventname=eventname):
- text.event_generate(eventname)
- rmenu.add_command(label=label, command=command)
- self.rmenu = rmenu
-
- def about_dialog(self, event=None):
- aboutDialog.AboutDialog(self.top,'About IDLE')
-
- def config_dialog(self, event=None):
- configDialog.ConfigDialog(self.top,'Settings')
-
- def help_dialog(self, event=None):
- fn=os.path.join(os.path.abspath(os.path.dirname(__file__)),'help.txt')
- textView.TextViewer(self.top,'Help',fn)
-
- def python_docs(self, event=None):
- if sys.platform[:3] == 'win':
- os.startfile(self.help_url)
- else:
- webbrowser.open(self.help_url)
- return "break"
-
- def cut(self,event):
- self.text.event_generate("<<Cut>>")
- return "break"
-
- def copy(self,event):
- if not self.text.tag_ranges("sel"):
- # There is no selection, so do nothing and maybe interrupt.
- return
- self.text.event_generate("<<Copy>>")
- return "break"
-
- def paste(self,event):
- self.text.event_generate("<<Paste>>")
- return "break"
-
- def select_all(self, event=None):
- self.text.tag_add("sel", "1.0", "end-1c")
- self.text.mark_set("insert", "1.0")
- self.text.see("insert")
- return "break"
-
- def remove_selection(self, event=None):
- self.text.tag_remove("sel", "1.0", "end")
- self.text.see("insert")
-
- def move_at_edge_if_selection(self, edge_index):
- """Cursor move begins at start or end of selection
-
- When a left/right cursor key is pressed create and return to Tkinter a
- function which causes a cursor move from the associated edge of the
- selection.
-
- """
- self_text_index = self.text.index
- self_text_mark_set = self.text.mark_set
- edges_table = ("sel.first+1c", "sel.last-1c")
- def move_at_edge(event):
- if (event.state & 5) == 0: # no shift(==1) or control(==4) pressed
- try:
- self_text_index("sel.first")
- self_text_mark_set("insert", edges_table[edge_index])
- except TclError:
- pass
- return move_at_edge
-
- def del_word_left(self, event):
- self.text.event_generate('<Meta-Delete>')
- return "break"
-
- def del_word_right(self, event):
- self.text.event_generate('<Meta-d>')
- return "break"
-
- def find_event(self, event):
- SearchDialog.find(self.text)
- return "break"
-
- def find_again_event(self, event):
- SearchDialog.find_again(self.text)
- return "break"
-
- def find_selection_event(self, event):
- SearchDialog.find_selection(self.text)
- return "break"
-
- def find_in_files_event(self, event):
- GrepDialog.grep(self.text, self.io, self.flist)
- return "break"
-
- def replace_event(self, event):
- ReplaceDialog.replace(self.text)
- return "break"
-
- def goto_line_event(self, event):
- text = self.text
- lineno = tkSimpleDialog.askinteger("Goto",
- "Go to line number:",parent=text)
- if lineno is None:
- return "break"
- if lineno <= 0:
- text.bell()
- return "break"
- text.mark_set("insert", "%d.0" % lineno)
- text.see("insert")
-
- def open_module(self, event=None):
- # XXX Shouldn't this be in IOBinding or in FileList?
- try:
- name = self.text.get("sel.first", "sel.last")
- except TclError:
- name = ""
- else:
- name = name.strip()
- name = tkSimpleDialog.askstring("Module",
- "Enter the name of a Python module\n"
- "to search on sys.path and open:",
- parent=self.text, initialvalue=name)
- if name:
- name = name.strip()
- if not name:
- return
- # XXX Ought to insert current file's directory in front of path
- try:
- (f, file, (suffix, mode, type)) = _find_module(name)
- except (NameError, ImportError), msg:
- tkMessageBox.showerror("Import error", str(msg), parent=self.text)
- return
- if type != imp.PY_SOURCE:
- tkMessageBox.showerror("Unsupported type",
- "%s is not a source module" % name, parent=self.text)
- return
- if f:
- f.close()
- if self.flist:
- self.flist.open(file)
- else:
- self.io.loadfile(file)
-
- def open_class_browser(self, event=None):
- filename = self.io.filename
- if not filename:
- tkMessageBox.showerror(
- "No filename",
- "This buffer has no associated filename",
- master=self.text)
- self.text.focus_set()
- return None
- head, tail = os.path.split(filename)
- base, ext = os.path.splitext(tail)
- import ClassBrowser
- ClassBrowser.ClassBrowser(self.flist, base, [head])
-
- def open_path_browser(self, event=None):
- import PathBrowser
- PathBrowser.PathBrowser(self.flist)
-
- 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 or os.path.isdir(filename):
- return True
- base, ext = os.path.splitext(os.path.basename(filename))
- if os.path.normcase(ext) in (".py", ".pyw"):
- return True
- try:
- f = open(filename)
- line = f.readline()
- f.close()
- except IOError:
- return False
- return line.startswith('#!') and line.find('python') >= 0
-
- def close_hook(self):
- if self.flist:
- self.flist.close_edit(self)
-
- def set_close_hook(self, close_hook):
- self.close_hook = close_hook
-
- def filename_change_hook(self):
- if self.flist:
- self.flist.filename_changed_edit(self)
- self.saved_change_hook()
- self.top.update_windowlist_registry(self)
- if self.ispythonsource(self.io.filename):
- self.addcolorizer()
- else:
- self.rmcolorizer()
-
- def addcolorizer(self):
- if self.color:
- return
- 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
- self.color.removecolors()
- self.per.removefilter(self.undo)
- self.per.removefilter(self.color)
- self.color = None
- self.per.insertfilter(self.undo)
-
- def ResetColorizer(self):
- "Update the colour theme if it is changed"
- # Called from configDialog.py
- if self.color:
- self.color = self.ColorDelegator()
- self.per.insertfilter(self.color)
- theme = idleConf.GetOption('main','Theme','name')
- self.text.config(idleConf.GetHighlight(theme, "normal"))
-
- def ResetFont(self):
- "Update the text widgets' font if it is changed"
- # Called from configDialog.py
- fontWeight='normal'
- if idleConf.GetOption('main','EditorWindow','font-bold',type='bool'):
- fontWeight='bold'
- self.text.config(font=(idleConf.GetOption('main','EditorWindow','font'),
- idleConf.GetOption('main','EditorWindow','font-size'),
- fontWeight))
-
- def RemoveKeybindings(self):
- "Remove the keybindings before they are changed."
- # Called from configDialog.py
- self.Bindings.default_keydefs = keydefs = idleConf.GetCurrentKeySet()
- for event, keylist in keydefs.items():
- self.text.event_delete(event, *keylist)
- for extensionName in self.get_standard_extension_names():
- xkeydefs = idleConf.GetExtensionBindings(extensionName)
- if xkeydefs:
- for event, keylist in xkeydefs.items():
- self.text.event_delete(event, *keylist)
-
- def ApplyKeybindings(self):
- "Update the keybindings after they are changed"
- # Called from configDialog.py
- self.Bindings.default_keydefs = keydefs = idleConf.GetCurrentKeySet()
- self.apply_bindings()
- for extensionName in self.get_standard_extension_names():
- xkeydefs = idleConf.GetExtensionBindings(extensionName)
- if xkeydefs:
- self.apply_bindings(xkeydefs)
- #update menu accelerators
- menuEventDict = {}
- for menu in self.Bindings.menudefs:
- menuEventDict[menu[0]] = {}
- for item in menu[1]:
- if item:
- menuEventDict[menu[0]][prepstr(item[0])[1]] = item[1]
- for menubarItem in self.menudict.keys():
- menu = self.menudict[menubarItem]
- end = menu.index(END) + 1
- for index in range(0, end):
- if menu.type(index) == 'command':
- accel = menu.entrycget(index, 'accelerator')
- if accel:
- itemName = menu.entrycget(index, 'label')
- event = ''
- if menuEventDict.has_key(menubarItem):
- if menuEventDict[menubarItem].has_key(itemName):
- event = menuEventDict[menubarItem][itemName]
- if event:
- accel = get_accelerator(keydefs, event)
- menu.entryconfig(index, accelerator=accel)
-
- def set_notabs_indentwidth(self):
- "Update the indentwidth if changed and not using tabs in this window"
- # Called from configDialog.py
- if not self.usetabs:
- self.indentwidth = idleConf.GetOption('main', 'Indent','num-spaces',
- type='int')
-
- def reset_help_menu_entries(self):
- "Update the additional help entries on the Help menu"
- help_list = idleConf.GetAllExtraHelpSourcesList()
- helpmenu = self.menudict['help']
- # first delete the extra help entries, if any
- helpmenu_length = helpmenu.index(END)
- if helpmenu_length > self.base_helpmenu_length:
- helpmenu.delete((self.base_helpmenu_length + 1), helpmenu_length)
- # then rebuild them
- if help_list:
- helpmenu.add_separator()
- for entry in help_list:
- cmd = self.__extra_help_callback(entry[1])
- helpmenu.add_command(label=entry[0], command=cmd)
- # and update the menu dictionary
- self.menudict['help'] = helpmenu
-
- def __extra_help_callback(self, helpfile):
- "Create a callback with the helpfile value frozen at definition time"
- def display_extra_help(helpfile=helpfile):
- if not helpfile.startswith(('www', 'http')):
- url = os.path.normpath(helpfile)
- if sys.platform[:3] == 'win':
- os.startfile(helpfile)
- else:
- webbrowser.open(helpfile)
- return display_extra_help
-
- def update_recent_files_list(self, new_file=None):
- "Load and update the recent files list and menus"
- rf_list = []
- if os.path.exists(self.recent_files_path):
- rf_list_file = open(self.recent_files_path,'r')
- try:
- rf_list = rf_list_file.readlines()
- finally:
- rf_list_file.close()
- if new_file:
- new_file = os.path.abspath(new_file) + '\n'
- if new_file in rf_list:
- rf_list.remove(new_file) # move to top
- rf_list.insert(0, new_file)
- # clean and save the recent files list
- bad_paths = []
- for path in rf_list:
- if '\0' in path or not os.path.exists(path[0:-1]):
- bad_paths.append(path)
- rf_list = [path for path in rf_list if path not in bad_paths]
- ulchars = "1234567890ABCDEFGHIJK"
- rf_list = rf_list[0:len(ulchars)]
- rf_file = open(self.recent_files_path, 'w')
- try:
- rf_file.writelines(rf_list)
- finally:
- rf_file.close()
- # for each edit window instance, construct the recent files menu
- for instance in self.top.instance_dict.keys():
- menu = instance.recent_files_menu
- menu.delete(1, END) # clear, and rebuild:
- for i, file in zip(count(), rf_list):
- file_name = file[0:-1] # zap \n
- # make unicode string to display non-ASCII chars correctly
- ufile_name = self._filename_to_unicode(file_name)
- callback = instance.__recent_file_callback(file_name)
- menu.add_command(label=ulchars[i] + " " + ufile_name,
- command=callback,
- underline=0)
-
- def __recent_file_callback(self, file_name):
- def open_recent_file(fn_closure=file_name):
- self.io.open(editFile=fn_closure)
- return open_recent_file
-
- def saved_change_hook(self):
- short = self.short_title()
- long = self.long_title()
- if short and long:
- title = short + " - " + long
- elif short:
- title = short
- elif long:
- title = long
- else:
- title = "Untitled"
- icon = short or long or title
- if not self.get_saved():
- title = "*%s*" % title
- icon = "*%s" % icon
- self.top.wm_title(title)
- self.top.wm_iconname(icon)
-
- def get_saved(self):
- return self.undo.get_saved()
-
- def set_saved(self, flag):
- self.undo.set_saved(flag)
-
- def reset_undo(self):
- self.undo.reset_undo()
-
- def short_title(self):
- filename = self.io.filename
- if filename:
- filename = os.path.basename(filename)
- # return unicode string to display non-ASCII chars correctly
- return self._filename_to_unicode(filename)
-
- def long_title(self):
- # return unicode string to display non-ASCII chars correctly
- return self._filename_to_unicode(self.io.filename or "")
-
- def center_insert_event(self, event):
- self.center()
-
- def center(self, mark="insert"):
- text = self.text
- top, bot = self.getwindowlines()
- lineno = self.getlineno(mark)
- height = bot - top
- newtop = max(1, lineno - height//2)
- text.yview(float(newtop))
-
- def getwindowlines(self):
- text = self.text
- top = self.getlineno("@0,0")
- bot = self.getlineno("@0,65535")
- if top == bot and text.winfo_height() == 1:
- # Geometry manager hasn't run yet
- height = int(text['height'])
- bot = top + height - 1
- return top, bot
-
- def getlineno(self, mark="insert"):
- text = self.text
- return int(float(text.index(mark)))
-
- def get_geometry(self):
- "Return (width, height, x, y)"
- geom = self.top.wm_geometry()
- m = re.match(r"(\d+)x(\d+)\+(-?\d+)\+(-?\d+)", geom)
- tuple = (map(int, m.groups()))
- return tuple
-
- def close_event(self, event):
- self.close()
-
- def maybesave(self):
- if self.io:
- if not self.get_saved():
- if self.top.state()!='normal':
- self.top.deiconify()
- self.top.lower()
- self.top.lift()
- return self.io.maybesave()
-
- def close(self):
- reply = self.maybesave()
- if str(reply) != "cancel":
- self._close()
- return reply
-
- def _close(self):
- if self.io.filename:
- self.update_recent_files_list(new_file=self.io.filename)
- WindowList.unregister_callback(self.postwindowsmenu)
- if self.close_hook:
- self.close_hook()
- self.flist = None
- colorizing = 0
- self.unload_extensions()
- self.io.close(); self.io = None
- self.undo = None # XXX
- if self.color:
- colorizing = self.color.colorizing
- doh = colorizing and self.top
- self.color.close(doh) # Cancel colorization
- self.text = None
- self.tkinter_vars = None
- self.per.close(); self.per = None
- if not colorizing:
- self.top.destroy()
-
- def load_extensions(self):
- self.extensions = {}
- self.load_standard_extensions()
-
- def unload_extensions(self):
- for ins in self.extensions.values():
- if hasattr(ins, "close"):
- ins.close()
- self.extensions = {}
-
- def load_standard_extensions(self):
- for name in self.get_standard_extension_names():
- try:
- self.load_extension(name)
- except:
- print "Failed to load extension", repr(name)
- import traceback
- traceback.print_exc()
-
- def get_standard_extension_names(self):
- return idleConf.GetExtensions(editor_only=True)
-
- def load_extension(self, name):
- try:
- mod = __import__(name, globals(), locals(), [])
- except ImportError:
- print "\nFailed to import extension: ", name
- return
- cls = getattr(mod, name)
- keydefs = idleConf.GetExtensionBindings(name)
- if hasattr(cls, "menudefs"):
- self.fill_menus(cls.menudefs, keydefs)
- ins = cls(self)
- self.extensions[name] = ins
- if keydefs:
- self.apply_bindings(keydefs)
- for vevent in keydefs.keys():
- methodname = vevent.replace("-", "_")
- while methodname[:1] == '<':
- methodname = methodname[1:]
- while methodname[-1:] == '>':
- methodname = methodname[:-1]
- methodname = methodname + "_event"
- if hasattr(ins, methodname):
- self.text.bind(vevent, getattr(ins, methodname))
-
- def apply_bindings(self, keydefs=None):
- if keydefs is None:
- keydefs = self.Bindings.default_keydefs
- text = self.text
- text.keydefs = keydefs
- for event, keylist in keydefs.items():
- if keylist:
- text.event_add(event, *keylist)
-
- def fill_menus(self, menudefs=None, keydefs=None):
- """Add appropriate entries to the menus and submenus
-
- Menus that are absent or None in self.menudict are ignored.
- """
- if menudefs is None:
- menudefs = self.Bindings.menudefs
- if keydefs is None:
- keydefs = self.Bindings.default_keydefs
- menudict = self.menudict
- text = self.text
- for mname, entrylist in menudefs:
- menu = menudict.get(mname)
- if not menu:
- continue
- for entry in entrylist:
- if not entry:
- menu.add_separator()
- else:
- label, eventname = entry
- checkbutton = (label[:1] == '!')
- if checkbutton:
- label = label[1:]
- underline, label = prepstr(label)
- accelerator = get_accelerator(keydefs, eventname)
- def command(text=text, eventname=eventname):
- text.event_generate(eventname)
- if checkbutton:
- var = self.get_var_obj(eventname, BooleanVar)
- menu.add_checkbutton(label=label, underline=underline,
- command=command, accelerator=accelerator,
- variable=var)
- else:
- menu.add_command(label=label, underline=underline,
- command=command,
- accelerator=accelerator)
-
- def getvar(self, name):
- var = self.get_var_obj(name)
- if var:
- value = var.get()
- return value
- else:
- raise NameError, name
-
- def setvar(self, name, value, vartype=None):
- var = self.get_var_obj(name, vartype)
- if var:
- var.set(value)
- else:
- raise NameError, name
-
- def get_var_obj(self, name, vartype=None):
- var = self.tkinter_vars.get(name)
- if not var and vartype:
- # create a Tkinter variable object with self.text as master:
- self.tkinter_vars[name] = var = vartype(self.text)
- return var
-
- # Tk implementations of "virtual text methods" -- each platform
- # reusing IDLE's support code needs to define these for its GUI's
- # flavor of widget.
-
- # Is character at text_index in a Python string? Return 0 for
- # "guaranteed no", true for anything else. This info is expensive
- # to compute ab initio, but is probably already known by the
- # platform's colorizer.
-
- def is_char_in_string(self, text_index):
- if self.color:
- # Return true iff colorizer hasn't (re)gotten this far
- # yet, or the character is tagged as being in a string
- return self.text.tag_prevrange("TODO", text_index) or \
- "STRING" in self.text.tag_names(text_index)
- else:
- # The colorizer is missing: assume the worst
- return 1
-
- # If a selection is defined in the text widget, return (start,
- # end) as Tkinter text indices, otherwise return (None, None)
- def get_selection_indices(self):
- try:
- first = self.text.index("sel.first")
- last = self.text.index("sel.last")
- return first, last
- except TclError:
- return None, None
-
- # Return the text widget's current view of what a tab stop means
- # (equivalent width in spaces).
-
- def get_tabwidth(self):
- current = self.text['tabs'] or TK_TABWIDTH_DEFAULT
- return int(current)
-
- # Set the text widget's current view of what a tab stop means.
-
- def set_tabwidth(self, newtabwidth):
- text = self.text
- if self.get_tabwidth() != newtabwidth:
- pixels = text.tk.call("font", "measure", text["font"],
- "-displayof", text.master,
- "n" * newtabwidth)
- text.configure(tabs=pixels)
-
- # If ispythonsource and guess are true, guess a good value for
- # indentwidth based on file content (if possible), and if
- # indentwidth != tabwidth set usetabs false.
- # In any case, adjust the Text widget's view of what a tab
- # character means.
-
- def set_indentation_params(self, ispythonsource, guess=True):
- if guess and ispythonsource:
- i = self.guess_indent()
- if 2 <= i <= 8:
- self.indentwidth = i
- if self.indentwidth != self.tabwidth:
- self.usetabs = False
- self.set_tabwidth(self.tabwidth)
-
- def smart_backspace_event(self, event):
- text = self.text
- first, last = self.get_selection_indices()
- if first and last:
- text.delete(first, last)
- text.mark_set("insert", first)
- return "break"
- # Delete whitespace left, until hitting a real char or closest
- # preceding virtual tab stop.
- chars = text.get("insert linestart", "insert")
- if chars == '':
- if text.compare("insert", ">", "1.0"):
- # easy: delete preceding newline
- text.delete("insert-1c")
- else:
- text.bell() # at start of buffer
- return "break"
- if chars[-1] not in " \t":
- # easy: delete preceding real char
- text.delete("insert-1c")
- return "break"
- # Ick. It may require *inserting* spaces if we back up over a
- # tab character! This is written to be clear, not fast.
- tabwidth = self.tabwidth
- have = len(chars.expandtabs(tabwidth))
- assert have > 0
- want = ((have - 1) // self.indentwidth) * self.indentwidth
- # Debug prompt is multilined....
- last_line_of_prompt = sys.ps1.split('\n')[-1]
- ncharsdeleted = 0
- while 1:
- if chars == last_line_of_prompt:
- break
- chars = chars[:-1]
- ncharsdeleted = ncharsdeleted + 1
- have = len(chars.expandtabs(tabwidth))
- if have <= want or chars[-1] not in " \t":
- break
- text.undo_block_start()
- text.delete("insert-%dc" % ncharsdeleted, "insert")
- if have < want:
- text.insert("insert", ' ' * (want - have))
- text.undo_block_stop()
- return "break"
-
- def smart_indent_event(self, event):
- # if intraline selection:
- # delete it
- # elif multiline selection:
- # do indent-region
- # else:
- # indent one level
- text = self.text
- first, last = self.get_selection_indices()
- text.undo_block_start()
- try:
- if first and last:
- if index2line(first) != index2line(last):
- return self.indent_region_event(event)
- text.delete(first, last)
- text.mark_set("insert", first)
- prefix = text.get("insert linestart", "insert")
- raw, effective = classifyws(prefix, self.tabwidth)
- if raw == len(prefix):
- # only whitespace to the left
- self.reindent_to(effective + self.indentwidth)
- else:
- # tab to the next 'stop' within or to right of line's text:
- if self.usetabs:
- pad = '\t'
- else:
- effective = len(prefix.expandtabs(self.tabwidth))
- n = self.indentwidth
- pad = ' ' * (n - effective % n)
- text.insert("insert", pad)
- text.see("insert")
- return "break"
- finally:
- text.undo_block_stop()
-
- def newline_and_indent_event(self, event):
- text = self.text
- first, last = self.get_selection_indices()
- text.undo_block_start()
- try:
- if first and last:
- text.delete(first, last)
- text.mark_set("insert", first)
- line = text.get("insert linestart", "insert")
- i, n = 0, len(line)
- while i < n and line[i] in " \t":
- i = i+1
- if i == n:
- # the cursor is in or at leading indentation in a continuation
- # line; just inject an empty line at the start
- text.insert("insert linestart", '\n')
- return "break"
- indent = line[:i]
- # strip whitespace before insert point unless it's in the prompt
- i = 0
- last_line_of_prompt = sys.ps1.split('\n')[-1]
- while line and line[-1] in " \t" and line != last_line_of_prompt:
- line = line[:-1]
- i = i+1
- if i:
- text.delete("insert - %d chars" % i, "insert")
- # strip whitespace after insert point
- while text.get("insert") in " \t":
- text.delete("insert")
- # start new line
- text.insert("insert", '\n')
-
- # adjust indentation for continuations and block
- # open/close first need to find the last stmt
- lno = index2line(text.index('insert'))
- y = PyParse.Parser(self.indentwidth, self.tabwidth)
- if not self.context_use_ps1:
- for context in self.num_context_lines:
- startat = max(lno - context, 1)
- startatindex = `startat` + ".0"
- rawtext = text.get(startatindex, "insert")
- y.set_str(rawtext)
- bod = y.find_good_parse_start(
- self.context_use_ps1,
- self._build_char_in_string_func(startatindex))
- if bod is not None or startat == 1:
- break
- y.set_lo(bod or 0)
- else:
- r = text.tag_prevrange("console", "insert")
- if r:
- startatindex = r[1]
- else:
- startatindex = "1.0"
- rawtext = text.get(startatindex, "insert")
- y.set_str(rawtext)
- y.set_lo(0)
-
- c = y.get_continuation_type()
- if c != PyParse.C_NONE:
- # The current stmt hasn't ended yet.
- if c == PyParse.C_STRING_FIRST_LINE:
- # after the first line of a string; do not indent at all
- pass
- elif c == PyParse.C_STRING_NEXT_LINES:
- # inside a string which started before this line;
- # just mimic the current indent
- text.insert("insert", indent)
- elif c == PyParse.C_BRACKET:
- # line up with the first (if any) element of the
- # last open bracket structure; else indent one
- # level beyond the indent of the line with the
- # last open bracket
- self.reindent_to(y.compute_bracket_indent())
- elif c == PyParse.C_BACKSLASH:
- # if more than one line in this stmt already, just
- # mimic the current indent; else if initial line
- # has a start on an assignment stmt, indent to
- # beyond leftmost =; else to beyond first chunk of
- # non-whitespace on initial line
- if y.get_num_lines_in_stmt() > 1:
- text.insert("insert", indent)
- else:
- self.reindent_to(y.compute_backslash_indent())
- else:
- assert 0, "bogus continuation type %r" % (c,)
- return "break"
-
- # This line starts a brand new stmt; indent relative to
- # indentation of initial line of closest preceding
- # interesting stmt.
- indent = y.get_base_indent_string()
- text.insert("insert", indent)
- if y.is_block_opener():
- self.smart_indent_event(event)
- elif indent and y.is_block_closer():
- self.smart_backspace_event(event)
- return "break"
- finally:
- text.see("insert")
- text.undo_block_stop()
-
- # Our editwin provides a is_char_in_string function that works
- # with a Tk text index, but PyParse only knows about offsets into
- # a string. This builds a function for PyParse that accepts an
- # offset.
-
- def _build_char_in_string_func(self, startindex):
- def inner(offset, _startindex=startindex,
- _icis=self.is_char_in_string):
- return _icis(_startindex + "+%dc" % offset)
- return inner
-
- def indent_region_event(self, event):
- head, tail, chars, lines = self.get_region()
- for pos in range(len(lines)):
- line = lines[pos]
- if line:
- raw, effective = classifyws(line, self.tabwidth)
- effective = effective + self.indentwidth
- lines[pos] = self._make_blanks(effective) + line[raw:]
- self.set_region(head, tail, chars, lines)
- return "break"
-
- def dedent_region_event(self, event):
- head, tail, chars, lines = self.get_region()
- for pos in range(len(lines)):
- line = lines[pos]
- if line:
- raw, effective = classifyws(line, self.tabwidth)
- effective = max(effective - self.indentwidth, 0)
- lines[pos] = self._make_blanks(effective) + line[raw:]
- self.set_region(head, tail, chars, lines)
- return "break"
-
- def comment_region_event(self, event):
- head, tail, chars, lines = self.get_region()
- for pos in range(len(lines) - 1):
- line = lines[pos]
- lines[pos] = '##' + line
- self.set_region(head, tail, chars, lines)
-
- def uncomment_region_event(self, event):
- head, tail, chars, lines = self.get_region()
- for pos in range(len(lines)):
- line = lines[pos]
- if not line:
- continue
- if line[:2] == '##':
- line = line[2:]
- elif line[:1] == '#':
- line = line[1:]
- lines[pos] = line
- self.set_region(head, tail, chars, lines)
-
- def tabify_region_event(self, event):
- head, tail, chars, lines = self.get_region()
- tabwidth = self._asktabwidth()
- for pos in range(len(lines)):
- line = lines[pos]
- if line:
- raw, effective = classifyws(line, tabwidth)
- ntabs, nspaces = divmod(effective, tabwidth)
- lines[pos] = '\t' * ntabs + ' ' * nspaces + line[raw:]
- self.set_region(head, tail, chars, lines)
-
- def untabify_region_event(self, event):
- head, tail, chars, lines = self.get_region()
- tabwidth = self._asktabwidth()
- for pos in range(len(lines)):
- lines[pos] = lines[pos].expandtabs(tabwidth)
- self.set_region(head, tail, chars, lines)
-
- def toggle_tabs_event(self, event):
- if self.askyesno(
- "Toggle tabs",
- "Turn tabs " + ("on", "off")[self.usetabs] +
- "?\nIndent width " +
- ("will be", "remains at")[self.usetabs] + " 8." +
- "\n Note: a tab is always 8 columns",
- parent=self.text):
- self.usetabs = not self.usetabs
- # Try to prevent inconsistent indentation.
- # User must change indent width manually after using tabs.
- self.indentwidth = 8
- return "break"
-
- # XXX this isn't bound to anything -- see tabwidth comments
-## def change_tabwidth_event(self, event):
-## new = self._asktabwidth()
-## if new != self.tabwidth:
-## self.tabwidth = new
-## self.set_indentation_params(0, guess=0)
-## return "break"
-
- def change_indentwidth_event(self, event):
- new = self.askinteger(
- "Indent width",
- "New indent width (2-16)\n(Always use 8 when using tabs)",
- parent=self.text,
- initialvalue=self.indentwidth,
- minvalue=2,
- maxvalue=16)
- if new and new != self.indentwidth and not self.usetabs:
- self.indentwidth = new
- return "break"
-
- def get_region(self):
- text = self.text
- first, last = self.get_selection_indices()
- if first and last:
- head = text.index(first + " linestart")
- tail = text.index(last + "-1c lineend +1c")
- else:
- head = text.index("insert linestart")
- tail = text.index("insert lineend +1c")
- chars = text.get(head, tail)
- lines = chars.split("\n")
- return head, tail, chars, lines
-
- def set_region(self, head, tail, chars, lines):
- text = self.text
- newchars = "\n".join(lines)
- if newchars == chars:
- text.bell()
- return
- text.tag_remove("sel", "1.0", "end")
- text.mark_set("insert", head)
- text.undo_block_start()
- text.delete(head, tail)
- text.insert(head, newchars)
- text.undo_block_stop()
- text.tag_add("sel", head, "insert")
-
- # Make string that displays as n leading blanks.
-
- def _make_blanks(self, n):
- if self.usetabs:
- ntabs, nspaces = divmod(n, self.tabwidth)
- return '\t' * ntabs + ' ' * nspaces
- else:
- return ' ' * n
-
- # Delete from beginning of line to insert point, then reinsert
- # column logical (meaning use tabs if appropriate) spaces.
-
- def reindent_to(self, column):
- text = self.text
- text.undo_block_start()
- if text.compare("insert linestart", "!=", "insert"):
- text.delete("insert linestart", "insert")
- if column:
- text.insert("insert", self._make_blanks(column))
- text.undo_block_stop()
-
- def _asktabwidth(self):
- return self.askinteger(
- "Tab width",
- "Columns per tab? (2-16)",
- parent=self.text,
- initialvalue=self.indentwidth,
- minvalue=2,
- maxvalue=16) or self.tabwidth
-
- # Guess indentwidth from text content.
- # Return guessed indentwidth. This should not be believed unless
- # it's in a reasonable range (e.g., it will be 0 if no indented
- # blocks are found).
-
- def guess_indent(self):
- opener, indented = IndentSearcher(self.text, self.tabwidth).run()
- if opener and indented:
- raw, indentsmall = classifyws(opener, self.tabwidth)
- raw, indentlarge = classifyws(indented, self.tabwidth)
- else:
- indentsmall = indentlarge = 0
- return indentlarge - indentsmall
-
-# "line.col" -> line, as an int
-def index2line(index):
- return int(float(index))
-
-# Look at the leading whitespace in s.
-# Return pair (# of leading ws characters,
-# effective # of leading blanks after expanding
-# tabs to width tabwidth)
-
-def classifyws(s, tabwidth):
- raw = effective = 0
- for ch in s:
- if ch == ' ':
- raw = raw + 1
- effective = effective + 1
- elif ch == '\t':
- raw = raw + 1
- effective = (effective // tabwidth + 1) * tabwidth
- else:
- break
- return raw, effective
-
-import tokenize
-_tokenize = tokenize
-del tokenize
-
-class IndentSearcher(object):
-
- # .run() chews over the Text widget, looking for a block opener
- # and the stmt following it. Returns a pair,
- # (line containing block opener, line containing stmt)
- # Either or both may be None.
-
- def __init__(self, text, tabwidth):
- self.text = text
- self.tabwidth = tabwidth
- self.i = self.finished = 0
- self.blkopenline = self.indentedline = None
-
- def readline(self):
- if self.finished:
- return ""
- i = self.i = self.i + 1
- mark = repr(i) + ".0"
- if self.text.compare(mark, ">=", "end"):
- return ""
- return self.text.get(mark, mark + " lineend+1c")
-
- def tokeneater(self, type, token, start, end, line,
- INDENT=_tokenize.INDENT,
- NAME=_tokenize.NAME,
- OPENERS=('class', 'def', 'for', 'if', 'try', 'while')):
- if self.finished:
- pass
- elif type == NAME and token in OPENERS:
- self.blkopenline = line
- elif type == INDENT and self.blkopenline:
- self.indentedline = line
- self.finished = 1
-
- def run(self):
- save_tabsize = _tokenize.tabsize
- _tokenize.tabsize = self.tabwidth
- try:
- try:
- _tokenize.tokenize(self.readline, self.tokeneater)
- except _tokenize.TokenError:
- # since we cut off the tokenizer early, we can trigger
- # spurious errors
- pass
- finally:
- _tokenize.tabsize = save_tabsize
- return self.blkopenline, self.indentedline
-
-### end autoindent code ###
-
-def prepstr(s):
- # Helper to extract the underscore from a string, e.g.
- # prepstr("Co_py") returns (2, "Copy").
- i = s.find('_')
- if i >= 0:
- s = s[:i] + s[i+1:]
- return i, s
-
-
-keynames = {
- 'bracketleft': '[',
- 'bracketright': ']',
- 'slash': '/',
-}
-
-def get_accelerator(keydefs, eventname):
- keylist = keydefs.get(eventname)
- if not keylist:
- return ""
- s = keylist[0]
- s = re.sub(r"-[a-z]\b", lambda m: m.group().upper(), s)
- s = re.sub(r"\b\w+\b", lambda m: keynames.get(m.group(), m.group()), s)
- s = re.sub("Key-", "", s)
- s = re.sub("Cancel","Ctrl-Break",s) # dscherer@cmu.edu
- s = re.sub("Control-", "Ctrl-", s)
- s = re.sub("-", "+", s)
- s = re.sub("><", " ", s)
- s = re.sub("<", "", s)
- s = re.sub(">", "", s)
- return s
-
-
-def fixwordbreaks(root):
- # Make sure that Tk's double-click and next/previous word
- # operations use our definition of a word (i.e. an identifier)
- 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=root, filename=filename)
- edit.set_close_hook(root.quit)
- root.mainloop()
- root.destroy()
-
-if __name__ == '__main__':
- test()
diff --git a/sys/lib/python/idlelib/FileList.py b/sys/lib/python/idlelib/FileList.py
deleted file mode 100644
index 4b5790102..000000000
--- a/sys/lib/python/idlelib/FileList.py
+++ /dev/null
@@ -1,124 +0,0 @@
-import os
-from Tkinter import *
-import tkMessageBox
-
-
-class FileList:
-
- from EditorWindow import EditorWindow # class variable, may be overridden
- # e.g. by PyShellFileList
-
- def __init__(self, root):
- self.root = root
- self.dict = {}
- self.inversedict = {}
- self.vars = {} # For EditorWindow.getrawvar (shared Tcl variables)
-
- def open(self, filename, action=None):
- assert filename
- filename = self.canonize(filename)
- if os.path.isdir(filename):
- # This can happen when bad filename is passed on command line:
- tkMessageBox.showerror(
- "File Error",
- "%r is a directory." % (filename,),
- master=self.root)
- return None
- key = os.path.normcase(filename)
- if self.dict.has_key(key):
- edit = self.dict[key]
- edit.top.wakeup()
- return edit
- if action:
- # Don't create window, perform 'action', e.g. open in same window
- return action(filename)
- else:
- return self.EditorWindow(self, filename, key)
-
- def gotofileline(self, filename, lineno=None):
- edit = self.open(filename)
- if edit is not None and lineno is not None:
- edit.gotoline(lineno)
-
- def new(self, filename=None):
- return self.EditorWindow(self, filename)
-
- def close_all_callback(self, event):
- for edit in self.inversedict.keys():
- reply = edit.close()
- if reply == "cancel":
- break
- return "break"
-
- def close_edit(self, edit):
- try:
- key = self.inversedict[edit]
- except KeyError:
- print "Don't know this EditorWindow object. (close)"
- return
- if key:
- del self.dict[key]
- del self.inversedict[edit]
- if not self.inversedict:
- self.root.quit()
-
- def filename_changed_edit(self, edit):
- edit.saved_change_hook()
- try:
- key = self.inversedict[edit]
- except KeyError:
- print "Don't know this EditorWindow object. (rename)"
- return
- filename = edit.io.filename
- if not filename:
- if key:
- del self.dict[key]
- self.inversedict[edit] = None
- return
- filename = self.canonize(filename)
- newkey = os.path.normcase(filename)
- if newkey == key:
- return
- if self.dict.has_key(newkey):
- conflict = self.dict[newkey]
- self.inversedict[conflict] = None
- tkMessageBox.showerror(
- "Name Conflict",
- "You now have multiple edit windows open for %r" % (filename,),
- master=self.root)
- self.dict[newkey] = edit
- self.inversedict[edit] = newkey
- if key:
- try:
- del self.dict[key]
- except KeyError:
- pass
-
- def canonize(self, filename):
- if not os.path.isabs(filename):
- try:
- pwd = os.getcwd()
- except os.error:
- pass
- else:
- filename = os.path.join(pwd, filename)
- return os.path.normpath(filename)
-
-
-def _test():
- from EditorWindow import fixwordbreaks
- import sys
- root = Tk()
- fixwordbreaks(root)
- root.withdraw()
- flist = FileList(root)
- if sys.argv[1:]:
- for filename in sys.argv[1:]:
- flist.open(filename)
- else:
- flist.new()
- if flist.inversedict:
- root.mainloop()
-
-if __name__ == '__main__':
- _test()
diff --git a/sys/lib/python/idlelib/FormatParagraph.py b/sys/lib/python/idlelib/FormatParagraph.py
deleted file mode 100644
index ed9f28d12..000000000
--- a/sys/lib/python/idlelib/FormatParagraph.py
+++ /dev/null
@@ -1,148 +0,0 @@
-# Extension to format a paragraph
-
-# Does basic, standard text formatting, and also understands Python
-# comment blocks. Thus, for editing Python source code, this
-# extension is really only suitable for reformatting these comment
-# blocks or triple-quoted strings.
-
-# Known problems with comment reformatting:
-# * If there is a selection marked, and the first line of the
-# selection is not complete, the block will probably not be detected
-# as comments, and will have the normal "text formatting" rules
-# applied.
-# * If a comment block has leading whitespace that mixes tabs and
-# spaces, they will not be considered part of the same block.
-# * Fancy comments, like this bulleted list, arent handled :-)
-
-import re
-from configHandler import idleConf
-
-class FormatParagraph:
-
- menudefs = [
- ('format', [ # /s/edit/format dscherer@cmu.edu
- ('Format Paragraph', '<<format-paragraph>>'),
- ])
- ]
-
- def __init__(self, editwin):
- self.editwin = editwin
-
- def close(self):
- self.editwin = None
-
- def format_paragraph_event(self, event):
- maxformatwidth = int(idleConf.GetOption('main','FormatParagraph','paragraph'))
- text = self.editwin.text
- first, last = self.editwin.get_selection_indices()
- if first and last:
- data = text.get(first, last)
- comment_header = ''
- else:
- first, last, comment_header, data = \
- find_paragraph(text, text.index("insert"))
- if comment_header:
- # Reformat the comment lines - convert to text sans header.
- lines = data.split("\n")
- lines = map(lambda st, l=len(comment_header): st[l:], lines)
- data = "\n".join(lines)
- # Reformat to maxformatwidth chars or a 20 char width, whichever is greater.
- format_width = max(maxformatwidth - len(comment_header), 20)
- newdata = reformat_paragraph(data, format_width)
- # re-split and re-insert the comment header.
- newdata = newdata.split("\n")
- # If the block ends in a \n, we dont want the comment
- # prefix inserted after it. (Im not sure it makes sense to
- # reformat a comment block that isnt made of complete
- # lines, but whatever!) Can't think of a clean soltution,
- # so we hack away
- block_suffix = ""
- if not newdata[-1]:
- block_suffix = "\n"
- newdata = newdata[:-1]
- builder = lambda item, prefix=comment_header: prefix+item
- newdata = '\n'.join(map(builder, newdata)) + block_suffix
- else:
- # Just a normal text format
- newdata = reformat_paragraph(data, maxformatwidth)
- text.tag_remove("sel", "1.0", "end")
- if newdata != data:
- text.mark_set("insert", first)
- text.undo_block_start()
- text.delete(first, last)
- text.insert(first, newdata)
- text.undo_block_stop()
- else:
- text.mark_set("insert", last)
- text.see("insert")
-
-def find_paragraph(text, mark):
- lineno, col = map(int, mark.split("."))
- line = text.get("%d.0" % lineno, "%d.0 lineend" % lineno)
- while text.compare("%d.0" % lineno, "<", "end") and is_all_white(line):
- lineno = lineno + 1
- line = text.get("%d.0" % lineno, "%d.0 lineend" % lineno)
- first_lineno = lineno
- comment_header = get_comment_header(line)
- comment_header_len = len(comment_header)
- while get_comment_header(line)==comment_header and \
- not is_all_white(line[comment_header_len:]):
- lineno = lineno + 1
- line = text.get("%d.0" % lineno, "%d.0 lineend" % lineno)
- last = "%d.0" % lineno
- # Search back to beginning of paragraph
- lineno = first_lineno - 1
- line = text.get("%d.0" % lineno, "%d.0 lineend" % lineno)
- while lineno > 0 and \
- get_comment_header(line)==comment_header and \
- not is_all_white(line[comment_header_len:]):
- lineno = lineno - 1
- line = text.get("%d.0" % lineno, "%d.0 lineend" % lineno)
- first = "%d.0" % (lineno+1)
- return first, last, comment_header, text.get(first, last)
-
-def reformat_paragraph(data, limit):
- lines = data.split("\n")
- i = 0
- n = len(lines)
- while i < n and is_all_white(lines[i]):
- i = i+1
- if i >= n:
- return data
- indent1 = get_indent(lines[i])
- if i+1 < n and not is_all_white(lines[i+1]):
- indent2 = get_indent(lines[i+1])
- else:
- indent2 = indent1
- new = lines[:i]
- partial = indent1
- while i < n and not is_all_white(lines[i]):
- # XXX Should take double space after period (etc.) into account
- words = re.split("(\s+)", lines[i])
- for j in range(0, len(words), 2):
- word = words[j]
- if not word:
- continue # Can happen when line ends in whitespace
- if len((partial + word).expandtabs()) > limit and \
- partial != indent1:
- new.append(partial.rstrip())
- partial = indent2
- partial = partial + word + " "
- if j+1 < len(words) and words[j+1] != " ":
- partial = partial + " "
- i = i+1
- new.append(partial.rstrip())
- # XXX Should reformat remaining paragraphs as well
- new.extend(lines[i:])
- return "\n".join(new)
-
-def is_all_white(line):
- return re.match(r"^\s*$", line) is not None
-
-def get_indent(line):
- return re.match(r"^(\s*)", line).group()
-
-def get_comment_header(line):
- m = re.match(r"^(\s*#*)", line)
- if m is None: return ""
- return m.group(1)
diff --git a/sys/lib/python/idlelib/GrepDialog.py b/sys/lib/python/idlelib/GrepDialog.py
deleted file mode 100644
index ab136bc11..000000000
--- a/sys/lib/python/idlelib/GrepDialog.py
+++ /dev/null
@@ -1,133 +0,0 @@
-import os
-import fnmatch
-import sys
-from Tkinter import *
-import SearchEngine
-from SearchDialogBase import SearchDialogBase
-
-def grep(text, io=None, flist=None):
- root = text._root()
- engine = SearchEngine.get(root)
- if not hasattr(engine, "_grepdialog"):
- engine._grepdialog = GrepDialog(root, engine, flist)
- dialog = engine._grepdialog
- searchphrase = text.get("sel.first", "sel.last")
- dialog.open(text, searchphrase, io)
-
-class GrepDialog(SearchDialogBase):
-
- title = "Find in Files Dialog"
- icon = "Grep"
- needwrapbutton = 0
-
- def __init__(self, root, engine, flist):
- SearchDialogBase.__init__(self, root, engine)
- self.flist = flist
- self.globvar = StringVar(root)
- self.recvar = BooleanVar(root)
-
- def open(self, text, searchphrase, io=None):
- SearchDialogBase.open(self, text, searchphrase)
- if io:
- path = io.filename or ""
- else:
- path = ""
- dir, base = os.path.split(path)
- head, tail = os.path.splitext(base)
- if not tail:
- tail = ".py"
- self.globvar.set(os.path.join(dir, "*" + tail))
-
- def create_entries(self):
- SearchDialogBase.create_entries(self)
- self.globent = self.make_entry("In files:", self.globvar)
-
- def create_other_buttons(self):
- f = self.make_frame()
-
- btn = Checkbutton(f, anchor="w",
- variable=self.recvar,
- text="Recurse down subdirectories")
- btn.pack(side="top", fill="both")
- btn.select()
-
- def create_command_buttons(self):
- SearchDialogBase.create_command_buttons(self)
- self.make_button("Search Files", self.default_command, 1)
-
- def default_command(self, event=None):
- prog = self.engine.getprog()
- if not prog:
- return
- path = self.globvar.get()
- if not path:
- self.top.bell()
- return
- from OutputWindow import OutputWindow
- save = sys.stdout
- try:
- sys.stdout = OutputWindow(self.flist)
- self.grep_it(prog, path)
- finally:
- sys.stdout = save
-
- def grep_it(self, prog, path):
- dir, base = os.path.split(path)
- list = self.findfiles(dir, base, self.recvar.get())
- list.sort()
- self.close()
- pat = self.engine.getpat()
- print "Searching %r in %s ..." % (pat, path)
- hits = 0
- for fn in list:
- try:
- f = open(fn)
- except IOError, msg:
- print msg
- continue
- lineno = 0
- while 1:
- block = f.readlines(100000)
- if not block:
- break
- for line in block:
- lineno = lineno + 1
- if line[-1:] == '\n':
- line = line[:-1]
- if prog.search(line):
- sys.stdout.write("%s: %s: %s\n" % (fn, lineno, line))
- hits = hits + 1
- if hits:
- if hits == 1:
- s = ""
- else:
- s = "s"
- print "Found", hits, "hit%s." % s
- print "(Hint: right-click to open locations.)"
- else:
- print "No hits."
-
- def findfiles(self, dir, base, rec):
- try:
- names = os.listdir(dir or os.curdir)
- except os.error, msg:
- print msg
- return []
- list = []
- subdirs = []
- for name in names:
- fn = os.path.join(dir, name)
- if os.path.isdir(fn):
- subdirs.append(fn)
- else:
- if fnmatch.fnmatch(name, base):
- list.append(fn)
- if rec:
- for subdir in subdirs:
- list.extend(self.findfiles(subdir, base, rec))
- return list
-
- def close(self, event=None):
- if self.top:
- self.top.grab_release()
- self.top.withdraw()
diff --git a/sys/lib/python/idlelib/HISTORY.txt b/sys/lib/python/idlelib/HISTORY.txt
deleted file mode 100644
index c0faaad87..000000000
--- a/sys/lib/python/idlelib/HISTORY.txt
+++ /dev/null
@@ -1,296 +0,0 @@
-IDLE History
-============
-
-This file contains the release messages for previous IDLE releases.
-As you read on you go back to the dark ages of IDLE's history.
-
-
-What's New in IDLEfork 0.8.1?
-=============================
-
-*Release date: 22-Jul-2001*
-
-- New tarball released as a result of the 'revitalisation' of the IDLEfork
- project.
-
-- This release requires python 2.1 or better. Compatability with earlier
- versions of python (especially ancient ones like 1.5x) is no longer a
- priority in IDLEfork development.
-
-- This release is based on a merging of the earlier IDLE fork work with current
- cvs IDLE (post IDLE version 0.8), with some minor additional coding by Kurt
- B. Kaiser and Stephen M. Gava.
-
-- This release is basically functional but also contains some known breakages,
- particularly with running things from the shell window. Also the debugger is
- not working, but I believe this was the case with the previous IDLE fork
- release (0.7.1) as well.
-
-- This release is being made now to mark the point at which IDLEfork is
- launching into a new stage of development.
-
-- IDLEfork CVS will now be branched to enable further development and
- exploration of the two "execution in a remote process" patches submitted by
- David Scherer (David's is currently in IDLEfork) and GvR, while stabilisation
- and development of less heavyweight improvements (like user customisation)
- can continue on the trunk.
-
-
-What's New in IDLEfork 0.7.1?
-==============================
-
-*Release date: 15-Aug-2000*
-
-- First project tarball released.
-
-- This was the first release of IDLE fork, which at this stage was a
- combination of IDLE 0.5 and the VPython idle fork, with additional changes
- coded by David Scherer, Peter Schneider-Kamp and Nicholas Riley.
-
-
-
-IDLEfork 0.7.1 - 29 May 2000
------------------------------
-
- David Scherer <dscherer@cmu.edu>
-
-- This is a modification of the CVS version of IDLE 0.5, updated as of
- 2000-03-09. It is alpha software and might be unstable. If it breaks, you
- get to keep both pieces.
-
-- If you have problems or suggestions, you should either contact me or post to
- the list at http://www.python.org/mailman/listinfo/idle-dev (making it clear
- that you are using this modified version of IDLE).
-
-- Changes:
-
- - The ExecBinding module, a replacement for ScriptBinding, executes programs
- in a separate process, piping standard I/O through an RPC mechanism to an
- OnDemandOutputWindow in IDLE. It supports executing unnamed programs
- (through a temporary file). It does not yet support debugging.
-
- - When running programs with ExecBinding, tracebacks will be clipped to
- exclude system modules. If, however, a system module calls back into the
- user program, that part of the traceback will be shown.
-
- - The OnDemandOutputWindow class has been improved. In particular, it now
- supports a readline() function used to implement user input, and a
- scroll_clear() operation which is used to hide the output of a previous run
- by scrolling it out of the window.
-
- - Startup behavior has been changed. By default IDLE starts up with just a
- blank editor window, rather than an interactive window. Opening a file in
- such a blank window replaces the (nonexistent) contents of that window
- instead of creating another window. Because of the need to have a
- well-known port for the ExecBinding protocol, only one copy of IDLE can be
- running. Additional invocations use the RPC mechanism to report their
- command line arguments to the copy already running.
-
- - The menus have been reorganized. In particular, the excessively large
- 'edit' menu has been split up into 'edit', 'format', and 'run'.
-
- - 'Python Documentation' now works on Windows, if the win32api module is
- present.
-
- - A few key bindings have been changed: F1 now loads Python Documentation
- instead of the IDLE help; shift-TAB is now a synonym for unindent.
-
-- New modules:
-
- ExecBinding.py Executes program through loader
- loader.py Bootstraps user program
- protocol.py RPC protocol
- Remote.py User-process interpreter
- spawn.py OS-specific code to start programs
-
-- Files modified:
-
- autoindent.py ( bindings tweaked )
- bindings.py ( menus reorganized )
- config.txt ( execbinding enabled )
- editorwindow.py ( new menus, fixed 'Python Documentation' )
- filelist.py ( hook for "open in same window" )
- formatparagraph.py ( bindings tweaked )
- idle.bat ( removed absolute pathname )
- idle.pyw ( weird bug due to import with same name? )
- iobinding.py ( open in same window, EOL convention )
- keydefs.py ( bindings tweaked )
- outputwindow.py ( readline, scroll_clear, etc )
- pyshell.py ( changed startup behavior )
- readme.txt ( <Recursion on file with id=1234567> )
-
-
-
-IDLE 0.5 - February 2000 - Release Notes
-----------------------------------------
-
-This is an early release of IDLE, my own attempt at a Tkinter-based
-IDE for Python.
-
-(For a more detailed change log, see the file ChangeLog.)
-
-FEATURES
-
-IDLE has the following features:
-
-- coded in 100% pure Python, using the Tkinter GUI toolkit (i.e. Tcl/Tk)
-
-- cross-platform: works on Windows and Unix (on the Mac, there are
-currently problems with Tcl/Tk)
-
-- multi-window text editor with multiple undo, Python colorizing
-and many other features, e.g. smart indent and call tips
-
-- Python shell window (a.k.a. interactive interpreter)
-
-- debugger (not complete, but you can set breakpoints, view and step)
-
-USAGE
-
-The main program is in the file "idle.py"; on Unix, you should be able
-to run it by typing "./idle.py" to your shell. On Windows, you can
-run it by double-clicking it; you can use idle.pyw to avoid popping up
-a DOS console. If you want to pass command line arguments on Windows,
-use the batch file idle.bat.
-
-Command line arguments: files passed on the command line are executed,
-not opened for editing, unless you give the -e command line option.
-Try "./idle.py -h" to see other command line options.
-
-IDLE requires Python 1.5.2, so it is currently only usable with a
-Python 1.5.2 distribution. (An older version of IDLE is distributed
-with Python 1.5.2; you can drop this version on top of it.)
-
-COPYRIGHT
-
-IDLE is covered by the standard Python copyright notice
-(http://www.python.org/doc/Copyright.html).
-
-
-New in IDLE 0.5 (2/15/2000)
----------------------------
-
-Tons of stuff, much of it contributed by Tim Peters and Mark Hammond:
-
-- Status bar, displaying current line/column (Moshe Zadka).
-
-- Better stack viewer, using tree widget. (XXX Only used by Stack
-Viewer menu, not by the debugger.)
-
-- Format paragraph now recognizes Python block comments and reformats
-them correctly (MH)
-
-- New version of pyclbr.py parses top-level functions and understands
-much more of Python's syntax; this is reflected in the class and path
-browsers (TP)
-
-- Much better auto-indent; knows how to indent the insides of
-multi-line statements (TP)
-
-- Call tip window pops up when you type the name of a known function
-followed by an open parenthesis. Hit ESC or click elsewhere in the
-window to close the tip window (MH)
-
-- Comment out region now inserts ## to make it stand out more (TP)
-
-- New path and class browsers based on a tree widget that looks
-familiar to Windows users
-
-- Reworked script running commands to be more intuitive: I/O now
-always goes to the *Python Shell* window, and raw_input() works
-correctly. You use F5 to import/reload a module: this adds the module
-name to the __main__ namespace. You use Control-F5 to run a script:
-this runs the script *in* the __main__ namespace. The latter also
-sets sys.argv[] to the script name
-
-
-New in IDLE 0.4 (4/7/99)
-------------------------
-
-Most important change: a new menu entry "File -> Path browser", shows
-a 4-column hierarchical browser which lets you browse sys.path,
-directories, modules, and classes. Yes, it's a superset of the Class
-browser menu entry. There's also a new internal module,
-MultiScrolledLists.py, which provides the framework for this dialog.
-
-
-New in IDLE 0.3 (2/17/99)
--------------------------
-
-Most important changes:
-
-- Enabled support for running a module, with or without the debugger.
-Output goes to a new window. Pressing F5 in a module is effectively a
-reload of that module; Control-F5 loads it under the debugger.
-
-- Re-enable tearing off the Windows menu, and make a torn-off Windows
-menu update itself whenever a window is opened or closed.
-
-- Menu items can now be have a checkbox (when the menu label starts
-with "!"); use this for the Debugger and "Auto-open stack viewer"
-(was: JIT stack viewer) menu items.
-
-- Added a Quit button to the Debugger API.
-
-- The current directory is explicitly inserted into sys.path.
-
-- Fix the debugger (when using Python 1.5.2b2) to use canonical
-filenames for breakpoints, so these actually work. (There's still a
-lot of work to be done to the management of breakpoints in the
-debugger though.)
-
-- Closing a window that is still colorizing now actually works.
-
-- Allow dragging of the separator between the two list boxes in the
-class browser.
-
-- Bind ESC to "close window" of the debugger, stack viewer and class
-browser. It removes the selection highlighting in regular text
-windows. (These are standard Windows conventions.)
-
-
-New in IDLE 0.2 (1/8/99)
-------------------------
-
-Lots of changes; here are the highlights:
-
-General:
-
-- You can now write and configure your own IDLE extension modules; see
-extend.txt.
-
-
-File menu:
-
-The command to open the Python shell window is now in the File menu.
-
-
-Edit menu:
-
-New Find dialog with more options; replace dialog; find in files dialog.
-
-Commands to tabify or untabify a region.
-
-Command to format a paragraph.
-
-
-Debug menu:
-
-JIT (Just-In-Time) stack viewer toggle -- if set, the stack viewer
-automaticall pops up when you get a traceback.
-
-Windows menu:
-
-Zoom height -- make the window full height.
-
-
-Help menu:
-
-The help text now show up in a regular window so you can search and
-even edit it if you like.
-
-
-
-IDLE 0.1 was distributed with the Python 1.5.2b1 release on 12/22/98.
-
-======================================================================
diff --git a/sys/lib/python/idlelib/HyperParser.py b/sys/lib/python/idlelib/HyperParser.py
deleted file mode 100644
index 519de74d1..000000000
--- a/sys/lib/python/idlelib/HyperParser.py
+++ /dev/null
@@ -1,241 +0,0 @@
-"""
-HyperParser
-===========
-This module defines the HyperParser class, which provides advanced parsing
-abilities for the ParenMatch and other extensions.
-The HyperParser uses PyParser. PyParser is intended mostly to give information
-on the proper indentation of code. HyperParser gives some information on the
-structure of code, used by extensions to help the user.
-"""
-
-import string
-import keyword
-import PyParse
-
-class HyperParser:
-
- def __init__(self, editwin, index):
- """Initialize the HyperParser to analyze the surroundings of the given
- index.
- """
-
- self.editwin = editwin
- self.text = text = editwin.text
-
- parser = PyParse.Parser(editwin.indentwidth, editwin.tabwidth)
-
- def index2line(index):
- return int(float(index))
- lno = index2line(text.index(index))
-
- if not editwin.context_use_ps1:
- for context in editwin.num_context_lines:
- startat = max(lno - context, 1)
- startatindex = `startat` + ".0"
- stopatindex = "%d.end" % lno
- # We add the newline because PyParse requires a newline at end.
- # We add a space so that index won't be at end of line, so that
- # its status will be the same as the char before it, if should.
- parser.set_str(text.get(startatindex, stopatindex)+' \n')
- bod = parser.find_good_parse_start(
- editwin._build_char_in_string_func(startatindex))
- if bod is not None or startat == 1:
- break
- parser.set_lo(bod or 0)
- else:
- r = text.tag_prevrange("console", index)
- if r:
- startatindex = r[1]
- else:
- startatindex = "1.0"
- stopatindex = "%d.end" % lno
- # We add the newline because PyParse requires a newline at end.
- # We add a space so that index won't be at end of line, so that
- # its status will be the same as the char before it, if should.
- parser.set_str(text.get(startatindex, stopatindex)+' \n')
- parser.set_lo(0)
-
- # We want what the parser has, except for the last newline and space.
- self.rawtext = parser.str[:-2]
- # As far as I can see, parser.str preserves the statement we are in,
- # so that stopatindex can be used to synchronize the string with the
- # text box indices.
- self.stopatindex = stopatindex
- self.bracketing = parser.get_last_stmt_bracketing()
- # find which pairs of bracketing are openers. These always correspond
- # to a character of rawtext.
- self.isopener = [i>0 and self.bracketing[i][1] > self.bracketing[i-1][1]
- for i in range(len(self.bracketing))]
-
- self.set_index(index)
-
- def set_index(self, index):
- """Set the index to which the functions relate. Note that it must be
- in the same statement.
- """
- indexinrawtext = \
- len(self.rawtext) - len(self.text.get(index, self.stopatindex))
- if indexinrawtext < 0:
- raise ValueError("The index given is before the analyzed statement")
- self.indexinrawtext = indexinrawtext
- # find the rightmost bracket to which index belongs
- self.indexbracket = 0
- while self.indexbracket < len(self.bracketing)-1 and \
- self.bracketing[self.indexbracket+1][0] < self.indexinrawtext:
- self.indexbracket += 1
- if self.indexbracket < len(self.bracketing)-1 and \
- self.bracketing[self.indexbracket+1][0] == self.indexinrawtext and \
- not self.isopener[self.indexbracket+1]:
- self.indexbracket += 1
-
- def is_in_string(self):
- """Is the index given to the HyperParser is in a string?"""
- # The bracket to which we belong should be an opener.
- # If it's an opener, it has to have a character.
- return self.isopener[self.indexbracket] and \
- self.rawtext[self.bracketing[self.indexbracket][0]] in ('"', "'")
-
- def is_in_code(self):
- """Is the index given to the HyperParser is in a normal code?"""
- return not self.isopener[self.indexbracket] or \
- self.rawtext[self.bracketing[self.indexbracket][0]] not in \
- ('#', '"', "'")
-
- def get_surrounding_brackets(self, openers='([{', mustclose=False):
- """If the index given to the HyperParser is surrounded by a bracket
- defined in openers (or at least has one before it), return the
- indices of the opening bracket and the closing bracket (or the
- end of line, whichever comes first).
- If it is not surrounded by brackets, or the end of line comes before
- the closing bracket and mustclose is True, returns None.
- """
- bracketinglevel = self.bracketing[self.indexbracket][1]
- before = self.indexbracket
- while not self.isopener[before] or \
- self.rawtext[self.bracketing[before][0]] not in openers or \
- self.bracketing[before][1] > bracketinglevel:
- before -= 1
- if before < 0:
- return None
- bracketinglevel = min(bracketinglevel, self.bracketing[before][1])
- after = self.indexbracket + 1
- while after < len(self.bracketing) and \
- self.bracketing[after][1] >= bracketinglevel:
- after += 1
-
- beforeindex = self.text.index("%s-%dc" %
- (self.stopatindex, len(self.rawtext)-self.bracketing[before][0]))
- if after >= len(self.bracketing) or \
- self.bracketing[after][0] > len(self.rawtext):
- if mustclose:
- return None
- afterindex = self.stopatindex
- else:
- # We are after a real char, so it is a ')' and we give the index
- # before it.
- afterindex = self.text.index("%s-%dc" %
- (self.stopatindex,
- len(self.rawtext)-(self.bracketing[after][0]-1)))
-
- return beforeindex, afterindex
-
- # This string includes all chars that may be in a white space
- _whitespace_chars = " \t\n\\"
- # This string includes all chars that may be in an identifier
- _id_chars = string.ascii_letters + string.digits + "_"
- # This string includes all chars that may be the first char of an identifier
- _id_first_chars = string.ascii_letters + "_"
-
- # Given a string and pos, return the number of chars in the identifier
- # which ends at pos, or 0 if there is no such one. Saved words are not
- # identifiers.
- def _eat_identifier(self, str, limit, pos):
- i = pos
- while i > limit and str[i-1] in self._id_chars:
- i -= 1
- if i < pos and (str[i] not in self._id_first_chars or \
- keyword.iskeyword(str[i:pos])):
- i = pos
- return pos - i
-
- def get_expression(self):
- """Return a string with the Python expression which ends at the given
- index, which is empty if there is no real one.
- """
- if not self.is_in_code():
- raise ValueError("get_expression should only be called if index "\
- "is inside a code.")
-
- rawtext = self.rawtext
- bracketing = self.bracketing
-
- brck_index = self.indexbracket
- brck_limit = bracketing[brck_index][0]
- pos = self.indexinrawtext
-
- last_identifier_pos = pos
- postdot_phase = True
-
- while 1:
- # Eat whitespaces, comments, and if postdot_phase is False - one dot
- while 1:
- if pos>brck_limit and rawtext[pos-1] in self._whitespace_chars:
- # Eat a whitespace
- pos -= 1
- elif not postdot_phase and \
- pos > brck_limit and rawtext[pos-1] == '.':
- # Eat a dot
- pos -= 1
- postdot_phase = True
- # The next line will fail if we are *inside* a comment, but we
- # shouldn't be.
- elif pos == brck_limit and brck_index > 0 and \
- rawtext[bracketing[brck_index-1][0]] == '#':
- # Eat a comment
- brck_index -= 2
- brck_limit = bracketing[brck_index][0]
- pos = bracketing[brck_index+1][0]
- else:
- # If we didn't eat anything, quit.
- break
-
- if not postdot_phase:
- # We didn't find a dot, so the expression end at the last
- # identifier pos.
- break
-
- ret = self._eat_identifier(rawtext, brck_limit, pos)
- if ret:
- # There is an identifier to eat
- pos = pos - ret
- last_identifier_pos = pos
- # Now, in order to continue the search, we must find a dot.
- postdot_phase = False
- # (the loop continues now)
-
- elif pos == brck_limit:
- # We are at a bracketing limit. If it is a closing bracket,
- # eat the bracket, otherwise, stop the search.
- level = bracketing[brck_index][1]
- while brck_index > 0 and bracketing[brck_index-1][1] > level:
- brck_index -= 1
- if bracketing[brck_index][0] == brck_limit:
- # We were not at the end of a closing bracket
- break
- pos = bracketing[brck_index][0]
- brck_index -= 1
- brck_limit = bracketing[brck_index][0]
- last_identifier_pos = pos
- if rawtext[pos] in "([":
- # [] and () may be used after an identifier, so we
- # continue. postdot_phase is True, so we don't allow a dot.
- pass
- else:
- # We can't continue after other types of brackets
- break
-
- else:
- # We've found an operator or something.
- break
-
- return rawtext[last_identifier_pos:self.indexinrawtext]
diff --git a/sys/lib/python/idlelib/IOBinding.py b/sys/lib/python/idlelib/IOBinding.py
deleted file mode 100644
index deeb5c527..000000000
--- a/sys/lib/python/idlelib/IOBinding.py
+++ /dev/null
@@ -1,584 +0,0 @@
-# changes by dscherer@cmu.edu
-# - IOBinding.open() replaces the current window with the opened file,
-# if the current window is both unmodified and unnamed
-# - IOBinding.loadfile() interprets Windows, UNIX, and Macintosh
-# end-of-line conventions, instead of relying on the standard library,
-# which will only understand the local convention.
-
-import os
-import types
-import sys
-import codecs
-import tempfile
-import tkFileDialog
-import tkMessageBox
-import re
-from Tkinter import *
-from SimpleDialog import SimpleDialog
-
-from configHandler import idleConf
-
-try:
- from codecs import BOM_UTF8
-except ImportError:
- # only available since Python 2.3
- BOM_UTF8 = '\xef\xbb\xbf'
-
-# Try setting the locale, so that we can find out
-# what encoding to use
-try:
- import locale
- locale.setlocale(locale.LC_CTYPE, "")
-except (ImportError, locale.Error):
- pass
-
-# Encoding for file names
-filesystemencoding = sys.getfilesystemencoding()
-
-encoding = "ascii"
-if sys.platform == 'win32':
- # On Windows, we could use "mbcs". However, to give the user
- # a portable encoding name, we need to find the code page
- try:
- encoding = locale.getdefaultlocale()[1]
- codecs.lookup(encoding)
- except LookupError:
- pass
-else:
- try:
- # Different things can fail here: the locale module may not be
- # loaded, it may not offer nl_langinfo, or CODESET, or the
- # resulting codeset may be unknown to Python. We ignore all
- # these problems, falling back to ASCII
- encoding = locale.nl_langinfo(locale.CODESET)
- if encoding is None or encoding is '':
- # situation occurs on Mac OS X
- encoding = 'ascii'
- codecs.lookup(encoding)
- except (NameError, AttributeError, LookupError):
- # Try getdefaultlocale well: it parses environment variables,
- # which may give a clue. Unfortunately, getdefaultlocale has
- # bugs that can cause ValueError.
- try:
- encoding = locale.getdefaultlocale()[1]
- if encoding is None or encoding is '':
- # situation occurs on Mac OS X
- encoding = 'ascii'
- codecs.lookup(encoding)
- except (ValueError, LookupError):
- pass
-
-encoding = encoding.lower()
-
-coding_re = re.compile("coding[:=]\s*([-\w_.]+)")
-
-class EncodingMessage(SimpleDialog):
- "Inform user that an encoding declaration is needed."
- def __init__(self, master, enc):
- self.should_edit = False
-
- self.root = top = Toplevel(master)
- top.bind("<Return>", self.return_event)
- top.bind("<Escape>", self.do_ok)
- top.protocol("WM_DELETE_WINDOW", self.wm_delete_window)
- top.wm_title("I/O Warning")
- top.wm_iconname("I/O Warning")
- self.top = top
-
- l1 = Label(top,
- text="Non-ASCII found, yet no encoding declared. Add a line like")
- l1.pack(side=TOP, anchor=W)
- l2 = Entry(top, font="courier")
- l2.insert(0, "# -*- coding: %s -*-" % enc)
- # For some reason, the text is not selectable anymore if the
- # widget is disabled.
- # l2['state'] = DISABLED
- l2.pack(side=TOP, anchor = W, fill=X)
- l3 = Label(top, text="to your file\n"
- "Choose OK to save this file as %s\n"
- "Edit your general options to silence this warning" % enc)
- l3.pack(side=TOP, anchor = W)
-
- buttons = Frame(top)
- buttons.pack(side=TOP, fill=X)
- # Both return and cancel mean the same thing: do nothing
- self.default = self.cancel = 0
- b1 = Button(buttons, text="Ok", default="active",
- command=self.do_ok)
- b1.pack(side=LEFT, fill=BOTH, expand=1)
- b2 = Button(buttons, text="Edit my file",
- command=self.do_edit)
- b2.pack(side=LEFT, fill=BOTH, expand=1)
-
- self._set_transient(master)
-
- def do_ok(self):
- self.done(0)
-
- def do_edit(self):
- self.done(1)
-
-def coding_spec(str):
- """Return the encoding declaration according to PEP 263.
-
- Raise LookupError if the encoding is declared but unknown.
- """
- # Only consider the first two lines
- str = str.split("\n")[:2]
- str = "\n".join(str)
-
- match = coding_re.search(str)
- if not match:
- return None
- name = match.group(1)
- # Check whether the encoding is known
- import codecs
- try:
- codecs.lookup(name)
- except LookupError:
- # The standard encoding error does not indicate the encoding
- raise LookupError, "Unknown encoding "+name
- return name
-
-
-class IOBinding:
-
- def __init__(self, editwin):
- self.editwin = editwin
- self.text = editwin.text
- self.__id_open = self.text.bind("<<open-window-from-file>>", self.open)
- self.__id_save = self.text.bind("<<save-window>>", self.save)
- self.__id_saveas = self.text.bind("<<save-window-as-file>>",
- self.save_as)
- self.__id_savecopy = self.text.bind("<<save-copy-of-window-as-file>>",
- self.save_a_copy)
- self.fileencoding = None
- self.__id_print = self.text.bind("<<print-window>>", self.print_window)
-
- def close(self):
- # Undo command bindings
- self.text.unbind("<<open-window-from-file>>", self.__id_open)
- self.text.unbind("<<save-window>>", self.__id_save)
- self.text.unbind("<<save-window-as-file>>",self.__id_saveas)
- self.text.unbind("<<save-copy-of-window-as-file>>", self.__id_savecopy)
- self.text.unbind("<<print-window>>", self.__id_print)
- # Break cycles
- self.editwin = None
- self.text = None
- self.filename_change_hook = None
-
- def get_saved(self):
- return self.editwin.get_saved()
-
- def set_saved(self, flag):
- self.editwin.set_saved(flag)
-
- def reset_undo(self):
- self.editwin.reset_undo()
-
- filename_change_hook = None
-
- def set_filename_change_hook(self, hook):
- self.filename_change_hook = hook
-
- filename = None
- dirname = None
-
- def set_filename(self, filename):
- if filename and os.path.isdir(filename):
- self.filename = None
- self.dirname = filename
- else:
- self.filename = filename
- self.dirname = None
- self.set_saved(1)
- if self.filename_change_hook:
- self.filename_change_hook()
-
- def open(self, event=None, editFile=None):
- if self.editwin.flist:
- if not editFile:
- filename = self.askopenfile()
- else:
- filename=editFile
- if filename:
- # If the current window has no filename and hasn't been
- # modified, we replace its contents (no loss). Otherwise
- # we open a new window. But we won't replace the
- # shell window (which has an interp(reter) attribute), which
- # gets set to "not modified" at every new prompt.
- try:
- interp = self.editwin.interp
- except:
- interp = None
- if not self.filename and self.get_saved() and not interp:
- self.editwin.flist.open(filename, self.loadfile)
- else:
- self.editwin.flist.open(filename)
- else:
- self.text.focus_set()
- return "break"
- #
- # Code for use outside IDLE:
- if self.get_saved():
- reply = self.maybesave()
- if reply == "cancel":
- self.text.focus_set()
- return "break"
- if not editFile:
- filename = self.askopenfile()
- else:
- filename=editFile
- if filename:
- self.loadfile(filename)
- else:
- self.text.focus_set()
- return "break"
-
- eol = r"(\r\n)|\n|\r" # \r\n (Windows), \n (UNIX), or \r (Mac)
- eol_re = re.compile(eol)
- eol_convention = os.linesep # Default
-
- def loadfile(self, filename):
- try:
- # open the file in binary mode so that we can handle
- # end-of-line convention ourselves.
- f = open(filename,'rb')
- chars = f.read()
- f.close()
- except IOError, msg:
- tkMessageBox.showerror("I/O Error", str(msg), master=self.text)
- return False
-
- chars = self.decode(chars)
- # We now convert all end-of-lines to '\n's
- firsteol = self.eol_re.search(chars)
- if firsteol:
- self.eol_convention = firsteol.group(0)
- if isinstance(self.eol_convention, unicode):
- # Make sure it is an ASCII string
- self.eol_convention = self.eol_convention.encode("ascii")
- chars = self.eol_re.sub(r"\n", chars)
-
- self.text.delete("1.0", "end")
- self.set_filename(None)
- self.text.insert("1.0", chars)
- self.reset_undo()
- self.set_filename(filename)
- self.text.mark_set("insert", "1.0")
- self.text.see("insert")
- self.updaterecentfileslist(filename)
- return True
-
- def decode(self, chars):
- """Create a Unicode string
-
- If that fails, let Tcl try its best
- """
- # Check presence of a UTF-8 signature first
- if chars.startswith(BOM_UTF8):
- try:
- chars = chars[3:].decode("utf-8")
- except UnicodeError:
- # has UTF-8 signature, but fails to decode...
- return chars
- else:
- # Indicates that this file originally had a BOM
- self.fileencoding = BOM_UTF8
- return chars
- # Next look for coding specification
- try:
- enc = coding_spec(chars)
- except LookupError, name:
- tkMessageBox.showerror(
- title="Error loading the file",
- message="The encoding '%s' is not known to this Python "\
- "installation. The file may not display correctly" % name,
- master = self.text)
- enc = None
- if enc:
- try:
- return unicode(chars, enc)
- except UnicodeError:
- pass
- # If it is ASCII, we need not to record anything
- try:
- return unicode(chars, 'ascii')
- except UnicodeError:
- pass
- # Finally, try the locale's encoding. This is deprecated;
- # the user should declare a non-ASCII encoding
- try:
- chars = unicode(chars, encoding)
- self.fileencoding = encoding
- except UnicodeError:
- pass
- return chars
-
- def maybesave(self):
- if self.get_saved():
- return "yes"
- message = "Do you want to save %s before closing?" % (
- self.filename or "this untitled document")
- m = tkMessageBox.Message(
- title="Save On Close",
- message=message,
- icon=tkMessageBox.QUESTION,
- type=tkMessageBox.YESNOCANCEL,
- master=self.text)
- reply = m.show()
- if reply == "yes":
- self.save(None)
- if not self.get_saved():
- reply = "cancel"
- self.text.focus_set()
- return reply
-
- def save(self, event):
- if not self.filename:
- self.save_as(event)
- else:
- if self.writefile(self.filename):
- self.set_saved(1)
- try:
- self.editwin.store_file_breaks()
- except AttributeError: # may be a PyShell
- pass
- self.text.focus_set()
- return "break"
-
- def save_as(self, event):
- filename = self.asksavefile()
- if filename:
- if self.writefile(filename):
- self.set_filename(filename)
- self.set_saved(1)
- try:
- self.editwin.store_file_breaks()
- except AttributeError:
- pass
- self.text.focus_set()
- self.updaterecentfileslist(filename)
- return "break"
-
- def save_a_copy(self, event):
- filename = self.asksavefile()
- if filename:
- self.writefile(filename)
- self.text.focus_set()
- self.updaterecentfileslist(filename)
- return "break"
-
- def writefile(self, filename):
- self.fixlastline()
- chars = self.encode(self.text.get("1.0", "end-1c"))
- if self.eol_convention != "\n":
- chars = chars.replace("\n", self.eol_convention)
- try:
- f = open(filename, "wb")
- f.write(chars)
- f.flush()
- f.close()
- return True
- except IOError, msg:
- tkMessageBox.showerror("I/O Error", str(msg),
- master=self.text)
- return False
-
- def encode(self, chars):
- if isinstance(chars, types.StringType):
- # This is either plain ASCII, or Tk was returning mixed-encoding
- # text to us. Don't try to guess further.
- return chars
- # See whether there is anything non-ASCII in it.
- # If not, no need to figure out the encoding.
- try:
- return chars.encode('ascii')
- except UnicodeError:
- pass
- # If there is an encoding declared, try this first.
- try:
- enc = coding_spec(chars)
- failed = None
- except LookupError, msg:
- failed = msg
- enc = None
- if enc:
- try:
- return chars.encode(enc)
- except UnicodeError:
- failed = "Invalid encoding '%s'" % enc
- if failed:
- tkMessageBox.showerror(
- "I/O Error",
- "%s. Saving as UTF-8" % failed,
- master = self.text)
- # If there was a UTF-8 signature, use that. This should not fail
- if self.fileencoding == BOM_UTF8 or failed:
- return BOM_UTF8 + chars.encode("utf-8")
- # Try the original file encoding next, if any
- if self.fileencoding:
- try:
- return chars.encode(self.fileencoding)
- except UnicodeError:
- tkMessageBox.showerror(
- "I/O Error",
- "Cannot save this as '%s' anymore. Saving as UTF-8" \
- % self.fileencoding,
- master = self.text)
- return BOM_UTF8 + chars.encode("utf-8")
- # Nothing was declared, and we had not determined an encoding
- # on loading. Recommend an encoding line.
- config_encoding = idleConf.GetOption("main","EditorWindow",
- "encoding")
- if config_encoding == 'utf-8':
- # User has requested that we save files as UTF-8
- return BOM_UTF8 + chars.encode("utf-8")
- ask_user = True
- try:
- chars = chars.encode(encoding)
- enc = encoding
- if config_encoding == 'locale':
- ask_user = False
- except UnicodeError:
- chars = BOM_UTF8 + chars.encode("utf-8")
- enc = "utf-8"
- if not ask_user:
- return chars
- dialog = EncodingMessage(self.editwin.top, enc)
- dialog.go()
- if dialog.num == 1:
- # User asked us to edit the file
- encline = "# -*- coding: %s -*-\n" % enc
- firstline = self.text.get("1.0", "2.0")
- if firstline.startswith("#!"):
- # Insert encoding after #! line
- self.text.insert("2.0", encline)
- else:
- self.text.insert("1.0", encline)
- return self.encode(self.text.get("1.0", "end-1c"))
- return chars
-
- def fixlastline(self):
- c = self.text.get("end-2c")
- if c != '\n':
- self.text.insert("end-1c", "\n")
-
- def print_window(self, event):
- tempfilename = None
- saved = self.get_saved()
- if saved:
- filename = self.filename
- # shell undo is reset after every prompt, looks saved, probably isn't
- if not saved or filename is None:
- # XXX KBK 08Jun03 Wouldn't it be better to ask the user to save?
- (tfd, tempfilename) = tempfile.mkstemp(prefix='IDLE_tmp_')
- filename = tempfilename
- os.close(tfd)
- if not self.writefile(tempfilename):
- os.unlink(tempfilename)
- return "break"
- platform=os.name
- printPlatform=1
- if platform == 'posix': #posix platform
- command = idleConf.GetOption('main','General',
- 'print-command-posix')
- command = command + " 2>&1"
- elif platform == 'nt': #win32 platform
- command = idleConf.GetOption('main','General','print-command-win')
- else: #no printing for this platform
- printPlatform=0
- if printPlatform: #we can try to print for this platform
- command = command % filename
- pipe = os.popen(command, "r")
- # things can get ugly on NT if there is no printer available.
- output = pipe.read().strip()
- status = pipe.close()
- if status:
- output = "Printing failed (exit status 0x%x)\n" % \
- status + output
- if output:
- output = "Printing command: %s\n" % repr(command) + output
- tkMessageBox.showerror("Print status", output, master=self.text)
- else: #no printing for this platform
- message="Printing is not enabled for this platform: %s" % platform
- tkMessageBox.showinfo("Print status", message, master=self.text)
- if tempfilename:
- os.unlink(tempfilename)
- return "break"
-
- opendialog = None
- savedialog = None
-
- filetypes = [
- ("Python and text files", "*.py *.pyw *.txt", "TEXT"),
- ("All text files", "*", "TEXT"),
- ("All files", "*"),
- ]
-
- def askopenfile(self):
- dir, base = self.defaultfilename("open")
- if not self.opendialog:
- self.opendialog = tkFileDialog.Open(master=self.text,
- filetypes=self.filetypes)
- filename = self.opendialog.show(initialdir=dir, initialfile=base)
- if isinstance(filename, unicode):
- filename = filename.encode(filesystemencoding)
- return filename
-
- def defaultfilename(self, mode="open"):
- if self.filename:
- return os.path.split(self.filename)
- elif self.dirname:
- return self.dirname, ""
- else:
- try:
- pwd = os.getcwd()
- except os.error:
- pwd = ""
- return pwd, ""
-
- def asksavefile(self):
- dir, base = self.defaultfilename("save")
- if not self.savedialog:
- self.savedialog = tkFileDialog.SaveAs(master=self.text,
- filetypes=self.filetypes)
- filename = self.savedialog.show(initialdir=dir, initialfile=base)
- if isinstance(filename, unicode):
- filename = filename.encode(filesystemencoding)
- return filename
-
- def updaterecentfileslist(self,filename):
- "Update recent file list on all editor windows"
- self.editwin.update_recent_files_list(filename)
-
-def test():
- root = Tk()
- class MyEditWin:
- def __init__(self, text):
- self.text = text
- self.flist = None
- self.text.bind("<Control-o>", self.open)
- self.text.bind("<Control-s>", self.save)
- self.text.bind("<Alt-s>", self.save_as)
- self.text.bind("<Alt-z>", self.save_a_copy)
- def get_saved(self): return 0
- def set_saved(self, flag): pass
- def reset_undo(self): pass
- def open(self, event):
- self.text.event_generate("<<open-window-from-file>>")
- def save(self, event):
- self.text.event_generate("<<save-window>>")
- def save_as(self, event):
- self.text.event_generate("<<save-window-as-file>>")
- def save_a_copy(self, event):
- self.text.event_generate("<<save-copy-of-window-as-file>>")
- text = Text(root)
- text.pack()
- text.focus_set()
- editwin = MyEditWin(text)
- io = IOBinding(editwin)
- root.mainloop()
-
-if __name__ == "__main__":
- test()
diff --git a/sys/lib/python/idlelib/Icons/folder.gif b/sys/lib/python/idlelib/Icons/folder.gif
deleted file mode 100644
index effe8dc8a..000000000
--- a/sys/lib/python/idlelib/Icons/folder.gif
+++ /dev/null
Binary files differ
diff --git a/sys/lib/python/idlelib/Icons/idle.icns b/sys/lib/python/idlelib/Icons/idle.icns
deleted file mode 100644
index f65e3130f..000000000
--- a/sys/lib/python/idlelib/Icons/idle.icns
+++ /dev/null
Binary files differ
diff --git a/sys/lib/python/idlelib/Icons/minusnode.gif b/sys/lib/python/idlelib/Icons/minusnode.gif
deleted file mode 100644
index c72e46ff8..000000000
--- a/sys/lib/python/idlelib/Icons/minusnode.gif
+++ /dev/null
Binary files differ
diff --git a/sys/lib/python/idlelib/Icons/openfolder.gif b/sys/lib/python/idlelib/Icons/openfolder.gif
deleted file mode 100644
index 24aea1beb..000000000
--- a/sys/lib/python/idlelib/Icons/openfolder.gif
+++ /dev/null
Binary files differ
diff --git a/sys/lib/python/idlelib/Icons/plusnode.gif b/sys/lib/python/idlelib/Icons/plusnode.gif
deleted file mode 100644
index 13ace90eb..000000000
--- a/sys/lib/python/idlelib/Icons/plusnode.gif
+++ /dev/null
Binary files differ
diff --git a/sys/lib/python/idlelib/Icons/python.gif b/sys/lib/python/idlelib/Icons/python.gif
deleted file mode 100644
index 58271edec..000000000
--- a/sys/lib/python/idlelib/Icons/python.gif
+++ /dev/null
Binary files differ
diff --git a/sys/lib/python/idlelib/Icons/tk.gif b/sys/lib/python/idlelib/Icons/tk.gif
deleted file mode 100644
index a603f5ecb..000000000
--- a/sys/lib/python/idlelib/Icons/tk.gif
+++ /dev/null
Binary files differ
diff --git a/sys/lib/python/idlelib/IdleHistory.py b/sys/lib/python/idlelib/IdleHistory.py
deleted file mode 100644
index 960242f78..000000000
--- a/sys/lib/python/idlelib/IdleHistory.py
+++ /dev/null
@@ -1,88 +0,0 @@
-from configHandler import idleConf
-
-class History:
-
- def __init__(self, text, output_sep = "\n"):
- self.text = text
- self.history = []
- self.history_prefix = None
- self.history_pointer = None
- self.output_sep = output_sep
- self.cyclic = idleConf.GetOption("main", "History", "cyclic", 1, "bool")
- text.bind("<<history-previous>>", self.history_prev)
- text.bind("<<history-next>>", self.history_next)
-
- def history_next(self, event):
- self.history_do(0)
- return "break"
-
- def history_prev(self, event):
- self.history_do(1)
- return "break"
-
- def _get_source(self, start, end):
- # Get source code from start index to end index. Lines in the
- # text control may be separated by sys.ps2 .
- lines = self.text.get(start, end).split(self.output_sep)
- return "\n".join(lines)
-
- def _put_source(self, where, source):
- output = self.output_sep.join(source.split("\n"))
- self.text.insert(where, output)
-
- def history_do(self, reverse):
- nhist = len(self.history)
- pointer = self.history_pointer
- prefix = self.history_prefix
- if pointer is not None and prefix is not None:
- if self.text.compare("insert", "!=", "end-1c") or \
- self._get_source("iomark", "end-1c") != self.history[pointer]:
- pointer = prefix = None
- if pointer is None or prefix is None:
- prefix = self._get_source("iomark", "end-1c")
- if reverse:
- pointer = nhist
- else:
- if self.cyclic:
- pointer = -1
- else:
- self.text.bell()
- return
- nprefix = len(prefix)
- while 1:
- if reverse:
- pointer = pointer - 1
- else:
- pointer = pointer + 1
- if pointer < 0 or pointer >= nhist:
- self.text.bell()
- if not self.cyclic and pointer < 0:
- return
- else:
- if self._get_source("iomark", "end-1c") != prefix:
- self.text.delete("iomark", "end-1c")
- self._put_source("iomark", prefix)
- pointer = prefix = None
- break
- item = self.history[pointer]
- if item[:nprefix] == prefix and len(item) > nprefix:
- self.text.delete("iomark", "end-1c")
- self._put_source("iomark", item)
- break
- self.text.mark_set("insert", "end-1c")
- self.text.see("insert")
- self.text.tag_remove("sel", "1.0", "end")
- self.history_pointer = pointer
- self.history_prefix = prefix
-
- def history_store(self, source):
- source = source.strip()
- if len(source) > 2:
- # avoid duplicates
- try:
- self.history.remove(source)
- except ValueError:
- pass
- self.history.append(source)
- self.history_pointer = None
- self.history_prefix = None
diff --git a/sys/lib/python/idlelib/MultiCall.py b/sys/lib/python/idlelib/MultiCall.py
deleted file mode 100644
index 547df13ee..000000000
--- a/sys/lib/python/idlelib/MultiCall.py
+++ /dev/null
@@ -1,406 +0,0 @@
-"""
-MultiCall - a class which inherits its methods from a Tkinter widget (Text, for
-example), but enables multiple calls of functions per virtual event - all
-matching events will be called, not only the most specific one. This is done
-by wrapping the event functions - event_add, event_delete and event_info.
-MultiCall recognizes only a subset of legal event sequences. Sequences which
-are not recognized are treated by the original Tk handling mechanism. A
-more-specific event will be called before a less-specific event.
-
-The recognized sequences are complete one-event sequences (no emacs-style
-Ctrl-X Ctrl-C, no shortcuts like <3>), for all types of events.
-Key/Button Press/Release events can have modifiers.
-The recognized modifiers are Shift, Control, Option and Command for Mac, and
-Control, Alt, Shift, Meta/M for other platforms.
-
-For all events which were handled by MultiCall, a new member is added to the
-event instance passed to the binded functions - mc_type. This is one of the
-event type constants defined in this module (such as MC_KEYPRESS).
-For Key/Button events (which are handled by MultiCall and may receive
-modifiers), another member is added - mc_state. This member gives the state
-of the recognized modifiers, as a combination of the modifier constants
-also defined in this module (for example, MC_SHIFT).
-Using these members is absolutely portable.
-
-The order by which events are called is defined by these rules:
-1. A more-specific event will be called before a less-specific event.
-2. A recently-binded event will be called before a previously-binded event,
- unless this conflicts with the first rule.
-Each function will be called at most once for each event.
-"""
-
-import sys
-import os
-import string
-import re
-import Tkinter
-
-# the event type constants, which define the meaning of mc_type
-MC_KEYPRESS=0; MC_KEYRELEASE=1; MC_BUTTONPRESS=2; MC_BUTTONRELEASE=3;
-MC_ACTIVATE=4; MC_CIRCULATE=5; MC_COLORMAP=6; MC_CONFIGURE=7;
-MC_DEACTIVATE=8; MC_DESTROY=9; MC_ENTER=10; MC_EXPOSE=11; MC_FOCUSIN=12;
-MC_FOCUSOUT=13; MC_GRAVITY=14; MC_LEAVE=15; MC_MAP=16; MC_MOTION=17;
-MC_MOUSEWHEEL=18; MC_PROPERTY=19; MC_REPARENT=20; MC_UNMAP=21; MC_VISIBILITY=22;
-# the modifier state constants, which define the meaning of mc_state
-MC_SHIFT = 1<<0; MC_CONTROL = 1<<2; MC_ALT = 1<<3; MC_META = 1<<5
-MC_OPTION = 1<<6; MC_COMMAND = 1<<7
-
-# define the list of modifiers, to be used in complex event types.
-if sys.platform == "darwin" and sys.executable.count(".app"):
- _modifiers = (("Shift",), ("Control",), ("Option",), ("Command",))
- _modifier_masks = (MC_SHIFT, MC_CONTROL, MC_OPTION, MC_COMMAND)
-else:
- _modifiers = (("Control",), ("Alt",), ("Shift",), ("Meta", "M"))
- _modifier_masks = (MC_CONTROL, MC_ALT, MC_SHIFT, MC_META)
-
-# a dictionary to map a modifier name into its number
-_modifier_names = dict([(name, number)
- for number in range(len(_modifiers))
- for name in _modifiers[number]])
-
-# A binder is a class which binds functions to one type of event. It has two
-# methods: bind and unbind, which get a function and a parsed sequence, as
-# returned by _parse_sequence(). There are two types of binders:
-# _SimpleBinder handles event types with no modifiers and no detail.
-# No Python functions are called when no events are binded.
-# _ComplexBinder handles event types with modifiers and a detail.
-# A Python function is called each time an event is generated.
-
-class _SimpleBinder:
- def __init__(self, type, widget, widgetinst):
- self.type = type
- self.sequence = '<'+_types[type][0]+'>'
- self.widget = widget
- self.widgetinst = widgetinst
- self.bindedfuncs = []
- self.handlerid = None
-
- def bind(self, triplet, func):
- if not self.handlerid:
- def handler(event, l = self.bindedfuncs, mc_type = self.type):
- event.mc_type = mc_type
- wascalled = {}
- for i in range(len(l)-1, -1, -1):
- func = l[i]
- if func not in wascalled:
- wascalled[func] = True
- r = func(event)
- if r:
- return r
- self.handlerid = self.widget.bind(self.widgetinst,
- self.sequence, handler)
- self.bindedfuncs.append(func)
-
- def unbind(self, triplet, func):
- self.bindedfuncs.remove(func)
- if not self.bindedfuncs:
- self.widget.unbind(self.widgetinst, self.sequence, self.handlerid)
- self.handlerid = None
-
- def __del__(self):
- if self.handlerid:
- self.widget.unbind(self.widgetinst, self.sequence, self.handlerid)
-
-# An int in range(1 << len(_modifiers)) represents a combination of modifiers
-# (if the least significent bit is on, _modifiers[0] is on, and so on).
-# _state_subsets gives for each combination of modifiers, or *state*,
-# a list of the states which are a subset of it. This list is ordered by the
-# number of modifiers is the state - the most specific state comes first.
-_states = range(1 << len(_modifiers))
-_state_names = [reduce(lambda x, y: x + y,
- [_modifiers[i][0]+'-' for i in range(len(_modifiers))
- if (1 << i) & s],
- "")
- for s in _states]
-_state_subsets = map(lambda i: filter(lambda j: not (j & (~i)), _states),
- _states)
-for l in _state_subsets:
- l.sort(lambda a, b, nummod = lambda x: len(filter(lambda i: (1<<i) & x,
- range(len(_modifiers)))):
- nummod(b) - nummod(a))
-# _state_codes gives for each state, the portable code to be passed as mc_state
-_state_codes = [reduce(lambda x, y: x | y,
- [_modifier_masks[i] for i in range(len(_modifiers))
- if (1 << i) & s],
- 0)
- for s in _states]
-
-class _ComplexBinder:
- # This class binds many functions, and only unbinds them when it is deleted.
- # self.handlerids is the list of seqs and ids of binded handler functions.
- # The binded functions sit in a dictionary of lists of lists, which maps
- # a detail (or None) and a state into a list of functions.
- # When a new detail is discovered, handlers for all the possible states
- # are binded.
-
- def __create_handler(self, lists, mc_type, mc_state):
- def handler(event, lists = lists,
- mc_type = mc_type, mc_state = mc_state,
- ishandlerrunning = self.ishandlerrunning,
- doafterhandler = self.doafterhandler):
- ishandlerrunning[:] = [True]
- event.mc_type = mc_type
- event.mc_state = mc_state
- wascalled = {}
- r = None
- for l in lists:
- for i in range(len(l)-1, -1, -1):
- func = l[i]
- if func not in wascalled:
- wascalled[func] = True
- r = l[i](event)
- if r:
- break
- if r:
- break
- ishandlerrunning[:] = []
- # Call all functions in doafterhandler and remove them from list
- while doafterhandler:
- doafterhandler.pop()()
- if r:
- return r
- return handler
-
- def __init__(self, type, widget, widgetinst):
- self.type = type
- self.typename = _types[type][0]
- self.widget = widget
- self.widgetinst = widgetinst
- self.bindedfuncs = {None: [[] for s in _states]}
- self.handlerids = []
- # we don't want to change the lists of functions while a handler is
- # running - it will mess up the loop and anyway, we usually want the
- # change to happen from the next event. So we have a list of functions
- # for the handler to run after it finishes calling the binded functions.
- # It calls them only once.
- # ishandlerrunning is a list. An empty one means no, otherwise - yes.
- # this is done so that it would be mutable.
- self.ishandlerrunning = []
- self.doafterhandler = []
- for s in _states:
- lists = [self.bindedfuncs[None][i] for i in _state_subsets[s]]
- handler = self.__create_handler(lists, type, _state_codes[s])
- seq = '<'+_state_names[s]+self.typename+'>'
- self.handlerids.append((seq, self.widget.bind(self.widgetinst,
- seq, handler)))
-
- def bind(self, triplet, func):
- if not self.bindedfuncs.has_key(triplet[2]):
- self.bindedfuncs[triplet[2]] = [[] for s in _states]
- for s in _states:
- lists = [ self.bindedfuncs[detail][i]
- for detail in (triplet[2], None)
- for i in _state_subsets[s] ]
- handler = self.__create_handler(lists, self.type,
- _state_codes[s])
- seq = "<%s%s-%s>"% (_state_names[s], self.typename, triplet[2])
- self.handlerids.append((seq, self.widget.bind(self.widgetinst,
- seq, handler)))
- doit = lambda: self.bindedfuncs[triplet[2]][triplet[0]].append(func)
- if not self.ishandlerrunning:
- doit()
- else:
- self.doafterhandler.append(doit)
-
- def unbind(self, triplet, func):
- doit = lambda: self.bindedfuncs[triplet[2]][triplet[0]].remove(func)
- if not self.ishandlerrunning:
- doit()
- else:
- self.doafterhandler.append(doit)
-
- def __del__(self):
- for seq, id in self.handlerids:
- self.widget.unbind(self.widgetinst, seq, id)
-
-# define the list of event types to be handled by MultiEvent. the order is
-# compatible with the definition of event type constants.
-_types = (
- ("KeyPress", "Key"), ("KeyRelease",), ("ButtonPress", "Button"),
- ("ButtonRelease",), ("Activate",), ("Circulate",), ("Colormap",),
- ("Configure",), ("Deactivate",), ("Destroy",), ("Enter",), ("Expose",),
- ("FocusIn",), ("FocusOut",), ("Gravity",), ("Leave",), ("Map",),
- ("Motion",), ("MouseWheel",), ("Property",), ("Reparent",), ("Unmap",),
- ("Visibility",),
-)
-
-# which binder should be used for every event type?
-_binder_classes = (_ComplexBinder,) * 4 + (_SimpleBinder,) * (len(_types)-4)
-
-# A dictionary to map a type name into its number
-_type_names = dict([(name, number)
- for number in range(len(_types))
- for name in _types[number]])
-
-_keysym_re = re.compile(r"^\w+$")
-_button_re = re.compile(r"^[1-5]$")
-def _parse_sequence(sequence):
- """Get a string which should describe an event sequence. If it is
- successfully parsed as one, return a tuple containing the state (as an int),
- the event type (as an index of _types), and the detail - None if none, or a
- string if there is one. If the parsing is unsuccessful, return None.
- """
- if not sequence or sequence[0] != '<' or sequence[-1] != '>':
- return None
- words = string.split(sequence[1:-1], '-')
-
- modifiers = 0
- while words and words[0] in _modifier_names:
- modifiers |= 1 << _modifier_names[words[0]]
- del words[0]
-
- if words and words[0] in _type_names:
- type = _type_names[words[0]]
- del words[0]
- else:
- return None
-
- if _binder_classes[type] is _SimpleBinder:
- if modifiers or words:
- return None
- else:
- detail = None
- else:
- # _ComplexBinder
- if type in [_type_names[s] for s in ("KeyPress", "KeyRelease")]:
- type_re = _keysym_re
- else:
- type_re = _button_re
-
- if not words:
- detail = None
- elif len(words) == 1 and type_re.match(words[0]):
- detail = words[0]
- else:
- return None
-
- return modifiers, type, detail
-
-def _triplet_to_sequence(triplet):
- if triplet[2]:
- return '<'+_state_names[triplet[0]]+_types[triplet[1]][0]+'-'+ \
- triplet[2]+'>'
- else:
- return '<'+_state_names[triplet[0]]+_types[triplet[1]][0]+'>'
-
-_multicall_dict = {}
-def MultiCallCreator(widget):
- """Return a MultiCall class which inherits its methods from the
- given widget class (for example, Tkinter.Text). This is used
- instead of a templating mechanism.
- """
- if widget in _multicall_dict:
- return _multicall_dict[widget]
-
- class MultiCall (widget):
- assert issubclass(widget, Tkinter.Misc)
-
- def __init__(self, *args, **kwargs):
- apply(widget.__init__, (self,)+args, kwargs)
- # a dictionary which maps a virtual event to a tuple with:
- # 0. the function binded
- # 1. a list of triplets - the sequences it is binded to
- self.__eventinfo = {}
- self.__binders = [_binder_classes[i](i, widget, self)
- for i in range(len(_types))]
-
- def bind(self, sequence=None, func=None, add=None):
- #print "bind(%s, %s, %s) called." % (sequence, func, add)
- if type(sequence) is str and len(sequence) > 2 and \
- sequence[:2] == "<<" and sequence[-2:] == ">>":
- if sequence in self.__eventinfo:
- ei = self.__eventinfo[sequence]
- if ei[0] is not None:
- for triplet in ei[1]:
- self.__binders[triplet[1]].unbind(triplet, ei[0])
- ei[0] = func
- if ei[0] is not None:
- for triplet in ei[1]:
- self.__binders[triplet[1]].bind(triplet, func)
- else:
- self.__eventinfo[sequence] = [func, []]
- return widget.bind(self, sequence, func, add)
-
- def unbind(self, sequence, funcid=None):
- if type(sequence) is str and len(sequence) > 2 and \
- sequence[:2] == "<<" and sequence[-2:] == ">>" and \
- sequence in self.__eventinfo:
- func, triplets = self.__eventinfo[sequence]
- if func is not None:
- for triplet in triplets:
- self.__binders[triplet[1]].unbind(triplet, func)
- self.__eventinfo[sequence][0] = None
- return widget.unbind(self, sequence, funcid)
-
- def event_add(self, virtual, *sequences):
- #print "event_add(%s,%s) was called"%(repr(virtual),repr(sequences))
- if virtual not in self.__eventinfo:
- self.__eventinfo[virtual] = [None, []]
-
- func, triplets = self.__eventinfo[virtual]
- for seq in sequences:
- triplet = _parse_sequence(seq)
- if triplet is None:
- #print >> sys.stderr, "Seq. %s was added by Tkinter."%seq
- widget.event_add(self, virtual, seq)
- else:
- if func is not None:
- self.__binders[triplet[1]].bind(triplet, func)
- triplets.append(triplet)
-
- def event_delete(self, virtual, *sequences):
- if virtual not in self.__eventinfo:
- return
- func, triplets = self.__eventinfo[virtual]
- for seq in sequences:
- triplet = _parse_sequence(seq)
- if triplet is None:
- #print >> sys.stderr, "Seq. %s was deleted by Tkinter."%seq
- widget.event_delete(self, virtual, seq)
- else:
- if func is not None:
- self.__binders[triplet[1]].unbind(triplet, func)
- triplets.remove(triplet)
-
- def event_info(self, virtual=None):
- if virtual is None or virtual not in self.__eventinfo:
- return widget.event_info(self, virtual)
- else:
- return tuple(map(_triplet_to_sequence,
- self.__eventinfo[virtual][1])) + \
- widget.event_info(self, virtual)
-
- def __del__(self):
- for virtual in self.__eventinfo:
- func, triplets = self.__eventinfo[virtual]
- if func:
- for triplet in triplets:
- self.__binders[triplet[1]].unbind(triplet, func)
-
-
- _multicall_dict[widget] = MultiCall
- return MultiCall
-
-if __name__ == "__main__":
- # Test
- root = Tkinter.Tk()
- text = MultiCallCreator(Tkinter.Text)(root)
- text.pack()
- def bindseq(seq, n=[0]):
- def handler(event):
- print seq
- text.bind("<<handler%d>>"%n[0], handler)
- text.event_add("<<handler%d>>"%n[0], seq)
- n[0] += 1
- bindseq("<Key>")
- bindseq("<Control-Key>")
- bindseq("<Alt-Key-a>")
- bindseq("<Control-Key-a>")
- bindseq("<Alt-Control-Key-a>")
- bindseq("<Key-b>")
- bindseq("<Control-Button-1>")
- bindseq("<Alt-Button-1>")
- bindseq("<FocusOut>")
- bindseq("<Enter>")
- bindseq("<Leave>")
- root.mainloop()
diff --git a/sys/lib/python/idlelib/MultiStatusBar.py b/sys/lib/python/idlelib/MultiStatusBar.py
deleted file mode 100644
index 2d4c5473d..000000000
--- a/sys/lib/python/idlelib/MultiStatusBar.py
+++ /dev/null
@@ -1,32 +0,0 @@
-from Tkinter import *
-
-class MultiStatusBar(Frame):
-
- def __init__(self, master=None, **kw):
- if master is None:
- master = Tk()
- Frame.__init__(self, master, **kw)
- self.labels = {}
-
- def set_label(self, name, text='', side=LEFT):
- if not self.labels.has_key(name):
- label = Label(self, bd=1, relief=SUNKEN, anchor=W)
- label.pack(side=side)
- self.labels[name] = label
- else:
- label = self.labels[name]
- label.config(text=text)
-
-def _test():
- b = Frame()
- c = Text(b)
- c.pack(side=TOP)
- a = MultiStatusBar(b)
- a.set_label("one", "hello")
- a.set_label("two", "world")
- a.pack(side=BOTTOM, fill=X)
- b.pack()
- b.mainloop()
-
-if __name__ == '__main__':
- _test()
diff --git a/sys/lib/python/idlelib/NEWS.txt b/sys/lib/python/idlelib/NEWS.txt
deleted file mode 100644
index 54ce807d6..000000000
--- a/sys/lib/python/idlelib/NEWS.txt
+++ /dev/null
@@ -1,613 +0,0 @@
-What's New in IDLE 1.2.1?
-=========================
-
-*Release date: 18-APR-2007*
-
-What's New in IDLE 1.2.1c1?
-===========================
-
-*Release date: 05-APR-2007*
-
-What's New in IDLE 1.2?
-=======================
-
-*Release date: 19-SEP-2006*
-
-What's New in IDLE 1.2c2?
-=========================
-
-*Release date: 12-SEP-2006*
-
-What's New in IDLE 1.2c1?
-=========================
-
-*Release date: 17-AUG-2006*
-
-- File menu hotkeys: there were three 'p' assignments. Reassign the
- 'Save Copy As' and 'Print' hotkeys to 'y' and 't'. Change the
- Shell hotkey from 's' to 'l'.
-
-- IDLE honors new quit() and exit() commands from site.py Quitter() object.
- Patch 1540892, Jim Jewett
-
-- The 'with' statement is now a Code Context block opener.
- Patch 1540851, Jim Jewett
-
-- Retrieval of previous shell command was not always preserving indentation
- (since 1.2a1) Patch 1528468 Tal Einat.
-
-- Changing tokenize (39046) to detect dedent broke tabnanny check (since 1.2a1)
-
-- ToggleTab dialog was setting indent to 8 even if cancelled (since 1.2a1).
-
-- When used w/o subprocess, all exceptions were preceded by an error
- message claiming they were IDLE internal errors (since 1.2a1).
-
-What's New in IDLE 1.2b3?
-=========================
-
-*Release date: 03-AUG-2006*
-
-- EditorWindow.test() was failing. Bug 1417598
-
-- EditorWindow failed when used stand-alone if sys.ps1 not set.
- Bug 1010370 Dave Florek
-
-- Tooltips failed on new-syle class __init__ args. Bug 1027566 Loren Guthrie
-
-- Avoid occasional failure to detect closing paren properly.
- Patch 1407280 Tal Einat
-
-- Rebinding Tab key was inserting 'tab' instead of 'Tab'. Bug 1179168.
-
-- Colorizer now handles #<builtin> correctly, also unicode strings and
- 'as' keyword in comment directly following import command. Closes 1325071.
- Patch 1479219 Tal Einat
-
-What's New in IDLE 1.2b2?
-=========================
-
-*Release date: 11-JUL-2006*
-
-What's New in IDLE 1.2b1?
-=========================
-
-*Release date: 20-JUN-2006*
-
-What's New in IDLE 1.2a2?
-=========================
-
-*Release date: 27-APR-2006*
-
-What's New in IDLE 1.2a1?
-=========================
-
-*Release date: 05-APR-2006*
-
-- Source file f.flush() after writing; trying to avoid lossage if user
- kills GUI.
-
-- Options / Keys / Advanced dialog made functional. Also, allow binding
- of 'movement' keys.
-
-- 'syntax' patch adds improved calltips and a new class attribute listbox.
- MultiCall module allows binding multiple actions to an event.
- Patch 906702 Noam Raphael
-
-- Better indentation after first line of string continuation.
- IDLEfork Patch 681992, Noam Raphael
-
-- Fixed CodeContext alignment problem, following suggestion from Tal Einat.
-
-- Increased performance in CodeContext extension Patch 936169 Noam Raphael
-
-- Mac line endings were incorrect when pasting code from some browsers
- when using X11 and the Fink distribution. Python Bug 1263656.
-
-- <Enter> when cursor is on a previous command retrieves that command. Instead
- of replacing the input line, the previous command is now appended to the
- input line. Indentation is preserved, and undo is enabled.
- Patch 1196917 Jeff Shute
-
-- Clarify "tab/space" Error Dialog and "Tab Width" Dialog associated with
- the Untabify command.
-
-- Corrected "tab/space" Error Dialog to show correct menu for Untabify.
- Patch 1196980 Jeff Shute
-
-- New files are colorized by default, and colorizing is removed when
- saving as non-Python files. Patch 1196895 Jeff Shute
- Closes Python Bugs 775012 and 800432, partial fix IDLEfork 763524
-
-- Improve subprocess link error notification.
-
-- run.py: use Queue's blocking feature instead of sleeping in the main
- loop. Patch # 1190163 Michiel de Hoon
-
-- Add config-main option to make the 'history' feature non-cyclic.
- Default remains cyclic. Python Patch 914546 Noam Raphael.
-
-- Removed ability to configure tabs indent from Options dialog. This 'feature'
- has never worked and no one has complained. It is still possible to set a
- default tabs (v. spaces) indent 'manually' via config-main.def (or to turn on
- tabs for the current EditorWindow via the Format menu) but IDLE will
- encourage indentation via spaces.
-
-- Enable setting the indentation width using the Options dialog.
- Bug # 783877
-
-- Add keybindings for del-word-left and del-word-right.
-
-- Discourage using an indent width other than 8 when using tabs to indent
- Python code.
-
-- Restore use of EditorWindow.set_indentation_params(), was dead code since
- Autoindent was merged into EditorWindow. This allows IDLE to conform to the
- indentation width of a loaded file. (But it still will not switch to tabs
- even if the file uses tabs.) Any change in indent width is local to that
- window.
-
-- Add Tabnanny check before Run/F5, not just when Checking module.
-
-- If an extension can't be loaded, print warning and skip it instead of
- erroring out.
-
-- Improve error handling when .idlerc can't be created (warn and exit).
-
-- The GUI was hanging if the shell window was closed while a raw_input()
- was pending. Restored the quit() of the readline() mainloop().
- http://mail.python.org/pipermail/idle-dev/2004-December/002307.html
-
-- The remote procedure call module rpc.py can now access data attributes of
- remote registered objects. Changes to these attributes are local, however.
-
-What's New in IDLE 1.1?
-=======================
-
-*Release date: 30-NOV-2004*
-
-- On OpenBSD, terminating IDLE with ctrl-c from the command line caused a
- stuck subprocess MainThread because only the SocketThread was exiting.
-
-What's New in IDLE 1.1b3/rc1?
-=============================
-
-*Release date: 18-NOV-2004*
-
-- Saving a Keyset w/o making changes (by using the "Save as New Custom Key Set"
- button) caused IDLE to fail on restart (no new keyset was created in
- config-keys.cfg). Also true for Theme/highlights. Python Bug 1064535.
-
-- A change to the linecache.py API caused IDLE to exit when an exception was
- raised while running without the subprocess (-n switch). Python Bug 1063840.
-
-What's New in IDLE 1.1b2?
-=========================
-
-*Release date: 03-NOV-2004*
-
-- When paragraph reformat width was made configurable, a bug was
- introduced that caused reformatting of comment blocks to ignore how
- far the block was indented, effectively adding the indentation width
- to the reformat width. This has been repaired, and the reformat
- width is again a bound on the total width of reformatted lines.
-
-What's New in IDLE 1.1b1?
-=========================
-
-*Release date: 15-OCT-2004*
-
-
-What's New in IDLE 1.1a3?
-=========================
-
-*Release date: 02-SEP-2004*
-
-- Improve keyboard focus binding, especially in Windows menu. Improve
- window raising, especially in the Windows menu and in the debugger.
- IDLEfork 763524.
-
-- If user passes a non-existant filename on the commandline, just
- open a new file, don't raise a dialog. IDLEfork 854928.
-
-
-What's New in IDLE 1.1a2?
-=========================
-
-*Release date: 05-AUG-2004*
-
-- EditorWindow.py was not finding the .chm help file on Windows. Typo
- at Rev 1.54. Python Bug 990954
-
-- checking sys.platform for substring 'win' was breaking IDLE docs on Mac
- (darwin). Also, Mac Safari browser requires full file:// URIs. SF 900580.
-
-
-What's New in IDLE 1.1a1?
-=========================
-
-*Release date: 08-JUL-2004*
-
-- Redirect the warning stream to the shell during the ScriptBinding check of
- user code and format the warning similarly to an exception for both that
- check and for runtime warnings raised in the subprocess.
-
-- CodeContext hint pane visibility state is now persistent across sessions.
- The pane no longer appears in the shell window. Added capability to limit
- extensions to shell window or editor windows. Noam Raphael addition
- to Patch 936169.
-
-- Paragraph reformat width is now a configurable parameter in the
- Options GUI.
-
-- New Extension: CodeContext. Provides block structuring hints for code
- which has scrolled above an edit window. Patch 936169 Noam Raphael.
-
-- If nulls somehow got into the strings in recent-files.lst
- EditorWindow.update_recent_files_list() was failing. Python Bug 931336.
-
-- If the normal background is changed via Configure/Highlighting, it will
- update immediately, thanks to the previously mentioned patch by Nigel Rowe.
-
-- Add a highlight theme for builtin keywords. Python Patch 805830 Nigel Rowe
- This also fixed IDLEfork bug [ 693418 ] Normal text background color not
- refreshed and Python bug [897872 ] Unknown color name on HP-UX
-
-- rpc.py:SocketIO - Large modules were generating large pickles when downloaded
- to the execution server. The return of the OK response from the subprocess
- initialization was interfering and causing the sending socket to be not
- ready. Add an IO ready test to fix this. Moved the polling IO ready test
- into pollpacket().
-
-- Fix typo in rpc.py, s/b "pickle.PicklingError" not "pickle.UnpicklingError".
-
-- Added a Tk error dialog to run.py inform the user if the subprocess can't
- connect to the user GUI process. Added a timeout to the GUI's listening
- socket. Added Tk error dialogs to PyShell.py to announce a failure to bind
- the port or connect to the subprocess. Clean up error handling during
- connection initiation phase. This is an update of Python Patch 778323.
-
-- Print correct exception even if source file changed since shell was
- restarted. IDLEfork Patch 869012 Noam Raphael
-
-- Keybindings with the Shift modifier now work correctly. So do bindings which
- use the Space key. Limit unmodified user keybindings to the function keys.
- Python Bug 775353, IDLEfork Bugs 755647, 761557
-
-- After an exception, run.py was not setting the exception vector. Noam
- Raphael suggested correcting this so pdb's postmortem pm() would work.
- IDLEfork Patch 844675
-
-- IDLE now does not fail to save the file anymore if the Tk buffer is not a
- Unicode string, yet eol_convention is. Python Bugs 774680, 788378
-
-- IDLE didn't start correctly when Python was installed in "Program Files" on
- W2K and XP. Python Bugs 780451, 784183
-
-- config-main.def documentation incorrectly referred to idle- instead of
- config- filenames. SF 782759 Also added note about .idlerc location.
-
-
-What's New in IDLE 1.0?
-=======================
-
-*Release date: 29-Jul-2003*
-
-- Added a banner to the shell discussing warnings possibly raised by personal
- firewall software. Added same comment to README.txt.
-
-
-What's New in IDLE 1.0 release candidate 2?
-===========================================
-
-*Release date: 24-Jul-2003*
-
-- Calltip error when docstring was None Python Bug 775541
-
-
-What's New in IDLE 1.0 release candidate 1?
-===========================================
-
-*Release date: 18-Jul-2003*
-
-- Updated extend.txt, help.txt, and config-extensions.def to correctly
- reflect the current status of the configuration system. Python Bug 768469
-
-- Fixed: Call Tip Trimming May Loop Forever. Python Patch 769142 (Daniels)
-
-- Replaced apply(f, args, kwds) with f(*args, **kwargs) to improve performance
- Python Patch 768187
-
-- Break or continue statements outside a loop were causing IDLE crash
- Python Bug 767794
-
-- Convert Unicode strings from readline to IOBinding.encoding. Also set
- sys.std{in|out|err}.encoding, for both the local and the subprocess case.
- SF IDLEfork patch 682347.
-
-
-What's New in IDLE 1.0b2?
-=========================
-
-*Release date: 29-Jun-2003*
-
-- Extend AboutDialog.ViewFile() to support file encodings. Make the CREDITS
- file Latin-1.
-
-- Updated the About dialog to reflect re-integration into Python. Provide
- buttons to display Python's NEWS, License, and Credits, plus additional
- buttons for IDLE's README and NEWS.
-
-- TextViewer() now has a third parameter which allows inserting text into the
- viewer instead of reading from a file.
-
-- (Created the .../Lib/idlelib directory in the Python CVS, which is a clone of
- IDLEfork modified to install in the Python environment. The code in the
- interrupt module has been moved to thread.interrupt_main(). )
-
-- Printing the Shell window was failing if it was not saved first SF 748975
-
-- When using the Search in Files dialog, if the user had a selection
- highlighted in his Editor window, insert it into the dialog search field.
-
-- The Python Shell entry was disappearing from the Windows menu.
-
-- Update the Windows file list when a file name change occurs
-
-- Change to File / Open Module: always pop up the dialog, using the current
- selection as the default value. This is easier to use habitually.
-
-- Avoided a problem with starting the subprocess when 'localhost' doesn't
- resolve to the user's loopback interface. SF 747772
-
-- Fixed an issue with highlighted errors never de-colorizing. SF 747677. Also
- improved notification of Tabnanny Token Error.
-
-- File / New will by default save in the directory of the Edit window from
- which it was initiated. SF 748973 Guido van Rossum patch.
-
-
-What's New in IDLEfork 0.9b1?
-=============================
-
-*Release date: 02-Jun-2003*
-
-- The current working directory of the execution environment (and shell
- following completion of execution) is now that of the module being run.
-
-- Added the delete-exitfunc option to config-main.def. (This option is not
- included in the Options dialog.) Setting this to True (the default) will
- cause IDLE to not run sys.exitfunc/atexit when the subprocess exits.
-
-- IDLE now preserves the line ending codes when editing a file produced on
- a different platform. SF 661759, SF 538584
-
-- Reduced default editor font size to 10 point and increased window height
- to provide a better initial impression on Windows.
-
-- Options / Fonts/Tabs / Set Base Editor Font: List box was not highlighting
- the default font when first installed on Windows. SF 661676
-
-- Added Autosave feature: when user runs code from edit window, if the file
- has been modified IDLE will silently save it if Autosave is enabled. The
- option is set in the Options dialog, and the default is to prompt the
- user to save the file. SF 661318 Bruce Sherwood patch.
-
-- Improved the RESTART annotation in the shell window when the user restarts
- the shell while it is generating output. Also improved annotation when user
- repeatedly hammers the Ctrl-F6 restart.
-
-- Allow IDLE to run when not installed and cwd is not the IDLE directory
- SF Patch 686254 "Run IDLEfork from any directory without set-up" - Raphael
-
-- When a module is run from an EditorWindow: if its directory is not in
- sys.path, prepend it. This allows the module to import other modules in
- the same directory. Do the same for a script run from the command line.
-
-- Correctly restart the subprocess if it is running user code and the user
- attempts to run some other module or restarts the shell. Do the same if
- the link is broken and it is possible to restart the subprocess and re-
- connect to the GUI. SF RFE 661321.
-
-- Improved exception reporting when running commands or scripts from the
- command line.
-
-- Added a -n command line switch to start IDLE without the subprocess.
- Removed the Shell menu when running in that mode. Updated help messages.
-
-- Added a comment to the shell startup header to indicate when IDLE is not
- using the subprocess.
-
-- Restore the ability to run without the subprocess. This can be important for
- some platforms or configurations. (Running without the subprocess allows the
- debugger to trace through parts of IDLE itself, which may or may not be
- desirable, depending on your point of view. In addition, the traditional
- reload/import tricks must be use if user source code is changed.) This is
- helpful for developing IDLE using IDLE, because one instance can be used to
- edit the code and a separate instance run to test changes. (Multiple
- concurrent IDLE instances with subprocesses is a future feature)
-
-- Improve the error message a user gets when saving a file with non-ASCII
- characters and no source encoding is specified. Done by adding a dialog
- 'EncodingMessage', which contains the line to add in a fixed-font entry
- widget, and which has a button to add that line to the file automatically.
- Also, add a configuration option 'EditorWindow/encoding', which has three
- possible values: none, utf-8, and locale. None is the default: IDLE will show
- this dialog when non-ASCII characters are encountered. utf-8 means that files
- with non-ASCII characters are saved as utf-8-with-bom. locale means that
- files are saved in the locale's encoding; the dialog is only displayed if the
- source contains characters outside the locale's charset. SF 710733 - Loewis
-
-- Improved I/O response by tweaking the wait parameter in various
- calls to signal.signal().
-
-- Implemented a threaded subprocess which allows interrupting a pass
- loop in user code using the 'interrupt' extension. User code runs
- in MainThread, while the RPCServer is handled by SockThread. This is
- necessary because Windows doesn't support signals.
-
-- Implemented the 'interrupt' extension module, which allows a subthread
- to raise a KeyboardInterrupt in the main thread.
-
-- Attempting to save the shell raised an error related to saving
- breakpoints, which are not implemented in the shell
-
-- Provide a correct message when 'exit' or 'quit' are entered at the
- IDLE command prompt SF 695861
-
-- Eliminate extra blank line in shell output caused by not flushing
- stdout when user code ends with an unterminated print. SF 695861
-
-- Moved responsibility for exception formatting (i.e. pruning IDLE internal
- calls) out of rpc.py into the client and server.
-
-- Exit IDLE cleanly even when doing subprocess I/O
-
-- Handle subprocess interrupt with an RPC message.
-
-- Restart the subprocess if it terminates itself. (VPython programs do that)
-
-- Support subclassing of exceptions, including in the shell, by moving the
- exception formatting to the subprocess.
-
-
-
-What's New in IDLEfork 0.9 Alpha 2?
-===================================
-
-*Release date: 27-Jan-2003*
-
-- Updated INSTALL.txt to claify use of the python2 rpm.
-
-- Improved formatting in IDLE Help.
-
-- Run menu: Replace "Run Script" with "Run Module".
-
-- Code encountering an unhandled exception under the debugger now shows
- the correct traceback, with IDLE internal levels pruned out.
-
-- If an exception occurs entirely in IDLE, don't prune the IDLE internal
- modules from the traceback displayed.
-
-- Class Browser and Path Browser now use Alt-Key-2 for vertical zoom.
-
-- IDLE icons will now install correctly even when setup.py is run from the
- build directory
-
-- Class Browser now compatible with Python2.3 version of pyclbr.py
-
-- Left cursor move in presence of selected text now moves from left end
- of the selection.
-
-- Add Meta keybindings to "IDLE Classic Windows" to handle reversed
- Alt/Meta on some Linux distros.
-
-- Change default: IDLE now starts with Python Shell.
-
-- Removed the File Path from the Additional Help Sources scrolled list.
-
-- Add capability to access Additional Help Sources on the web if the
- Help File Path begins with //http or www. (Otherwise local path is
- validated, as before.)
-
-- Additional Help Sources were not being posted on the Help menu in the
- order entered. Implement sorting the list by [HelpFiles] 'option'
- number.
-
-- Add Browse button to New Help Source dialog. Arrange to start in
- Python/Doc if platform is Windows, otherwise start in current directory.
-
-- Put the Additional Help Sources directly on the Help menu instead of in
- an Extra Help cascade menu. Rearrange the Help menu so the Additional
- Help Sources come last. Update help.txt appropriately.
-
-- Fix Tk root pop-ups in configSectionNameDialog.py and configDialog.py
-
-- Uniform capitalization in General tab of ConfigDialog, update the doc string.
-
-- Fix bug in ConfigDialog where SaveAllChangedConfig() was unexpectedly
- deleting Additional Help Sources from the user's config file.
-
-- Make configHelpSourceEdit OK button the default and bind <Return>
-
-- Fix Tk root pop-ups in configHelpSourceEdit: error dialogs not attached
- to parents.
-
-- Use os.startfile() to open both Additional Help and Python Help on the
- Windows platform. The application associated with the file type will act as
- the viewer. Windows help files (.chm) are now supported via the
- Settings/General/Additional Help facility.
-
-- If Python Help files are installed locally on Linux, use them instead of
- accessing python.org.
-
-- Make the methods for finding the Python help docs more robust, and make
- them work in the installed configuration, also.
-
-- On the Save Before Run dialog, make the OK button the default. One
- less mouse action!
-
-- Add a method: EditorWindow.get_geometry() for future use in implementing
- window location persistence.
-
-- Removed the "Help/Advice" menu entry. Thanks, David! We'll remember!
-
-- Change the "Classic Windows" theme's paste key to be <ctrl-v>.
-
-- Rearrange the Shell menu to put Stack Viewer entries adjacent.
-
-- Add the ability to restart the subprocess interpreter from the shell window;
- add an associated menu entry "Shell/Restart" with binding Control-F6. Update
- IDLE help.
-
-- Upon a restart, annotate the shell window with a "restart boundary". Add a
- shell window menu "Shell/View Restart" with binding F6 to jump to the most
- recent restart boundary.
-
-- Add Shell menu to Python Shell; change "Settings" to "Options".
-
-- Remove incorrect comment in setup.py: IDLEfork is now installed as a package.
-
-- Add INSTALL.txt, HISTORY.txt, NEWS.txt to installed configuration.
-
-- In installer text, fix reference to Visual Python, should be VPython.
- Properly credit David Scherer.
-
-- Modified idle, idle.py, idle.pyw to improve exception handling.
-
-
-What's New in IDLEfork 0.9 Alpha 1?
-===================================
-
-*Release date: 31-Dec-2002*
-
-- First release of major new functionality. For further details refer to
- Idle-dev and/or the Sourceforge CVS.
-
-- Adapted to the Mac platform.
-
-- Overhauled the IDLE startup options and revised the idle -h help message,
- which provides details of command line usage.
-
-- Multiple bug fixes and usability enhancements.
-
-- Introduced the new RPC implementation, which includes a debugger. The output
- of user code is to the shell, and the shell may be used to inspect the
- environment after the run has finished. (In version 0.8.1 the shell
- environment was separate from the environment of the user code.)
-
-- Introduced the configuration GUI and a new About dialog.
-
-- Removed David Scherer's Remote Procedure Call code and replaced with Guido
- van Rossum's. GvR code has support for the IDLE debugger and uses the shell
- to inspect the environment of code Run from an Edit window. Files removed:
- ExecBinding.py, loader.py, protocol.py, Remote.py, spawn.py
-
---------------------------------------------------------------------
-Refer to HISTORY.txt for additional information on earlier releases.
---------------------------------------------------------------------
-
-
-
-
-
diff --git a/sys/lib/python/idlelib/ObjectBrowser.py b/sys/lib/python/idlelib/ObjectBrowser.py
deleted file mode 100644
index a2a6cee49..000000000
--- a/sys/lib/python/idlelib/ObjectBrowser.py
+++ /dev/null
@@ -1,151 +0,0 @@
-# XXX TO DO:
-# - popup menu
-# - support partial or total redisplay
-# - more doc strings
-# - tooltips
-
-# object browser
-
-# XXX TO DO:
-# - for classes/modules, add "open source" to object browser
-
-from TreeWidget import TreeItem, TreeNode, ScrolledCanvas
-
-from repr import Repr
-
-myrepr = Repr()
-myrepr.maxstring = 100
-myrepr.maxother = 100
-
-class ObjectTreeItem(TreeItem):
- def __init__(self, labeltext, object, setfunction=None):
- self.labeltext = labeltext
- self.object = object
- self.setfunction = setfunction
- def GetLabelText(self):
- return self.labeltext
- def GetText(self):
- return myrepr.repr(self.object)
- def GetIconName(self):
- if not self.IsExpandable():
- return "python"
- def IsEditable(self):
- return self.setfunction is not None
- def SetText(self, text):
- try:
- value = eval(text)
- self.setfunction(value)
- except:
- pass
- else:
- self.object = value
- def IsExpandable(self):
- return not not dir(self.object)
- def GetSubList(self):
- keys = dir(self.object)
- sublist = []
- for key in keys:
- try:
- value = getattr(self.object, key)
- except AttributeError:
- continue
- item = make_objecttreeitem(
- str(key) + " =",
- value,
- lambda value, key=key, object=self.object:
- setattr(object, key, value))
- sublist.append(item)
- return sublist
-
-class InstanceTreeItem(ObjectTreeItem):
- def IsExpandable(self):
- return True
- def GetSubList(self):
- sublist = ObjectTreeItem.GetSubList(self)
- sublist.insert(0,
- make_objecttreeitem("__class__ =", self.object.__class__))
- return sublist
-
-class ClassTreeItem(ObjectTreeItem):
- def IsExpandable(self):
- return True
- def GetSubList(self):
- sublist = ObjectTreeItem.GetSubList(self)
- if len(self.object.__bases__) == 1:
- item = make_objecttreeitem("__bases__[0] =",
- self.object.__bases__[0])
- else:
- item = make_objecttreeitem("__bases__ =", self.object.__bases__)
- sublist.insert(0, item)
- return sublist
-
-class AtomicObjectTreeItem(ObjectTreeItem):
- def IsExpandable(self):
- return 0
-
-class SequenceTreeItem(ObjectTreeItem):
- def IsExpandable(self):
- return len(self.object) > 0
- def keys(self):
- return range(len(self.object))
- def GetSubList(self):
- sublist = []
- for key in self.keys():
- try:
- value = self.object[key]
- except KeyError:
- continue
- def setfunction(value, key=key, object=self.object):
- object[key] = value
- item = make_objecttreeitem("%r:" % (key,), value, setfunction)
- sublist.append(item)
- return sublist
-
-class DictTreeItem(SequenceTreeItem):
- def keys(self):
- keys = self.object.keys()
- try:
- keys.sort()
- except:
- pass
- return keys
-
-from types import *
-
-dispatch = {
- IntType: AtomicObjectTreeItem,
- LongType: AtomicObjectTreeItem,
- FloatType: AtomicObjectTreeItem,
- StringType: AtomicObjectTreeItem,
- TupleType: SequenceTreeItem,
- ListType: SequenceTreeItem,
- DictType: DictTreeItem,
- InstanceType: InstanceTreeItem,
- ClassType: ClassTreeItem,
-}
-
-def make_objecttreeitem(labeltext, object, setfunction=None):
- t = type(object)
- if dispatch.has_key(t):
- c = dispatch[t]
- else:
- c = ObjectTreeItem
- return c(labeltext, object, setfunction)
-
-# Test script
-
-def _test():
- import sys
- from Tkinter import Tk
- root = Tk()
- root.configure(bd=0, bg="yellow")
- root.focus_set()
- sc = ScrolledCanvas(root, bg="white", highlightthickness=0, takefocus=1)
- sc.frame.pack(expand=1, fill="both")
- item = make_objecttreeitem("sys", sys)
- node = TreeNode(sc.canvas, None, item)
- node.update()
- root.mainloop()
-
-if __name__ == '__main__':
- _test()
diff --git a/sys/lib/python/idlelib/OutputWindow.py b/sys/lib/python/idlelib/OutputWindow.py
deleted file mode 100644
index 787e9b0bb..000000000
--- a/sys/lib/python/idlelib/OutputWindow.py
+++ /dev/null
@@ -1,157 +0,0 @@
-from Tkinter import *
-from EditorWindow import EditorWindow
-import re
-import tkMessageBox
-import IOBinding
-
-class OutputWindow(EditorWindow):
-
- """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.
- """
-
- def __init__(self, *args):
- EditorWindow.__init__(self, *args)
- self.text.bind("<<goto-file-line>>", self.goto_file_line)
-
- # Customize EditorWindow
-
- def ispythonsource(self, filename):
- # No colorization needed
- return 0
-
- def short_title(self):
- return "Output"
-
- def maybesave(self):
- # Override base class method -- don't ask any questions
- if self.get_saved():
- return "yes"
- else:
- return "no"
-
- # Act as output file
-
- def write(self, s, tags=(), mark="insert"):
- # Tk assumes that byte strings are Latin-1;
- # we assume that they are in the locale's encoding
- if isinstance(s, str):
- try:
- s = unicode(s, IOBinding.encoding)
- except UnicodeError:
- # some other encoding; let Tcl deal with it
- pass
- self.text.insert(mark, s, tags)
- self.text.see(mark)
- self.text.update()
-
- def writelines(self, l):
- map(self.write, l)
-
- def flush(self):
- pass
-
- # Our own right-button menu
-
- rmenu_specs = [
- ("Go to file/line", "<<goto-file-line>>"),
- ]
-
- file_line_pats = [
- r'file "([^"]*)", line (\d+)',
- r'([^\s]+)\((\d+)\)',
- r'([^\s]+):\s*(\d+):',
- ]
-
- file_line_progs = None
-
- def goto_file_line(self, event=None):
- if self.file_line_progs is None:
- l = []
- for pat in self.file_line_pats:
- l.append(re.compile(pat, re.IGNORECASE))
- self.file_line_progs = l
- # x, y = self.event.x, self.event.y
- # self.text.mark_set("insert", "@%d,%d" % (x, y))
- line = self.text.get("insert linestart", "insert lineend")
- result = self._file_line_helper(line)
- if not result:
- # Try the previous line. This is handy e.g. in tracebacks,
- # where you tend to right-click on the displayed source line
- line = self.text.get("insert -1line linestart",
- "insert -1line lineend")
- result = self._file_line_helper(line)
- if not result:
- tkMessageBox.showerror(
- "No special line",
- "The line you point at doesn't look like "
- "a valid file name followed by a line number.",
- master=self.text)
- return
- filename, lineno = result
- edit = self.flist.open(filename)
- edit.gotoline(lineno)
-
- def _file_line_helper(self, line):
- for prog in self.file_line_progs:
- m = prog.search(line)
- if m:
- break
- else:
- return None
- filename, lineno = m.group(1, 2)
- try:
- f = open(filename, "r")
- f.close()
- except IOError:
- return None
- try:
- return filename, int(lineno)
- except TypeError:
- return None
-
-# These classes are currently not used but might come in handy
-
-class OnDemandOutputWindow:
-
- tagdefs = {
- # XXX Should use IdlePrefs.ColorPrefs
- "stdout": {"foreground": "blue"},
- "stderr": {"foreground": "#007700"},
- }
-
- def __init__(self, flist):
- self.flist = flist
- self.owin = None
-
- def write(self, s, tags, mark):
- if not self.owin:
- self.setup()
- self.owin.write(s, tags, mark)
-
- def setup(self):
- self.owin = owin = OutputWindow(self.flist)
- text = owin.text
- for tag, cnf in self.tagdefs.items():
- if cnf:
- 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
diff --git a/sys/lib/python/idlelib/ParenMatch.py b/sys/lib/python/idlelib/ParenMatch.py
deleted file mode 100644
index 250ae8b70..000000000
--- a/sys/lib/python/idlelib/ParenMatch.py
+++ /dev/null
@@ -1,172 +0,0 @@
-"""ParenMatch -- An IDLE extension for parenthesis matching.
-
-When you hit a right paren, the cursor should move briefly to the left
-paren. Paren here is used generically; the matching applies to
-parentheses, square brackets, and curly braces.
-"""
-
-from HyperParser import HyperParser
-from configHandler import idleConf
-
-_openers = {')':'(',']':'[','}':'{'}
-CHECK_DELAY = 100 # miliseconds
-
-class ParenMatch:
- """Highlight matching parentheses
-
- There are three supported style of paren matching, based loosely
- on the Emacs options. The style is select based on the
- HILITE_STYLE attribute; it can be changed used the set_style
- method.
-
- The supported styles are:
-
- default -- When a right paren is typed, highlight the matching
- left paren for 1/2 sec.
-
- expression -- When a right paren is typed, highlight the entire
- expression from the left paren to the right paren.
-
- TODO:
- - extend IDLE with configuration dialog to change options
- - implement rest of Emacs highlight styles (see below)
- - print mismatch warning in IDLE status window
-
- Note: In Emacs, there are several styles of highlight where the
- matching paren is highlighted whenever the cursor is immediately
- to the right of a right paren. I don't know how to do that in Tk,
- so I haven't bothered.
- """
- menudefs = [
- ('edit', [
- ("Show surrounding parens", "<<flash-paren>>"),
- ])
- ]
- STYLE = idleConf.GetOption('extensions','ParenMatch','style',
- default='expression')
- FLASH_DELAY = idleConf.GetOption('extensions','ParenMatch','flash-delay',
- type='int',default=500)
- HILITE_CONFIG = idleConf.GetHighlight(idleConf.CurrentTheme(),'hilite')
- BELL = idleConf.GetOption('extensions','ParenMatch','bell',
- type='bool',default=1)
-
- RESTORE_VIRTUAL_EVENT_NAME = "<<parenmatch-check-restore>>"
- # We want the restore event be called before the usual return and
- # backspace events.
- RESTORE_SEQUENCES = ("<KeyPress>", "<ButtonPress>",
- "<Key-Return>", "<Key-BackSpace>")
-
- def __init__(self, editwin):
- self.editwin = editwin
- self.text = editwin.text
- # Bind the check-restore event to the function restore_event,
- # so that we can then use activate_restore (which calls event_add)
- # and deactivate_restore (which calls event_delete).
- editwin.text.bind(self.RESTORE_VIRTUAL_EVENT_NAME,
- self.restore_event)
- self.counter = 0
- self.is_restore_active = 0
- self.set_style(self.STYLE)
-
- def activate_restore(self):
- if not self.is_restore_active:
- for seq in self.RESTORE_SEQUENCES:
- self.text.event_add(self.RESTORE_VIRTUAL_EVENT_NAME, seq)
- self.is_restore_active = True
-
- def deactivate_restore(self):
- if self.is_restore_active:
- for seq in self.RESTORE_SEQUENCES:
- self.text.event_delete(self.RESTORE_VIRTUAL_EVENT_NAME, seq)
- self.is_restore_active = False
-
- def set_style(self, style):
- self.STYLE = style
- if style == "default":
- self.create_tag = self.create_tag_default
- self.set_timeout = self.set_timeout_last
- elif style == "expression":
- self.create_tag = self.create_tag_expression
- self.set_timeout = self.set_timeout_none
-
- def flash_paren_event(self, event):
- indices = HyperParser(self.editwin, "insert").get_surrounding_brackets()
- if indices is None:
- self.warn_mismatched()
- return
- self.activate_restore()
- self.create_tag(indices)
- self.set_timeout_last()
-
- def paren_closed_event(self, event):
- # If it was a shortcut and not really a closing paren, quit.
- closer = self.text.get("insert-1c")
- if closer not in _openers:
- return
- hp = HyperParser(self.editwin, "insert-1c")
- if not hp.is_in_code():
- return
- indices = hp.get_surrounding_brackets(_openers[closer], True)
- if indices is None:
- self.warn_mismatched()
- return
- self.activate_restore()
- self.create_tag(indices)
- self.set_timeout()
-
- def restore_event(self, event=None):
- self.text.tag_delete("paren")
- self.deactivate_restore()
- self.counter += 1 # disable the last timer, if there is one.
-
- def handle_restore_timer(self, timer_count):
- if timer_count == self.counter:
- self.restore_event()
-
- def warn_mismatched(self):
- if self.BELL:
- self.text.bell()
-
- # any one of the create_tag_XXX methods can be used depending on
- # the style
-
- def create_tag_default(self, indices):
- """Highlight the single paren that matches"""
- self.text.tag_add("paren", indices[0])
- self.text.tag_config("paren", self.HILITE_CONFIG)
-
- def create_tag_expression(self, indices):
- """Highlight the entire expression"""
- if self.text.get(indices[1]) in (')', ']', '}'):
- rightindex = indices[1]+"+1c"
- else:
- rightindex = indices[1]
- self.text.tag_add("paren", indices[0], rightindex)
- self.text.tag_config("paren", self.HILITE_CONFIG)
-
- # any one of the set_timeout_XXX methods can be used depending on
- # the style
-
- def set_timeout_none(self):
- """Highlight will remain until user input turns it off
- or the insert has moved"""
- # After CHECK_DELAY, call a function which disables the "paren" tag
- # if the event is for the most recent timer and the insert has changed,
- # or schedules another call for itself.
- self.counter += 1
- def callme(callme, self=self, c=self.counter,
- index=self.text.index("insert")):
- if index != self.text.index("insert"):
- self.handle_restore_timer(c)
- else:
- self.editwin.text_frame.after(CHECK_DELAY, callme, callme)
- self.editwin.text_frame.after(CHECK_DELAY, callme, callme)
-
- def set_timeout_last(self):
- """The last highlight created will be removed after .5 sec"""
- # associate a counter with an event; only disable the "paren"
- # tag if the event is for the most recent timer.
- self.counter += 1
- self.editwin.text_frame.after(self.FLASH_DELAY,
- lambda self=self, c=self.counter: \
- self.handle_restore_timer(c))
diff --git a/sys/lib/python/idlelib/PathBrowser.py b/sys/lib/python/idlelib/PathBrowser.py
deleted file mode 100644
index 86cd2707d..000000000
--- a/sys/lib/python/idlelib/PathBrowser.py
+++ /dev/null
@@ -1,95 +0,0 @@
-import os
-import sys
-import imp
-
-from TreeWidget import TreeItem
-from ClassBrowser import ClassBrowser, ModuleBrowserTreeItem
-
-class PathBrowser(ClassBrowser):
-
- def __init__(self, flist):
- self.init(flist)
-
- def settitle(self):
- self.top.wm_title("Path Browser")
- self.top.wm_iconname("Path Browser")
-
- def rootnode(self):
- return PathBrowserTreeItem()
-
-class PathBrowserTreeItem(TreeItem):
-
- def GetText(self):
- return "sys.path"
-
- def GetSubList(self):
- sublist = []
- for dir in sys.path:
- item = DirBrowserTreeItem(dir)
- sublist.append(item)
- return sublist
-
-class DirBrowserTreeItem(TreeItem):
-
- def __init__(self, dir, packages=[]):
- self.dir = dir
- self.packages = packages
-
- def GetText(self):
- if not self.packages:
- return self.dir
- else:
- return self.packages[-1] + ": package"
-
- def GetSubList(self):
- try:
- names = os.listdir(self.dir or os.curdir)
- except os.error:
- return []
- packages = []
- for name in names:
- file = os.path.join(self.dir, name)
- if self.ispackagedir(file):
- nn = os.path.normcase(name)
- packages.append((nn, name, file))
- packages.sort()
- sublist = []
- for nn, name, file in packages:
- item = DirBrowserTreeItem(file, self.packages + [name])
- sublist.append(item)
- for nn, name in self.listmodules(names):
- item = ModuleBrowserTreeItem(os.path.join(self.dir, name))
- sublist.append(item)
- return sublist
-
- def ispackagedir(self, file):
- if not os.path.isdir(file):
- return 0
- init = os.path.join(file, "__init__.py")
- return os.path.exists(init)
-
- def listmodules(self, allnames):
- modules = {}
- suffixes = imp.get_suffixes()
- sorted = []
- for suff, mode, flag in suffixes:
- i = -len(suff)
- for name in allnames[:]:
- normed_name = os.path.normcase(name)
- if normed_name[i:] == suff:
- mod_name = name[:i]
- if not modules.has_key(mod_name):
- modules[mod_name] = None
- sorted.append((normed_name, name))
- allnames.remove(name)
- sorted.sort()
- return sorted
-
-def main():
- import PyShell
- PathBrowser(PyShell.flist)
- if sys.stdin is sys.__stdin__:
- mainloop()
-
-if __name__ == "__main__":
- main()
diff --git a/sys/lib/python/idlelib/Percolator.py b/sys/lib/python/idlelib/Percolator.py
deleted file mode 100644
index ebbcba9e6..000000000
--- a/sys/lib/python/idlelib/Percolator.py
+++ /dev/null
@@ -1,85 +0,0 @@
-from WidgetRedirector import WidgetRedirector
-from Delegator import Delegator
-
-class Percolator:
-
- def __init__(self, text):
- # XXX would be nice to inherit from Delegator
- self.text = text
- self.redir = WidgetRedirector(text)
- self.top = self.bottom = Delegator(text)
- self.bottom.insert = self.redir.register("insert", self.insert)
- self.bottom.delete = self.redir.register("delete", self.delete)
- self.filters = []
-
- def close(self):
- while self.top is not self.bottom:
- self.removefilter(self.top)
- self.top = None
- self.bottom.setdelegate(None); self.bottom = None
- self.redir.close(); self.redir = None
- self.text = None
-
- def insert(self, index, chars, tags=None):
- # Could go away if inheriting from Delegator
- self.top.insert(index, chars, tags)
-
- def delete(self, index1, index2=None):
- # Could go away if inheriting from Delegator
- self.top.delete(index1, index2)
-
- def insertfilter(self, filter):
- # Perhaps rename to pushfilter()?
- assert isinstance(filter, Delegator)
- assert filter.delegate is None
- filter.setdelegate(self.top)
- self.top = filter
-
- def removefilter(self, filter):
- # XXX Perhaps should only support popfilter()?
- assert isinstance(filter, Delegator)
- assert filter.delegate is not None
- f = self.top
- if f is filter:
- self.top = filter.delegate
- filter.setdelegate(None)
- else:
- while f.delegate is not filter:
- assert f is not self.bottom
- f.resetcache()
- f = f.delegate
- f.setdelegate(filter.delegate)
- filter.setdelegate(None)
-
-
-def main():
- class Tracer(Delegator):
- def __init__(self, name):
- self.name = name
- Delegator.__init__(self, None)
- def insert(self, *args):
- print self.name, ": insert", args
- self.delegate.insert(*args)
- def delete(self, *args):
- print self.name, ": delete", args
- self.delegate.delete(*args)
- root = Tk()
- root.wm_protocol("WM_DELETE_WINDOW", root.quit)
- text = Text()
- text.pack()
- text.focus_set()
- p = Percolator(text)
- t1 = Tracer("t1")
- t2 = Tracer("t2")
- p.insertfilter(t1)
- p.insertfilter(t2)
- root.mainloop()
- p.removefilter(t2)
- root.mainloop()
- p.insertfilter(t2)
- p.removefilter(t1)
- root.mainloop()
-
-if __name__ == "__main__":
- from Tkinter import *
- main()
diff --git a/sys/lib/python/idlelib/PyParse.py b/sys/lib/python/idlelib/PyParse.py
deleted file mode 100644
index 1a9db6743..000000000
--- a/sys/lib/python/idlelib/PyParse.py
+++ /dev/null
@@ -1,594 +0,0 @@
-import re
-import sys
-
-# Reason last stmt is continued (or C_NONE if it's not).
-(C_NONE, C_BACKSLASH, C_STRING_FIRST_LINE,
- C_STRING_NEXT_LINES, C_BRACKET) = range(5)
-
-if 0: # for throwaway debugging output
- def dump(*stuff):
- sys.__stdout__.write(" ".join(map(str, stuff)) + "\n")
-
-# Find what looks like the start of a popular stmt.
-
-_synchre = re.compile(r"""
- ^
- [ \t]*
- (?: while
- | else
- | def
- | return
- | assert
- | break
- | class
- | continue
- | elif
- | try
- | except
- | raise
- | import
- | yield
- )
- \b
-""", re.VERBOSE | re.MULTILINE).search
-
-# Match blank line or non-indenting comment line.
-
-_junkre = re.compile(r"""
- [ \t]*
- (?: \# \S .* )?
- \n
-""", re.VERBOSE).match
-
-# Match any flavor of string; the terminating quote is optional
-# so that we're robust in the face of incomplete program text.
-
-_match_stringre = re.compile(r"""
- \""" [^"\\]* (?:
- (?: \\. | "(?!"") )
- [^"\\]*
- )*
- (?: \""" )?
-
-| " [^"\\\n]* (?: \\. [^"\\\n]* )* "?
-
-| ''' [^'\\]* (?:
- (?: \\. | '(?!'') )
- [^'\\]*
- )*
- (?: ''' )?
-
-| ' [^'\\\n]* (?: \\. [^'\\\n]* )* '?
-""", re.VERBOSE | re.DOTALL).match
-
-# Match a line that starts with something interesting;
-# used to find the first item of a bracket structure.
-
-_itemre = re.compile(r"""
- [ \t]*
- [^\s#\\] # if we match, m.end()-1 is the interesting char
-""", re.VERBOSE).match
-
-# Match start of stmts that should be followed by a dedent.
-
-_closere = re.compile(r"""
- \s*
- (?: return
- | break
- | continue
- | raise
- | pass
- )
- \b
-""", re.VERBOSE).match
-
-# Chew up non-special chars as quickly as possible. If match is
-# successful, m.end() less 1 is the index of the last boring char
-# matched. If match is unsuccessful, the string starts with an
-# interesting char.
-
-_chew_ordinaryre = re.compile(r"""
- [^[\](){}#'"\\]+
-""", re.VERBOSE).match
-
-# Build translation table to map uninteresting chars to "x", open
-# brackets to "(", and close brackets to ")".
-
-_tran = ['x'] * 256
-for ch in "({[":
- _tran[ord(ch)] = '('
-for ch in ")}]":
- _tran[ord(ch)] = ')'
-for ch in "\"'\\\n#":
- _tran[ord(ch)] = ch
-_tran = ''.join(_tran)
-del ch
-
-try:
- UnicodeType = type(unicode(""))
-except NameError:
- UnicodeType = None
-
-class Parser:
-
- def __init__(self, indentwidth, tabwidth):
- self.indentwidth = indentwidth
- self.tabwidth = tabwidth
-
- def set_str(self, str):
- assert len(str) == 0 or str[-1] == '\n'
- if type(str) is UnicodeType:
- # The parse functions have no idea what to do with Unicode, so
- # replace all Unicode characters with "x". This is "safe"
- # so long as the only characters germane to parsing the structure
- # of Python are 7-bit ASCII. It's *necessary* because Unicode
- # strings don't have a .translate() method that supports
- # deletechars.
- uniphooey = str
- str = []
- push = str.append
- for raw in map(ord, uniphooey):
- push(raw < 127 and chr(raw) or "x")
- str = "".join(str)
- self.str = str
- self.study_level = 0
-
- # Return index of a good place to begin parsing, as close to the
- # end of the string as possible. This will be the start of some
- # popular stmt like "if" or "def". Return None if none found:
- # the caller should pass more prior context then, if possible, or
- # if not (the entire program text up until the point of interest
- # has already been tried) pass 0 to set_lo.
- #
- # This will be reliable iff given a reliable is_char_in_string
- # function, meaning that when it says "no", it's absolutely
- # guaranteed that the char is not in a string.
-
- def find_good_parse_start(self, is_char_in_string=None,
- _synchre=_synchre):
- str, pos = self.str, None
-
- if not is_char_in_string:
- # no clue -- make the caller pass everything
- return None
-
- # Peek back from the end for a good place to start,
- # but don't try too often; pos will be left None, or
- # bumped to a legitimate synch point.
- limit = len(str)
- for tries in range(5):
- i = str.rfind(":\n", 0, limit)
- if i < 0:
- break
- i = str.rfind('\n', 0, i) + 1 # start of colon line
- m = _synchre(str, i, limit)
- if m and not is_char_in_string(m.start()):
- pos = m.start()
- break
- limit = i
- if pos is None:
- # Nothing looks like a block-opener, or stuff does
- # but is_char_in_string keeps returning true; most likely
- # we're in or near a giant string, the colorizer hasn't
- # caught up enough to be helpful, or there simply *aren't*
- # any interesting stmts. In any of these cases we're
- # going to have to parse the whole thing to be sure, so
- # give it one last try from the start, but stop wasting
- # time here regardless of the outcome.
- m = _synchre(str)
- if m and not is_char_in_string(m.start()):
- pos = m.start()
- return pos
-
- # Peeking back worked; look forward until _synchre no longer
- # matches.
- i = pos + 1
- while 1:
- m = _synchre(str, i)
- if m:
- s, i = m.span()
- if not is_char_in_string(s):
- pos = s
- else:
- break
- return pos
-
- # Throw away the start of the string. Intended to be called with
- # find_good_parse_start's result.
-
- def set_lo(self, lo):
- assert lo == 0 or self.str[lo-1] == '\n'
- if lo > 0:
- self.str = self.str[lo:]
-
- # As quickly as humanly possible <wink>, find the line numbers (0-
- # based) of the non-continuation lines.
- # Creates self.{goodlines, continuation}.
-
- def _study1(self):
- if self.study_level >= 1:
- return
- self.study_level = 1
-
- # Map all uninteresting characters to "x", all open brackets
- # to "(", all close brackets to ")", then collapse runs of
- # uninteresting characters. This can cut the number of chars
- # by a factor of 10-40, and so greatly speed the following loop.
- str = self.str
- str = str.translate(_tran)
- str = str.replace('xxxxxxxx', 'x')
- str = str.replace('xxxx', 'x')
- str = str.replace('xx', 'x')
- str = str.replace('xx', 'x')
- str = str.replace('\nx', '\n')
- # note that replacing x\n with \n would be incorrect, because
- # x may be preceded by a backslash
-
- # March over the squashed version of the program, accumulating
- # the line numbers of non-continued stmts, and determining
- # whether & why the last stmt is a continuation.
- continuation = C_NONE
- level = lno = 0 # level is nesting level; lno is line number
- self.goodlines = goodlines = [0]
- push_good = goodlines.append
- i, n = 0, len(str)
- while i < n:
- ch = str[i]
- i = i+1
-
- # cases are checked in decreasing order of frequency
- if ch == 'x':
- continue
-
- if ch == '\n':
- lno = lno + 1
- if level == 0:
- push_good(lno)
- # else we're in an unclosed bracket structure
- continue
-
- if ch == '(':
- level = level + 1
- continue
-
- if ch == ')':
- if level:
- level = level - 1
- # else the program is invalid, but we can't complain
- continue
-
- if ch == '"' or ch == "'":
- # consume the string
- quote = ch
- if str[i-1:i+2] == quote * 3:
- quote = quote * 3
- firstlno = lno
- w = len(quote) - 1
- i = i+w
- while i < n:
- ch = str[i]
- i = i+1
-
- if ch == 'x':
- continue
-
- if str[i-1:i+w] == quote:
- i = i+w
- break
-
- if ch == '\n':
- lno = lno + 1
- if w == 0:
- # unterminated single-quoted string
- if level == 0:
- push_good(lno)
- break
- continue
-
- if ch == '\\':
- assert i < n
- if str[i] == '\n':
- lno = lno + 1
- i = i+1
- continue
-
- # else comment char or paren inside string
-
- else:
- # didn't break out of the loop, so we're still
- # inside a string
- if (lno - 1) == firstlno:
- # before the previous \n in str, we were in the first
- # line of the string
- continuation = C_STRING_FIRST_LINE
- else:
- continuation = C_STRING_NEXT_LINES
- continue # with outer loop
-
- if ch == '#':
- # consume the comment
- i = str.find('\n', i)
- assert i >= 0
- continue
-
- assert ch == '\\'
- assert i < n
- if str[i] == '\n':
- lno = lno + 1
- if i+1 == n:
- continuation = C_BACKSLASH
- i = i+1
-
- # The last stmt may be continued for all 3 reasons.
- # String continuation takes precedence over bracket
- # continuation, which beats backslash continuation.
- if (continuation != C_STRING_FIRST_LINE
- and continuation != C_STRING_NEXT_LINES and level > 0):
- continuation = C_BRACKET
- self.continuation = continuation
-
- # Push the final line number as a sentinel value, regardless of
- # whether it's continued.
- assert (continuation == C_NONE) == (goodlines[-1] == lno)
- if goodlines[-1] != lno:
- push_good(lno)
-
- def get_continuation_type(self):
- self._study1()
- return self.continuation
-
- # study1 was sufficient to determine the continuation status,
- # but doing more requires looking at every character. study2
- # does this for the last interesting statement in the block.
- # Creates:
- # self.stmt_start, stmt_end
- # slice indices of last interesting stmt
- # self.stmt_bracketing
- # the bracketing structure of the last interesting stmt;
- # for example, for the statement "say(boo) or die", stmt_bracketing
- # will be [(0, 0), (3, 1), (8, 0)]. Strings and comments are
- # treated as brackets, for the matter.
- # self.lastch
- # last non-whitespace character before optional trailing
- # comment
- # self.lastopenbracketpos
- # if continuation is C_BRACKET, index of last open bracket
-
- def _study2(self):
- if self.study_level >= 2:
- return
- self._study1()
- self.study_level = 2
-
- # Set p and q to slice indices of last interesting stmt.
- str, goodlines = self.str, self.goodlines
- i = len(goodlines) - 1
- p = len(str) # index of newest line
- while i:
- assert p
- # p is the index of the stmt at line number goodlines[i].
- # Move p back to the stmt at line number goodlines[i-1].
- q = p
- for nothing in range(goodlines[i-1], goodlines[i]):
- # tricky: sets p to 0 if no preceding newline
- p = str.rfind('\n', 0, p-1) + 1
- # The stmt str[p:q] isn't a continuation, but may be blank
- # or a non-indenting comment line.
- if _junkre(str, p):
- i = i-1
- else:
- break
- if i == 0:
- # nothing but junk!
- assert p == 0
- q = p
- self.stmt_start, self.stmt_end = p, q
-
- # Analyze this stmt, to find the last open bracket (if any)
- # and last interesting character (if any).
- lastch = ""
- stack = [] # stack of open bracket indices
- push_stack = stack.append
- bracketing = [(p, 0)]
- while p < q:
- # suck up all except ()[]{}'"#\\
- m = _chew_ordinaryre(str, p, q)
- if m:
- # we skipped at least one boring char
- newp = m.end()
- # back up over totally boring whitespace
- i = newp - 1 # index of last boring char
- while i >= p and str[i] in " \t\n":
- i = i-1
- if i >= p:
- lastch = str[i]
- p = newp
- if p >= q:
- break
-
- ch = str[p]
-
- if ch in "([{":
- push_stack(p)
- bracketing.append((p, len(stack)))
- lastch = ch
- p = p+1
- continue
-
- if ch in ")]}":
- if stack:
- del stack[-1]
- lastch = ch
- p = p+1
- bracketing.append((p, len(stack)))
- continue
-
- if ch == '"' or ch == "'":
- # consume string
- # Note that study1 did this with a Python loop, but
- # we use a regexp here; the reason is speed in both
- # cases; the string may be huge, but study1 pre-squashed
- # strings to a couple of characters per line. study1
- # also needed to keep track of newlines, and we don't
- # have to.
- bracketing.append((p, len(stack)+1))
- lastch = ch
- p = _match_stringre(str, p, q).end()
- bracketing.append((p, len(stack)))
- continue
-
- if ch == '#':
- # consume comment and trailing newline
- bracketing.append((p, len(stack)+1))
- p = str.find('\n', p, q) + 1
- assert p > 0
- bracketing.append((p, len(stack)))
- continue
-
- assert ch == '\\'
- p = p+1 # beyond backslash
- assert p < q
- if str[p] != '\n':
- # the program is invalid, but can't complain
- lastch = ch + str[p]
- p = p+1 # beyond escaped char
-
- # end while p < q:
-
- self.lastch = lastch
- if stack:
- self.lastopenbracketpos = stack[-1]
- self.stmt_bracketing = tuple(bracketing)
-
- # Assuming continuation is C_BRACKET, return the number
- # of spaces the next line should be indented.
-
- def compute_bracket_indent(self):
- self._study2()
- assert self.continuation == C_BRACKET
- j = self.lastopenbracketpos
- str = self.str
- n = len(str)
- origi = i = str.rfind('\n', 0, j) + 1
- j = j+1 # one beyond open bracket
- # find first list item; set i to start of its line
- while j < n:
- m = _itemre(str, j)
- if m:
- j = m.end() - 1 # index of first interesting char
- extra = 0
- break
- else:
- # this line is junk; advance to next line
- i = j = str.find('\n', j) + 1
- else:
- # nothing interesting follows the bracket;
- # reproduce the bracket line's indentation + a level
- j = i = origi
- while str[j] in " \t":
- j = j+1
- extra = self.indentwidth
- return len(str[i:j].expandtabs(self.tabwidth)) + extra
-
- # Return number of physical lines in last stmt (whether or not
- # it's an interesting stmt! this is intended to be called when
- # continuation is C_BACKSLASH).
-
- def get_num_lines_in_stmt(self):
- self._study1()
- goodlines = self.goodlines
- return goodlines[-1] - goodlines[-2]
-
- # Assuming continuation is C_BACKSLASH, return the number of spaces
- # the next line should be indented. Also assuming the new line is
- # the first one following the initial line of the stmt.
-
- def compute_backslash_indent(self):
- self._study2()
- assert self.continuation == C_BACKSLASH
- str = self.str
- i = self.stmt_start
- while str[i] in " \t":
- i = i+1
- startpos = i
-
- # See whether the initial line starts an assignment stmt; i.e.,
- # look for an = operator
- endpos = str.find('\n', startpos) + 1
- found = level = 0
- while i < endpos:
- ch = str[i]
- if ch in "([{":
- level = level + 1
- i = i+1
- elif ch in ")]}":
- if level:
- level = level - 1
- i = i+1
- elif ch == '"' or ch == "'":
- i = _match_stringre(str, i, endpos).end()
- elif ch == '#':
- break
- elif level == 0 and ch == '=' and \
- (i == 0 or str[i-1] not in "=<>!") and \
- str[i+1] != '=':
- found = 1
- break
- else:
- i = i+1
-
- if found:
- # found a legit =, but it may be the last interesting
- # thing on the line
- i = i+1 # move beyond the =
- found = re.match(r"\s*\\", str[i:endpos]) is None
-
- if not found:
- # oh well ... settle for moving beyond the first chunk
- # of non-whitespace chars
- i = startpos
- while str[i] not in " \t\n":
- i = i+1
-
- return len(str[self.stmt_start:i].expandtabs(\
- self.tabwidth)) + 1
-
- # Return the leading whitespace on the initial line of the last
- # interesting stmt.
-
- def get_base_indent_string(self):
- self._study2()
- i, n = self.stmt_start, self.stmt_end
- j = i
- str = self.str
- while j < n and str[j] in " \t":
- j = j + 1
- return str[i:j]
-
- # Did the last interesting stmt open a block?
-
- def is_block_opener(self):
- self._study2()
- return self.lastch == ':'
-
- # Did the last interesting stmt close a block?
-
- def is_block_closer(self):
- self._study2()
- return _closere(self.str, self.stmt_start) is not None
-
- # index of last open bracket ({[, or None if none
- lastopenbracketpos = None
-
- def get_last_open_bracket_pos(self):
- self._study2()
- return self.lastopenbracketpos
-
- # the structure of the bracketing of the last interesting statement,
- # in the format defined in _study2, or None if the text didn't contain
- # anything
- stmt_bracketing = None
-
- def get_last_stmt_bracketing(self):
- self._study2()
- return self.stmt_bracketing
diff --git a/sys/lib/python/idlelib/PyShell.py b/sys/lib/python/idlelib/PyShell.py
deleted file mode 100644
index 1bdd0a64c..000000000
--- a/sys/lib/python/idlelib/PyShell.py
+++ /dev/null
@@ -1,1441 +0,0 @@
-#! /usr/bin/env python
-
-import os
-import os.path
-import sys
-import string
-import getopt
-import re
-import socket
-import time
-import threading
-import traceback
-import types
-import macosxSupport
-
-import linecache
-from code import InteractiveInterpreter
-
-try:
- from Tkinter import *
-except ImportError:
- print>>sys.__stderr__, "** IDLE can't import Tkinter. " \
- "Your Python may not be configured for Tk. **"
- sys.exit(1)
-import tkMessageBox
-
-from EditorWindow import EditorWindow, fixwordbreaks
-from FileList import FileList
-from ColorDelegator import ColorDelegator
-from UndoDelegator import UndoDelegator
-from OutputWindow import OutputWindow
-from configHandler import idleConf
-import idlever
-
-import rpc
-import Debugger
-import RemoteDebugger
-
-IDENTCHARS = string.ascii_letters + string.digits + "_"
-LOCALHOST = '127.0.0.1'
-
-try:
- from signal import SIGTERM
-except ImportError:
- SIGTERM = 15
-
-# Override warnings module to write to warning_stream. Initialize to send IDLE
-# internal warnings to the console. ScriptBinding.check_syntax() will
-# temporarily redirect the stream to the shell window to display warnings when
-# checking user's code.
-global warning_stream
-warning_stream = sys.__stderr__
-try:
- import warnings
-except ImportError:
- pass
-else:
- def idle_showwarning(message, category, filename, lineno):
- file = warning_stream
- try:
- file.write(warnings.formatwarning(message, category, filename, lineno))
- except IOError:
- pass ## file (probably __stderr__) is invalid, warning dropped.
- warnings.showwarning = idle_showwarning
- def idle_formatwarning(message, category, filename, lineno):
- """Format warnings the IDLE way"""
- s = "\nWarning (from warnings module):\n"
- s += ' File \"%s\", line %s\n' % (filename, lineno)
- line = linecache.getline(filename, lineno).strip()
- if line:
- s += " %s\n" % line
- s += "%s: %s\n>>> " % (category.__name__, message)
- return s
- warnings.formatwarning = idle_formatwarning
-
-def extended_linecache_checkcache(filename=None,
- orig_checkcache=linecache.checkcache):
- """Extend linecache.checkcache to preserve the <pyshell#...> entries
-
- Rather than repeating the linecache code, patch it to save the
- <pyshell#...> entries, call the original linecache.checkcache()
- (which destroys them), and then restore the saved entries.
-
- orig_checkcache is bound at definition time to the original
- method, allowing it to be patched.
-
- """
- cache = linecache.cache
- save = {}
- for filename in cache.keys():
- if filename[:1] + filename[-1:] == '<>':
- save[filename] = cache[filename]
- orig_checkcache()
- cache.update(save)
-
-# Patch linecache.checkcache():
-linecache.checkcache = extended_linecache_checkcache
-
-
-class PyShellEditorWindow(EditorWindow):
- "Regular text edit window in IDLE, supports breakpoints"
-
- def __init__(self, *args):
- self.breakpoints = []
- EditorWindow.__init__(self, *args)
- self.text.bind("<<set-breakpoint-here>>", self.set_breakpoint_here)
- self.text.bind("<<clear-breakpoint-here>>", self.clear_breakpoint_here)
- self.text.bind("<<open-python-shell>>", self.flist.open_shell)
-
- self.breakpointPath = os.path.join(idleConf.GetUserCfgDir(),
- 'breakpoints.lst')
- # whenever a file is changed, restore breakpoints
- if self.io.filename: self.restore_file_breaks()
- def filename_changed_hook(old_hook=self.io.filename_change_hook,
- self=self):
- self.restore_file_breaks()
- old_hook()
- self.io.set_filename_change_hook(filename_changed_hook)
-
- rmenu_specs = [("Set Breakpoint", "<<set-breakpoint-here>>"),
- ("Clear Breakpoint", "<<clear-breakpoint-here>>")]
-
- def set_breakpoint(self, lineno):
- text = self.text
- filename = self.io.filename
- text.tag_add("BREAK", "%d.0" % lineno, "%d.0" % (lineno+1))
- try:
- i = self.breakpoints.index(lineno)
- except ValueError: # only add if missing, i.e. do once
- self.breakpoints.append(lineno)
- try: # update the subprocess debugger
- debug = self.flist.pyshell.interp.debugger
- debug.set_breakpoint_here(filename, lineno)
- except: # but debugger may not be active right now....
- pass
-
- def set_breakpoint_here(self, event=None):
- text = self.text
- filename = self.io.filename
- if not filename:
- text.bell()
- return
- lineno = int(float(text.index("insert")))
- self.set_breakpoint(lineno)
-
- def clear_breakpoint_here(self, event=None):
- text = self.text
- filename = self.io.filename
- if not filename:
- text.bell()
- return
- lineno = int(float(text.index("insert")))
- try:
- self.breakpoints.remove(lineno)
- except:
- pass
- text.tag_remove("BREAK", "insert linestart",\
- "insert lineend +1char")
- try:
- debug = self.flist.pyshell.interp.debugger
- debug.clear_breakpoint_here(filename, lineno)
- except:
- pass
-
- def clear_file_breaks(self):
- if self.breakpoints:
- text = self.text
- filename = self.io.filename
- if not filename:
- text.bell()
- return
- self.breakpoints = []
- text.tag_remove("BREAK", "1.0", END)
- try:
- debug = self.flist.pyshell.interp.debugger
- debug.clear_file_breaks(filename)
- except:
- pass
-
- def store_file_breaks(self):
- "Save breakpoints when file is saved"
- # XXX 13 Dec 2002 KBK Currently the file must be saved before it can
- # be run. The breaks are saved at that time. If we introduce
- # a temporary file save feature the save breaks functionality
- # needs to be re-verified, since the breaks at the time the
- # temp file is created may differ from the breaks at the last
- # permanent save of the file. Currently, a break introduced
- # after a save will be effective, but not persistent.
- # This is necessary to keep the saved breaks synched with the
- # saved file.
- #
- # Breakpoints are set as tagged ranges in the text. Certain
- # kinds of edits cause these ranges to be deleted: Inserting
- # or deleting a line just before a breakpoint, and certain
- # deletions prior to a breakpoint. These issues need to be
- # investigated and understood. It's not clear if they are
- # Tk issues or IDLE issues, or whether they can actually
- # be fixed. Since a modified file has to be saved before it is
- # run, and since self.breakpoints (from which the subprocess
- # debugger is loaded) is updated during the save, the visible
- # breaks stay synched with the subprocess even if one of these
- # unexpected breakpoint deletions occurs.
- breaks = self.breakpoints
- filename = self.io.filename
- try:
- lines = open(self.breakpointPath,"r").readlines()
- except IOError:
- lines = []
- new_file = open(self.breakpointPath,"w")
- for line in lines:
- if not line.startswith(filename + '='):
- new_file.write(line)
- self.update_breakpoints()
- breaks = self.breakpoints
- if breaks:
- new_file.write(filename + '=' + str(breaks) + '\n')
- new_file.close()
-
- def restore_file_breaks(self):
- self.text.update() # this enables setting "BREAK" tags to be visible
- filename = self.io.filename
- if filename is None:
- return
- if os.path.isfile(self.breakpointPath):
- lines = open(self.breakpointPath,"r").readlines()
- for line in lines:
- if line.startswith(filename + '='):
- breakpoint_linenumbers = eval(line[len(filename)+1:])
- for breakpoint_linenumber in breakpoint_linenumbers:
- self.set_breakpoint(breakpoint_linenumber)
-
- def update_breakpoints(self):
- "Retrieves all the breakpoints in the current window"
- text = self.text
- ranges = text.tag_ranges("BREAK")
- linenumber_list = self.ranges_to_linenumbers(ranges)
- self.breakpoints = linenumber_list
-
- def ranges_to_linenumbers(self, ranges):
- lines = []
- for index in range(0, len(ranges), 2):
- lineno = int(float(ranges[index]))
- end = int(float(ranges[index+1]))
- while lineno < end:
- lines.append(lineno)
- lineno += 1
- return lines
-
-# XXX 13 Dec 2002 KBK Not used currently
-# def saved_change_hook(self):
-# "Extend base method - clear breaks if module is modified"
-# if not self.get_saved():
-# self.clear_file_breaks()
-# EditorWindow.saved_change_hook(self)
-
- def _close(self):
- "Extend base method - clear breaks when module is closed"
- self.clear_file_breaks()
- EditorWindow._close(self)
-
-
-class PyShellFileList(FileList):
- "Extend base class: IDLE supports a shell and breakpoints"
-
- # override FileList's class variable, instances return PyShellEditorWindow
- # instead of EditorWindow when new edit windows are created.
- EditorWindow = PyShellEditorWindow
-
- pyshell = None
-
- def open_shell(self, event=None):
- if self.pyshell:
- self.pyshell.top.wakeup()
- else:
- self.pyshell = PyShell(self)
- if self.pyshell:
- if not self.pyshell.begin():
- return None
- return self.pyshell
-
-
-class ModifiedColorDelegator(ColorDelegator):
- "Extend base class: colorizer for the shell window itself"
-
- def __init__(self):
- ColorDelegator.__init__(self)
- self.LoadTagDefs()
-
- def recolorize_main(self):
- self.tag_remove("TODO", "1.0", "iomark")
- self.tag_add("SYNC", "1.0", "iomark")
- ColorDelegator.recolorize_main(self)
-
- def LoadTagDefs(self):
- ColorDelegator.LoadTagDefs(self)
- theme = idleConf.GetOption('main','Theme','name')
- self.tagdefs.update({
- "stdin": {'background':None,'foreground':None},
- "stdout": idleConf.GetHighlight(theme, "stdout"),
- "stderr": idleConf.GetHighlight(theme, "stderr"),
- "console": idleConf.GetHighlight(theme, "console"),
- None: idleConf.GetHighlight(theme, "normal"),
- })
-
-class ModifiedUndoDelegator(UndoDelegator):
- "Extend base class: forbid insert/delete before the I/O mark"
-
- def insert(self, index, chars, tags=None):
- try:
- if self.delegate.compare(index, "<", "iomark"):
- 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"):
- self.delegate.bell()
- return
- except TclError:
- pass
- UndoDelegator.delete(self, index1, index2)
-
-
-class MyRPCClient(rpc.RPCClient):
-
- def handle_EOF(self):
- "Override the base class - just re-raise EOFError"
- raise EOFError
-
-
-class ModifiedInterpreter(InteractiveInterpreter):
-
- def __init__(self, tkconsole):
- self.tkconsole = tkconsole
- locals = sys.modules['__main__'].__dict__
- InteractiveInterpreter.__init__(self, locals=locals)
- self.save_warnings_filters = None
- self.restarting = False
- self.subprocess_arglist = self.build_subprocess_arglist()
-
- port = 8833
- rpcclt = None
- rpcpid = None
-
- def spawn_subprocess(self):
- args = self.subprocess_arglist
- self.rpcpid = os.spawnv(os.P_NOWAIT, sys.executable, args)
-
- def build_subprocess_arglist(self):
- w = ['-W' + s for s in sys.warnoptions]
- if 1/2 > 0: # account for new division
- w.append('-Qnew')
- # Maybe IDLE is installed and is being accessed via sys.path,
- # or maybe it's not installed and the idle.py script is being
- # run from the IDLE source directory.
- del_exitf = idleConf.GetOption('main', 'General', 'delete-exitfunc',
- default=False, type='bool')
- if __name__ == 'idlelib.PyShell':
- command = "__import__('idlelib.run').run.main(%r)" % (del_exitf,)
- else:
- command = "__import__('run').main(%r)" % (del_exitf,)
- if sys.platform[:3] == 'win' and ' ' in sys.executable:
- # handle embedded space in path by quoting the argument
- decorated_exec = '"%s"' % sys.executable
- else:
- decorated_exec = sys.executable
- return [decorated_exec] + w + ["-c", command, str(self.port)]
-
- def start_subprocess(self):
- # spawning first avoids passing a listening socket to the subprocess
- self.spawn_subprocess()
- #time.sleep(20) # test to simulate GUI not accepting connection
- addr = (LOCALHOST, self.port)
- # Idle starts listening for connection on localhost
- for i in range(3):
- time.sleep(i)
- try:
- self.rpcclt = MyRPCClient(addr)
- break
- except socket.error, err:
- pass
- else:
- self.display_port_binding_error()
- return None
- # Accept the connection from the Python execution server
- self.rpcclt.listening_sock.settimeout(10)
- try:
- self.rpcclt.accept()
- except socket.timeout, err:
- self.display_no_subprocess_error()
- return None
- self.rpcclt.register("stdin", self.tkconsole)
- self.rpcclt.register("stdout", self.tkconsole.stdout)
- self.rpcclt.register("stderr", self.tkconsole.stderr)
- self.rpcclt.register("flist", self.tkconsole.flist)
- self.rpcclt.register("linecache", linecache)
- self.rpcclt.register("interp", self)
- self.transfer_path()
- self.poll_subprocess()
- return self.rpcclt
-
- def restart_subprocess(self):
- if self.restarting:
- return self.rpcclt
- self.restarting = True
- # close only the subprocess debugger
- debug = self.getdebugger()
- if debug:
- try:
- # Only close subprocess debugger, don't unregister gui_adap!
- RemoteDebugger.close_subprocess_debugger(self.rpcclt)
- except:
- pass
- # Kill subprocess, spawn a new one, accept connection.
- self.rpcclt.close()
- self.unix_terminate()
- console = self.tkconsole
- was_executing = console.executing
- console.executing = False
- self.spawn_subprocess()
- try:
- self.rpcclt.accept()
- except socket.timeout, err:
- self.display_no_subprocess_error()
- return None
- self.transfer_path()
- # annotate restart in shell window and mark it
- console.text.delete("iomark", "end-1c")
- if was_executing:
- console.write('\n')
- console.showprompt()
- halfbar = ((int(console.width) - 16) // 2) * '='
- console.write(halfbar + ' RESTART ' + halfbar)
- console.text.mark_set("restart", "end-1c")
- console.text.mark_gravity("restart", "left")
- console.showprompt()
- # restart subprocess debugger
- if debug:
- # Restarted debugger connects to current instance of debug GUI
- gui = RemoteDebugger.restart_subprocess_debugger(self.rpcclt)
- # reload remote debugger breakpoints for all PyShellEditWindows
- debug.load_breakpoints()
- self.restarting = False
- return self.rpcclt
-
- def __request_interrupt(self):
- self.rpcclt.remotecall("exec", "interrupt_the_server", (), {})
-
- def interrupt_subprocess(self):
- threading.Thread(target=self.__request_interrupt).start()
-
- def kill_subprocess(self):
- try:
- self.rpcclt.close()
- except AttributeError: # no socket
- pass
- self.unix_terminate()
- self.tkconsole.executing = False
- self.rpcclt = None
-
- def unix_terminate(self):
- "UNIX: make sure subprocess is terminated and collect status"
- if hasattr(os, 'kill'):
- try:
- os.kill(self.rpcpid, SIGTERM)
- except OSError:
- # process already terminated:
- return
- else:
- try:
- os.waitpid(self.rpcpid, 0)
- except OSError:
- return
-
- def transfer_path(self):
- self.runcommand("""if 1:
- import sys as _sys
- _sys.path = %r
- del _sys
- \n""" % (sys.path,))
-
- active_seq = None
-
- def poll_subprocess(self):
- clt = self.rpcclt
- if clt is None:
- return
- try:
- response = clt.pollresponse(self.active_seq, wait=0.05)
- except (EOFError, IOError, KeyboardInterrupt):
- # lost connection or subprocess terminated itself, restart
- # [the KBI is from rpc.SocketIO.handle_EOF()]
- if self.tkconsole.closing:
- return
- response = None
- self.restart_subprocess()
- if response:
- self.tkconsole.resetoutput()
- self.active_seq = None
- how, what = response
- console = self.tkconsole.console
- if how == "OK":
- if what is not None:
- print >>console, repr(what)
- elif how == "EXCEPTION":
- if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
- self.remote_stack_viewer()
- elif how == "ERROR":
- errmsg = "PyShell.ModifiedInterpreter: Subprocess ERROR:\n"
- print >>sys.__stderr__, errmsg, what
- print >>console, errmsg, what
- # we received a response to the currently active seq number:
- try:
- self.tkconsole.endexecuting()
- except AttributeError: # shell may have closed
- pass
- # Reschedule myself
- if not self.tkconsole.closing:
- self.tkconsole.text.after(self.tkconsole.pollinterval,
- self.poll_subprocess)
-
- debugger = None
-
- def setdebugger(self, debugger):
- self.debugger = debugger
-
- def getdebugger(self):
- return self.debugger
-
- def open_remote_stack_viewer(self):
- """Initiate the remote stack viewer from a separate thread.
-
- This method is called from the subprocess, and by returning from this
- method we allow the subprocess to unblock. After a bit the shell
- requests the subprocess to open the remote stack viewer which returns a
- static object looking at the last exceptiopn. It is queried through
- the RPC mechanism.
-
- """
- self.tkconsole.text.after(300, self.remote_stack_viewer)
- return
-
- def remote_stack_viewer(self):
- import RemoteObjectBrowser
- oid = self.rpcclt.remotequeue("exec", "stackviewer", ("flist",), {})
- if oid is None:
- self.tkconsole.root.bell()
- return
- item = RemoteObjectBrowser.StubObjectTreeItem(self.rpcclt, oid)
- from TreeWidget import ScrolledCanvas, TreeNode
- top = Toplevel(self.tkconsole.root)
- theme = idleConf.GetOption('main','Theme','name')
- background = idleConf.GetHighlight(theme, 'normal')['background']
- sc = ScrolledCanvas(top, bg=background, highlightthickness=0)
- sc.frame.pack(expand=1, fill="both")
- node = TreeNode(sc.canvas, None, item)
- node.expand()
- # XXX Should GC the remote tree when closing the window
-
- gid = 0
-
- def execsource(self, source):
- "Like runsource() but assumes complete exec source"
- filename = self.stuffsource(source)
- self.execfile(filename, source)
-
- def execfile(self, filename, source=None):
- "Execute an existing file"
- if source is None:
- source = open(filename, "r").read()
- try:
- code = compile(source, filename, "exec")
- except (OverflowError, SyntaxError):
- self.tkconsole.resetoutput()
- tkerr = self.tkconsole.stderr
- print>>tkerr, '*** Error in script or command!\n'
- print>>tkerr, 'Traceback (most recent call last):'
- InteractiveInterpreter.showsyntaxerror(self, filename)
- self.tkconsole.showprompt()
- else:
- self.runcode(code)
-
- def runsource(self, source):
- "Extend base class method: Stuff the source in the line cache first"
- filename = self.stuffsource(source)
- self.more = 0
- self.save_warnings_filters = warnings.filters[:]
- warnings.filterwarnings(action="error", category=SyntaxWarning)
- if isinstance(source, types.UnicodeType):
- import IOBinding
- try:
- source = source.encode(IOBinding.encoding)
- except UnicodeError:
- self.tkconsole.resetoutput()
- self.write("Unsupported characters in input\n")
- return
- try:
- # InteractiveInterpreter.runsource() calls its runcode() method,
- # which is overridden (see below)
- return InteractiveInterpreter.runsource(self, source, filename)
- finally:
- if self.save_warnings_filters is not None:
- warnings.filters[:] = self.save_warnings_filters
- self.save_warnings_filters = None
-
- def stuffsource(self, source):
- "Stuff source in the filename cache"
- filename = "<pyshell#%d>" % self.gid
- self.gid = self.gid + 1
- lines = source.split("\n")
- linecache.cache[filename] = len(source)+1, 0, lines, filename
- return filename
-
- def prepend_syspath(self, filename):
- "Prepend sys.path with file's directory if not already included"
- self.runcommand("""if 1:
- _filename = %r
- import sys as _sys
- from os.path import dirname as _dirname
- _dir = _dirname(_filename)
- if not _dir in _sys.path:
- _sys.path.insert(0, _dir)
- del _filename, _sys, _dirname, _dir
- \n""" % (filename,))
-
- def showsyntaxerror(self, filename=None):
- """Extend base class method: Add Colorizing
-
- Color the offending position instead of printing it and pointing at it
- with a caret.
-
- """
- text = self.tkconsole.text
- stuff = self.unpackerror()
- if stuff:
- msg, lineno, offset, line = stuff
- if lineno == 1:
- pos = "iomark + %d chars" % (offset-1)
- else:
- pos = "iomark linestart + %d lines + %d chars" % \
- (lineno-1, offset-1)
- text.tag_add("ERROR", pos)
- text.see(pos)
- char = text.get(pos)
- if char and char in IDENTCHARS:
- text.tag_add("ERROR", pos + " wordstart", pos)
- self.tkconsole.resetoutput()
- self.write("SyntaxError: %s\n" % str(msg))
- else:
- self.tkconsole.resetoutput()
- InteractiveInterpreter.showsyntaxerror(self, filename)
- self.tkconsole.showprompt()
-
- def unpackerror(self):
- type, value, tb = sys.exc_info()
- ok = type is SyntaxError
- if ok:
- try:
- msg, (dummy_filename, lineno, offset, line) = value
- if not offset:
- offset = 0
- except:
- ok = 0
- if ok:
- return msg, lineno, offset, line
- else:
- return None
-
- def showtraceback(self):
- "Extend base class method to reset output properly"
- self.tkconsole.resetoutput()
- self.checklinecache()
- InteractiveInterpreter.showtraceback(self)
- if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
- self.tkconsole.open_stack_viewer()
-
- def checklinecache(self):
- c = linecache.cache
- for key in c.keys():
- if key[:1] + key[-1:] != "<>":
- del c[key]
-
- def runcommand(self, code):
- "Run the code without invoking the debugger"
- # The code better not raise an exception!
- if self.tkconsole.executing:
- self.display_executing_dialog()
- return 0
- if self.rpcclt:
- self.rpcclt.remotequeue("exec", "runcode", (code,), {})
- else:
- exec code in self.locals
- return 1
-
- def runcode(self, code):
- "Override base class method"
- if self.tkconsole.executing:
- self.interp.restart_subprocess()
- self.checklinecache()
- if self.save_warnings_filters is not None:
- warnings.filters[:] = self.save_warnings_filters
- self.save_warnings_filters = None
- debugger = self.debugger
- try:
- self.tkconsole.beginexecuting()
- try:
- if not debugger and self.rpcclt is not None:
- self.active_seq = self.rpcclt.asyncqueue("exec", "runcode",
- (code,), {})
- elif debugger:
- debugger.run(code, self.locals)
- else:
- exec code in self.locals
- except SystemExit:
- if not self.tkconsole.closing:
- if tkMessageBox.askyesno(
- "Exit?",
- "Do you want to exit altogether?",
- default="yes",
- master=self.tkconsole.text):
- raise
- else:
- self.showtraceback()
- else:
- raise
- except:
- if use_subprocess:
- print >> self.tkconsole.stderr, \
- "IDLE internal error in runcode()"
- self.showtraceback()
- if use_subprocess:
- self.tkconsole.endexecuting()
- finally:
- if not use_subprocess:
- try:
- self.tkconsole.endexecuting()
- except AttributeError: # shell may have closed
- pass
-
- def write(self, s):
- "Override base class method"
- self.tkconsole.stderr.write(s)
-
- def display_port_binding_error(self):
- tkMessageBox.showerror(
- "Port Binding Error",
- "IDLE can't bind TCP/IP port 8833, which is necessary to "
- "communicate with its Python execution server. Either "
- "no networking is installed on this computer or another "
- "process (another IDLE?) is using the port. Run IDLE with the -n "
- "command line switch to start without a subprocess and refer to "
- "Help/IDLE Help 'Running without a subprocess' for further "
- "details.",
- master=self.tkconsole.text)
-
- def display_no_subprocess_error(self):
- tkMessageBox.showerror(
- "Subprocess Startup Error",
- "IDLE's subprocess didn't make connection. Either IDLE can't "
- "start a subprocess or personal firewall software is blocking "
- "the connection.",
- master=self.tkconsole.text)
-
- def display_executing_dialog(self):
- tkMessageBox.showerror(
- "Already executing",
- "The Python Shell window is already executing a command; "
- "please wait until it is finished.",
- master=self.tkconsole.text)
-
-
-class PyShell(OutputWindow):
-
- shell_title = "Python Shell"
-
- # Override classes
- ColorDelegator = ModifiedColorDelegator
- UndoDelegator = ModifiedUndoDelegator
-
- # Override menus
- menu_specs = [
- ("file", "_File"),
- ("edit", "_Edit"),
- ("debug", "_Debug"),
- ("options", "_Options"),
- ("windows", "_Windows"),
- ("help", "_Help"),
- ]
-
- if macosxSupport.runningAsOSXApp():
- del menu_specs[-3]
- menu_specs[-2] = ("windows", "_Window")
-
-
- # New classes
- from IdleHistory import History
-
- def __init__(self, flist=None):
- if use_subprocess:
- ms = self.menu_specs
- if ms[2][0] != "shell":
- ms.insert(2, ("shell", "She_ll"))
- self.interp = ModifiedInterpreter(self)
- if flist is None:
- root = Tk()
- fixwordbreaks(root)
- root.withdraw()
- flist = PyShellFileList(root)
- #
- OutputWindow.__init__(self, flist, None, None)
- #
-## self.config(usetabs=1, indentwidth=8, context_use_ps1=1)
- self.usetabs = True
- # indentwidth must be 8 when using tabs. See note in EditorWindow:
- self.indentwidth = 8
- self.context_use_ps1 = True
- #
- text = self.text
- text.configure(wrap="char")
- text.bind("<<newline-and-indent>>", self.enter_callback)
- text.bind("<<plain-newline-and-indent>>", self.linefeed_callback)
- text.bind("<<interrupt-execution>>", self.cancel_callback)
- text.bind("<<beginning-of-line>>", self.home_callback)
- text.bind("<<end-of-file>>", self.eof_callback)
- text.bind("<<open-stack-viewer>>", self.open_stack_viewer)
- text.bind("<<toggle-debugger>>", self.toggle_debugger)
- text.bind("<<toggle-jit-stack-viewer>>", self.toggle_jit_stack_viewer)
- if use_subprocess:
- text.bind("<<view-restart>>", self.view_restart_mark)
- text.bind("<<restart-shell>>", self.restart_shell)
- #
- self.save_stdout = sys.stdout
- self.save_stderr = sys.stderr
- self.save_stdin = sys.stdin
- import IOBinding
- self.stdout = PseudoFile(self, "stdout", IOBinding.encoding)
- self.stderr = PseudoFile(self, "stderr", IOBinding.encoding)
- self.console = PseudoFile(self, "console", IOBinding.encoding)
- if not use_subprocess:
- sys.stdout = self.stdout
- sys.stderr = self.stderr
- sys.stdin = self
- #
- self.history = self.History(self.text)
- #
- self.pollinterval = 50 # millisec
-
- def get_standard_extension_names(self):
- return idleConf.GetExtensions(shell_only=True)
-
- reading = False
- executing = False
- canceled = False
- endoffile = False
- closing = False
-
- def set_warning_stream(self, stream):
- global warning_stream
- warning_stream = stream
-
- def get_warning_stream(self):
- return warning_stream
-
- def toggle_debugger(self, event=None):
- if self.executing:
- tkMessageBox.showerror("Don't debug now",
- "You can only toggle the debugger when idle",
- master=self.text)
- self.set_debugger_indicator()
- return "break"
- else:
- db = self.interp.getdebugger()
- if db:
- self.close_debugger()
- else:
- self.open_debugger()
-
- def set_debugger_indicator(self):
- db = self.interp.getdebugger()
- self.setvar("<<toggle-debugger>>", not not db)
-
- def toggle_jit_stack_viewer(self, event=None):
- pass # All we need is the variable
-
- def close_debugger(self):
- db = self.interp.getdebugger()
- if db:
- self.interp.setdebugger(None)
- db.close()
- if self.interp.rpcclt:
- RemoteDebugger.close_remote_debugger(self.interp.rpcclt)
- self.resetoutput()
- self.console.write("[DEBUG OFF]\n")
- sys.ps1 = ">>> "
- self.showprompt()
- self.set_debugger_indicator()
-
- def open_debugger(self):
- if self.interp.rpcclt:
- dbg_gui = RemoteDebugger.start_remote_debugger(self.interp.rpcclt,
- self)
- else:
- dbg_gui = Debugger.Debugger(self)
- self.interp.setdebugger(dbg_gui)
- dbg_gui.load_breakpoints()
- sys.ps1 = "[DEBUG ON]\n>>> "
- self.showprompt()
- self.set_debugger_indicator()
-
- def beginexecuting(self):
- "Helper for ModifiedInterpreter"
- self.resetoutput()
- self.executing = 1
-
- def endexecuting(self):
- "Helper for ModifiedInterpreter"
- self.executing = 0
- self.canceled = 0
- self.showprompt()
-
- def close(self):
- "Extend EditorWindow.close()"
- if self.executing:
- response = tkMessageBox.askokcancel(
- "Kill?",
- "The program is still running!\n Do you want to kill it?",
- default="ok",
- parent=self.text)
- if response == False:
- return "cancel"
- if self.reading:
- self.top.quit()
- self.canceled = True
- self.closing = True
- # Wait for poll_subprocess() rescheduling to stop
- self.text.after(2 * self.pollinterval, self.close2)
-
- def close2(self):
- return EditorWindow.close(self)
-
- def _close(self):
- "Extend EditorWindow._close(), shut down debugger and execution server"
- self.close_debugger()
- if use_subprocess:
- self.interp.kill_subprocess()
- # Restore std streams
- sys.stdout = self.save_stdout
- sys.stderr = self.save_stderr
- sys.stdin = self.save_stdin
- # Break cycles
- self.interp = None
- self.console = None
- self.flist.pyshell = None
- self.history = None
- EditorWindow._close(self)
-
- def ispythonsource(self, filename):
- "Override EditorWindow method: never remove the colorizer"
- return True
-
- def short_title(self):
- return self.shell_title
-
- COPYRIGHT = \
- 'Type "copyright", "credits" or "license()" for more information.'
-
- firewallmessage = """
- ****************************************************************
- Personal firewall software may warn about the connection IDLE
- makes to its subprocess using this computer's internal loopback
- interface. This connection is not visible on any external
- interface and no data is sent to or received from the Internet.
- ****************************************************************
- """
-
- def begin(self):
- self.resetoutput()
- if use_subprocess:
- nosub = ''
- client = self.interp.start_subprocess()
- if not client:
- self.close()
- return False
- else:
- nosub = "==== No Subprocess ===="
- self.write("Python %s on %s\n%s\n%s\nIDLE %s %s\n" %
- (sys.version, sys.platform, self.COPYRIGHT,
- self.firewallmessage, idlever.IDLE_VERSION, nosub))
- self.showprompt()
- import Tkinter
- Tkinter._default_root = None # 03Jan04 KBK What's this?
- return True
-
- def readline(self):
- save = self.reading
- try:
- self.reading = 1
- self.top.mainloop() # nested mainloop()
- finally:
- self.reading = save
- line = self.text.get("iomark", "end-1c")
- if len(line) == 0: # may be EOF if we quit our mainloop with Ctrl-C
- line = "\n"
- if isinstance(line, unicode):
- import IOBinding
- try:
- line = line.encode(IOBinding.encoding)
- except UnicodeError:
- pass
- self.resetoutput()
- if self.canceled:
- self.canceled = 0
- if not use_subprocess:
- raise KeyboardInterrupt
- if self.endoffile:
- self.endoffile = 0
- line = ""
- return line
-
- def isatty(self):
- return True
-
- def cancel_callback(self, event=None):
- try:
- if self.text.compare("sel.first", "!=", "sel.last"):
- return # Active selection -- always use default binding
- except:
- pass
- if not (self.executing or self.reading):
- self.resetoutput()
- self.interp.write("KeyboardInterrupt\n")
- self.showprompt()
- return "break"
- self.endoffile = 0
- self.canceled = 1
- if (self.executing and self.interp.rpcclt):
- if self.interp.getdebugger():
- self.interp.restart_subprocess()
- else:
- self.interp.interrupt_subprocess()
- if self.reading:
- self.top.quit() # exit the nested mainloop() in readline()
- return "break"
-
- def eof_callback(self, event):
- if self.executing and not self.reading:
- return # Let the default binding (delete next char) take over
- if not (self.text.compare("iomark", "==", "insert") and
- self.text.compare("insert", "==", "end-1c")):
- return # Let the default binding (delete next char) take over
- if not self.executing:
- self.resetoutput()
- self.close()
- else:
- self.canceled = 0
- self.endoffile = 1
- self.top.quit()
- return "break"
-
- def home_callback(self, event):
- if event.state != 0 and event.keysym == "Home":
- return # <Modifier-Home>; fall back to class binding
- if self.text.compare("iomark", "<=", "insert") and \
- self.text.compare("insert linestart", "<=", "iomark"):
- self.text.mark_set("insert", "iomark")
- self.text.tag_remove("sel", "1.0", "end")
- self.text.see("insert")
- return "break"
-
- def linefeed_callback(self, event):
- # Insert a linefeed without entering anything (still autoindented)
- if self.reading:
- self.text.insert("insert", "\n")
- self.text.see("insert")
- else:
- self.newline_and_indent_event(event)
- return "break"
-
- def enter_callback(self, event):
- if self.executing and not self.reading:
- return # Let the default binding (insert '\n') take over
- # If some text is selected, recall the selection
- # (but only if this before the I/O mark)
- try:
- sel = self.text.get("sel.first", "sel.last")
- if sel:
- if self.text.compare("sel.last", "<=", "iomark"):
- self.recall(sel, event)
- return "break"
- except:
- pass
- # If we're strictly before the line containing iomark, recall
- # the current line, less a leading prompt, less leading or
- # trailing whitespace
- if self.text.compare("insert", "<", "iomark linestart"):
- # Check if there's a relevant stdin range -- if so, use it
- prev = self.text.tag_prevrange("stdin", "insert")
- if prev and self.text.compare("insert", "<", prev[1]):
- self.recall(self.text.get(prev[0], prev[1]), event)
- return "break"
- next = self.text.tag_nextrange("stdin", "insert")
- if next and self.text.compare("insert lineend", ">=", next[0]):
- self.recall(self.text.get(next[0], next[1]), event)
- return "break"
- # No stdin mark -- just get the current line, less any prompt
- indices = self.text.tag_nextrange("console", "insert linestart")
- if indices and \
- self.text.compare(indices[0], "<=", "insert linestart"):
- self.recall(self.text.get(indices[1], "insert lineend"), event)
- else:
- self.recall(self.text.get("insert linestart", "insert lineend"), event)
- return "break"
- # If we're between the beginning of the line and the iomark, i.e.
- # in the prompt area, move to the end of the prompt
- if self.text.compare("insert", "<", "iomark"):
- self.text.mark_set("insert", "iomark")
- # If we're in the current input and there's only whitespace
- # beyond the cursor, erase that whitespace first
- s = self.text.get("insert", "end-1c")
- if s and not s.strip():
- self.text.delete("insert", "end-1c")
- # If we're in the current input before its last line,
- # insert a newline right at the insert point
- if self.text.compare("insert", "<", "end-1c linestart"):
- self.newline_and_indent_event(event)
- return "break"
- # We're in the last line; append a newline and submit it
- self.text.mark_set("insert", "end-1c")
- if self.reading:
- self.text.insert("insert", "\n")
- self.text.see("insert")
- else:
- self.newline_and_indent_event(event)
- self.text.tag_add("stdin", "iomark", "end-1c")
- self.text.update_idletasks()
- if self.reading:
- self.top.quit() # Break out of recursive mainloop() in raw_input()
- else:
- self.runit()
- return "break"
-
- def recall(self, s, event):
- # remove leading and trailing empty or whitespace lines
- s = re.sub(r'^\s*\n', '' , s)
- s = re.sub(r'\n\s*$', '', s)
- lines = s.split('\n')
- self.text.undo_block_start()
- try:
- self.text.tag_remove("sel", "1.0", "end")
- self.text.mark_set("insert", "end-1c")
- prefix = self.text.get("insert linestart", "insert")
- if prefix.rstrip().endswith(':'):
- self.newline_and_indent_event(event)
- prefix = self.text.get("insert linestart", "insert")
- self.text.insert("insert", lines[0].strip())
- if len(lines) > 1:
- orig_base_indent = re.search(r'^([ \t]*)', lines[0]).group(0)
- new_base_indent = re.search(r'^([ \t]*)', prefix).group(0)
- for line in lines[1:]:
- if line.startswith(orig_base_indent):
- # replace orig base indentation with new indentation
- line = new_base_indent + line[len(orig_base_indent):]
- self.text.insert('insert', '\n'+line.rstrip())
- finally:
- self.text.see("insert")
- self.text.undo_block_stop()
-
- def runit(self):
- line = self.text.get("iomark", "end-1c")
- # Strip off last newline and surrounding whitespace.
- # (To allow you to hit return twice to end a statement.)
- i = len(line)
- while i > 0 and line[i-1] in " \t":
- i = i-1
- if i > 0 and line[i-1] == "\n":
- i = i-1
- while i > 0 and line[i-1] in " \t":
- i = i-1
- line = line[:i]
- more = self.interp.runsource(line)
-
- def open_stack_viewer(self, event=None):
- if self.interp.rpcclt:
- return self.interp.remote_stack_viewer()
- try:
- sys.last_traceback
- except:
- tkMessageBox.showerror("No stack trace",
- "There is no stack trace yet.\n"
- "(sys.last_traceback is not defined)",
- master=self.text)
- return
- from StackViewer import StackBrowser
- sv = StackBrowser(self.root, self.flist)
-
- def view_restart_mark(self, event=None):
- self.text.see("iomark")
- self.text.see("restart")
-
- def restart_shell(self, event=None):
- self.interp.restart_subprocess()
-
- def showprompt(self):
- self.resetoutput()
- try:
- s = str(sys.ps1)
- except:
- s = ""
- self.console.write(s)
- self.text.mark_set("insert", "end-1c")
- self.set_line_and_column()
- self.io.reset_undo()
-
- def resetoutput(self):
- source = self.text.get("iomark", "end-1c")
- if self.history:
- self.history.history_store(source)
- if self.text.get("end-2c") != "\n":
- self.text.insert("end-1c", "\n")
- self.text.mark_set("iomark", "end-1c")
- self.set_line_and_column()
- sys.stdout.softspace = 0
-
- def write(self, s, tags=()):
- try:
- self.text.mark_gravity("iomark", "right")
- OutputWindow.write(self, s, tags, "iomark")
- self.text.mark_gravity("iomark", "left")
- except:
- pass
- if self.canceled:
- self.canceled = 0
- if not use_subprocess:
- raise KeyboardInterrupt
-
-class PseudoFile(object):
-
- def __init__(self, shell, tags, encoding=None):
- self.shell = shell
- self.tags = tags
- self.softspace = 0
- self.encoding = encoding
-
- def write(self, s):
- self.shell.write(s, self.tags)
-
- def writelines(self, l):
- map(self.write, l)
-
- def flush(self):
- pass
-
- def isatty(self):
- return True
-
-
-usage_msg = """\
-
-USAGE: idle [-deins] [-t title] [file]*
- idle [-dns] [-t title] (-c cmd | -r file) [arg]*
- idle [-dns] [-t title] - [arg]*
-
- -h print this help message and exit
- -n run IDLE without a subprocess (see Help/IDLE Help for details)
-
-The following options will override the IDLE 'settings' configuration:
-
- -e open an edit window
- -i open a shell window
-
-The following options imply -i and will open a shell:
-
- -c cmd run the command in a shell, or
- -r file run script from file
-
- -d enable the debugger
- -s run $IDLESTARTUP or $PYTHONSTARTUP before anything else
- -t title set title of shell window
-
-A default edit window will be bypassed when -c, -r, or - are used.
-
-[arg]* are passed to the command (-c) or script (-r) in sys.argv[1:].
-
-Examples:
-
-idle
- Open an edit window or shell depending on IDLE's configuration.
-
-idle foo.py foobar.py
- Edit the files, also open a shell if configured to start with shell.
-
-idle -est "Baz" foo.py
- Run $IDLESTARTUP or $PYTHONSTARTUP, edit foo.py, and open a shell
- window with the title "Baz".
-
-idle -c "import sys; print sys.argv" "foo"
- Open a shell window and run the command, passing "-c" in sys.argv[0]
- and "foo" in sys.argv[1].
-
-idle -d -s -r foo.py "Hello World"
- Open a shell window, run a startup script, enable the debugger, and
- run foo.py, passing "foo.py" in sys.argv[0] and "Hello World" in
- sys.argv[1].
-
-echo "import sys; print sys.argv" | idle - "foobar"
- Open a shell window, run the script piped in, passing '' in sys.argv[0]
- and "foobar" in sys.argv[1].
-"""
-
-def main():
- global flist, root, use_subprocess
-
- use_subprocess = True
- enable_shell = False
- enable_edit = False
- debug = False
- cmd = None
- script = None
- startup = False
- try:
- opts, args = getopt.getopt(sys.argv[1:], "c:deihnr:st:")
- except getopt.error, msg:
- sys.stderr.write("Error: %s\n" % str(msg))
- sys.stderr.write(usage_msg)
- sys.exit(2)
- for o, a in opts:
- if o == '-c':
- cmd = a
- enable_shell = True
- if o == '-d':
- debug = True
- enable_shell = True
- if o == '-e':
- enable_edit = True
- if o == '-h':
- sys.stdout.write(usage_msg)
- sys.exit()
- if o == '-i':
- enable_shell = True
- if o == '-n':
- use_subprocess = False
- if o == '-r':
- script = a
- if os.path.isfile(script):
- pass
- else:
- print "No script file: ", script
- sys.exit()
- enable_shell = True
- if o == '-s':
- startup = True
- enable_shell = True
- if o == '-t':
- PyShell.shell_title = a
- enable_shell = True
- if args and args[0] == '-':
- cmd = sys.stdin.read()
- enable_shell = True
- # process sys.argv and sys.path:
- for i in range(len(sys.path)):
- sys.path[i] = os.path.abspath(sys.path[i])
- if args and args[0] == '-':
- sys.argv = [''] + args[1:]
- elif cmd:
- sys.argv = ['-c'] + args
- elif script:
- sys.argv = [script] + args
- elif args:
- enable_edit = True
- pathx = []
- for filename in args:
- pathx.append(os.path.dirname(filename))
- for dir in pathx:
- dir = os.path.abspath(dir)
- if not dir in sys.path:
- sys.path.insert(0, dir)
- else:
- dir = os.getcwd()
- if not dir in sys.path:
- sys.path.insert(0, dir)
- # check the IDLE settings configuration (but command line overrides)
- edit_start = idleConf.GetOption('main', 'General',
- 'editor-on-startup', type='bool')
- enable_edit = enable_edit or edit_start
- enable_shell = enable_shell or not edit_start
- # start editor and/or shell windows:
- root = Tk(className="Idle")
-
- fixwordbreaks(root)
- root.withdraw()
- flist = PyShellFileList(root)
- macosxSupport.setupApp(root, flist)
-
- if enable_edit:
- if not (cmd or script):
- for filename in args:
- flist.open(filename)
- if not args:
- flist.new()
- if enable_shell:
- shell = flist.open_shell()
- if not shell:
- return # couldn't open shell
-
- if macosxSupport.runningAsOSXApp() and flist.dict:
- # On OSX: when the user has double-clicked on a file that causes
- # IDLE to be launched the shell window will open just in front of
- # the file she wants to see. Lower the interpreter window when
- # there are open files.
- shell.top.lower()
-
- shell = flist.pyshell
- # handle remaining options:
- if debug:
- shell.open_debugger()
- if startup:
- filename = os.environ.get("IDLESTARTUP") or \
- os.environ.get("PYTHONSTARTUP")
- if filename and os.path.isfile(filename):
- shell.interp.execfile(filename)
- if shell and cmd or script:
- shell.interp.runcommand("""if 1:
- import sys as _sys
- _sys.argv = %r
- del _sys
- \n""" % (sys.argv,))
- if cmd:
- shell.interp.execsource(cmd)
- elif script:
- shell.interp.prepend_syspath(script)
- shell.interp.execfile(script)
-
- root.mainloop()
- root.destroy()
-
-if __name__ == "__main__":
- sys.modules['PyShell'] = sys.modules['__main__']
- main()
diff --git a/sys/lib/python/idlelib/README.txt b/sys/lib/python/idlelib/README.txt
deleted file mode 100644
index 101f7eba1..000000000
--- a/sys/lib/python/idlelib/README.txt
+++ /dev/null
@@ -1,63 +0,0 @@
-IDLE is Python's Tkinter-based Integrated DeveLopment Environment.
-
-IDLE emphasizes a lightweight, clean design with a simple user interface.
-Although it is suitable for beginners, even advanced users will find that
-IDLE has everything they really need to develop pure Python code.
-
-IDLE features a multi-window text editor with multiple undo, Python colorizing,
-and many other capabilities, e.g. smart indent, call tips, and autocompletion.
-
-The editor has comprehensive search functions, including searching through
-multiple files. Class browsers and path browsers provide fast access to
-code objects from a top level viewpoint without dealing with code folding.
-
-There is a Python Shell window which features colorizing and command recall.
-
-IDLE executes Python code in a separate process, which is restarted for each
-Run (F5) initiated from an editor window. The environment can also be
-restarted from the Shell window without restarting IDLE.
-
-This enhancement has often been requested, and is now finally available. The
-magic "reload/import *" incantations are no longer required when editing and
-testing a module two or three steps down the import chain.
-
-(Personal firewall software may warn about the connection IDLE makes to its
-subprocess using this computer's internal loopback interface. This connection
-is not visible on any external interface and no data is sent to or received
-from the Internet.)
-
-It is possible to interrupt tightly looping user code, even on Windows.
-
-Applications which cannot support subprocesses and/or sockets can still run
-IDLE in a single process.
-
-IDLE has an integrated debugger with stepping, persistent breakpoints, and call
-stack visibility.
-
-There is a GUI configuration manager which makes it easy to select fonts,
-colors, keybindings, and startup options. This facility includes a feature
-which allows the user to specify additional help sources, either locally or on
-the web.
-
-IDLE is coded in 100% pure Python, using the Tkinter GUI toolkit (Tk/Tcl)
-and is cross-platform, working on Unix, Mac, and Windows.
-
-IDLE accepts command line arguments. Try idle -h to see the options.
-
-
-If you find bugs or have suggestions, let us know about them by using the
-Python Bug Tracker:
-
-http://sourceforge.net/projects/python
-
-Patches are always appreciated at the Python Patch Tracker, and change
-requests should be posted to the RFE Tracker.
-
-For further details and links, read the Help files and check the IDLE home
-page at
-
-http://www.python.org/idle/
-
-There is a mail list for IDLE: idle-dev@python.org. You can join at
-
-http://mail.python.org/mailman/listinfo/idle-dev
diff --git a/sys/lib/python/idlelib/RemoteDebugger.py b/sys/lib/python/idlelib/RemoteDebugger.py
deleted file mode 100644
index 74085c36f..000000000
--- a/sys/lib/python/idlelib/RemoteDebugger.py
+++ /dev/null
@@ -1,381 +0,0 @@
-"""Support for remote Python debugging.
-
-Some ASCII art to describe the structure:
-
- IN PYTHON SUBPROCESS # IN IDLE PROCESS
- #
- # oid='gui_adapter'
- +----------+ # +------------+ +-----+
- | GUIProxy |--remote#call-->| GUIAdapter |--calls-->| GUI |
-+-----+--calls-->+----------+ # +------------+ +-----+
-| Idb | # /
-+-----+<-calls--+------------+ # +----------+<--calls-/
- | IdbAdapter |<--remote#call--| IdbProxy |
- +------------+ # +----------+
- oid='idb_adapter' #
-
-The purpose of the Proxy and Adapter classes is to translate certain
-arguments and return values that cannot be transported through the RPC
-barrier, in particular frame and traceback objects.
-
-"""
-
-import sys
-import types
-import rpc
-import Debugger
-
-debugging = 0
-
-idb_adap_oid = "idb_adapter"
-gui_adap_oid = "gui_adapter"
-
-#=======================================
-#
-# In the PYTHON subprocess:
-
-frametable = {}
-dicttable = {}
-codetable = {}
-tracebacktable = {}
-
-def wrap_frame(frame):
- fid = id(frame)
- frametable[fid] = frame
- return fid
-
-def wrap_info(info):
- "replace info[2], a traceback instance, by its ID"
- if info is None:
- return None
- else:
- traceback = info[2]
- assert isinstance(traceback, types.TracebackType)
- traceback_id = id(traceback)
- tracebacktable[traceback_id] = traceback
- modified_info = (info[0], info[1], traceback_id)
- return modified_info
-
-class GUIProxy:
-
- def __init__(self, conn, gui_adap_oid):
- self.conn = conn
- self.oid = gui_adap_oid
-
- def interaction(self, message, frame, info=None):
- # calls rpc.SocketIO.remotecall() via run.MyHandler instance
- # pass frame and traceback object IDs instead of the objects themselves
- self.conn.remotecall(self.oid, "interaction",
- (message, wrap_frame(frame), wrap_info(info)),
- {})
-
-class IdbAdapter:
-
- def __init__(self, idb):
- self.idb = idb
-
- #----------called by an IdbProxy----------
-
- def set_step(self):
- self.idb.set_step()
-
- def set_quit(self):
- self.idb.set_quit()
-
- def set_continue(self):
- self.idb.set_continue()
-
- def set_next(self, fid):
- frame = frametable[fid]
- self.idb.set_next(frame)
-
- def set_return(self, fid):
- frame = frametable[fid]
- self.idb.set_return(frame)
-
- def get_stack(self, fid, tbid):
- ##print >>sys.__stderr__, "get_stack(%r, %r)" % (fid, tbid)
- frame = frametable[fid]
- if tbid is None:
- tb = None
- else:
- tb = tracebacktable[tbid]
- stack, i = self.idb.get_stack(frame, tb)
- ##print >>sys.__stderr__, "get_stack() ->", stack
- stack = [(wrap_frame(frame), k) for frame, k in stack]
- ##print >>sys.__stderr__, "get_stack() ->", stack
- return stack, i
-
- def run(self, cmd):
- import __main__
- self.idb.run(cmd, __main__.__dict__)
-
- def set_break(self, filename, lineno):
- msg = self.idb.set_break(filename, lineno)
- return msg
-
- def clear_break(self, filename, lineno):
- msg = self.idb.clear_break(filename, lineno)
- return msg
-
- def clear_all_file_breaks(self, filename):
- msg = self.idb.clear_all_file_breaks(filename)
- return msg
-
- #----------called by a FrameProxy----------
-
- def frame_attr(self, fid, name):
- frame = frametable[fid]
- return getattr(frame, name)
-
- def frame_globals(self, fid):
- frame = frametable[fid]
- dict = frame.f_globals
- did = id(dict)
- dicttable[did] = dict
- return did
-
- def frame_locals(self, fid):
- frame = frametable[fid]
- dict = frame.f_locals
- did = id(dict)
- dicttable[did] = dict
- return did
-
- def frame_code(self, fid):
- frame = frametable[fid]
- code = frame.f_code
- cid = id(code)
- codetable[cid] = code
- return cid
-
- #----------called by a CodeProxy----------
-
- def code_name(self, cid):
- code = codetable[cid]
- return code.co_name
-
- def code_filename(self, cid):
- code = codetable[cid]
- return code.co_filename
-
- #----------called by a DictProxy----------
-
- def dict_keys(self, did):
- dict = dicttable[did]
- return dict.keys()
-
- def dict_item(self, did, key):
- dict = dicttable[did]
- value = dict[key]
- value = repr(value)
- return value
-
-#----------end class IdbAdapter----------
-
-
-def start_debugger(rpchandler, gui_adap_oid):
- """Start the debugger and its RPC link in the Python subprocess
-
- Start the subprocess side of the split debugger and set up that side of the
- RPC link by instantiating the GUIProxy, Idb debugger, and IdbAdapter
- objects and linking them together. Register the IdbAdapter with the
- RPCServer to handle RPC requests from the split debugger GUI via the
- IdbProxy.
-
- """
- gui_proxy = GUIProxy(rpchandler, gui_adap_oid)
- idb = Debugger.Idb(gui_proxy)
- idb_adap = IdbAdapter(idb)
- rpchandler.register(idb_adap_oid, idb_adap)
- return idb_adap_oid
-
-
-#=======================================
-#
-# In the IDLE process:
-
-
-class FrameProxy:
-
- def __init__(self, conn, fid):
- self._conn = conn
- self._fid = fid
- self._oid = "idb_adapter"
- self._dictcache = {}
-
- def __getattr__(self, name):
- if name[:1] == "_":
- raise AttributeError, name
- if name == "f_code":
- return self._get_f_code()
- if name == "f_globals":
- return self._get_f_globals()
- if name == "f_locals":
- return self._get_f_locals()
- return self._conn.remotecall(self._oid, "frame_attr",
- (self._fid, name), {})
-
- def _get_f_code(self):
- cid = self._conn.remotecall(self._oid, "frame_code", (self._fid,), {})
- return CodeProxy(self._conn, self._oid, cid)
-
- def _get_f_globals(self):
- did = self._conn.remotecall(self._oid, "frame_globals",
- (self._fid,), {})
- return self._get_dict_proxy(did)
-
- def _get_f_locals(self):
- did = self._conn.remotecall(self._oid, "frame_locals",
- (self._fid,), {})
- return self._get_dict_proxy(did)
-
- def _get_dict_proxy(self, did):
- if self._dictcache.has_key(did):
- return self._dictcache[did]
- dp = DictProxy(self._conn, self._oid, did)
- self._dictcache[did] = dp
- return dp
-
-
-class CodeProxy:
-
- def __init__(self, conn, oid, cid):
- self._conn = conn
- self._oid = oid
- self._cid = cid
-
- def __getattr__(self, name):
- if name == "co_name":
- return self._conn.remotecall(self._oid, "code_name",
- (self._cid,), {})
- if name == "co_filename":
- return self._conn.remotecall(self._oid, "code_filename",
- (self._cid,), {})
-
-
-class DictProxy:
-
- def __init__(self, conn, oid, did):
- self._conn = conn
- self._oid = oid
- self._did = did
-
- def keys(self):
- return self._conn.remotecall(self._oid, "dict_keys", (self._did,), {})
-
- def __getitem__(self, key):
- return self._conn.remotecall(self._oid, "dict_item",
- (self._did, key), {})
-
- def __getattr__(self, name):
- ##print >>sys.__stderr__, "failed DictProxy.__getattr__:", name
- raise AttributeError, name
-
-
-class GUIAdapter:
-
- def __init__(self, conn, gui):
- self.conn = conn
- self.gui = gui
-
- def interaction(self, message, fid, modified_info):
- ##print "interaction: (%s, %s, %s)" % (message, fid, modified_info)
- frame = FrameProxy(self.conn, fid)
- self.gui.interaction(message, frame, modified_info)
-
-
-class IdbProxy:
-
- def __init__(self, conn, shell, oid):
- self.oid = oid
- self.conn = conn
- self.shell = shell
-
- def call(self, methodname, *args, **kwargs):
- ##print "**IdbProxy.call %s %s %s" % (methodname, args, kwargs)
- value = self.conn.remotecall(self.oid, methodname, args, kwargs)
- ##print "**IdbProxy.call %s returns %r" % (methodname, value)
- return value
-
- def run(self, cmd, locals):
- # Ignores locals on purpose!
- seq = self.conn.asyncqueue(self.oid, "run", (cmd,), {})
- self.shell.interp.active_seq = seq
-
- def get_stack(self, frame, tbid):
- # passing frame and traceback IDs, not the objects themselves
- stack, i = self.call("get_stack", frame._fid, tbid)
- stack = [(FrameProxy(self.conn, fid), k) for fid, k in stack]
- return stack, i
-
- def set_continue(self):
- self.call("set_continue")
-
- def set_step(self):
- self.call("set_step")
-
- def set_next(self, frame):
- self.call("set_next", frame._fid)
-
- def set_return(self, frame):
- self.call("set_return", frame._fid)
-
- def set_quit(self):
- self.call("set_quit")
-
- def set_break(self, filename, lineno):
- msg = self.call("set_break", filename, lineno)
- return msg
-
- def clear_break(self, filename, lineno):
- msg = self.call("clear_break", filename, lineno)
- return msg
-
- def clear_all_file_breaks(self, filename):
- msg = self.call("clear_all_file_breaks", filename)
- return msg
-
-def start_remote_debugger(rpcclt, pyshell):
- """Start the subprocess debugger, initialize the debugger GUI and RPC link
-
- Request the RPCServer start the Python subprocess debugger and link. Set
- up the Idle side of the split debugger by instantiating the IdbProxy,
- debugger GUI, and debugger GUIAdapter objects and linking them together.
-
- Register the GUIAdapter with the RPCClient to handle debugger GUI
- interaction requests coming from the subprocess debugger via the GUIProxy.
-
- The IdbAdapter will pass execution and environment requests coming from the
- Idle debugger GUI to the subprocess debugger via the IdbProxy.
-
- """
- global idb_adap_oid
-
- idb_adap_oid = rpcclt.remotecall("exec", "start_the_debugger",\
- (gui_adap_oid,), {})
- idb_proxy = IdbProxy(rpcclt, pyshell, idb_adap_oid)
- gui = Debugger.Debugger(pyshell, idb_proxy)
- gui_adap = GUIAdapter(rpcclt, gui)
- rpcclt.register(gui_adap_oid, gui_adap)
- return gui
-
-def close_remote_debugger(rpcclt):
- """Shut down subprocess debugger and Idle side of debugger RPC link
-
- Request that the RPCServer shut down the subprocess debugger and link.
- Unregister the GUIAdapter, which will cause a GC on the Idle process
- debugger and RPC link objects. (The second reference to the debugger GUI
- is deleted in PyShell.close_remote_debugger().)
-
- """
- close_subprocess_debugger(rpcclt)
- rpcclt.unregister(gui_adap_oid)
-
-def close_subprocess_debugger(rpcclt):
- rpcclt.remotecall("exec", "stop_the_debugger", (idb_adap_oid,), {})
-
-def restart_subprocess_debugger(rpcclt):
- idb_adap_oid_ret = rpcclt.remotecall("exec", "start_the_debugger",\
- (gui_adap_oid,), {})
- assert idb_adap_oid_ret == idb_adap_oid, 'Idb restarted with different oid'
diff --git a/sys/lib/python/idlelib/RemoteObjectBrowser.py b/sys/lib/python/idlelib/RemoteObjectBrowser.py
deleted file mode 100644
index 6ba339137..000000000
--- a/sys/lib/python/idlelib/RemoteObjectBrowser.py
+++ /dev/null
@@ -1,36 +0,0 @@
-import rpc
-
-def remote_object_tree_item(item):
- wrapper = WrappedObjectTreeItem(item)
- oid = id(wrapper)
- rpc.objecttable[oid] = wrapper
- return oid
-
-class WrappedObjectTreeItem:
- # Lives in PYTHON subprocess
-
- def __init__(self, item):
- self.__item = item
-
- def __getattr__(self, name):
- value = getattr(self.__item, name)
- return value
-
- def _GetSubList(self):
- list = self.__item._GetSubList()
- return map(remote_object_tree_item, list)
-
-class StubObjectTreeItem:
- # Lives in IDLE process
-
- def __init__(self, sockio, oid):
- self.sockio = sockio
- self.oid = oid
-
- def __getattr__(self, name):
- value = rpc.MethodProxy(self.sockio, self.oid, name)
- return value
-
- def _GetSubList(self):
- list = self.sockio.remotecall(self.oid, "_GetSubList", (), {})
- return [StubObjectTreeItem(self.sockio, oid) for oid in list]
diff --git a/sys/lib/python/idlelib/ReplaceDialog.py b/sys/lib/python/idlelib/ReplaceDialog.py
deleted file mode 100644
index c8eb1c8c4..000000000
--- a/sys/lib/python/idlelib/ReplaceDialog.py
+++ /dev/null
@@ -1,167 +0,0 @@
-from Tkinter import *
-import SearchEngine
-from SearchDialogBase import SearchDialogBase
-
-def replace(text):
- root = text._root()
- engine = SearchEngine.get(root)
- if not hasattr(engine, "_replacedialog"):
- engine._replacedialog = ReplaceDialog(root, engine)
- dialog = engine._replacedialog
- dialog.open(text)
-
-class ReplaceDialog(SearchDialogBase):
-
- title = "Replace Dialog"
- icon = "Replace"
-
- def __init__(self, root, engine):
- SearchDialogBase.__init__(self, root, engine)
- self.replvar = StringVar(root)
-
- def open(self, text):
- SearchDialogBase.open(self, text)
- try:
- first = text.index("sel.first")
- except TclError:
- first = None
- try:
- last = text.index("sel.last")
- except TclError:
- last = None
- first = first or text.index("insert")
- last = last or first
- self.show_hit(first, last)
- self.ok = 1
-
- def create_entries(self):
- SearchDialogBase.create_entries(self)
- self.replent = self.make_entry("Replace with:", self.replvar)
-
- def create_command_buttons(self):
- SearchDialogBase.create_command_buttons(self)
- self.make_button("Find", self.find_it)
- self.make_button("Replace", self.replace_it)
- self.make_button("Replace+Find", self.default_command, 1)
- self.make_button("Replace All", self.replace_all)
-
- def find_it(self, event=None):
- self.do_find(0)
-
- def replace_it(self, event=None):
- if self.do_find(self.ok):
- self.do_replace()
-
- def default_command(self, event=None):
- if self.do_find(self.ok):
- self.do_replace()
- self.do_find(0)
-
- def replace_all(self, event=None):
- prog = self.engine.getprog()
- if not prog:
- return
- repl = self.replvar.get()
- text = self.text
- res = self.engine.search_text(text, prog)
- if not res:
- text.bell()
- return
- text.tag_remove("sel", "1.0", "end")
- text.tag_remove("hit", "1.0", "end")
- line = res[0]
- col = res[1].start()
- if self.engine.iswrap():
- line = 1
- col = 0
- ok = 1
- first = last = None
- # XXX ought to replace circular instead of top-to-bottom when wrapping
- text.undo_block_start()
- while 1:
- res = self.engine.search_forward(text, prog, line, col, 0, ok)
- if not res:
- break
- line, m = res
- chars = text.get("%d.0" % line, "%d.0" % (line+1))
- orig = m.group()
- new = m.expand(repl)
- i, j = m.span()
- first = "%d.%d" % (line, i)
- last = "%d.%d" % (line, j)
- if new == orig:
- text.mark_set("insert", last)
- else:
- text.mark_set("insert", first)
- if first != last:
- text.delete(first, last)
- if new:
- text.insert(first, new)
- col = i + len(new)
- ok = 0
- text.undo_block_stop()
- if first and last:
- self.show_hit(first, last)
- self.close()
-
- def do_find(self, ok=0):
- if not self.engine.getprog():
- return False
- text = self.text
- res = self.engine.search_text(text, None, ok)
- if not res:
- text.bell()
- return False
- line, m = res
- i, j = m.span()
- first = "%d.%d" % (line, i)
- last = "%d.%d" % (line, j)
- self.show_hit(first, last)
- self.ok = 1
- return True
-
- def do_replace(self):
- prog = self.engine.getprog()
- if not prog:
- return False
- text = self.text
- try:
- first = pos = text.index("sel.first")
- last = text.index("sel.last")
- except TclError:
- pos = None
- if not pos:
- first = last = pos = text.index("insert")
- line, col = SearchEngine.get_line_col(pos)
- chars = text.get("%d.0" % line, "%d.0" % (line+1))
- m = prog.match(chars, col)
- if not prog:
- return False
- new = m.expand(self.replvar.get())
- text.mark_set("insert", first)
- text.undo_block_start()
- if m.group():
- text.delete(first, last)
- if new:
- text.insert(first, new)
- text.undo_block_stop()
- self.show_hit(first, text.index("insert"))
- self.ok = 0
- return True
-
- def show_hit(self, first, last):
- text = self.text
- text.mark_set("insert", first)
- text.tag_remove("sel", "1.0", "end")
- text.tag_add("sel", first, last)
- text.tag_remove("hit", "1.0", "end")
- if first == last:
- text.tag_add("hit", first)
- else:
- text.tag_add("hit", first, last)
- text.see("insert")
- text.update_idletasks()
-
- def close(self, event=None):
- SearchDialogBase.close(self, event)
- self.text.tag_remove("hit", "1.0", "end")
diff --git a/sys/lib/python/idlelib/ScriptBinding.py b/sys/lib/python/idlelib/ScriptBinding.py
deleted file mode 100644
index f325ad1d2..000000000
--- a/sys/lib/python/idlelib/ScriptBinding.py
+++ /dev/null
@@ -1,210 +0,0 @@
-"""Extension to execute code outside the Python shell window.
-
-This adds the following commands:
-
-- Check module does a full syntax check of the current module.
- It also runs the tabnanny to catch any inconsistent tabs.
-
-- Run module executes the module's code in the __main__ namespace. The window
- must have been saved previously. The module is added to sys.modules, and is
- also added to the __main__ namespace.
-
-XXX GvR Redesign this interface (yet again) as follows:
-
-- Present a dialog box for ``Run Module''
-
-- Allow specify command line arguments in the dialog box
-
-"""
-
-import os
-import re
-import string
-import tabnanny
-import tokenize
-import tkMessageBox
-import PyShell
-
-from configHandler import idleConf
-
-IDENTCHARS = string.ascii_letters + string.digits + "_"
-
-indent_message = """Error: Inconsistent indentation detected!
-
-1) Your indentation is outright incorrect (easy to fix), OR
-
-2) Your indentation mixes tabs and spaces.
-
-To fix case 2, change all tabs to spaces by using Edit->Select All followed \
-by Format->Untabify Region and specify the number of columns used by each tab.
-"""
-
-class ScriptBinding:
-
- menudefs = [
- ('run', [None,
- ('Check Module', '<<check-module>>'),
- ('Run Module', '<<run-module>>'), ]), ]
-
- def __init__(self, editwin):
- self.editwin = editwin
- # Provide instance variables referenced by Debugger
- # XXX This should be done differently
- self.flist = self.editwin.flist
- self.root = self.editwin.root
-
- def check_module_event(self, event):
- filename = self.getfilename()
- if not filename:
- return
- if not self.tabnanny(filename):
- return
- self.checksyntax(filename)
-
- def tabnanny(self, filename):
- f = open(filename, 'r')
- try:
- tabnanny.process_tokens(tokenize.generate_tokens(f.readline))
- except tokenize.TokenError, msg:
- msgtxt, (lineno, start) = msg
- self.editwin.gotoline(lineno)
- self.errorbox("Tabnanny Tokenizing Error",
- "Token Error: %s" % msgtxt)
- return False
- except tabnanny.NannyNag, nag:
- # The error messages from tabnanny are too confusing...
- self.editwin.gotoline(nag.get_lineno())
- self.errorbox("Tab/space error", indent_message)
- return False
- except IndentationError:
- # From tokenize(), let compile() in checksyntax find it again.
- pass
- return True
-
- def checksyntax(self, filename):
- self.shell = shell = self.flist.open_shell()
- saved_stream = shell.get_warning_stream()
- shell.set_warning_stream(shell.stderr)
- f = open(filename, 'r')
- source = f.read()
- f.close()
- if '\r' in source:
- source = re.sub(r"\r\n", "\n", source)
- source = re.sub(r"\r", "\n", source)
- if source and source[-1] != '\n':
- source = source + '\n'
- text = self.editwin.text
- text.tag_remove("ERROR", "1.0", "end")
- try:
- try:
- # If successful, return the compiled code
- return compile(source, filename, "exec")
- except (SyntaxError, OverflowError), err:
- try:
- msg, (errorfilename, lineno, offset, line) = err
- if not errorfilename:
- err.args = msg, (filename, lineno, offset, line)
- err.filename = filename
- self.colorize_syntax_error(msg, lineno, offset)
- except:
- msg = "*** " + str(err)
- self.errorbox("Syntax error",
- "There's an error in your program:\n" + msg)
- return False
- finally:
- shell.set_warning_stream(saved_stream)
-
- def colorize_syntax_error(self, msg, lineno, offset):
- text = self.editwin.text
- pos = "0.0 + %d lines + %d chars" % (lineno-1, offset-1)
- text.tag_add("ERROR", pos)
- char = text.get(pos)
- if char and char in IDENTCHARS:
- text.tag_add("ERROR", pos + " wordstart", pos)
- if '\n' == text.get(pos): # error at line end
- text.mark_set("insert", pos)
- else:
- text.mark_set("insert", pos + "+1c")
- text.see(pos)
-
- def run_module_event(self, event):
- """Run the module after setting up the environment.
-
- First check the syntax. If OK, make sure the shell is active and
- then transfer the arguments, set the run environment's working
- directory to the directory of the module being executed and also
- add that directory to its sys.path if not already included.
-
- """
- filename = self.getfilename()
- if not filename:
- return
- if not self.tabnanny(filename):
- return
- code = self.checksyntax(filename)
- if not code:
- return
- shell = self.shell
- interp = shell.interp
- if PyShell.use_subprocess:
- shell.restart_shell()
- dirname = os.path.dirname(filename)
- # XXX Too often this discards arguments the user just set...
- interp.runcommand("""if 1:
- _filename = %r
- import sys as _sys
- from os.path import basename as _basename
- if (not _sys.argv or
- _basename(_sys.argv[0]) != _basename(_filename)):
- _sys.argv = [_filename]
- import os as _os
- _os.chdir(%r)
- del _filename, _sys, _basename, _os
- \n""" % (filename, dirname))
- interp.prepend_syspath(filename)
- # XXX KBK 03Jul04 When run w/o subprocess, runtime warnings still
- # go to __stderr__. With subprocess, they go to the shell.
- # Need to change streams in PyShell.ModifiedInterpreter.
- interp.runcode(code)
-
- def getfilename(self):
- """Get source filename. If not saved, offer to save (or create) file
-
- The debugger requires a source file. Make sure there is one, and that
- the current version of the source buffer has been saved. If the user
- declines to save or cancels the Save As dialog, return None.
-
- If the user has configured IDLE for Autosave, the file will be
- silently saved if it already exists and is dirty.
-
- """
- filename = self.editwin.io.filename
- if not self.editwin.get_saved():
- autosave = idleConf.GetOption('main', 'General',
- 'autosave', type='bool')
- if autosave and filename:
- self.editwin.io.save(None)
- else:
- reply = self.ask_save_dialog()
- self.editwin.text.focus_set()
- if reply == "ok":
- self.editwin.io.save(None)
- filename = self.editwin.io.filename
- else:
- filename = None
- return filename
-
- def ask_save_dialog(self):
- msg = "Source Must Be Saved\n" + 5*' ' + "OK to Save?"
- mb = tkMessageBox.Message(title="Save Before Run or Check",
- message=msg,
- icon=tkMessageBox.QUESTION,
- type=tkMessageBox.OKCANCEL,
- default=tkMessageBox.OK,
- master=self.editwin.text)
- return mb.show()
-
- def errorbox(self, title, message):
- # XXX This should really be a function of EditorWindow...
- tkMessageBox.showerror(title, message, master=self.editwin.text)
- self.editwin.text.focus_set()
diff --git a/sys/lib/python/idlelib/ScrolledList.py b/sys/lib/python/idlelib/ScrolledList.py
deleted file mode 100644
index 921193657..000000000
--- a/sys/lib/python/idlelib/ScrolledList.py
+++ /dev/null
@@ -1,139 +0,0 @@
-from Tkinter import *
-
-class ScrolledList:
-
- default = "(None)"
-
- def __init__(self, master, **options):
- # Create top frame, with scrollbar and listbox
- self.master = master
- self.frame = frame = Frame(master)
- self.frame.pack(fill="both", expand=1)
- self.vbar = vbar = Scrollbar(frame, name="vbar")
- self.vbar.pack(side="right", fill="y")
- self.listbox = listbox = Listbox(frame, exportselection=0,
- background="white")
- if options:
- listbox.configure(options)
- listbox.pack(expand=1, fill="both")
- # Tie listbox and scrollbar together
- vbar["command"] = listbox.yview
- listbox["yscrollcommand"] = vbar.set
- # Bind events to the list box
- listbox.bind("<ButtonRelease-1>", self.click_event)
- listbox.bind("<Double-ButtonRelease-1>", self.double_click_event)
- listbox.bind("<ButtonPress-3>", self.popup_event)
- listbox.bind("<Key-Up>", self.up_event)
- listbox.bind("<Key-Down>", self.down_event)
- # Mark as empty
- self.clear()
-
- def close(self):
- self.frame.destroy()
-
- def clear(self):
- self.listbox.delete(0, "end")
- self.empty = 1
- self.listbox.insert("end", self.default)
-
- def append(self, item):
- if self.empty:
- self.listbox.delete(0, "end")
- self.empty = 0
- self.listbox.insert("end", str(item))
-
- def get(self, index):
- return self.listbox.get(index)
-
- def click_event(self, event):
- self.listbox.activate("@%d,%d" % (event.x, event.y))
- index = self.listbox.index("active")
- self.select(index)
- self.on_select(index)
- return "break"
-
- def double_click_event(self, event):
- index = self.listbox.index("active")
- self.select(index)
- self.on_double(index)
- return "break"
-
- menu = None
-
- def popup_event(self, event):
- if not self.menu:
- self.make_menu()
- menu = self.menu
- self.listbox.activate("@%d,%d" % (event.x, event.y))
- index = self.listbox.index("active")
- self.select(index)
- menu.tk_popup(event.x_root, event.y_root)
-
- def make_menu(self):
- menu = Menu(self.listbox, tearoff=0)
- self.menu = menu
- self.fill_menu()
-
- def up_event(self, event):
- index = self.listbox.index("active")
- if self.listbox.selection_includes(index):
- index = index - 1
- else:
- index = self.listbox.size() - 1
- if index < 0:
- self.listbox.bell()
- else:
- self.select(index)
- self.on_select(index)
- return "break"
-
- def down_event(self, event):
- index = self.listbox.index("active")
- if self.listbox.selection_includes(index):
- index = index + 1
- else:
- index = 0
- if index >= self.listbox.size():
- self.listbox.bell()
- else:
- self.select(index)
- self.on_select(index)
- return "break"
-
- def select(self, index):
- self.listbox.focus_set()
- self.listbox.activate(index)
- self.listbox.selection_clear(0, "end")
- self.listbox.selection_set(index)
- self.listbox.see(index)
-
- # Methods to override for specific actions
-
- def fill_menu(self):
- pass
-
- def on_select(self, index):
- pass
-
- def on_double(self, index):
- pass
-
-
-def test():
- root = Tk()
- root.protocol("WM_DELETE_WINDOW", root.destroy)
- class MyScrolledList(ScrolledList):
- def fill_menu(self): self.menu.add_command(label="pass")
- def on_select(self, index): print "select", self.get(index)
- def on_double(self, index): print "double", self.get(index)
- s = MyScrolledList(root)
- for i in range(30):
- s.append("item %02d" % i)
- return root
-
-def main():
- root = test()
- root.mainloop()
-
-if __name__ == '__main__':
- main()
diff --git a/sys/lib/python/idlelib/SearchDialog.py b/sys/lib/python/idlelib/SearchDialog.py
deleted file mode 100644
index d7124d67f..000000000
--- a/sys/lib/python/idlelib/SearchDialog.py
+++ /dev/null
@@ -1,68 +0,0 @@
-from Tkinter import *
-import SearchEngine
-from SearchDialogBase import SearchDialogBase
-
-
-def _setup(text):
- root = text._root()
- engine = SearchEngine.get(root)
- if not hasattr(engine, "_searchdialog"):
- engine._searchdialog = SearchDialog(root, engine)
- return engine._searchdialog
-
-def find(text):
- pat = text.get("sel.first", "sel.last")
- return _setup(text).open(text,pat)
-
-def find_again(text):
- return _setup(text).find_again(text)
-
-def find_selection(text):
- return _setup(text).find_selection(text)
-
-class SearchDialog(SearchDialogBase):
-
- def create_widgets(self):
- f = SearchDialogBase.create_widgets(self)
- self.make_button("Find", self.default_command, 1)
-
- def default_command(self, event=None):
- if not self.engine.getprog():
- return
- if self.find_again(self.text):
- self.close()
-
- def find_again(self, text):
- if not self.engine.getpat():
- self.open(text)
- return False
- if not self.engine.getprog():
- return False
- res = self.engine.search_text(text)
- if res:
- line, m = res
- i, j = m.span()
- first = "%d.%d" % (line, i)
- last = "%d.%d" % (line, j)
- try:
- selfirst = text.index("sel.first")
- sellast = text.index("sel.last")
- if selfirst == first and sellast == last:
- text.bell()
- return False
- except TclError:
- pass
- text.tag_remove("sel", "1.0", "end")
- text.tag_add("sel", first, last)
- text.mark_set("insert", self.engine.isback() and first or last)
- text.see("insert")
- return True
- else:
- text.bell()
- return False
-
- def find_selection(self, text):
- pat = text.get("sel.first", "sel.last")
- if pat:
- self.engine.setcookedpat(pat)
- return self.find_again(text)
diff --git a/sys/lib/python/idlelib/SearchDialogBase.py b/sys/lib/python/idlelib/SearchDialogBase.py
deleted file mode 100644
index f63e7ae37..000000000
--- a/sys/lib/python/idlelib/SearchDialogBase.py
+++ /dev/null
@@ -1,140 +0,0 @@
-from Tkinter import *
-
-class SearchDialogBase:
-
- title = "Search Dialog"
- icon = "Search"
- needwrapbutton = 1
-
- def __init__(self, root, engine):
- self.root = root
- self.engine = engine
- self.top = None
-
- def open(self, text, searchphrase=None):
- self.text = text
- if not self.top:
- self.create_widgets()
- else:
- self.top.deiconify()
- self.top.tkraise()
- if searchphrase:
- self.ent.delete(0,"end")
- self.ent.insert("end",searchphrase)
- self.ent.focus_set()
- self.ent.selection_range(0, "end")
- self.ent.icursor(0)
- self.top.grab_set()
-
- def close(self, event=None):
- if self.top:
- self.top.grab_release()
- self.top.withdraw()
-
- def create_widgets(self):
- top = Toplevel(self.root)
- top.bind("<Return>", self.default_command)
- top.bind("<Escape>", self.close)
- top.protocol("WM_DELETE_WINDOW", self.close)
- top.wm_title(self.title)
- top.wm_iconname(self.icon)
- self.top = top
-
- self.row = 0
- self.top.grid_columnconfigure(0, pad=2, weight=0)
- self.top.grid_columnconfigure(1, pad=2, minsize=100, weight=100)
-
- self.create_entries()
- self.create_option_buttons()
- self.create_other_buttons()
- return self.create_command_buttons()
-
- def make_entry(self, label, var):
- l = Label(self.top, text=label)
- l.grid(row=self.row, column=0, sticky="nw")
- e = Entry(self.top, textvariable=var, exportselection=0)
- e.grid(row=self.row, column=1, sticky="nwe")
- self.row = self.row + 1
- return e
-
- def make_frame(self,labeltext=None):
- if labeltext:
- l = Label(self.top, text=labeltext)
- l.grid(row=self.row, column=0, sticky="nw")
- f = Frame(self.top)
- f.grid(row=self.row, column=1, columnspan=1, sticky="nwe")
- self.row = self.row + 1
- return f
-
- def make_button(self, label, command, isdef=0):
- b = Button(self.buttonframe,
- text=label, command=command,
- default=isdef and "active" or "normal")
- cols,rows=self.buttonframe.grid_size()
- b.grid(pady=1,row=rows,column=0,sticky="ew")
- self.buttonframe.grid(rowspan=rows+1)
- return b
-
- def create_entries(self):
- self.ent = self.make_entry("Find:", self.engine.patvar)
-
- def create_option_buttons(self):
- f = self.make_frame("Options")
-
- btn = Checkbutton(f, anchor="w",
- variable=self.engine.revar,
- text="Regular expression")
- btn.pack(side="left", fill="both")
- if self.engine.isre():
- btn.select()
-
- btn = Checkbutton(f, anchor="w",
- variable=self.engine.casevar,
- text="Match case")
- btn.pack(side="left", fill="both")
- if self.engine.iscase():
- btn.select()
-
- btn = Checkbutton(f, anchor="w",
- variable=self.engine.wordvar,
- text="Whole word")
- btn.pack(side="left", fill="both")
- if self.engine.isword():
- btn.select()
-
- if self.needwrapbutton:
- btn = Checkbutton(f, anchor="w",
- variable=self.engine.wrapvar,
- text="Wrap around")
- btn.pack(side="left", fill="both")
- if self.engine.iswrap():
- btn.select()
-
- def create_other_buttons(self):
- f = self.make_frame("Direction")
-
- #lbl = Label(f, text="Direction: ")
- #lbl.pack(side="left")
-
- btn = Radiobutton(f, anchor="w",
- variable=self.engine.backvar, value=1,
- text="Up")
- btn.pack(side="left", fill="both")
- if self.engine.isback():
- btn.select()
-
- btn = Radiobutton(f, anchor="w",
- variable=self.engine.backvar, value=0,
- text="Down")
- btn.pack(side="left", fill="both")
- if not self.engine.isback():
- btn.select()
-
- def create_command_buttons(self):
- #
- # place button frame on the right
- f = self.buttonframe = Frame(self.top)
- f.grid(row=0,column=2,padx=2,pady=2,ipadx=2,ipady=2)
-
- b = self.make_button("close", self.close)
- b.lower()
diff --git a/sys/lib/python/idlelib/SearchEngine.py b/sys/lib/python/idlelib/SearchEngine.py
deleted file mode 100644
index cc40a00c5..000000000
--- a/sys/lib/python/idlelib/SearchEngine.py
+++ /dev/null
@@ -1,220 +0,0 @@
-import re
-from Tkinter import *
-import tkMessageBox
-
-def get(root):
- if not hasattr(root, "_searchengine"):
- root._searchengine = SearchEngine(root)
- # XXX This will never garbage-collect -- who cares
- return root._searchengine
-
-class SearchEngine:
-
- def __init__(self, root):
- self.root = root
- # State shared by search, replace, and grep;
- # the search dialogs bind these to UI elements.
- self.patvar = StringVar(root) # search pattern
- self.revar = BooleanVar(root) # regular expression?
- self.casevar = BooleanVar(root) # match case?
- self.wordvar = BooleanVar(root) # match whole word?
- self.wrapvar = BooleanVar(root) # wrap around buffer?
- self.wrapvar.set(1) # (on by default)
- self.backvar = BooleanVar(root) # search backwards?
-
- # Access methods
-
- def getpat(self):
- return self.patvar.get()
-
- def setpat(self, pat):
- self.patvar.set(pat)
-
- def isre(self):
- return self.revar.get()
-
- def iscase(self):
- return self.casevar.get()
-
- def isword(self):
- return self.wordvar.get()
-
- def iswrap(self):
- return self.wrapvar.get()
-
- def isback(self):
- return self.backvar.get()
-
- # Higher level access methods
-
- def getcookedpat(self):
- pat = self.getpat()
- if not self.isre():
- pat = re.escape(pat)
- if self.isword():
- pat = r"\b%s\b" % pat
- return pat
-
- def getprog(self):
- pat = self.getpat()
- if not pat:
- self.report_error(pat, "Empty regular expression")
- return None
- pat = self.getcookedpat()
- flags = 0
- if not self.iscase():
- flags = flags | re.IGNORECASE
- try:
- prog = re.compile(pat, flags)
- except re.error, what:
- try:
- msg, col = what
- except:
- msg = str(what)
- col = -1
- self.report_error(pat, msg, col)
- return None
- return prog
-
- def report_error(self, pat, msg, col=-1):
- # Derived class could overrid this with something fancier
- msg = "Error: " + str(msg)
- if pat:
- msg = msg + "\np\Pattern: " + str(pat)
- if col >= 0:
- msg = msg + "\nOffset: " + str(col)
- tkMessageBox.showerror("Regular expression error",
- msg, master=self.root)
-
- def setcookedpat(self, pat):
- if self.isre():
- pat = re.escape(pat)
- self.setpat(pat)
-
- def search_text(self, text, prog=None, ok=0):
- """Search a text widget for the pattern.
-
- If prog is given, it should be the precompiled pattern.
- Return a tuple (lineno, matchobj); None if not found.
-
- This obeys the wrap and direction (back) settings.
-
- The search starts at the selection (if there is one) or
- at the insert mark (otherwise). If the search is forward,
- it starts at the right of the selection; for a backward
- search, it starts at the left end. An empty match exactly
- at either end of the selection (or at the insert mark if
- there is no selection) is ignored unless the ok flag is true
- -- this is done to guarantee progress.
-
- If the search is allowed to wrap around, it will return the
- original selection if (and only if) it is the only match.
-
- """
- if not prog:
- prog = self.getprog()
- if not prog:
- return None # Compilation failed -- stop
- wrap = self.wrapvar.get()
- first, last = get_selection(text)
- if self.isback():
- if ok:
- start = last
- else:
- start = first
- line, col = get_line_col(start)
- res = self.search_backward(text, prog, line, col, wrap, ok)
- else:
- if ok:
- start = first
- else:
- start = last
- line, col = get_line_col(start)
- res = self.search_forward(text, prog, line, col, wrap, ok)
- return res
-
- def search_forward(self, text, prog, line, col, wrap, ok=0):
- wrapped = 0
- startline = line
- chars = text.get("%d.0" % line, "%d.0" % (line+1))
- while chars:
- m = prog.search(chars[:-1], col)
- if m:
- if ok or m.end() > col:
- return line, m
- line = line + 1
- if wrapped and line > startline:
- break
- col = 0
- ok = 1
- chars = text.get("%d.0" % line, "%d.0" % (line+1))
- if not chars and wrap:
- wrapped = 1
- wrap = 0
- line = 1
- chars = text.get("1.0", "2.0")
- return None
-
- def search_backward(self, text, prog, line, col, wrap, ok=0):
- wrapped = 0
- startline = line
- chars = text.get("%d.0" % line, "%d.0" % (line+1))
- while 1:
- m = search_reverse(prog, chars[:-1], col)
- if m:
- if ok or m.start() < col:
- return line, m
- line = line - 1
- if wrapped and line < startline:
- break
- ok = 1
- if line <= 0:
- if not wrap:
- break
- wrapped = 1
- wrap = 0
- pos = text.index("end-1c")
- line, col = map(int, pos.split("."))
- chars = text.get("%d.0" % line, "%d.0" % (line+1))
- col = len(chars) - 1
- return None
-
-# Helper to search backwards in a string.
-# (Optimized for the case where the pattern isn't found.)
-
-def search_reverse(prog, chars, col):
- m = prog.search(chars)
- if not m:
- return None
- found = None
- i, j = m.span()
- while i < col and j <= col:
- found = m
- if i == j:
- j = j+1
- m = prog.search(chars, j)
- if not m:
- break
- i, j = m.span()
- return found
-
-# Helper to get selection end points, defaulting to insert mark.
-# Return a tuple of indices ("line.col" strings).
-
-def get_selection(text):
- try:
- first = text.index("sel.first")
- last = text.index("sel.last")
- except TclError:
- first = last = None
- if not first:
- first = text.index("insert")
- if not last:
- last = first
- return first, last
-
-# Helper to parse a text index into a (line, col) tuple.
-
-def get_line_col(index):
- line, col = map(int, index.split(".")) # Fails on invalid index
- return line, col
diff --git a/sys/lib/python/idlelib/StackViewer.py b/sys/lib/python/idlelib/StackViewer.py
deleted file mode 100644
index 6b7730bcd..000000000
--- a/sys/lib/python/idlelib/StackViewer.py
+++ /dev/null
@@ -1,137 +0,0 @@
-import os
-import sys
-import linecache
-
-from TreeWidget import TreeNode, TreeItem, ScrolledCanvas
-from ObjectBrowser import ObjectTreeItem, make_objecttreeitem
-
-def StackBrowser(root, flist=None, tb=None, top=None):
- if top is None:
- from Tkinter import Toplevel
- top = Toplevel(root)
- sc = ScrolledCanvas(top, bg="white", highlightthickness=0)
- sc.frame.pack(expand=1, fill="both")
- item = StackTreeItem(flist, tb)
- node = TreeNode(sc.canvas, None, item)
- node.expand()
-
-class StackTreeItem(TreeItem):
-
- def __init__(self, flist=None, tb=None):
- self.flist = flist
- self.stack = self.get_stack(tb)
- self.text = self.get_exception()
-
- def get_stack(self, tb):
- if tb is None:
- tb = sys.last_traceback
- stack = []
- if tb and tb.tb_frame is None:
- tb = tb.tb_next
- while tb is not None:
- stack.append((tb.tb_frame, tb.tb_lineno))
- tb = tb.tb_next
- return stack
-
- def get_exception(self):
- type = sys.last_type
- value = sys.last_value
- if hasattr(type, "__name__"):
- type = type.__name__
- s = str(type)
- if value is not None:
- s = s + ": " + str(value)
- return s
-
- def GetText(self):
- return self.text
-
- def GetSubList(self):
- sublist = []
- for info in self.stack:
- item = FrameTreeItem(info, self.flist)
- sublist.append(item)
- return sublist
-
-class FrameTreeItem(TreeItem):
-
- def __init__(self, info, flist):
- self.info = info
- self.flist = flist
-
- def GetText(self):
- frame, lineno = self.info
- try:
- modname = frame.f_globals["__name__"]
- except:
- modname = "?"
- code = frame.f_code
- filename = code.co_filename
- funcname = code.co_name
- sourceline = linecache.getline(filename, lineno)
- sourceline = sourceline.strip()
- if funcname in ("?", "", None):
- item = "%s, line %d: %s" % (modname, lineno, sourceline)
- else:
- item = "%s.%s(...), line %d: %s" % (modname, funcname,
- lineno, sourceline)
- return item
-
- def GetSubList(self):
- frame, lineno = self.info
- sublist = []
- if frame.f_globals is not frame.f_locals:
- item = VariablesTreeItem("<locals>", frame.f_locals, self.flist)
- sublist.append(item)
- item = VariablesTreeItem("<globals>", frame.f_globals, self.flist)
- sublist.append(item)
- return sublist
-
- def OnDoubleClick(self):
- if self.flist:
- frame, lineno = self.info
- filename = frame.f_code.co_filename
- if os.path.isfile(filename):
- self.flist.gotofileline(filename, lineno)
-
-class VariablesTreeItem(ObjectTreeItem):
-
- def GetText(self):
- return self.labeltext
-
- def GetLabelText(self):
- return None
-
- def IsExpandable(self):
- return len(self.object) > 0
-
- def keys(self):
- return self.object.keys()
-
- def GetSubList(self):
- sublist = []
- for key in self.keys():
- try:
- value = self.object[key]
- except KeyError:
- continue
- def setfunction(value, key=key, object=self.object):
- object[key] = value
- item = make_objecttreeitem(key + " =", value, setfunction)
- sublist.append(item)
- return sublist
-
-
-def _test():
- try:
- import testcode
- reload(testcode)
- except:
- sys.last_type, sys.last_value, sys.last_traceback = sys.exc_info()
- from Tkinter import Tk
- root = Tk()
- StackBrowser(None, top=root)
- root.mainloop()
-
-if __name__ == "__main__":
- _test()
diff --git a/sys/lib/python/idlelib/TODO.txt b/sys/lib/python/idlelib/TODO.txt
deleted file mode 100644
index e2f1ac0f2..000000000
--- a/sys/lib/python/idlelib/TODO.txt
+++ /dev/null
@@ -1,210 +0,0 @@
-Original IDLE todo, much of it now outdated:
-============================================
-TO DO:
-
-- improve debugger:
- - manage breakpoints globally, allow bp deletion, tbreak, cbreak etc.
- - real object browser
- - help on how to use it (a simple help button will do wonders)
- - performance? (updates of large sets of locals are slow)
- - better integration of "debug module"
- - debugger should be global resource (attached to flist, not to shell)
- - fix the stupid bug where you need to step twice
- - display class name in stack viewer entries for methods
- - suppress tracing through IDLE internals (e.g. print) DONE
- - add a button to suppress through a specific module or class or method
- - more object inspection to stack viewer, e.g. to view all array items
-- insert the initial current directory into sys.path DONE
-- default directory attribute for each window instead of only for windows
- that have an associated filename
-- command expansion from keywords, module contents, other buffers, etc.
-- "Recent documents" menu item DONE
-- Filter region command
-- Optional horizontal scroll bar
-- more Emacsisms:
- - ^K should cut to buffer
- - M-[, M-] to move by paragraphs
- - incremental search?
-- search should indicate wrap-around in some way
-- restructure state sensitive code to avoid testing flags all the time
-- persistent user state (e.g. window and cursor positions, bindings)
-- make backups when saving
-- check file mtimes at various points
-- Pluggable interface with RCS/CVS/Perforce/Clearcase
-- better help?
-- don't open second class browser on same module (nor second path browser)
-- unify class and path browsers
-- Need to define a standard way whereby one can determine one is running
- inside IDLE (needed for Tk mainloop, also handy for $PYTHONSTARTUP)
-- Add more utility methods for use by extensions (a la get_selection)
-- Way to run command in totally separate interpreter (fork+os.system?) DONE
-- Way to find definition of fully-qualified name:
- In other words, select "UserDict.UserDict", hit some magic key and
- it loads up UserDict.py and finds the first def or class for UserDict.
-- need a way to force colorization on/off
-- need a way to force auto-indent on/off
-
-Details:
-
-- ^O (on Unix -- open-line) should honor autoindent
-- after paste, show end of pasted text
-- on Windows, should turn short filename to long filename (not only in argv!)
- (shouldn't this be done -- or undone -- by ntpath.normpath?)
-- new autoindent after colon even indents when the colon is in a comment!
-- sometimes forward slashes in pathname remain
-- sometimes star in window name remains in Windows menu
-- With unix bindings, ESC by itself is ignored
-- Sometimes for no apparent reason a selection from the cursor to the
- end of the command buffer appears, which is hard to get rid of
- because it stays when you are typing!
-- The Line/Col in the status bar can be wrong initially in PyShell DONE
-
-Structural problems:
-
-- too much knowledge in FileList about EditorWindow (for example)
-- should add some primitives for accessing the selection etc.
- to repeat cumbersome code over and over
-
-======================================================================
-
-Jeff Bauer suggests:
-
-- Open Module doesn't appear to handle hierarchical packages.
-- Class browser should also allow hierarchical packages.
-- Open and Open Module could benefit from a history, DONE
- either command line style, or Microsoft recent-file
- style.
-- Add a Smalltalk-style inspector (i.e. Tkinspect)
-
-The last suggestion is already a reality, but not yet
-integrated into IDLE. I use a module called inspector.py,
-that used to be available from python.org(?) It no longer
-appears to be in the contributed section, and the source
-has no author attribution.
-
-In any case, the code is useful for visually navigating
-an object's attributes, including its container hierarchy.
-
- >>> from inspector import Tkinspect
- >>> Tkinspect(None, myObject)
-
-Tkinspect could probably be extended and refined to
-integrate better into IDLE.
-
-======================================================================
-
-Comparison to PTUI
-------------------
-
-+ PTUI's help is better (HTML!)
-
-+ PTUI can attach a shell to any module
-
-+ PTUI has some more I/O commands:
- open multiple
- append
- examine (what's that?)
-
-======================================================================
-
-Notes after trying to run Grail
--------------------------------
-
-- Grail does stuff to sys.path based on sys.argv[0]; you must set
-sys.argv[0] to something decent first (it is normally set to the path of
-the idle script).
-
-- Grail must be exec'ed in __main__ because that's imported by some
-other parts of Grail.
-
-- Grail uses a module called History and so does idle :-(
-
-======================================================================
-
-Robin Friedrich's items:
-
-Things I'd like to see:
- - I'd like support for shift-click extending the selection. There's a
- bug now that it doesn't work the first time you try it.
- - Printing is needed. How hard can that be on Windows? FIRST CUT DONE
- - The python-mode trick of autoindenting a line with <tab> is neat and
- very handy.
- - (someday) a spellchecker for docstrings and comments.
- - a pagedown/up command key which moves to next class/def statement (top
- level)
- - split window capability
- - DnD text relocation/copying
-
-Things I don't want to see.
- - line numbers... will probably slow things down way too much.
- - Please use another icon for the tree browser leaf. The small snake
- isn't cutting it.
-
-----------------------------------------------------------------------
-
-- Customizable views (multi-window or multi-pane). (Markus Gritsch)
-
-- Being able to double click (maybe double right click) on a callable
-object in the editor which shows the source of the object, if
-possible. (Gerrit Holl)
-
-- Hooks into the guts, like in Emacs. (Mike Romberg)
-
-- Sharing the editor with a remote tutor. (Martijn Faassen)
-
-- Multiple views on the same file. (Tony J Ibbs)
-
-- Store breakpoints in a global (per-project) database (GvR); Dirk
-Heise adds: save some space-trimmed context and search around when
-reopening a file that might have been edited by someone else.
-
-- Capture menu events in extensions without changing the IDLE source.
-(Matthias Barmeier)
-
-- Use overlapping panels (a "notebook" in MFC terms I think) for info
-that doesn't need to be accessible simultaneously (e.g. HTML source
-and output). Use multi-pane windows for info that does need to be
-shown together (e.g. class browser and source). (Albert Brandl)
-
-- A project should invisibly track all symbols, for instant search,
-replace and cross-ref. Projects should be allowed to span multiple
-directories, hosts, etc. Project management files are placed in a
-directory you specify. A global mapping between project names and
-project directories should exist [not so sure --GvR]. (Tim Peters)
-
-- Merge attr-tips and auto-expand. (Mark Hammond, Tim Peters)
-
-- Python Shell should behave more like a "shell window" as users know
-it -- i.e. you can only edit the current command, and the cursor can't
-escape from the command area. (Albert Brandl)
-
-- Set X11 class to "idle/Idle", set icon and title to something
-beginning with "idle" -- for window manangers. (Randall Hopper)
-
-- Config files editable through a preferences dialog. (me) DONE
-
-- Config files still editable outside the preferences dialog.
-(Randall Hopper) DONE
-
-- When you're editing a command in PyShell, and there are only blank
-lines below the cursor, hitting Return should ignore or delete those
-blank lines rather than deciding you're not on the last line. (me)
-
-- Run command (F5 c.s.) should be more like Pythonwin's Run -- a
-dialog with options to give command line arguments, run the debugger,
-etc. (me)
-
-- Shouldn't be able to delete part of the prompt (or any text before
-it) in the PyShell. (Martijn Faassen) DONE
-
-- Emacs style auto-fill (also smart about comments and strings).
-(Jeremy Hylton)
-
-- Output of Run Script should go to a separate output window, not to
-the shell window. Output of separate runs should all go to the same
-window but clearly delimited. (David Scherer) REJECT FIRST, LATTER DONE
-
-- GUI form designer to kick VB's butt. (Robert Geiger) THAT'S NOT IDLE
-
-- Printing! Possibly via generation of PDF files which the user must
-then send to the printer separately. (Dinu Gherman) FIRST CUT
diff --git a/sys/lib/python/idlelib/ToolTip.py b/sys/lib/python/idlelib/ToolTip.py
deleted file mode 100644
index ce7a3d3ee..000000000
--- a/sys/lib/python/idlelib/ToolTip.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# general purpose 'tooltip' routines - currently unused in idlefork
-# (although the 'calltips' extension is partly based on this code)
-# may be useful for some purposes in (or almost in ;) the current project scope
-# Ideas gleaned from PySol
-
-from Tkinter import *
-
-class ToolTipBase:
-
- def __init__(self, button):
- self.button = button
- self.tipwindow = None
- self.id = None
- self.x = self.y = 0
- self._id1 = self.button.bind("<Enter>", self.enter)
- self._id2 = self.button.bind("<Leave>", self.leave)
- self._id3 = self.button.bind("<ButtonPress>", self.leave)
-
- def enter(self, event=None):
- self.schedule()
-
- def leave(self, event=None):
- self.unschedule()
- self.hidetip()
-
- def schedule(self):
- self.unschedule()
- self.id = self.button.after(1500, self.showtip)
-
- def unschedule(self):
- id = self.id
- self.id = None
- if id:
- self.button.after_cancel(id)
-
- def showtip(self):
- if self.tipwindow:
- return
- # The tip window must be completely outside the button;
- # otherwise when the mouse enters the tip window we get
- # a leave event and it disappears, and then we get an enter
- # event and it reappears, and so on forever :-(
- x = self.button.winfo_rootx() + 20
- y = self.button.winfo_rooty() + self.button.winfo_height() + 1
- self.tipwindow = tw = Toplevel(self.button)
- tw.wm_overrideredirect(1)
- tw.wm_geometry("+%d+%d" % (x, y))
- self.showcontents()
-
- def showcontents(self, text="Your text here"):
- # Override this in derived class
- label = Label(self.tipwindow, text=text, justify=LEFT,
- background="#ffffe0", relief=SOLID, borderwidth=1)
- label.pack()
-
- def hidetip(self):
- tw = self.tipwindow
- self.tipwindow = None
- if tw:
- tw.destroy()
-
-class ToolTip(ToolTipBase):
- def __init__(self, button, text):
- ToolTipBase.__init__(self, button)
- self.text = text
- def showcontents(self):
- ToolTipBase.showcontents(self, self.text)
-
-class ListboxToolTip(ToolTipBase):
- def __init__(self, button, items):
- ToolTipBase.__init__(self, button)
- self.items = items
- def showcontents(self):
- listbox = Listbox(self.tipwindow, background="#ffffe0")
- listbox.pack()
- for item in self.items:
- listbox.insert(END, item)
-
-def main():
- # Test code
- root = Tk()
- b = Button(root, text="Hello", command=root.destroy)
- b.pack()
- root.update()
- tip = ListboxToolTip(b, ["Hello", "world"])
- root.mainloop()
-
-if __name__ == '__main__':
- main()
diff --git a/sys/lib/python/idlelib/TreeWidget.py b/sys/lib/python/idlelib/TreeWidget.py
deleted file mode 100644
index c5c171fb8..000000000
--- a/sys/lib/python/idlelib/TreeWidget.py
+++ /dev/null
@@ -1,478 +0,0 @@
-# XXX TO DO:
-# - popup menu
-# - support partial or total redisplay
-# - key bindings (instead of quick-n-dirty bindings on Canvas):
-# - up/down arrow keys to move focus around
-# - ditto for page up/down, home/end
-# - left/right arrows to expand/collapse & move out/in
-# - more doc strings
-# - add icons for "file", "module", "class", "method"; better "python" icon
-# - callback for selection???
-# - multiple-item selection
-# - tooltips
-# - redo geometry without magic numbers
-# - keep track of object ids to allow more careful cleaning
-# - optimize tree redraw after expand of subnode
-
-import os
-import sys
-from Tkinter import *
-import imp
-
-import ZoomHeight
-from configHandler import idleConf
-
-ICONDIR = "Icons"
-
-# Look for Icons subdirectory in the same directory as this module
-try:
- _icondir = os.path.join(os.path.dirname(__file__), ICONDIR)
-except NameError:
- _icondir = ICONDIR
-if os.path.isdir(_icondir):
- ICONDIR = _icondir
-elif not os.path.isdir(ICONDIR):
- raise RuntimeError, "can't find icon directory (%r)" % (ICONDIR,)
-
-def listicons(icondir=ICONDIR):
- """Utility to display the available icons."""
- root = Tk()
- import glob
- list = glob.glob(os.path.join(icondir, "*.gif"))
- list.sort()
- images = []
- row = column = 0
- for file in list:
- name = os.path.splitext(os.path.basename(file))[0]
- image = PhotoImage(file=file, master=root)
- images.append(image)
- label = Label(root, image=image, bd=1, relief="raised")
- label.grid(row=row, column=column)
- label = Label(root, text=name)
- label.grid(row=row+1, column=column)
- column = column + 1
- if column >= 10:
- row = row+2
- column = 0
- root.images = images
-
-
-class TreeNode:
-
- def __init__(self, canvas, parent, item):
- self.canvas = canvas
- self.parent = parent
- self.item = item
- self.state = 'collapsed'
- self.selected = False
- self.children = []
- self.x = self.y = None
- self.iconimages = {} # cache of PhotoImage instances for icons
-
- def destroy(self):
- for c in self.children[:]:
- self.children.remove(c)
- c.destroy()
- self.parent = None
-
- def geticonimage(self, name):
- try:
- return self.iconimages[name]
- except KeyError:
- pass
- file, ext = os.path.splitext(name)
- ext = ext or ".gif"
- fullname = os.path.join(ICONDIR, file + ext)
- image = PhotoImage(master=self.canvas, file=fullname)
- self.iconimages[name] = image
- return image
-
- def select(self, event=None):
- if self.selected:
- return
- self.deselectall()
- self.selected = True
- self.canvas.delete(self.image_id)
- self.drawicon()
- self.drawtext()
-
- def deselect(self, event=None):
- if not self.selected:
- return
- self.selected = False
- self.canvas.delete(self.image_id)
- self.drawicon()
- self.drawtext()
-
- def deselectall(self):
- if self.parent:
- self.parent.deselectall()
- else:
- self.deselecttree()
-
- def deselecttree(self):
- if self.selected:
- self.deselect()
- for child in self.children:
- child.deselecttree()
-
- def flip(self, event=None):
- if self.state == 'expanded':
- self.collapse()
- else:
- self.expand()
- self.item.OnDoubleClick()
- return "break"
-
- def expand(self, event=None):
- if not self.item._IsExpandable():
- return
- if self.state != 'expanded':
- self.state = 'expanded'
- self.update()
- self.view()
-
- def collapse(self, event=None):
- if self.state != 'collapsed':
- self.state = 'collapsed'
- self.update()
-
- def view(self):
- top = self.y - 2
- bottom = self.lastvisiblechild().y + 17
- height = bottom - top
- visible_top = self.canvas.canvasy(0)
- visible_height = self.canvas.winfo_height()
- visible_bottom = self.canvas.canvasy(visible_height)
- if visible_top <= top and bottom <= visible_bottom:
- return
- x0, y0, x1, y1 = self.canvas._getints(self.canvas['scrollregion'])
- if top >= visible_top and height <= visible_height:
- fraction = top + height - visible_height
- else:
- fraction = top
- fraction = float(fraction) / y1
- self.canvas.yview_moveto(fraction)
-
- def lastvisiblechild(self):
- if self.children and self.state == 'expanded':
- return self.children[-1].lastvisiblechild()
- else:
- return self
-
- def update(self):
- if self.parent:
- self.parent.update()
- else:
- oldcursor = self.canvas['cursor']
- self.canvas['cursor'] = "watch"
- self.canvas.update()
- self.canvas.delete(ALL) # XXX could be more subtle
- self.draw(7, 2)
- x0, y0, x1, y1 = self.canvas.bbox(ALL)
- self.canvas.configure(scrollregion=(0, 0, x1, y1))
- self.canvas['cursor'] = oldcursor
-
- def draw(self, x, y):
- # XXX This hard-codes too many geometry constants!
- self.x, self.y = x, y
- self.drawicon()
- self.drawtext()
- if self.state != 'expanded':
- return y+17
- # draw children
- if not self.children:
- sublist = self.item._GetSubList()
- if not sublist:
- # _IsExpandable() was mistaken; that's allowed
- return y+17
- for item in sublist:
- child = self.__class__(self.canvas, self, item)
- self.children.append(child)
- cx = x+20
- cy = y+17
- cylast = 0
- for child in self.children:
- cylast = cy
- self.canvas.create_line(x+9, cy+7, cx, cy+7, fill="gray50")
- cy = child.draw(cx, cy)
- if child.item._IsExpandable():
- if child.state == 'expanded':
- iconname = "minusnode"
- callback = child.collapse
- else:
- iconname = "plusnode"
- callback = child.expand
- image = self.geticonimage(iconname)
- id = self.canvas.create_image(x+9, cylast+7, image=image)
- # XXX This leaks bindings until canvas is deleted:
- self.canvas.tag_bind(id, "<1>", callback)
- self.canvas.tag_bind(id, "<Double-1>", lambda x: None)
- id = self.canvas.create_line(x+9, y+10, x+9, cylast+7,
- ##stipple="gray50", # XXX Seems broken in Tk 8.0.x
- fill="gray50")
- self.canvas.tag_lower(id) # XXX .lower(id) before Python 1.5.2
- return cy
-
- def drawicon(self):
- if self.selected:
- imagename = (self.item.GetSelectedIconName() or
- self.item.GetIconName() or
- "openfolder")
- else:
- imagename = self.item.GetIconName() or "folder"
- image = self.geticonimage(imagename)
- id = self.canvas.create_image(self.x, self.y, anchor="nw", image=image)
- self.image_id = id
- self.canvas.tag_bind(id, "<1>", self.select)
- self.canvas.tag_bind(id, "<Double-1>", self.flip)
-
- def drawtext(self):
- textx = self.x+20-1
- texty = self.y-1
- labeltext = self.item.GetLabelText()
- if labeltext:
- id = self.canvas.create_text(textx, texty, anchor="nw",
- text=labeltext)
- self.canvas.tag_bind(id, "<1>", self.select)
- self.canvas.tag_bind(id, "<Double-1>", self.flip)
- x0, y0, x1, y1 = self.canvas.bbox(id)
- textx = max(x1, 200) + 10
- text = self.item.GetText() or "<no text>"
- try:
- self.entry
- except AttributeError:
- pass
- else:
- self.edit_finish()
- try:
- label = self.label
- except AttributeError:
- # padding carefully selected (on Windows) to match Entry widget:
- self.label = Label(self.canvas, text=text, bd=0, padx=2, pady=2)
- theme = idleConf.GetOption('main','Theme','name')
- if self.selected:
- self.label.configure(idleConf.GetHighlight(theme, 'hilite'))
- else:
- self.label.configure(idleConf.GetHighlight(theme, 'normal'))
- id = self.canvas.create_window(textx, texty,
- anchor="nw", window=self.label)
- self.label.bind("<1>", self.select_or_edit)
- self.label.bind("<Double-1>", self.flip)
- self.text_id = id
-
- def select_or_edit(self, event=None):
- if self.selected and self.item.IsEditable():
- self.edit(event)
- else:
- self.select(event)
-
- def edit(self, event=None):
- self.entry = Entry(self.label, bd=0, highlightthickness=1, width=0)
- self.entry.insert(0, self.label['text'])
- self.entry.selection_range(0, END)
- self.entry.pack(ipadx=5)
- self.entry.focus_set()
- self.entry.bind("<Return>", self.edit_finish)
- self.entry.bind("<Escape>", self.edit_cancel)
-
- def edit_finish(self, event=None):
- try:
- entry = self.entry
- del self.entry
- except AttributeError:
- return
- text = entry.get()
- entry.destroy()
- if text and text != self.item.GetText():
- self.item.SetText(text)
- text = self.item.GetText()
- self.label['text'] = text
- self.drawtext()
- self.canvas.focus_set()
-
- def edit_cancel(self, event=None):
- try:
- entry = self.entry
- del self.entry
- except AttributeError:
- return
- entry.destroy()
- self.drawtext()
- self.canvas.focus_set()
-
-
-class TreeItem:
-
- """Abstract class representing tree items.
-
- Methods should typically be overridden, otherwise a default action
- is used.
-
- """
-
- def __init__(self):
- """Constructor. Do whatever you need to do."""
-
- def GetText(self):
- """Return text string to display."""
-
- def GetLabelText(self):
- """Return label text string to display in front of text (if any)."""
-
- expandable = None
-
- def _IsExpandable(self):
- """Do not override! Called by TreeNode."""
- if self.expandable is None:
- self.expandable = self.IsExpandable()
- return self.expandable
-
- def IsExpandable(self):
- """Return whether there are subitems."""
- return 1
-
- def _GetSubList(self):
- """Do not override! Called by TreeNode."""
- if not self.IsExpandable():
- return []
- sublist = self.GetSubList()
- if not sublist:
- self.expandable = 0
- return sublist
-
- def IsEditable(self):
- """Return whether the item's text may be edited."""
-
- def SetText(self, text):
- """Change the item's text (if it is editable)."""
-
- def GetIconName(self):
- """Return name of icon to be displayed normally."""
-
- def GetSelectedIconName(self):
- """Return name of icon to be displayed when selected."""
-
- def GetSubList(self):
- """Return list of items forming sublist."""
-
- def OnDoubleClick(self):
- """Called on a double-click on the item."""
-
-
-# Example application
-
-class FileTreeItem(TreeItem):
-
- """Example TreeItem subclass -- browse the file system."""
-
- def __init__(self, path):
- self.path = path
-
- def GetText(self):
- return os.path.basename(self.path) or self.path
-
- def IsEditable(self):
- return os.path.basename(self.path) != ""
-
- def SetText(self, text):
- newpath = os.path.dirname(self.path)
- newpath = os.path.join(newpath, text)
- if os.path.dirname(newpath) != os.path.dirname(self.path):
- return
- try:
- os.rename(self.path, newpath)
- self.path = newpath
- except os.error:
- pass
-
- def GetIconName(self):
- if not self.IsExpandable():
- return "python" # XXX wish there was a "file" icon
-
- def IsExpandable(self):
- return os.path.isdir(self.path)
-
- def GetSubList(self):
- try:
- names = os.listdir(self.path)
- except os.error:
- return []
- names.sort(lambda a, b: cmp(os.path.normcase(a), os.path.normcase(b)))
- sublist = []
- for name in names:
- item = FileTreeItem(os.path.join(self.path, name))
- sublist.append(item)
- return sublist
-
-
-# A canvas widget with scroll bars and some useful bindings
-
-class ScrolledCanvas:
- def __init__(self, master, **opts):
- if not opts.has_key('yscrollincrement'):
- opts['yscrollincrement'] = 17
- self.master = master
- self.frame = Frame(master)
- self.frame.rowconfigure(0, weight=1)
- self.frame.columnconfigure(0, weight=1)
- self.canvas = Canvas(self.frame, **opts)
- self.canvas.grid(row=0, column=0, sticky="nsew")
- self.vbar = Scrollbar(self.frame, name="vbar")
- self.vbar.grid(row=0, column=1, sticky="nse")
- self.hbar = Scrollbar(self.frame, name="hbar", orient="horizontal")
- self.hbar.grid(row=1, column=0, sticky="ews")
- self.canvas['yscrollcommand'] = self.vbar.set
- self.vbar['command'] = self.canvas.yview
- self.canvas['xscrollcommand'] = self.hbar.set
- self.hbar['command'] = self.canvas.xview
- self.canvas.bind("<Key-Prior>", self.page_up)
- self.canvas.bind("<Key-Next>", self.page_down)
- self.canvas.bind("<Key-Up>", self.unit_up)
- self.canvas.bind("<Key-Down>", self.unit_down)
- #if isinstance(master, Toplevel) or isinstance(master, Tk):
- self.canvas.bind("<Alt-Key-2>", self.zoom_height)
- self.canvas.focus_set()
- def page_up(self, event):
- self.canvas.yview_scroll(-1, "page")
- return "break"
- def page_down(self, event):
- self.canvas.yview_scroll(1, "page")
- return "break"
- def unit_up(self, event):
- self.canvas.yview_scroll(-1, "unit")
- return "break"
- def unit_down(self, event):
- self.canvas.yview_scroll(1, "unit")
- return "break"
- def zoom_height(self, event):
- ZoomHeight.zoom_height(self.master)
- return "break"
-
-
-# Testing functions
-
-def test():
- import PyShell
- root = Toplevel(PyShell.root)
- root.configure(bd=0, bg="yellow")
- root.focus_set()
- sc = ScrolledCanvas(root, bg="white", highlightthickness=0, takefocus=1)
- sc.frame.pack(expand=1, fill="both")
- item = FileTreeItem("C:/windows/desktop")
- node = TreeNode(sc.canvas, None, item)
- node.expand()
-
-def test2():
- # test w/o scrolling canvas
- root = Tk()
- root.configure(bd=0)
- canvas = Canvas(root, bg="white", highlightthickness=0)
- canvas.pack(expand=1, fill="both")
- item = FileTreeItem(os.curdir)
- node = TreeNode(canvas, None, item)
- node.update()
- canvas.focus_set()
-
-if __name__ == '__main__':
- test()
diff --git a/sys/lib/python/idlelib/UndoDelegator.py b/sys/lib/python/idlelib/UndoDelegator.py
deleted file mode 100644
index 182a1170e..000000000
--- a/sys/lib/python/idlelib/UndoDelegator.py
+++ /dev/null
@@ -1,352 +0,0 @@
-import sys
-import string
-from Tkinter import *
-from Delegator import Delegator
-
-#$ event <<redo>>
-#$ win <Control-y>
-#$ unix <Alt-z>
-
-#$ event <<undo>>
-#$ win <Control-z>
-#$ unix <Control-z>
-
-#$ event <<dump-undo-state>>
-#$ win <Control-backslash>
-#$ unix <Control-backslash>
-
-
-class UndoDelegator(Delegator):
-
- max_undo = 1000
-
- def __init__(self):
- Delegator.__init__(self)
- self.reset_undo()
-
- def setdelegate(self, delegate):
- if self.delegate is not None:
- self.unbind("<<undo>>")
- self.unbind("<<redo>>")
- self.unbind("<<dump-undo-state>>")
- Delegator.setdelegate(self, delegate)
- if delegate is not None:
- self.bind("<<undo>>", self.undo_event)
- self.bind("<<redo>>", self.redo_event)
- self.bind("<<dump-undo-state>>", self.dump_event)
-
- def dump_event(self, event):
- from pprint import pprint
- pprint(self.undolist[:self.pointer])
- print "pointer:", self.pointer,
- print "saved:", self.saved,
- print "can_merge:", self.can_merge,
- print "get_saved():", self.get_saved()
- pprint(self.undolist[self.pointer:])
- return "break"
-
- def reset_undo(self):
- self.was_saved = -1
- self.pointer = 0
- self.undolist = []
- self.undoblock = 0 # or a CommandSequence instance
- self.set_saved(1)
-
- def set_saved(self, flag):
- if flag:
- self.saved = self.pointer
- else:
- self.saved = -1
- self.can_merge = False
- self.check_saved()
-
- def get_saved(self):
- return self.saved == self.pointer
-
- saved_change_hook = None
-
- def set_saved_change_hook(self, hook):
- self.saved_change_hook = hook
-
- was_saved = -1
-
- def check_saved(self):
- is_saved = self.get_saved()
- if is_saved != self.was_saved:
- self.was_saved = is_saved
- if self.saved_change_hook:
- self.saved_change_hook()
-
- def insert(self, index, chars, tags=None):
- self.addcmd(InsertCommand(index, chars, tags))
-
- def delete(self, index1, index2=None):
- self.addcmd(DeleteCommand(index1, index2))
-
- # Clients should call undo_block_start() and undo_block_stop()
- # around a sequence of editing cmds to be treated as a unit by
- # undo & redo. Nested matching calls are OK, and the inner calls
- # then act like nops. OK too if no editing cmds, or only one
- # editing cmd, is issued in between: if no cmds, the whole
- # sequence has no effect; and if only one cmd, that cmd is entered
- # directly into the undo list, as if undo_block_xxx hadn't been
- # called. The intent of all that is to make this scheme easy
- # to use: all the client has to worry about is making sure each
- # _start() call is matched by a _stop() call.
-
- def undo_block_start(self):
- if self.undoblock == 0:
- self.undoblock = CommandSequence()
- self.undoblock.bump_depth()
-
- def undo_block_stop(self):
- if self.undoblock.bump_depth(-1) == 0:
- cmd = self.undoblock
- self.undoblock = 0
- if len(cmd) > 0:
- if len(cmd) == 1:
- # no need to wrap a single cmd
- cmd = cmd.getcmd(0)
- # this blk of cmds, or single cmd, has already
- # been done, so don't execute it again
- self.addcmd(cmd, 0)
-
- def addcmd(self, cmd, execute=True):
- if execute:
- cmd.do(self.delegate)
- if self.undoblock != 0:
- self.undoblock.append(cmd)
- return
- if self.can_merge and self.pointer > 0:
- lastcmd = self.undolist[self.pointer-1]
- if lastcmd.merge(cmd):
- return
- self.undolist[self.pointer:] = [cmd]
- if self.saved > self.pointer:
- self.saved = -1
- self.pointer = self.pointer + 1
- if len(self.undolist) > self.max_undo:
- ##print "truncating undo list"
- del self.undolist[0]
- self.pointer = self.pointer - 1
- if self.saved >= 0:
- self.saved = self.saved - 1
- self.can_merge = True
- self.check_saved()
-
- def undo_event(self, event):
- if self.pointer == 0:
- self.bell()
- return "break"
- cmd = self.undolist[self.pointer - 1]
- cmd.undo(self.delegate)
- self.pointer = self.pointer - 1
- self.can_merge = False
- self.check_saved()
- return "break"
-
- def redo_event(self, event):
- if self.pointer >= len(self.undolist):
- self.bell()
- return "break"
- cmd = self.undolist[self.pointer]
- cmd.redo(self.delegate)
- self.pointer = self.pointer + 1
- self.can_merge = False
- self.check_saved()
- return "break"
-
-
-class Command:
-
- # Base class for Undoable commands
-
- tags = None
-
- def __init__(self, index1, index2, chars, tags=None):
- self.marks_before = {}
- self.marks_after = {}
- self.index1 = index1
- self.index2 = index2
- self.chars = chars
- if tags:
- self.tags = tags
-
- def __repr__(self):
- s = self.__class__.__name__
- t = (self.index1, self.index2, self.chars, self.tags)
- if self.tags is None:
- t = t[:-1]
- return s + repr(t)
-
- def do(self, text):
- pass
-
- def redo(self, text):
- pass
-
- def undo(self, text):
- pass
-
- def merge(self, cmd):
- return 0
-
- def save_marks(self, text):
- marks = {}
- for name in text.mark_names():
- if name != "insert" and name != "current":
- marks[name] = text.index(name)
- return marks
-
- def set_marks(self, text, marks):
- for name, index in marks.items():
- text.mark_set(name, index)
-
-
-class InsertCommand(Command):
-
- # Undoable insert command
-
- def __init__(self, index1, chars, tags=None):
- Command.__init__(self, index1, None, chars, tags)
-
- def do(self, text):
- self.marks_before = self.save_marks(text)
- self.index1 = text.index(self.index1)
- if text.compare(self.index1, ">", "end-1c"):
- # Insert before the final newline
- self.index1 = text.index("end-1c")
- text.insert(self.index1, self.chars, self.tags)
- self.index2 = text.index("%s+%dc" % (self.index1, len(self.chars)))
- self.marks_after = self.save_marks(text)
- ##sys.__stderr__.write("do: %s\n" % self)
-
- def redo(self, text):
- text.mark_set('insert', self.index1)
- text.insert(self.index1, self.chars, self.tags)
- self.set_marks(text, self.marks_after)
- text.see('insert')
- ##sys.__stderr__.write("redo: %s\n" % self)
-
- def undo(self, text):
- text.mark_set('insert', self.index1)
- text.delete(self.index1, self.index2)
- self.set_marks(text, self.marks_before)
- text.see('insert')
- ##sys.__stderr__.write("undo: %s\n" % self)
-
- def merge(self, cmd):
- if self.__class__ is not cmd.__class__:
- return False
- if self.index2 != cmd.index1:
- return False
- if self.tags != cmd.tags:
- return False
- if len(cmd.chars) != 1:
- return False
- if self.chars and \
- self.classify(self.chars[-1]) != self.classify(cmd.chars):
- return False
- self.index2 = cmd.index2
- self.chars = self.chars + cmd.chars
- return True
-
- alphanumeric = string.ascii_letters + string.digits + "_"
-
- def classify(self, c):
- if c in self.alphanumeric:
- return "alphanumeric"
- if c == "\n":
- return "newline"
- return "punctuation"
-
-
-class DeleteCommand(Command):
-
- # Undoable delete command
-
- def __init__(self, index1, index2=None):
- Command.__init__(self, index1, index2, None, None)
-
- def do(self, text):
- self.marks_before = self.save_marks(text)
- self.index1 = text.index(self.index1)
- if self.index2:
- self.index2 = text.index(self.index2)
- else:
- self.index2 = text.index(self.index1 + " +1c")
- if text.compare(self.index2, ">", "end-1c"):
- # Don't delete the final newline
- self.index2 = text.index("end-1c")
- self.chars = text.get(self.index1, self.index2)
- text.delete(self.index1, self.index2)
- self.marks_after = self.save_marks(text)
- ##sys.__stderr__.write("do: %s\n" % self)
-
- def redo(self, text):
- text.mark_set('insert', self.index1)
- text.delete(self.index1, self.index2)
- self.set_marks(text, self.marks_after)
- text.see('insert')
- ##sys.__stderr__.write("redo: %s\n" % self)
-
- def undo(self, text):
- text.mark_set('insert', self.index1)
- text.insert(self.index1, self.chars)
- self.set_marks(text, self.marks_before)
- text.see('insert')
- ##sys.__stderr__.write("undo: %s\n" % self)
-
-class CommandSequence(Command):
-
- # Wrapper for a sequence of undoable cmds to be undone/redone
- # as a unit
-
- def __init__(self):
- self.cmds = []
- self.depth = 0
-
- def __repr__(self):
- s = self.__class__.__name__
- strs = []
- for cmd in self.cmds:
- strs.append(" %r" % (cmd,))
- return s + "(\n" + ",\n".join(strs) + "\n)"
-
- def __len__(self):
- return len(self.cmds)
-
- def append(self, cmd):
- self.cmds.append(cmd)
-
- def getcmd(self, i):
- return self.cmds[i]
-
- def redo(self, text):
- for cmd in self.cmds:
- cmd.redo(text)
-
- def undo(self, text):
- cmds = self.cmds[:]
- cmds.reverse()
- for cmd in cmds:
- cmd.undo(text)
-
- def bump_depth(self, incr=1):
- self.depth = self.depth + incr
- return self.depth
-
-def main():
- from Percolator import Percolator
- root = Tk()
- root.wm_protocol("WM_DELETE_WINDOW", root.quit)
- text = Text()
- text.pack()
- text.focus_set()
- p = Percolator(text)
- d = UndoDelegator()
- p.insertfilter(d)
- root.mainloop()
-
-if __name__ == "__main__":
- main()
diff --git a/sys/lib/python/idlelib/WidgetRedirector.py b/sys/lib/python/idlelib/WidgetRedirector.py
deleted file mode 100644
index df60cea4f..000000000
--- a/sys/lib/python/idlelib/WidgetRedirector.py
+++ /dev/null
@@ -1,92 +0,0 @@
-from Tkinter import *
-
-
-class WidgetRedirector:
-
- """Support for redirecting arbitrary widget subcommands."""
-
- def __init__(self, widget):
- self.dict = {}
- self.widget = widget
- self.tk = tk = widget.tk
- w = widget._w
- self.orig = w + "_orig"
- tk.call("rename", w, self.orig)
- tk.createcommand(w, self.dispatch)
-
- def __repr__(self):
- return "WidgetRedirector(%s<%s>)" % (self.widget.__class__.__name__,
- self.widget._w)
-
- def close(self):
- for name in self.dict.keys():
- self.unregister(name)
- widget = self.widget; del self.widget
- orig = self.orig; del self.orig
- tk = widget.tk
- w = widget._w
- tk.deletecommand(w)
- tk.call("rename", orig, w)
-
- def register(self, name, function):
- if self.dict.has_key(name):
- previous = dict[name]
- else:
- previous = OriginalCommand(self, name)
- self.dict[name] = function
- setattr(self.widget, name, function)
- return previous
-
- def unregister(self, name):
- if self.dict.has_key(name):
- function = self.dict[name]
- del self.dict[name]
- if hasattr(self.widget, name):
- delattr(self.widget, name)
- return function
- else:
- return None
-
- def dispatch(self, cmd, *args):
- m = self.dict.get(cmd)
- try:
- if m:
- return m(*args)
- else:
- return self.tk.call((self.orig, cmd) + args)
- except TclError:
- return ""
-
-
-class OriginalCommand:
-
- def __init__(self, redir, name):
- self.redir = redir
- self.name = name
- self.tk = redir.tk
- self.orig = redir.orig
- self.tk_call = self.tk.call
- self.orig_and_name = (self.orig, self.name)
-
- def __repr__(self):
- return "OriginalCommand(%r, %r)" % (self.redir, self.name)
-
- def __call__(self, *args):
- return self.tk_call(self.orig_and_name + args)
-
-
-def main():
- root = Tk()
- text = Text()
- text.pack()
- text.focus_set()
- redir = WidgetRedirector(text)
- global orig_insert
- def my_insert(*args):
- print "insert", args
- orig_insert(*args)
- orig_insert = redir.register("insert", my_insert)
- root.mainloop()
-
-if __name__ == "__main__":
- main()
diff --git a/sys/lib/python/idlelib/WindowList.py b/sys/lib/python/idlelib/WindowList.py
deleted file mode 100644
index 658502b20..000000000
--- a/sys/lib/python/idlelib/WindowList.py
+++ /dev/null
@@ -1,90 +0,0 @@
-from Tkinter import *
-
-class WindowList:
-
- def __init__(self):
- self.dict = {}
- self.callbacks = []
-
- def add(self, window):
- window.after_idle(self.call_callbacks)
- self.dict[str(window)] = window
-
- def delete(self, window):
- try:
- del self.dict[str(window)]
- except KeyError:
- # Sometimes, destroy() is called twice
- pass
- self.call_callbacks()
-
- def add_windows_to_menu(self, menu):
- list = []
- for key in self.dict.keys():
- window = self.dict[key]
- try:
- title = window.get_title()
- except TclError:
- continue
- list.append((title, window))
- list.sort()
- for title, window in list:
- menu.add_command(label=title, command=window.wakeup)
-
- def register_callback(self, callback):
- self.callbacks.append(callback)
-
- def unregister_callback(self, callback):
- try:
- self.callbacks.remove(callback)
- except ValueError:
- pass
-
- def call_callbacks(self):
- for callback in self.callbacks:
- try:
- callback()
- except:
- print "warning: callback failed in WindowList", \
- sys.exc_type, ":", sys.exc_value
-
-registry = WindowList()
-
-add_windows_to_menu = registry.add_windows_to_menu
-register_callback = registry.register_callback
-unregister_callback = registry.unregister_callback
-
-
-class ListedToplevel(Toplevel):
-
- def __init__(self, master, **kw):
- Toplevel.__init__(self, master, kw)
- registry.add(self)
- self.focused_widget = self
-
- def destroy(self):
- registry.delete(self)
- Toplevel.destroy(self)
- # If this is Idle's last window then quit the mainloop
- # (Needed for clean exit on Windows 98)
- if not registry.dict:
- self.quit()
-
- def update_windowlist_registry(self, window):
- registry.call_callbacks()
-
- def get_title(self):
- # Subclass can override
- return self.wm_title()
-
- def wakeup(self):
- try:
- if self.wm_state() == "iconic":
- self.wm_withdraw()
- self.wm_deiconify()
- self.tkraise()
- self.focused_widget.focus_set()
- except TclError:
- # This can happen when the window menu was torn off.
- # Simply ignore it.
- pass
diff --git a/sys/lib/python/idlelib/ZoomHeight.py b/sys/lib/python/idlelib/ZoomHeight.py
deleted file mode 100644
index 83ca3a697..000000000
--- a/sys/lib/python/idlelib/ZoomHeight.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Sample extension: zoom a window to maximum height
-
-import re
-import sys
-import macosxSupport
-
-class ZoomHeight:
-
- menudefs = [
- ('windows', [
- ('_Zoom Height', '<<zoom-height>>'),
- ])
- ]
-
- def __init__(self, editwin):
- self.editwin = editwin
-
- def zoom_height_event(self, event):
- top = self.editwin.top
- zoom_height(top)
-
-def zoom_height(top):
- geom = top.wm_geometry()
- m = re.match(r"(\d+)x(\d+)\+(-?\d+)\+(-?\d+)", geom)
- if not m:
- top.bell()
- return
- width, height, x, y = map(int, m.groups())
- newheight = top.winfo_screenheight()
- if sys.platform == 'win32':
- newy = 0
- newheight = newheight - 72
-
- elif macosxSupport.runningAsOSXApp():
- # The '88' below is a magic number that avoids placing the bottom
- # of the window below the panel on my machine. I don't know how
- # to calculate the correct value for this with tkinter.
- newy = 22
- newheight = newheight - newy - 88
-
- else:
- #newy = 24
- newy = 0
- #newheight = newheight - 96
- newheight = newheight - 88
- if height >= newheight:
- newgeom = ""
- else:
- newgeom = "%dx%d+%d+%d" % (width, newheight, x, newy)
- top.wm_geometry(newgeom)
diff --git a/sys/lib/python/idlelib/__init__.py b/sys/lib/python/idlelib/__init__.py
deleted file mode 100644
index 7a83ddea7..000000000
--- a/sys/lib/python/idlelib/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-# Dummy file to make this a package.
diff --git a/sys/lib/python/idlelib/aboutDialog.py b/sys/lib/python/idlelib/aboutDialog.py
deleted file mode 100644
index c1210612e..000000000
--- a/sys/lib/python/idlelib/aboutDialog.py
+++ /dev/null
@@ -1,163 +0,0 @@
-"""About Dialog for IDLE
-
-"""
-
-from Tkinter import *
-import string, os
-import textView
-import idlever
-
-class AboutDialog(Toplevel):
- """Modal about dialog for idle
-
- """
- def __init__(self,parent,title):
- Toplevel.__init__(self, parent)
- self.configure(borderwidth=5)
- self.geometry("+%d+%d" % (parent.winfo_rootx()+30,
- parent.winfo_rooty()+30))
- self.bg = "#707070"
- self.fg = "#ffffff"
- self.CreateWidgets()
- self.resizable(height=FALSE, width=FALSE)
- self.title(title)
- self.transient(parent)
- self.grab_set()
- self.protocol("WM_DELETE_WINDOW", self.Ok)
- self.parent = parent
- self.buttonOk.focus_set()
- self.bind('<Return>',self.Ok) #dismiss dialog
- self.bind('<Escape>',self.Ok) #dismiss dialog
- self.wait_window()
-
- def CreateWidgets(self):
- frameMain = Frame(self, borderwidth=2, relief=SUNKEN)
- frameButtons = Frame(self)
- frameButtons.pack(side=BOTTOM, fill=X)
- frameMain.pack(side=TOP, expand=TRUE, fill=BOTH)
- self.buttonOk = Button(frameButtons, text='Close',
- command=self.Ok)
- self.buttonOk.pack(padx=5, pady=5)
- #self.picture = Image('photo', data=self.pictureData)
- frameBg = Frame(frameMain, bg=self.bg)
- frameBg.pack(expand=TRUE, fill=BOTH)
- labelTitle = Label(frameBg, text='IDLE', fg=self.fg, bg=self.bg,
- font=('courier', 24, 'bold'))
- labelTitle.grid(row=0, column=0, sticky=W, padx=10, pady=10)
- #labelPicture = Label(frameBg, text='[picture]')
- #image=self.picture, bg=self.bg)
- #labelPicture.grid(row=1, column=1, sticky=W, rowspan=2,
- # padx=0, pady=3)
- byline = "Python's Integrated DeveLopment Environment" + 5*'\n'
- labelDesc = Label(frameBg, text=byline, justify=LEFT,
- fg=self.fg, bg=self.bg)
- labelDesc.grid(row=2, column=0, sticky=W, columnspan=3, padx=10, pady=5)
- labelEmail = Label(frameBg, text='email: idle-dev@python.org',
- justify=LEFT, fg=self.fg, bg=self.bg)
- labelEmail.grid(row=6, column=0, columnspan=2,
- sticky=W, padx=10, pady=0)
- labelWWW = Label(frameBg, text='www: http://www.python.org/idle/',
- justify=LEFT, fg=self.fg, bg=self.bg)
- labelWWW.grid(row=7, column=0, columnspan=2, sticky=W, padx=10, pady=0)
- Frame(frameBg, borderwidth=1, relief=SUNKEN,
- height=2, bg=self.bg).grid(row=8, column=0, sticky=EW,
- columnspan=3, padx=5, pady=5)
- labelPythonVer = Label(frameBg, text='Python version: ' + \
- sys.version.split()[0], fg=self.fg, bg=self.bg)
- labelPythonVer.grid(row=9, column=0, sticky=W, padx=10, pady=0)
- # handle weird tk version num in windoze python >= 1.6 (?!?)
- tkVer = repr(TkVersion).split('.')
- tkVer[len(tkVer)-1] = str('%.3g' % (float('.'+tkVer[len(tkVer)-1])))[2:]
- if tkVer[len(tkVer)-1] == '':
- tkVer[len(tkVer)-1] = '0'
- tkVer = string.join(tkVer,'.')
- labelTkVer = Label(frameBg, text='Tk version: '+
- tkVer, fg=self.fg, bg=self.bg)
- labelTkVer.grid(row=9, column=1, sticky=W, padx=2, pady=0)
- py_button_f = Frame(frameBg, bg=self.bg)
- py_button_f.grid(row=10, column=0, columnspan=2, sticky=NSEW)
- buttonLicense = Button(py_button_f, text='License', width=8,
- highlightbackground=self.bg,
- command=self.ShowLicense)
- buttonLicense.pack(side=LEFT, padx=10, pady=10)
- buttonCopyright = Button(py_button_f, text='Copyright', width=8,
- highlightbackground=self.bg,
- command=self.ShowCopyright)
- buttonCopyright.pack(side=LEFT, padx=10, pady=10)
- buttonCredits = Button(py_button_f, text='Credits', width=8,
- highlightbackground=self.bg,
- command=self.ShowPythonCredits)
- buttonCredits.pack(side=LEFT, padx=10, pady=10)
- Frame(frameBg, borderwidth=1, relief=SUNKEN,
- height=2, bg=self.bg).grid(row=11, column=0, sticky=EW,
- columnspan=3, padx=5, pady=5)
- idle_v = Label(frameBg, text='IDLE version: ' + idlever.IDLE_VERSION,
- fg=self.fg, bg=self.bg)
- idle_v.grid(row=12, column=0, sticky=W, padx=10, pady=0)
- idle_button_f = Frame(frameBg, bg=self.bg)
- idle_button_f.grid(row=13, column=0, columnspan=3, sticky=NSEW)
- idle_about_b = Button(idle_button_f, text='README', width=8,
- highlightbackground=self.bg,
- command=self.ShowIDLEAbout)
- idle_about_b.pack(side=LEFT, padx=10, pady=10)
- idle_news_b = Button(idle_button_f, text='NEWS', width=8,
- highlightbackground=self.bg,
- command=self.ShowIDLENEWS)
- idle_news_b.pack(side=LEFT, padx=10, pady=10)
- idle_credits_b = Button(idle_button_f, text='Credits', width=8,
- highlightbackground=self.bg,
- command=self.ShowIDLECredits)
- idle_credits_b.pack(side=LEFT, padx=10, pady=10)
-
- def ShowLicense(self):
- self.display_printer_text(license, 'About - License')
-
- def ShowCopyright(self):
- self.display_printer_text(copyright, 'About - Copyright')
-
- def ShowPythonCredits(self):
- self.display_printer_text(credits, 'About - Python Credits')
-
- def ShowIDLECredits(self):
- self.ViewFile('About - Credits','CREDITS.txt', 'iso-8859-1')
-
- def ShowIDLEAbout(self):
- self.ViewFile('About - Readme', 'README.txt')
-
- def ShowIDLENEWS(self):
- self.ViewFile('About - NEWS', 'NEWS.txt')
-
- def display_printer_text(self, printer, title):
- printer._Printer__setup()
- data = '\n'.join(printer._Printer__lines)
- textView.TextViewer(self, title, None, data)
-
- def ViewFile(self, viewTitle, viewFile, encoding=None):
- fn = os.path.join(os.path.abspath(os.path.dirname(__file__)), viewFile)
- if encoding:
- import codecs
- try:
- textFile = codecs.open(fn, 'r')
- except IOError:
- import tkMessageBox
- tkMessageBox.showerror(title='File Load Error',
- message='Unable to load file %r .' % (fn,),
- parent=self)
- return
- else:
- data = textFile.read()
- else:
- data = None
- textView.TextViewer(self, viewTitle, fn, data=data)
-
- def Ok(self, event=None):
- self.destroy()
-
-if __name__ == '__main__':
- # test the dialog
- root = Tk()
- def run():
- import aboutDialog
- aboutDialog.AboutDialog(root, 'About')
- Button(root, text='Dialog', command=run).pack()
- root.mainloop()
diff --git a/sys/lib/python/idlelib/config-extensions.def b/sys/lib/python/idlelib/config-extensions.def
deleted file mode 100644
index 2d5cf6822..000000000
--- a/sys/lib/python/idlelib/config-extensions.def
+++ /dev/null
@@ -1,88 +0,0 @@
-# config-extensions.def
-#
-# IDLE reads several config files to determine user preferences. This
-# file is the default configuration file for IDLE extensions settings.
-#
-# Each extension must have at least one section, named after the extension
-# module. This section must contain an 'enable' item (=1 to enable the
-# extension, =0 to disable it), it may contain 'enable_editor' or 'enable_shell'
-# items, to apply it only to editor/shell windows, and may also contain any
-# other general configuration items for the extension.
-#
-# Each extension must define at least one section named ExtensionName_bindings
-# or ExtensionName_cfgBindings. If present, ExtensionName_bindings defines
-# virtual event bindings for the extension that are not user re-configurable.
-# If present, ExtensionName_cfgBindings defines virtual event bindings for the
-# extension that may be sensibly re-configured.
-#
-# If there are no keybindings for a menus' virtual events, include lines like
-# <<toggle-code-context>>= (See [CodeContext], below.)
-#
-# Currently it is necessary to manually modify this file to change extension
-# key bindings and default values. To customize, create
-# ~/.idlerc/config-extensions.cfg and append the appropriate customized
-# section(s). Those sections will override the defaults in this file.
-#
-# Note: If a keybinding is already in use when the extension is
-# loaded, the extension's virtual event's keybinding will be set to ''.
-#
-# See config-keys.def for notes on specifying keys and extend.txt for
-# information on creating IDLE extensions.
-
-[FormatParagraph]
-enable=1
-[FormatParagraph_cfgBindings]
-format-paragraph=<Alt-Key-q>
-
-[AutoExpand]
-enable=1
-[AutoExpand_cfgBindings]
-expand-word=<Alt-Key-slash>
-
-[ZoomHeight]
-enable=1
-[ZoomHeight_cfgBindings]
-zoom-height=<Alt-Key-2>
-
-[ScriptBinding]
-enable=1
-[ScriptBinding_cfgBindings]
-run-module=<Key-F5>
-check-module=<Alt-Key-x>
-
-[CallTips]
-enable=1
-[CallTips_cfgBindings]
-force-open-calltip=<Control-Key-backslash>
-[CallTips_bindings]
-try-open-calltip=<KeyRelease-parenleft>
-refresh-calltip=<KeyRelease-parenright> <KeyRelease-0>
-
-[ParenMatch]
-enable=1
-style= expression
-flash-delay= 500
-bell= 1
-[ParenMatch_cfgBindings]
-flash-paren=<Control-Key-0>
-[ParenMatch_bindings]
-paren-closed=<KeyRelease-parenright> <KeyRelease-bracketright> <KeyRelease-braceright>
-
-[AutoComplete]
-enable=1
-popupwait=2000
-[AutoComplete_cfgBindings]
-force-open-completions=<Control-Key-space>
-[AutoComplete_bindings]
-autocomplete=<Key-Tab>
-try-open-completions=<KeyRelease-period> <KeyRelease-slash> <KeyRelease-backslash>
-
-[CodeContext]
-enable=1
-enable_shell=0
-numlines=3
-visible=0
-bgcolor=LightGray
-fgcolor=Black
-[CodeContext_bindings]
-toggle-code-context=
diff --git a/sys/lib/python/idlelib/config-highlight.def b/sys/lib/python/idlelib/config-highlight.def
deleted file mode 100644
index 7d20f7824..000000000
--- a/sys/lib/python/idlelib/config-highlight.def
+++ /dev/null
@@ -1,64 +0,0 @@
-# IDLE reads several config files to determine user preferences. This
-# file is the default config file for idle highlight theme settings.
-
-[IDLE Classic]
-normal-foreground= #000000
-normal-background= #ffffff
-keyword-foreground= #ff7700
-keyword-background= #ffffff
-builtin-foreground= #900090
-builtin-background= #ffffff
-comment-foreground= #dd0000
-comment-background= #ffffff
-string-foreground= #00aa00
-string-background= #ffffff
-definition-foreground= #0000ff
-definition-background= #ffffff
-hilite-foreground= #000000
-hilite-background= gray
-break-foreground= black
-break-background= #ffff55
-hit-foreground= #ffffff
-hit-background= #000000
-error-foreground= #000000
-error-background= #ff7777
-#cursor (only foreground can be set, restart IDLE)
-cursor-foreground= black
-#shell window
-stdout-foreground= blue
-stdout-background= #ffffff
-stderr-foreground= red
-stderr-background= #ffffff
-console-foreground= #770000
-console-background= #ffffff
-
-[IDLE New]
-normal-foreground= #000000
-normal-background= #ffffff
-keyword-foreground= #ff7700
-keyword-background= #ffffff
-builtin-foreground= #900090
-builtin-background= #ffffff
-comment-foreground= #dd0000
-comment-background= #ffffff
-string-foreground= #00aa00
-string-background= #ffffff
-definition-foreground= #0000ff
-definition-background= #ffffff
-hilite-foreground= #000000
-hilite-background= gray
-break-foreground= black
-break-background= #ffff55
-hit-foreground= #ffffff
-hit-background= #000000
-error-foreground= #000000
-error-background= #ff7777
-#cursor (only foreground can be set, restart IDLE)
-cursor-foreground= black
-#shell window
-stdout-foreground= blue
-stdout-background= #ffffff
-stderr-foreground= red
-stderr-background= #ffffff
-console-foreground= #770000
-console-background= #ffffff
diff --git a/sys/lib/python/idlelib/config-keys.def b/sys/lib/python/idlelib/config-keys.def
deleted file mode 100644
index fb0aaf4dc..000000000
--- a/sys/lib/python/idlelib/config-keys.def
+++ /dev/null
@@ -1,214 +0,0 @@
-# IDLE reads several config files to determine user preferences. This
-# file is the default config file for idle key binding settings.
-# Where multiple keys are specified for an action: if they are separated
-# by a space (eg. action=<key1> <key2>) then the keys are alternatives, if
-# there is no space (eg. action=<key1><key2>) then the keys comprise a
-# single 'emacs style' multi-keystoke binding. The tk event specifier 'Key'
-# is used in all cases, for consistency in auto key conflict checking in the
-# configuration gui.
-
-[IDLE Classic Windows]
-copy=<Control-Key-c> <Control-Key-C>
-cut=<Control-Key-x> <Control-Key-X>
-paste=<Control-Key-v> <Control-Key-V>
-beginning-of-line= <Key-Home>
-center-insert=<Control-Key-l> <Control-Key-L>
-close-all-windows=<Control-Key-q>
-close-window=<Alt-Key-F4> <Meta-Key-F4>
-do-nothing=<Control-Key-F12>
-end-of-file=<Control-Key-d> <Control-Key-D>
-python-docs=<Key-F1>
-python-context-help=<Shift-Key-F1>
-history-next=<Alt-Key-n> <Meta-Key-n>
-history-previous=<Alt-Key-p> <Meta-Key-p>
-interrupt-execution=<Control-Key-c> <Control-Key-C>
-view-restart=<Key-F6>
-restart-shell=<Control-Key-F6>
-open-class-browser=<Alt-Key-c> <Meta-Key-c> <Alt-Key-C>
-open-module=<Alt-Key-m> <Meta-Key-m> <Alt-Key-M>
-open-new-window=<Control-Key-n> <Control-Key-N>
-open-window-from-file=<Control-Key-o> <Control-Key-O>
-plain-newline-and-indent=<Control-Key-j> <Control-Key-J>
-print-window=<Control-Key-p> <Control-Key-P>
-redo=<Control-Shift-Key-Z>
-remove-selection=<Key-Escape>
-save-copy-of-window-as-file=<Alt-Shift-Key-S>
-save-window-as-file=<Control-Shift-Key-S>
-save-window=<Control-Key-s>
-select-all=<Control-Key-a>
-toggle-auto-coloring=<Control-Key-slash>
-undo=<Control-Key-z> <Control-Key-Z>
-find=<Control-Key-f> <Control-Key-F>
-find-again=<Control-Key-g> <Key-F3>
-find-in-files=<Alt-Key-F3> <Meta-Key-F3>
-find-selection=<Control-Key-F3>
-replace=<Control-Key-h> <Control-Key-H>
-goto-line=<Alt-Key-g> <Meta-Key-g>
-smart-backspace=<Key-BackSpace>
-newline-and-indent=<Key-Return> <Key-KP_Enter>
-smart-indent=<Key-Tab>
-indent-region=<Control-Key-bracketright>
-dedent-region=<Control-Key-bracketleft>
-comment-region=<Alt-Key-3> <Meta-Key-3>
-uncomment-region=<Alt-Key-4> <Meta-Key-4>
-tabify-region=<Alt-Key-5> <Meta-Key-5>
-untabify-region=<Alt-Key-6> <Meta-Key-6>
-toggle-tabs=<Alt-Key-t> <Meta-Key-t> <Alt-Key-T>
-change-indentwidth=<Alt-Key-u> <Meta-Key-u> <Alt-Key-U>
-del-word-left=<Control-Key-BackSpace>
-del-word-right=<Control-Key-Delete>
-
-[IDLE Classic Unix]
-copy=<Alt-Key-w> <Meta-Key-w>
-cut=<Control-Key-w>
-paste=<Control-Key-y>
-beginning-of-line=<Control-Key-a> <Key-Home>
-center-insert=<Control-Key-l>
-close-all-windows=<Control-Key-x><Control-Key-c>
-close-window=<Control-Key-x><Control-Key-0>
-do-nothing=<Control-Key-x>
-end-of-file=<Control-Key-d>
-history-next=<Alt-Key-n> <Meta-Key-n>
-history-previous=<Alt-Key-p> <Meta-Key-p>
-interrupt-execution=<Control-Key-c>
-view-restart=<Key-F6>
-restart-shell=<Control-Key-F6>
-open-class-browser=<Control-Key-x><Control-Key-b>
-open-module=<Control-Key-x><Control-Key-m>
-open-new-window=<Control-Key-x><Control-Key-n>
-open-window-from-file=<Control-Key-x><Control-Key-f>
-plain-newline-and-indent=<Control-Key-j>
-print-window=<Control-x><Control-Key-p>
-python-docs=<Control-Key-h>
-python-context-help=<Control-Shift-Key-H>
-redo=<Alt-Key-z> <Meta-Key-z>
-remove-selection=<Key-Escape>
-save-copy-of-window-as-file=<Control-Key-x><Control-Key-y>
-save-window-as-file=<Control-Key-x><Control-Key-w>
-save-window=<Control-Key-x><Control-Key-s>
-select-all=<Alt-Key-a> <Meta-Key-a>
-toggle-auto-coloring=<Control-Key-slash>
-undo=<Control-Key-z>
-find=<Control-Key-u><Control-Key-u><Control-Key-s>
-find-again=<Control-Key-u><Control-Key-s>
-find-in-files=<Alt-Key-s> <Meta-Key-s>
-find-selection=<Control-Key-s>
-replace=<Control-Key-r>
-goto-line=<Alt-Key-g> <Meta-Key-g>
-smart-backspace=<Key-BackSpace>
-newline-and-indent=<Key-Return> <Key-KP_Enter>
-smart-indent=<Key-Tab>
-indent-region=<Control-Key-bracketright>
-dedent-region=<Control-Key-bracketleft>
-comment-region=<Alt-Key-3>
-uncomment-region=<Alt-Key-4>
-tabify-region=<Alt-Key-5>
-untabify-region=<Alt-Key-6>
-toggle-tabs=<Alt-Key-t>
-change-indentwidth=<Alt-Key-u>
-del-word-left=<Alt-Key-BackSpace>
-del-word-right=<Alt-Key-d>
-
-[IDLE Classic Mac]
-copy=<Command-Key-c>
-cut=<Command-Key-x>
-paste=<Command-Key-v>
-beginning-of-line= <Key-Home>
-center-insert=<Control-Key-l>
-close-all-windows=<Command-Key-q>
-close-window=<Command-Key-w>
-do-nothing=<Control-Key-F12>
-end-of-file=<Control-Key-d>
-python-docs=<Key-F1>
-python-context-help=<Shift-Key-F1>
-history-next=<Control-Key-n>
-history-previous=<Control-Key-p>
-interrupt-execution=<Control-Key-c>
-view-restart=<Key-F6>
-restart-shell=<Control-Key-F6>
-open-class-browser=<Command-Key-b>
-open-module=<Command-Key-m>
-open-new-window=<Command-Key-n>
-open-window-from-file=<Command-Key-o>
-plain-newline-and-indent=<Control-Key-j>
-print-window=<Command-Key-p>
-redo=<Shift-Command-Key-Z>
-remove-selection=<Key-Escape>
-save-window-as-file=<Shift-Command-Key-S>
-save-window=<Command-Key-s>
-save-copy-of-window-as-file=<Option-Command-Key-s>
-select-all=<Command-Key-a>
-toggle-auto-coloring=<Control-Key-slash>
-undo=<Command-Key-z>
-find=<Command-Key-f>
-find-again=<Command-Key-g> <Key-F3>
-find-in-files=<Command-Key-F3>
-find-selection=<Shift-Command-Key-F3>
-replace=<Command-Key-r>
-goto-line=<Command-Key-j>
-smart-backspace=<Key-BackSpace>
-newline-and-indent=<Key-Return> <Key-KP_Enter>
-smart-indent=<Key-Tab>
-indent-region=<Command-Key-bracketright>
-dedent-region=<Command-Key-bracketleft>
-comment-region=<Control-Key-3>
-uncomment-region=<Control-Key-4>
-tabify-region=<Control-Key-5>
-untabify-region=<Control-Key-6>
-toggle-tabs=<Control-Key-t>
-change-indentwidth=<Control-Key-u>
-del-word-left=<Control-Key-BackSpace>
-del-word-right=<Control-Key-Delete>
-
-[IDLE Classic OSX]
-toggle-tabs = <Control-Key-t>
-interrupt-execution = <Control-Key-c>
-untabify-region = <Control-Key-6>
-remove-selection = <Key-Escape>
-print-window = <Command-Key-p>
-replace = <Command-Key-r>
-goto-line = <Command-Key-j>
-plain-newline-and-indent = <Control-Key-j>
-history-previous = <Control-Key-p>
-beginning-of-line = <Control-Key-Left>
-end-of-line = <Control-Key-Right>
-comment-region = <Control-Key-3>
-redo = <Shift-Command-Key-Z>
-close-window = <Command-Key-w>
-restart-shell = <Control-Key-F6>
-save-window-as-file = <Command-Key-S>
-close-all-windows = <Command-Key-q>
-view-restart = <Key-F6>
-tabify-region = <Control-Key-5>
-find-again = <Command-Key-g> <Key-F3>
-find = <Command-Key-f>
-toggle-auto-coloring = <Control-Key-slash>
-select-all = <Command-Key-a>
-smart-backspace = <Key-BackSpace>
-change-indentwidth = <Control-Key-u>
-do-nothing = <Control-Key-F12>
-smart-indent = <Key-Tab>
-center-insert = <Control-Key-l>
-history-next = <Control-Key-n>
-del-word-right = <Option-Key-Delete>
-undo = <Command-Key-z>
-save-window = <Command-Key-s>
-uncomment-region = <Control-Key-4>
-cut = <Command-Key-x>
-find-in-files = <Command-Key-F3>
-dedent-region = <Command-Key-bracketleft>
-copy = <Command-Key-c>
-paste = <Command-Key-v>
-indent-region = <Command-Key-bracketright>
-del-word-left = <Option-Key-BackSpace> <Option-Command-Key-BackSpace>
-newline-and-indent = <Key-Return> <Key-KP_Enter>
-end-of-file = <Control-Key-d>
-open-class-browser = <Command-Key-b>
-open-new-window = <Command-Key-n>
-open-module = <Command-Key-m>
-find-selection = <Shift-Command-Key-F3>
-python-context-help = <Shift-Key-F1>
-save-copy-of-window-as-file = <Shift-Command-Key-s>
-open-window-from-file = <Command-Key-o>
-python-docs = <Key-F1>
-
diff --git a/sys/lib/python/idlelib/config-main.def b/sys/lib/python/idlelib/config-main.def
deleted file mode 100644
index 5ddd098de..000000000
--- a/sys/lib/python/idlelib/config-main.def
+++ /dev/null
@@ -1,79 +0,0 @@
-# IDLE reads several config files to determine user preferences. This
-# file is the default config file for general idle settings.
-#
-# When IDLE starts, it will look in
-# the following two sets of files, in order:
-#
-# default configuration
-# ---------------------
-# config-main.def the default general config file
-# config-extensions.def the default extension config file
-# config-highlight.def the default highlighting config file
-# config-keys.def the default keybinding config file
-#
-# user configuration
-# -------------------
-# ~/.idlerc/config-main.cfg the user general config file
-# ~/.idlerc/config-extensions.cfg the user extension config file
-# ~/.idlerc/config-highlight.cfg the user highlighting config file
-# ~/.idlerc/config-keys.cfg the user keybinding config file
-#
-# On Windows2000 and Windows XP the .idlerc directory is at
-# Documents and Settings\<username>\.idlerc
-#
-# On Windows98 it is at c:\.idlerc
-#
-# Any options the user saves through the config dialog will be saved to
-# the relevant user config file. Reverting any general setting to the
-# default causes that entry to be wiped from the user file and re-read
-# from the default file. User highlighting themes or keybinding sets are
-# retained unless specifically deleted within the config dialog. Choosing
-# one of the default themes or keysets just applies the relevant settings
-# from the default file.
-#
-# Additional help sources are listed in the [HelpFiles] section and must be
-# viewable by a web browser (or the Windows Help viewer in the case of .chm
-# files). These sources will be listed on the Help menu. The pattern is
-# <sequence_number = menu item;/path/to/help/source>
-# You can't use a semi-colon in a menu item or path. The path will be platform
-# specific because of path separators, drive specs etc.
-#
-# It is best to use the Configuration GUI to set up additional help sources!
-# Example:
-#1 = My Extra Help Source;/usr/share/doc/foo/index.html
-#2 = Another Help Source;/path/to/another.pdf
-
-[General]
-editor-on-startup= 0
-autosave= 0
-print-command-posix=lpr %s
-print-command-win=start /min notepad /p %s
-delete-exitfunc= 1
-
-[EditorWindow]
-width= 80
-height= 40
-font= courier
-font-size= 10
-font-bold= 0
-encoding= none
-
-[FormatParagraph]
-paragraph=70
-
-[Indent]
-use-spaces= 1
-num-spaces= 4
-
-[Theme]
-default= 1
-name= IDLE Classic
-
-[Keys]
-default= 1
-name= IDLE Classic Windows
-
-[History]
-cyclic=1
-
-[HelpFiles]
diff --git a/sys/lib/python/idlelib/configDialog.py b/sys/lib/python/idlelib/configDialog.py
deleted file mode 100644
index 2d8835c2a..000000000
--- a/sys/lib/python/idlelib/configDialog.py
+++ /dev/null
@@ -1,1147 +0,0 @@
-"""IDLE Configuration Dialog: support user customization of IDLE by GUI
-
-Customize font faces, sizes, and colorization attributes. Set indentation
-defaults. Customize keybindings. Colorization and keybindings can be
-saved as user defined sets. Select startup options including shell/editor
-and default window size. Define additional help sources.
-
-Note that tab width in IDLE is currently fixed at eight due to Tk issues.
-Refer to comments in EditorWindow autoindent code for details.
-
-"""
-from Tkinter import *
-import tkMessageBox, tkColorChooser, tkFont
-import string, copy
-
-from configHandler import idleConf
-from dynOptionMenuWidget import DynOptionMenu
-from tabpage import TabPageSet
-from keybindingDialog import GetKeysDialog
-from configSectionNameDialog import GetCfgSectionNameDialog
-from configHelpSourceEdit import GetHelpSourceDialog
-
-class ConfigDialog(Toplevel):
-
- def __init__(self,parent,title):
- Toplevel.__init__(self, parent)
- self.configure(borderwidth=5)
- self.geometry("+%d+%d" % (parent.winfo_rootx()+20,
- parent.winfo_rooty()+30))
- #Theme Elements. Each theme element key is its display name.
- #The first value of the tuple is the sample area tag name.
- #The second value is the display name list sort index.
- self.themeElements={'Normal Text':('normal','00'),
- 'Python Keywords':('keyword','01'),
- 'Python Definitions':('definition','02'),
- 'Python Builtins':('builtin', '03'),
- 'Python Comments':('comment','04'),
- 'Python Strings':('string','05'),
- 'Selected Text':('hilite','06'),
- 'Found Text':('hit','07'),
- 'Cursor':('cursor','08'),
- 'Error Text':('error','09'),
- 'Shell Normal Text':('console','10'),
- 'Shell Stdout Text':('stdout','11'),
- 'Shell Stderr Text':('stderr','12'),
- }
- self.ResetChangedItems() #load initial values in changed items dict
- self.CreateWidgets()
- self.resizable(height=FALSE,width=FALSE)
- self.transient(parent)
- self.grab_set()
- self.protocol("WM_DELETE_WINDOW", self.Cancel)
- self.parent = parent
- self.tabPages.focus_set()
- #key bindings for this dialog
- #self.bind('<Escape>',self.Cancel) #dismiss dialog, no save
- #self.bind('<Alt-a>',self.Apply) #apply changes, save
- #self.bind('<F1>',self.Help) #context help
- self.LoadConfigs()
- self.AttachVarCallbacks() #avoid callbacks during LoadConfigs
- self.wait_window()
-
- def CreateWidgets(self):
- self.tabPages = TabPageSet(self,
- pageNames=['Fonts/Tabs','Highlighting','Keys','General'])
- self.tabPages.ChangePage()#activates default (first) page
- frameActionButtons = Frame(self)
- #action buttons
- self.buttonHelp = Button(frameActionButtons,text='Help',
- command=self.Help,takefocus=FALSE)
- self.buttonOk = Button(frameActionButtons,text='Ok',
- command=self.Ok,takefocus=FALSE)
- self.buttonApply = Button(frameActionButtons,text='Apply',
- command=self.Apply,takefocus=FALSE)
- self.buttonCancel = Button(frameActionButtons,text='Cancel',
- command=self.Cancel,takefocus=FALSE)
- self.CreatePageFontTab()
- self.CreatePageHighlight()
- self.CreatePageKeys()
- self.CreatePageGeneral()
- self.buttonHelp.pack(side=RIGHT,padx=5,pady=5)
- self.buttonOk.pack(side=LEFT,padx=5,pady=5)
- self.buttonApply.pack(side=LEFT,padx=5,pady=5)
- self.buttonCancel.pack(side=LEFT,padx=5,pady=5)
- frameActionButtons.pack(side=BOTTOM)
- self.tabPages.pack(side=TOP,expand=TRUE,fill=BOTH)
-
- def CreatePageFontTab(self):
- #tkVars
- self.fontSize=StringVar(self)
- self.fontBold=BooleanVar(self)
- self.fontName=StringVar(self)
- self.spaceNum=IntVar(self)
- self.editFont=tkFont.Font(self,('courier',10,'normal'))
- ##widget creation
- #body frame
- frame=self.tabPages.pages['Fonts/Tabs']['page']
- #body section frames
- frameFont=Frame(frame,borderwidth=2,relief=GROOVE)
- frameIndent=Frame(frame,borderwidth=2,relief=GROOVE)
- #frameFont
- labelFontTitle=Label(frameFont,text='Set Base Editor Font')
- frameFontName=Frame(frameFont)
- frameFontParam=Frame(frameFont)
- labelFontNameTitle=Label(frameFontName,justify=LEFT,
- text='Font :')
- self.listFontName=Listbox(frameFontName,height=5,takefocus=FALSE,
- exportselection=FALSE)
- self.listFontName.bind('<ButtonRelease-1>',self.OnListFontButtonRelease)
- scrollFont=Scrollbar(frameFontName)
- scrollFont.config(command=self.listFontName.yview)
- self.listFontName.config(yscrollcommand=scrollFont.set)
- labelFontSizeTitle=Label(frameFontParam,text='Size :')
- self.optMenuFontSize=DynOptionMenu(frameFontParam,self.fontSize,None,
- command=self.SetFontSample)
- checkFontBold=Checkbutton(frameFontParam,variable=self.fontBold,
- onvalue=1,offvalue=0,text='Bold',command=self.SetFontSample)
- frameFontSample=Frame(frameFont,relief=SOLID,borderwidth=1)
- self.labelFontSample=Label(frameFontSample,
- text='AaBbCcDdEe\nFfGgHhIiJjK\n1234567890\n#:+=(){}[]',
- justify=LEFT,font=self.editFont)
- #frameIndent
- frameIndentSize=Frame(frameIndent)
- labelSpaceNumTitle=Label(frameIndentSize, justify=LEFT,
- text='Python Standard: 4 Spaces!')
- self.scaleSpaceNum=Scale(frameIndentSize, variable=self.spaceNum,
- label='Indentation Width', orient='horizontal',
- tickinterval=2, from_=2, to=16)
- #widget packing
- #body
- frameFont.pack(side=LEFT,padx=5,pady=10,expand=TRUE,fill=BOTH)
- frameIndent.pack(side=LEFT,padx=5,pady=10,fill=Y)
- #frameFont
- labelFontTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
- frameFontName.pack(side=TOP,padx=5,pady=5,fill=X)
- frameFontParam.pack(side=TOP,padx=5,pady=5,fill=X)
- labelFontNameTitle.pack(side=TOP,anchor=W)
- self.listFontName.pack(side=LEFT,expand=TRUE,fill=X)
- scrollFont.pack(side=LEFT,fill=Y)
- labelFontSizeTitle.pack(side=LEFT,anchor=W)
- self.optMenuFontSize.pack(side=LEFT,anchor=W)
- checkFontBold.pack(side=LEFT,anchor=W,padx=20)
- frameFontSample.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH)
- self.labelFontSample.pack(expand=TRUE,fill=BOTH)
- #frameIndent
- frameIndentSize.pack(side=TOP,padx=5,pady=5,fill=BOTH)
- labelSpaceNumTitle.pack(side=TOP,anchor=W,padx=5)
- self.scaleSpaceNum.pack(side=TOP,padx=5,fill=X)
- return frame
-
- def CreatePageHighlight(self):
- self.builtinTheme=StringVar(self)
- self.customTheme=StringVar(self)
- self.fgHilite=BooleanVar(self)
- self.colour=StringVar(self)
- self.fontName=StringVar(self)
- self.themeIsBuiltin=BooleanVar(self)
- self.highlightTarget=StringVar(self)
- ##widget creation
- #body frame
- frame=self.tabPages.pages['Highlighting']['page']
- #body section frames
- frameCustom=Frame(frame,borderwidth=2,relief=GROOVE)
- frameTheme=Frame(frame,borderwidth=2,relief=GROOVE)
- #frameCustom
- self.textHighlightSample=Text(frameCustom,relief=SOLID,borderwidth=1,
- font=('courier',12,''),cursor='hand2',width=21,height=10,
- takefocus=FALSE,highlightthickness=0,wrap=NONE)
- text=self.textHighlightSample
- text.bind('<Double-Button-1>',lambda e: 'break')
- text.bind('<B1-Motion>',lambda e: 'break')
- textAndTags=(('#you can click here','comment'),('\n','normal'),
- ('#to choose items','comment'),('\n','normal'),('def','keyword'),
- (' ','normal'),('func','definition'),('(param):','normal'),
- ('\n ','normal'),('"""string"""','string'),('\n var0 = ','normal'),
- ("'string'",'string'),('\n var1 = ','normal'),("'selected'",'hilite'),
- ('\n var2 = ','normal'),("'found'",'hit'),
- ('\n var3 = ','normal'),('list', 'builtin'), ('(','normal'),
- ('None', 'builtin'),(')\n\n','normal'),
- (' error ','error'),(' ','normal'),('cursor |','cursor'),
- ('\n ','normal'),('shell','console'),(' ','normal'),('stdout','stdout'),
- (' ','normal'),('stderr','stderr'),('\n','normal'))
- for txTa in textAndTags:
- text.insert(END,txTa[0],txTa[1])
- for element in self.themeElements.keys():
- text.tag_bind(self.themeElements[element][0],'<ButtonPress-1>',
- lambda event,elem=element: event.widget.winfo_toplevel()
- .highlightTarget.set(elem))
- text.config(state=DISABLED)
- self.frameColourSet=Frame(frameCustom,relief=SOLID,borderwidth=1)
- frameFgBg=Frame(frameCustom)
- labelCustomTitle=Label(frameCustom,text='Set Custom Highlighting')
- buttonSetColour=Button(self.frameColourSet,text='Choose Colour for :',
- command=self.GetColour,highlightthickness=0)
- self.optMenuHighlightTarget=DynOptionMenu(self.frameColourSet,
- self.highlightTarget,None,highlightthickness=0)#,command=self.SetHighlightTargetBinding
- self.radioFg=Radiobutton(frameFgBg,variable=self.fgHilite,
- value=1,text='Foreground',command=self.SetColourSampleBinding)
- self.radioBg=Radiobutton(frameFgBg,variable=self.fgHilite,
- value=0,text='Background',command=self.SetColourSampleBinding)
- self.fgHilite.set(1)
- buttonSaveCustomTheme=Button(frameCustom,
- text='Save as New Custom Theme',command=self.SaveAsNewTheme)
- #frameTheme
- labelThemeTitle=Label(frameTheme,text='Select a Highlighting Theme')
- labelTypeTitle=Label(frameTheme,text='Select : ')
- self.radioThemeBuiltin=Radiobutton(frameTheme,variable=self.themeIsBuiltin,
- value=1,command=self.SetThemeType,text='a Built-in Theme')
- self.radioThemeCustom=Radiobutton(frameTheme,variable=self.themeIsBuiltin,
- value=0,command=self.SetThemeType,text='a Custom Theme')
- self.optMenuThemeBuiltin=DynOptionMenu(frameTheme,
- self.builtinTheme,None,command=None)
- self.optMenuThemeCustom=DynOptionMenu(frameTheme,
- self.customTheme,None,command=None)
- self.buttonDeleteCustomTheme=Button(frameTheme,text='Delete Custom Theme',
- command=self.DeleteCustomTheme)
- ##widget packing
- #body
- frameCustom.pack(side=LEFT,padx=5,pady=10,expand=TRUE,fill=BOTH)
- frameTheme.pack(side=LEFT,padx=5,pady=10,fill=Y)
- #frameCustom
- labelCustomTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
- self.frameColourSet.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=X)
- frameFgBg.pack(side=TOP,padx=5,pady=0)
- self.textHighlightSample.pack(side=TOP,padx=5,pady=5,expand=TRUE,
- fill=BOTH)
- buttonSetColour.pack(side=TOP,expand=TRUE,fill=X,padx=8,pady=4)
- self.optMenuHighlightTarget.pack(side=TOP,expand=TRUE,fill=X,padx=8,pady=3)
- self.radioFg.pack(side=LEFT,anchor=E)
- self.radioBg.pack(side=RIGHT,anchor=W)
- buttonSaveCustomTheme.pack(side=BOTTOM,fill=X,padx=5,pady=5)
- #frameTheme
- labelThemeTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
- labelTypeTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
- self.radioThemeBuiltin.pack(side=TOP,anchor=W,padx=5)
- self.radioThemeCustom.pack(side=TOP,anchor=W,padx=5,pady=2)
- self.optMenuThemeBuiltin.pack(side=TOP,fill=X,padx=5,pady=5)
- self.optMenuThemeCustom.pack(side=TOP,fill=X,anchor=W,padx=5,pady=5)
- self.buttonDeleteCustomTheme.pack(side=TOP,fill=X,padx=5,pady=5)
- return frame
-
- def CreatePageKeys(self):
- #tkVars
- self.bindingTarget=StringVar(self)
- self.builtinKeys=StringVar(self)
- self.customKeys=StringVar(self)
- self.keysAreBuiltin=BooleanVar(self)
- self.keyBinding=StringVar(self)
- ##widget creation
- #body frame
- frame=self.tabPages.pages['Keys']['page']
- #body section frames
- frameCustom=Frame(frame,borderwidth=2,relief=GROOVE)
- frameKeySets=Frame(frame,borderwidth=2,relief=GROOVE)
- #frameCustom
- frameTarget=Frame(frameCustom)
- labelCustomTitle=Label(frameCustom,text='Set Custom Key Bindings')
- labelTargetTitle=Label(frameTarget,text='Action - Key(s)')
- scrollTargetY=Scrollbar(frameTarget)
- scrollTargetX=Scrollbar(frameTarget,orient=HORIZONTAL)
- self.listBindings=Listbox(frameTarget,takefocus=FALSE,
- exportselection=FALSE)
- self.listBindings.bind('<ButtonRelease-1>',self.KeyBindingSelected)
- scrollTargetY.config(command=self.listBindings.yview)
- scrollTargetX.config(command=self.listBindings.xview)
- self.listBindings.config(yscrollcommand=scrollTargetY.set)
- self.listBindings.config(xscrollcommand=scrollTargetX.set)
- self.buttonNewKeys=Button(frameCustom,text='Get New Keys for Selection',
- command=self.GetNewKeys,state=DISABLED)
- buttonSaveCustomKeys=Button(frameCustom,
- text='Save as New Custom Key Set',command=self.SaveAsNewKeySet)
- #frameKeySets
- labelKeysTitle=Label(frameKeySets,text='Select a Key Set')
- labelTypeTitle=Label(frameKeySets,text='Select : ')
- self.radioKeysBuiltin=Radiobutton(frameKeySets,variable=self.keysAreBuiltin,
- value=1,command=self.SetKeysType,text='a Built-in Key Set')
- self.radioKeysCustom=Radiobutton(frameKeySets,variable=self.keysAreBuiltin,
- value=0,command=self.SetKeysType,text='a Custom Key Set')
- self.optMenuKeysBuiltin=DynOptionMenu(frameKeySets,
- self.builtinKeys,None,command=None)
- self.optMenuKeysCustom=DynOptionMenu(frameKeySets,
- self.customKeys,None,command=None)
- self.buttonDeleteCustomKeys=Button(frameKeySets,text='Delete Custom Key Set',
- command=self.DeleteCustomKeys)
- ##widget packing
- #body
- frameCustom.pack(side=LEFT,padx=5,pady=5,expand=TRUE,fill=BOTH)
- frameKeySets.pack(side=LEFT,padx=5,pady=5,fill=Y)
- #frameCustom
- labelCustomTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
- buttonSaveCustomKeys.pack(side=BOTTOM,fill=X,padx=5,pady=5)
- self.buttonNewKeys.pack(side=BOTTOM,fill=X,padx=5,pady=5)
- frameTarget.pack(side=LEFT,padx=5,pady=5,expand=TRUE,fill=BOTH)
- #frame target
- frameTarget.columnconfigure(0,weight=1)
- frameTarget.rowconfigure(1,weight=1)
- labelTargetTitle.grid(row=0,column=0,columnspan=2,sticky=W)
- self.listBindings.grid(row=1,column=0,sticky=NSEW)
- scrollTargetY.grid(row=1,column=1,sticky=NS)
- scrollTargetX.grid(row=2,column=0,sticky=EW)
- #frameKeySets
- labelKeysTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
- labelTypeTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
- self.radioKeysBuiltin.pack(side=TOP,anchor=W,padx=5)
- self.radioKeysCustom.pack(side=TOP,anchor=W,padx=5,pady=2)
- self.optMenuKeysBuiltin.pack(side=TOP,fill=X,padx=5,pady=5)
- self.optMenuKeysCustom.pack(side=TOP,fill=X,anchor=W,padx=5,pady=5)
- self.buttonDeleteCustomKeys.pack(side=TOP,fill=X,padx=5,pady=5)
- return frame
-
- def CreatePageGeneral(self):
- #tkVars
- self.winWidth=StringVar(self)
- self.winHeight=StringVar(self)
- self.paraWidth=StringVar(self)
- self.startupEdit=IntVar(self)
- self.autoSave=IntVar(self)
- self.encoding=StringVar(self)
- self.userHelpBrowser=BooleanVar(self)
- self.helpBrowser=StringVar(self)
- #widget creation
- #body
- frame=self.tabPages.pages['General']['page']
- #body section frames
- frameRun=Frame(frame,borderwidth=2,relief=GROOVE)
- frameSave=Frame(frame,borderwidth=2,relief=GROOVE)
- frameWinSize=Frame(frame,borderwidth=2,relief=GROOVE)
- frameParaSize=Frame(frame,borderwidth=2,relief=GROOVE)
- frameEncoding=Frame(frame,borderwidth=2,relief=GROOVE)
- frameHelp=Frame(frame,borderwidth=2,relief=GROOVE)
- #frameRun
- labelRunTitle=Label(frameRun,text='Startup Preferences')
- labelRunChoiceTitle=Label(frameRun,text='At Startup')
- radioStartupEdit=Radiobutton(frameRun,variable=self.startupEdit,
- value=1,command=self.SetKeysType,text="Open Edit Window")
- radioStartupShell=Radiobutton(frameRun,variable=self.startupEdit,
- value=0,command=self.SetKeysType,text='Open Shell Window')
- #frameSave
- labelSaveTitle=Label(frameSave,text='Autosave Preference')
- labelRunSaveTitle=Label(frameSave,text='At Start of Run (F5) ')
- radioSaveAsk=Radiobutton(frameSave,variable=self.autoSave,
- value=0,command=self.SetKeysType,text="Prompt to Save")
- radioSaveAuto=Radiobutton(frameSave,variable=self.autoSave,
- value=1,command=self.SetKeysType,text='No Prompt')
- #frameWinSize
- labelWinSizeTitle=Label(frameWinSize,text='Initial Window Size'+
- ' (in characters)')
- labelWinWidthTitle=Label(frameWinSize,text='Width')
- entryWinWidth=Entry(frameWinSize,textvariable=self.winWidth,
- width=3)
- labelWinHeightTitle=Label(frameWinSize,text='Height')
- entryWinHeight=Entry(frameWinSize,textvariable=self.winHeight,
- width=3)
- #paragraphFormatWidth
- labelParaWidthTitle=Label(frameParaSize,text='Paragraph reformat'+
- ' width (in characters)')
- entryParaWidth=Entry(frameParaSize,textvariable=self.paraWidth,
- width=3)
- #frameEncoding
- labelEncodingTitle=Label(frameEncoding,text="Default Source Encoding")
- radioEncLocale=Radiobutton(frameEncoding,variable=self.encoding,
- value="locale",text="Locale-defined")
- radioEncUTF8=Radiobutton(frameEncoding,variable=self.encoding,
- value="utf-8",text="UTF-8")
- radioEncNone=Radiobutton(frameEncoding,variable=self.encoding,
- value="none",text="None")
- #frameHelp
- frameHelpList=Frame(frameHelp)
- frameHelpListButtons=Frame(frameHelpList)
- labelHelpListTitle=Label(frameHelpList,text='Additional Help Sources:')
- scrollHelpList=Scrollbar(frameHelpList)
- self.listHelp=Listbox(frameHelpList,height=5,takefocus=FALSE,
- exportselection=FALSE)
- scrollHelpList.config(command=self.listHelp.yview)
- self.listHelp.config(yscrollcommand=scrollHelpList.set)
- self.listHelp.bind('<ButtonRelease-1>',self.HelpSourceSelected)
- self.buttonHelpListEdit=Button(frameHelpListButtons,text='Edit',
- state=DISABLED,width=8,command=self.HelpListItemEdit)
- self.buttonHelpListAdd=Button(frameHelpListButtons,text='Add',
- width=8,command=self.HelpListItemAdd)
- self.buttonHelpListRemove=Button(frameHelpListButtons,text='Remove',
- state=DISABLED,width=8,command=self.HelpListItemRemove)
- #widget packing
- #body
- frameRun.pack(side=TOP,padx=5,pady=5,fill=X)
- frameSave.pack(side=TOP,padx=5,pady=5,fill=X)
- frameWinSize.pack(side=TOP,padx=5,pady=5,fill=X)
- frameParaSize.pack(side=TOP,padx=5,pady=5,fill=X)
- frameEncoding.pack(side=TOP,padx=5,pady=5,fill=X)
- frameHelp.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH)
- #frameRun
- labelRunTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
- labelRunChoiceTitle.pack(side=LEFT,anchor=W,padx=5,pady=5)
- radioStartupShell.pack(side=RIGHT,anchor=W,padx=5,pady=5)
- radioStartupEdit.pack(side=RIGHT,anchor=W,padx=5,pady=5)
- #frameSave
- labelSaveTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
- labelRunSaveTitle.pack(side=LEFT,anchor=W,padx=5,pady=5)
- radioSaveAuto.pack(side=RIGHT,anchor=W,padx=5,pady=5)
- radioSaveAsk.pack(side=RIGHT,anchor=W,padx=5,pady=5)
- #frameWinSize
- labelWinSizeTitle.pack(side=LEFT,anchor=W,padx=5,pady=5)
- entryWinHeight.pack(side=RIGHT,anchor=E,padx=10,pady=5)
- labelWinHeightTitle.pack(side=RIGHT,anchor=E,pady=5)
- entryWinWidth.pack(side=RIGHT,anchor=E,padx=10,pady=5)
- labelWinWidthTitle.pack(side=RIGHT,anchor=E,pady=5)
- #paragraphFormatWidth
- labelParaWidthTitle.pack(side=LEFT,anchor=W,padx=5,pady=5)
- entryParaWidth.pack(side=RIGHT,anchor=E,padx=10,pady=5)
- #frameEncoding
- labelEncodingTitle.pack(side=LEFT,anchor=W,padx=5,pady=5)
- radioEncNone.pack(side=RIGHT,anchor=E,pady=5)
- radioEncUTF8.pack(side=RIGHT,anchor=E,pady=5)
- radioEncLocale.pack(side=RIGHT,anchor=E,pady=5)
- #frameHelp
- frameHelpListButtons.pack(side=RIGHT,padx=5,pady=5,fill=Y)
- frameHelpList.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH)
- labelHelpListTitle.pack(side=TOP,anchor=W)
- scrollHelpList.pack(side=RIGHT,anchor=W,fill=Y)
- self.listHelp.pack(side=LEFT,anchor=E,expand=TRUE,fill=BOTH)
- self.buttonHelpListEdit.pack(side=TOP,anchor=W,pady=5)
- self.buttonHelpListAdd.pack(side=TOP,anchor=W)
- self.buttonHelpListRemove.pack(side=TOP,anchor=W,pady=5)
- return frame
-
- def AttachVarCallbacks(self):
- self.fontSize.trace_variable('w',self.VarChanged_fontSize)
- self.fontName.trace_variable('w',self.VarChanged_fontName)
- self.fontBold.trace_variable('w',self.VarChanged_fontBold)
- self.spaceNum.trace_variable('w',self.VarChanged_spaceNum)
- self.colour.trace_variable('w',self.VarChanged_colour)
- self.builtinTheme.trace_variable('w',self.VarChanged_builtinTheme)
- self.customTheme.trace_variable('w',self.VarChanged_customTheme)
- self.themeIsBuiltin.trace_variable('w',self.VarChanged_themeIsBuiltin)
- self.highlightTarget.trace_variable('w',self.VarChanged_highlightTarget)
- self.keyBinding.trace_variable('w',self.VarChanged_keyBinding)
- self.builtinKeys.trace_variable('w',self.VarChanged_builtinKeys)
- self.customKeys.trace_variable('w',self.VarChanged_customKeys)
- self.keysAreBuiltin.trace_variable('w',self.VarChanged_keysAreBuiltin)
- self.winWidth.trace_variable('w',self.VarChanged_winWidth)
- self.winHeight.trace_variable('w',self.VarChanged_winHeight)
- self.paraWidth.trace_variable('w',self.VarChanged_paraWidth)
- self.startupEdit.trace_variable('w',self.VarChanged_startupEdit)
- self.autoSave.trace_variable('w',self.VarChanged_autoSave)
- self.encoding.trace_variable('w',self.VarChanged_encoding)
-
- def VarChanged_fontSize(self,*params):
- value=self.fontSize.get()
- self.AddChangedItem('main','EditorWindow','font-size',value)
-
- def VarChanged_fontName(self,*params):
- value=self.fontName.get()
- self.AddChangedItem('main','EditorWindow','font',value)
-
- def VarChanged_fontBold(self,*params):
- value=self.fontBold.get()
- self.AddChangedItem('main','EditorWindow','font-bold',value)
-
- def VarChanged_spaceNum(self,*params):
- value=self.spaceNum.get()
- self.AddChangedItem('main','Indent','num-spaces',value)
-
- def VarChanged_colour(self,*params):
- self.OnNewColourSet()
-
- def VarChanged_builtinTheme(self,*params):
- value=self.builtinTheme.get()
- self.AddChangedItem('main','Theme','name',value)
- self.PaintThemeSample()
-
- def VarChanged_customTheme(self,*params):
- value=self.customTheme.get()
- if value != '- no custom themes -':
- self.AddChangedItem('main','Theme','name',value)
- self.PaintThemeSample()
-
- def VarChanged_themeIsBuiltin(self,*params):
- value=self.themeIsBuiltin.get()
- self.AddChangedItem('main','Theme','default',value)
- if value:
- self.VarChanged_builtinTheme()
- else:
- self.VarChanged_customTheme()
-
- def VarChanged_highlightTarget(self,*params):
- self.SetHighlightTarget()
-
- def VarChanged_keyBinding(self,*params):
- value=self.keyBinding.get()
- keySet=self.customKeys.get()
- event=self.listBindings.get(ANCHOR).split()[0]
- if idleConf.IsCoreBinding(event):
- #this is a core keybinding
- self.AddChangedItem('keys',keySet,event,value)
- else: #this is an extension key binding
- extName=idleConf.GetExtnNameForEvent(event)
- extKeybindSection=extName+'_cfgBindings'
- self.AddChangedItem('extensions',extKeybindSection,event,value)
-
- def VarChanged_builtinKeys(self,*params):
- value=self.builtinKeys.get()
- self.AddChangedItem('main','Keys','name',value)
- self.LoadKeysList(value)
-
- def VarChanged_customKeys(self,*params):
- value=self.customKeys.get()
- if value != '- no custom keys -':
- self.AddChangedItem('main','Keys','name',value)
- self.LoadKeysList(value)
-
- def VarChanged_keysAreBuiltin(self,*params):
- value=self.keysAreBuiltin.get()
- self.AddChangedItem('main','Keys','default',value)
- if value:
- self.VarChanged_builtinKeys()
- else:
- self.VarChanged_customKeys()
-
- def VarChanged_winWidth(self,*params):
- value=self.winWidth.get()
- self.AddChangedItem('main','EditorWindow','width',value)
-
- def VarChanged_winHeight(self,*params):
- value=self.winHeight.get()
- self.AddChangedItem('main','EditorWindow','height',value)
-
- def VarChanged_paraWidth(self,*params):
- value=self.paraWidth.get()
- self.AddChangedItem('main','FormatParagraph','paragraph',value)
-
- def VarChanged_startupEdit(self,*params):
- value=self.startupEdit.get()
- self.AddChangedItem('main','General','editor-on-startup',value)
-
- def VarChanged_autoSave(self,*params):
- value=self.autoSave.get()
- self.AddChangedItem('main','General','autosave',value)
-
- def VarChanged_encoding(self,*params):
- value=self.encoding.get()
- self.AddChangedItem('main','EditorWindow','encoding',value)
-
- def ResetChangedItems(self):
- #When any config item is changed in this dialog, an entry
- #should be made in the relevant section (config type) of this
- #dictionary. The key should be the config file section name and the
- #value a dictionary, whose key:value pairs are item=value pairs for
- #that config file section.
- self.changedItems={'main':{},'highlight':{},'keys':{},'extensions':{}}
-
- def AddChangedItem(self,type,section,item,value):
- value=str(value) #make sure we use a string
- if not self.changedItems[type].has_key(section):
- self.changedItems[type][section]={}
- self.changedItems[type][section][item]=value
-
- def GetDefaultItems(self):
- dItems={'main':{},'highlight':{},'keys':{},'extensions':{}}
- for configType in dItems.keys():
- sections=idleConf.GetSectionList('default',configType)
- for section in sections:
- dItems[configType][section]={}
- options=idleConf.defaultCfg[configType].GetOptionList(section)
- for option in options:
- dItems[configType][section][option]=(
- idleConf.defaultCfg[configType].Get(section,option))
- return dItems
-
- def SetThemeType(self):
- if self.themeIsBuiltin.get():
- self.optMenuThemeBuiltin.config(state=NORMAL)
- self.optMenuThemeCustom.config(state=DISABLED)
- self.buttonDeleteCustomTheme.config(state=DISABLED)
- else:
- self.optMenuThemeBuiltin.config(state=DISABLED)
- self.radioThemeCustom.config(state=NORMAL)
- self.optMenuThemeCustom.config(state=NORMAL)
- self.buttonDeleteCustomTheme.config(state=NORMAL)
-
- def SetKeysType(self):
- if self.keysAreBuiltin.get():
- self.optMenuKeysBuiltin.config(state=NORMAL)
- self.optMenuKeysCustom.config(state=DISABLED)
- self.buttonDeleteCustomKeys.config(state=DISABLED)
- else:
- self.optMenuKeysBuiltin.config(state=DISABLED)
- self.radioKeysCustom.config(state=NORMAL)
- self.optMenuKeysCustom.config(state=NORMAL)
- self.buttonDeleteCustomKeys.config(state=NORMAL)
-
- def GetNewKeys(self):
- listIndex=self.listBindings.index(ANCHOR)
- binding=self.listBindings.get(listIndex)
- bindName=binding.split()[0] #first part, up to first space
- if self.keysAreBuiltin.get():
- currentKeySetName=self.builtinKeys.get()
- else:
- currentKeySetName=self.customKeys.get()
- currentBindings=idleConf.GetCurrentKeySet()
- if currentKeySetName in self.changedItems['keys'].keys(): #unsaved changes
- keySetChanges=self.changedItems['keys'][currentKeySetName]
- for event in keySetChanges.keys():
- currentBindings[event]=keySetChanges[event].split()
- currentKeySequences=currentBindings.values()
- newKeys=GetKeysDialog(self,'Get New Keys',bindName,
- currentKeySequences).result
- if newKeys: #new keys were specified
- if self.keysAreBuiltin.get(): #current key set is a built-in
- message=('Your changes will be saved as a new Custom Key Set. '+
- 'Enter a name for your new Custom Key Set below.')
- newKeySet=self.GetNewKeysName(message)
- if not newKeySet: #user cancelled custom key set creation
- self.listBindings.select_set(listIndex)
- self.listBindings.select_anchor(listIndex)
- return
- else: #create new custom key set based on previously active key set
- self.CreateNewKeySet(newKeySet)
- self.listBindings.delete(listIndex)
- self.listBindings.insert(listIndex,bindName+' - '+newKeys)
- self.listBindings.select_set(listIndex)
- self.listBindings.select_anchor(listIndex)
- self.keyBinding.set(newKeys)
- else:
- self.listBindings.select_set(listIndex)
- self.listBindings.select_anchor(listIndex)
-
- def GetNewKeysName(self,message):
- usedNames=(idleConf.GetSectionList('user','keys')+
- idleConf.GetSectionList('default','keys'))
- newKeySet=GetCfgSectionNameDialog(self,'New Custom Key Set',
- message,usedNames).result
- return newKeySet
-
- def SaveAsNewKeySet(self):
- newKeysName=self.GetNewKeysName('New Key Set Name:')
- if newKeysName:
- self.CreateNewKeySet(newKeysName)
-
- def KeyBindingSelected(self,event):
- self.buttonNewKeys.config(state=NORMAL)
-
- def CreateNewKeySet(self,newKeySetName):
- #creates new custom key set based on the previously active key set,
- #and makes the new key set active
- if self.keysAreBuiltin.get():
- prevKeySetName=self.builtinKeys.get()
- else:
- prevKeySetName=self.customKeys.get()
- prevKeys=idleConf.GetCoreKeys(prevKeySetName)
- newKeys={}
- for event in prevKeys.keys(): #add key set to changed items
- eventName=event[2:-2] #trim off the angle brackets
- binding=string.join(prevKeys[event])
- newKeys[eventName]=binding
- #handle any unsaved changes to prev key set
- if prevKeySetName in self.changedItems['keys'].keys():
- keySetChanges=self.changedItems['keys'][prevKeySetName]
- for event in keySetChanges.keys():
- newKeys[event]=keySetChanges[event]
- #save the new theme
- self.SaveNewKeySet(newKeySetName,newKeys)
- #change gui over to the new key set
- customKeyList=idleConf.GetSectionList('user','keys')
- customKeyList.sort()
- self.optMenuKeysCustom.SetMenu(customKeyList,newKeySetName)
- self.keysAreBuiltin.set(0)
- self.SetKeysType()
-
- def LoadKeysList(self,keySetName):
- reselect=0
- newKeySet=0
- if self.listBindings.curselection():
- reselect=1
- listIndex=self.listBindings.index(ANCHOR)
- keySet=idleConf.GetKeySet(keySetName)
- bindNames=keySet.keys()
- bindNames.sort()
- self.listBindings.delete(0,END)
- for bindName in bindNames:
- key=string.join(keySet[bindName]) #make key(s) into a string
- bindName=bindName[2:-2] #trim off the angle brackets
- if keySetName in self.changedItems['keys'].keys():
- #handle any unsaved changes to this key set
- if bindName in self.changedItems['keys'][keySetName].keys():
- key=self.changedItems['keys'][keySetName][bindName]
- self.listBindings.insert(END, bindName+' - '+key)
- if reselect:
- self.listBindings.see(listIndex)
- self.listBindings.select_set(listIndex)
- self.listBindings.select_anchor(listIndex)
-
- def DeleteCustomKeys(self):
- keySetName=self.customKeys.get()
- if not tkMessageBox.askyesno('Delete Key Set','Are you sure you wish '+
- 'to delete the key set %r ?' % (keySetName),
- parent=self):
- return
- #remove key set from config
- idleConf.userCfg['keys'].remove_section(keySetName)
- if self.changedItems['keys'].has_key(keySetName):
- del(self.changedItems['keys'][keySetName])
- #write changes
- idleConf.userCfg['keys'].Save()
- #reload user key set list
- itemList=idleConf.GetSectionList('user','keys')
- itemList.sort()
- if not itemList:
- self.radioKeysCustom.config(state=DISABLED)
- self.optMenuKeysCustom.SetMenu(itemList,'- no custom keys -')
- else:
- self.optMenuKeysCustom.SetMenu(itemList,itemList[0])
- #revert to default key set
- self.keysAreBuiltin.set(idleConf.defaultCfg['main'].Get('Keys','default'))
- self.builtinKeys.set(idleConf.defaultCfg['main'].Get('Keys','name'))
- #user can't back out of these changes, they must be applied now
- self.Apply()
- self.SetKeysType()
-
- def DeleteCustomTheme(self):
- themeName=self.customTheme.get()
- if not tkMessageBox.askyesno('Delete Theme','Are you sure you wish '+
- 'to delete the theme %r ?' % (themeName,),
- parent=self):
- return
- #remove theme from config
- idleConf.userCfg['highlight'].remove_section(themeName)
- if self.changedItems['highlight'].has_key(themeName):
- del(self.changedItems['highlight'][themeName])
- #write changes
- idleConf.userCfg['highlight'].Save()
- #reload user theme list
- itemList=idleConf.GetSectionList('user','highlight')
- itemList.sort()
- if not itemList:
- self.radioThemeCustom.config(state=DISABLED)
- self.optMenuThemeCustom.SetMenu(itemList,'- no custom themes -')
- else:
- self.optMenuThemeCustom.SetMenu(itemList,itemList[0])
- #revert to default theme
- self.themeIsBuiltin.set(idleConf.defaultCfg['main'].Get('Theme','default'))
- self.builtinTheme.set(idleConf.defaultCfg['main'].Get('Theme','name'))
- #user can't back out of these changes, they must be applied now
- self.Apply()
- self.SetThemeType()
-
- def GetColour(self):
- target=self.highlightTarget.get()
- prevColour=self.frameColourSet.cget('bg')
- rgbTuplet, colourString = tkColorChooser.askcolor(parent=self,
- title='Pick new colour for : '+target,initialcolor=prevColour)
- if colourString and (colourString!=prevColour):
- #user didn't cancel, and they chose a new colour
- if self.themeIsBuiltin.get(): #current theme is a built-in
- message=('Your changes will be saved as a new Custom Theme. '+
- 'Enter a name for your new Custom Theme below.')
- newTheme=self.GetNewThemeName(message)
- if not newTheme: #user cancelled custom theme creation
- return
- else: #create new custom theme based on previously active theme
- self.CreateNewTheme(newTheme)
- self.colour.set(colourString)
- else: #current theme is user defined
- self.colour.set(colourString)
-
- def OnNewColourSet(self):
- newColour=self.colour.get()
- self.frameColourSet.config(bg=newColour)#set sample
- if self.fgHilite.get(): plane='foreground'
- else: plane='background'
- sampleElement=self.themeElements[self.highlightTarget.get()][0]
- self.textHighlightSample.tag_config(sampleElement, **{plane:newColour})
- theme=self.customTheme.get()
- themeElement=sampleElement+'-'+plane
- self.AddChangedItem('highlight',theme,themeElement,newColour)
-
- def GetNewThemeName(self,message):
- usedNames=(idleConf.GetSectionList('user','highlight')+
- idleConf.GetSectionList('default','highlight'))
- newTheme=GetCfgSectionNameDialog(self,'New Custom Theme',
- message,usedNames).result
- return newTheme
-
- def SaveAsNewTheme(self):
- newThemeName=self.GetNewThemeName('New Theme Name:')
- if newThemeName:
- self.CreateNewTheme(newThemeName)
-
- def CreateNewTheme(self,newThemeName):
- #creates new custom theme based on the previously active theme,
- #and makes the new theme active
- if self.themeIsBuiltin.get():
- themeType='default'
- themeName=self.builtinTheme.get()
- else:
- themeType='user'
- themeName=self.customTheme.get()
- newTheme=idleConf.GetThemeDict(themeType,themeName)
- #apply any of the old theme's unsaved changes to the new theme
- if themeName in self.changedItems['highlight'].keys():
- themeChanges=self.changedItems['highlight'][themeName]
- for element in themeChanges.keys():
- newTheme[element]=themeChanges[element]
- #save the new theme
- self.SaveNewTheme(newThemeName,newTheme)
- #change gui over to the new theme
- customThemeList=idleConf.GetSectionList('user','highlight')
- customThemeList.sort()
- self.optMenuThemeCustom.SetMenu(customThemeList,newThemeName)
- self.themeIsBuiltin.set(0)
- self.SetThemeType()
-
- def OnListFontButtonRelease(self,event):
- font = self.listFontName.get(ANCHOR)
- self.fontName.set(font.lower())
- self.SetFontSample()
-
- def SetFontSample(self,event=None):
- fontName=self.fontName.get()
- if self.fontBold.get():
- fontWeight=tkFont.BOLD
- else:
- fontWeight=tkFont.NORMAL
- self.editFont.config(size=self.fontSize.get(),
- weight=fontWeight,family=fontName)
-
- def SetHighlightTarget(self):
- if self.highlightTarget.get()=='Cursor': #bg not possible
- self.radioFg.config(state=DISABLED)
- self.radioBg.config(state=DISABLED)
- self.fgHilite.set(1)
- else: #both fg and bg can be set
- self.radioFg.config(state=NORMAL)
- self.radioBg.config(state=NORMAL)
- self.fgHilite.set(1)
- self.SetColourSample()
-
- def SetColourSampleBinding(self,*args):
- self.SetColourSample()
-
- def SetColourSample(self):
- #set the colour smaple area
- tag=self.themeElements[self.highlightTarget.get()][0]
- if self.fgHilite.get(): plane='foreground'
- else: plane='background'
- colour=self.textHighlightSample.tag_cget(tag,plane)
- self.frameColourSet.config(bg=colour)
-
- def PaintThemeSample(self):
- if self.themeIsBuiltin.get(): #a default theme
- theme=self.builtinTheme.get()
- else: #a user theme
- theme=self.customTheme.get()
- for elementTitle in self.themeElements.keys():
- element=self.themeElements[elementTitle][0]
- colours=idleConf.GetHighlight(theme,element)
- if element=='cursor': #cursor sample needs special painting
- colours['background']=idleConf.GetHighlight(theme,
- 'normal', fgBg='bg')
- #handle any unsaved changes to this theme
- if theme in self.changedItems['highlight'].keys():
- themeDict=self.changedItems['highlight'][theme]
- if themeDict.has_key(element+'-foreground'):
- colours['foreground']=themeDict[element+'-foreground']
- if themeDict.has_key(element+'-background'):
- colours['background']=themeDict[element+'-background']
- self.textHighlightSample.tag_config(element, **colours)
- self.SetColourSample()
-
- def HelpSourceSelected(self,event):
- self.SetHelpListButtonStates()
-
- def SetHelpListButtonStates(self):
- if self.listHelp.size()<1: #no entries in list
- self.buttonHelpListEdit.config(state=DISABLED)
- self.buttonHelpListRemove.config(state=DISABLED)
- else: #there are some entries
- if self.listHelp.curselection(): #there currently is a selection
- self.buttonHelpListEdit.config(state=NORMAL)
- self.buttonHelpListRemove.config(state=NORMAL)
- else: #there currently is not a selection
- self.buttonHelpListEdit.config(state=DISABLED)
- self.buttonHelpListRemove.config(state=DISABLED)
-
- def HelpListItemAdd(self):
- helpSource=GetHelpSourceDialog(self,'New Help Source').result
- if helpSource:
- self.userHelpList.append( (helpSource[0],helpSource[1]) )
- self.listHelp.insert(END,helpSource[0])
- self.UpdateUserHelpChangedItems()
- self.SetHelpListButtonStates()
-
- def HelpListItemEdit(self):
- itemIndex=self.listHelp.index(ANCHOR)
- helpSource=self.userHelpList[itemIndex]
- newHelpSource=GetHelpSourceDialog(self,'Edit Help Source',
- menuItem=helpSource[0],filePath=helpSource[1]).result
- if (not newHelpSource) or (newHelpSource==helpSource):
- return #no changes
- self.userHelpList[itemIndex]=newHelpSource
- self.listHelp.delete(itemIndex)
- self.listHelp.insert(itemIndex,newHelpSource[0])
- self.UpdateUserHelpChangedItems()
- self.SetHelpListButtonStates()
-
- def HelpListItemRemove(self):
- itemIndex=self.listHelp.index(ANCHOR)
- del(self.userHelpList[itemIndex])
- self.listHelp.delete(itemIndex)
- self.UpdateUserHelpChangedItems()
- self.SetHelpListButtonStates()
-
- def UpdateUserHelpChangedItems(self):
- "Clear and rebuild the HelpFiles section in self.changedItems"
- self.changedItems['main']['HelpFiles'] = {}
- for num in range(1,len(self.userHelpList)+1):
- self.AddChangedItem('main','HelpFiles',str(num),
- string.join(self.userHelpList[num-1][:2],';'))
-
- def LoadFontCfg(self):
- ##base editor font selection list
- fonts=list(tkFont.families(self))
- fonts.sort()
- for font in fonts:
- self.listFontName.insert(END,font)
- configuredFont=idleConf.GetOption('main','EditorWindow','font',
- default='courier')
- lc_configuredFont = configuredFont.lower()
- self.fontName.set(lc_configuredFont)
- lc_fonts = [s.lower() for s in fonts]
- if lc_configuredFont in lc_fonts:
- currentFontIndex = lc_fonts.index(lc_configuredFont)
- self.listFontName.see(currentFontIndex)
- self.listFontName.select_set(currentFontIndex)
- self.listFontName.select_anchor(currentFontIndex)
- ##font size dropdown
- fontSize=idleConf.GetOption('main','EditorWindow','font-size',
- default='10')
- self.optMenuFontSize.SetMenu(('7','8','9','10','11','12','13','14',
- '16','18','20','22'),fontSize )
- ##fontWeight
- self.fontBold.set(idleConf.GetOption('main','EditorWindow',
- 'font-bold',default=0,type='bool'))
- ##font sample
- self.SetFontSample()
-
- def LoadTabCfg(self):
- ##indent sizes
- spaceNum=idleConf.GetOption('main','Indent','num-spaces',
- default=4,type='int')
- self.spaceNum.set(spaceNum)
-
- def LoadThemeCfg(self):
- ##current theme type radiobutton
- self.themeIsBuiltin.set(idleConf.GetOption('main','Theme','default',
- type='bool',default=1))
- ##currently set theme
- currentOption=idleConf.CurrentTheme()
- ##load available theme option menus
- if self.themeIsBuiltin.get(): #default theme selected
- itemList=idleConf.GetSectionList('default','highlight')
- itemList.sort()
- self.optMenuThemeBuiltin.SetMenu(itemList,currentOption)
- itemList=idleConf.GetSectionList('user','highlight')
- itemList.sort()
- if not itemList:
- self.radioThemeCustom.config(state=DISABLED)
- self.customTheme.set('- no custom themes -')
- else:
- self.optMenuThemeCustom.SetMenu(itemList,itemList[0])
- else: #user theme selected
- itemList=idleConf.GetSectionList('user','highlight')
- itemList.sort()
- self.optMenuThemeCustom.SetMenu(itemList,currentOption)
- itemList=idleConf.GetSectionList('default','highlight')
- itemList.sort()
- self.optMenuThemeBuiltin.SetMenu(itemList,itemList[0])
- self.SetThemeType()
- ##load theme element option menu
- themeNames=self.themeElements.keys()
- themeNames.sort(self.__ThemeNameIndexCompare)
- self.optMenuHighlightTarget.SetMenu(themeNames,themeNames[0])
- self.PaintThemeSample()
- self.SetHighlightTarget()
-
- def __ThemeNameIndexCompare(self,a,b):
- if self.themeElements[a][1]<self.themeElements[b][1]: return -1
- elif self.themeElements[a][1]==self.themeElements[b][1]: return 0
- else: return 1
-
- def LoadKeyCfg(self):
- ##current keys type radiobutton
- self.keysAreBuiltin.set(idleConf.GetOption('main','Keys','default',
- type='bool',default=1))
- ##currently set keys
- currentOption=idleConf.CurrentKeys()
- ##load available keyset option menus
- if self.keysAreBuiltin.get(): #default theme selected
- itemList=idleConf.GetSectionList('default','keys')
- itemList.sort()
- self.optMenuKeysBuiltin.SetMenu(itemList,currentOption)
- itemList=idleConf.GetSectionList('user','keys')
- itemList.sort()
- if not itemList:
- self.radioKeysCustom.config(state=DISABLED)
- self.customKeys.set('- no custom keys -')
- else:
- self.optMenuKeysCustom.SetMenu(itemList,itemList[0])
- else: #user key set selected
- itemList=idleConf.GetSectionList('user','keys')
- itemList.sort()
- self.optMenuKeysCustom.SetMenu(itemList,currentOption)
- itemList=idleConf.GetSectionList('default','keys')
- itemList.sort()
- self.optMenuKeysBuiltin.SetMenu(itemList,itemList[0])
- self.SetKeysType()
- ##load keyset element list
- keySetName=idleConf.CurrentKeys()
- self.LoadKeysList(keySetName)
-
- def LoadGeneralCfg(self):
- #startup state
- self.startupEdit.set(idleConf.GetOption('main','General',
- 'editor-on-startup',default=1,type='bool'))
- #autosave state
- self.autoSave.set(idleConf.GetOption('main', 'General', 'autosave',
- default=0, type='bool'))
- #initial window size
- self.winWidth.set(idleConf.GetOption('main','EditorWindow','width'))
- self.winHeight.set(idleConf.GetOption('main','EditorWindow','height'))
- #initial paragraph reformat size
- self.paraWidth.set(idleConf.GetOption('main','FormatParagraph','paragraph'))
- # default source encoding
- self.encoding.set(idleConf.GetOption('main', 'EditorWindow',
- 'encoding', default='none'))
- # additional help sources
- self.userHelpList = idleConf.GetAllExtraHelpSourcesList()
- for helpItem in self.userHelpList:
- self.listHelp.insert(END,helpItem[0])
- self.SetHelpListButtonStates()
-
- def LoadConfigs(self):
- """
- load configuration from default and user config files and populate
- the widgets on the config dialog pages.
- """
- ### fonts / tabs page
- self.LoadFontCfg()
- self.LoadTabCfg()
- ### highlighting page
- self.LoadThemeCfg()
- ### keys page
- self.LoadKeyCfg()
- ### general page
- self.LoadGeneralCfg()
-
- def SaveNewKeySet(self,keySetName,keySet):
- """
- save a newly created core key set.
- keySetName - string, the name of the new key set
- keySet - dictionary containing the new key set
- """
- if not idleConf.userCfg['keys'].has_section(keySetName):
- idleConf.userCfg['keys'].add_section(keySetName)
- for event in keySet.keys():
- value=keySet[event]
- idleConf.userCfg['keys'].SetOption(keySetName,event,value)
-
- def SaveNewTheme(self,themeName,theme):
- """
- save a newly created theme.
- themeName - string, the name of the new theme
- theme - dictionary containing the new theme
- """
- if not idleConf.userCfg['highlight'].has_section(themeName):
- idleConf.userCfg['highlight'].add_section(themeName)
- for element in theme.keys():
- value=theme[element]
- idleConf.userCfg['highlight'].SetOption(themeName,element,value)
-
- def SetUserValue(self,configType,section,item,value):
- if idleConf.defaultCfg[configType].has_option(section,item):
- if idleConf.defaultCfg[configType].Get(section,item)==value:
- #the setting equals a default setting, remove it from user cfg
- return idleConf.userCfg[configType].RemoveOption(section,item)
- #if we got here set the option
- return idleConf.userCfg[configType].SetOption(section,item,value)
-
- def SaveAllChangedConfigs(self):
- "Save configuration changes to the user config file."
- idleConf.userCfg['main'].Save()
- for configType in self.changedItems.keys():
- cfgTypeHasChanges = False
- for section in self.changedItems[configType].keys():
- if section == 'HelpFiles':
- #this section gets completely replaced
- idleConf.userCfg['main'].remove_section('HelpFiles')
- cfgTypeHasChanges = True
- for item in self.changedItems[configType][section].keys():
- value = self.changedItems[configType][section][item]
- if self.SetUserValue(configType,section,item,value):
- cfgTypeHasChanges = True
- if cfgTypeHasChanges:
- idleConf.userCfg[configType].Save()
- for configType in ['keys', 'highlight']:
- # save these even if unchanged!
- idleConf.userCfg[configType].Save()
- self.ResetChangedItems() #clear the changed items dict
-
- def DeactivateCurrentConfig(self):
- #Before a config is saved, some cleanup of current
- #config must be done - remove the previous keybindings
- winInstances=self.parent.instance_dict.keys()
- for instance in winInstances:
- instance.RemoveKeybindings()
-
- def ActivateConfigChanges(self):
- "Dynamically apply configuration changes"
- winInstances=self.parent.instance_dict.keys()
- for instance in winInstances:
- instance.ResetColorizer()
- instance.ResetFont()
- instance.set_notabs_indentwidth()
- instance.ApplyKeybindings()
- instance.reset_help_menu_entries()
-
- def Cancel(self):
- self.destroy()
-
- def Ok(self):
- self.Apply()
- self.destroy()
-
- def Apply(self):
- self.DeactivateCurrentConfig()
- self.SaveAllChangedConfigs()
- self.ActivateConfigChanges()
-
- def Help(self):
- pass
-
-if __name__ == '__main__':
- #test the dialog
- root=Tk()
- Button(root,text='Dialog',
- command=lambda:ConfigDialog(root,'Settings')).pack()
- root.instance_dict={}
- root.mainloop()
diff --git a/sys/lib/python/idlelib/configHandler.py b/sys/lib/python/idlelib/configHandler.py
deleted file mode 100644
index 826fb5dbb..000000000
--- a/sys/lib/python/idlelib/configHandler.py
+++ /dev/null
@@ -1,696 +0,0 @@
-"""Provides access to stored IDLE configuration information.
-
-Refer to the comments at the beginning of config-main.def for a description of
-the available configuration files and the design implemented to update user
-configuration information. In particular, user configuration choices which
-duplicate the defaults will be removed from the user's configuration files,
-and if a file becomes empty, it will be deleted.
-
-The contents of the user files may be altered using the Options/Configure IDLE
-menu to access the configuration GUI (configDialog.py), or manually.
-
-Throughout this module there is an emphasis on returning useable defaults
-when a problem occurs in returning a requested configuration value back to
-idle. This is to allow IDLE to continue to function in spite of errors in
-the retrieval of config information. When a default is returned instead of
-a requested config value, a message is printed to stderr to aid in
-configuration problem notification and resolution.
-
-"""
-import os
-import sys
-import string
-import macosxSupport
-from ConfigParser import ConfigParser, NoOptionError, NoSectionError
-
-class InvalidConfigType(Exception): pass
-class InvalidConfigSet(Exception): pass
-class InvalidFgBg(Exception): pass
-class InvalidTheme(Exception): pass
-
-class IdleConfParser(ConfigParser):
- """
- A ConfigParser specialised for idle configuration file handling
- """
- def __init__(self, cfgFile, cfgDefaults=None):
- """
- cfgFile - string, fully specified configuration file name
- """
- self.file=cfgFile
- ConfigParser.__init__(self,defaults=cfgDefaults)
-
- def Get(self, section, option, type=None, default=None):
- """
- Get an option value for given section/option or return default.
- If type is specified, return as type.
- """
- if type=='bool':
- getVal=self.getboolean
- elif type=='int':
- getVal=self.getint
- else:
- getVal=self.get
- if self.has_option(section,option):
- #return getVal(section, option, raw, vars, default)
- return getVal(section, option)
- else:
- return default
-
- def GetOptionList(self,section):
- """
- Get an option list for given section
- """
- if self.has_section(section):
- return self.options(section)
- else: #return a default value
- return []
-
- def Load(self):
- """
- Load the configuration file from disk
- """
- self.read(self.file)
-
-class IdleUserConfParser(IdleConfParser):
- """
- IdleConfigParser specialised for user configuration handling.
- """
-
- def AddSection(self,section):
- """
- if section doesn't exist, add it
- """
- if not self.has_section(section):
- self.add_section(section)
-
- def RemoveEmptySections(self):
- """
- remove any sections that have no options
- """
- for section in self.sections():
- if not self.GetOptionList(section):
- self.remove_section(section)
-
- def IsEmpty(self):
- """
- Remove empty sections and then return 1 if parser has no sections
- left, else return 0.
- """
- self.RemoveEmptySections()
- if self.sections():
- return 0
- else:
- return 1
-
- def RemoveOption(self,section,option):
- """
- If section/option exists, remove it.
- Returns 1 if option was removed, 0 otherwise.
- """
- if self.has_section(section):
- return self.remove_option(section,option)
-
- def SetOption(self,section,option,value):
- """
- Sets option to value, adding section if required.
- Returns 1 if option was added or changed, otherwise 0.
- """
- if self.has_option(section,option):
- if self.get(section,option)==value:
- return 0
- else:
- self.set(section,option,value)
- return 1
- else:
- if not self.has_section(section):
- self.add_section(section)
- self.set(section,option,value)
- return 1
-
- def RemoveFile(self):
- """
- Removes the user config file from disk if it exists.
- """
- if os.path.exists(self.file):
- os.remove(self.file)
-
- def Save(self):
- """Update user configuration file.
-
- Remove empty sections. If resulting config isn't empty, write the file
- to disk. If config is empty, remove the file from disk if it exists.
-
- """
- if not self.IsEmpty():
- cfgFile=open(self.file,'w')
- self.write(cfgFile)
- else:
- self.RemoveFile()
-
-class IdleConf:
- """
- holds config parsers for all idle config files:
- default config files
- (idle install dir)/config-main.def
- (idle install dir)/config-extensions.def
- (idle install dir)/config-highlight.def
- (idle install dir)/config-keys.def
- user config files
- (user home dir)/.idlerc/config-main.cfg
- (user home dir)/.idlerc/config-extensions.cfg
- (user home dir)/.idlerc/config-highlight.cfg
- (user home dir)/.idlerc/config-keys.cfg
- """
- def __init__(self):
- self.defaultCfg={}
- self.userCfg={}
- self.cfg={}
- self.CreateConfigHandlers()
- self.LoadCfgFiles()
- #self.LoadCfg()
-
- def CreateConfigHandlers(self):
- """
- set up a dictionary of config parsers for default and user
- configurations respectively
- """
- #build idle install path
- if __name__ != '__main__': # we were imported
- idleDir=os.path.dirname(__file__)
- else: # we were exec'ed (for testing only)
- idleDir=os.path.abspath(sys.path[0])
- userDir=self.GetUserCfgDir()
- configTypes=('main','extensions','highlight','keys')
- defCfgFiles={}
- usrCfgFiles={}
- for cfgType in configTypes: #build config file names
- defCfgFiles[cfgType]=os.path.join(idleDir,'config-'+cfgType+'.def')
- usrCfgFiles[cfgType]=os.path.join(userDir,'config-'+cfgType+'.cfg')
- for cfgType in configTypes: #create config parsers
- self.defaultCfg[cfgType]=IdleConfParser(defCfgFiles[cfgType])
- self.userCfg[cfgType]=IdleUserConfParser(usrCfgFiles[cfgType])
-
- def GetUserCfgDir(self):
- """
- Creates (if required) and returns a filesystem directory for storing
- user config files.
-
- """
- cfgDir = '.idlerc'
- userDir = os.path.expanduser('~')
- if userDir != '~': # expanduser() found user home dir
- if not os.path.exists(userDir):
- warn = ('\n Warning: os.path.expanduser("~") points to\n '+
- userDir+',\n but the path does not exist.\n')
- sys.stderr.write(warn)
- userDir = '~'
- if userDir == "~": # still no path to home!
- # traditionally IDLE has defaulted to os.getcwd(), is this adequate?
- userDir = os.getcwd()
- userDir = os.path.join(userDir, cfgDir)
- if not os.path.exists(userDir):
- try:
- os.mkdir(userDir)
- except (OSError, IOError):
- warn = ('\n Warning: unable to create user config directory\n'+
- userDir+'\n Check path and permissions.\n Exiting!\n\n')
- sys.stderr.write(warn)
- raise SystemExit
- return userDir
-
- def GetOption(self, configType, section, option, default=None, type=None,
- warn_on_default=True):
- """
- Get an option value for given config type and given general
- configuration section/option or return a default. If type is specified,
- return as type. Firstly the user configuration is checked, with a
- fallback to the default configuration, and a final 'catch all'
- fallback to a useable passed-in default if the option isn't present in
- either the user or the default configuration.
- configType must be one of ('main','extensions','highlight','keys')
- If a default is returned, and warn_on_default is True, a warning is
- printed to stderr.
-
- """
- if self.userCfg[configType].has_option(section,option):
- return self.userCfg[configType].Get(section, option, type=type)
- elif self.defaultCfg[configType].has_option(section,option):
- return self.defaultCfg[configType].Get(section, option, type=type)
- else: #returning default, print warning
- if warn_on_default:
- warning = ('\n Warning: configHandler.py - IdleConf.GetOption -\n'
- ' problem retrieving configration option %r\n'
- ' from section %r.\n'
- ' returning default value: %r\n' %
- (option, section, default))
- sys.stderr.write(warning)
- return default
-
- def SetOption(self, configType, section, option, value):
- """In user's config file, set section's option to value.
-
- """
- self.userCfg[configType].SetOption(section, option, value)
-
- def GetSectionList(self, configSet, configType):
- """
- Get a list of sections from either the user or default config for
- the given config type.
- configSet must be either 'user' or 'default'
- configType must be one of ('main','extensions','highlight','keys')
- """
- if not (configType in ('main','extensions','highlight','keys')):
- raise InvalidConfigType, 'Invalid configType specified'
- if configSet == 'user':
- cfgParser=self.userCfg[configType]
- elif configSet == 'default':
- cfgParser=self.defaultCfg[configType]
- else:
- raise InvalidConfigSet, 'Invalid configSet specified'
- return cfgParser.sections()
-
- def GetHighlight(self, theme, element, fgBg=None):
- """
- return individual highlighting theme elements.
- fgBg - string ('fg'or'bg') or None, if None return a dictionary
- containing fg and bg colours (appropriate for passing to Tkinter in,
- e.g., a tag_config call), otherwise fg or bg colour only as specified.
- """
- if self.defaultCfg['highlight'].has_section(theme):
- themeDict=self.GetThemeDict('default',theme)
- else:
- themeDict=self.GetThemeDict('user',theme)
- fore=themeDict[element+'-foreground']
- if element=='cursor': #there is no config value for cursor bg
- back=themeDict['normal-background']
- else:
- back=themeDict[element+'-background']
- highlight={"foreground": fore,"background": back}
- if not fgBg: #return dict of both colours
- return highlight
- else: #return specified colour only
- if fgBg == 'fg':
- return highlight["foreground"]
- if fgBg == 'bg':
- return highlight["background"]
- else:
- raise InvalidFgBg, 'Invalid fgBg specified'
-
- def GetThemeDict(self,type,themeName):
- """
- type - string, 'default' or 'user' theme type
- themeName - string, theme name
- Returns a dictionary which holds {option:value} for each element
- in the specified theme. Values are loaded over a set of ultimate last
- fallback defaults to guarantee that all theme elements are present in
- a newly created theme.
- """
- if type == 'user':
- cfgParser=self.userCfg['highlight']
- elif type == 'default':
- cfgParser=self.defaultCfg['highlight']
- else:
- raise InvalidTheme, 'Invalid theme type specified'
- #foreground and background values are provded for each theme element
- #(apart from cursor) even though all these values are not yet used
- #by idle, to allow for their use in the future. Default values are
- #generally black and white.
- theme={ 'normal-foreground':'#000000',
- 'normal-background':'#ffffff',
- 'keyword-foreground':'#000000',
- 'keyword-background':'#ffffff',
- 'builtin-foreground':'#000000',
- 'builtin-background':'#ffffff',
- 'comment-foreground':'#000000',
- 'comment-background':'#ffffff',
- 'string-foreground':'#000000',
- 'string-background':'#ffffff',
- 'definition-foreground':'#000000',
- 'definition-background':'#ffffff',
- 'hilite-foreground':'#000000',
- 'hilite-background':'gray',
- 'break-foreground':'#ffffff',
- 'break-background':'#000000',
- 'hit-foreground':'#ffffff',
- 'hit-background':'#000000',
- 'error-foreground':'#ffffff',
- 'error-background':'#000000',
- #cursor (only foreground can be set)
- 'cursor-foreground':'#000000',
- #shell window
- 'stdout-foreground':'#000000',
- 'stdout-background':'#ffffff',
- 'stderr-foreground':'#000000',
- 'stderr-background':'#ffffff',
- 'console-foreground':'#000000',
- 'console-background':'#ffffff' }
- for element in theme.keys():
- if not cfgParser.has_option(themeName,element):
- #we are going to return a default, print warning
- warning=('\n Warning: configHandler.py - IdleConf.GetThemeDict'
- ' -\n problem retrieving theme element %r'
- '\n from theme %r.\n'
- ' returning default value: %r\n' %
- (element, themeName, theme[element]))
- sys.stderr.write(warning)
- colour=cfgParser.Get(themeName,element,default=theme[element])
- theme[element]=colour
- return theme
-
- def CurrentTheme(self):
- """
- Returns the name of the currently active theme
- """
- return self.GetOption('main','Theme','name',default='')
-
- def CurrentKeys(self):
- """
- Returns the name of the currently active key set
- """
- return self.GetOption('main','Keys','name',default='')
-
- def GetExtensions(self, active_only=True, editor_only=False, shell_only=False):
- """
- Gets a list of all idle extensions declared in the config files.
- active_only - boolean, if true only return active (enabled) extensions
- """
- extns=self.RemoveKeyBindNames(
- self.GetSectionList('default','extensions'))
- userExtns=self.RemoveKeyBindNames(
- self.GetSectionList('user','extensions'))
- for extn in userExtns:
- if extn not in extns: #user has added own extension
- extns.append(extn)
- if active_only:
- activeExtns=[]
- for extn in extns:
- if self.GetOption('extensions', extn, 'enable', default=True,
- type='bool'):
- #the extension is enabled
- if editor_only or shell_only:
- if editor_only:
- option = "enable_editor"
- else:
- option = "enable_shell"
- if self.GetOption('extensions', extn,option,
- default=True, type='bool',
- warn_on_default=False):
- activeExtns.append(extn)
- else:
- activeExtns.append(extn)
- return activeExtns
- else:
- return extns
-
- def RemoveKeyBindNames(self,extnNameList):
- #get rid of keybinding section names
- names=extnNameList
- kbNameIndicies=[]
- for name in names:
- if name.endswith(('_bindings', '_cfgBindings')):
- kbNameIndicies.append(names.index(name))
- kbNameIndicies.sort()
- kbNameIndicies.reverse()
- for index in kbNameIndicies: #delete each keybinding section name
- del(names[index])
- return names
-
- def GetExtnNameForEvent(self,virtualEvent):
- """
- Returns the name of the extension that virtualEvent is bound in, or
- None if not bound in any extension.
- virtualEvent - string, name of the virtual event to test for, without
- the enclosing '<< >>'
- """
- extName=None
- vEvent='<<'+virtualEvent+'>>'
- for extn in self.GetExtensions(active_only=0):
- for event in self.GetExtensionKeys(extn).keys():
- if event == vEvent:
- extName=extn
- return extName
-
- def GetExtensionKeys(self,extensionName):
- """
- returns a dictionary of the configurable keybindings for a particular
- extension,as they exist in the dictionary returned by GetCurrentKeySet;
- that is, where previously used bindings are disabled.
- """
- keysName=extensionName+'_cfgBindings'
- activeKeys=self.GetCurrentKeySet()
- extKeys={}
- if self.defaultCfg['extensions'].has_section(keysName):
- eventNames=self.defaultCfg['extensions'].GetOptionList(keysName)
- for eventName in eventNames:
- event='<<'+eventName+'>>'
- binding=activeKeys[event]
- extKeys[event]=binding
- return extKeys
-
- def __GetRawExtensionKeys(self,extensionName):
- """
- returns a dictionary of the configurable keybindings for a particular
- extension, as defined in the configuration files, or an empty dictionary
- if no bindings are found
- """
- keysName=extensionName+'_cfgBindings'
- extKeys={}
- if self.defaultCfg['extensions'].has_section(keysName):
- eventNames=self.defaultCfg['extensions'].GetOptionList(keysName)
- for eventName in eventNames:
- binding=self.GetOption('extensions',keysName,
- eventName,default='').split()
- event='<<'+eventName+'>>'
- extKeys[event]=binding
- return extKeys
-
- def GetExtensionBindings(self,extensionName):
- """
- Returns a dictionary of all the event bindings for a particular
- extension. The configurable keybindings are returned as they exist in
- the dictionary returned by GetCurrentKeySet; that is, where re-used
- keybindings are disabled.
- """
- bindsName=extensionName+'_bindings'
- extBinds=self.GetExtensionKeys(extensionName)
- #add the non-configurable bindings
- if self.defaultCfg['extensions'].has_section(bindsName):
- eventNames=self.defaultCfg['extensions'].GetOptionList(bindsName)
- for eventName in eventNames:
- binding=self.GetOption('extensions',bindsName,
- eventName,default='').split()
- event='<<'+eventName+'>>'
- extBinds[event]=binding
-
- return extBinds
-
- def GetKeyBinding(self, keySetName, eventStr):
- """
- returns the keybinding for a specific event.
- keySetName - string, name of key binding set
- eventStr - string, the virtual event we want the binding for,
- represented as a string, eg. '<<event>>'
- """
- eventName=eventStr[2:-2] #trim off the angle brackets
- binding=self.GetOption('keys',keySetName,eventName,default='').split()
- return binding
-
- def GetCurrentKeySet(self):
- result = self.GetKeySet(self.CurrentKeys())
-
- if macosxSupport.runningAsOSXApp():
- # We're using AquaTk, replace all keybingings that use the
- # Alt key by ones that use the Option key because the former
- # don't work reliably.
- for k, v in result.items():
- v2 = [ x.replace('<Alt-', '<Option-') for x in v ]
- if v != v2:
- result[k] = v2
-
- return result
-
- def GetKeySet(self,keySetName):
- """
- Returns a dictionary of: all requested core keybindings, plus the
- keybindings for all currently active extensions. If a binding defined
- in an extension is already in use, that binding is disabled.
- """
- keySet=self.GetCoreKeys(keySetName)
- activeExtns=self.GetExtensions(active_only=1)
- for extn in activeExtns:
- extKeys=self.__GetRawExtensionKeys(extn)
- if extKeys: #the extension defines keybindings
- for event in extKeys.keys():
- if extKeys[event] in keySet.values():
- #the binding is already in use
- extKeys[event]='' #disable this binding
- keySet[event]=extKeys[event] #add binding
- return keySet
-
- def IsCoreBinding(self,virtualEvent):
- """
- returns true if the virtual event is bound in the core idle keybindings.
- virtualEvent - string, name of the virtual event to test for, without
- the enclosing '<< >>'
- """
- return ('<<'+virtualEvent+'>>') in self.GetCoreKeys().keys()
-
- def GetCoreKeys(self, keySetName=None):
- """
- returns the requested set of core keybindings, with fallbacks if
- required.
- Keybindings loaded from the config file(s) are loaded _over_ these
- defaults, so if there is a problem getting any core binding there will
- be an 'ultimate last resort fallback' to the CUA-ish bindings
- defined here.
- """
- keyBindings={
- '<<copy>>': ['<Control-c>', '<Control-C>'],
- '<<cut>>': ['<Control-x>', '<Control-X>'],
- '<<paste>>': ['<Control-v>', '<Control-V>'],
- '<<beginning-of-line>>': ['<Control-a>', '<Home>'],
- '<<center-insert>>': ['<Control-l>'],
- '<<close-all-windows>>': ['<Control-q>'],
- '<<close-window>>': ['<Alt-F4>'],
- '<<do-nothing>>': ['<Control-x>'],
- '<<end-of-file>>': ['<Control-d>'],
- '<<python-docs>>': ['<F1>'],
- '<<python-context-help>>': ['<Shift-F1>'],
- '<<history-next>>': ['<Alt-n>'],
- '<<history-previous>>': ['<Alt-p>'],
- '<<interrupt-execution>>': ['<Control-c>'],
- '<<view-restart>>': ['<F6>'],
- '<<restart-shell>>': ['<Control-F6>'],
- '<<open-class-browser>>': ['<Alt-c>'],
- '<<open-module>>': ['<Alt-m>'],
- '<<open-new-window>>': ['<Control-n>'],
- '<<open-window-from-file>>': ['<Control-o>'],
- '<<plain-newline-and-indent>>': ['<Control-j>'],
- '<<print-window>>': ['<Control-p>'],
- '<<redo>>': ['<Control-y>'],
- '<<remove-selection>>': ['<Escape>'],
- '<<save-copy-of-window-as-file>>': ['<Alt-Shift-S>'],
- '<<save-window-as-file>>': ['<Alt-s>'],
- '<<save-window>>': ['<Control-s>'],
- '<<select-all>>': ['<Alt-a>'],
- '<<toggle-auto-coloring>>': ['<Control-slash>'],
- '<<undo>>': ['<Control-z>'],
- '<<find-again>>': ['<Control-g>', '<F3>'],
- '<<find-in-files>>': ['<Alt-F3>'],
- '<<find-selection>>': ['<Control-F3>'],
- '<<find>>': ['<Control-f>'],
- '<<replace>>': ['<Control-h>'],
- '<<goto-line>>': ['<Alt-g>'],
- '<<smart-backspace>>': ['<Key-BackSpace>'],
- '<<newline-and-indent>>': ['<Key-Return> <Key-KP_Enter>'],
- '<<smart-indent>>': ['<Key-Tab>'],
- '<<indent-region>>': ['<Control-Key-bracketright>'],
- '<<dedent-region>>': ['<Control-Key-bracketleft>'],
- '<<comment-region>>': ['<Alt-Key-3>'],
- '<<uncomment-region>>': ['<Alt-Key-4>'],
- '<<tabify-region>>': ['<Alt-Key-5>'],
- '<<untabify-region>>': ['<Alt-Key-6>'],
- '<<toggle-tabs>>': ['<Alt-Key-t>'],
- '<<change-indentwidth>>': ['<Alt-Key-u>'],
- '<<del-word-left>>': ['<Control-Key-BackSpace>'],
- '<<del-word-right>>': ['<Control-Key-Delete>']
- }
- if keySetName:
- for event in keyBindings.keys():
- binding=self.GetKeyBinding(keySetName,event)
- if binding:
- keyBindings[event]=binding
- else: #we are going to return a default, print warning
- warning=('\n Warning: configHandler.py - IdleConf.GetCoreKeys'
- ' -\n problem retrieving key binding for event %r'
- '\n from key set %r.\n'
- ' returning default value: %r\n' %
- (event, keySetName, keyBindings[event]))
- sys.stderr.write(warning)
- return keyBindings
-
- def GetExtraHelpSourceList(self,configSet):
- """Fetch list of extra help sources from a given configSet.
-
- Valid configSets are 'user' or 'default'. Return a list of tuples of
- the form (menu_item , path_to_help_file , option), or return the empty
- list. 'option' is the sequence number of the help resource. 'option'
- values determine the position of the menu items on the Help menu,
- therefore the returned list must be sorted by 'option'.
-
- """
- helpSources=[]
- if configSet=='user':
- cfgParser=self.userCfg['main']
- elif configSet=='default':
- cfgParser=self.defaultCfg['main']
- else:
- raise InvalidConfigSet, 'Invalid configSet specified'
- options=cfgParser.GetOptionList('HelpFiles')
- for option in options:
- value=cfgParser.Get('HelpFiles',option,default=';')
- if value.find(';')==-1: #malformed config entry with no ';'
- menuItem='' #make these empty
- helpPath='' #so value won't be added to list
- else: #config entry contains ';' as expected
- value=string.split(value,';')
- menuItem=value[0].strip()
- helpPath=value[1].strip()
- if menuItem and helpPath: #neither are empty strings
- helpSources.append( (menuItem,helpPath,option) )
- helpSources.sort(self.__helpsort)
- return helpSources
-
- def __helpsort(self, h1, h2):
- if int(h1[2]) < int(h2[2]):
- return -1
- elif int(h1[2]) > int(h2[2]):
- return 1
- else:
- return 0
-
- def GetAllExtraHelpSourcesList(self):
- """
- Returns a list of tuples containing the details of all additional help
- sources configured, or an empty list if there are none. Tuples are of
- the format returned by GetExtraHelpSourceList.
- """
- allHelpSources=( self.GetExtraHelpSourceList('default')+
- self.GetExtraHelpSourceList('user') )
- return allHelpSources
-
- def LoadCfgFiles(self):
- """
- load all configuration files.
- """
- for key in self.defaultCfg.keys():
- self.defaultCfg[key].Load()
- self.userCfg[key].Load() #same keys
-
- def SaveUserCfgFiles(self):
- """
- write all loaded user configuration files back to disk
- """
- for key in self.userCfg.keys():
- self.userCfg[key].Save()
-
-idleConf=IdleConf()
-
-### module test
-if __name__ == '__main__':
- def dumpCfg(cfg):
- print '\n',cfg,'\n'
- for key in cfg.keys():
- sections=cfg[key].sections()
- print key
- print sections
- for section in sections:
- options=cfg[key].options(section)
- print section
- print options
- for option in options:
- print option, '=', cfg[key].Get(section,option)
- dumpCfg(idleConf.defaultCfg)
- dumpCfg(idleConf.userCfg)
- print idleConf.userCfg['main'].Get('Theme','name')
- #print idleConf.userCfg['highlight'].GetDefHighlight('Foo','normal')
diff --git a/sys/lib/python/idlelib/configHelpSourceEdit.py b/sys/lib/python/idlelib/configHelpSourceEdit.py
deleted file mode 100644
index 661162196..000000000
--- a/sys/lib/python/idlelib/configHelpSourceEdit.py
+++ /dev/null
@@ -1,169 +0,0 @@
-"Dialog to specify or edit the parameters for a user configured help source."
-
-import os
-import sys
-
-from Tkinter import *
-import tkMessageBox
-import tkFileDialog
-
-class GetHelpSourceDialog(Toplevel):
- def __init__(self, parent, title, menuItem='', filePath=''):
- """Get menu entry and url/ local file location for Additional Help
-
- User selects a name for the Help resource and provides a web url
- or a local file as its source. The user can enter a url or browse
- for the file.
-
- """
- Toplevel.__init__(self, parent)
- self.configure(borderwidth=5)
- self.resizable(height=FALSE, width=FALSE)
- self.title(title)
- self.transient(parent)
- self.grab_set()
- self.protocol("WM_DELETE_WINDOW", self.Cancel)
- self.parent = parent
- self.result = None
- self.CreateWidgets()
- self.menu.set(menuItem)
- self.path.set(filePath)
- self.withdraw() #hide while setting geometry
- #needs to be done here so that the winfo_reqwidth is valid
- self.update_idletasks()
- #centre dialog over parent:
- self.geometry("+%d+%d" %
- ((parent.winfo_rootx() + ((parent.winfo_width()/2)
- -(self.winfo_reqwidth()/2)),
- parent.winfo_rooty() + ((parent.winfo_height()/2)
- -(self.winfo_reqheight()/2)))))
- self.deiconify() #geometry set, unhide
- self.bind('<Return>', self.Ok)
- self.wait_window()
-
- def CreateWidgets(self):
- self.menu = StringVar(self)
- self.path = StringVar(self)
- self.fontSize = StringVar(self)
- self.frameMain = Frame(self, borderwidth=2, relief=GROOVE)
- self.frameMain.pack(side=TOP, expand=TRUE, fill=BOTH)
- labelMenu = Label(self.frameMain, anchor=W, justify=LEFT,
- text='Menu Item:')
- self.entryMenu = Entry(self.frameMain, textvariable=self.menu,
- width=30)
- self.entryMenu.focus_set()
- labelPath = Label(self.frameMain, anchor=W, justify=LEFT,
- text='Help File Path: Enter URL or browse for file')
- self.entryPath = Entry(self.frameMain, textvariable=self.path,
- width=40)
- self.entryMenu.focus_set()
- labelMenu.pack(anchor=W, padx=5, pady=3)
- self.entryMenu.pack(anchor=W, padx=5, pady=3)
- labelPath.pack(anchor=W, padx=5, pady=3)
- self.entryPath.pack(anchor=W, padx=5, pady=3)
- browseButton = Button(self.frameMain, text='Browse', width=8,
- command=self.browseFile)
- browseButton.pack(pady=3)
- frameButtons = Frame(self)
- frameButtons.pack(side=BOTTOM, fill=X)
- self.buttonOk = Button(frameButtons, text='OK',
- width=8, default=ACTIVE, command=self.Ok)
- self.buttonOk.grid(row=0, column=0, padx=5,pady=5)
- self.buttonCancel = Button(frameButtons, text='Cancel',
- width=8, command=self.Cancel)
- self.buttonCancel.grid(row=0, column=1, padx=5, pady=5)
-
- def browseFile(self):
- filetypes = [
- ("HTML Files", "*.htm *.html", "TEXT"),
- ("PDF Files", "*.pdf", "TEXT"),
- ("Windows Help Files", "*.chm"),
- ("Text Files", "*.txt", "TEXT"),
- ("All Files", "*")]
- path = self.path.get()
- if path:
- dir, base = os.path.split(path)
- else:
- base = None
- if sys.platform[:3] == 'win':
- dir = os.path.join(os.path.dirname(sys.executable), 'Doc')
- if not os.path.isdir(dir):
- dir = os.getcwd()
- else:
- dir = os.getcwd()
- opendialog = tkFileDialog.Open(parent=self, filetypes=filetypes)
- file = opendialog.show(initialdir=dir, initialfile=base)
- if file:
- self.path.set(file)
-
- def MenuOk(self):
- "Simple validity check for a sensible menu item name"
- menuOk = True
- menu = self.menu.get()
- menu.strip()
- if not menu:
- tkMessageBox.showerror(title='Menu Item Error',
- message='No menu item specified',
- parent=self)
- self.entryMenu.focus_set()
- menuOk = False
- elif len(menu) > 30:
- tkMessageBox.showerror(title='Menu Item Error',
- message='Menu item too long:'
- '\nLimit 30 characters.',
- parent=self)
- self.entryMenu.focus_set()
- menuOk = False
- return menuOk
-
- def PathOk(self):
- "Simple validity check for menu file path"
- pathOk = True
- path = self.path.get()
- path.strip()
- if not path: #no path specified
- tkMessageBox.showerror(title='File Path Error',
- message='No help file path specified.',
- parent=self)
- self.entryPath.focus_set()
- pathOk = False
- elif path.startswith(('www.', 'http')):
- pass
- else:
- if path[:5] == 'file:':
- path = path[5:]
- if not os.path.exists(path):
- tkMessageBox.showerror(title='File Path Error',
- message='Help file path does not exist.',
- parent=self)
- self.entryPath.focus_set()
- pathOk = False
- return pathOk
-
- def Ok(self, event=None):
- if self.MenuOk() and self.PathOk():
- self.result = (self.menu.get().strip(),
- self.path.get().strip())
- if sys.platform == 'darwin':
- path = self.result[1]
- if path.startswith(('www', 'file:', 'http:')):
- pass
- else:
- # Mac Safari insists on using the URI form for local files
- self.result = list(self.result)
- self.result[1] = "file://" + path
- self.destroy()
-
- def Cancel(self, event=None):
- self.result = None
- self.destroy()
-
-if __name__ == '__main__':
- #test the dialog
- root = Tk()
- def run():
- keySeq = ''
- dlg = GetHelpSourceDialog(root, 'Get Help Source')
- print dlg.result
- Button(root,text='Dialog', command=run).pack()
- root.mainloop()
diff --git a/sys/lib/python/idlelib/configSectionNameDialog.py b/sys/lib/python/idlelib/configSectionNameDialog.py
deleted file mode 100644
index 4f1b002af..000000000
--- a/sys/lib/python/idlelib/configSectionNameDialog.py
+++ /dev/null
@@ -1,97 +0,0 @@
-"""
-Dialog that allows user to specify a new config file section name.
-Used to get new highlight theme and keybinding set names.
-"""
-from Tkinter import *
-import tkMessageBox
-
-class GetCfgSectionNameDialog(Toplevel):
- def __init__(self,parent,title,message,usedNames):
- """
- message - string, informational message to display
- usedNames - list, list of names already in use for validity check
- """
- Toplevel.__init__(self, parent)
- self.configure(borderwidth=5)
- self.resizable(height=FALSE,width=FALSE)
- self.title(title)
- self.transient(parent)
- self.grab_set()
- self.protocol("WM_DELETE_WINDOW", self.Cancel)
- self.parent = parent
- self.message=message
- self.usedNames=usedNames
- self.result=''
- self.CreateWidgets()
- self.withdraw() #hide while setting geometry
- self.update_idletasks()
- #needs to be done here so that the winfo_reqwidth is valid
- self.messageInfo.config(width=self.frameMain.winfo_reqwidth())
- self.geometry("+%d+%d" %
- ((parent.winfo_rootx()+((parent.winfo_width()/2)
- -(self.winfo_reqwidth()/2)),
- parent.winfo_rooty()+((parent.winfo_height()/2)
- -(self.winfo_reqheight()/2)) )) ) #centre dialog over parent
- self.deiconify() #geometry set, unhide
- self.wait_window()
-
- def CreateWidgets(self):
- self.name=StringVar(self)
- self.fontSize=StringVar(self)
- self.frameMain = Frame(self,borderwidth=2,relief=SUNKEN)
- self.frameMain.pack(side=TOP,expand=TRUE,fill=BOTH)
- self.messageInfo=Message(self.frameMain,anchor=W,justify=LEFT,padx=5,pady=5,
- text=self.message)#,aspect=200)
- entryName=Entry(self.frameMain,textvariable=self.name,width=30)
- entryName.focus_set()
- self.messageInfo.pack(padx=5,pady=5)#,expand=TRUE,fill=BOTH)
- entryName.pack(padx=5,pady=5)
- frameButtons=Frame(self)
- frameButtons.pack(side=BOTTOM,fill=X)
- self.buttonOk = Button(frameButtons,text='Ok',
- width=8,command=self.Ok)
- self.buttonOk.grid(row=0,column=0,padx=5,pady=5)
- self.buttonCancel = Button(frameButtons,text='Cancel',
- width=8,command=self.Cancel)
- self.buttonCancel.grid(row=0,column=1,padx=5,pady=5)
-
- def NameOk(self):
- #simple validity check for a sensible
- #ConfigParser file section name
- nameOk=1
- name=self.name.get()
- name.strip()
- if not name: #no name specified
- tkMessageBox.showerror(title='Name Error',
- message='No name specified.', parent=self)
- nameOk=0
- elif len(name)>30: #name too long
- tkMessageBox.showerror(title='Name Error',
- message='Name too long. It should be no more than '+
- '30 characters.', parent=self)
- nameOk=0
- elif name in self.usedNames:
- tkMessageBox.showerror(title='Name Error',
- message='This name is already in use.', parent=self)
- nameOk=0
- return nameOk
-
- def Ok(self, event=None):
- if self.NameOk():
- self.result=self.name.get().strip()
- self.destroy()
-
- def Cancel(self, event=None):
- self.result=''
- self.destroy()
-
-if __name__ == '__main__':
- #test the dialog
- root=Tk()
- def run():
- keySeq=''
- dlg=GetCfgSectionNameDialog(root,'Get Name',
- 'The information here should need to be word wrapped. Test.')
- print dlg.result
- Button(root,text='Dialog',command=run).pack()
- root.mainloop()
diff --git a/sys/lib/python/idlelib/dynOptionMenuWidget.py b/sys/lib/python/idlelib/dynOptionMenuWidget.py
deleted file mode 100644
index e81f7babe..000000000
--- a/sys/lib/python/idlelib/dynOptionMenuWidget.py
+++ /dev/null
@@ -1,35 +0,0 @@
-"""
-OptionMenu widget modified to allow dynamic menu reconfiguration
-and setting of highlightthickness
-"""
-from Tkinter import OptionMenu
-from Tkinter import _setit
-import copy
-
-class DynOptionMenu(OptionMenu):
- """
- unlike OptionMenu, our kwargs can include highlightthickness
- """
- def __init__(self, master, variable, value, *values, **kwargs):
- #get a copy of kwargs before OptionMenu.__init__ munges them
- kwargsCopy=copy.copy(kwargs)
- if 'highlightthickness' in kwargs.keys():
- del(kwargs['highlightthickness'])
- OptionMenu.__init__(self, master, variable, value, *values, **kwargs)
- self.config(highlightthickness=kwargsCopy.get('highlightthickness'))
- #self.menu=self['menu']
- self.variable=variable
- self.command=kwargs.get('command')
-
- def SetMenu(self,valueList,value=None):
- """
- clear and reload the menu with a new set of options.
- valueList - list of new options
- value - initial value to set the optionmenu's menubutton to
- """
- self['menu'].delete(0,'end')
- for item in valueList:
- self['menu'].add_command(label=item,
- command=_setit(self.variable,item,self.command))
- if value:
- self.variable.set(value)
diff --git a/sys/lib/python/idlelib/extend.txt b/sys/lib/python/idlelib/extend.txt
deleted file mode 100644
index f5fb3e040..000000000
--- a/sys/lib/python/idlelib/extend.txt
+++ /dev/null
@@ -1,83 +0,0 @@
-Writing an IDLE extension
-=========================
-
-An IDLE extension can define new key bindings and menu entries for IDLE
-edit windows. There is a simple mechanism to load extensions when IDLE
-starts up and to attach them to each edit window. (It is also possible
-to make other changes to IDLE, but this must be done by editing the IDLE
-source code.)
-
-The list of extensions loaded at startup time is configured by editing
-the file config-extensions.def. See below for details.
-
-An IDLE extension is defined by a class. Methods of the class define
-actions that are invoked by event bindings or menu entries. Class (or
-instance) variables define the bindings and menu additions; these are
-automatically applied by IDLE when the extension is linked to an edit
-window.
-
-An IDLE extension class is instantiated with a single argument,
-`editwin', an EditorWindow instance. The extension cannot assume much
-about this argument, but it is guarateed to have the following instance
-variables:
-
- text a Text instance (a widget)
- io an IOBinding instance (more about this later)
- flist the FileList instance (shared by all edit windows)
-
-(There are a few more, but they are rarely useful.)
-
-The extension class must not directly bind Window Manager (e.g. X) events.
-Rather, it must define one or more virtual events, e.g. <<zoom-height>>, and
-corresponding methods, e.g. zoom_height_event(). The virtual events will be
-bound to the corresponding methods, and Window Manager events can then be bound
-to the virtual events. (This indirection is done so that the key bindings can
-easily be changed, and so that other sources of virtual events can exist, such
-as menu entries.)
-
-An extension can define menu entries. This is done with a class or instance
-variable named menudefs; it should be a list of pairs, where each pair is a
-menu name (lowercase) and a list of menu entries. Each menu entry is either
-None (to insert a separator entry) or a pair of strings (menu_label,
-virtual_event). Here, menu_label is the label of the menu entry, and
-virtual_event is the virtual event to be generated when the entry is selected.
-An underscore in the menu label is removed; the character following the
-underscore is displayed underlined, to indicate the shortcut character (for
-Windows).
-
-At the moment, extensions cannot define whole new menus; they must define
-entries in existing menus. Some menus are not present on some windows; such
-entry definitions are then ignored, but key bindings are still applied. (This
-should probably be refined in the future.)
-
-Extensions are not required to define menu entries for all the events they
-implement. (They are also not required to create keybindings, but in that
-case there must be empty bindings in cofig-extensions.def)
-
-Here is a complete example example:
-
-class ZoomHeight:
-
- menudefs = [
- ('edit', [
- None, # Separator
- ('_Zoom Height', '<<zoom-height>>'),
- ])
- ]
-
- def __init__(self, editwin):
- self.editwin = editwin
-
- def zoom_height_event(self, event):
- "...Do what you want here..."
-
-The final piece of the puzzle is the file "config-extensions.def", which is
-used to to configure the loading of extensions and to establish key (or, more
-generally, event) bindings to the virtual events defined in the extensions.
-
-See the comments at the top of config-extensions.def for information. It's
-currently necessary to manually modify that file to change IDLE's extension
-loading or extension key bindings.
-
-For further information on binding refer to the Tkinter Resources web page at
-python.org and to the Tk Command "bind" man page.
diff --git a/sys/lib/python/idlelib/help.txt b/sys/lib/python/idlelib/help.txt
deleted file mode 100644
index 6d2ba2fff..000000000
--- a/sys/lib/python/idlelib/help.txt
+++ /dev/null
@@ -1,213 +0,0 @@
-[See the end of this file for ** TIPS ** on using IDLE !!]
-
-Click on the dotted line at the top of a menu to "tear it off": a
-separate window containing the menu is created.
-
-File Menu:
-
- New Window -- Create a new editing window
- Open... -- Open an existing file
- Recent Files... -- Open a list of recent files
- Open Module... -- Open an existing module (searches sys.path)
- Class Browser -- Show classes and methods in current file
- Path Browser -- Show sys.path directories, modules, classes
- and methods
- ---
- Save -- Save current window to the associated file (unsaved
- windows have a * before and after the window title)
-
- Save As... -- Save current window to new file, which becomes
- the associated file
- Save Copy As... -- Save current window to different file
- without changing the associated file
- ---
- Print Window -- Print the current window
- ---
- Close -- Close current window (asks to save if unsaved)
- Exit -- Close all windows, quit (asks to save if unsaved)
-
-Edit Menu:
-
- Undo -- Undo last change to current window
- (A maximum of 1000 changes may be undone)
- Redo -- Redo last undone change to current window
- ---
- Cut -- Copy a selection into system-wide clipboard,
- then delete the selection
- Copy -- Copy selection into system-wide clipboard
- Paste -- Insert system-wide clipboard into window
- Select All -- Select the entire contents of the edit buffer
- ---
- Find... -- Open a search dialog box with many options
- Find Again -- Repeat last search
- Find Selection -- Search for the string in the selection
- Find in Files... -- Open a search dialog box for searching files
- Replace... -- Open a search-and-replace dialog box
- Go to Line -- Ask for a line number and show that line
- Expand Word -- Expand the word you have typed to match another
- word in the same buffer; repeat to get a
- different expansion
-
-Format Menu (only in Edit window):
-
- Indent Region -- Shift selected lines right 4 spaces
- Dedent Region -- Shift selected lines left 4 spaces
- Comment Out Region -- Insert ## in front of selected lines
- Uncomment Region -- Remove leading # or ## from selected lines
- Tabify Region -- Turns *leading* stretches of spaces into tabs
- (Note: We recommend using 4 space blocks to indent Python code.)
- Untabify Region -- Turn *all* tabs into the right number of spaces
- New Indent Width... -- Open dialog to change indent width
- Format Paragraph -- Reformat the current blank-line-separated
- paragraph
-
-Run Menu (only in Edit window):
-
- Python Shell -- Open or wake up the Python shell window
- ---
- Check Module -- Run a syntax check on the module
- Run Module -- Execute the current file in the __main__ namespace
-
-Shell Menu (only in Shell window):
-
- View Last Restart -- Scroll the shell window to the last restart
- Restart Shell -- Restart the interpreter with a fresh environment
-
-Debug Menu (only in Shell window):
-
- Go to File/Line -- look around the insert point for a filename
- and linenumber, open the file, and show the line
- Debugger (toggle) -- Run commands in the shell under the debugger
- Stack Viewer -- Show the stack traceback of the last exception
- Auto-open Stack Viewer (toggle) -- Open stack viewer on traceback
-
-Options Menu:
-
- Configure IDLE -- Open a configuration dialog. Fonts, indentation,
- keybindings, and color themes may be altered.
- Startup Preferences may be set, and Additional Help
- Souces can be specified.
- ---
- Code Context -- Open a pane at the top of the edit window which
- shows the block context of the section of code
- which is scrolling off the top or the window.
-
-Windows Menu:
-
- Zoom Height -- toggles the window between configured size
- and maximum height.
- ---
- The rest of this menu lists the names of all open windows;
- select one to bring it to the foreground (deiconifying it if
- necessary).
-
-Help Menu:
-
- About IDLE -- Version, copyright, license, credits
- IDLE Readme -- Background discussion and change details
- ---
- IDLE Help -- Display this file
- Python Docs -- Access local Python documentation, if
- installed. Otherwise, access www.python.org.
- ---
- (Additional Help Sources may be added here)
-
-
-** TIPS **
-==========
-
-Additional Help Sources:
-
- Windows users can Google on zopeshelf.chm to access Zope help files in
- the Windows help format. The Additional Help Sources feature of the
- configuration GUI supports .chm, along with any other filetypes
- supported by your browser. Supply a Menu Item title, and enter the
- location in the Help File Path slot of the New Help Source dialog. Use
- http:// and/or www. to identify external URLs, or download the file and
- browse for its path on your machine using the Browse button.
-
- All users can access the extensive sources of help, including
- tutorials, available at www.python.org/doc. Selected URLs can be added
- or removed from the Help menu at any time using Configure IDLE.
-
-Basic editing and navigation:
-
- Backspace deletes char to the left; DEL deletes char to the right.
- Control-backspace deletes word left, Control-DEL deletes word right.
- Arrow keys and Page Up/Down move around.
- Control-left/right Arrow moves by words in a strange but useful way.
- Home/End go to begin/end of line.
- Control-Home/End go to begin/end of file.
- Some useful Emacs bindings (Control-a, Control-e, Control-k, etc.)
- are inherited from Tcl/Tk.
- Standard Windows bindings may work on that platform.
- Keybindings are selected in the Settings Dialog, look there.
-
-Automatic indentation:
-
- After a block-opening statement, the next line is indented by 4 spaces
- (in the Python Shell window by one tab). After certain keywords
- (break, return etc.) the next line is dedented. In leading
- indentation, Backspace deletes up to 4 spaces if they are there. Tab
- inserts spaces (in the Python Shell window one tab), number depends on
- Indent Width. (N.B. Currently tabs are restricted to four spaces due
- to Tcl/Tk issues.)
-
- See also the indent/dedent region commands in the edit menu.
-
-Python Shell window:
-
- Control-c interrupts executing command.
- Control-d sends end-of-file; closes window if typed at >>> prompt
- (this is Control-z on Windows).
-
- Command history:
-
- Alt-p retrieves previous command matching what you have typed.
- Alt-n retrieves next.
- (These are Control-p, Control-n on the Mac)
- Return while cursor is on a previous command retrieves that command.
- Expand word is also useful to reduce typing.
-
- Syntax colors:
-
- The coloring is applied in a background "thread", so you may
- occasionally see uncolorized text. To change the color
- scheme, use the Configure IDLE / Highlighting dialog.
-
- Python default syntax colors:
-
- Keywords orange
- Builtins royal purple
- Strings green
- Comments red
- Definitions blue
-
- Shell default colors:
-
- Console output brown
- stdout blue
- stderr red
- stdin black
-
-Other preferences:
-
- The font preferences, keybinding, and startup preferences can
- be changed using the Settings dialog.
-
-Command line usage:
-
- Enter idle -h at the command prompt to get a usage message.
-
-Running without a subprocess:
-
- If IDLE is started with the -n command line switch it will run in a
- single process and will not create the subprocess which runs the RPC
- Python execution server. This can be useful if Python cannot create
- the subprocess or the RPC socket interface on your platform. However,
- in this mode user code is not isolated from IDLE itself. Also, the
- environment is not restarted when Run/Run Module (F5) is selected. If
- your code has been modified, you must reload() the affected modules and
- re-import any specific items (e.g. from foo import baz) if the changes
- are to take effect. For these reasons, it is preferable to run IDLE
- with the default subprocess if at all possible.
diff --git a/sys/lib/python/idlelib/idle.bat b/sys/lib/python/idlelib/idle.bat
deleted file mode 100755
index c1b5fd28a..000000000
--- a/sys/lib/python/idlelib/idle.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-@echo off
-rem Working IDLE bat for Windows - uses start instead of absolute pathname
-start idle.pyw %1 %2 %3 %4 %5 %6 %7 %8 %9
diff --git a/sys/lib/python/idlelib/idle.py b/sys/lib/python/idlelib/idle.py
deleted file mode 100644
index 537dd5a9a..000000000
--- a/sys/lib/python/idlelib/idle.py
+++ /dev/null
@@ -1,21 +0,0 @@
-try:
- import idlelib.PyShell
-except ImportError:
- # IDLE is not installed, but maybe PyShell is on sys.path:
- try:
- import PyShell
- except ImportError:
- raise
- else:
- import os
- idledir = os.path.dirname(os.path.abspath(PyShell.__file__))
- if idledir != os.getcwd():
- # We're not in the IDLE directory, help the subprocess find run.py
- pypath = os.environ.get('PYTHONPATH', '')
- if pypath:
- os.environ['PYTHONPATH'] = pypath + ':' + idledir
- else:
- os.environ['PYTHONPATH'] = idledir
- PyShell.main()
-else:
- idlelib.PyShell.main()
diff --git a/sys/lib/python/idlelib/idle.pyw b/sys/lib/python/idlelib/idle.pyw
deleted file mode 100644
index 537dd5a9a..000000000
--- a/sys/lib/python/idlelib/idle.pyw
+++ /dev/null
@@ -1,21 +0,0 @@
-try:
- import idlelib.PyShell
-except ImportError:
- # IDLE is not installed, but maybe PyShell is on sys.path:
- try:
- import PyShell
- except ImportError:
- raise
- else:
- import os
- idledir = os.path.dirname(os.path.abspath(PyShell.__file__))
- if idledir != os.getcwd():
- # We're not in the IDLE directory, help the subprocess find run.py
- pypath = os.environ.get('PYTHONPATH', '')
- if pypath:
- os.environ['PYTHONPATH'] = pypath + ':' + idledir
- else:
- os.environ['PYTHONPATH'] = idledir
- PyShell.main()
-else:
- idlelib.PyShell.main()
diff --git a/sys/lib/python/idlelib/idlever.py b/sys/lib/python/idlelib/idlever.py
deleted file mode 100644
index 9f7fb5a5b..000000000
--- a/sys/lib/python/idlelib/idlever.py
+++ /dev/null
@@ -1 +0,0 @@
-IDLE_VERSION = "1.2.1"
diff --git a/sys/lib/python/idlelib/keybindingDialog.py b/sys/lib/python/idlelib/keybindingDialog.py
deleted file mode 100644
index aff9cac58..000000000
--- a/sys/lib/python/idlelib/keybindingDialog.py
+++ /dev/null
@@ -1,268 +0,0 @@
-"""
-Dialog for building Tkinter accelerator key bindings
-"""
-from Tkinter import *
-import tkMessageBox
-import string, os
-
-class GetKeysDialog(Toplevel):
- def __init__(self,parent,title,action,currentKeySequences):
- """
- action - string, the name of the virtual event these keys will be
- mapped to
- currentKeys - list, a list of all key sequence lists currently mapped
- to virtual events, for overlap checking
- """
- Toplevel.__init__(self, parent)
- self.configure(borderwidth=5)
- self.resizable(height=FALSE,width=FALSE)
- self.title(title)
- self.transient(parent)
- self.grab_set()
- self.protocol("WM_DELETE_WINDOW", self.Cancel)
- self.parent = parent
- self.action=action
- self.currentKeySequences=currentKeySequences
- self.result=''
- self.keyString=StringVar(self)
- self.keyString.set('')
- self.SetModifiersForPlatform() # set self.modifiers, self.modifier_label
- self.modifier_vars = []
- for modifier in self.modifiers:
- variable = StringVar(self)
- variable.set('')
- self.modifier_vars.append(variable)
- self.advanced = False
- self.CreateWidgets()
- self.LoadFinalKeyList()
- self.withdraw() #hide while setting geometry
- self.update_idletasks()
- self.geometry("+%d+%d" %
- ((parent.winfo_rootx()+((parent.winfo_width()/2)
- -(self.winfo_reqwidth()/2)),
- parent.winfo_rooty()+((parent.winfo_height()/2)
- -(self.winfo_reqheight()/2)) )) ) #centre dialog over parent
- self.deiconify() #geometry set, unhide
- self.wait_window()
-
- def CreateWidgets(self):
- frameMain = Frame(self,borderwidth=2,relief=SUNKEN)
- frameMain.pack(side=TOP,expand=TRUE,fill=BOTH)
- frameButtons=Frame(self)
- frameButtons.pack(side=BOTTOM,fill=X)
- self.buttonOK = Button(frameButtons,text='OK',
- width=8,command=self.OK)
- self.buttonOK.grid(row=0,column=0,padx=5,pady=5)
- self.buttonCancel = Button(frameButtons,text='Cancel',
- width=8,command=self.Cancel)
- self.buttonCancel.grid(row=0,column=1,padx=5,pady=5)
- self.frameKeySeqBasic = Frame(frameMain)
- self.frameKeySeqAdvanced = Frame(frameMain)
- self.frameControlsBasic = Frame(frameMain)
- self.frameHelpAdvanced = Frame(frameMain)
- self.frameKeySeqAdvanced.grid(row=0,column=0,sticky=NSEW,padx=5,pady=5)
- self.frameKeySeqBasic.grid(row=0,column=0,sticky=NSEW,padx=5,pady=5)
- self.frameKeySeqBasic.lift()
- self.frameHelpAdvanced.grid(row=1,column=0,sticky=NSEW,padx=5)
- self.frameControlsBasic.grid(row=1,column=0,sticky=NSEW,padx=5)
- self.frameControlsBasic.lift()
- self.buttonLevel = Button(frameMain,command=self.ToggleLevel,
- text='Advanced Key Binding Entry >>')
- self.buttonLevel.grid(row=2,column=0,stick=EW,padx=5,pady=5)
- labelTitleBasic = Label(self.frameKeySeqBasic,
- text="New keys for '"+self.action+"' :")
- labelTitleBasic.pack(anchor=W)
- labelKeysBasic = Label(self.frameKeySeqBasic,justify=LEFT,
- textvariable=self.keyString,relief=GROOVE,borderwidth=2)
- labelKeysBasic.pack(ipadx=5,ipady=5,fill=X)
- self.modifier_checkbuttons = {}
- column = 0
- for modifier, variable in zip(self.modifiers, self.modifier_vars):
- label = self.modifier_label.get(modifier, modifier)
- check=Checkbutton(self.frameControlsBasic,
- command=self.BuildKeyString,
- text=label,variable=variable,onvalue=modifier,offvalue='')
- check.grid(row=0,column=column,padx=2,sticky=W)
- self.modifier_checkbuttons[modifier] = check
- column += 1
- labelFnAdvice=Label(self.frameControlsBasic,justify=LEFT,
- text=\
- "Select the desired modifier keys\n"+
- "above, and the final key from the\n"+
- "list on the right.\n\n" +
- "Use upper case Symbols when using\n" +
- "the Shift modifier. (Letters will be\n" +
- "converted automatically.)")
- labelFnAdvice.grid(row=1,column=0,columnspan=4,padx=2,sticky=W)
- self.listKeysFinal=Listbox(self.frameControlsBasic,width=15,height=10,
- selectmode=SINGLE)
- self.listKeysFinal.bind('<ButtonRelease-1>',self.FinalKeySelected)
- self.listKeysFinal.grid(row=0,column=4,rowspan=4,sticky=NS)
- scrollKeysFinal=Scrollbar(self.frameControlsBasic,orient=VERTICAL,
- command=self.listKeysFinal.yview)
- self.listKeysFinal.config(yscrollcommand=scrollKeysFinal.set)
- scrollKeysFinal.grid(row=0,column=5,rowspan=4,sticky=NS)
- self.buttonClear=Button(self.frameControlsBasic,
- text='Clear Keys',command=self.ClearKeySeq)
- self.buttonClear.grid(row=2,column=0,columnspan=4)
- labelTitleAdvanced = Label(self.frameKeySeqAdvanced,justify=LEFT,
- text="Enter new binding(s) for '"+self.action+"' :\n"+
- "(These bindings will not be checked for validity!)")
- labelTitleAdvanced.pack(anchor=W)
- self.entryKeysAdvanced=Entry(self.frameKeySeqAdvanced,
- textvariable=self.keyString)
- self.entryKeysAdvanced.pack(fill=X)
- labelHelpAdvanced=Label(self.frameHelpAdvanced,justify=LEFT,
- text="Key bindings are specified using Tkinter keysyms as\n"+
- "in these samples: <Control-f>, <Shift-F2>, <F12>,\n"
- "<Control-space>, <Meta-less>, <Control-Alt-Shift-X>.\n"
- "Upper case is used when the Shift modifier is present!\n\n" +
- "'Emacs style' multi-keystroke bindings are specified as\n" +
- "follows: <Control-x><Control-y>, where the first key\n" +
- "is the 'do-nothing' keybinding.\n\n" +
- "Multiple separate bindings for one action should be\n"+
- "separated by a space, eg., <Alt-v> <Meta-v>." )
- labelHelpAdvanced.grid(row=0,column=0,sticky=NSEW)
-
- def SetModifiersForPlatform(self):
- """Determine list of names of key modifiers for this platform.
-
- The names are used to build Tk bindings -- it doesn't matter if the
- keyboard has these keys, it matters if Tk understands them. The
- order is also important: key binding equality depends on it, so
- config-keys.def must use the same ordering.
- """
- import sys
- if sys.platform == 'darwin' and sys.argv[0].count('.app'):
- self.modifiers = ['Shift', 'Control', 'Option', 'Command']
- else:
- self.modifiers = ['Control', 'Alt', 'Shift']
- self.modifier_label = {'Control': 'Ctrl'} # short name
-
- def ToggleLevel(self):
- if self.buttonLevel.cget('text')[:8]=='Advanced':
- self.ClearKeySeq()
- self.buttonLevel.config(text='<< Basic Key Binding Entry')
- self.frameKeySeqAdvanced.lift()
- self.frameHelpAdvanced.lift()
- self.entryKeysAdvanced.focus_set()
- self.advanced = True
- else:
- self.ClearKeySeq()
- self.buttonLevel.config(text='Advanced Key Binding Entry >>')
- self.frameKeySeqBasic.lift()
- self.frameControlsBasic.lift()
- self.advanced = False
-
- def FinalKeySelected(self,event):
- self.BuildKeyString()
-
- def BuildKeyString(self):
- keyList = modifiers = self.GetModifiers()
- finalKey = self.listKeysFinal.get(ANCHOR)
- if finalKey:
- finalKey = self.TranslateKey(finalKey, modifiers)
- keyList.append(finalKey)
- self.keyString.set('<' + string.join(keyList,'-') + '>')
-
- def GetModifiers(self):
- modList = [variable.get() for variable in self.modifier_vars]
- return filter(None, modList)
-
- def ClearKeySeq(self):
- self.listKeysFinal.select_clear(0,END)
- self.listKeysFinal.yview(MOVETO, '0.0')
- for variable in self.modifier_vars:
- variable.set('')
- self.keyString.set('')
-
- def LoadFinalKeyList(self):
- #these tuples are also available for use in validity checks
- self.functionKeys=('F1','F2','F2','F4','F5','F6','F7','F8','F9',
- 'F10','F11','F12')
- self.alphanumKeys=tuple(string.ascii_lowercase+string.digits)
- self.punctuationKeys=tuple('~!@#%^&*()_-+={}[]|;:,.<>/?')
- self.whitespaceKeys=('Tab','Space','Return')
- self.editKeys=('BackSpace','Delete','Insert')
- self.moveKeys=('Home','End','Page Up','Page Down','Left Arrow',
- 'Right Arrow','Up Arrow','Down Arrow')
- #make a tuple of most of the useful common 'final' keys
- keys=(self.alphanumKeys+self.punctuationKeys+self.functionKeys+
- self.whitespaceKeys+self.editKeys+self.moveKeys)
- self.listKeysFinal.insert(END, *keys)
-
- def TranslateKey(self, key, modifiers):
- "Translate from keycap symbol to the Tkinter keysym"
- translateDict = {'Space':'space',
- '~':'asciitilde','!':'exclam','@':'at','#':'numbersign',
- '%':'percent','^':'asciicircum','&':'ampersand','*':'asterisk',
- '(':'parenleft',')':'parenright','_':'underscore','-':'minus',
- '+':'plus','=':'equal','{':'braceleft','}':'braceright',
- '[':'bracketleft',']':'bracketright','|':'bar',';':'semicolon',
- ':':'colon',',':'comma','.':'period','<':'less','>':'greater',
- '/':'slash','?':'question','Page Up':'Prior','Page Down':'Next',
- 'Left Arrow':'Left','Right Arrow':'Right','Up Arrow':'Up',
- 'Down Arrow': 'Down', 'Tab':'Tab'}
- if key in translateDict.keys():
- key = translateDict[key]
- if 'Shift' in modifiers and key in string.ascii_lowercase:
- key = key.upper()
- key = 'Key-' + key
- return key
-
- def OK(self, event=None):
- if self.advanced or self.KeysOK(): # doesn't check advanced string yet
- self.result=self.keyString.get()
- self.destroy()
-
- def Cancel(self, event=None):
- self.result=''
- self.destroy()
-
- def KeysOK(self):
- '''Validity check on user's 'basic' keybinding selection.
-
- Doesn't check the string produced by the advanced dialog because
- 'modifiers' isn't set.
-
- '''
- keys = self.keyString.get()
- keys.strip()
- finalKey = self.listKeysFinal.get(ANCHOR)
- modifiers = self.GetModifiers()
- # create a key sequence list for overlap check:
- keySequence = keys.split()
- keysOK = False
- title = 'Key Sequence Error'
- if not keys:
- tkMessageBox.showerror(title=title, parent=self,
- message='No keys specified.')
- elif not keys.endswith('>'):
- tkMessageBox.showerror(title=title, parent=self,
- message='Missing the final Key')
- elif (not modifiers
- and finalKey not in self.functionKeys + self.moveKeys):
- tkMessageBox.showerror(title=title, parent=self,
- message='No modifier key(s) specified.')
- elif (modifiers == ['Shift']) \
- and (finalKey not in
- self.functionKeys + self.moveKeys + ('Tab', 'Space')):
- msg = 'The shift modifier by itself may not be used with'\
- ' this key symbol.'
- tkMessageBox.showerror(title=title, parent=self, message=msg)
- elif keySequence in self.currentKeySequences:
- msg = 'This key combination is already in use.'
- tkMessageBox.showerror(title=title, parent=self, message=msg)
- else:
- keysOK = True
- return keysOK
-
-if __name__ == '__main__':
- #test the dialog
- root=Tk()
- def run():
- keySeq=''
- dlg=GetKeysDialog(root,'Get Keys','find-again',[])
- print dlg.result
- Button(root,text='Dialog',command=run).pack()
- root.mainloop()
diff --git a/sys/lib/python/idlelib/macosxSupport.py b/sys/lib/python/idlelib/macosxSupport.py
deleted file mode 100644
index ad61fff46..000000000
--- a/sys/lib/python/idlelib/macosxSupport.py
+++ /dev/null
@@ -1,112 +0,0 @@
-"""
-A number of function that enhance IDLE on MacOSX when it used as a normal
-GUI application (as opposed to an X11 application).
-"""
-import sys
-
-def runningAsOSXApp():
- """ Returns True iff running from the IDLE.app bundle on OSX """
- return (sys.platform == 'darwin' and 'IDLE.app' in sys.argv[0])
-
-def addOpenEventSupport(root, flist):
- """
- This ensures that the application will respont to open AppleEvents, which
- makes is feaseable to use IDLE as the default application for python files.
- """
- def doOpenFile(*args):
- for fn in args:
- flist.open(fn)
-
- # The command below is a hook in aquatk that is called whenever the app
- # receives a file open event. The callback can have multiple arguments,
- # one for every file that should be opened.
- root.createcommand("::tk::mac::OpenDocument", doOpenFile)
-
-def hideTkConsole(root):
- root.tk.call('console', 'hide')
-
-def overrideRootMenu(root, flist):
- """
- Replace the Tk root menu by something that's more appropriate for
- IDLE.
- """
- # The menu that is attached to the Tk root (".") is also used by AquaTk for
- # all windows that don't specify a menu of their own. The default menubar
- # contains a number of menus, none of which are appropriate for IDLE. The
- # Most annoying of those is an 'About Tck/Tk...' menu in the application
- # menu.
- #
- # This function replaces the default menubar by a mostly empty one, it
- # should only contain the correct application menu and the window menu.
- #
- # Due to a (mis-)feature of TkAqua the user will also see an empty Help
- # menu.
- from Tkinter import Menu, Text, Text
- from EditorWindow import prepstr, get_accelerator
- import Bindings
- import WindowList
- from MultiCall import MultiCallCreator
-
- menubar = Menu(root)
- root.configure(menu=menubar)
- menudict = {}
-
- menudict['windows'] = menu = Menu(menubar, name='windows')
- menubar.add_cascade(label='Window', menu=menu, underline=0)
-
- def postwindowsmenu(menu=menu):
- end = menu.index('end')
- if end is None:
- end = -1
-
- if end > 0:
- menu.delete(0, end)
- WindowList.add_windows_to_menu(menu)
- WindowList.register_callback(postwindowsmenu)
-
- menudict['application'] = menu = Menu(menubar, name='apple')
- menubar.add_cascade(label='IDLE', menu=menu)
-
- def about_dialog(event=None):
- import aboutDialog
- aboutDialog.AboutDialog(root, 'About IDLE')
-
- def config_dialog(event=None):
- import configDialog
- configDialog.ConfigDialog(root, 'Settings')
-
- root.bind('<<about-idle>>', about_dialog)
- root.bind('<<open-config-dialog>>', config_dialog)
- if flist:
- root.bind('<<close-all-windows>>', flist.close_all_callback)
-
- for mname, entrylist in Bindings.menudefs:
- menu = menudict.get(mname)
- if not menu:
- continue
- for entry in entrylist:
- if not entry:
- menu.add_separator()
- else:
- label, eventname = entry
- underline, label = prepstr(label)
- accelerator = get_accelerator(Bindings.default_keydefs,
- eventname)
- def command(text=root, eventname=eventname):
- text.event_generate(eventname)
- menu.add_command(label=label, underline=underline,
- command=command, accelerator=accelerator)
-
-
-
-
-
-def setupApp(root, flist):
- """
- Perform setup for the OSX application bundle.
- """
- if not runningAsOSXApp(): return
-
- hideTkConsole(root)
- overrideRootMenu(root, flist)
- addOpenEventSupport(root, flist)
diff --git a/sys/lib/python/idlelib/rpc.py b/sys/lib/python/idlelib/rpc.py
deleted file mode 100644
index 3bac6a30b..000000000
--- a/sys/lib/python/idlelib/rpc.py
+++ /dev/null
@@ -1,602 +0,0 @@
-"""RPC Implemention, originally written for the Python Idle IDE
-
-For security reasons, GvR requested that Idle's Python execution server process
-connect to the Idle process, which listens for the connection. Since Idle has
-has only one client per server, this was not a limitation.
-
- +---------------------------------+ +-------------+
- | SocketServer.BaseRequestHandler | | SocketIO |
- +---------------------------------+ +-------------+
- ^ | register() |
- | | unregister()|
- | +-------------+
- | ^ ^
- | | |
- | + -------------------+ |
- | | |
- +-------------------------+ +-----------------+
- | RPCHandler | | RPCClient |
- | [attribute of RPCServer]| | |
- +-------------------------+ +-----------------+
-
-The RPCServer handler class is expected to provide register/unregister methods.
-RPCHandler inherits the mix-in class SocketIO, which provides these methods.
-
-See the Idle run.main() docstring for further information on how this was
-accomplished in Idle.
-
-"""
-
-import sys
-import os
-import socket
-import select
-import SocketServer
-import struct
-import cPickle as pickle
-import threading
-import Queue
-import traceback
-import copy_reg
-import types
-import marshal
-
-
-def unpickle_code(ms):
- co = marshal.loads(ms)
- assert isinstance(co, types.CodeType)
- return co
-
-def pickle_code(co):
- assert isinstance(co, types.CodeType)
- ms = marshal.dumps(co)
- return unpickle_code, (ms,)
-
-# XXX KBK 24Aug02 function pickling capability not used in Idle
-# def unpickle_function(ms):
-# return ms
-
-# def pickle_function(fn):
-# assert isinstance(fn, type.FunctionType)
-# return repr(fn)
-
-copy_reg.pickle(types.CodeType, pickle_code, unpickle_code)
-# copy_reg.pickle(types.FunctionType, pickle_function, unpickle_function)
-
-BUFSIZE = 8*1024
-LOCALHOST = '127.0.0.1'
-
-class RPCServer(SocketServer.TCPServer):
-
- def __init__(self, addr, handlerclass=None):
- if handlerclass is None:
- handlerclass = RPCHandler
- SocketServer.TCPServer.__init__(self, addr, handlerclass)
-
- def server_bind(self):
- "Override TCPServer method, no bind() phase for connecting entity"
- pass
-
- def server_activate(self):
- """Override TCPServer method, connect() instead of listen()
-
- Due to the reversed connection, self.server_address is actually the
- address of the Idle Client to which we are connecting.
-
- """
- self.socket.connect(self.server_address)
-
- def get_request(self):
- "Override TCPServer method, return already connected socket"
- return self.socket, self.server_address
-
- def handle_error(self, request, client_address):
- """Override TCPServer method
-
- Error message goes to __stderr__. No error message if exiting
- normally or socket raised EOF. Other exceptions not handled in
- server code will cause os._exit.
-
- """
- try:
- raise
- except SystemExit:
- raise
- except:
- erf = sys.__stderr__
- print>>erf, '\n' + '-'*40
- print>>erf, 'Unhandled server exception!'
- print>>erf, 'Thread: %s' % threading.currentThread().getName()
- print>>erf, 'Client Address: ', client_address
- print>>erf, 'Request: ', repr(request)
- traceback.print_exc(file=erf)
- print>>erf, '\n*** Unrecoverable, server exiting!'
- print>>erf, '-'*40
- os._exit(0)
-
-#----------------- end class RPCServer --------------------
-
-objecttable = {}
-request_queue = Queue.Queue(0)
-response_queue = Queue.Queue(0)
-
-
-class SocketIO(object):
-
- nextseq = 0
-
- def __init__(self, sock, objtable=None, debugging=None):
- self.sockthread = threading.currentThread()
- if debugging is not None:
- self.debugging = debugging
- self.sock = sock
- if objtable is None:
- objtable = objecttable
- self.objtable = objtable
- self.responses = {}
- self.cvars = {}
-
- def close(self):
- sock = self.sock
- self.sock = None
- if sock is not None:
- sock.close()
-
- def exithook(self):
- "override for specific exit action"
- os._exit()
-
- def debug(self, *args):
- if not self.debugging:
- return
- s = self.location + " " + str(threading.currentThread().getName())
- for a in args:
- s = s + " " + str(a)
- print>>sys.__stderr__, s
-
- def register(self, oid, object):
- self.objtable[oid] = object
-
- def unregister(self, oid):
- try:
- del self.objtable[oid]
- except KeyError:
- pass
-
- def localcall(self, seq, request):
- self.debug("localcall:", request)
- try:
- how, (oid, methodname, args, kwargs) = request
- except TypeError:
- return ("ERROR", "Bad request format")
- if not self.objtable.has_key(oid):
- return ("ERROR", "Unknown object id: %r" % (oid,))
- obj = self.objtable[oid]
- if methodname == "__methods__":
- methods = {}
- _getmethods(obj, methods)
- return ("OK", methods)
- if methodname == "__attributes__":
- attributes = {}
- _getattributes(obj, attributes)
- return ("OK", attributes)
- if not hasattr(obj, methodname):
- return ("ERROR", "Unsupported method name: %r" % (methodname,))
- method = getattr(obj, methodname)
- try:
- if how == 'CALL':
- ret = method(*args, **kwargs)
- if isinstance(ret, RemoteObject):
- ret = remoteref(ret)
- return ("OK", ret)
- elif how == 'QUEUE':
- request_queue.put((seq, (method, args, kwargs)))
- return("QUEUED", None)
- else:
- return ("ERROR", "Unsupported message type: %s" % how)
- except SystemExit:
- raise
- except socket.error:
- raise
- except:
- msg = "*** Internal Error: rpc.py:SocketIO.localcall()\n\n"\
- " Object: %s \n Method: %s \n Args: %s\n"
- print>>sys.__stderr__, msg % (oid, method, args)
- traceback.print_exc(file=sys.__stderr__)
- return ("EXCEPTION", None)
-
- def remotecall(self, oid, methodname, args, kwargs):
- self.debug("remotecall:asynccall: ", oid, methodname)
- seq = self.asynccall(oid, methodname, args, kwargs)
- return self.asyncreturn(seq)
-
- def remotequeue(self, oid, methodname, args, kwargs):
- self.debug("remotequeue:asyncqueue: ", oid, methodname)
- seq = self.asyncqueue(oid, methodname, args, kwargs)
- return self.asyncreturn(seq)
-
- def asynccall(self, oid, methodname, args, kwargs):
- request = ("CALL", (oid, methodname, args, kwargs))
- seq = self.newseq()
- if threading.currentThread() != self.sockthread:
- cvar = threading.Condition()
- self.cvars[seq] = cvar
- self.debug(("asynccall:%d:" % seq), oid, methodname, args, kwargs)
- self.putmessage((seq, request))
- return seq
-
- def asyncqueue(self, oid, methodname, args, kwargs):
- request = ("QUEUE", (oid, methodname, args, kwargs))
- seq = self.newseq()
- if threading.currentThread() != self.sockthread:
- cvar = threading.Condition()
- self.cvars[seq] = cvar
- self.debug(("asyncqueue:%d:" % seq), oid, methodname, args, kwargs)
- self.putmessage((seq, request))
- return seq
-
- def asyncreturn(self, seq):
- self.debug("asyncreturn:%d:call getresponse(): " % seq)
- response = self.getresponse(seq, wait=0.05)
- self.debug(("asyncreturn:%d:response: " % seq), response)
- return self.decoderesponse(response)
-
- def decoderesponse(self, response):
- how, what = response
- if how == "OK":
- return what
- if how == "QUEUED":
- return None
- if how == "EXCEPTION":
- self.debug("decoderesponse: EXCEPTION")
- return None
- if how == "EOF":
- self.debug("decoderesponse: EOF")
- self.decode_interrupthook()
- return None
- if how == "ERROR":
- self.debug("decoderesponse: Internal ERROR:", what)
- raise RuntimeError, what
- raise SystemError, (how, what)
-
- def decode_interrupthook(self):
- ""
- raise EOFError
-
- def mainloop(self):
- """Listen on socket until I/O not ready or EOF
-
- pollresponse() will loop looking for seq number None, which
- never comes, and exit on EOFError.
-
- """
- try:
- self.getresponse(myseq=None, wait=0.05)
- except EOFError:
- self.debug("mainloop:return")
- return
-
- def getresponse(self, myseq, wait):
- response = self._getresponse(myseq, wait)
- if response is not None:
- how, what = response
- if how == "OK":
- response = how, self._proxify(what)
- return response
-
- def _proxify(self, obj):
- if isinstance(obj, RemoteProxy):
- return RPCProxy(self, obj.oid)
- if isinstance(obj, types.ListType):
- return map(self._proxify, obj)
- # XXX Check for other types -- not currently needed
- return obj
-
- def _getresponse(self, myseq, wait):
- self.debug("_getresponse:myseq:", myseq)
- if threading.currentThread() is self.sockthread:
- # this thread does all reading of requests or responses
- while 1:
- response = self.pollresponse(myseq, wait)
- if response is not None:
- return response
- else:
- # wait for notification from socket handling thread
- cvar = self.cvars[myseq]
- cvar.acquire()
- while not self.responses.has_key(myseq):
- cvar.wait()
- response = self.responses[myseq]
- self.debug("_getresponse:%s: thread woke up: response: %s" %
- (myseq, response))
- del self.responses[myseq]
- del self.cvars[myseq]
- cvar.release()
- return response
-
- def newseq(self):
- self.nextseq = seq = self.nextseq + 2
- return seq
-
- def putmessage(self, message):
- self.debug("putmessage:%d:" % message[0])
- try:
- s = pickle.dumps(message)
- except pickle.PicklingError:
- print >>sys.__stderr__, "Cannot pickle:", repr(message)
- raise
- s = struct.pack("<i", len(s)) + s
- while len(s) > 0:
- try:
- r, w, x = select.select([], [self.sock], [])
- n = self.sock.send(s[:BUFSIZE])
- except (AttributeError, TypeError):
- raise IOError, "socket no longer exists"
- except socket.error:
- raise
- else:
- s = s[n:]
-
- buffer = ""
- bufneed = 4
- bufstate = 0 # meaning: 0 => reading count; 1 => reading data
-
- def pollpacket(self, wait):
- self._stage0()
- if len(self.buffer) < self.bufneed:
- r, w, x = select.select([self.sock.fileno()], [], [], wait)
- if len(r) == 0:
- return None
- try:
- s = self.sock.recv(BUFSIZE)
- except socket.error:
- raise EOFError
- if len(s) == 0:
- raise EOFError
- self.buffer += s
- self._stage0()
- return self._stage1()
-
- def _stage0(self):
- if self.bufstate == 0 and len(self.buffer) >= 4:
- s = self.buffer[:4]
- self.buffer = self.buffer[4:]
- self.bufneed = struct.unpack("<i", s)[0]
- self.bufstate = 1
-
- def _stage1(self):
- if self.bufstate == 1 and len(self.buffer) >= self.bufneed:
- packet = self.buffer[:self.bufneed]
- self.buffer = self.buffer[self.bufneed:]
- self.bufneed = 4
- self.bufstate = 0
- return packet
-
- def pollmessage(self, wait):
- packet = self.pollpacket(wait)
- if packet is None:
- return None
- try:
- message = pickle.loads(packet)
- except pickle.UnpicklingError:
- print >>sys.__stderr__, "-----------------------"
- print >>sys.__stderr__, "cannot unpickle packet:", repr(packet)
- traceback.print_stack(file=sys.__stderr__)
- print >>sys.__stderr__, "-----------------------"
- raise
- return message
-
- def pollresponse(self, myseq, wait):
- """Handle messages received on the socket.
-
- Some messages received may be asynchronous 'call' or 'queue' requests,
- and some may be responses for other threads.
-
- 'call' requests are passed to self.localcall() with the expectation of
- immediate execution, during which time the socket is not serviced.
-
- 'queue' requests are used for tasks (which may block or hang) to be
- processed in a different thread. These requests are fed into
- request_queue by self.localcall(). Responses to queued requests are
- taken from response_queue and sent across the link with the associated
- sequence numbers. Messages in the queues are (sequence_number,
- request/response) tuples and code using this module removing messages
- from the request_queue is responsible for returning the correct
- sequence number in the response_queue.
-
- pollresponse() will loop until a response message with the myseq
- sequence number is received, and will save other responses in
- self.responses and notify the owning thread.
-
- """
- while 1:
- # send queued response if there is one available
- try:
- qmsg = response_queue.get(0)
- except Queue.Empty:
- pass
- else:
- seq, response = qmsg
- message = (seq, ('OK', response))
- self.putmessage(message)
- # poll for message on link
- try:
- message = self.pollmessage(wait)
- if message is None: # socket not ready
- return None
- except EOFError:
- self.handle_EOF()
- return None
- except AttributeError:
- return None
- seq, resq = message
- how = resq[0]
- self.debug("pollresponse:%d:myseq:%s" % (seq, myseq))
- # process or queue a request
- if how in ("CALL", "QUEUE"):
- self.debug("pollresponse:%d:localcall:call:" % seq)
- response = self.localcall(seq, resq)
- self.debug("pollresponse:%d:localcall:response:%s"
- % (seq, response))
- if how == "CALL":
- self.putmessage((seq, response))
- elif how == "QUEUE":
- # don't acknowledge the 'queue' request!
- pass
- continue
- # return if completed message transaction
- elif seq == myseq:
- return resq
- # must be a response for a different thread:
- else:
- cv = self.cvars.get(seq, None)
- # response involving unknown sequence number is discarded,
- # probably intended for prior incarnation of server
- if cv is not None:
- cv.acquire()
- self.responses[seq] = resq
- cv.notify()
- cv.release()
- continue
-
- def handle_EOF(self):
- "action taken upon link being closed by peer"
- self.EOFhook()
- self.debug("handle_EOF")
- for key in self.cvars:
- cv = self.cvars[key]
- cv.acquire()
- self.responses[key] = ('EOF', None)
- cv.notify()
- cv.release()
- # call our (possibly overridden) exit function
- self.exithook()
-
- def EOFhook(self):
- "Classes using rpc client/server can override to augment EOF action"
- pass
-
-#----------------- end class SocketIO --------------------
-
-class RemoteObject(object):
- # Token mix-in class
- pass
-
-def remoteref(obj):
- oid = id(obj)
- objecttable[oid] = obj
- return RemoteProxy(oid)
-
-class RemoteProxy(object):
-
- def __init__(self, oid):
- self.oid = oid
-
-class RPCHandler(SocketServer.BaseRequestHandler, SocketIO):
-
- debugging = False
- location = "#S" # Server
-
- def __init__(self, sock, addr, svr):
- svr.current_handler = self ## cgt xxx
- SocketIO.__init__(self, sock)
- SocketServer.BaseRequestHandler.__init__(self, sock, addr, svr)
-
- def handle(self):
- "handle() method required by SocketServer"
- self.mainloop()
-
- def get_remote_proxy(self, oid):
- return RPCProxy(self, oid)
-
-class RPCClient(SocketIO):
-
- debugging = False
- location = "#C" # Client
-
- nextseq = 1 # Requests coming from the client are odd numbered
-
- def __init__(self, address, family=socket.AF_INET, type=socket.SOCK_STREAM):
- self.listening_sock = socket.socket(family, type)
- self.listening_sock.setsockopt(socket.SOL_SOCKET,
- socket.SO_REUSEADDR, 1)
- self.listening_sock.bind(address)
- self.listening_sock.listen(1)
-
- def accept(self):
- working_sock, address = self.listening_sock.accept()
- if self.debugging:
- print>>sys.__stderr__, "****** Connection request from ", address
- if address[0] == LOCALHOST:
- SocketIO.__init__(self, working_sock)
- else:
- print>>sys.__stderr__, "** Invalid host: ", address
- raise socket.error
-
- def get_remote_proxy(self, oid):
- return RPCProxy(self, oid)
-
-class RPCProxy(object):
-
- __methods = None
- __attributes = None
-
- def __init__(self, sockio, oid):
- self.sockio = sockio
- self.oid = oid
-
- def __getattr__(self, name):
- if self.__methods is None:
- self.__getmethods()
- if self.__methods.get(name):
- return MethodProxy(self.sockio, self.oid, name)
- if self.__attributes is None:
- self.__getattributes()
- if self.__attributes.has_key(name):
- value = self.sockio.remotecall(self.oid, '__getattribute__',
- (name,), {})
- return value
- else:
- raise AttributeError, name
-
- def __getattributes(self):
- self.__attributes = self.sockio.remotecall(self.oid,
- "__attributes__", (), {})
-
- def __getmethods(self):
- self.__methods = self.sockio.remotecall(self.oid,
- "__methods__", (), {})
-
-def _getmethods(obj, methods):
- # Helper to get a list of methods from an object
- # Adds names to dictionary argument 'methods'
- for name in dir(obj):
- attr = getattr(obj, name)
- if callable(attr):
- methods[name] = 1
- if type(obj) == types.InstanceType:
- _getmethods(obj.__class__, methods)
- if type(obj) == types.ClassType:
- for super in obj.__bases__:
- _getmethods(super, methods)
-
-def _getattributes(obj, attributes):
- for name in dir(obj):
- attr = getattr(obj, name)
- if not callable(attr):
- attributes[name] = 1
-
-class MethodProxy(object):
-
- def __init__(self, sockio, oid, name):
- self.sockio = sockio
- self.oid = oid
- self.name = name
-
- def __call__(self, *args, **kwargs):
- value = self.sockio.remotecall(self.oid, self.name, args, kwargs)
- return value
-
-
-# XXX KBK 09Sep03 We need a proper unit test for this module. Previously
-# existing test code was removed at Rev 1.27.
diff --git a/sys/lib/python/idlelib/run.py b/sys/lib/python/idlelib/run.py
deleted file mode 100644
index ae810c4ec..000000000
--- a/sys/lib/python/idlelib/run.py
+++ /dev/null
@@ -1,327 +0,0 @@
-import sys
-import os
-import linecache
-import time
-import socket
-import traceback
-import thread
-import threading
-import Queue
-
-import CallTips
-import AutoComplete
-
-import RemoteDebugger
-import RemoteObjectBrowser
-import StackViewer
-import rpc
-
-import __main__
-
-LOCALHOST = '127.0.0.1'
-
-try:
- import warnings
-except ImportError:
- pass
-else:
- def idle_formatwarning_subproc(message, category, filename, lineno):
- """Format warnings the IDLE way"""
- s = "\nWarning (from warnings module):\n"
- s += ' File \"%s\", line %s\n' % (filename, lineno)
- line = linecache.getline(filename, lineno).strip()
- if line:
- s += " %s\n" % line
- s += "%s: %s\n" % (category.__name__, message)
- return s
- warnings.formatwarning = idle_formatwarning_subproc
-
-# Thread shared globals: Establish a queue between a subthread (which handles
-# the socket) and the main thread (which runs user code), plus global
-# completion and exit flags:
-
-exit_now = False
-quitting = False
-
-def main(del_exitfunc=False):
- """Start the Python execution server in a subprocess
-
- In the Python subprocess, RPCServer is instantiated with handlerclass
- MyHandler, which inherits register/unregister methods from RPCHandler via
- the mix-in class SocketIO.
-
- When the RPCServer 'server' is instantiated, the TCPServer initialization
- creates an instance of run.MyHandler and calls its handle() method.
- handle() instantiates a run.Executive object, passing it a reference to the
- MyHandler object. That reference is saved as attribute rpchandler of the
- Executive instance. The Executive methods have access to the reference and
- can pass it on to entities that they command
- (e.g. RemoteDebugger.Debugger.start_debugger()). The latter, in turn, can
- call MyHandler(SocketIO) register/unregister methods via the reference to
- register and unregister themselves.
-
- """
- global exit_now
- global quitting
- global no_exitfunc
- no_exitfunc = del_exitfunc
- port = 8833
- #time.sleep(15) # test subprocess not responding
- if sys.argv[1:]:
- port = int(sys.argv[1])
- sys.argv[:] = [""]
- sockthread = threading.Thread(target=manage_socket,
- name='SockThread',
- args=((LOCALHOST, port),))
- sockthread.setDaemon(True)
- sockthread.start()
- while 1:
- try:
- if exit_now:
- try:
- exit()
- except KeyboardInterrupt:
- # exiting but got an extra KBI? Try again!
- continue
- try:
- seq, request = rpc.request_queue.get(block=True, timeout=0.05)
- except Queue.Empty:
- continue
- method, args, kwargs = request
- ret = method(*args, **kwargs)
- rpc.response_queue.put((seq, ret))
- except KeyboardInterrupt:
- if quitting:
- exit_now = True
- continue
- except SystemExit:
- raise
- except:
- type, value, tb = sys.exc_info()
- try:
- print_exception()
- rpc.response_queue.put((seq, None))
- except:
- # Link didn't work, print same exception to __stderr__
- traceback.print_exception(type, value, tb, file=sys.__stderr__)
- exit()
- else:
- continue
-
-def manage_socket(address):
- for i in range(3):
- time.sleep(i)
- try:
- server = MyRPCServer(address, MyHandler)
- break
- except socket.error, err:
- print>>sys.__stderr__,"IDLE Subprocess: socket error: "\
- + err[1] + ", retrying...."
- else:
- print>>sys.__stderr__, "IDLE Subprocess: Connection to "\
- "IDLE GUI failed, exiting."
- show_socket_error(err, address)
- global exit_now
- exit_now = True
- return
- server.handle_request() # A single request only
-
-def show_socket_error(err, address):
- import Tkinter
- import tkMessageBox
- root = Tkinter.Tk()
- root.withdraw()
- if err[0] == 61: # connection refused
- msg = "IDLE's subprocess can't connect to %s:%d. This may be due "\
- "to your personal firewall configuration. It is safe to "\
- "allow this internal connection because no data is visible on "\
- "external ports." % address
- tkMessageBox.showerror("IDLE Subprocess Error", msg, parent=root)
- else:
- tkMessageBox.showerror("IDLE Subprocess Error", "Socket Error: %s" % err[1])
- root.destroy()
-
-def print_exception():
- import linecache
- linecache.checkcache()
- flush_stdout()
- efile = sys.stderr
- typ, val, tb = excinfo = sys.exc_info()
- sys.last_type, sys.last_value, sys.last_traceback = excinfo
- tbe = traceback.extract_tb(tb)
- print>>efile, '\nTraceback (most recent call last):'
- exclude = ("run.py", "rpc.py", "threading.py", "Queue.py",
- "RemoteDebugger.py", "bdb.py")
- cleanup_traceback(tbe, exclude)
- traceback.print_list(tbe, file=efile)
- lines = traceback.format_exception_only(typ, val)
- for line in lines:
- print>>efile, line,
-
-def cleanup_traceback(tb, exclude):
- "Remove excluded traces from beginning/end of tb; get cached lines"
- orig_tb = tb[:]
- while tb:
- for rpcfile in exclude:
- if tb[0][0].count(rpcfile):
- break # found an exclude, break for: and delete tb[0]
- else:
- break # no excludes, have left RPC code, break while:
- del tb[0]
- while tb:
- for rpcfile in exclude:
- if tb[-1][0].count(rpcfile):
- break
- else:
- break
- del tb[-1]
- if len(tb) == 0:
- # exception was in IDLE internals, don't prune!
- tb[:] = orig_tb[:]
- print>>sys.stderr, "** IDLE Internal Exception: "
- rpchandler = rpc.objecttable['exec'].rpchandler
- for i in range(len(tb)):
- fn, ln, nm, line = tb[i]
- if nm == '?':
- nm = "-toplevel-"
- if not line and fn.startswith("<pyshell#"):
- line = rpchandler.remotecall('linecache', 'getline',
- (fn, ln), {})
- tb[i] = fn, ln, nm, line
-
-def flush_stdout():
- try:
- if sys.stdout.softspace:
- sys.stdout.softspace = 0
- sys.stdout.write("\n")
- except (AttributeError, EOFError):
- pass
-
-def exit():
- """Exit subprocess, possibly after first deleting sys.exitfunc
-
- If config-main.cfg/.def 'General' 'delete-exitfunc' is True, then any
- sys.exitfunc will be removed before exiting. (VPython support)
-
- """
- if no_exitfunc:
- del sys.exitfunc
- sys.exit(0)
-
-class MyRPCServer(rpc.RPCServer):
-
- def handle_error(self, request, client_address):
- """Override RPCServer method for IDLE
-
- Interrupt the MainThread and exit server if link is dropped.
-
- """
- global quitting
- try:
- raise
- except SystemExit:
- raise
- except EOFError:
- global exit_now
- exit_now = True
- thread.interrupt_main()
- except:
- erf = sys.__stderr__
- print>>erf, '\n' + '-'*40
- print>>erf, 'Unhandled server exception!'
- print>>erf, 'Thread: %s' % threading.currentThread().getName()
- print>>erf, 'Client Address: ', client_address
- print>>erf, 'Request: ', repr(request)
- traceback.print_exc(file=erf)
- print>>erf, '\n*** Unrecoverable, server exiting!'
- print>>erf, '-'*40
- quitting = True
- thread.interrupt_main()
-
-
-class MyHandler(rpc.RPCHandler):
-
- def handle(self):
- """Override base method"""
- executive = Executive(self)
- self.register("exec", executive)
- sys.stdin = self.console = self.get_remote_proxy("stdin")
- sys.stdout = self.get_remote_proxy("stdout")
- sys.stderr = self.get_remote_proxy("stderr")
- import IOBinding
- sys.stdin.encoding = sys.stdout.encoding = \
- sys.stderr.encoding = IOBinding.encoding
- self.interp = self.get_remote_proxy("interp")
- rpc.RPCHandler.getresponse(self, myseq=None, wait=0.05)
-
- def exithook(self):
- "override SocketIO method - wait for MainThread to shut us down"
- time.sleep(10)
-
- def EOFhook(self):
- "Override SocketIO method - terminate wait on callback and exit thread"
- global quitting
- quitting = True
- thread.interrupt_main()
-
- def decode_interrupthook(self):
- "interrupt awakened thread"
- global quitting
- quitting = True
- thread.interrupt_main()
-
-
-class Executive(object):
-
- def __init__(self, rpchandler):
- self.rpchandler = rpchandler
- self.locals = __main__.__dict__
- self.calltip = CallTips.CallTips()
- self.autocomplete = AutoComplete.AutoComplete()
-
- def runcode(self, code):
- try:
- self.usr_exc_info = None
- exec code in self.locals
- except:
- self.usr_exc_info = sys.exc_info()
- if quitting:
- exit()
- # even print a user code SystemExit exception, continue
- print_exception()
- jit = self.rpchandler.console.getvar("<<toggle-jit-stack-viewer>>")
- if jit:
- self.rpchandler.interp.open_remote_stack_viewer()
- else:
- flush_stdout()
-
- def interrupt_the_server(self):
- thread.interrupt_main()
-
- def start_the_debugger(self, gui_adap_oid):
- return RemoteDebugger.start_debugger(self.rpchandler, gui_adap_oid)
-
- def stop_the_debugger(self, idb_adap_oid):
- "Unregister the Idb Adapter. Link objects and Idb then subject to GC"
- self.rpchandler.unregister(idb_adap_oid)
-
- def get_the_calltip(self, name):
- return self.calltip.fetch_tip(name)
-
- def get_the_completion_list(self, what, mode):
- return self.autocomplete.fetch_completions(what, mode)
-
- def stackviewer(self, flist_oid=None):
- if self.usr_exc_info:
- typ, val, tb = self.usr_exc_info
- else:
- return None
- flist = None
- if flist_oid is not None:
- flist = self.rpchandler.get_remote_proxy(flist_oid)
- while tb and tb.tb_frame.f_globals["__name__"] in ["rpc", "run"]:
- tb = tb.tb_next
- sys.last_type = typ
- sys.last_value = val
- item = StackViewer.StackTreeItem(flist, tb)
- return RemoteObjectBrowser.remote_object_tree_item(item)
diff --git a/sys/lib/python/idlelib/tabpage.py b/sys/lib/python/idlelib/tabpage.py
deleted file mode 100644
index 12f89291d..000000000
--- a/sys/lib/python/idlelib/tabpage.py
+++ /dev/null
@@ -1,113 +0,0 @@
-"""
-a couple of classes for implementing partial tabbed-page like behaviour
-"""
-
-from Tkinter import *
-
-class InvalidTabPage(Exception): pass
-class AlreadyExists(Exception): pass
-
-class PageTab(Frame):
- """
- a 'page tab' like framed button
- """
- def __init__(self,parent):
- Frame.__init__(self, parent,borderwidth=2,relief=RIDGE)
- self.button=Radiobutton(self,padx=5,pady=5,takefocus=FALSE,
- indicatoron=FALSE,highlightthickness=0,
- borderwidth=0,selectcolor=self.cget('bg'))
- self.button.pack()
-
-class TabPageSet(Frame):
- """
- a set of 'pages' with TabButtons for controlling their display
- """
- def __init__(self,parent,pageNames=[],**kw):
- """
- pageNames - a list of strings, each string will be the dictionary key
- to a page's data, and the name displayed on the page's tab. Should be
- specified in desired page order. The first page will be the default
- and first active page.
- """
- Frame.__init__(self, parent, kw)
- self.grid_location(0,0)
- self.columnconfigure(0,weight=1)
- self.rowconfigure(1,weight=1)
- self.tabBar=Frame(self)
- self.tabBar.grid(row=0,column=0,sticky=EW)
- self.activePage=StringVar(self)
- self.defaultPage=''
- self.pages={}
- for name in pageNames:
- self.AddPage(name)
-
- def ChangePage(self,pageName=None):
- if pageName:
- if pageName in self.pages.keys():
- self.activePage.set(pageName)
- else:
- raise InvalidTabPage, 'Invalid TabPage Name'
- ## pop up the active 'tab' only
- for page in self.pages.keys():
- self.pages[page]['tab'].config(relief=RIDGE)
- self.pages[self.GetActivePage()]['tab'].config(relief=RAISED)
- ## switch page
- self.pages[self.GetActivePage()]['page'].lift()
-
- def GetActivePage(self):
- return self.activePage.get()
-
- def AddPage(self,pageName):
- if pageName in self.pages.keys():
- raise AlreadyExists, 'TabPage Name Already Exists'
- self.pages[pageName]={'tab':PageTab(self.tabBar),
- 'page':Frame(self,borderwidth=2,relief=RAISED)}
- self.pages[pageName]['tab'].button.config(text=pageName,
- command=self.ChangePage,variable=self.activePage,
- value=pageName)
- self.pages[pageName]['tab'].pack(side=LEFT)
- self.pages[pageName]['page'].grid(row=1,column=0,sticky=NSEW)
- if len(self.pages)==1: # adding first page
- self.defaultPage=pageName
- self.activePage.set(self.defaultPage)
- self.ChangePage()
-
- def RemovePage(self,pageName):
- if not pageName in self.pages.keys():
- raise InvalidTabPage, 'Invalid TabPage Name'
- self.pages[pageName]['tab'].pack_forget()
- self.pages[pageName]['page'].grid_forget()
- self.pages[pageName]['tab'].destroy()
- self.pages[pageName]['page'].destroy()
- del(self.pages[pageName])
- # handle removing last remaining, or default, or active page
- if not self.pages: # removed last remaining page
- self.defaultPage=''
- return
- if pageName==self.defaultPage: # set a new default page
- self.defaultPage=\
- self.tabBar.winfo_children()[0].button.cget('text')
- if pageName==self.GetActivePage(): # set a new active page
- self.activePage.set(self.defaultPage)
- self.ChangePage()
-
-if __name__ == '__main__':
- #test dialog
- root=Tk()
- tabPage=TabPageSet(root,pageNames=['Foobar','Baz'])
- tabPage.pack(expand=TRUE,fill=BOTH)
- Label(tabPage.pages['Foobar']['page'],text='Foo',pady=20).pack()
- Label(tabPage.pages['Foobar']['page'],text='Bar',pady=20).pack()
- Label(tabPage.pages['Baz']['page'],text='Baz').pack()
- entryPgName=Entry(root)
- buttonAdd=Button(root,text='Add Page',
- command=lambda:tabPage.AddPage(entryPgName.get()))
- buttonRemove=Button(root,text='Remove Page',
- command=lambda:tabPage.RemovePage(entryPgName.get()))
- labelPgName=Label(root,text='name of page to add/remove:')
- buttonAdd.pack(padx=5,pady=5)
- buttonRemove.pack(padx=5,pady=5)
- labelPgName.pack(padx=5)
- entryPgName.pack(padx=5)
- tabPage.ChangePage()
- root.mainloop()
diff --git a/sys/lib/python/idlelib/testcode.py b/sys/lib/python/idlelib/testcode.py
deleted file mode 100644
index 05eaa562c..000000000
--- a/sys/lib/python/idlelib/testcode.py
+++ /dev/null
@@ -1,31 +0,0 @@
-import string
-
-def f():
- a = 0
- b = 1
- c = 2
- d = 3
- e = 4
- g()
-
-def g():
- h()
-
-def h():
- i()
-
-def i():
- j()
-
-def j():
- k()
-
-def k():
- l()
-
-l = lambda: test()
-
-def test():
- string.capwords(1)
-
-f()
diff --git a/sys/lib/python/idlelib/textView.py b/sys/lib/python/idlelib/textView.py
deleted file mode 100644
index 917a6cc0c..000000000
--- a/sys/lib/python/idlelib/textView.py
+++ /dev/null
@@ -1,78 +0,0 @@
-"""Simple text browser for IDLE
-
-"""
-
-from Tkinter import *
-import tkMessageBox
-
-class TextViewer(Toplevel):
- """
- simple text viewer dialog for idle
- """
- def __init__(self, parent, title, fileName, data=None):
- """If data exists, load it into viewer, otherwise try to load file.
-
- fileName - string, should be an absoulute filename
- """
- Toplevel.__init__(self, parent)
- self.configure(borderwidth=5)
- self.geometry("=%dx%d+%d+%d" % (625, 500,
- parent.winfo_rootx() + 10,
- parent.winfo_rooty() + 10))
- #elguavas - config placeholders til config stuff completed
- self.bg = '#ffffff'
- self.fg = '#000000'
-
- self.CreateWidgets()
- self.title(title)
- self.transient(parent)
- self.grab_set()
- self.protocol("WM_DELETE_WINDOW", self.Ok)
- self.parent = parent
- self.textView.focus_set()
- #key bindings for this dialog
- self.bind('<Return>',self.Ok) #dismiss dialog
- self.bind('<Escape>',self.Ok) #dismiss dialog
- if data:
- self.textView.insert(0.0, data)
- else:
- self.LoadTextFile(fileName)
- self.textView.config(state=DISABLED)
- self.wait_window()
-
- def LoadTextFile(self, fileName):
- textFile = None
- try:
- textFile = open(fileName, 'r')
- except IOError:
- tkMessageBox.showerror(title='File Load Error',
- message='Unable to load file %r .' % (fileName,))
- else:
- self.textView.insert(0.0,textFile.read())
-
- def CreateWidgets(self):
- frameText = Frame(self, relief=SUNKEN, height=700)
- frameButtons = Frame(self)
- self.buttonOk = Button(frameButtons, text='Close',
- command=self.Ok, takefocus=FALSE)
- self.scrollbarView = Scrollbar(frameText, orient=VERTICAL,
- takefocus=FALSE, highlightthickness=0)
- self.textView = Text(frameText, wrap=WORD, highlightthickness=0,
- fg=self.fg, bg=self.bg)
- self.scrollbarView.config(command=self.textView.yview)
- self.textView.config(yscrollcommand=self.scrollbarView.set)
- self.buttonOk.pack()
- self.scrollbarView.pack(side=RIGHT,fill=Y)
- self.textView.pack(side=LEFT,expand=TRUE,fill=BOTH)
- frameButtons.pack(side=BOTTOM,fill=X)
- frameText.pack(side=TOP,expand=TRUE,fill=BOTH)
-
- def Ok(self, event=None):
- self.destroy()
-
-if __name__ == '__main__':
- #test the dialog
- root=Tk()
- Button(root,text='View',
- command=lambda:TextViewer(root,'Text','./textView.py')).pack()
- root.mainloop()