Sun, 28 Oct 2018 12:30:45 +0100
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).
--- 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"
--- 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>