Anonymous avatar Anonymous committed b942a11

Removed non-library files

Comments (0)

Files changed (72)

+include README.txt COPYING setup.py MANIFEST.in
+recursive-include rope *.py
+recursive-include docs *.txt
+recursive-include ropetest *.py
+========================================
+ rope, a python refactoring library ...
+========================================
+
+
+Overview
+========
+
+`Rope`_ is a python refactoring library.
+
+.. _`rope`: http://rope.sf.net/
+
+
+New Features
+============
+
+
+Getting Started
+===============
+
+* List of features: `docs/index.txt`_
+* Using as a library: `docs/library.txt`_
+* Contributing: `docs/contributing.txt`_
+
+To change your project preferences edit
+``$PROJECT_ROOT/.ropeproject/config.py`` where ``$PROJECT_ROOT`` is
+the root folder of your project (this file is created the first time
+you open a project).
+
+
+Project Road Map
+================
+
+The main motive for starting this project was the lack of good
+refactoring tools for Python programming language.  Refactoring
+programs like "bicycle repair man" aren't reliable due to type
+inference problems and they support a limited number of refactorings.
+*Rope* tries to improve these limitations.
+
+The main goal of *rope* is to concentrate on the type inference and
+refactoring of python programs and not a state of art IDE (at least
+not in the first phase).  The type inference and refactoring parts
+will not be dependent on *rope* IDE and if successful, will be
+released as standalone programs and libraries so that other projects
+may use them.
+
+
+Bug Reports
+===========
+
+Send your bug reports and feature requests to `rope-dev (at)
+googlegroups.com`_.
+
+.. _`rope-dev (at) googlegroups.com`: http://groups.google.com/group/rope-dev
+
+
+License
+=======
+
+This program is under the terms of GPL (GNU General Public License).
+Have a look at ``COPYING`` file for more information.
+
+
+.. _`docs/index.txt`: docs/index.html
+.. _`docs/contributing.txt`: docs/contributing.html
+.. _`docs/library.txt`: docs/library.html

docs/dev/issues.txt

 * Should `rope.base` be thread safe? which parts?
 
 
-Splitting The Repository
-========================
-
-Currently rope, ropeide and ropemacs are in rope main repo.  I think
-putting them in separate repos will make releasing them easier.
-
-
-rope_py3k Branch
-----------------
-
-In rope_py3k, ropeide changes are minor.  So I think only having a
-separate rope_py3k suffies.  Ropeide for py3k can be obtained using a
-small patch.
-
-
-The Process
------------
-
-Fortunately hg convert extension takes a filemap file that can be used
-for filtering and renaming files.
-
-ropeide filemap::
-
-  exclude .
-  include rope/ui
-  include ropeide
-  include rope/ide
-  exclude rope/ide/generate.py
-  exclude rope/ide/codeassist.py
-  exclude rope/ide/ropemacs.py
-
-  include ropetest/ui
-  include ropetest/ide
-  exclude ropetest/ide/codeassisttest.py
-  exclude ropetest/ide/generatetest.py
-
-  include COPYING
-  include rope.py
-  include ropeide.py
-  rename tools/ropeide_MANIFEST.txt MANIFEST.txt
-  rename tools/ropeide_setup.py setup.py
-  rename docs/ropeide.txt README.txt
-
-ropemacs filemap::
-
-  exclude .
-  include rope/contrib/ropemacs.py
-  include ropemacs.py
-
-  include COPYING
-  include docs/pymacs_python25.patch
-  rename tools/ropemacs_MANIFEST.txt MANIFEST.txt
-  rename tools/ropemacs_setup.py setup.py
-  rename docs/ropemacs.txt README.txt
-
-Other Issues
-------------
-
-* Common docs in rope and ropeide
-* Renaming docs/dev/done.txt to NEWS or ChangeLog?
-* Cleaning up stories.txt and done.txt
-* Renaming docs/dev/stories.txt to TODO?
-
-
-
 Cross-Project Refactorings
 ==========================
 
 * Removing ``pass`` when introducing factory for empty classes
 * Importing star and removing self imports; stack overflow
 
-UI and IDE:
-
-* Inserting common prefix when using codeassist
-* Renaming files, folders, modules, and packages in project tree view
-* Completion in module entries
-* Goto definition for ``"# comment.\na_var"``
-* Comments should be indented
-
 Docs:
 
 * Explain why rope does not stop users from performing wrong

docs/dev/stories.txt

 * Introduce redirection
 
 
