c++ - QSyntaxHighlighter 和多行注释

标签 c++ qt syntax-highlighting

我正在使用 Qt 的 QSyntaxHighlighter 为 QML TextEdit 中的一些类似 C 的语法着色

除了多行注释,一切都很好。

我是这样检测它们的:

void highlightBlock(QString const& text) override {
    bool inMultilineComment = previousBlockState() == STATES::COMMENT;
    bool inSingleLineComment = false;
    int previousIndex = 0;

    QRegularExpression expr("(\\/\\*|\\*\\/|\\/\\/|\n)"); // will match either /**, /**, // or \n
    QRegularExpressionMatchIterator it = expr.globalMatch(text);

    while(it.hasNext()) {
        QRegularExpressionMatch match = it.next();

        const QString captured = match.captured(1);

        if(captured == "/*" && !inSingleLineComment) {
            inMultilineComment = true;
            previousIndex = match.capturedStart(1);
        }

        if(captured == "*/" && inMultilineComment) {
            inMultilineComment = false;
            setFormat(previousIndex, match.capturedEnd(1) - previousIndex, _commentFormat);
        }

        if(captured == "//" && !inMultilineComment) {
            inSingleLineComment = true;
        }

        if(captured == "\n" && inSingleLineComment) {
            inSingleLineComment = false;
        }
    }

    if(inMultilineComment) {
        setFormat(previousIndex, text.size() - previousIndex, _commentFormat);
        setCurrentBlockState(STATES::COMMENT);
    }
    else {
        setCurrentBlockState(STATES::NONE);
    }
}

它一直有效,直到我采用已经着色的多行注释并删除开头的 /* 。只有包含 /* 的 block 会被处理和重新着色,但后面的 block 不会,这意味着它们在未被注释时继续显示为注释。

有没有简单的方法告诉 QSyntaxHighlighter 重新处理以下 block 以防止此类错误着色?

最佳答案

我最近遇到了同样的问题,发现 Qt 实际上应该为您处理这个问题,假设您正确设置了 blockState。

如果您查看 Qt5 源代码中 QSyntaxHighlighterPrivate::reformatBlocks 的源代码,您会看到

while (block.isValid() && (block.position() < endPosition || forceHighlightOfNextBlock)) {
    const int stateBeforeHighlight = block.userState();
    reformatBlock(block);
    forceHighlightOfNextBlock = (block.userState() != stateBeforeHighlight);
    block = block.next();
}

取自https://code.woboq.org/qt5/qtbase/src/gui/text/qsyntaxhighlighter.cpp.html#165

该代码(由荧光笔打开的 QTextDocument 的 contentsChange 信号触发)将从刚刚修改的 block 开始遍历每个 block (行)。假设 block 的状态根据刚刚发生的类型更改而改变,它将继续处理后面的 block 。这意味着您需要让每一行的 userState 都正确,Qt 应该处理其余的。

举个例子

    /*
     * This is a comment
     *
     * That I made
     */

除了最后一行应设置为 STATES::NONE 之外,您希望在每一行都设置了 STATES::COMMENT 的情况下开始。一旦您执行了诸如删除初始 /* 之类的操作,您需要确保将 block 状态重置为 STATES::NONE。这将触发 Qt 重新运行下一个 block ,该 block 还需要更改其状态等。

在我的 (python) 代码中,我最终结合使用打印语句和实际调试来跟踪状态更改的传播,并找出未正确更新和破坏更新链的位置。您的代码表面上看起来是正确的,尽管我没有尝试编译和运行它,但我怀疑在某些情况下会触发编辑后状态未正确更新的情况。

关于c++ - QSyntaxHighlighter 和多行注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51012969/

相关文章:

c++ - 使用MSBuild和Visual Studio 2012+预处理C++文件

c++ - googletest - 找出意外调用的位置

c++ - QSemaphore 是否足以制作 QQueue 的线程安全类比?

c++ - Qt Creator - 设置架构标志

vim - 改变vim中的语法颜色?

c# - Visual Studio 2022 .razor 代码块闪烁

c++ - 单例使用 C++

c++ - opencv:检查两个 iplimages 在 c/c++ 中是否相等?

qt - QT运行时如何在QTimeEdit中设置时间?

Eclipse不是build.xml以外的语法高亮显示文件吗?