diff options
Diffstat (limited to 'src/plugins/cpptools/semantichighlighter.cpp')
-rw-r--r-- | src/plugins/cpptools/semantichighlighter.cpp | 66 |
1 files changed, 65 insertions, 1 deletions
diff --git a/src/plugins/cpptools/semantichighlighter.cpp b/src/plugins/cpptools/semantichighlighter.cpp index 2fdce4c743..a0c21c3b97 100644 --- a/src/plugins/cpptools/semantichighlighter.cpp +++ b/src/plugins/cpptools/semantichighlighter.cpp @@ -44,6 +44,69 @@ static Q_LOGGING_CATEGORY(log, "qtc.cpptools.semantichighlighter", QtWarningMsg) namespace CppTools { +static const QList<std::pair<HighlightingResult, QTextBlock>> +splitRawStringLiteral(const HighlightingResult &result, const QTextBlock &startBlock) +{ + if (result.textStyles.mainStyle != C_STRING) + return {{result, startBlock}}; + + QTextCursor cursor(startBlock); + cursor.setPosition(cursor.position() + result.column - 1); + cursor.setPosition(cursor.position() + result.length, QTextCursor::KeepAnchor); + const QString theString = cursor.selectedText(); + + // Find all the components of a raw string literal. If we don't succeed, then it's + // something else. + if (!theString.endsWith('"')) + return {{result, startBlock}}; + int rOffset = -1; + if (theString.startsWith("R\"")) { + rOffset = 0; + } else if (theString.startsWith("LR\"") + || theString.startsWith("uR\"") + || theString.startsWith("UR\"")) { + rOffset = 1; + } else if (theString.startsWith("u8R\"")) { + rOffset = 2; + } + if (rOffset == -1) + return {{result, startBlock}}; + const int delimiterOffset = rOffset + 2; + const int openParenOffset = theString.indexOf('(', delimiterOffset); + if (openParenOffset == -1) + return {{result, startBlock}}; + const QStringView delimiter = theString.mid(delimiterOffset, openParenOffset - delimiterOffset); + const int endDelimiterOffset = theString.length() - 1 - delimiter.length(); + if (theString.mid(endDelimiterOffset, delimiter.length()) != delimiter) + return {{result, startBlock}}; + if (theString.at(endDelimiterOffset - 1) != ')') + return {{result, startBlock}}; + + // Now split the result. For clarity, we display only the actual content as a string, + // and the rest (including the delimiter) as a keyword. + HighlightingResult prefix = result; + prefix.textStyles.mainStyle = C_KEYWORD; + prefix.textStyles.mixinStyles = {}; + prefix.length = delimiterOffset + delimiter.length() + 1; + cursor.setPosition(startBlock.position() + result.column - 1 + prefix.length); + QTextBlock stringBlock = cursor.block(); + HighlightingResult actualString = result; + actualString.line = stringBlock.blockNumber() + 1; + actualString.column = cursor.positionInBlock() + 1; + actualString.length = endDelimiterOffset - openParenOffset - 2; + cursor.setPosition(cursor.position() + actualString.length); + QTextBlock suffixBlock = cursor.block(); + HighlightingResult suffix = result; + suffix.textStyles.mainStyle = C_KEYWORD; + suffix.textStyles.mixinStyles = {}; + suffix.line = suffixBlock.blockNumber() + 1; + suffix.column = cursor.positionInBlock() + 1; + suffix.length = delimiter.length() + 2; + QTC_CHECK(prefix.length + actualString.length + suffix.length == result.length); + + return {{prefix, startBlock}, {actualString, stringBlock}, {suffix, suffixBlock}}; +} + SemanticHighlighter::SemanticHighlighter(TextDocument *baseTextDocument) : QObject(baseTextDocument) , m_baseTextDocument(baseTextDocument) @@ -94,7 +157,8 @@ void SemanticHighlighter::onHighlighterResultAvailable(int from, int to) SyntaxHighlighter *highlighter = m_baseTextDocument->syntaxHighlighter(); QTC_ASSERT(highlighter, return); - incrementalApplyExtraAdditionalFormats(highlighter, m_watcher->future(), from, to, m_formatMap); + incrementalApplyExtraAdditionalFormats(highlighter, m_watcher->future(), from, to, m_formatMap, + &splitRawStringLiteral); } void SemanticHighlighter::onHighlighterFinished() |