Python: Fix highlighting of parentheses

This enables the PythonEditor to handle (un)matching
parentheses correctly.

Change-Id: I31516a5fee922de6b3cfc2254b209739bc42c540
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Stenger
2020-07-03 14:14:05 +02:00
parent f5d9091f56
commit c7bc8a98ac
4 changed files with 27 additions and 1 deletions

View File

@@ -41,6 +41,8 @@ enum Format {
Format_Identifier, Format_Identifier,
Format_Whitespace, Format_Whitespace,
Format_ImportedModule, Format_ImportedModule,
Format_LParen,
Format_RParen,
Format_FormatsAmount Format_FormatsAmount
}; };

View File

@@ -79,6 +79,8 @@ static TextEditor::TextStyle styleForFormat(int format)
case Format_Identifier: return C_TEXT; case Format_Identifier: return C_TEXT;
case Format_Whitespace: return C_VISUAL_WHITESPACE; case Format_Whitespace: return C_VISUAL_WHITESPACE;
case Format_ImportedModule: return C_STRING; case Format_ImportedModule: return C_STRING;
case Format_LParen: return C_OPERATOR;
case Format_RParen: return C_OPERATOR;
case Format_FormatsAmount: case Format_FormatsAmount:
QTC_CHECK(false); // should never get here QTC_CHECK(false); // should never get here
return C_TEXT; return C_TEXT;
@@ -164,6 +166,7 @@ int PythonHighlighter::highlightLine(const QString &text, int initialState)
} }
FormatToken tk; FormatToken tk;
TextEditor::Parentheses parentheses;
bool hasOnlyWhitespace = true; bool hasOnlyWhitespace = true;
while (!(tk = scanner.read()).isEndOfBlock()) { while (!(tk = scanner.read()).isEndOfBlock()) {
Format format = tk.format(); Format format = tk.format();
@@ -175,11 +178,20 @@ int PythonHighlighter::highlightLine(const QString &text, int initialState)
|| format == Format_Doxygen) { || format == Format_Doxygen) {
setFormatWithSpaces(text, tk.begin(), tk.length(), formatForCategory(format)); setFormatWithSpaces(text, tk.begin(), tk.length(), formatForCategory(format));
} else { } else {
if (format == Format_LParen) {
parentheses.append(TextEditor::Parenthesis(TextEditor::Parenthesis::Opened,
text.at(tk.begin()), tk.begin()));
} else if (format == Format_RParen) {
parentheses.append(TextEditor::Parenthesis(TextEditor::Parenthesis::Closed,
text.at(tk.begin()), tk.begin()));
}
setFormat(tk.begin(), tk.length(), formatForCategory(format)); setFormat(tk.begin(), tk.length(), formatForCategory(format));
} }
if (format != Format_Whitespace) if (format != Format_Whitespace)
hasOnlyWhitespace = false; hasOnlyWhitespace = false;
} }
TextEditor::TextDocumentLayout::setParentheses(currentBlock(), parentheses);
return scanner.state(); return scanner.state();
} }

View File

@@ -98,6 +98,11 @@ FormatToken Scanner::onDefaultState()
return readComment(); return readComment();
} }
if (first == '(' || first == '[' || first == '{')
return readBrace(true);
if (first == ')' || first == ']' || first == '}')
return readBrace(false);
if (first.isSpace()) if (first.isSpace())
return readWhiteSpace(); return readWhiteSpace();
@@ -363,7 +368,7 @@ FormatToken Scanner::readWhiteSpace()
*/ */
FormatToken Scanner::readOperator() FormatToken Scanner::readOperator()
{ {
static const QString EXCLUDED_CHARS = "\'\"_#"; static const QString EXCLUDED_CHARS = "\'\"_#([{}])";
QChar ch = peek(); QChar ch = peek();
while (ch.isPunct() && !EXCLUDED_CHARS.contains(ch)) { while (ch.isPunct() && !EXCLUDED_CHARS.contains(ch)) {
move(); move();
@@ -372,6 +377,12 @@ FormatToken Scanner::readOperator()
return FormatToken(Format_Operator, anchor(), length()); return FormatToken(Format_Operator, anchor(), length());
} }
FormatToken Scanner::readBrace(bool isOpening)
{
Format format = isOpening ? Format_LParen : Format_RParen;
return FormatToken(format, anchor(), length());
}
void Scanner::clearState() void Scanner::clearState()
{ {
m_state = 0; m_state = 0;

View File

@@ -67,6 +67,7 @@ private:
FormatToken readDoxygenComment(); FormatToken readDoxygenComment();
FormatToken readWhiteSpace(); FormatToken readWhiteSpace();
FormatToken readOperator(); FormatToken readOperator();
FormatToken readBrace(bool isOpening);
void clearState(); void clearState();
void saveState(State state, QChar savedData); void saveState(State state, QChar savedData);