Generalize function for visualizing whitespace from CppHighligher

Move function which formats all non-whitespace with a given format, and
all whitespace in the same range with correct whitespace highlighting
(merged with the non-whitespace format), from CppHighlighter to
SyntaxHighligher.

Change-Id: I8cac306f6362e804698068a0df0292f88726264f
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Eike Ziller
2017-05-07 17:04:37 +02:00
parent db11c01df8
commit 0a1376dd2c
4 changed files with 43 additions and 34 deletions

View File

@@ -76,9 +76,9 @@ void CppHighlighter::highlightBlock(const QString &text)
TextDocumentLayout::clearParentheses(currentBlock()); TextDocumentLayout::clearParentheses(currentBlock());
if (text.length()) {// the empty line can still contain whitespace if (text.length()) {// the empty line can still contain whitespace
if (initialLexerState == T_COMMENT) if (initialLexerState == T_COMMENT)
highlightLine(text, 0, text.length(), formatForCategory(C_COMMENT)); setFormatWithSpaces(text, 0, text.length(), formatForCategory(C_COMMENT));
else if (initialLexerState == T_DOXY_COMMENT) else if (initialLexerState == T_DOXY_COMMENT)
highlightLine(text, 0, text.length(), formatForCategory(C_DOXYGEN_COMMENT)); setFormatWithSpaces(text, 0, text.length(), formatForCategory(C_DOXYGEN_COMMENT));
else else
setFormat(0, text.length(), formatForCategory(C_VISUAL_WHITESPACE)); setFormat(0, text.length(), formatForCategory(C_VISUAL_WHITESPACE));
} }
@@ -147,7 +147,7 @@ void CppHighlighter::highlightBlock(const QString &text)
continue; continue;
if (i == 0 && tk.is(T_POUND)) { if (i == 0 && tk.is(T_POUND)) {
highlightLine(text, tk.utf16charsBegin(), tk.utf16chars(), setFormatWithSpaces(text, tk.utf16charsBegin(), tk.utf16chars(),
formatForCategory(C_PREPROCESSOR)); formatForCategory(C_PREPROCESSOR));
expectPreprocessorKeyword = true; expectPreprocessorKeyword = true;
} else if (highlightCurrentWordAsPreprocessor } else if (highlightCurrentWordAsPreprocessor
@@ -164,11 +164,11 @@ void CppHighlighter::highlightBlock(const QString &text)
} else if (tk.is(T_NUMERIC_LITERAL)) { } else if (tk.is(T_NUMERIC_LITERAL)) {
setFormat(tk.utf16charsBegin(), tk.utf16chars(), formatForCategory(C_NUMBER)); setFormat(tk.utf16charsBegin(), tk.utf16chars(), formatForCategory(C_NUMBER));
} else if (tk.isStringLiteral() || tk.isCharLiteral()) { } else if (tk.isStringLiteral() || tk.isCharLiteral()) {
highlightLine(text, tk.utf16charsBegin(), tk.utf16chars(), formatForCategory(C_STRING)); setFormatWithSpaces(text, tk.utf16charsBegin(), tk.utf16chars(), formatForCategory(C_STRING));
} else if (tk.isComment()) { } else if (tk.isComment()) {
const int startPosition = initialLexerState ? previousTokenEnd : tk.utf16charsBegin(); const int startPosition = initialLexerState ? previousTokenEnd : tk.utf16charsBegin();
if (tk.is(T_COMMENT) || tk.is(T_CPP_COMMENT)) { if (tk.is(T_COMMENT) || tk.is(T_CPP_COMMENT)) {
highlightLine(text, startPosition, tk.utf16charsEnd() - startPosition, setFormatWithSpaces(text, startPosition, tk.utf16charsEnd() - startPosition,
formatForCategory(C_COMMENT)); formatForCategory(C_COMMENT));
} }
@@ -214,7 +214,7 @@ void CppHighlighter::highlightBlock(const QString &text)
// mark the trailing white spaces // mark the trailing white spaces
const int lastTokenEnd = tokens.last().utf16charsEnd(); const int lastTokenEnd = tokens.last().utf16charsEnd();
if (text.length() > lastTokenEnd) if (text.length() > lastTokenEnd)
highlightLine(text, lastTokenEnd, text.length() - lastTokenEnd, formatForCategory(C_VISUAL_WHITESPACE)); setFormatWithSpaces(text, lastTokenEnd, text.length() - lastTokenEnd, formatForCategory(C_VISUAL_WHITESPACE));
if (!initialLexerState && lexerState && !tokens.isEmpty()) { if (!initialLexerState && lexerState && !tokens.isEmpty()) {
const Token &lastToken = tokens.last(); const Token &lastToken = tokens.last();
@@ -343,30 +343,6 @@ bool CppHighlighter::isPPKeyword(const QStringRef &text) const
return false; return false;
} }
void CppHighlighter::highlightLine(const QString &text, int position, int length,
const QTextCharFormat &format)
{
QTextCharFormat visualSpaceFormat = formatForCategory(C_VISUAL_WHITESPACE);
visualSpaceFormat.setBackground(format.background());
const int end = position + length;
int index = position;
while (index != end) {
const bool isSpace = text.at(index).isSpace();
const int start = index;
do { ++index; }
while (index != end && text.at(index).isSpace() == isSpace);
const int tokenLength = index - start;
if (isSpace)
setFormat(start, tokenLength, visualSpaceFormat);
else if (format.isValid())
setFormat(start, tokenLength, format);
}
}
void CppHighlighter::highlightWord(QStringRef word, int position, int length) void CppHighlighter::highlightWord(QStringRef word, int position, int length)
{ {
// try to highlight Qt 'identifiers' like QObject and Q_PROPERTY // try to highlight Qt 'identifiers' like QObject and Q_PROPERTY
@@ -406,7 +382,7 @@ void CppHighlighter::highlightDoxygenComment(const QString &text, int position,
int k = CppTools::classifyDoxygenTag(start, it - start); int k = CppTools::classifyDoxygenTag(start, it - start);
if (k != CppTools::T_DOXY_IDENTIFIER) { if (k != CppTools::T_DOXY_IDENTIFIER) {
highlightLine(text, initial, start - uc - initial, format); setFormatWithSpaces(text, initial, start - uc - initial, format);
setFormat(start - uc - 1, it - start + 1, kwFormat); setFormat(start - uc - 1, it - start + 1, kwFormat);
initial = it - uc; initial = it - uc;
} }
@@ -414,6 +390,6 @@ void CppHighlighter::highlightDoxygenComment(const QString &text, int position,
++it; ++it;
} }
highlightLine(text, initial, it - uc - initial, format); setFormatWithSpaces(text, initial, it - uc - initial, format);
} }

View File

@@ -49,8 +49,6 @@ public:
private: private:
void highlightWord(QStringRef word, int position, int length); void highlightWord(QStringRef word, int position, int length);
void highlightLine(const QString &line, int position, int length,
const QTextCharFormat &format);
void highlightDoxygenComment(const QString &text, int position, void highlightDoxygenComment(const QString &text, int position,
int length); int length);

View File

@@ -494,6 +494,39 @@ void SyntaxHighlighter::formatSpaces(const QString &text)
} }
} }
/*!
The specified \a format is applied to all non-whitespace characters in the current text block
with \a text, from the \a start position for a length of \a count characters.
Whitespace characters are formatted with the visual whitespace format, merged with the
non-whitespace format.
\sa setFormat()
*/
void SyntaxHighlighter::setFormatWithSpaces(const QString &text, int start, int count,
const QTextCharFormat &format)
{
Q_D(const SyntaxHighlighter);
QTextCharFormat visualSpaceFormat = d->whitespaceFormat;
visualSpaceFormat.setBackground(format.background());
const int end = start + count;
int index = start;
while (index != end) {
const bool isSpace = text.at(index).isSpace();
const int start = index;
do { ++index; }
while (index != end && text.at(index).isSpace() == isSpace);
const int tokenLength = index - start;
if (isSpace)
setFormat(start, tokenLength, visualSpaceFormat);
else if (format.isValid())
setFormat(start, tokenLength, format);
}
}
/*! /*!
Returns the format at \a position inside the syntax highlighter's Returns the format at \a position inside the syntax highlighter's
current text block. current text block.

View File

@@ -85,6 +85,8 @@ protected:
QTextCharFormat format(int pos) const; QTextCharFormat format(int pos) const;
void formatSpaces(const QString &text); void formatSpaces(const QString &text);
void setFormatWithSpaces(const QString &text, int start, int count,
const QTextCharFormat &format);
int previousBlockState() const; int previousBlockState() const;
int currentBlockState() const; int currentBlockState() const;