Example #1
0
def zoom_height(top):
    geom = top.wm_geometry()
    m = re.match(r"(\d+)x(\d+)\+(-?\d+)\+(-?\d+)", geom)
    if not m:
        top.bell()
        return
    width, height, x, y = map(int, m.groups())
    newheight = top.winfo_screenheight()
    if sys.platform == 'win32':
        newy = 0
        newheight = newheight - 72

    elif macosxSupport.runningAsOSXApp():
        # The '88' below is a magic number that avoids placing the bottom
        # of the window below the panel on my machine. I don't know how
        # to calculate the correct value for this with tkinter.
        newy = 22
        newheight = newheight - newy - 88

    else:
        #newy = 24
        newy = 0
        #newheight = newheight - 96
        newheight = newheight - 88
    if height >= newheight:
        newgeom = ""
    else:
        newgeom = "%dx%d+%d+%d" % (width, newheight, x, newy)
    top.wm_geometry(newgeom)
Example #2
0
def zoom_height(top):
    geom = top.wm_geometry()
    m = re.match(r"(\d+)x(\d+)\+(-?\d+)\+(-?\d+)", geom)
    if not m:
        top.bell()
        return
    width, height, x, y = map(int, m.groups())
    newheight = top.winfo_screenheight()
    if sys.platform == 'win32':
        newy = 0
        newheight = newheight - 72

    elif macosxSupport.runningAsOSXApp():
        # The '88' below is a magic number that avoids placing the bottom
        # of the window below the panel on my machine. I don't know how
        # to calculate the correct value for this with tkinter.
        newy = 22
        newheight = newheight - newy - 88

    else:
        #newy = 24
        newy = 0
        #newheight = newheight - 96
        newheight = newheight - 88
    if height >= newheight:
        newgeom = ""
    else:
        newgeom = "%dx%d+%d+%d" % (width, newheight, x, newy)
    top.wm_geometry(newgeom)
 def __init__(self, editwin):
     self.editwin = editwin
     self.flist = self.editwin.flist
     self.root = self.editwin.root
     if macosxSupport.runningAsOSXApp():
         self.editwin.text_frame.bind('<<run-module-event-2>>',
                                      self._run_module_event)
Example #4
0
    def delay(self):
        e = self.editwin
        m = e.rmenu_specs
        try:
            # This functionality in OutputWindow.py
            # requires the cursor to leave the input area in the shell.
            # IDLE should not do that.
            m.remove(('Go to file/line', '<<goto-file-line>>'))

        except:
            pass

        text = self.text
        if macosxSupport.runningAsOSXApp():
            # Some OS X systems have only one mouse button,
            # so use control-click for pulldown menus there.
            #  (Note, AquaTk defines <2> as the right button if
            #   present and the Tk Text widget already binds <2>.)
            text.bind("<Control-Button-1>", self.right_menu_event)
        else:
            # Elsewhere, use right-click for pulldown menus.
            text.bind("<3>", self.right_menu_event)

        bmenu = [None]  # breakpoint options
        for i in m:
            if 'breakpoint' in i[0].lower():
                bmenu.append(i)
            else:
                self.rmenu_specs.append(i)

        self.rmenu_specs.extend(bmenu)

        self.make_rmenu()
Example #5
0
    def delay(self):
        e = self.editwin
        m = e.rmenu_specs
        try:
            # This functionality in OutputWindow.py
            # requires the cursor to leave the input area in the shell.
            # IDLE should not do that.
            m.remove(('Go to file/line', '<<goto-file-line>>'))

        except:
            pass

        text = self.text
        if macosxSupport.runningAsOSXApp():
            # Some OS X systems have only one mouse button,
            # so use control-click for pulldown menus there.
            #  (Note, AquaTk defines <2> as the right button if
            #   present and the Tk Text widget already binds <2>.)
            text.bind("<Control-Button-1>",self.right_menu_event)
        else:
            # Elsewhere, use right-click for pulldown menus.
            text.bind("<3>",self.right_menu_event)


        bmenu = [None]  # breakpoint options
        for i in m:
            if 'breakpoint' in i[0].lower():
                bmenu.append(i)
            else:
                self.rmenu_specs.append(i)

        self.rmenu_specs.extend(bmenu)


        self.make_rmenu()
Example #6
0
def main(runme=None):
    global flist, root, use_subprocess

    use_subprocess = True
    enable_shell = False
    enable_edit = False
    debug = False
    cmd = None
    script = None
    startup = False
    enable_shell = True

    args = []

    if runme!=None:
        script = runme
        if os.path.isfile(script):
            pass
        else:
            print("Script not found: ", script)
            script = None
    
    use_subprocess = False # ehh?
    PyShell.shell_title = "durp"

    if script:
        sys.argv = [script] + args
        
    # start editor and/or shell windows:
    root = Tk(className="Idle")

    fixwordbreaks(root)
    root.withdraw()
    flist = PyShellFileList(root)
    macosxSupport.setupApp(root, flist)

    if enable_shell:
        shell = flist.open_shell()
        if not shell:
            return # couldn't open shell
        if macosxSupport.runningAsOSXApp() and flist.dict:
            # On OSX: when the user has double-clicked on a file that causes
            # IDLE to be launched the shell window will open just in front of
            # the file she wants to see. Lower the interpreter window when
            # there are open files.
            shell.top.lower()

    shell = flist.pyshell
    # handle remaining options:
    if script:
        shell.interp.runcommand("""if 1:
            import sys as _sys
            _sys.argv = %r
            del _sys
            \n""" % (sys.argv,))
        shell.interp.prepend_syspath(script)
        shell.interp.execfile(script)
    root.mainloop()
    root.destroy()
Example #7
0
    def __init__(self, editwin):
        self.editwin = editwin
        # Provide instance variables referenced by Debugger
        # XXX This should be done differently
        self.flist = self.editwin.flist
        self.root = self.editwin.root

        if macosxSupport.runningAsOSXApp():
            self.editwin.text_frame.bind('<<run-module-event-2>>', self._run_module_event)
    def GetCurrentKeySet(self):
        result = self.GetKeySet(self.CurrentKeys())
        if macosxSupport.runningAsOSXApp():
            for k, v in result.items():
                v2 = [x.replace('<Alt-', '<Option-') for x in v]
                if v != v2:
                    result[k] = v2

        return result
 def set_status_bar(self):
     self.status_bar = self.MultiStatusBar(self.top)
     if macosxSupport.runningAsOSXApp():
         self.status_bar.set_label('_padding1', '    ', side=RIGHT)
     self.status_bar.set_label('column', 'Col: ?', side=RIGHT)
     self.status_bar.set_label('line', 'Ln: ?', side=RIGHT)
     self.status_bar.pack(side=BOTTOM, fill=X)
     self.text.bind('<<set-line-and-column>>', self.set_line_and_column)
     self.text.event_add('<<set-line-and-column>>', '<KeyRelease>', '<ButtonRelease>')
     self.text.after_idle(self.set_line_and_column)
Example #10
0
 def __init__(self, master, flist, gui):
     if macosxSupport.runningAsOSXApp():
         # At least on with the stock AquaTk version on OSX 10.4 you'll
         # get an shaking GUI that eventually kills IDLE if the width
         # argument is specified.
         ScrolledList.__init__(self, master)
     else:
         ScrolledList.__init__(self, master, width=80)
     self.flist = flist
     self.gui = gui
     self.stack = []
Example #11
0
 def __init__(self, master, flist, gui):
     if macosxSupport.runningAsOSXApp():
         # At least on with the stock AquaTk version on OSX 10.4 you'll
         # get an shaking GUI that eventually kills IDLE if the width
         # argument is specified.
         ScrolledList.__init__(self, master)
     else:
         ScrolledList.__init__(self, master, width=80)
     self.flist = flist
     self.gui = gui
     self.stack = []
Example #12
0
    def createmenubar(self):
        mbar = self.menubar
        self.menudict = menudict = {}
        for name, label in self.menu_specs:
            underline, label = EditorWindow.prepstr(label)
            menudict[name] = menu = Menu(mbar, name=name)
            mbar.add_cascade(label=label, menu=menu, underline=underline)

        if macosxSupport.runningAsOSXApp():
            # Insert the application menu
            menudict['application'] = menu = Menu(mbar, name='apple')
            mbar.add_cascade(label='IDLE', menu=menu)
Example #13
0
    def createmenubar(self):
        mbar = self.menubar
        self.menudict = menudict = {}
        for name, label in self.menu_specs:
            underline, label = EditorWindow.prepstr(label)
            menudict[name] = menu = Menu(mbar, name=name)
            mbar.add_cascade(label=label, menu=menu, underline=underline)

        if macosxSupport.runningAsOSXApp():
            # Insert the application menu
            menudict['application'] = menu = Menu(mbar, name='apple')
            mbar.add_cascade(label='IDLE', menu=menu)
Example #14
0
 def run_module_event(self, event):
     if macosxSupport.runningAsOSXApp():
         # Tk-Cocoa in MacOSX is broken until at least
         # Tk 8.5.9, and without this rather
         # crude workaround IDLE would hang when a user
         # tries to run a module using the keyboard shortcut
         # (the menu item works fine).
         self.editwin.text_frame.after(200,
             lambda: self.editwin.text_frame.event_generate('<<run-module-event-2>>'))
         return 'break'
     else:
         return self._run_module_event(event)
Example #15
0
    def GetCurrentKeySet(self):
        result = self.GetKeySet(self.CurrentKeys())

        if macosxSupport.runningAsOSXApp():
            # We're using AquaTk, replace all keybingings that use the
            # Alt key by ones that use the Option key because the former
            # don't work reliably.
            for k, v in result.items():
                v2 = [ x.replace('<Alt-', '<Option-') for x in v ]
                if v != v2:
                    result[k] = v2

        return result
    def GetCurrentKeySet(self):
        result = self.GetKeySet(self.CurrentKeys())

        if macosxSupport.runningAsOSXApp():
            # We're using AquaTk, replace all keybingings that use the
            # Alt key by ones that use the Option key because the former
            # don't work reliably.
            for k, v in result.items():
                v2 = [x.replace('<Alt-', '<Option-') for x in v]
                if v != v2:
                    result[k] = v2

        return result
Example #17
0
 def SetModifiersForPlatform(self):
     """Determine list of names of key modifiers for this platform.
     
     The names are used to build Tk bindings -- it doesn't matter if the
     keyboard has these keys, it matters if Tk understands them. The
     order is also important: key binding equality depends on it, so
     config-keys.def must use the same ordering.
     """
     from idlelib import macosxSupport
     if macosxSupport.runningAsOSXApp():
         self.modifiers = ['Shift', 'Control', 'Option', 'Command']
     else:
         self.modifiers = ['Control', 'Alt', 'Shift']
     self.modifier_label = {'Control': 'Ctrl'}
Example #18
0
    def SetModifiersForPlatform(self):
        """Determine list of names of key modifiers for this platform.

        The names are used to build Tk bindings -- it doesn't matter if the
        keyboard has these keys, it matters if Tk understands them. The
        order is also important: key binding equality depends on it, so
        config-keys.def must use the same ordering.
        """
        from idlelib import macosxSupport
        if macosxSupport.runningAsOSXApp():
            self.modifiers = ['Shift', 'Control', 'Option', 'Command']
        else:
            self.modifiers = ['Control', 'Alt', 'Shift']
        self.modifier_label = {'Control': 'Ctrl'} # short name
Example #19
0
def initialise():
    import sys
    global menudefs
    global default_keydefs

    if menudefs is not None:
        return

    menudefs = [
     # underscore prefixes character to underscore
     #('file', [
     #           ]),
     ('edit', [
       ('_Undo', '<<undo>>'),
       ('_Redo', '<<redo>>'),
       None,
       ('Cu_t', '<<cut>>'),
       ('_Copy', '<<copy>>'),
       ('_Paste', '<<paste>>'),
       ('Select _All', '<<select-all>>'),
       None,
       ('_Find...', '<<find>>'),
       ('Find A_gain', '<<find-again>>'),
       ('Find _Selection', '<<find-selection>>'),
       ('Find in Files...', '<<find-in-files>>'),
       ('R_eplace...', '<<replace>>'),
       ('Go to _Line', '<<goto-line>>'),
      ]),
    ('format', [
       ('_Indent Region', '<<indent-region>>'),
       ('_Dedent Region', '<<dedent-region>>'),
       ('Comment _Out Region', '<<comment-region>>'),
       ('U_ncomment Region', '<<uncomment-region>>'),
       ('Tabify Region', '<<tabify-region>>'),
       ('Untabify Region', '<<untabify-region>>'),
       ('Toggle Tabs', '<<toggle-tabs>>'),
       ('New Indent Width', '<<change-indentwidth>>'),
       ]),
    ]

    if macosxSupport.runningAsOSXApp():
        # Running as a proper MacOS application bundle. This block restructures
        # the menus a little to make them conform better to the HIG.

        quitItem = menudefs[0][1][-1]
        closeItem = menudefs[0][1][-2]


    default_keydefs = idleConf.GetCurrentKeySet()
Example #20
0
def macosx_workaround():
    # restore "Options" menu on MacOSX
    if not macosxSupport.runningAsOSXApp():
        return

    def restore(menu_specs):
        c = [a for a,b in menu_specs]
        if "options" not in c:
            menu_specs.insert(-2, ("options", "Options"))

    import idlelib.EditorWindow
    restore(idlelib.EditorWindow.EditorWindow.menu_specs)

    import idlelib.PyShell
    restore(idlelib.PyShell.PyShell.menu_specs)
Example #21
0
def macosx_workaround():
    # restore "Options" menu on MacOSX
    if not macosxSupport.runningAsOSXApp():
        return

    def restore(menu_specs):
        c = [a for a,b in menu_specs]
        if "options" not in c:
            menu_specs.insert(-2, ("options", "Options"))

    import idlelib.EditorWindow
    restore(idlelib.EditorWindow.EditorWindow.menu_specs)

    import idlelib.PyShell
    restore(idlelib.PyShell.PyShell.menu_specs)
Example #22
0
def initialise():
    import sys
    global menudefs
    global default_keydefs

    if menudefs is not None:
        return

    menudefs = [
        # underscore prefixes character to underscore
        #('file', [
        #           ]),
        ('edit', [
            ('_Undo', '<<undo>>'),
            ('_Redo', '<<redo>>'),
            None,
            ('Cu_t', '<<cut>>'),
            ('_Copy', '<<copy>>'),
            ('_Paste', '<<paste>>'),
            ('Select _All', '<<select-all>>'),
            None,
            ('_Find...', '<<find>>'),
            ('Find A_gain', '<<find-again>>'),
            ('Find _Selection', '<<find-selection>>'),
            ('Find in Files...', '<<find-in-files>>'),
            ('R_eplace...', '<<replace>>'),
            ('Go to _Line', '<<goto-line>>'),
        ]),
        ('format', [
            ('_Indent Region', '<<indent-region>>'),
            ('_Dedent Region', '<<dedent-region>>'),
            ('Comment _Out Region', '<<comment-region>>'),
            ('U_ncomment Region', '<<uncomment-region>>'),
            ('Tabify Region', '<<tabify-region>>'),
            ('Untabify Region', '<<untabify-region>>'),
            ('Toggle Tabs', '<<toggle-tabs>>'),
            ('New Indent Width', '<<change-indentwidth>>'),
        ]),
    ]

    if macosxSupport.runningAsOSXApp():
        # Running as a proper MacOS application bundle. This block restructures
        # the menus a little to make them conform better to the HIG.

        quitItem = menudefs[0][1][-1]
        closeItem = menudefs[0][1][-2]

    default_keydefs = idleConf.GetCurrentKeySet()
def get_accelerator(keydefs, eventname):
    keylist = keydefs.get(eventname)
    if not keylist or macosxSupport.runningAsOSXApp() and eventname in {
     '<<open-module>>',
     '<<goto-line>>',
     '<<change-indentwidth>>'}:
        return ''
    s = keylist[0]
    s = re.sub('-[a-z]\\b', lambda m: m.group().upper(), s)
    s = re.sub('\\b\\w+\\b', lambda m: keynames.get(m.group(), m.group()), s)
    s = re.sub('Key-', '', s)
    s = re.sub('Cancel', 'Ctrl-Break', s)
    s = re.sub('Control-', 'Ctrl-', s)
    s = re.sub('-', '+', s)
    s = re.sub('><', ' ', s)
    s = re.sub('<', '', s)
    s = re.sub('>', '', s)
    return s
