FakeVim: Don't overuse cursor setting and scrolling in editor

Set new text cursor and scroll in editor widget only if it's only
needed. Sometimes these action can have side-effects.

Set new cursor and scroll especially after no pending input and commands
are available to process for FakeVim.

Change-Id: I47df4d0328ac990e2e5c6981955ea7d1bd608c71
Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
hluk
2013-04-08 20:06:17 +02:00
committed by hjk
parent 8b8a5db129
commit 2ed88c44fd
5 changed files with 562 additions and 178 deletions

View File

@@ -2948,3 +2948,357 @@ void FakeVimPlugin::test_macros()
KEYS("gg@x", "abc" N X "def");
data.doCommand("unmap <S-down>");
}
void FakeVimPlugin::test_vim_qtcreator()
{
TestData data;
setup(&data);
// Pass input keys in insert mode to underlying editor widget.
data.doCommand("set passkeys");
data.setText("" N "");
KEYS("i" "void f(int arg1) {<cr>// TODO<cr>;",
"void f(int arg1) {" N
" // TODO" N
" ;" X N
"}" N
"");
KEYS("cc" "assert(arg1 != 0",
"void f(int arg1) {" N
" // TODO" N
" assert(arg1 != 0" X ")" N
"}" N
"");
KEYS("k" "." "A;",
"void f(int arg1) {" N
" assert(arg1 != 0);" X N
" assert(arg1 != 0)" N
"}" N
"");
KEYS("j.",
"void f(int arg1) {" N
" assert(arg1 != 0);" N
" assert(arg1 != 0)" X ";" N
"}" N
"");
KEYS("4b2#",
"void f(int " X "arg1) {" N
" assert(arg1 != 0);" N
" assert(arg1 != 0);" N
"}" N
"");
KEYS("e" "a, int arg2 = 0<esc>" "n",
"void f(int " X "arg1, int arg2 = 0) {" N
" assert(arg1 != 0);" N
" assert(arg1 != 0);" N
"}" N
"");
// Record macro.
KEYS("2j" "qa" "<C-A>" "f!" "2s>=<esc>" "q",
"void f(int arg1, int arg2 = 0) {" N
" assert(arg1 != 0);" N
" assert(arg2 >" X "= 0);" N
"}" N
"");
// Replay macro.
KEYS("n" "@a",
"void f(int arg1, int arg2 = 0) {" N
" assert(arg2 >" X "= 0);" N
" assert(arg2 >= 0);" N
"}" N
"");
// Undo.
KEYS("u",
"void f(int arg1, int arg2 = 0) {" N
" assert(" X "arg1 != 0);" N
" assert(arg2 >= 0);" N
"}" N
"");
KEYS("u",
"void f(int arg1, int arg2 = 0) {" N
" assert(arg1 != 0);" N
" assert(arg2 " X "!= 0);" N
"}" N
"");
KEYS("u",
"void f(int arg1, int arg2 = 0) {" N
" assert(arg1 != 0);" N
" assert(" X "arg1 != 0);" N
"}" N
"");
KEYS("u",
"void f(int arg1" X ") {" N
" assert(arg1 != 0);" N
" assert(arg1 != 0);" N
"}" N
"");
KEYS("u",
"void f(int arg1) {" N
" assert(arg1 != 0);" N
" assert(arg1 != 0" X ")" N
"}" N
"");
KEYS("u",
"void f(int arg1) {" N
" assert(arg1 != 0" X ")" N
" assert(arg1 != 0)" N
"}" N
"");
KEYS("u",
"void f(int arg1) {" N
" " X "// TODO" N
" assert(arg1 != 0)" N
"}" N
"");
KEYS("u",
"void f(int arg1) {" N
" // TODO" N
" " X ";" N
"}" N
"");
// Redo and occasional undo.
KEYS("<C-R>",
"void f(int arg1) {" N
" // TODO" N
" " X "assert(arg1 != 0)" N
"}" N
"");
KEYS("<C-R>",
"void f(int arg1) {" N
" " X "assert(arg1 != 0)" N
" assert(arg1 != 0)" N
"}" N
"");
KEYS("<C-R>",
"void f(int arg1) {" N
" assert(arg1 != 0)" X ";" N
" assert(arg1 != 0)" N
"}" N
"");
KEYS("u",
"void f(int arg1) {" N
" assert(arg1 != 0" X ")" N
" assert(arg1 != 0)" N
"}" N
"");
KEYS("<C-R>",
"void f(int arg1) {" N
" assert(arg1 != 0)" X ";" N
" assert(arg1 != 0)" N
"}" N
"");
KEYS("<C-R>",
"void f(int arg1) {" N
" assert(arg1 != 0);" N
" assert(arg1 != 0)" X ";" N
"}" N
"");
KEYS("<C-R>",
"void f(int arg1" X ", int arg2 = 0) {" N
" assert(arg1 != 0);" N
" assert(arg1 != 0);" N
"}" N
"");
KEYS("<C-R>",
"void f(int arg1, int arg2 = 0) {" N
" assert(arg1 != 0);" N
" assert(" X "arg2 != 0);" N
"}" N
"");
KEYS("<C-R>",
"void f(int arg1, int arg2 = 0) {" N
" assert(arg1 != 0);" N
" assert(arg2 " X ">= 0);" N
"}" N
"");
KEYS("<C-R>",
"void f(int arg1, int arg2 = 0) {" N
" assert(" X "arg2 >= 0);" N
" assert(arg2 >= 0);" N
"}" N
"");
KEYS("3u",
"void f(int arg1, int arg2 = 0) {" N
" assert(arg1 != 0);" N
" assert(" X "arg1 != 0);" N
"}" N
"");
// Repeat last command.
KEYS("w.",
"void f(int arg1, int arg2 = 0) {" N
" assert(arg1 != 0);" N
" assert(arg1 >" X "= 0);" N
"}" N
"");
KEYS("kdd",
"void f(int arg1, int arg2 = 0) {" N
" " X "assert(arg1 >= 0);" N
"}" N
"");
// Make mistakes.
KEYS("4<esc>3<esc>" "2oif (arg3<bs>2<bs>1 > 0) return true;<esc>",
"void f(int arg1, int arg2 = 0) {" N
" assert(arg1 >= 0);" N
" if (arg1 > 0) return true;" N
" if (arg1 > 0) return true" X ";" N
"}" N
"");
// Jumps around and change stuff.
KEYS("gg" "ciw" "bool",
"bool" X " f(int arg1, int arg2 = 0) {" N
" assert(arg1 >= 0);" N
" if (arg1 > 0) return true;" N
" if (arg1 > 0) return true;" N
"}" N
"");
KEYS("`'",
"bool f(int arg1, int arg2 = 0) {" N
" assert(arg1 >= 0);" N
" if (arg1 > 0) return true;" N
" if (arg1 > 0) return true" X ";" N
"}" N
"");
KEYS("caW" " false;",
"bool f(int arg1, int arg2 = 0) {" N
" assert(arg1 >= 0);" N
" if (arg1 > 0) return true;" N
" if (arg1 > 0) return false;" X N
"}" N
"");
KEYS("k.",
"bool f(int arg1, int arg2 = 0) {" N
" assert(arg1 >= 0);" N
" if (arg1 > 0) return false" X ";" N
" if (arg1 > 0) return false;" N
"}" N
"");
// Undo/redo again.
KEYS("u",
"bool f(int arg1, int arg2 = 0) {" N
" assert(arg1 >= 0);" N
" if (arg1 > 0) return" X " true;" N
" if (arg1 > 0) return false;" N
"}" N
"");
KEYS("u",
"bool f(int arg1, int arg2 = 0) {" N
" assert(arg1 >= 0);" N
" if (arg1 > 0) return true;" N
" if (arg1 > 0) return" X " true;" N
"}" N
"");
KEYS("<C-R>",
"bool f(int arg1, int arg2 = 0) {" N
" assert(arg1 >= 0);" N
" if (arg1 > 0) return true;" N
" if (arg1 > 0) return" X " false;" N
"}" N
"");
KEYS("u",
"bool f(int arg1, int arg2 = 0) {" N
" assert(arg1 >= 0);" N
" if (arg1 > 0) return true;" N
" if (arg1 > 0) return" X " true;" N
"}" N
"");
KEYS("u",
X "void f(int arg1, int arg2 = 0) {" N
" assert(arg1 >= 0);" N
" if (arg1 > 0) return true;" N
" if (arg1 > 0) return true;" N
"}" N
"");
// Record long insert mode.
KEYS("qb" "4s" "bool" "<down>" "Q_<insert>ASSERT" "<down><down>" "<insert><bs>2"
"<c-o>2w<delete>1" "<c-o>:s/true/false<cr><esc>" "q",
"bool f(int arg1, int arg2 = 0) {" N
" Q_ASSERT(arg1 >= 0);" N
" if (arg1 > 0) return true;" N
" " X " if (arg2 > 1) return false;" N
"}" N
"");
KEYS("u",
"bool f(int arg1, int arg2 = 0) {" N
" Q_ASSERT(arg1 >= 0);" N
" if (arg1 > 0) return true;" N
X " if (arg2 > 1) return true;" N
"}" N
"");
KEYS("u",
"bool f(int arg1, int arg2 = 0) {" N
" Q_ASSERT(arg1 >= 0);" N
" if (arg1 > 0) return true;" N
" if (arg2 > " X "0) return true;" N
"}" N
"");
KEYS("u",
"bool f(int arg1, int arg2 = 0) {" N
" Q_ASSERT(arg1 >= 0);" N
" if (arg1 > 0) return true;" N
" if (arg1" X " > 0) return true;" N
"}" N
"");
KEYS("u",
"bool f(int arg1, int arg2 = 0) {" N
" " X "assert(arg1 >= 0);" N
" if (arg1 > 0) return true;" N
" if (arg1 > 0) return true;" N
"}" N
"");
KEYS("u",
X "void f(int arg1, int arg2 = 0) {" N
" assert(arg1 >= 0);" N
" if (arg1 > 0) return true;" N
" if (arg1 > 0) return true;" N
"}" N
"");
// Replay.
KEYS("@b",
"bool f(int arg1, int arg2 = 0) {" N
" Q_ASSERT(arg1 >= 0);" N
" if (arg1 > 0) return true;" N
" " X " if (arg2 > 1) return false;" N
"}" N
"");
// Return to the first change.
KEYS("99u" "<C-R>",
X "void f(int arg1) {" N
" // TODO" N
" ;" N
"}" N
"");
KEYS("<C-R>",
"void f(int arg1) {" N
" // TODO" N
" " X "assert(arg1 != 0)" N
"}" N
"");
KEYS("<C-R>",
"void f(int arg1) {" N
" " X "assert(arg1 != 0)" N
" assert(arg1 != 0)" N
"}" N
"");
// Return to the last change.
KEYS("99<C-R>",
"bool f(int arg1, int arg2 = 0) {" N
" Q_ASSERT(arg1 >= 0);" N
" if (arg1 > 0) return true;" N
" if (arg2 > 1) return false;" N
"}" N
"");
}