-IDE And UI Stories
-==================
-
-* Editor folding
-* Auto-importing modules
-* Replacement; M-%
-* Remembering last open project
-* Go to matching parenthesis
-* Indenting a region of a file
-* Finding available refactorings
-* Auto completion type
-
-  * Inserting or overwriting
-  * Inserting common prefixes
-
-* ReST
-
-  * highlighting inside pydocs
-  * goto definition
-  * outlines
-  * codeassists
-
-* Show PyDoc reST highlighting
-* Enhancing module running
-
-  * Showing running status in the GUI
-  * Printing output
-  * Getting input
-  * Customizing CWD and parameters
-  * Running last run
-
-* Formating code
-* Spell checking python source
-
-
 Stories
 =======
 
 * Extract class
 
 
-* Supporting templates in text modes
-
-
-* Next/prev sentence
-
-
-* Searching inside `EnhancedList`\s
-
-
 * Supporting modules without source code
 
 
 * Changing method to static method refactoring
 
 
-* Better warnings
-
-
 * Enhanced occurrence finding
 
 
 * Move refactoring and moving a group of elements together
 
 
-* View type hierarchy
-
-
 * Removing files/folders
 
 
   imports
 
 
-* Generate ~/.rope graphically
-
-
 > Public Release 0.7.1
 
 
-* ropemacs: only activating keybinding in python files
-
-
-* ropemacs: previewing changes
-
-
-* ropemacs: showing refactoring progress
-
-
-* ropemacs: specifying refactoring options
-
-
-* ropemacs: adding a menu
-
-
 * Performing refactorings across multiple projects
-
-
-* ropemacs: find file dialog
-
-
-* ropemacs: auto-complete

docs/pymacs_python25.patch

---- a/Pymacs/Rebox/rebox.py
-+++ b/Pymacs/Rebox/rebox.py
-@@ -1,4 +1,5 @@
- #!/usr/bin/env python
-+# -*- coding: latin-1 -*-
- # Copyright � 1991-1998, 2000, 2002 Progiciels Bourbeau-Pinard inc.
- # Fran�ois Pinard <pinard@iro.umontreal.ca>, April 1991.
- 
---- a/Pymacs/__init__.py
-+++ b/Pymacs/__init__.py
-@@ -1,4 +1,5 @@
- #!/usr/bin/env python
-+# -*- coding: latin-1 -*-
- # Copyright � 2002, 2003 Progiciels Bourbeau-Pinard inc.
- # Fran�ois Pinard <pinard@iro.umontreal.ca>, 2002.
- 
---- a/Pymacs/pymacs.py
-+++ b/Pymacs/pymacs.py
-@@ -1,3 +1,4 @@
- #!/usr/bin/env python
-+# -*- coding: latin-1 -*-
- # Copyright � 2001, 2002, 2003 Progiciels Bourbeau-Pinard inc.
- # Fran�ois Pinard <pinard@iro.umontreal.ca>, 2001.

docs/rope.txt

-========================================
- rope, a python refactoring library ...
-========================================
-
-
-Overview
-========
-
-`Rope`_ is a python refactoring library.
-
-.. _`rope`: http://rope.sf.net/
-
-
-New Features
-============
-
-
-Getting Started
-===============
-
-* List of features: `docs/index.txt`_
-* Using as a library: `docs/library.txt`_
-* Contributing: `docs/contributing.txt`_
-
-To change your project preferences edit
-``$PROJECT_ROOT/.ropeproject/config.py`` where ``$PROJECT_ROOT`` is
-the root folder of your project (this file is created the first time
-you open a project).
-
-
-Project Road Map
-================
-
-The main motive for starting this project was the lack of good
-refactoring tools for Python programming language.  Refactoring
-programs like "bicycle repair man" aren't reliable due to type
-inference problems and they support a limited number of refactorings.
-*Rope* tries to improve these limitations.
-
-The main goal of *rope* is to concentrate on the type inference and
-refactoring of python programs and not a state of art IDE (at least
-not in the first phase).  The type inference and refactoring parts
-will not be dependent on *rope* IDE and if successful, will be
-released as standalone programs and libraries so that other projects
-may use them.
-
-
-Bug Reports
-===========
-
-Send your bug reports and feature requests to `rope-dev (at)
-googlegroups.com`_.
-
-.. _`rope-dev (at) googlegroups.com`: http://groups.google.com/group/rope-dev
-
-
-License
-=======
-
-This program is under the terms of GPL (GNU General Public License).
-Have a look at ``COPYING`` file for more information.
-
-
-.. _`docs/index.txt`: docs/index.html
-.. _`docs/contributing.txt`: docs/contributing.html
-.. _`docs/library.txt`: docs/library.html

