Anonymous avatar Anonymous committed d4cbddf

Moved rope.ui to ropeide

Comments (0)

Files changed (69)

 #! /usr/bin/python
-import rope.ui.core
+import ropeide.core
 
 
 if __name__ == '__main__':
-    rope.ui.core.Core.get_core().run()
+    ropeide.core.Core.get_core().run()

rope/ui/__init__.py

-"""rope UI package
-
-This package contains a sample GUI that uses rope core
-parts.  Currently it uses `Tkinter` but in future this will
-probably change.  The UI modules use other rope packages
-such as `rope.base`, `rope.refactor` and `rope.ide`.
-
-Note that there might be some modules that do not rely on
-the GUI library.  These modules can be moved to
-`rope.ide` package if they are general enough so that if
-we plan to use an new graphical library (maybe wxpython) we
-can reuse those modules.
-
-"""

rope/ui/actionhelpers.py

-import threading
-
-import Tkinter
-
-import rope.base.project
-import rope.refactor.change_signature
-import rope.ui.uihelpers
-import rope.base.taskhandle
-
-
-class StoppableTaskRunner(object):
-
-    def __init__(self, task, title='Task', interrupts=True):
-        """Task is a function that takes a `TaskHandle`"""
-        self.task = task
-        self.title = title
-        self.interrupts = interrupts
-
-    def __call__(self):
-        handle = rope.base.taskhandle.TaskHandle(self.title,
-                                                 interrupts=self.interrupts)
-        toplevel = Tkinter.Toplevel()
-        toplevel.title('Performing Task ' + self.title)
-        frame = Tkinter.Frame(toplevel)
-        progress = rope.ui.uihelpers.ProgressBar(frame)
-        def update_progress():
-            jobset = handle.current_jobset()
-            if jobset:
-                text = ''
-                if jobset.get_name() is not None:
-                    text += jobset.get_name()
-                if jobset.get_active_job_name() is not None:
-                    text += ' : ' + jobset.get_active_job_name()
-                progress.set_text(text)
-                percent = jobset.get_percent_done()
-                if percent is not None:
-                    progress.set_done_percent(percent)
-        handle.add_observer(update_progress)
-        class Calculate(object):
-
-            def __init__(self, task):
-                self.task = task
-                self.result = None
-                self.exception = None
-
-            def __call__(self):
-                toplevel.bind('<<dont_wait_here>>', self._quit)
-                try:
-                    self.result = self.task(handle)
-                except Exception, e:
-                    self.exception = e
-                finally:
-                    toplevel.event_generate('<<dont_wait_here>>')
-
-            def _quit(self, event):
-                toplevel.quit()
-
-        calculate = Calculate(self.task)
-        def stop(event=None):
-            handle.stop()
-        frame.grid(row=0)
-        stop_button = Tkinter.Button(toplevel, text='Stop',
-                                     command=stop, width=20)
-        toplevel.bind('<Control-g>', stop)
-        toplevel.bind('<Escape>', stop)
-        stop_button.grid(row=1)
-
-        toplevel.grab_set()
-        stop_button.focus_set()
-        thread = threading.Thread(target=calculate)
-        thread.start()
-        toplevel.mainloop()
-        toplevel.destroy()
-        if calculate.exception is not None:
-            description = type(calculate.exception).__name__ + ': ' + \
-                          str(calculate.exception)
-            raise rope.base.exceptions.InterruptedTaskError(
-                'Task <%s> was interrupted.\nReason: <%s>' %
-                (self.title, description))
-        return calculate.result
-
-def simple_stoppable(description, interrupts=True):
-    def decorator(function):
-        def caller():
-            def do_call(handle):
-                return function(handle)
-            return StoppableTaskRunner(do_call, description,
-                                       interrupts=interrupts)()
-        return caller
-    return decorator
-
-
-def check_project(core):
-    if core.project is rope.base.project.get_no_project():
-        core._report_error(message='Open a project first!',
-                           title='No Open Project')
-        return False
-    return True
-
-
-class ConfirmEditorsAreSaved(object):
-
-    def __init__(self, callback, all=True):
-        self.callback = callback
-        self.all = all
-
-    def __call__(self, context):
-        fileeditor = context.fileeditor
-        if self.all:
-            editors = context.get_core().get_editor_manager().editors
-        else:
-            editors = [context.fileeditor]
-        is_modified = False
-        for editor in editors:
-            if editor.get_editor().is_modified():
-                is_modified = True
-                break
-        if not is_modified:
-            return self.callback(context)
-        toplevel = Tkinter.Toplevel()
-        toplevel.title('Save All')
-        frame = Tkinter.Frame(toplevel)
-        message = 'These editors should be saved before performing this action:\n* '
-        label = Tkinter.Label(frame, text=message +
-                              '\n* '.join([fileeditor.file.path
-                                           for fileeditor in editors]))
-        label.grid(row=0, column=0, columnspan=2)
-        def ok(event=None):
-            context.get_core().save_all_editors()
-            toplevel.destroy()
-            self.callback(context)
-        def cancel(event=None):
-            toplevel.destroy()
-        ok_button = Tkinter.Button(frame, text='Save All',
-                                   command=ok, width=10)
-        cancel_button = Tkinter.Button(frame, text='Cancel',
-                                       command=cancel, width=10)
-        ok_button.grid(row=1, column=0)
-        toplevel.bind('<Return>', lambda event: ok())
-        toplevel.bind('<Escape>', lambda event: cancel())
-        toplevel.bind('<Control-g>', lambda event: cancel())
-        cancel_button.grid(row=1, column=1)
-        frame.grid()
-        ok_button.focus_set()

rope/ui/core.py

