PyShell.py revision bea57c6c355ba98cd9019d13e5adf7d715377edf
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
197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererfrom Tkinter import *
207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport tkMessageBox
217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererfrom EditorWindow import EditorWindow, fixwordbreaks
237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererfrom FileList import FileList
247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererfrom ColorDelegator import ColorDelegator
257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererfrom UndoDelegator import UndoDelegator
26969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiserfrom OutputWindow import OutputWindow
279930061ce28b1fc60d267ae3474c74a41e655cd5Steven M. Gavafrom configHandler import idleConf
287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport idlever
297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
305d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teyimport rpc
317f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiserimport Debugger
32ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiserimport RemoteDebugger
335d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
34b97641994617115321719d4ecf797a461e2d5cf2Kurt B. KaiserIDENTCHARS = string.ascii_letters + string.digits + "_"
3524d7e0cbb8b978738f223d4bb6cb184054d72e18Kurt B. KaiserLOCALHOST = '127.0.0.1'
36b97641994617115321719d4ecf797a461e2d5cf2Kurt B. Kaiser
37a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaisertry:
38a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser    from signal import SIGTERM
39a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiserexcept ImportError:
40a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser    SIGTERM = 15
41a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser
425d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey# Change warnings module to write to sys.__stderr__
435d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teytry:
445d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    import warnings
455d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teyexcept ImportError:
465d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    pass
475d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teyelse:
485d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    def idle_showwarning(message, category, filename, lineno):
495d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        file = sys.__stderr__
505d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        file.write(warnings.formatwarning(message, category, filename, lineno))
515d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    warnings.showwarning = idle_showwarning
525d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
53818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiserdef extended_linecache_checkcache(orig_checkcache=linecache.checkcache):
5445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    """Extend linecache.checkcache to preserve the <pyshell#...> entries
5545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
56818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiser    Rather than repeating the linecache code, patch it to save the pyshell#
57818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiser    entries, call the original linecache.checkcache(), and then restore the
58818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiser    saved entries.  Assigning the orig_checkcache keyword arg freezes its value
59818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiser    at definition time to the (original) method linecache.checkcache(), i.e.
60818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiser    makes orig_checkcache lexical.
6145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
6245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    """
637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    cache = linecache.cache
647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    save = {}
657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    for filename in cache.keys():
667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if filename[:1] + filename[-1:] == '<>':
677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            save[filename] = cache[filename]
687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    orig_checkcache()
697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    cache.update(save)
706655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
71818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiser# Patch linecache.checkcache():
72818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiserlinecache.checkcache = extended_linecache_checkcache
737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass PyShellEditorWindow(EditorWindow):
76ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiser    "Regular text edit window when a shell is present"
7745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def __init__(self, *args):
7945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        self.breakpoints = []
807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        apply(EditorWindow.__init__, (self,) + args)
817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.bind("<<set-breakpoint-here>>", self.set_breakpoint_here)
8245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        self.text.bind("<<clear-breakpoint-here>>", self.clear_breakpoint_here)
837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.bind("<<open-python-shell>>", self.flist.open_shell)
847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
85bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        self.breakpointPath = os.path.join(idleConf.GetUserCfgDir(),
86bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                                           'breakpoints.lst')
87a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        # whenever a file is changed, restore breakpoints
88a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        if self.io.filename: self.restore_file_breaks()
89bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        def filename_changed_hook(old_hook=self.io.filename_change_hook,
90bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                                  self=self):
91a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey            self.restore_file_breaks()
92a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey            old_hook()
93a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        self.io.set_filename_change_hook(filename_changed_hook)
94a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey
9545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    rmenu_specs = [("Set Breakpoint", "<<set-breakpoint-here>>"),
9645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                   ("Clear Breakpoint", "<<clear-breakpoint-here>>")]
977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
98a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey    def set_breakpoint(self, lineno):
9945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        text = self.text
10045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        filename = self.io.filename
101a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        text.tag_add("BREAK", "%d.0" % lineno, "%d.0" % (lineno+1))
10245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        try:
10345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            i = self.breakpoints.index(lineno)
104a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        except ValueError:  # only add if missing, i.e. do once
10545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            self.breakpoints.append(lineno)
10645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        try:    # update the subprocess debugger
10745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug = self.flist.pyshell.interp.debugger
10845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug.set_breakpoint_here(filename, lineno)
10945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        except: # but debugger may not be active right now....
11045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            pass
1117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
112a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey    def set_breakpoint_here(self, event=None):
113a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        text = self.text
114a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        filename = self.io.filename
115a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        if not filename:
116a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey            text.bell()
117a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey            return
118a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        lineno = int(float(text.index("insert")))
119a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        self.set_breakpoint(lineno)
120a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey
121669f4c3850eaaf4e00a79032ef960a79e6ca6ad7Kurt B. Kaiser    def clear_breakpoint_here(self, event=None):
12245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        text = self.text
12345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        filename = self.io.filename
12445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        if not filename:
12545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            text.bell()
126669f4c3850eaaf4e00a79032ef960a79e6ca6ad7Kurt B. Kaiser            return
12745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        lineno = int(float(text.index("insert")))
12845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        try:
12945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            self.breakpoints.remove(lineno)
13045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        except:
13145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            pass
13245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        text.tag_remove("BREAK", "insert linestart",\
13345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                        "insert lineend +1char")
13445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        try:
13545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug = self.flist.pyshell.interp.debugger
13645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug.clear_breakpoint_here(filename, lineno)
13745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        except:
13845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            pass
13945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
14045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    def clear_file_breaks(self):
14145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        if self.breakpoints:
14245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            text = self.text
14345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            filename = self.io.filename
14445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            if not filename:
14545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                text.bell()
14645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                return
14745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            self.breakpoints = []
14845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            text.tag_remove("BREAK", "1.0", END)
14945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            try:
15045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                debug = self.flist.pyshell.interp.debugger
15145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                debug.clear_file_breaks(filename)
15245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            except:
15345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                pass
15445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
155a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey    def store_file_breaks(self):
156bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        "Save breakpoints when file is saved"
157bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        # XXX 13 Dec 2002 KBK Currently the file must be saved before it can
158bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     be run.  The breaks are saved at that time.  If we introduce
159bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     a temporary file save feature the save breaks functionality
160bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     needs to be re-verified, since the breaks at the time the
161bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     temp file is created may differ from the breaks at the last
1627f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        #     permanent save of the file.  Currently, a break introduced
1637f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        #     after a save will be effective, but not persistent.
1647f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        #     This is necessary to keep the saved breaks synched with the
1657f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        #     saved file.
166bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #
167bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     Breakpoints are set as tagged ranges in the text.  Certain
168bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     kinds of edits cause these ranges to be deleted: Inserting
169bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     or deleting a line just before a breakpoint, and certain
170bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     deletions prior to a breakpoint.  These issues need to be
171bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     investigated and understood.  It's not clear if they are
172bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     Tk issues or IDLE issues, or whether they can actually
173bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     be fixed.  Since a modified file has to be saved before it is
174bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     run, and since self.breakpoints (from which the subprocess
175bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     debugger is loaded) is updated during the save, the visible
176bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     breaks stay synched with the subprocess even if one of these
177bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     unexpected breakpoint deletions occurs.
178bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        breaks = self.breakpoints
179bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        filename = self.io.filename
180a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        try:
181bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            lines = open(self.breakpointPath,"r").readlines()
182a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        except IOError:
183bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            lines = []
184bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        new_file = open(self.breakpointPath,"w")
185a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        for line in lines:
186bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            if not line.startswith(filename + '='):
187a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey                new_file.write(line)
188bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        self.update_breakpoints()
189bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        breaks = self.breakpoints
190bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        if breaks:
191bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            new_file.write(filename + '=' + str(breaks) + '\n')
192a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        new_file.close()
193a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey
194a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey    def restore_file_breaks(self):
195a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        self.text.update()   # this enables setting "BREAK" tags to be visible
196bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        filename = self.io.filename
197bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        if filename is None:
198bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            return
19969371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey        if os.path.isfile(self.breakpointPath):
200bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            lines = open(self.breakpointPath,"r").readlines()
20169371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey            for line in lines:
202bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                if line.startswith(filename + '='):
2036655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser                    breakpoint_linenumbers = eval(line[len(filename)+1:])
20469371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey                    for breakpoint_linenumber in breakpoint_linenumbers:
20569371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey                        self.set_breakpoint(breakpoint_linenumber)
206a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey
207bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser    def update_breakpoints(self):
208bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        "Retrieves all the breakpoints in the current window"
209a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        text = self.text
210bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        ranges = text.tag_ranges("BREAK")
211bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        linenumber_list = self.ranges_to_linenumbers(ranges)
212bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        self.breakpoints = linenumber_list
213bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser
214bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser    def ranges_to_linenumbers(self, ranges):
215bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        lines = []
216bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        for index in range(0, len(ranges), 2):
217bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            lineno = int(float(ranges[index]))
218bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            end = int(float(ranges[index+1]))
219bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            while lineno < end:
220bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                lines.append(lineno)
221bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                lineno += 1
222bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        return lines
223bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser
22411220fad1d7eee24f1d9809c6d5023875099cb37Kurt B. Kaiser# XXX 13 Dec 2002 KBK Not used currently
225bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#    def saved_change_hook(self):
226bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#        "Extend base method - clear breaks if module is modified"
227bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#        if not self.get_saved():
228bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#            self.clear_file_breaks()
229bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#        EditorWindow.saved_change_hook(self)
23045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
23145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    def _close(self):
23245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        "Extend base method - clear breaks when module is closed"
23345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        self.clear_file_breaks()
23445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        EditorWindow._close(self)
2356655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
2367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass PyShellFileList(FileList):
23883118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser    "Extend base class: file list when a shell is present"
2397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    EditorWindow = PyShellEditorWindow
2417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    pyshell = None
2437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def open_shell(self, event=None):
2457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.pyshell:
2467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.pyshell.wakeup()
2477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
2487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.pyshell = PyShell(self)
2497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.pyshell.begin()
2507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return self.pyshell
2517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass ModifiedColorDelegator(ColorDelegator):
25483118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser    "Extend base class: colorizer for the shell window itself"
2556655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
256b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava    def __init__(self):
257b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        ColorDelegator.__init__(self)
258b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        self.LoadTagDefs()
2597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def recolorize_main(self):
2617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tag_remove("TODO", "1.0", "iomark")
2627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tag_add("SYNC", "1.0", "iomark")
2637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        ColorDelegator.recolorize_main(self)
2646655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
265b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava    def LoadTagDefs(self):
266b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        ColorDelegator.LoadTagDefs(self)
267b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        theme = idleConf.GetOption('main','Theme','name')
268b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        self.tagdefs.update({
269b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            "stdin": {'background':None,'foreground':None},
270b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            "stdout": idleConf.GetHighlight(theme, "stdout"),
271b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            "stderr": idleConf.GetHighlight(theme, "stderr"),
272b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            "console": idleConf.GetHighlight(theme, "console"),
273b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            None: idleConf.GetHighlight(theme, "normal"),
274b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        })
2757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass ModifiedUndoDelegator(UndoDelegator):
27783118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser    "Extend base class: forbid insert/delete before the I/O mark"
2787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def insert(self, index, chars, tags=None):
2807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
2817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if self.delegate.compare(index, "<", "iomark"):
2827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.delegate.bell()
2837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return
2847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except TclError:
2857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            pass
2867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        UndoDelegator.insert(self, index, chars, tags)
2877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def delete(self, index1, index2=None):
2897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
2907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if self.delegate.compare(index1, "<", "iomark"):
2917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.delegate.bell()
2927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return
2937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except TclError:
2947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            pass
2957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        UndoDelegator.delete(self, index1, index2)
2967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
29767fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser
29867fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiserclass MyRPCClient(rpc.RPCClient):
29967fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser
30067fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser    def handle_EOF(self):
30167fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser        "Override the base class - just re-raise EOFError"
30267fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser        raise EOFError
30367fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser
3048d1f11b0ef7ec31db75a4e640e9dfd75fc4ee08dKurt B. Kaiser
3057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass ModifiedInterpreter(InteractiveInterpreter):
3067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
3077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def __init__(self, tkconsole):
3087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tkconsole = tkconsole
3097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        locals = sys.modules['__main__'].__dict__
3107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        InteractiveInterpreter.__init__(self, locals=locals)
31194bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        self.save_warnings_filters = None
3126f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        self.restarting = False
31362df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser        self.subprocess_arglist = self.build_subprocess_arglist()
3147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
31563857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser    port = 8833
3165d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    rpcclt = None
3175d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    rpcpid = None
3185d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
3196655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser    def spawn_subprocess(self):
32062df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser        args = self.subprocess_arglist
3215d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.rpcpid = os.spawnv(os.P_NOWAIT, args[0], args)
32263857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser
323f53dec2e4e8a017641db4de73456a2724a75e64bTony Lownds    def build_subprocess_arglist(self):
3242398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        w = ['-W' + s for s in sys.warnoptions]
3252398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        # Maybe IDLE is installed and is being accessed via sys.path,
3262398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        # or maybe it's not installed and the idle.py script is being
3272398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        # run from the IDLE source directory.
32862df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser        del_exitf = idleConf.GetOption('main', 'General', 'delete-exitfunc',
32962df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser                                       default=False, type='bool')
3302398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        if __name__ == 'idlelib.PyShell':
33162df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser            command = "__import__('idlelib.run').run.main(" + `del_exitf` +")"
332f2324b9e8964a7aef964ae6168827ad300f920d6Tony Lownds        else:
33362df0448850000739edd1df8b4c0e702119d476eKurt B. Kaiser            command = "__import__('run').main(" + `del_exitf` + ")"
3342398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        return [sys.executable] + w + ["-c", command, str(self.port)]
335f2324b9e8964a7aef964ae6168827ad300f920d6Tony Lownds
33663857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser    def start_subprocess(self):
33724d7e0cbb8b978738f223d4bb6cb184054d72e18Kurt B. Kaiser        addr = (LOCALHOST, self.port)
3388dcdb77132563c734c228e815498c47e487f95cfKurt B. Kaiser        # Idle starts listening for connection on localhost
3395db4843c5e7d2b420b9ca9189b9e30669b62e55eKurt B. Kaiser        for i in range(3):
3405d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            time.sleep(i)
3415d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            try:
34267fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser                self.rpcclt = MyRPCClient(addr)
3435d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey                break
3445d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            except socket.error, err:
3458f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser                print>>sys.__stderr__,"IDLE socket error: " + err[1]\
346b417936d4080004b6a7811fb411c6f77db4cc262Kurt B. Kaiser                                                    + ", retrying..."
3475d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        else:
348969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser            display_port_binding_error()
349a2a3cb23defa5e17a159982adac33e3dd58d8a93Kurt B. Kaiser            sys.exit()
3505db4843c5e7d2b420b9ca9189b9e30669b62e55eKurt B. Kaiser        self.spawn_subprocess()
351b417936d4080004b6a7811fb411c6f77db4cc262Kurt B. Kaiser        # Accept the connection from the Python execution server
352b417936d4080004b6a7811fb411c6f77db4cc262Kurt B. Kaiser        self.rpcclt.accept()
353969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        self.rpcclt.register("stdin", self.tkconsole)
354969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        self.rpcclt.register("stdout", self.tkconsole.stdout)
355969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        self.rpcclt.register("stderr", self.tkconsole.stderr)
3565d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.rpcclt.register("flist", self.tkconsole.flist)
3578cd0def10dc028e3522a04bd136c67f92f90da04Kurt B. Kaiser        self.rpcclt.register("linecache", linecache)
3589f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        self.rpcclt.register("interp", self)
359f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        self.transfer_path()
3605d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.poll_subprocess()
3615d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
36263857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser    def restart_subprocess(self):
3636f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        if self.restarting:
3646f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser            return
3656f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        self.restarting = True
36663857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser        # close only the subprocess debugger
36745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        debug = self.getdebugger()
36845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        if debug:
369003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            try:
3709ec454ec00088e051195e80363499a14cafc131aKurt B. Kaiser                # Only close subprocess debugger, don't unregister gui_adap!
371003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser                RemoteDebugger.close_subprocess_debugger(self.rpcclt)
372003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            except:
373003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser                pass
374003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        # Kill subprocess, spawn a new one, accept connection.
375a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.rpcclt.close()
376a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.unix_terminate()
3777f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        console = self.tkconsole
3786f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        was_executing = console.executing
3797f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        console.executing = False
38063857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser        self.spawn_subprocess()
38163857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser        self.rpcclt.accept()
382f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        self.transfer_path()
3831061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        # annotate restart in shell window and mark it
3844cc5ef5dbe12cbc9dc1a00c7583ffd0117f4c31eKurt B. Kaiser        console.text.delete("iomark", "end-1c")
3856f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        if was_executing:
3866f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser            console.write('\n')
3876f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser            console.showprompt()
3881061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        halfbar = ((int(console.width) - 16) // 2) * '='
3891061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        console.write(halfbar + ' RESTART ' + halfbar)
3901061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        console.text.mark_set("restart", "end-1c")
3911061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        console.text.mark_gravity("restart", "left")
3927f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        console.showprompt()
393003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        # restart subprocess debugger
39445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        if debug:
3959ec454ec00088e051195e80363499a14cafc131aKurt B. Kaiser            # Restarted debugger connects to current instance of debug GUI
39663857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser            gui = RemoteDebugger.restart_subprocess_debugger(self.rpcclt)
39745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            # reload remote debugger breakpoints for all PyShellEditWindows
39845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug.load_breakpoints()
3996f805942290b8d83f0e229de98c8d0d7a2a7c3e8Kurt B. Kaiser        self.restarting = False
40045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
401003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    def __request_interrupt(self):
402a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.rpcclt.remotecall("exec", "interrupt_the_server", (), {})
403003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser
404003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    def interrupt_subprocess(self):
405a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        threading.Thread(target=self.__request_interrupt).start()
406003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser
407a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser    def kill_subprocess(self):
408a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.rpcclt.close()
409a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.unix_terminate()
410a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.tkconsole.executing = False
411a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.rpcclt = None
41211c53e2ea7f7d2a2969c98e81c1489c4e72254c4Kurt B. Kaiser
413a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser    def unix_terminate(self):
414a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        "UNIX: make sure subprocess is terminated and collect status"
415a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        if hasattr(os, 'kill'):
416a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            try:
417a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                os.kill(self.rpcpid, SIGTERM)
418a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            except OSError:
419a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                # process already terminated:
420a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                return
421a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            else:
422a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                try:
423a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                    os.waitpid(self.rpcpid, 0)
424a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                except OSError:
425a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                    return
42611c53e2ea7f7d2a2969c98e81c1489c4e72254c4Kurt B. Kaiser
427f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    def transfer_path(self):
428f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        self.runcommand("""if 1:
429f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        import sys as _sys
430f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        _sys.path = %s
431f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        del _sys
432b2487335bf8c9258d347d96cf615d964d57f5658Kurt B. Kaiser        _msg = 'Use File/Exit or your end-of-file key to quit IDLE'
433b2487335bf8c9258d347d96cf615d964d57f5658Kurt B. Kaiser        __builtins__.quit = __builtins__.exit = _msg
434b2487335bf8c9258d347d96cf615d964d57f5658Kurt B. Kaiser        del _msg
435f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        \n""" % `sys.path`)
436f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
4375d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    active_seq = None
4385d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
4395d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    def poll_subprocess(self):
4405d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        clt = self.rpcclt
4415d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if clt is None:
4425d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            return
443003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        try:
444a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            response = clt.pollresponse(self.active_seq, wait=0.05)
445a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        except (EOFError, IOError, KeyboardInterrupt):
446a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            # lost connection or subprocess terminated itself, restart
447a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            # [the KBI is from rpc.SocketIO.handle_EOF()]
44867fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser            if self.tkconsole.closing:
44967fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser                return
450003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            response = None
451003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            self.restart_subprocess()
4525d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if response:
4535d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            self.tkconsole.resetoutput()
4545d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            self.active_seq = None
4555d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            how, what = response
456bc2861313cc53711d837a0e8a5bf303bf5291bf3Kurt B. Kaiser            console = self.tkconsole.console
4575d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            if how == "OK":
4585d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey                if what is not None:
459bc2861313cc53711d837a0e8a5bf303bf5291bf3Kurt B. Kaiser                    print >>console, `what`
4605d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            elif how == "EXCEPTION":
4615d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey                if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
4625d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey                    self.remote_stack_viewer()
4635d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            elif how == "ERROR":
4640930c43e43f79617a33a6c3be32afbe184780307Kurt B. Kaiser                errmsg = "PyShell.ModifiedInterpreter: Subprocess ERROR:\n"
4650930c43e43f79617a33a6c3be32afbe184780307Kurt B. Kaiser                print >>sys.__stderr__, errmsg, what
466bc2861313cc53711d837a0e8a5bf303bf5291bf3Kurt B. Kaiser                print >>console, errmsg, what
467bc2861313cc53711d837a0e8a5bf303bf5291bf3Kurt B. Kaiser            # we received a response to the currently active seq number:
4685d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            self.tkconsole.endexecuting()
46988957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser        # Reschedule myself
47088957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser        if not self.tkconsole.closing:
47188957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser            self.tkconsole.text.after(self.tkconsole.pollinterval,
47288957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser                                      self.poll_subprocess)
4735d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
47445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    debugger = None
47545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
47645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    def setdebugger(self, debugger):
47745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        self.debugger = debugger
47845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
47945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    def getdebugger(self):
48045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        return self.debugger
48145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
4829f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser    def open_remote_stack_viewer(self):
4839f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        """Initiate the remote stack viewer from a separate thread.
4849f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser
4859f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        This method is called from the subprocess, and by returning from this
4869f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        method we allow the subprocess to unblock.  After a bit the shell
4879f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        requests the subprocess to open the remote stack viewer which returns a
4889f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        static object looking at the last exceptiopn.  It is queried through
4899f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        the RPC mechanism.
4909f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser
4919f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        """
4929f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        self.tkconsole.text.after(300, self.remote_stack_viewer)
4939f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser        return
4949f3660972003dddcc1cced41934488513e277220Kurt B. Kaiser
4955d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    def remote_stack_viewer(self):
4965d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        import RemoteObjectBrowser
497a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        oid = self.rpcclt.remotequeue("exec", "stackviewer", ("flist",), {})
4985d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if oid is None:
4995d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            self.tkconsole.root.bell()
5005d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            return
5015d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        item = RemoteObjectBrowser.StubObjectTreeItem(self.rpcclt, oid)
5025d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        from TreeWidget import ScrolledCanvas, TreeNode
5035d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        top = Toplevel(self.tkconsole.root)
5045d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        sc = ScrolledCanvas(top, bg="white", highlightthickness=0)
5055d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        sc.frame.pack(expand=1, fill="both")
5065d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        node = TreeNode(sc.canvas, None, item)
5075d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        node.expand()
5085d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        # XXX Should GC the remote tree when closing the window
5095d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
5107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    gid = 0
5117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
5127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def execsource(self, source):
51383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Like runsource() but assumes complete exec source"
5147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        filename = self.stuffsource(source)
5157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.execfile(filename, source)
5167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
5177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def execfile(self, filename, source=None):
51883118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Execute an existing file"
5197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if source is None:
5207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            source = open(filename, "r").read()
5217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
5227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            code = compile(source, filename, "exec")
5237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except (OverflowError, SyntaxError):
5247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.tkconsole.resetoutput()
5257f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            tkerr = self.tkconsole.stderr
5267f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            print>>tkerr, '*** Error in script or command!\n'
5277f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            print>>tkerr, 'Traceback (most recent call last):'
5287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            InteractiveInterpreter.showsyntaxerror(self, filename)
5296e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            self.tkconsole.showprompt()
5307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
5317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.runcode(code)
5327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
5337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def runsource(self, source):
53483118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Extend base class method: Stuff the source in the line cache first"
5357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        filename = self.stuffsource(source)
5367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.more = 0
53794bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        self.save_warnings_filters = warnings.filters[:]
53894bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        warnings.filterwarnings(action="error", category=SyntaxWarning)
539837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        if isinstance(source, types.UnicodeType):
540837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser            import IOBinding
541837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser            try:
542837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser                source = source.encode(IOBinding.encoding)
543837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser            except UnicodeError:
544837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser                self.tkconsole.resetoutput()
545837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser                self.write("Unsupported characters in input")
546837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser                return
54794bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        try:
54894bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser            return InteractiveInterpreter.runsource(self, source, filename)
54994bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        finally:
55094bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser            if self.save_warnings_filters is not None:
55194bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser                warnings.filters[:] = self.save_warnings_filters
55294bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser                self.save_warnings_filters = None
5537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
5547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def stuffsource(self, source):
55583118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Stuff source in the filename cache"
5567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        filename = "<pyshell#%d>" % self.gid
5577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.gid = self.gid + 1
558837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        lines = source.split("\n")
5597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        linecache.cache[filename] = len(source)+1, 0, lines, filename
5607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return filename
5616655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
56211659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser    def prepend_syspath(self, filename):
56311659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser        "Prepend sys.path with file's directory if not already included"
56411659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser        self.runcommand("""if 1:
56511659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            _filename = %s
56611659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            import sys as _sys
56711659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            from os.path import dirname as _dirname
56811659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            _dir = _dirname(_filename)
56911659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            if not _dir in _sys.path:
57011659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser                _sys.path.insert(0, _dir)
57111659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            del _filename, _sys, _dirname, _dir
57211659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            \n""" % `filename`)
57311659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser
5747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def showsyntaxerror(self, filename=None):
57583118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        """Extend base class method: Add Colorizing
57683118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser
57783118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        Color the offending position instead of printing it and pointing at it
57883118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        with a caret.
57983118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser
58083118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        """
5817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text = self.tkconsole.text
5827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        stuff = self.unpackerror()
5836e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser        if stuff:
5846e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            msg, lineno, offset, line = stuff
5856e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            if lineno == 1:
5866e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser                pos = "iomark + %d chars" % (offset-1)
5876e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            else:
5886e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser                pos = "iomark linestart + %d lines + %d chars" % \
5896e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser                      (lineno-1, offset-1)
5906e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            text.tag_add("ERROR", pos)
5916e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            text.see(pos)
5926e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            char = text.get(pos)
5936e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            if char and char in IDENTCHARS:
5946e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser                text.tag_add("ERROR", pos + " wordstart", pos)
5957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.tkconsole.resetoutput()
5966e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            self.write("SyntaxError: %s\n" % str(msg))
5977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
5986e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            self.tkconsole.resetoutput()
5996e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            InteractiveInterpreter.showsyntaxerror(self, filename)
6006e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser        self.tkconsole.showprompt()
6017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def unpackerror(self):
6037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        type, value, tb = sys.exc_info()
6047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        ok = type is SyntaxError
6057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if ok:
6067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            try:
6077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                msg, (dummy_filename, lineno, offset, line) = value
608bea57c6c355ba98cd9019d13e5adf7d715377edfKurt B. Kaiser                if not offset:
609bea57c6c355ba98cd9019d13e5adf7d715377edfKurt B. Kaiser                    offset = 0
6107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            except:
6117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                ok = 0
6127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if ok:
6137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return msg, lineno, offset, line
6147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
6157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return None
6167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def showtraceback(self):
61883118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Extend base class method to reset output properly"
6197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tkconsole.resetoutput()
6207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.checklinecache()
6217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        InteractiveInterpreter.showtraceback(self)
6225d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
6235d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            self.tkconsole.open_stack_viewer()
6247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def checklinecache(self):
6267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        c = linecache.cache
6277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        for key in c.keys():
6287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if key[:1] + key[-1:] != "<>":
6297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                del c[key]
6307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
63163857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser    def display_executing_dialog(self):
63263857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser        tkMessageBox.showerror(
63363857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser            "Already executing",
63463857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser            "The Python Shell window is already executing a command; "
63563857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser            "please wait until it is finished.",
63663857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser            master=self.tkconsole.text)
6376655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
6385d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    def runcommand(self, code):
63983118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Run the code without invoking the debugger"
6405d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        # The code better not raise an exception!
6415d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.tkconsole.executing:
642f4c4f115d80a26eb83d90593c24a1580f236c443Neal Norwitz            self.display_executing_dialog()
6435d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            return 0
6445d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.rpcclt:
645a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            self.rpcclt.remotequeue("exec", "runcode", (code,), {})
6465d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        else:
6475d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            exec code in self.locals
6485d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        return 1
6495d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
6507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def runcode(self, code):
65183118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Override base class method"
6525d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.tkconsole.executing:
653003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            self.interp.restart_subprocess()
6545d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.checklinecache()
65594bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        if self.save_warnings_filters is not None:
65694bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser            warnings.filters[:] = self.save_warnings_filters
65794bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser            self.save_warnings_filters = None
6587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        debugger = self.debugger
6597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
6607f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            self.tkconsole.beginexecuting()
6617f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            try:
6627f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                if not debugger and self.rpcclt is not None:
6637f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    self.active_seq = self.rpcclt.asyncqueue("exec", "runcode",
6647f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                                                            (code,), {})
6657f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                elif debugger:
6667f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    debugger.run(code, self.locals)
6677f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                else:
6687f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    exec code in self.locals
6697f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            except SystemExit:
6707f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                if tkMessageBox.askyesno(
6717f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    "Exit?",
6727f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    "Do you want to exit altogether?",
6737f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    default="yes",
6747f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    master=self.tkconsole.text):
6757f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    raise
6767f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                else:
6777f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    self.showtraceback()
6787f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            except:
6797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.showtraceback()
6807f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        finally:
6817f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            if not use_subprocess:
6827f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                self.tkconsole.endexecuting()
6837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def write(self, s):
68583118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Override base class method"
6867f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        self.tkconsole.stderr.write(s)
6877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass PyShell(OutputWindow):
6897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    shell_title = "Python Shell"
6917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    # Override classes
6937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    ColorDelegator = ModifiedColorDelegator
6947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    UndoDelegator = ModifiedUndoDelegator
6957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
696f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # Override menus
697dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser    menu_specs = [
698dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        ("file", "_File"),
699dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        ("edit", "_Edit"),
7004cc5ef5dbe12cbc9dc1a00c7583ffd0117f4c31eKurt B. Kaiser        ("debug", "_Debug"),
7011061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        ("options", "_Options"),
702dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        ("windows", "_Windows"),
703dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        ("help", "_Help"),
704dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser    ]
7057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    # New classes
7077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    from IdleHistory import History
7087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def __init__(self, flist=None):
7108f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser        if use_subprocess:
71167fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser            ms = self.menu_specs
71267fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser            if ms[2][0] != "shell":
71367fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser                ms.insert(2, ("shell", "_Shell"))
7147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.interp = ModifiedInterpreter(self)
7157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if flist is None:
7167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            root = Tk()
7177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            fixwordbreaks(root)
7187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            root.withdraw()
7197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            flist = PyShellFileList(root)
7205afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
7217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        OutputWindow.__init__(self, flist, None, None)
7225afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
7237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        import __builtin__
7247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        __builtin__.quit = __builtin__.exit = "To exit, type Ctrl-D."
7255afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
726ee7afca550f69ace3e20d25b84432f45c246c600Kurt B. Kaiser        self.config(usetabs=1, indentwidth=8, context_use_ps1=1)
7275afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
7287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text = self.text
7297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.configure(wrap="char")
7307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<newline-and-indent>>", self.enter_callback)
7317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<plain-newline-and-indent>>", self.linefeed_callback)
7327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<interrupt-execution>>", self.cancel_callback)
7337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<beginning-of-line>>", self.home_callback)
7347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<end-of-file>>", self.eof_callback)
7357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<open-stack-viewer>>", self.open_stack_viewer)
73657bfe5dc5a4873026679fb911939beb69e35a9e8Kurt B. Kaiser        text.bind("<<toggle-debugger>>", self.toggle_debugger)
7377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<open-python-shell>>", self.flist.open_shell)
7387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<toggle-jit-stack-viewer>>", self.toggle_jit_stack_viewer)
7398f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser        if use_subprocess:
7408f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser            text.bind("<<view-restart>>", self.view_restart_mark)
7418f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser            text.bind("<<restart-shell>>", self.restart_shell)
7425afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
7437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.save_stdout = sys.stdout
7447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.save_stderr = sys.stderr
7457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.save_stdin = sys.stdin
746bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis        import IOBinding
747bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis        self.stdout = PseudoFile(self, "stdout", IOBinding.encoding)
748bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis        self.stderr = PseudoFile(self, "stderr", IOBinding.encoding)
749bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis        self.console = PseudoFile(self, "console", IOBinding.encoding)
7505d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if not use_subprocess:
7515d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            sys.stdout = self.stdout
7525d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            sys.stderr = self.stderr
7535d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            sys.stdin = self
7545afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
7557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.history = self.History(self.text)
7565afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
75788957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser        self.pollinterval = 50  # millisec
7585d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if use_subprocess:
75963857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser            self.interp.start_subprocess()
7605d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
761003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    reading = False
762003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    executing = False
763003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    canceled = False
764003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    endoffile = False
765003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    closing = False
7667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def toggle_debugger(self, event=None):
7687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.executing:
7697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            tkMessageBox.showerror("Don't debug now",
7707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                "You can only toggle the debugger when idle",
7717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                master=self.text)
7727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.set_debugger_indicator()
7737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
7747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
7757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            db = self.interp.getdebugger()
7767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if db:
7777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.close_debugger()
7787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            else:
7797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.open_debugger()
7807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def set_debugger_indicator(self):
7827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        db = self.interp.getdebugger()
7837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.setvar("<<toggle-debugger>>", not not db)
7847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7851061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser    def toggle_jit_stack_viewer(self, event=None):
7867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        pass # All we need is the variable
7877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def close_debugger(self):
7897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        db = self.interp.getdebugger()
7907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if db:
7917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.interp.setdebugger(None)
7927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            db.close()
793ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiser            if self.interp.rpcclt:
794ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiser                RemoteDebugger.close_remote_debugger(self.interp.rpcclt)
7957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.resetoutput()
7967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.console.write("[DEBUG OFF]\n")
7977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            sys.ps1 = ">>> "
7987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.showprompt()
7997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.set_debugger_indicator()
8007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def open_debugger(self):
8025d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.interp.rpcclt:
8037f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            dbg_gui = RemoteDebugger.start_remote_debugger(self.interp.rpcclt,
8047f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                                                           self)
8057f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        else:
8067f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            dbg_gui = Debugger.Debugger(self)
8077f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        self.interp.setdebugger(dbg_gui)
8087f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        dbg_gui.load_breakpoints()
8095d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        sys.ps1 = "[DEBUG ON]\n>>> "
8105d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.showprompt()
8115d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.set_debugger_indicator()
8125d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
8137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def beginexecuting(self):
814ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiser        "Helper for ModifiedInterpreter"
8157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.resetoutput()
8167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.executing = 1
8177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def endexecuting(self):
81983118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Helper for ModifiedInterpreter"
8207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.executing = 0
8217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.canceled = 0
8225d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.showprompt()
8237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def close(self):
82583118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Extend EditorWindow.close()"
8267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.executing:
827003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            response = tkMessageBox.askokcancel(
8287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                "Kill?",
829003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser                "The program is still running!\n Do you want to kill it?",
8307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                default="ok",
8317f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                parent=self.text)
832003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            if response == False:
8337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return "cancel"
83467fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser        self.closing = True
83567fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser        # Wait for poll_subprocess() rescheduling to stop
83667fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser        self.text.after(2 * self.pollinterval, self.close2)
83788957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser
83888957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser    def close2(self):
83988957d8d0d9bf6d45603171927aa82d921bf9697Kurt B. Kaiser        return EditorWindow.close(self)
8407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def _close(self):
84283118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Extend EditorWindow._close(), shut down debugger and execution server"
8437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.close_debugger()
8447f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        if use_subprocess:
8457f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            self.interp.kill_subprocess()
8467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # Restore std streams
8477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sys.stdout = self.save_stdout
8487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sys.stderr = self.save_stderr
8497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sys.stdin = self.save_stdin
8507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # Break cycles
8517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.interp = None
8527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.console = None
8537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.flist.pyshell = None
8547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.history = None
85583118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        EditorWindow._close(self)
8567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def ispythonsource(self, filename):
85883118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Override EditorWindow method: never remove the colorizer"
859837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        return True
8607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def short_title(self):
8627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return self.shell_title
8637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
86494bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser    COPYRIGHT = \
8658f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser          'Type "copyright", "credits" or "license()" for more information.'
86694bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser
8677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def begin(self):
8687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.resetoutput()
8697f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        if use_subprocess:
8707f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            nosub = ''
8717f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        else:
8727f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            nosub = "==== No Subprocess ===="
873ae8bbff2313afc3ad9a5c69795ca4667fae45041Kurt B. Kaiser        self.write("Python %s on %s\n%s\nIDLE %s      %s\n" %
87494bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser                   (sys.version, sys.platform, self.COPYRIGHT,
8757f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    idlever.IDLE_VERSION, nosub))
8767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.showprompt()
8777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        import Tkinter
8787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        Tkinter._default_root = None
8797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def interact(self):
8817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.begin()
8827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.top.mainloop()
8837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def readline(self):
8857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        save = self.reading
8867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
8877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.reading = 1
8887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.top.mainloop()
8897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        finally:
8907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.reading = save
8917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        line = self.text.get("iomark", "end-1c")
892bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis        if isinstance(line, unicode):
893bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis            import IOBinding
894bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis            try:
895bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis                line = line.encode(IOBinding.encoding)
896bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis            except UnicodeError:
897bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis                pass
8987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.resetoutput()
8997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.canceled:
9007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.canceled = 0
9017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            raise KeyboardInterrupt
9027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.endoffile:
9037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.endoffile = 0
9047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return ""
9057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return line
9067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def isatty(self):
908837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        return True
9097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
910003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    def cancel_callback(self, event=None):
9117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
9127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if self.text.compare("sel.first", "!=", "sel.last"):
9137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return # Active selection -- always use default binding
9147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except:
9157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            pass
9167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if not (self.executing or self.reading):
9177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.resetoutput()
9187f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            self.interp.write("KeyboardInterrupt\n")
9197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.showprompt()
9207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
9217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.endoffile = 0
922003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        self.canceled = 1
9237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.reading:
9247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.top.quit()
925003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        elif (self.executing and self.interp.rpcclt):
92667fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser            if self.interp.getdebugger():
92767fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser                self.interp.restart_subprocess()
92867fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser            else:
92967fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser                self.interp.interrupt_subprocess()
9307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return "break"
9317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def eof_callback(self, event):
9337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.executing and not self.reading:
9347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return # Let the default binding (delete next char) take over
9357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if not (self.text.compare("iomark", "==", "insert") and
9367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.text.compare("insert", "==", "end-1c")):
9377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return # Let the default binding (delete next char) take over
9387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if not self.executing:
9397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.resetoutput()
9407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.close()
9417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
9427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.canceled = 0
9437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.endoffile = 1
9447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.top.quit()
9457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return "break"
9467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def home_callback(self, event):
9487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if event.state != 0 and event.keysym == "Home":
9497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return # <Modifier-Home>; fall back to class binding
9507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.text.compare("iomark", "<=", "insert") and \
9517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer           self.text.compare("insert linestart", "<=", "iomark"):
9527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.mark_set("insert", "iomark")
9537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.tag_remove("sel", "1.0", "end")
9547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.see("insert")
9557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
9567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def linefeed_callback(self, event):
9587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # Insert a linefeed without entering anything (still autoindented)
9597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.reading:
9607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.insert("insert", "\n")
9617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.see("insert")
9627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
963822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser            self.newline_and_indent_event(event)
9647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return "break"
9657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def enter_callback(self, event):
9677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.executing and not self.reading:
9687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return # Let the default binding (insert '\n') take over
9697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # If some text is selected, recall the selection
9707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # (but only if this before the I/O mark)
9717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
9727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            sel = self.text.get("sel.first", "sel.last")
9737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if sel:
9747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                if self.text.compare("sel.last", "<=", "iomark"):
9757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                    self.recall(sel)
9767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                    return "break"
9777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except:
9787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            pass
9797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # If we're strictly before the line containing iomark, recall
9807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # the current line, less a leading prompt, less leading or
9817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # trailing whitespace
9827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.text.compare("insert", "<", "iomark linestart"):
9837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            # Check if there's a relevant stdin range -- if so, use it
9847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            prev = self.text.tag_prevrange("stdin", "insert")
9857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if prev and self.text.compare("insert", "<", prev[1]):
9867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.recall(self.text.get(prev[0], prev[1]))
9877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return "break"
9887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            next = self.text.tag_nextrange("stdin", "insert")
9897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if next and self.text.compare("insert lineend", ">=", next[0]):
9907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.recall(self.text.get(next[0], next[1]))
9917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return "break"
9924ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser            # No stdin mark -- just get the current line, less any prompt
9934ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser            line = self.text.get("insert linestart", "insert lineend")
9944ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser            last_line_of_prompt = sys.ps1.split('\n')[-1]
9954ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser            if line.startswith(last_line_of_prompt):
9964ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser                line = line[len(last_line_of_prompt):]
9974ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser            self.recall(line)
9987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
999822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser        # If we're between the beginning of the line and the iomark, i.e.
10004ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser        # in the prompt area, move to the end of the prompt
1001822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser        if self.text.compare("insert", "<", "iomark"):
10024ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser            self.text.mark_set("insert", "iomark")
10037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # If we're in the current input and there's only whitespace
10047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # beyond the cursor, erase that whitespace first
10057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        s = self.text.get("insert", "end-1c")
1006837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        if s and not s.strip():
10077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.delete("insert", "end-1c")
10087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # If we're in the current input before its last line,
10097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # insert a newline right at the insert point
10107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.text.compare("insert", "<", "end-1c linestart"):
1011822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser            self.newline_and_indent_event(event)
10127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
10137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # We're in the last line; append a newline and submit it
10147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.mark_set("insert", "end-1c")
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        self.text.tag_add("stdin", "iomark", "end-1c")
10217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.update_idletasks()
10227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.reading:
10237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.top.quit() # Break out of recursive mainloop() in raw_input()
10247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
10257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.runit()
10267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return "break"
10277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def recall(self, s):
10297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.history:
10307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.history.recall(s)
10317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def runit(self):
10337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        line = self.text.get("iomark", "end-1c")
10347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # Strip off last newline and surrounding whitespace.
10357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # (To allow you to hit return twice to end a statement.)
10367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        i = len(line)
10377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        while i > 0 and line[i-1] in " \t":
10387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            i = i-1
10397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if i > 0 and line[i-1] == "\n":
10407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            i = i-1
10417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        while i > 0 and line[i-1] in " \t":
10427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            i = i-1
10437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        line = line[:i]
10447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        more = self.interp.runsource(line)
10457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def open_stack_viewer(self, event=None):
10475d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.interp.rpcclt:
10485d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            return self.interp.remote_stack_viewer()
10497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
10507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            sys.last_traceback
10517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except:
10527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            tkMessageBox.showerror("No stack trace",
10537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                "There is no stack trace yet.\n"
10547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                "(sys.last_traceback is not defined)",
10557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                master=self.text)
10567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return
10577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        from StackViewer import StackBrowser
10587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sv = StackBrowser(self.root, self.flist)
10597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10601061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser    def view_restart_mark(self, event=None):
10611061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        self.text.see("iomark")
10621061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        self.text.see("restart")
10631061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser
10641061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser    def restart_shell(self, event=None):
106567fd0ea46d187ccab90ed574207bc88503bde3eaKurt B. Kaiser        self.interp.restart_subprocess()
10661061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser
10677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def showprompt(self):
10687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.resetoutput()
10697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
10707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            s = str(sys.ps1)
10717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except:
10727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            s = ""
10737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.console.write(s)
10747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.mark_set("insert", "end-1c")
10755d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.set_line_and_column()
1076dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        self.io.reset_undo()
10777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def resetoutput(self):
10797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        source = self.text.get("iomark", "end-1c")
10807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.history:
10817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.history.history_store(source)
10827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.text.get("end-2c") != "\n":
10837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.insert("end-1c", "\n")
10847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.mark_set("iomark", "end-1c")
10855d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.set_line_and_column()
10867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sys.stdout.softspace = 0
10877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def write(self, s, tags=()):
1089003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        try:
1090003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            self.text.mark_gravity("iomark", "right")
1091003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            OutputWindow.write(self, s, tags, "iomark")
1092003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            self.text.mark_gravity("iomark", "left")
1093003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        except:
1094003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            pass
10957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.canceled:
10967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.canceled = 0
10977f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            if not use_subprocess:
10987f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                raise KeyboardInterrupt
10997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
11007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass PseudoFile:
11017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1102bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis    def __init__(self, shell, tags, encoding=None):
11037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.shell = shell
11047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tags = tags
11055d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.softspace = 0
1106bcc651a1f954bad7a14d93d41e95728072e48ea0Martin v. Löwis        self.encoding = encoding
11077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
11087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def write(self, s):
11097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.shell.write(s, self.tags)
11107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
11117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def writelines(self, l):
11127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        map(self.write, l)
11137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
11147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def flush(self):
11157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        pass
11167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
11177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def isatty(self):
1118837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        return True
11197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1120969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser
11217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererusage_msg = """\
11227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
112311659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. KaiserUSAGE: idle  [-deins] [-t title] [file]*
112411659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser       idle  [-dns] [-t title] (-c cmd | -r file) [arg]*
112511659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser       idle  [-dns] [-t title] - [arg]*
11266655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
1127f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -h         print this help message and exit
11288f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser  -n         run IDLE without a subprocess (see Help/IDLE Help for details)
1129f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1130f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserThe following options will override the IDLE 'settings' configuration:
1131f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1132f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -e         open an edit window
1133f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -i         open a shell window
1134f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1135f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserThe following options imply -i and will open a shell:
1136f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1137f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -c cmd     run the command in a shell, or
1138f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -r file    run script from file
1139f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1140f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -d         enable the debugger
1141f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -s         run $IDLESTARTUP or $PYTHONSTARTUP before anything else
1142f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -t title   set title of shell window
1143f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1144f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserA default edit window will be bypassed when -c, -r, or - are used.
1145f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1146f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser[arg]* are passed to the command (-c) or script (-r) in sys.argv[1:].
1147f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1148f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserExamples:
11497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1150f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle
1151f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Open an edit window or shell depending on IDLE's configuration.
115296d88422373ffb32aef75157647e0575a0471c03Kurt B. Kaiser
1153f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle foo.py foobar.py
1154f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Edit the files, also open a shell if configured to start with shell.
1155f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1156f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle -est "Baz" foo.py
1157f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Run $IDLESTARTUP or $PYTHONSTARTUP, edit foo.py, and open a shell
1158f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        window with the title "Baz".
1159f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1160f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle -c "import sys; print sys.argv" "foo"
1161f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Open a shell window and run the command, passing "-c" in sys.argv[0]
1162f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        and "foo" in sys.argv[1].
1163f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1164f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle -d -s -r foo.py "Hello World"
1165f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Open a shell window, run a startup script, enable the debugger, and
1166f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        run foo.py, passing "foo.py" in sys.argv[0] and "Hello World" in
1167f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        sys.argv[1].
1168f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1169f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiserecho "import sys; print sys.argv" | idle - "foobar"
1170f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Open a shell window, run the script piped in, passing '' in sys.argv[0]
1171f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        and "foobar" in sys.argv[1].
11727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer"""
11737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1174969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiserdef main():
1175f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    global flist, root, use_subprocess
1176f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
11778f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser    use_subprocess = True
1178f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    enable_shell = False
1179f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    enable_edit = False
1180f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    debug = False
1181969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    cmd = None
1182969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    script = None
1183f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    startup = False
1184969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    try:
11854ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser        sys.ps1
11864ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser    except AttributeError:
11874ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser        sys.ps1 = '>>> '
11884ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser    try:
11898f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser        opts, args = getopt.getopt(sys.argv[1:], "c:deihnr:st:")
1190969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    except getopt.error, msg:
1191969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        sys.stderr.write("Error: %s\n" % str(msg))
1192969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        sys.stderr.write(usage_msg)
1193969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        sys.exit(2)
1194969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    for o, a in opts:
1195969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-c':
1196969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser            cmd = a
1197f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1198969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-d':
1199f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            debug = True
1200f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1201969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-e':
1202f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_edit = True
1203f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        if o == '-h':
1204f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            sys.stdout.write(usage_msg)
1205f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            sys.exit()
1206f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        if o == '-i':
1207f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
12088f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser        if o == '-n':
12098f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser            use_subprocess = False
1210969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-r':
1211969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser            script = a
1212f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            if os.path.isfile(script):
1213f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                pass
1214f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            else:
1215f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                print "No script file: ", script
1216f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                sys.exit()
1217f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1218969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-s':
1219f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            startup = True
1220f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1221969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-t':
1222969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser            PyShell.shell_title = a
1223f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1224f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    if args and args[0] == '-':
1225f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        cmd = sys.stdin.read()
1226f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        enable_shell = True
1227f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # process sys.argv and sys.path:
1228969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    for i in range(len(sys.path)):
1229969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        sys.path[i] = os.path.abspath(sys.path[i])
1230f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    if args and args[0] == '-':
1231f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        sys.argv = [''] + args[1:]
1232f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    elif cmd:
1233f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        sys.argv = ['-c'] + args
1234f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    elif script:
1235f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        sys.argv = [script] + args
1236f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    elif args:
1237f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        enable_edit = True
1238f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        pathx = []
1239969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        for filename in args:
1240969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser            pathx.append(os.path.dirname(filename))
1241f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        for dir in pathx:
1242f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            dir = os.path.abspath(dir)
1243f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            if not dir in sys.path:
1244f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                sys.path.insert(0, dir)
1245ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser    else:
1246ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser        dir = os.getcwd()
1247ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser        if not dir in sys.path:
1248ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser            sys.path.insert(0, dir)
1249f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # check the IDLE settings configuration (but command line overrides)
1250f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    edit_start = idleConf.GetOption('main', 'General',
12516655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser                                    'editor-on-startup', type='bool')
1252f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    enable_edit = enable_edit or edit_start
12536655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser    enable_shell = enable_shell or not edit_start
1254f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # start editor and/or shell windows:
1255969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    root = Tk(className="Idle")
1256969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    fixwordbreaks(root)
1257969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    root.withdraw()
1258969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    flist = PyShellFileList(root)
1259f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    if enable_edit:
1260f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        if not (cmd or script):
1261f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            for filename in args:
1262f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                flist.open(filename)
1263f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            if not args:
1264f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                flist.new()
1265f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        if enable_shell:
1266f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            flist.open_shell()
1267f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    elif enable_shell:
1268f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        flist.pyshell = PyShell(flist)
1269f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        flist.pyshell.begin()
1270f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    shell = flist.pyshell
1271f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # handle remaining options:
1272f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    if debug:
1273f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        shell.open_debugger()
1274969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    if startup:
1275969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        filename = os.environ.get("IDLESTARTUP") or \
1276969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser                   os.environ.get("PYTHONSTARTUP")
1277969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if filename and os.path.isfile(filename):
1278f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            shell.interp.execfile(filename)
1279f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    if cmd or script:
1280f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        shell.interp.runcommand("""if 1:
1281f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            import sys as _sys
1282f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            _sys.argv = %s
1283f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            del _sys
1284f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            \n""" % `sys.argv`)
1285f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        if cmd:
1286f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            shell.interp.execsource(cmd)
1287f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        elif script:
128811659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            shell.interp.prepend_syspath(script)
1289f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            shell.interp.execfile(script)
1290969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    root.mainloop()
1291969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    root.destroy()
1292969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser
1293f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1294969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiserdef display_port_binding_error():
1295969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    print """\
12968f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser\nIDLE cannot run.
12971f733baa04a56eed0a5823158205fc04502e3050Steven M. Gava
12988f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. KaiserIDLE needs to use a specific TCP/IP port (8833) in order to communicate with
12998f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiserits Python execution server.  IDLE is unable to bind to this port, and so
13008f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaisercannot start. Here are some possible causes of this problem:
13011f733baa04a56eed0a5823158205fc04502e3050Steven M. Gava
13021f733baa04a56eed0a5823158205fc04502e3050Steven M. Gava  1. TCP/IP networking is not installed or not working on this computer
13038f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser  2. Another program (another IDLE?) is running that uses this port
1304969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser  3. Personal firewall software is preventing IDLE from using this port
13051f733baa04a56eed0a5823158205fc04502e3050Steven M. Gava
13068f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. KaiserRun IDLE with the -n command line switch to start without a subprocess
13078f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiserand refer to Help/IDLE Help "Running without a subprocess" for further
13088f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiserdetails.
13091f733baa04a56eed0a5823158205fc04502e3050Steven M. Gava"""
13107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
13117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererif __name__ == "__main__":
13129e8b828f07d0a55676e987b4ca70c247853f5695Kurt B. Kaiser    sys.modules['PyShell'] = sys.modules['__main__']
13137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    main()
1314