docs/ropeide.txt

-====================================
- rope, a python refactoring IDE ...
-====================================
-
-
-Overview
-========
-
-`Ropeide`_ is a python refactoring IDE.  It uses rope_ library to
-provide features like refactoring, code assist, and auto-completion.
-It is written in python.  The IDE uses `Tkinter` library.
-
-You should install `rope`_ library before using this IDE.
-
-.. _`ropeide`: http://rope.sf.net/
-.. _`rope`: http://rope.sf.net/
-
-
-New Features
-============
-
-
-Getting Started
-===============
-
-* Overview and keybinding: `docs/overview.txt`_
-* List of features: `docs/index.txt`_
-* Tutorial: `docs/tutorial.txt`_
-* Contributing: `docs/contributing.txt`_
-
-To change rope IDE preferences like font edit your ``~/.ropeide``
-(which is created the first time you start rope).  To change your
-project preferences edit ``$PROJECT_ROOT/.ropeproject/config.py``
-where ``$PROJECT_ROOT`` is the root folder of your project (this file
-is created the first time you open a project).
-
-If you don't like rope's default emacs-like keybinding, edit the
-default ``~/.ropeide`` file and change `i_like_emacs` variable to
-`False`.
-
-
-Bug Reports
-===========
-
-Send your bug reports and feature requests to `rope-dev (at)
-googlegroups.com`_.
-
-.. _`rope-dev (at) googlegroups.com`: http://groups.google.com/group/rope-dev
-
-
-License
-=======
-
-This program is under the terms of GPL (GNU General Public License).
-Have a look at ``COPYING`` file for more information.
-
-
-.. _`docs/overview.txt`: docs/overview.html
-.. _`docs/tutorial.txt`: docs/tutorial.html
-.. _`docs/index.txt`: docs/index.html
-.. _`docs/contributing.txt`: docs/contributing.html

docs/ropemacs.txt

-=========================
- ropemacs, rope in emacs
-=========================
-
-Using rope in emacs.  You should install `rope`_ library before using
-ropemacs.
-
-.. _`rope`: http://rope.sf.net/
-
-
-New Features
-============
-
-
-Setting Up
-==========
-
-You can get Pymacs from http://www.iro.umontreal.ca/~pinard/pymacs/.
-But version 0.22 does not work with Python 2.5 because of the lack of
-file encoding declarations.  A simple patch is included:
-``docs/pymacs_python25.patch``.
-
-After installing pymacs, add these lines to your ``~/.emacs`` file::
-
-  (load-library "pymacs")
-  (pymacs-load "ropemacs" "rope-")
-  (rope-init)
-
-
-Keybinding
-==========
-
-Uses almost the same keybinding as rope.
-
-=============   ============================
-Key             Action
-=============   ============================
-C-x p o         rope-open-project
-C-x p k         rope-close-project
-C-x p u         rope-undo-refactoring
-C-x p r         rope-redo-refactoring
-
-C-c r r         rope-rename
-C-c r l         rope-extract-variable
-C-c r m         rope-extract-method
-C-c r i         rope-inline
-C-c r v         rope-move
-C-c r 1 r       rope-rename-current-module
-C-c r 1 v       rope-move-current-module
-C-c r 1 p       rope-module-to-package
-
-C-c g           rope-goto-definition
-C-c C-d         rope-show-doc
-C-c i o         rope-organize-imports
-=============   ============================
-
-
-Getting Started
-===============
-
-* List of features: `docs/index.txt`_
-* Contributing: `docs/contributing.txt`_
-
-.. _`docs/index.txt`: docs/index.html
-.. _`docs/contributing.txt`: docs/contributing.html
-
-
-License
-=======
-
-This program is under the terms of GPL (GNU General Public License).
-Have a look at ``COPYING`` file for more information.

docs/tutorial.txt

