CodeAssistServer: improved code completions and calltips for files belonging to a project (that may be using an interpreter different from the one used by eric or configured globally). release-6.5.0

Sun, 28 Oct 2018 12:30:45 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sun, 28 Oct 2018 12:30:45 +0100
changeset 283
d98e971d9e4c
parent 282
ccb5c268df65
child 284
18f32c079abc

CodeAssistServer: improved code completions and calltips for files belonging to a project (that may be using an interpreter different from the one used by eric or configured globally).

ChangeLog file | annotate | diff | comparison | revisions
PluginRefactoringRope.py file | annotate | diff | comparison | revisions
PluginRefactoringRope.zip file | annotate | diff | comparison | revisions
RefactoringRope/CodeAssistServer.py file | annotate | diff | comparison | revisions
RefactoringRope/Documentation/source/Plugin_Refactoring_Rope.RefactoringRope.CodeAssistClient.html file | annotate | diff | comparison | revisions
RefactoringRope/Documentation/source/Plugin_Refactoring_Rope.RefactoringRope.CodeAssistServer.html file | annotate | diff | comparison | revisions
RefactoringRope/Documentation/source/Plugin_Refactoring_Rope.RefactoringRope.RefactoringClient.html file | annotate | diff | comparison | revisions
--- a/ChangeLog	Sun Sep 16 13:17:08 2018 +0200
+++ b/ChangeLog	Sun Oct 28 12:30:45 2018 +0100
@@ -1,5 +1,10 @@
 ChangeLog
 ---------
+Version 6.5.0:
+- improved code completions and calltips for files belonging to a project
+  (that may be using an interpreter different from the one used by eric or
+  configured globally)
+
 Version 6.4.0:
 - use default virtual environment as of eric6 18.10
 
--- a/PluginRefactoringRope.py	Sun Sep 16 13:17:08 2018 +0200
+++ b/PluginRefactoringRope.py	Sun Oct 28 12:30:45 2018 +0100
@@ -23,7 +23,7 @@
 author = "Detlev Offenbach <detlev@die-offenbachs.de>"
 autoactivate = True
 deactivateable = True
-version = "6.4.0"
+version = "6.5.0"
 className = "RefactoringRopePlugin"
 packageName = "RefactoringRope"
 internalPackages = "rope"
Binary file PluginRefactoringRope.zip has changed
--- a/RefactoringRope/CodeAssistServer.py	Sun Sep 16 13:17:08 2018 +0200
+++ b/RefactoringRope/CodeAssistServer.py	Sun Oct 28 12:30:45 2018 +0100
@@ -21,12 +21,15 @@
 
 import Globals
 import Preferences
+import Utilities
 
 
 class CodeAssistServer(JsonServer):
     """
     Class implementing the autocompletion interface to rope.
     """
+    IdProject = "Project"
+    
     def __init__(self, plugin, parent=None):
         """
         Constructor
@@ -42,6 +45,7 @@
         self.__plugin = plugin
         self.__ui = parent
         self.__vm = e5App().getObject("ViewManager")
+        self.__e5project = e5App().getObject("Project")
         
         self.__editorLanguageMapping = {}
         self.__clientConfigs = {}
@@ -100,6 +104,40 @@
                     "Pygments|Python 3": "Python3",
                 })
     
+    def isSupportedLanguage(self, language):
+        """
+        Public method to check, if the given language is supported.
+        
+        @param language editor programming language to check
+        @type str
+        @return flag indicating the support status
+        @rtype bool
+        """
+        return language in self.__editorLanguageMapping
+    
+    def __idString(self, editor):
+        """
+        Private method to determine the ID string for the back-end.
+        
+        @param editor reference to the editor to determine the ID string for
+        @type QScintilla.Editor
+        @return ID string
+        @rtype str
+        """
+        idString = ""
+        
+        language = editor.getLanguage()
+        if self.__e5project.isOpen() and \
+           self.__e5project.getProjectLanguage() == language:
+            filename = editor.getFileName()
+            if self.__e5project.isProjectSource(filename):
+                idString = CodeAssistServer.IdProject
+        
+        if not idString and language in self.__editorLanguageMapping:
+            idString = self.__editorLanguageMapping[language]
+        
+        return idString
+    
     def __getConfigs(self):
         """
         Private method to get the configurations of all connected clients.
