vim-mode: bug fixes

1. Enable repeat in f/t/F/T movement;
2. Make cw/W behave like ce/E;
This commit is contained in:
Le Tan 2017-06-27 22:03:41 +08:00
parent bd5e8be1c0
commit 11f06bf617
3 changed files with 38 additions and 17 deletions

View File

@ -215,26 +215,34 @@ bool VEditUtils::findTargetWithinBlock(QTextCursor &p_cursor,
QTextCursor::MoveMode p_mode,
QChar p_target,
bool p_forward,
bool p_inclusive)
bool p_inclusive,
int p_repeat)
{
qDebug() << "find target" << p_target << p_forward << p_inclusive;
if (p_repeat < 1) {
return false;
}
QTextBlock block = p_cursor.block();
QString text = block.text();
int pib = p_cursor.positionInBlock();
int delta = p_forward ? 1 : -1;
int idx = pib + delta;
repeat:
// The index to start searching.
int idx = pib + (p_inclusive ? delta : 2 * delta);
for (; idx < text.size() && idx >= 0; idx += delta) {
if (text[idx] == p_target) {
if (--p_repeat == 0) {
break;
}
}
}
if (idx < 0 || idx >= text.size()) {
if (idx < 0 || idx >= text.size() || p_repeat > 0) {
return false;
}
// text[idx] is the target character.
if ((p_forward && p_inclusive && p_mode == QTextCursor::KeepAnchor)
|| (!p_forward && !p_inclusive)) {
++idx;
@ -242,12 +250,6 @@ repeat:
--idx;
}
if (idx == pib) {
// We need to skip current match.
idx = pib + delta * 2;
goto repeat;
}
p_cursor.setPosition(block.position() + idx, p_mode);
return true;
}

View File

@ -65,13 +65,14 @@ public:
static void unindentBlock(QTextCursor &p_cursor,
const QString &p_indentationText);
// Find a char within a block.
// Find @p_repeat th occurence a char within a block.
// Returns true if target is found.
static bool findTargetWithinBlock(QTextCursor &p_cursor,
QTextCursor::MoveMode p_mode,
QChar p_target,
bool p_forward,
bool p_inclusive);
bool p_inclusive,
int p_repeat);
// Get the count of blocks selected.
static int selectedBlockCount(const QTextCursor &p_cursor);

View File

@ -1206,7 +1206,17 @@ bool VVim::handleKeyPressEvent(int key, int modifiers, bool *p_autoIndented)
mm = Movement::WORDForward;
}
if (checkActionToken(Action::Change)) {
// In Change action, cw equals to ce.
if (shift) {
mm = Movement::ForwardEndOfWORD;
} else {
mm = Movement::ForwardEndOfWord;
}
} else {
tryAddMoveAction();
}
addMovementToken(mm);
processCommand(m_tokens);
break;
@ -2322,11 +2332,19 @@ bool VVim::processMovement(QTextCursor &p_cursor, const QTextDocument *p_doc,
case Movement::FindForward:
{
handle_target:
if (p_repeat == -1) {
p_repeat = 1;
}
const Key &key = p_token.m_key;
QChar target = keyToChar(key.m_key, key.m_modifiers);
if (!target.isNull()) {
hasMoved = VEditUtils::findTargetWithinBlock(p_cursor, p_moveMode,
target, forward, inclusive);
hasMoved = VEditUtils::findTargetWithinBlock(p_cursor,
p_moveMode,
target,
forward,
inclusive,
p_repeat);
}
break;