Daniel Poelzleithner avatar Daniel Poelzleithner committed 1b9d0c1

updates to definer functionality and implment a python definer based on rope

Comments (0)

Files changed (6)

pida-plugins/python/python.py

 from pida.core.features import FeaturesConfig
 from pida.core.languages import (LanguageService, Outliner, Validator,
     Completer, LanguageServiceFeaturesConfig, LanguageInfo, PRIO_VERY_GOOD,
-    PRIO_GOOD)
+    PRIO_GOOD, Definer, Definition)
 
 # services
 import pida.services.filemanager.filehiddencheck as filehiddencheck
         return [c.name for c in so if c.name.startswith(base)]
 
 
+class PythonDefiner(Definer):
+    
+    def get_definition(self, buffer, offset):
+        mp = ModuleParser(self.document.filename)
+        buffer = buffer + ('\n' * 20)
+        
+        from rope.contrib.findit  import find_definition
+        from rope.base.exceptions import RopeError
+        
+        try:
+            dl = find_definition(mp.project, buffer, offset)
+        except RopeError:
+            return None
+        dl = find_definition(mp.project, buffer, offset)
+        if not dl:
+            return None
+
+        rv = Definition(file_name=dl.resource.path, offset=dl.offset, 
+                        line=dl.lineno, length=(dl.region[1]-dl.region[0]))
+
+        return rv
+            
+        #(project, code, offset, resource=None, maxfixes=1)
+
 class Python(LanguageService):
 
     language_name = 'Python'
     outliner_factory = PythonOutliner
     validator_factory = PythonValidator
     completer_factory = PythonCompleter
+    definer_factory = PythonDefiner
 
     features_config = PythonFeaturesConfig
     actions_config = PythonActionsConfig

pida/core/languages.py

 
 class Definition(object):
     """Returned by a Definer instance"""
-    def __init__(self, document=None, line=0, signature="", doc=""):
-        self.document = document
+    def __init__(self, file_name=None, offset=None, length=None, line=None,
+                 signature=None, doc=None):
+        self.file_name = file_name
+        self.offset = offset
+        self.length = length
         self.line = line
         self.signature = signature
         self.doc = doc
+        
+    def __repr__(self):
+        where = ""
+        if self.offset is not None:
+            where = " offset %s " %self.offset
+        elif self.line is not None:
+            where = " line %s " %self.line
+        return '<Definition %s%s>' %(self.file_name, where)
 
 class Definer(BaseDocumentHandler):
     """
     The definer class is used to allow the user to the definition of a
     word.
     """
-    def get_definition(self, offset):
+    def get_definition(self, buffer, offset):
         """
-        Returns a Definition class pointing to document defining the word
+        Returns the Definition class pointing to document defining the word
         searched for. The Definier has to find out which word the offset is on.
 
         @offset - nth char in the document point is on

pida/editors/mooedit/mooedit.py

         i = buf.get_iter_at_offset(buf.props.cursor_position)
         return i.get_line()+1
 
+    def get_cursor_position(self):
+        buf = self._current.editor.get_buffer()
+        return buf.props.cursor_position
+
+    def set_cursor_position(self, position, scroll=True):
+        #FIXME: return current position
+        buf = self._current.editor.get_buffer()
+        itr = buf.get_iter_at_offset(position)
+        buf.place_cursor(itr)
+        if scroll:
+            itr = buf.get_iter_at_offset(position)
+            self._current.editor.scroll_to_iter(itr, 0.05, use_align=True)
+
     def replace_line(self, editor, lineno, text):
         """
         Replace a line in the editor. lineno is index 0 based.

pida/editors/vim/vim.py

     def set_path(self, path):
         return self._com.cd(path)
 
+    #def get_cursor_position(self):
+    #    #FIXME: return current position
+    #    return 0
+
+    #def set_cursor_position(self, position, scroll=True):
+    #    #FIXME: return current position
+    #    pass
+
     def stop(self):
         self._com.quit(reply_handler=lambda *a: None,
                        error_handler=lambda *a: None)

pida/services/buffer/buffer.py

             self._add_document(document)
         self.view_document(document, line=line)
         self.emit('document-opened', document=document)
+        return document
 
     def open_files(self, files):
         if not files:

pida/services/language/language.py

 from pida.core.languages import LanguageInfo
 from pida.utils.pdbus import EXPORT
 
-from pida.utils.gthreads import GeneratorTask
+from pida.utils.gthreads import GeneratorTask, gcall
 
 
 # core
             self.svc.show_browser()
         else:
             self.svc.hide_browser()
-            
+
     def on_goto_definition(self, action):
-        print "goto definition", action
-        
+        self.svc.goto_defintion()
 
 
 class LanguageCommandsConfig(CommandsConfig):
     def hide_browser(self):
         self.boss.cmd('window', 'remove_view', view=self._view_outliner)
 
+
+    def goto_defintion(self):
+        doc = self.boss.cmd('buffer', 'get_current')
+        definer = self.get_definer(doc)
+        res = definer.get_definition(doc.content, 
+                                      self.boss.editor.get_cursor_position())
+
+        if res:
+            ndoc = self.boss.cmd('buffer', 'open_file', file_name=res.file_name)
+            self.boss.get_service('buffer').view_document(ndoc)
+            # FIXME: we have a timeing problem here. so we have to use
+            # gcall which is ugly in my opinion
+            if res.offset is not None and \
+               hasattr(self.boss.editor, 'set_cursor_position'):
+                gcall(self.boss.editor.set_cursor_position, res.offset)
+
+            elif res.line is not None:
+                gcall(self.boss.editor.goto_line, res.line)
+        else:
+            self.boss.get_service('notify').notify(
+            data=_('No definition found'), timeout=2000)
+        #self.boss.cmd('window', 'remove_view', view=self._view_outliner)
+
+
     def on_buffer_typechanged(self, document):
         for k in ("_lng_outliner", "_lng_validator", "_lng_completer",
                  "_lng_definer"):
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.