-import os
-import imp
-
-import tkFileDialog
-from Tkinter import *
-
-import rope.ui.editor
-import rope.ui.editorpile
-import rope.ui.keybinder
-import rope.ui.statusbar
-from rope.base.exceptions import RopeError
-from rope.base.project import Project, get_no_project
-from rope.ui import editingcontexts, registers
-from rope.ui.extension import ActionContext
-from rope.ui.menubar import MenuBarManager
-import rope.base.prefs
-
-
-class Core(object):
-    """The Core of the IDE"""
-
-    def __init__(self):
-        self.rebound_keys = {}
-        self.actions = []
-        self.prefs = rope.base.prefs.Prefs()
-        self.last_action = None
-        self.registers = registers.Registers()
-        self.menu_cascades = []
-        self.project = get_no_project()
-        self.extension_modules = []
-        editingcontexts.init_contexts(self)
-
-    def _init_x(self):
-        self.root = Tk()
-        self.root.title('ropeide')
-
-        self.main = Frame(self.root, height='13c', width='26c', relief=RIDGE, bd=2)
-        self.editor_panel = Frame(self.main, borderwidth=0)
-        self.status_bar = Frame(self.main, borderwidth=1, relief=RIDGE)
-
-        self.status_bar_manager = rope.ui.statusbar.StatusBarManager(
-            self.status_bar, font=self.prefs.get('statusbar_font', None))
-        buffer_status = self.status_bar_manager.create_status('buffer')
-        buffer_status.set_width(40)
-        self.editor_manager = rope.ui.editorpile.EditorPile(
-            self.editor_panel, self, buffer_status,
-            font=self.prefs.get('editorlist_font', None))
-
-        line_status = self.status_bar_manager.create_status('line')
-        line_status.set_width(8)
-
-        for context in editingcontexts.contexts.values():
-            context.key_binding = rope.ui.keybinder.KeyBinder(
-                self.status_bar_manager,
-                prefix=self.prefs.get('action_prefix', None))
-        self.root.protocol('WM_DELETE_WINDOW', self._close_project_and_exit)
-
-    def add_extension(self, module_name):
-        """Add an extension module
-
-        `module_name` is the name of the module.  Rope imports that
-        module when it loads extensions.  Should use
-        `Core.register_action()` for registering actions in extension
-        modules.
-
-        """
-        self.extension_modules.append(module_name)
-
-    def _load_actions(self):
-        """Load extension modules
-
-        The modules that are loaded here use `Core.register_action()`
-        to register their `Action`\s.
-        """
-        for module_name in self.extension_modules:
-            __import__(module_name)
-
-    def set(self, key, value):
-        """Set a preference
-
-        Set the preference for `key` to `value`.
-        """
-        self.prefs.set(key, value)
-
-    def add(self, key, value):
-        """Add an entry to a list preference
-
-        Add `value` to the list of entries for the `key` preference.
-
-        """
-        self.prefs.add(key, value)
-
-    def get_prefs(self):
-        """Return a `rope.ui.pref.Prefs` object"""
-        return self.prefs
-
-    def add_menu_cascade(self, menu_address, active_contexts):
-        active_contexts = self._get_matching_contexts(active_contexts)
-        self.menu_cascades.append((menu_address, active_contexts))
-
-    def _close_project_and_exit(self):
-        self._close_project_dialog(exit_=True)
-
-    def _init_key_binding(self):
-        line_status = self.status_bar_manager.get_status('line')
-        def show_current_line_number(event):
-            line_text = ' '
-            if self.editor_manager.active_editor:
-                editor = self.editor_manager.active_editor.get_editor()
-                line_text = '%d: %d' % (editor.get_current_line_number(),
-                                        editor.get_current_column_number())
-            line_status.set_text(line_text)
-        self.root.bind('<Any-KeyRelease>', show_current_line_number)
-        self.root.bind('<Any-Button>', show_current_line_number)
-        self.root.bind('<FocusIn>', show_current_line_number)
-        for action in self.actions:
-            callback = self._make_callback(action)
-            key = self._get_action_key(action)
-            if key:
-                self._bind_key(key, callback, action.get_active_contexts())
-
-    def _get_action_key(self, action):
-        key = action.get_default_key()
-        if action.get_name() in self.rebound_keys:
-            key = self.rebound_keys[action.get_name()]
-        return key
-
-    def _init_menus(self):
-        font = self.prefs.get('menu_font', None)
-        for context in editingcontexts.contexts.values():
-            context.menu = Menu(self.root, relief=RAISED, borderwidth=1)
-            if font:
-                context.menu['font'] = font
-            context.menu_manager = MenuBarManager(context.menu)
-        for menu_address, contexts in self.menu_cascades:
-            for context in contexts:
-                context.menu_manager.add_menu_cascade(menu_address)
-        for action in self.actions:
-            callback = self._make_callback(action)
-            menu = action.get_menu()
-            key = self._get_action_key(action)
-            if menu:
-                if key:
-                    menu.address[-1] = menu.address[-1].ljust(32) + key
-                self._add_menu_command(menu, callback,
-                                       action.get_active_contexts())
-        self._editor_changed()
-
-    def _bind_none_context_keys(self):
-        context = editingcontexts.none
-        context.key_binding.bind(self.root)
-
-    def _get_matching_contexts(self, contexts):
-        result = set()
-        for name in self._get_matching_context_names(contexts):
-            if name in editingcontexts.contexts:
-                result.add(editingcontexts.contexts[name])
-        return result
-
-    def _get_matching_context_names(self, contexts):
-        contexts = set(contexts)
-        result = set()
-        if 'all' in contexts:
-            contexts.remove('all')
-            for name in editingcontexts.contexts.keys():
-                if name != 'none':
-                    result.add(name)
-        for name in contexts:
-                result.add(name)
-        return result
-
-    def _bind_key(self, key, function, active_contexts=['all']):
-        active_contexts = self._get_matching_contexts(active_contexts)
-        for context in active_contexts:
-            context.key_binding.add_key(key, function)
-
-    def _set_key_binding(self, graphical_editor):
-        context = graphical_editor.get_editing_context()
-        context.key_binding.bind(graphical_editor.getWidget())
-
-    def _close_active_editor_dialog(self):
-        active_editor = self.editor_manager.active_editor
-        if not active_editor:
-            return
-        if not active_editor.get_editor().is_modified():
-            return self.close_active_editor()
-        toplevel = Toplevel()
-        toplevel.title('Killing Unsaved Buffer')
-        label = Label(toplevel, text='Killing Unsaved Buffer <%s>' %
-                      active_editor.get_file().path)
-        def save():
-            active_editor.save()
-            self.close_active_editor()
-            toplevel.destroy()
-        def dont_save():
-            self.close_active_editor()
-            toplevel.destroy()
-        def cancel(event=None):
-            toplevel.destroy()
-        save_button = Button(toplevel, text='Save', command=save)
-        dont_save_button = Button(toplevel, text="Don't Save", command=dont_save)
-        cancel_button = Button(toplevel, text='Cancel', command=cancel)
-        toplevel.bind('<Control-g>', cancel)
-        toplevel.bind('<Escape>', cancel)
-        label.grid(row=0, column=0, columnspan=3)
-        save_button.grid(row=1, column=0)
-        dont_save_button.grid(row=1, column=1)
-        cancel_button.grid(row=1, column=2)
-        save_button.focus_set()
-
-    def run(self):
-        self.add_extension('rope.ui.fileactions')
-        self.add_extension('rope.ui.editactions')
-        self.add_extension('rope.ui.sourceactions')
-        self.add_extension('rope.ui.refactor')
-        self.add_extension('rope.ui.helpactions')
-        self._load_dot_rope()
-        self._load_actions()
-        self._init_x()
-        self._init_key_binding()
-        self._bind_none_context_keys()
-        self._init_menus()
-        self.editor_manager.show(self.prefs.get('show_buffer_list', True))
-        self.root.rowconfigure(0, weight=1)
-        self.root.columnconfigure(0, weight=1)
-        self.main.rowconfigure(0, weight=1)
-        self.main.columnconfigure(0, weight=1)
-        self.editor_panel.pack(fill=BOTH, expand=1)
-        if self.prefs.get('show_status_bar', True):
-            self.status_bar.pack(fill=BOTH, side=BOTTOM)
-        self.main.pack(fill=BOTH, expand=1)
-        self.main.pack_propagate(0)
-        self.root.mainloop()
-
-    def _load_dot_rope(self):
-        dot_rope = os.path.expanduser('~%s.rope' % os.path.sep)
-        try:
-            if not os.path.exists(dot_rope):
-                write_dot_rope(dot_rope)
-            run_globals = {}
-            run_globals.update({'__name__': '__main__',
-                                '__builtins__': __builtins__,
-                                '__file__': dot_rope})
-            execfile(dot_rope, run_globals)
-            if 'starting_rope' in run_globals:
-                run_globals['starting_rope'](self)
-        except IOError, e:
-            print 'Unable to load <~.rope> file: ' + e
-
-    def open_file(self, file_name):
-        if self.project is get_no_project():
-            raise RopeError('No project is open')
-        file_ = self.project.get_resource(file_name)
-        return self.editor_manager.get_resource_editor(file_)
-
-    def activate_editor(self, editor):
-        self.editor_manager.activate_editor(editor)
-
-    def close_active_editor(self):
-        self.editor_manager.close_active_editor()
-
-    def save_active_editor(self):
-        active_editor = self.editor_manager.active_editor
-        if active_editor:
-            active_editor.save()
-
-    def save_all_editors(self):
-        for editor in self.editor_manager.editors:
-            editor.save()
-
-    def create_file(self, file_name):
-        if self.project is  get_no_project():
-            raise RopeError('No project is open')
-        try:
-            last_slash = file_name.rindex('/')
-            parent = project.get_resource(file_name[: last_slash])
-            file_name = file_name[last_slash + 1:]
-        except ValueError:
-            parent = self.project.root
-        parent.create_file(file_name)
-        return self.open_file(file_name)
-
-    def open_project(self, project_root):
-        if self.project:
-            self.close_project()
-        ropefolder = self.prefs.get('project_rope_folder', '.ropeproject')
-        self.project = Project(project_root, ropefolder=ropefolder)
-
-    def _close_project_dialog(self, exit_=False):
-        modified_editors = [editor for editor in self.editor_manager.editors
-                            if editor.get_editor().is_modified()]
-        if not modified_editors:
-            self.close_project()
-            if exit_:
-                self.exit()
-            return
-        toplevel = Toplevel()
-        toplevel.title('Closing Project')
-        label = Label(toplevel, text='Which modified editors to save?')
-        label.grid(row=0, columnspan=2)
-        int_vars = []
-        for i, editor in enumerate(modified_editors):
-            int_var = IntVar()
-            button = Checkbutton(toplevel, text=editor.get_file().path,
-                                 variable=int_var, onvalue=1, offvalue=0)
-            int_vars.append(int_var)
-            button.grid(row=i+1, columnspan=2)
-        def done():
-            for editor, int_var in zip(modified_editors, int_vars):
-                if int_var.get() == 1:
-                    editor.save()
-            self.close_project()
-            toplevel.destroy()
-            if exit_:
-                self.exit()
-        def cancel():
-            toplevel.destroy()
-        done_button = Button(toplevel, text='Done', command=done)
-        done_button.grid(row=len(int_vars) + 1, column=0)
-        cancel_button = Button(toplevel, text='Cancel', command=cancel)
-        toplevel.bind('<Escape>', lambda event: cancel())
-        toplevel.bind('<Control-g>', lambda event: cancel())
-        toplevel.bind('<Return>', lambda event: done())
-        cancel_button.grid(row=len(int_vars) + 1, column=1)
-
-    def close_project(self):
-        while self.editor_manager.active_editor is not None:
-            self.close_active_editor()
-        self.project.close()
-        self.registers.project_closed()
-        self.project = get_no_project()
-
-    def create_folder(self, folder_name):
-        try:
-            last_slash = folder_name.rindex('/')
-            parent = project.get_resource(folder_name[:last_slash])
-            folder_name = folder_name[last_slash + 1:]
-        except ValueError:
-            parent = self.project.root
-        parent.create_folder(folder_name)
-
-    def exit(self):
-        self.root.quit()
-
-    def get_open_project(self):
-        return self.project
-
-    def switch_active_editor(self):
-        self.editor_manager.switch_active_editor()
-
-    def get_active_editor(self):
-        return self.editor_manager.active_editor
-
-    def get_editor_manager(self):
-        return self.editor_manager
-
-    def register_action(self, action):
-        """Register a `rope.ui.extension.Action`"""
-        self.actions.append(action)
-
-    def rebind_action(self, name, key):
-        self.rebound_keys[name] = key
-
-    def _add_menu_command(self, menu, callback, active_contexts):
-        active_contexts = self._get_matching_contexts(active_contexts)
-        for context in active_contexts:
-            context.menu_manager.add_menu_command(menu, callback)
-
-    def _make_callback(self, action):
-        def callback(prefix=None):
-            try:
-                action.do(ActionContext(self, prefix))
-                if action.get_name() != 'repeat_last_action':
-                    self.last_action = action
-            except RopeError, e:
-                self._report_error(e, type(e).__name__)
-        return callback
-
-    def perform_action(self, action):
-        self._make_callback(action)()
-
-    def repeat_last_action(self):
-        if self.last_action is not None:
-            self.perform_action(self.last_action)
-
-    def _report_error(self, message, title='RopeError Was Raised'):
-        toplevel = Toplevel()
-        toplevel.title(title)
-        label = Label(toplevel, text=str(message))
-        def ok(event=None):
-            toplevel.destroy()
-            return 'break'
-        ok_button = Button(toplevel, text='OK', command=ok, width=15)
-        label.grid(row=0)
-        toplevel.bind('<Control-g>', lambda event: ok())
-        toplevel.bind('<Escape>', lambda event: ok())
-        toplevel.bind('<Return>', lambda event: ok())
-        ok_button.grid(row=1)
-        toplevel.grab_set()
-        ok_button.focus_set()
-
-    def _editor_changed(self):
-        active_editor = self.editor_manager.active_editor
-        if not self.prefs.get('show_menu_bar', True):
-            self.root['menu'] = None
-            return
-        if active_editor:
-            self.root['menu'] = active_editor.get_editor().get_editing_context().menu
-        else:
-            self.root['menu'] = editingcontexts.none.menu
-
-    def get_available_actions(self):
-        """Return applicable actions in current context"""
-        context = 'none'
-        active_editor = self.editor_manager.active_editor
-        if active_editor:
-            context = active_editor.get_editor().get_editing_context().name
-        for action in self.actions:
-            action_contexts = self._get_matching_context_names(
-                action.get_active_contexts())
-            if context in action_contexts:
-                yield action
-
-    _core = None
-
-    @staticmethod
-    def get_core():
-        """Get the singleton instance of Core"""
-        result = Core._core
-        if result is None:
-            result = Core._core = Core()
-        return result
-
-
-def get_core():
-    return Core.get_core()
-
-
-def write_dot_rope(dot_rope):
-    import rope.ui.dot_rope
-    import inspect
-    text = inspect.getsource(rope.ui.dot_rope)
-    output = open(dot_rope, 'w')
-    output.write(text)
-    output.close()