View File

@@ -1499,14 +1499,14 @@ public:
int mvCount() const { return m_mvcount.isEmpty() ? 1 : m_mvcount.toInt(); }
int opCount() const { return m_opcount.isEmpty() ? 1 : m_opcount.toInt(); }
int count() const { return mvCount() * opCount(); }
QTextBlock block() const { return cursor().block(); }
QTextBlock block() const { return m_cursor.block(); }
int leftDist() const { return position() - block().position(); }
int rightDist() const { return block().length() - leftDist() - 1; }
bool atBlockStart() const { return cursor().atBlockStart(); }
bool atBlockEnd() const { return cursor().atBlockEnd(); }
bool atBlockStart() const { return m_cursor.atBlockStart(); }
bool atBlockEnd() const { return m_cursor.atBlockEnd(); }
bool atEndOfLine() const { return atBlockEnd() && block().length() > 1; }
bool atDocumentEnd() const { return position() >= lastPositionInDocument(); }
bool atDocumentStart() const { return cursor().atStart(); }
bool atDocumentStart() const { return m_cursor.atStart(); }
bool atEmptyLine(const QTextCursor &tc = QTextCursor()) const;
bool atBoundary(bool end, bool simple, bool onlyWords = false,
@@ -1540,8 +1540,11 @@ public:
int logicalToPhysicalColumn(int logical, const QString &text) const;
int windowScrollOffset() const; // return scrolloffset but max half the current window height
Column cursorColumn() const; // as visible on screen
void updateFirstVisibleLine();
int firstVisibleLine() const;
void setScrollBarValue(int line);
int lastVisibleLine() const;
int lineOnTop(int count = 1) const; // [count]-th line from top reachable without scrolling
int lineOnBottom(int count = 1) const; // [count]-th line from bottom reachable without scrolling
void scrollToLine(int line);
void scrollUp(int count);
void scrollDown(int count) { scrollUp(-count); }
@@ -1549,6 +1552,8 @@ public:
void alignViewportToCursor(Qt::AlignmentFlag align, int line = -1,
bool moveToNonBlank = false);
int lineToBlockNumber(int line) const;
void setCursorPosition(const CursorPosition &p);
void setCursorPosition(QTextCursor *tc, const CursorPosition &p);
@@ -1596,56 +1601,38 @@ public:
}
void moveRight(int n = 1) {
//dump("RIGHT 1");
QTextCursor tc = cursor();
tc.movePosition(Right, KeepAnchor, n);
setCursor(tc);
m_cursor.movePosition(Right, KeepAnchor, n);
if (atEndOfLine())
emit q->fold(1, false);
//dump("RIGHT 2");
}
void moveLeft(int n = 1) {
QTextCursor tc = cursor();
tc.movePosition(Left, KeepAnchor, n);
setCursor(tc);
m_cursor.movePosition(Left, KeepAnchor, n);
}
void setAnchor() {
QTextCursor tc = cursor();
tc.setPosition(tc.position(), MoveAnchor);
setCursor(tc);
m_cursor.setPosition(position(), MoveAnchor);
}
void setAnchor(int position) {
QTextCursor tc = cursor();
tc.setPosition(tc.anchor(), MoveAnchor);
tc.setPosition(position, KeepAnchor);
setCursor(tc);
m_cursor.setPosition(position, KeepAnchor);
}
void setPosition(int position) {
QTextCursor tc = cursor();
tc.setPosition(position, KeepAnchor);
setCursor(tc);
m_cursor.setPosition(position, KeepAnchor);
}
void setAnchorAndPosition(int anchor, int position) {
QTextCursor tc = cursor();
tc.setPosition(anchor, MoveAnchor);
tc.setPosition(position, KeepAnchor);
setCursor(tc);
m_cursor.setPosition(anchor, MoveAnchor);
m_cursor.setPosition(position, KeepAnchor);
}
// Set cursor in text editor widget.
void commitCursor() {
if (editor())
EDITOR(setTextCursor(m_cursor));
}
// Workaround for occational crash when setting text cursor while in edit block.
// Values to save when starting FakeVim processing.
bool m_inFakeVim;
int m_firstVisibleLine;
QTextCursor m_cursor;
QTextCursor cursor() const {
if (m_editBlockLevel > 0)
return m_cursor;
return EDITOR(textCursor());
}
void setCursor(const QTextCursor &tc) {
m_cursor = tc;
if (m_editBlockLevel == 0)
EDITOR(setTextCursor(tc));
}
bool moveToPreviousParagraph(int count) { return moveToNextParagraph(-count); }
bool moveToNextParagraph(int count);
@@ -1747,8 +1734,8 @@ public:
bool m_breakEditBlock;
int anchor() const { return cursor().anchor(); }
int position() const { return cursor().position(); }
int anchor() const { return m_cursor.anchor(); }
int position() const { return m_cursor.position(); }
struct TransformationData
{
@@ -2009,6 +1996,8 @@ void FakeVimHandler::Private::init()
m_searchStartPosition = 0;
m_searchFromScreenLine = 0;
m_editBlockLevel = 0;
m_inFakeVim = false;
m_firstVisibleLine = 0;
setupCharClass();
}
@@ -2026,29 +2015,32 @@ void FakeVimHandler::Private::focus()
void FakeVimHandler::Private::enterFakeVim()
{
QTC_ASSERT(!m_inFakeVim, qDebug() << "enterFakeVim() shouldn't be called recursively!");
m_cursor = EDITOR(textCursor());
m_inFakeVim = true;
updateFirstVisibleLine();
importSelection();
QTextCursor tc = cursor();
// Position changed externally, e.g. by code completion.
if (tc.position() != m_oldPosition) {
if (position() != m_oldPosition) {
// record external jump to different line
if (m_oldPosition != -1 && lineForPosition(m_oldPosition) != lineForPosition(tc.position()))
if (m_oldPosition != -1 && lineForPosition(m_oldPosition) != lineForPosition(position()))
recordJump(m_oldPosition);
setTargetColumn();
if (atEndOfLine() && !isVisualMode() && !isInsertMode())
moveLeft();
}
tc.setVisualNavigation(true);
setCursor(tc);
if (m_fakeEnd)
moveRight();
}
void FakeVimHandler::Private::leaveFakeVim()
{
QTC_ASSERT(m_inFakeVim, qDebug() << "enterFakeVim() not called before leaveFakeVim()!");
// The command might have destroyed the editor.
if (m_textedit || m_plaintextedit) {
// We fake vi-style end-of-line behaviour
@@ -2066,7 +2058,18 @@ void FakeVimHandler::Private::leaveFakeVim()
exportSelection();
updateCursorShape();
commitCursor();
// Move cursor line to middle of screen if it's not visible.
const int line = cursorLine();
if (line < firstVisibleLine() || line >= firstVisibleLine() + linesOnScreen())
scrollToLine(qMax(0, line - linesOnScreen() / 2));
else
scrollToLine(firstVisibleLine());
updateScrollOffset();
}
m_inFakeVim = false;
}
bool FakeVimHandler::Private::wantsOverride(QKeyEvent *ev)
@@ -2144,7 +2147,7 @@ EventResult FakeVimHandler::Private::handleEvent(QKeyEvent *ev)
#endif
// Fake "End of line"
//m_tc = cursor();
//m_tc = m_cursor;
//bool hasBlock = false;
//emit q->requestHasBlockSelection(&hasBlock);
@@ -2257,7 +2260,7 @@ void FakeVimHandler::Private::exportSelection()
setMark(QLatin1Char('>'), mark(QLatin1Char('>')).position);
} else {
if (m_subsubmode == SearchSubSubMode && !m_searchCursor.isNull())
setCursor(m_searchCursor);
m_cursor = m_searchCursor;
else
setAnchorAndPosition(pos, pos);
}
@@ -2339,7 +2342,7 @@ void FakeVimHandler::Private::importSelection()
} else {
// Import new selection.
Qt::KeyboardModifiers mods = QApplication::keyboardModifiers();
if (cursor().hasSelection()) {
if (m_cursor.hasSelection()) {
if (mods & HostOsInfo::controlModifier())
m_visualMode = VisualBlockMode;
else if (mods & Qt::AltModifier)
@@ -2587,8 +2590,7 @@ void FakeVimHandler::Private::stopIncrementalFind()
{
if (g.findPending) {
g.findPending = false;
QTextCursor tc = cursor();
setAnchorAndPosition(m_findStartPosition, tc.selectionStart());
setAnchorAndPosition(m_findStartPosition, m_cursor.selectionStart());
finishMovement();
setAnchor();
}
@@ -2621,7 +2623,7 @@ bool FakeVimHandler::Private::isInputCount(const Input &input) const
bool FakeVimHandler::Private::atEmptyLine(const QTextCursor &tc) const
{
if (tc.isNull())
return atEmptyLine(cursor());
return atEmptyLine(m_cursor);
return tc.block().length() == 1;
}
@@ -2629,7 +2631,7 @@ bool FakeVimHandler::Private::atBoundary(bool end, bool simple, bool onlyWords,
const QTextCursor &tc) const
{
if (tc.isNull())
return atBoundary(end, simple, onlyWords, cursor());
return atBoundary(end, simple, onlyWords, m_cursor);
if (atEmptyLine(tc))
return true;
int pos = tc.position();
@@ -2674,12 +2676,13 @@ void FakeVimHandler::Private::pushUndoState(bool overwrite)
int pos = position();
if (!isInsertMode()) {
if (isVisualMode() || m_submode == DeleteSubMode) {
if (isVisualMode() || m_submode == DeleteSubMode
|| (m_submode == ChangeSubMode && m_movetype != MoveLineWise)) {
pos = qMin(pos, anchor());
if (isVisualLineMode())
pos = firstPositionInLine(lineForPosition(pos));
} else if (m_movetype == MoveLineWise && hasConfig(ConfigStartOfLine)) {
QTextCursor tc = cursor();
QTextCursor tc = m_cursor;
if (m_submode == ShiftLeftSubMode || m_submode == ShiftRightSubMode
|| m_submode == IndentSubMode) {
pos = qMin(pos, anchor());
@@ -2702,7 +2705,7 @@ void FakeVimHandler::Private::pushUndoState(bool overwrite)
void FakeVimHandler::Private::moveDown(int n)
{
QTextBlock block = cursor().block();
QTextBlock block = m_cursor.block();
const int col = position() - block.position();
const int targetLine = qMax(0, lineNumber(block) + n);
@@ -2711,8 +2714,6 @@ void FakeVimHandler::Private::moveDown(int n)
block = document()->lastBlock();
setPosition(block.position() + qMax(0, qMin(block.length() - 2, col)));
moveToTargetColumn();
updateScrollOffset();
}
void FakeVimHandler::Private::movePageDown(int count)
@@ -2726,7 +2727,7 @@ void FakeVimHandler::Private::movePageDown(int count)
if (count > 0)
scrollToLine(cursorLine());
else
scrollToLine(qMax(0, cursorLine() - screenLines));
scrollToLine(qMax(0, cursorLine() - screenLines + 1));
}
bool FakeVimHandler::Private::moveToNextParagraph(int count)
@@ -2891,7 +2892,7 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement)
QString dotCommand;
if (m_submode == ChangeSubMode) {
pushUndoState();
pushUndoState(false);
beginEditBlock();
removeText(currentRange());
dotCommand = _("c");
@@ -2902,7 +2903,7 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement)
m_lastInsertion.clear();
g.returnToMode = InsertMode;
} else if (m_submode == DeleteSubMode) {
pushUndoState();
pushUndoState(false);
beginEditBlock();
const int pos = position();
// Always delete something (e.g. 'dw' on an empty line deletes the line).
@@ -2919,7 +2920,7 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement)
setTargetColumn();
endEditBlock();
} else if (m_submode == YankSubMode) {
const QTextCursor tc = cursor();
const QTextCursor tc = m_cursor;
if (m_rangemode == RangeBlockMode) {
const int pos1 = tc.block().position();
const int pos2 = document()->findBlock(tc.anchor()).position();
@@ -2955,7 +2956,7 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement)
|| m_submode == ShiftRightSubMode
|| m_submode == ShiftLeftSubMode) {
recordJump();
pushUndoState();
pushUndoState(false);
if (m_submode == IndentSubMode) {
indentSelectedText();
dotCommand = _("=");
@@ -3010,11 +3011,11 @@ void FakeVimHandler::Private::updateSelection()
for (MarksIterator it(m_marks); it.hasNext(); ) {
it.next();
QTextEdit::ExtraSelection sel;
sel.cursor = cursor();
sel.cursor = m_cursor;
setCursorPosition(&sel.cursor, it.value().position);
sel.cursor.setPosition(sel.cursor.position(), MoveAnchor);
sel.cursor.movePosition(Right, KeepAnchor);
sel.format = cursor().blockCharFormat();
sel.format = m_cursor.blockCharFormat();
sel.format.setForeground(Qt::blue);
sel.format.setBackground(Qt::green);
selections.append(sel);
@@ -3181,7 +3182,7 @@ bool FakeVimHandler::Private::handleCommandSubSubMode(const Input &input)
handled = false;
}
} else if (m_subsubmode == MarkSubSubMode) {
setMark(input.asChar(), CursorPosition(cursor()));
setMark(input.asChar(), CursorPosition(m_cursor));
m_subsubmode = NoSubSubMode;
} else if (m_subsubmode == BackTickSubSubMode
|| m_subsubmode == TickSubSubMode) {
@@ -3295,7 +3296,7 @@ bool FakeVimHandler::Private::handleMovement(const Input &input)
} else if (input.is('#') || input.is('*')) {
// FIXME: That's not proper vim behaviour
QString needle;
QTextCursor tc = cursor();
QTextCursor tc = m_cursor;
tc.select(QTextCursor::WordUnderCursor);
needle = QRegExp::escape(tc.selection().toPlainText());
if (!m_gflag)
@@ -3420,6 +3421,7 @@ bool FakeVimHandler::Private::handleMovement(const Input &input)
setPosition(firstPositionInLine(n, false));
}
setTargetColumn();
updateScrollOffset();
} else if (input.is('h') || input.isKey(Key_Left) || input.isBackspace()) {
m_movetype = MoveExclusive;
int n = qMin(count, leftDist());
@@ -3429,8 +3431,8 @@ bool FakeVimHandler::Private::handleMovement(const Input &input)
setTargetColumn();
movement = _("h");
} else if (input.is('H')) {
setCursor(EDITOR(cursorForPosition(QPoint(0, 0))));
moveDown(qMax(count - 1, 0));
const CursorPosition pos(lineToBlockNumber(lineOnTop(count)), 0);
setCursorPosition(&m_cursor, pos);
handleStartOfLine();
} else if (input.is('j') || input.isKey(Key_Down)
|| input.isControl('j') || input.isControl('n')) {
@@ -3449,28 +3451,26 @@ bool FakeVimHandler::Private::handleMovement(const Input &input)
if (pastEnd && isVisualMode())
m_visualTargetColumn = -1;
} else if (input.is('L')) {
QTextCursor tc = EDITOR(cursorForPosition(QPoint(0, EDITOR(height()))));
setCursor(tc);
moveUp(qMax(count, 1));
const CursorPosition pos(lineToBlockNumber(lineOnBottom(count)), 0);
setCursorPosition(&m_cursor, pos);
handleStartOfLine();
} else if (m_gflag && input.is('m')) {
moveToStartOfLine();
moveRight(qMin(columnsOnScreen() / 2, rightDist()) - 1);
setTargetColumn();
} else if (input.is('M')) {
QTextCursor tc = EDITOR(cursorForPosition(QPoint(0, EDITOR(height()) / 2)));
setCursor(tc);
m_cursor = EDITOR(cursorForPosition(QPoint(0, EDITOR(height()) / 2)));
handleStartOfLine();
} else if (input.is('n') || input.is('N')) {
if (hasConfig(ConfigUseCoreSearch)) {
bool forward = (input.is('n')) ? g.lastSearchForward : !g.lastSearchForward;
int pos = position();
emit q->findNextRequested(!forward);
if (forward && pos == cursor().selectionStart()) {
if (forward && pos == m_cursor.selectionStart()) {
// if cursor is already positioned at the start of a find result, this is returned
emit q->findNextRequested(false);
}
setPosition(cursor().selectionStart());
setPosition(m_cursor.selectionStart());
} else {
searchNext(input.is('n'));
}
@@ -3647,7 +3647,7 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input)
// << input;
QString savedCommand = g.dotCommand;
g.dotCommand.clear();
beginEditBlock();
beginLargeEditBlock();
replay(savedCommand);
endEditBlock();
resetCommandMode();
@@ -3765,7 +3765,8 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input)
removeText(currentRange());
setPosition(qMin(position(), anchor()));
} else if (input.isControl('d')) {
int sline = cursorLineOnScreen();
const int scrollOffset = windowScrollOffset();
int sline = cursorLine() < scrollOffset ? scrollOffset : cursorLineOnScreen();
// FIXME: this should use the "scroll" option, and "count"
moveDown(linesOnScreen() / 2);
handleStartOfLine();
@@ -4382,11 +4383,11 @@ EventResult FakeVimHandler::Private::handleInsertMode(const Input &input)
pos.column = qMax(lastPosition.column, lastAnchor.column) + 1;
while (pos.line < lastPosition.line) {
++pos.line;
QTextCursor tc = cursor();
QTextCursor tc = m_cursor;
setCursorPosition(&tc, pos);
if (pos.line != tc.blockNumber())
break;
setCursor(tc);
m_cursor = tc;
if (tc.positionInBlock() == pos.column)
replay(text.repeated(repeat));
}
@@ -4417,10 +4418,10 @@ EventResult FakeVimHandler::Private::handleInsertMode(const Input &input)
m_ctrlVActive = true;
insert = _("<C-V>");
} else if (input.isControl('w')) {
const int blockNumber = cursor().blockNumber();
const int blockNumber = m_cursor.blockNumber();
const int endPos = position();
moveToNextWordStart(count(), false, false);
if (blockNumber != cursor().blockNumber())
if (blockNumber != m_cursor.blockNumber())
moveToEndOfLine();
const int beginPos = position();
Range range(beginPos, endPos, RangeCharMode);
@@ -4488,7 +4489,7 @@ EventResult FakeVimHandler::Private::handleInsertMode(const Input &input)
moveRight(prefix.size());
} else {
setAnchor();
cursor().deletePreviousChar();
m_cursor.deletePreviousChar();
}
}
insert = _("<BS>");
@@ -4497,7 +4498,7 @@ EventResult FakeVimHandler::Private::handleInsertMode(const Input &input)
} else if (input.isKey(Key_Delete)) {
if (!handleInsertInEditor(input, &insert)) {
joinPreviousEditBlock();
cursor().deleteChar();
m_cursor.deleteChar();
insert = _("<DELETE>");
endEditBlock();
}
@@ -4541,10 +4542,10 @@ EventResult FakeVimHandler::Private::handleInsertMode(const Input &input)
//} else if (key >= control('a') && key <= control('z')) {
// // ignore these
} else if (input.isControl('p') || input.isControl('n')) {
QTextCursor tc = cursor();
QTextCursor tc = m_cursor;
moveToNextWordStart(count(), false, false);
QString str = selectText(Range(position(), tc.position()));
setCursor(tc);
m_cursor = tc;
emit q->simpleCompletionRequested(str, input.isControl('n'));
if (input.isControl('p'))
insert = _("<C-P>");
@@ -4997,7 +4998,7 @@ bool FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd)
lastBlock = block;
beginEditBlock();
}
QTextCursor tc = cursor();
QTextCursor tc = m_cursor;
const int pos = block.position();
const int anchor = pos + block.length() - 1;
tc.setPosition(anchor);
@@ -5779,7 +5780,7 @@ void FakeVimHandler::Private::search(const SearchData &sd, bool showMessages)
QTextCursor tc = search(sd, m_searchStartPosition, count(), showMessages);
if (tc.isNull()) {
tc = cursor();
tc = m_cursor;
tc.setPosition(m_searchStartPosition);
}
@@ -5796,7 +5797,7 @@ void FakeVimHandler::Private::search(const SearchData &sd, bool showMessages)
if (oldLine != cursorLine() - cursorLineOnScreen())
scrollToLine(cursorLine() - linesOnScreen() / 2);
m_searchCursor = cursor();
m_searchCursor = m_cursor;
setTargetColumn();
}
@@ -5824,9 +5825,7 @@ void FakeVimHandler::Private::highlightMatches(const QString &needle)
void FakeVimHandler::Private::moveToFirstNonBlankOnLine()
{
QTextCursor tc2 = cursor();
moveToFirstNonBlankOnLine(&tc2);
setPosition(tc2.position());
moveToFirstNonBlankOnLine(&m_cursor);
}
void FakeVimHandler::Private::moveToFirstNonBlankOnLine(QTextCursor *tc)
@@ -5835,11 +5834,11 @@ void FakeVimHandler::Private::moveToFirstNonBlankOnLine(QTextCursor *tc)
int firstPos = tc->block().position();
for (int i = firstPos, n = firstPos + block().length(); i < n; ++i) {
if (!doc->characterAt(i).isSpace() || i == n - 1) {
tc->setPosition(i);
tc->setPosition(i, KeepAnchor);
return;
}
}
tc->setPosition(block().position());
tc->setPosition(block().position(), KeepAnchor);
}
void FakeVimHandler::Private::indentSelectedText(QChar typedChar)
@@ -5897,7 +5896,7 @@ void FakeVimHandler::Private::shiftRegionRight(int repeat)
QTextBlock block = document()->findBlockByLineNumber(beginLine - 1);
while (block.isValid() && lineNumber(block) <= endLine) {
const Column col = indentation(block.text());
QTextCursor tc = cursor();
QTextCursor tc = m_cursor;
tc.setPosition(block.position());
if (col.physical > 0)
tc.setPosition(tc.position() + col.physical, KeepAnchor);
@@ -6042,7 +6041,7 @@ void FakeVimHandler::Private::moveToBoundary(bool simple, bool forward)
c = doc->characterAt(tc.position());
int thisClass = charClass(c, simple);
if (thisClass != lastClass || (forward ? tc.atBlockEnd() : tc.atBlockStart())) {
if (tc != cursor())
if (tc != m_cursor)
tc.movePosition(forward ? Left : Right);
break;
}
@@ -6162,7 +6161,7 @@ void FakeVimHandler::Private::moveToMatchingParanthesis()
bool forward = false;
const int anc = anchor();
QTextCursor tc = cursor();
QTextCursor tc = m_cursor;
emit q->moveToMatchingParenthesis(&moved, &forward, &tc);
if (moved && forward)
tc.movePosition(Left, KeepAnchor, 1);
@@ -6265,39 +6264,62 @@ Column FakeVimHandler::Private::cursorColumn() const
int FakeVimHandler::Private::linesInDocument() const
{
if (cursor().isNull())
if (m_cursor.isNull())
return 0;
return document()->blockCount();
}
void FakeVimHandler::Private::setScrollBarValue(int line)
void FakeVimHandler::Private::scrollToLine(int line)
{
QScrollBar *scrollBar = EDITOR(verticalScrollBar());
// Convert line number to scroll bar value.
const int maxValue = scrollBar->maximum();
const int scrollLines = qMax(1, linesInDocument() - linesOnScreen());
const int scrollLines = qMax(1, linesInDocument() - linesOnScreen() + 1);
const int value = maxValue >= scrollLines ? line * maxValue / scrollLines : line;
scrollBar->setValue(value);
updateFirstVisibleLine();
}
void FakeVimHandler::Private::scrollToLine(int line)
void FakeVimHandler::Private::updateFirstVisibleLine()
{
setScrollBarValue(line);
updateScrollOffset();
QScrollBar *scrollBar = EDITOR(verticalScrollBar());
// Convert scroll bar value to line number.
const int maxValue = qMax(1, scrollBar->maximum());
const int scrollLines = qMax(1, linesInDocument() - linesOnScreen() + 1);
const int value = scrollBar->value();
m_firstVisibleLine = maxValue >= scrollLines ? value * scrollLines / maxValue : value;
}
int FakeVimHandler::Private::firstVisibleLine() const
{
QScrollBar *scrollBar = EDITOR(verticalScrollBar());
if (0 && scrollBar->value() != cursorLine() - cursorLineOnScreen()) {
qDebug() << "SCROLLBAR: " << scrollBar->value()
<< "CURSORLINE IN DOC" << cursorLine()
<< "CURSORLINE ON SCREEN" << cursorLineOnScreen();
}
//return scrollBar->value();
return cursorLine() - cursorLineOnScreen();
return m_firstVisibleLine;
}
int FakeVimHandler::Private::lastVisibleLine() const
{
const int blockNumber = lineToBlockNumber(m_firstVisibleLine + linesOnScreen());
const QTextBlock block = document()->findBlockByNumber(blockNumber);
return block.isValid() ? block.firstLineNumber() : document()->lastBlock().firstLineNumber();
}
int FakeVimHandler::Private::lineOnTop(int count) const
{
const int scrollOffset = qMax(count - 1, windowScrollOffset());
const int line = firstVisibleLine();
return line == 0 ? count - 1 : scrollOffset + line;
}
int FakeVimHandler::Private::lineOnBottom(int count) const
{
const int scrollOffset = qMax(count - 1, windowScrollOffset());
const int line = lastVisibleLine();
return line >= document()->lastBlock().firstLineNumber() ? line - count + 1
: line - scrollOffset - 1;
}
void FakeVimHandler::Private::scrollUp(int count)
@@ -6307,18 +6329,11 @@ void FakeVimHandler::Private::scrollUp(int count)
void FakeVimHandler::Private::updateScrollOffset()
{
// Precision of scroll offset depends on singleStep property of vertical scroll bar.
const int offset = windowScrollOffset();
const int line = cursorLine();
const int scrollLine = firstVisibleLine();
int d = line - scrollLine;
if (d <= offset) {
setScrollBarValue(scrollLine - offset + d);
} else {
d = linesOnScreen() - d;
if (d <= offset)
setScrollBarValue(scrollLine + offset - d + 1);
}
if (line < lineOnTop())
scrollToLine(qMax(0, line - windowScrollOffset()));
else if (line > lineOnBottom())
scrollToLine(line - linesOnScreen() + windowScrollOffset() + 1);
}
void FakeVimHandler::Private::alignViewportToCursor(AlignmentFlag align, int line,
@@ -6337,16 +6352,18 @@ void FakeVimHandler::Private::alignViewportToCursor(AlignmentFlag align, int lin
scrollUp(linesOnScreen() - cursorLineOnScreen());
}
int FakeVimHandler::Private::lineToBlockNumber(int line) const
{
return document()->findBlockByLineNumber(line).blockNumber();
}
void FakeVimHandler::Private::setCursorPosition(const CursorPosition &p)
{
const int firstLine = firstVisibleLine();
const int firstBlock = document()->findBlockByLineNumber(firstLine).blockNumber();
const int lastBlock =
document()->findBlockByLineNumber(firstLine + linesOnScreen() - 2).blockNumber();
const int firstBlock = lineToBlockNumber(firstLine);
const int lastBlock = lineToBlockNumber(firstLine + linesOnScreen() - 2);
bool isLineVisible = firstBlock <= p.line && p.line <= lastBlock;
QTextCursor tc = cursor();
setCursorPosition(&tc, p);
setCursor(tc);
setCursorPosition(&m_cursor, p);
if (!isLineVisible)
alignViewportToCursor(Qt::AlignVCenter);
}
@@ -6426,7 +6443,7 @@ void FakeVimHandler::Private::yankText(const Range &range, int reg)
void FakeVimHandler::Private::transformText(const Range &range,
Transformation transformFunc, const QVariant &extra)
{
QTextCursor tc = cursor();
QTextCursor tc = m_cursor;
int posAfter = range.beginPos;
switch (range.rangemode) {
case RangeCharMode: {
@@ -6505,9 +6522,8 @@ void FakeVimHandler::Private::transformText(const Range &range,
void FakeVimHandler::Private::insertText(QTextCursor &tc, const QString &text)
{
if (hasConfig(ConfigPassKeys)) {
QTextCursor oldTc = cursor();
setCursor(tc);
EDITOR(setOverwriteMode(false));
QTextCursor oldTc = m_cursor;
m_cursor = tc;
if (tc.hasSelection() && text.isEmpty()) {
QKeyEvent event(QEvent::KeyPress, Qt::Key_Delete, Qt::NoModifier, QString());
@@ -6520,7 +6536,7 @@ void FakeVimHandler::Private::insertText(QTextCursor &tc, const QString &text)
}
updateCursorShape();
setCursor(oldTc);
m_cursor = oldTc;
} else {
tc.insertText(text);
}
@@ -6531,7 +6547,7 @@ void FakeVimHandler::Private::insertText(const Register &reg)
QTC_ASSERT(reg.rangemode == RangeCharMode,
qDebug() << "WRONG INSERT MODE: " << reg.rangemode; return);
setAnchor();
cursor().insertText(reg.contents);
m_cursor.insertText(reg.contents);
//dump("AFTER INSERT");
}
@@ -6649,7 +6665,7 @@ void FakeVimHandler::Private::pasteText(bool afterCursor)
}
case RangeLineMode:
case RangeLineModeExclusive: {
QTextCursor tc = cursor();
QTextCursor tc = m_cursor;
if (visualCharMode)
tc.insertBlock();
else
@@ -6678,7 +6694,7 @@ void FakeVimHandler::Private::pasteText(bool afterCursor)
const int pos = position();
if (pasteAfter && rightDist() > 0)
moveRight();
QTextCursor tc = cursor();
QTextCursor tc = m_cursor;
const int col = tc.columnNumber();
QTextBlock block = tc.block();
const QStringList lines = text.split(QLatin1Char('\n'));
@@ -6719,7 +6735,7 @@ void FakeVimHandler::Private::pasteText(bool afterCursor)
void FakeVimHandler::Private::joinLines(int count, bool preserveSpace)
{
int pos = position();
const int blockNumber = cursor().blockNumber();
const int blockNumber = m_cursor.blockNumber();
for (int i = qMax(count - 2, 0); i >= 0 && blockNumber < document()->blockCount(); --i) {
moveBehindEndOfLine();
pos = position();
@@ -6730,7 +6746,7 @@ void FakeVimHandler::Private::joinLines(int count, bool preserveSpace)
} else {
while (characterAtCursor() == QLatin1Char(' ') || characterAtCursor() == QLatin1Char('\t'))
moveRight();
cursor().insertText(QString(QLatin1Char(' ')));
m_cursor.insertText(QString(QLatin1Char(' ')));
}
}
setPosition(pos);
@@ -6760,6 +6776,7 @@ bool FakeVimHandler::Private::handleInsertInEditor(const Input &input, QString *
QKeyEvent event(QEvent::KeyPress, input.key(),
static_cast<Qt::KeyboardModifiers>(input.modifiers()), input.text());
setAnchor();
if (!passEventToEditor(event))
return false;
@@ -6777,14 +6794,14 @@ bool FakeVimHandler::Private::passEventToEditor(QEvent &event)
{
removeEventFilter();
QTextCursor tc = m_cursor;
EDITOR(setTextCursor(tc));
commitCursor();
EDITOR(setOverwriteMode(false));
bool accepted = QApplication::sendEvent(editor(), &event);
installEventFilter();
if (accepted)
setPosition(EDITOR(textCursor()).position());
m_cursor = EDITOR(textCursor());
return accepted;
}
@@ -6811,7 +6828,7 @@ QString FakeVimHandler::Private::guessInsertCommand(int pos1, int pos2, int len1
} else if (len1 < len2) {
// Text inserted.
if (pos1 < pos2) {
QTextCursor tc = cursor();
QTextCursor tc = m_cursor;
tc.setPosition(pos1);
tc.setPosition(pos2, KeepAnchor);
insert = QString(tc.selectedText()).replace(_("<"), _("<LT>"));
@@ -6861,7 +6878,7 @@ QString FakeVimHandler::Private::lineContents(int line) const
void FakeVimHandler::Private::setLineContents(int line, const QString &contents)
{
QTextBlock block = document()->findBlockByLineNumber(line - 1);
QTextCursor tc = cursor();
QTextCursor tc = m_cursor;
const int begin = block.position();
const int len = block.length();
tc.setPosition(begin);
@@ -6876,7 +6893,7 @@ int FakeVimHandler::Private::blockBoundary(const QString &left,
const QString &end = closing ? right : left;
// shift cursor if it is already on opening/closing string
QTextCursor tc1 = cursor();
QTextCursor tc1 = m_cursor;
int pos = tc1.position();
int max = document()->characterCount();
int sz = left.size();
@@ -6899,7 +6916,7 @@ int FakeVimHandler::Private::blockBoundary(const QString &left,
// - on closing string:
tc1.setPosition(from + i);
} else {
tc1 = cursor();
tc1 = m_cursor;
}
}
@@ -7035,7 +7052,7 @@ void FakeVimHandler::Private::joinPreviousEditBlock()
UNDO_DEBUG("JOIN");
if (m_breakEditBlock && m_editBlockLevel == 0) {
beginEditBlock();
QTextCursor tc(cursor());
QTextCursor tc(m_cursor);
tc.setPosition(tc.position());
tc.beginEditBlock();
tc.insertText(_("X"));
@@ -7051,9 +7068,6 @@ void FakeVimHandler::Private::joinPreviousEditBlock()
void FakeVimHandler::Private::beginEditBlock(bool largeEditBlock)
{
UNDO_DEBUG("BEGIN EDIT BLOCK");
if (m_editBlockLevel == 0)
m_cursor = cursor();
if (!largeEditBlock && !m_undoState.isValid())
pushUndoState(false);
++m_editBlockLevel;
@@ -7066,14 +7080,9 @@ void FakeVimHandler::Private::endEditBlock()
QTC_ASSERT(m_editBlockLevel > 0,
qDebug() << "beginEditBlock() not called before endEditBlock()!"; return);
--m_editBlockLevel;
if (m_editBlockLevel == 0) {
setCursor(m_cursor);
if (m_undoState.isValid()) {
if (m_undoState.revisions > 0) {
m_undo.push(m_undoState);
m_undoState = State();
}
}
if (m_editBlockLevel == 0 && m_undoState.isValid() && m_undoState.revisions > 0) {
m_undo.push(m_undoState);
m_undoState = State();
}
}
@@ -7118,9 +7127,7 @@ void FakeVimHandler::Private::undoRedo(bool undo)
State state = !stack.empty() ? stack.pop() : State();
const int firstLine = firstVisibleLine();
CursorPosition lastPos(cursor());
CursorPosition lastPos(m_cursor);
const int current = revision();
++m_editBlockLevel;
@@ -7137,8 +7144,6 @@ void FakeVimHandler::Private::undoRedo(bool undo)
--m_editBlockLevel;
scrollToLine(firstLine);
if (current == revision()) {
const QString msg = undo ? FakeVimHandler::tr("Already at oldest change.")
: FakeVimHandler::tr("Already at newest change.");
@@ -7160,6 +7165,9 @@ void FakeVimHandler::Private::undoRedo(bool undo)
setCursorPosition(m_lastChangePosition);
setAnchor();
stack2.push(state);
} else {
updateFirstVisibleLine();
m_cursor = EDITOR(textCursor());
}
setTargetColumn();
@@ -7183,7 +7191,7 @@ void FakeVimHandler::Private::updateCursorShape()
|| m_subsubmode == SearchSubSubMode
|| m_mode == InsertMode
|| isVisualMode()
|| cursor().hasSelection();
|| m_cursor.hasSelection();
EDITOR(setOverwriteMode(!thinCursor));
}
@@ -7259,7 +7267,7 @@ void FakeVimHandler::Private::enterExMode(const QString &contents)
void FakeVimHandler::Private::recordJump(int position)
{
CursorPosition pos = position >= 0 ? CursorPosition(document(), position)
: CursorPosition(cursor());
: CursorPosition(m_cursor);
setMark(QLatin1Char('\''), pos);
setMark(QLatin1Char('`'), pos);
if (m_jumpListUndo.isEmpty() || m_jumpListUndo.top() != pos)
@@ -7273,7 +7281,7 @@ void FakeVimHandler::Private::jump(int distance)
QStack<CursorPosition> &from = (distance > 0) ? m_jumpListRedo : m_jumpListUndo;
QStack<CursorPosition> &to = (distance > 0) ? m_jumpListUndo : m_jumpListRedo;
int len = qMin(qAbs(distance), from.size());
CursorPosition m(cursor());
CursorPosition m(m_cursor);
setMark(QLatin1Char('\''), m);
setMark(QLatin1Char('`'), m);
for (int i = 0; i < len; ++i) {
@@ -7358,6 +7366,7 @@ void FakeVimHandler::Private::handleStartOfLine()
void FakeVimHandler::Private::replay(const QString &command)
{
//qDebug() << "REPLAY: " << quoteUnprintable(command);
clearCommandMode();
Inputs inputs(command);
foreach (const Input &in, inputs) {
if (handleDefaultKey(in) != EventHandled)
@@ -7367,7 +7376,7 @@ void FakeVimHandler::Private::replay(const QString &command)
QString FakeVimHandler::Private::visualDotCommand() const
{
QTextCursor start(cursor());
QTextCursor start(m_cursor);
QTextCursor end(start);
end.setPosition(end.anchor());
@@ -7443,7 +7452,8 @@ void FakeVimHandler::Private::selectTextObject(bool simple, bool inner)
moveToWordStart(1, simple, false);
// select trailing spaces if no leading space
if (!leadingSpace && document()->characterAt(position() + direction).isSpace()
QChar afterCursor = document()->characterAt(position() + direction);
if (!leadingSpace && afterCursor.isSpace() && afterCursor != ParagraphSeparator
&& !atBlockStart()) {
if (forward)
moveToNextBoundaryEnd(1, simple);
@@ -7543,7 +7553,7 @@ bool FakeVimHandler::Private::changeNumberTextObject(int count)
{
const QTextBlock block = this->block();
const QString lineText = block.text();
const int posMin = cursor().positionInBlock() + 1;
const int posMin = m_cursor.positionInBlock() + 1;
// find first decimal, hexadecimal or octal number under or after cursor position
QRegExp re(_("(0[xX])(0*[0-9a-fA-F]+)|(0)(0*[0-7]+)(?=\\D|$)|(\\d+)"));
@@ -7607,7 +7617,7 @@ bool FakeVimHandler::Private::changeNumberTextObject(int count)
bool FakeVimHandler::Private::selectQuotedStringTextObject(bool inner,
const QString &quote)
{
QTextCursor tc = cursor();
QTextCursor tc = m_cursor;
int sz = quote.size();
QTextCursor tc1;
@@ -7983,6 +7993,19 @@ void FakeVimHandler::setTextCursorPosition(int position)
d->setAnchorAndPosition(pos, pos);
d->m_fakeEnd = false;
d->setTargetColumn();
if (!d->m_inFakeVim)
d->commitCursor();
}
QTextCursor FakeVimHandler::textCursor() const
{
return d->m_cursor;
}
void FakeVimHandler::setTextCursor(const QTextCursor &cursor)
{
d->m_cursor = cursor;
}
bool FakeVimHandler::jumpToLocalMark(QChar mark, bool backTickMode)

View File

@@ -125,6 +125,9 @@ public slots:
// Set text cursor position. Keeps anchor if in visual mode.
void setTextCursorPosition(int position);
QTextCursor textCursor() const;
void setTextCursor(const QTextCursor &cursor);
bool jumpToLocalMark(QChar mark, bool backTickMode);
signals:

View File

@@ -1406,10 +1406,10 @@ void FakeVimPluginPrivate::findNext(bool reverse)
void FakeVimPluginPrivate::foldToggle(int depth)
{
IEditor *ieditor = EditorManager::currentEditor();
BaseTextEditorWidget *editor = qobject_cast<BaseTextEditorWidget *>(ieditor->widget());
QTC_ASSERT(editor != 0, return);
FakeVimHandler *handler = m_editorToHandler.value(ieditor, 0);
QTC_ASSERT(handler != 0, return);
QTextBlock block = editor->textCursor().block();
QTextBlock block = handler->textCursor().block();
fold(depth, !BaseTextDocumentLayout::isFolded(block));
}
@@ -1437,6 +1437,8 @@ void FakeVimPluginPrivate::foldAll(bool fold)
void FakeVimPluginPrivate::fold(int depth, bool fold)
{
IEditor *ieditor = EditorManager::currentEditor();
FakeVimHandler *handler = m_editorToHandler.value(ieditor, 0);
QTC_ASSERT(handler != 0, return);
BaseTextEditorWidget *editor = qobject_cast<BaseTextEditorWidget *>(ieditor->widget());
QTC_ASSERT(editor != 0, return);
@@ -1445,7 +1447,7 @@ void FakeVimPluginPrivate::fold(int depth, bool fold)
qobject_cast<BaseTextDocumentLayout*>(doc->documentLayout());
QTC_ASSERT(documentLayout != 0, return);
QTextBlock block = editor->textCursor().block();
QTextBlock block = handler->textCursor().block();
int indent = BaseTextDocumentLayout::foldingIndent(block);
if (fold) {
if (BaseTextDocumentLayout::isFolded(block)) {
@@ -1496,10 +1498,10 @@ void FakeVimPluginPrivate::fold(int depth, bool fold)
void FakeVimPluginPrivate::foldGoTo(int count, bool current)
{
IEditor *ieditor = EditorManager::currentEditor();
BaseTextEditorWidget *editor = qobject_cast<BaseTextEditorWidget *>(ieditor->widget());
QTC_ASSERT(editor != 0, return);
FakeVimHandler *handler = m_editorToHandler.value(ieditor, 0);
QTC_ASSERT(handler != 0, return);
QTextCursor tc = editor->textCursor();
QTextCursor tc = handler->textCursor();
QTextBlock block = tc.block();
int pos = -1;
@@ -1546,7 +1548,7 @@ void FakeVimPluginPrivate::foldGoTo(int count, bool current)
if (pos != -1) {
tc.setPosition(pos, QTextCursor::KeepAnchor);
editor->setTextCursor(tc);
handler->setTextCursor(tc);
}
}

View File

@@ -142,6 +142,8 @@ private slots:
void test_macros();
void test_vim_qtcreator();
// special tests
void test_i_cw_i();