Example #24
0
def zoom_height(top):
    geom = top.wm_geometry()
    m = re.match('(\\d+)x(\\d+)\\+(-?\\d+)\\+(-?\\d+)', geom)
    if not m:
        top.bell()
        return
    width, height, x, y = map(int, m.groups())
    newheight = top.winfo_screenheight()
    if sys.platform == 'win32':
        newy = 0
        newheight = newheight - 72
    elif macosxSupport.runningAsOSXApp():
        newy = 22
        newheight = newheight - newy - 88
    else:
        newy = 0
        newheight = newheight - 88
    if height >= newheight:
        newgeom = ''
    else:
        newgeom = '%dx%d+%d+%d' % (width, newheight, x, newy)
    top.wm_geometry(newgeom)
Example #25
0
class PyShell(OutputWindow):
    shell_title = 'Python Shell'
    ColorDelegator = ModifiedColorDelegator
    UndoDelegator = ModifiedUndoDelegator
    menu_specs = [
     ('file', '_File'),
     ('edit', '_Edit'),
     ('debug', '_Debug'),
     ('options', '_Options'),
     ('windows', '_Windows'),
     ('help', '_Help')]
    if macosxSupport.runningAsOSXApp():
        del menu_specs[-3]
        menu_specs[-2] = ('windows', '_Window')
    from idlelib.IdleHistory import History

    def __init__(self, flist=None):
        if use_subprocess:
            ms = self.menu_specs
            if ms[2][0] != 'shell':
                ms.insert(2, ('shell', 'She_ll'))
        self.interp = ModifiedInterpreter(self)
        if flist is None:
            root = Tk()
            fixwordbreaks(root)
            root.withdraw()
            flist = PyShellFileList(root)
        OutputWindow.__init__(self, flist, None, None)
        self.usetabs = True
        self.indentwidth = 8
        self.context_use_ps1 = True
        text = self.text
        text.configure(wrap='char')
        text.bind('<<newline-and-indent>>', self.enter_callback)
        text.bind('<<plain-newline-and-indent>>', self.linefeed_callback)
        text.bind('<<interrupt-execution>>', self.cancel_callback)
        text.bind('<<end-of-file>>', self.eof_callback)
        text.bind('<<open-stack-viewer>>', self.open_stack_viewer)
        text.bind('<<toggle-debugger>>', self.toggle_debugger)
        text.bind('<<toggle-jit-stack-viewer>>', self.toggle_jit_stack_viewer)
        if use_subprocess:
            text.bind('<<view-restart>>', self.view_restart_mark)
            text.bind('<<restart-shell>>', self.restart_shell)
        self.save_stdout = sys.stdout
        self.save_stderr = sys.stderr
        self.save_stdin = sys.stdin
        from idlelib import IOBinding
        self.stdout = PseudoFile(self, 'stdout', IOBinding.encoding)
        self.stderr = PseudoFile(self, 'stderr', IOBinding.encoding)
        self.console = PseudoFile(self, 'console', IOBinding.encoding)
        if not use_subprocess:
            sys.stdout = self.stdout
            sys.stderr = self.stderr
            sys.stdin = self
        self.history = self.History(self.text)
        self.pollinterval = 50
        return

    def get_standard_extension_names(self):
        return idleConf.GetExtensions(shell_only=True)

    reading = False
    executing = False
    canceled = False
    endoffile = False
    closing = False

    def set_warning_stream(self, stream):
        global warning_stream
        warning_stream = stream

    def get_warning_stream(self):
        return warning_stream

    def toggle_debugger(self, event=None):
        if self.executing:
            tkMessageBox.showerror("Don't debug now", 'You can only toggle the debugger when idle', master=self.text)
            self.set_debugger_indicator()
            return 'break'
        db = self.interp.getdebugger()
        if db:
            self.close_debugger()
        else:
            self.open_debugger()

    def set_debugger_indicator(self):
        db = self.interp.getdebugger()
        self.setvar('<<toggle-debugger>>', not not db)

    def toggle_jit_stack_viewer(self, event=None):
        pass

    def close_debugger(self):
        db = self.interp.getdebugger()
        if db:
            self.interp.setdebugger(None)
            db.close()
            if self.interp.rpcclt:
                RemoteDebugger.close_remote_debugger(self.interp.rpcclt)
            self.resetoutput()
            self.console.write('[DEBUG OFF]\n')
            sys.ps1 = '>>> '
            self.showprompt()
        self.set_debugger_indicator()
        return

    def open_debugger(self):
        if self.interp.rpcclt:
            dbg_gui = RemoteDebugger.start_remote_debugger(self.interp.rpcclt, self)
        else:
            dbg_gui = Debugger.Debugger(self)
        self.interp.setdebugger(dbg_gui)
        dbg_gui.load_breakpoints()
        sys.ps1 = '[DEBUG ON]\n>>> '
        self.showprompt()
        self.set_debugger_indicator()

    def beginexecuting(self):
        """Helper for ModifiedInterpreter"""
        self.resetoutput()
        self.executing = 1

    def endexecuting(self):
        """Helper for ModifiedInterpreter"""
        self.executing = 0
        self.canceled = 0
        self.showprompt()

    def close(self):
        """Extend EditorWindow.close()"""
        if self.executing:
            response = tkMessageBox.askokcancel('Kill?', 'The program is still running!\n Do you want to kill it?', default='ok', parent=self.text)
            if response is False:
                return 'cancel'
        if self.reading:
            self.top.quit()
        self.canceled = True
        self.closing = True
        self.text.after(2 * self.pollinterval, self.close2)

    def close2(self):
        return EditorWindow.close(self)

    def _close(self):
        """Extend EditorWindow._close(), shut down debugger and execution server"""
        self.close_debugger()
        if use_subprocess:
            self.interp.kill_subprocess()
        sys.stdout = self.save_stdout
        sys.stderr = self.save_stderr
        sys.stdin = self.save_stdin
        self.interp = None
        self.console = None
        self.flist.pyshell = None
        self.history = None
        EditorWindow._close(self)
        return

    def ispythonsource(self, filename):
        """Override EditorWindow method: never remove the colorizer"""
        return True

    def short_title(self):
        return self.shell_title

    COPYRIGHT = 'Type "copyright", "credits" or "license()" for more information.'

    def begin(self):
        self.resetoutput()
        if use_subprocess:
            nosub = ''
            client = self.interp.start_subprocess()
            if not client:
                self.close()
                return False
        else:
            nosub = '==== No Subprocess ===='
        self.write('Python %s on %s\n%s\n%s' % (
         sys.version, sys.platform, self.COPYRIGHT, nosub))
        self.showprompt()
        import Tkinter
        Tkinter._default_root = None
        return True

    def readline(self):
        save = self.reading
        try:
            self.reading = 1
            self.top.mainloop()
        finally:
            self.reading = save

        line = self.text.get('iomark', 'end-1c')
        if len(line) == 0:
            line = '\n'
        if isinstance(line, unicode):
            from idlelib import IOBinding
            try:
                line = line.encode(IOBinding.encoding)
            except UnicodeError:
                pass

        self.resetoutput()
        if self.canceled:
            self.canceled = 0
            if not use_subprocess:
                raise KeyboardInterrupt
        if self.endoffile:
            self.endoffile = 0
            line = ''
        return line

    def isatty(self):
        return True

    def cancel_callback(self, event=None):
        try:
            if self.text.compare('sel.first', '!=', 'sel.last'):
                return
        except:
            pass

        if not (self.executing or self.reading):
            self.resetoutput()
            self.interp.write('KeyboardInterrupt\n')
            self.showprompt()
            return 'break'
        self.endoffile = 0
        self.canceled = 1
        if self.executing and self.interp.rpcclt:
            if self.interp.getdebugger():
                self.interp.restart_subprocess()
            else:
                self.interp.interrupt_subprocess()
        if self.reading:
            self.top.quit()
        return 'break'

    def eof_callback(self, event):
        if self.executing and not self.reading:
            return
        if not (self.text.compare('iomark', '==', 'insert') and self.text.compare('insert', '==', 'end-1c')):
            return
        if not self.executing:
            self.resetoutput()
            self.close()
        else:
            self.canceled = 0
            self.endoffile = 1
            self.top.quit()
        return 'break'

    def linefeed_callback(self, event):
        if self.reading:
            self.text.insert('insert', '\n')
            self.text.see('insert')
        else:
            self.newline_and_indent_event(event)
        return 'break'

    def enter_callback(self, event):
        if self.executing and not self.reading:
            return
        try:
            sel = self.text.get('sel.first', 'sel.last')
            if sel:
                if self.text.compare('sel.last', '<=', 'iomark'):
                    self.recall(sel, event)
                    return 'break'
        except:
            pass

        if self.text.compare('insert', '<', 'iomark linestart'):
            prev = self.text.tag_prevrange('stdin', 'insert')
            if prev and self.text.compare('insert', '<', prev[1]):
                self.recall(self.text.get(prev[0], prev[1]), event)
                return 'break'
            next = self.text.tag_nextrange('stdin', 'insert')
            if next and self.text.compare('insert lineend', '>=', next[0]):
                self.recall(self.text.get(next[0], next[1]), event)
                return 'break'
            indices = self.text.tag_nextrange('console', 'insert linestart')
            if indices and self.text.compare(indices[0], '<=', 'insert linestart'):
                self.recall(self.text.get(indices[1], 'insert lineend'), event)
            else:
                self.recall(self.text.get('insert linestart', 'insert lineend'), event)
            return 'break'
        if self.text.compare('insert', '<', 'iomark'):
            self.text.mark_set('insert', 'iomark')
        s = self.text.get('insert', 'end-1c')
        if s and not s.strip():
            self.text.delete('insert', 'end-1c')
        if self.text.compare('insert', '<', 'end-1c linestart'):
            self.newline_and_indent_event(event)
            return 'break'
        self.text.mark_set('insert', 'end-1c')
        if self.reading:
            self.text.insert('insert', '\n')
            self.text.see('insert')
        else:
            self.newline_and_indent_event(event)
        self.text.tag_add('stdin', 'iomark', 'end-1c')
        self.text.update_idletasks()
        if self.reading:
            self.top.quit()
        else:
            self.runit()
        return 'break'

    def recall(self, s, event):
        s = re.sub('^\\s*\\n', '', s)
        s = re.sub('\\n\\s*$', '', s)
        lines = s.split('\n')
        self.text.undo_block_start()
        try:
            self.text.tag_remove('sel', '1.0', 'end')
            self.text.mark_set('insert', 'end-1c')
            prefix = self.text.get('insert linestart', 'insert')
            if prefix.rstrip().endswith(':'):
                self.newline_and_indent_event(event)
                prefix = self.text.get('insert linestart', 'insert')
            self.text.insert('insert', lines[0].strip())
            if len(lines) > 1:
                orig_base_indent = re.search('^([ \\t]*)', lines[0]).group(0)
                new_base_indent = re.search('^([ \\t]*)', prefix).group(0)
                for line in lines[1:]:
                    if line.startswith(orig_base_indent):
                        line = new_base_indent + line[len(orig_base_indent):]
                    self.text.insert('insert', '\n' + line.rstrip())

        finally:
            self.text.see('insert')
            self.text.undo_block_stop()

    def runit(self):
        line = self.text.get('iomark', 'end-1c')
        i = len(line)
        while i > 0 and line[i - 1] in ' \t':
            i = i - 1

        if i > 0 and line[i - 1] == '\n':
            i = i - 1
        while i > 0 and line[i - 1] in ' \t':
            i = i - 1

        line = line[:i]
        more = self.interp.runsource(line)

    def open_stack_viewer(self, event=None):
        if self.interp.rpcclt:
            return self.interp.remote_stack_viewer()
        try:
            sys.last_traceback
        except:
            tkMessageBox.showerror('No stack trace', 'There is no stack trace yet.\n(sys.last_traceback is not defined)', master=self.text)
            return

        from idlelib.StackViewer import StackBrowser
        sv = StackBrowser(self.root, self.flist)

    def view_restart_mark(self, event=None):
        self.text.see('iomark')
        self.text.see('restart')

    def restart_shell(self, event=None):
        self.interp.restart_subprocess()

    def showprompt(self):
        self.resetoutput()
        try:
            s = str(sys.ps1)
        except:
            s = ''

        self.console.write(s)
        self.text.mark_set('insert', 'end-1c')
        self.set_line_and_column()
        self.io.reset_undo()

    def resetoutput(self):
        source = self.text.get('iomark', 'end-1c')
        if self.history:
            self.history.history_store(source)
        if self.text.get('end-2c') != '\n':
            self.text.insert('end-1c', '\n')
        self.text.mark_set('iomark', 'end-1c')
        self.set_line_and_column()
        sys.stdout.softspace = 0

    def write(self, s, tags=()):
        try:
            self.text.mark_gravity('iomark', 'right')
            OutputWindow.write(self, s, tags, 'iomark')
            self.text.mark_gravity('iomark', 'left')
        except:
            pass

        if self.canceled:
            self.canceled = 0
            if not use_subprocess:
                raise KeyboardInterrupt
Example #26
0
    root.withdraw()
    flist = PyShellFileList(root)
    macosxSupport.setupApp(root, flist)

    if enable_edit:
        if not (cmd or script):
            for filename in args:
                flist.open(filename)
            if not args:
                flist.new()
    if enable_shell:
        shell = flist.open_shell()
        if not shell:
            return  # couldn't open shell

        if macosxSupport.runningAsOSXApp() and flist.dict:
            # On OSX: when the user has double-clicked on a file that causes
            # IDLE to be launched the shell window will open just in front of
            # the file she wants to see. Lower the interpreter window when
            # there are open files.
            shell.top.lower()

    shell = flist.pyshell
    # handle remaining options:
    if debug:
        shell.open_debugger()
    if startup:
        filename = os.environ.get("IDLESTARTUP") or os.environ.get("PYTHONSTARTUP")
        if filename and os.path.isfile(filename):
            shell.interp.execfile(filename)
    if shell and cmd or script:
Example #27
0
MC_MOTION = 17
MC_MOUSEWHEEL = 18
MC_PROPERTY = 19
MC_REPARENT = 20
MC_UNMAP = 21
MC_VISIBILITY = 22
# the modifier state constants, which define the meaning of mc_state
MC_SHIFT = 1 << 0
MC_CONTROL = 1 << 2
MC_ALT = 1 << 3
MC_META = 1 << 5
MC_OPTION = 1 << 6
MC_COMMAND = 1 << 7

# define the list of modifiers, to be used in complex event types.
if macosxSupport.runningAsOSXApp():
    _modifiers = (("Shift", ), ("Control", ), ("Option", ), ("Command", ))
    _modifier_masks = (MC_SHIFT, MC_CONTROL, MC_OPTION, MC_COMMAND)
else:
    _modifiers = (("Control", ), ("Alt", ), ("Shift", ), ("Meta", "M"))
    _modifier_masks = (MC_CONTROL, MC_ALT, MC_SHIFT, MC_META)

# a dictionary to map a modifier name into its number
_modifier_names = dict([(name, number) for number in range(len(_modifiers))
                        for name in _modifiers[number]])