rope/ui/dot_rope.py

-# The default ~/.rope file for *rope*.
-#
-# You can edit this file to change some of rope's preferences.  If
-# you like you can edit this file using rope itself.
-# (``edit_dot_rope`` in execute command or ``Edit ~/.rope`` in
-# ``Edit`` menu.)
-#
-# Note: Since this file is not inside a project you cannot perform
-#   refactorings on it.
-#
-
-
-def starting_rope(core):
-    """Change rope preferences.
-
-    This function is called when rope starts.
-
-    """
-
-    # Changing editor font
-    #core.set('font', ('Courier', 16))
-    #core.set('font', ('Bitstream Vera Sans Mono', 16))
-
-    # Changing font for other parts
-    core.set('menu_font', ('Courier', 12, 'bold'))
-    core.set('statusbar_font', ('Courier', 12))
-    core.set('editorlist_font', ('Courier', 12))
-
-    # Hiding menu bar
-    #core.set('show_menu_bar', False)
-
-    # Hiding buffer list
-    #core.set('show_buffer_list', False)
-
-    # Hiding status bar
-    #core.set('show_status_bar', False)
-
-
-    # If you don't like emacs keybindings, change this to False
-    i_like_emacs = True
-    if not i_like_emacs:
-        _change_to_nonemacs_keybinding(core)
-
-    # The key used for prefixing actions
-    #core.set('action_prefix', 'C-u')
-
-
-    # Add your python templates
-    core.add('templates', ('say_hello', "print 'Hello, my name is ${name}'\n"))
-    core.add('templates', ('set_field', "self.${field}${cursor} = ${field}\n"))
-
-
-    # The folder relative to project root that holds config files and
-    # information about the project.  If this folder does not exist it is
-    # created.  Specifying `None` means do not make and use a rope folder.
-    #core.set('project_rope_folder', '.ropeproject')
-
-    # You can register your own actions
-    _register_my_actions(core)
-
-
-def _register_my_actions(core):
-    # Adding your own `Action`\s:
-    # If you're interested in adding your own actions to rope you can do so
-    # like this.
-    # Plugins can use this interface for registering their actions.  For
-    # more information see `rope.ui.extension` module.
-    from rope.ui.extension import SimpleAction
-
-    def say_hello(context):
-        print('Hello Action!')
-
-    hello_action = SimpleAction('hello_action', say_hello, 'C-h h')
-    core.register_action(hello_action)
-
-    # A more advanced example that uses `Tkinter`
-    def rope_info(context):
-        import gc
-        import Tkinter
-        import rope.base.pyobjects
-
-        info = 'Rope Running Info\n=================\n\n'
-        info += 'Rope version %s\n\n' % rope.VERSION
-        info += str(context.project.history) + '\n'
-        module_count = 0
-        for obj in gc.get_objects():
-            # Checking the real type; not isinstance
-            if type(obj) in (rope.base.pyobjects.PyModule,
-                             rope.base.pyobjects.PyPackage):
-                module_count += 1
-        info += 'Memory contains %s PyModules\n' % module_count
-        info += str(context.project.pycore) + '\n'
-
-        toplevel = Tkinter.Toplevel()
-        toplevel.title('Rope Running Info')
-        label = Tkinter.Label(toplevel, text=info, height=10, width=50,
-                              justify=Tkinter.LEFT, relief=Tkinter.GROOVE)
-        label.grid(row=0)
-        def ok():
-            toplevel.destroy()
-        ok_button = Tkinter.Button(toplevel, text='OK', command=ok, width=20)
-        ok_button.grid(row=1)
-        ok_button.focus_set()
-        toplevel.bind('<Escape>', lambda event: ok())
-        toplevel.bind('<Control-g>', lambda event: ok())
-        toplevel.bind('<Return>', lambda event: ok())
-
-    info_action = SimpleAction('rope_info', rope_info, 'C-h i')
-    core.register_action(info_action)
-
-    # Alternatively you can put your actions in an extension module
-    # and register the module using `Core.add_extension()`.  When
-    # rope starts it loads all extension modules.  You should register
-    # your actions when the module is loading
-    #core.add_extension('my.extension.module')
-
-
-def _change_to_nonemacs_keybinding(core):
-    # file actions
-    core.rebind_action('open_project', 'C-P')
-    core.rebind_action('close_project', None)
-    core.rebind_action('create_file', None)
-    core.rebind_action('create_folder', None)
-    core.rebind_action('create_module', None)
-    core.rebind_action('create_package', None)
-    core.rebind_action('project_tree', 'M-Q r')
-    core.rebind_action('validate_project', 'F5')
-    core.rebind_action('edit_project_config', None)
-    core.rebind_action('sync_project', None)
-    core.rebind_action('find_file', 'C-R')
-    core.rebind_action('find_type', 'C-T')
-    core.rebind_action('change_buffer', 'C-E')
-    core.rebind_action('save_buffer', 'C-s')
-    core.rebind_action('save_all_buffers', 'C-S')
-    core.rebind_action('close_buffer', 'C-w')
-    core.rebind_action('exit', 'C-W')
-
-    core.rebind_action('undo_project', 'C-Z')
-    core.rebind_action('redo_project', 'C-Y')
-    core.rebind_action('project_history', None)
-    core.rebind_action('current_file_history', None)
-
-    # edit actions
-    core.rebind_action('set_mark', None)
-    core.rebind_action('copy', 'C-c')
-    core.rebind_action('cut', 'C-x')
-    core.rebind_action('paste', 'C-v')
-    core.rebind_action('yank', None)
-    core.rebind_action('goto_line', 'C-l')
-    core.rebind_action('goto_last_edit_location', 'C-q')
-    core.rebind_action('swap_mark_and_insert', None)
-    core.rebind_action('undo', 'C-z')
-    core.rebind_action('redo', 'C-y')
-    core.rebind_action('repeat_last_action', None)
-    core.rebind_action('search_forward', 'C-f')
-    core.rebind_action('search_backward', 'C-F')
-    core.rebind_action('edit_dot_rope', None)
-    core.rebind_action('execute_command', None)
-
-    # source actions
-    core.rebind_action('correct_line_indentation', 'C-i')
-    core.rebind_action('show_codetags', None)
-    core.rebind_action('show_errors', None)
-    core.rebind_action('show_warnings', None)
-    core.rebind_action('show_annotations', None)
-    core.rebind_action('format_code', 'C-F')
-    core.rebind_action('comment_line', 'C-3')
-    core.rebind_action('comment_region', None)
-    core.rebind_action('generate_variable', 'M-G v')
-    core.rebind_action('generate_function', 'M-G f')
-    core.rebind_action('generate_class', 'M-G c')
-    core.rebind_action('generate_module', 'M-G m')
-    core.rebind_action('generate_package', 'M-G g')
-    core.rebind_action('memorize_location', 'M-M m')
-    core.rebind_action('remember_location', 'M-M b')
-    core.rebind_action('memorize_string', 'M-M s')
-    core.rebind_action('remember_string', 'M-M i')
-    core.rebind_action('spellcheck_word', None)
-    core.rebind_action('spellcheck_buffer', None)
-    core.rebind_action('spellcheck_region', None)
-    core.rebind_action('sort_by_alpha', None)
-    core.rebind_action('sort_by_kind', None)
-    core.rebind_action('sort_by_pydoc', None)
-    core.rebind_action('sort_by_underlined', None)
-    core.rebind_action('sort_by_special', None)
-
-    core.rebind_action('code_assist', 'C-space')
-    core.rebind_action('goto_definition', 'F3')
-    core.rebind_action('show_doc', 'F2')
-    core.rebind_action('quick_outline', 'C-o')
-    core.rebind_action('find_occurrences', 'C-G')
-    core.rebind_action('run_module', 'M-X p')
-    core.rebind_action('run_unit_tests', 'M-X t')
-    core.rebind_action('run_soi', 'M-X s')
-
-    # refactorings
-    core.rebind_action('rename', 'M-R')
-    core.rebind_action('move', 'M-V')
-    core.rebind_action('extract_method', 'M-M')
-    core.rebind_action('inline', 'M-I')
-    core.rebind_action('extract_local_variable', 'M-L')
-    core.rebind_action('rename_in_file', None)
-    core.rebind_action('change_signature', 'M-C')
-    core.rebind_action('introduce_factory', None)
-    core.rebind_action('encapsulate_field', None)
-    core.rebind_action('change_occurrences', None)
-    core.rebind_action('local_to_field', None)
-    core.rebind_action('inline_argument_default', None)
-    core.rebind_action('introduce_parameter', None)
-    core.rebind_action('method_object', None)
-    core.rebind_action('module_to_package', None)
-    core.rebind_action('rename_current_module', None)
-    core.rebind_action('move_current_module', None)
-    core.rebind_action('restructure', None)
-    # import actions
-    core.rebind_action('organize_imports', 'C-O')
-    core.rebind_action('expand_star_imports', None)
-    core.rebind_action('relatives_to_absolutes', None)
-    core.rebind_action('froms_to_imports', None)
-    core.rebind_action('handle_long_imports', None)
-
-    # help actions
-    core.rebind_action('readme', None)
-    core.rebind_action('features', None)
-    core.rebind_action('overview', None)
-    core.rebind_action('tutorial', None)
-    core.rebind_action('contributing', None)
-    core.rebind_action('library', None)
-    core.rebind_action('about', None)
-
-    # other actions
-    core.rebind_action('prev_word', 'C-Left')
-    core.rebind_action('next_word', 'C-Right')
-    core.rebind_action('lower_next_word', None)
-    core.rebind_action('upper_next_word', None)
-    core.rebind_action('capitalize_next_word', None)
-    core.rebind_action('goto_center_line', None)
-    core.rebind_action('prev_statement', None)
-    core.rebind_action('next_statement', None)
-    core.rebind_action('prev_scope', 'C-Up')
-    core.rebind_action('next_scope', 'C-Down')

