示例#1
0
文件: syntax.py 项目: D3f0/prymatex
 def beginParse(self, scopeName):
     self.scope = Scope(scopeName)
示例#2
0
class CodeEditorSyntaxProcessor(CodeEditorBaseProcessor, SyntaxProcessorMixin):
    NOT_STATE = -1
    NOT_REVISION = -1
    CACHE = {}
    def __init__(self, editor):
        super().__init__(editor)
        self.stack = []
        self.scope = None
        self.stacks = {}
        syntax = self.editor.application().supportManager.getBundleItem(self.editor.default_syntax)
        self.setScopeName(syntax and syntax.scopeName or "")
    
    def setScopeName(self, name):
        self.scope_name = name
        self.empty_scope = Scope(self.scope_name)
        self.empty_token = CodeEditorToken(0, 0, self.empty_scope, "")
        self.empty_user_data = CodeEditorBlockUserData(
            (self.empty_token, ), "", self.NOT_STATE, self.NOT_REVISION
        )
    
    def scopeName(self):
        return self.scope_name

    def emptyUserData(self):
        return self.empty_user_data

    def managed(self):
        return True

    def beginExecution(self, bundleItem):
        if self.bundleItem is not None and self.bundleItem == bundleItem:
            return
        
        self.editor.syntaxHighlighter.stop()

        # Get Wrapped Syntax
        super().beginExecution(bundleItem)
        
        self.beginParse(bundleItem.scopeName)
        
        self.editor.syntaxHighlighter.start()
        self.editor.syntaxHighlighter.rehighlight()
        self.editor.showMessage("Syntax changed to <b>%s</b>" % bundleItem.name)
        self.editor.syntaxChanged.emit(bundleItem)

    def endExecution(self, bundleItem):
        self.endParse(bundleItem.scopeName)
        CodeEditorBaseProcessor.endExecution(self, bundleItem)

    def textRevision(self, text, previous_state):
        return _revision(self.scope_name, text, previous_state)

    def blockRevision(self, block):
        return self.textRevision(block.text() + "\n", block.previous().userState())

    def testRevision(self, block):
        return block.userData() is not None and block.userData().revision == self.blockRevision(block)
        
    def textUserData(self, text, previous_state=NOT_STATE, previous_revision=NOT_REVISION):
        if not self.isReady():
            return self.empty_user_data

        revision = _revision(self.scope_name, text, previous_state)
        if revision not in self.CACHE:
            # ------ Restore Stack State
            if previous_revision in self.stacks:
                self.stack, self.scope = self.stacks[previous_revision]
            else:
                self.stack, self.scope = ([(self.bundleItem.grammar, None)], Scope(self.bundleItem.scopeName))
    
            self.bundleItem.parseLine(self.stack, text, self)
            # ------- Save Stack State
            if len(self.stack) > 1:
                self.stacks[revision] = (self.stack[:], self.scope.clone())
            self.CACHE[revision] = (tuple(self.__tokens), text,
                hash(self.scope.back()) & (0xFFFFFFFF >> 2), revision
            )
        return CodeEditorBlockUserData(*self.CACHE[revision])
        
    def blockUserData(self, block, previous_user_data=None):
        user_data = previous_user_data or block.previous().userData()
        return self.textUserData(
            block.text() + "\n",
            block.previous().userState(),
            user_data and user_data.revision or self.NOT_REVISION
        )

    # -------- Parsing
    def beginParse(self, scopeName):
        self.setScopeName(scopeName)
        self.scope = Scope(scopeName)
        self.stack = [(self.bundleItem.grammar, None)]

    def endParse(self, scopeName):
        self.scope.pop_scope()
        self.stack = []

    # -------- Line
    def beginLine(self, line):
        self.line = line
        self.__tokens = []
        self.__indexes = []
        for _ in range(self.scope.size()):
            self.openToken(0)

    def endLine(self, line):
        while self.__indexes:
            self.closeToken(len(self.line))

    # -------- Tag
    def openTag(self, scopeName, position):
        #Open token
        self.openToken(position)
        self.scope.push_scope(scopeName)

    def closeTag(self, scopeName, position):
        self.closeToken(position)
        self.scope.pop_scope()

    # --------- Create tokens
    def openToken(self, start):
        self.__tokens.append(None)
        self.__indexes.append((start, len(self.__tokens) - 1))

    def closeToken(self, end):
        start, index = self.__indexes.pop()
        self.__tokens[index] = CodeEditorToken(
            start=start,
            end=end,
            scope=self.scope.clone(),
            chunk=self.line[start:end]
        )
