diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2020-06-12 16:11:28 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2020-06-19 07:28:52 +0000 |
commit | 38a156c5a40f6971abde3de786c922d9c5eb2438 (patch) | |
tree | 1167dd6a91e29bf7327ccf02381bf58f332b22a4 /src/plugins/cppeditor/cpphighlighter.cpp | |
parent | 54575fe42dfc7b2299b8cc0e5add3246ba193a32 (diff) |
CppEditor: Better highlighting for raw string literals
It can be rather difficult to see the actual content of a raw string
literal among all the clutter. Let us help the user by highlighting the
string differently from the delimiter.
Fixes: QTCREATORBUG-19119
Change-Id: I14447d62a686d82a2f2e123786a9b0eec16a0fa2
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
Diffstat (limited to 'src/plugins/cppeditor/cpphighlighter.cpp')
-rw-r--r-- | src/plugins/cppeditor/cpphighlighter.cpp | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/src/plugins/cppeditor/cpphighlighter.cpp b/src/plugins/cppeditor/cpphighlighter.cpp index 6cfa94ee52..1d309f2b49 100644 --- a/src/plugins/cppeditor/cpphighlighter.cpp +++ b/src/plugins/cppeditor/cpphighlighter.cpp @@ -164,7 +164,10 @@ void CppHighlighter::highlightBlock(const QString &text) } else if (tk.is(T_NUMERIC_LITERAL)) { setFormat(tk.utf16charsBegin(), tk.utf16chars(), formatForCategory(C_NUMBER)); } else if (tk.isStringLiteral() || tk.isCharLiteral()) { - setFormatWithSpaces(text, tk.utf16charsBegin(), tk.utf16chars(), formatForCategory(C_STRING)); + if (!highlightRawStringLiteral(text, tk)) { + setFormatWithSpaces(text, tk.utf16charsBegin(), tk.utf16chars(), + formatForCategory(C_STRING)); + } } else if (tk.isComment()) { const int startPosition = initialLexerState ? previousTokenEnd : tk.utf16charsBegin(); if (tk.is(T_COMMENT) || tk.is(T_CPP_COMMENT)) { @@ -363,6 +366,49 @@ void CppHighlighter::highlightWord(QStringRef word, int position, int length) } } +bool CppHighlighter::highlightRawStringLiteral(const QStringView &text, const Token &tk) +{ + // Step one: Does the lexer think this is a raw string literal? + switch (tk.kind()) { + case T_RAW_STRING_LITERAL: + case T_RAW_WIDE_STRING_LITERAL: + case T_RAW_UTF8_STRING_LITERAL: + case T_RAW_UTF16_STRING_LITERAL: + case T_RAW_UTF32_STRING_LITERAL: + break; + default: + return false; + } + + // Step two: Find all the components. Bail out if we don't have a complete, + // well-formed raw string literal. + const int rOffset = text.indexOf(QLatin1String("R\""), tk.utf16charsBegin()); + if (rOffset == -1) + return false; + const int delimiterOffset = rOffset + 2; + const int openParenOffset = text.indexOf('(', delimiterOffset); + if (openParenOffset == -1) + return false; + const QStringView delimiter = text.mid(delimiterOffset, openParenOffset - delimiterOffset); + if (text.at(tk.utf16charsEnd() - 1) != '"') + return false; + const int endDelimiterOffset = tk.utf16charsEnd() - 1 - delimiter.length(); + if (text.mid(endDelimiterOffset, delimiter.length()) != delimiter) + return false; + if (text.at(endDelimiterOffset - 1) != ')') + return false; + + // Step three: Do the actual formatting. For clarity, we display only the actual content as + // a string, and the rest (including the delimiter) as a keyword. + const QTextCharFormat delimiterFormat = formatForCategory(C_KEYWORD); + const int stringOffset = delimiterOffset + delimiter.length() + 1; + setFormat(tk.utf16charsBegin(), stringOffset, delimiterFormat); + setFormatWithSpaces(text.toString(), stringOffset, endDelimiterOffset - stringOffset - 1, + formatForCategory(C_STRING)); + setFormat(endDelimiterOffset - 1, delimiter.length() + 2, delimiterFormat); + return true; +} + void CppHighlighter::highlightDoxygenComment(const QString &text, int position, int) { int initial = position; |