rope/ui/editactions.py

-import os.path
-
-import Tkinter
-
-import rope.base.project
-import rope.ui.core
-from rope.ui import uihelpers, fill
-from rope.ui.extension import SimpleAction
-from rope.ui.menubar import MenuAddress
-from rope.ide import movements
-
-
-def set_mark(context):
-    if context.get_active_editor():
-        context.get_active_editor().get_editor().set_mark()
-
-def copy(context):
-    if context.get_active_editor():
-        context.get_active_editor().get_editor().copy_region()
-
-def cut(context):
-    if context.get_active_editor():
-        context.get_active_editor().get_editor().cut_region()
-
-def paste(context):
-    if context.get_active_editor():
-        context.get_active_editor().get_editor().paste()
-
-
-class Yank(object):
-
-    _yank_count = 0
-
-    def __call__(self, context):
-        last_command = context.core.last_action
-        if last_command is None or last_command.get_name() not in ['paste', 'yank']:
-            return
-        if last_command.get_name() == 'paste':
-            self._yank_count = 1
-        if last_command.get_name() == 'yank':
-            self._yank_count += 1
-        if context.get_active_editor():
-            context.get_active_editor().get_editor().yank(self._yank_count)
-
-
-class FillParagraph(object):
-
-    def __init__(self):
-        self.fill = fill.Fill()
-
-    def __call__(self, context):
-        text = context.editor.get_text()
-        offset = context.editor.get_current_offset()
-        start, end, filled = self.fill.fill_paragraph(text, offset)
-        if text[start:end] != filled:
-            start_index = context.editor.get_index(start)
-            end_index = context.editor.get_index(end)
-            context.editor.delete(start_index, end_index)
-            context.editor.insert(start_index, filled)
-            context.editor.set_insert(context.editor.get_index(offset))
-
-
-def undo_editing(context):
-    if context.get_active_editor():
-        context.get_active_editor().get_editor().undo()
-
-def redo_editing(context):
-    if context.get_active_editor():
-        context.get_active_editor().get_editor().redo()
-
-def forward_search(context):
-    if context.get_active_editor():
-        context.get_active_editor().get_editor().start_searching(True)
-
-def backward_search(context):
-    if context.get_active_editor():
-        context.get_active_editor().get_editor().start_searching(False)
-
-def goto_line(context):
-    if not context.get_active_editor():
-        return
-    editor = context.get_active_editor().get_editor()
-    toplevel = Tkinter.Toplevel()
-    toplevel.title('Goto Line')
-    label = Tkinter.Label(toplevel, text='Line Number :')
-    line_entry = Tkinter.Entry(toplevel)
-    label.grid(row=0, column=0)
-    line_entry.grid(row=0, column=1)
-    def cancel(event=None):
-        toplevel.destroy()
-    def ok(event=None):
-        editor.goto_line(int(line_entry.get()))
-        toplevel.destroy()
-    line_entry.bind('<Return>', ok)
-    line_entry.bind('<Control-g>', cancel)
-    line_entry.bind('<Escape>', cancel)
-    toplevel.grid()
-    line_entry.focus_set()
-
-def goto_last_edit_location(context):
-    context.get_core().get_editor_manager().goto_last_edit_location()
-
-
-def swap_mark_and_insert(context):
-    context.editor.swap_mark_and_insert()
-
-
-def edit_dot_rope(context):
-    resource = rope.base.project.get_no_project().get_resource(
-        os.path.expanduser('~%s.rope' % os.path.sep))
-    editor_manager = context.get_core().get_editor_manager()
-    editor_manager.get_resource_editor(resource, mode='python')
-
-def repeat_last_action(context):
-    if context.get_active_editor():
-        context.core.repeat_last_action()
-
-
-class FindCommandHandle(uihelpers.FindItemHandle):
-
-    def __init__(self, core):
-        self.core = core
-        self.matcher = uihelpers.HelperMatcher(
-            list(self.core.get_available_actions()),
-            uihelpers.DoesMatch(self._to_search_text))
-
-    def _to_search_text(self, action):
-        return action.get_name()
-
-    def find_matches(self, starting):
-        return self.matcher.find_matches(starting)
-
-    def selected(self, action):
-        self.core.perform_action(action)
-
-    def to_string(self, action):
-        return action.get_name()
-
-    def to_name(self, action):
-        return self.to_string(action)
-
-
-def execute_command(context):
-    uihelpers.find_item_dialog(
-        FindCommandHandle(context.core), 'Execute Command',
-        'Matched Commands', height=10, width=25)
-
-
-def next_word(context):
-    context.editor.next_word()
-
-def prev_word(context):
-    context.editor.prev_word()
-
-def delete_next_word(context):
-    context.editor.delete_next_word()
-
-def delete_prev_word(context):
-    context.editor.delete_prev_word()
-
-def lower_word(context):
-    context.editor.lower_next_word()
-
-def upper_word(context):
-    context.editor.upper_next_word()
-
-def capitalize_word(context):
-    context.editor.capitalize_next_word()
-
-def goto_center_line(context):
-    context.editor.goto_center_line()
-
-def next_page(context):
-    context.editor.next_page()
-
-def prev_page(context):
-    context.editor.prev_page()
-
-def center_line(context):
-    context.editor.center_line()
-
-def end_of_buffer(context):
-    context.editor.goto_end()
-
-def beginning_of_buffer(context):
-    context.editor.goto_start()
-
-def kill_line(context):
-    append = context.core.last_action.get_name() == 'kill_line'
-    context.editor.kill_line(append=append)
-
-
-class PrevNextElement(object):
-
-    def __init__(self, next=True, element=movements.Statements):
-        self.next = next
-        self.element_type = element
-        self.elements = None
-
-    def __call__(self, context):
-        editor = context.editor
-        text = editor.get_text()
-        if self.elements is None or text != self.elements.source:
-            self.elements = self.element_type(text)
-        offset = editor.get_current_offset()
-        diff = self._new_offset(self.elements, offset) - offset
-        editor.set_insert(editor.get_relative(editor.get_insert(), diff))
-
-    def _new_offset(self, elements, offset):
-        if self.next:
-            return elements.next(offset)
-        else:
-            return elements.prev(offset)
-
-
-core = rope.ui.core.Core.get_core()
-core.add_menu_cascade(MenuAddress(['Edit'], 'e'), ['all', 'none'])
-actions = []
-
-others = MenuAddress(['Edit', 'Others'], 'o', 0)
-core.add_menu_cascade(others, ['all'])
-
-actions.append(SimpleAction('next_word', next_word, 'M-f',
-                            others.child('Next Word'), ['all']))
-actions.append(SimpleAction('prev_word', prev_word, 'M-b',
-                            others.child('Prev Word'), ['all']))
-actions.append(SimpleAction('goto_center_line', goto_center_line, 'M-r',
-                            others.child('Goto Center Line'), ['all']))
-actions.append(SimpleAction('next_page', next_page, 'C-v',
-                            others.child('Next Page'), ['all']))
-actions.append(SimpleAction('prev_page', prev_page, 'M-v',
-                            others.child('Prev Page'), ['all']))
-actions.append(SimpleAction('center_line', center_line, 'C-l',
-                            others.child('Center Line'), ['all']))
-actions.append(SimpleAction('beginning_of_buffer', beginning_of_buffer, 'M-<',
-                            others.child('Beginning Of Buffer'), ['all']))
-actions.append(SimpleAction('end_of_buffer', end_of_buffer, 'M->',
-                            others.child('End Of Buffer'), ['all']))
-
-actions.append(SimpleAction('delete_next_word', delete_next_word, 'M-d',
-                            others.child('Delete Next Word'), ['all']))
-actions.append(SimpleAction('delete_prev_word', delete_prev_word, 'M-BackSpace',
-                            others.child('Delete Prev Word'), ['all']))
-actions.append(SimpleAction('lower_next_word', lower_word, 'M-l',
-                            others.child('Lower Next Word'), ['all']))
-actions.append(SimpleAction('upper_next_word', upper_word, 'M-u',
-                            others.child('Upper Next Word'), ['all']))
-actions.append(SimpleAction('capitalize_next_word', capitalize_word, 'M-c',
-                            others.child('Capitalize Next Word'), ['all']))
-actions.append(SimpleAction('kill_line', kill_line, 'C-k',
-                            others.child('Kill Line'), ['all']))
-actions.append(SimpleAction('next_statement', PrevNextElement(), 'M-e',
-                            others.child('Next Statement'), ['python']))
-actions.append(SimpleAction('prev_statement', PrevNextElement(False), 'M-a',
-                            others.child('Prev Statement'), ['python']))
-actions.append(
-    SimpleAction('next_scope', PrevNextElement(element=movements.Scopes), 'C-M-e',
-                 others.child('Next Scope'), ['python']))
-actions.append(
-    SimpleAction('prev_scope', PrevNextElement(False, movements.Scopes), 'M-C-a',
-                 others.child('Prev Scope'), ['python']))
-
-
-actions.append(SimpleAction('set_mark', set_mark, 'C-space',
-                            MenuAddress(['Edit', 'Set Mark'], 's'), ['all']))
-actions.append(SimpleAction('copy', copy, 'M-w',
-                            MenuAddress(['Edit', 'Copy'], 'c'), ['all']))
-actions.append(SimpleAction('cut', cut, 'C-w',
-                            MenuAddress(['Edit', 'Cut'], 't'), ['all']))
-actions.append(SimpleAction('paste', paste, 'C-y',
-                            MenuAddress(['Edit', 'Paste'], 'p'), ['all']))
-actions.append(SimpleAction('yank', Yank(), 'M-y',
-                            MenuAddress(['Edit', 'Yank'], 'y'), ['all']))
-actions.append(SimpleAction('goto_line', goto_line, 'C-x g',
-                            MenuAddress(['Edit', 'Goto Line'], 'g'), ['all']))
-actions.append(SimpleAction('goto_last_edit_location', goto_last_edit_location, 'C-x C-q',
-                            MenuAddress(['Edit', 'Goto Last Edit Location'], 'e'), ['all', 'none']))
-actions.append(SimpleAction('swap_mark_and_insert', swap_mark_and_insert, 'C-x C-x',
-                            None, ['all']))
-actions.append(SimpleAction('fill_paragraph', FillParagraph(), 'M-q',
-                            MenuAddress(['Edit', 'Fill Paragraph']), ['all']))
-
-actions.append(SimpleAction('undo', undo_editing, 'C-x u',
-                            MenuAddress(['Edit', 'Undo Editing'], 'u', 1), ['all']))
-actions.append(SimpleAction('redo', redo_editing, 'C-x r',
-                            MenuAddress(['Edit', 'Redo Editing'], 'r', 1), ['all']))
-actions.append(SimpleAction('repeat_last_action', repeat_last_action, 'C-x z',
-                            MenuAddress(['Edit', 'Repeat Last Action'], 'l', 1), ['all']))
-actions.append(SimpleAction('search_forward', forward_search, 'C-s',
-                            MenuAddress(['Edit', 'Forward Search'], 'f', 3), ['all']))
-actions.append(SimpleAction('search_backward', backward_search, 'C-r',
-                            MenuAddress(['Edit', 'Backward Search'], 'b', 3), ['all']))
-
-actions.append(SimpleAction('execute_command', execute_command, 'M-x',
-                            MenuAddress(['Edit', 'Execute Command'], 'x', 4), ['all', 'none']))
-actions.append(SimpleAction('edit_dot_rope', edit_dot_rope, 'C-x c',
-                            MenuAddress(['Edit', 'Edit ~/.rope'], '.', 4), ['all', 'none']))
-
-
-for action in actions:
-    core.register_action(action)

