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 @@ 0 0 - 511 - 437 + 551 + 465 @@ -227,13 +227,49 @@ In addition, Shift+Enter inserts an escape character at the cursor position and - + Highlight automatically inserted text + + true + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 30 + 20 + + + + + + + + Skip automatically inserted character if re-typed manually after completion. + + + Skip automatically inserted character when typing + + + true + + + + + @@ -254,7 +290,7 @@ In addition, Shift+Enter inserts an escape character at the cursor position and - + @@ -324,6 +360,7 @@ In addition, Shift+Enter inserts an escape character at the cursor position and spaceAfterFunctionName animateAutoComplete highlightAutoComplete + skipAutoComplete enableDoxygenCheckBox generateBriefCheckBox leadingAsterisksCheckBox @@ -337,12 +374,28 @@ In addition, Shift+Enter inserts an escape character at the cursor position and setEnabled(bool) - 174 - 294 + 195 + 383 - 262 - 321 + 320 + 410 + + + + + highlightAutoComplete + toggled(bool) + skipAutoComplete + setEnabled(bool) + + + 176 + 277 + + + 186 + 306 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 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();