Anonymous avatar Anonymous committed ad717e3

Find type; C-x C-t
Updating documentations

Comments (0)

Files changed (20)

docs/dev/done.txt

 ===========
 
 
+- Open Type; ``C-x C-t`` : April 23, 2007
+
+
+- Adding persisted_memory objectdb : April 20, 2007
+
+
+- Adding sqlite objectdb : April 20, 2007
+
+
 > Public Release 0.5m5 : April 15, 2007
 
 

docs/dev/issues.txt

 -------------------
 
 The internal DB has to be enhanced.  The `shelve` module can not be
-used since it is known to make mysterious exceptions.
+used since it is known to throw mysterious exceptions.
 
 * A single hierarchy; depth? Maybe 3
 * Keys are strings

docs/dev/stories.txt

 
 
 * Showing file history
-
-
-* Open Type; ``C-T``

docs/dev/workingon.txt

-Adding SqliteDB For ObjectInfo
-==============================
+Small Stories
+=============
 
-- Added ``persisted_memory`` objectdb
-- Document ``sqlite`` value for ``objectdb_type``project config
-- Document ``persisted_memory`` value for ``objectdb_type``project config
+- Adding HelperMatcher
+- Problem finding the changed region after whole buffer change
+- Reporting exceptions that happen in `StoppableTaskRunner`
+- Which objectdb should be the default? 'persisted_memory'
+- Removing listing keybindings in overview.txt and showing all in menus
+- Open type
 
-* Reporting exceptions that happen in `StoppableTaskRunner`
-* Which objectdb should be the default?
+* Problems for highlighting after refactorings
+* Move refactoring and moving a group of elements together
+
+
+For 0.5
+=======
+
+* How rope helps for custom refactorings
+* Request for contributions: ui, documentation, others
+* Write more docs
+* Adding ``random_hacks.txt``?
+* A better homepage with screen-shots?
 
 
 Remaining Small Stories
 
 * Refactorings
 
-  * Rename class/function/module/package/method/variable/keyword arg
+  * Rename everything!
   * Extract method
-  * Extract variable
+  * Extract local variable
   * Move class/function/module/package/method
   * Inline method/local variable
   * Change method signature
   * Convert local variable to field
   * Replace method with method object
   * Inline argument default value
+
   * Basic implicit interfaces handling
+  * Fixing imports when needed
   * Previewing refactorings
   * Stopping refactorings
   * Undo/redo refactorings
 
 * Object Inference
 
+  * A static object inference approach
   * A dynamic object inference approach
-  * A static object inference approach
   * Automatic SOI analysis
   * Handling built-in container types
   * Saving object information on disk
-  * Basic stored object data validation
+  * Stored object data validation
 
 
 Download

docs/user/overview.txt

  Rope Features
 ===============
 
-.. contents:: Table of Contents
-
-
-Overview
-========
 
 The purpose of this file is to give an overview of some of rope's
 features.  It is incomplete.  Because rope is enhancing very fast
 rope try its features and see its unit tests.
 
 
+.. contents:: Table of Contents
+
+
 Keybinding
 ==========
 