# A binder is a class which binds functions to one type of event. It has two
# methods: bind and unbind, which get a function and a parsed sequence, as
# returned by _parse_sequence(). There are two types of binders:
# _SimpleBinder handles event types with no modifiers and no detail.
# No Python functions are called when no events are binded.
    def __init__(self, flist=None, filename=None, key=None, root=None):
        if EditorWindow.help_url is None:
            dochome = os.path.join(sys.prefix, 'Doc', 'index.html')
            if sys.platform.count('linux'):
                pyver = 'python-docs-' + '%s.%s.%s' % sys.version_info[:3]
                if os.path.isdir('/var/www/html/python/'):
                    dochome = '/var/www/html/python/index.html'
                else:
                    basepath = '/usr/share/doc/'
                    dochome = os.path.join(basepath, pyver, 'Doc', 'index.html')
            elif sys.platform[:3] == 'win':
                chmfile = os.path.join(sys.prefix, 'Doc', 'Python%s.chm' % _sphinx_version())
                if os.path.isfile(chmfile):
                    dochome = chmfile
            elif macosxSupport.runningAsOSXApp():
                dochome = os.path.join(sys.prefix, 'Resources/English.lproj/Documentation/index.html')
            dochome = os.path.normpath(dochome)
            if os.path.isfile(dochome):
                EditorWindow.help_url = dochome
                if sys.platform == 'darwin':
                    EditorWindow.help_url = 'file://' + EditorWindow.help_url
            else:
                EditorWindow.help_url = 'http://docs.python.org/%d.%d' % sys.version_info[:2]
        currentTheme = idleConf.CurrentTheme()
        self.flist = flist
        root = root or flist.root
        self.root = root
        try:
            sys.ps1
        except AttributeError:
            sys.ps1 = '>>> '

        self.menubar = Menu(root)
        self.top = top = WindowList.ListedToplevel(root, menu=self.menubar)
        if flist:
            self.tkinter_vars = flist.vars
            self.top.instance_dict = flist.inversedict
        else:
            self.tkinter_vars = {}
            self.top.instance_dict = {}
        self.recent_files_path = os.path.join(idleConf.GetUserCfgDir(), 'recent-files.lst')
        self.text_frame = text_frame = Frame(top)
        self.vbar = vbar = Scrollbar(text_frame, name='vbar')
        self.width = idleConf.GetOption('main', 'EditorWindow', 'width')
        text_options = {'name': 'text',
           'padx': 5,
           'wrap': 'none',
           'width': self.width,
           'height': idleConf.GetOption('main', 'EditorWindow', 'height')
           }
        if TkVersion >= 8.5:
            text_options['tabstyle'] = 'wordprocessor'
        self.text = text = MultiCallCreator(Text)(text_frame, **text_options)
        self.top.focused_widget = self.text
        self.createmenubar()
        self.apply_bindings()
        self.top.protocol('WM_DELETE_WINDOW', self.close)
        self.top.bind('<<close-window>>', self.close_event)
        if macosxSupport.runningAsOSXApp():
            text.bind('<<close-window>>', self.close_event)
            text.bind('<Control-Button-1>', self.right_menu_event)
        else:
            text.bind('<3>', self.right_menu_event)
        text.bind('<<cut>>', self.cut)
        text.bind('<<copy>>', self.copy)
        text.bind('<<paste>>', self.paste)
        text.bind('<<center-insert>>', self.center_insert_event)
        text.bind('<<help>>', self.help_dialog)
        text.bind('<<python-docs>>', self.python_docs)
        text.bind('<<about-idle>>', self.about_dialog)
        text.bind('<<open-config-dialog>>', self.config_dialog)
        text.bind('<<open-module>>', self.open_module)
        text.bind('<<do-nothing>>', lambda event: 'break')
        text.bind('<<select-all>>', self.select_all)
        text.bind('<<remove-selection>>', self.remove_selection)
        text.bind('<<find>>', self.find_event)
        text.bind('<<find-again>>', self.find_again_event)
        text.bind('<<find-in-files>>', self.find_in_files_event)
        text.bind('<<find-selection>>', self.find_selection_event)
        text.bind('<<replace>>', self.replace_event)
        text.bind('<<goto-line>>', self.goto_line_event)
        text.bind('<<smart-backspace>>', self.smart_backspace_event)
        text.bind('<<newline-and-indent>>', self.newline_and_indent_event)
        text.bind('<<smart-indent>>', self.smart_indent_event)
        text.bind('<<indent-region>>', self.indent_region_event)
        text.bind('<<dedent-region>>', self.dedent_region_event)
        text.bind('<<comment-region>>', self.comment_region_event)
        text.bind('<<uncomment-region>>', self.uncomment_region_event)
        text.bind('<<tabify-region>>', self.tabify_region_event)
        text.bind('<<untabify-region>>', self.untabify_region_event)
        text.bind('<<toggle-tabs>>', self.toggle_tabs_event)
        text.bind('<<change-indentwidth>>', self.change_indentwidth_event)
        text.bind('<Left>', self.move_at_edge_if_selection(0))
        text.bind('<Right>', self.move_at_edge_if_selection(1))
        text.bind('<<del-word-left>>', self.del_word_left)
        text.bind('<<del-word-right>>', self.del_word_right)
        text.bind('<<beginning-of-line>>', self.home_callback)
        if flist:
            flist.inversedict[self] = key
            if key:
                flist.dict[key] = self
            text.bind('<<open-new-window>>', self.new_callback)
            text.bind('<<close-all-windows>>', self.flist.close_all_callback)
            text.bind('<<open-class-browser>>', self.open_class_browser)
            text.bind('<<open-path-browser>>', self.open_path_browser)
        self.set_status_bar()
        vbar['command'] = text.yview
        vbar.pack(side=RIGHT, fill=Y)
        text['yscrollcommand'] = vbar.set
        fontWeight = 'normal'
        if idleConf.GetOption('main', 'EditorWindow', 'font-bold', type='bool'):
            fontWeight = 'bold'
        text.config(font=(idleConf.GetOption('main', 'EditorWindow', 'font'),
         idleConf.GetOption('main', 'EditorWindow', 'font-size'),
         fontWeight))
        text_frame.pack(side=LEFT, fill=BOTH, expand=1)
        text.pack(side=TOP, fill=BOTH, expand=1)
        text.focus_set()
        usespaces = idleConf.GetOption('main', 'Indent', 'use-spaces', type='bool')
        self.usetabs = not usespaces
        self.tabwidth = 8
        self.indentwidth = self.tabwidth
        self.set_notabs_indentwidth()
        self.context_use_ps1 = False
        self.num_context_lines = (50, 500, 5000000)
        self.per = per = self.Percolator(text)
        self.undo = undo = self.UndoDelegator()
        per.insertfilter(undo)
        text.undo_block_start = undo.undo_block_start
        text.undo_block_stop = undo.undo_block_stop
        undo.set_saved_change_hook(self.saved_change_hook)
        self.io = io = self.IOBinding(self)
        io.set_filename_change_hook(self.filename_change_hook)
        self.recent_files_menu = Menu(self.menubar)
        self.menudict['file'].insert_cascade(3, label='Recent Files', underline=0, menu=self.recent_files_menu)
        self.update_recent_files_list()
        self.color = None
        if filename:
            if os.path.exists(filename) and not os.path.isdir(filename):
                io.loadfile(filename)
            else:
                io.set_filename(filename)
        self.ResetColorizer()
        self.saved_change_hook()
        self.set_indentation_params(self.ispythonsource(filename))
        self.load_extensions()
        menu = self.menudict.get('windows')
        if menu:
            end = menu.index('end')
            if end is None:
                end = -1
            if end >= 0:
                menu.add_separator()
                end = end + 1
            self.wmenu_end = end
            WindowList.register_callback(self.postwindowsmenu)
        self.askyesno = tkMessageBox.askyesno
        self.askinteger = tkSimpleDialog.askinteger
        self.showerror = tkMessageBox.showerror
        return
class PyShell(OutputWindow):

    shell_title = "Python Shell"

    # Override classes
    ColorDelegator = ModifiedColorDelegator
    UndoDelegator = ModifiedUndoDelegator

    # Override menus
    menu_specs = [
        ("file", "_File"),
        ("edit", "_Edit"),
        ("debug", "_Debug"),
        ("options", "_Options"),
        ("windows", "_Windows"),
        ("help", "_Help"),
    ]

    if macosxSupport.runningAsOSXApp():
        del menu_specs[-3]
        menu_specs[-2] = ("windows", "_Window")


    # New classes
    from idlelib.IdleHistory import History

    def __init__(self, flist=None):
        if use_subprocess:
            ms = self.menu_specs
            if ms[2][0] != "shell":
                ms.insert(2, ("shell", "She_ll"))
        self.interp = ModifiedInterpreter(self)
        if flist is None:
            root = Tk()
            fixwordbreaks(root)
            root.withdraw()
            flist = PyShellFileList(root)
        #
        OutputWindow.__init__(self, flist, None, None)
        #
##        self.config(usetabs=1, indentwidth=8, context_use_ps1=1)
        self.usetabs = True
        # indentwidth must be 8 when using tabs.  See note in EditorWindow:
        self.indentwidth = 8
        self.context_use_ps1 = True
        #
        text = self.text
        text.configure(wrap="char")
        text.bind("<<newline-and-indent>>", self.enter_callback)
        text.bind("<<plain-newline-and-indent>>", self.linefeed_callback)
        text.bind("<<interrupt-execution>>", self.cancel_callback)
        text.bind("<<end-of-file>>", self.eof_callback)
        text.bind("<<open-stack-viewer>>", self.open_stack_viewer)
        text.bind("<<toggle-debugger>>", self.toggle_debugger)
        text.bind("<<toggle-jit-stack-viewer>>", self.toggle_jit_stack_viewer)
        self.color = color = self.ColorDelegator()
        self.per.insertfilter(color)
        if use_subprocess:
            text.bind("<<view-restart>>", self.view_restart_mark)
            text.bind("<<restart-shell>>", self.restart_shell)
        #
        self.save_stdout = sys.stdout
        self.save_stderr = sys.stderr
        self.save_stdin = sys.stdin
        from idlelib import IOBinding
        self.stdout = PseudoFile(self, "stdout", IOBinding.encoding)
        self.stderr = PseudoFile(self, "stderr", IOBinding.encoding)
        self.console = PseudoFile(self, "console", IOBinding.encoding)
        if not use_subprocess:
            sys.stdout = self.stdout
            sys.stderr = self.stderr
            sys.stdin = self
        try:
            # page help() text to shell.
            import pydoc # import must be done here to capture i/o rebinding.
            # XXX KBK 27Dec07 use a textView someday, but must work w/o subproc
            pydoc.pager = pydoc.plainpager
        except:
            sys.stderr = sys.__stderr__
            raise
        #
        self.history = self.History(self.text)
        #
        self.pollinterval = 50  # millisec

    def get_standard_extension_names(self):
        return idleConf.GetExtensions(shell_only=True)

    reading = False
    executing = False
    canceled = False
    endoffile = False
    closing = False

    def set_warning_stream(self, stream):
        global warning_stream
        warning_stream = stream

    def get_warning_stream(self):
        return warning_stream

    def toggle_debugger(self, event=None):
        if self.executing:
            tkMessageBox.showerror("Don't debug now",
                "You can only toggle the debugger when idle",
                master=self.text)
            self.set_debugger_indicator()
            return "break"
        else:
            db = self.interp.getdebugger()
            if db:
                self.close_debugger()
            else:
                self.open_debugger()

    def set_debugger_indicator(self):
        db = self.interp.getdebugger()
        self.setvar("<<toggle-debugger>>", not not db)

    def toggle_jit_stack_viewer(self, event=None):
        pass # All we need is the variable

    def close_debugger(self):
        db = self.interp.getdebugger()
        if db:
            self.interp.setdebugger(None)
            db.close()
            if self.interp.rpcclt:
                RemoteDebugger.close_remote_debugger(self.interp.rpcclt)
            self.resetoutput()
            self.console.write("[DEBUG OFF]\n")
            sys.ps1 = ">>> "
            self.showprompt()
        self.set_debugger_indicator()

    def open_debugger(self):
        if self.interp.rpcclt:
            dbg_gui = RemoteDebugger.start_remote_debugger(self.interp.rpcclt,
                                                           self)
        else:
            dbg_gui = Debugger.Debugger(self)
        self.interp.setdebugger(dbg_gui)
        dbg_gui.load_breakpoints()
        sys.ps1 = "[DEBUG ON]\n>>> "
        self.showprompt()
        self.set_debugger_indicator()

    def beginexecuting(self):
        "Helper for ModifiedInterpreter"
        self.resetoutput()
        self.executing = 1

    def endexecuting(self):
        "Helper for ModifiedInterpreter"
        self.executing = 0
        self.canceled = 0
        self.showprompt()

    def close(self):
        "Extend EditorWindow.close()"
        if self.executing:
            response = tkMessageBox.askokcancel(
                "Kill?",
                "The program is still running!\n Do you want to kill it?",
                default="ok",
                parent=self.text)
            if response is False:
                return "cancel"
        if self.reading:
            self.top.quit()
        self.canceled = True
        self.closing = True
        # Wait for poll_subprocess() rescheduling to stop
        self.text.after(2 * self.pollinterval, self.close2)

    def close2(self):
        return EditorWindow.close(self)

    def _close(self):
        "Extend EditorWindow._close(), shut down debugger and execution server"
        self.close_debugger()
        if use_subprocess:
            self.interp.kill_subprocess()
        # Restore std streams
        sys.stdout = self.save_stdout
        sys.stderr = self.save_stderr
        sys.stdin = self.save_stdin
        # Break cycles
        self.interp = None
        self.console = None
        self.flist.pyshell = None
        self.history = None
        EditorWindow._close(self)

    def ispythonsource(self, filename):
        "Override EditorWindow method: never remove the colorizer"
        return True

    def short_title(self):
        return self.shell_title

    COPYRIGHT = \
          'Type "copyright", "credits" or "license()" for more information.'

    def begin(self):
        self.text.mark_set("iomark", "insert")
        self.resetoutput()
        if use_subprocess:
            nosub = ''
            client = self.interp.start_subprocess()
            if not client:
                self.close()
                return False
        else:
            nosub = "==== No Subprocess ===="
        self.write("Python %s on %s\n%s\n%s" %
                   (sys.version, sys.platform, self.COPYRIGHT, nosub))
        self.showprompt()
        import tkinter
        tkinter._default_root = None # 03Jan04 KBK What's this?
        return True

    def readline(self):
        save = self.reading
        try:
            self.reading = 1
            self.top.mainloop()  # nested mainloop()
        finally:
            self.reading = save
        line = self.text.get("iomark", "end-1c")
        if len(line) == 0:  # may be EOF if we quit our mainloop with Ctrl-C
            line = "\n"
        self.resetoutput()
        if self.canceled:
            self.canceled = 0
            if not use_subprocess:
                raise KeyboardInterrupt
        if self.endoffile:
            self.endoffile = 0
            line = ""
        return line

    def isatty(self):
        return True

    def cancel_callback(self, event=None):
        try:
            if self.text.compare("sel.first", "!=", "sel.last"):
                return # Active selection -- always use default binding
        except:
            pass
        if not (self.executing or self.reading):
            self.resetoutput()
            self.interp.write("KeyboardInterrupt\n")
            self.showprompt()
            return "break"
        self.endoffile = 0
        self.canceled = 1
        if (self.executing and self.interp.rpcclt):
            if self.interp.getdebugger():
                self.interp.restart_subprocess()
            else:
                self.interp.interrupt_subprocess()
        if self.reading:
            self.top.quit()  # exit the nested mainloop() in readline()
        return "break"

    def eof_callback(self, event):
        if self.executing and not self.reading:
            return # Let the default binding (delete next char) take over
        if not (self.text.compare("iomark", "==", "insert") and
                self.text.compare("insert", "==", "end-1c")):
            return # Let the default binding (delete next char) take over
        if not self.executing:
            self.resetoutput()
            self.close()
        else:
            self.canceled = 0
            self.endoffile = 1
            self.top.quit()
        return "break"

    def linefeed_callback(self, event):
        # Insert a linefeed without entering anything (still autoindented)
        if self.reading:
            self.text.insert("insert", "\n")
            self.text.see("insert")
        else:
            self.newline_and_indent_event(event)
        return "break"

    def enter_callback(self, event):
        if self.executing and not self.reading:
            return # Let the default binding (insert '\n') take over
        # If some text is selected, recall the selection
        # (but only if this before the I/O mark)
        try:
            sel = self.text.get("sel.first", "sel.last")
            if sel:
                if self.text.compare("sel.last", "<=", "iomark"):
                    self.recall(sel, event)
                    return "break"
        except:
            pass
        # If we're strictly before the line containing iomark, recall
        # the current line, less a leading prompt, less leading or
        # trailing whitespace
        if self.text.compare("insert", "<", "iomark linestart"):
            # Check if there's a relevant stdin range -- if so, use it
            prev = self.text.tag_prevrange("stdin", "insert")
            if prev and self.text.compare("insert", "<", prev[1]):
                self.recall(self.text.get(prev[0], prev[1]), event)
                return "break"
            next = self.text.tag_nextrange("stdin", "insert")
            if next and self.text.compare("insert lineend", ">=", next[0]):
                self.recall(self.text.get(next[0], next[1]), event)
                return "break"
            # No stdin mark -- just get the current line, less any prompt
            indices = self.text.tag_nextrange("console", "insert linestart")
            if indices and \
               self.text.compare(indices[0], "<=", "insert linestart"):
                self.recall(self.text.get(indices[1], "insert lineend"), event)
            else:
                self.recall(self.text.get("insert linestart", "insert lineend"), event)
            return "break"
        # If we're between the beginning of the line and the iomark, i.e.
        # in the prompt area, move to the end of the prompt
        if self.text.compare("insert", "<", "iomark"):
            self.text.mark_set("insert", "iomark")
        # If we're in the current input and there's only whitespace
        # beyond the cursor, erase that whitespace first
        s = self.text.get("insert", "end-1c")
        if s and not s.strip():
            self.text.delete("insert", "end-1c")
        # If we're in the current input before its last line,
        # insert a newline right at the insert point
        if self.text.compare("insert", "<", "end-1c linestart"):
            self.newline_and_indent_event(event)
            return "break"
        # We're in the last line; append a newline and submit it
        self.text.mark_set("insert", "end-1c")
        if self.reading:
            self.text.insert("insert", "\n")
            self.text.see("insert")
        else:
            self.newline_and_indent_event(event)
        self.text.tag_add("stdin", "iomark", "end-1c")
        self.text.update_idletasks()
        if self.reading:
            self.top.quit() # Break out of recursive mainloop()
        else:
            self.runit()
        return "break"

    def recall(self, s, event):
        # remove leading and trailing empty or whitespace lines
        s = re.sub(r'^\s*\n', '' , s)
        s = re.sub(r'\n\s*$', '', s)
        lines = s.split('\n')
        self.text.undo_block_start()
        try:
            self.text.tag_remove("sel", "1.0", "end")
            self.text.mark_set("insert", "end-1c")
            prefix = self.text.get("insert linestart", "insert")
            if prefix.rstrip().endswith(':'):
                self.newline_and_indent_event(event)
                prefix = self.text.get("insert linestart", "insert")
            self.text.insert("insert", lines[0].strip())
            if len(lines) > 1:
                orig_base_indent = re.search(r'^([ \t]*)', lines[0]).group(0)
                new_base_indent  = re.search(r'^([ \t]*)', prefix).group(0)
                for line in lines[1:]:
                    if line.startswith(orig_base_indent):
                        # replace orig base indentation with new indentation
                        line = new_base_indent + line[len(orig_base_indent):]
                    self.text.insert('insert', '\n'+line.rstrip())
        finally:
            self.text.see("insert")
            self.text.undo_block_stop()

    def runit(self):
        line = self.text.get("iomark", "end-1c")
        # Strip off last newline and surrounding whitespace.
        # (To allow you to hit return twice to end a statement.)
        i = len(line)
        while i > 0 and line[i-1] in " \t":
            i = i-1
        if i > 0 and line[i-1] == "\n":
            i = i-1
        while i > 0 and line[i-1] in " \t":
            i = i-1
        line = line[:i]
        more = self.interp.runsource(line)

    def open_stack_viewer(self, event=None):
        if self.interp.rpcclt:
            return self.interp.remote_stack_viewer()
        try:
            sys.last_traceback
        except:
            tkMessageBox.showerror("No stack trace",
                "There is no stack trace yet.\n"
                "(sys.last_traceback is not defined)",
                master=self.text)
            return
        from idlelib.StackViewer import StackBrowser
        sv = StackBrowser(self.root, self.flist)

    def view_restart_mark(self, event=None):
        self.text.see("iomark")
        self.text.see("restart")

    def restart_shell(self, event=None):
        self.interp.restart_subprocess()

    def showprompt(self):
        self.resetoutput()
        try:
            s = str(sys.ps1)
        except:
            s = ""
        self.console.write(s)
        self.text.mark_set("insert", "end-1c")
        self.set_line_and_column()
        self.io.reset_undo()

    def resetoutput(self):
        source = self.text.get("iomark", "end-1c")
        if self.history:
            self.history.history_store(source)
        if self.text.get("end-2c") != "\n":
            self.text.insert("end-1c", "\n")
        self.text.mark_set("iomark", "end-1c")
        self.set_line_and_column()

    def write(self, s, tags=()):
        try:
            self.text.mark_gravity("iomark", "right")
            OutputWindow.write(self, s, tags, "iomark")
            self.text.mark_gravity("iomark", "left")
        except:
            raise ###pass  # ### 11Aug07 KBK if we are expecting exceptions
                           # let's find out what they are and be specific.
        if self.canceled:
            self.canceled = 0
            if not use_subprocess:
                raise KeyboardInterrupt