@@ -170,17 +208,6 @@
                 self.tr("""The Rope configuration file '{0}' does"""
                         """ not exist.""").format(configfile))
     
-    def isSupportedLanguage(self, language):
-        """
-        Public method to check, if the given language is supported.
-        
-        @param language editor programming language to check
-        @type str
-        @return flag indicating the support status
-        @rtype bool
-        """
-        return language in self.__editorLanguageMapping
-    
     def getCompletions(self, editor, context):
         """
         Public method to calculate the possible completions.
@@ -197,8 +224,7 @@
         # reset the completions buffer
         self.__completions = None
         
-        language = editor.getLanguage()
-        if language not in self.__editorLanguageMapping:
+        if not self.__idString(editor):
             return []
         
         self.requestCompletions(editor, context, "")
@@ -226,10 +252,9 @@
         @param acText text to be completed
         @type str
         """
-        language = editor.getLanguage()
-        if language not in self.__editorLanguageMapping:
+        idString = self.__idString(editor)
+        if not idString:
             return
-        idString = self.__editorLanguageMapping[language]
         
         filename = editor.getFileName()
         line, index = editor.getCursorPosition()
@@ -284,10 +309,9 @@
         # reset the calltips buffer
         self.__calltips = None
         
-        language = editor.getLanguage()
-        if language not in self.__editorLanguageMapping:
+        idString = self.__idString(editor)
+        if not idString:
             return []
-        idString = self.__editorLanguageMapping[language]
         
         filename = editor.getFileName()
         source = editor.text()