-===============
- Rope Tutorial
-===============
-
-.. contents::
-
-Overview
-========
-
-Right now most of rope's development efforts are toward developing
-core parts and not the UI.  Because of this UI parts don't look very
-user friendly and there is no documentation or help for the UI
-parts.  For this reason I think the best way for learning more about
-rope is using it and trying its menu items.
-
-This tutorial merely tries to demonstrate how to use rope for basic
-editing tasks.  This tutorial attempts to give a fast overview of
-rope and some of its basic features.  It covers things like opening
-projects, creating and editing files.  Read `where to go next`_
-section for more information.
-
-
-Starting Rope
-=============
-
-Simply run the ``rope.py`` included in the root of the package::
-
-  python rope.py
-
-
-Creating And Opening Projects
-=============================
-
-To create or open a project select the ``Open Project`` from the file
-menu.  You will be asked about the location of the root (toplevel)
-folder of your project.
-
-
-Making Files And Folders
-========================
-
-Consider we want to make a hierarchy like this::
-
-  project/
-    file1.txt
-    folder1/
-      file2.txt
-      folder2/
-        file3.txt
-
-In order to make this project tree, after opening the project you
-can use the following table.
-
-====================  ==================  =================
-Selected Menu Item    Parent Folder       File/Folder Name
-====================  ==================  =================
-File.New File                             file1.txt
-File.New Folder                           folder1
-File.New File         folder1             file2.txt
-File.New Folder       folder1             folder2
-File.New File         folder1/folder2     file3.txt
-====================  ==================  =================
-
-Note that for making ``file3.txt`` we've used ``/`` as a directory
-separator.  You should always use ``/`` as directory separator
-regardless of the operating system you are running rope on.
-
-
-Making Modules and Packages
-===========================
-
-Consider we want to make a hierarchy like this::
-
-  project/
-    mod1.py
-    pkg1/
-      __init__.py
-      mod2.py
-      pkg2/
-        __init__.py
-        mod3.py
-    src/
-       mod4.py
-
-
-In order to make this project tree, after opening the project you
-can use the following table.
-
-====================  ==================  ====================
-Selected Menu Item    Source Folder       Module/Package Name
-====================  ==================  ====================
-File.New Module                           mod1
-File.New Package                          pkg1
-File.New Module                           pkg1.mod2
-File.New package                          pkg1.pkg2
-File.New Module                           pkg1.pkg2.mod3
-File.New Folder                           src
-File.New Module       src                 mod4
-====================  ==================  ====================
-
-
-Opening Files
-=============
-
-You can select the ``Find File`` item from the ``File`` menu or use
-``C-x C-f``.  In the `Find File` dialog use the name of the file or
-module to find it.  The dialog shows all files that start with the
-given name.  Press enter to open the file.
-
-In the find file dialog, you can use ``/``\s to match parent folders.
-For instance for opening ``rope/base/__init__.py`` you can use
-``base/__init__.py`` or ``ba*/__``.
-
-
-Saving A File
-=============
-
-Use ``C-x C-s`` to save the contents of the active editor.
-
-
-Changing Editor
-===============
-
-With rope you can open and edit many files at the same time.  To switch
-between open editors you can use ``C-x b``.
-
-
-Closing An Editor
-=================
-
-Use ``C-x k`` to close active editor.
-
-
-Emacs Keybindings
-=================
-
-*rope* uses emacs keybindings most of the time.  For example in most of
-the dialogs like ``code assist`` or ``outline`` you can use ``C-n``
-and ``C-p`` to move over the items.
-
-
-Copying And Cutting
--------------------
-
-Select the beginning of the region you want to copy or cut by moving
-the cursor on it and pressing ``Ctrl-space``.  Then move the cursor to
-the end of that region and use ``Alt-w`` or ``Ctrl-w`` for copying or
-cutting.
-
-For pasting move the cursor to the place you want to paste and press
-``Ctrl-y``.
-
-
-Undoing Actions
-===============
-
-Rope comes with two kinds of undo/redos.
-
-* Undo/redoing editing
-
-  You can undo/redo the editing changes using ``C-x u``/``C-x r``.
-
-* Undo/redoing project changes
-
-  Project changes are the changes made to the files in the project.
-  These changes consist of things like saving files, creating files/
-  folders and refactoring.  You can undo/redo project changes using
-  ``C-x p u``/``C-x p r``.
-
-
-ReStructuredText Files
-======================
-
-All ``*.txt`` files are considered to be in `ReST` format and are
-highlighted.
-
-
-Editing Python Files
-====================
-
-Rope considers all ``*.py`` files to be python files.  It highlights
-them and makes features like auto-completion, goto definition,
-show doc, quick outline, refactorings and ... available.
-
-
-Where To Go Next
-================
-
-The best way to learn about rope features is to use the features.
-Have a look and try menu items.  The default keybinding for each
-menu item is written in front of them.  For example `Code` menu
-contains the entry `Code Assist (Auto-Complete)  M-slash`.  This means
-you can use rope's auto-complete feature by pressing `alt` and
-`/` keys.  Note that some of the menu items disappear when you're
-not editing a file suitable for performing that action.  For example
-code assist command is only active when editing a python file.
-
-Have a look at `overview.txt`_ for an overview of some of rope's
-features.  If you really want to see what rope can do, have a
-look at the unit tests in the `ropetest` package.
-
-
-.. _overview.txt: overview.html

