summaryrefslogtreecommitdiff
path: root/Tools
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2003-06-14 00:08:37 +0000
committerGuido van Rossum <guido@python.org>2003-06-14 00:08:37 +0000
commit5db9ff42657d80a06fe28b0836bdd7bfd5fbdec8 (patch)
tree2bf9bb961941d2e1610ffe19e5d65586cdc220f4 /Tools
parent12c1bd4ab62db0259b8ee35ea546bd0a851124ea (diff)
downloadcpython-5db9ff42657d80a06fe28b0836bdd7bfd5fbdec8.tar.gz
Get rid of old IDLE. Lib/idlelib rules!
Diffstat (limited to 'Tools')
-rw-r--r--Tools/README2
-rw-r--r--Tools/idle/AutoExpand.py91
-rw-r--r--Tools/idle/AutoIndent.py551
-rw-r--r--Tools/idle/Bindings.py58
-rw-r--r--Tools/idle/CallTipWindow.py76
-rw-r--r--Tools/idle/CallTips.py197
-rw-r--r--Tools/idle/ChangeLog1017
-rw-r--r--Tools/idle/ClassBrowser.py217
-rw-r--r--Tools/idle/ColorDelegator.py246
-rw-r--r--Tools/idle/Debugger.py308
-rw-r--r--Tools/idle/Delegator.py33
-rw-r--r--Tools/idle/EditorWindow.py756
-rw-r--r--Tools/idle/FileList.py138
-rw-r--r--Tools/idle/FormatParagraph.py154
-rw-r--r--Tools/idle/FrameViewer.py38
-rw-r--r--Tools/idle/GrepDialog.py132
-rw-r--r--Tools/idle/IOBinding.py448
-rw-r--r--Tools/idle/Icons/folder.gifbin120 -> 0 bytes
-rw-r--r--Tools/idle/Icons/minusnode.gifbin56 -> 0 bytes
-rw-r--r--Tools/idle/Icons/openfolder.gifbin125 -> 0 bytes
-rw-r--r--Tools/idle/Icons/plusnode.gifbin79 -> 0 bytes
-rw-r--r--Tools/idle/Icons/python.gifbin125 -> 0 bytes
-rw-r--r--Tools/idle/Icons/tk.gifbin85 -> 0 bytes
-rw-r--r--Tools/idle/IdleConf.py113
-rw-r--r--Tools/idle/IdleHistory.py86
-rw-r--r--Tools/idle/MANIFEST.in4
-rw-r--r--Tools/idle/MultiScrolledLists.py137
-rw-r--r--Tools/idle/MultiStatusBar.py32
-rw-r--r--Tools/idle/NEWS.txt130
-rw-r--r--Tools/idle/ObjectBrowser.py151
-rw-r--r--Tools/idle/OldStackViewer.py275
-rw-r--r--Tools/idle/OutputWindow.py157
-rw-r--r--Tools/idle/ParenMatch.py189
-rw-r--r--Tools/idle/PathBrowser.py95
-rw-r--r--Tools/idle/Percolator.py85
-rw-r--r--Tools/idle/PyParse.py584
-rw-r--r--Tools/idle/PyShell.py794
-rw-r--r--Tools/idle/README.txt53
-rw-r--r--Tools/idle/RemoteInterp.py341
-rw-r--r--Tools/idle/ReplaceDialog.py167
-rw-r--r--Tools/idle/ScriptBinding.py175
-rw-r--r--Tools/idle/ScrolledList.py139
-rw-r--r--Tools/idle/SearchBinding.py97
-rw-r--r--Tools/idle/SearchDialog.py67
-rw-r--r--Tools/idle/SearchDialogBase.py128
-rw-r--r--Tools/idle/SearchEngine.py220
-rw-r--r--Tools/idle/Separator.py92
-rw-r--r--Tools/idle/StackViewer.py146
-rw-r--r--Tools/idle/TODO.txt211
-rw-r--r--Tools/idle/ToolTip.py86
-rw-r--r--Tools/idle/TreeWidget.py476
-rw-r--r--Tools/idle/UndoDelegator.py352
-rw-r--r--Tools/idle/WidgetRedirector.py92
-rw-r--r--Tools/idle/WindowList.py85
-rw-r--r--Tools/idle/ZoomHeight.py46
-rw-r--r--Tools/idle/__init__.py1
-rw-r--r--Tools/idle/config-mac.txt3
-rw-r--r--Tools/idle/config-unix.txt4
-rw-r--r--Tools/idle/config-win.txt4
-rw-r--r--Tools/idle/config.txt64
-rw-r--r--Tools/idle/eventparse.py89
-rw-r--r--Tools/idle/extend.txt120
-rw-r--r--Tools/idle/help.txt157
-rwxr-xr-xTools/idle/idle12
-rw-r--r--Tools/idle/idle.bat3
-rwxr-xr-xTools/idle/idle.py4
-rw-r--r--Tools/idle/idle.pyw8
-rw-r--r--Tools/idle/idlever.py1
-rw-r--r--Tools/idle/keydefs.py57
-rw-r--r--Tools/idle/setup.py100
-rw-r--r--Tools/idle/testcode.py31
71 files changed, 0 insertions, 10925 deletions
diff --git a/Tools/README b/Tools/README
index 5d20e9bd46..404ba4dbfc 100644
--- a/Tools/README
+++ b/Tools/README
@@ -24,8 +24,6 @@ i18n Tools for internationalization. pygettext.py
and msgfmt.py generates a binary message catalog
from a catalog in text format.
-idle A Tkinter-based Python IDE.
-
modulator Interactively generate boiler plate for an extension
module. Works easiest if you have Tk.
diff --git a/Tools/idle/AutoExpand.py b/Tools/idle/AutoExpand.py
deleted file mode 100644
index 40d39f3f42..0000000000
--- a/Tools/idle/AutoExpand.py
+++ /dev/null
@@ -1,91 +0,0 @@
-import string
-import re
-
-###$ event <<expand-word>>
-###$ win <Alt-slash>
-###$ unix <Alt-slash>
-
-class AutoExpand:
-
- keydefs = {
- '<<expand-word>>': ['<Alt-slash>'],
- }
-
- unix_keydefs = {
- '<<expand-word>>': ['<Meta-slash>', '<Alt-slash>'],
- }
-
- 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/Tools/idle/AutoIndent.py b/Tools/idle/AutoIndent.py
deleted file mode 100644
index 7bc195b19b..0000000000
--- a/Tools/idle/AutoIndent.py
+++ /dev/null
@@ -1,551 +0,0 @@
-#from Tkinter import TclError
-#import tkMessageBox
-#import tkSimpleDialog
-
-###$ event <<newline-and-indent>>
-###$ win <Key-Return>
-###$ win <KP_Enter>
-###$ unix <Key-Return>
-###$ unix <KP_Enter>
-
-###$ event <<indent-region>>
-###$ win <Control-bracketright>
-###$ unix <Alt-bracketright>
-###$ unix <Control-bracketright>
-
-###$ event <<dedent-region>>
-###$ win <Control-bracketleft>
-###$ unix <Alt-bracketleft>
-###$ unix <Control-bracketleft>
-
-###$ event <<comment-region>>
-###$ win <Alt-Key-3>
-###$ unix <Alt-Key-3>
-
-###$ event <<uncomment-region>>
-###$ win <Alt-Key-4>
-###$ unix <Alt-Key-4>
-
-###$ event <<tabify-region>>
-###$ win <Alt-Key-5>
-###$ unix <Alt-Key-5>
-
-###$ event <<untabify-region>>
-###$ win <Alt-Key-6>
-###$ unix <Alt-Key-6>
-
-import PyParse
-
-class AutoIndent:
-
- menudefs = [
- ('edit', [
- None,
- ('_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>>'),
- ]),
- ]
-
- keydefs = {
- '<<smart-backspace>>': ['<Key-BackSpace>'],
- '<<newline-and-indent>>': ['<Key-Return>', '<KP_Enter>'],
- '<<smart-indent>>': ['<Key-Tab>']
- }
-
- windows_keydefs = {
- '<<indent-region>>': ['<Control-bracketright>'],
- '<<dedent-region>>': ['<Control-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>'],
- }
-
- unix_keydefs = {
- '<<indent-region>>': ['<Alt-bracketright>',
- '<Meta-bracketright>',
- '<Control-bracketright>'],
- '<<dedent-region>>': ['<Alt-bracketleft>',
- '<Meta-bracketleft>',
- '<Control-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>'],
- '<<change-indentwidth>>': ['<Alt-Key-u>'],
- }
-
- # usetabs true -> literal tab characters are used by indent and
- # dedent cmds, possibly mixed with spaces if
- # indentwidth is not a multiple of tabwidth
- # false -> tab characters are converted to spaces by indent
- # and dedent cmds, and ditto TAB keystrokes
- # indentwidth is the number of characters per logical indent level.
- # 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.
- usetabs = 1
- indentwidth = 4
- tabwidth = 8 # for IDLE use, must remain 8 until Tk is fixed
-
- # If context_use_ps1 is true, parsing searches back for a ps1 line;
- # else searches for a popular (if, def, ...) Python stmt.
- context_use_ps1 = 0
-
- # 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.
- num_context_lines = 50, 500, 5000000
-
- def __init__(self, editwin):
- self.editwin = editwin
- self.text = editwin.text
-
- def config(self, **options):
- for key, value in options.items():
- if key == 'usetabs':
- self.usetabs = value
- elif key == 'indentwidth':
- self.indentwidth = value
- elif key == 'tabwidth':
- self.tabwidth = value
- elif key == 'context_use_ps1':
- self.context_use_ps1 = value
- else:
- raise KeyError, "bad option name: %s" % `key`
-
- # 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=1):
- if guess and ispythonsource:
- i = self.guess_indent()
- if 2 <= i <= 8:
- self.indentwidth = i
- if self.indentwidth != self.tabwidth:
- self.usetabs = 0
-
- self.editwin.set_tabwidth(self.tabwidth)
-
- def smart_backspace_event(self, event):
- text = self.text
- first, last = self.editwin.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
- ncharsdeleted = 0
- while 1:
- 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 & return
- # indent one level
- text = self.text
- first, last = self.editwin.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:
- 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.editwin.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; just inject
- # an empty line at the start
- text.insert("insert linestart", '\n')
- return "break"
- indent = line[:i]
- # strip whitespace before insert point
- i = 0
- while line and line[-1] in " \t":
- 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)
- 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)
- c = y.get_continuation_type()
- if c != PyParse.C_NONE:
- # The current stmt hasn't ended yet.
- if c == PyParse.C_STRING:
- # inside a string; 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 " + `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()
-
- auto_indent = newline_and_indent_event
-
- # 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.editwin.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.editwin.askyesno(
- "Toggle tabs",
- "Turn tabs " + ("on", "off")[self.usetabs] + "?",
- parent=self.text):
- self.usetabs = not self.usetabs
- return "break"
-
- # XXX this isn't bound to anything -- see class 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.editwin.askinteger(
- "Indent width",
- "New indent width (1-16)",
- parent=self.text,
- initialvalue=self.indentwidth,
- minvalue=1,
- maxvalue=16)
- if new and new != self.indentwidth:
- self.indentwidth = new
- return "break"
-
- def get_region(self):
- text = self.text
- first, last = self.editwin.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.editwin.askinteger(
- "Tab width",
- "Spaces per tab?",
- parent=self.text,
- initialvalue=self.tabwidth,
- minvalue=1,
- 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:
-
- # .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 = `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
diff --git a/Tools/idle/Bindings.py b/Tools/idle/Bindings.py
deleted file mode 100644
index a7d3802eb9..0000000000
--- a/Tools/idle/Bindings.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# This file defines the menu contents and key bindings. Note that
-# 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 by the code here. This makes it possible to define the
-# Debug menu here, which is only present in the PythonShell window.
-
-import sys
-from keydefs import *
-
-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>>'),
- ('Python shell', '<<open-python-shell>>'),
- None,
- ('_Save', '<<save-window>>'),
- ('Save _As...', '<<save-window-as-file>>'),
- ('Save Co_py As...', '<<save-copy-of-window-as-file>>'),
- None,
- ('_Print 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>>'),
- ]),
- ('debug', [
- ('_Go to file/line', '<<goto-file-line>>'),
- ('_Stack viewer', '<<open-stack-viewer>>'),
- ('!_Debugger', '<<toggle-debugger>>'),
- ('!_Auto-open stack viewer', '<<toggle-jit-stack-viewer>>' ),
- ]),
- ('help', [
- ('_Help...', '<<help>>'),
- ('Python _Documentation...', '<<python-docs>>'),
- None,
- ('_About IDLE...', '<<about-idle>>'),
- ]),
-]
-
-if sys.platform == 'win32':
- default_keydefs = windows_keydefs
-else:
- default_keydefs = unix_keydefs
-
-del sys
diff --git a/Tools/idle/CallTipWindow.py b/Tools/idle/CallTipWindow.py
deleted file mode 100644
index 24af6b0e46..0000000000
--- a/Tools/idle/CallTipWindow.py
+++ /dev/null
@@ -1,76 +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 *
-
-class CallTip:
-
- def __init__(self, widget):
- self.widget = widget
- self.tipwindow = None
- self.id = None
- self.x = self.y = 0
-
- def showtip(self, text):
- # SF bug 546078: IDLE calltips cause application error.
- # There were crashes on various Windows flavors, and even a
- # crashing X server on Linux, with very long calltips.
- if len(text) >= 79:
- text = text[:75] + ' ...'
- self.text = text
-
- if self.tipwindow or not self.text:
- return
- self.widget.see("insert")
- x, y, cx, cy = self.widget.bbox("insert")
- x = x + self.widget.winfo_rootx() + 2
- y = y + cy + self.widget.winfo_rooty()
- self.tipwindow = tw = Toplevel(self.widget)
- tw.wm_overrideredirect(1)
- tw.wm_geometry("+%d+%d" % (x, y))
- label = Label(tw, text=self.text, justify=LEFT,
- background="#ffffe0", relief=SOLID, borderwidth=1,
- font = self.widget['font'])
- label.pack()
-
- def hidetip(self):
- tw = self.tipwindow
- self.tipwindow = None
- if tw:
- tw.destroy()
-
-
-###############################
-#
-# 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() # not in idle
-
- 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/Tools/idle/CallTips.py b/Tools/idle/CallTips.py
deleted file mode 100644
index 8d35d5c130..0000000000
--- a/Tools/idle/CallTips.py
+++ /dev/null
@@ -1,197 +0,0 @@
-# CallTips.py - An IDLE extension that provides "Call Tips" - ie, a floating window that
-# displays parameter information as you open parens.
-
-import string
-import types
-
-class CallTips:
-
- menudefs = [
- ]
-
- keydefs = {
- '<<paren-open>>': ['<Key-parenleft>'],
- '<<paren-close>>': ['<Key-parenright>'],
- '<<check-calltip-cancel>>': ['<KeyRelease>'],
- '<<calltip-cancel>>': ['<ButtonPress>', '<Key-Escape>'],
- }
-
- windows_keydefs = {
- }
-
- unix_keydefs = {
- }
-
- def __init__(self, editwin):
- self.editwin = editwin
- self.text = editwin.text
- self.calltip = None
- if hasattr(self.text, "make_calltip_window"):
- self._make_calltip_window = self.text.make_calltip_window
- else:
- self._make_calltip_window = self._make_tk_calltip_window
-
- def close(self):
- self._make_calltip_window = None
-
- # Makes a Tk based calltip window. Used by IDLE, but not Pythonwin.
- # See __init__ above for how this is used.
- def _make_tk_calltip_window(self):
- import CallTipWindow
- return CallTipWindow.CallTip(self.text)
-
- def _remove_calltip_window(self):
- if self.calltip:
- self.calltip.hidetip()
- self.calltip = None
-
- def paren_open_event(self, event):
- self._remove_calltip_window()
- arg_text = get_arg_text(self.get_object_at_cursor())
- if arg_text:
- self.calltip_start = self.text.index("insert")
- self.calltip = self._make_calltip_window()
- self.calltip.showtip(arg_text)
- return "" #so the event is handled normally.
-
- def paren_close_event(self, event):
- # Now just hides, but later we should check if other
- # paren'd expressions remain open.
- self._remove_calltip_window()
- return "" #so the event is handled normally.
-
- def check_calltip_cancel_event(self, event):
- if self.calltip:
- # If we have moved before the start of the calltip,
- # or off the calltip line, then cancel the tip.
- # (Later need to be smarter about multi-line, etc)
- if self.text.compare("insert", "<=", self.calltip_start) or \
- self.text.compare("insert", ">", self.calltip_start + " lineend"):
- self._remove_calltip_window()
- return "" #so the event is handled normally.
-
- def calltip_cancel_event(self, event):
- self._remove_calltip_window()
- return "" #so the event is handled normally.
-
- def get_object_at_cursor(self,
- wordchars="._" + string.ascii_letters + string.digits):
- # Usage of ascii_letters is necessary to avoid UnicodeErrors
- # if chars contains non-ASCII.
-
- # XXX - This needs to be moved to a better place
- # so the "." attribute lookup code can also use it.
- text = self.text
- chars = text.get("insert linestart", "insert")
- i = len(chars)
- while i and chars[i-1] in wordchars:
- i = i-1
- word = chars[i:]
- if word:
- # How is this for a hack!
- import sys, __main__
- namespace = sys.modules.copy()
- namespace.update(__main__.__dict__)
- try:
- return eval(word, namespace)
- except:
- pass
- return None # Can't find an object.
-
-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)==types.ClassType:
- # 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" % 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:
- while doc[:1] in " \t\n":
- doc = doc[1:]
- 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 ):
- failed=[]
- for t in tests:
- expected = t.__doc__ + "\n" + t.__doc__
- if get_arg_text(t) != expected:
- failed.append(t)
- print "%s - expected %s, but got %s" % (t, `expected`, `get_arg_text(t)`)
- 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/Tools/idle/ChangeLog b/Tools/idle/ChangeLog
deleted file mode 100644
index b853a34af3..0000000000
--- a/Tools/idle/ChangeLog
+++ /dev/null
@@ -1,1017 +0,0 @@
-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/Tools/idle/ClassBrowser.py b/Tools/idle/ClassBrowser.py
deleted file mode 100644
index 2d81f9eda0..0000000000
--- a/Tools/idle/ClassBrowser.py
+++ /dev/null
@@ -1,217 +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
-
-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
- sc = ScrolledCanvas(top, bg="white", 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):
- try:
- return bool(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/Tools/idle/ColorDelegator.py b/Tools/idle/ColorDelegator.py
deleted file mode 100644
index 059108f65c..0000000000
--- a/Tools/idle/ColorDelegator.py
+++ /dev/null
@@ -1,246 +0,0 @@
-import time
-import re
-import keyword
-from Tkinter import *
-from Delegator import Delegator
-from IdleConf import idleconf
-
-#$ event <<toggle-auto-coloring>>
-#$ win <Control-slash>
-#$ unix <Control-slash>
-
-DEBUG = 0
-
-
-def any(name, list):
- return "(?P<%s>" % name + "|".join(list) + ")"
-
-def make_pat():
- kw = r"\b" + any("KEYWORD", keyword.kwlist) + r"\b"
- comment = any("COMMENT", [r"#[^\n]*"])
- sqstring = r"(\b[rR])?'[^'\\\n]*(\\.[^'\\\n]*)*'?"
- dqstring = r'(\b[rR])?"[^"\\\n]*(\\.[^"\\\n]*)*"?'
- sq3string = r"(\b[rR])?'''[^'\\]*((\\.|'(?!''))[^'\\]*)*(''')?"
- dq3string = r'(\b[rR])?"""[^"\\]*((\\.|"(?!""))[^"\\]*)*(""")?'
- string = any("STRING", [sq3string, dq3string, sqstring, dqstring])
- return kw + "|" + 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", re.S)
-
-class ColorDelegator(Delegator):
-
- def __init__(self):
- Delegator.__init__(self)
- self.prog = prog
- self.idprog = idprog
- self.asprog = asprog
-
- 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:
- apply(self.tag_configure, (tag,), cnf)
- self.tag_raise('sel')
-
- cconf = idleconf.getsection('Colors')
-
- tagdefs = {
- "COMMENT": cconf.getcolor("comment"),
- "KEYWORD": cconf.getcolor("keyword"),
- "STRING": cconf.getcolor("string"),
- "DEFINITION": cconf.getcolor("definition"),
- "SYNC": cconf.getcolor("sync"),
- "TODO": cconf.getcolor("todo"),
- "BREAK": cconf.getcolor("break"),
- # The following is used by ReplaceDialog:
- "hit": cconf.getcolor("hit"),
- }
-
- 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 = 1
- colorizing = 0
-
- 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 = 1
- 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 = 0
- self.stop_colorizing = 1
- 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 = 1
- 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 = 0
- self.colorizing = 1
- if DEBUG: print "colorizing..."
- t0 = time.clock()
- self.recolorize_main()
- t1 = time.clock()
- if DEBUG: print "%.3f seconds" % (t1-t0)
- finally:
- self.colorizing = 0
- 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 1:
- 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 = 0
- 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, "->", `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;
- # cheap approximation to the truth
- while 1:
- m1 = self.asprog.match(chars, b)
- 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 = 0
- 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 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/Tools/idle/Debugger.py b/Tools/idle/Debugger.py
deleted file mode 100644
index 0883597769..0000000000
--- a/Tools/idle/Debugger.py
+++ /dev/null
@@ -1,308 +0,0 @@
-import os
-import bdb
-from Tkinter import *
-from WindowList import ListedToplevel
-
-import StackViewer
-
-
-class Debugger(bdb.Bdb):
-
- interacting = 0
-
- vstack = vsource = vlocals = vglobals = None
-
- def __init__(self, pyshell):
- bdb.Bdb.__init__(self)
- self.pyshell = pyshell
- self.make_gui()
-
- def canonic(self, filename):
- # Canonicalize filename -- called by Bdb
- return os.path.normcase(os.path.abspath(filename))
-
- def close(self, event=None):
- if self.interacting:
- self.top.bell()
- return
- if self.stackviewer:
- self.stackviewer.close(); self.stackviewer = None
- self.pyshell.close_debugger()
- self.top.destroy()
-
- def run(self, *args):
- try:
- self.interacting = 1
- return apply(bdb.Bdb.run, (self,) + args)
- finally:
- self.interacting = 0
-
- def user_line(self, frame):
- self.interaction(frame)
-
- def user_return(self, frame, rv):
- # XXX show rv?
- ##self.interaction(frame)
- pass
-
- def user_exception(self, frame, info):
- self.interaction(frame, info)
-
- 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.vsource.set(1)
- 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.vglobals.set(1)
- 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()
-
- frame = None
-
- def interaction(self, frame, info=None):
- self.frame = frame
- code = frame.f_code
- file = code.co_filename
- base = os.path.basename(file)
- lineno = frame.f_lineno
- #
- message = "%s:%s" % (base, lineno)
- if code.co_name != "?":
- message = "%s: %s()" % (message, code.co_name)
- 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.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.tkraise()
- 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
- code = frame.f_code
- file = code.co_filename
- lineno = frame.f_lineno
- if file[:1] + file[-1:] != "<>" and os.path.exists(file):
- edit = self.flist.open(file)
- if edit:
- edit.gotoline(lineno)
-
- def cont(self):
- self.set_continue()
- self.root.quit()
-
- def step(self):
- self.set_step()
- self.root.quit()
-
- def next(self):
- self.set_next(self.frame)
- self.root.quit()
-
- def ret(self):
- self.set_return(self.frame)
- self.root.quit()
-
- def quit(self):
- self.set_quit()
- self.root.quit()
-
- stackviewer = None
-
- def show_stack(self):
- if not self.stackviewer and self.vstack.get():
- self.stackviewer = sv = StackViewer.StackViewer(
- self.fstack, self.flist, self)
- if self.frame:
- stack, i = self.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 = StackViewer.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 = StackViewer.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)
- if gv:
- gv.load_dict(gdict, force)
-
- def set_breakpoint_here(self, edit):
- text = edit.text
- filename = edit.io.filename
- if not filename:
- text.bell()
- return
- lineno = int(float(text.index("insert")))
- msg = self.set_break(filename, lineno)
- if msg:
- text.bell()
- return
- text.tag_add("BREAK", "insert linestart", "insert lineend +1char")
-
- # A literal copy of Bdb.set_break() without the print statement at the end
- def set_break(self, filename, lineno, temporary=0, cond = None):
- import linecache # Import as late as possible
- filename = self.canonic(filename)
- line = linecache.getline(filename, lineno)
- if not line:
- return 'That line does not exist!'
- if not self.breaks.has_key(filename):
- self.breaks[filename] = []
- list = self.breaks[filename]
- if not lineno in list:
- list.append(lineno)
- bp = bdb.Breakpoint(filename, lineno, temporary, cond)
diff --git a/Tools/idle/Delegator.py b/Tools/idle/Delegator.py
deleted file mode 100644
index 6125591fe0..0000000000
--- a/Tools/idle/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/Tools/idle/EditorWindow.py b/Tools/idle/EditorWindow.py
deleted file mode 100644
index e8c310a1cc..0000000000
--- a/Tools/idle/EditorWindow.py
+++ /dev/null
@@ -1,756 +0,0 @@
-import sys
-import os
-import re
-import imp
-from Tkinter import *
-import tkSimpleDialog
-import tkMessageBox
-
-import webbrowser
-import idlever
-import WindowList
-from IdleConf import idleconf
-
-# The default tab setting for a Text widget, in average-width characters.
-TK_TABWIDTH_DEFAULT = 8
-
-# File menu
-
-#$ event <<open-module>>
-#$ win <Alt-m>
-#$ unix <Control-x><Control-m>
-
-#$ event <<open-class-browser>>
-#$ win <Alt-c>
-#$ unix <Control-x><Control-b>
-
-#$ event <<open-path-browser>>
-
-#$ event <<close-window>>
-
-#$ unix <Control-x><Control-0>
-#$ unix <Control-x><Key-0>
-#$ win <Alt-F4>
-
-# Edit menu
-
-#$ event <<Copy>>
-#$ win <Control-c>
-#$ unix <Alt-w>
-
-#$ event <<Cut>>
-#$ win <Control-x>
-#$ unix <Control-w>
-
-#$ event <<Paste>>
-#$ win <Control-v>
-#$ unix <Control-y>
-
-#$ event <<select-all>>
-#$ win <Alt-a>
-#$ unix <Alt-a>
-
-# Help menu
-
-#$ event <<help>>
-#$ win <F1>
-#$ unix <F1>
-
-#$ event <<about-idle>>
-
-# Events without menu entries
-
-#$ event <<remove-selection>>
-#$ win <Escape>
-
-#$ event <<center-insert>>
-#$ win <Control-l>
-#$ unix <Control-l>
-
-#$ event <<do-nothing>>
-#$ unix <Control-x>
-
-
-about_title = "About IDLE"
-about_text = """\
-IDLE %s
-
-An Integrated DeveLopment Environment for Python
-
-by Guido van Rossum
-""" % idlever.IDLE_VERSION
-
-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:
-
- from Percolator import Percolator
- from ColorDelegator import ColorDelegator
- from UndoDelegator import UndoDelegator
- from IOBinding import IOBinding
- import Bindings
- from Tkinter import Toplevel
- from MultiStatusBar import MultiStatusBar
-
- about_title = about_title
- about_text = about_text
-
- vars = {}
- runnable = False # Shell window cannot Import Module or Run Script
-
- def __init__(self, flist=None, filename=None, key=None, root=None):
- edconf = idleconf.getsection('EditorWindow')
- coconf = idleconf.getsection('Colors')
- self.flist = flist
- root = root or flist.root
- self.root = root
- if flist:
- self.vars = flist.vars
- self.menubar = Menu(root)
- self.top = top = self.Toplevel(root, menu=self.menubar)
- self.vbar = vbar = Scrollbar(top, name='vbar')
- self.text_frame = text_frame = Frame(top)
- self.text = text = Text(text_frame, name='text', padx=5,
- foreground=coconf.getdef('normal-foreground'),
- background=coconf.getdef('normal-background'),
- highlightcolor=coconf.getdef('hilite-foreground'),
- highlightbackground=coconf.getdef('hilite-background'),
- insertbackground=coconf.getdef('cursor-background'),
- width=edconf.getint('width'),
- height=edconf.getint('height'),
- wrap="none")
-
- self.createmenubar()
- self.apply_bindings()
-
- self.top.protocol("WM_DELETE_WINDOW", self.close)
- self.top.bind("<<close-window>>", self.close_event)
- 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-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("<3>", self.right_menu_event)
- if flist:
- flist.inversedict[self] = key
- if key:
- flist.dict[key] = self
- text.bind("<<open-new-window>>", self.flist.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)
-
- vbar['command'] = text.yview
- vbar.pack(side=RIGHT, fill=Y)
-
- text['yscrollcommand'] = vbar.set
- text['font'] = edconf.get('font-name'), edconf.get('font-size')
- text_frame.pack(side=LEFT, fill=BOTH, expand=1)
- text.pack(side=TOP, fill=BOTH, expand=1)
- text.focus_set()
-
- self.per = per = self.Percolator(text)
- if self.ispythonsource(filename):
- self.color = color = self.ColorDelegator(); per.insertfilter(color)
- ##print "Initial colorizer"
- else:
- ##print "No initial colorizer"
- self.color = None
- self.undo = undo = self.UndoDelegator(); per.insertfilter(undo)
- self.io = io = self.IOBinding(self)
-
- 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)
- io.set_filename_change_hook(self.filename_change_hook)
-
- if filename:
- if os.path.exists(filename):
- io.loadfile(filename)
- else:
- io.set_filename(filename)
-
- self.saved_change_hook()
-
- 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
-
- if self.extensions.has_key('AutoIndent'):
- self.extensions['AutoIndent'].set_indentation_params(
- self.ispythonsource(filename))
- self.set_status_bar()
-
- def set_status_bar(self):
- self.status_bar = self.MultiStatusBar(self.text_frame)
- 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('<KeyRelease>', self.set_line_and_column)
- self.text.bind('<ButtonRelease>', self.set_line_and_column)
- 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)
-
- def wakeup(self):
- if self.top.wm_state() == "iconic":
- self.top.wm_deiconify()
- else:
- self.top.tkraise()
- self.text.focus_set()
-
- menu_specs = [
- ("file", "_File"),
- ("edit", "_Edit"),
- ("windows", "_Windows"),
- ("help", "_Help"),
- ]
-
- 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)
- self.fill_menus()
-
- def postwindowsmenu(self):
- # Only called when Windows menu exists
- # XXX Actually, this Just-In-Time updating interferes badly
- # XXX with the tear-off feature. It would be better to update
- # XXX all Windows menus whenever the list of windows changes.
- 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):
- tkMessageBox.showinfo(self.about_title, self.about_text,
- master=self.text)
-
- helpfile = "help.txt"
-
- def help_dialog(self, event=None):
- try:
- helpfile = os.path.join(os.path.dirname(__file__), self.helpfile)
- except NameError:
- helpfile = self.helpfile
- if self.flist:
- self.flist.open(helpfile)
- else:
- self.io.loadfile(helpfile)
-
- help_url = "http://www.python.org/doc/current/"
- if sys.platform[:3] == "win":
- fn = os.path.dirname(__file__)
- fn = os.path.join(fn, os.pardir, os.pardir, "pythlp.chm")
- fn = os.path.normpath(fn)
- if os.path.isfile(fn):
- help_url = fn
- else:
- fn = os.path.dirname(__file__)
- fn = os.path.join(fn, os.pardir, os.pardir, "Doc", "index.html")
- fn = os.path.normpath(fn)
- if os.path.isfile(fn):
- help_url = fn
- del fn
-
- def python_docs(self, event=None):
- os.startfile(self.help_url)
- else:
- def python_docs(self, event=None):
- webbrowser.open(self.help_url)
-
- 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 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()
- if not name:
- name = tkSimpleDialog.askstring("Module",
- "Enter the name of a Python module\n"
- "to search on sys.path and open:",
- parent=self.text)
- 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:
- 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 'python' in line
-
- 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()
- if self.ispythonsource(self.io.filename):
- self.addcolorizer()
- else:
- self.rmcolorizer()
-
- def addcolorizer(self):
- if self.color:
- return
- ##print "Add colorizer"
- self.per.removefilter(self.undo)
- self.color = self.ColorDelegator()
- self.per.insertfilter(self.color)
- self.per.insertfilter(self.undo)
-
- def rmcolorizer(self):
- if not self.color:
- return
- ##print "Remove colorizer"
- self.per.removefilter(self.undo)
- self.per.removefilter(self.color)
- self.color = None
- self.per.insertfilter(self.undo)
-
- def saved_change_hook(self):
- 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 filename
-
- def long_title(self):
- return 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 close_event(self, event):
- self.close()
-
- def maybesave(self):
- if self.io:
- return self.io.maybesave()
-
- def close(self):
- self.top.wm_deiconify()
- self.top.tkraise()
- reply = self.maybesave()
- if reply != "cancel":
- self._close()
- return reply
-
- def _close(self):
- 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.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", `name`
- import traceback
- traceback.print_exc()
-
- def get_standard_extension_names(self):
- return idleconf.getextensions()
-
- def load_extension(self, name):
- mod = __import__(name, globals(), locals(), [])
- cls = getattr(mod, name)
- ins = cls(self)
- self.extensions[name] = ins
- kdnames = ["keydefs"]
- if sys.platform == 'win32':
- kdnames.append("windows_keydefs")
- elif sys.platform == 'mac':
- kdnames.append("mac_keydefs")
- else:
- kdnames.append("unix_keydefs")
- keydefs = {}
- for kdname in kdnames:
- if hasattr(ins, kdname):
- keydefs.update(getattr(ins, kdname))
- 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))
- if hasattr(ins, "menudefs"):
- self.fill_menus(ins.menudefs, keydefs)
- return ins
-
- 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:
- apply(text.event_add, (event,) + tuple(keylist))
-
- def fill_menus(self, defs=None, keydefs=None):
- # Fill the menus. Menus that are absent or None in
- # self.menudict are ignored.
- if defs is None:
- defs = self.Bindings.menudefs
- if keydefs is None:
- keydefs = self.Bindings.default_keydefs
- menudict = self.menudict
- text = self.text
- for mname, itemlist in defs:
- menu = menudict.get(mname)
- if not menu:
- continue
- for item in itemlist:
- if not item:
- menu.add_separator()
- else:
- label, event = item
- checkbutton = (label[:1] == '!')
- if checkbutton:
- label = label[1:]
- underline, label = prepstr(label)
- accelerator = get_accelerator(keydefs, event)
- def command(text=text, event=event):
- text.event_generate(event)
- if checkbutton:
- var = self.getrawvar(event, 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.getrawvar(name)
- if var:
- return var.get()
-
- def setvar(self, name, value, vartype=None):
- var = self.getrawvar(name, vartype)
- if var:
- var.set(value)
-
- def getrawvar(self, name, vartype=None):
- var = self.vars.get(name)
- if not var and vartype:
- self.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)
-
-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, event):
- keylist = keydefs.get(event)
- 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("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/Tools/idle/FileList.py b/Tools/idle/FileList.py
deleted file mode 100644
index 0a1c81a7ca..0000000000
--- a/Tools/idle/FileList.py
+++ /dev/null
@@ -1,138 +0,0 @@
-import os
-from Tkinter import *
-import tkMessageBox
-
-import WindowList
-
-#$ event <<open-new-window>>
-#$ win <Control-n>
-#$ unix <Control-x><Control-n>
-
-# (This is labeled as 'Exit'in the File menu)
-#$ event <<close-all-windows>>
-#$ win <Control-q>
-#$ unix <Control-x><Control-c>
-
-class FileList:
-
- from EditorWindow import EditorWindow
- EditorWindow.Toplevel = WindowList.ListedToplevel # XXX Patch it!
-
- def __init__(self, root):
- self.root = root
- self.dict = {}
- self.inversedict = {}
- self.vars = {} # For EditorWindow.getrawvar (shared Tcl variables)
-
- def open(self, filename):
- assert filename
- filename = self.canonize(filename)
- if os.path.isdir(filename):
- tkMessageBox.showerror(
- "Is A Directory",
- "The path %s 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.wakeup()
- return edit
- if not os.path.exists(filename):
- tkMessageBox.showinfo(
- "New File",
- "Opening non-existent file %s" % `filename`,
- master=self.root)
- 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):
- return self.EditorWindow(self)
-
- def new_callback(self, event):
- self.new()
- return "break"
-
- 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 %s" % `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/Tools/idle/FormatParagraph.py b/Tools/idle/FormatParagraph.py
deleted file mode 100644
index c1bc769c22..0000000000
--- a/Tools/idle/FormatParagraph.py
+++ /dev/null
@@ -1,154 +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
-
-class FormatParagraph:
-
- menudefs = [
- ('edit', [
- ('Format Paragraph', '<<format-paragraph>>'),
- ])
- ]
-
- keydefs = {
- '<<format-paragraph>>': ['<Alt-q>'],
- }
-
- unix_keydefs = {
- '<<format-paragraph>>': ['<Meta-q>'],
- }
-
- def __init__(self, editwin):
- self.editwin = editwin
-
- def close(self):
- self.editwin = None
-
- def format_paragraph_event(self, event):
- 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 70 chars or a 20 char width, whichever is greater.
- format_width = max(70-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)
- 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=70):
- 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/Tools/idle/FrameViewer.py b/Tools/idle/FrameViewer.py
deleted file mode 100644
index 2ce0935ba3..0000000000
--- a/Tools/idle/FrameViewer.py
+++ /dev/null
@@ -1,38 +0,0 @@
-from repr import Repr
-from Tkinter import *
-
-class FrameViewer:
-
- def __init__(self, root, frame):
- self.root = root
- self.frame = frame
- self.top = Toplevel(self.root)
- self.repr = Repr()
- self.repr.maxstring = 60
- self.load_variables()
-
- def load_variables(self):
- row = 0
- if self.frame.f_locals is not self.frame.f_globals:
- l = Label(self.top, text="Local Variables",
- borderwidth=2, relief="raised")
- l.grid(row=row, column=0, columnspan=2, sticky="ew")
- row = self.load_names(self.frame.f_locals, row+1)
- l = Label(self.top, text="Global Variables",
- borderwidth=2, relief="raised")
- l.grid(row=row, column=0, columnspan=2, sticky="ew")
- row = self.load_names(self.frame.f_globals, row+1)
-
- def load_names(self, dict, row):
- names = dict.keys()
- names.sort()
- for name in names:
- value = dict[name]
- svalue = self.repr.repr(value)
- l = Label(self.top, text=name)
- l.grid(row=row, column=0, sticky="w")
- l = Entry(self.top, width=60, borderwidth=0)
- l.insert(0, svalue)
- l.grid(row=row, column=1, sticky="w")
- row = row+1
- return row
diff --git a/Tools/idle/GrepDialog.py b/Tools/idle/GrepDialog.py
deleted file mode 100644
index 84cac0ea31..0000000000
--- a/Tools/idle/GrepDialog.py
+++ /dev/null
@@ -1,132 +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
- dialog.open(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, io=None):
- SearchDialogBase.open(self, None)
- 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 %s 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/Tools/idle/IOBinding.py b/Tools/idle/IOBinding.py
deleted file mode 100644
index 8d654b9aec..0000000000
--- a/Tools/idle/IOBinding.py
+++ /dev/null
@@ -1,448 +0,0 @@
-import os
-import types
-import sys
-import codecs
-import re
-import tempfile
-import tkFileDialog
-import tkMessageBox
-from IdleConf import idleconf
-
-#$ event <<open-window-from-file>>
-#$ win <Control-o>
-#$ unix <Control-x><Control-f>
-
-#$ event <<save-window>>
-#$ win <Control-s>
-#$ unix <Control-x><Control-s>
-
-#$ event <<save-window-as-file>>
-#$ win <Alt-s>
-#$ unix <Control-x><Control-w>
-
-#$ event <<save-copy-of-window-as-file>>
-#$ win <Alt-Shift-s>
-#$ unix <Control-x><w>
-
-#$ event <<print-window>>
-#$ win <Control-p>
-#$ unix <Control-x><Control-p>
-
-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:
- pass
-
-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)
- 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]
- codecs.lookup(encoding)
- except (ValueError, LookupError):
- pass
-
-encoding = encoding.lower()
-
-coding_re = re.compile("coding[:=]\s*([-\w_.]+)")
-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.__id_print = self.text.bind("<<print-window>>", self.print_window)
- self.fileencoding = None
-
- 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
-
- def set_filename(self, filename):
- self.filename = filename
- self.set_saved(1)
- if self.filename_change_hook:
- self.filename_change_hook()
-
- def open(self, event):
- if self.editwin.flist:
- filename = self.askopenfile()
- if filename:
- 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"
- filename = self.askopenfile()
- if filename:
- self.loadfile(filename)
- else:
- self.text.focus_set()
- return "break"
-
- def loadfile(self, filename):
- try:
- f = open(filename)
- chars = f.read()
- f.close()
- except IOError, msg:
- tkMessageBox.showerror("I/O Error", str(msg), master=self.text)
- return False
-
- chars = self.decode(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")
- return True
-
- def decode(self, chars):
- # Try to 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)
- 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)
- self.text.focus_set()
- return "break"
-
- def save_a_copy(self, event):
- filename = self.asksavefile()
- if filename:
- self.writefile(filename)
- self.text.focus_set()
- return "break"
-
- def print_window(self, event):
- if self.get_saved():
- filename = self.filename
- else:
- (tfd, tfn) = tempfile.mkstemp()
- os.close(tfd)
- filename = tfn
- if not self.writefile(filename):
- os.unlink(tfn)
- return "break"
- edconf = idleconf.getsection('EditorWindow')
- command = edconf.get('print-command')
- command = command % filename
- if os.name == 'posix':
- command = command + " 2>&1"
- pipe = os.popen(command, "r")
- 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)
- return "break"
-
- def writefile(self, filename):
- self.fixlastline()
- chars = self.encode(self.text.get("1.0", "end-1c"))
- try:
- f = open(filename, "w")
- f.write(chars)
- f.close()
- ## print "saved to", `filename`
- 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.
- try:
- chars = chars.encode(encoding)
- enc = encoding
- except UnicodeError:
- chars = BOM_UTF8 + chars.encode("utf-8")
- enc = "utf-8"
- tkMessageBox.showerror(
- "I/O Error",
- "Non-ASCII found, yet no encoding declared. Add a line like\n"
- "# -*- coding: %s -*- \nto your file" % enc,
- master = self.text)
- return chars
-
- def fixlastline(self):
- c = self.text.get("end-2c")
- if c != '\n':
- self.text.insert("end-1c", "\n")
-
- 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)
- return self.opendialog.show(initialdir=dir, initialfile=base)
-
- def defaultfilename(self, mode="open"):
- if self.filename:
- return os.path.split(self.filename)
- 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)
- return self.savedialog.show(initialdir=dir, initialfile=base)
-
-
-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__":
- from Tkinter import *
- test()
diff --git a/Tools/idle/Icons/folder.gif b/Tools/idle/Icons/folder.gif
deleted file mode 100644
index effe8dc8a0..0000000000
--- a/Tools/idle/Icons/folder.gif
+++ /dev/null
Binary files differ
diff --git a/Tools/idle/Icons/minusnode.gif b/Tools/idle/Icons/minusnode.gif
deleted file mode 100644
index ceaaee18d1..0000000000
--- a/Tools/idle/Icons/minusnode.gif
+++ /dev/null
Binary files differ
diff --git a/Tools/idle/Icons/openfolder.gif b/Tools/idle/Icons/openfolder.gif
deleted file mode 100644
index 24aea1bebe..0000000000
--- a/Tools/idle/Icons/openfolder.gif
+++ /dev/null
Binary files differ
diff --git a/Tools/idle/Icons/plusnode.gif b/Tools/idle/Icons/plusnode.gif
deleted file mode 100644
index 13ace90eb3..0000000000
--- a/Tools/idle/Icons/plusnode.gif
+++ /dev/null
Binary files differ
diff --git a/Tools/idle/Icons/python.gif b/Tools/idle/Icons/python.gif
deleted file mode 100644
index 58271edec4..0000000000
--- a/Tools/idle/Icons/python.gif
+++ /dev/null
Binary files differ
diff --git a/Tools/idle/Icons/tk.gif b/Tools/idle/Icons/tk.gif
deleted file mode 100644
index a603f5ecb0..0000000000
--- a/Tools/idle/Icons/tk.gif
+++ /dev/null
Binary files differ
diff --git a/Tools/idle/IdleConf.py b/Tools/idle/IdleConf.py
deleted file mode 100644
index 8eaa8e06b5..0000000000
--- a/Tools/idle/IdleConf.py
+++ /dev/null
@@ -1,113 +0,0 @@
-"""Provides access to configuration information"""
-
-import os
-import sys
-from ConfigParser import ConfigParser, NoOptionError, NoSectionError
-
-class IdleConfParser(ConfigParser):
-
- # these conf sections do not define extensions!
- builtin_sections = {}
- for section in ('EditorWindow', 'Colors'):
- builtin_sections[section] = section
-
- def getcolor(self, sec, name):
- """Return a dictionary with foreground and background colors
-
- The return value is appropriate for passing to Tkinter in, e.g.,
- a tag_config call.
- """
- fore = self.getdef(sec, name + "-foreground")
- back = self.getdef(sec, name + "-background")
- return {"foreground": fore,
- "background": back}
-
- def getdef(self, sec, options, raw=0, vars=None, default=None):
- """Get an option value for given section or return default"""
- try:
- return self.get(sec, options, raw, vars)
- except (NoSectionError, NoOptionError):
- return default
-
- def getsection(self, section):
- """Return a SectionConfigParser object"""
- return SectionConfigParser(section, self)
-
- def getextensions(self):
- exts = []
- for sec in self.sections():
- if self.builtin_sections.has_key(sec):
- continue
- # enable is a bool, but it may not be defined
- if self.getdef(sec, 'enable') != '0':
- exts.append(sec)
- return exts
-
- def reload(self):
- global idleconf
- idleconf = IdleConfParser()
- load(_dir) # _dir is a global holding the last directory loaded
-
-class SectionConfigParser:
- """A ConfigParser object specialized for one section
-
- This class has all the get methods that a regular ConfigParser does,
- but without requiring a section argument.
- """
- def __init__(self, section, config):
- self.section = section
- self.config = config
-
- def options(self):
- return self.config.options(self.section)
-
- def get(self, options, raw=0, vars=None):
- return self.config.get(self.section, options, raw, vars)
-
- def getdef(self, options, raw=0, vars=None, default=None):
- return self.config.getdef(self.section, options, raw, vars, default)
-
- def getint(self, option):
- return self.config.getint(self.section, option)
-
- def getfloat(self, option):
- return self.config.getint(self.section, option)
-
- def getboolean(self, option):
- return self.config.getint(self.section, option)
-
- def getcolor(self, option):
- return self.config.getcolor(self.section, option)
-
-def load(dir):
- """Load IDLE configuration files based on IDLE install in dir
-
- Attempts to load two config files:
- dir/config.txt
- dir/config-[win/mac/unix].txt
- dir/config-%(sys.platform)s.txt
- ~/.idle
- """
- global _dir
- _dir = dir
-
- if sys.platform[:3] == 'win':
- genplatfile = os.path.join(dir, "config-win.txt")
- # XXX don't know what the platform string is on a Mac
- elif sys.platform[:3] == 'mac':
- genplatfile = os.path.join(dir, "config-mac.txt")
- else:
- genplatfile = os.path.join(dir, "config-unix.txt")
-
- platfile = os.path.join(dir, "config-%s.txt" % sys.platform)
-
- try:
- homedir = os.environ['HOME']
- except KeyError:
- homedir = os.getcwd()
-
- idleconf.read((os.path.join(dir, "config.txt"), genplatfile, platfile,
- os.path.join(homedir, ".idle")))
-
-idleconf = IdleConfParser()
-load(os.path.dirname(__file__))
diff --git a/Tools/idle/IdleHistory.py b/Tools/idle/IdleHistory.py
deleted file mode 100644
index 46e70e1224..0000000000
--- a/Tools/idle/IdleHistory.py
+++ /dev/null
@@ -1,86 +0,0 @@
-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
- 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:
- pointer = -1
- nprefix = len(prefix)
- while 1:
- if reverse:
- pointer = pointer - 1
- else:
- pointer = pointer + 1
- if pointer < 0 or pointer >= nhist:
- self.text.bell()
- 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
-
- def recall(self, s):
- s = s.strip()
- self.text.tag_remove("sel", "1.0", "end")
- self.text.delete("iomark", "end-1c")
- self.text.mark_set("insert", "end-1c")
- self.text.insert("insert", s)
- self.text.see("insert")
diff --git a/Tools/idle/MANIFEST.in b/Tools/idle/MANIFEST.in
deleted file mode 100644
index 440c9d1c81..0000000000
--- a/Tools/idle/MANIFEST.in
+++ /dev/null
@@ -1,4 +0,0 @@
-include *.txt
-include idle
-include MANIFEST.in
-include MANIFEST \ No newline at end of file
diff --git a/Tools/idle/MultiScrolledLists.py b/Tools/idle/MultiScrolledLists.py
deleted file mode 100644
index 6398b86dd3..0000000000
--- a/Tools/idle/MultiScrolledLists.py
+++ /dev/null
@@ -1,137 +0,0 @@
-# One or more ScrolledLists with HSeparators between them.
-# There is a hierarchical relationship between them:
-# the right list displays the substructure of the selected item
-# in the left list.
-
-from Tkinter import *
-from WindowList import ListedToplevel
-from Separator import HSeparator
-from ScrolledList import ScrolledList
-
-class MultiScrolledLists:
-
- def __init__(self, root, nlists=2):
- assert nlists >= 1
- self.root = root
- self.nlists = nlists
- self.path = []
- # create top
- self.top = top = ListedToplevel(root)
- top.protocol("WM_DELETE_WINDOW", self.close)
- top.bind("<Escape>", self.close)
- self.settitle()
- # create frames and separators in between
- self.frames = []
- self.separators = []
- last = top
- for i in range(nlists-1):
- sepa = HSeparator(last)
- self.separators.append(sepa)
- frame, last = sepa.parts()
- self.frames.append(frame)
- self.frames.append(last)
- # create labels and lists
- self.labels = []
- self.lists = []
- for i in range(nlists):
- frame = self.frames[i]
- label = Label(frame, text=self.subtitle(i),
- relief="groove", borderwidth=2)
- label.pack(fill="x")
- self.labels.append(label)
- list = ScrolledList(frame, width=self.width(i),
- height=self.height(i))
- self.lists.append(list)
- list.on_select = \
- lambda index, i=i, self=self: self.on_select(index, i)
- list.on_double = \
- lambda index, i=i, self=self: self.on_double(index, i)
- # fill leftmost list (rest get filled on demand)
- self.fill(0)
- # XXX one after_idle isn't enough; two are...
- top.after_idle(self.call_pack_propagate_1)
-
- def call_pack_propagate_1(self):
- self.top.after_idle(self.call_pack_propagate)
-
- def call_pack_propagate(self):
- for frame in self.frames:
- frame.pack_propagate(0)
-
- def close(self, event=None):
- self.top.destroy()
-
- def settitle(self):
- short = self.shorttitle()
- long = self.longtitle()
- if short and long:
- title = short + " - " + long
- elif short:
- title = short
- elif long:
- title = long
- else:
- title = "Untitled"
- icon = short or long or title
- self.top.wm_title(title)
- self.top.wm_iconname(icon)
-
- def longtitle(self):
- # override this
- return "Multi Scrolled Lists"
-
- def shorttitle(self):
- # override this
- return None
-
- def width(self, i):
- # override this
- return 20
-
- def height(self, i):
- # override this
- return 10
-
- def subtitle(self, i):
- # override this
- return "Column %d" % i
-
- def fill(self, i):
- for k in range(i, self.nlists):
- self.lists[k].clear()
- self.labels[k].configure(text=self.subtitle(k))
- list = self.lists[i]
- l = self.items(i)
- for s in l:
- list.append(s)
-
- def on_select(self, index, i):
- item = self.lists[i].get(index)
- del self.path[i:]
- self.path.append(item)
- if i+1 < self.nlists:
- self.fill(i+1)
-
- def items(self, i):
- # override this
- l = []
- for k in range(10):
- s = str(k)
- if i > 0:
- s = self.path[i-1] + "." + s
- l.append(s)
- return l
-
- def on_double(self, index, i):
- pass
-
-
-def main():
- root = Tk()
- quit = Button(root, text="Exit", command=root.destroy)
- quit.pack()
- MultiScrolledLists(root, 4)
- root.mainloop()
-
-if __name__ == "__main__":
- main()
diff --git a/Tools/idle/MultiStatusBar.py b/Tools/idle/MultiStatusBar.py
deleted file mode 100644
index dd6d04145f..0000000000
--- a/Tools/idle/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()
- apply(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/Tools/idle/NEWS.txt b/Tools/idle/NEWS.txt
deleted file mode 100644
index 86cbc7609f..0000000000
--- a/Tools/idle/NEWS.txt
+++ /dev/null
@@ -1,130 +0,0 @@
-(For a more detailed change log, see the file ChangeLog.)
-
-----------------------------------------------------------------------
-
-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/Tools/idle/ObjectBrowser.py b/Tools/idle/ObjectBrowser.py
deleted file mode 100644
index 416be5a15f..0000000000
--- a/Tools/idle/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(`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/Tools/idle/OldStackViewer.py b/Tools/idle/OldStackViewer.py
deleted file mode 100644
index 4f295e8dbe..0000000000
--- a/Tools/idle/OldStackViewer.py
+++ /dev/null
@@ -1,275 +0,0 @@
-import sys
-import os
-from Tkinter import *
-import linecache
-from repr import Repr
-from WindowList import ListedToplevel
-
-from ScrolledList import ScrolledList
-
-
-class StackBrowser:
-
- def __init__(self, root, flist, stack=None):
- self.top = top = ListedToplevel(root)
- top.protocol("WM_DELETE_WINDOW", self.close)
- top.bind("<Key-Escape>", self.close)
- top.wm_title("Stack viewer")
- top.wm_iconname("Stack")
- # Create help label
- self.helplabel = Label(top,
- text="Click once to view variables; twice for source",
- borderwidth=2, relief="groove")
- self.helplabel.pack(fill="x")
- #
- self.sv = StackViewer(top, flist, self)
- if stack is None:
- stack = get_stack()
- self.sv.load_stack(stack)
-
- def close(self, event=None):
- self.top.destroy()
-
- localsframe = None
- localsviewer = None
- localsdict = None
- globalsframe = None
- globalsviewer = None
- globalsdict = None
- curframe = None
-
- def show_frame(self, (frame, lineno)):
- if frame is self.curframe:
- return
- self.curframe = None
- if frame.f_globals is not self.globalsdict:
- self.show_globals(frame)
- self.show_locals(frame)
- self.curframe = frame
-
- def show_globals(self, frame):
- title = "Global Variables"
- if frame.f_globals.has_key("__name__"):
- try:
- name = str(frame.f_globals["__name__"]) + ""
- except:
- name = ""
- if name:
- title = title + " in module " + name
- self.globalsdict = None
- if self.globalsviewer:
- self.globalsviewer.close()
- self.globalsviewer = None
- if not self.globalsframe:
- self.globalsframe = Frame(self.top)
- self.globalsdict = frame.f_globals
- self.globalsviewer = NamespaceViewer(
- self.globalsframe,
- title,
- self.globalsdict)
- self.globalsframe.pack(fill="both", side="bottom")
-
- def show_locals(self, frame):
- self.localsdict = None
- if self.localsviewer:
- self.localsviewer.close()
- self.localsviewer = None
- if frame.f_locals is not frame.f_globals:
- title = "Local Variables"
- code = frame.f_code
- funcname = code.co_name
- if funcname not in ("?", "", None):
- title = title + " in " + funcname
- if not self.localsframe:
- self.localsframe = Frame(self.top)
- self.localsdict = frame.f_locals
- self.localsviewer = NamespaceViewer(
- self.localsframe,
- title,
- self.localsdict)
- self.localsframe.pack(fill="both", side="top")
- else:
- if self.localsframe:
- self.localsframe.forget()
-
-
-class StackViewer(ScrolledList):
-
- def __init__(self, master, flist, browser):
- ScrolledList.__init__(self, master, width=80)
- self.flist = flist
- self.browser = browser
- self.stack = []
-
- def load_stack(self, stack, index=None):
- self.stack = stack
- self.clear()
-## if len(stack) > 10:
-## l["height"] = 10
-## self.topframe.pack(expand=1)
-## else:
-## l["height"] = len(stack)
-## self.topframe.pack(expand=0)
- 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
- 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)
- if i == index:
- item = "> " + item
- self.append(item)
- if index is not None:
- self.select(index)
-
- def popup_event(self, event):
- if self.stack:
- return ScrolledList.popup_event(self, event)
-
- def fill_menu(self):
- 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):
- if 0 <= index < len(self.stack):
- self.browser.show_frame(self.stack[index])
-
- def on_double(self, index):
- 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.browser.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)
-
-
-def get_stack(t=None, f=None):
- if t is None:
- t = sys.last_traceback
- stack = []
- if t and t.tb_frame is f:
- t = t.tb_next
- while f is not None:
- stack.append((f, f.f_lineno))
- if f is self.botframe:
- break
- f = f.f_back
- stack.reverse()
- while t is not None:
- stack.append((t.tb_frame, t.tb_lineno))
- t = t.tb_next
- return stack
-
-
-def getexception(type=None, value=None):
- if type is None:
- 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
-
-
-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
- self.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):
- 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)
- l = Label(subframe, text=name)
- l.grid(row=row, column=0, sticky="nw")
- ## l = Label(subframe, text=svalue, justify="l", wraplength=300)
- l = Entry(subframe, width=0, borderwidth=0)
- l.insert(0, svalue)
- ## l["state"] = "disabled"
- 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/Tools/idle/OutputWindow.py b/Tools/idle/OutputWindow.py
deleted file mode 100644
index 0e7fba231a..0000000000
--- a/Tools/idle/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):
- apply(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:
- apply(text.tag_configure, (tag,), cnf)
- text.tag_raise('sel')
- self.write = self.owin.write
-
-class PseudoFile:
-
- def __init__(self, owin, tags, mark="end"):
- self.owin = owin
- self.tags = tags
- self.mark = mark
-
- def write(self, s):
- self.owin.write(s, self.tags, self.mark)
-
- def writelines(self, l):
- map(self.write, l)
-
- def flush(self):
- pass
diff --git a/Tools/idle/ParenMatch.py b/Tools/idle/ParenMatch.py
deleted file mode 100644
index 1be60c0fda..0000000000
--- a/Tools/idle/ParenMatch.py
+++ /dev/null
@@ -1,189 +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.
-
-WARNING: This extension will fight with the CallTips extension,
-because they both are interested in the KeyRelease-parenright event.
-We'll have to fix IDLE to do something reasonable when two or more
-extensions what to capture the same event.
-"""
-
-import PyParse
-from AutoIndent import AutoIndent, index2line
-from IdleConf import idleconf
-
-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:
- - fix interaction with CallTips
- - 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 = []
-
- keydefs = {
- '<<flash-open-paren>>' : ('<KeyRelease-parenright>',
- '<KeyRelease-bracketright>',
- '<KeyRelease-braceright>'),
- '<<check-restore>>' : ('<KeyPress>',),
- }
-
- windows_keydefs = {}
- unix_keydefs = {}
-
- iconf = idleconf.getsection('ParenMatch')
- STYLE = iconf.getdef('style', 'default')
- FLASH_DELAY = iconf.getint('flash-delay')
- HILITE_CONFIG = iconf.getcolor('hilite')
- BELL = iconf.getboolean('bell')
- del iconf
-
- def __init__(self, editwin):
- self.editwin = editwin
- self.text = editwin.text
- self.finder = LastOpenBracketFinder(editwin)
- self.counter = 0
- self._restore = None
- self.set_style(self.STYLE)
-
- 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_open_paren_event(self, event):
- index = self.finder.find(keysym_type(event.keysym))
- if index is None:
- self.warn_mismatched()
- return
- self._restore = 1
- self.create_tag(index)
- self.set_timeout()
-
- def check_restore_event(self, event=None):
- if self._restore:
- self.text.tag_delete("paren")
- self._restore = None
-
- def handle_restore_timer(self, timer_count):
- if timer_count + 1 == self.counter:
- self.check_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, index):
- """Highlight the single paren that matches"""
- self.text.tag_add("paren", index)
- self.text.tag_config("paren", self.HILITE_CONFIG)
-
- def create_tag_expression(self, index):
- """Highlight the entire expression"""
- self.text.tag_add("paren", index, "insert")
- 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"""
- pass
-
- 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.editwin.text_frame.after(self.FLASH_DELAY,
- lambda self=self, c=self.counter: \
- self.handle_restore_timer(c))
- self.counter = self.counter + 1
-
-def keysym_type(ks):
- # Not all possible chars or keysyms are checked because of the
- # limited context in which the function is used.
- if ks == "parenright" or ks == "(":
- return "paren"
- if ks == "bracketright" or ks == "[":
- return "bracket"
- if ks == "braceright" or ks == "{":
- return "brace"
-
-class LastOpenBracketFinder:
- num_context_lines = AutoIndent.num_context_lines
- indentwidth = AutoIndent.indentwidth
- tabwidth = AutoIndent.tabwidth
- context_use_ps1 = AutoIndent.context_use_ps1
-
- def __init__(self, editwin):
- self.editwin = editwin
- self.text = editwin.text
-
- def _find_offset_in_buf(self, lno):
- y = PyParse.Parser(self.indentwidth, self.tabwidth)
- for context in self.num_context_lines:
- startat = max(lno - context, 1)
- startatindex = `startat` + ".0"
- # rawtext needs to contain everything up to the last
- # character, which was the close paren. the parser also
- # requires that the last line ends with "\n"
- rawtext = self.text.get(startatindex, "insert")[:-1] + "\n"
- 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)
- i = y.get_last_open_bracket_pos()
- return i, y.str
-
- def find(self, right_keysym_type):
- """Return the location of the last open paren"""
- lno = index2line(self.text.index("insert"))
- i, buf = self._find_offset_in_buf(lno)
- if i is None \
- or keysym_type(buf[i]) != right_keysym_type:
- return None
- lines_back = buf[i:].count("\n") - 1
- # subtract one for the "\n" added to please the parser
- upto_open = buf[:i]
- j = upto_open.rfind("\n") + 1 # offset of column 0 of line
- offset = i - j
- return "%d.%d" % (lno - lines_back, offset)
-
- def _build_char_in_string_func(self, startindex):
- def inner(offset, startindex=startindex,
- icis=self.editwin.is_char_in_string):
- return icis(startindex + "%dc" % offset)
- return inner
diff --git a/Tools/idle/PathBrowser.py b/Tools/idle/PathBrowser.py
deleted file mode 100644
index 86cd2707dc..0000000000
--- a/Tools/idle/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/Tools/idle/Percolator.py b/Tools/idle/Percolator.py
deleted file mode 100644
index 5682111137..0000000000
--- a/Tools/idle/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
- apply(self.delegate.insert, args)
- def delete(self, *args):
- print self.name, ": delete", args
- apply(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/Tools/idle/PyParse.py b/Tools/idle/PyParse.py
deleted file mode 100644
index 422a86cc76..0000000000
--- a/Tools/idle/PyParse.py
+++ /dev/null
@@ -1,584 +0,0 @@
-import re
-import sys
-
-# Reason last stmt is continued (or C_NONE if it's not).
-C_NONE, C_BACKSLASH, C_STRING, C_BRACKET = range(4)
-
-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]*
- (?: if
- | for
- | 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.
- #
- # Ack, hack: in the shell window this kills us, because there's
- # no way to tell the differences between output, >>> etc and
- # user input. Indeed, IDLE's first output line makes the rest
- # look like it's in an unclosed paren!:
- # Python 1.5.2 (#0, Apr 13 1999, ...
-
- def find_good_parse_start(self, use_ps1, is_char_in_string=None,
- _synchre=_synchre):
- str, pos = self.str, None
- if use_ps1:
- # shell window
- ps1 = '\n' + sys.ps1
- i = str.rfind(ps1)
- if i >= 0:
- pos = i + len(ps1)
- # make it look like there's a newline instead
- # of ps1 at the start -- hacking here once avoids
- # repeated hackery later
- self.str = str[:pos-1] + '\n' + str[pos:]
- return pos
-
- # File window -- real work.
- 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
- 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
- continuation = C_STRING
- 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 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.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
- 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)
- lastch = ch
- p = p+1
- continue
-
- if ch in ")]}":
- if stack:
- del stack[-1]
- lastch = ch
- p = p+1
- 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.
- lastch = ch
- p = _match_stringre(str, p, q).end()
- continue
-
- if ch == '#':
- # consume comment and trailing newline
- p = str.find('\n', p, q) + 1
- assert p > 0
- 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]
-
- # 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
diff --git a/Tools/idle/PyShell.py b/Tools/idle/PyShell.py
deleted file mode 100644
index 2eaf93623b..0000000000
--- a/Tools/idle/PyShell.py
+++ /dev/null
@@ -1,794 +0,0 @@
-#! /usr/bin/env python
-
-import os
-import sys
-import string
-import getopt
-import re
-import warnings
-import types
-
-import linecache
-from code import InteractiveInterpreter
-
-from Tkinter import *
-import tkMessageBox
-
-from EditorWindow import EditorWindow, fixwordbreaks
-from FileList import FileList
-from ColorDelegator import ColorDelegator
-from UndoDelegator import UndoDelegator
-from OutputWindow import OutputWindow
-from IdleConf import idleconf
-import idlever
-
-# We need to patch linecache.checkcache, because we don't want it
-# to throw away our <pyshell#...> entries.
-# Rather than repeating its code here, we save those entries,
-# then call the original function, and then restore the saved entries.
-def linecache_checkcache(orig_checkcache=linecache.checkcache):
- cache = linecache.cache
- save = {}
- for filename in cache.keys():
- if filename[:1] + filename[-1:] == '<>':
- save[filename] = cache[filename]
- orig_checkcache()
- cache.update(save)
-linecache.checkcache = linecache_checkcache
-
-
-IDENTCHARS = string.ascii_letters + string.digits + "_"
-
-
-# Note: <<newline-and-indent>> event is defined in AutoIndent.py
-
-#$ event <<plain-newline-and-indent>>
-#$ win <Control-j>
-#$ unix <Control-j>
-
-#$ event <<beginning-of-line>>
-#$ win <Control-a>
-#$ win <Home>
-#$ unix <Control-a>
-#$ unix <Home>
-
-#$ event <<history-next>>
-#$ win <Alt-n>
-#$ unix <Alt-n>
-
-#$ event <<history-previous>>
-#$ win <Alt-p>
-#$ unix <Alt-p>
-
-#$ event <<interrupt-execution>>
-#$ win <Control-c>
-#$ unix <Control-c>
-
-#$ event <<end-of-file>>
-#$ win <Control-d>
-#$ unix <Control-d>
-
-#$ event <<open-stack-viewer>>
-
-#$ event <<toggle-debugger>>
-
-
-class PyShellEditorWindow(EditorWindow):
-
- # Regular text edit window when a shell is present
- # XXX ought to merge with regular editor window
- runnable = True # Shell not present, enable Import Module and Run Script
-
- def __init__(self, *args):
- apply(EditorWindow.__init__, (self,) + args)
- self.text.bind("<<set-breakpoint-here>>", self.set_breakpoint_here)
- self.text.bind("<<open-python-shell>>", self.flist.open_shell)
-
- rmenu_specs = [
- ("Set breakpoint here", "<<set-breakpoint-here>>"),
- ]
-
- def set_breakpoint_here(self, event=None):
- if not self.flist.pyshell or not self.flist.pyshell.interp.debugger:
- self.text.bell()
- return
- self.flist.pyshell.interp.debugger.set_breakpoint_here(self)
-
-
-class PyShellFileList(FileList):
-
- # File list when a shell is present
-
- EditorWindow = PyShellEditorWindow
-
- pyshell = None
-
- def open_shell(self, event=None):
- if self.pyshell:
- self.pyshell.wakeup()
- else:
- self.pyshell = PyShell(self)
- self.pyshell.begin()
- return self.pyshell
-
-
-class ModifiedColorDelegator(ColorDelegator):
-
- # Colorizer for the shell window itself
-
- def recolorize_main(self):
- self.tag_remove("TODO", "1.0", "iomark")
- self.tag_add("SYNC", "1.0", "iomark")
- ColorDelegator.recolorize_main(self)
-
- tagdefs = ColorDelegator.tagdefs.copy()
- cconf = idleconf.getsection('Colors')
-
- tagdefs.update({
- "stdin": cconf.getcolor("stdin"),
- "stdout": cconf.getcolor("stdout"),
- "stderr": cconf.getcolor("stderr"),
- "console": cconf.getcolor("console"),
- "ERROR": cconf.getcolor("ERROR"),
- None: cconf.getcolor("normal"),
- })
-
-
-class ModifiedUndoDelegator(UndoDelegator):
-
- # 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 ModifiedInterpreter(InteractiveInterpreter):
-
- def __init__(self, tkconsole):
- self.tkconsole = tkconsole
- locals = sys.modules['__main__'].__dict__
- InteractiveInterpreter.__init__(self, locals=locals)
- self.save_warnings_filters = None
-
- 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()
- InteractiveInterpreter.showsyntaxerror(self, filename)
- else:
- self.runcode(code)
-
- def runsource(self, source):
- # Extend base class to 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")
- return
- try:
- 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 showsyntaxerror(self, filename=None):
- # Extend base class to color the offending position
- # (instead of printing it and pointing at it with a caret)
- text = self.tkconsole.text
- stuff = self.unpackerror()
- if not stuff:
- self.tkconsole.resetoutput()
- InteractiveInterpreter.showsyntaxerror(self, filename)
- return
- 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))
-
- def unpackerror(self):
- type, value, tb = sys.exc_info()
- ok = type is SyntaxError
- if ok:
- try:
- msg, (dummy_filename, lineno, offset, line) = value
- 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)
-
- def checklinecache(self):
- c = linecache.cache
- for key in c.keys():
- if key[:1] + key[-1:] != "<>":
- del c[key]
-
- debugger = None
-
- def setdebugger(self, debugger):
- self.debugger = debugger
-
- def getdebugger(self):
- return self.debugger
-
- def runcode(self, code):
- # Override base class method
- 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 debugger:
- debugger.run(code, self.locals)
- else:
- exec code in self.locals
- except SystemExit:
- if tkMessageBox.askyesno(
- "Exit?",
- "Do you want to exit altogether?",
- default="yes",
- master=self.tkconsole.text):
- raise
- else:
- self.showtraceback()
- if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
- self.tkconsole.open_stack_viewer()
- except:
- self.showtraceback()
- if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
- self.tkconsole.open_stack_viewer()
-
- finally:
- self.tkconsole.endexecuting()
-
- def write(self, s):
- # Override base class write
- self.tkconsole.console.write(s)
-
-
-class PyShell(OutputWindow):
-
- shell_title = "Python Shell"
-
- # Override classes
- ColorDelegator = ModifiedColorDelegator
- UndoDelegator = ModifiedUndoDelegator
-
- # Override menu bar specs
- menu_specs = PyShellEditorWindow.menu_specs[:]
- menu_specs.insert(len(menu_specs)-2, ("debug", "_Debug"))
-
- # New classes
- from IdleHistory import History
-
- def __init__(self, flist=None):
- self.interp = ModifiedInterpreter(self)
- if flist is None:
- root = Tk()
- fixwordbreaks(root)
- root.withdraw()
- flist = PyShellFileList(root)
-
- OutputWindow.__init__(self, flist, None, None)
-
- import __builtin__
- __builtin__.quit = __builtin__.exit = "To exit, type Ctrl-D."
-
- self.auto = self.extensions["AutoIndent"] # Required extension
- self.auto.config(usetabs=1, indentwidth=8, context_use_ps1=1)
-
- 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("<<open-python-shell>>", self.flist.open_shell)
- text.bind("<<toggle-jit-stack-viewer>>", self.toggle_jit_stack_viewer)
-
- self.save_stdout = sys.stdout
- self.save_stderr = sys.stderr
- self.save_stdin = sys.stdin
- sys.stdout = PseudoFile(self, "stdout")
- sys.stderr = PseudoFile(self, "stderr")
- sys.stdin = self
- self.console = PseudoFile(self, "console")
-
- self.history = self.History(self.text)
-
- reading = 0
- executing = 0
- canceled = 0
- endoffile = 0
-
- 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()
- self.resetoutput()
- self.console.write("[DEBUG OFF]\n")
- sys.ps1 = ">>> "
- self.showprompt()
- self.set_debugger_indicator()
-
- def open_debugger(self):
- import Debugger
- self.interp.setdebugger(Debugger.Debugger(self))
- sys.ps1 = "[DEBUG ON]\n>>> "
- self.showprompt()
- self.set_debugger_indicator()
-
- def beginexecuting(self):
- # Helper for ModifiedInterpreter
- self.resetoutput()
- self.executing = 1
- ##self._cancel_check = self.cancel_check
- ##sys.settrace(self._cancel_check)
-
- def endexecuting(self):
- # Helper for ModifiedInterpreter
- ##sys.settrace(None)
- ##self._cancel_check = None
- self.executing = 0
- self.canceled = 0
-
- def close(self):
- # Extend base class method
- if self.executing:
- # XXX Need to ask a question here
- if not tkMessageBox.askokcancel(
- "Kill?",
- "The program is still running; do you want to kill it?",
- default="ok",
- master=self.text):
- return "cancel"
- self.canceled = 1
- if self.reading:
- self.top.quit()
- return "cancel"
- return OutputWindow.close(self)
-
- def _close(self):
- self.close_debugger()
- # 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.auto = None
- self.flist.pyshell = None
- self.history = None
- OutputWindow._close(self) # Really EditorWindow._close
-
- def ispythonsource(self, filename):
- # Override this so EditorWindow never removes the colorizer
- return True
-
- def short_title(self):
- return self.shell_title
-
- COPYRIGHT = \
- 'Type "copyright", "credits" or "license" for more information.'
-
- def begin(self):
- self.resetoutput()
- self.write("Python %s on %s\n%s\nIDLE %s -- press F1 for help\n" %
- (sys.version, sys.platform, self.COPYRIGHT,
- idlever.IDLE_VERSION))
- try:
- sys.ps1
- except AttributeError:
- sys.ps1 = ">>> "
- self.showprompt()
- import Tkinter
- Tkinter._default_root = None
-
- def interact(self):
- self.begin()
- self.top.mainloop()
-
- def readline(self):
- save = self.reading
- try:
- self.reading = 1
- self.top.mainloop()
- finally:
- self.reading = save
- line = self.text.get("iomark", "end-1c")
- self.resetoutput()
- if self.canceled:
- self.canceled = 0
- raise KeyboardInterrupt
- if self.endoffile:
- self.endoffile = 0
- return ""
- return line
-
- def isatty(self):
- return True
-
- def cancel_callback(self, event):
- 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.write("KeyboardInterrupt\n")
- self.showprompt()
- return "break"
- self.endoffile = 0
- self.canceled = 1
- if self.reading:
- self.top.quit()
- 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:
-## if not tkMessageBox.askokcancel(
-## "Exit?",
-## "Are you sure you want to exit?",
-## default="ok", master=self.text):
-## return "break"
- 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.auto.auto_indent(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)
- 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]))
- 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]))
- return "break"
- # No stdin mark -- just get the current line
- self.recall(self.text.get("insert linestart", "insert lineend"))
- return "break"
- # 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.auto.auto_indent(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.auto.auto_indent(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):
- if self.history:
- self.history.recall(s)
-
- 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)
- if not more:
- self.showprompt()
-
- def cancel_check(self, frame, what, args,
- dooneevent=tkinter.dooneevent,
- dontwait=tkinter.DONT_WAIT):
- # Hack -- use the debugger hooks to be able to handle events
- # and interrupt execution at any time.
- # This slows execution down quite a bit, so you may want to
- # disable this (by not calling settrace() in runcode() above)
- # for full-bore (uninterruptable) speed.
- # XXX This should become a user option.
- if self.canceled:
- return
- dooneevent(dontwait)
- if self.canceled:
- self.canceled = 0
- raise KeyboardInterrupt
- return self._cancel_check
-
- def open_stack_viewer(self, event=None):
- 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 showprompt(self):
- self.resetoutput()
- try:
- s = str(sys.ps1)
- except:
- s = ""
- self.console.write(s)
- self.text.mark_set("insert", "end-1c")
-
- 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")
- sys.stdout.softspace = 0
-
- def write(self, s, tags=()):
- self.text.mark_gravity("iomark", "right")
- OutputWindow.write(self, s, tags, "iomark")
- self.text.mark_gravity("iomark", "left")
- if self.canceled:
- self.canceled = 0
- raise KeyboardInterrupt
-
-class PseudoFile:
-
- def __init__(self, shell, tags):
- self.shell = shell
- self.tags = tags
-
- 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.py [-c command] [-d] [-e] [-s] [-t title] [arg] ...
-
--c command run this command
--d enable debugger
--e edit mode; arguments are files to be edited
--s run $IDLESTARTUP or $PYTHONSTARTUP before anything else
--t title set title of shell window
-
-When neither -c nor -e is used, and there are arguments, and the first
-argument is not '-', the first argument is run as a script. Remaining
-arguments are arguments to the script or to the command run by -c.
-"""
-
-def main():
- cmd = None
- edit = 0
- debug = 0
- startup = 0
-
- try:
- opts, args = getopt.getopt(sys.argv[1:], "c:deist:")
- 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
- if o == '-d':
- debug = 1
- if o == '-e':
- edit = 1
- if o == '-s':
- startup = 1
- if o == '-t':
- PyShell.shell_title = a
-
- for i in range(len(sys.path)):
- sys.path[i] = os.path.abspath(sys.path[i])
-
- pathx = []
- if edit:
- for filename in args:
- pathx.append(os.path.dirname(filename))
- elif args and args[0] != "-":
- pathx.append(os.path.dirname(args[0]))
- else:
- pathx.append(os.curdir)
- for dir in pathx:
- dir = os.path.abspath(dir)
- if not dir in sys.path:
- sys.path.insert(0, dir)
-
- global flist, root
- root = Tk(className="Idle")
- fixwordbreaks(root)
- root.withdraw()
- flist = PyShellFileList(root)
-
- if edit:
- for filename in args:
- flist.open(filename)
- else:
- if cmd:
- sys.argv = ["-c"] + args
- else:
- sys.argv = args or [""]
-
-
- shell = PyShell(flist)
- interp = shell.interp
- flist.pyshell = shell
-
- if startup:
- filename = os.environ.get("IDLESTARTUP") or \
- os.environ.get("PYTHONSTARTUP")
- if filename and os.path.isfile(filename):
- interp.execfile(filename)
-
- if debug:
- shell.open_debugger()
- if cmd:
- interp.execsource(cmd)
- elif not edit and args and args[0] != "-":
- interp.execfile(args[0])
-
- shell.begin()
- root.mainloop()
- root.destroy()
-
-
-if __name__ == "__main__":
- main()
diff --git a/Tools/idle/README.txt b/Tools/idle/README.txt
deleted file mode 100644
index 782f6a7b76..0000000000
--- a/Tools/idle/README.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-IDLE 0.5 - February 2000
-------------------------
-
-This is an early release of IDLE, my own attempt at a Tkinter-based
-IDE for Python.
-
-For news about this release, see the file NEWS.txt. (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 or later, so it is currently only usable
-with a Python 1.5.2 (or later) 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).
-
-FEEDBACK
-
-For feedback, please use the Python Bugs List
-(http://www.python.org/search/search_bugs.html).
-
---Guido van Rossum (home page: http://www.python.org/~guido/)
diff --git a/Tools/idle/RemoteInterp.py b/Tools/idle/RemoteInterp.py
deleted file mode 100644
index e6f767102e..0000000000
--- a/Tools/idle/RemoteInterp.py
+++ /dev/null
@@ -1,341 +0,0 @@
-import select
-import socket
-import struct
-import sys
-import types
-
-VERBOSE = None
-
-class SocketProtocol:
- """A simple protocol for sending strings across a socket"""
- BUF_SIZE = 8192
-
- def __init__(self, sock):
- self.sock = sock
- self._buffer = ''
- self._closed = 0
-
- def close(self):
- self._closed = 1
- self.sock.close()
-
- def send(self, buf):
- """Encode buf and write it on the socket"""
- if VERBOSE:
- VERBOSE.write('send %d:%s\n' % (len(buf), `buf`))
- self.sock.send('%d:%s' % (len(buf), buf))
-
- def receive(self, timeout=0):
- """Get next complete string from socket or return None
-
- Raise EOFError on EOF
- """
- buf = self._read_from_buffer()
- if buf is not None:
- return buf
- recvbuf = self._read_from_socket(timeout)
- if recvbuf is None:
- return None
- if recvbuf == '' and self._buffer == '':
- raise EOFError
- if VERBOSE:
- VERBOSE.write('recv %s\n' % `recvbuf`)
- self._buffer = self._buffer + recvbuf
- r = self._read_from_buffer()
- return r
-
- def _read_from_socket(self, timeout):
- """Does not block"""
- if self._closed:
- return ''
- if timeout is not None:
- r, w, x = select.select([self.sock], [], [], timeout)
- if timeout is None or r:
- return self.sock.recv(self.BUF_SIZE)
- else:
- return None
-
- def _read_from_buffer(self):
- buf = self._buffer
- i = buf.find(':')
- if i == -1:
- return None
- buflen = int(buf[:i])
- enclen = i + 1 + buflen
- if len(buf) >= enclen:
- s = buf[i+1:enclen]
- self._buffer = buf[enclen:]
- return s
- else:
- self._buffer = buf
- return None
-
-# helpers for registerHandler method below
-
-def get_methods(obj):
- methods = []
- for name in dir(obj):
- attr = getattr(obj, name)
- if callable(attr):
- methods.append(name)
- if type(obj) == types.InstanceType:
- methods = methods + get_methods(obj.__class__)
- if type(obj) == types.ClassType:
- for super in obj.__bases__:
- methods = methods + get_methods(super)
- return methods
-
-class CommandProtocol:
- def __init__(self, sockp):
- self.sockp = sockp
- self.seqno = 0
- self.handlers = {}
-
- def close(self):
- self.sockp.close()
- self.handlers.clear()
-
- def registerHandler(self, handler):
- """A Handler is an object with handle_XXX methods"""
- for methname in get_methods(handler):
- if methname[:7] == "handle_":
- name = methname[7:]
- self.handlers[name] = getattr(handler, methname)
-
- def send(self, cmd, arg='', seqno=None):
- if arg:
- msg = "%s %s" % (cmd, arg)
- else:
- msg = cmd
- if seqno is None:
- seqno = self.get_seqno()
- msgbuf = self.encode_seqno(seqno) + msg
- self.sockp.send(msgbuf)
- if cmd == "reply":
- return
- reply = self.sockp.receive(timeout=None)
- r_cmd, r_arg, r_seqno = self._decode_msg(reply)
- assert r_seqno == seqno and r_cmd == "reply", "bad reply"
- return r_arg
-
- def _decode_msg(self, msg):
- seqno = self.decode_seqno(msg[:self.SEQNO_ENC_LEN])
- msg = msg[self.SEQNO_ENC_LEN:]
- parts = msg.split(" ", 2)
- if len(parts) == 1:
- cmd = msg
- arg = ''
- else:
- cmd = parts[0]
- arg = parts[1]
- return cmd, arg, seqno
-
- def dispatch(self):
- msg = self.sockp.receive()
- if msg is None:
- return
- cmd, arg, seqno = self._decode_msg(msg)
- self._current_reply = seqno
- h = self.handlers.get(cmd, self.default_handler)
- try:
- r = h(arg)
- except TypeError, msg:
- raise TypeError, "handle_%s: %s" % (cmd, msg)
- if self._current_reply is None:
- if r is not None:
- sys.stderr.write("ignoring %s return value type %s\n" % \
- (cmd, type(r).__name__))
- return
- if r is None:
- r = ''
- if type(r) != types.StringType:
- raise ValueError, "invalid return type for %s" % cmd
- self.send("reply", r, seqno=seqno)
-
- def reply(self, arg=''):
- """Send a reply immediately
-
- otherwise reply will be sent when handler returns
- """
- self.send("reply", arg, self._current_reply)
- self._current_reply = None
-
- def default_handler(self, arg):
- sys.stderr.write("WARNING: unhandled message %s\n" % arg)
- return ''
-
- SEQNO_ENC_LEN = 4
-
- def get_seqno(self):
- seqno = self.seqno
- self.seqno = seqno + 1
- return seqno
-
- def encode_seqno(self, seqno):
- return struct.pack("I", seqno)
-
- def decode_seqno(self, buf):
- return struct.unpack("I", buf)[0]
-
-
-class StdioRedirector:
- """Redirect sys.std{in,out,err} to a set of file-like objects"""
-
- def __init__(self, stdin, stdout, stderr):
- self.stdin = stdin
- self.stdout = stdout
- self.stderr = stderr
-
- def redirect(self):
- self.save()
- sys.stdin = self.stdin
- sys.stdout = self.stdout
- sys.stderr = self.stderr
-
- def save(self):
- self._stdin = sys.stdin
- self._stdout = sys.stdout
- self._stderr = sys.stderr
-
- def restore(self):
- sys.stdin = self._stdin
- sys.stdout = self._stdout
- sys.stderr = self._stderr
-
-class IOWrapper:
- """Send output from a file-like object across a SocketProtocol
-
- XXX Should this be more tightly integrated with the CommandProtocol?
- """
-
- def __init__(self, name, cmdp):
- self.name = name
- self.cmdp = cmdp
- self.buffer = []
-
-class InputWrapper(IOWrapper):
- def write(self, buf):
- # XXX what should this do on Windows?
- raise IOError, (9, '[Errno 9] Bad file descriptor')
-
- def read(self, arg=None):
- if arg is not None:
- if arg <= 0:
- return ''
- else:
- arg = 0
- return self.cmdp.send(self.name, "read,%s" % arg)
-
- def readline(self):
- return self.cmdp.send(self.name, "readline")
-
-class OutputWrapper(IOWrapper):
- def write(self, buf):
- self.cmdp.send(self.name, buf)
-
- def read(self, arg=None):
- return ''
-
-class RemoteInterp:
- def __init__(self, sock):
- self._sock = SocketProtocol(sock)
- self._cmd = CommandProtocol(self._sock)
- self._cmd.registerHandler(self)
-
- def run(self):
- try:
- while 1:
- self._cmd.dispatch()
- except EOFError:
- pass
-
- def handle_execfile(self, arg):
- self._cmd.reply()
- io = StdioRedirector(InputWrapper("stdin", self._cmd),
- OutputWrapper("stdout", self._cmd),
- OutputWrapper("stderr", self._cmd))
- io.redirect()
- execfile(arg, {'__name__':'__main__'})
- io.restore()
- self._cmd.send("terminated")
-
- def handle_quit(self, arg):
- self._cmd.reply()
- self._cmd.close()
-
-def startRemoteInterp(id):
- import os
- # UNIX domain sockets are simpler for starters
- sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- sock.bind("/var/tmp/ri.%s" % id)
- try:
- sock.listen(1)
- cli, addr = sock.accept()
- rinterp = RemoteInterp(cli)
- rinterp.run()
- finally:
- os.unlink("/var/tmp/ri.%s" % id)
-
-class RIClient:
- """Client of the remote interpreter"""
- def __init__(self, sock):
- self._sock = SocketProtocol(sock)
- self._cmd = CommandProtocol(self._sock)
- self._cmd.registerHandler(self)
-
- def execfile(self, file):
- self._cmd.send("execfile", file)
-
- def run(self):
- try:
- while 1:
- self._cmd.dispatch()
- except EOFError:
- pass
-
- def handle_stdout(self, buf):
- sys.stdout.write(buf)
-## sys.stdout.flush()
-
- def handle_stderr(self, buf):
- sys.stderr.write(buf)
-
- def handle_stdin(self, arg):
- if arg == "readline":
- return sys.stdin.readline()
- i = arg.find(",") + 1
- bytes = int(arg[i:])
- if bytes == 0:
- return sys.stdin.read()
- else:
- return sys.stdin.read(bytes)
-
- def handle_terminated(self, arg):
- self._cmd.reply()
- self._cmd.send("quit")
- self._cmd.close()
-
-def riExec(id, file):
- sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- sock.connect("/var/tmp/ri.%s" % id)
- cli = RIClient(sock)
- cli.execfile(file)
- cli.run()
-
-if __name__ == "__main__":
- import getopt
-
- SERVER = 1
- opts, args = getopt.getopt(sys.argv[1:], 'cv')
- for o, v in opts:
- if o == '-c':
- SERVER = 0
- elif o == '-v':
- VERBOSE = sys.stderr
- id = args[0]
-
- if SERVER:
- startRemoteInterp(id)
- else:
- file = args[1]
- riExec(id, file)
diff --git a/Tools/idle/ReplaceDialog.py b/Tools/idle/ReplaceDialog.py
deleted file mode 100644
index c8eb1c8c45..0000000000
--- a/Tools/idle/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/Tools/idle/ScriptBinding.py b/Tools/idle/ScriptBinding.py
deleted file mode 100644
index 3e1279ccbc..0000000000
--- a/Tools/idle/ScriptBinding.py
+++ /dev/null
@@ -1,175 +0,0 @@
-"""Extension to execute code outside the Python shell window.
-
-This adds the following commands (to the Edit menu, until there's a
-separate Python menu):
-
-- Check module (Alt-F5) does a full syntax check of the current module.
-It also runs the tabnanny to catch any inconsistent tabs.
-
-- Import module (F5) is equivalent to either import or reload of the
-current module. The window must have been saved previously. The
-module is added to sys.modules, and is also added to the __main__
-namespace. Output goes to the shell window.
-
-- Run module (Control-F5) does the same but executes the module's
-code in the __main__ namespace.
-
-"""
-
-import sys
-import os
-import imp
-import tkMessageBox
-
-indent_message = """Error: Inconsistent indentation detected!
-
-This means that either:
-
-(1) your indentation is outright incorrect (easy to fix), or
-
-(2) your indentation mixes tabs and spaces in a way that depends on \
-how many spaces a tab is worth.
-
-To fix case 2, change all tabs to spaces by using Select All followed \
-by Untabify Region (both in the Edit menu)."""
-
-class ScriptBinding:
-
- keydefs = {
- '<<check-module>>': ['<Alt-F5>', '<Meta-F5>'],
- '<<import-module>>': ['<F5>'],
- '<<run-script>>': ['<Control-F5>'],
- }
-
- menudefs = [
- ('edit', [None,
- ('Check module', '<<check-module>>'),
- ('Import module', '<<import-module>>'),
- ('Run script', '<<run-script>>'),
- ]
- ),
- ]
-
- def __init__(self, editwin):
- if not editwin.runnable:
- self.menudefs = []
- self.keydefs = {}
- self.editwin = editwin
- # Provide instance variables referenced by Debugger
- # XXX This should be done differently
- self.flist = self.editwin.flist
- self.root = self.flist.root
-
- def check_module_event(self, event):
- filename = self.getfilename()
- if not filename:
- return
- if not self.tabnanny(filename):
- return
- if not self.checksyntax(filename):
- return
-
- def tabnanny(self, filename):
- import tabnanny
- import tokenize
- f = open(filename, 'r')
- try:
- tabnanny.process_tokens(tokenize.generate_tokens(f.readline))
- except tokenize.TokenError, msg:
- self.errorbox("Token error",
- "Token error:\n%s" % str(msg))
- return 0
- 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 0
- return 1
-
- def checksyntax(self, filename):
- f = open(filename, 'r')
- source = f.read()
- f.close()
- if '\r' in source:
- import re
- source = re.sub(r"\r\n", "\n", source)
- if source and source[-1] != '\n':
- source = source + '\n'
- try:
- 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
- except:
- lineno = None
- msg = "*** " + str(err)
- if lineno:
- self.editwin.gotoline(lineno)
- self.errorbox("Syntax error",
- "There's an error in your program:\n" + msg)
- return 1
-
- def import_module_event(self, event):
- filename = self.getfilename()
- if not filename:
- return
-
- modname, ext = os.path.splitext(os.path.basename(filename))
- if sys.modules.has_key(modname):
- mod = sys.modules[modname]
- else:
- mod = imp.new_module(modname)
- sys.modules[modname] = mod
- mod.__file__ = filename
- setattr(sys.modules['__main__'], modname, mod)
-
- dir = os.path.dirname(filename)
- dir = os.path.normpath(os.path.abspath(dir))
- if dir not in sys.path:
- sys.path.insert(0, dir)
-
- flist = self.editwin.flist
- shell = flist.open_shell()
- interp = shell.interp
- interp.runcode("reload(%s)" % modname)
-
- def run_script_event(self, event):
- filename = self.getfilename()
- if not filename:
- return
-
- flist = self.editwin.flist
- shell = flist.open_shell()
- interp = shell.interp
- if (not sys.argv or
- os.path.basename(sys.argv[0]) != os.path.basename(filename)):
- # XXX Too often this discards arguments the user just set...
- sys.argv = [filename]
- interp.execfile(filename)
-
- def getfilename(self):
- # Logic to make sure we have a saved filename
- # XXX Better logic would offer to save!
- if not self.editwin.get_saved():
- name = (self.editwin.short_title() or
- self.editwin.long_title() or
- "Untitled")
- self.errorbox("Not saved",
- "The buffer for %s is not saved.\n" % name +
- "Please save it first!")
- self.editwin.text.focus_set()
- return
- filename = self.editwin.io.filename
- if not filename:
- self.errorbox("No file name",
- "This window has no file name")
- return
- return filename
-
- 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/Tools/idle/ScrolledList.py b/Tools/idle/ScrolledList.py
deleted file mode 100644
index 9211936577..0000000000
--- a/Tools/idle/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/Tools/idle/SearchBinding.py b/Tools/idle/SearchBinding.py
deleted file mode 100644
index 5943e3baec..0000000000
--- a/Tools/idle/SearchBinding.py
+++ /dev/null
@@ -1,97 +0,0 @@
-import tkSimpleDialog
-
-###$ event <<find>>
-###$ win <Control-f>
-###$ unix <Control-u><Control-u><Control-s>
-
-###$ event <<find-again>>
-###$ win <Control-g>
-###$ win <F3>
-###$ unix <Control-u><Control-s>
-
-###$ event <<find-selection>>
-###$ win <Control-F3>
-###$ unix <Control-s>
-
-###$ event <<find-in-files>>
-###$ win <Alt-F3>
-
-###$ event <<replace>>
-###$ win <Control-h>
-
-###$ event <<goto-line>>
-###$ win <Alt-g>
-###$ unix <Alt-g>
-
-class SearchBinding:
-
- windows_keydefs = {
- '<<find-again>>': ['<Control-g>', '<F3>'],
- '<<find-in-files>>': ['<Alt-F3>'],
- '<<find-selection>>': ['<Control-F3>'],
- '<<find>>': ['<Control-f>'],
- '<<replace>>': ['<Control-h>'],
- '<<goto-line>>': ['<Alt-g>'],
- }
-
- unix_keydefs = {
- '<<find-again>>': ['<Control-u><Control-s>'],
- '<<find-in-files>>': ['<Alt-s>', '<Meta-s>'],
- '<<find-selection>>': ['<Control-s>'],
- '<<find>>': ['<Control-u><Control-u><Control-s>'],
- '<<replace>>': ['<Control-r>'],
- '<<goto-line>>': ['<Alt-g>', '<Meta-g>'],
- }
-
- menudefs = [
- ('edit', [
- 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>>'),
- ]),
- ]
-
- def __init__(self, editwin):
- self.editwin = editwin
-
- def find_event(self, event):
- import SearchDialog
- SearchDialog.find(self.editwin.text)
- return "break"
-
- def find_again_event(self, event):
- import SearchDialog
- SearchDialog.find_again(self.editwin.text)
- return "break"
-
- def find_selection_event(self, event):
- import SearchDialog
- SearchDialog.find_selection(self.editwin.text)
- return "break"
-
- def find_in_files_event(self, event):
- import GrepDialog
- GrepDialog.grep(self.editwin.text, self.editwin.io, self.editwin.flist)
- return "break"
-
- def replace_event(self, event):
- import ReplaceDialog
- ReplaceDialog.replace(self.editwin.text)
- return "break"
-
- def goto_line_event(self, event):
- text = self.editwin.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")
diff --git a/Tools/idle/SearchDialog.py b/Tools/idle/SearchDialog.py
deleted file mode 100644
index 8d275c4437..0000000000
--- a/Tools/idle/SearchDialog.py
+++ /dev/null
@@ -1,67 +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):
- return _setup(text).open(text)
-
-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/Tools/idle/SearchDialogBase.py b/Tools/idle/SearchDialogBase.py
deleted file mode 100644
index 9a88e25f56..0000000000
--- a/Tools/idle/SearchDialogBase.py
+++ /dev/null
@@ -1,128 +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):
- self.text = text
- if not self.top:
- self.create_widgets()
- else:
- self.top.deiconify()
- self.top.tkraise()
- 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, weight=0)
- self.top.grid_columnconfigure(1, 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="w")
- e = Entry(self.top, textvariable=var, exportselection=0)
- e.grid(row=self.row, column=1, sticky="we")
- self.row = self.row + 1
- return e
-
- def make_frame(self):
- f = Frame(self.top)
- f.grid(row=self.row, column=0, columnspan=2, sticky="we")
- self.row = self.row + 1
- return f
-
- def make_button(self, label, command, isdef=0, side="left"):
- b = Button(self.buttonframe,
- text=label, command=command,
- default=isdef and "active" or "normal")
- b.pack(side=side)
- return b
-
- def create_entries(self):
- self.ent = self.make_entry("Find:", self.engine.patvar)
-
- def create_option_buttons(self):
- f = self.make_frame()
-
- 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()
-
- 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):
- f = self.buttonframe = self.make_frame()
- b = self.make_button("close", self.close, side="right")
- b.lower()
diff --git a/Tools/idle/SearchEngine.py b/Tools/idle/SearchEngine.py
deleted file mode 100644
index cc40a00c50..0000000000
--- a/Tools/idle/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/Tools/idle/Separator.py b/Tools/idle/Separator.py
deleted file mode 100644
index 7145559c7b..0000000000
--- a/Tools/idle/Separator.py
+++ /dev/null
@@ -1,92 +0,0 @@
-from Tkinter import *
-
-class Separator:
-
- def __init__(self, master, orient, min=10, thickness=5, bg=None):
- self.min = max(1, min)
- self.thickness = max(1, thickness)
- if orient in ("h", "horizontal"):
- self.side = "left"
- self.dim = "width"
- self.dir = "x"
- self.cursor = "sb_h_double_arrow"
- elif orient in ("v", "vertical"):
- self.side = "top"
- self.dim = "height"
- self.dir = "y"
- self.cursor = "sb_v_double_arrow"
- else:
- raise ValueError, "Separator: orient should be h or v"
- self.winfo_dim = "winfo_" + self.dim
- self.master = master = Frame(master)
- master.pack(expand=1, fill="both")
- self.f1 = Frame(master)
- self.f1.pack(expand=1, fill="both", side=self.side)
- self.div = Frame(master, cursor=self.cursor)
- self.div[self.dim] = self.thickness
- self.div.pack(fill="both", side=self.side)
- self.f2 = Frame(master)
- self.f2.pack(expand=1, fill="both", side=self.side)
- self.div.bind("<ButtonPress-1>", self.divider_press)
- if bg:
- ##self.f1["bg"] = bg
- ##self.f2["bg"] = bg
- self.div["bg"] = bg
-
- def parts(self):
- return self.f1, self.f2
-
- def divider_press(self, event):
- self.press_event = event
- self.f1.pack_propagate(0)
- self.f2.pack_propagate(0)
- for f in self.f1, self.f2:
- for dim in "width", "height":
- f[dim] = getattr(f, "winfo_"+dim)()
- self.div.bind("<Motion>", self.div_motion)
- self.div.bind("<ButtonRelease-1>", self.div_release)
- self.div.grab_set()
-
- def div_motion(self, event):
- delta = getattr(event, self.dir) - getattr(self.press_event, self.dir)
- if delta:
- dim1 = getattr(self.f1, self.winfo_dim)()
- dim2 = getattr(self.f2, self.winfo_dim)()
- delta = max(delta, self.min-dim1)
- delta = min(delta, dim2-self.min)
- dim1 = dim1 + delta
- dim2 = dim2 - delta
- self.f1[self.dim] = dim1
- self.f2[self.dim] = dim2
-
- def div_release(self, event):
- self.div_motion(event)
- self.div.unbind("<Motion>")
- self.div.grab_release()
-
-class VSeparator(Separator):
-
- def __init__(self, master, min=10, thickness=5, bg=None):
- Separator.__init__(self, master, "v", min, thickness, bg)
-
-class HSeparator(Separator):
-
- def __init__(self, master, min=10, thickness=5, bg=None):
- Separator.__init__(self, master, "h", min, thickness, bg)
-
-def main():
- root = Tk()
- tlist = []
- outer = HSeparator(root, bg="red")
- for part in outer.parts():
- inner = VSeparator(part, bg="blue")
- for f in inner.parts():
- t = Text(f, width=40, height=10, borderwidth=0)
- t.pack(fill="both", expand=1)
- tlist.append(t)
- tlist[0].insert("1.0", "Make your own Mondrian!")
- tlist[1].insert("1.0", "Move the colored dividers...")
- root.mainloop()
-
-if __name__ == '__main__':
- main()
diff --git a/Tools/idle/StackViewer.py b/Tools/idle/StackViewer.py
deleted file mode 100644
index 7f57c0d385..0000000000
--- a/Tools/idle/StackViewer.py
+++ /dev/null
@@ -1,146 +0,0 @@
-import os
-import sys
-import linecache
-
-from TreeWidget import TreeNode, TreeItem, ScrolledCanvas
-from ObjectBrowser import ObjectTreeItem, make_objecttreeitem
-from OldStackViewer import StackViewer, NamespaceViewer
-
-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 = get_stack(tb)
- self.text = get_exception()
-
- 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)
-## if i == index:
-## item = "> " + item
- 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 get_stack(t=None, f=None):
- if t is None:
- t = sys.last_traceback
- stack = []
- if t and t.tb_frame is f:
- t = t.tb_next
- while f is not None:
- stack.append((f, f.f_lineno))
- if f is self.botframe:
- break
- f = f.f_back
- stack.reverse()
- while t is not None:
- stack.append((t.tb_frame, t.tb_lineno))
- t = t.tb_next
- return stack
-
-def get_exception(type=None, value=None):
- if type is None:
- 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 _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/Tools/idle/TODO.txt b/Tools/idle/TODO.txt
deleted file mode 100644
index b5ec7e81cb..0000000000
--- a/Tools/idle/TODO.txt
+++ /dev/null
@@ -1,211 +0,0 @@
-
-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)
- - 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
-- 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
-- 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?)
-- 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:
-
-- when there's a selection, left/right arrow should go to either
- end of the selection
-- ^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
-
-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,
- 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?
- - 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)
-
-- Config files still editable outside the preferences dialog.
-(Randall Hopper)
-
-- 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)
-
-- 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)
-
-- GUI form designer to kick VB's butt. (Robert Geiger)
-
-- Printing! Possibly via generation of PDF files which the user must
-then send to the printer separately. (Dinu Gherman)
diff --git a/Tools/idle/ToolTip.py b/Tools/idle/ToolTip.py
deleted file mode 100644
index 77d18c2f56..0000000000
--- a/Tools/idle/ToolTip.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# 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() # not in idle
-
-main()
diff --git a/Tools/idle/TreeWidget.py b/Tools/idle/TreeWidget.py
deleted file mode 100644
index d7132648ac..0000000000
--- a/Tools/idle/TreeWidget.py
+++ /dev/null
@@ -1,476 +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
-
-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 (%s)" % `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 = 0
- 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 = 1
- self.canvas.delete(self.image_id)
- self.drawicon()
- self.drawtext()
-
- def deselect(self, event=None):
- if not self.selected:
- return
- self.selected = 0
- 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)
- if self.selected:
- self.label.configure(fg="white", bg="darkblue")
- else:
- self.label.configure(fg="black", bg="white")
- 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 = apply(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-F2>", 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/Tools/idle/UndoDelegator.py b/Tools/idle/UndoDelegator.py
deleted file mode 100644
index 54b0851081..0000000000
--- a/Tools/idle/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 = 0
- 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=1):
- 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 = 1
- 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 = 0
- 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 = 0
- 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 + `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 0
- if self.index2 != cmd.index1:
- return 0
- if self.tags != cmd.tags:
- return 0
- if len(cmd.chars) != 1:
- return 0
- if self.chars and \
- self.classify(self.chars[-1]) != self.classify(cmd.chars):
- return 0
- self.index2 = cmd.index2
- self.chars = self.chars + cmd.chars
- return 1
-
- 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(" " + `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/Tools/idle/WidgetRedirector.py b/Tools/idle/WidgetRedirector.py
deleted file mode 100644
index b49ccf1c59..0000000000
--- a/Tools/idle/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 apply(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(%s, %s)" % (`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
- apply(orig_insert, args)
- orig_insert = redir.register("insert", my_insert)
- root.mainloop()
-
-if __name__ == "__main__":
- main()
diff --git a/Tools/idle/WindowList.py b/Tools/idle/WindowList.py
deleted file mode 100644
index 7e05a57c03..0000000000
--- a/Tools/idle/WindowList.py
+++ /dev/null
@@ -1,85 +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:
- if title == "Python Shell":
- # Hack -- until we have a better way to this
- continue
- 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)
-
- def destroy(self):
- registry.delete(self)
- Toplevel.destroy(self)
-
- def get_title(self):
- # Subclass can override
- return self.wm_title()
-
- def wakeup(self):
- try:
- if self.wm_state() == "iconic":
- self.wm_deiconify()
- else:
- self.tkraise()
- self.focus_set()
- except TclError:
- # This can happen when the window menu was torn off.
- # Simply ignore it.
- pass
diff --git a/Tools/idle/ZoomHeight.py b/Tools/idle/ZoomHeight.py
deleted file mode 100644
index ecc306a733..0000000000
--- a/Tools/idle/ZoomHeight.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Sample extension: zoom a window to maximum height
-
-import re
-import sys
-
-class ZoomHeight:
-
- menudefs = [
- ('windows', [
- ('_Zoom Height', '<<zoom-height>>'),
- ])
- ]
-
- windows_keydefs = {
- '<<zoom-height>>': ['<Alt-F2>'],
- }
- unix_keydefs = {
- '<<zoom-height>>': ['<Control-x><Control-z>'],
- }
-
- 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
- else:
- newy = 24
- newheight = newheight - 96
- if height >= newheight:
- newgeom = ""
- else:
- newgeom = "%dx%d+%d+%d" % (width, newheight, x, newy)
- top.wm_geometry(newgeom)
diff --git a/Tools/idle/__init__.py b/Tools/idle/__init__.py
deleted file mode 100644
index 4c5b567c3a..0000000000
--- a/Tools/idle/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-# Dummy file to make this a potential package.
diff --git a/Tools/idle/config-mac.txt b/Tools/idle/config-mac.txt
deleted file mode 100644
index ee36e13fe7..0000000000
--- a/Tools/idle/config-mac.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-[EditorWindow]
-font-name= monaco
-font-size= 9
diff --git a/Tools/idle/config-unix.txt b/Tools/idle/config-unix.txt
deleted file mode 100644
index 782965f7d1..0000000000
--- a/Tools/idle/config-unix.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-[EditorWindow]
-font-name= courier
-font-size= 10
-print-command=lpr %s
diff --git a/Tools/idle/config-win.txt b/Tools/idle/config-win.txt
deleted file mode 100644
index aeb6ab96c4..0000000000
--- a/Tools/idle/config-win.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-[EditorWindow]
-font-name: courier new
-font-size: 10
-print-command=start /min notepad /p %s
diff --git a/Tools/idle/config.txt b/Tools/idle/config.txt
deleted file mode 100644
index 6f98a3e8e4..0000000000
--- a/Tools/idle/config.txt
+++ /dev/null
@@ -1,64 +0,0 @@
-# IDLE reads several config files to determine user preferences. This
-# file is the default config file. When IDLE starts, it will look in
-# the following four files in order:
-# config.txt the default config file
-# config-[win/unix/mac].txt the generic platform config file
-# config-[sys.platform].txt the specific platform config file
-# ~/.idle the user config file
-# XXX what about Windows?
-#
-# The last definition of each option is used. For example, you can
-# override the default window size (80x24) by defining width and
-# height options in the EditorWindow section of your ~/.idle file
-#
-# IDLE extensions can be enabled and disabled by adding them to one of
-# the config files. To enable an extension, create a section with the
-# same name as the extension, e.g. the [ParenMatch] section below. To
-# disable an extension, either remove the section or add the 'enable'
-# option with the value 0.
-
-[EditorWindow]
-width= 80
-height= 24
-# fonts defined in config-[win/unix].txt
-
-[Colors]
-normal-foreground= black
-normal-background= white
-# These color types are not explicitly defined= sync, todo, stdin
-keyword-foreground= #ff7700
-comment-foreground= #dd0000
-string-foreground= #00aa00
-definition-foreground= #0000ff
-hilite-foreground= #000068
-hilite-background= #006868
-break-foreground= #ff7777
-hit-foreground= #ffffff
-hit-background= #000000
-stdout-foreground= blue
-stderr-foreground= red
-console-foreground= #770000
-error-background= #ff7777
-cursor-background= black
-
-[SearchBinding]
-
-[AutoIndent]
-
-[AutoExpand]
-
-[FormatParagraph]
-
-[ZoomHeight]
-
-[ScriptBinding]
-
-[CallTips]
-
-[ParenMatch]
-enable= 0
-style= expression
-flash-delay= 500
-bell= 1
-hilite-foreground= black
-hilite-background= #43cd80
diff --git a/Tools/idle/eventparse.py b/Tools/idle/eventparse.py
deleted file mode 100644
index f253b2a984..0000000000
--- a/Tools/idle/eventparse.py
+++ /dev/null
@@ -1,89 +0,0 @@
-#! /usr/bin/env python
-
-"""Parse event definitions out of comments in source files."""
-
-import sys
-import glob
-import fileinput
-import pprint
-
-def main():
- hits = []
- sublist = []
- args = sys.argv[1:]
- if not args:
- args = filter(lambda s: 'A' <= s[0] <= 'Z', glob.glob("*.py"))
- if not args:
- print "No arguments, no [A-Z]*.py files."
- return 1
- for line in fileinput.input(args):
- if line[:2] == '#$':
- if not sublist:
- sublist.append('file %s' % fileinput.filename())
- sublist.append('line %d' % fileinput.lineno())
- sublist.append(line[2:-1].strip())
- else:
- if sublist:
- hits.append(sublist)
- sublist = []
- if sublist:
- hits.append(sublist)
- sublist = []
- dd = {}
- for sublist in hits:
- d = {}
- for line in sublist:
- words = line.split(None, 1)
- if len(words) != 2:
- continue
- tag = words[0]
- l = d.get(tag, [])
- l.append(words[1])
- d[tag] = l
- if d.has_key('event'):
- keys = d['event']
- if len(keys) != 1:
- print "Multiple event keys in", d
- print 'File "%s", line %d' % (d['file'], d['line'])
- key = keys[0]
- if dd.has_key(key):
- print "Duplicate event in", d
- print 'File "%s", line %d' % (d['file'], d['line'])
- return
- dd[key] = d
- else:
- print "No event key in", d
- print 'File "%s", line %d' % (d['file'], d['line'])
- winevents = getevents(dd, "win")
- unixevents = getevents(dd, "unix")
- save = sys.stdout
- f = open("keydefs.py", "w")
- try:
- sys.stdout = f
- print "windows_keydefs = \\"
- pprint.pprint(winevents)
- print
- print "unix_keydefs = \\"
- pprint.pprint(unixevents)
- finally:
- sys.stdout = save
- f.close()
-
-def getevents(dd, key):
- res = {}
- events = dd.keys()
- events.sort()
- for e in events:
- d = dd[e]
- if d.has_key(key) or d.has_key("all"):
- list = []
- for x in d.get(key, []) + d.get("all", []):
- list.append(x)
- if key == "unix" and x[:5] == "<Alt-":
- x = "<Meta-" + x[5:]
- list.append(x)
- res[e] = list
- return res
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/Tools/idle/extend.txt b/Tools/idle/extend.txt
deleted file mode 100644
index a1756f0dbe..0000000000
--- a/Tools/idle/extend.txt
+++ /dev/null
@@ -1,120 +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.txt; see below for details.
-
-An IDLE extension is defined by a class. Methods of the class define
-actions that are invoked by those 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 bind key events. Rather, it must define
-one or more virtual events, e.g. <<zoom-height>>, and corresponding
-methods, e.g. zoom_height_event(), and have one or more class (or instance)
-variables that define mappings between virtual events and key sequences,
-e.g. <Alt-F2>. When the extension is loaded, these key sequences will
-be bound to the corresponding virtual events, and the virtual events
-will be bound to the corresponding methods. (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.)
-
-The following class or instance variables are used to define key
-bindings for virtual events:
-
- keydefs for all platforms
- mac_keydefs for Macintosh
- windows_keydefs for Windows
- unix_keydefs for Unix (and other platforms)
-
-Each of these variables, if it exists, must be a dictionary whose
-keys are virtual events, and whose values are lists of key sequences.
-
-An extension can define menu entries in a similar fashion. This is done
-with a class or instance variable named menudefs; it should be a list of
-pair, 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 the key bindings
-are still applied. (This should probably be refined in the future.)
-
-Here is a complete example example:
-
-class ZoomHeight:
-
- menudefs = [
- ('edit', [
- None, # Separator
- ('_Zoom Height', '<<zoom-height>>'),
- ])
- ]
-
- windows_keydefs = {
- '<<zoom-height>>': ['<Alt-F2>'],
- }
- unix_keydefs = {
- '<<zoom-height>>': ['<Control-z><Control-z>'],
- }
-
- 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.txt", which is used
-to to configure the loading of extensions. For each extension,
-you must include a section in config.txt (or in any of the other
-configuration files that are consulted at startup: config-unix.txt,
-config-win.txt, or ~/.idle). A section is headed by the module name
-in square brackets, e.g.
-
- [ZoomHeight]
-
-The section may be empty, or it may define configuration options for
-the extension. (See ParenMatch.py for an example.) A special option
-is 'enable': including
-
- enable = 0
-
-in a section disables that extension. More than one configuration
-file may specify options for the same extension, so a user may disable
-an extension that is loaded by default, or enable an extension that is
-disabled by default.
-
-Extensions can define key bindings and menu entries that reference
-events they don't implement (including standard events); however this is
-not recommended (and may be forbidden in the future).
-
-Extensions are not required to define menu entries for all events they
-implement.
-
-Note: in order to change key bindings, you must currently edit the file
-keydefs. It contains two dictionaries named and formatted like the
-keydefs dictionaries described above, one for the Unix bindings and one
-for the Windows bindings. In the future, a better mechanism will be
-provided.
diff --git a/Tools/idle/help.txt b/Tools/idle/help.txt
deleted file mode 100644
index 63327d7d81..0000000000
--- a/Tools/idle/help.txt
+++ /dev/null
@@ -1,157 +0,0 @@
-[See end for tips.]
-
-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
- 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
- ---
- Close -- close current window (asks to save if unsaved)
- Exit -- close all windows and quit IDLE (asks to save if unsaved)
-
-Edit menu:
-
- Undo -- Undo last change to current window (max 1000 changes)
- Redo -- Redo last undone change to current window
- ---
- Cut -- Copy selection into system-wide clipboard; then delete 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
- ---
- 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
- Untabify region -- Turn *all* tabs into the right number of spaces
- Expand word -- Expand the word you have typed to match another
- word in the same buffer; repeat to get a different expansion
- Format Paragraph -- Reformat the current blank-line-separated paragraph
- ---
- Import module -- Import or reload the current module
- Run script -- Execute the current file in the __main__ namespace
-
-Windows menu:
-
- Zoom Height -- toggles the window between normal size (24x80)
- 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).
-
-Debug menu (in the Python Shell window only):
-
- Go to file/line -- look around the insert point for a filename
- and linenumber, open the file, and show the line
- Open stack viewer -- show the stack traceback of the last exception
- Debugger toggle -- Run commands in the shell under the debugger
- JIT Stack viewer toggle -- Open stack viewer on traceback
-
-Basic editing and navigation:
-
- Backspace deletes to the left; DEL deletes to the right
- Arrow keys and Page Up/Down to move around
- Home/End go to begin/end of line
- Control-Home/End go to begin/end of file
- Some Emacs bindings may also work, e.g. ^B/^P/^A/^E/^D/^L
-
-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 1-4 spaces (in the
- Python Shell window one tab). See also the indent/dedent
- region commands in the edit menu.
-
-Python Shell window:
-
- ^C interrupts executing command
- ^D sends end-of-file; closes window if typed at >>> prompt
-
- Command history:
-
- Alt-p retrieves previous command matching what you have typed
- Alt-n retrieves next
- Return while on any previous command retrieves that command
- Alt-/ (Expand word) is also useful here
-
-Syntax colors:
-
- The coloring is applied in a background "thread", so you may
- occasionally see uncolorized text. To change the color
- scheme, edit the [Colors] section in config.txt (or add a
- [Colors] section to ~/.idle).
-
- Python syntax colors:
-
- Keywords orange
- Strings green
- Comments red
- Definitions blue
-
- Shell colors:
-
- Console output brown
- stdout blue
- stderr dark green
- stdin black
-
-Other preferences:
-
- Most preferences can be changed by editing one of the
- configuration text files: config.txt (generic) or one of
- config-unix.txt, config-win.txt, config.mac.txt (platform
- specific). User-specific preferences can be stored in
- $HOME/.idle, which overrides the config*.txt files.
-
- To change keyboard bindings, edit Bindings.py
-
-Command line usage:
-
- idle.py [-c command] [-d] [-e] [-s] [-t title] [arg] ...
-
- -c command run this command
- -d enable debugger
- -e edit mode; arguments are files to be edited
- -s run $IDLESTARTUP or $PYTHONSTARTUP first
- -t title set title of shell window
-
- If there are arguments:
-
- If -e is used, arguments are files opened for editing and
- sys.argv reflects the arguments passed to IDLE itself.
-
- Otherwise, if -c is used, all arguments are placed in
- sys.argv[1:...], with sys.argv[0] set to '-c'.
-
- Otherwise, if neither -e nor -c is used, the first
- argument is a script which is executed with the remaining
- arguments in sys.argv[1:...] and sys.argv[0] set to the
- script name. If the script name is '-', no script is
- executed but an interactive Python session is started; the
- arguments are still available in sys.argv.
diff --git a/Tools/idle/idle b/Tools/idle/idle
deleted file mode 100755
index 2a854978a5..0000000000
--- a/Tools/idle/idle
+++ /dev/null
@@ -1,12 +0,0 @@
-#! /usr/bin/env python
-
-import os
-import sys
-from idlelib import IdleConf
-
-idle_dir = os.path.dirname(IdleConf.__file__)
-IdleConf.load(idle_dir)
-
-# defer importing Pyshell until IdleConf is loaded
-from idlelib import PyShell
-PyShell.main()
diff --git a/Tools/idle/idle.bat b/Tools/idle/idle.bat
deleted file mode 100644
index 9024d02e0d..0000000000
--- a/Tools/idle/idle.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-rem idle.bat
-
-start idle.pyw %1 %2 %3 %4 %5 %6 %7 %8 %9
diff --git a/Tools/idle/idle.py b/Tools/idle/idle.py
deleted file mode 100755
index 8638a165b4..0000000000
--- a/Tools/idle/idle.py
+++ /dev/null
@@ -1,4 +0,0 @@
-#! /usr/bin/env python
-
-import PyShell
-PyShell.main()
diff --git a/Tools/idle/idle.pyw b/Tools/idle/idle.pyw
deleted file mode 100644
index 79fe26fef5..0000000000
--- a/Tools/idle/idle.pyw
+++ /dev/null
@@ -1,8 +0,0 @@
-try:
- import idle
-except SystemExit:
- raise
-except:
- import traceback
- traceback.print_exc()
- raw_input("Hit return to exit...")
diff --git a/Tools/idle/idlever.py b/Tools/idle/idlever.py
deleted file mode 100644
index 82c5781d56..0000000000
--- a/Tools/idle/idlever.py
+++ /dev/null
@@ -1 +0,0 @@
-IDLE_VERSION = "0.8"
diff --git a/Tools/idle/keydefs.py b/Tools/idle/keydefs.py
deleted file mode 100644
index 9761258e5f..0000000000
--- a/Tools/idle/keydefs.py
+++ /dev/null
@@ -1,57 +0,0 @@
-windows_keydefs = \
-{'<<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>'],
- '<<dump-undo-state>>': ['<Control-backslash>'],
- '<<end-of-file>>': ['<Control-d>'],
- '<<help>>': ['<F1>'],
- '<<history-next>>': ['<Alt-n>'],
- '<<history-previous>>': ['<Alt-p>'],
- '<<interrupt-execution>>': ['<Control-c>'],
- '<<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>>': ['<Control-a>'],
- '<<toggle-auto-coloring>>': ['<Control-slash>'],
- '<<undo>>': ['<Control-z>']}
-
-unix_keydefs = \
-{'<<Copy>>': ['<Alt-w>', '<Meta-w>'],
- '<<Cut>>': ['<Control-w>'],
- '<<Paste>>': ['<Control-y>'],
- '<<beginning-of-line>>': ['<Control-a>', '<Home>'],
- '<<center-insert>>': ['<Control-l>'],
- '<<close-all-windows>>': ['<Control-x><Control-c>'],
- '<<close-window>>': ['<Control-x><Control-0>', '<Control-x><Key-0>'],
- '<<do-nothing>>': ['<Control-x>'],
- '<<dump-undo-state>>': ['<Control-backslash>'],
- '<<end-of-file>>': ['<Control-d>'],
- '<<help>>': ['<F1>'],
- '<<history-next>>': ['<Alt-n>', '<Meta-n>'],
- '<<history-previous>>': ['<Alt-p>', '<Meta-p>'],
- '<<interrupt-execution>>': ['<Control-c>'],
- '<<open-class-browser>>': ['<Control-x><Control-b>'],
- '<<open-module>>': ['<Control-x><Control-m>'],
- '<<open-new-window>>': ['<Control-x><Control-n>'],
- '<<open-window-from-file>>': ['<Control-x><Control-f>'],
- '<<plain-newline-and-indent>>': ['<Control-j>'],
- '<<print-window>>': ['<Control-x><Control-p>'],
- '<<redo>>': ['<Alt-z>', '<Meta-z>'],
- '<<save-copy-of-window-as-file>>': ['<Control-x><w>'],
- '<<save-window-as-file>>': ['<Control-x><Control-w>'],
- '<<save-window>>': ['<Control-x><Control-s>'],
- '<<select-all>>': ['<Alt-a>', '<Meta-a>'],
- '<<toggle-auto-coloring>>': ['<Control-slash>'],
- '<<undo>>': ['<Control-z>']}
diff --git a/Tools/idle/setup.py b/Tools/idle/setup.py
deleted file mode 100644
index b96909244b..0000000000
--- a/Tools/idle/setup.py
+++ /dev/null
@@ -1,100 +0,0 @@
-import os, glob, sys
-from distutils.core import setup
-from distutils.command.build_py import build_py
-from distutils.command.install_lib import install_lib
-import idlever
-
-try:
- pos = sys.argv.index("--check-tkinter")
-except ValueError:
- pass
-else:
- del sys.argv[pos]
- try:
- import _tkinter
- except ImportError:
- print >>sys.stderr, "Cannot install IDLE without _tkinter"
- raise SystemExit
-
-try:
- package_dir = os.path.join(os.environ["SRCDIR"], "Tools", "idle")
-except KeyError:
- package_dir = "."
-
-# name of idle package
-idlelib = "idlelib"
-
-# the normal build_py would not incorporate the .txt files
-txt_files = ['config-unix.txt','config-win.txt','config.txt', 'help.txt']
-Icons = glob.glob1(os.path.join(package_dir,"Icons"),"*.gif")
-class idle_build_py(build_py):
- def get_plain_outfile(self, build_dir, package, file):
- # like get_module_outfile, but does not append .py
- outfile_path = [build_dir] + list(package) + [file]
- return apply(os.path.join, outfile_path)
-
- def run(self):
- # Copies all .py files, then also copies the txt and gif files
- build_py.run(self)
- assert self.packages == [idlelib]
- for name in txt_files:
- outfile = self.get_plain_outfile(self.build_lib, [idlelib], name)
- dir = os.path.dirname(outfile)
- self.mkpath(dir)
- self.copy_file(os.path.join(package_dir, name), outfile,
- preserve_mode = 0)
- for name in Icons:
- outfile = self.get_plain_outfile(self.build_lib,
- [idlelib,"Icons"], name)
- dir = os.path.dirname(outfile)
- self.mkpath(dir)
- self.copy_file(os.path.join(package_dir, "Icons", name),
- outfile, preserve_mode = 0)
-
- def get_source_files(self):
- # returns the .py files, the .txt files, and the icons
- icons = [os.path.join(package_dir, "Icons",name) for name in Icons]
- txts = [os.path.join(package_dir, name) for name in txt_files]
- return build_py.get_source_files(self)+txt_files+icons
-
- def get_outputs(self, include_bytecode=1):
- # returns the built files
- outputs = build_py.get_outputs(self, include_bytecode)
- if not include_bytecode:
- return outputs
- for name in txt_files:
- filename = self.get_plain_outfile(self.build_lib,
- [idlelib], name)
- outputs.append(filename)
- for name in Icons:
- filename = self.get_plain_outfile(self.build_lib,
- [idlelib,"Icons"], name)
- outputs.append(filename)
- return outputs
-
-# Arghhh. install_lib thinks that all files returned from build_py's
-# get_outputs are bytecode files
-class idle_install_lib(install_lib):
- def _bytecode_filenames(self, files):
- files = [n for n in files if n.endswith('.py')]
- return install_lib._bytecode_filenames(self,files)
-
-
-setup(name="IDLE",
- version = idlever.IDLE_VERSION,
- description = "IDLE, the Python IDE",
- author = "Guido van Rossum",
- author_email = "guido@python.org",
- #url =
- long_description =
-"""IDLE is a Tkinter based IDE for Python. It is written in 100% pure
-Python and works both on Windows and Unix. It features a multi-window
-text editor with multiple undo, Python colorizing, and many other things,
-as well as a Python shell window and a debugger.""",
-
- cmdclass = {'build_py':idle_build_py,
- 'install_lib':idle_install_lib},
- package_dir = {idlelib: package_dir},
- packages = [idlelib],
- scripts = [os.path.join(package_dir, 'idle')]
- )
diff --git a/Tools/idle/testcode.py b/Tools/idle/testcode.py
deleted file mode 100644
index 05eaa562cd..0000000000
--- a/Tools/idle/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()