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

View File

@ -65,13 +65,14 @@ public:
static void unindentBlock(QTextCursor &p_cursor, static void unindentBlock(QTextCursor &p_cursor,
const QString &p_indentationText); 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. // Returns true if target is found.
static bool findTargetWithinBlock(QTextCursor &p_cursor, static bool findTargetWithinBlock(QTextCursor &p_cursor,
QTextCursor::MoveMode p_mode, QTextCursor::MoveMode p_mode,
QChar p_target, QChar p_target,
bool p_forward, bool p_forward,
bool p_inclusive); bool p_inclusive,
int p_repeat);
// Get the count of blocks selected. // Get the count of blocks selected.
static int selectedBlockCount(const QTextCursor &p_cursor); 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; 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(); tryAddMoveAction();
}
addMovementToken(mm); addMovementToken(mm);
processCommand(m_tokens); processCommand(m_tokens);
break; break;
@ -2322,11 +2332,19 @@ bool VVim::processMovement(QTextCursor &p_cursor, const QTextDocument *p_doc,
case Movement::FindForward: case Movement::FindForward:
{ {
handle_target: handle_target:
if (p_repeat == -1) {
p_repeat = 1;
}
const Key &key = p_token.m_key; const Key &key = p_token.m_key;
QChar target = keyToChar(key.m_key, key.m_modifiers); QChar target = keyToChar(key.m_key, key.m_modifiers);
if (!target.isNull()) { if (!target.isNull()) {
hasMoved = VEditUtils::findTargetWithinBlock(p_cursor, p_moveMode, hasMoved = VEditUtils::findTargetWithinBlock(p_cursor,
target, forward, inclusive); p_moveMode,
target,
forward,
inclusive,
p_repeat);
} }
break; break;