forked from qt-creator/qt-creator
FakeVim: Use QTextDocument::revision() for undo/redo
Using QTextDocument::availableUndoSteps() to get revision of document is very bad because it undo/redo stack starts to break when maximal number of undo is reached. On the other hand QTextDocument::revision() number is always increased, even on QTextDocument::redo(), so external undo/redo can still break undo/redo commands in FakeVim. Change-Id: If1698df8f43a878295eebddd59aebe304cdf3081 Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
@@ -288,14 +288,16 @@ typedef QHashIterator<QChar, Mark> MarksIterator;
|
|||||||
|
|
||||||
struct State
|
struct State
|
||||||
{
|
{
|
||||||
State() : revision(-1), position(), marks(), lastVisualMode(NoVisualMode),
|
State() : revisions(0), position(), marks(), lastVisualMode(NoVisualMode),
|
||||||
lastVisualModeInverted(false) {}
|
lastVisualModeInverted(false) {}
|
||||||
State(int revision, const CursorPosition &position, const Marks &marks,
|
State(const CursorPosition &position, const Marks &marks,
|
||||||
VisualMode lastVisualMode, bool lastVisualModeInverted) : revision(revision),
|
VisualMode lastVisualMode, bool lastVisualModeInverted) : revisions(0),
|
||||||
position(position), marks(marks), lastVisualMode(lastVisualMode),
|
position(position), marks(marks), lastVisualMode(lastVisualMode),
|
||||||
lastVisualModeInverted(lastVisualModeInverted) {}
|
lastVisualModeInverted(lastVisualModeInverted) {}
|
||||||
|
|
||||||
int revision;
|
bool isValid() const { return position.isValid(); }
|
||||||
|
|
||||||
|
int revisions;
|
||||||
CursorPosition position;
|
CursorPosition position;
|
||||||
Marks marks;
|
Marks marks;
|
||||||
VisualMode lastVisualMode;
|
VisualMode lastVisualMode;
|
||||||
@@ -1661,13 +1663,16 @@ public:
|
|||||||
{ return document()->characterAt(position()); }
|
{ return document()->characterAt(position()); }
|
||||||
|
|
||||||
int m_editBlockLevel; // current level of edit blocks
|
int m_editBlockLevel; // current level of edit blocks
|
||||||
int m_largeEditBlockRevision; // current level of large edit block
|
|
||||||
void joinPreviousEditBlock();
|
void joinPreviousEditBlock();
|
||||||
void beginEditBlock(bool largeEditBlock = false);
|
void beginEditBlock(bool largeEditBlock = false);
|
||||||
void beginLargeEditBlock() { beginEditBlock(true); }
|
void beginLargeEditBlock() { beginEditBlock(true); }
|
||||||
void endEditBlock();
|
void endEditBlock();
|
||||||
void breakEditBlock() { m_breakEditBlock = true; }
|
void breakEditBlock() { m_breakEditBlock = true; }
|
||||||
|
|
||||||
Q_SLOT void onContentsChanged();
|
Q_SLOT void onContentsChanged();
|
||||||
|
Q_SLOT void onUndoCommandAdded();
|
||||||
|
|
||||||
|
bool isInsertMode() const { return m_mode == InsertMode || m_mode == ReplaceMode; }
|
||||||
|
|
||||||
bool isVisualMode() const { return m_visualMode != NoVisualMode; }
|
bool isVisualMode() const { return m_visualMode != NoVisualMode; }
|
||||||
bool isNoVisualMode() const { return m_visualMode == NoVisualMode; }
|
bool isNoVisualMode() const { return m_visualMode == NoVisualMode; }
|
||||||
@@ -1787,8 +1792,7 @@ public:
|
|||||||
QString guessInsertCommand(int pos1, int pos2, int len1, int len2);
|
QString guessInsertCommand(int pos1, int pos2, int len1, int len2);
|
||||||
|
|
||||||
// undo handling
|
// undo handling
|
||||||
int revision() const { return document()->availableUndoSteps(); }
|
int revision() const { return document()->revision(); }
|
||||||
int lastUndoRevision() const { return m_undo.empty() ? -1 : m_undo.top().revision; }
|
|
||||||
void undoRedo(bool undo);
|
void undoRedo(bool undo);
|
||||||
void undo();
|
void undo();
|
||||||
void redo();
|
void redo();
|
||||||
@@ -1796,6 +1800,7 @@ public:
|
|||||||
// revision -> state
|
// revision -> state
|
||||||
QStack<State> m_undo;
|
QStack<State> m_undo;
|
||||||
QStack<State> m_redo;
|
QStack<State> m_redo;
|
||||||
|
State m_undoState;
|
||||||
|
|
||||||
// extra data for '.'
|
// extra data for '.'
|
||||||
void replay(const QString &text);
|
void replay(const QString &text);
|
||||||
@@ -1956,8 +1961,10 @@ FakeVimHandler::Private::Private(FakeVimHandler *parent, QWidget *widget)
|
|||||||
q = parent;
|
q = parent;
|
||||||
m_textedit = qobject_cast<QTextEdit *>(widget);
|
m_textedit = qobject_cast<QTextEdit *>(widget);
|
||||||
m_plaintextedit = qobject_cast<QPlainTextEdit *>(widget);
|
m_plaintextedit = qobject_cast<QPlainTextEdit *>(widget);
|
||||||
if (editor())
|
if (editor()) {
|
||||||
connect(EDITOR(document()), SIGNAL(contentsChanged()), SLOT(onContentsChanged()));
|
connect(EDITOR(document()), SIGNAL(contentsChanged()), SLOT(onContentsChanged()));
|
||||||
|
connect(EDITOR(document()), SIGNAL(undoCommandAdded()), SLOT(onUndoCommandAdded()));
|
||||||
|
}
|
||||||
//new Highlighter(document(), &pythonRules);
|
//new Highlighter(document(), &pythonRules);
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
@@ -1996,7 +2003,6 @@ void FakeVimHandler::Private::init()
|
|||||||
m_searchStartPosition = 0;
|
m_searchStartPosition = 0;
|
||||||
m_searchFromScreenLine = 0;
|
m_searchFromScreenLine = 0;
|
||||||
m_editBlockLevel = 0;
|
m_editBlockLevel = 0;
|
||||||
m_largeEditBlockRevision = -1;
|
|
||||||
|
|
||||||
setupCharClass();
|
setupCharClass();
|
||||||
}
|
}
|
||||||
@@ -2024,7 +2030,7 @@ void FakeVimHandler::Private::enterFakeVim()
|
|||||||
if (m_oldPosition != -1 && lineForPosition(m_oldPosition) != lineForPosition(tc.position()))
|
if (m_oldPosition != -1 && lineForPosition(m_oldPosition) != lineForPosition(tc.position()))
|
||||||
recordJump(m_oldPosition);
|
recordJump(m_oldPosition);
|
||||||
setTargetColumn();
|
setTargetColumn();
|
||||||
if (atEndOfLine() && !isVisualMode() && m_mode != InsertMode && m_mode != ReplaceMode)
|
if (atEndOfLine() && !isVisualMode() && !isInsertMode())
|
||||||
moveLeft();
|
moveLeft();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2189,8 +2195,11 @@ void FakeVimHandler::Private::setupWidget()
|
|||||||
|
|
||||||
recordJump();
|
recordJump();
|
||||||
setTargetColumn();
|
setTargetColumn();
|
||||||
if (atEndOfLine() && !isVisualMode() && m_mode != InsertMode && m_mode != ReplaceMode)
|
if (atEndOfLine() && !isVisualMode() && !isInsertMode())
|
||||||
moveLeft();
|
moveLeft();
|
||||||
|
|
||||||
|
m_oldExternalAnchor = anchor();
|
||||||
|
m_oldExternalPosition = position();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeVimHandler::Private::exportSelection()
|
void FakeVimHandler::Private::exportSelection()
|
||||||
@@ -2651,25 +2660,14 @@ bool FakeVimHandler::Private::isFirstNonBlankOnLine(int pos)
|
|||||||
|
|
||||||
void FakeVimHandler::Private::pushUndoState(bool overwrite)
|
void FakeVimHandler::Private::pushUndoState(bool overwrite)
|
||||||
{
|
{
|
||||||
if (m_editBlockLevel != 0 && m_largeEditBlockRevision == -1)
|
if (m_editBlockLevel != 0 && m_undoState.isValid())
|
||||||
return; // No need to save undo state for inner edit blocks.
|
return; // No need to save undo state for inner edit blocks.
|
||||||
|
|
||||||
// Use revision of large edit block if started.
|
if (m_undoState.isValid() && !overwrite)
|
||||||
int rev;
|
|
||||||
if (m_largeEditBlockRevision != -1) {
|
|
||||||
rev = m_largeEditBlockRevision;
|
|
||||||
m_largeEditBlockRevision = -1;
|
|
||||||
} else {
|
|
||||||
rev = revision();
|
|
||||||
if (!overwrite && lastUndoRevision() == rev)
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
while (lastUndoRevision() == rev)
|
|
||||||
m_undo.pop();
|
|
||||||
|
|
||||||
int pos = position();
|
int pos = position();
|
||||||
if (m_mode != InsertMode && m_mode != ReplaceMode) {
|
if (!isInsertMode()) {
|
||||||
if (isVisualMode() || m_submode == DeleteSubMode) {
|
if (isVisualMode() || m_submode == DeleteSubMode) {
|
||||||
pos = qMin(pos, anchor());
|
pos = qMin(pos, anchor());
|
||||||
if (isVisualLineMode())
|
if (isVisualLineMode())
|
||||||
@@ -2692,8 +2690,8 @@ void FakeVimHandler::Private::pushUndoState(bool overwrite)
|
|||||||
setMark(QLatin1Char('<'), mark(QLatin1Char('<')).position);
|
setMark(QLatin1Char('<'), mark(QLatin1Char('<')).position);
|
||||||
setMark(QLatin1Char('>'), mark(QLatin1Char('>')).position);
|
setMark(QLatin1Char('>'), mark(QLatin1Char('>')).position);
|
||||||
}
|
}
|
||||||
m_undo.push(
|
m_undoState = State(m_lastChangePosition, m_marks, m_lastVisualMode,
|
||||||
State(rev, m_lastChangePosition, m_marks, m_lastVisualMode, m_lastVisualModeInverted));
|
m_lastVisualModeInverted);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeVimHandler::Private::moveDown(int n)
|
void FakeVimHandler::Private::moveDown(int n)
|
||||||
@@ -2872,9 +2870,6 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement)
|
|||||||
|| m_submode == InvertCaseSubMode
|
|| m_submode == InvertCaseSubMode
|
||||||
|| m_submode == DownCaseSubMode
|
|| m_submode == DownCaseSubMode
|
||||||
|| m_submode == UpCaseSubMode) {
|
|| m_submode == UpCaseSubMode) {
|
||||||
if (m_submode != YankSubMode)
|
|
||||||
beginEditBlock();
|
|
||||||
|
|
||||||
fixSelection();
|
fixSelection();
|
||||||
|
|
||||||
if (m_submode != InvertCaseSubMode
|
if (m_submode != InvertCaseSubMode
|
||||||
@@ -2890,8 +2885,8 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement)
|
|||||||
|
|
||||||
QString dotCommand;
|
QString dotCommand;
|
||||||
if (m_submode == ChangeSubMode) {
|
if (m_submode == ChangeSubMode) {
|
||||||
if (m_rangemode != RangeLineModeExclusive)
|
|
||||||
pushUndoState();
|
pushUndoState();
|
||||||
|
beginEditBlock();
|
||||||
removeText(currentRange());
|
removeText(currentRange());
|
||||||
dotCommand = _("c");
|
dotCommand = _("c");
|
||||||
if (m_movetype == MoveLineWise)
|
if (m_movetype == MoveLineWise)
|
||||||
@@ -2902,6 +2897,7 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement)
|
|||||||
g.returnToMode = InsertMode;
|
g.returnToMode = InsertMode;
|
||||||
} else if (m_submode == DeleteSubMode) {
|
} else if (m_submode == DeleteSubMode) {
|
||||||
pushUndoState();
|
pushUndoState();
|
||||||
|
beginEditBlock();
|
||||||
const int pos = position();
|
const int pos = position();
|
||||||
// Always delete something (e.g. 'dw' on an empty line deletes the line).
|
// Always delete something (e.g. 'dw' on an empty line deletes the line).
|
||||||
if (pos == anchor() && m_movetype == MoveInclusive)
|
if (pos == anchor() && m_movetype == MoveInclusive)
|
||||||
@@ -2935,6 +2931,7 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement)
|
|||||||
} else if (m_submode == InvertCaseSubMode
|
} else if (m_submode == InvertCaseSubMode
|
||||||
|| m_submode == UpCaseSubMode
|
|| m_submode == UpCaseSubMode
|
||||||
|| m_submode == DownCaseSubMode) {
|
|| m_submode == DownCaseSubMode) {
|
||||||
|
beginEditBlock();
|
||||||
if (m_submode == InvertCaseSubMode) {
|
if (m_submode == InvertCaseSubMode) {
|
||||||
invertCase(currentRange());
|
invertCase(currentRange());
|
||||||
dotCommand = QString::fromLatin1("g~");
|
dotCommand = QString::fromLatin1("g~");
|
||||||
@@ -3681,11 +3678,9 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input)
|
|||||||
moveRight();
|
moveRight();
|
||||||
breakEditBlock();
|
breakEditBlock();
|
||||||
enterInsertMode();
|
enterInsertMode();
|
||||||
pushUndoState();
|
|
||||||
} else if (input.is('A')) {
|
} else if (input.is('A')) {
|
||||||
breakEditBlock();
|
breakEditBlock();
|
||||||
moveBehindEndOfLine();
|
moveBehindEndOfLine();
|
||||||
pushUndoState();
|
|
||||||
setAnchor();
|
setAnchor();
|
||||||
enterInsertMode();
|
enterInsertMode();
|
||||||
setTargetColumn();
|
setTargetColumn();
|
||||||
@@ -5007,8 +5002,7 @@ bool FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (lastBlock.isValid()) {
|
if (lastBlock.isValid()) {
|
||||||
State &state = m_undo.top();
|
m_undoState.position = CursorPosition(firstBlock.blockNumber(), 0);
|
||||||
state.position = CursorPosition(firstBlock.blockNumber(), 0);
|
|
||||||
|
|
||||||
leaveVisualMode();
|
leaveVisualMode();
|
||||||
setPosition(lastBlock.position());
|
setPosition(lastBlock.position());
|
||||||
@@ -6362,7 +6356,7 @@ void FakeVimHandler::Private::setCursorPosition(QTextCursor *tc, const CursorPos
|
|||||||
int FakeVimHandler::Private::lastPositionInDocument(bool ignoreMode) const
|
int FakeVimHandler::Private::lastPositionInDocument(bool ignoreMode) const
|
||||||
{
|
{
|
||||||
return document()->characterCount()
|
return document()->characterCount()
|
||||||
- (ignoreMode || isVisualMode() || m_mode == InsertMode || m_mode == ReplaceMode ? 1 : 2);
|
- (ignoreMode || isVisualMode() || isInsertMode() ? 1 : 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString FakeVimHandler::Private::selectText(const Range &range) const
|
QString FakeVimHandler::Private::selectText(const Range &range) const
|
||||||
@@ -6974,7 +6968,7 @@ int FakeVimHandler::Private::lastPositionInLine(int line, bool onlyVisibleLines)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const int position = block.position() + block.length() - 1;
|
const int position = block.position() + block.length() - 1;
|
||||||
if (block.length() > 1 && !isVisualMode() && m_mode != InsertMode && m_mode != ReplaceMode)
|
if (block.length() > 1 && !isVisualMode() && !isInsertMode())
|
||||||
return position - 1;
|
return position - 1;
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
@@ -7033,7 +7027,7 @@ QWidget *FakeVimHandler::Private::editor() const
|
|||||||
void FakeVimHandler::Private::joinPreviousEditBlock()
|
void FakeVimHandler::Private::joinPreviousEditBlock()
|
||||||
{
|
{
|
||||||
UNDO_DEBUG("JOIN");
|
UNDO_DEBUG("JOIN");
|
||||||
if (m_breakEditBlock) {
|
if (m_breakEditBlock && m_editBlockLevel == 0) {
|
||||||
beginEditBlock();
|
beginEditBlock();
|
||||||
QTextCursor tc(cursor());
|
QTextCursor tc(cursor());
|
||||||
tc.setPosition(tc.position());
|
tc.setPosition(tc.position());
|
||||||
@@ -7042,9 +7036,9 @@ void FakeVimHandler::Private::joinPreviousEditBlock()
|
|||||||
tc.deletePreviousChar();
|
tc.deletePreviousChar();
|
||||||
tc.endEditBlock();
|
tc.endEditBlock();
|
||||||
} else {
|
} else {
|
||||||
if (m_editBlockLevel == 0)
|
if (m_editBlockLevel == 0 && !m_undo.empty())
|
||||||
m_cursor = cursor();
|
m_undoState = m_undo.pop();
|
||||||
++m_editBlockLevel;
|
beginEditBlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7054,12 +7048,8 @@ void FakeVimHandler::Private::beginEditBlock(bool largeEditBlock)
|
|||||||
if (m_editBlockLevel == 0)
|
if (m_editBlockLevel == 0)
|
||||||
m_cursor = cursor();
|
m_cursor = cursor();
|
||||||
|
|
||||||
if (m_editBlockLevel == 0 || m_largeEditBlockRevision != -1) {
|
if (!largeEditBlock && !m_undoState.isValid())
|
||||||
if (largeEditBlock)
|
|
||||||
m_largeEditBlockRevision = revision();
|
|
||||||
else
|
|
||||||
pushUndoState(false);
|
pushUndoState(false);
|
||||||
}
|
|
||||||
++m_editBlockLevel;
|
++m_editBlockLevel;
|
||||||
m_breakEditBlock = false;
|
m_breakEditBlock = false;
|
||||||
}
|
}
|
||||||
@@ -7070,30 +7060,32 @@ void FakeVimHandler::Private::endEditBlock()
|
|||||||
QTC_ASSERT(m_editBlockLevel > 0,
|
QTC_ASSERT(m_editBlockLevel > 0,
|
||||||
qDebug() << "beginEditBlock() not called before endEditBlock()!"; return);
|
qDebug() << "beginEditBlock() not called before endEditBlock()!"; return);
|
||||||
--m_editBlockLevel;
|
--m_editBlockLevel;
|
||||||
if (m_editBlockLevel == 0)
|
if (m_editBlockLevel == 0) {
|
||||||
setCursor(m_cursor);
|
setCursor(m_cursor);
|
||||||
if (m_largeEditBlockRevision != -1)
|
if (m_undoState.isValid()) {
|
||||||
m_largeEditBlockRevision = -1;
|
if (m_undoState.revisions > 0) {
|
||||||
|
m_undo.push(m_undoState);
|
||||||
|
m_undoState = State();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeVimHandler::Private::onContentsChanged()
|
void FakeVimHandler::Private::onContentsChanged()
|
||||||
{
|
{
|
||||||
if (!document()->isUndoAvailable())
|
if (!document()->isUndoAvailable())
|
||||||
m_undo.clear();
|
m_undo.clear();
|
||||||
|
else if (m_editBlockLevel == 0 && !m_undo.isEmpty() && !isInsertMode())
|
||||||
|
m_undo.push(State()); // Save undo state for external change.
|
||||||
|
}
|
||||||
|
|
||||||
const int rev = revision();
|
void FakeVimHandler::Private::onUndoCommandAdded()
|
||||||
if (lastUndoRevision() > rev) {
|
{
|
||||||
m_redo.clear();
|
m_redo.clear();
|
||||||
while (lastUndoRevision() > rev)
|
if (m_editBlockLevel == 0 && !m_undo.isEmpty() && isInsertMode())
|
||||||
m_undo.pop();
|
++m_undo.top().revisions;
|
||||||
} else {
|
else
|
||||||
while (!m_redo.empty() && m_redo.top().revision < rev)
|
++m_undoState.revisions;
|
||||||
m_redo.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
// External change.
|
|
||||||
if (m_editBlockLevel == 0 && document()->isUndoAvailable())
|
|
||||||
pushUndoState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char FakeVimHandler::Private::currentModeCode() const
|
char FakeVimHandler::Private::currentModeCode() const
|
||||||
@@ -7118,44 +7110,39 @@ void FakeVimHandler::Private::undoRedo(bool undo)
|
|||||||
QStack<State> &stack = undo ? m_undo : m_redo;
|
QStack<State> &stack = undo ? m_undo : m_redo;
|
||||||
QStack<State> &stack2 = undo ? m_redo : m_undo;
|
QStack<State> &stack2 = undo ? m_redo : m_undo;
|
||||||
|
|
||||||
bool validState = !stack.empty();
|
State state = !stack.empty() ? stack.pop() : State();
|
||||||
State state = validState ? stack.pop() : State();
|
|
||||||
|
|
||||||
++m_editBlockLevel;
|
|
||||||
const int firstLine = firstVisibleLine();
|
const int firstLine = firstVisibleLine();
|
||||||
|
|
||||||
CursorPosition lastPos(cursor());
|
CursorPosition lastPos(cursor());
|
||||||
const int current = revision();
|
const int current = revision();
|
||||||
const int prevRev = validState ? state.revision : current;
|
|
||||||
int rev = current;
|
++m_editBlockLevel;
|
||||||
int last;
|
|
||||||
if (undo) {
|
// Do undo/redo [count] times to reach previous revision.
|
||||||
do {
|
int count = m_undoState.isValid() ? m_undoState.revisions
|
||||||
last = rev;
|
: state.isValid() ? state.revisions : 1;
|
||||||
|
while (count-- > 0) {
|
||||||
|
if (undo)
|
||||||
EDITOR(undo());
|
EDITOR(undo());
|
||||||
rev = revision();
|
else
|
||||||
} while (prevRev < rev && last != rev);
|
|
||||||
} else {
|
|
||||||
do {
|
|
||||||
last = rev;
|
|
||||||
EDITOR(redo());
|
EDITOR(redo());
|
||||||
rev = revision();
|
|
||||||
} while (prevRev > rev && last != rev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollToLine(firstLine);
|
|
||||||
--m_editBlockLevel;
|
--m_editBlockLevel;
|
||||||
|
|
||||||
if (current == rev) {
|
scrollToLine(firstLine);
|
||||||
|
|
||||||
|
if (current == revision()) {
|
||||||
const QString msg = undo ? FakeVimHandler::tr("Already at oldest change.")
|
const QString msg = undo ? FakeVimHandler::tr("Already at oldest change.")
|
||||||
: FakeVimHandler::tr("Already at newest change.");
|
: FakeVimHandler::tr("Already at newest change.");
|
||||||
showMessage(MessageInfo, msg);
|
showMessage(MessageInfo, msg);
|
||||||
|
stack.push(state);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
clearMessage();
|
clearMessage();
|
||||||
|
|
||||||
if (validState) {
|
if (state.isValid()) {
|
||||||
if (state.revision == rev) {
|
|
||||||
m_lastChangePosition = state.position;
|
m_lastChangePosition = state.position;
|
||||||
Marks marks = m_marks;
|
Marks marks = m_marks;
|
||||||
marks.swap(state.marks);
|
marks.swap(state.marks);
|
||||||
@@ -7165,11 +7152,7 @@ void FakeVimHandler::Private::undoRedo(bool undo)
|
|||||||
setMark(QLatin1Char('\''), lastPos);
|
setMark(QLatin1Char('\''), lastPos);
|
||||||
setCursorPosition(m_lastChangePosition);
|
setCursorPosition(m_lastChangePosition);
|
||||||
setAnchor();
|
setAnchor();
|
||||||
state.revision = current;
|
|
||||||
stack2.push(state);
|
stack2.push(state);
|
||||||
} else {
|
|
||||||
stack.push(state);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setTargetColumn();
|
setTargetColumn();
|
||||||
|
Reference in New Issue
Block a user