-The keybinding will be customizable in future.  Some of these bindings
-are chosen from emacs and some from eclipse.  ("C" stands for Control
-key and "M" for Meta(Alt) key.)
-
-==========================  =============  =============
-binding                     emacs binding  normal
-==========================  =============  =============
-open/new project            C-x C-p        C-P
-close project               C-x p k
-show project tree           C-x p t        M-Q r
-edit project config         C-x p c
-validate project files      C-x p v        F5
-sync project to disk        C-x p s
---------------------------  -------------  -------------
-new module                  C-x n m
-new package                 C-x n p
-new file                    C-x n f
-new directory               C-x n d
-find file                   C-x C-f        C-R
-change active editor        C-x b          C-E
-close active editor         C-x k          C-w
-exit                        C-x C-c        C-W
-run active editor           C-c x p        M-X p
-run unit-tests              C-c x t        M-X t
-run SOI                     C-c x s
---------------------------  -------------  -------------
-save                        C-x C-s        C-s
-save all                    C-x s          C-S
-undo project change         C-x p u        C-Z
-redo project change         C-x p r        C-Y
-project history             C-x p h
---------------------------  -------------  -------------
-forward character           C-f
-backward character          C-b
-next line                   C-n
-previous line               C-p
-next word                   M-f
-previous word               M-b
-next page                   C-v
-previous page               M-v
-downcase word               M-l
-capitalize word             M-c
-upcase word                 M-u
-start searching             C-s            C-f
-start reverse searching     C-r            C-F
-last edit location          C-x C-q        C-q
-goto line                   C-x C-g        C-g
---------------------------  -------------  -------------
-set mark                    C-space
-cut region                  C-w            C-x
-copy region                 M-w            C-c
-swap mark and insert        C-x C-x
-paste                       C-y            C-v
-yank                        M-y
-undo editing                C-x u          C-z
-redo editing                C-x r          C-y
-repeat last action          C-x z
---------------------------  -------------  -------------
-Execute Command             M-x
-Edit ~/.rope                C-x c
---------------------------  -------------  -------------
-code-assist(auto-complete)  M-/            C-space
-go to definition location   C-c g          F3
-show doc                    C-c C-d        F2
-show quick outline          C-c C-o        C-o
-correct line indentation    C-i            C-i
-remove extra spaces         C-c C-f        C-F
-comment current line        C-c c          C-3
-comment region lines        C-c C-c
-find occurrences            C-c C-s        C-G
-show codetags               C-c a t
-show errors                 C-c a e
-show warnings               C-c a w
-show all annotations        C-c a a
---------------------------  -------------  -------------
-rename refactoring          C-c r r        M-R
-extract method              C-c r m        M-M
-move refactoring            C-c r v        M-V
-inline refactoring          C-c r i        M-I
-change method signature     C-c r c        M-C
-extract local variable      C-c r l        M-L
-introduce factory           C-c r f
-method to method object     C-c r j
-encapsulate field           C-c r s
-introduce parameter         C-c r p
-rename in file              C-c r e
-local to field              C-c r b
-inline argument default     C-c r d
-module to package           C-c r 1 p
-rename current module       C-c r 1 r
-move current package        C-c r 1 v
---------------------------  -------------  -------------
-organize imports            C-c i o        C-O
-expand star imports         C-c i x
-relatives to absolutes      C-c i a
-froms to imports            C-c i i
-handle long imports         C-c i l
---------------------------  -------------  -------------
-generate variable           C-c n v        M-G v
-generate function/method    C-c n f        M-G f
-generate class              C-c n c        M-G c
-generate module             C-c n m        M-G m
-generate package            C-c n p        M-G p
---------------------------  -------------  -------------
-spell-check word            M-$
-spell-check buffer          C-x $ b
-spell-check region          C-x $ r
---------------------------  -------------  -------------
-about                       C-h a
-README                      C-h r
-features                    C-h f
-overview                    C-h o
-tutorial                    C-h t
-using as library            C-h l
-contributing                C-h c
-==========================  =============  =============
+You can change the keybinding in ``~/.rope``.  The keybinding is shown
+next to every action in menus.  Some of these bindings are chosen from
+emacs and some from eclipse.  ("C" stands for Control key and "M" for
+Meta(Alt) key.)
 
 
 Code Assist(Auto Complete)
 ``.ropeproject`` Folder
 =======================
 
-``0.5m4`` release added of a new
-folder in projects for holding configurations and other information
-for a project.  Its default name is ``.ropeproject``, but it can be
-changed in ``~/.rope`` or `Project` constructor (if using rope as a
-library).  You can also force rope not to make such a folder by using
-`None` instead of a `str`.
+``0.5m4`` release added of a new folder inside projects for holding
+configurations and other information for a project.  Its default name
+is ``.ropeproject``, but it can be changed in ``~/.rope`` or `Project`
+constructor (if using rope as a library).  You can also force rope not
+to make such a folder by using `None` instead of a `str`.
 
