diff --git a/src/plugins/clangcodemodel/clangassistproposalitem.cpp b/src/plugins/clangcodemodel/clangassistproposalitem.cpp index 012ac9af5e1..75dc40c6710 100644 --- a/src/plugins/clangcodemodel/clangassistproposalitem.cpp +++ b/src/plugins/clangcodemodel/clangassistproposalitem.cpp @@ -76,6 +76,7 @@ void ClangAssistProposalItem::apply(TextEditor::TextDocumentManipulatorInterface int extraLength = 0; int cursorOffset = 0; bool setAutoCompleteSkipPos = false; + int currentPosition = manipulator.currentPosition(); bool autoParenthesesEnabled = true; if (m_completionOperator == T_SIGNAL || m_completionOperator == T_SLOT) { @@ -124,7 +125,7 @@ void ClangAssistProposalItem::apply(TextEditor::TextDocumentManipulatorInterface // If the function doesn't return anything, automatically place the semicolon, // unless we're doing a scope completion (then it might be function definition). - const QChar characterAtCursor = manipulator.characterAt(manipulator.currentPosition()); + const QChar characterAtCursor = manipulator.characterAt(currentPosition); bool endWithSemicolon = m_typedCharacter == QLatin1Char(';')/* || (function->returnType()->isVoidType() && m_completionOperator != T_COLON_COLON)*/; //### const QChar semicolon = m_typedCharacter.isNull() ? QLatin1Char(';') : m_typedCharacter; @@ -181,7 +182,13 @@ void ClangAssistProposalItem::apply(TextEditor::TextDocumentManipulatorInterface // Avoid inserting characters that are already there QTextCursor cursor = manipulator.textCursorAt(basePosition); cursor.movePosition(QTextCursor::EndOfWord); - const int currentPosition = cursor.position(); + const QString textAfterCursor = manipulator.textAt(currentPosition, + cursor.position() - currentPosition); + + if (textToBeInserted != textAfterCursor + && textToBeInserted.indexOf(textAfterCursor, currentPosition - basePosition) >= 0) { + currentPosition = cursor.position(); + } for (int i = 0; i < extraCharacters.length(); ++i) { const QChar a = extraCharacters.at(i); diff --git a/src/plugins/cpptools/cppcompletionassist.cpp b/src/plugins/cpptools/cppcompletionassist.cpp index 0a31d52b848..26b139e6478 100644 --- a/src/plugins/cpptools/cppcompletionassist.cpp +++ b/src/plugins/cpptools/cppcompletionassist.cpp @@ -309,28 +309,20 @@ void CppAssistProposalItem::applyContextualContent(TextDocumentManipulatorInterf --cursorOffset; } - // Determine the length of characters that should just be kept on the editor, but do - // not consider content that ends as an identifier (which could be undesired). - const int lineEnd = manipulator.positionAt(EndOfLinePosition); - const QString inEditor = manipulator.textAt(manipulator.currentPosition(), - lineEnd - manipulator.currentPosition()); - int preserveLength = 0; - if (!inEditor.isEmpty()) { - preserveLength = toInsert.length() - (manipulator.currentPosition() - basePosition); - const int inEditorLength = inEditor.length(); - while (preserveLength > 0) { - if (inEditor.startsWith(toInsert.right(preserveLength)) - && (inEditorLength == preserveLength - || !CppTools::isValidIdentifierChar(inEditor.at(preserveLength)))) { - break; - } - --preserveLength; - } + // Avoid inserting characters that are already there + int currentPosition = manipulator.currentPosition(); + QTextCursor cursor = manipulator.textCursorAt(basePosition); + cursor.movePosition(QTextCursor::EndOfWord); + const QString textAfterCursor = manipulator.textAt(currentPosition, + cursor.position() - currentPosition); + if (toInsert != textAfterCursor + && toInsert.indexOf(textAfterCursor, currentPosition - basePosition) >= 0) { + currentPosition = cursor.position(); } for (int i = 0; i < extraChars.length(); ++i) { const QChar a = extraChars.at(i); - const QChar b = manipulator.characterAt(manipulator.currentPosition() + i + preserveLength); + const QChar b = manipulator.characterAt(currentPosition + i); if (a == b) ++extraLength; else @@ -340,8 +332,9 @@ void CppAssistProposalItem::applyContextualContent(TextDocumentManipulatorInterf toInsert += extraChars; // Insert the remainder of the name - const int length = manipulator.currentPosition() - basePosition + preserveLength + extraLength; + const int length = currentPosition - basePosition + extraLength; manipulator.replace(basePosition, length, toInsert); + manipulator.setCursorPosition(basePosition + toInsert.length()); if (cursorOffset) manipulator.setCursorPosition(manipulator.currentPosition() + cursorOffset); if (setAutoCompleteSkipPos) diff --git a/src/plugins/texteditor/codeassist/codeassistant.cpp b/src/plugins/texteditor/codeassist/codeassistant.cpp index caff27918df..0622f29f10d 100644 --- a/src/plugins/texteditor/codeassist/codeassistant.cpp +++ b/src/plugins/texteditor/codeassist/codeassistant.cpp @@ -365,8 +365,21 @@ void CodeAssistantPrivate::handlePrefixExpansion(const QString &newPrefix) cursor.setPosition(m_proposal->basePosition()); cursor.movePosition(QTextCursor::EndOfWord); + int currentPosition = m_editorWidget->position(); + const QString textAfterCursor = m_editorWidget->textAt(currentPosition, + cursor.position() - currentPosition); + if (!textAfterCursor.startsWith(newPrefix)) { + if (newPrefix.indexOf(textAfterCursor, currentPosition - m_proposal->basePosition()) >= 0) + currentPosition = cursor.position(); + const QStringRef prefixAddition = + newPrefix.midRef(currentPosition - m_proposal->basePosition()); + // If remaining string starts with the prefix addition + if (textAfterCursor.startsWith(prefixAddition)) + currentPosition += prefixAddition.size(); + } + m_editorWidget->setCursorPosition(m_proposal->basePosition()); - m_editorWidget->replace(cursor.position() - m_proposal->basePosition(), newPrefix); + m_editorWidget->replace(currentPosition - m_proposal->basePosition(), newPrefix); notifyChange(); }