Example #30
0
            from os.path import basename as _basename
            if (not _sys.argv or
                _basename(_sys.argv[0]) != _basename(_filename)):
                _sys.argv = [_filename]
            import os as _os
            _os.chdir(%r)
            del _filename, _sys, _basename, _os
            \n""" % (filename, dirname))
        interp.prepend_syspath(filename)
        # XXX KBK 03Jul04 When run w/o subprocess, runtime warnings still
        #         go to __stderr__.  With subprocess, they go to the shell.
        #         Need to change streams in PyShell.ModifiedInterpreter.
        interp.runcode(code)
        return 'break'

    if macosxSupport.runningAsOSXApp():
        # Tk-Cocoa in MacOSX is broken until at least
        # Tk 8.5.9, and without this rather
        # crude workaround IDLE would hang when a user
        # tries to run a module using the keyboard shortcut
        # (the menu item works fine).
        _run_module_event = run_module_event

        def run_module_event(self, event):
            self.editwin.text_frame.after(200,
                lambda: self.editwin.text_frame.event_generate('<<run-module-event-2>>'))
            return 'break'

    def getfilename(self):
        """Get source filename.  If not saved, offer to save (or create) file
Example #31
0
    flist = idlelib.PyShell.PyShellFileList(root)
    macosxSupport.setupApp(root, flist)

    if enable_edit:
        if not (cmd or script):
            for filename in args:
                flist.open(filename)
            if not args:
                window_handle=flist.new()
                unique_id=str(uuid.uuid1())
    if enable_shell:
        shell = flist.open_shell()
        if not shell:
            return # couldn't open shell

        if macosxSupport.runningAsOSXApp() and flist.dict:
            # On OSX: when the user has double-clicked on a file that causes
            # IDLE to be launched the shell window will open just in front of
            # the file she wants to see. Lower the interpreter window when
            # there are open files.
            shell.top.lower()

    shell = flist.pyshell
    # handle remaining options:
    if debug:
        shell.open_debugger()
    if startup:
        filename = os.environ.get("IDLESTARTUP") or \
                   os.environ.get("PYTHONSTARTUP")
        if filename and os.path.isfile(filename):
            shell.interp.execfile(filename)
Example #32
0
def main():
    global root
    global flist
    global use_subprocess
    use_subprocess = True
    enable_shell = True
    enable_edit = False
    debug = False
    cmd = None
    script = None
    startup = False
    try:
        opts, args = getopt.getopt(sys.argv[1:], 'c:deihnr:st:')
    except getopt.error as msg:
        sys.stderr.write('Error: %s\n' % str(msg))
        sys.stderr.write(usage_msg)
        sys.exit(2)

    for o, a in opts:
        if o == '-c':
            cmd = a
            enable_shell = True
        if o == '-d':
            debug = True
            enable_shell = True
        if o == '-e':
            enable_edit = True
            enable_shell = False
        if o == '-h':
            sys.stdout.write(usage_msg)
            sys.exit()
        if o == '-i':
            enable_shell = True
        if o == '-n':
            use_subprocess = False
        if o == '-r':
            script = a
            if os.path.isfile(script):
                pass
            else:
                print 'No script file: ', script
                sys.exit()
            enable_shell = True
        if o == '-s':
            startup = True
            enable_shell = True
        if o == '-t':
            PyShell.shell_title = a
            enable_shell = True

    if args and args[0] == '-':
        cmd = sys.stdin.read()
        enable_shell = True
    for i in range(len(sys.path)):
        sys.path[i] = os.path.abspath(sys.path[i])

    if args and args[0] == '-':
        sys.argv = [
         ''] + args[1:]
    elif cmd:
        sys.argv = [
         '-c'] + args
    elif script:
        sys.argv = [
         script] + args
    elif args:
        enable_edit = True
        pathx = []
        for filename in args:
            pathx.append(os.path.dirname(filename))

        for dir in pathx:
            dir = os.path.abspath(dir)
            if dir not in sys.path:
                sys.path.insert(0, dir)

    else:
        dir = os.getcwd()
        if dir not in sys.path:
            sys.path.insert(0, dir)
    edit_start = idleConf.GetOption('main', 'General', 'editor-on-startup', type='bool')
    enable_edit = enable_edit or edit_start
    root = Tk(className='Idle')
    fixwordbreaks(root)
    root.withdraw()
    flist = PyShellFileList(root)
    macosxSupport.setupApp(root, flist)
    if enable_edit:
        if not (cmd or script):
            for filename in args:
                flist.open(filename)

            if not args:
                flist.new()
    if enable_shell:
        shell = flist.open_shell()
        if not shell:
            return
        if macosxSupport.runningAsOSXApp() and flist.dict:
            shell.top.lower()
    shell = flist.pyshell
    if debug:
        shell.open_debugger()
    if startup:
        filename = os.environ.get('IDLESTARTUP') or os.environ.get('PYTHONSTARTUP')
        if filename and os.path.isfile(filename):
            shell.interp.execfile(filename)
    if shell and cmd or script:
        shell.interp.runcommand('if 1:\n            import sys as _sys\n            _sys.argv = %r\n            del _sys\n            \n' % (sys.argv,))
        if cmd:
            shell.interp.execsource(cmd)
        elif script:
            shell.interp.prepend_syspath(script)
            shell.interp.execfile(script)
    tkversionwarning = macosxSupport.tkVersionWarning(root)
    if tkversionwarning:
        shell.interp.runcommand(''.join(("print('", tkversionwarning, "')")))
    root.mainloop()
    root.destroy()
    return
def main():
    global flist, root, use_subprocess

    use_subprocess = True
    enable_shell = False
    enable_edit = False
    debug = False
    cmd = None
    script = None
    startup = False
    try:
        opts, args = getopt.getopt(sys.argv[1:], "c:deihnr:st:")
    except getopt.error as msg:
        sys.stderr.write("Error: %s\n" % str(msg))
        sys.stderr.write(usage_msg)
        sys.exit(2)
    for o, a in opts:
        if o == '-c':
            cmd = a
            enable_shell = True
        if o == '-d':
            debug = True
            enable_shell = True
        if o == '-e':
            enable_edit = True
        if o == '-h':
            sys.stdout.write(usage_msg)
            sys.exit()
        if o == '-i':
            enable_shell = True
        if o == '-n':
            use_subprocess = False
        if o == '-r':
            script = a
            if os.path.isfile(script):
                pass
            else:
                print("No script file: ", script)
                sys.exit()
            enable_shell = True
        if o == '-s':
            startup = True
            enable_shell = True
        if o == '-t':
            PyShell.shell_title = a
            enable_shell = True
    if args and args[0] == '-':
        cmd = sys.stdin.read()
        enable_shell = True
    # process sys.argv and sys.path:
    for i in range(len(sys.path)):
        sys.path[i] = os.path.abspath(sys.path[i])
    if args and args[0] == '-':
        sys.argv = [''] + args[1:]
    elif cmd:
        sys.argv = ['-c'] + args
    elif script:
        sys.argv = [script] + args
    elif args:
        enable_edit = True
        pathx = []
        for filename in args:
            pathx.append(os.path.dirname(filename))
        for dir in pathx:
            dir = os.path.abspath(dir)
            if not dir in sys.path:
                sys.path.insert(0, dir)
    else:
        dir = os.getcwd()
        if dir not in sys.path:
            sys.path.insert(0, dir)
    # check the IDLE settings configuration (but command line overrides)
    edit_start = idleConf.GetOption('main', 'General',
                                    'editor-on-startup', type='bool')
    enable_edit = enable_edit or edit_start
    enable_shell = enable_shell or not edit_start
    # start editor and/or shell windows:
    root = Tk(className="Idle")

    fixwordbreaks(root)
    root.withdraw()
    flist = PyShellFileList(root)
    macosxSupport.setupApp(root, flist)

    if enable_edit:
        if not (cmd or script):
            for filename in args:
                flist.open(filename)
            if not args:
                flist.new()
    if enable_shell:
        shell = flist.open_shell()
        if not shell:
            return # couldn't open shell

        if macosxSupport.runningAsOSXApp() and flist.dict:
            # On OSX: when the user has double-clicked on a file that causes
            # IDLE to be launched the shell window will open just in front of
            # the file she wants to see. Lower the interpreter window when
            # there are open files.
            shell.top.lower()

    shell = flist.pyshell
    # handle remaining options:
    if debug:
        shell.open_debugger()
    if startup:
        filename = os.environ.get("IDLESTARTUP") or \
                   os.environ.get("PYTHONSTARTUP")
        if filename and os.path.isfile(filename):
            shell.interp.execfile(filename)
    if shell and cmd or script:
        shell.interp.runcommand("""if 1:
            import sys as _sys
            _sys.argv = %r
            del _sys
            \n""" % (sys.argv,))
        if cmd:
            shell.interp.execsource(cmd)
        elif script:
            shell.interp.prepend_syspath(script)
            shell.interp.execfile(script)

    root.mainloop()
    root.destroy()
