Ejemplo n.º 1
0
class CTags(object):
    def __init__(self, view):
        self.view = view
        self.setting = Setting(self.view)
        self.folder = None
        for folder in self.view.window().folders():
            if folder == self.view.file_name()[:len(folder)]:
                self.folder = folder
                break
        if self.folder is None:
            raise CTagsException('CTags needs a sublime folder to work')
        self.tagsFile = self.folder + "/.tags" + self.setting.getSyntax()
        if not os.path.exists(self.tagsFile):
            raise CTagsException('CTags file not found: ' + self.tagsFile)

    @staticmethod
    def rebuild(view):
        folders = view.window().folders()
        if len(folders) > 0:
            for folder in folders:
                for lang in Setting.getSupportedLanguages():
                    cTagsBinary = None
                    if os.path.exists('/usr/bin/ctags'):
                        cTagsBinary = '/usr/bin/ctags'
                    if os.path.exists('/opt/local/bin/ctags'):
                        cTagsBinary = '/opt/local/bin/ctags'
                    if cTagsBinary is None:
                        raise CTagsException('YAC: ctags binary not found')
                    cTagsFile = os.path.join(folder, '.tags' + lang)
                    if os.path.exists(cTagsFile):
                        os.remove(cTagsFile)
                    cmd = cTagsBinary + ' -R --languages=' + lang + ' -f "' + cTagsFile + '" "' + folder + '"'
                    os.popen(cmd)
        else:
            raise CTagsException('No folders detected')

    def getRelativeFilePath(self, filePath):
        return filePath[len(os.path.dirname(self.tagsFile))+1:]

    def getClassFromName(self, searchString):
        if searchString:
            return self._getClasses(searchString)[0]
        else:
            return None

    def getClassesFromName(self, searchString):
        if searchString:
            return self._getClasses(searchString)
        else:
            return []

    def _getClasses(self, searchString):
        results = []
        f = os.popen("grep \"^" + searchString + "\" '" + self.tagsFile + "' | grep \"[c|i]$\"")
        for i in f.readlines():
            className = i[:i.find("\t")]
            classFileName = i[i.find("\t")+1:i.find("\t", i.find("\t") + 1)]
            line = i[i.find('/^')+2:i.find('$/;"')]
            if line.find('extends') >= 0:
                parentClassName = line[line.find('extends')+7:].strip().split()[0]
            else:
                parentClassName = None
            results.append(Class(className, classFileName, parentClassName))
        return results

    def _getMethodsFromClass(self, searchClass, prefix=None):
        results = []
        cmd = ''
        if prefix:
            cmd = "grep '^" + prefix + "' '" + self.tagsFile + "' | grep -F \"\t" + searchClass.getFile() + "\t\" | grep \"f$\""
        else:
            cmd = "grep -F \"\t" + searchClass.getFile() + "\t\" " + self.tagsFile + " | grep \"f$\""
        f = os.popen(cmd)
        for i in f.readlines():
            results.append(self._extractMethod(i, searchClass))
        return results

    def _extractMethod(self, tagsLine, classObject):
        name = tagsLine[:tagsLine.find("\t")-1]
        line = tagsLine[tagsLine.find('/^')+2:tagsLine.find('$/;"')]
        line.strip()
        line = line[line.find('function')+8:line.find('{')]
        method = Method(name, classObject, line)
        return method

    def getMethodsFromClass(self, currentClass, prefix=None):
        results = []
        i = 0
        while isinstance(currentClass, Class) and currentClass.classExists():
            i = i + 1
            if i > 10:
                raise Exception('YAC: Recursion limit reached')
            for result in self._getMethodsFromClass(currentClass, prefix):
                results.append(result)
            currentClass = self.getClassFromName(currentClass.getParentClassName())
        return results

    def getFunctionsFromName(self, name):
        results = []
        f = os.popen("grep \"^" + name + "\" '" + self.tagsFile + "' | grep \"f$\"")
        for i in f.readlines():
            functionName = i[:i.find("\t")]
            functionFileName = i[i.find("\t")+1:i.find("\t", i.find("\t") + 1)]
            line = i[i.find('/^')+2:i.find('$/;"')]
            results.append(Function(functionName, functionFileName, line))
        return results