PyShell.py revision 7663729ec72f5ffe44b8e7f76bdb56d8663c5e6e
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
140930c43e43f79617a33a6c3be32afbe184780307Kurt B. Kaiserimport exceptions
157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport linecache
177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererfrom code import InteractiveInterpreter
187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
192303b1c19abd79c94da327d630cbac6f4e83a05cKurt B. Kaisertry:
202303b1c19abd79c94da327d630cbac6f4e83a05cKurt B. Kaiser    from Tkinter import *
212303b1c19abd79c94da327d630cbac6f4e83a05cKurt B. Kaiserexcept ImportError:
222303b1c19abd79c94da327d630cbac6f4e83a05cKurt B. Kaiser    print>>sys.__stderr__, "** IDLE can't import Tkinter.  " \
232303b1c19abd79c94da327d630cbac6f4e83a05cKurt B. Kaiser                           "Your Python may not be configured for Tk. **"
242303b1c19abd79c94da327d630cbac6f4e83a05cKurt B. Kaiser    sys.exit(1)
257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport tkMessageBox
267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererfrom EditorWindow import EditorWindow, fixwordbreaks
287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererfrom FileList import FileList
297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererfrom ColorDelegator import ColorDelegator
307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererfrom UndoDelegator import UndoDelegator
31969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiserfrom OutputWindow import OutputWindow
329930061ce28b1fc60d267ae3474c74a41e655cd5Steven M. Gavafrom configHandler import idleConf
337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport idlever
347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
355d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teyimport rpc
367f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiserimport Debugger
37ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiserimport RemoteDebugger
385d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
39b97641994617115321719d4ecf797a461e2d5cf2Kurt B. KaiserIDENTCHARS = string.ascii_letters + string.digits + "_"
4024d7e0cbb8b978738f223d4bb6cb184054d72e18Kurt B. KaiserLOCALHOST = '127.0.0.1'
41b97641994617115321719d4ecf797a461e2d5cf2Kurt B. Kaiser
42a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaisertry:
43a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser    from signal import SIGTERM
44a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiserexcept ImportError:
45a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser    SIGTERM = 15
46a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser
475d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey# Change warnings module to write to sys.__stderr__
485d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teytry:
495d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    import warnings
505d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teyexcept ImportError:
515d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    pass
525d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teyelse:
535d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    def idle_showwarning(message, category, filename, lineno):
545d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        file = sys.__stderr__
555d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        file.write(warnings.formatwarning(message, category, filename, lineno))
565d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    warnings.showwarning = idle_showwarning
575d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
58818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiserdef extended_linecache_checkcache(orig_checkcache=linecache.checkcache):
5945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    """Extend linecache.checkcache to preserve the <pyshell#...> entries
6045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
61818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiser    Rather than repeating the linecache code, patch it to save the pyshell#
62818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiser    entries, call the original linecache.checkcache(), and then restore the
63818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiser    saved entries.  Assigning the orig_checkcache keyword arg freezes its value
64818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiser    at definition time to the (original) method linecache.checkcache(), i.e.
65818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiser    makes orig_checkcache lexical.
6645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
6745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    """
687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    cache = linecache.cache
697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    save = {}
707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    for filename in cache.keys():
717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if filename[:1] + filename[-1:] == '<>':
727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            save[filename] = cache[filename]
737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    orig_checkcache()
747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    cache.update(save)
756655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
76818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiser# Patch linecache.checkcache():
77818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiserlinecache.checkcache = extended_linecache_checkcache
787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass PyShellEditorWindow(EditorWindow):
81ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiser    "Regular text edit window when a shell is present"
8245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def __init__(self, *args):
8445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        self.breakpoints = []
85931237e2e66975c54e2ac6c5e503ee2992a22bcfRaymond Hettinger        EditorWindow.__init__(self, *args)
867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.bind("<<set-breakpoint-here>>", self.set_breakpoint_here)
8745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        self.text.bind("<<clear-breakpoint-here>>", self.clear_breakpoint_here)
887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.bind("<<open-python-shell>>", self.flist.open_shell)
897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
90bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        self.breakpointPath = os.path.join(idleConf.GetUserCfgDir(),
91bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                                           'breakpoints.lst')
92a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        # whenever a file is changed, restore breakpoints
93a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        if self.io.filename: self.restore_file_breaks()
94bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        def filename_changed_hook(old_hook=self.io.filename_change_hook,
95bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                                  self=self):
96a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey            self.restore_file_breaks()
97a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey            old_hook()
98a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        self.io.set_filename_change_hook(filename_changed_hook)
99a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey
10045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    rmenu_specs = [("Set Breakpoint", "<<set-breakpoint-here>>"),
10145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                   ("Clear Breakpoint", "<<clear-breakpoint-here>>")]
1027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
103a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey    def set_breakpoint(self, lineno):
10445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        text = self.text
10545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        filename = self.io.filename
106a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        text.tag_add("BREAK", "%d.0" % lineno, "%d.0" % (lineno+1))
10745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        try:
10845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            i = self.breakpoints.index(lineno)
109a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        except ValueError:  # only add if missing, i.e. do once
11045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            self.breakpoints.append(lineno)
11145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        try:    # update the subprocess debugger
11245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug = self.flist.pyshell.interp.debugger
11345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug.set_breakpoint_here(filename, lineno)
11445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        except: # but debugger may not be active right now....
11545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            pass
1167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
117a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey    def set_breakpoint_here(self, event=None):
118a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        text = self.text
119a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        filename = self.io.filename
120a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        if not filename:
121a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey            text.bell()
122a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey            return
123a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        lineno = int(float(text.index("insert")))
124a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        self.set_breakpoint(lineno)
125a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey
126669f4c3850eaaf4e00a79032ef960a79e6ca6ad7Kurt B. Kaiser    def clear_breakpoint_here(self, event=None):
12745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        text = self.text
12845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        filename = self.io.filename
12945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        if not filename:
13045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            text.bell()
131669f4c3850eaaf4e00a79032ef960a79e6ca6ad7Kurt B. Kaiser            return
13245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        lineno = int(float(text.index("insert")))
13345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        try:
13445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            self.breakpoints.remove(lineno)
13545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        except:
13645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            pass
13745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        text.tag_remove("BREAK", "insert linestart",\
13845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                        "insert lineend +1char")
13945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        try:
14045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug = self.flist.pyshell.interp.debugger
14145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug.clear_breakpoint_here(filename, lineno)
14245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        except:
14345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            pass
14445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
14545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    def clear_file_breaks(self):
14645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        if self.breakpoints:
14745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            text = self.text
14845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            filename = self.io.filename
14945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            if not filename:
15045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                text.bell()
15145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                return
15245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            self.breakpoints = []
15345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            text.tag_remove("BREAK", "1.0", END)
15445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            try:
15545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                debug = self.flist.pyshell.interp.debugger
15645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                debug.clear_file_breaks(filename)
15745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            except:
15845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                pass
15945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
160a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey    def store_file_breaks(self):
161bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        "Save breakpoints when file is saved"
162bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        # XXX 13 Dec 2002 KBK Currently the file must be saved before it can
163bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     be run.  The breaks are saved at that time.  If we introduce
164bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     a temporary file save feature the save breaks functionality
165bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     needs to be re-verified, since the breaks at the time the
166bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     temp file is created may differ from the breaks at the last
1677f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        #     permanent save of the file.  Currently, a break introduced
1687f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        #     after a save will be effective, but not persistent.
1697f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        #     This is necessary to keep the saved breaks synched with the
1707f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        #     saved file.
171bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #
172bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     Breakpoints are set as tagged ranges in the text.  Certain
173bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     kinds of edits cause these ranges to be deleted: Inserting
174bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     or deleting a line just before a breakpoint, and certain
175bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     deletions prior to a breakpoint.  These issues need to be
176bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     investigated and understood.  It's not clear if they are
177bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     Tk issues or IDLE issues, or whether they can actually
178bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     be fixed.  Since a modified file has to be saved before it is
179bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     run, and since self.breakpoints (from which the subprocess
180bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     debugger is loaded) is updated during the save, the visible
181bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     breaks stay synched with the subprocess even if one of these
182bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     unexpected breakpoint deletions occurs.
183bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        breaks = self.breakpoints
184bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        filename = self.io.filename
185a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        try:
186bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            lines = open(self.breakpointPath,"r").readlines()
187a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        except IOError:
188bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            lines = []
189bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        new_file = open(self.breakpointPath,"w")
190a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        for line in lines:
191bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            if not line.startswith(filename + '='):
192a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey                new_file.write(line)
193bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        self.update_breakpoints()
194bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        breaks = self.breakpoints
195bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        if breaks:
196bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            new_file.write(filename + '=' + str(breaks) + '\n')
197a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        new_file.close()
198a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey
199a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey    def restore_file_breaks(self):
200a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        self.text.update()   # this enables setting "BREAK" tags to be visible
201bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        filename = self.io.filename
202bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        if filename is None:
203bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            return
20469371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey        if os.path.isfile(self.breakpointPath):
205bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            lines = open(self.breakpointPath,"r").readlines()
20669371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey            for line in lines:
207bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                if line.startswith(filename + '='):
2086655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser                    breakpoint_linenumbers = eval(line[len(filename)+1:])
20969371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey                    for breakpoint_linenumber in breakpoint_linenumbers:
21069371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey                        self.set_breakpoint(breakpoint_linenumber)
211a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey
212bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser    def update_breakpoints(self):
213bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        "Retrieves all the breakpoints in the current window"
214a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        text = self.text
215bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        ranges = text.tag_ranges("BREAK")
216bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        linenumber_list = self.ranges_to_linenumbers(ranges)
217bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        self.breakpoints = linenumber_list
218bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser
219bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser    def ranges_to_linenumbers(self, ranges):
220bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        lines = []
221bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        for index in range(0, len(ranges), 2):
222bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            lineno = int(float(ranges[index]))
223bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            end = int(float(ranges[index+1]))
224bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            while lineno < end:
225bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                lines.append(lineno)
226bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                lineno += 1
227bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        return lines
228bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser
22911220fad1d7eee24f1d9809c6d5023875099cb37Kurt B. Kaiser# XXX 13 Dec 2002 KBK Not used currently
230bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#    def saved_change_hook(self):
231bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#        "Extend base method - clear breaks if module is modified"
232bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#        if not self.get_saved():
233bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#            self.clear_file_breaks()
234bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#        EditorWindow.saved_change_hook(self)
23545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
23645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    def _close(self):
23745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        "Extend base method - clear breaks when module is closed"
23845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        self.clear_file_breaks()
23945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        EditorWindow._close(self)
2406655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
2417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass PyShellFileList(FileList):
24383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser    "Extend base class: file list when a shell is present"
2447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    EditorWindow = PyShellEditorWindow
2467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    pyshell = None
2487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def open_shell(self, event=None):
2507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.pyshell:
2517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.pyshell.wakeup()
2527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
2537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.pyshell = PyShell(self)
254af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            if self.pyshell:
255af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser                if not self.pyshell.begin():
256af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser                    return None
2577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return self.pyshell
2587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass ModifiedColorDelegator(ColorDelegator):
26183118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser    "Extend base class: colorizer for the shell window itself"
2626655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
263b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava    def __init__(self):
264b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        ColorDelegator.__init__(self)
265b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        self.LoadTagDefs()
2667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def recolorize_main(self):
2687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tag_remove("TODO", "1.0", "iomark")
2697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tag_add("SYNC", "1.0", "iomark")
2707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        ColorDelegator.recolorize_main(self)
2716655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
272b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava    def LoadTagDefs(self):
273b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        ColorDelegator.LoadTagDefs(self)
274b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        theme = idleConf.GetOption('main','Theme','name')
275b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        self.tagdefs.update({
276b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            "stdin": {'background':None,'foreground':None},
277b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            "stdout": idleConf.GetHighlight(theme, "stdout"),
278b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            "stderr": idleConf.GetHighlight(theme, "stderr"),
279b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            "console": idleConf.GetHighlight(theme, "console"),
280b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            None: idleConf.GetHighlight(theme, "normal"),
281b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        })
2827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass ModifiedUndoDelegator(UndoDelegator):
28483118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser    "Extend base class: forbid insert/delete before the I/O mark"
2857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def insert(self, index, chars, tags=None):
2877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
2887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if self.delegate.compare(index, "<", "iomark"):
2897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.delegate.bell()
2907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return
2917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except TclError:
2927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            pass
2937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        UndoDelegator.insert(self, index, chars, tags)
2947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def delete(self, index1, index2=None):
2967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
2977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if self.delegate.compare(index1, "<", "iomark"):
2987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.delegate.bell()
2997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return
3007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except TclError:
3017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            pass
3027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        UndoDelegator.delete(self, index1, index2)
3037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
30467fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser
30567fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiserclass MyRPCClient(rpc.RPCClient):
30667fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser
30767fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser    def handle_EOF(self):
30867fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser        "Override the base class - just re-raise EOFError"
30967fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser        raise EOFError
31067fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser
3118d1f11b0ef7ec31db75a4e640e9dfd75fc4ee08dKurt B. Kaiser
3127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass ModifiedInterpreter(InteractiveInterpreter):
3137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
3147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def __init__(self, tkconsole):
3157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tkconsole = tkconsole
3167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        locals = sys.modules['__main__'].__dict__
3177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        InteractiveInterpreter.__init__(self, locals=locals)
31894bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        self.save_warnings_filters = None
3196f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        self.restarting = False
32062df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser        self.subprocess_arglist = self.build_subprocess_arglist()
3217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
32263857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser    port = 8833
3235d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    rpcclt = None
3245d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    rpcpid = None
3255d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
3266655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser    def spawn_subprocess(self):
32762df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser        args = self.subprocess_arglist
328b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser        self.rpcpid = os.spawnv(os.P_NOWAIT, sys.executable, args)
32963857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser
330f53dec2e4e8a017641db4de73456a2724a75e64bTony Lownds    def build_subprocess_arglist(self):
3312398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        w = ['-W' + s for s in sys.warnoptions]
3322398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        # Maybe IDLE is installed and is being accessed via sys.path,
3332398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        # or maybe it's not installed and the idle.py script is being
3342398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        # run from the IDLE source directory.
33562df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser        del_exitf = idleConf.GetOption('main', 'General', 'delete-exitfunc',
33662df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser                                       default=False, type='bool')
3372398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        if __name__ == 'idlelib.PyShell':
33862df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser            command = "__import__('idlelib.run').run.main(" + `del_exitf` +")"
339f2324b9e8964a7aef964ae6168827ad300f920d6Tony Lownds        else:
34062df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser            command = "__import__('run').main(" + `del_exitf` + ")"
341b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser        if sys.platform[:3] == 'win' and ' ' in sys.executable:
342b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser            # handle embedded space in path by quoting the argument
343b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser            decorated_exec = '"%s"' % sys.executable
344b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser        else:
345b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser            decorated_exec = sys.executable
346b785518d051dab322feafaed0fc79d7218ce6cb0Kurt B. Kaiser        return [decorated_exec] + w + ["-c", command, str(self.port)]
347f2324b9e8964a7aef964ae6168827ad300f920d6Tony Lownds
34863857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser    def start_subprocess(self):
349af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        # spawning first avoids passing a listening socket to the subprocess
350af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        self.spawn_subprocess()
351af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        #time.sleep(20) # test to simulate GUI not accepting connection
35224d7e0cbb8b978738f223d4bb6cb184054d72e18Kurt B. Kaiser        addr = (LOCALHOST, self.port)
3538dcdb77132563c734c228e815498c47e487f95cfKurt B. Kaiser        # Idle starts listening for connection on localhost
3545db4843c5e7d2b420b9ca9189b9e30669b62e55eKurt B. Kaiser        for i in range(3):
3555d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            time.sleep(i)
3565d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            try:
35767fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser                self.rpcclt = MyRPCClient(addr)
3585d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey                break
3595d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            except socket.error, err:
360af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser                pass
3615d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        else:
362af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            self.display_port_binding_error()
363af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            return None
364b417936d4080004b6a7811fb411c6f77db4cc262Kurt B. Kaiser        # Accept the connection from the Python execution server
365af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        self.rpcclt.listening_sock.settimeout(10)
366af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        try:
367af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            self.rpcclt.accept()
368af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        except socket.timeout, err:
369af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            self.display_no_subprocess_error()
370af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            return None
371969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        self.rpcclt.register("stdin", self.tkconsole)
372969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        self.rpcclt.register("stdout", self.tkconsole.stdout)
373969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        self.rpcclt.register("stderr", self.tkconsole.stderr)
3745d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.rpcclt.register("flist", self.tkconsole.flist)
3758cd0def10dc028e3522a04bd136c67f92f90da04Kurt B. Kaiser        self.rpcclt.register("linecache", linecache)
3769f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        self.rpcclt.register("interp", self)
377f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        self.transfer_path()
3785d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.poll_subprocess()
379af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        return self.rpcclt
3805d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
38163857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser    def restart_subprocess(self):
3826f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        if self.restarting:
383af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            return self.rpcclt
3846f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        self.restarting = True
38563857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser        # close only the subprocess debugger
38645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        debug = self.getdebugger()
38745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        if debug:
388003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            try:
3899ec454ec00088e051195e80363499a14cafc131aKurt B. Kaiser                # Only close subprocess debugger, don't unregister gui_adap!
390003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser                RemoteDebugger.close_subprocess_debugger(self.rpcclt)
391003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            except:
392003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser                pass
393003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        # Kill subprocess, spawn a new one, accept connection.
394a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.rpcclt.close()
395a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.unix_terminate()
3967f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        console = self.tkconsole
3976f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        was_executing = console.executing
3987f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        console.executing = False
39963857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser        self.spawn_subprocess()
400af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        try:
401af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            self.rpcclt.accept()
402af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        except socket.timeout, err:
403af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            self.display_no_subprocess_error()
404af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            return None
405f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        self.transfer_path()
4061061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        # annotate restart in shell window and mark it
4074cc5ef5dbe12cbc9dc1a00c7583ffd0117f4c31eKurt B. Kaiser        console.text.delete("iomark", "end-1c")
4086f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        if was_executing:
4096f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser            console.write('\n')
4106f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser            console.showprompt()
4111061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        halfbar = ((int(console.width) - 16) // 2) * '='
4121061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        console.write(halfbar + ' RESTART ' + halfbar)
4131061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        console.text.mark_set("restart", "end-1c")
4141061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        console.text.mark_gravity("restart", "left")
4157f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        console.showprompt()
416003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        # restart subprocess debugger
41745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        if debug:
4189ec454ec00088e051195e80363499a14cafc131aKurt B. Kaiser            # Restarted debugger connects to current instance of debug GUI
41963857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser            gui = RemoteDebugger.restart_subprocess_debugger(self.rpcclt)
42045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            # reload remote debugger breakpoints for all PyShellEditWindows
42145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug.load_breakpoints()
4226f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        self.restarting = False
423af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        return self.rpcclt
42445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
425003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    def __request_interrupt(self):
426a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.rpcclt.remotecall("exec", "interrupt_the_server", (), {})
427003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser
428003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    def interrupt_subprocess(self):
429a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        threading.Thread(target=self.__request_interrupt).start()
430003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser
431a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser    def kill_subprocess(self):
432af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        try:
433af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            self.rpcclt.close()
434af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        except AttributeError:  # no socket
435af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            pass
436a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.unix_terminate()
437a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.tkconsole.executing = False
438a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.rpcclt = None
43911c53e2ea7f7d2a2969c98e81c1489c4e72254c4Kurt B. Kaiser
440a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser    def unix_terminate(self):
441a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        "UNIX: make sure subprocess is terminated and collect status"
442a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        if hasattr(os, 'kill'):
443a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            try:
444a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                os.kill(self.rpcpid, SIGTERM)
445a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            except OSError:
446a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                # process already terminated:
447a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                return
448a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            else:
449a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                try:
450a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                    os.waitpid(self.rpcpid, 0)
451a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                except OSError:
452a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                    return
45311c53e2ea7f7d2a2969c98e81c1489c4e72254c4Kurt B. Kaiser
454f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    def transfer_path(self):
455f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        self.runcommand("""if 1:
456f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        import sys as _sys
457f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        _sys.path = %s
458f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        del _sys
459b2487335bf8c9258d347d96cf615d964d57f5658Kurt B. Kaiser        _msg = 'Use File/Exit or your end-of-file key to quit IDLE'
460b2487335bf8c9258d347d96cf615d964d57f5658Kurt B. Kaiser        __builtins__.quit = __builtins__.exit = _msg
461b2487335bf8c9258d347d96cf615d964d57f5658Kurt B. Kaiser        del _msg
462f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        \n""" % `sys.path`)
463f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
4645d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    active_seq = None
4655d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
4665d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    def poll_subprocess(self):
4675d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        clt = self.rpcclt
4685d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if clt is None:
4695d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            return
470003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        try:
471a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            response = clt.pollresponse(self.active_seq, wait=0.05)
472a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        except (EOFError, IOError, KeyboardInterrupt):
473a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            # lost connection or subprocess terminated itself, restart
474a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            # [the KBI is from rpc.SocketIO.handle_EOF()]
47567fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser            if self.tkconsole.closing:
47667fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser                return
477003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            response = None
478003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            self.restart_subprocess()
4795d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if response:
4805d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            self.tkconsole.resetoutput()
4815d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            self.active_seq = None
4825d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            how, what = response
483bc2861313cc53711d837a0e8a5bf303bf5291bf3Kurt B. Kaiser            console = self.tkconsole.console
4845d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            if how == "OK":
4855d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey                if what is not None:
486bc2861313cc53711d837a0e8a5bf303bf5291bf3Kurt B. Kaiser                    print >>console, `what`
4875d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            elif how == "EXCEPTION":
4885d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey                if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
4895d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey                    self.remote_stack_viewer()
4905d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            elif how == "ERROR":
4910930c43e43f79617a33a6c3be32afbe184780307Kurt B. Kaiser                errmsg = "PyShell.ModifiedInterpreter: Subprocess ERROR:\n"
4920930c43e43f79617a33a6c3be32afbe184780307Kurt B. Kaiser                print >>sys.__stderr__, errmsg, what
493bc2861313cc53711d837a0e8a5bf303bf5291bf3Kurt B. Kaiser                print >>console, errmsg, what
494bc2861313cc53711d837a0e8a5bf303bf5291bf3Kurt B. Kaiser            # we received a response to the currently active seq number:
4955d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            self.tkconsole.endexecuting()
49688957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser        # Reschedule myself
49788957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser        if not self.tkconsole.closing:
49888957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser            self.tkconsole.text.after(self.tkconsole.pollinterval,
49988957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser                                      self.poll_subprocess)
5005d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
50145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    debugger = None
50245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
50345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    def setdebugger(self, debugger):
50445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        self.debugger = debugger
50545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
50645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    def getdebugger(self):
50745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        return self.debugger
50845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
5099f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser    def open_remote_stack_viewer(self):
5109f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        """Initiate the remote stack viewer from a separate thread.
5119f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser
5129f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        This method is called from the subprocess, and by returning from this
5139f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        method we allow the subprocess to unblock.  After a bit the shell
5149f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        requests the subprocess to open the remote stack viewer which returns a
5159f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        static object looking at the last exceptiopn.  It is queried through
5169f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        the RPC mechanism.
5179f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser
5189f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        """
5199f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        self.tkconsole.text.after(300, self.remote_stack_viewer)
5209f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        return
5219f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser
5225d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    def remote_stack_viewer(self):
5235d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        import RemoteObjectBrowser
524a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        oid = self.rpcclt.remotequeue("exec", "stackviewer", ("flist",), {})
5255d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if oid is None:
5265d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            self.tkconsole.root.bell()
5275d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            return
5285d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        item = RemoteObjectBrowser.StubObjectTreeItem(self.rpcclt, oid)
5295d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        from TreeWidget import ScrolledCanvas, TreeNode
5305d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        top = Toplevel(self.tkconsole.root)
5315d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        sc = ScrolledCanvas(top, bg="white", highlightthickness=0)
5325d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        sc.frame.pack(expand=1, fill="both")
5335d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        node = TreeNode(sc.canvas, None, item)
5345d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        node.expand()
5355d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        # XXX Should GC the remote tree when closing the window
5365d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
5377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    gid = 0
5387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
5397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def execsource(self, source):
54083118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Like runsource() but assumes complete exec source"
5417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        filename = self.stuffsource(source)
5427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.execfile(filename, source)
5437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
5447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def execfile(self, filename, source=None):
54583118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Execute an existing file"
5467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if source is None:
5477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            source = open(filename, "r").read()
5487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
5497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            code = compile(source, filename, "exec")
5507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except (OverflowError, SyntaxError):
5517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.tkconsole.resetoutput()
5527f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            tkerr = self.tkconsole.stderr
5537f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            print>>tkerr, '*** Error in script or command!\n'
5547f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            print>>tkerr, 'Traceback (most recent call last):'
5557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            InteractiveInterpreter.showsyntaxerror(self, filename)
5566e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            self.tkconsole.showprompt()
5577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
5587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.runcode(code)
5597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
5607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def runsource(self, source):
56183118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Extend base class method: Stuff the source in the line cache first"
5627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        filename = self.stuffsource(source)
5637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.more = 0
56494bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        self.save_warnings_filters = warnings.filters[:]
56594bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        warnings.filterwarnings(action="error", category=SyntaxWarning)
566837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        if isinstance(source, types.UnicodeType):
567837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser            import IOBinding
568837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser            try:
569837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser                source = source.encode(IOBinding.encoding)
570837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser            except UnicodeError:
571837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser                self.tkconsole.resetoutput()
572837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser                self.write("Unsupported characters in input")
573837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser                return
57494bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        try:
57594bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser            return InteractiveInterpreter.runsource(self, source, filename)
57694bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        finally:
57794bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser            if self.save_warnings_filters is not None:
57894bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser                warnings.filters[:] = self.save_warnings_filters
57994bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser                self.save_warnings_filters = None
5807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
5817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def stuffsource(self, source):
58283118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Stuff source in the filename cache"
5837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        filename = "<pyshell#%d>" % self.gid
5847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.gid = self.gid + 1
585837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        lines = source.split("\n")
5867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        linecache.cache[filename] = len(source)+1, 0, lines, filename
5877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return filename
5886655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
58911659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser    def prepend_syspath(self, filename):
59011659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser        "Prepend sys.path with file's directory if not already included"
59111659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser        self.runcommand("""if 1:
59211659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            _filename = %s
59311659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            import sys as _sys
59411659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            from os.path import dirname as _dirname
59511659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            _dir = _dirname(_filename)
59611659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            if not _dir in _sys.path:
59711659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser                _sys.path.insert(0, _dir)
59811659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            del _filename, _sys, _dirname, _dir
59911659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            \n""" % `filename`)
60011659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser
6017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def showsyntaxerror(self, filename=None):
60283118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        """Extend base class method: Add Colorizing
60383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser
60483118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        Color the offending position instead of printing it and pointing at it
60583118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        with a caret.
60683118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser
60783118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        """
6087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text = self.tkconsole.text
6097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        stuff = self.unpackerror()
6106e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser        if stuff:
6116e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            msg, lineno, offset, line = stuff
6126e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            if lineno == 1:
6136e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser                pos = "iomark + %d chars" % (offset-1)
6146e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            else:
6156e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser                pos = "iomark linestart + %d lines + %d chars" % \
6166e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser                      (lineno-1, offset-1)
6176e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            text.tag_add("ERROR", pos)
6186e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            text.see(pos)
6196e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            char = text.get(pos)
6206e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            if char and char in IDENTCHARS:
6216e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser                text.tag_add("ERROR", pos + " wordstart", pos)
6227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.tkconsole.resetoutput()
6236e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            self.write("SyntaxError: %s\n" % str(msg))
6247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
6256e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            self.tkconsole.resetoutput()
6266e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            InteractiveInterpreter.showsyntaxerror(self, filename)
6276e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser        self.tkconsole.showprompt()
6287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def unpackerror(self):
6307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        type, value, tb = sys.exc_info()
6317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        ok = type is SyntaxError
6327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if ok:
6337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            try:
6347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                msg, (dummy_filename, lineno, offset, line) = value
635bea57c6c355ba98cd9019d13e5adf7d715377edfKurt B. Kaiser                if not offset:
636bea57c6c355ba98cd9019d13e5adf7d715377edfKurt B. Kaiser                    offset = 0
6377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            except:
6387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                ok = 0
6397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if ok:
6407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return msg, lineno, offset, line
6417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
6427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return None
6437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def showtraceback(self):
64583118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Extend base class method to reset output properly"
6467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tkconsole.resetoutput()
6477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.checklinecache()
6487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        InteractiveInterpreter.showtraceback(self)
6495d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
6505d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            self.tkconsole.open_stack_viewer()
6517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def checklinecache(self):
6537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        c = linecache.cache
6547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        for key in c.keys():
6557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if key[:1] + key[-1:] != "<>":
6567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                del c[key]
6577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6585d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    def runcommand(self, code):
65983118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Run the code without invoking the debugger"
6605d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        # The code better not raise an exception!
6615d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.tkconsole.executing:
662f4c4f115d80a26eb83d90593c24a1580f236c443Neal Norwitz            self.display_executing_dialog()
6635d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            return 0
6645d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.rpcclt:
665a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            self.rpcclt.remotequeue("exec", "runcode", (code,), {})
6665d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        else:
6675d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            exec code in self.locals
6685d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        return 1
6695d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
6707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def runcode(self, code):
67183118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Override base class method"
6725d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.tkconsole.executing:
673003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            self.interp.restart_subprocess()
6745d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.checklinecache()
67594bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        if self.save_warnings_filters is not None:
67694bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser            warnings.filters[:] = self.save_warnings_filters
67794bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser            self.save_warnings_filters = None
6787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        debugger = self.debugger
6797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
6807f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            self.tkconsole.beginexecuting()
6817f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            try:
6827f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                if not debugger and self.rpcclt is not None:
6837f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    self.active_seq = self.rpcclt.asyncqueue("exec", "runcode",
6847f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                                                            (code,), {})
6857f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                elif debugger:
6867f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    debugger.run(code, self.locals)
6877f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                else:
6887f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    exec code in self.locals
6897f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            except SystemExit:
6907f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                if tkMessageBox.askyesno(
6917f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    "Exit?",
6927f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    "Do you want to exit altogether?",
6937f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    default="yes",
6947f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    master=self.tkconsole.text):
6957f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    raise
6967f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                else:
6977f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    self.showtraceback()
6987f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            except:
6997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.showtraceback()
7007f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        finally:
7017f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            if not use_subprocess:
7027f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                self.tkconsole.endexecuting()
7037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def write(self, s):
70583118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Override base class method"
7067f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        self.tkconsole.stderr.write(s)
7077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
708af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser    def display_port_binding_error(self):
709af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        tkMessageBox.showerror(
710af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "Port Binding Error",
711af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "IDLE can't bind TCP/IP port 8833, which is necessary to "
712af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "communicate with its Python execution server.  Either "
713af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "no networking is installed on this computer or another "
714af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "process (another IDLE?) is using the port.  Run IDLE with the -n "
715af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "command line switch to start without a subprocess and refer to "
716af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "Help/IDLE Help 'Running without a subprocess' for further "
717af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "details.",
718af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            master=self.tkconsole.text)
719af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser
720af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser    def display_no_subprocess_error(self):
721af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        tkMessageBox.showerror(
722af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "Subprocess Startup Error",
723af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "IDLE's subprocess didn't make connection.  Either IDLE can't "
724af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "start a subprocess or personal firewall software is blocking "
725af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "the connection.",
726af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            master=self.tkconsole.text)
727af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser
728af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser    def display_executing_dialog(self):
729af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        tkMessageBox.showerror(
730af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "Already executing",
731af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "The Python Shell window is already executing a command; "
732af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            "please wait until it is finished.",
733af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            master=self.tkconsole.text)
734af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser
735af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser
7367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass PyShell(OutputWindow):
7377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    shell_title = "Python Shell"
7397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    # Override classes
7417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    ColorDelegator = ModifiedColorDelegator
7427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    UndoDelegator = ModifiedUndoDelegator
7437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
744f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # Override menus
745dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser    menu_specs = [
746dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        ("file", "_File"),
747dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        ("edit", "_Edit"),
7484cc5ef5dbe12cbc9dc1a00c7583ffd0117f4c31eKurt B. Kaiser        ("debug", "_Debug"),
7491061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        ("options", "_Options"),
750dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        ("windows", "_Windows"),
751dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        ("help", "_Help"),
752dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser    ]
7537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    # New classes
7557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    from IdleHistory import History
7567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def __init__(self, flist=None):
7588f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser        if use_subprocess:
75967fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser            ms = self.menu_specs
76067fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser            if ms[2][0] != "shell":
76167fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser                ms.insert(2, ("shell", "_Shell"))
7627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.interp = ModifiedInterpreter(self)
7637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if flist is None:
7647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            root = Tk()
7657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            fixwordbreaks(root)
7667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            root.withdraw()
7677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            flist = PyShellFileList(root)
7685afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
7697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        OutputWindow.__init__(self, flist, None, None)
7705afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
7717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        import __builtin__
7727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        __builtin__.quit = __builtin__.exit = "To exit, type Ctrl-D."
7735afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
774ee7afca550f69ace3e20d25b84432f45c246c600Kurt B. Kaiser        self.config(usetabs=1, indentwidth=8, context_use_ps1=1)
7755afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
7767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text = self.text
7777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.configure(wrap="char")
7787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<newline-and-indent>>", self.enter_callback)
7797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<plain-newline-and-indent>>", self.linefeed_callback)
7807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<interrupt-execution>>", self.cancel_callback)
7817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<beginning-of-line>>", self.home_callback)
7827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<end-of-file>>", self.eof_callback)
7837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<open-stack-viewer>>", self.open_stack_viewer)
78457bfe5dc5a4873026679fb911939beb69e35a9e8Kurt B. Kaiser        text.bind("<<toggle-debugger>>", self.toggle_debugger)
7857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<open-python-shell>>", self.flist.open_shell)
7867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<toggle-jit-stack-viewer>>", self.toggle_jit_stack_viewer)
7878f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser        if use_subprocess:
7888f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser            text.bind("<<view-restart>>", self.view_restart_mark)
7898f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser            text.bind("<<restart-shell>>", self.restart_shell)
7905afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
7917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.save_stdout = sys.stdout
7927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.save_stderr = sys.stderr
7937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.save_stdin = sys.stdin
794bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis        import IOBinding
795bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis        self.stdout = PseudoFile(self, "stdout", IOBinding.encoding)
796bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis        self.stderr = PseudoFile(self, "stderr", IOBinding.encoding)
797bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis        self.console = PseudoFile(self, "console", IOBinding.encoding)
7985d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if not use_subprocess:
7995d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            sys.stdout = self.stdout
8005d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            sys.stderr = self.stderr
8015d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            sys.stdin = self
8025afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
8037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.history = self.History(self.text)
8045afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
80588957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser        self.pollinterval = 50  # millisec
8065d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
807003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    reading = False
808003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    executing = False
809003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    canceled = False
810003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    endoffile = False
811003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    closing = False
8127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def toggle_debugger(self, event=None):
8147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.executing:
8157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            tkMessageBox.showerror("Don't debug now",
8167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                "You can only toggle the debugger when idle",
8177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                master=self.text)
8187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.set_debugger_indicator()
8197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
8207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
8217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            db = self.interp.getdebugger()
8227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if db:
8237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.close_debugger()
8247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            else:
8257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.open_debugger()
8267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def set_debugger_indicator(self):
8287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        db = self.interp.getdebugger()
8297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.setvar("<<toggle-debugger>>", not not db)
8307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8311061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser    def toggle_jit_stack_viewer(self, event=None):
8327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        pass # All we need is the variable
8337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def close_debugger(self):
8357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        db = self.interp.getdebugger()
8367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if db:
8377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.interp.setdebugger(None)
8387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            db.close()
839ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiser            if self.interp.rpcclt:
840ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiser                RemoteDebugger.close_remote_debugger(self.interp.rpcclt)
8417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.resetoutput()
8427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.console.write("[DEBUG OFF]\n")
8437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            sys.ps1 = ">>> "
8447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.showprompt()
8457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.set_debugger_indicator()
8467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def open_debugger(self):
8485d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.interp.rpcclt:
8497f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            dbg_gui = RemoteDebugger.start_remote_debugger(self.interp.rpcclt,
8507f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                                                           self)
8517f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        else:
8527f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            dbg_gui = Debugger.Debugger(self)
8537f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        self.interp.setdebugger(dbg_gui)
8547f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        dbg_gui.load_breakpoints()
8555d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        sys.ps1 = "[DEBUG ON]\n>>> "
8565d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.showprompt()
8575d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.set_debugger_indicator()
8585d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
8597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def beginexecuting(self):
860ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiser        "Helper for ModifiedInterpreter"
8617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.resetoutput()
8627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.executing = 1
8637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def endexecuting(self):
86583118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Helper for ModifiedInterpreter"
8667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.executing = 0
8677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.canceled = 0
8685d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.showprompt()
8697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def close(self):
87183118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Extend EditorWindow.close()"
8727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.executing:
873003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            response = tkMessageBox.askokcancel(
8747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                "Kill?",
875003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser                "The program is still running!\n Do you want to kill it?",
8767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                default="ok",
8777f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                parent=self.text)
878003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            if response == False:
8797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return "cancel"
88067fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser        self.closing = True
88167fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser        # Wait for poll_subprocess() rescheduling to stop
88267fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser        self.text.after(2 * self.pollinterval, self.close2)
88388957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser
88488957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser    def close2(self):
88588957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser        return EditorWindow.close(self)
8867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def _close(self):
88883118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Extend EditorWindow._close(), shut down debugger and execution server"
8897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.close_debugger()
8907f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        if use_subprocess:
8917f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            self.interp.kill_subprocess()
8927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # Restore std streams
8937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sys.stdout = self.save_stdout
8947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sys.stderr = self.save_stderr
8957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sys.stdin = self.save_stdin
8967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # Break cycles
8977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.interp = None
8987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.console = None
8997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.flist.pyshell = None
9007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.history = None
90183118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        EditorWindow._close(self)
9027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def ispythonsource(self, filename):
90483118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Override EditorWindow method: never remove the colorizer"
905837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        return True
9067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def short_title(self):
9087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return self.shell_title
9097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
91094bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser    COPYRIGHT = \
9118f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser          'Type "copyright", "credits" or "license()" for more information.'
91294bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser
913220fecf0f45b7ad6dde43a60e33f755793d8318dKurt B. Kaiser    firewallmessage = """
914220fecf0f45b7ad6dde43a60e33f755793d8318dKurt B. Kaiser    ****************************************************************
915220fecf0f45b7ad6dde43a60e33f755793d8318dKurt B. Kaiser    Personal firewall software may warn about the connection IDLE
916220fecf0f45b7ad6dde43a60e33f755793d8318dKurt B. Kaiser    makes to its subprocess using this computer's internal loopback
917220fecf0f45b7ad6dde43a60e33f755793d8318dKurt B. Kaiser    interface.  This connection is not visible on any external
918220fecf0f45b7ad6dde43a60e33f755793d8318dKurt B. Kaiser    interface and no data is sent to or received from the Internet.
919220fecf0f45b7ad6dde43a60e33f755793d8318dKurt B. Kaiser    ****************************************************************
920220fecf0f45b7ad6dde43a60e33f755793d8318dKurt B. Kaiser    """
921220fecf0f45b7ad6dde43a60e33f755793d8318dKurt B. Kaiser
9227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def begin(self):
9237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.resetoutput()
9247f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        if use_subprocess:
9257f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            nosub = ''
926af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            client = self.interp.start_subprocess()
927af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            if not client:
928af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser                self.close()
9297663729ec72f5ffe44b8e7f76bdb56d8663c5e6eKurt B. Kaiser                return False
9307f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        else:
9317f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            nosub = "==== No Subprocess ===="
932220fecf0f45b7ad6dde43a60e33f755793d8318dKurt B. Kaiser        self.write("Python %s on %s\n%s\n%s\nIDLE %s      %s\n" %
93394bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser                   (sys.version, sys.platform, self.COPYRIGHT,
934220fecf0f45b7ad6dde43a60e33f755793d8318dKurt B. Kaiser                    self.firewallmessage, idlever.IDLE_VERSION, nosub))
9357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.showprompt()
9367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        import Tkinter
937af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        Tkinter._default_root = None # 03Jan04 KBK What's this?
9387663729ec72f5ffe44b8e7f76bdb56d8663c5e6eKurt B. Kaiser        return True
9397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def readline(self):
9417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        save = self.reading
9427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
9437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.reading = 1
9447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.top.mainloop()
9457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        finally:
9467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.reading = save
9477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        line = self.text.get("iomark", "end-1c")
948bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis        if isinstance(line, unicode):
949bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis            import IOBinding
950bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis            try:
951bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis                line = line.encode(IOBinding.encoding)
952bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis            except UnicodeError:
953bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis                pass
9547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.resetoutput()
9557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.canceled:
9567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.canceled = 0
9577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            raise KeyboardInterrupt
9587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.endoffile:
9597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.endoffile = 0
9607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return ""
9617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return line
9627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def isatty(self):
964837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        return True
9657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
966003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    def cancel_callback(self, event=None):
9677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
9687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if self.text.compare("sel.first", "!=", "sel.last"):
9697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return # Active selection -- always use default binding
9707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except:
9717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            pass
9727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if not (self.executing or self.reading):
9737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.resetoutput()
9747f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            self.interp.write("KeyboardInterrupt\n")
9757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.showprompt()
9767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
9777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.endoffile = 0
978003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        self.canceled = 1
9797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.reading:
9807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.top.quit()
981003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        elif (self.executing and self.interp.rpcclt):
98267fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser            if self.interp.getdebugger():
98367fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser                self.interp.restart_subprocess()
98467fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser            else:
98567fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser                self.interp.interrupt_subprocess()
9867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return "break"
9877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def eof_callback(self, event):
9897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.executing and not self.reading:
9907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return # Let the default binding (delete next char) take over
9917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if not (self.text.compare("iomark", "==", "insert") and
9927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.text.compare("insert", "==", "end-1c")):
9937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return # Let the default binding (delete next char) take over
9947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if not self.executing:
9957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.resetoutput()
9967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.close()
9977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
9987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.canceled = 0
9997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.endoffile = 1
10007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.top.quit()
10017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return "break"
10027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def home_callback(self, event):
10047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if event.state != 0 and event.keysym == "Home":
10057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return # <Modifier-Home>; fall back to class binding
10067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.text.compare("iomark", "<=", "insert") and \
10077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer           self.text.compare("insert linestart", "<=", "iomark"):
10087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.mark_set("insert", "iomark")
10097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.tag_remove("sel", "1.0", "end")
10107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.see("insert")
10117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
10127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def linefeed_callback(self, event):
10147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # Insert a linefeed without entering anything (still autoindented)
10157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.reading:
10167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.insert("insert", "\n")
10177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.see("insert")
10187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
1019822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser            self.newline_and_indent_event(event)
10207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return "break"
10217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def enter_callback(self, event):
10237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.executing and not self.reading:
10247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return # Let the default binding (insert '\n') take over
10257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # If some text is selected, recall the selection
10267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # (but only if this before the I/O mark)
10277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
10287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            sel = self.text.get("sel.first", "sel.last")
10297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if sel:
10307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                if self.text.compare("sel.last", "<=", "iomark"):
10317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                    self.recall(sel)
10327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                    return "break"
10337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except:
10347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            pass
10357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # If we're strictly before the line containing iomark, recall
10367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # the current line, less a leading prompt, less leading or
10377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # trailing whitespace
10387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.text.compare("insert", "<", "iomark linestart"):
10397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            # Check if there's a relevant stdin range -- if so, use it
10407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            prev = self.text.tag_prevrange("stdin", "insert")
10417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if prev and self.text.compare("insert", "<", prev[1]):
10427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.recall(self.text.get(prev[0], prev[1]))
10437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return "break"
10447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            next = self.text.tag_nextrange("stdin", "insert")
10457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if next and self.text.compare("insert lineend", ">=", next[0]):
10467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.recall(self.text.get(next[0], next[1]))
10477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return "break"
10484ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser            # No stdin mark -- just get the current line, less any prompt
10494ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser            line = self.text.get("insert linestart", "insert lineend")
10504ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser            last_line_of_prompt = sys.ps1.split('\n')[-1]
10514ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser            if line.startswith(last_line_of_prompt):
10524ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser                line = line[len(last_line_of_prompt):]
10534ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser            self.recall(line)
10547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
1055822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser        # If we're between the beginning of the line and the iomark, i.e.
10564ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser        # in the prompt area, move to the end of the prompt
1057822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser        if self.text.compare("insert", "<", "iomark"):
10584ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser            self.text.mark_set("insert", "iomark")
10597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # If we're in the current input and there's only whitespace
10607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # beyond the cursor, erase that whitespace first
10617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        s = self.text.get("insert", "end-1c")
1062837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        if s and not s.strip():
10637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.delete("insert", "end-1c")
10647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # If we're in the current input before its last line,
10657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # insert a newline right at the insert point
10667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.text.compare("insert", "<", "end-1c linestart"):
1067822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser            self.newline_and_indent_event(event)
10687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
10697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # We're in the last line; append a newline and submit it
10707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.mark_set("insert", "end-1c")
10717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.reading:
10727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.insert("insert", "\n")
10737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.see("insert")
10747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
1075822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser            self.newline_and_indent_event(event)
10767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.tag_add("stdin", "iomark", "end-1c")
10777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.update_idletasks()
10787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.reading:
10797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.top.quit() # Break out of recursive mainloop() in raw_input()
10807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
10817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.runit()
10827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return "break"
10837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def recall(self, s):
10857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.history:
10867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.history.recall(s)
10877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def runit(self):
10897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        line = self.text.get("iomark", "end-1c")
10907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # Strip off last newline and surrounding whitespace.
10917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # (To allow you to hit return twice to end a statement.)
10927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        i = len(line)
10937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        while i > 0 and line[i-1] in " \t":
10947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            i = i-1
10957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if i > 0 and line[i-1] == "\n":
10967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            i = i-1
10977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        while i > 0 and line[i-1] in " \t":
10987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            i = i-1
10997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        line = line[:i]
11007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        more = self.interp.runsource(line)
11017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
11027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def open_stack_viewer(self, event=None):
11035d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.interp.rpcclt:
11045d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            return self.interp.remote_stack_viewer()
11057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
11067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            sys.last_traceback
11077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except:
11087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            tkMessageBox.showerror("No stack trace",
11097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                "There is no stack trace yet.\n"
11107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                "(sys.last_traceback is not defined)",
11117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                master=self.text)
11127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return
11137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        from StackViewer import StackBrowser
11147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sv = StackBrowser(self.root, self.flist)
11157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
11161061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser    def view_restart_mark(self, event=None):
11171061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        self.text.see("iomark")
11181061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        self.text.see("restart")
11191061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser
11201061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser    def restart_shell(self, event=None):
112167fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser        self.interp.restart_subprocess()
11221061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser
11237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def showprompt(self):
11247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.resetoutput()
11257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
11267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            s = str(sys.ps1)
11277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except:
11287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            s = ""
11297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.console.write(s)
11307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.mark_set("insert", "end-1c")
11315d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.set_line_and_column()
1132dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        self.io.reset_undo()
11337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
11347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def resetoutput(self):
11357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        source = self.text.get("iomark", "end-1c")
11367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.history:
11377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.history.history_store(source)
11387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.text.get("end-2c") != "\n":
11397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.insert("end-1c", "\n")
11407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.mark_set("iomark", "end-1c")
11415d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.set_line_and_column()
11427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sys.stdout.softspace = 0
11437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
11447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def write(self, s, tags=()):
1145003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        try:
1146003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            self.text.mark_gravity("iomark", "right")
1147003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            OutputWindow.write(self, s, tags, "iomark")
1148003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            self.text.mark_gravity("iomark", "left")
1149003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        except:
1150003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            pass
11517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.canceled:
11527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.canceled = 0
11537f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            if not use_subprocess:
11547f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                raise KeyboardInterrupt
11557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
11567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass PseudoFile:
11577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1158bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis    def __init__(self, shell, tags, encoding=None):
11597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.shell = shell
11607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tags = tags
11615d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.softspace = 0
1162bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis        self.encoding = encoding
11637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
11647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def write(self, s):
11657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.shell.write(s, self.tags)
11667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
11677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def writelines(self, l):
11687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        map(self.write, l)
11697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
11707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def flush(self):
11717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        pass
11727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
11737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def isatty(self):
1174837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        return True
11757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1176969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser
11777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererusage_msg = """\
11787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
117911659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. KaiserUSAGE: idle  [-deins] [-t title] [file]*
118011659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser       idle  [-dns] [-t title] (-c cmd | -r file) [arg]*
118111659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser       idle  [-dns] [-t title] - [arg]*
11826655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
1183f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -h         print this help message and exit
11848f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser  -n         run IDLE without a subprocess (see Help/IDLE Help for details)
1185f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1186f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserThe following options will override the IDLE 'settings' configuration:
1187f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1188f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -e         open an edit window
1189f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -i         open a shell window
1190f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1191f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserThe following options imply -i and will open a shell:
1192f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1193f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -c cmd     run the command in a shell, or
1194f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -r file    run script from file
1195f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1196f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -d         enable the debugger
1197f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -s         run $IDLESTARTUP or $PYTHONSTARTUP before anything else
1198f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -t title   set title of shell window
1199f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1200f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserA default edit window will be bypassed when -c, -r, or - are used.
1201f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1202f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser[arg]* are passed to the command (-c) or script (-r) in sys.argv[1:].
1203f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1204f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserExamples:
12057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1206f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle
1207f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Open an edit window or shell depending on IDLE's configuration.
120896d88422373ffb32aef75157647e0575a0471c03Kurt B. Kaiser
1209f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle foo.py foobar.py
1210f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Edit the files, also open a shell if configured to start with shell.
1211f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1212f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle -est "Baz" foo.py
1213f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Run $IDLESTARTUP or $PYTHONSTARTUP, edit foo.py, and open a shell
1214f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        window with the title "Baz".
1215f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1216f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle -c "import sys; print sys.argv" "foo"
1217f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Open a shell window and run the command, passing "-c" in sys.argv[0]
1218f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        and "foo" in sys.argv[1].
1219f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1220f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle -d -s -r foo.py "Hello World"
1221f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Open a shell window, run a startup script, enable the debugger, and
1222f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        run foo.py, passing "foo.py" in sys.argv[0] and "Hello World" in
1223f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        sys.argv[1].
1224f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1225f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiserecho "import sys; print sys.argv" | idle - "foobar"
1226f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Open a shell window, run the script piped in, passing '' in sys.argv[0]
1227f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        and "foobar" in sys.argv[1].
12287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer"""
12297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1230969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiserdef main():
1231f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    global flist, root, use_subprocess
1232f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
12338f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser    use_subprocess = True
1234f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    enable_shell = False
1235f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    enable_edit = False
1236f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    debug = False
1237969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    cmd = None
1238969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    script = None
1239f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    startup = False
1240969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    try:
12414ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser        sys.ps1
12424ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser    except AttributeError:
12434ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser        sys.ps1 = '>>> '
12444ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser    try:
12458f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser        opts, args = getopt.getopt(sys.argv[1:], "c:deihnr:st:")
1246969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    except getopt.error, msg:
1247969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        sys.stderr.write("Error: %s\n" % str(msg))
1248969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        sys.stderr.write(usage_msg)
1249969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        sys.exit(2)
1250969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    for o, a in opts:
1251969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-c':
1252969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser            cmd = a
1253f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1254969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-d':
1255f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            debug = True
1256f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1257969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-e':
1258f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_edit = True
1259f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        if o == '-h':
1260f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            sys.stdout.write(usage_msg)
1261f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            sys.exit()
1262f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        if o == '-i':
1263f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
12648f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser        if o == '-n':
12658f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser            use_subprocess = False
1266969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-r':
1267969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser            script = a
1268f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            if os.path.isfile(script):
1269f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                pass
1270f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            else:
1271f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                print "No script file: ", script
1272f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                sys.exit()
1273f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1274969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-s':
1275f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            startup = True
1276f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1277969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-t':
1278969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser            PyShell.shell_title = a
1279f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1280f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    if args and args[0] == '-':
1281f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        cmd = sys.stdin.read()
1282f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        enable_shell = True
1283f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # process sys.argv and sys.path:
1284969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    for i in range(len(sys.path)):
1285969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        sys.path[i] = os.path.abspath(sys.path[i])
1286f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    if args and args[0] == '-':
1287f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        sys.argv = [''] + args[1:]
1288f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    elif cmd:
1289f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        sys.argv = ['-c'] + args
1290f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    elif script:
1291f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        sys.argv = [script] + args
1292f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    elif args:
1293f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        enable_edit = True
1294f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        pathx = []
1295969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        for filename in args:
1296969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser            pathx.append(os.path.dirname(filename))
1297f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        for dir in pathx:
1298f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            dir = os.path.abspath(dir)
1299f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            if not dir in sys.path:
1300f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                sys.path.insert(0, dir)
1301ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser    else:
1302ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser        dir = os.getcwd()
1303ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser        if not dir in sys.path:
1304ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser            sys.path.insert(0, dir)
1305f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # check the IDLE settings configuration (but command line overrides)
1306f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    edit_start = idleConf.GetOption('main', 'General',
13076655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser                                    'editor-on-startup', type='bool')
1308f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    enable_edit = enable_edit or edit_start
13096655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser    enable_shell = enable_shell or not edit_start
1310f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # start editor and/or shell windows:
1311969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    root = Tk(className="Idle")
1312969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    fixwordbreaks(root)
1313969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    root.withdraw()
1314969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    flist = PyShellFileList(root)
1315f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    if enable_edit:
1316f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        if not (cmd or script):
1317f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            for filename in args:
1318f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                flist.open(filename)
1319f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            if not args:
1320f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                flist.new()
1321af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser    if enable_shell:
1322af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser        if not flist.open_shell():
1323af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser            return # couldn't open shell
1324f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    shell = flist.pyshell
1325f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # handle remaining options:
1326f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    if debug:
1327f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        shell.open_debugger()
1328969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    if startup:
1329969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        filename = os.environ.get("IDLESTARTUP") or \
1330969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser                   os.environ.get("PYTHONSTARTUP")
1331969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if filename and os.path.isfile(filename):
1332f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            shell.interp.execfile(filename)
1333af3eb878027954fa578f43ba490599d13215eb3aKurt B. Kaiser    if shell and cmd or script:
1334f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        shell.interp.runcommand("""if 1:
1335f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            import sys as _sys
1336f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            _sys.argv = %s
1337f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            del _sys
1338f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            \n""" % `sys.argv`)
1339f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        if cmd:
1340f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            shell.interp.execsource(cmd)
1341f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        elif script:
134211659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            shell.interp.prepend_syspath(script)
1343f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            shell.interp.execfile(script)
1344969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    root.mainloop()
1345969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    root.destroy()
1346969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser
13477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererif __name__ == "__main__":
13489e8b828f07d0a55676e987b4ca70c247853f5695Kurt B. Kaiser    sys.modules['PyShell'] = sys.modules['__main__']
13497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    main()
1350