forked from qt-creator/qt-creator
FakeVim: Improve handling of content changes
..when indenter or auto completer may interfere. Task-number: QTCREATORBUG-26195 Change-Id: Iaf0eefd74344423409fa0c22f8e3ea618b4c9930 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -8261,7 +8261,8 @@ void FakeVimHandler::Private::onContentsChanged(int position, int charsRemoved,
|
||||
g.dotCommand = "i";
|
||||
resetCount();
|
||||
}
|
||||
|
||||
int indentation = 0;
|
||||
bool changedAtEnd = false;
|
||||
// Ignore changes outside inserted text (e.g. renaming other occurrences of a variable).
|
||||
if (position + charsRemoved >= insertState.pos1 && position <= insertState.pos2) {
|
||||
if (charsRemoved > 0) {
|
||||
@@ -8280,17 +8281,39 @@ void FakeVimHandler::Private::onContentsChanged(int position, int charsRemoved,
|
||||
if (position < insertState.pos1) {
|
||||
// <BACKSPACE>
|
||||
const int backspaceCount = insertState.pos1 - position;
|
||||
if (backspaceCount != charsRemoved || (oldPosition == charsRemoved && wholeDocumentChanged)) {
|
||||
const QString inserted = textAt(position, position + charsAdded);
|
||||
const QString unified = inserted.startsWith('\n') ? inserted.mid(1) : inserted;
|
||||
changedAtEnd = unified.startsWith(insertState.textBeforeCursor);
|
||||
|
||||
int indentNew = 0;
|
||||
for (int i = 0, end = unified.size(); i < end; ++i) {
|
||||
if (unified.at(i) != ' ')
|
||||
break;
|
||||
++indentNew;
|
||||
}
|
||||
int indentOld = 0;
|
||||
for (int i = 0, end = insertState.textBeforeCursor.size(); i < end; ++i) {
|
||||
if (insertState.textBeforeCursor.at(i) != ' ')
|
||||
break;
|
||||
--indentOld;
|
||||
}
|
||||
indentation = indentNew + indentOld;
|
||||
|
||||
if ((backspaceCount != charsRemoved && indentation == 0 && !changedAtEnd)
|
||||
|| (oldPosition == charsRemoved && wholeDocumentChanged)) {
|
||||
invalidateInsertState();
|
||||
} else {
|
||||
const QString inserted = textAt(position, oldPosition);
|
||||
const QString removed = insertState.textBeforeCursor.right(backspaceCount);
|
||||
// Ignore backspaces if same text was just inserted.
|
||||
if ( !inserted.endsWith(removed) ) {
|
||||
const QString removed = insertState.textBeforeCursor.right(
|
||||
qMax(backspaceCount, charsRemoved));
|
||||
if (indentation != 0 || changedAtEnd) {
|
||||
// automatic indent by electric chars / skipping of automatic inserted
|
||||
insertState.pos1 = position + backspaceCount + indentation;
|
||||
insertState.pos2 = position + charsAdded;
|
||||
} else if ( !inserted.endsWith(removed) ) {
|
||||
insertState.backspaces += backspaceCount;
|
||||
insertState.pos1 = position;
|
||||
insertState.pos2 = qMax(position, insertState.pos2 - backspaceCount);
|
||||
}
|
||||
} // Ignore backspaces if same text was just inserted.
|
||||
}
|
||||
} else if (position + charsRemoved > insertState.pos2) {
|
||||
// <DELETE>
|
||||
@@ -8309,6 +8332,7 @@ void FakeVimHandler::Private::onContentsChanged(int position, int charsRemoved,
|
||||
}
|
||||
|
||||
const int newPosition = position + charsAdded;
|
||||
if (indentation == 0 && !changedAtEnd) // (un)indented has pos2 set correctly already
|
||||
insertState.pos2 = qMax(insertState.pos2 + charsAdded - charsRemoved, newPosition);
|
||||
insertState.textBeforeCursor = textAt(block().position(), newPosition);
|
||||
}
|
||||
|
Reference in New Issue
Block a user