Wed, 27 Sep 2017 19:30:16 +0200
Extended the auto completions pictures supported by code assist.
# -*- coding: utf-8 -*- # Copyright (c) 2017 Detlev Offenbach <detlev@die-offenbachs.de> # """ Module implementing the code assist client interface to rope. """ from __future__ import unicode_literals import sys import os sys.path.insert(0, os.path.dirname(__file__)) if sys.version_info[0] >= 3: path = os.path.join(os.path.dirname(__file__), 'rope_py3') else: path = os.path.join(os.path.dirname(__file__), 'rope_py2') str = unicode # __IGNORE_WARNING__ sys.path.insert(0, path) import rope.base.libutils import rope.contrib.codeassist from JsonClient import JsonClient class CodeAssistClient(JsonClient): """ Class implementing the code assist client interface to rope. """ PictureIDs = { "class": "?{0}".format(1), # Editor.ClassID "_class": "?{0}".format(2), # Editor.ClassProtectedID "__class": "?{0}".format(3), # Editor.ClassPrivateID "instance": "?{0}".format(1), # Editor.ClassID "_instance": "?{0}".format(2), # Editor.ClassProtectedID "__instance": "?{0}".format(3), # Editor.ClassPrivateID "function": "?{0}".format(4), # Editor.MethodID "_function": "?{0}".format(5), # Editor.MethodProtectedID "__function": "?{0}".format(6), # Editor.MethodPrivateID "module": "?{0}".format(7), # Editor.AttributeID "_module": "?{0}".format(8), # Editor.AttributeProtectedID "__module": "?{0}".format(9), # Editor.AttributePrivateID "None": "", } # The various ID values are a copy of the ones found in the Editor # class in order to make this module/script independent from an # installed eric def __init__(self, host, port, idString, projectPath): """ Constructor @param host ip address the background service is listening @type str @param port port of the background service @type int @param idString assigned client id to be sent back to the server in order to identify the connection @param str @param projectPath path to the project @type str """ super(CodeAssistClient, self).__init__(host, port, idString) self.__methodMapping = { "getCompletions": self.__getCompletions, "getCallTips": self.__getCallTips, "reportChanged": self.__reportChanged, } self.__projectpath = projectPath self.__project = rope.base.project.Project(self.__projectpath) self.__project.validate(self.__project.root) def handleCall(self, method, params): """ Public method to handle a method call from the server. @param method requested method name @type str @param params dictionary with method specific parameters @type dict """ self.__methodMapping[method](params) def __handleRopeError(self, err): """ Private method to process a rope error. @param err rope exception object @type Exception @return dictionary containing the error information @rtype dict """ ropeError = str(type(err)).split()[-1] ropeError = ropeError[1:-2].split('.')[-1] errorDict = { "Error": ropeError, "ErrorString": str(err), } if ropeError == 'ModuleSyntaxError': errorDict["ErrorFile"] = err.filename errorDict["ErrorLine"] = err.lineno return errorDict def __getCompletions(self, params): """ Private method to calculate possible completions. @param params dictionary containing the method parameters @type dict """ filename = params["FileName"] source = params["Source"] offset = params["Offset"] maxfixes = params["MaxFixes"] if filename: resource = rope.base.libutils.path_to_resource( self.__project, filename) else: resource = None errorDict = {} completions = [] try: proposals = rope.contrib.codeassist.code_assist( self.__project, source, offset, resource, maxfixes=maxfixes) proposals = rope.contrib.codeassist.sorted_proposals(proposals) for proposal in proposals: proposalType = proposal.type if proposal.name.startswith("__"): proposalType = "__" + proposalType elif proposal.name.startswith("_"): proposalType = "_" + proposalType completions.append( proposal.name + self.PictureIDs[proposalType]) except Exception as err: errorDict = self.__handleRopeError(err) result = { "Completions": completions, } result.update(errorDict) self.sendJson("CompletionsResult", result) def __getCallTips(self, params): """ Private method to calculate possible calltips. @param params dictionary containing the method parameters @type dict """ filename = params["FileName"] source = params["Source"] offset = params["Offset"] maxfixes = params["MaxFixes"] if filename: resource = rope.base.libutils.path_to_resource( self.__project, filename) else: resource = None errorDict = {} calltips = [] try: cts = rope.contrib.codeassist.get_calltip( self.__project, source, offset, resource, maxfixes=maxfixes, remove_self=True) if cts is not None: calltips = [cts] except Exception as err: errorDict = self.__handleRopeError(err) result = { "CallTips": calltips, } result.update(errorDict) self.sendJson("CallTipsResult", result) def __reportChanged(self, params): """ Private method to register some changed sources. @param params dictionary containing the method parameters sent by the server @type dict """ filename = params["FileName"] oldSource = params["OldSource"] try: rope.base.libutils.report_change( self.__project, filename, oldSource) except Exception: # simply ignore it pass if __name__ == '__main__': if len(sys.argv) != 5: print('Host, port, id and project path parameters are missing. Abort.') sys.exit(1) host, port, idString, projectPath = sys.argv[1:] # Create a Qt4/5 application object in order to allow the processing of # modules containing Qt stuff. try: from PyQt5.QtCore import QCoreApplication except ImportError: try: from PyQt4.QtCore import QCoreApplication except ImportError: QCoreApplication = None if QCoreApplication is not None: app = QCoreApplication(sys.argv) client = CodeAssistClient(host, int(port), idString, projectPath) # Start the main loop client.run() sys.exit(0) # # eflag: noqa = M801