aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Schulz <david.schulz@qt.io>2016-06-10 15:13:38 +0200
committerDavid Schulz <david.schulz@theqtcompany.com>2016-06-21 11:56:56 +0000
commit675060724453fc2a5d12431b656fdbb599e529f6 (patch)
treecbf5a1fc06919089d4028bd31c6ae7e15ee575b6 /src
parent08dcad9c829abfbc592d6a4628d091d942a87c0f (diff)
Editor: Skip auto completed character only if it was recently inserted.
This means you can skip automatically inserted characters as long as you don't explicitly move the text cursor and the editor doesn't lose the focus. This will be visualized by highlighting the automatically inserted character as long as you can perform the skipping. This will reduce unexpected skipping in the case a cursor was explicitly placed before an closing brace and a closing brace is typed. Change-Id: I28e29e79ba10c9c48e8bc8817405fea630cca9bd Reviewed-by: Christian Stenger <christian.stenger@qt.io> Reviewed-by: Eike Ziller <eike.ziller@qt.io> Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io> Reviewed-by: David Schulz <david.schulz@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r--src/libs/cplusplus/MatchingText.cpp18
-rw-r--r--src/libs/cplusplus/MatchingText.h4
-rw-r--r--src/plugins/clangcodemodel/clangassistproposalitem.cpp4
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeautocompleter.cpp26
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeautocompleter.h4
-rw-r--r--src/plugins/cppeditor/cppautocompleter.cpp16
-rw-r--r--src/plugins/cppeditor/cppautocompleter.h2
-rw-r--r--src/plugins/cpptools/cppcompletionassist.cpp4
-rw-r--r--src/plugins/glsleditor/glslautocompleter.cpp10
-rw-r--r--src/plugins/glsleditor/glslautocompleter.h4
-rw-r--r--src/plugins/qmljseditor/qmljsautocompleter.cpp10
-rw-r--r--src/plugins/qmljseditor/qmljsautocompleter.h2
-rw-r--r--src/plugins/qmljseditor/qmljscompletionassist.cpp4
-rw-r--r--src/plugins/texteditor/autocompleter.cpp15
-rw-r--r--src/plugins/texteditor/autocompleter.h6
-rw-r--r--src/plugins/texteditor/codeassist/keywordscompletionassist.cpp5
-rw-r--r--src/plugins/texteditor/codeassist/textdocumentmanipulator.cpp7
-rw-r--r--src/plugins/texteditor/codeassist/textdocumentmanipulator.h1
-rw-r--r--src/plugins/texteditor/codeassist/textdocumentmanipulatorinterface.h1
-rw-r--r--src/plugins/texteditor/completionsettings.cpp5
-rw-r--r--src/plugins/texteditor/completionsettings.h3
-rw-r--r--src/plugins/texteditor/completionsettingspage.cpp3
-rw-r--r--src/plugins/texteditor/completionsettingspage.ui69
-rw-r--r--src/plugins/texteditor/texteditor.cpp16
-rw-r--r--src/plugins/texteditor/texteditor.h1
25 files changed, 182 insertions, 58 deletions
diff --git a/src/libs/cplusplus/MatchingText.cpp b/src/libs/cplusplus/MatchingText.cpp
index e4266653f94..08ea34c9182 100644
--- a/src/libs/cplusplus/MatchingText.cpp
+++ b/src/libs/cplusplus/MatchingText.cpp
@@ -255,7 +255,7 @@ bool MatchingText::isInStringHelper(const QTextCursor &cursor)
}
QString MatchingText::insertMatchingBrace(const QTextCursor &cursor, const QString &textToProcess,
- QChar /*lookAhead*/, int *skippedChars)
+ QChar /*lookAhead*/, bool skipChars, int *skippedChars)
{
if (textToProcess.isEmpty())
return QString();
@@ -266,10 +266,12 @@ QString MatchingText::insertMatchingBrace(const QTextCursor &cursor, const QStri
const QString blockText = tc.block().text().mid(tc.positionInBlock());
const QString trimmedBlockText = blockText.trimmed();
- *skippedChars = countSkippedChars(blockText, textToProcess);
- if (*skippedChars != 0) {
- tc.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, *skippedChars);
- text = textToProcess.mid(*skippedChars);
+ if (skipChars) {
+ *skippedChars = countSkippedChars(blockText, textToProcess);
+ if (*skippedChars != 0) {
+ tc.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, *skippedChars);
+ text = textToProcess.mid(*skippedChars);
+ }
}
QString result;
@@ -285,7 +287,7 @@ QString MatchingText::insertMatchingBrace(const QTextCursor &cursor, const QStri
}
QString MatchingText::insertMatchingQuote(const QTextCursor &cursor, const QString &textToProcess,
- QChar lookAhead, int *skippedChars)
+ QChar lookAhead, bool skipChars, int *skippedChars)
{
if (textToProcess.isEmpty())
return QString();
@@ -293,7 +295,7 @@ QString MatchingText::insertMatchingQuote(const QTextCursor &cursor, const QStri
QTextCursor tc = cursor;
QString text = textToProcess;
- if (!isEscaped(tc)) {
+ if (skipChars && !isEscaped(tc)) {
const QString blockText = tc.block().text().mid(tc.positionInBlock());
*skippedChars = countSkippedChars(blockText, textToProcess);
if (*skippedChars != 0) {
@@ -313,7 +315,7 @@ QString MatchingText::insertMatchingQuote(const QTextCursor &cursor, const QStri
qWarning() << Q_FUNC_INFO << "handle event compression";
BackwardsScanner tk(tc, LanguageFeatures::defaultFeatures(), MAX_NUM_LINES,
- textToProcess.left(*skippedChars));
+ textToProcess.left(skippedChars ? *skippedChars : 0));
if (insertQuote(ch, tk))
return ch;
}
diff --git a/src/libs/cplusplus/MatchingText.h b/src/libs/cplusplus/MatchingText.h
index c93488c8ec8..0f861d152d0 100644
--- a/src/libs/cplusplus/MatchingText.h
+++ b/src/libs/cplusplus/MatchingText.h
@@ -49,9 +49,9 @@ public:
static bool isInStringHelper(const QTextCursor &cursor);
static QString insertMatchingBrace(const QTextCursor &tc, const QString &text,
- QChar lookAhead, int *skippedChars);
+ QChar lookAhead, bool skipChars, int *skippedChars);
static QString insertMatchingQuote(const QTextCursor &tc, const QString &text,
- QChar lookAhead, int *skippedChars);
+ QChar lookAhead, bool skipChars, int *skippedChars);
static QString insertParagraphSeparator(const QTextCursor &tc);
};
diff --git a/src/plugins/clangcodemodel/clangassistproposalitem.cpp b/src/plugins/clangcodemodel/clangassistproposalitem.cpp
index 8ec96a80984..34b4b9b2dd1 100644
--- a/src/plugins/clangcodemodel/clangassistproposalitem.cpp
+++ b/src/plugins/clangcodemodel/clangassistproposalitem.cpp
@@ -75,6 +75,7 @@ void ClangAssistProposalItem::apply(TextEditor::TextDocumentManipulatorInterface
QString extraCharacters;
int extraLength = 0;
int cursorOffset = 0;
+ bool setAutoCompleteSkipPos = false;
bool autoParenthesesEnabled = true;
if (m_completionOperator == T_SIGNAL || m_completionOperator == T_SLOT) {
@@ -141,6 +142,7 @@ void ClangAssistProposalItem::apply(TextEditor::TextDocumentManipulatorInterface
if (MatchingText::shouldInsertMatchingText(lookAhead)) {
extraCharacters += QLatin1Char(')');
--cursorOffset;
+ setAutoCompleteSkipPos = true;
if (endWithSemicolon) {
extraCharacters += semicolon;
--cursorOffset;
@@ -200,6 +202,8 @@ void ClangAssistProposalItem::apply(TextEditor::TextDocumentManipulatorInterface
if (isReplaced) {
if (cursorOffset)
manipulator.setCursorPosition(manipulator.currentPosition() + cursorOffset);
+ if (setAutoCompleteSkipPos)
+ manipulator.setAutoCompleteSkipPosition(manipulator.currentPosition());
if (ccr.completionKind() == CodeCompletion::KeywordCompletionKind)
manipulator.autoIndent(basePosition, textToBeInserted.size());
diff --git a/src/plugins/cmakeprojectmanager/cmakeautocompleter.cpp b/src/plugins/cmakeprojectmanager/cmakeautocompleter.cpp
index 60cbfcddb79..2605830d0b5 100644
--- a/src/plugins/cmakeprojectmanager/cmakeautocompleter.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeautocompleter.cpp
@@ -73,11 +73,13 @@ bool CMakeAutoCompleter::isInString(const QTextCursor &cursor) const
return inString;
}
-QString CMakeAutoCompleter::insertMatchingBrace(const QTextCursor &cursor, const QString &text,
- QChar lookAhead, int *skippedChars) const
+QString CMakeAutoCompleter::insertMatchingBrace(const QTextCursor &cursor,
+ const QString &text,
+ QChar lookAhead,
+ bool skipChars,
+ int *skippedChars) const
{
Q_UNUSED(cursor)
- Q_UNUSED(skippedChars)
if (text.isEmpty())
return QString();
const QChar current = text.at(0);
@@ -86,7 +88,7 @@ QString CMakeAutoCompleter::insertMatchingBrace(const QTextCursor &cursor, const
return QStringLiteral(")");
case ')':
- if (current == lookAhead)
+ if (current == lookAhead && skipChars)
++*skippedChars;
break;
@@ -97,17 +99,21 @@ QString CMakeAutoCompleter::insertMatchingBrace(const QTextCursor &cursor, const
return QString();
}
-QString CMakeAutoCompleter::insertMatchingQuote(const QTextCursor &cursor, const QString &text,
- QChar lookAhead, int *skippedChars) const
+QString CMakeAutoCompleter::insertMatchingQuote(const QTextCursor &cursor,
+ const QString &text,
+ QChar lookAhead,
+ bool skipChars,
+ int *skippedChars) const
{
Q_UNUSED(cursor)
static const QChar quote(QLatin1Char('"'));
if (text.isEmpty() || text != quote)
return QString();
- if (lookAhead != quote)
- return quote;
- ++*skippedChars;
- return QString();
+ if (lookAhead == quote && skipChars) {
+ ++*skippedChars;
+ return QString();
+ }
+ return quote;
}
int CMakeAutoCompleter::paragraphSeparatorAboutToBeInserted(QTextCursor &cursor, const TextEditor::TabSettings &tabSettings)
diff --git a/src/plugins/cmakeprojectmanager/cmakeautocompleter.h b/src/plugins/cmakeprojectmanager/cmakeautocompleter.h
index dee6655d94b..ded51afc450 100644
--- a/src/plugins/cmakeprojectmanager/cmakeautocompleter.h
+++ b/src/plugins/cmakeprojectmanager/cmakeautocompleter.h
@@ -40,9 +40,9 @@ public:
bool isInComment(const QTextCursor &cursor) const override;
bool isInString(const QTextCursor &cursor) const override;
QString insertMatchingBrace(const QTextCursor &cursor, const QString &text,
- QChar lookAhead, int *skippedChars) const override;
+ QChar lookAhead, bool skipChars, int *skippedChars) const override;
QString insertMatchingQuote(const QTextCursor &cursor, const QString &text,
- QChar lookAhead, int *skippedChars) const override;
+ QChar lookAhead, bool skipChars, int *skippedChars) const override;
int paragraphSeparatorAboutToBeInserted(QTextCursor &cursor, const TextEditor::TabSettings &tabSettings) override;
bool contextAllowsAutoBrackets(const QTextCursor &cursor, const QString &textToInsert) const override;
bool contextAllowsAutoQuotes(const QTextCursor &cursor, const QString &textToInsert) const override;
diff --git a/src/plugins/cppeditor/cppautocompleter.cpp b/src/plugins/cppeditor/cppautocompleter.cpp
index 2114a86e679..2df19e8a02c 100644
--- a/src/plugins/cppeditor/cppautocompleter.cpp
+++ b/src/plugins/cppeditor/cppautocompleter.cpp
@@ -60,15 +60,17 @@ bool CppAutoCompleter::isInString(const QTextCursor &cursor) const
}
QString CppAutoCompleter::insertMatchingBrace(const QTextCursor &cursor, const QString &text,
- QChar lookAhead, int *skippedChars) const
+ QChar lookAhead, bool skipChars, int *skippedChars) const
{
- return CPlusPlus::MatchingText::insertMatchingBrace(cursor, text, lookAhead, skippedChars);
+ return CPlusPlus::MatchingText::insertMatchingBrace(cursor, text, lookAhead,
+ skipChars, skippedChars);
}
QString CppAutoCompleter::insertMatchingQuote(const QTextCursor &cursor, const QString &text,
- QChar lookAhead, int *skippedChars) const
+ QChar lookAhead, bool skipChars, int *skippedChars) const
{
- return CPlusPlus::MatchingText::insertMatchingQuote(cursor, text, lookAhead, skippedChars);
+ return CPlusPlus::MatchingText::insertMatchingQuote(cursor, text, lookAhead,
+ skipChars, skippedChars);
}
QString CppAutoCompleter::insertParagraphSeparator(const QTextCursor &cursor) const
@@ -291,7 +293,8 @@ void CppEditorPlugin::test_autoComplete()
QVERIFY(!tc.isNull());
- const QString &matchingText = CppAutoCompleter().autoComplete(tc, textToInsert);
+ const QString &matchingText = CppAutoCompleter().autoComplete(tc, textToInsert,
+ true /*skipChars*/);
int skippedChars = tc.selectedText().size();
@@ -351,7 +354,8 @@ void CppEditorPlugin::test_surroundWithSelection()
QVERIFY(!tc.isNull());
- const QString &matchingText = CppAutoCompleter().autoComplete(tc, textToInsert);
+ const QString &matchingText = CppAutoCompleter().autoComplete(tc, textToInsert,
+ true /*skipChars*/);
QCOMPARE(matchingText, expectedText);
}
diff --git a/src/plugins/cppeditor/cppautocompleter.h b/src/plugins/cppeditor/cppautocompleter.h
index 3508c38a2b0..5c90d73dca3 100644
--- a/src/plugins/cppeditor/cppautocompleter.h
+++ b/src/plugins/cppeditor/cppautocompleter.h
@@ -45,10 +45,12 @@ public:
QString insertMatchingBrace(const QTextCursor &cursor,
const QString &text,
QChar lookAhead,
+ bool skipChars,
int *skippedChars) const override;
QString insertMatchingQuote(const QTextCursor &cursor,
const QString &text,
QChar lookAhead,
+ bool skipChars,
int *skippedChars) const override;
QString insertParagraphSeparator(const QTextCursor &cursor) const override;
};
diff --git a/src/plugins/cpptools/cppcompletionassist.cpp b/src/plugins/cpptools/cppcompletionassist.cpp
index f8070985298..9aa5a4538f3 100644
--- a/src/plugins/cpptools/cppcompletionassist.cpp
+++ b/src/plugins/cpptools/cppcompletionassist.cpp
@@ -203,6 +203,7 @@ void CppAssistProposalItem::applyContextualContent(TextDocumentManipulatorInterf
QString extraChars;
int extraLength = 0;
int cursorOffset = 0;
+ bool setAutoCompleteSkipPos = false;
bool autoParenthesesEnabled = true;
@@ -278,6 +279,7 @@ void CppAssistProposalItem::applyContextualContent(TextDocumentManipulatorInterf
if (MatchingText::shouldInsertMatchingText(lookAhead)) {
extraChars += QLatin1Char(')');
--cursorOffset;
+ setAutoCompleteSkipPos = true;
if (endWithSemicolon) {
extraChars += semicolon;
--cursorOffset;
@@ -345,6 +347,8 @@ void CppAssistProposalItem::applyContextualContent(TextDocumentManipulatorInterf
manipulator.replace(basePosition, length, toInsert);
if (cursorOffset)
manipulator.setCursorPosition(manipulator.currentPosition() + cursorOffset);
+ if (setAutoCompleteSkipPos)
+ manipulator.setAutoCompleteSkipPosition(manipulator.currentPosition());
}
// --------------------
diff --git a/src/plugins/glsleditor/glslautocompleter.cpp b/src/plugins/glsleditor/glslautocompleter.cpp
index e0ff3df2e84..cf19c7310e8 100644
--- a/src/plugins/glsleditor/glslautocompleter.cpp
+++ b/src/plugins/glsleditor/glslautocompleter.cpp
@@ -55,15 +55,17 @@ bool GlslCompleter::isInComment(const QTextCursor &cursor) const
}
QString GlslCompleter::insertMatchingBrace(const QTextCursor &cursor, const QString &text,
- QChar lookAhead, int *skippedChars) const
+ QChar lookAhead, bool skipChars, int *skippedChars) const
{
- return CPlusPlus::MatchingText::insertMatchingBrace(cursor, text, lookAhead, skippedChars);
+ return CPlusPlus::MatchingText::insertMatchingBrace(cursor, text, lookAhead,
+ skipChars, skippedChars);
}
QString GlslCompleter::insertMatchingQuote(const QTextCursor &cursor, const QString &text,
- QChar lookAhead, int *skippedChars) const
+ QChar lookAhead, bool skipChars, int *skippedChars) const
{
- return CPlusPlus::MatchingText::insertMatchingQuote(cursor, text, lookAhead, skippedChars);
+ return CPlusPlus::MatchingText::insertMatchingQuote(cursor, text, lookAhead,
+ skipChars, skippedChars);
}
QString GlslCompleter::insertParagraphSeparator(const QTextCursor &cursor) const
diff --git a/src/plugins/glsleditor/glslautocompleter.h b/src/plugins/glsleditor/glslautocompleter.h
index 59cfd3daed5..9e193132e81 100644
--- a/src/plugins/glsleditor/glslautocompleter.h
+++ b/src/plugins/glsleditor/glslautocompleter.h
@@ -40,9 +40,9 @@ public:
bool contextAllowsElectricCharacters(const QTextCursor &cursor) const override;
bool isInComment(const QTextCursor &cursor) const override;
QString insertMatchingBrace(const QTextCursor &cursor, const QString &text,
- QChar lookAhead, int *skippedChars) const override;
+ QChar lookAhead, bool skipChars, int *skippedChars) const override;
QString insertMatchingQuote(const QTextCursor &cursor, const QString &text,
- QChar lookAhead, int *skippedChars) const override;
+ QChar lookAhead, bool skipChars, int *skippedChars) const override;
QString insertParagraphSeparator(const QTextCursor &cursor) const override;
};
diff --git a/src/plugins/qmljseditor/qmljsautocompleter.cpp b/src/plugins/qmljseditor/qmljsautocompleter.cpp
index b379ed62ddf..e50c268d2ca 100644
--- a/src/plugins/qmljseditor/qmljsautocompleter.cpp
+++ b/src/plugins/qmljseditor/qmljsautocompleter.cpp
@@ -268,6 +268,7 @@ bool AutoCompleter::isInComment(const QTextCursor &cursor) const
QString AutoCompleter::insertMatchingBrace(const QTextCursor &cursor,
const QString &text,
QChar lookAhead,
+ bool skipChars,
int *skippedChars) const
{
if (text.length() != 1)
@@ -291,7 +292,7 @@ QString AutoCompleter::insertMatchingBrace(const QTextCursor &cursor,
case ']':
case '}':
case ';':
- if (lookAhead == ch)
+ if (lookAhead == ch && skipChars)
++*skippedChars;
break;
@@ -303,12 +304,13 @@ QString AutoCompleter::insertMatchingBrace(const QTextCursor &cursor,
}
QString AutoCompleter::insertMatchingQuote(const QTextCursor &/*tc*/, const QString &text,
- QChar lookAhead, int *skippedChars) const
+ QChar lookAhead, bool skipChars, int *skippedChars) const
{
if (isQuote(text)) {
- if (lookAhead != text)
+ if (lookAhead == text && skipChars)
+ ++*skippedChars;
+ else
return text;
- ++*skippedChars;
}
return QString();
}
diff --git a/src/plugins/qmljseditor/qmljsautocompleter.h b/src/plugins/qmljseditor/qmljsautocompleter.h
index dda7173d390..e0834448b80 100644
--- a/src/plugins/qmljseditor/qmljsautocompleter.h
+++ b/src/plugins/qmljseditor/qmljsautocompleter.h
@@ -45,10 +45,12 @@ public:
QString insertMatchingBrace(const QTextCursor &tc,
const QString &text,
QChar lookAhead,
+ bool skipChars,
int *skippedChars) const override;
QString insertMatchingQuote(const QTextCursor &tc,
const QString &text,
QChar lookAhead,
+ bool skipChars,
int *skippedChars) const override;
QString insertParagraphSeparator(const QTextCursor &tc) const override;
};
diff --git a/src/plugins/qmljseditor/qmljscompletionassist.cpp b/src/plugins/qmljseditor/qmljscompletionassist.cpp
index 9bc9f298967..0734e96fb0f 100644
--- a/src/plugins/qmljseditor/qmljscompletionassist.cpp
+++ b/src/plugins/qmljseditor/qmljscompletionassist.cpp
@@ -379,8 +379,10 @@ void QmlJSAssistProposalItem::applyContextualContent(TextEditor::TextDocumentMan
}
const int length = manipulator.currentPosition() - basePosition + replacedLength;
manipulator.replace(basePosition, length, content);
- if (cursorOffset)
+ if (cursorOffset) {
manipulator.setCursorPosition(manipulator.currentPosition() + cursorOffset);
+ manipulator.setAutoCompleteSkipPosition(manipulator.currentPosition());
+ }
}
// -------------------------
diff --git a/src/plugins/texteditor/autocompleter.cpp b/src/plugins/texteditor/autocompleter.cpp
index d457382a4cc..1cc4a9ee561 100644
--- a/src/plugins/texteditor/autocompleter.cpp
+++ b/src/plugins/texteditor/autocompleter.cpp
@@ -148,7 +148,8 @@ QString AutoCompleter::replaceSelection(QTextCursor &cursor, const QString &text
return QString();
}
-QString AutoCompleter::autoComplete(QTextCursor &cursor, const QString &textToInsert) const
+QString AutoCompleter::autoComplete(QTextCursor &cursor, const QString &textToInsert,
+ bool skipChars) const
{
const bool checkBlockEnd = m_allowSkippingOfBlockEnd;
m_allowSkippingOfBlockEnd = false; // consume blockEnd.
@@ -164,12 +165,12 @@ QString AutoCompleter::autoComplete(QTextCursor &cursor, const QString &textToIn
if (isQuote(textToInsert) && m_autoInsertQuotes
&& contextAllowsAutoQuotes(cursor, textToInsert)) {
- autoText = insertMatchingQuote(cursor, textToInsert, lookAhead, &skippedChars);
+ autoText = insertMatchingQuote(cursor, textToInsert, lookAhead, skipChars, &skippedChars);
} else if (m_autoInsertBrackets && contextAllowsAutoBrackets(cursor, textToInsert)) {
if (fixesBracketsError(textToInsert, cursor))
return QString();
- autoText = insertMatchingBrace(cursor, textToInsert, lookAhead, &skippedChars);
+ autoText = insertMatchingBrace(cursor, textToInsert, lookAhead, skipChars, &skippedChars);
if (checkBlockEnd && textToInsert.at(0) == QLatin1Char('}')) {
if (textToInsert.length() > 1)
@@ -179,14 +180,14 @@ QString AutoCompleter::autoComplete(QTextCursor &cursor, const QString &textToIn
while (doc->characterAt(pos).isSpace())
++pos;
- if (doc->characterAt(pos) == QLatin1Char('}'))
+ if (doc->characterAt(pos) == QLatin1Char('}') && skipChars)
skippedChars += (pos - startPos) + 1;
}
} else {
return QString();
}
- if (skippedChars) {
+ if (skipChars && skippedChars) {
const int pos = cursor.position();
cursor.setPosition(pos + skippedChars);
cursor.setPosition(pos, QTextCursor::KeepAnchor);
@@ -341,11 +342,13 @@ bool AutoCompleter::isInString(const QTextCursor &cursor) const
QString AutoCompleter::insertMatchingBrace(const QTextCursor &cursor,
const QString &text,
QChar lookAhead,
+ bool skipChars,
int *skippedChars) const
{
Q_UNUSED(cursor);
Q_UNUSED(text);
Q_UNUSED(lookAhead);
+ Q_UNUSED(skipChars);
Q_UNUSED(skippedChars);
return QString();
}
@@ -353,11 +356,13 @@ QString AutoCompleter::insertMatchingBrace(const QTextCursor &cursor,
QString AutoCompleter::insertMatchingQuote(const QTextCursor &cursor,
const QString &text,
QChar lookAhead,
+ bool skipChars,
int *skippedChars) const
{
Q_UNUSED(cursor);
Q_UNUSED(text);
Q_UNUSED(lookAhead);
+ Q_UNUSED(skipChars);
Q_UNUSED(skippedChars);
return QString();
}
diff --git a/src/plugins/texteditor/autocompleter.h b/src/plugins/texteditor/autocompleter.h
index 1470fa1065d..91d5f98dc49 100644
--- a/src/plugins/texteditor/autocompleter.h
+++ b/src/plugins/texteditor/autocompleter.h
@@ -54,7 +54,7 @@ public:
bool isSurroundWithQuotesEnabled() const { return m_surroundWithQuotes; }
// Returns the text to complete at the cursor position, or an empty string
- virtual QString autoComplete(QTextCursor &cursor, const QString &text) const;
+ virtual QString autoComplete(QTextCursor &cursor, const QString &text, bool skipChars) const;
// Handles backspace. When returning true, backspace processing is stopped
virtual bool autoBackspace(QTextCursor &cursor);
@@ -77,12 +77,12 @@ public:
virtual QString insertMatchingBrace(const QTextCursor &cursor, const
QString &text,
- QChar lookAhead,
+ QChar lookAhead, bool skipChars,
int *skippedChars) const;
virtual QString insertMatchingQuote(const QTextCursor &cursor, const
QString &text,
- QChar lookAhead,
+ QChar lookAhead, bool skipChars,
int *skippedChars) const;
// Returns the text that needs to be inserted
diff --git a/src/plugins/texteditor/codeassist/keywordscompletionassist.cpp b/src/plugins/texteditor/codeassist/keywordscompletionassist.cpp
index 4449f06d525..56918becab0 100644
--- a/src/plugins/texteditor/codeassist/keywordscompletionassist.cpp
+++ b/src/plugins/texteditor/codeassist/keywordscompletionassist.cpp
@@ -101,6 +101,7 @@ void KeywordsAssistProposalItem::applyContextualContent(TextDocumentManipulatorI
QString toInsert = text();
int cursorOffset = 0;
const QChar characterAtCurrentPosition = manipulator.characterAt(manipulator.currentPosition());
+ bool setAutoCompleteSkipPosition = false;
if (m_isFunction && settings.m_autoInsertBrackets) {
if (settings.m_spaceAfterFunctionName) {
@@ -113,6 +114,7 @@ void KeywordsAssistProposalItem::applyContextualContent(TextDocumentManipulatorI
} else {
toInsert += QLatin1String(" ()");
cursorOffset = -1;
+ setAutoCompleteSkipPosition = true;
}
} else {
if (characterAtCurrentPosition == QLatin1Char('(')) {
@@ -120,6 +122,7 @@ void KeywordsAssistProposalItem::applyContextualContent(TextDocumentManipulatorI
} else {
toInsert += QLatin1String("()");
cursorOffset = -1;
+ setAutoCompleteSkipPosition = true;
}
}
}
@@ -127,6 +130,8 @@ void KeywordsAssistProposalItem::applyContextualContent(TextDocumentManipulatorI
manipulator.replace(basePosition, replaceLength, toInsert);
if (cursorOffset)
manipulator.setCursorPosition(manipulator.currentPosition() + cursorOffset);
+ if (setAutoCompleteSkipPosition)
+ manipulator.setAutoCompleteSkipPosition(manipulator.currentPosition());
}
// -------------------------
diff --git a/src/plugins/texteditor/codeassist/textdocumentmanipulator.cpp b/src/plugins/texteditor/codeassist/textdocumentmanipulator.cpp
index 86c4674d265..0eee5793dbd 100644
--- a/src/plugins/texteditor/codeassist/textdocumentmanipulator.cpp
+++ b/src/plugins/texteditor/codeassist/textdocumentmanipulator.cpp
@@ -68,6 +68,13 @@ void TextDocumentManipulator::setCursorPosition(int position)
m_textEditorWidget->setCursorPosition(position);
}
+void TextDocumentManipulator::setAutoCompleteSkipPosition(int position)
+{
+ QTextCursor cursor = m_textEditorWidget->textCursor();
+ cursor.setPosition(position);
+ m_textEditorWidget->setAutoCompleteSkipPosition(cursor);
+}
+
bool TextDocumentManipulator::replace(int position, int length, const QString &text)
{
bool textWillBeReplaced = textIsDifferentAt(position, length, text);
diff --git a/src/plugins/texteditor/codeassist/textdocumentmanipulator.h b/src/plugins/texteditor/codeassist/textdocumentmanipulator.h
index 8b4547f1130..d820e2edade 100644
--- a/src/plugins/texteditor/codeassist/textdocumentmanipulator.h
+++ b/src/plugins/texteditor/codeassist/textdocumentmanipulator.h
@@ -43,6 +43,7 @@ public:
QTextCursor textCursorAt(int position) const final;
void setCursorPosition(int position) final;
+ void setAutoCompleteSkipPosition(int position) final;
bool replace(int position, int length, const QString &text) final;
void insertCodeSnippet(int position, const QString &text) final;
void paste() final;
diff --git a/src/plugins/texteditor/codeassist/textdocumentmanipulatorinterface.h b/src/plugins/texteditor/codeassist/textdocumentmanipulatorinterface.h
index 62c6489fb54..ae803260c79 100644
--- a/src/plugins/texteditor/codeassist/textdocumentmanipulatorinterface.h
+++ b/src/plugins/texteditor/codeassist/textdocumentmanipulatorinterface.h
@@ -47,6 +47,7 @@ public:
virtual QTextCursor textCursorAt(int position) const = 0;
virtual void setCursorPosition(int position) = 0;
+ virtual void setAutoCompleteSkipPosition(int position) = 0;
virtual bool replace(int position, int length, const QString &text) = 0;
virtual void insertCodeSnippet(int position, const QString &text) = 0;
virtual void paste() = 0;
diff --git a/src/plugins/texteditor/completionsettings.cpp b/src/plugins/texteditor/completionsettings.cpp
index 8bdcbded959..a012e407c2f 100644
--- a/src/plugins/texteditor/completionsettings.cpp
+++ b/src/plugins/texteditor/completionsettings.cpp
@@ -40,6 +40,7 @@ static const char spaceAfterFunctionNameKey[] = "SpaceAfterFunctionName";
static const char autoSplitStringsKey[] = "AutoSplitStrings";
static const char animateAutoCompleteKey[] = "AnimateAutoComplete";
static const char highlightAutoCompleteKey[] = "HighlightAutoComplete";
+static const char skipAutoCompleteKey[] = "SkipAutoComplete";
using namespace TextEditor;
@@ -58,6 +59,7 @@ void CompletionSettings::toSettings(QSettings *s) const
s->setValue(autoSplitStringsKey, m_autoSplitStrings);
s->setValue(animateAutoCompleteKey, m_animateAutoComplete);
s->setValue(highlightAutoCompleteKey, m_highlightAutoComplete);
+ s->setValue(skipAutoCompleteKey, m_skipAutoCompletedText);
s->endGroup();
}
@@ -90,6 +92,8 @@ void CompletionSettings::fromSettings(QSettings *s)
s->value(animateAutoCompleteKey, m_animateAutoComplete).toBool();
m_highlightAutoComplete =
s->value(highlightAutoCompleteKey, m_highlightAutoComplete).toBool();
+ m_skipAutoCompletedText =
+ s->value(skipAutoCompleteKey, m_skipAutoCompletedText).toBool();
s->endGroup();
}
@@ -107,5 +111,6 @@ bool CompletionSettings::equals(const CompletionSettings &cs) const
&& m_autoSplitStrings == cs.m_autoSplitStrings
&& m_animateAutoComplete == cs.m_animateAutoComplete
&& m_highlightAutoComplete == cs.m_highlightAutoComplete
+ && m_skipAutoCompletedText == cs.m_skipAutoCompletedText
;
}
diff --git a/src/plugins/texteditor/completionsettings.h b/src/plugins/texteditor/completionsettings.h
index 0b466718f97..7ca5535b3eb 100644
--- a/src/plugins/texteditor/completionsettings.h
+++ b/src/plugins/texteditor/completionsettings.h
@@ -67,7 +67,8 @@ public:
bool m_spaceAfterFunctionName = false;
bool m_autoSplitStrings = true;
bool m_animateAutoComplete = true;
- bool m_highlightAutoComplete = false;
+ bool m_highlightAutoComplete = true;
+ bool m_skipAutoCompletedText = true;
};
inline bool operator==(const CompletionSettings &t1, const CompletionSettings &t2) { return t1.equals(t2); }
diff --git a/src/plugins/texteditor/completionsettingspage.cpp b/src/plugins/texteditor/completionsettingspage.cpp
index fce419b422d..1c5d4e2ddea 100644
--- a/src/plugins/texteditor/completionsettingspage.cpp
+++ b/src/plugins/texteditor/completionsettingspage.cpp
@@ -104,12 +104,14 @@ QWidget *CompletionSettingsPage::widget()
m_page->autoSplitStrings->setChecked(m_completionSettings.m_autoSplitStrings);
m_page->animateAutoComplete->setChecked(m_completionSettings.m_animateAutoComplete);
m_page->highlightAutoComplete->setChecked(m_completionSettings.m_highlightAutoComplete);
+ m_page->skipAutoComplete->setChecked(m_completionSettings.m_skipAutoCompletedText);
m_page->enableDoxygenCheckBox->setChecked(m_commentsSettings.m_enableDoxygen);
m_page->generateBriefCheckBox->setChecked(m_commentsSettings.m_generateBrief);
m_page->leadingAsterisksCheckBox->setChecked(m_commentsSettings.m_leadingAsterisks);
m_page->generateBriefCheckBox->setEnabled(m_page->enableDoxygenCheckBox->isChecked());
+ m_page->skipAutoComplete->setEnabled(m_page->highlightAutoComplete->isChecked());
}
return m_widget;
}
@@ -179,6 +181,7 @@ void CompletionSettingsPage::settingsFromUi(CompletionSettings &completion, Comm
completion.m_autoSplitStrings = m_page->autoSplitStrings->isChecked();
completion.m_animateAutoComplete = m_page->animateAutoComplete->isChecked();
completion.m_highlightAutoComplete = m_page->highlightAutoComplete->isChecked();
+ completion.m_skipAutoCompletedText = m_page->skipAutoComplete->isChecked();
comment.m_enableDoxygen = m_page->enableDoxygenCheckBox->isChecked();
comment.m_generateBrief = m_page->generateBriefCheckBox->isChecked();
diff --git a/src/plugins/texteditor/completionsettingspage.ui b/src/plugins/texteditor/completionsettingspage.ui
index 23e61d22be4..b5bf12a0a0e 100644
--- a/src/plugins/texteditor/completionsettingspage.ui
+++ b/src/plugins/texteditor/completionsettingspage.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>511</width>
- <height>437</height>
+ <width>551</width>
+ <height>465</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
@@ -227,13 +227,49 @@ In addition, Shift+Enter inserts an escape character at the cursor position and
</property>
</widget>
</item>
- <item row="3" column="1">
+ <item row="3" column="0">
<widget class="QCheckBox" name="highlightAutoComplete">
<property name="text">
<string>Highlight automatically inserted text</string>
</property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
</widget>
</item>
+ <item row="4" column="0">
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <spacer name="horizontalSpacer_6">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>30</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="skipAutoComplete">
+ <property name="toolTip">
+ <string>Skip automatically inserted character if re-typed manually after completion.</string>
+ </property>
+ <property name="text">
+ <string>Skip automatically inserted character when typing</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
</layout>
</widget>
</item>
@@ -254,7 +290,7 @@ In addition, Shift+Enter inserts an escape character at the cursor position and
</widget>
</item>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
@@ -324,6 +360,7 @@ In addition, Shift+Enter inserts an escape character at the cursor position and
<tabstop>spaceAfterFunctionName</tabstop>
<tabstop>animateAutoComplete</tabstop>
<tabstop>highlightAutoComplete</tabstop>
+ <tabstop>skipAutoComplete</tabstop>
<tabstop>enableDoxygenCheckBox</tabstop>
<tabstop>generateBriefCheckBox</tabstop>
<tabstop>leadingAsterisksCheckBox</tabstop>
@@ -337,12 +374,28 @@ In addition, Shift+Enter inserts an escape character at the cursor position and
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
- <x>174</x>
- <y>294</y>
+ <x>195</x>
+ <y>383</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>320</x>
+ <y>410</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>highlightAutoComplete</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>skipAutoComplete</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>176</x>
+ <y>277</y>
</hint>
<hint type="destinationlabel">
- <x>262</x>
- <y>321</y>
+ <x>186</x>
+ <y>306</y>
</hint>
</hints>
</connection>
diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp
index a4929cb986d..5f0ecb647b3 100644
--- a/src/plugins/texteditor/texteditor.cpp
+++ b/src/plugins/texteditor/texteditor.cpp
@@ -455,6 +455,7 @@ public:
QPointer<TextEditorAnimator> m_autocompleteAnimator;
bool m_animateAutoComplete = true;
bool m_highlightAutoComplete = true;
+ bool m_skipAutoCompletedText = true;
bool m_keepAutoCompletionHighlight = false;
QTextCursor m_autoCompleteHighlightPos;
@@ -2392,8 +2393,11 @@ void TextEditorWidget::keyPressEvent(QKeyEvent *e)
// only go here if control is not pressed, except if also alt is pressed
// because AltGr maps to Alt + Ctrl
QTextCursor cursor = textCursor();
- const QString &autoText = inOverwriteMode
- ? QString() : autoCompleter()->autoComplete(cursor, eventText);
+ QString autoText;
+ if (!inOverwriteMode) {
+ autoText = autoCompleter()->autoComplete(cursor, eventText,
+ d->m_skipAutoCompletedText && cursor == d->m_autoCompleteHighlightPos);
+ }
const bool cursorWithinSnippet = d->snippetCheckCursor(cursor);
QChar electricChar;
@@ -6566,6 +6570,7 @@ void TextEditorWidget::setCompletionSettings(const CompletionSettings &completio
d->m_autoCompleter->setSurroundWithQuotesEnabled(completionSettings.m_surroundingAutoQuotes);
d->m_animateAutoComplete = completionSettings.m_animateAutoComplete;
d->m_highlightAutoComplete = completionSettings.m_highlightAutoComplete;
+ d->m_skipAutoCompletedText = completionSettings.m_skipAutoCompletedText;
}
void TextEditorWidget::setExtraEncodingSettings(const ExtraEncodingSettings &extraEncodingSettings)
@@ -7032,6 +7037,13 @@ void TextEditorWidget::keepAutoCompletionHighlight(bool keepHighlight)
d->m_keepAutoCompletionHighlight = keepHighlight;
}
+void TextEditorWidget::setAutoCompleteSkipPosition(const QTextCursor &cursor)
+{
+ QTextCursor tc = cursor;
+ tc.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
+ d->autocompleterHighlight(tc);
+}
+
int BaseTextEditor::currentLine() const
{
return editorWidget()->textCursor().blockNumber() + 1;
diff --git a/src/plugins/texteditor/texteditor.h b/src/plugins/texteditor/texteditor.h
index 87182f18cf3..3f70117f2e5 100644
--- a/src/plugins/texteditor/texteditor.h
+++ b/src/plugins/texteditor/texteditor.h
@@ -326,6 +326,7 @@ public:
// keep the auto completion even if the focus is lost
void keepAutoCompletionHighlight(bool keepHighlight);
+ void setAutoCompleteSkipPosition(const QTextCursor &cursor);
virtual void copy();
virtual void paste();