PyShell.py revision 8eab008b53c9aeb1ceabac378ec4bf306fdde44b
17aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#! /usr/bin/env python
27aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
37aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport os
46e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiserimport os.path
57aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport sys
67aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport string
77aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport getopt
87aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport re
95d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teyimport socket
105d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teyimport time
11003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiserimport threading
125d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teyimport traceback
13628339807e76d075a610aa6dd963e702ef25afc8Kurt B. Kaiserimport types
14e2b5624ee8cc4ac505162e6b3d99cfb4c2e8aa77Martin v. Löwisimport io
157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport linecache
177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererfrom code import InteractiveInterpreter
18d676a3a221b99e1b352e18be0939158dfc37ef82Terry Jan Reedyfrom platform import python_version
197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
202303b1c19abd79c94da327d630cbac6f4e83a05cKurt B. Kaisertry:
216634bf2919d855ccd821e878b8cc00c7209f1cbeGeorg Brandl    from Tkinter import *
222303b1c19abd79c94da327d630cbac6f4e83a05cKurt B. Kaiserexcept ImportError:
236634bf2919d855ccd821e878b8cc00c7209f1cbeGeorg Brandl    print>>sys.__stderr__, "** IDLE can't import Tkinter.  " \
242303b1c19abd79c94da327d630cbac6f4e83a05cKurt B. Kaiser                           "Your Python may not be configured for Tk. **"
252303b1c19abd79c94da327d630cbac6f4e83a05cKurt B. Kaiser    sys.exit(1)
266634bf2919d855ccd821e878b8cc00c7209f1cbeGeorg Brandlimport tkMessageBox
277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
28d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib.EditorWindow import EditorWindow, fixwordbreaks
29d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib.FileList import FileList
30d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib.ColorDelegator import ColorDelegator
31d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib.UndoDelegator import UndoDelegator
32d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib.OutputWindow import OutputWindow
33d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib.configHandler import idleConf
34d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib import idlever
35d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib import rpc
36d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib import Debugger
37d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib import RemoteDebugger
38d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xiclunafrom idlelib import macosxSupport
395d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
40b97641994617115321719d4ecf797a461e2d5cf2Kurt B. KaiserIDENTCHARS = string.ascii_letters + string.digits + "_"
41013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. KaiserHOST = '127.0.0.1' # python execution server on localhost loopback
42013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. KaiserPORT = 0  # someday pass in host, port for remote debug capability
43b97641994617115321719d4ecf797a461e2d5cf2Kurt B. Kaiser
44a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaisertry:
45a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser    from signal import SIGTERM
46a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiserexcept ImportError:
47a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser    SIGTERM = 15
48a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser
4949a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser# Override warnings module to write to warning_stream.  Initialize to send IDLE
5049a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser# internal warnings to the console.  ScriptBinding.check_syntax() will
5149a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser# temporarily redirect the stream to the shell window to display warnings when
5249a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser# checking user's code.
538eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedywarning_stream = sys.__stderr__  # None, at least on Windows, if no console.
548eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedyimport warnings
558eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy
568eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedydef idle_formatwarning(message, category, filename, lineno, line=None):
578eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    """Format warnings the IDLE way."""
588eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy
598eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    s = "\nWarning (from warnings module):\n"
608eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    s += '  File \"%s\", line %s\n' % (filename, lineno)
618eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    if line is None:
628eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy        line = linecache.getline(filename, lineno)
638eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    line = line.strip()
648eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    if line:
658eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy        s += "    %s\n" % line
668eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    s += "%s: %s\n" % (category.__name__, message)
678eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    return s
688eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy
698eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedydef idle_showwarning(
708eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy        message, category, filename, lineno, file=None, line=None):
718eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    """Show Idle-format warning (after replacing warnings.showwarning).
728eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy
738eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    The differences are the formatter called, the file=None replacement,
748eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    which can be None, the capture of the consequence AttributeError,
758eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    and the output of a hard-coded prompt.
768eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    """
778eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    if file is None:
788eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy        file = warning_stream
798eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    try:
808eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy        file.write(idle_formatwarning(
818eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy                message, category, filename, lineno, line=line))
828eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy        file.write(">>> ")
838eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    except (AttributeError, IOError):
848eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy        pass  # if file (probably __stderr__) is invalid, skip warning.
858eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy
868eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy_warnings_showwarning = None
878eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy
888eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedydef capture_warnings(capture):
898eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    "Replace warning.showwarning with idle_showwarning, or reverse."
908eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy
918eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    global _warnings_showwarning
928eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    if capture:
938eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy        if _warnings_showwarning is None:
948eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy            _warnings_showwarning = warnings.showwarning
958eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy            warnings.showwarning = idle_showwarning
968eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    else:
978eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy        if _warnings_showwarning is not None:
988eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy            warnings.showwarning = _warnings_showwarning
998eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy            _warnings_showwarning = None
1008eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy
1018eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedycapture_warnings(True)
1025d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
103f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiserdef extended_linecache_checkcache(filename=None,
104f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser                                  orig_checkcache=linecache.checkcache):
10545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    """Extend linecache.checkcache to preserve the <pyshell#...> entries
10645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
107f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser    Rather than repeating the linecache code, patch it to save the
108f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser    <pyshell#...> entries, call the original linecache.checkcache()
109f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo    (skipping them), and then restore the saved entries.
110f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser
111f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser    orig_checkcache is bound at definition time to the original
112f7a8899f33fb0a1efe6cb57fc1b712fa1059d0a6Kurt B. Kaiser    method, allowing it to be patched.
11345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    """
1147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    cache = linecache.cache
1157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    save = {}
116f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo    for key in list(cache):
117f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo        if key[:1] + key[-1:] == '<>':
118f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo            save[key] = cache.pop(key)
119f198ac2db28109c0761395b80c7b482f9167f515Guilherme Polo    orig_checkcache(filename)
1207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    cache.update(save)
1216655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
122818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiser# Patch linecache.checkcache():
123818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiserlinecache.checkcache = extended_linecache_checkcache
1247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
12545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
1267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass PyShellEditorWindow(EditorWindow):
127183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser    "Regular text edit window in IDLE, supports breakpoints"
12845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
1297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def __init__(self, *args):
13045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        self.breakpoints = []
131931237e2e66975c54e2ac6c5e503ee2992a22bcfRaymond Hettinger        EditorWindow.__init__(self, *args)
1327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.bind("<<set-breakpoint-here>>", self.set_breakpoint_here)
13345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        self.text.bind("<<clear-breakpoint-here>>", self.clear_breakpoint_here)
1347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.bind("<<open-python-shell>>", self.flist.open_shell)
1357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
136bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        self.breakpointPath = os.path.join(idleConf.GetUserCfgDir(),
137bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                                           'breakpoints.lst')
138a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        # whenever a file is changed, restore breakpoints
139bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        def filename_changed_hook(old_hook=self.io.filename_change_hook,
140bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                                  self=self):
141a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey            self.restore_file_breaks()
142a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey            old_hook()
143a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        self.io.set_filename_change_hook(filename_changed_hook)
144d7c9d9cdcdc179a0c9a458c70f814cd9db024e5dRoger Serwy        if self.io.filename:
145d7c9d9cdcdc179a0c9a458c70f814cd9db024e5dRoger Serwy            self.restore_file_breaks()
146a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey
1475018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov    rmenu_specs = [
1485018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov        ("Cut", "<<cut>>", "rmenu_check_cut"),
1495018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov        ("Copy", "<<copy>>", "rmenu_check_copy"),
1505018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov        ("Paste", "<<paste>>", "rmenu_check_paste"),
1515018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov        ("Set Breakpoint", "<<set-breakpoint-here>>", None),
1525018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov        ("Clear Breakpoint", "<<clear-breakpoint-here>>", None)
1535018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov    ]
1547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
155a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey    def set_breakpoint(self, lineno):
15645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        text = self.text
15745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        filename = self.io.filename
158a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        text.tag_add("BREAK", "%d.0" % lineno, "%d.0" % (lineno+1))
15945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        try:
16045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            i = self.breakpoints.index(lineno)
161a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        except ValueError:  # only add if missing, i.e. do once
16245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            self.breakpoints.append(lineno)
16345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        try:    # update the subprocess debugger
16445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug = self.flist.pyshell.interp.debugger
16545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug.set_breakpoint_here(filename, lineno)
16645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        except: # but debugger may not be active right now....
16745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            pass
1687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
169a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey    def set_breakpoint_here(self, event=None):
170a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        text = self.text
171a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        filename = self.io.filename
172a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        if not filename:
173a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey            text.bell()
174a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey            return
175a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        lineno = int(float(text.index("insert")))
176a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        self.set_breakpoint(lineno)
177a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey
178669f4c3850eaaf4e00a79032ef960a79e6ca6ad7Kurt B. Kaiser    def clear_breakpoint_here(self, event=None):
17945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        text = self.text
18045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        filename = self.io.filename
18145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        if not filename:
18245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            text.bell()
183669f4c3850eaaf4e00a79032ef960a79e6ca6ad7Kurt B. Kaiser            return
18445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        lineno = int(float(text.index("insert")))
18545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        try:
18645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            self.breakpoints.remove(lineno)
18745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        except:
18845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            pass
18945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        text.tag_remove("BREAK", "insert linestart",\
19045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                        "insert lineend +1char")
19145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        try:
19245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug = self.flist.pyshell.interp.debugger
19345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug.clear_breakpoint_here(filename, lineno)
19445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        except:
19545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            pass
19645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
19745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    def clear_file_breaks(self):
19845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        if self.breakpoints:
19945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            text = self.text
20045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            filename = self.io.filename
20145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            if not filename:
20245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                text.bell()
20345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                return
20445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            self.breakpoints = []
20545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            text.tag_remove("BREAK", "1.0", END)
20645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            try:
20745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                debug = self.flist.pyshell.interp.debugger
20845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                debug.clear_file_breaks(filename)
20945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            except:
21045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                pass
21145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
212a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey    def store_file_breaks(self):
213bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        "Save breakpoints when file is saved"
214bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        # XXX 13 Dec 2002 KBK Currently the file must be saved before it can
215bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     be run.  The breaks are saved at that time.  If we introduce
216bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     a temporary file save feature the save breaks functionality
217bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     needs to be re-verified, since the breaks at the time the
218bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     temp file is created may differ from the breaks at the last
2197f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        #     permanent save of the file.  Currently, a break introduced
2207f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        #     after a save will be effective, but not persistent.
2217f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        #     This is necessary to keep the saved breaks synched with the
2227f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        #     saved file.
223bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #
224bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     Breakpoints are set as tagged ranges in the text.  Certain
225bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     kinds of edits cause these ranges to be deleted: Inserting
226bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     or deleting a line just before a breakpoint, and certain
227bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     deletions prior to a breakpoint.  These issues need to be
228bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     investigated and understood.  It's not clear if they are
229bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     Tk issues or IDLE issues, or whether they can actually
230bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     be fixed.  Since a modified file has to be saved before it is
231bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     run, and since self.breakpoints (from which the subprocess
232bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     debugger is loaded) is updated during the save, the visible
233bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     breaks stay synched with the subprocess even if one of these
234bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     unexpected breakpoint deletions occurs.
235bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        breaks = self.breakpoints
236bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        filename = self.io.filename
237a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        try:
23840ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily            with open(self.breakpointPath,"r") as old_file:
23940ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily                lines = old_file.readlines()
240a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        except IOError:
241bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            lines = []
24240ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily        try:
24340ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily            with open(self.breakpointPath,"w") as new_file:
24440ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily                for line in lines:
24540ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily                    if not line.startswith(filename + '='):
24640ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily                        new_file.write(line)
24740ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily                self.update_breakpoints()
24840ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily                breaks = self.breakpoints
24940ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily                if breaks:
25040ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily                    new_file.write(filename + '=' + str(breaks) + '\n')
25140ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily        except IOError as err:
25240ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily            if not getattr(self.root, "breakpoint_error_displayed", False):
25340ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily                self.root.breakpoint_error_displayed = True
25440ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily                tkMessageBox.showerror(title='IDLE Error',
25540ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily                    message='Unable to update breakpoint list:\n%s'
25640ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily                        % str(err),
25740ad04171d7f3773ed29a3ff13a1d58eefab57c2Ned Deily                    parent=self.text)
258a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey
259a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey    def restore_file_breaks(self):
260a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        self.text.update()   # this enables setting "BREAK" tags to be visible
261d7c9d9cdcdc179a0c9a458c70f814cd9db024e5dRoger Serwy        if self.io is None:
262d7c9d9cdcdc179a0c9a458c70f814cd9db024e5dRoger Serwy            # can happen if IDLE closes due to the .update() call
263d7c9d9cdcdc179a0c9a458c70f814cd9db024e5dRoger Serwy            return
264bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        filename = self.io.filename
265bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        if filename is None:
266bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            return
26769371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey        if os.path.isfile(self.breakpointPath):
268bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            lines = open(self.breakpointPath,"r").readlines()
26969371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey            for line in lines:
270bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                if line.startswith(filename + '='):
2716655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser                    breakpoint_linenumbers = eval(line[len(filename)+1:])
27269371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey                    for breakpoint_linenumber in breakpoint_linenumbers:
27369371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey                        self.set_breakpoint(breakpoint_linenumber)
274a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey
275bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser    def update_breakpoints(self):
276bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        "Retrieves all the breakpoints in the current window"
277a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        text = self.text
278bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        ranges = text.tag_ranges("BREAK")
279bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        linenumber_list = self.ranges_to_linenumbers(ranges)
280bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        self.breakpoints = linenumber_list
281bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser
282bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser    def ranges_to_linenumbers(self, ranges):
283bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        lines = []
284bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        for index in range(0, len(ranges), 2):
2858a15c37df7415189f6e9291df074fba68b68df43Andrew Svetlov            lineno = int(float(ranges[index].string))
2868a15c37df7415189f6e9291df074fba68b68df43Andrew Svetlov            end = int(float(ranges[index+1].string))
287bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            while lineno < end:
288bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                lines.append(lineno)
289bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                lineno += 1
290bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        return lines
291bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser
29211220fad1d7eee24f1d9809c6d5023875099cb37Kurt B. Kaiser# XXX 13 Dec 2002 KBK Not used currently
293bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#    def saved_change_hook(self):
294bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#        "Extend base method - clear breaks if module is modified"
295bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#        if not self.get_saved():
296bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#            self.clear_file_breaks()
297bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#        EditorWindow.saved_change_hook(self)
29845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
29945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    def _close(self):
30045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        "Extend base method - clear breaks when module is closed"
30145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        self.clear_file_breaks()
30245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        EditorWindow._close(self)
3036655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
3047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
3057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass PyShellFileList(FileList):
306183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser    "Extend base class: IDLE supports a shell and breakpoints"
3077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
308183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser    # override FileList's class variable, instances return PyShellEditorWindow
309183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser    # instead of EditorWindow when new edit windows are created.
3107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    EditorWindow = PyShellEditorWindow
3117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
3127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    pyshell = None
3137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
3147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def open_shell(self, event=None):
3157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.pyshell:
316183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser            self.pyshell.top.wakeup()
3177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
3187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.pyshell = PyShell(self)
319af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            if self.pyshell:
320af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser                if not self.pyshell.begin():
321af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser                    return None
3227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return self.pyshell
3237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
3247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
3257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass ModifiedColorDelegator(ColorDelegator):
32683118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser    "Extend base class: colorizer for the shell window itself"
3276655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
328b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava    def __init__(self):
329b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        ColorDelegator.__init__(self)
330b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        self.LoadTagDefs()
3317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
3327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def recolorize_main(self):
3337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tag_remove("TODO", "1.0", "iomark")
3347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tag_add("SYNC", "1.0", "iomark")
3357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        ColorDelegator.recolorize_main(self)
3366655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
337b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava    def LoadTagDefs(self):
338b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        ColorDelegator.LoadTagDefs(self)
339b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        theme = idleConf.GetOption('main','Theme','name')
340b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        self.tagdefs.update({
341b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            "stdin": {'background':None,'foreground':None},
342b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            "stdout": idleConf.GetHighlight(theme, "stdout"),
343b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            "stderr": idleConf.GetHighlight(theme, "stderr"),
344b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            "console": idleConf.GetHighlight(theme, "console"),
345b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        })
3467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
3475e247b705e3bdd77967bca76601b791003389adaNed Deily    def removecolors(self):
3485e247b705e3bdd77967bca76601b791003389adaNed Deily        # Don't remove shell color tags before "iomark"
3495e247b705e3bdd77967bca76601b791003389adaNed Deily        for tag in self.tagdefs:
3505e247b705e3bdd77967bca76601b791003389adaNed Deily            self.tag_remove(tag, "iomark", "end")
3515e247b705e3bdd77967bca76601b791003389adaNed Deily
3527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass ModifiedUndoDelegator(UndoDelegator):
35383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser    "Extend base class: forbid insert/delete before the I/O mark"
3547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
3557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def insert(self, index, chars, tags=None):
3567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
3577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if self.delegate.compare(index, "<", "iomark"):
3587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.delegate.bell()
3597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return
3607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except TclError:
3617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            pass
3627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        UndoDelegator.insert(self, index, chars, tags)
3637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
3647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def delete(self, index1, index2=None):
3657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
3667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if self.delegate.compare(index1, "<", "iomark"):
3677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.delegate.bell()
3687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return
3697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except TclError:
3707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            pass
3717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        UndoDelegator.delete(self, index1, index2)
3727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
37367fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser
37467fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiserclass MyRPCClient(rpc.RPCClient):
37567fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser
37667fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser    def handle_EOF(self):
37767fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser        "Override the base class - just re-raise EOFError"
37867fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser        raise EOFError
37967fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser
3808d1f11b0ef7ec31db75a4e640e9dfd75fc4ee08dKurt B. Kaiser
3817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass ModifiedInterpreter(InteractiveInterpreter):
3827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
3837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def __init__(self, tkconsole):
3847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tkconsole = tkconsole
3857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        locals = sys.modules['__main__'].__dict__
3867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        InteractiveInterpreter.__init__(self, locals=locals)
38794bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        self.save_warnings_filters = None
3886f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        self.restarting = False
389013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser        self.subprocess_arglist = None
390013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser        self.port = PORT
39186d669bdb849ab5cf99623494c706a5ab416e84eNed Deily        self.original_compiler_flags = self.compile.compiler.flags
3927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
39316ce43a6d8c4f6e0da088c8bc68dbbbdbb2e9a36Roger Serwy    _afterid = None
3945d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    rpcclt = None
3955d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    rpcpid = None
3965d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
3976655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser    def spawn_subprocess(self):
398c8a730bf72b1c95651a8a39766bf56635956a2e0Florent Xicluna        if self.subprocess_arglist is None:
399013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser            self.subprocess_arglist = self.build_subprocess_arglist()
40062df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser        args = self.subprocess_arglist
401b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser        self.rpcpid = os.spawnv(os.P_NOWAIT, sys.executable, args)
40263857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser
403f53dec2e4e8a017641db4de73456a2724a75e64bTony Lownds    def build_subprocess_arglist(self):
404013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser        assert (self.port!=0), (
405013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser            "Socket should have been assigned a port number.")
4062398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        w = ['-W' + s for s in sys.warnoptions]
407d076153ee8a9e4e2e7ecd3ff77fdb3b7aaf7ef77Georg Brandl        if 1/2 > 0: # account for new division
408d076153ee8a9e4e2e7ecd3ff77fdb3b7aaf7ef77Georg Brandl            w.append('-Qnew')
4092398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        # Maybe IDLE is installed and is being accessed via sys.path,
4102398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        # or maybe it's not installed and the idle.py script is being
4112398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        # run from the IDLE source directory.
41262df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser        del_exitf = idleConf.GetOption('main', 'General', 'delete-exitfunc',
41362df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser                                       default=False, type='bool')
4142398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        if __name__ == 'idlelib.PyShell':
41570a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald            command = "__import__('idlelib.run').run.main(%r)" % (del_exitf,)
416f2324b9e8964a7aef964ae6168827ad300f920d6Tony Lownds        else:
41770a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald            command = "__import__('run').main(%r)" % (del_exitf,)
418b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser        if sys.platform[:3] == 'win' and ' ' in sys.executable:
419b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser            # handle embedded space in path by quoting the argument
420b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser            decorated_exec = '"%s"' % sys.executable
421b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser        else:
422b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser            decorated_exec = sys.executable
423b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser        return [decorated_exec] + w + ["-c", command, str(self.port)]
424f2324b9e8964a7aef964ae6168827ad300f920d6Tony Lownds
42563857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser    def start_subprocess(self):
426013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser        addr = (HOST, self.port)
427013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser        # GUI makes several attempts to acquire socket, listens for connection
4285db4843c5e7d2b420b9ca9189b9e30669b62e55eKurt B. Kaiser        for i in range(3):
4295d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            time.sleep(i)
4305d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            try:
43167fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser                self.rpcclt = MyRPCClient(addr)
4325d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey                break
4335d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            except socket.error, err:
434af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser                pass
4355d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        else:
436af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            self.display_port_binding_error()
437af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            return None
438013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser        # if PORT was 0, system will assign an 'ephemeral' port. Find it out:
439013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser        self.port = self.rpcclt.listening_sock.getsockname()[1]
440013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser        # if PORT was not 0, probably working with a remote execution server
441013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser        if PORT != 0:
442013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser            # To allow reconnection within the 2MSL wait (cf. Stevens TCP
443013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser            # V1, 18.6),  set SO_REUSEADDR.  Note that this can be problematic
444013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser            # on Windows since the implementation allows two active sockets on
445013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser            # the same address!
446013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser            self.rpcclt.listening_sock.setsockopt(socket.SOL_SOCKET,
447013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser                                           socket.SO_REUSEADDR, 1)
448013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser        self.spawn_subprocess()
449013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser        #time.sleep(20) # test to simulate GUI not accepting connection
450b417936d4080004b6a7811fb411c6f77db4cc262Kurt B. Kaiser        # Accept the connection from the Python execution server
451af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        self.rpcclt.listening_sock.settimeout(10)
452af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        try:
453af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            self.rpcclt.accept()
454af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        except socket.timeout, err:
455af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            self.display_no_subprocess_error()
456af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            return None
4579abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        self.rpcclt.register("console", self.tkconsole)
4589abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        self.rpcclt.register("stdin", self.tkconsole.stdin)
459969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        self.rpcclt.register("stdout", self.tkconsole.stdout)
460969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        self.rpcclt.register("stderr", self.tkconsole.stderr)
4615d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.rpcclt.register("flist", self.tkconsole.flist)
4628cd0def10dc028e3522a04bd136c67f92f90da04Kurt B. Kaiser        self.rpcclt.register("linecache", linecache)
4639f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        self.rpcclt.register("interp", self)
464b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy        self.transfer_path(with_cwd=True)
4655d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.poll_subprocess()
466af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        return self.rpcclt
4675d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
468b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy    def restart_subprocess(self, with_cwd=False):
4696f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        if self.restarting:
470af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            return self.rpcclt
4716f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        self.restarting = True
47263857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser        # close only the subprocess debugger
47345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        debug = self.getdebugger()
47445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        if debug:
475003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            try:
4769ec454ec00088e051195e80363499a14cafc131aKurt B. Kaiser                # Only close subprocess debugger, don't unregister gui_adap!
477003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser                RemoteDebugger.close_subprocess_debugger(self.rpcclt)
478003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            except:
479003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser                pass
480003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        # Kill subprocess, spawn a new one, accept connection.
481a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.rpcclt.close()
482a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.unix_terminate()
4837f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        console = self.tkconsole
4846f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        was_executing = console.executing
4857f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        console.executing = False
48663857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser        self.spawn_subprocess()
487af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        try:
488af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            self.rpcclt.accept()
489af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        except socket.timeout, err:
490af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            self.display_no_subprocess_error()
491af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            return None
492b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy        self.transfer_path(with_cwd=with_cwd)
493ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy        console.stop_readline()
4941061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        # annotate restart in shell window and mark it
4954cc5ef5dbe12cbc9dc1a00c7583ffd0117f4c31eKurt B. Kaiser        console.text.delete("iomark", "end-1c")
4966f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        if was_executing:
4976f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser            console.write('\n')
4986f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser            console.showprompt()
4991061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        halfbar = ((int(console.width) - 16) // 2) * '='
5001061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        console.write(halfbar + ' RESTART ' + halfbar)
5011061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        console.text.mark_set("restart", "end-1c")
5021061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        console.text.mark_gravity("restart", "left")
5037f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        console.showprompt()
504003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        # restart subprocess debugger
50545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        if debug:
5069ec454ec00088e051195e80363499a14cafc131aKurt B. Kaiser            # Restarted debugger connects to current instance of debug GUI
50763857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser            gui = RemoteDebugger.restart_subprocess_debugger(self.rpcclt)
50845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            # reload remote debugger breakpoints for all PyShellEditWindows
50945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug.load_breakpoints()
51086d669bdb849ab5cf99623494c706a5ab416e84eNed Deily        self.compile.compiler.flags = self.original_compiler_flags
5116f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        self.restarting = False
512af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        return self.rpcclt
51345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
514003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    def __request_interrupt(self):
515a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.rpcclt.remotecall("exec", "interrupt_the_server", (), {})
516003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser
517003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    def interrupt_subprocess(self):
518a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        threading.Thread(target=self.__request_interrupt).start()
519003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser
520a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser    def kill_subprocess(self):
52116ce43a6d8c4f6e0da088c8bc68dbbbdbb2e9a36Roger Serwy        if self._afterid is not None:
52216ce43a6d8c4f6e0da088c8bc68dbbbdbb2e9a36Roger Serwy            self.tkconsole.text.after_cancel(self._afterid)
523af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        try:
524af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            self.rpcclt.close()
525af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        except AttributeError:  # no socket
526af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            pass
527a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.unix_terminate()
528a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.tkconsole.executing = False
529a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.rpcclt = None
53011c53e2ea7f7d2a2969c98e81c1489c4e72254c4Kurt B. Kaiser
531a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser    def unix_terminate(self):
532a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        "UNIX: make sure subprocess is terminated and collect status"
533a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        if hasattr(os, 'kill'):
534a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            try:
535a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                os.kill(self.rpcpid, SIGTERM)
536a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            except OSError:
537a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                # process already terminated:
538a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                return
539a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            else:
540a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                try:
541a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                    os.waitpid(self.rpcpid, 0)
542a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                except OSError:
543a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                    return
54411c53e2ea7f7d2a2969c98e81c1489c4e72254c4Kurt B. Kaiser
545b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy    def transfer_path(self, with_cwd=False):
546b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy        if with_cwd:        # Issue 13506
547b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy            path = ['']     # include Current Working Directory
548b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy            path.extend(sys.path)
549b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy        else:
550b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy            path = sys.path
5511d4ae48f48b2da82a89769a714644eb55a541888Terry Jan Reedy
552f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        self.runcommand("""if 1:
553f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        import sys as _sys
55470a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald        _sys.path = %r
555f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        del _sys
556b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy        \n""" % (path,))
557f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
5585d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    active_seq = None
5595d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
5605d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    def poll_subprocess(self):
5615d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        clt = self.rpcclt
5625d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if clt is None:
5635d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            return
564003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        try:
565a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            response = clt.pollresponse(self.active_seq, wait=0.05)
566a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        except (EOFError, IOError, KeyboardInterrupt):
567a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            # lost connection or subprocess terminated itself, restart
568a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            # [the KBI is from rpc.SocketIO.handle_EOF()]
56967fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser            if self.tkconsole.closing:
57067fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser                return
571003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            response = None
572003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            self.restart_subprocess()
5735d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if response:
5745d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            self.tkconsole.resetoutput()
5755d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            self.active_seq = None
5765d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            how, what = response
577bc2861313cc53711d837a0e8a5bf303bf5291bf3Kurt B. Kaiser            console = self.tkconsole.console
5785d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            if how == "OK":
5795d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey                if what is not None:
58070a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald                    print >>console, repr(what)
5815d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            elif how == "EXCEPTION":
5825d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey                if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
5835d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey                    self.remote_stack_viewer()
5845d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            elif how == "ERROR":
5850930c43e43f79617a33a6c3be32afbe184780307Kurt B. Kaiser                errmsg = "PyShell.ModifiedInterpreter: Subprocess ERROR:\n"
5860930c43e43f79617a33a6c3be32afbe184780307Kurt B. Kaiser                print >>sys.__stderr__, errmsg, what
587bc2861313cc53711d837a0e8a5bf303bf5291bf3Kurt B. Kaiser                print >>console, errmsg, what
588bc2861313cc53711d837a0e8a5bf303bf5291bf3Kurt B. Kaiser            # we received a response to the currently active seq number:
589d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser            try:
590d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser                self.tkconsole.endexecuting()
591d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser            except AttributeError:  # shell may have closed
592d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser                pass
59388957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser        # Reschedule myself
59488957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser        if not self.tkconsole.closing:
59516ce43a6d8c4f6e0da088c8bc68dbbbdbb2e9a36Roger Serwy            self._afterid = self.tkconsole.text.after(
59616ce43a6d8c4f6e0da088c8bc68dbbbdbb2e9a36Roger Serwy                self.tkconsole.pollinterval, self.poll_subprocess)
5975d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
59845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    debugger = None
59945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
60045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    def setdebugger(self, debugger):
60145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        self.debugger = debugger
60245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
60345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    def getdebugger(self):
60445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        return self.debugger
60545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
6069f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser    def open_remote_stack_viewer(self):
6079f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        """Initiate the remote stack viewer from a separate thread.
6089f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser
6099f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        This method is called from the subprocess, and by returning from this
6109f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        method we allow the subprocess to unblock.  After a bit the shell
6119f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        requests the subprocess to open the remote stack viewer which returns a
612c569cfebcebd3d3c8cf77e6c8971a19c78ff7261Ezio Melotti        static object looking at the last exception.  It is queried through
6139f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        the RPC mechanism.
6149f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser
6159f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        """
6169f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        self.tkconsole.text.after(300, self.remote_stack_viewer)
6179f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        return
6189f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser
6195d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    def remote_stack_viewer(self):
620d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna        from idlelib import RemoteObjectBrowser
621a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        oid = self.rpcclt.remotequeue("exec", "stackviewer", ("flist",), {})
6225d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if oid is None:
6235d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            self.tkconsole.root.bell()
6245d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            return
6255d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        item = RemoteObjectBrowser.StubObjectTreeItem(self.rpcclt, oid)
626d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna        from idlelib.TreeWidget import ScrolledCanvas, TreeNode
6275d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        top = Toplevel(self.tkconsole.root)
62873360a3e61274ffcc4c9fc3d09746bd6603e92a5Kurt B. Kaiser        theme = idleConf.GetOption('main','Theme','name')
62973360a3e61274ffcc4c9fc3d09746bd6603e92a5Kurt B. Kaiser        background = idleConf.GetHighlight(theme, 'normal')['background']
63073360a3e61274ffcc4c9fc3d09746bd6603e92a5Kurt B. Kaiser        sc = ScrolledCanvas(top, bg=background, highlightthickness=0)
6315d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        sc.frame.pack(expand=1, fill="both")
6325d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        node = TreeNode(sc.canvas, None, item)
6335d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        node.expand()
6345d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        # XXX Should GC the remote tree when closing the window
6355d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
6367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    gid = 0
6377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def execsource(self, source):
63983118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Like runsource() but assumes complete exec source"
6407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        filename = self.stuffsource(source)
6417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.execfile(filename, source)
6427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def execfile(self, filename, source=None):
64483118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Execute an existing file"
6457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if source is None:
6467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            source = open(filename, "r").read()
6477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
6487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            code = compile(source, filename, "exec")
6497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except (OverflowError, SyntaxError):
6507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.tkconsole.resetoutput()
6517f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            tkerr = self.tkconsole.stderr
6527f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            print>>tkerr, '*** Error in script or command!\n'
6537f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            print>>tkerr, 'Traceback (most recent call last):'
6547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            InteractiveInterpreter.showsyntaxerror(self, filename)
6556e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            self.tkconsole.showprompt()
6567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
6577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.runcode(code)
6587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def runsource(self, source):
66083118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Extend base class method: Stuff the source in the line cache first"
6617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        filename = self.stuffsource(source)
6627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.more = 0
66394bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        self.save_warnings_filters = warnings.filters[:]
66494bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        warnings.filterwarnings(action="error", category=SyntaxWarning)
665837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        if isinstance(source, types.UnicodeType):
666d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna            from idlelib import IOBinding
667837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser            try:
668837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser                source = source.encode(IOBinding.encoding)
669837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser            except UnicodeError:
670837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser                self.tkconsole.resetoutput()
671cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser                self.write("Unsupported characters in input\n")
672837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser                return
67394bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        try:
674935ea9a0b291b2ce42a5cf02d9f2f2955e21a6aaKurt B. Kaiser            # InteractiveInterpreter.runsource() calls its runcode() method,
675935ea9a0b291b2ce42a5cf02d9f2f2955e21a6aaKurt B. Kaiser            # which is overridden (see below)
67694bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser            return InteractiveInterpreter.runsource(self, source, filename)
67794bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        finally:
67894bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser            if self.save_warnings_filters is not None:
67994bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser                warnings.filters[:] = self.save_warnings_filters
68094bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser                self.save_warnings_filters = None
6817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def stuffsource(self, source):
68383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Stuff source in the filename cache"
6847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        filename = "<pyshell#%d>" % self.gid
6857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.gid = self.gid + 1
686837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        lines = source.split("\n")
6877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        linecache.cache[filename] = len(source)+1, 0, lines, filename
6887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return filename
6896655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
69011659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser    def prepend_syspath(self, filename):
69111659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser        "Prepend sys.path with file's directory if not already included"
69211659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser        self.runcommand("""if 1:
69370a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald            _filename = %r
69411659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            import sys as _sys
69511659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            from os.path import dirname as _dirname
69611659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            _dir = _dirname(_filename)
69711659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            if not _dir in _sys.path:
69811659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser                _sys.path.insert(0, _dir)
69911659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            del _filename, _sys, _dirname, _dir
70070a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald            \n""" % (filename,))
70111659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser
7027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def showsyntaxerror(self, filename=None):
70383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        """Extend base class method: Add Colorizing
70483118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser
70583118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        Color the offending position instead of printing it and pointing at it
70683118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        with a caret.
70783118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser
70883118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        """
7097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text = self.tkconsole.text
7107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        stuff = self.unpackerror()
7116e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser        if stuff:
7126e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            msg, lineno, offset, line = stuff
7136e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            if lineno == 1:
7146e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser                pos = "iomark + %d chars" % (offset-1)
7156e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            else:
7166e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser                pos = "iomark linestart + %d lines + %d chars" % \
7176e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser                      (lineno-1, offset-1)
7186e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            text.tag_add("ERROR", pos)
7196e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            text.see(pos)
7206e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            char = text.get(pos)
7216e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            if char and char in IDENTCHARS:
7226e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser                text.tag_add("ERROR", pos + " wordstart", pos)
7237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.tkconsole.resetoutput()
7246e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            self.write("SyntaxError: %s\n" % str(msg))
7257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
7266e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            self.tkconsole.resetoutput()
7276e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            InteractiveInterpreter.showsyntaxerror(self, filename)
7286e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser        self.tkconsole.showprompt()
7297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def unpackerror(self):
7317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        type, value, tb = sys.exc_info()
7327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        ok = type is SyntaxError
7337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if ok:
7347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            try:
7357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                msg, (dummy_filename, lineno, offset, line) = value
736bea57c6c355ba98cd9019d13e5adf7d715377edfKurt B. Kaiser                if not offset:
737bea57c6c355ba98cd9019d13e5adf7d715377edfKurt B. Kaiser                    offset = 0
7387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            except:
7397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                ok = 0
7407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if ok:
7417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return msg, lineno, offset, line
7427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
7437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return None
7447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def showtraceback(self):
74683118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Extend base class method to reset output properly"
7477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tkconsole.resetoutput()
7487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.checklinecache()
7497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        InteractiveInterpreter.showtraceback(self)
7505d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
7515d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            self.tkconsole.open_stack_viewer()
7527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def checklinecache(self):
7547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        c = linecache.cache
7557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        for key in c.keys():
7567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if key[:1] + key[-1:] != "<>":
7577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                del c[key]
7587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7595d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    def runcommand(self, code):
76083118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Run the code without invoking the debugger"
7615d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        # The code better not raise an exception!
7625d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.tkconsole.executing:
763f4c4f115d80a26eb83d90593c24a1580f236c443Neal Norwitz            self.display_executing_dialog()
7645d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            return 0
7655d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.rpcclt:
766a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            self.rpcclt.remotequeue("exec", "runcode", (code,), {})
7675d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        else:
7685d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            exec code in self.locals
7695d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        return 1
7705d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
7717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def runcode(self, code):
77283118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Override base class method"
7735d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.tkconsole.executing:
774003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            self.interp.restart_subprocess()
7755d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.checklinecache()
77694bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        if self.save_warnings_filters is not None:
77794bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser            warnings.filters[:] = self.save_warnings_filters
77894bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser            self.save_warnings_filters = None
7797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        debugger = self.debugger
7807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
7817f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            self.tkconsole.beginexecuting()
782dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser            if not debugger and self.rpcclt is not None:
783dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                self.active_seq = self.rpcclt.asyncqueue("exec", "runcode",
784dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                                                        (code,), {})
785dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser            elif debugger:
786dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                debugger.run(code, self.locals)
787dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser            else:
788dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                exec code in self.locals
789dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser        except SystemExit:
790dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser            if not self.tkconsole.closing:
791dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                if tkMessageBox.askyesno(
792dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                    "Exit?",
793dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                    "Do you want to exit altogether?",
794dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                    default="yes",
795dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                    master=self.tkconsole.text):
796f137e1df2c02f5782c5b0f18a2b3b649f255f63aKurt B. Kaiser                    raise
797dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                else:
798dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                    self.showtraceback()
799dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser            else:
800dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                raise
801dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser        except:
802dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser            if use_subprocess:
803dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                print >>self.tkconsole.stderr, \
804dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                         "IDLE internal error in runcode()"
8057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.showtraceback()
806dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                self.tkconsole.endexecuting()
807dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser            else:
808dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                if self.tkconsole.canceled:
809dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                    self.tkconsole.canceled = False
810dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                    print >>self.tkconsole.stderr, "KeyboardInterrupt"
811dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                else:
812dddeb0eec4dcb1ba3c408a54ad01e1a1ea4d5670Kurt B. Kaiser                    self.showtraceback()
8137f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        finally:
8147f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            if not use_subprocess:
815d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser                try:
816d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser                    self.tkconsole.endexecuting()
817d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser                except AttributeError:  # shell may have closed
818d112bc7958151fa17c4ccb27413c43e45b8476fbKurt B. Kaiser                    pass
8197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def write(self, s):
82183118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Override base class method"
8227f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        self.tkconsole.stderr.write(s)
8237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
824af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser    def display_port_binding_error(self):
825af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        tkMessageBox.showerror(
826af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "Port Binding Error",
827013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser            "IDLE can't bind to a TCP/IP port, which is necessary to "
828013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser            "communicate with its Python execution server.  This might be "
829013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser            "because no networking is installed on this computer.  "
830013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser            "Run IDLE with the -n command line switch to start without a "
831013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser            "subprocess and refer to Help/IDLE Help 'Running without a "
832013d6cc0df238013075930c5adb1c4724f38aa49Kurt B. Kaiser            "subprocess' for further details.",
833af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            master=self.tkconsole.text)
834af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser
835af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser    def display_no_subprocess_error(self):
836af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        tkMessageBox.showerror(
837af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "Subprocess Startup Error",
838af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "IDLE's subprocess didn't make connection.  Either IDLE can't "
839af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "start a subprocess or personal firewall software is blocking "
840af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "the connection.",
841af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            master=self.tkconsole.text)
842af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser
843af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser    def display_executing_dialog(self):
844af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        tkMessageBox.showerror(
845af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "Already executing",
846af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "The Python Shell window is already executing a command; "
847af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "please wait until it is finished.",
848af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            master=self.tkconsole.text)
849af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser
850af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser
8517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass PyShell(OutputWindow):
8527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
853d676a3a221b99e1b352e18be0939158dfc37ef82Terry Jan Reedy    shell_title = "Python " + python_version() + " Shell"
8547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    # Override classes
8567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    ColorDelegator = ModifiedColorDelegator
8577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    UndoDelegator = ModifiedUndoDelegator
8587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
859f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # Override menus
860dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser    menu_specs = [
861dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        ("file", "_File"),
862dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        ("edit", "_Edit"),
8634cc5ef5dbe12cbc9dc1a00c7583ffd0117f4c31eKurt B. Kaiser        ("debug", "_Debug"),
8641061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        ("options", "_Options"),
865dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        ("windows", "_Windows"),
866dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        ("help", "_Help"),
867dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser    ]
8687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
86919302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren    if macosxSupport.runningAsOSXApp():
87019302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren        menu_specs[-2] = ("windows", "_Window")
87119302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren
87219302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren
8737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    # New classes
874d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna    from idlelib.IdleHistory import History
8757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def __init__(self, flist=None):
8778f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser        if use_subprocess:
87867fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser            ms = self.menu_specs
87967fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser            if ms[2][0] != "shell":
8807ae354846fff616746eeba6d27ccd5c175591caeKurt B. Kaiser                ms.insert(2, ("shell", "She_ll"))
8817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.interp = ModifiedInterpreter(self)
8827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if flist is None:
8837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            root = Tk()
8847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            fixwordbreaks(root)
8857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            root.withdraw()
8867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            flist = PyShellFileList(root)
8875afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
8887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        OutputWindow.__init__(self, flist, None, None)
8895afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
8906af44986029c84c4c5df62a64c60a6ed978a3693Kurt B. Kaiser##        self.config(usetabs=1, indentwidth=8, context_use_ps1=1)
8916af44986029c84c4c5df62a64c60a6ed978a3693Kurt B. Kaiser        self.usetabs = True
8926af44986029c84c4c5df62a64c60a6ed978a3693Kurt B. Kaiser        # indentwidth must be 8 when using tabs.  See note in EditorWindow:
8936af44986029c84c4c5df62a64c60a6ed978a3693Kurt B. Kaiser        self.indentwidth = 8
8946af44986029c84c4c5df62a64c60a6ed978a3693Kurt B. Kaiser        self.context_use_ps1 = True
8955afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
8967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text = self.text
8977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.configure(wrap="char")
8987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<newline-and-indent>>", self.enter_callback)
8997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<plain-newline-and-indent>>", self.linefeed_callback)
9007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<interrupt-execution>>", self.cancel_callback)
9017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<end-of-file>>", self.eof_callback)
9027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<open-stack-viewer>>", self.open_stack_viewer)
90357bfe5dc5a4873026679fb911939beb69e35a9e8Kurt B. Kaiser        text.bind("<<toggle-debugger>>", self.toggle_debugger)
9047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<toggle-jit-stack-viewer>>", self.toggle_jit_stack_viewer)
9058f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser        if use_subprocess:
9068f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser            text.bind("<<view-restart>>", self.view_restart_mark)
9078f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser            text.bind("<<restart-shell>>", self.restart_shell)
9085afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
9097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.save_stdout = sys.stdout
9107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.save_stderr = sys.stderr
9117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.save_stdin = sys.stdin
912d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna        from idlelib import IOBinding
9139abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        self.stdin = PseudoInputFile(self, "stdin", IOBinding.encoding)
9149abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        self.stdout = PseudoOutputFile(self, "stdout", IOBinding.encoding)
9159abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        self.stderr = PseudoOutputFile(self, "stderr", IOBinding.encoding)
9169abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        self.console = PseudoOutputFile(self, "console", IOBinding.encoding)
9175d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if not use_subprocess:
9185d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            sys.stdout = self.stdout
9195d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            sys.stderr = self.stderr
920e2b5624ee8cc4ac505162e6b3d99cfb4c2e8aa77Martin v. Löwis            sys.stdin = self.stdin
9215afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
9227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.history = self.History(self.text)
9235afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
92488957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser        self.pollinterval = 50  # millisec
9255d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
9264d5bc6031ca883201f87e0e3c94e5746f9f91439Kurt B. Kaiser    def get_standard_extension_names(self):
9274d5bc6031ca883201f87e0e3c94e5746f9f91439Kurt B. Kaiser        return idleConf.GetExtensions(shell_only=True)
9284d5bc6031ca883201f87e0e3c94e5746f9f91439Kurt B. Kaiser
929003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    reading = False
930003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    executing = False
931003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    canceled = False
932003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    endoffile = False
933003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    closing = False
934ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy    _stop_readline_flag = False
9357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
93649a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser    def set_warning_stream(self, stream):
937d91614234375621f3b78cb9c8c5a58b77c961fe8Skip Montanaro        global warning_stream
938d91614234375621f3b78cb9c8c5a58b77c961fe8Skip Montanaro        warning_stream = stream
93949a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser
94049a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser    def get_warning_stream(self):
94149a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser        return warning_stream
94249a5fe107fceb0239d87119842b20a7421043b5aKurt B. Kaiser
9437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def toggle_debugger(self, event=None):
9447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.executing:
9457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            tkMessageBox.showerror("Don't debug now",
9467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                "You can only toggle the debugger when idle",
9477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                master=self.text)
9487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.set_debugger_indicator()
9497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
9507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
9517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            db = self.interp.getdebugger()
9527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if db:
9537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.close_debugger()
9547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            else:
9557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.open_debugger()
9567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def set_debugger_indicator(self):
9587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        db = self.interp.getdebugger()
9597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.setvar("<<toggle-debugger>>", not not db)
9607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9611061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser    def toggle_jit_stack_viewer(self, event=None):
9627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        pass # All we need is the variable
9637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def close_debugger(self):
9657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        db = self.interp.getdebugger()
9667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if db:
9677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.interp.setdebugger(None)
9687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            db.close()
969ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiser            if self.interp.rpcclt:
970ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiser                RemoteDebugger.close_remote_debugger(self.interp.rpcclt)
9717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.resetoutput()
9727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.console.write("[DEBUG OFF]\n")
9737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            sys.ps1 = ">>> "
9747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.showprompt()
9757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.set_debugger_indicator()
9767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def open_debugger(self):
9785d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.interp.rpcclt:
9797f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            dbg_gui = RemoteDebugger.start_remote_debugger(self.interp.rpcclt,
9807f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                                                           self)
9817f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        else:
9827f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            dbg_gui = Debugger.Debugger(self)
9837f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        self.interp.setdebugger(dbg_gui)
9847f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        dbg_gui.load_breakpoints()
9855d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        sys.ps1 = "[DEBUG ON]\n>>> "
9865d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.showprompt()
9875d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.set_debugger_indicator()
9885d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
9897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def beginexecuting(self):
990ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiser        "Helper for ModifiedInterpreter"
9917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.resetoutput()
9927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.executing = 1
9937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def endexecuting(self):
99583118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Helper for ModifiedInterpreter"
9967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.executing = 0
9977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.canceled = 0
9985d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.showprompt()
9997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def close(self):
100183118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Extend EditorWindow.close()"
10027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.executing:
1003003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            response = tkMessageBox.askokcancel(
10047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                "Kill?",
1005003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser                "The program is still running!\n Do you want to kill it?",
10067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                default="ok",
10077f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                parent=self.text)
10085b63acd31e0e40c1a9a9e9762905b0054ff37994Benjamin Peterson            if response is False:
10097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return "cancel"
1010ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy        self.stop_readline()
10115c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser        self.canceled = True
101267fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser        self.closing = True
101388957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser        return EditorWindow.close(self)
10147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def _close(self):
101683118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Extend EditorWindow._close(), shut down debugger and execution server"
10177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.close_debugger()
10187f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        if use_subprocess:
10197f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            self.interp.kill_subprocess()
10207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # Restore std streams
10217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sys.stdout = self.save_stdout
10227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sys.stderr = self.save_stderr
10237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sys.stdin = self.save_stdin
10247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # Break cycles
10257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.interp = None
10267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.console = None
10277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.flist.pyshell = None
10287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.history = None
102983118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        EditorWindow._close(self)
10307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def ispythonsource(self, filename):
103283118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Override EditorWindow method: never remove the colorizer"
1033837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        return True
10347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def short_title(self):
10367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return self.shell_title
10377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
103894bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser    COPYRIGHT = \
10398f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser          'Type "copyright", "credits" or "license()" for more information.'
104094bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser
10417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def begin(self):
10427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.resetoutput()
10437f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        if use_subprocess:
10447f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            nosub = ''
1045af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            client = self.interp.start_subprocess()
1046af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            if not client:
1047af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser                self.close()
10487663729ec72f5ffe44b8e7f76bdb56d8663c5e6eKurt B. Kaiser                return False
10497f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        else:
10507f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            nosub = "==== No Subprocess ===="
1051bf3f69ee85d3c497bfdeae3ac3338c1409ca454cRaymond Hettinger        self.write("Python %s on %s\n%s\n%s" %
1052bf3f69ee85d3c497bfdeae3ac3338c1409ca454cRaymond Hettinger                   (sys.version, sys.platform, self.COPYRIGHT, nosub))
10537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.showprompt()
10546634bf2919d855ccd821e878b8cc00c7209f1cbeGeorg Brandl        import Tkinter
10556634bf2919d855ccd821e878b8cc00c7209f1cbeGeorg Brandl        Tkinter._default_root = None # 03Jan04 KBK What's this?
10567663729ec72f5ffe44b8e7f76bdb56d8663c5e6eKurt B. Kaiser        return True
10577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1058ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy    def stop_readline(self):
1059ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy        if not self.reading:  # no nested mainloop to exit.
1060ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy            return
1061ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy        self._stop_readline_flag = True
1062ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy        self.top.quit()
1063ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy
10647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def readline(self):
10657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        save = self.reading
10667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
10677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.reading = 1
10685c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser            self.top.mainloop()  # nested mainloop()
10697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        finally:
10707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.reading = save
1071ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy        if self._stop_readline_flag:
1072ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy            self._stop_readline_flag = False
1073ad8cad3c6d18f1455de9b4d3d370702eb3a1ee9fRoger Serwy            return ""
10747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        line = self.text.get("iomark", "end-1c")
10755c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser        if len(line) == 0:  # may be EOF if we quit our mainloop with Ctrl-C
10765c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser            line = "\n"
1077bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis        if isinstance(line, unicode):
1078d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna            from idlelib import IOBinding
1079bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis            try:
1080bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis                line = line.encode(IOBinding.encoding)
1081bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis            except UnicodeError:
1082bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis                pass
10837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.resetoutput()
10847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.canceled:
10857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.canceled = 0
10865c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser            if not use_subprocess:
10875c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser                raise KeyboardInterrupt
10887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.endoffile:
10897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.endoffile = 0
10905c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser            line = ""
10917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return line
10927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def isatty(self):
1094837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        return True
10957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1096003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    def cancel_callback(self, event=None):
10977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
10987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if self.text.compare("sel.first", "!=", "sel.last"):
10997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return # Active selection -- always use default binding
11007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except:
11017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            pass
11027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if not (self.executing or self.reading):
11037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.resetoutput()
11047f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            self.interp.write("KeyboardInterrupt\n")
11057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.showprompt()
11067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
11077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.endoffile = 0
1108003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        self.canceled = 1
11095c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser        if (self.executing and self.interp.rpcclt):
111067fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser            if self.interp.getdebugger():
111167fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser                self.interp.restart_subprocess()
111267fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser            else:
111367fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser                self.interp.interrupt_subprocess()
11145c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser        if self.reading:
11155c3df35b6b1f48cb48c91b0c7a8754590a694171Kurt B. Kaiser            self.top.quit()  # exit the nested mainloop() in readline()
11167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return "break"
11177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
11187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def eof_callback(self, event):
11197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.executing and not self.reading:
11207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return # Let the default binding (delete next char) take over
11217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if not (self.text.compare("iomark", "==", "insert") and
11227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.text.compare("insert", "==", "end-1c")):
11237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return # Let the default binding (delete next char) take over
11247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if not self.executing:
11257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.resetoutput()
11267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.close()
11277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
11287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.canceled = 0
11297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.endoffile = 1
11307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.top.quit()
11317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return "break"
11327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
11337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def linefeed_callback(self, event):
11347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # Insert a linefeed without entering anything (still autoindented)
11357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.reading:
11367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.insert("insert", "\n")
11377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.see("insert")
11387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
1139822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser            self.newline_and_indent_event(event)
11407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return "break"
11417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
11427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def enter_callback(self, event):
11437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.executing and not self.reading:
11447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return # Let the default binding (insert '\n') take over
11457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # If some text is selected, recall the selection
11467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # (but only if this before the I/O mark)
11477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
11487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            sel = self.text.get("sel.first", "sel.last")
11497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if sel:
11507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                if self.text.compare("sel.last", "<=", "iomark"):
1151a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser                    self.recall(sel, event)
11527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                    return "break"
11537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except:
11547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            pass
11557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # If we're strictly before the line containing iomark, recall
11567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # the current line, less a leading prompt, less leading or
11577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # trailing whitespace
11587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.text.compare("insert", "<", "iomark linestart"):
11597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            # Check if there's a relevant stdin range -- if so, use it
11607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            prev = self.text.tag_prevrange("stdin", "insert")
11617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if prev and self.text.compare("insert", "<", prev[1]):
1162a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser                self.recall(self.text.get(prev[0], prev[1]), event)
11637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return "break"
11647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            next = self.text.tag_nextrange("stdin", "insert")
11657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if next and self.text.compare("insert lineend", ">=", next[0]):
1166a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser                self.recall(self.text.get(next[0], next[1]), event)
11677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return "break"
11684ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser            # No stdin mark -- just get the current line, less any prompt
1169b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser            indices = self.text.tag_nextrange("console", "insert linestart")
1170b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser            if indices and \
1171b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser               self.text.compare(indices[0], "<=", "insert linestart"):
1172b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser                self.recall(self.text.get(indices[1], "insert lineend"), event)
1173b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser            else:
1174b17544551fc8dfd1304d5679c6e444cad4d34d97Kurt B. Kaiser                self.recall(self.text.get("insert linestart", "insert lineend"), event)
11757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
1176822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser        # If we're between the beginning of the line and the iomark, i.e.
11774ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser        # in the prompt area, move to the end of the prompt
1178822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser        if self.text.compare("insert", "<", "iomark"):
11794ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser            self.text.mark_set("insert", "iomark")
11807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # If we're in the current input and there's only whitespace
11817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # beyond the cursor, erase that whitespace first
11827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        s = self.text.get("insert", "end-1c")
1183837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        if s and not s.strip():
11847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.delete("insert", "end-1c")
11857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # If we're in the current input before its last line,
11867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # insert a newline right at the insert point
11877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.text.compare("insert", "<", "end-1c linestart"):
1188822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser            self.newline_and_indent_event(event)
11897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
11907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # We're in the last line; append a newline and submit it
11917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.mark_set("insert", "end-1c")
11927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.reading:
11937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.insert("insert", "\n")
11947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.see("insert")
11957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
1196822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser            self.newline_and_indent_event(event)
11977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.tag_add("stdin", "iomark", "end-1c")
11987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.update_idletasks()
11997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.reading:
12007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.top.quit() # Break out of recursive mainloop() in raw_input()
12017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
12027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.runit()
12037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return "break"
12047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1205a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser    def recall(self, s, event):
1206cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser        # remove leading and trailing empty or whitespace lines
1207cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser        s = re.sub(r'^\s*\n', '' , s)
1208cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser        s = re.sub(r'\n\s*$', '', s)
1209cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser        lines = s.split('\n')
1210a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser        self.text.undo_block_start()
1211a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser        try:
1212a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser            self.text.tag_remove("sel", "1.0", "end")
1213a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser            self.text.mark_set("insert", "end-1c")
1214cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser            prefix = self.text.get("insert linestart", "insert")
1215cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser            if prefix.rstrip().endswith(':'):
12168fa7eb563bb9a14651bcdc8ee60c5e45302c2f59Kurt B. Kaiser                self.newline_and_indent_event(event)
1217cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser                prefix = self.text.get("insert linestart", "insert")
1218cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser            self.text.insert("insert", lines[0].strip())
12198fa7eb563bb9a14651bcdc8ee60c5e45302c2f59Kurt B. Kaiser            if len(lines) > 1:
1220cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser                orig_base_indent = re.search(r'^([ \t]*)', lines[0]).group(0)
1221cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser                new_base_indent  = re.search(r'^([ \t]*)', prefix).group(0)
12228fa7eb563bb9a14651bcdc8ee60c5e45302c2f59Kurt B. Kaiser                for line in lines[1:]:
1223cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser                    if line.startswith(orig_base_indent):
1224cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser                        # replace orig base indentation with new indentation
1225cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser                        line = new_base_indent + line[len(orig_base_indent):]
1226cd3d8bee022cda55c43c2130122d092f5059d115Kurt B. Kaiser                    self.text.insert('insert', '\n'+line.rstrip())
1227a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser        finally:
1228a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser            self.text.see("insert")
1229a7daba6866136d1c554ba6bf278e9ddaf52ecac6Kurt B. Kaiser            self.text.undo_block_stop()
12307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
12317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def runit(self):
12327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        line = self.text.get("iomark", "end-1c")
12337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # Strip off last newline and surrounding whitespace.
12347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # (To allow you to hit return twice to end a statement.)
12357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        i = len(line)
12367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        while i > 0 and line[i-1] in " \t":
12377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            i = i-1
12387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if i > 0 and line[i-1] == "\n":
12397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            i = i-1
12407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        while i > 0 and line[i-1] in " \t":
12417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            i = i-1
12427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        line = line[:i]
12437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        more = self.interp.runsource(line)
12447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
12457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def open_stack_viewer(self, event=None):
12465d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.interp.rpcclt:
12475d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            return self.interp.remote_stack_viewer()
12487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
12497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            sys.last_traceback
12507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except:
12517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            tkMessageBox.showerror("No stack trace",
12527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                "There is no stack trace yet.\n"
12537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                "(sys.last_traceback is not defined)",
12547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                master=self.text)
12557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return
1256d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna        from idlelib.StackViewer import StackBrowser
12577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sv = StackBrowser(self.root, self.flist)
12587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
12591061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser    def view_restart_mark(self, event=None):
12601061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        self.text.see("iomark")
12611061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        self.text.see("restart")
12621061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser
12631061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser    def restart_shell(self, event=None):
1264b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy        "Callback for Run/Restart Shell Cntl-F6"
1265b98000ab5bd3fcb3774666ce3bb127e71634c349Terry Jan Reedy        self.interp.restart_subprocess(with_cwd=True)
12661061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser
12677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def showprompt(self):
12687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.resetoutput()
12697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
12707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            s = str(sys.ps1)
12717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except:
12727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            s = ""
12737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.console.write(s)
12747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.mark_set("insert", "end-1c")
12755d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.set_line_and_column()
1276dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        self.io.reset_undo()
12777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
12787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def resetoutput(self):
12797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        source = self.text.get("iomark", "end-1c")
12807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.history:
12817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.history.history_store(source)
12827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.text.get("end-2c") != "\n":
12837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.insert("end-1c", "\n")
12847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.mark_set("iomark", "end-1c")
12855d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.set_line_and_column()
12867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sys.stdout.softspace = 0
12877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
12887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def write(self, s, tags=()):
1289003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        try:
1290003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            self.text.mark_gravity("iomark", "right")
1291003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            OutputWindow.write(self, s, tags, "iomark")
1292003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            self.text.mark_gravity("iomark", "left")
1293003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        except:
1294003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            pass
12957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.canceled:
12967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.canceled = 0
12977f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            if not use_subprocess:
12987f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                raise KeyboardInterrupt
12997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
13005018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov    def rmenu_check_cut(self):
13015018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov        try:
13025018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov            if self.text.compare('sel.first', '<', 'iomark'):
13035018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov                return 'disabled'
13045018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov        except TclError: # no selection, so the index 'sel.first' doesn't exist
13055018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov            return 'disabled'
13065018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov        return super(PyShell, self).rmenu_check_cut()
13075018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov
13085018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov    def rmenu_check_paste(self):
13095018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov        if self.text.compare('insert', '<', 'iomark'):
13105018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov            return 'disabled'
13115018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov        return super(PyShell, self).rmenu_check_paste()
13125018db76aa433430e1bdb0826086df1c025a1f70Andrew Svetlov
13139abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchakaclass PseudoFile(io.TextIOBase):
13147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1315bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis    def __init__(self, shell, tags, encoding=None):
13167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.shell = shell
13177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tags = tags
13185d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.softspace = 0
13199abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        self._encoding = encoding
13209abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka
13219abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka    @property
13229abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka    def encoding(self):
13239abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        return self._encoding
13249abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka
13259abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka    @property
13269abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka    def name(self):
13279abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        return '<%s>' % self.tags
13289abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka
13299abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka    def isatty(self):
13309abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        return True
13319abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka
13329abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka
13339abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchakaclass PseudoOutputFile(PseudoFile):
13349abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka
13359abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka    def writable(self):
13369abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        return True
13377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
13387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def write(self, s):
13399abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        if self.closed:
13409abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka            raise ValueError("write to closed file")
1341f8fc674f0bc1819a85e64e1f3174b682260adab6Terry Jan Reedy        if not isinstance(s, (basestring, bytearray)):
1342f8fc674f0bc1819a85e64e1f3174b682260adab6Terry Jan Reedy            raise TypeError('must be string, not ' + type(s).__name__)
13439abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        return self.shell.write(s, self.tags)
13447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
13457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
13469abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchakaclass PseudoInputFile(PseudoFile):
13477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
13489abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka    def __init__(self, shell, tags, encoding=None):
13499abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        PseudoFile.__init__(self, shell, tags, encoding)
13509abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        self._line_buffer = ''
13517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
13529abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka    def readable(self):
13539abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        return True
1354e2b5624ee8cc4ac505162e6b3d99cfb4c2e8aa77Martin v. Löwis
13559abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka    def read(self, size=-1):
13569abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        if self.closed:
13579abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka            raise ValueError("read from closed file")
13589abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        if size is None:
13599abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka            size = -1
13609abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        elif not isinstance(size, int):
13619abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka            raise TypeError('must be int, not ' + type(size).__name__)
13629abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        result = self._line_buffer
13639abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        self._line_buffer = ''
13649abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        if size < 0:
13659abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka            while True:
13669abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka                line = self.shell.readline()
13679abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka                if not line: break
13689abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka                result += line
13699abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        else:
13709abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka            while len(result) < size:
13719abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka                line = self.shell.readline()
13729abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka                if not line: break
13739abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka                result += line
13749abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka            self._line_buffer = result[size:]
13759abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka            result = result[:size]
13769abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        return result
13779abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka
13789abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka    def readline(self, size=-1):
13799abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        if self.closed:
13809abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka            raise ValueError("read from closed file")
13819abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        if size is None:
13829abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka            size = -1
13839abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        elif not isinstance(size, int):
13849abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka            raise TypeError('must be int, not ' + type(size).__name__)
13859abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        line = self._line_buffer or self.shell.readline()
13869abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        if size < 0:
13879abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka            size = len(line)
13889abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        self._line_buffer = line[size:]
13899abc830c6a7b490f7ae248e5fa63c50e55d98cccSerhiy Storchaka        return line[:size]
1390e2b5624ee8cc4ac505162e6b3d99cfb4c2e8aa77Martin v. Löwis
139153dc4f0148f08d0da5c394089b7061cd77269fc0Roger Serwy    def close(self):
139253dc4f0148f08d0da5c394089b7061cd77269fc0Roger Serwy        self.shell.close()
139353dc4f0148f08d0da5c394089b7061cd77269fc0Roger Serwy
1394969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser
13957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererusage_msg = """\
13967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
139711659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. KaiserUSAGE: idle  [-deins] [-t title] [file]*
139811659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser       idle  [-dns] [-t title] (-c cmd | -r file) [arg]*
139911659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser       idle  [-dns] [-t title] - [arg]*
14006655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
1401f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -h         print this help message and exit
14028f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser  -n         run IDLE without a subprocess (see Help/IDLE Help for details)
1403f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1404f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserThe following options will override the IDLE 'settings' configuration:
1405f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1406f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -e         open an edit window
1407f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -i         open a shell window
1408f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1409f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserThe following options imply -i and will open a shell:
1410f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1411f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -c cmd     run the command in a shell, or
1412f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -r file    run script from file
1413f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1414f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -d         enable the debugger
1415f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -s         run $IDLESTARTUP or $PYTHONSTARTUP before anything else
1416f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -t title   set title of shell window
1417f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1418f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserA default edit window will be bypassed when -c, -r, or - are used.
1419f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1420f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser[arg]* are passed to the command (-c) or script (-r) in sys.argv[1:].
1421f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1422f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserExamples:
14237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1424f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle
1425f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Open an edit window or shell depending on IDLE's configuration.
142696d88422373ffb32aef75157647e0575a0471c03Kurt B. Kaiser
1427f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle foo.py foobar.py
1428f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Edit the files, also open a shell if configured to start with shell.
1429f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1430f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle -est "Baz" foo.py
1431f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Run $IDLESTARTUP or $PYTHONSTARTUP, edit foo.py, and open a shell
1432f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        window with the title "Baz".
1433f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1434f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle -c "import sys; print sys.argv" "foo"
1435f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Open a shell window and run the command, passing "-c" in sys.argv[0]
1436f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        and "foo" in sys.argv[1].
1437f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1438f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle -d -s -r foo.py "Hello World"
1439f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Open a shell window, run a startup script, enable the debugger, and
1440f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        run foo.py, passing "foo.py" in sys.argv[0] and "Hello World" in
1441f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        sys.argv[1].
1442f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1443f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiserecho "import sys; print sys.argv" | idle - "foobar"
1444f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Open a shell window, run the script piped in, passing '' in sys.argv[0]
1445f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        and "foobar" in sys.argv[1].
14467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer"""
14477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1448969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiserdef main():
1449f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    global flist, root, use_subprocess
1450f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
14518eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    capture_warnings(True)
14528f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser    use_subprocess = True
145334d0c66ef2bcfae00beb9f2b14e393cd00f499e4Roger Serwy    enable_shell = False
1454f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    enable_edit = False
1455f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    debug = False
1456969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    cmd = None
1457969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    script = None
1458f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    startup = False
1459969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    try:
14608f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser        opts, args = getopt.getopt(sys.argv[1:], "c:deihnr:st:")
1461969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    except getopt.error, msg:
1462969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        sys.stderr.write("Error: %s\n" % str(msg))
1463969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        sys.stderr.write(usage_msg)
1464969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        sys.exit(2)
1465969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    for o, a in opts:
1466969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-c':
1467969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser            cmd = a
1468f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1469969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-d':
1470f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            debug = True
1471f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1472969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-e':
1473f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_edit = True
1474f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        if o == '-h':
1475f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            sys.stdout.write(usage_msg)
1476f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            sys.exit()
1477f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        if o == '-i':
1478f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
14798f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser        if o == '-n':
14808f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser            use_subprocess = False
1481969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-r':
1482969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser            script = a
1483f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            if os.path.isfile(script):
1484f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                pass
1485f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            else:
1486f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                print "No script file: ", script
1487f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                sys.exit()
1488f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1489969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-s':
1490f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            startup = True
1491f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1492969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-t':
1493969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser            PyShell.shell_title = a
1494f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1495f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    if args and args[0] == '-':
1496f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        cmd = sys.stdin.read()
1497f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        enable_shell = True
1498f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # process sys.argv and sys.path:
1499969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    for i in range(len(sys.path)):
1500969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        sys.path[i] = os.path.abspath(sys.path[i])
1501f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    if args and args[0] == '-':
1502f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        sys.argv = [''] + args[1:]
1503f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    elif cmd:
1504f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        sys.argv = ['-c'] + args
1505f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    elif script:
1506f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        sys.argv = [script] + args
1507f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    elif args:
1508f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        enable_edit = True
1509f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        pathx = []
1510969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        for filename in args:
1511969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser            pathx.append(os.path.dirname(filename))
1512f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        for dir in pathx:
1513f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            dir = os.path.abspath(dir)
1514d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna            if dir not in sys.path:
1515f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                sys.path.insert(0, dir)
1516ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser    else:
1517ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser        dir = os.getcwd()
1518ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser        if not dir in sys.path:
1519ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser            sys.path.insert(0, dir)
1520f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # check the IDLE settings configuration (but command line overrides)
1521f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    edit_start = idleConf.GetOption('main', 'General',
15226655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser                                    'editor-on-startup', type='bool')
1523f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    enable_edit = enable_edit or edit_start
152434d0c66ef2bcfae00beb9f2b14e393cd00f499e4Roger Serwy    enable_shell = enable_shell or not enable_edit
1525f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # start editor and/or shell windows:
1526969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    root = Tk(className="Idle")
152719302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren
1528969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    fixwordbreaks(root)
1529969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    root.withdraw()
1530969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    flist = PyShellFileList(root)
153119302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren    macosxSupport.setupApp(root, flist)
153219302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren
1533f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    if enable_edit:
1534f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        if not (cmd or script):
15357c010ee00cc0bfb859c326d9a78bd8dd2bf92246Andrew Svetlov            for filename in args[:]:
15367c010ee00cc0bfb859c326d9a78bd8dd2bf92246Andrew Svetlov                if flist.open(filename) is None:
15377c010ee00cc0bfb859c326d9a78bd8dd2bf92246Andrew Svetlov                    # filename is a directory actually, disconsider it
15387c010ee00cc0bfb859c326d9a78bd8dd2bf92246Andrew Svetlov                    args.remove(filename)
1539f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            if not args:
1540f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                flist.new()
1541af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser    if enable_shell:
154219302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren        shell = flist.open_shell()
154319302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren        if not shell:
1544af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            return # couldn't open shell
154519302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren
154619302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren        if macosxSupport.runningAsOSXApp() and flist.dict:
154719302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren            # On OSX: when the user has double-clicked on a file that causes
15484f96f1f2b5068b8e8bd8d0f83f856b6e2883a3abTim Peters            # IDLE to be launched the shell window will open just in front of
15494f96f1f2b5068b8e8bd8d0f83f856b6e2883a3abTim Peters            # the file she wants to see. Lower the interpreter window when
155019302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren            # there are open files.
155119302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren            shell.top.lower()
155219302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren
1553f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    shell = flist.pyshell
1554f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # handle remaining options:
1555f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    if debug:
1556f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        shell.open_debugger()
1557969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    if startup:
1558969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        filename = os.environ.get("IDLESTARTUP") or \
1559969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser                   os.environ.get("PYTHONSTARTUP")
1560969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if filename and os.path.isfile(filename):
1561f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            shell.interp.execfile(filename)
1562af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser    if shell and cmd or script:
1563f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        shell.interp.runcommand("""if 1:
1564f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            import sys as _sys
156570a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald            _sys.argv = %r
1566f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            del _sys
156770a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald            \n""" % (sys.argv,))
1568f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        if cmd:
1569f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            shell.interp.execsource(cmd)
1570f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        elif script:
157111659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            shell.interp.prepend_syspath(script)
1572f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            shell.interp.execfile(script)
157319302d927e6688e02553df16177e4867e2d0e3b3Ronald Oussoren
15742a6f4b33271742f66a8e58a5ffd37e890e0acae3Ned Deily    # Check for problematic OS X Tk versions and print a warning message
15752a6f4b33271742f66a8e58a5ffd37e890e0acae3Ned Deily    # in the IDLE shell window; this is less intrusive than always opening
15762a6f4b33271742f66a8e58a5ffd37e890e0acae3Ned Deily    # a separate window.
15772a6f4b33271742f66a8e58a5ffd37e890e0acae3Ned Deily    tkversionwarning = macosxSupport.tkVersionWarning(root)
15782a6f4b33271742f66a8e58a5ffd37e890e0acae3Ned Deily    if tkversionwarning:
15792a6f4b33271742f66a8e58a5ffd37e890e0acae3Ned Deily        shell.interp.runcommand(''.join(("print('", tkversionwarning, "')")))
15802a6f4b33271742f66a8e58a5ffd37e890e0acae3Ned Deily
1581eaa7e7825e9f4b211bc104cfde6cc951f9dcb94eTerry Jan Reedy    while flist.inversedict:  # keep IDLE running while files are open.
1582eaa7e7825e9f4b211bc104cfde6cc951f9dcb94eTerry Jan Reedy        root.mainloop()
1583969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    root.destroy()
15848eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy    capture_warnings(False)
1585969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser
15867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererif __name__ == "__main__":
15879e8b828f07d0a55676e987b4ca70c247853f5695Kurt B. Kaiser    sys.modules['PyShell'] = sys.modules['__main__']
15887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    main()
15898eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedy
15908eab008b53c9aeb1ceabac378ec4bf306fdde44bTerry Jan Reedycapture_warnings(False)  # Make sure turned off; see issue 18081
1591