1. zjes
  2. rope_py3k

Commits

Ali Gholami Rudi  committed 7813f38

Adding rope.tkhelpers
Removing rope.editor.TextEditor interface

  • Participants
  • Parent commits 53478d4
  • Branches trunk

Comments (0)

Files changed (10)

File docs/done.txt

View file
 ===========
 
 
+- Extending menus : July 25, 2006
+
+
 - ReST highlighting : July 24, 2006
 
 

File docs/stories.txt

View file
 * 'global' keyword issues for pycore
 
 
-* Read __init__.py of packages
+* Read ``__init__.py`` of packages
 
 
 * Auto completion contexts; strings, comments, imports, functions and ...
   * Clearing selection if something happens
   * Unifying builtin and emacs-style selections; if selection
     is active do the builtin cut and paste
-  * File : save, close
-  * Edit : set mark, copy, cut, paste, undo, redo, search, backward
-  * Code : code assist, quick outline, rename, correct indentation
-  * Help : about
 
 
 * Asking whether to save modified buffers when exiting @ 4h

File docs/workingon.txt

View file
 
 Possible solutions
 * Adding Highlighting.get_highlighting_region(text, index)
-- Making Highlighting independent of the editor
-- Pushing up Highlighting.highlights()
-- Experiment about memory usage of Text.get(START, END)
-  
+* `Text.after_idle`
+* `WidgetRedirector`
 
 
 Pre-Release Refactorings
 ==============================
 * Better color selection for reST highlighting
 * Better change editor dialog
-
-
+* Better next/prev
+* Goto definition for ``# comment.\na_var``
 
 
 Before 0.2 Release
 * Having only one Refactoring instance for a project?
 * PyObject and PyName equality checks; Value objects?
 * Consider using `StatementRangeFinder` in highlight module?
-* Directories should contain __init__.py to be packages in codeassist?
+* Directories should contain ``__init__.py`` to be packages in codeassist?
 * Separating ui and core modules and packages?
 
   * Decide which modules are the domain and which are the presentation

File rope/core.py

View file
             if activeEditor:
                 activeEditor.get_editor()._show_completion_window()
 
-        codeMenu.add_command(label='Code Assist', 
+        codeMenu.add_command(label='Code Assist',
                              command=code_assist, underline=0)
         def rename():
             activeEditor = self.editor_manager.active_editor
                'but WITHOUT ANY WARRANTY; without even the implied warranty of\n' + \
                'MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n' + \
                'GNU General Public License for more details.\n'
-        label = Label(toplevel, text=text, height=15, width=70, justify=LEFT)
+        label = Label(toplevel, text=text, height=15, width=70, 
+                      justify=LEFT, relief=GROOVE)
         def ok():
             toplevel.destroy()
         ok_button = Button(toplevel, text='OK', command=ok)

File rope/editor.py

View file
 import rope.editingtools
 from rope.uihelpers import EnhancedList, EnhancedListHandle
 from rope.uihelpers import TreeViewer, TreeViewerHandle
-
-
-class TextEditor(object):
-    """The base class for all text editor"""
-    def get_text(self):
-        pass
-    
-    def set_text(self, text):
-        pass
-
-    def get_start(self):
-        pass
-
-    def get_insert(self):
-        pass
-
-    def get_end(self):
-        pass
-
-    def get_relative(self, base_index, offset):
-        pass
-
-    def get_index(self, offset):
-        pass
-
-    def set_insert(self, index):
-        pass
-
-    def get(self, start=None, end=None):
-        pass
-
-    def insert(self, index, text):
-        pass
-
-    def delete(self, start=None, end=None):
-        pass
-
-    def next_word(self):
-        pass
-
-    def prev_word(self):
-        pass
-
-    def delete_next_word(self):
-        pass
-
-    def delete_prev_word(self):
-        pass
-
-    def goto_start(self):
-        pass
-
-    def goto_end(self):
-        pass
-
-    def highlight_match(self, match):
-        pass
-
-    def search(self, keyword, start, case=True, forwards=True):
-        pass
-
-    def line_editor(self):
-        pass
-
-
-class TextIndex(object):
-    """A class for pointing to a position in a text"""
-
+from rope.tkhelpers import WidgetRedirector
 
 class LineEditor(object):
     """An interface for line oriented editors"""
     def get_children(self, outline_node):
         return outline_node.get_children()
         
-        
-class GraphicalEditor(TextEditor):
+
+class _TextChangeInspector(object):
+
+    def __init__(self, text_widget):
+        self.redirector = WidgetRedirector(text_widget)
+        self.old_insert = self.redirector.register('insert', self._insert)
+        self.old_delete = self.redirector.register('delete', self._delete)
+    
+    def _insert(self, *args):
+        self.old_insert(*args)
+    
+    def _delete(self, *args):
+        self.old_delete(*args)
+
+
+class GraphicalEditor(object):
 
     def __init__(self, parent, editor_tools):
         font = None
         self._initialize_highlighting()
         self.status_bar_manager = None
         self.modification_observers = []
+        self.change_inspector = _TextChangeInspector(self.text)
 
     def _initialize_highlighting(self):
         def colorize(event=None):
             if start_tags:
                 tag = start_tags[0]
                 range_ = self.text.tag_prevrange(tag, start + '+1c')
-                if self.text.compare(range_[0], '<', start):
+                if range_ and self.text.compare(range_[0], '<', start):
                     start = range_[0]
-                if self.text.compare(range_[1], '>', end):
+                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 self.text.compare(range_[1], '>', end):
+                if range_ and self.text.compare(range_[1], '>', end):
                     end = range_[1]
             self._highlight_range(start, end)
         self.modified_flag = False
         return GraphicalLineEditor(self)
 
 
-class GraphicalTextIndex(TextIndex):
+class GraphicalTextIndex(object):
     """An immutable class for pointing to a position in a text"""
 
     def __init__(self, editor, index):

File rope/highlight.py

View file
                 if value:
                     a, b = match.span(key)
 #                    print a, b, key
-                    yield (start + a,
-                           start + b, key)
+                    yield (start + a, start + b, key)
     
     def _get_pattern(self):
         if not self.pattern:
     def get_styles(self):
         return {'keyword': HighlightingStyle(color='blue', bold=True),
                 'defkeyword': HighlightingStyle(color='blue', bold=True),
-                'string' : HighlightingStyle(color='#004080'),
-                'comment' : HighlightingStyle(color='#008000', italic=True),
-                'builtin' : HighlightingStyle(color='#908080'),
-                'definition' : HighlightingStyle(color='purple', bold=True)}
+                'string': HighlightingStyle(color='#004080'),
+                'comment': HighlightingStyle(color='#008000', italic=True),
+                'builtin': HighlightingStyle(color='#908080'),
+                'definition': HighlightingStyle(color='purple', bold=True)}
 
 
 class NoHighlighting(Highlighting):
         directive_pattern = '(?P<directive>\\.\\. \\w+.+::)'
         emphasis_pattern = '(?P<emphasis>\\*[^*\n]+\\*)'
         strongemphasis_pattern = '(?P<strongemphasis>\\*\\*[^*\n]+\\*\\*)'