-Currently it is used for these purposes:
+Currently it is used for things such as:
 
 * There is a ``config.py`` file in this folder in which you can change
   project configurations.  Look at the default ``config.py`` file,
 Refactorings
 ============
 
-This section shows some random refactorings you can do using rope.
+This section shows some random refactorings you can perform using rope.
 
 
 Renaming attributes
 parameters that are passed to a function.
 
 
-Basic Object Inference
-======================
+Object Inference
+================
+
+
+Static Object Inference
+-----------------------
 
 ::
 
     def a_func(arg):
         return arg.c_func()
 
-    a_var = a_func(C)
+    a_var = a_func(C())
 
 Here rope knows that the type of a_var is a `list` that holds `str`\s.
 
 
 Another thing that has been added is SOI analysis (Available in
 ``Edit`` menu or by using ``C-c x s``).  It analyzes a module for
-finding useful object information.  Currently it is used only when the
-user askes (Just like DOI), but in future that might change.
+finding useful object information.  Rope runs SOI analysis whenever a
+files is changed on the changed scopes automatically. (This can be
+overridden in project ``config.py``.)
 
-Many kinds of information is collected during SOI like per name data
+Many kind of information is collected during SOI like per name data
 for builtin container types::
 
   l1 = [C()]
 about them in future releases.
 
 'Rename when unsure' option has been added to rename refactoring.  This
-option tells rope to rename when it doesn't know whether it is an exact
-match or not.  For example after renaming `C.a_func` when the
+option tells rope to rename when it doesn't know whether it is an
+exact match or not.  For example after renaming `C.a_func` when the
 'rename when unsure' option is set in::
 
   class C(object):
 
 
 Dynamic Object Inference
-========================
+------------------------
 
 Dynamic type inference gets its needed information from running
 modules (``M-X p``) or unit tests (``M-X t``).  You open the module
 
 
 Builtin Container Types