示例#3
0
文件: syntax.py 项目: D3f0/prymatex
class CodeEditorSyntaxProcessor(CodeEditorBaseProcessor, SyntaxProcessorMixin):
    NO_STATE = -1
    SINGLE_LINE = 1
    MULTI_LINE = 2

    def __init__(self, editor):
        CodeEditorBaseProcessor.__init__(self, editor)
        self.stack = []
        self.scope = None

    def managed(self):
        return True

    def beginExecution(self, bundleItem):
        if self.bundleItem == bundleItem:
            return

        self.editor.syntaxHighlighter.stop()
        # ------------ Previous syntax
        if self.bundleItem is not None:
            self.endExecution(self.bundleItem)
        
        # Set syntax
        CodeEditorBaseProcessor.beginExecution(self, bundleItem)
        syntax = self.editor.application.supportManager.getBundleItem(bundleItem.uuid)

        self.stack = [(syntax.grammar, None)]
        self.beginParse(syntax.scopeName)
        
        self.editor.syntaxHighlighter.start()
        self.editor.syntaxChanged.emit(syntax)

    def endExecution(self, bundleItem):
        self.endParse(bundleItem.scopeName)
        CodeEditorBaseProcessor.endExecution(self, bundleItem)
    
    def restoreState(self, block):
        if block.isValid():
            self.stack, self.scope = self.editor.blockUserData(block).processorState()

    def saveState(self, block):
        self.editor.blockUserData(block).setProcessorState((self.stack[:], self.scope.clone()))

    def blockUserData(self, block):
        text = block.text() + "\n"
        revision = build_userData_revision(self.bundleItem.scopeName, 
            text, block.previous().userState())

        userData = self.editor.blockUserData(block)
        if block.revision() != revision:

            self.restoreState(block.previous())
            self.bundleItem.parseLine(self.stack, text, self)
            
            userData.setTokens(self.__tokens)
            userData.setBlank(text.strip() == "")
            self.editor.processBlockUserData(text, block, userData)

            block.setRevision(revision)

            # Store stack and state
            block.setUserState(len(self.stack) > 1 and self.MULTI_LINE or self.SINGLE_LINE)
            self.saveState(block)
        return userData

    # -------- Parsing
    def beginParse(self, scopeName):
        self.scope = Scope(scopeName)

    def endParse(self, scopeName):
        self.scope.pop_scope()

    # -------- Line
    def beginLine(self, line):
        self.line = line
        self.__tokens = []
        self.__indexes = []
        for _ in range(self.scope.size()):
            self.openToken(0)

    def endLine(self, line):
        self.closeToken(len(self.line), closeAll=True)

    # -------- Tag
    def openTag(self, scopeName, position):
        #Open token
        self.openToken(position)
        self.scope.push_scope(scopeName)

    def closeTag(self, scopeName, position):
        self.closeToken(position)
        self.scope.pop_scope()

    # --------- Create tokens
    def openToken(self, start):
        self.__tokens.append(None)
        self.__indexes.append((start, len(self.__tokens) - 1))

    def closeToken(self, end, closeAll=False):
        while self.__indexes:
            start, index = self.__indexes.pop()
            self.__tokens[index] = CodeEditorToken(
                start=start,
                end=end,
                scope=self.scope.clone(),
                chunk=self.line[start:end]
            )
            if not closeAll:
                break
示例#4
0
 def beginParse(self, scopeName):
     self.setScopeName(scopeName)
     self.scope = Scope(scopeName)
     self.stack = [(self.bundleItem.grammar, None)]