aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/cplusplus/MatchingText.cpp
diff options
context:
space:
mode:
authorDavid Schulz <david.schulz@theqtcompany.com>2016-04-14 10:09:31 +0200
committerDavid Schulz <david.schulz@theqtcompany.com>2016-05-20 12:35:07 +0000
commit61be2397955fe29e328b9fc4ac1783390604d6e4 (patch)
tree3ea9c9f9bf051e4944ad3955fa983cbacab737fb /src/libs/cplusplus/MatchingText.cpp
parent3a78b610d76f315e5ac1a0c26844258b5c910a04 (diff)
CppEditor: Simplify insert matching characters.
Change-Id: Ib3a94d016b615d71b1635ebe13a87575b8dc12c5 Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
Diffstat (limited to 'src/libs/cplusplus/MatchingText.cpp')
-rw-r--r--src/libs/cplusplus/MatchingText.cpp120
1 files changed, 61 insertions, 59 deletions
diff --git a/src/libs/cplusplus/MatchingText.cpp b/src/libs/cplusplus/MatchingText.cpp
index d553753dcae..16264894d9f 100644
--- a/src/libs/cplusplus/MatchingText.cpp
+++ b/src/libs/cplusplus/MatchingText.cpp
@@ -75,6 +75,56 @@ static bool isCompleteCharLiteral(const BackwardsScanner &tk, int index)
return false;
}
+static bool isEscaped(const QTextCursor &tc)
+{
+ const QTextDocument *doc = tc.document();
+
+ int escapeCount = 0;
+ int index = tc.selectionEnd() - 1;
+ while (doc->characterAt(index) == '\\') {
+ ++escapeCount;
+ --index;
+ }
+
+ return (escapeCount % 2) != 0;
+}
+
+static bool isQuote(const QChar c)
+{
+ return c == '\'' || c == '"';
+}
+
+static bool insertQuote(const QChar ch, const BackwardsScanner &tk)
+{
+ // Always insert matching quote on an empty line
+ if (tk.size() == 0)
+ return true;
+
+ const int index = tk.startToken() - 1;
+ const Token &token = tk[index];
+ // Do not insert a matching quote when we are closing an open string/char literal.
+ return (ch == '"' && token.isStringLiteral() == isCompleteStringLiteral(tk, index))
+ || (ch == '\'' && token.isCharLiteral() == isCompleteCharLiteral(tk, index));
+}
+
+static int countSkippedChars(const QString blockText, const QString &textToProcess)
+{
+ int skippedChars = 0;
+ const int length = qMin(blockText.length(), textToProcess.length());
+ for (int i = 0; i < length; ++i) {
+ const QChar ch1 = blockText.at(i);
+ const QChar ch2 = textToProcess.at(i);
+
+ if (ch1 != ch2)
+ break;
+ else if (! shouldOverrideChar(ch1))
+ break;
+
+ ++skippedChars;
+ }
+ return skippedChars;
+}
+
bool MatchingText::shouldInsertMatchingText(const QTextCursor &tc)
{
QTextDocument *doc = tc.document();
@@ -101,90 +151,42 @@ QString MatchingText::insertMatchingBrace(const QTextCursor &cursor, const QStri
QChar la, int *skippedChars)
{
QTextCursor tc = cursor;
- QTextDocument *doc = tc.document();
QString text = textToProcess;
const QString blockText = tc.block().text().mid(tc.positionInBlock());
const QString trimmedBlockText = blockText.trimmed();
- const int length = qMin(blockText.length(), textToProcess.length());
- const QChar previousChar = doc->characterAt(tc.selectionEnd() - 1);
-
- bool escape = false;
-
- if (! text.isEmpty() && (text.at(0) == QLatin1Char('"') ||
- text.at(0) == QLatin1Char('\''))) {
- if (previousChar == QLatin1Char('\\')) {
- int escapeCount = 0;
- int index = tc.selectionEnd() - 1;
- do {
- ++escapeCount;
- --index;
- } while (doc->characterAt(index) == QLatin1Char('\\'));
-
- if ((escapeCount % 2) != 0)
- escape = true;
- }
- }
-
- if (! escape) {
- for (int i = 0; i < length; ++i) {
- const QChar ch1 = blockText.at(i);
- const QChar ch2 = textToProcess.at(i);
-
- if (ch1 != ch2)
- break;
- else if (! shouldOverrideChar(ch1))
- break;
-
- ++*skippedChars;
+ if (!textToProcess.isEmpty()) {
+ if (!isQuote(textToProcess.at(0)) || !isEscaped(tc)) {
+ *skippedChars = countSkippedChars(blockText, textToProcess);
+ if (*skippedChars != 0) {
+ tc.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, *skippedChars);
+ text = textToProcess.mid(*skippedChars);
+ }
}
}
- if (*skippedChars != 0) {
- tc.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, *skippedChars);
- text = textToProcess.mid(*skippedChars);
- }
-
if (text.isEmpty() || !shouldInsertMatchingText(la))
return QString();
BackwardsScanner tk(tc, LanguageFeatures::defaultFeatures(), MAX_NUM_LINES,
textToProcess.left(*skippedChars));
- const int startToken = tk.startToken();
- int index = startToken;
-
- const Token &token = tk[index - 1];
-
- if (text.at(0) == QLatin1Char('"') && token.isStringLiteral()) {
- if (text.length() != 1)
- qWarning() << Q_FUNC_INFO << "handle event compression";
-
- if (isCompleteStringLiteral(tk, index - 1))
- return QLatin1String("\"");
-
- return QString();
- } else if (text.at(0) == QLatin1Char('\'') && token.isCharLiteral()) {
+ const QChar ch0 = text.at(0);
+ if (isQuote(ch0)) {
if (text.length() != 1)
qWarning() << Q_FUNC_INFO << "handle event compression";
-
- if (isCompleteCharLiteral(tk, index - 1))
- return QLatin1String("'");
-
+ if (insertQuote(ch0, tk))
+ return ch0;
return QString();
}
QString result;
-
foreach (const QChar &ch, text) {
if (ch == QLatin1Char('(')) result += QLatin1Char(')');
else if (ch == QLatin1Char('[')) result += QLatin1Char(']');
- else 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('}');
-
}
return result;