rope/ui/editingcontexts.py

-from rope.ui import editingtools
-
-
-class EditingContext(object):
-
-    def __init__(self, name, core):
-        self.core = core
-        self.name = name
-
-    def _get_editing_tools(self):
-        project = self.core.get_open_project()
-        return editingtools.get_editingtools_for_context(
-            self, project, self.core.get_prefs())
-
-    editingtools = property(_get_editing_tools)
-
-contexts = {}
-
-def init_contexts(core):
-    for name in ['python', 'rst', 'others', 'none']:
-        if name not in contexts:
-            context = EditingContext(name, core)
-            globals()[name] = context
-            contexts[name] = context

rope/ui/editingtools.py

-import rope.ide.codeassist
-import rope.refactor.sourceutils
-import rope.ui.highlighter
-import rope.ui.indenter
-
-
-def get_editingtools_for_context(editing_context, project, prefs):
-    if editing_context.name == 'python':
-        return PythonEditingTools(project, prefs)
-    if editing_context.name == 'rst':
-        return ReSTEditingTools()
-    return NormalEditingTools()
-
-
-class EditingTools(object):
-
-    def create_indenter(self, editor):
-        pass
-
-    def create_highlighting(self):
-        pass
-
-
-class PythonEditingTools(EditingTools):
-
-    def __init__(self, project, prefs):
-        self.project = project
-        self.prefs = prefs
-        self._code_assist = None
-        self._outline = None
-
-    def create_indenter(self, editor):
-        indents = rope.refactor.sourceutils.get_indent(self.project.get_pycore())
-        return rope.ui.indenter.PythonCodeIndenter(editor, indents=indents)
-
-    def create_highlighting(self):
-        return rope.ui.highlighter.PythonHighlighting()
-
-
-class ReSTEditingTools(EditingTools):
-
-    def create_indenter(self, editor):
-        return rope.ui.indenter.NormalIndenter(editor)
-
-    def create_highlighting(self):
-        return rope.ui.highlighter.ReSTHighlighting()
-
-
-class NormalEditingTools(EditingTools):
-
-    def create_indenter(self, editor):
-        return rope.ui.indenter.NormalIndenter(editor)
-
-    def create_highlighting(self):
-        return rope.ui.highlighter.NoHighlighting()

rope/ui/editor.py