@@ -336,10 +360,8 @@
         """
         editor = self.__vm.getOpenEditor(filename)
         if editor is not None:
-            language = editor.getLanguage()
-            if language in self.__editorLanguageMapping:
-                idString = self.__editorLanguageMapping[language]
-                
+            idString = self.__idString(editor)
+            if idString:
                 self.__ensureActive(idString)
                 self.sendJson("reportChanged", {
                     "FileName": filename,
@@ -359,7 +381,7 @@
             return
         
         language = editor.getLanguage()
-        if language not in self.__editorLanguageMapping:
+        if not self.isSupportedLanguage(language):
             if Preferences.getDocuViewer("ShowInfoAsRichText"):
                 warning = self.tr("Language <b>{0}</b> is not supported.")\
                     .format(language)
@@ -370,7 +392,9 @@
                 warning, isWarning=True)
             return
         
-        idString = self.__editorLanguageMapping[language]
+        idString = self.__idString(editor)
+        if not idString:
+            return
         
         filename = editor.getFileName()
         source = editor.text()
@@ -496,7 +520,11 @@
         ok = False
         
         if interpreter:
-            configDir = os.path.join(Globals.getConfigDir(), "rope", idString)
+            if idString == CodeAssistServer.IdProject:
+                configDir = self.__e5project.getProjectPath()
+            else:
+                configDir = os.path.join(Globals.getConfigDir(), "rope",
+                                         idString)
             if not os.path.exists(configDir):
                 os.makedirs(configDir)
             
@@ -531,50 +559,112 @@
         ok = idString in self.connectionNames()
         if not ok:
             # client is not running
-            try:
-                # new code using virtual environments
-                venvManager = e5App().getObject("VirtualEnvManager")
-                if idString == "Python2":
-                    # Python 2
-                    venvName = Preferences.getDebugger("Python2VirtualEnv")
-                    if not venvName and sys.version_info[0] == 2:
-                        try:
-                            venvName, _ = venvManager.getDefaultEnvironment()
-                        except AttributeError:
-                            # ignore for eric6 < 18.10
-                            pass
-                elif idString == "Python3":
-                    # Python 3
-                    venvName = Preferences.getDebugger("Python3VirtualEnv")
-                    if not venvName and sys.version_info[0] == 3:
-                        try:
-                            venvName, _ = venvManager.getDefaultEnvironment()
-                        except AttributeError:
-                            # ignore for eric6 < 18.10
-                            pass
-                else:
-                    venvName = ""
-                if venvName:
-                    interpreter = e5App().getObject("VirtualEnvManager")\
-                        .getVirtualenvInterpreter(venvName)
-                else:
-                    interpreter = ""
-            except KeyError:
-                # backward compatibility (eric <18.07)
-                if idString == "Python2":
-                    # Python 2
-                    interpreter = Preferences.getDebugger("PythonInterpreter")
-                elif idString == "Python3":
-                    # Python 3
-                    interpreter = Preferences.getDebugger("Python3Interpreter")
-                else:
-                    interpreter = ""
+            if idString == CodeAssistServer.IdProject:
+                interpreter = self.__interpreterForProject()
+            else:
+                interpreter = ""
+                venvName = ""
+                try:
+                    # new code using virtual environments
+                    venvManager = e5App().getObject("VirtualEnvManager")
+                    if idString == "Python2":
+                        # Python 2
+                        venvName = Preferences.getDebugger("Python2VirtualEnv")
+                        if not venvName and sys.version_info[0] == 2:
+                            try:
+                                venvName, _ = \
+                                    venvManager.getDefaultEnvironment()
+                            except AttributeError:
+                                # ignore for eric6 < 18.10
+                                pass
+                    elif idString == "Python3":
+                        # Python 3
+                        venvName = Preferences.getDebugger("Python3VirtualEnv")
+                        if not venvName and sys.version_info[0] == 3:
+                            try:
+                                venvName, _ = \
+                                    venvManager.getDefaultEnvironment()
+                            except AttributeError:
+                                # ignore for eric6 < 18.10
+                                pass
+                    if venvName:
+                        interpreter = \
+                            venvManager.getVirtualenvInterpreter(venvName)
+                except KeyError:
+                    # backward compatibility (eric <18.07)
+                    if idString == "Python2":
+                        # Python 2
+                        interpreter = \
+                            Preferences.getDebugger("PythonInterpreter")
+                    elif idString == "Python3":
+                        # Python 3
+                        interpreter = \
+                            Preferences.getDebugger("Python3Interpreter")
             if interpreter:
                 ok = self.__startCodeAssistClient(interpreter, idString)
             else:
                 ok = False
         return ok
     
+    def __interpreterForProject(self):
+        """
+        Private method to determine the interpreter for the current project.
+        
+        @return interpreter of the current project
+        @rtype str
+        """
+        interpreter = ""
+        projectLanguage = self.__e5project.getProjectLanguage()
+        
+        if projectLanguage.startswith("Python"):
+            try:
+                # new code using virtual environments
+                venvManager = e5App().getObject("VirtualEnvManager")
+                
+                # get virtual environment from project first
+                venvName = self.__e5project.getDebugProperty("VIRTUALENV")
+                if not venvName:
+                    # get it from debugger settings next
+                    if projectLanguage == "Python2":
+                        # Python 2
+                        venvName = Preferences.getDebugger("Python2VirtualEnv")
+                        if not venvName and sys.version_info[0] == 2:
+                            try:
+                                venvName, _ = \
+                                    venvManager.getDefaultEnvironment()
+                            except AttributeError:
+                                # ignore for eric6 < 18.10
+                                pass
+                    elif projectLanguage == "Python3":
+                        # Python 3
+                        venvName = Preferences.getDebugger("Python3VirtualEnv")
+                        if not venvName and sys.version_info[0] == 3:
+                            try:
+                                venvName, _ = \
+                                    venvManager.getDefaultEnvironment()
+                            except AttributeError:
+                                # ignore for eric6 < 18.10
+                                pass
+                    else:
+                        venvName = ""
+                if venvName:
+                    interpreter = \
+                        venvManager.getVirtualenvInterpreter(venvName)
+            except KeyError:
+                # backward compatibility (eric < 18.07)
+                # get interpreter from project first
+                interpreter = self.__e5project.getDebugProperty("INTERPRETER")
+                if not interpreter or not Utilities.isinpath(interpreter):
+                    # get it from debugger settings second
+                    if projectLanguage == "Python2":
+                        interpreter = Preferences.getDebugger(
+                            "PythonInterpreter")
+                    elif projectLanguage == "Python3":
+                        interpreter = Preferences.getDebugger(
+                            "Python3Interpreter")
+        
+        return interpreter
+    
     @pyqtSlot()
     def handleNewConnection(self):
         """