class ScriptBinding:
    menudefs = [('run', [
        None, ('Check Module', '<<check-module>>'),
        ('Run Module', '<<run-module>>')
    ])]

    def __init__(self, editwin):
        self.editwin = editwin
        self.flist = self.editwin.flist
        self.root = self.editwin.root
        if macosxSupport.runningAsOSXApp():
            self.editwin.text_frame.bind('<<run-module-event-2>>',
                                         self._run_module_event)

    def check_module_event(self, event):
        filename = self.getfilename()
        if not filename:
            return 'break'
        if not self.checksyntax(filename):
            return 'break'
        if not self.tabnanny(filename):
            return 'break'

    def tabnanny(self, filename):
        f = open(filename, 'r')
        try:
            tabnanny.process_tokens(tokenize.generate_tokens(f.readline))
        except tokenize.TokenError as msg:
            msgtxt, (lineno, start) = msg
            self.editwin.gotoline(lineno)
            self.errorbox('Tabnanny Tokenizing Error',
                          'Token Error: %s' % msgtxt)
            return False
        except tabnanny.NannyNag as nag:
            self.editwin.gotoline(nag.get_lineno())
            self.errorbox('Tab/space error', indent_message)
            return False

        return True

    def checksyntax(self, filename):
        self.shell = shell = self.flist.open_shell()
        saved_stream = shell.get_warning_stream()
        shell.set_warning_stream(shell.stderr)
        f = open(filename, 'r')
        source = f.read()
        f.close()
        if '\r' in source:
            source = re.sub('\\r\\n', '\n', source)
            source = re.sub('\\r', '\n', source)
        if source and source[-1] != '\n':
            source = source + '\n'
        text = self.editwin.text
        text.tag_remove('ERROR', '1.0', 'end')
        try:
            try:
                return compile(source, filename, 'exec')
            except (SyntaxError, OverflowError) as err:
                try:
                    msg, (errorfilename, lineno, offset, line) = err
                    if not errorfilename:
                        err.args = (msg, (filename, lineno, offset, line))
                        err.filename = filename
                    self.colorize_syntax_error(msg, lineno, offset)
                except:
                    msg = '*** ' + str(err)

                self.errorbox('Syntax error',
                              "There's an error in your program:\n" + msg)
                return False

        finally:
            shell.set_warning_stream(saved_stream)

    def colorize_syntax_error(self, msg, lineno, offset):
        text = self.editwin.text
        pos = '0.0 + %d lines + %d chars' % (lineno - 1, offset - 1)
        text.tag_add('ERROR', pos)
        char = text.get(pos)
        if char and char in IDENTCHARS:
            text.tag_add('ERROR', pos + ' wordstart', pos)
        if '\n' == text.get(pos):
            text.mark_set('insert', pos)
        else:
            text.mark_set('insert', pos + '+1c')
        text.see(pos)

    def run_module_event(self, event):
        """Run the module after setting up the environment.
        
        First check the syntax.  If OK, make sure the shell is active and
        then transfer the arguments, set the run environment's working
        directory to the directory of the module being executed and also
        add that directory to its sys.path if not already included.
        
        """
        filename = self.getfilename()
        if not filename:
            return 'break'
        code = self.checksyntax(filename)
        if not code:
            return 'break'
        if not self.tabnanny(filename):
            return 'break'
        shell = self.shell
        interp = shell.interp
        if PyShell.use_subprocess:
            shell.restart_shell()
        dirname = os.path.dirname(filename)
        interp.runcommand(
            'if 1:\n            _filename = %r\n            import sys as _sys\n            from os.path import basename as _basename\n            if (not _sys.argv or\n                _basename(_sys.argv[0]) != _basename(_filename)):\n                _sys.argv = [_filename]\n            import os as _os\n            _os.chdir(%r)\n            del _filename, _sys, _basename, _os\n            \n'
            % (filename, dirname))
        interp.prepend_syspath(filename)
        interp.runcode(code)
        return 'break'

    if macosxSupport.runningAsOSXApp():
        _run_module_event = run_module_event

        def run_module_event(self, event):
            self.editwin.text_frame.after(
                200, lambda: self.editwin.text_frame.event_generate(
                    '<<run-module-event-2>>'))
            return 'break'

    def getfilename(self):
        """Get source filename.  If not saved, offer to save (or create) file
        
        The debugger requires a source file.  Make sure there is one, and that
        the current version of the source buffer has been saved.  If the user
        declines to save or cancels the Save As dialog, return None.
        
        If the user has configured IDLE for Autosave, the file will be
        silently saved if it already exists and is dirty.
        
        """
        filename = self.editwin.io.filename
        if not self.editwin.get_saved():
            autosave = idleConf.GetOption('main',
                                          'General',
                                          'autosave',
                                          type='bool')
            if autosave and filename:
                self.editwin.io.save(None)
            else:
                confirm = self.ask_save_dialog()
                self.editwin.text.focus_set()
                if confirm:
                    self.editwin.io.save(None)
                    filename = self.editwin.io.filename
                else:
                    filename = None
        return filename

    def ask_save_dialog(self):
        msg = 'Source Must Be Saved\n' + '     ' + 'OK to Save?'
        confirm = tkMessageBox.askokcancel(title='Save Before Run or Check',
                                           message=msg,
                                           default=tkMessageBox.OK,
                                           master=self.editwin.text)
        return confirm

    def errorbox(self, title, message):
        tkMessageBox.showerror(title, message, master=self.editwin.text)
        self.editwin.text.focus_set()
    def _make_toolbar(self):
        if self.TB is not None:
            return  # toolbar exists

        top = self.editwin.top

        f = Frame(top)
        widgets = self.editwin.top.pack_slaves()
        widgets = list(widgets)  # list for Python 3 support
        f.pack(side="top", fill=X, before=widgets[0])  # make toolbar play nicely with CodeContext

        f.config(height=8)
        mvar = [StringVar(top), StringVar(top)]
        Separator = Label

        try:
            osx = macosxSupport.runningAsOSXApp() or sys.platform == "darwin"
        except:
            osx = False

        toolbar = [
            (
                Button(f, command=lambda: self.toolbar("titles"), text=">", width=1 if not osx else 2),
                None,
                "Show SubCode Labels",
            ),
            (
                Button(f, command=lambda: self.toolbar("ins"), text="##", width=2 if not osx else 3),
                None,
                "Insert SubCode Marker",
            ),
            (Separator(f), {"fill": Y, "pady": 0, "padx": 4}, None),
            (
                Button(f, command=lambda: self.toolbar("minus"), text="-", width=1 if not osx else 2),
                None,
                "Subtract from number by cursor then run subcode",
            ),
            (Entry(f, width=6, justify="center", textvar=mvar[0]), {"fill": Y}, "+ - value"),
            (
                Button(f, command=lambda: self.toolbar("plus"), text="+", width=1 if not osx else 2),
                None,
                "Add to number by cursor then run subcode",
            ),
            (Separator(f), {"fill": Y, "pady": 0, "padx": 4}, None),
            (
                Button(f, command=lambda: self.toolbar("div"), text="/", width=1 if not osx else 2),
                None,
                "Divide number by cursor then run subcode",
            ),
            (Entry(f, width=6, justify="center", textvar=mvar[1]), {"fill": Y}, "* / value"),
            (
                Button(f, command=lambda: self.toolbar("mult"), text="*", width=1 if not osx else 2),
                None,
                "Multiply number by cursor then run subcode",
            ),
            (Separator(f), {"fill": Y, "pady": 0, "padx": 4}, None),
            (
                Button(f, command=lambda: self.toolbar("run_subcode"), text="RS", width=2 if not osx else 4),
                None,
                "Run SubCode",
            ),
            (
                Button(f, command=lambda: self.toolbar("run_subcode_proceed"), text="RSP", width=3 if not osx else 4),
                None,
                "Run SubCode and Proceed",
            ),
            (
                Button(f, command=lambda: self.toolbar("run_all"), text="RA", width=2 if not osx else 4),
                None,
                "Run All SubCodes",
            ),
            (Separator(f), {"fill": Y, "pady": 0, "padx": 4}, None),
        ]

        mvar[0].set("1.0")
        mvar[1].set("1.1")
        self.mvar = mvar

        for i, cfg, tooltip in toolbar:
            if cfg is None:
                cfg = {}
            try:
                i.configure(pady=0, padx=7)
                i.configure(wraplength=0)
                i.configure(borderwidth=1)
            except:  # catch ALL THE ERRORS
                # print 'error',i, cfg, tooltip
                pass
            i.pack(side="left", **cfg)
            if tooltip is not None:
                ToolTip.ToolTip(i, " %s " % tooltip)

        self.TB = f
        self.TITLES = toolbar[0][0]  # pointer to the titles button
def main():
    global flist, root, use_subprocess

    use_subprocess = True
    enable_shell = False
    enable_edit = False
    debug = False
    cmd = None
    script = None
    startup = False
    try:
        opts, args = getopt.getopt(sys.argv[1:], "c:deihnr:st:")
    except getopt.error as msg:
        sys.stderr.write("Error: %s\n" % str(msg))
        sys.stderr.write(usage_msg)
        sys.exit(2)
    for o, a in opts:
        if o == '-c':
            cmd = a
            enable_shell = True
        if o == '-d':
            debug = True
            enable_shell = True
        if o == '-e':
            enable_edit = True
        if o == '-h':
            sys.stdout.write(usage_msg)
            sys.exit()
        if o == '-i':
            enable_shell = True
        if o == '-n':
            use_subprocess = False
        if o == '-r':
            script = a
            if os.path.isfile(script):
                pass
            else:
                print("No script file: ", script)
                sys.exit()
            enable_shell = True
        if o == '-s':
            startup = True
            enable_shell = True
        if o == '-t':
            PyShell.shell_title = a
            enable_shell = True
    if args and args[0] == '-':
        cmd = sys.stdin.read()
        enable_shell = True
    # process sys.argv and sys.path:
    for i in range(len(sys.path)):
        sys.path[i] = os.path.abspath(sys.path[i])
    if args and args[0] == '-':
        sys.argv = [''] + args[1:]
    elif cmd:
        sys.argv = ['-c'] + args
    elif script:
        sys.argv = [script] + args
    elif args:
        enable_edit = True
        pathx = []
        for filename in args:
            pathx.append(os.path.dirname(filename))
        for dir in pathx:
            dir = os.path.abspath(dir)
            if not dir in sys.path:
                sys.path.insert(0, dir)
    else:
        dir = os.getcwd()
        if dir not in sys.path:
            sys.path.insert(0, dir)
    # check the IDLE settings configuration (but command line overrides)
    edit_start = idleConf.GetOption('main', 'General',
                                    'editor-on-startup', type='bool')
    enable_edit = enable_edit or edit_start
    enable_shell = enable_shell or not edit_start
    # start editor and/or shell windows:
    root = Tk(className="Idle")

    fixwordbreaks(root)
    root.withdraw()
    flist = PyShellFileList(root)
    macosxSupport.setupApp(root, flist)

    if enable_edit:
        if not (cmd or script):
            for filename in args:
                flist.open(filename)
            if not args:
                flist.new()
    if enable_shell:
        shell = flist.open_shell()
        if not shell:
            return # couldn't open shell

        if macosxSupport.runningAsOSXApp() and flist.dict:
            # On OSX: when the user has double-clicked on a file that causes
            # IDLE to be launched the shell window will open just in front of
            # the file she wants to see. Lower the interpreter window when
            # there are open files.
            shell.top.lower()

    shell = flist.pyshell
    # handle remaining options:
    if debug:
        shell.open_debugger()
    if startup:
        filename = os.environ.get("IDLESTARTUP") or \
                   os.environ.get("PYTHONSTARTUP")
        if filename and os.path.isfile(filename):
            shell.interp.execfile(filename)
    if shell and cmd or script:
        shell.interp.runcommand("""if 1:
            import sys as _sys
            _sys.argv = %r
            del _sys
            \n""" % (sys.argv,))
        if cmd:
            shell.interp.execsource(cmd)
        elif script:
            shell.interp.prepend_syspath(script)
            shell.interp.execfile(script)

    root.mainloop()
    root.destroy()
Example #37
0
    def _make_toolbar(self):
        if self.TB is not None:
            return  # toolbar exists

        top = self.editwin.top

        f = Frame(top)
        widgets = self.editwin.top.pack_slaves()
        widgets = list(widgets) # list for Python 3 support
        f.pack(side='top', fill=X, before=widgets[0])  # make toolbar play nicely with CodeContext


        f.config(height=8)
        mvar = [StringVar(top), StringVar(top)]
        Separator = Label

        try:
            osx = (macosxSupport.runningAsOSXApp() or
                    sys.platform == 'darwin')
        except:
            osx = False

        toolbar = [(Button(f, command=lambda: self.toolbar('titles'), text='>',
                           width=1 if not osx else 2),
                    None, 'Show %s Labels' % SUBCODE_STR),

                   (Button(f, command=lambda: self.toolbar('ins'), text='##',
                           width=2 if not osx else 3),
                    None, 'Insert %s Marker' % SUBCODE_STR),

                   (Separator(f), {'fill':Y, 'pady':0, 'padx':4}, None),

                   (Button(f, command=lambda: self.toolbar('minus'), text='-',
                           width=1 if not osx else 2),
                    None, 'Subtract from number by cursor then run %s' % SUBCODE_STR.lower()),

                   (Entry(f, width=6, justify='center', textvar=mvar[0]), {'fill':Y},
                    '+ - value'),

                   (Button(f, command=lambda: self.toolbar('plus'), text='+',
                           width=1 if not osx else 2),
                    None, 'Add to number by cursor then run %s' % SUBCODE_STR.lower()),

                   (Separator(f), {'fill':Y, 'pady':0, 'padx':4}, None),

                   (Button(f, command=lambda: self.toolbar('div'), text='/',
                           width=1 if not osx else 2),
                    None, 'Divide number by cursor then run %s' % SUBCODE_STR.lower()),

                   (Entry(f, width=6, justify='center',
                          textvar=mvar[1]), {'fill':Y},
                    '* / value'),

                   (Button(f, command=lambda: self.toolbar('mult'), text='*',
                           width=1 if not osx else 2),
                    None, 'Multiply number by cursor then run %s' % SUBCODE_STR.lower()),

                   (Separator(f), {'fill':Y, 'pady':0, 'padx':4}, None),

                   (Button(f, command=lambda: self.toolbar('run_subcode'), text='R%s' %
                           SUBCODE_STR[0].upper(),
                           width=2 if not osx else 4),
                    None, 'Run %s' % SUBCODE_STR),

                   (Button(f, command=lambda: self.toolbar('run_subcode_proceed'), text='R%sP' %
                           SUBCODE_STR[0].upper(),
                           width=3 if not osx else 4),
                    None, 'Run %s and Proceed' % SUBCODE_STR),

                   (Button(f, command=lambda: self.toolbar('run_all'), text='RA',
                           width=2 if not osx else 4),
                    None, 'Run All %ss' % SUBCODE_STR),

                   (Separator(f), {'fill':Y, 'pady':0, 'padx':4}, None),

                    ]

        mvar[0].set('1.0')
        mvar[1].set('1.1')
        self.mvar = mvar

        for i, cfg, tooltip  in toolbar:
            if cfg is None:
                cfg = {}
            try:
                i.configure(pady=0, padx=7)
                i.configure(wraplength=0)
                i.configure(borderwidth=1)
            except:  # catch ALL THE ERRORS
                #print 'error',i, cfg, tooltip
                pass
            i.pack(side='left', **cfg)
            if tooltip is not None:
                ToolTip.ToolTip(i, ' %s ' % tooltip)

        self.TB = f
        self.TITLES = toolbar[0][0]  # pointer to the titles button
