diff --git a/src/libs/cplusplus/MatchingText.cpp b/src/libs/cplusplus/MatchingText.cpp index 2033218e10e..f783d4c508e 100644 --- a/src/libs/cplusplus/MatchingText.cpp +++ b/src/libs/cplusplus/MatchingText.cpp @@ -41,7 +41,7 @@ enum { MAX_NUM_LINES = 20 }; static bool shouldOverrideChar(QChar ch) { switch (ch.unicode()) { - case ')': case ']': case ';': case '"': case '\'': + case ')': case ']': case '}': case ';': case '"': case '\'': return true; default: @@ -262,13 +262,11 @@ QString MatchingText::insertMatchingBrace(const QTextCursor &cursor, const QStri if (textToProcess.isEmpty()) return QString(); - QTextCursor tc = cursor; QString text = textToProcess; - const QString blockText = tc.block().text().mid(tc.positionInBlock()); - const QString trimmedBlockText = blockText.trimmed(); - if (skipChars) { + QTextCursor tc = cursor; + const QString blockText = tc.block().text().mid(tc.positionInBlock()); *skippedChars = countSkippedChars(blockText, textToProcess); if (*skippedChars != 0) { tc.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, *skippedChars); @@ -280,9 +278,7 @@ QString MatchingText::insertMatchingBrace(const QTextCursor &cursor, const QStri foreach (const QChar &ch, text) { if (ch == QLatin1Char('(')) result += QLatin1Char(')'); else if (ch == QLatin1Char('[')) result += QLatin1Char(']'); - // Handle '{' appearance within functinon call context - else if (ch == QLatin1Char('{') && !trimmedBlockText.isEmpty() && trimmedBlockText.at(0) == QLatin1Char(')')) - result += QLatin1Char('}'); + else if (ch == QLatin1Char('{')) result += QLatin1Char('}'); } return result; diff --git a/src/plugins/cppeditor/cppautocompleter.cpp b/src/plugins/cppeditor/cppautocompleter.cpp index d5a97c38aea..f5bb7e9e798 100644 --- a/src/plugins/cppeditor/cppautocompleter.cpp +++ b/src/plugins/cppeditor/cppautocompleter.cpp @@ -245,17 +245,17 @@ void CppEditorPlugin::test_autoComplete_data() int skippedChar = 0; // We always expect to get a closing char in an empty file - if (fc == EmptyFile && c != QLatin1Char('{') && isOpeningChar(c)) + if (fc == EmptyFile && isOpeningChar(c)) expectedText = closingChar(c); if (fc == InBetween) { - // When we are inside the mathing chars and a closing char is inserted we want + // When we are inside the matching chars and a closing char is inserted we want // to skip the already present closing char instead of adding an additional one. - if (isClosingChar(c) && c != QLatin1Char('}')) + if (isClosingChar(c)) ++skippedChar; // If another opening char is inserted we // expect the same behavior as in an empty file - else if (isOpeningChar(c) && c != QLatin1Char('{')) + else if (isOpeningChar(c)) expectedText = closingChar(c); } @@ -371,7 +371,7 @@ void CppEditorPlugin::test_autoBackspace_data() QTest::newRow((QLatin1String("Inside ") + charGroupTestName(c)).toLatin1().data()) << fileContent(InBetween, c) - << QString("(['\"").contains(c); + << QString("({['\"").contains(c); } } diff --git a/src/plugins/texteditor/autocompleter.cpp b/src/plugins/texteditor/autocompleter.cpp index 4a5d502801c..2e1f9d9ec70 100644 --- a/src/plugins/texteditor/autocompleter.cpp +++ b/src/plugins/texteditor/autocompleter.cpp @@ -76,12 +76,25 @@ static void countBrackets(QTextCursor cursor, int from, int end, QChar open, QCh } } +enum class CharType { OpenChar, CloseChar }; +static QChar charType(const QChar &c, CharType type) +{ + switch (c.unicode()) { + case '(': case ')': + return type == CharType::OpenChar ? QLatin1Char('(') : QLatin1Char(')'); + case '[': case ']': + return type == CharType::OpenChar ? QLatin1Char('[') : QLatin1Char(']'); + case '{': case '}': + return type == CharType::OpenChar ? QLatin1Char('{') : QLatin1Char('}'); + } + return QChar(); +} + static bool fixesBracketsError(const QString &textToInsert, const QTextCursor &cursor) { const QChar character = textToInsert.at(0); - const QString parentheses = QLatin1String("()"); - const QString brackets = QLatin1String("[]"); - if (!parentheses.contains(character) && !brackets.contains(character)) + const QString allParentheses = QLatin1String("()[]{}"); + if (!allParentheses.contains(character)) return false; QTextCursor tmp = cursor; @@ -90,8 +103,8 @@ static bool fixesBracketsError(const QString &textToInsert, const QTextCursor &c tmp = cursor; bool foundBlockEnd = TextBlockUserData::findNextBlockClosingParenthesis(&tmp); int blockEnd = foundBlockEnd ? tmp.position() : (cursor.document()->characterCount() - 1); - const QChar openChar = parentheses.contains(character) ? QLatin1Char('(') : QLatin1Char('['); - const QChar closeChar = parentheses.contains(character) ? QLatin1Char(')') : QLatin1Char(']'); + const QChar openChar = charType(character, CharType::OpenChar); + const QChar closeChar = charType(character, CharType::CloseChar); int errors = 0; int stillopen = 0; @@ -215,7 +228,9 @@ bool AutoCompleter::autoBackspace(QTextCursor &cursor) const QChar lookFurtherBehind = doc->characterAt(pos - 2); const QChar character = lookBehind; - if (character == QLatin1Char('(') || character == QLatin1Char('[')) { + if (character == QLatin1Char('(') + || character == QLatin1Char('[') + || character == QLatin1Char('{')) { QTextCursor tmp = cursor; TextBlockUserData::findPreviousBlockOpenParenthesis(&tmp); int blockStart = tmp.isNull() ? 0 : tmp.position(); @@ -223,7 +238,7 @@ bool AutoCompleter::autoBackspace(QTextCursor &cursor) TextBlockUserData::findNextBlockClosingParenthesis(&tmp); int blockEnd = tmp.isNull() ? (cursor.document()->characterCount()-1) : tmp.position(); QChar openChar = character; - QChar closeChar = (character == QLatin1Char('(')) ? QLatin1Char(')') : QLatin1Char(']'); + QChar closeChar = charType(character, CharType::CloseChar); int errors = 0; int stillopen = 0; @@ -242,6 +257,7 @@ bool AutoCompleter::autoBackspace(QTextCursor &cursor) // ### this code needs to be generalized if ((lookBehind == QLatin1Char('(') && lookAhead == QLatin1Char(')')) || (lookBehind == QLatin1Char('[') && lookAhead == QLatin1Char(']')) + || (lookBehind == QLatin1Char('{') && lookAhead == QLatin1Char('}')) || (lookBehind == QLatin1Char('"') && lookAhead == QLatin1Char('"') && lookFurtherBehind != QLatin1Char('\\')) || (lookBehind == QLatin1Char('\'') && lookAhead == QLatin1Char('\'') diff --git a/src/plugins/texteditor/textdocumentlayout.cpp b/src/plugins/texteditor/textdocumentlayout.cpp index df6a82495d7..666afeeaee7 100644 --- a/src/plugins/texteditor/textdocumentlayout.cpp +++ b/src/plugins/texteditor/textdocumentlayout.cpp @@ -238,8 +238,7 @@ bool TextBlockUserData::findPreviousBlockOpenParenthesis(QTextCursor *cursor, bo if (!parenList.isEmpty() && !TextDocumentLayout::ifdefedOut(block)) { for (int i = parenList.count()-1; i >= 0; --i) { Parenthesis paren = parenList.at(i); - if (paren.chr != QLatin1Char('{') && paren.chr != QLatin1Char('}') - && paren.chr != QLatin1Char('+') && paren.chr != QLatin1Char('-')) + if (paren.chr != QLatin1Char('+') && paren.chr != QLatin1Char('-')) continue; if (block == cursor->block()) { if (position - block.position() <= paren.pos + (paren.type == Parenthesis::Closed ? 1 : 0)) @@ -300,8 +299,7 @@ bool TextBlockUserData::findNextBlockClosingParenthesis(QTextCursor *cursor) if (!parenList.isEmpty() && !TextDocumentLayout::ifdefedOut(block)) { for (int i = 0; i < parenList.count(); ++i) { Parenthesis paren = parenList.at(i); - if (paren.chr != QLatin1Char('{') && paren.chr != QLatin1Char('}') - && paren.chr != QLatin1Char('+') && paren.chr != QLatin1Char('-')) + if (paren.chr != QLatin1Char('+') && paren.chr != QLatin1Char('-')) continue; if (block == cursor->block() && (position - block.position() > paren.pos - (paren.type == Parenthesis::Opened ? 1 : 0)))