ropeide.py

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

ropeide/__init__.py

-"""ropeide, a python refactoring IDE"""
-
-INFO = __doc__
-VERSION = '0.7.1'
-COPYRIGHT = """\
-Copyright (C) 2006-2007 Ali Gholami Rudi
-
-This program is free software; you can redistribute it and/or modify it
-under the terms of GNU General Public License as published by the
-Free Software Foundation; either version 2 of the license, or (at your
-opinion) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details."""

ropeide/actionhelpers.py

-import threading
-
-import Tkinter
-
-import rope.base.project
-import rope.refactor.change_signature
-import ropeide.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 = ropeide.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()

ropeide/core.py

-import os
-import imp
-
-import tkFileDialog
-from Tkinter import *
-
-import ropeide.editor
-import ropeide.editorpile
-import ropeide.keybinder
-import ropeide.statusbar
-from rope.base.exceptions import RopeError
-from rope.base.project import Project, get_no_project
-from ropeide import editingcontexts, registers
-from ropeide.extension import ActionContext
-from ropeide.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 = ropeide.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 = ropeide.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 = ropeide.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.ropeide.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('ropeide.fileactions')
-        self.add_extension('ropeide.editactions')
-        self.add_extension('ropeide.sourceactions')
-        self.add_extension('ropeide.refactor')
-        self.add_extension('ropeide.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.ropeide' % 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 <~/.ropeide> 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.ropeide.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 ropeide.dot_ropeide
-    import inspect
-    text = inspect.getsource(ropeide.dot_ropeide)
-    output = open(dot_rope, 'w')
-    output.write(text)
-    output.close()

ropeide/dot_ropeide.py

-# The default ~/.ropeide file for *ropeide*.
-#
-# 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_ropeide`` in execute command or ``Edit ~/.ropeide``
-# 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 other fonts
-    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 ropeide.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_ropeide', 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')

ropeide/editactions.py

-import os.path
-
-import Tkinter
-
-import rope.base.project
-import ropeide.core
-from ropeide import uihelpers, fill
-from ropeide.extension import SimpleAction
-from ropeide.menubar import MenuAddress
-import ropeide.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_ropeide(context):
-    resource = rope.base.project.get_no_project().get_resource(
-        os.path.expanduser('~%s.ropeide' % 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=ropeide.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 = ropeide.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=ropeide.movements.Scopes), 'C-M-e',
-                 others.child('Next Scope'), ['python']))
-actions.append(
-    SimpleAction('prev_scope', PrevNextElement(False, ropeide.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_ropeide', edit_dot_ropeide, 'C-x c',
-                            MenuAddress(['Edit', 'Edit ~/.rope'], '.', 4), ['all', 'none']))
-
-
-for action in actions:
-    core.register_action(action)

ropeide/editingcontexts.py

-from ropeide 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

ropeide/editingtools.py

-import rope.refactor.sourceutils
-import ropeide.highlighter
-import ropeide.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
-
-    def create_indenter(self, editor):
-        indents = rope.refactor.sourceutils.get_indent(self.project.get_pycore())
-        return ropeide.indenter.PythonCodeIndenter(editor, indents=indents)
-
-    def create_highlighting(self):
-        return ropeide.highlighter.PythonHighlighting()
-
-
-class ReSTEditingTools(EditingTools):
-
-    def create_indenter(self, editor):
-        return ropeide.indenter.NormalIndenter(editor)
-
-    def create_highlighting(self):
-        return ropeide.highlighter.ReSTHighlighting()
-
-
-class NormalEditingTools(EditingTools):
-
-    def create_indenter(self, editor):
-        return ropeide.indenter.NormalIndenter(editor)
-
-    def create_highlighting(self):
-        return ropeide.highlighter.NoHighlighting()

ropeide/editor.py

-import os
-
-import ScrolledText
-import Tkinter
-import tkFont
-from Tkinter import END, TclError, SEL_FIRST, SEL, SEL_LAST, INSERT
-
-import ropeide.editingtools
-import ropeide.searcher
-import ropeide.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 = ropeide.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))