-import os
-
-import ScrolledText
-import tkFont
-import Tkinter
-from Tkinter import END, TclError, SEL_FIRST, SEL, SEL_LAST, INSERT, Toplevel, Text
-
-import rope.ide.codeassist
-import rope.ui.editingtools
-import rope.ui.searcher
-import rope.ui.tkhelpers
-
-
-class GraphicalEditor(object):
-
-    def __init__(self, parent, editorcontext, font=None):
-        if font is None:
-            if os.name == 'posix':
-                font = tkFont.Font(family='Typewriter', size=14)
-            else:
-                font = tkFont.Font(family='Courier', size=14)
-        self.text = ScrolledText.ScrolledText(
-            parent, bg='white', font=font, undo=True,
-            maxundo=100, highlightcolor='#99A')
-        self.change_inspector = _TextChangeInspector(self, self._text_changed)
-        self.searcher = rope.ui.searcher.Searcher(self)
-        self._set_editingcontexts(editorcontext)
-        self._bind_keys()
-        self.status_bar_manager = None
-        self.modification_observers = []
-        self.change_observers = []
-        self.modified_flag = False
-        self.kill_ring = KillRingManager()
-        self.text.bind('<<Modified>>', self._editor_modified)
-        self.text.edit_modified(False)
-
-    def _text_changed(self):
-        if not self.change_inspector.is_changed():
-            return
-        start, end = self.change_inspector.get_changed_region()
-        self.change_inspector.clear_changed()
-        self._colorize(start, end)
-        if self.modified_flag:
-            for observer in self.change_observers:
-                observer(end)
-
-    def _colorize(self, start, end):
-        start_offset, end_offset = \
-            self.highlighting.get_suspected_region_after_change(
-            self.get_text(), self.get_offset(start), self.get_offset(end))
-        start = self.text.index('1.0 +%dc' % start_offset)
-        end = self.text.index(start + ' +%dc' % (end_offset - start_offset))
-        start_tags = self.text.tag_names(start)
-        if start_tags:
-            tag = start_tags[0]
-            range_ = self.text.tag_prevrange(tag, start + '+1c')
-            if range_ and self.text.compare(range_[0], '<', start):
-                start = range_[0]
-            if range_ and self.text.compare(range_[1], '>', end):
-                end = range_[1]
-        end_tags = self.text.tag_names(end)
-        if end_tags:
-            tag = end_tags[0]
-            range_ = self.text.tag_prevrange(tag, end + '+1c')
-            if range_ and self.text.compare(range_[1], '>', end):
-                end = range_[1]
-        self._highlight_range(start, end)
-
-    def _highlight_range(self, start_index, end_index):
-        for style in self.highlighting.get_styles().keys():
-            self.text.tag_remove(style, start_index, end_index)
-        start_offset = self.get_offset(start_index)
-        end_offset = self.get_offset(end_index)
-        indexer = _OffsetToIndexCacher(self.text)
-        for start, end, kind in self.highlighting.highlights(self.get_text(),
-                                                             start_offset,
-                                                             end_offset):
-            self.text.tag_add(kind, indexer.get_index(start),
-                              indexer.get_index(end))
-
-    def select_range(self, start_index, end_index):
-        self.text.tag_remove(SEL, '1.0', END)
-        self.text.tag_add(SEL, start_index._getIndex(),
-                          end_index._getIndex())
-        self.text.see(start_index._getIndex())
-
-    def _bind_keys(self):
-        def escape(event):
-            self.clear_mark()
-            if self.get_searcher().is_searching():
-                self.get_searcher().cancel_searching()
-        self.text.bind('<Control-g>', escape)
-        self.text.bind('<Escape>', escape)
-        def do_insert_tab(event):
-            self.insert_tab()
-            return 'break'
-        self.text.bind('<Tab>', do_insert_tab)
-        def return_handler(event):
-            if self.searcher.is_searching():
-                self.searcher.end_searching()
-                return 'break'
-            self._insert_new_line()
-            return 'break'
-        def backspace(event):
-            if self.searcher.is_searching():
-                self.searcher.shorten_keyword()
-                return 'break'
-            line_starting = self.text.get('insert linestart', 'insert')
-            current_char = self.text.get(INSERT)
-            if line_starting.isspace() and (not current_char.isspace()
-                                            or current_char == '' or current_char == '\n'):
-                self.indenter.deindent(self.get_current_line_number())
-                return 'break'
-        self.text.bind('<Return>', return_handler)
-        self.text.bind('<Any-KeyPress>', self._search_handler)
-        self.text.bind('<BackSpace>', backspace, '+')
-        self.text.bind('<FocusOut>', lambda event: self._focus_went_out())
-        self.text.bind('<Destroy>', lambda event: self._focus_went_out(False))
-
-    def center_line(self):
-        mid = self._get_center_line()
-        current = self._get_line_from_index(self.text.index(INSERT))
-        diffs = current - mid
-        self.text.yview_scroll(diffs, Tkinter.UNITS)
-
-    def goto_center_line(self):
-        mid = self._get_center_line()
-        self.goto_line(mid)
-
-    def _get_center_line(self):
-        start = self._get_line_from_index(self.text.index('@0,0'))
-        end = self._get_line_from_index(
-            self.text.index('@0,%d' % self.text.winfo_height()))
-        return (start + end) // 2
-
-    def get_region_offset(self):
-        start, end = self._get_region_index()
-        start_offset = self.get_offset(start)
-        end_offset = self.get_offset(end)
-        return (start_offset, end_offset)
-
-    def _get_region_index(self):
-        start = ''
-        end = ''
-        try:
-            start = self.text.index(SEL_FIRST)
-            end = self.text.index(SEL_LAST)
-        except TclError:
-            pass
-        if start == '' or end == '':
-            start = self.text.index('mark')
-            end = self.text.index(INSERT)
-            if start == '':
-                start = end
-        if self.text.compare(start, '>', end):
-            start, end = end, start
-        return start, end
-
-    def _focus_went_out(self, save=True):
-        if self.searcher.is_searching():
-            self.searcher.end_searching(save)
-
-    def goto_line(self, lineno, colno=0):
-        self.text.mark_set(INSERT, '%d.%d' % (lineno, colno))
-        self.text.see(INSERT)
-
-    def _insert_new_line(self):
-        self.text.insert(INSERT, '\n')
-        lineno = self.get_current_line_number()
-        self.indenter.entering_new_line(lineno)
-        first_non_space = 0
-        while self.text.get('%d.%d' % (lineno, first_non_space)) == ' ':
-            first_non_space += 1
-        self.text.mark_set(INSERT, '%d.%d' % (lineno, first_non_space))
-        self.text.see(INSERT)
-
-    def _editor_modified(self, event):
-        if self.modified_flag:
-            self.modified_flag = False
-        else:
-            self.modified_flag = True
-        for observer in self.modification_observers:
-            observer()
-
-    def add_modification_observer(self, observer):
-        self.modification_observers.append(observer)
-
-    def add_change_observer(self, observer):
-        self.change_observers.append(observer)
-
-    def is_modified(self):
-        return self.modified_flag
-
-    def correct_line_indentation(self):
-        lineno = self.get_current_line_number()
-        cols_from_end = len(self.text.get(INSERT, 'insert lineend'))
-        self.indenter.correct_indentation(lineno)
-        from_end = '%d.end -%dc' % (lineno, cols_from_end)
-        first_non_space = 0
-        while self.text.get('%d.%d' % (lineno, first_non_space)) == ' ':
-            first_non_space += 1
-        new_insert = '%d.%d' % (lineno, first_non_space)
-        if self.text.compare(new_insert, '<', from_end):
-            new_insert = from_end
-        self.text.mark_set(INSERT, new_insert)
-        self.text.see(INSERT)
-
-    def get_text(self):
-        return self.text.get('1.0', 'end-1c')
-
-    def set_text(self, text, reset_editor=True):
-        initial_position = self.text.index(INSERT)
-        # IDEA: When to use `_change_text2` that uses difflib;
-        # Maybe when the number of changes is few
-        self._change_text1(text)
-        self.text.mark_set(INSERT, initial_position)
-        self.text.see(INSERT)
-        if reset_editor:
-            self.text.edit_reset()
-            self.text.edit_modified(False)
-
-    def _change_text1(self, text):
-        self.text.delete('1.0', END)
-        self.text.insert('1.0', text)
-
-    def _change_text2(self, text):
-        import difflib
-        old_text = self.get_text()
-        differ = difflib.Differ()
-        current_line = 1
-        for line in differ.compare(old_text.splitlines(True),
-                                   text.splitlines(True)):
-            if line.startswith(' '):
-                current_line += 1
-                continue
-            if line.startswith('+'):
-                self.text.insert('%s.0' % current_line, line[2:])
-                current_line += 1
-                continue
-            if line.startswith('-'):
-                self.text.delete('%s.0' % current_line, '%s.0' % (current_line + 1))
-                continue
-
-    def get_start(self):
-        return GraphicalTextIndex(self, '1.0')
-
-    def get_insert(self):
-        return GraphicalTextIndex(self, INSERT)
-
-    def get_end(self):
-        return GraphicalTextIndex(self, END)
-
-    def get_relative(self, textIndex, offset):
-        return GraphicalTextIndex(self, self._go(textIndex._getIndex(), offset))
-
-    def get_index(self, offset):
-        return GraphicalTextIndex(self, self._go('1.0', offset))
-
-    def _go(self, fromIndex, count):
-        if count >= 0:
-            return fromIndex + ('+%dc' % count)
-        else:
-            return fromIndex + ('%dc' % count)
-
-    def _get_line_from_index(self, index):
-        return int(str(self.text.index(index)).split('.')[0])
-
-    def _get_column_from_index(self, index):
-        return int(str(self.text.index(index)).split('.')[1])
-
-    def set_insert(self, textIndex):
-        if isinstance(textIndex, basestring):
-            self.text.mark_set(INSERT, textIndex)
-        else:
-            self.text.mark_set(INSERT, textIndex._getIndex())
-        self.text.see(INSERT)
-
-    def get(self, start=None, end=None):
-        startIndex = INSERT
-        endIndex = None
-        if start is not None:
-            startIndex = start._getIndex()
-            if start == self.get_end():
-                return ''
-        if end is not None:
-            endIndex = end._getIndex()
-        return self.text.get(startIndex, endIndex)
-
-    def insert(self, text_index, text):
-        self.text.insert(text_index._getIndex(), text)
-
-    def delete(self, start=None, end=None):
-        startIndex = INSERT
-        if start is not None:
-            startIndex = start._getIndex()
-            if start == self.get_end():
-                return
-        endIndex = None
-        if end is not None:
-            endIndex = end._getIndex()
-        self.text.delete(startIndex, endIndex)
-
-    def _get_next_word_index_old(self):
-        result = INSERT
-        while self.text.compare(result, '!=', 'end-1c') and \
-              not self.text.get(result)[0].isalnum():
-            result = str(self.text.index(result + '+1c'))
-        return result + ' wordend'
-
-    def _get_next_word_index(self):
-        line = self.text.get('insert', 'insert lineend')
-        if line == '':
-            return 'insert +1l linestart'
-        offset = 0
-        while offset < len(line) and not line[offset].isalnum():
-            offset += 1
-        if offset == 0:
-            offset = 1
-        while offset < len(line) and line[offset].isalnum():
-            if offset > 0 and line[offset - 1].isalnum() and \
-               line[offset].isupper() and offset + 1 < len(line) and \
-               line[offset + 1].islower():
-                break
-            if offset > 0 and line[offset - 1].islower() and \
-               line[offset].isupper():
-                break
-            offset += 1
-        return 'insert +%dc' % offset
-
-    def next_word(self):
-        self.text.mark_set(INSERT, self._get_next_word_index())
-        self.text.see(INSERT)
-
-    def _change_next_word(self, function):
-        next_word = self.text.index(self._get_next_word_index())
-        while self.text.compare('insert', '<', 'end -1c') and \
-              not self.text.get(INSERT).isalnum() and \
-              self.text.compare('insert', '<', next_word):
-            self.text.mark_set(INSERT, 'insert +1c')
-
-        if self.text.compare('insert', '!=', next_word):
-            word = self.text.get(INSERT, next_word)
-            self.text.delete(INSERT, next_word)
-            self.text.insert(INSERT, function(word))
-            self.text.mark_set(INSERT, next_word)
-        self.text.see(INSERT)
-
-    def upper_next_word(self):
-        self._change_next_word(str.upper)
-
-    def lower_next_word(self):
-        self._change_next_word(str.lower)
-
-    def capitalize_next_word(self):
-        self._change_next_word(str.capitalize)
-
-    def _get_prev_word_index_old(self):
-        result = INSERT
-        while not self.text.compare(result, '==', '1.0') and \
-              not self.text.get(result + '-1c')[0].isalnum():
-            result = str(self.text.index(result + '-1c'))
-        return result + '-1c wordstart'
-
-    def _get_prev_word_index(self):
-        column = self._get_column_from_index('insert')
-        if column == 0:
-            if self._get_line_from_index('insert') != 1:
-                return 'insert -1l lineend'
-            else:
-                return 'insert'
-        offset = column
-        line = self.text.get('insert linestart', 'insert +1c')
-        while offset > 0 and not line[offset - 1].isalnum():
-            offset -= 1
-        if offset == column:
-            offset -= 1
-        while offset > 0 and line[offset - 1].isalnum():
-            if offset < len(line) - 1 and line[offset].isupper() and \
-               line[offset + 1].islower():
-                break
-            if offset > 0 and line[offset - 1].islower() and \
-               line[offset].isupper():
-                break
-            offset -= 1
-        return 'insert linestart +%dc' % offset
-
-    def prev_word(self):
-        self.text.mark_set(INSERT, self._get_prev_word_index())
-        self.text.see(INSERT)
-
-    def delete_next_word(self):
-        self.text.delete(INSERT, self._get_next_word_index())
-
-    def delete_prev_word(self):
-        self.text.delete(self._get_prev_word_index(), INSERT)
-
-    def getWidget(self):
-        return self.text
-
-    def saving_editor(self):
-        self.text.edit_separator()
-        if self.is_modified():
-            self.text.edit_modified(False)
-
-    def undo(self):
-        try:
-            self.text.edit_undo()
-        except TclError:
-            pass
-
-    def redo(self):
-        try:
-            self.text.edit_redo()
-        except TclError:
-            pass
-
-    def goto_start(self):
-        self.set_insert(self.get_start())
-
-    def goto_end(self):
-        self.set_insert(self.get_end())
-
-    def generate_event(self, event):
-        self.text.event_generate(event)
-
-    def set_mark(self):
-        self.text.mark_set('mark', INSERT)
-
-    def clear_mark(self):
-        self.text.mark_unset('mark')
-
-    def _select_region(self):
-        start, end = self._get_region_index()
-        self.text.tag_add(SEL, start, end)
-
-    def copy_region(self):
-        try:
-            self._add_yank()
-            self._select_region()
-            self.text.event_generate('<<Copy>>')
-            self.text.tag_remove(SEL, '1.0', END)
-        except TclError:
-            pass
-
-    def cut_region(self):
-        try:
-            self._add_yank()
-            self._select_region()
-            self.text.event_generate('<<Cut>>')
-            self.text.see(INSERT)
-        except TclError, e:
-            pass
-
-    def _add_yank(self):
-        start, end = self._get_region_index()
-        selected = self.text.get(start, end)
-        self.kill_ring.killed(selected)
-
-    def yank(self, count):
-        result = self.kill_ring.yank(count)
-        if result is not None:
-            old = self.kill_ring.yank(count - 1)
-            self.text.delete('insert -%dc' % len(old), INSERT)
-            self.text.insert(INSERT, result)
-
-    def paste(self):
-        self.text.event_generate('<<Paste>>')
-        self.text.see(INSERT)
-
-    def swap_mark_and_insert(self):
-        try:
-            mark = self.text.index('mark')
-            self.set_mark()
-            self.text.mark_set(INSERT, mark)
-            self.text.see(INSERT)
-        except TclError:
-            pass
-
-    def kill_line(self, append=False):
-        if self.text.compare('insert', '>=', 'end -1c'):
-            return
-        text = self.text.get('insert', 'insert lineend')
-        if not append:
-            self.text.clipboard_clear()
-        if text == '':
-            self.text.clipboard_append('\n')
-            self.text.delete('insert')
-        else:
-            self.text.clipboard_append(text)
-            self.text.delete('insert', 'insert lineend')
-        if append:
-            self.kill_ring.update_last(self.text.clipboard_get())
-        else:
-            self.kill_ring.killed(self.text.clipboard_get())
-
-    def next_page(self):
-        self.text.event_generate('<Next>')
-
-    def prev_page(self):
-        self.text.event_generate('<Prior>')
-
-    def insert_tab(self, text_index = None):
-        if text_index is None:
-            text_index = self.get_insert()
-        self.indenter.insert_tab(text_index)
-
-    def set_highlighting(self, highlighting):
-        self.highlighting = highlighting
-        for name, style in self.highlighting.get_styles().items():
-            fontKWs = {}
-            if style.italic is not None:
-                if style.italic:
-                    fontKWs['slant'] = 'italic'
-                else:
-                    fontKWs['slant'] = 'roman'
-            if style.bold is not None:
-                if style.bold:
-                    fontKWs['weight'] = 'bold'
-                else:
-                    fontKWs['weight'] = 'normal'
-            if style.underline is not None:
-                if style.underline:
-                    fontKWs['underline'] = 1
-                else:
-                    fontKWs['underline'] = 0
-            if style.strikethrough is not None:
-                if style.strikethrough:
-                    fontKWs['overstrike'] = 1
-                else:
-                    fontKWs['overstrike'] = 0
-            font = tkFont.Font(font=self.text['font']).copy()
-            font.configure(**fontKWs)
-            configKWs = {}
-            if style.color is not None:
-                configKWs['foreground'] = style.color
-            configKWs['font'] = font
-            self.text.tag_config(name, **configKWs)
-        self._highlight_range('0.0', 'end')
-
-    def get_searcher(self):
-        return self.searcher
-
-    def highlight_match(self, match):
-        if not match:
-            return
-        self.text.tag_remove(SEL, '1.0', END)
-        self.text.tag_add(SEL, match.start._getIndex(), match.end._getIndex())
-        if match.side == 'right':
-            self.text.mark_set(INSERT, match.end._getIndex())
-        else:
-            self.text.mark_set(INSERT, match.start._getIndex())
-        self.text.see(INSERT)
-
-
-    def start_searching(self, forward):
-        if self.searcher.is_searching():
-            self.searcher.configure_search(forward)
-            self.searcher.next_match()
-        else:
-            self.searcher.start_searching()
-            self.searcher.configure_search(forward)
-
-    def _search_handler(self, event):
-        if not self.searcher.is_searching():
-            return
-        import string
-        if len(event.char) == 1 and (event.char.isalnum() or
-                                     event.char in string.punctuation):
-            self.searcher.append_keyword(event.char)
-            return 'break'
-        if event.keysym == 'space':
-            self.searcher.append_keyword(event.char)
-            return 'break'
-        if event.keysym == 'BackSpace':
-            self.searcher.shorten_keyword()
-            return 'break'
-        if event.keysym == 'Return':
-            self.searcher.end_searching()
-            return 'break'
-        return 'break'
-
-    def search(self, keyword, start, case=True, forwards=True):
-        found = self.text.search(keyword, start._getIndex(),
-                                 nocase=int(not case),
-                                 backwards=int(not forwards))
-        if not found:
-            return None
-        return GraphicalTextIndex(self, found)
-
-    def set_indenter(self, text_indenter):
-        self.indenter = text_indenter
-
-    def get_indenter(self):
-        return self.indenter
-
-    def get_current_line_number(self):
-        return self._get_line_from_index(INSERT)
-
-    def get_current_column_number(self):
-        return self._get_column_from_index(INSERT)
-
-    def get_current_offset(self):
-        return self.get_offset(INSERT)
-
-    def _get_offset1(self, index):
-        # adding up line lengths
-        result = self._get_column_from_index(index)
-        current_line = self._get_line_from_index(index)
-        current_pos = '1.0 lineend'
-        for x in range(current_line - 1):
-            result += self._get_column_from_index(current_pos) + 1
-            current_pos = str(self.text.index(current_pos + ' +1l lineend'))
-        return result
-
-    def _get_offset2(self, index):
-        # walking the whole text
-        text = self.get_text()
-        column = self._get_column_from_index(index)
-        line = self._get_line_from_index(index)
-        current_pos = 0
-        current_line = 1
-        while current_line < line and current_pos < len(text):
-            if text[current_pos] == '\n':
-                current_line += 1
-            current_pos += 1
-        for i in range(column):
-            if not current_pos < len(text) and text[current_pos] != '\n':
-                break
-            current_pos += 1
-        return current_pos
-
-    def _get_offset3(self, index):
-        # using binary search
-        text = self.get_text()
-        start = 0
-        end = len(text)
-        indexer = _OffsetToIndexCacher(self.text)
-        while start < end:
-            mid = (start + end) // 2
-            if self.text.compare(indexer.get_index(mid), '>', index):
-                end = mid - 1
-            elif self.text.compare(indexer.get_index(mid), '==', index):
-                return mid
-            else:
-                start = mid + 1
-        return start
-
-    def get_offset(self, get_offset):
-        return self._get_offset3(get_offset)
-
-    def set_status_bar_manager(self, manager):
-        self.status_bar_manager = manager
-
-    def _set_editingcontexts(self, editingcontext):
-        self.editingcontext = editingcontext
-        editingtools = editingcontext.editingtools
-        self.set_indenter(editingtools.create_indenter(self))
-        self.set_highlighting(editingtools.create_highlighting())
-
-    def get_editing_context(self):
-        return self.editingcontext
-
-    def line_editor(self):
-        return GraphicalLineEditor(self)
-
-
-class GraphicalTextIndex(object):
-    """An immutable class for pointing to a position in a text"""
-
-    def __init__(self, editor, index):
-        self.index = index
-        self.editor = editor
-        if self.editor.text.compare(index, '==', 'end'):
-            self.index = 'end-1c'
-        self.index = editor.text.index(self.index)
-
-    def __cmp__(self, index):
-        assert self.editor == index.editor
-        if self.editor.text.compare(self.index, '<', index.index):
-            return -1
-        if self.editor.text.compare(self.index, '>', index.index):
-            return +1
-        return 0
-
-    def _getIndex(self):
-        return str(self.index)
-
-    def __str__(self):
-        return '<%s, %s>' % (self.__class__.__name__, self.index)
-
-
-class _TextChangeInspector(object):
-
-    def __init__(self, editor, change_observer=None):
-        self.editor = editor
-        self.text = editor.text
-        self.redirector = rope.ui.tkhelpers.WidgetRedirector(self.text)
-        self.old_insert = self.redirector.register('insert', self._insert)
-        self.old_delete = self.redirector.register('delete', self._delete)
-        self.old_edit = self.redirector.register('edit', self._edit)
-        self.change_observer = change_observer
-        self.changed_region = None
-
-    def _insert(self, *args):
-        start = self.text.index(args[0])
-        result = self.old_insert(*args)
-        end = self.text.index(start + ' +%dc' % len(args[1]))
-        if not start or not end:
-            return
-        if self.changed_region is not None:
-            if self.text.compare(start, '<', self.changed_region[1]):
-                end = self.text.index(self.changed_region[1] + ' +%dc' % len(args[1]))
-            if self.text.compare(self.changed_region[0], '<', start):
-                start = self.changed_region[0]
-        self.changed_region = (start, end)
-        self._notify_observer()
-        return result
-
-    def _notify_observer(self):
-        if self.is_changed() and self.change_observer:
-            self.text.after_idle(self.change_observer)
-
-    def _delete(self, *args):
-        start = self.text.index(args[0])
-        result = self.old_delete(*args)
-        end = start
-        if not start:
-            return
-        if self.changed_region is not None:
-            if self.text.compare(end, '<', self.changed_region[1]):
-                delete_len = 1
-                if len(args) > 1 and args[1] is not None:
-                    delete_len = self.editor.get_offset(str(self.text.index(args[1]))) - \
-                                 self.editor.get_offset(start)
-                end = self.text.index(self.changed_region[1] + ' -%dc' % delete_len)
-            if self.text.compare(self.changed_region[0], '<', start):
-                start = self.changed_region[0]
-        self.changed_region = (start, end)
-        self._notify_observer()
-        return result
-
-    def _edit(self, *args):
-        if len(args) < 1 or args[0] not in ['undo', 'redo']:
-            return self.old_edit(*args)
-        start = self.text.index(INSERT)
-        result = self.old_edit(*args)
-        end = self.text.index(INSERT)
-        if self.text.compare(end, '<', start):
-            start, end = end, start
-        if self.changed_region is not None:
-            if self.text.compare(self.changed_region[0], '<', start):
-                start = self.changed_region[0]
-            if self.text.compare(self.changed_region[1], '>', end):
-                end = self.changed_region[1]
-        self.changed_region = (start, end)
-        self._notify_observer()
-        return result
-
-    def get_changed_region(self):
-        return self.changed_region
-
-    def is_changed(self):
-        return self.changed_region is not None
-
-    def clear_changed(self):
-        self.changed_region = None
-
-
-class EditorFactory(object):
-
-    def create(self):
-        pass
-
-
-class GraphicalEditorFactory(EditorFactory):
-
-    def __init__(self, frame, **kwds):
-        self.frame = frame
-        self.kwds = kwds
-
-    def create(self, *args, **kwds):
-        kwds.update(self.kwds)
-        return GraphicalEditor(self.frame, *args, **kwds)
-
-
-class GraphicalLineEditor(object):
-    """An interface for line oriented editors"""
-
-    def __init__(self, editor):
-        self.editor = editor
-
-    def get_line(self, line_number):
-        return self.editor.text.get('%d.0' % line_number, '%d.0 lineend' % line_number)
-
-    def length(self):
-        result = self.editor._get_line_from_index(END) - 1
-        return result
-
-    def indent_line(self, line_number, count):
-        if count == 0:
-            return
-        if count > 0:
-            self.editor.text.insert('%d.0' % line_number, count * ' ')
-        else:
-            self.editor.text.delete('%d.0' % line_number,
-                                    '%d.%d' % (line_number, -count))
-
-    def insert_to_line(self, line_number, text):
-        self.editor.text.insert('%d.0' % line_number, text)
-
-
-class _OffsetToIndexCacher(object):
-    """A faster way to convert offset to `Tkinter` index
-
-    This should not be used if the text changes during calls to
-    `get_index()` method.
-
-    """
-    def __init__(self, editor):
-        self.editor = editor
-        self.index = '1.0'
-        self.offset = 0
-
-    def get_index(self, offset):
-        diff = offset - self.offset
-        if diff == 0:
-            return self.index
-        if diff > 0:
-            new_index = self.index + ' +%dc' % diff
-        else:
-            new_index = self.index + ' %dc' % diff
-        if abs(diff) > 1:
-            new_index = self.editor.index(new_index)
-            self.index = new_index
-            self.offset = offset
-        return new_index
-
-
-class OffsetToIndexCacher(object):
-    """A faster way to convert offset to `GraphicalTextIndex`"""
-    def __init__(self, editor):
-        self.editor = editor
-        self.cacher = _OffsetToIndexCacher(editor)
-
-    def get_index(self, offset):
-        return GraphicalTextIndex(editor, self.cacher.get_index(offset))
-
-
-class KillRingManager(object):
-
-    def __init__(self, limit=20):
-        self.ring = []
-        self.limit = limit
-
-    def yank(self, count):
-        if self.ring:
-            return self.ring[count % len(self.ring)]
-
-    def killed(self, killed):
-        self.ring.insert(0, killed)
-        if len(self.ring) > self.limit:
-            del self.ring[-1]
-
-    def update_last(self, new_text):
-        if self.ring:
-            self.ring[0] = new_text