class EditorWindow(object):
    from idlelib.Percolator import Percolator
    from idlelib.ColorDelegator import ColorDelegator
    from idlelib.UndoDelegator import UndoDelegator
    from idlelib.IOBinding import IOBinding, filesystemencoding, encoding
    from idlelib import Bindings
    from Tkinter import Toplevel
    from idlelib.MultiStatusBar import MultiStatusBar
    help_url = None

    def __init__(self, flist=None, filename=None, key=None, root=None):
        if EditorWindow.help_url is None:
            dochome = os.path.join(sys.prefix, 'Doc', 'index.html')
            if sys.platform.count('linux'):
                pyver = 'python-docs-' + '%s.%s.%s' % sys.version_info[:3]
                if os.path.isdir('/var/www/html/python/'):
                    dochome = '/var/www/html/python/index.html'
                else:
                    basepath = '/usr/share/doc/'
                    dochome = os.path.join(basepath, pyver, 'Doc', 'index.html')
            elif sys.platform[:3] == 'win':
                chmfile = os.path.join(sys.prefix, 'Doc', 'Python%s.chm' % _sphinx_version())
                if os.path.isfile(chmfile):
                    dochome = chmfile
            elif macosxSupport.runningAsOSXApp():
                dochome = os.path.join(sys.prefix, 'Resources/English.lproj/Documentation/index.html')
            dochome = os.path.normpath(dochome)
            if os.path.isfile(dochome):
                EditorWindow.help_url = dochome
                if sys.platform == 'darwin':
                    EditorWindow.help_url = 'file://' + EditorWindow.help_url
            else:
                EditorWindow.help_url = 'http://docs.python.org/%d.%d' % sys.version_info[:2]
        currentTheme = idleConf.CurrentTheme()
        self.flist = flist
        root = root or flist.root
        self.root = root
        try:
            sys.ps1
        except AttributeError:
            sys.ps1 = '>>> '

        self.menubar = Menu(root)
        self.top = top = WindowList.ListedToplevel(root, menu=self.menubar)
        if flist:
            self.tkinter_vars = flist.vars
            self.top.instance_dict = flist.inversedict
        else:
            self.tkinter_vars = {}
            self.top.instance_dict = {}
        self.recent_files_path = os.path.join(idleConf.GetUserCfgDir(), 'recent-files.lst')
        self.text_frame = text_frame = Frame(top)
        self.vbar = vbar = Scrollbar(text_frame, name='vbar')
        self.width = idleConf.GetOption('main', 'EditorWindow', 'width')
        text_options = {'name': 'text',
           'padx': 5,
           'wrap': 'none',
           'width': self.width,
           'height': idleConf.GetOption('main', 'EditorWindow', 'height')
           }
        if TkVersion >= 8.5:
            text_options['tabstyle'] = 'wordprocessor'
        self.text = text = MultiCallCreator(Text)(text_frame, **text_options)
        self.top.focused_widget = self.text
        self.createmenubar()
        self.apply_bindings()
        self.top.protocol('WM_DELETE_WINDOW', self.close)
        self.top.bind('<<close-window>>', self.close_event)
        if macosxSupport.runningAsOSXApp():
            text.bind('<<close-window>>', self.close_event)
            text.bind('<Control-Button-1>', self.right_menu_event)
        else:
            text.bind('<3>', self.right_menu_event)
        text.bind('<<cut>>', self.cut)
        text.bind('<<copy>>', self.copy)
        text.bind('<<paste>>', self.paste)
        text.bind('<<center-insert>>', self.center_insert_event)
        text.bind('<<help>>', self.help_dialog)
        text.bind('<<python-docs>>', self.python_docs)
        text.bind('<<about-idle>>', self.about_dialog)
        text.bind('<<open-config-dialog>>', self.config_dialog)
        text.bind('<<open-module>>', self.open_module)
        text.bind('<<do-nothing>>', lambda event: 'break')
        text.bind('<<select-all>>', self.select_all)
        text.bind('<<remove-selection>>', self.remove_selection)
        text.bind('<<find>>', self.find_event)
        text.bind('<<find-again>>', self.find_again_event)
        text.bind('<<find-in-files>>', self.find_in_files_event)
        text.bind('<<find-selection>>', self.find_selection_event)
        text.bind('<<replace>>', self.replace_event)
        text.bind('<<goto-line>>', self.goto_line_event)
        text.bind('<<smart-backspace>>', self.smart_backspace_event)
        text.bind('<<newline-and-indent>>', self.newline_and_indent_event)
        text.bind('<<smart-indent>>', self.smart_indent_event)
        text.bind('<<indent-region>>', self.indent_region_event)
        text.bind('<<dedent-region>>', self.dedent_region_event)
        text.bind('<<comment-region>>', self.comment_region_event)
        text.bind('<<uncomment-region>>', self.uncomment_region_event)
        text.bind('<<tabify-region>>', self.tabify_region_event)
        text.bind('<<untabify-region>>', self.untabify_region_event)
        text.bind('<<toggle-tabs>>', self.toggle_tabs_event)
        text.bind('<<change-indentwidth>>', self.change_indentwidth_event)
        text.bind('<Left>', self.move_at_edge_if_selection(0))
        text.bind('<Right>', self.move_at_edge_if_selection(1))
        text.bind('<<del-word-left>>', self.del_word_left)
        text.bind('<<del-word-right>>', self.del_word_right)
        text.bind('<<beginning-of-line>>', self.home_callback)
        if flist:
            flist.inversedict[self] = key
            if key:
                flist.dict[key] = self
            text.bind('<<open-new-window>>', self.new_callback)
            text.bind('<<close-all-windows>>', self.flist.close_all_callback)
            text.bind('<<open-class-browser>>', self.open_class_browser)
            text.bind('<<open-path-browser>>', self.open_path_browser)
        self.set_status_bar()
        vbar['command'] = text.yview
        vbar.pack(side=RIGHT, fill=Y)
        text['yscrollcommand'] = vbar.set
        fontWeight = 'normal'
        if idleConf.GetOption('main', 'EditorWindow', 'font-bold', type='bool'):
            fontWeight = 'bold'
        text.config(font=(idleConf.GetOption('main', 'EditorWindow', 'font'),
         idleConf.GetOption('main', 'EditorWindow', 'font-size'),
         fontWeight))
        text_frame.pack(side=LEFT, fill=BOTH, expand=1)
        text.pack(side=TOP, fill=BOTH, expand=1)
        text.focus_set()
        usespaces = idleConf.GetOption('main', 'Indent', 'use-spaces', type='bool')
        self.usetabs = not usespaces
        self.tabwidth = 8
        self.indentwidth = self.tabwidth
        self.set_notabs_indentwidth()
        self.context_use_ps1 = False
        self.num_context_lines = (50, 500, 5000000)
        self.per = per = self.Percolator(text)
        self.undo = undo = self.UndoDelegator()
        per.insertfilter(undo)
        text.undo_block_start = undo.undo_block_start
        text.undo_block_stop = undo.undo_block_stop
        undo.set_saved_change_hook(self.saved_change_hook)
        self.io = io = self.IOBinding(self)
        io.set_filename_change_hook(self.filename_change_hook)
        self.recent_files_menu = Menu(self.menubar)
        self.menudict['file'].insert_cascade(3, label='Recent Files', underline=0, menu=self.recent_files_menu)
        self.update_recent_files_list()
        self.color = None
        if filename:
            if os.path.exists(filename) and not os.path.isdir(filename):
                io.loadfile(filename)
            else:
                io.set_filename(filename)
        self.ResetColorizer()
        self.saved_change_hook()
        self.set_indentation_params(self.ispythonsource(filename))
        self.load_extensions()
        menu = self.menudict.get('windows')
        if menu:
            end = menu.index('end')
            if end is None:
                end = -1
            if end >= 0:
                menu.add_separator()
                end = end + 1
            self.wmenu_end = end
            WindowList.register_callback(self.postwindowsmenu)
        self.askyesno = tkMessageBox.askyesno
        self.askinteger = tkSimpleDialog.askinteger
        self.showerror = tkMessageBox.showerror
        return

    def _filename_to_unicode(self, filename):
        """convert filename to unicode in order to display it in Tk"""
        if isinstance(filename, unicode) or not filename:
            return filename
        try:
            return filename.decode(self.filesystemencoding)
        except UnicodeDecodeError:
            try:
                return filename.decode(self.encoding)
            except UnicodeDecodeError:
                return filename.decode('iso8859-1')

    def new_callback(self, event):
        dirname, basename = self.io.defaultfilename()
        self.flist.new(dirname)
        return 'break'

    def home_callback(self, event):
        if event.state & 4 != 0 and event.keysym == 'Home':
            return
        if self.text.index('iomark') and self.text.compare('iomark', '<=', 'insert lineend') and self.text.compare('insert linestart', '<=', 'iomark'):
            insertpt = int(self.text.index('iomark').split('.')[1])
        else:
            line = self.text.get('insert linestart', 'insert lineend')
            for insertpt in xrange(len(line)):
                if line[insertpt] not in (' ', '\t'):
                    break
            else:
                insertpt = len(line)

        lineat = int(self.text.index('insert').split('.')[1])
        if insertpt == lineat:
            insertpt = 0
        dest = 'insert linestart+' + str(insertpt) + 'c'
        if event.state & 1 == 0:
            self.text.tag_remove('sel', '1.0', 'end')
        else:
            if not self.text.index('sel.first'):
                self.text.mark_set('my_anchor', 'insert')
            elif self.text.compare(self.text.index('sel.first'), '<', self.text.index('insert')):
                self.text.mark_set('my_anchor', 'sel.first')
            else:
                self.text.mark_set('my_anchor', 'sel.last')
            first = self.text.index(dest)
            last = self.text.index('my_anchor')
            if self.text.compare(first, '>', last):
                first, last = last, first
            self.text.tag_remove('sel', '1.0', 'end')
            self.text.tag_add('sel', first, last)
        self.text.mark_set('insert', dest)
        self.text.see('insert')
        return 'break'

    def set_status_bar(self):
        self.status_bar = self.MultiStatusBar(self.top)
        if macosxSupport.runningAsOSXApp():
            self.status_bar.set_label('_padding1', '    ', side=RIGHT)
        self.status_bar.set_label('column', 'Col: ?', side=RIGHT)
        self.status_bar.set_label('line', 'Ln: ?', side=RIGHT)
        self.status_bar.pack(side=BOTTOM, fill=X)
        self.text.bind('<<set-line-and-column>>', self.set_line_and_column)
        self.text.event_add('<<set-line-and-column>>', '<KeyRelease>', '<ButtonRelease>')
        self.text.after_idle(self.set_line_and_column)

    def set_line_and_column(self, event=None):
        line, column = self.text.index(INSERT).split('.')
        self.status_bar.set_label('column', 'Col: %s' % column)
        self.status_bar.set_label('line', 'Ln: %s' % line)

    menu_specs = [
     ('file', '_File'),
     ('edit', '_Edit'),
     ('format', 'F_ormat'),
     ('run', '_Run'),
     ('options', '_Options'),
     ('windows', '_Windows'),
     ('help', '_Help')]
    if macosxSupport.runningAsOSXApp():
        del menu_specs[-3]
        menu_specs[-2] = ('windows', '_Window')

    def createmenubar(self):
        mbar = self.menubar
        self.menudict = menudict = {}
        for name, label in self.menu_specs:
            underline, label = prepstr(label)
            menudict[name] = menu = Menu(mbar, name=name)
            mbar.add_cascade(label=label, menu=menu, underline=underline)

        if macosxSupport.isCarbonAquaTk(self.root):
            menudict['application'] = menu = Menu(mbar, name='apple')
            mbar.add_cascade(label='IDLE', menu=menu)
        self.fill_menus()
        self.base_helpmenu_length = self.menudict['help'].index(END)
        self.reset_help_menu_entries()

    def postwindowsmenu(self):
        menu = self.menudict['windows']
        end = menu.index('end')
        if end is None:
            end = -1
        if end > self.wmenu_end:
            menu.delete(self.wmenu_end + 1, end)
        WindowList.add_windows_to_menu(menu)
        return

    rmenu = None

    def right_menu_event(self, event):
        self.text.tag_remove('sel', '1.0', 'end')
        self.text.mark_set('insert', '@%d,%d' % (event.x, event.y))
        if not self.rmenu:
            self.make_rmenu()
        rmenu = self.rmenu
        self.event = event
        iswin = sys.platform[:3] == 'win'
        if iswin:
            self.text.config(cursor='arrow')
        rmenu.tk_popup(event.x_root, event.y_root)
        if iswin:
            self.text.config(cursor='ibeam')

    rmenu_specs = [
     ('Close', '<<close-window>>')]

    def make_rmenu(self):
        rmenu = Menu(self.text, tearoff=0)
        for label, eventname in self.rmenu_specs:

            def command(text=self.text, eventname=eventname):
                text.event_generate(eventname)

            rmenu.add_command(label=label, command=command)

        self.rmenu = rmenu

    def about_dialog(self, event=None):
        aboutDialog.AboutDialog(self.top, 'About IDLE')

    def config_dialog(self, event=None):
        configDialog.ConfigDialog(self.top, 'Settings')

    def help_dialog(self, event=None):
        fn = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'help.txt')
        textView.view_file(self.top, 'Help', fn)

    def python_docs(self, event=None):
        if sys.platform[:3] == 'win':
            try:
                os.startfile(self.help_url)
            except WindowsError as why:
                tkMessageBox.showerror(title='Document Start Failure', message=str(why), parent=self.text)

        else:
            webbrowser.open(self.help_url)
        return 'break'

    def cut(self, event):
        self.text.event_generate('<<Cut>>')
        return 'break'

    def copy(self, event):
        if not self.text.tag_ranges('sel'):
            return
        self.text.event_generate('<<Copy>>')
        return 'break'

    def paste(self, event):
        self.text.event_generate('<<Paste>>')
        self.text.see('insert')
        return 'break'

    def select_all(self, event=None):
        self.text.tag_add('sel', '1.0', 'end-1c')
        self.text.mark_set('insert', '1.0')
        self.text.see('insert')
        return 'break'

    def remove_selection(self, event=None):
        self.text.tag_remove('sel', '1.0', 'end')
        self.text.see('insert')

    def move_at_edge_if_selection(self, edge_index):
        """Cursor move begins at start or end of selection
        
        When a left/right cursor key is pressed create and return to Tkinter a
        function which causes a cursor move from the associated edge of the
        selection.
        
        """
        self_text_index = self.text.index
        self_text_mark_set = self.text.mark_set
        edges_table = ('sel.first+1c', 'sel.last-1c')

        def move_at_edge(event):
            if event.state & 5 == 0:
                try:
                    self_text_index('sel.first')
                    self_text_mark_set('insert', edges_table[edge_index])
                except TclError:
                    pass

        return move_at_edge

    def del_word_left(self, event):
        self.text.event_generate('<Meta-Delete>')
        return 'break'

    def del_word_right(self, event):
        self.text.event_generate('<Meta-d>')
        return 'break'

    def find_event(self, event):
        SearchDialog.find(self.text)
        return 'break'

    def find_again_event(self, event):
        SearchDialog.find_again(self.text)
        return 'break'

    def find_selection_event(self, event):
        SearchDialog.find_selection(self.text)
        return 'break'

    def find_in_files_event(self, event):
        GrepDialog.grep(self.text, self.io, self.flist)
        return 'break'

    def replace_event(self, event):
        ReplaceDialog.replace(self.text)
        return 'break'

    def goto_line_event(self, event):
        text = self.text
        lineno = tkSimpleDialog.askinteger('Goto', 'Go to line number:', parent=text)
        if lineno is None:
            return 'break'
        else:
            if lineno <= 0:
                text.bell()
                return 'break'
            text.mark_set('insert', '%d.0' % lineno)
            text.see('insert')
            return

    def open_module(self, event=None):
        try:
            name = self.text.get('sel.first', 'sel.last')
        except TclError:
            name = ''
        else:
            name = name.strip()

        name = tkSimpleDialog.askstring('Module', 'Enter the name of a Python module\nto search on sys.path and open:', parent=self.text, initialvalue=name)
        if name:
            name = name.strip()
        if not name:
            return
        try:
            f, file, (suffix, mode, type) = _find_module(name)
        except (NameError, ImportError) as msg:
            tkMessageBox.showerror('Import error', str(msg), parent=self.text)
            return

        if type != imp.PY_SOURCE:
            tkMessageBox.showerror('Unsupported type', '%s is not a source module' % name, parent=self.text)
            return
        if f:
            f.close()
        if self.flist:
            self.flist.open(file)
        else:
            self.io.loadfile(file)

    def open_class_browser(self, event=None):
        filename = self.io.filename
        if not filename:
            tkMessageBox.showerror('No filename', 'This buffer has no associated filename', master=self.text)
            self.text.focus_set()
            return None
        else:
            head, tail = os.path.split(filename)
            base, ext = os.path.splitext(tail)
            from idlelib import ClassBrowser
            ClassBrowser.ClassBrowser(self.flist, base, [head])
            return None

    def open_path_browser(self, event=None):
        from idlelib import PathBrowser
        PathBrowser.PathBrowser(self.flist)

    def gotoline(self, lineno):
        if lineno is not None and lineno > 0:
            self.text.mark_set('insert', '%d.0' % lineno)
            self.text.tag_remove('sel', '1.0', 'end')
            self.text.tag_add('sel', 'insert', 'insert +1l')
            self.center()
        return

    def ispythonsource(self, filename):
        if not filename or os.path.isdir(filename):
            return True
        base, ext = os.path.splitext(os.path.basename(filename))
        if os.path.normcase(ext) in ('.py', '.pyw'):
            return True
        try:
            f = open(filename)
            line = f.readline()
            f.close()
        except IOError:
            return False

        return line.startswith('#!') and line.find('python') >= 0

    def close_hook(self):
        if self.flist:
            self.flist.unregister_maybe_terminate(self)
            self.flist = None
        return

    def set_close_hook(self, close_hook):
        self.close_hook = close_hook

    def filename_change_hook(self):
        if self.flist:
            self.flist.filename_changed_edit(self)
        self.saved_change_hook()
        self.top.update_windowlist_registry(self)
        self.ResetColorizer()

    def _addcolorizer(self):
        if self.color:
            return
        if self.ispythonsource(self.io.filename):
            self.color = self.ColorDelegator()
        if self.color:
            self.per.removefilter(self.undo)
            self.per.insertfilter(self.color)
            self.per.insertfilter(self.undo)

    def _rmcolorizer(self):
        if not self.color:
            return
        else:
            self.color.removecolors()
            self.per.removefilter(self.color)
            self.color = None
            return

    def ResetColorizer(self):
        """Update the colour theme"""
        self._rmcolorizer()
        self._addcolorizer()
        theme = idleConf.GetOption('main', 'Theme', 'name')
        normal_colors = idleConf.GetHighlight(theme, 'normal')
        cursor_color = idleConf.GetHighlight(theme, 'cursor', fgBg='fg')
        select_colors = idleConf.GetHighlight(theme, 'hilite')
        self.text.config(foreground=normal_colors['foreground'], background=normal_colors['background'], insertbackground=cursor_color, selectforeground=select_colors['foreground'], selectbackground=select_colors['background'])

    def ResetFont(self):
        """Update the text widgets' font if it is changed"""
        fontWeight = 'normal'
        if idleConf.GetOption('main', 'EditorWindow', 'font-bold', type='bool'):
            fontWeight = 'bold'
        self.text.config(font=(idleConf.GetOption('main', 'EditorWindow', 'font'),
         idleConf.GetOption('main', 'EditorWindow', 'font-size'),
         fontWeight))

    def RemoveKeybindings(self):
        """Remove the keybindings before they are changed."""
        self.Bindings.default_keydefs = keydefs = idleConf.GetCurrentKeySet()
        for event, keylist in keydefs.items():
            self.text.event_delete(event, *keylist)

        for extensionName in self.get_standard_extension_names():
            xkeydefs = idleConf.GetExtensionBindings(extensionName)
            if xkeydefs:
                for event, keylist in xkeydefs.items():
                    self.text.event_delete(event, *keylist)

    def ApplyKeybindings(self):
        """Update the keybindings after they are changed"""
        self.Bindings.default_keydefs = keydefs = idleConf.GetCurrentKeySet()
        self.apply_bindings()
        for extensionName in self.get_standard_extension_names():
            xkeydefs = idleConf.GetExtensionBindings(extensionName)
            if xkeydefs:
                self.apply_bindings(xkeydefs)

        menuEventDict = {}
        for menu in self.Bindings.menudefs:
            menuEventDict[menu[0]] = {}
            for item in menu[1]:
                if item:
                    menuEventDict[menu[0]][prepstr(item[0])[1]] = item[1]

        for menubarItem in self.menudict.keys():
            menu = self.menudict[menubarItem]
            end = menu.index(END) + 1
            for index in range(0, end):
                if menu.type(index) == 'command':
                    accel = menu.entrycget(index, 'accelerator')
                    if accel:
                        itemName = menu.entrycget(index, 'label')
                        event = ''
                        if menubarItem in menuEventDict:
                            if itemName in menuEventDict[menubarItem]:
                                event = menuEventDict[menubarItem][itemName]
                        if event:
                            accel = get_accelerator(keydefs, event)
                            menu.entryconfig(index, accelerator=accel)

    def set_notabs_indentwidth(self):
        """Update the indentwidth if changed and not using tabs in this window"""
        if not self.usetabs:
            self.indentwidth = idleConf.GetOption('main', 'Indent', 'num-spaces', type='int')

    def reset_help_menu_entries(self):
        """Update the additional help entries on the Help menu"""
        help_list = idleConf.GetAllExtraHelpSourcesList()
        helpmenu = self.menudict['help']
        helpmenu_length = helpmenu.index(END)
        if helpmenu_length > self.base_helpmenu_length:
            helpmenu.delete(self.base_helpmenu_length + 1, helpmenu_length)
        if help_list:
            helpmenu.add_separator()
            for entry in help_list:
                cmd = self.__extra_help_callback(entry[1])
                helpmenu.add_command(label=entry[0], command=cmd)

        self.menudict['help'] = helpmenu

    def __extra_help_callback(self, helpfile):
        """Create a callback with the helpfile value frozen at definition time"""

        def display_extra_help(helpfile=helpfile):
            if not helpfile.startswith(('www', 'http')):
                helpfile = os.path.normpath(helpfile)
            if sys.platform[:3] == 'win':
                try:
                    os.startfile(helpfile)
                except WindowsError as why:
                    tkMessageBox.showerror(title='Document Start Failure', message=str(why), parent=self.text)

            else:
                webbrowser.open(helpfile)

        return display_extra_help

    def update_recent_files_list(self, new_file=None):
        """Load and update the recent files list and menus"""
        rf_list = []
        if os.path.exists(self.recent_files_path):
            rf_list_file = open(self.recent_files_path, 'r')
            try:
                rf_list = rf_list_file.readlines()
            finally:
                rf_list_file.close()

        if new_file:
            new_file = os.path.abspath(new_file) + '\n'
            if new_file in rf_list:
                rf_list.remove(new_file)
            rf_list.insert(0, new_file)
        bad_paths = []
        for path in rf_list:
            if '\x00' in path or not os.path.exists(path[0:-1]):
                bad_paths.append(path)

        rf_list = [ path for path in rf_list if path not in bad_paths ]
        ulchars = '1234567890ABCDEFGHIJK'
        rf_list = rf_list[0:len(ulchars)]
        rf_file = open(self.recent_files_path, 'w')
        try:
            rf_file.writelines(rf_list)
        finally:
            rf_file.close()

        for instance in self.top.instance_dict.keys():
            menu = instance.recent_files_menu
            menu.delete(1, END)
            for i, file_name in enumerate(rf_list):
                file_name = file_name.rstrip()
                ufile_name = self._filename_to_unicode(file_name)
                callback = instance.__recent_file_callback(file_name)
                menu.add_command(label=ulchars[i] + ' ' + ufile_name, command=callback, underline=0)

    def __recent_file_callback(self, file_name):

        def open_recent_file(fn_closure=file_name):
            self.io.open(editFile=fn_closure)

        return open_recent_file

    def saved_change_hook(self):
        short = self.short_title()
        long = self.long_title()
        if short and long:
            title = short + ' - ' + long
        elif short:
            title = short
        elif long:
            title = long
        else:
            title = 'Untitled'
        icon = short or long or title
        if not self.get_saved():
            title = '*%s*' % title
            icon = '*%s' % icon
        self.top.wm_title(title)
        self.top.wm_iconname(icon)

    def get_saved(self):
        return self.undo.get_saved()

    def set_saved(self, flag):
        self.undo.set_saved(flag)

    def reset_undo(self):
        self.undo.reset_undo()

    def short_title(self):
        filename = self.io.filename
        if filename:
            filename = os.path.basename(filename)
        return self._filename_to_unicode(filename)

    def long_title(self):
        return self._filename_to_unicode(self.io.filename or '')

    def center_insert_event(self, event):
        self.center()

    def center(self, mark='insert'):
        text = self.text
        top, bot = self.getwindowlines()
        lineno = self.getlineno(mark)
        height = bot - top
        newtop = max(1, lineno - height // 2)
        text.yview(float(newtop))

    def getwindowlines(self):
        text = self.text
        top = self.getlineno('@0,0')
        bot = self.getlineno('@0,65535')
        if top == bot and text.winfo_height() == 1:
            height = int(text['height'])
            bot = top + height - 1
        return (top, bot)

    def getlineno(self, mark='insert'):
        text = self.text
        return int(float(text.index(mark)))

    def get_geometry(self):
        """Return (width, height, x, y)"""
        geom = self.top.wm_geometry()
        m = re.match('(\\d+)x(\\d+)\\+(-?\\d+)\\+(-?\\d+)', geom)
        tuple = map(int, m.groups())
        return tuple

    def close_event(self, event):
        self.close()

    def maybesave(self):
        if self.io:
            if not self.get_saved():
                if self.top.state() != 'normal':
                    self.top.deiconify()
                self.top.lower()
                self.top.lift()
            return self.io.maybesave()

    def close(self):
        reply = self.maybesave()
        if str(reply) != 'cancel':
            self._close()
        return reply

    def _close(self):
        if self.io.filename:
            self.update_recent_files_list(new_file=self.io.filename)
        WindowList.unregister_callback(self.postwindowsmenu)
        self.unload_extensions()
        self.io.close()
        self.io = None
        self.undo = None
        if self.color:
            self.color.close(False)
            self.color = None
        self.text = None
        self.tkinter_vars = None
        self.per.close()
        self.per = None
        self.top.destroy()
        if self.close_hook:
            self.close_hook()
        return

    def load_extensions(self):
        self.extensions = {}
        self.load_standard_extensions()

    def unload_extensions(self):
        for ins in self.extensions.values():
            if hasattr(ins, 'close'):
                ins.close()

        self.extensions = {}

    def load_standard_extensions(self):
        for name in self.get_standard_extension_names():
            try:
                self.load_extension(name)
            except:
                print 'Failed to load extension', repr(name)
                import traceback
                traceback.print_exc()

    def get_standard_extension_names(self):
        return idleConf.GetExtensions(editor_only=True)

    def load_extension(self, name):
        try:
            mod = __import__(name, globals(), locals(), [])
        except ImportError:
            print '\nFailed to import extension: ', name
            return

        cls = getattr(mod, name)
        keydefs = idleConf.GetExtensionBindings(name)
        if hasattr(cls, 'menudefs'):
            self.fill_menus(cls.menudefs, keydefs)
        ins = cls(self)
        self.extensions[name] = ins
        if keydefs:
            self.apply_bindings(keydefs)
            for vevent in keydefs.keys():
                methodname = vevent.replace('-', '_')
                while methodname[:1] == '<':
                    methodname = methodname[1:]

                while methodname[-1:] == '>':
                    methodname = methodname[:-1]

                methodname = methodname + '_event'
                if hasattr(ins, methodname):
                    self.text.bind(vevent, getattr(ins, methodname))

    def apply_bindings(self, keydefs=None):
        if keydefs is None:
            keydefs = self.Bindings.default_keydefs
        text = self.text
        text.keydefs = keydefs
        for event, keylist in keydefs.items():
            if keylist:
                text.event_add(event, *keylist)

        return

    def fill_menus(self, menudefs=None, keydefs=None):
        """Add appropriate entries to the menus and submenus
        
        Menus that are absent or None in self.menudict are ignored.
        """
        if menudefs is None:
            menudefs = self.Bindings.menudefs
        if keydefs is None:
            keydefs = self.Bindings.default_keydefs
        menudict = self.menudict
        text = self.text
        for mname, entrylist in menudefs:
            menu = menudict.get(mname)
            if not menu:
                continue
            for entry in entrylist:
                if not entry:
                    menu.add_separator()
                else:
                    label, eventname = entry
                    checkbutton = label[:1] == '!'
                    if checkbutton:
                        label = label[1:]
                    underline, label = prepstr(label)
                    accelerator = get_accelerator(keydefs, eventname)

                    def command(text=text, eventname=eventname):
                        text.event_generate(eventname)

                    if checkbutton:
                        var = self.get_var_obj(eventname, BooleanVar)
                        menu.add_checkbutton(label=label, underline=underline, command=command, accelerator=accelerator, variable=var)
                    else:
                        menu.add_command(label=label, underline=underline, command=command, accelerator=accelerator)

        return

    def getvar(self, name):
        var = self.get_var_obj(name)
        if var:
            value = var.get()
            return value
        raise NameError, name

    def setvar(self, name, value, vartype=None):
        var = self.get_var_obj(name, vartype)
        if var:
            var.set(value)
        else:
            raise NameError, name

    def get_var_obj(self, name, vartype=None):
        var = self.tkinter_vars.get(name)
        if not var and vartype:
            self.tkinter_vars[name] = var = vartype(self.text)
        return var

    def is_char_in_string(self, text_index):
        if self.color:
            return self.text.tag_prevrange('TODO', text_index) or 'STRING' in self.text.tag_names(text_index)
        else:
            return 1

    def get_selection_indices(self):
        try:
            first = self.text.index('sel.first')
            last = self.text.index('sel.last')
            return (
             first, last)
        except TclError:
            return (None, None)

        return None

    def get_tabwidth(self):
        current = self.text['tabs'] or TK_TABWIDTH_DEFAULT
        return int(current)

    def set_tabwidth(self, newtabwidth):
        text = self.text
        if self.get_tabwidth() != newtabwidth:
            pixels = text.tk.call('font', 'measure', text['font'], '-displayof', text.master, 'n' * newtabwidth)
            text.configure(tabs=pixels)

    def set_indentation_params(self, ispythonsource, guess=True):
        if guess and ispythonsource:
            i = self.guess_indent()
            if 2 <= i <= 8:
                self.indentwidth = i
            if self.indentwidth != self.tabwidth:
                self.usetabs = False
        self.set_tabwidth(self.tabwidth)

    def smart_backspace_event(self, event):
        text = self.text
        first, last = self.get_selection_indices()
        if first and last:
            text.delete(first, last)
            text.mark_set('insert', first)
            return 'break'
        chars = text.get('insert linestart', 'insert')
        if chars == '':
            if text.compare('insert', '>', '1.0'):
                text.delete('insert-1c')
            else:
                text.bell()
            return 'break'
        if chars[-1] not in ' \t':
            text.delete('insert-1c')
            return 'break'
        tabwidth = self.tabwidth
        have = len(chars.expandtabs(tabwidth))
        want = (have - 1) // self.indentwidth * self.indentwidth
        last_line_of_prompt = sys.ps1.split('\n')[-1]
        ncharsdeleted = 0
        while 1:
            if chars == last_line_of_prompt:
                break
            chars = chars[:-1]
            ncharsdeleted = ncharsdeleted + 1
            have = len(chars.expandtabs(tabwidth))
            if have <= want or chars[-1] not in ' \t':
                break

        text.undo_block_start()
        text.delete('insert-%dc' % ncharsdeleted, 'insert')
        if have < want:
            text.insert('insert', ' ' * (want - have))
        text.undo_block_stop()
        return 'break'

    def smart_indent_event(self, event):
        text = self.text
        first, last = self.get_selection_indices()
        text.undo_block_start()
        try:
            if first and last:
                if index2line(first) != index2line(last):
                    return self.indent_region_event(event)
                text.delete(first, last)
                text.mark_set('insert', first)
            prefix = text.get('insert linestart', 'insert')
            raw, effective = classifyws(prefix, self.tabwidth)
            if raw == len(prefix):
                self.reindent_to(effective + self.indentwidth)
            else:
                if self.usetabs:
                    pad = '\t'
                else:
                    effective = len(prefix.expandtabs(self.tabwidth))
                    n = self.indentwidth
                    pad = ' ' * (n - effective % n)
                text.insert('insert', pad)
            text.see('insert')
            return 'break'
        finally:
            text.undo_block_stop()

    def newline_and_indent_event(self, event):
        text = self.text
        first, last = self.get_selection_indices()
        text.undo_block_start()
        try:
            if first and last:
                text.delete(first, last)
                text.mark_set('insert', first)
            line = text.get('insert linestart', 'insert')
            i, n = 0, len(line)
            while i < n and line[i] in ' \t':
                i = i + 1

            if i == n:
                text.insert('insert linestart', '\n')
                return 'break'
            indent = line[:i]
            i = 0
            last_line_of_prompt = sys.ps1.split('\n')[-1]
            while line and line[-1] in ' \t' and line != last_line_of_prompt:
                line = line[:-1]
                i = i + 1

            if i:
                text.delete('insert - %d chars' % i, 'insert')
            while text.get('insert') in ' \t':
                text.delete('insert')

            text.insert('insert', '\n')
            lno = index2line(text.index('insert'))
            y = PyParse.Parser(self.indentwidth, self.tabwidth)
            if not self.context_use_ps1:
                for context in self.num_context_lines:
                    startat = max(lno - context, 1)
                    startatindex = repr(startat) + '.0'
                    rawtext = text.get(startatindex, 'insert')
                    y.set_str(rawtext)
                    bod = y.find_good_parse_start(self.context_use_ps1, self._build_char_in_string_func(startatindex))
                    if bod is not None or startat == 1:
                        break

                y.set_lo(bod or 0)
            else:
                r = text.tag_prevrange('console', 'insert')
                if r:
                    startatindex = r[1]
                else:
                    startatindex = '1.0'
                rawtext = text.get(startatindex, 'insert')
                y.set_str(rawtext)
                y.set_lo(0)
            c = y.get_continuation_type()
            if c != PyParse.C_NONE:
                if c == PyParse.C_STRING_FIRST_LINE:
                    pass
                elif c == PyParse.C_STRING_NEXT_LINES:
                    text.insert('insert', indent)
                elif c == PyParse.C_BRACKET:
                    self.reindent_to(y.compute_bracket_indent())
                elif c == PyParse.C_BACKSLASH:
                    if y.get_num_lines_in_stmt() > 1:
                        text.insert('insert', indent)
                    else:
                        self.reindent_to(y.compute_backslash_indent())
                return 'break'
            indent = y.get_base_indent_string()
            text.insert('insert', indent)
            if y.is_block_opener():
                self.smart_indent_event(event)
            elif indent and y.is_block_closer():
                self.smart_backspace_event(event)
            return 'break'
        finally:
            text.see('insert')
            text.undo_block_stop()

        return

    def _build_char_in_string_func(self, startindex):

        def inner(offset, _startindex=startindex, _icis=self.is_char_in_string):
            return _icis(_startindex + '+%dc' % offset)

        return inner

    def indent_region_event(self, event):
        head, tail, chars, lines = self.get_region()
        for pos in range(len(lines)):
            line = lines[pos]
            if line:
                raw, effective = classifyws(line, self.tabwidth)
                effective = effective + self.indentwidth
                lines[pos] = self._make_blanks(effective) + line[raw:]

        self.set_region(head, tail, chars, lines)
        return 'break'

    def dedent_region_event(self, event):
        head, tail, chars, lines = self.get_region()
        for pos in range(len(lines)):
            line = lines[pos]
            if line:
                raw, effective = classifyws(line, self.tabwidth)
                effective = max(effective - self.indentwidth, 0)
                lines[pos] = self._make_blanks(effective) + line[raw:]

        self.set_region(head, tail, chars, lines)
        return 'break'

    def comment_region_event(self, event):
        head, tail, chars, lines = self.get_region()
        for pos in range(len(lines) - 1):
            line = lines[pos]
            lines[pos] = '##' + line

        self.set_region(head, tail, chars, lines)

    def uncomment_region_event(self, event):
        head, tail, chars, lines = self.get_region()
        for pos in range(len(lines)):
            line = lines[pos]
            if not line:
                continue
            if line[:2] == '##':
                line = line[2:]
            elif line[:1] == '#':
                line = line[1:]
            lines[pos] = line

        self.set_region(head, tail, chars, lines)

    def tabify_region_event(self, event):
        head, tail, chars, lines = self.get_region()
        tabwidth = self._asktabwidth()
        for pos in range(len(lines)):
            line = lines[pos]
            if line:
                raw, effective = classifyws(line, tabwidth)
                ntabs, nspaces = divmod(effective, tabwidth)
                lines[pos] = '\t' * ntabs + ' ' * nspaces + line[raw:]

        self.set_region(head, tail, chars, lines)

    def untabify_region_event(self, event):
        head, tail, chars, lines = self.get_region()
        tabwidth = self._asktabwidth()
        for pos in range(len(lines)):
            lines[pos] = lines[pos].expandtabs(tabwidth)

        self.set_region(head, tail, chars, lines)

    def toggle_tabs_event(self, event):
        if self.askyesno('Toggle tabs', 'Turn tabs ' + ('on', 'off')[self.usetabs] + '?\nIndent width ' + ('will be',
                                                                                                           'remains at')[self.usetabs] + ' 8.' + '\n Note: a tab is always 8 columns', parent=self.text):
            self.usetabs = not self.usetabs
            self.indentwidth = 8
        return 'break'

    def change_indentwidth_event(self, event):
        new = self.askinteger('Indent width', 'New indent width (2-16)\n(Always use 8 when using tabs)', parent=self.text, initialvalue=self.indentwidth, minvalue=2, maxvalue=16)
        if new and new != self.indentwidth and not self.usetabs:
            self.indentwidth = new
        return 'break'

    def get_region(self):
        text = self.text
        first, last = self.get_selection_indices()
        if first and last:
            head = text.index(first + ' linestart')
            tail = text.index(last + '-1c lineend +1c')
        else:
            head = text.index('insert linestart')
            tail = text.index('insert lineend +1c')
        chars = text.get(head, tail)
        lines = chars.split('\n')
        return (
         head, tail, chars, lines)

    def set_region(self, head, tail, chars, lines):
        text = self.text
        newchars = '\n'.join(lines)
        if newchars == chars:
            text.bell()
            return
        text.tag_remove('sel', '1.0', 'end')
        text.mark_set('insert', head)
        text.undo_block_start()
        text.delete(head, tail)
        text.insert(head, newchars)
        text.undo_block_stop()
        text.tag_add('sel', head, 'insert')

    def _make_blanks(self, n):
        if self.usetabs:
            ntabs, nspaces = divmod(n, self.tabwidth)
            return '\t' * ntabs + ' ' * nspaces
        else:
            return ' ' * n

    def reindent_to(self, column):
        text = self.text
        text.undo_block_start()
        if text.compare('insert linestart', '!=', 'insert'):
            text.delete('insert linestart', 'insert')
        if column:
            text.insert('insert', self._make_blanks(column))
        text.undo_block_stop()

    def _asktabwidth(self):
        return self.askinteger('Tab width', 'Columns per tab? (2-16)', parent=self.text, initialvalue=self.indentwidth, minvalue=2, maxvalue=16) or self.tabwidth

    def guess_indent(self):
        opener, indented = IndentSearcher(self.text, self.tabwidth).run()
        if opener and indented:
            raw, indentsmall = classifyws(opener, self.tabwidth)
            raw, indentlarge = classifyws(indented, self.tabwidth)
        else:
            indentsmall = indentlarge = 0
        return indentlarge - indentsmall
Example #39
0
class ScriptBinding:

    menudefs = [
        ('run', [
            None,
            ('Check Module', '<<check-module>>'),
            ('Run Module', '<<run-module>>'),
        ]),
    ]

    def __init__(self, editwin):
        self.editwin = editwin
        # Provide instance variables referenced by Debugger
        # XXX This should be done differently
        self.flist = self.editwin.flist
        self.root = self.editwin.root

        if macosxSupport.runningAsOSXApp():
            self.editwin.text_frame.bind('<<run-module-event-2>>',
                                         self._run_module_event)

    def check_module_event(self, event):
        filename = self.getfilename()
        if not filename:
            return 'break'
        if not self.checksyntax(filename):
            return 'break'
        if not self.tabnanny(filename):
            return 'break'

    def tabnanny(self, filename):
        f = open(filename, 'r')
        try:
            tabnanny.process_tokens(tokenize.generate_tokens(f.readline))
        except tokenize.TokenError as msg:
            msgtxt, (lineno, start) = msg
            self.editwin.gotoline(lineno)
            self.errorbox("Tabnanny Tokenizing Error",
                          "Token Error: %s" % msgtxt)
            return False
        except tabnanny.NannyNag as nag:
            # The error messages from tabnanny are too confusing...
            self.editwin.gotoline(nag.get_lineno())
            self.errorbox("Tab/space error", indent_message)
            return False
        return True

    def checksyntax(self, filename):
        self.shell = shell = self.flist.open_shell()
        saved_stream = shell.get_warning_stream()
        shell.set_warning_stream(shell.stderr)
        with open(filename, 'r') as f:
            source = f.read()
        if '\r' in source:
            source = re.sub(r"\r\n", "\n", source)
            source = re.sub(r"\r", "\n", source)
        if source and source[-1] != '\n':
            source = source + '\n'
        text = self.editwin.text
        text.tag_remove("ERROR", "1.0", "end")
        try:
            try:
                # If successful, return the compiled code
                return compile(source, filename, "exec")
            except (SyntaxError, OverflowError, ValueError) as err:
                try:
                    msg, (errorfilename, lineno, offset, line) = err
                    if not errorfilename:
                        err.args = msg, (filename, lineno, offset, line)
                        err.filename = filename
                    self.colorize_syntax_error(msg, lineno, offset)
                except:
                    msg = "*** " + str(err)
                self.errorbox("Syntax error",
                              "There's an error in your program:\n" + msg)
                return False
        finally:
            shell.set_warning_stream(saved_stream)

    def colorize_syntax_error(self, msg, lineno, offset):
        text = self.editwin.text
        pos = "0.0 + %d lines + %d chars" % (lineno - 1, offset - 1)
        text.tag_add("ERROR", pos)
        char = text.get(pos)
        if char and char in IDENTCHARS:
            text.tag_add("ERROR", pos + " wordstart", pos)
        if '\n' == text.get(pos):  # error at line end
            text.mark_set("insert", pos)
        else:
            text.mark_set("insert", pos + "+1c")
        text.see(pos)

    def run_module_event(self, event):
        """Run the module after setting up the environment.

        First check the syntax.  If OK, make sure the shell is active and
        then transfer the arguments, set the run environment's working
        directory to the directory of the module being executed and also
        add that directory to its sys.path if not already included.

        """
        filename = self.getfilename()
        if not filename:
            return 'break'
        code = self.checksyntax(filename)
        if not code:
            return 'break'
        if not self.tabnanny(filename):
            return 'break'
        interp = self.shell.interp
        if PyShell.use_subprocess:
            interp.restart_subprocess(with_cwd=False)
        dirname = os.path.dirname(filename)
        # XXX Too often this discards arguments the user just set...
        interp.runcommand("""if 1:
            __file__ = {filename!r}
            import sys as _sys
            from os.path import basename as _basename
            if (not _sys.argv or
                _basename(_sys.argv[0]) != _basename(__file__)):
                _sys.argv = [__file__]
            import os as _os
            _os.chdir({dirname!r})
            del _sys, _basename, _os
            \n""".format(filename=filename, dirname=dirname))
        interp.prepend_syspath(filename)
        # XXX KBK 03Jul04 When run w/o subprocess, runtime warnings still
        #         go to __stderr__.  With subprocess, they go to the shell.
        #         Need to change streams in PyShell.ModifiedInterpreter.
        interp.runcode(code)
        return 'break'

    if macosxSupport.runningAsOSXApp():
        # Tk-Cocoa in MacOSX is broken until at least
        # Tk 8.5.9, and without this rather
        # crude workaround IDLE would hang when a user
        # tries to run a module using the keyboard shortcut
        # (the menu item works fine).
        _run_module_event = run_module_event

        def run_module_event(self, event):
            self.editwin.text_frame.after(
                200, lambda: self.editwin.text_frame.event_generate(
                    '<<run-module-event-2>>'))
            return 'break'

    def getfilename(self):
        """Get source filename.  If not saved, offer to save (or create) file

        The debugger requires a source file.  Make sure there is one, and that
        the current version of the source buffer has been saved.  If the user
        declines to save or cancels the Save As dialog, return None.

        If the user has configured IDLE for Autosave, the file will be
        silently saved if it already exists and is dirty.

        """
        filename = self.editwin.io.filename
        if not self.editwin.get_saved():
            autosave = idleConf.GetOption('main',
                                          'General',
                                          'autosave',
                                          type='bool')
            if autosave and filename:
                self.editwin.io.save(None)
            else:
                confirm = self.ask_save_dialog()
                self.editwin.text.focus_set()
                if confirm:
                    self.editwin.io.save(None)
                    filename = self.editwin.io.filename
                else:
                    filename = None
        return filename

    def ask_save_dialog(self):
        msg = "Source Must Be Saved\n" + 5 * ' ' + "OK to Save?"
        confirm = tkMessageBox.askokcancel(title="Save Before Run or Check",
                                           message=msg,
                                           default=tkMessageBox.OK,
                                           master=self.editwin.text)
        return confirm

    def errorbox(self, title, message):
        # XXX This should really be a function of EditorWindow...
        tkMessageBox.showerror(title, message, master=self.editwin.text)
        self.editwin.text.focus_set()
Example #40
0
def initialise():
    import sys
    global menudefs
    global default_keydefs

    if menudefs is not None:
        return

    menudefs = [
     # underscore prefixes character to underscore
     ('file', [
       ('Load From...', '<<load-from>>'),
       ('Revert', '<<revert>>'),
       None,
       ('_Save', '<<save-window>>'),
       #('Save _As...', '<<save-window-as-file>>'),
       ('Save Cop_y As...', '<<save-copy-of-window-as-file>>'),
       None,
       ('Prin_t Window', '<<print-window>>'),
       None,
       ('_Close', '<<close-window>>'),
       ('E_xit', '<<close-all-windows>>'),
      ]),
     ('edit', [
       ('_Undo', '<<undo>>'),
       ('_Redo', '<<redo>>'),
       None,
       ('Cu_t', '<<cut>>'),
       ('_Copy', '<<copy>>'),
       ('_Paste', '<<paste>>'),
       ('Select _All', '<<select-all>>'),
       None,
       ('_Find...', '<<find>>'),
       ('Find A_gain', '<<find-again>>'),
       ('Find _Selection', '<<find-selection>>'),
       ('Find in Files...', '<<find-in-files>>'),
       ('R_eplace...', '<<replace>>'),
       ('Go to _Line', '<<goto-line>>'),
      ]),
     ('format', [
       ('_Indent Region', '<<indent-region>>'),
       ('_Dedent Region', '<<dedent-region>>'),
       ('Comment _Out Region', '<<comment-region>>'),
       ('U_ncomment Region', '<<uncomment-region>>'),
       ('Tabify Region', '<<tabify-region>>'),
       ('Untabify Region', '<<untabify-region>>'),
       ('Toggle Tabs', '<<toggle-tabs>>'),
       ('New Indent Width', '<<change-indentwidth>>'),
       ]),
      ('options', [
                ('_Configure IDLE...', '<<open-config-dialog>>'),
       None,
       ]),
      ("check", [
                ("Check    F5", '<<check>>')
                ]),
      ("online", [
                ("Login", '<<login>>'),
                ("Logout", '<<logout>>'),
                ("Change Password", '<<change_password>>'),
                None,
                ("Upload Problem Answer", '<<upload_answer>>'),
                ("Download Problem Answer", '<<download_answer>>'),
                None,
                ("Submit Answer              F6", '<<submit_answer>>'),
                ("Show Submissions", '<<show_submit>>')
                ]),

      ('help', [
       ('_About IDLE', '<<about-idle>>'),
       None,
       ('_IDLE Help', '<<help>>'),
       ('Python _Docs', '<<python-docs>>'),
       None,
       ('About _Tutor', '<<about-tutor>>'),
       ('Tutor Help', '<<help-tutor>>'),
       ]),
    ]

    if macosxSupport.runningAsOSXApp():
        # Running as a proper MacOS application bundle. This block restructures
        # the menus a little to make them conform better to the HIG.

        quitItem = menudefs[0][1][-1]
        closeItem = menudefs[0][1][-2]

        # Remove the last 3 items of the file menu: a separator, close window and
        # quit. Close window will be reinserted just above the save item, where
        # it should be according to the HIG. Quit is in the application menu.
        del menudefs[0][1][-3:]
        menudefs[0][1].insert(6, closeItem)

        # Remove the 'About' entry from the help menu, it is in the application
        # menu
        del menudefs[-1][1][0:2]

        menudefs.insert(0,
                        ('application', [
                            ('About IDLE', '<<about-idle>>'),
                            None,
                            ('_Preferences....', '<<open-config-dialog>>'),
                        ]))

    default_keydefs = idleConf.GetCurrentKeySet()
Example #41
0
def initialise():
    import sys
    global menudefs
    global default_keydefs

    if menudefs is not None:
        return

    menudefs = [
        # underscore prefixes character to underscore
        (
            'file',
            [
                ('Load From...', '<<load-from>>'),
                ('Revert', '<<revert>>'),
                None,
                ('_Save', '<<save-window>>'),
                #('Save _As...', '<<save-window-as-file>>'),
                ('Save Cop_y As...', '<<save-copy-of-window-as-file>>'),
                None,
                ('Prin_t Window', '<<print-window>>'),
                None,
                ('_Close', '<<close-window>>'),
                ('E_xit', '<<close-all-windows>>'),
            ]),
        ('edit', [
            ('_Undo', '<<undo>>'),
            ('_Redo', '<<redo>>'),
            None,
            ('Cu_t', '<<cut>>'),
            ('_Copy', '<<copy>>'),
            ('_Paste', '<<paste>>'),
            ('Select _All', '<<select-all>>'),
            None,
            ('_Find...', '<<find>>'),
            ('Find A_gain', '<<find-again>>'),
            ('Find _Selection', '<<find-selection>>'),
            ('Find in Files...', '<<find-in-files>>'),
            ('R_eplace...', '<<replace>>'),
            ('Go to _Line', '<<goto-line>>'),
        ]),
        ('format', [
            ('_Indent Region', '<<indent-region>>'),
            ('_Dedent Region', '<<dedent-region>>'),
            ('Comment _Out Region', '<<comment-region>>'),
            ('U_ncomment Region', '<<uncomment-region>>'),
            ('Tabify Region', '<<tabify-region>>'),
            ('Untabify Region', '<<untabify-region>>'),
            ('Toggle Tabs', '<<toggle-tabs>>'),
            ('New Indent Width', '<<change-indentwidth>>'),
        ]),
        ('options', [
            ('_Configure IDLE...', '<<open-config-dialog>>'),
            None,
        ]),
        ("check", [("Check    F5", '<<check>>')]),
        ("online", [("Login", '<<login>>'), ("Logout", '<<logout>>'),
                    ("Change Password", '<<change_password>>'), None,
                    ("Upload Problem Answer", '<<upload_answer>>'),
                    ("Download Problem Answer", '<<download_answer>>'), None,
                    ("Submit Answer              F6", '<<submit_answer>>'),
                    ("Show Submissions", '<<show_submit>>')]),
        ('help', [
            ('_About IDLE', '<<about-idle>>'),
            None,
            ('_IDLE Help', '<<help>>'),
            ('Python _Docs', '<<python-docs>>'),
            None,
            ('About _Tutor', '<<about-tutor>>'),
            ('Tutor Help', '<<help-tutor>>'),
        ]),
    ]

    if macosxSupport.runningAsOSXApp():
        # Running as a proper MacOS application bundle. This block restructures
        # the menus a little to make them conform better to the HIG.

        quitItem = menudefs[0][1][-1]
        closeItem = menudefs[0][1][-2]

        # Remove the last 3 items of the file menu: a separator, close window and
        # quit. Close window will be reinserted just above the save item, where
        # it should be according to the HIG. Quit is in the application menu.
        del menudefs[0][1][-3:]
        menudefs[0][1].insert(6, closeItem)

        # Remove the 'About' entry from the help menu, it is in the application
        # menu
        del menudefs[-1][1][0:2]

        menudefs.insert(0, ('application', [
            ('About IDLE', '<<about-idle>>'),
            None,
            ('_Preferences....', '<<open-config-dialog>>'),
        ]))

    default_keydefs = idleConf.GetCurrentKeySet()