PyShell.py revision 11659ade1e63095ac6217b4e190c14b494ddcf82
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
22b693f8e4fa15c21980da9e0a90d990c35d99a8e0Tony Lownds# Preserve 2.2 compatibility for Mac OS X:
23b693f8e4fa15c21980da9e0a90d990c35d99a8e0Tony Lowndsimport boolcheck
24b693f8e4fa15c21980da9e0a90d990c35d99a8e0Tony Lownds
257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererfrom EditorWindow import EditorWindow, fixwordbreaks
267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererfrom FileList import FileList
277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererfrom ColorDelegator import ColorDelegator
287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererfrom UndoDelegator import UndoDelegator
29969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiserfrom OutputWindow import OutputWindow
309930061ce28b1fc60d267ae3474c74a41e655cd5Steven M. Gavafrom configHandler import idleConf
317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport idlever
327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
335d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teyimport rpc
347f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiserimport Debugger
35ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiserimport RemoteDebugger
365d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
37b97641994617115321719d4ecf797a461e2d5cf2Kurt B. KaiserIDENTCHARS = string.ascii_letters + string.digits + "_"
38b97641994617115321719d4ecf797a461e2d5cf2Kurt B. Kaiser
39a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaisertry:
40a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser    from signal import SIGTERM
41a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiserexcept ImportError:
42a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser    SIGTERM = 15
43a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser
445d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey# Change warnings module to write to sys.__stderr__
455d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teytry:
465d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    import warnings
475d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teyexcept ImportError:
485d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    pass
495d2af63cc36ca1141e1ec7412fc33866f3908408Chui Teyelse:
505d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    def idle_showwarning(message, category, filename, lineno):
515d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        file = sys.__stderr__
525d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        file.write(warnings.formatwarning(message, category, filename, lineno))
535d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    warnings.showwarning = idle_showwarning
545d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
55818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiserdef extended_linecache_checkcache(orig_checkcache=linecache.checkcache):
5645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    """Extend linecache.checkcache to preserve the <pyshell#...> entries
5745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
58818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiser    Rather than repeating the linecache code, patch it to save the pyshell#
59818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiser    entries, call the original linecache.checkcache(), and then restore the
60818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiser    saved entries.  Assigning the orig_checkcache keyword arg freezes its value
61818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiser    at definition time to the (original) method linecache.checkcache(), i.e.
62818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiser    makes orig_checkcache lexical.
6345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
6445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    """
657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    cache = linecache.cache
667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    save = {}
677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    for filename in cache.keys():
687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if filename[:1] + filename[-1:] == '<>':
697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            save[filename] = cache[filename]
707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    orig_checkcache()
717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    cache.update(save)
726655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
73818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiser# Patch linecache.checkcache():
74818855939ac016492cb59d1fc2fea94cc0764855Kurt B. Kaiserlinecache.checkcache = extended_linecache_checkcache
757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass PyShellEditorWindow(EditorWindow):
78ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiser    "Regular text edit window when a shell is present"
7945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def __init__(self, *args):
8145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        self.breakpoints = []
827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        apply(EditorWindow.__init__, (self,) + args)
837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.bind("<<set-breakpoint-here>>", self.set_breakpoint_here)
8445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        self.text.bind("<<clear-breakpoint-here>>", self.clear_breakpoint_here)
857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.bind("<<open-python-shell>>", self.flist.open_shell)
867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
87bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        self.breakpointPath = os.path.join(idleConf.GetUserCfgDir(),
88bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                                           'breakpoints.lst')
89a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        # whenever a file is changed, restore breakpoints
90a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        if self.io.filename: self.restore_file_breaks()
91bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        def filename_changed_hook(old_hook=self.io.filename_change_hook,
92bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                                  self=self):
93a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey            self.restore_file_breaks()
94a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey            old_hook()
95a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        self.io.set_filename_change_hook(filename_changed_hook)
96a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey
9745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    rmenu_specs = [("Set Breakpoint", "<<set-breakpoint-here>>"),
9845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                   ("Clear Breakpoint", "<<clear-breakpoint-here>>")]
997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
100a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey    def set_breakpoint(self, lineno):
10145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        text = self.text
10245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        filename = self.io.filename
103a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        text.tag_add("BREAK", "%d.0" % lineno, "%d.0" % (lineno+1))
10445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        try:
10545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            i = self.breakpoints.index(lineno)
106a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        except ValueError:  # only add if missing, i.e. do once
10745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            self.breakpoints.append(lineno)
10845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        try:    # update the subprocess debugger
10945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug = self.flist.pyshell.interp.debugger
11045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug.set_breakpoint_here(filename, lineno)
11145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        except: # but debugger may not be active right now....
11245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            pass
1137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
114a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey    def set_breakpoint_here(self, event=None):
115a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        text = self.text
116a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        filename = self.io.filename
117a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        if not filename:
118a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey            text.bell()
119a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey            return
120a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        lineno = int(float(text.index("insert")))
121a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        self.set_breakpoint(lineno)
122a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey
123669f4c3850eaaf4e00a79032ef960a79e6ca6ad7Kurt B. Kaiser    def clear_breakpoint_here(self, event=None):
12445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        text = self.text
12545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        filename = self.io.filename
12645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        if not filename:
12745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            text.bell()
128669f4c3850eaaf4e00a79032ef960a79e6ca6ad7Kurt B. Kaiser            return
12945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        lineno = int(float(text.index("insert")))
13045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        try:
13145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            self.breakpoints.remove(lineno)
13245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        except:
13345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            pass
13445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        text.tag_remove("BREAK", "insert linestart",\
13545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                        "insert lineend +1char")
13645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        try:
13745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug = self.flist.pyshell.interp.debugger
13845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug.clear_breakpoint_here(filename, lineno)
13945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        except:
14045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            pass
14145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
14245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    def clear_file_breaks(self):
14345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        if self.breakpoints:
14445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            text = self.text
14545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            filename = self.io.filename
14645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            if not filename:
14745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                text.bell()
14845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                return
14945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            self.breakpoints = []
15045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            text.tag_remove("BREAK", "1.0", END)
15145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            try:
15245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                debug = self.flist.pyshell.interp.debugger
15345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                debug.clear_file_breaks(filename)
15445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            except:
15545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser                pass
15645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
157a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey    def store_file_breaks(self):
158bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        "Save breakpoints when file is saved"
159bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        # XXX 13 Dec 2002 KBK Currently the file must be saved before it can
160bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     be run.  The breaks are saved at that time.  If we introduce
161bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     a temporary file save feature the save breaks functionality
162bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     needs to be re-verified, since the breaks at the time the
163bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     temp file is created may differ from the breaks at the last
1647f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        #     permanent save of the file.  Currently, a break introduced
1657f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        #     after a save will be effective, but not persistent.
1667f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        #     This is necessary to keep the saved breaks synched with the
1677f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        #     saved file.
168bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #
169bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     Breakpoints are set as tagged ranges in the text.  Certain
170bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     kinds of edits cause these ranges to be deleted: Inserting
171bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     or deleting a line just before a breakpoint, and certain
172bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     deletions prior to a breakpoint.  These issues need to be
173bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     investigated and understood.  It's not clear if they are
174bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     Tk issues or IDLE issues, or whether they can actually
175bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     be fixed.  Since a modified file has to be saved before it is
176bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     run, and since self.breakpoints (from which the subprocess
177bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     debugger is loaded) is updated during the save, the visible
178bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     breaks stay synched with the subprocess even if one of these
179bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        #     unexpected breakpoint deletions occurs.
180bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        breaks = self.breakpoints
181bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        filename = self.io.filename
182a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        try:
183bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            lines = open(self.breakpointPath,"r").readlines()
184a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        except IOError:
185bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            lines = []
186bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        new_file = open(self.breakpointPath,"w")
187a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        for line in lines:
188bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            if not line.startswith(filename + '='):
189a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey                new_file.write(line)
190bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        self.update_breakpoints()
191bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        breaks = self.breakpoints
192bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        if breaks:
193bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            new_file.write(filename + '=' + str(breaks) + '\n')
194a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        new_file.close()
195a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey
196a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey    def restore_file_breaks(self):
197a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        self.text.update()   # this enables setting "BREAK" tags to be visible
198bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        filename = self.io.filename
199bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        if filename is None:
200bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            return
20169371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey        if os.path.isfile(self.breakpointPath):
202bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            lines = open(self.breakpointPath,"r").readlines()
20369371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey            for line in lines:
204bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                if line.startswith(filename + '='):
2056655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser                    breakpoint_linenumbers = eval(line[len(filename)+1:])
20669371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey                    for breakpoint_linenumber in breakpoint_linenumbers:
20769371d6530cf6a14742e3d907dcbe03de06f8406Chui Tey                        self.set_breakpoint(breakpoint_linenumber)
208a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey
209bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser    def update_breakpoints(self):
210bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        "Retrieves all the breakpoints in the current window"
211a2adb0f6d99124101adbeac017b2d5623ad864baChui Tey        text = self.text
212bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        ranges = text.tag_ranges("BREAK")
213bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        linenumber_list = self.ranges_to_linenumbers(ranges)
214bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        self.breakpoints = linenumber_list
215bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser
216bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser    def ranges_to_linenumbers(self, ranges):
217bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        lines = []
218bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        for index in range(0, len(ranges), 2):
219bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            lineno = int(float(ranges[index]))
220bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            end = int(float(ranges[index+1]))
221bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser            while lineno < end:
222bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                lines.append(lineno)
223bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser                lineno += 1
224bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser        return lines
225bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser
22611220fad1d7eee24f1d9809c6d5023875099cb37Kurt B. Kaiser# XXX 13 Dec 2002 KBK Not used currently
227bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#    def saved_change_hook(self):
228bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#        "Extend base method - clear breaks if module is modified"
229bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#        if not self.get_saved():
230bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#            self.clear_file_breaks()
231bfed346259b27a51153b1f1bf5e4f062247e6246Kurt B. Kaiser#        EditorWindow.saved_change_hook(self)
23245186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
23345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    def _close(self):
23445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        "Extend base method - clear breaks when module is closed"
23545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        self.clear_file_breaks()
23645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        EditorWindow._close(self)
2376655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
2387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass PyShellFileList(FileList):
24083118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser    "Extend base class: file list when a shell is present"
2417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    EditorWindow = PyShellEditorWindow
2437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    pyshell = None
2457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def open_shell(self, event=None):
2477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.pyshell:
2487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.pyshell.wakeup()
2497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
2507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.pyshell = PyShell(self)
2517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.pyshell.begin()
2527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return self.pyshell
2537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass ModifiedColorDelegator(ColorDelegator):
25683118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser    "Extend base class: colorizer for the shell window itself"
2576655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
258b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava    def __init__(self):
259b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        ColorDelegator.__init__(self)
260b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        self.LoadTagDefs()
2617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def recolorize_main(self):
2637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tag_remove("TODO", "1.0", "iomark")
2647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tag_add("SYNC", "1.0", "iomark")
2657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        ColorDelegator.recolorize_main(self)
2666655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
267b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava    def LoadTagDefs(self):
268b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        ColorDelegator.LoadTagDefs(self)
269b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        theme = idleConf.GetOption('main','Theme','name')
270b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        self.tagdefs.update({
271b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            "stdin": {'background':None,'foreground':None},
272b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            "stdout": idleConf.GetHighlight(theme, "stdout"),
273b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            "stderr": idleConf.GetHighlight(theme, "stderr"),
274b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            "console": idleConf.GetHighlight(theme, "console"),
275b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava            None: idleConf.GetHighlight(theme, "normal"),
276b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava        })
2777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass ModifiedUndoDelegator(UndoDelegator):
27983118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser    "Extend base class: forbid insert/delete before the I/O mark"
2807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def insert(self, index, chars, tags=None):
2827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
2837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if self.delegate.compare(index, "<", "iomark"):
2847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.delegate.bell()
2857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return
2867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except TclError:
2877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            pass
2887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        UndoDelegator.insert(self, index, chars, tags)
2897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def delete(self, index1, index2=None):
2917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
2927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if self.delegate.compare(index1, "<", "iomark"):
2937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.delegate.bell()
2947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return
2957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except TclError:
2967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            pass
2977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        UndoDelegator.delete(self, index1, index2)
2987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
2997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass ModifiedInterpreter(InteractiveInterpreter):
3007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
3017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def __init__(self, tkconsole):
3027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tkconsole = tkconsole
3037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        locals = sys.modules['__main__'].__dict__
3047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        InteractiveInterpreter.__init__(self, locals=locals)
30594bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        self.save_warnings_filters = None
3067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
30763857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser    port = 8833
3085d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    rpcclt = None
3095d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    rpcpid = None
3105d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
3116655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser    def spawn_subprocess(self):
312f53dec2e4e8a017641db4de73456a2724a75e64bTony Lownds        args = self.build_subprocess_arglist()
3135d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.rpcpid = os.spawnv(os.P_NOWAIT, args[0], args)
31463857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser
315f53dec2e4e8a017641db4de73456a2724a75e64bTony Lownds    def build_subprocess_arglist(self):
3162398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        w = ['-W' + s for s in sys.warnoptions]
3172398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        # Maybe IDLE is installed and is being accessed via sys.path,
3182398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        # or maybe it's not installed and the idle.py script is being
3192398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        # run from the IDLE source directory.
3202398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        if __name__ == 'idlelib.PyShell':
3212398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds            command = "__import__('idlelib.run').run.main()"
322f2324b9e8964a7aef964ae6168827ad300f920d6Tony Lownds        else:
3232398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds            command = "__import__('run').main()"
3242398d578a367aa0f9155afb7275a5aec4e5caef9Tony Lownds        return [sys.executable] + w + ["-c", command, str(self.port)]
325f2324b9e8964a7aef964ae6168827ad300f920d6Tony Lownds
32663857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser    def start_subprocess(self):
32763857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser        addr = ("localhost", self.port)
3288dcdb77132563c734c228e815498c47e487f95cfKurt B. Kaiser        # Idle starts listening for connection on localhost
3295db4843c5e7d2b420b9ca9189b9e30669b62e55eKurt B. Kaiser        for i in range(3):
3305d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            time.sleep(i)
3315d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            try:
3325d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey                self.rpcclt = rpc.RPCClient(addr)
3335d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey                break
3345d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            except socket.error, err:
3358f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser                print>>sys.__stderr__,"IDLE socket error: " + err[1]\
336b417936d4080004b6a7811fb411c6f77db4cc262Kurt B. Kaiser                                                    + ", retrying..."
3375d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        else:
338969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser            display_port_binding_error()
339a2a3cb23defa5e17a159982adac33e3dd58d8a93Kurt B. Kaiser            sys.exit()
3405db4843c5e7d2b420b9ca9189b9e30669b62e55eKurt B. Kaiser        self.spawn_subprocess()
341b417936d4080004b6a7811fb411c6f77db4cc262Kurt B. Kaiser        # Accept the connection from the Python execution server
342b417936d4080004b6a7811fb411c6f77db4cc262Kurt B. Kaiser        self.rpcclt.accept()
343969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        self.rpcclt.register("stdin", self.tkconsole)
344969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        self.rpcclt.register("stdout", self.tkconsole.stdout)
345969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        self.rpcclt.register("stderr", self.tkconsole.stderr)
3465d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.rpcclt.register("flist", self.tkconsole.flist)
3478cd0def10dc028e3522a04bd136c67f92f90da04Kurt B. Kaiser        self.rpcclt.register("linecache", linecache)
348f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        self.transfer_path()
3495d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.poll_subprocess()
3505d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
35163857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser    def restart_subprocess(self):
35263857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser        # close only the subprocess debugger
35345186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        debug = self.getdebugger()
35445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        if debug:
355003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            try:
3569ec454ec00088e051195e80363499a14cafc131aKurt B. Kaiser                # Only close subprocess debugger, don't unregister gui_adap!
357003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser                RemoteDebugger.close_subprocess_debugger(self.rpcclt)
358003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            except:
359003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser                pass
360003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        # Kill subprocess, spawn a new one, accept connection.
361a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.rpcclt.close()
362a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.unix_terminate()
3637f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        console = self.tkconsole
3647f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        console.executing = False
36563857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser        self.spawn_subprocess()
36663857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser        self.rpcclt.accept()
367f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        self.transfer_path()
3681061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        # annotate restart in shell window and mark it
3694cc5ef5dbe12cbc9dc1a00c7583ffd0117f4c31eKurt B. Kaiser        console.text.delete("iomark", "end-1c")
3701061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        halfbar = ((int(console.width) - 16) // 2) * '='
3711061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        console.write(halfbar + ' RESTART ' + halfbar)
3721061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        console.text.mark_set("restart", "end-1c")
3731061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        console.text.mark_gravity("restart", "left")
3747f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        console.showprompt()
375003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        # restart subprocess debugger
37645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        if debug:
3779ec454ec00088e051195e80363499a14cafc131aKurt B. Kaiser            # Restarted debugger connects to current instance of debug GUI
37863857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser            gui = RemoteDebugger.restart_subprocess_debugger(self.rpcclt)
37945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            # reload remote debugger breakpoints for all PyShellEditWindows
38045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser            debug.load_breakpoints()
38145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
382003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    def __request_interrupt(self):
383a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.rpcclt.remotecall("exec", "interrupt_the_server", (), {})
384003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser
385003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    def interrupt_subprocess(self):
386a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        threading.Thread(target=self.__request_interrupt).start()
387003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser
388a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser    def kill_subprocess(self):
389a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.rpcclt.close()
390a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.unix_terminate()
391a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.tkconsole.executing = False
392a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.rpcclt = None
39311c53e2ea7f7d2a2969c98e81c1489c4e72254c4Kurt B. Kaiser
394a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser    def unix_terminate(self):
395a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        "UNIX: make sure subprocess is terminated and collect status"
396a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        if hasattr(os, 'kill'):
397a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            try:
398a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                os.kill(self.rpcpid, SIGTERM)
399a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            except OSError:
400a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                # process already terminated:
401a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                return
402a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            else:
403a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                try:
404a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                    os.waitpid(self.rpcpid, 0)
405a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                except OSError:
406a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser                    return
40711c53e2ea7f7d2a2969c98e81c1489c4e72254c4Kurt B. Kaiser
408f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    def transfer_path(self):
409f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        self.runcommand("""if 1:
410f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        import sys as _sys
411f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        _sys.path = %s
412f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        del _sys
413b2487335bf8c9258d347d96cf615d964d57f5658Kurt B. Kaiser        _msg = 'Use File/Exit or your end-of-file key to quit IDLE'
414b2487335bf8c9258d347d96cf615d964d57f5658Kurt B. Kaiser        __builtins__.quit = __builtins__.exit = _msg
415b2487335bf8c9258d347d96cf615d964d57f5658Kurt B. Kaiser        del _msg
416f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        \n""" % `sys.path`)
417f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
4185d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    active_seq = None
4195d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
4205d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    def poll_subprocess(self):
4215d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        clt = self.rpcclt
4225d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if clt is None:
4235d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            return
424003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        try:
425a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            response = clt.pollresponse(self.active_seq, wait=0.05)
426a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        except (EOFError, IOError, KeyboardInterrupt):
427a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            # lost connection or subprocess terminated itself, restart
428a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            # [the KBI is from rpc.SocketIO.handle_EOF()]
429003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            if self.tkconsole.closing:
430003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser                return
431003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            response = None
432003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            self.restart_subprocess()
433003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            self.tkconsole.endexecuting()
4345d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if response:
4355d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            self.tkconsole.resetoutput()
4365d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            self.active_seq = None
4375d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            how, what = response
438bc2861313cc53711d837a0e8a5bf303bf5291bf3Kurt B. Kaiser            console = self.tkconsole.console
4395d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            if how == "OK":
4405d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey                if what is not None:
441bc2861313cc53711d837a0e8a5bf303bf5291bf3Kurt B. Kaiser                    print >>console, `what`
4425d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            elif how == "EXCEPTION":
4435d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey                if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
4445d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey                    self.remote_stack_viewer()
4455d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            elif how == "ERROR":
4460930c43e43f79617a33a6c3be32afbe184780307Kurt B. Kaiser                errmsg = "PyShell.ModifiedInterpreter: Subprocess ERROR:\n"
4470930c43e43f79617a33a6c3be32afbe184780307Kurt B. Kaiser                print >>sys.__stderr__, errmsg, what
448bc2861313cc53711d837a0e8a5bf303bf5291bf3Kurt B. Kaiser                print >>console, errmsg, what
449bc2861313cc53711d837a0e8a5bf303bf5291bf3Kurt B. Kaiser            # we received a response to the currently active seq number:
4505d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            self.tkconsole.endexecuting()
451a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        # Reschedule myself in 50 ms
452a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        self.tkconsole.text.after(50, self.poll_subprocess)
4535d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
45445186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    debugger = None
45545186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
45645186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    def setdebugger(self, debugger):
45745186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        self.debugger = debugger
45845186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
45945186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser    def getdebugger(self):
46045186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser        return self.debugger
46145186c4ce08093d5f0d2f141f6e557e9726aedb4Kurt B. Kaiser
4625d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    def remote_stack_viewer(self):
4635d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        import RemoteObjectBrowser
464a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser        oid = self.rpcclt.remotequeue("exec", "stackviewer", ("flist",), {})
4655d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if oid is None:
4665d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            self.tkconsole.root.bell()
4675d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            return
4685d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        item = RemoteObjectBrowser.StubObjectTreeItem(self.rpcclt, oid)
4695d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        from TreeWidget import ScrolledCanvas, TreeNode
4705d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        top = Toplevel(self.tkconsole.root)
4715d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        sc = ScrolledCanvas(top, bg="white", highlightthickness=0)
4725d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        sc.frame.pack(expand=1, fill="both")
4735d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        node = TreeNode(sc.canvas, None, item)
4745d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        node.expand()
4755d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        # XXX Should GC the remote tree when closing the window
4765d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
4777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    gid = 0
4787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
4797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def execsource(self, source):
48083118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Like runsource() but assumes complete exec source"
4817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        filename = self.stuffsource(source)
4827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.execfile(filename, source)
4837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
4847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def execfile(self, filename, source=None):
48583118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Execute an existing file"
4867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if source is None:
4877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            source = open(filename, "r").read()
4887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
4897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            code = compile(source, filename, "exec")
4907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except (OverflowError, SyntaxError):
4917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.tkconsole.resetoutput()
4927f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            tkerr = self.tkconsole.stderr
4937f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            print>>tkerr, '*** Error in script or command!\n'
4947f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            print>>tkerr, 'Traceback (most recent call last):'
4957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            InteractiveInterpreter.showsyntaxerror(self, filename)
4966e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            self.tkconsole.showprompt()
4977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
4987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.runcode(code)
4997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
5007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def runsource(self, source):
50183118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Extend base class method: Stuff the source in the line cache first"
5027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        filename = self.stuffsource(source)
5037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.more = 0
50494bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        self.save_warnings_filters = warnings.filters[:]
50594bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        warnings.filterwarnings(action="error", category=SyntaxWarning)
506837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        if isinstance(source, types.UnicodeType):
507837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser            import IOBinding
508837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser            try:
509837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser                source = source.encode(IOBinding.encoding)
510837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser            except UnicodeError:
511837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser                self.tkconsole.resetoutput()
512837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser                self.write("Unsupported characters in input")
513837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser                return
51494bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        try:
51594bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser            return InteractiveInterpreter.runsource(self, source, filename)
51694bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        finally:
51794bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser            if self.save_warnings_filters is not None:
51894bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser                warnings.filters[:] = self.save_warnings_filters
51994bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser                self.save_warnings_filters = None
5207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
5217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def stuffsource(self, source):
52283118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Stuff source in the filename cache"
5237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        filename = "<pyshell#%d>" % self.gid
5247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.gid = self.gid + 1
525837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        lines = source.split("\n")
5267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        linecache.cache[filename] = len(source)+1, 0, lines, filename
5277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return filename
5286655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
52911659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser    def prepend_syspath(self, filename):
53011659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser        "Prepend sys.path with file's directory if not already included"
53111659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser        self.runcommand("""if 1:
53211659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            _filename = %s
53311659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            import sys as _sys
53411659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            from os.path import dirname as _dirname
53511659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            _dir = _dirname(_filename)
53611659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            if not _dir in _sys.path:
53711659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser                _sys.path.insert(0, _dir)
53811659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            del _filename, _sys, _dirname, _dir
53911659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            \n""" % `filename`)
54011659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser
5417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def showsyntaxerror(self, filename=None):
54283118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        """Extend base class method: Add Colorizing
54383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser
54483118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        Color the offending position instead of printing it and pointing at it
54583118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        with a caret.
54683118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser
54783118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        """
5487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text = self.tkconsole.text
5497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        stuff = self.unpackerror()
5506e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser        if stuff:
5516e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            msg, lineno, offset, line = stuff
5526e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            if lineno == 1:
5536e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser                pos = "iomark + %d chars" % (offset-1)
5546e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            else:
5556e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser                pos = "iomark linestart + %d lines + %d chars" % \
5566e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser                      (lineno-1, offset-1)
5576e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            text.tag_add("ERROR", pos)
5586e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            text.see(pos)
5596e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            char = text.get(pos)
5606e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            if char and char in IDENTCHARS:
5616e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser                text.tag_add("ERROR", pos + " wordstart", pos)
5627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.tkconsole.resetoutput()
5636e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            self.write("SyntaxError: %s\n" % str(msg))
5647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
5656e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            self.tkconsole.resetoutput()
5666e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser            InteractiveInterpreter.showsyntaxerror(self, filename)
5676e44cc236900c8f85164e543d0d3e7f429a1f1c8Kurt B. Kaiser        self.tkconsole.showprompt()
5687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
5697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def unpackerror(self):
5707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        type, value, tb = sys.exc_info()
5717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        ok = type is SyntaxError
5727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if ok:
5737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            try:
5747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                msg, (dummy_filename, lineno, offset, line) = value
5757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            except:
5767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                ok = 0
5777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if ok:
5787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return msg, lineno, offset, line
5797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
5807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return None
5817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
5827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def showtraceback(self):
58383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Extend base class method to reset output properly"
5847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tkconsole.resetoutput()
5857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.checklinecache()
5867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        InteractiveInterpreter.showtraceback(self)
5875d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.tkconsole.getvar("<<toggle-jit-stack-viewer>>"):
5885d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            self.tkconsole.open_stack_viewer()
5897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
5907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def checklinecache(self):
5917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        c = linecache.cache
5927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        for key in c.keys():
5937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if key[:1] + key[-1:] != "<>":
5947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                del c[key]
5957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
59663857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser    def display_executing_dialog(self):
59763857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser        tkMessageBox.showerror(
59863857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser            "Already executing",
59963857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser            "The Python Shell window is already executing a command; "
60063857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser            "please wait until it is finished.",
60163857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser            master=self.tkconsole.text)
6026655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
6035d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey    def runcommand(self, code):
60483118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Run the code without invoking the debugger"
6055d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        # The code better not raise an exception!
6065d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.tkconsole.executing:
607f4c4f115d80a26eb83d90593c24a1580f236c443Neal Norwitz            self.display_executing_dialog()
6085d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            return 0
6095d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.rpcclt:
610a00050f209acf2201b2382f9d534a2595bacf5c3Kurt B. Kaiser            self.rpcclt.remotequeue("exec", "runcode", (code,), {})
6115d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        else:
6125d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            exec code in self.locals
6135d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        return 1
6145d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
6157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def runcode(self, code):
61683118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Override base class method"
6175d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.tkconsole.executing:
618003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            self.interp.restart_subprocess()
6195d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.checklinecache()
62094bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser        if self.save_warnings_filters is not None:
62194bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser            warnings.filters[:] = self.save_warnings_filters
62294bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser            self.save_warnings_filters = None
6237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        debugger = self.debugger
6247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
6257f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            self.tkconsole.beginexecuting()
6267f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            try:
6277f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                if not debugger and self.rpcclt is not None:
6287f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    self.active_seq = self.rpcclt.asyncqueue("exec", "runcode",
6297f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                                                            (code,), {})
6307f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                elif debugger:
6317f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    debugger.run(code, self.locals)
6327f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                else:
6337f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    exec code in self.locals
6347f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            except SystemExit:
6357f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                if tkMessageBox.askyesno(
6367f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    "Exit?",
6377f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    "Do you want to exit altogether?",
6387f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    default="yes",
6397f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    master=self.tkconsole.text):
6407f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    raise
6417f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                else:
6427f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    self.showtraceback()
6437f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            except:
6447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.showtraceback()
6457f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        finally:
6467f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            if not use_subprocess:
6477f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                self.tkconsole.endexecuting()
6487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def write(self, s):
65083118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Override base class method"
6517f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        self.tkconsole.stderr.write(s)
6527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass PyShell(OutputWindow):
6547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    shell_title = "Python Shell"
6567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    # Override classes
6587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    ColorDelegator = ModifiedColorDelegator
6597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    UndoDelegator = ModifiedUndoDelegator
6607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
661f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # Override menus
662dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser    menu_specs = [
663dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        ("file", "_File"),
664dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        ("edit", "_Edit"),
6654cc5ef5dbe12cbc9dc1a00c7583ffd0117f4c31eKurt B. Kaiser        ("debug", "_Debug"),
6661061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        ("options", "_Options"),
667dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        ("windows", "_Windows"),
668dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        ("help", "_Help"),
669dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser    ]
6707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    # New classes
6727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    from IdleHistory import History
6737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
6747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def __init__(self, flist=None):
6758f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser        if use_subprocess:
6768f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser            self.menu_specs.insert(2, ("shell", "_Shell"))
6777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.interp = ModifiedInterpreter(self)
6787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if flist is None:
6797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            root = Tk()
6807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            fixwordbreaks(root)
6817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            root.withdraw()
6827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            flist = PyShellFileList(root)
6835afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
6847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        OutputWindow.__init__(self, flist, None, None)
6855afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
6867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        import __builtin__
6877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        __builtin__.quit = __builtin__.exit = "To exit, type Ctrl-D."
6885afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
689ee7afca550f69ace3e20d25b84432f45c246c600Kurt B. Kaiser        self.config(usetabs=1, indentwidth=8, context_use_ps1=1)
6905afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
6917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text = self.text
6927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.configure(wrap="char")
6937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<newline-and-indent>>", self.enter_callback)
6947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<plain-newline-and-indent>>", self.linefeed_callback)
6957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<interrupt-execution>>", self.cancel_callback)
6967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<beginning-of-line>>", self.home_callback)
6977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<end-of-file>>", self.eof_callback)
6987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<open-stack-viewer>>", self.open_stack_viewer)
69957bfe5dc5a4873026679fb911939beb69e35a9e8Kurt B. Kaiser        text.bind("<<toggle-debugger>>", self.toggle_debugger)
7007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<open-python-shell>>", self.flist.open_shell)
7017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        text.bind("<<toggle-jit-stack-viewer>>", self.toggle_jit_stack_viewer)
7028f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser        if use_subprocess:
7038f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser            text.bind("<<view-restart>>", self.view_restart_mark)
7048f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser            text.bind("<<restart-shell>>", self.restart_shell)
7055afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
7067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.save_stdout = sys.stdout
7077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.save_stderr = sys.stderr
7087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.save_stdin = sys.stdin
7095d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.stdout = PseudoFile(self, "stdout")
7105d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.stderr = PseudoFile(self, "stderr")
7117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.console = PseudoFile(self, "console")
7125d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if not use_subprocess:
7135d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            sys.stdout = self.stdout
7145d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            sys.stderr = self.stderr
7155d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            sys.stdin = self
7165afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
7177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.history = self.History(self.text)
7185afa1dfb72311b8360904363cc3ebb7cbfc8b6e4Kurt B. Kaiser        #
7195d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if use_subprocess:
72063857a454d85fda475264575b7c1a031970219a0Kurt B. Kaiser            self.interp.start_subprocess()
7215d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
722003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    reading = False
723003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    executing = False
724003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    canceled = False
725003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    endoffile = False
726003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    closing = False
7277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def toggle_debugger(self, event=None):
7297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.executing:
7307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            tkMessageBox.showerror("Don't debug now",
7317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                "You can only toggle the debugger when idle",
7327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                master=self.text)
7337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.set_debugger_indicator()
7347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
7357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
7367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            db = self.interp.getdebugger()
7377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if db:
7387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.close_debugger()
7397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            else:
7407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.open_debugger()
7417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def set_debugger_indicator(self):
7437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        db = self.interp.getdebugger()
7447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.setvar("<<toggle-debugger>>", not not db)
7457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7461061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser    def toggle_jit_stack_viewer(self, event=None):
7477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        pass # All we need is the variable
7487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def close_debugger(self):
7507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        db = self.interp.getdebugger()
7517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if db:
7527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.interp.setdebugger(None)
7537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            db.close()
754ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiser            if self.interp.rpcclt:
755ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiser                RemoteDebugger.close_remote_debugger(self.interp.rpcclt)
7567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.resetoutput()
7577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.console.write("[DEBUG OFF]\n")
7587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            sys.ps1 = ">>> "
7597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.showprompt()
7607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.set_debugger_indicator()
7617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def open_debugger(self):
7635d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.interp.rpcclt:
7647f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            dbg_gui = RemoteDebugger.start_remote_debugger(self.interp.rpcclt,
7657f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                                                           self)
7667f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        else:
7677f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            dbg_gui = Debugger.Debugger(self)
7687f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        self.interp.setdebugger(dbg_gui)
7697f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        dbg_gui.load_breakpoints()
7705d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        sys.ps1 = "[DEBUG ON]\n>>> "
7715d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.showprompt()
7725d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.set_debugger_indicator()
7735d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey
7747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def beginexecuting(self):
775ffd3a4217a557bad4984621c22f5ae312d708169Kurt B. Kaiser        "Helper for ModifiedInterpreter"
7767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.resetoutput()
7777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.executing = 1
7787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def endexecuting(self):
78083118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Helper for ModifiedInterpreter"
7817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.executing = 0
7827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.canceled = 0
7835d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.showprompt()
7847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
7857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def close(self):
78683118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Extend EditorWindow.close()"
7877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.executing:
788003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            response = tkMessageBox.askokcancel(
7897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                "Kill?",
790003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser                "The program is still running!\n Do you want to kill it?",
7917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                default="ok",
7927f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                parent=self.text)
793003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            if response == False:
7947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return "cancel"
795003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            # interrupt the subprocess
7967f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            self.canceled = True
7977f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            if use_subprocess:
7987f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                self.interp.interrupt_subprocess()
7997f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            return "cancel"
8007f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        else:
8017f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            return EditorWindow.close(self)
8027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def _close(self):
80483118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Extend EditorWindow._close(), shut down debugger and execution server"
8057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.close_debugger()
8067f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        if use_subprocess:
8077f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            self.interp.kill_subprocess()
8087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # Restore std streams
8097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sys.stdout = self.save_stdout
8107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sys.stderr = self.save_stderr
8117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sys.stdin = self.save_stdin
8127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # Break cycles
8137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.interp = None
8147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.console = None
8157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.flist.pyshell = None
8167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.history = None
81783118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        EditorWindow._close(self)
8187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def ispythonsource(self, filename):
82083118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser        "Override EditorWindow method: never remove the colorizer"
821837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        return True
8227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def short_title(self):
8247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return self.shell_title
8257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
82694bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser    COPYRIGHT = \
8278f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser          'Type "copyright", "credits" or "license()" for more information.'
82894bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser
8297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def begin(self):
8307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.resetoutput()
8317f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        if use_subprocess:
8327f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            nosub = ''
8337f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        else:
8347f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            nosub = "==== No Subprocess ===="
8357f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        self.write("Python %s on %s\n%s\nIDLEfork %s      %s\n" %
83694bd77415fc44ada4ceba856a81fe029c12bf313Kurt B. Kaiser                   (sys.version, sys.platform, self.COPYRIGHT,
8377f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                    idlever.IDLE_VERSION, nosub))
8387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.showprompt()
8397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        import Tkinter
8407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        Tkinter._default_root = None
8417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def interact(self):
8437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.begin()
8447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.top.mainloop()
8457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def readline(self):
8477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        save = self.reading
8487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
8497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.reading = 1
8507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.top.mainloop()
8517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        finally:
8527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.reading = save
8537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        line = self.text.get("iomark", "end-1c")
8547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.resetoutput()
8557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.canceled:
8567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.canceled = 0
8577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            raise KeyboardInterrupt
8587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.endoffile:
8597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.endoffile = 0
8607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return ""
8617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return line
8627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def isatty(self):
864837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        return True
8657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
866003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser    def cancel_callback(self, event=None):
8677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
8687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if self.text.compare("sel.first", "!=", "sel.last"):
8697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return # Active selection -- always use default binding
8707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except:
8717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            pass
8727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if not (self.executing or self.reading):
8737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.resetoutput()
8747f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            self.interp.write("KeyboardInterrupt\n")
8757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.showprompt()
8767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
8777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.endoffile = 0
878003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        self.canceled = 1
8797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.reading:
8807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.top.quit()
881003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        elif (self.executing and self.interp.rpcclt):
882003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            self.interp.interrupt_subprocess()
8837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return "break"
8847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def eof_callback(self, event):
8867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.executing and not self.reading:
8877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return # Let the default binding (delete next char) take over
8887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if not (self.text.compare("iomark", "==", "insert") and
8897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.text.compare("insert", "==", "end-1c")):
8907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return # Let the default binding (delete next char) take over
8917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if not self.executing:
8927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.resetoutput()
8937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.close()
8947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
8957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.canceled = 0
8967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.endoffile = 1
8977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.top.quit()
8987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return "break"
8997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def home_callback(self, event):
9017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if event.state != 0 and event.keysym == "Home":
9027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return # <Modifier-Home>; fall back to class binding
9037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.text.compare("iomark", "<=", "insert") and \
9047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer           self.text.compare("insert linestart", "<=", "iomark"):
9057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.mark_set("insert", "iomark")
9067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.tag_remove("sel", "1.0", "end")
9077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.see("insert")
9087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
9097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def linefeed_callback(self, event):
9117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # Insert a linefeed without entering anything (still autoindented)
9127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.reading:
9137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.insert("insert", "\n")
9147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.see("insert")
9157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
916822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser            self.newline_and_indent_event(event)
9177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return "break"
9187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def enter_callback(self, event):
9207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.executing and not self.reading:
9217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return # Let the default binding (insert '\n') take over
9227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # If some text is selected, recall the selection
9237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # (but only if this before the I/O mark)
9247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
9257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            sel = self.text.get("sel.first", "sel.last")
9267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if sel:
9277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                if self.text.compare("sel.last", "<=", "iomark"):
9287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                    self.recall(sel)
9297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                    return "break"
9307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except:
9317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            pass
9327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # If we're strictly before the line containing iomark, recall
9337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # the current line, less a leading prompt, less leading or
9347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # trailing whitespace
9357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.text.compare("insert", "<", "iomark linestart"):
9367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            # Check if there's a relevant stdin range -- if so, use it
9377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            prev = self.text.tag_prevrange("stdin", "insert")
9387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if prev and self.text.compare("insert", "<", prev[1]):
9397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.recall(self.text.get(prev[0], prev[1]))
9407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return "break"
9417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            next = self.text.tag_nextrange("stdin", "insert")
9427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if next and self.text.compare("insert lineend", ">=", next[0]):
9437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                self.recall(self.text.get(next[0], next[1]))
9447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                return "break"
9454ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser            # No stdin mark -- just get the current line, less any prompt
9464ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser            line = self.text.get("insert linestart", "insert lineend")
9474ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser            last_line_of_prompt = sys.ps1.split('\n')[-1]
9484ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser            if line.startswith(last_line_of_prompt):
9494ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser                line = line[len(last_line_of_prompt):]
9504ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser            self.recall(line)
9517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
952822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser        # If we're between the beginning of the line and the iomark, i.e.
9534ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser        # in the prompt area, move to the end of the prompt
954822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser        if self.text.compare("insert", "<", "iomark"):
9554ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser            self.text.mark_set("insert", "iomark")
9567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # If we're in the current input and there's only whitespace
9577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # beyond the cursor, erase that whitespace first
9587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        s = self.text.get("insert", "end-1c")
959837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        if s and not s.strip():
9607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.delete("insert", "end-1c")
9617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # If we're in the current input before its last line,
9627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # insert a newline right at the insert point
9637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.text.compare("insert", "<", "end-1c linestart"):
964822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser            self.newline_and_indent_event(event)
9657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return "break"
9667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # We're in the last line; append a newline and submit it
9677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.mark_set("insert", "end-1c")
9687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.reading:
9697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.insert("insert", "\n")
9707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.see("insert")
9717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
972822a77fcc761b3c9992950ddf48b3f0bec917b4dKurt B. Kaiser            self.newline_and_indent_event(event)
9737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.tag_add("stdin", "iomark", "end-1c")
9747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.update_idletasks()
9757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.reading:
9767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.top.quit() # Break out of recursive mainloop() in raw_input()
9777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        else:
9787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.runit()
9797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return "break"
9807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def recall(self, s):
9827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.history:
9837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.history.recall(s)
9847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def runit(self):
9867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        line = self.text.get("iomark", "end-1c")
9877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # Strip off last newline and surrounding whitespace.
9887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        # (To allow you to hit return twice to end a statement.)
9897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        i = len(line)
9907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        while i > 0 and line[i-1] in " \t":
9917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            i = i-1
9927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if i > 0 and line[i-1] == "\n":
9937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            i = i-1
9947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        while i > 0 and line[i-1] in " \t":
9957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            i = i-1
9967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        line = line[:i]
9977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        more = self.interp.runsource(line)
9987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
9997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def open_stack_viewer(self, event=None):
10005d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        if self.interp.rpcclt:
10015d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey            return self.interp.remote_stack_viewer()
10027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
10037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            sys.last_traceback
10047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except:
10057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            tkMessageBox.showerror("No stack trace",
10067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                "There is no stack trace yet.\n"
10077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                "(sys.last_traceback is not defined)",
10087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                master=self.text)
10097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return
10107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        from StackViewer import StackBrowser
10117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sv = StackBrowser(self.root, self.flist)
10127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10131061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser    def view_restart_mark(self, event=None):
10141061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        self.text.see("iomark")
10151061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser        self.text.see("restart")
10161061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser
10171061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser    def restart_shell(self, event=None):
10187f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        if self.executing:
10197f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            self.cancel_callback()
10207f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            # Wait for subprocess to interrupt and restart
10217f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            # This can be a long time if shell is scrolling on a slow system
10227f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            # XXX 14 May 03 KBK This delay (and one in ScriptBinding) could be
10237f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            #     shorter if we didn't print the KeyboardInterrupt on
10247f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            #     restarting while user code is running....
10257f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            self.text.after(2000, self.interp.restart_subprocess)
10267f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser        else:
10277f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            self.interp.restart_subprocess()
10281061e7270b13a0e632c5a28791a46e38b48a39a0Kurt B. Kaiser
10297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def showprompt(self):
10307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.resetoutput()
10317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
10327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            s = str(sys.ps1)
10337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except:
10347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            s = ""
10357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.console.write(s)
10367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.mark_set("insert", "end-1c")
10375d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.set_line_and_column()
1038dc1e70987f49aa23bf1d07f32c476edeba0cec30Kurt B. Kaiser        self.io.reset_undo()
10397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def resetoutput(self):
10417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        source = self.text.get("iomark", "end-1c")
10427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.history:
10437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.history.history_store(source)
10447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.text.get("end-2c") != "\n":
10457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.text.insert("end-1c", "\n")
10467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.text.mark_set("iomark", "end-1c")
10475d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.set_line_and_column()
10487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        sys.stdout.softspace = 0
10497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def write(self, s, tags=()):
1051003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        try:
1052003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            self.text.mark_gravity("iomark", "right")
1053003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            OutputWindow.write(self, s, tags, "iomark")
1054003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            self.text.mark_gravity("iomark", "left")
1055003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser        except:
1056003091cd51c5278e3ef76b6db01bd719b8b1c416Kurt B. Kaiser            pass
10577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if self.canceled:
10587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.canceled = 0
10597f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser            if not use_subprocess:
10607f38ec0849fd2b19e660350c59d42b8b5cfae2d1Kurt B. Kaiser                raise KeyboardInterrupt
10617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass PseudoFile:
10637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def __init__(self, shell, tags):
10657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.shell = shell
10667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.tags = tags
10675d2af63cc36ca1141e1ec7412fc33866f3908408Chui Tey        self.softspace = 0
10687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def write(self, s):
10707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.shell.write(s, self.tags)
10717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def writelines(self, l):
10737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        map(self.write, l)
10747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def flush(self):
10767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        pass
10777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
10787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def isatty(self):
1079837d15c5b5deee769079faa94117d8a83adb53ecKurt B. Kaiser        return True
10807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1081969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser
10827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererusage_msg = """\
10837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
108411659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. KaiserUSAGE: idle  [-deins] [-t title] [file]*
108511659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser       idle  [-dns] [-t title] (-c cmd | -r file) [arg]*
108611659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser       idle  [-dns] [-t title] - [arg]*
10876655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser
1088f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -h         print this help message and exit
10898f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser  -n         run IDLE without a subprocess (see Help/IDLE Help for details)
1090f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1091f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserThe following options will override the IDLE 'settings' configuration:
1092f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1093f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -e         open an edit window
1094f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -i         open a shell window
1095f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1096f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserThe following options imply -i and will open a shell:
1097f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1098f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -c cmd     run the command in a shell, or
1099f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -r file    run script from file
1100f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1101f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -d         enable the debugger
1102f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -s         run $IDLESTARTUP or $PYTHONSTARTUP before anything else
1103f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser  -t title   set title of shell window
1104f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1105f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserA default edit window will be bypassed when -c, -r, or - are used.
1106f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1107f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser[arg]* are passed to the command (-c) or script (-r) in sys.argv[1:].
1108f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1109f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. KaiserExamples:
11107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1111f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle
1112f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Open an edit window or shell depending on IDLE's configuration.
111396d88422373ffb32aef75157647e0575a0471c03Kurt B. Kaiser
1114f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle foo.py foobar.py
1115f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Edit the files, also open a shell if configured to start with shell.
1116f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1117f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle -est "Baz" foo.py
1118f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Run $IDLESTARTUP or $PYTHONSTARTUP, edit foo.py, and open a shell
1119f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        window with the title "Baz".
1120f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1121f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle -c "import sys; print sys.argv" "foo"
1122f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Open a shell window and run the command, passing "-c" in sys.argv[0]
1123f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        and "foo" in sys.argv[1].
1124f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1125f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiseridle -d -s -r foo.py "Hello World"
1126f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Open a shell window, run a startup script, enable the debugger, and
1127f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        run foo.py, passing "foo.py" in sys.argv[0] and "Hello World" in
1128f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        sys.argv[1].
1129f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1130f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiserecho "import sys; print sys.argv" | idle - "foobar"
1131f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        Open a shell window, run the script piped in, passing '' in sys.argv[0]
1132f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        and "foobar" in sys.argv[1].
11337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer"""
11347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1135969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiserdef main():
1136f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    global flist, root, use_subprocess
1137f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
11388f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser    use_subprocess = True
1139f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    enable_shell = False
1140f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    enable_edit = False
1141f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    debug = False
1142969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    cmd = None
1143969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    script = None
1144f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    startup = False
1145969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    try:
11464ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser        sys.ps1
11474ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser    except AttributeError:
11484ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser        sys.ps1 = '>>> '
11494ada7ad3bc9ab269189ed20e57943d9721664debKurt B. Kaiser    try:
11508f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser        opts, args = getopt.getopt(sys.argv[1:], "c:deihnr:st:")
1151969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    except getopt.error, msg:
1152969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        sys.stderr.write("Error: %s\n" % str(msg))
1153969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        sys.stderr.write(usage_msg)
1154969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        sys.exit(2)
1155969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    for o, a in opts:
1156969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-c':
1157969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser            cmd = a
1158f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1159969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-d':
1160f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            debug = True
1161f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1162969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-e':
1163f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_edit = True
1164f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        if o == '-h':
1165f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            sys.stdout.write(usage_msg)
1166f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            sys.exit()
1167f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        if o == '-i':
1168f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
11698f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser        if o == '-n':
11708f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser            use_subprocess = False
1171969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-r':
1172969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser            script = a
1173f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            if os.path.isfile(script):
1174f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                pass
1175f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            else:
1176f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                print "No script file: ", script
1177f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                sys.exit()
1178f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1179969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-s':
1180f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            startup = True
1181f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1182969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if o == '-t':
1183969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser            PyShell.shell_title = a
1184f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            enable_shell = True
1185f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    if args and args[0] == '-':
1186f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        cmd = sys.stdin.read()
1187f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        enable_shell = True
1188f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # process sys.argv and sys.path:
1189969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    for i in range(len(sys.path)):
1190969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        sys.path[i] = os.path.abspath(sys.path[i])
1191f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    if args and args[0] == '-':
1192f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        sys.argv = [''] + args[1:]
1193f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    elif cmd:
1194f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        sys.argv = ['-c'] + args
1195f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    elif script:
1196f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        sys.argv = [script] + args
1197f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    elif args:
1198f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        enable_edit = True
1199f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        pathx = []
1200969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        for filename in args:
1201969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser            pathx.append(os.path.dirname(filename))
1202f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        for dir in pathx:
1203f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            dir = os.path.abspath(dir)
1204f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            if not dir in sys.path:
1205f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                sys.path.insert(0, dir)
1206ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser    else:
1207ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser        dir = os.getcwd()
1208ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser        if not dir in sys.path:
1209ff002b93057d1ba8662caed8f9bcbb643fe66c8aKurt B. Kaiser            sys.path.insert(0, dir)
1210f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # check the IDLE settings configuration (but command line overrides)
1211f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    edit_start = idleConf.GetOption('main', 'General',
12126655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser                                    'editor-on-startup', type='bool')
1213f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    enable_edit = enable_edit or edit_start
12146655e4bc2752f1114a2e1f9a63ffd4191fa50d0dKurt B. Kaiser    enable_shell = enable_shell or not edit_start
1215f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # start editor and/or shell windows:
1216969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    root = Tk(className="Idle")
1217969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    fixwordbreaks(root)
1218969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    root.withdraw()
1219969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    flist = PyShellFileList(root)
1220f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    if enable_edit:
1221f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        if not (cmd or script):
1222f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            for filename in args:
1223f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                flist.open(filename)
1224f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            if not args:
1225f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser                flist.new()
1226f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        if enable_shell:
1227f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            flist.open_shell()
1228f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    elif enable_shell:
1229f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        flist.pyshell = PyShell(flist)
1230f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        flist.pyshell.begin()
1231f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    shell = flist.pyshell
1232f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    # handle remaining options:
1233f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    if debug:
1234f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        shell.open_debugger()
1235969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    if startup:
1236969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        filename = os.environ.get("IDLESTARTUP") or \
1237969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser                   os.environ.get("PYTHONSTARTUP")
1238969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser        if filename and os.path.isfile(filename):
1239f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            shell.interp.execfile(filename)
1240f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser    if cmd or script:
1241f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        shell.interp.runcommand("""if 1:
1242f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            import sys as _sys
1243f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            _sys.argv = %s
1244f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            del _sys
1245f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            \n""" % `sys.argv`)
1246f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        if cmd:
1247f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            shell.interp.execsource(cmd)
1248f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser        elif script:
124911659ade1e63095ac6217b4e190c14b494ddcf82Kurt B. Kaiser            shell.interp.prepend_syspath(script)
1250f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser            shell.interp.execfile(script)
1251969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    root.mainloop()
1252969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    root.destroy()
1253969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser
1254f06eed08a899e941c1e6db9b1b5fb126f9e33b85Kurt B. Kaiser
1255969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiserdef display_port_binding_error():
1256969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser    print """\
12578f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser\nIDLE cannot run.
12581f733baa04a56eed0a5823158205fc04502e3050Steven M. Gava
12598f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. KaiserIDLE needs to use a specific TCP/IP port (8833) in order to communicate with
12608f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiserits Python execution server.  IDLE is unable to bind to this port, and so
12618f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaisercannot start. Here are some possible causes of this problem:
12621f733baa04a56eed0a5823158205fc04502e3050Steven M. Gava
12631f733baa04a56eed0a5823158205fc04502e3050Steven M. Gava  1. TCP/IP networking is not installed or not working on this computer
12648f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiser  2. Another program (another IDLE?) is running that uses this port
1265969de458aa12e831942637bbcd9994b29dc86252Kurt B. Kaiser  3. Personal firewall software is preventing IDLE from using this port
12661f733baa04a56eed0a5823158205fc04502e3050Steven M. Gava
12678f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. KaiserRun IDLE with the -n command line switch to start without a subprocess
12688f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiserand refer to Help/IDLE Help "Running without a subprocess" for further
12698f570a768fcefef5e8c9f9cf1facc4f8cdc3ef3fKurt B. Kaiserdetails.
12701f733baa04a56eed0a5823158205fc04502e3050Steven M. Gava"""
12717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
12727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererif __name__ == "__main__":
12737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    main()
1274