-        literal_pattern = '(?P<literal>``[^`]+``)'
+        literal_pattern = '(?P<literal>``([^`]|`[^`])+``)'
         interpreted_pattern = '(?P<interpreted>`[^`]+`)(?P<role>:\\w+:)?'
         hyperlink_target_pattern = '(?P<hyperlink_target>\\w+://[^\\s]+)'
         hyperlink_pattern = '(?P<hyperlink>[\\w]+_|`[^`]+`_)\\b'

File rope/tkhelpers.py

View file
+from Tkinter import *
+
+
+class WidgetRedirector(object):
+    """Got from idlelib for redirecting messages to widgets"""
+
+    def __init__(self, widget):
+        self.dict = {}
+        self.widget = widget
+        self.tk = tk = widget.tk
+        w = widget._w
+        self.orig = w + "_orig"
+        tk.call("rename", w, self.orig)
+        tk.createcommand(w, self.dispatch)
+
+    def close(self):
+        for name in self.dict.keys():
+            self.unregister(name)
+        widget = self.widget; del self.widget
+        orig = self.orig; del self.orig
+        tk = widget.tk
+        w = widget._w
+        tk.deletecommand(w)
+        tk.call("rename", orig, w)
+
+    def register(self, name, function):
+        if self.dict.has_key(name):
+            previous = dict[name]
+        else:
+            previous = OriginalCommand(self, name)
+        self.dict[name] = function
+        setattr(self.widget, name, function)
+        return previous
+
+    def unregister(self, name):
+        if self.dict.has_key(name):
+            function = self.dict[name]
+            del self.dict[name]
+            if hasattr(self.widget, name):
+                delattr(self.widget, name)
+            return function
+        else:
+            return None
+
+    def dispatch(self, cmd, *args):
+        m = self.dict.get(cmd)
+        try:
+            if m:
+                return m(*args)
+            else:
+                return self.tk.call((self.orig, cmd) + args)
+        except TclError:
+            return ""
+
+
+class OriginalCommand(object):
+
+    def __init__(self, redir, name):
+        self.redir = redir
+        self.name = name
+        self.tk = redir.tk
+        self.orig = redir.orig
+        self.tk_call = self.tk.call
+        self.orig_and_name = (self.orig, self.name)
+
+    def __call__(self, *args):
+        return self.tk_call(self.orig_and_name + args)
+

File ropetest/highlighttest.py

View file
     def test_escaping(self):
         self.assertFalse(self.in_highlights('\\`Age\\` 3 months', (1, 7, 'interpreted')))
 
+    def test_back_quotes_inside_literals(self):
+        self.assertTrue(self.in_highlights('``a`b``', (0, 7, 'literal')))
+
+    def test_following_literals(self):
+        self.assertTrue(self.in_highlights('``a````b``', (0, 5, 'literal')))
+        self.assertTrue(self.in_highlights('``a````b``', (5, 10, 'literal')))
+
 
 def suite():
     result = unittest.TestSuite()

File ropetest/mockeditor.py

View file
-from rope.editor import TextEditor, TextIndex, LineEditor, EditorFactory
+from rope.editor import LineEditor, EditorFactory
 
 class MockEditorFactory(EditorFactory):
 
         self.editor.set_text('\n'.join(lines))
 
 
-class MockEditor(TextEditor):
+class MockEditor(object):
     '''A mock editor for testing editing commands'''
     def __init__(self):
         self.content = ''
         return MockLineEditor(self)
 
 
-class MockTextIndex(TextIndex):
+class MockTextIndex(object):
     def __init__(self, editor, index):
         self.editor = editor
         self.index = index

File setup.py

View file
 from distutils.core import setup
 
 setup(name='rope',
-      version='0.2',
+      version='0.2RC',
       description='A Python IDE ...',
       author='Ali Gholami Rudi',
       author_email='aligrudi@users.sourceforge.net',