rope/ui/editorpile.py

-from Tkinter import *
-
-import rope.ui.fileeditor
-
-
-class EditorPile(object):
-
-    def __init__(self, editor_panel, core, status, font=None):
-        self.core = core
-        self.status = status
-        self.editor_list = Frame(editor_panel, borderwidth=0)
-        self.editor_frame = Frame(editor_panel, borderwidth=0, relief=RIDGE)
-        self.editors = []
-        self.buttons = {}
-        self.active_file_path = StringVar()
-        self.active_editor = None
-        self.last_edited_location = None
-        self.font = font
-
-    def show(self, show_list=True):
-        if show_list:
-            self.editor_list.pack(fill=BOTH, side=TOP)
-        self.editor_frame.pack(fill=BOTH, expand=1)
-        self.editor_frame.pack_propagate(0)
-
-    def _editor_was_modified(self, editor):
-        if editor not in self.buttons:
-            return
-        new_title = editor.get_file().name
-        if editor.get_editor().is_modified():
-            new_title = '*' + new_title
-        if not editor.get_file().exists():
-            new_title = '! ' + new_title
-        self.buttons[editor]['text'] = new_title
-        self._update_buffer_status()
-
-    def _editor_was_changed(self, resource, offset):
-        self.last_edited_location = (resource, offset)
-
-    def activate_editor(self, editor):
-        if self.active_editor:
-            self.active_editor.get_editor().getWidget().forget()
-        editor.get_editor().getWidget().pack(fill=BOTH, expand=1)
-        editor.get_editor().getWidget().focus_set()
-        self.buttons[editor].select()
-        self.active_editor = editor
-        self.editors.remove(editor)
-        self.editors.insert(0, editor)
-        self._update_buffer_status()
-        self.core._editor_changed()
-
-    def get_resource_editor(self, file_, readonly=False, mode=None):
-        for editor in self.editors:
-            if editor.get_file() == file_:
-                self.buttons[editor].invoke()
-                return editor
-        font = self.core.prefs.get('font', None)
-        editor = rope.ui.fileeditor.FileEditor(
-            self.core.get_open_project(), file_,
-            rope.ui.editor.GraphicalEditorFactory(self.editor_frame, font=font),
-            readonly=readonly, mode=mode)
-        editor.get_editor().set_status_bar_manager(self.core.status_bar_manager)
-        editor.add_change_observer(self._editor_was_changed)
-        self.editors.append(editor)
-        title = Radiobutton(self.editor_list, text=file_.name,
-                            variable=self.active_file_path,
-                            value=file_.path, indicatoron=0, bd=2,
-                            command=lambda: self.activate_editor(editor),
-                            selectcolor='#99A', relief=GROOVE, font=self.font)
-        self.buttons[editor] = title
-        title.select()
-        title.pack(fill=BOTH, side=LEFT)
-        self.activate_editor(editor)
-        self.core._set_key_binding(editor.get_editor())
-        editor.add_modification_observer(self._editor_was_modified)
-        return editor
-
-    def switch_active_editor(self):
-        if len(self.editors) >= 2:
-            self.activate_editor(self.editors[1])
-
-    def close_active_editor(self):
-        if self.active_editor is None:
-            return
-        widget = self.active_editor.get_editor().getWidget()
-        widget.forget()
-        widget.destroy()
-        self.editors.remove(self.active_editor)
-        button = self.buttons[self.active_editor]
-        button.forget()
-        button.destroy()
-        self.active_editor.close()
-        del self.buttons[self.active_editor]
-        self.active_editor = None