C++: Handle curly braces like other brace types

Unless it balances the curly braces
 * typing '{' leads to auto insertion of '}'.
 * typing '}' skips already present '}'.
 * removing '{' leads to auto removal of '}'.

This prevents unbalanced curly braces, which are problematic for clang.
Concrete use cases are: typing of initializer lists, lambdas, function
definitions.

Task-number: QTCREATORBUG-15073
Change-Id: Iec8c6aa5aca054455c1e1bfde3a65c4fd1f579c3
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Nikolai Kosjar
2017-05-08 09:47:52 +02:00
parent 19a178e1b1
commit 986a518c17
4 changed files with 34 additions and 24 deletions

View File

@@ -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('\'')