@@ -599,6 +689,8 @@
         except AttributeError:
             # eric6 before 17.11 doesn't have this
             pass
+        
+        self.__e5project.projectClosed.connect(self.__projectClosed)
     
     def deactivate(self):
         """
@@ -613,8 +705,21 @@
         for idString in self.connectionNames():
             self.sendJson("closeProject", {}, flush=True, idString=idString)
         
+        try:
+            self.__e5project.projectClosed.disconnect(self.__projectClosed)
+        except TypeError:
+            # ignore it, the signal may be disconnected already
+            pass
+        
         self.stopAllClients()
     
+    @pyqtSlot()
+    def __projectClosed(self):
+        """
+        Private slot to handle the projectClosed signal.
+        """
+        self.stopClient(idString=CodeAssistServer.IdProject)
+    
     #######################################################################
     ## Methods below handle setting/unsetting the hook methods
     #######################################################################
--- a/RefactoringRope/Documentation/source/Plugin_Refactoring_Rope.RefactoringRope.CodeAssistClient.html	Sun Sep 16 13:17:08 2018 +0200
+++ b/RefactoringRope/Documentation/source/Plugin_Refactoring_Rope.RefactoringRope.CodeAssistClient.html	Sun Oct 28 12:30:45 2018 +0100
@@ -48,7 +48,7 @@
 JsonClient
 <h3>Class Attributes</h3>
 <table>
-<tr><td>PictureIDs</td></tr><tr><td>client</td></tr>
+<tr><td>PictureIDs</td></tr>
 </table>
 <h3>Class Methods</h3>
 <table>
--- a/RefactoringRope/Documentation/source/Plugin_Refactoring_Rope.RefactoringRope.CodeAssistServer.html	Sun Sep 16 13:17:08 2018 +0200
+++ b/RefactoringRope/Documentation/source/Plugin_Refactoring_Rope.RefactoringRope.CodeAssistServer.html	Sun Oct 28 12:30:45 2018 +0100
@@ -48,7 +48,7 @@
 JsonServer
 <h3>Class Attributes</h3>
 <table>
-<tr><td>None</td></tr>
+<tr><td>IdProject</td></tr>
 </table>
 <h3>Class Methods</h3>
 <table>
@@ -69,6 +69,12 @@
 <td><a href="#CodeAssistServer.__getConfigs">__getConfigs</a></td>
 <td>Private method to get the configurations of all connected clients.</td>
 </tr><tr>
+<td><a href="#CodeAssistServer.__idString">__idString</a></td>
+<td>Private method to determine the ID string for the back-end.</td>
+</tr><tr>
+<td><a href="#CodeAssistServer.__interpreterForProject">__interpreterForProject</a></td>
+<td>Private method to determine the interpreter for the current project.</td>
+</tr><tr>
 <td><a href="#CodeAssistServer.__processCallTipsResult">__processCallTipsResult</a></td>
 <td>Private method to process the calltips sent by the client.</td>
 </tr><tr>
@@ -81,6 +87,9 @@
 <td><a href="#CodeAssistServer.__processDocumentationResult">__processDocumentationResult</a></td>
 <td>Private method to process the documentation sent by the client.</td>
 </tr><tr>
+<td><a href="#CodeAssistServer.__projectClosed">__projectClosed</a></td>
+<td>Private slot to handle the projectClosed signal.</td>
+</tr><tr>
 <td><a href="#CodeAssistServer.__ropeConfigFile">__ropeConfigFile</a></td>
 <td>Private method to get the name of the rope configuration file.</td>
 </tr><tr>
@@ -199,7 +208,42 @@
 <b>__getConfigs</b>(<i></i>)
 <p>
         Private method to get the configurations of all connected clients.
-</p><a NAME="CodeAssistServer.__processCallTipsResult" ID="CodeAssistServer.__processCallTipsResult"></a>
+</p><a NAME="CodeAssistServer.__idString" ID="CodeAssistServer.__idString"></a>
+<h4>CodeAssistServer.__idString</h4>
+<b>__idString</b>(<i>editor</i>)
+<p>
+        Private method to determine the ID string for the back-end.
+</p><dl>
+<dt><i>editor</i> (QScintilla.Editor)</dt>
+<dd>
+reference to the editor to determine the ID string for
+</dd>
+</dl><dl>
+<dt>Returns:</dt>
+<dd>
+ID string
+</dd>
+</dl><dl>
+<dt>Return Type:</dt>
+<dd>
+str
+</dd>
+</dl><a NAME="CodeAssistServer.__interpreterForProject" ID="CodeAssistServer.__interpreterForProject"></a>
+<h4>CodeAssistServer.__interpreterForProject</h4>
+<b>__interpreterForProject</b>(<i></i>)
+<p>
+        Private method to determine the interpreter for the current project.
+</p><dl>
+<dt>Returns:</dt>
+<dd>
+interpreter of the current project
+</dd>
+</dl><dl>
+<dt>Return Type:</dt>
+<dd>
+str
+</dd>
+</dl><a NAME="CodeAssistServer.__processCallTipsResult" ID="CodeAssistServer.__processCallTipsResult"></a>
 <h4>CodeAssistServer.__processCallTipsResult</h4>
 <b>__processCallTipsResult</b>(<i>result</i>)
 <p>
@@ -239,7 +283,12 @@
 <dd>
 dictionary containing the result sent by the client
 </dd>
-</dl><a NAME="CodeAssistServer.__ropeConfigFile" ID="CodeAssistServer.__ropeConfigFile"></a>
+</dl><a NAME="CodeAssistServer.__projectClosed" ID="CodeAssistServer.__projectClosed"></a>
+<h4>CodeAssistServer.__projectClosed</h4>
+<b>__projectClosed</b>(<i></i>)
+<p>
+        Private slot to handle the projectClosed signal.
+</p><a NAME="CodeAssistServer.__ropeConfigFile" ID="CodeAssistServer.__ropeConfigFile"></a>
 <h4>CodeAssistServer.__ropeConfigFile</h4>
 <b>__ropeConfigFile</b>(<i>idString</i>)
 <p>
--- a/RefactoringRope/Documentation/source/Plugin_Refactoring_Rope.RefactoringRope.RefactoringClient.html	Sun Sep 16 13:17:08 2018 +0200
+++ b/RefactoringRope/Documentation/source/Plugin_Refactoring_Rope.RefactoringRope.RefactoringClient.html	Sun Oct 28 12:30:45 2018 +0100
@@ -48,7 +48,7 @@
 JsonClient
 <h3>Class Attributes</h3>
 <table>
-<tr><td>client</td></tr>
+<tr><td>None</td></tr>
 </table>
 <h3>Class Methods</h3>
 <table>

eric ide

mercurial