Wed, 27 Sep 2017 18:25:08 +0200
IMplemented the distributed code assist completions method.
# -*- 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 "instance": "?{0}".format(1), # Editor.ClassID "function": "?{0}".format(4), # Editor.MethodID "module": "?{0}".format(7), # Editor.AttributeID "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, } 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) # TODO: extend this to include PictureIDs for protected and # private stuff (i.e. names starting with _ or __) completions = [proposal.name + self.PictureIDs[proposal.type] for proposal in proposals] except Exception as err: errorDict = self.__handleRopeError(err) result = { "Completions": completions, } result.update(errorDict) self.sendJson("CompletionsResult", result) 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