------------------------
+'''''''''''''''''''''''
 
 Builtin types can be handled in a limited way, too::
 
 Automatic SOI Analysis
 ----------------------
 
-Maybe the most important internal feature added in this release is
-automatic static object inference analysis.  When turned on, it
-analyzes the changed scopes of a file when saving for obtaining object
-information; So this might make saving files a bit more time
-consuming.  This feature is by default turned on, but you can turn it
-off by editing your project ``config.py`` file (available in
-``${your_project_root}/.ropeproject/config.py``, if you're new to
-rope), though that is not recommended.
+When turned on, it analyzes the changed scopes of a file when saving
+for obtaining object information; So this might make saving files a
+bit more time consuming.  This feature is by default turned on, but
+you can turn it off by editing your project ``config.py`` file
+(available in ``${your_project_root}/.ropeproject/config.py``, if
+you're new to rope), though that is not recommended.
 
 
 Outline

docs/user/tutorial.txt

   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 U``/``C-x R``.
+  ``C-x p u``/``C-x p r``.
 
 
 ReStructuredText Files

rope/base/default_config.py

+# The default ``config.py``
+
+
+def set_prefs(prefs):
+    """This function is called before the project is opened"""
+
+    # Specify which files and folders to ignore in the project.
+    # Changes to ignored resources are not added to the history and
+    # VCSs.  Also they are not shown in "Find File" dialog.
+    prefs['ignored_resources'] = ['*.pyc', '.svn', '*~', '.ropeproject']
+
+    # This option tells rope how to hold and save object information.
+    # Possible values are:
+    #
+    # * 'memory': It holds all information in
+    #   memory.  So it is the fastest and the least memory efficient.
+    #   Its biggest problem is that the data is not saved and
+    #   the information is lost when you open a project in future.
+    #   You probably never want to use this (it is used in unit
+    #   tests), but if you decide not to have rope folder (see ~/.rope
+    #   file) this db is used.
+    #
+    # * 'persisted_memory': Exactly like 'memory' but the information is
+    #   saved for future sessions.  The problem with this approach is
+    #   that it might take lots of memory (This is not an issue for
+    #   small projects).  It might also make opening and closing
+    #   projects a bit slower.
+    #
+    # * 'shelve': It stores data in `shelve` files.  This solves
+    #   both the memory efficiency and the persistency problems.  But
+    #   `shelve` is known to cause misterious problems in rare
+    #   conditions.
+    #
+    # * 'sqlite': It uses `sqlite3` module which is available in
+    #   Python distributions starting from ``2.5``.  It is like
+    #   'shelve' but probably more reliable.  But it is much less CPU
+    #   efficient.
+    #
+    # The choice of the objectdb might be hard.  For small
+    # projects I think 'persisted_memory' is the best.  For larger
+    # projects I prefer 'shelve'.  If you encounter mysterious
+    # problems when using 'shelve' use the slower 'sqlite'.
+    prefs['objectdb_type'] = 'persisted_memory'
+
+    # Shows whether to save history across sessions.  Defaults to
+    # `False`.
+    prefs['save_history'] = True
+    prefs['max_history_items'] = 100
+
+    # If `False` when running modules or unit tests "Dynamic Object
+    # Inference" is turned off.  This makes them much faster.  The
+    # default is `True`.
+    prefs['perform_doi'] = True
+
+    # Rope can test the validity of its object DB when running.  You
+    # can turn this feature off by using `False`.  Defaults to
+    # `True`.
+    prefs['validate_objectdb'] = True
+
+    # If `True`, rope will analyze each module when it is saved.
+    prefs['automatic_soi'] = True
+
+    # Set the number spaces used for indenting.  According to
+    # :PEP:`8`, it is best to use 4 spaces.  Since most of rope's
+    # unit-tests use 4 spaces it is more reliable, too.
+    prefs['indent_size'] = 4
+
+
+def project_opened(project):
+    """This function is called after the project is opened"""
+    # Do whatever you like here!

rope/base/oi/objectinfo.py

         preferred = self.project.get_prefs().get('objectdb_type', 'memory')
         validation = TextualValidation(self.to_pyobject)
         if preferred == 'memory' or self.project.ropefolder is None:
-            db = memorydb.MemoryDB()
+            db = memorydb.MemoryDB(self.project)
         elif preferred == 'sqlite' and sys.version_info >= (2, 5, 0):
             import rope.base.oi.sqlitedb
             db = rope.base.oi.sqlitedb.SqliteDB(self.project)

rope/base/oi/sqlitedb.py

                         'scope_id INTEGER,' \
                         'name VARCHAR(255),' \
                         'value BLOB,' \
-                        'FOREIGN KEY (scope_id) REFERENCES scopes (scope_id))'
+                        'FOREIGN KEY (scope_id) REFERENCES scopes ( scope_id ))'
+
         self.execute(files_table)
         self.execute(scopes_table)
         self.execute(callinfo_table)

rope/base/project.py

 
     def close(self):
         """Closes project open resources"""
+        if self._history is None:
+            self.history.sync()
 
     def sync(self):
         """Closes project open resources"""
     def _init_prefs(self, prefs):
         run_globals = {}
         if self.ropefolder is not None:
-            if self._ropefolder.has_child('config.py'):
-                config = self._ropefolder.get_child('config.py')
-            else:
-                config = self._ropefolder.create_file('config.py')
-                config.write(_DEFAULT_CONFIG_PY)
+            if not self._ropefolder.has_child('config.py'):
+                config = self._write_config()
+            config = self._ropefolder.get_child('config.py')
             run_globals.update({'__name__': '__main__',
                                 '__builtins__': __builtins__,
                                 '__file__': config.real_path})
         if 'project_opened' in run_globals:
             run_globals['project_opened'](self)
 
+    def _write_config(self):
+        import rope.base.default_config
+        import inspect
+        text = inspect.getsource(rope.base.default_config)
+        config = self._ropefolder.create_file('config.py')
+        config.write(text)
+        return config
+
     def _init_other_parts(self):
         # Forcing the creation of `self.pycore` to register observers
         self.pycore
 
     def close(self):
         self.pycore.object_info.sync()
-        self.history.sync()
+        super(Project, self).close()
 
     def set(self, key, value):
         """Set the `key` preference to `value`"""
 
     def _validate(self, resource):
         self._list = None
-
-
-_DEFAULT_CONFIG_PY = '''# The default ``config.py``
-
-
-def set_prefs(prefs):
-    """This function is called before the project is opened"""
-
-    # Specify which files and folders to ignore in the project.
-    # Changes to ignored resources are not added to the history and
-    # VCSs.  Also they are not shown in "Find File" dialog.
-    prefs['ignored_resources'] = ['*.pyc', '.svn', '*~', '.ropeproject']
-
-    # This option tells rope how to hold and save object information.
-    # Possible values are:
-    #
-    # * 'memory': It holds all information in
-    #   memory.  So it is the fastest and the least memory efficient.
-    #   Its biggest problem is that the data is not saved and
-    #   the information is lost when you open a project in future.
-    #   You probably never want to use this (it is used in unit
-    #   tests), but if you decide not to have rope folder (see ~/.rope
-    #   file) this db is used.
-    #
-    # * 'persisted_memory': Exactly like 'memory' but the information is
-    #   saved for future sessions.  The problem with this approach is
-    #   that it might take lots of memory (This is not an issue for
-    #   small projects).
-    #
-    # * 'shelve': It stores data in `shelve` files.  This solves
-    #   both the memory efficiency and the persistency problems.  But
-    #   `shelve` is known to cause misterious problems in rare
-    #   conditions.
-    #
-    # * 'sqlite': It uses `sqlite3` module which is available in
-    #   Python distributions from ``2.5``.  It is like 'shelve'
-    #   but probably more reliable.  But it is much less CPU
-    #   efficient.
-    #
-    # The choice of objectdb might be hard.  For small
-    # projects I think 'persisted_memory' is the best.  For larger
-    # projects I prefer 'shelve'.  If you encounter mysterious
-    # problems when using 'shelve' use the slower 'sqlite'.
-    prefs['objectdb_type'] = 'persisted_memory'
-
-    # Shows whether to save history across sessions.  Defaults to
-    # `False`.
-    prefs['save_history'] = True
-    prefs['max_history_items'] = 100
-
-    # If `False` when running modules or unit tests "Dynamic Object
-    # Inference" is turned off.  This makes them much faster.  The
-    # default is `True`.
-    prefs['perform_doi'] = True
-
-    # Rope can test the validity of its object DB when running.  You
-    # can turn this feature off by using `False`.  Defaults to
-    # `True`.
-    prefs['validate_objectdb'] = True
-
-    # If `True`, rope will analyze each module when it is saved.
-    prefs['automatic_soi'] = True
-
-    # Set the number spaces used for indenting.  According to
-    # :PEP:`8`, it is best to use 4 spaces.  Since most of rope's
-    # unit-tests use 4 spaces it is more reliable, too.
-    prefs['indent_size'] = 4
-
-
-def project_opened(project):
-    """This function is called after the project is opened"""
-    # Do whatever you like here!
-'''

rope/ui/actionhelpers.py

             def __init__(self, task):
                 self.task = task
                 self.result = None
-                self.interrupted = False
+                self.exception = None
 
             def __call__(self):
                 try:
                     try:
                         self.result = self.task(handle)
-                    except rope.base.exceptions.InterruptedTaskError:
-                        self.interrupted = True
+                    except Exception, e:
+                        self.exception = e
                 finally:
                     toplevel.quit()
         
         stop_button.focus_set()
         toplevel.mainloop()
         toplevel.destroy()
-        if calculate.interrupted:
+        if calculate.exception is not None:
+            description = type(calculate.exception).__name__ + ': ' + \
+                          str(calculate.exception)
             raise rope.base.exceptions.InterruptedTaskError(
-                'Task <%s> was interrupted' % self.title)
+                'Task <%s> was interrupted.\nReason: <%s>' %
+                (self.title, description))
         return calculate.result
 
 def simple_stoppable(description):

rope/ui/dot_rope.py

     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')

rope/ui/editactions.py

         context.core.repeat_last_action()
 
 
-class FindCommandHandle(uihelpers.FindItemHandle):
+class FindCommandHandle(uihelpers.EnhancedListHandle):
 
     def __init__(self, core):
         self.core = core
+        self.matcher = uihelpers.HelperMatcher(
+            list(self.core.get_available_actions()), self._to_search_text)
+
+    def _to_search_text(self, action):
+        return action.get_name()
 
     def find_matches(self, starting):
-        return [action for action in self.core.get_available_actions()
-                if action.get_name().startswith(starting)]
+        return self.matcher.find_matches(starting)
 
     def selected(self, action):
         self.core.perform_action(action)
 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):
+    context.editor.kill_line()
+
 core = rope.ui.core.Core.get_core()
 core.add_menu_cascade(MenuAddress(['Edit'], 'e'), ['all', 'none'])
 actions = []
 
-actions.append(SimpleAction('next_word', next_word, 'M-f', None, ['all']))
-actions.append(SimpleAction('prev_word', prev_word, 'M-b', None, ['all']))
-actions.append(SimpleAction('delete_next_word', delete_next_word, 'M-d', None, ['all']))
-actions.append(SimpleAction('delete_prev_word', delete_prev_word, 'M-BackSpace', None, ['all']))
-actions.append(SimpleAction('lower_next_word', lower_word, 'M-l', None, ['all']))
-actions.append(SimpleAction('upper_next_word', upper_word, 'M-u', None, ['all']))
-actions.append(SimpleAction('capitalize_next_word', capitalize_word, 'M-c', None, ['all']))
-actions.append(SimpleAction('goto_center_line', goto_center_line, 'M-r', None, ['all']))
+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('set_mark', set_mark, 'C-space',
                             MenuAddress(['Edit', 'Set Mark'], 's'), ['all']))

rope/ui/editor.py

         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._colorize(start, end)
         self.change_inspector.clear_changed()
         self.text.see(start_index._getIndex())
 
     def _bind_keys(self):
-        def do_goto_start(event):
-            self.goto_start()
-            self.text.see(INSERT)
-        def do_goto_end(event):
-            self.goto_end()
-            self.text.see(INSERT)
-        self.text.bind('<Alt-less>', do_goto_start)
-        self.text.bind('<Alt-KeyPress->>', do_goto_end)
         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 go_next_page(event):
-            self.next_page()
-            return 'break'
-        self.text.bind('<Control-v>', go_next_page)
-        def go_prev_page(event):
-            self.prev_page()
-            return 'break'
-        self.text.bind('<Alt-v>', go_prev_page)
         def do_insert_tab(event):
             self.insert_tab()
             return 'break'
         self.text.bind('<Any-KeyPress>', self._search_handler)
         self.text.bind('<BackSpace>', backspace, '+')
         self.text.bind('<FocusOut>', lambda event: self._focus_went_out())
-        def kill_line(event):
-            self.kill_line()
-            return 'break'
-        self.text.bind('<Control-k>', kill_line)
-        self.text.bind('<Control-l>', lambda event: self.center_line())
 
     def center_line(self):
         mid = self._get_center_line()
                 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]
-        if self.changed_region is None and self.change_observer:
+        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)
-        self.changed_region = (start, end)
-        return result
 
     def _delete(self, *args):
         start = self.text.index(args[0])
                 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]
-        if self.changed_region is None and self.change_observer:
-            self.text.after_idle(self.change_observer)
         self.changed_region = (start, end)
+        self._notify_observer()
         return result
 
     def _edit(self, *args):
                 start = self.changed_region[0]
             if self.text.compare(self.changed_region[1], '>', end):
                 end = self.changed_region[1]
-        if self.changed_region is None and self.change_observer:
-            self.text.after_idle(self.change_observer)
         self.changed_region = (start, end)
+        self._notify_observer()
         return result
 
     def get_changed_region(self):

rope/ui/fileactions.py

 from rope.ui.extension import SimpleAction
 from rope.ui.menubar import MenuAddress
 from rope.ui.uihelpers import (TreeViewHandle, TreeView, find_item_dialog,
-                               SearchableList, SearchableListHandle)
+                               SearchableList, SearchableListHandle, HelperMatcher)
 
 
 def open_project(context):
     _create_resource_dialog(context.get_core(), do_create_package, 'Package', 'Source Folder')
 
 
-class _NormalSelector(object):
-
-    def __init__(self, pattern):
-        self.pattern = pattern
-
-    def can_select(self, input_str):
-        return input_str.startswith(self.pattern)
-
-
-class _RESelector(object):
-
-    def __init__(self, pattern):
-        self.pattern = re.compile((pattern + '*').replace('?', '.').
-                                  replace('*', '.*'))
-
-    def can_select(self, input_str):
-        return self.pattern.match(input_str)
-
-
 class FindFileHandle(object):
 
     def __init__(self, context):
         self.core = context.core
         self.project = context.project
-        self.all_files = None
-        self.last_keyword = None
-        self.last_result = None
+        self.matcher = None
 
     def find_matches(self, starting):
         """Returns the Files in the project whose names starts with starting"""
-        files = []
-        if self.last_keyword is not None and starting.startswith(self.last_keyword):
-            files = self.last_result
-        else:
-            if self.all_files is None:
-                self.all_files = list(self.project.get_files())
-                self.all_files.sort(cmp=self._compare_files)
-            files = self.all_files
-        result = []
-        selector = self._create_selector(starting)
-        for file_ in files:
-            if selector.can_select(file_.name):
-                result.append(file_)
-            elif file_.name == '__init__.py' and \
-                 selector.can_select(file_.parent.name):
-                result.append(file_)
-        self.last_keyword = starting
-        self.last_result = result
-        return result
+        if self.matcher is None:
+            files = list(self.project.get_files())
+            files.sort(cmp=self._compare_files)
+            self.matcher = HelperMatcher(files, self._to_search_text)
+        return self.matcher.find_matches(starting)
 
-    def _create_selector(self, pattern):
-        if '?' in pattern or '*' in pattern:
-            return _RESelector(pattern)
-        else:
-            return _NormalSelector(pattern)
+    def _to_search_text(self, entry):
+        if entry.name == '__init__.py':
+            return [entry.parent.name, '__init__.py']
+        return entry.name
 
     def selected(self, resource):
         self.core.open_file(resource.path)
     find_item_dialog(FindFileHandle(context), title='Find Project File',
                      matches='Matching Files')
 
+
+class FindTypeHandle(object):
+
+    def __init__(self, context):
+        self.core = context.core
+        self.pycore = context.project.get_pycore()
+        self.matcher = None
+
+    def find_matches(self, starting):
+        """Returns the Files in the project whose names starts with starting"""
+        if self.matcher is None:
+            types = list(self.pycore.get_classes())
+            types.sort(cmp=self._compare_types)
+            self.matcher = HelperMatcher(types, self._to_search_text)
+        return self.matcher.find_matches(starting)
+
+    def _to_search_text(self, entry):
+        return entry.get_name()
+
+    def selected(self, pyclass):
+        editor_manager = self.core.get_editor_manager()
+        pymodule = pyclass.get_module()
+        file_editor = editor_manager.get_resource_editor(
+            pymodule.get_resource())
+        file_editor.get_editor().goto_line(pyclass.get_ast().lineno)
+
+    def to_string(self, pyclass):
+        return '%s: %s' % (pyclass.get_module().get_resource().path,
+                           pyclass.get_name())
+
+    def _compare_types(self, type1, type2):
+        return cmp(type1.get_name(), type2.get_name())
+
+def find_type(context):
+    if not rope.ui.actionhelpers.check_project(context.core):
+        return
+    find_item_dialog(FindTypeHandle(context), title='Find Project Type',
+                     matches='Matching Types')
+
 class _ResourceViewHandle(TreeViewHandle):
 
     def __init__(self, core, toplevel):
 
 actions.append(SimpleAction('find_file', find_file, 'C-x C-f',
                             MenuAddress(['File', 'Find File...'], 'f', 1)))
+actions.append(SimpleAction('find_type', find_type, 'C-x C-t',
+                            MenuAddress(['File', 'Find Type...'], None, 1)))
 core.add_menu_cascade(MenuAddress(['File', 'New'], 'n', 1), ['all', 'none'])
 actions.append(SimpleAction('create_file', create_file, 'C-x n f',
                             MenuAddress(['File', 'New', 'New File...'], 'f')))

rope/ui/keybinder.py

         modifier = modifier.replace('M-', 'Alt-').replace('C-', 'Control-')
         if key.isdigit():
             key = 'KeyPress-' + key
-        key = key.replace('/', 'slash').replace('$', 'dollar')
+        key = key.replace('/', 'slash').replace('$', 'dollar').\
+              replace('<', 'less').replace('>', 'KeyPress->')
         result.append('<%s>' % (modifier + key))
     return ''.join(result)

rope/ui/statusbar.py

         return self.status_text[kind]
 
     def remove_status(self, status):
-        status.label.destroy()
-        del self.status_text[status.kind]
-
+        if status.kind in self.status_text:
+            status.label.destroy()
+            del self.status_text[status.kind]

rope/ui/uihelpers.py

+import re
 import ScrolledText
 import Tkinter
 from Tkinter import *
         width = int(self.canvas['width']) * self.percent / 100
         self.canvas.create_rectangle(0, 0, width, self.canvas['height'],
                                      fill=self.color)
+
+
+class HelperMatcher(object):
+
+    def __init__(self, all_entries, to_search_text):
+        self.all_entries = all_entries
+        self.to_search_text = to_search_text
+        self.last_keyword = None
+        self.last_result = None
+
+    def find_matches(self, starting):
+        if starting == self.last_keyword:
+            return self.last_result
+        entries = []
+        if self.last_keyword is not None and \
+           starting.startswith(self.last_keyword):
+            entries = self.last_result
+        else:
+            entries = self.all_entries
+        result = []
+        selector = self._create_selector(starting)
+        for entry in entries:
+            if self._can_match(selector, entry):
+                result.append(entry)
+        self.last_keyword = starting
+        self.last_result = result
+        return result
+
+    def _can_match(self, selector, entry):
+        text = self.to_search_text(entry)
+        if isinstance(text, basestring):
+            return selector.can_select(text)
+        if isinstance(text, list):
+            for subtext in text:
+                if selector.can_select(subtext):
+                    return True
+        return False
+
+    def _create_selector(self, pattern):
+        if '?' in pattern or '*' in pattern:
+            return _RESelector(pattern)
+        else:
+            return _NormalSelector(pattern)
+
+
+class _NormalSelector(object):
+
+    def __init__(self, pattern):
+        self.pattern = pattern
+
+    def can_select(self, input_str):
+        return input_str.startswith(self.pattern)
+
+
+class _RESelector(object):
+
+    def __init__(self, pattern):
+        self.pattern = re.compile((pattern + '*').replace('?', '.').
+                                  replace('*', '.*'))
+
+    def can_select(self, input_str):
+        return self.pattern.match(input_str)

ropetest/objectdbtest.py

         self.project = testutils.sample_project()
         validation = _MockValidation()
         self.dbs = [
-            objectdb.ObjectDB(memorydb.MemoryDB(), validation),
+            objectdb.ObjectDB(memorydb.MemoryDB(self.project), validation),
             objectdb.ObjectDB(shelvedb.ShelveDB(self.project), validation),
             objectdb.ObjectDB(sqlitedb.SqliteDB(self.project), validation)]
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.