aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/cppeditor/cpphighlighter.cpp
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@qt.io>2020-06-12 16:11:28 +0200
committerChristian Kandeler <christian.kandeler@qt.io>2020-06-19 07:28:52 +0000
commit38a156c5a40f6971abde3de786c922d9c5eb2438 (patch)
tree1167dd6a91e29bf7327ccf02381bf58f332b22a4 /src/plugins/cppeditor/cpphighlighter.cpp
parent54575fe42dfc7b2299b8cc0e5add3246ba193a32 (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.cpp48
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;