forked from qt-creator/qt-creator
Fixed yanking and deleting using marks ma "ay'a
Fixed yanking with e (ye) Fixed ce followed by . Initial implementation for mark updates (marks should stay on the same line after adding/deleting lines) Fixed yank with Y Added fakevim tests for yanking using marks and yanking using Y. Fixed yanking with marks when a mark was set to a blank line. Combined yy and Y to use the same yanking method. Merge-request: 1314 Reviewed-by: hjk <qtc-committer@nokia.com>
This commit is contained in:
@@ -249,6 +249,7 @@ public:
|
||||
bool wantsOverride(QKeyEvent *ev);
|
||||
void handleCommand(const QString &cmd); // sets m_tc + handleExCommand
|
||||
void handleExCommand(const QString &cmd);
|
||||
void fixMarks(int positionAction, int positionChange); //Updates marks positions by the difference in positionChange
|
||||
|
||||
void installEventFilter();
|
||||
void setupWidget();
|
||||
@@ -746,10 +747,12 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand)
|
||||
enterInsertMode();
|
||||
m_submode = NoSubMode;
|
||||
} else if (m_submode == DeleteSubMode) {
|
||||
if (m_movetype == MoveInclusive)
|
||||
moveRight(); // correction
|
||||
if (anchor() >= position())
|
||||
m_anchor++;
|
||||
if (m_rangemode == RangeCharMode) {
|
||||
if (m_movetype == MoveInclusive)
|
||||
moveRight(); // correction
|
||||
if (anchor() >= position())
|
||||
m_anchor++;
|
||||
}
|
||||
if (!dotCommand.isEmpty())
|
||||
setDotCommand("d" + dotCommand);
|
||||
yankSelectedText();
|
||||
@@ -761,8 +764,13 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand)
|
||||
setTargetColumn();
|
||||
} else if (m_submode == YankSubMode) {
|
||||
yankSelectedText();
|
||||
setPosition(m_savedYankPosition);
|
||||
m_submode = NoSubMode;
|
||||
if (m_register != '"') {
|
||||
setPosition(m_marks[m_register]);
|
||||
moveToStartOfLine();
|
||||
} else {
|
||||
setPosition(m_savedYankPosition);
|
||||
}
|
||||
} else if (m_submode == ReplaceSubMode) {
|
||||
m_submode = NoSubMode;
|
||||
} else if (m_submode == IndentSubMode) {
|
||||
@@ -941,6 +949,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
} else if (m_submode == RegisterSubMode) {
|
||||
m_register = key;
|
||||
m_submode = NoSubMode;
|
||||
m_rangemode = RangeLineMode;
|
||||
} else if (m_submode == ChangeSubMode && key == 'c') { // tested
|
||||
moveDown(count() - 1);
|
||||
moveToEndOfLine();
|
||||
@@ -964,14 +973,6 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
moveToFirstNonBlankOnLine();
|
||||
setTargetColumn();
|
||||
finishMovement();
|
||||
} else if (m_submode == YankSubMode && key == 'y') {
|
||||
m_movetype = MoveLineWise;
|
||||
int endPos = firstPositionInLine(lineForPosition(position()) + count() - 1);
|
||||
Range range(position(), endPos, RangeLineMode);
|
||||
///range.extendByLines(count() - 1);
|
||||
yankText(range);
|
||||
m_submode = NoSubMode;
|
||||
finishMovement();
|
||||
} else if (m_submode == ShiftLeftSubMode && key == '<') {
|
||||
setAnchor();
|
||||
moveDown(count() - 1);
|
||||
@@ -1232,9 +1233,16 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
} else if (key == control('c')) {
|
||||
showBlackMessage("Type Alt-v,Alt-v to quit FakeVim mode");
|
||||
} else if (key == 'd' && m_visualMode == NoVisualMode) {
|
||||
if (atEndOfLine())
|
||||
moveLeft();
|
||||
setAnchor();
|
||||
if (m_rangemode == RangeLineMode) {
|
||||
m_savedYankPosition = m_tc.position();
|
||||
moveToEndOfLine();
|
||||
setAnchor();
|
||||
setPosition(m_savedYankPosition);
|
||||
} else {
|
||||
if (atEndOfLine())
|
||||
moveLeft();
|
||||
setAnchor();
|
||||
}
|
||||
m_opcount = m_mvcount;
|
||||
m_mvcount.clear();
|
||||
m_submode = DeleteSubMode;
|
||||
@@ -1271,7 +1279,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
} else if (key == 'e') { // tested
|
||||
m_movetype = MoveInclusive;
|
||||
moveToWordBoundary(false, true);
|
||||
finishMovement();
|
||||
finishMovement("e");
|
||||
} else if (key == 'E') {
|
||||
m_movetype = MoveInclusive;
|
||||
moveToWordBoundary(true, true);
|
||||
@@ -1512,13 +1520,30 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
removeSelectedText();
|
||||
}
|
||||
finishMovement();
|
||||
} else if (key == 'y' && m_visualMode == NoVisualMode) {
|
||||
m_savedYankPosition = m_tc.position();
|
||||
if (atEndOfLine())
|
||||
moveLeft();
|
||||
setAnchor();
|
||||
} else if ((m_submode == YankSubMode && key == 'y')
|
||||
|| (key == 'Y' && m_visualMode == NoVisualMode)) {
|
||||
const int line = cursorLineInDocument() + 1;
|
||||
m_savedYankPosition = position();
|
||||
setAnchor(firstPositionInLine(line));
|
||||
setPosition(lastPositionInLine(line+count() - 1));
|
||||
if (count() > 1)
|
||||
showBlackMessage(QString("%1 lines yanked").arg(count()));
|
||||
m_rangemode = RangeLineMode;
|
||||
m_movetype = MoveLineWise;
|
||||
m_submode = YankSubMode;
|
||||
finishMovement();
|
||||
} else if (key == 'y' && m_visualMode == NoVisualMode) {
|
||||
if (m_rangemode == RangeLineMode) {
|
||||
m_savedYankPosition = position();
|
||||
setAnchor(firstPositionInLine(cursorLineInDocument() + 1));
|
||||
} else {
|
||||
m_savedYankPosition = position();
|
||||
if (atEndOfLine())
|
||||
moveLeft();
|
||||
setAnchor();
|
||||
m_rangemode = RangeCharMode;
|
||||
}
|
||||
m_submode = YankSubMode;
|
||||
m_rangemode = RangeCharMode;
|
||||
} else if (key == 'y' && m_visualMode == VisualCharMode) {
|
||||
Range range(position(), anchor(), RangeCharMode);
|
||||
range.endPos++; // MoveInclusive
|
||||
@@ -1526,13 +1551,6 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
|
||||
setPosition(qMin(position(), anchor()));
|
||||
leaveVisualMode();
|
||||
finishMovement();
|
||||
} else if (key == 'Y' && m_visualMode == NoVisualMode) {
|
||||
const int line = cursorLineInDocument() + 1;
|
||||
selectRange(line, line + count() - 1);
|
||||
m_rangemode = RangeLineMode;
|
||||
yankSelectedText();
|
||||
setPosition(qMin(position(), anchor()));
|
||||
finishMovement();
|
||||
} else if ((key == 'y' && m_visualMode == VisualLineMode)
|
||||
|| (key == 'Y' && m_visualMode == VisualLineMode)
|
||||
|| (key == 'Y' && m_visualMode == VisualCharMode)) {
|
||||
@@ -2476,6 +2494,12 @@ QString FakeVimHandler::Private::text(const Range &range) const
|
||||
tc.setPosition(range.endPos, KeepAnchor);
|
||||
return tc.selection().toPlainText();
|
||||
}
|
||||
if (range.rangemode == RangeLineMode) {
|
||||
QTextCursor tc = m_tc;
|
||||
tc.setPosition(firstPositionInLine(lineForPosition(range.beginPos)), MoveAnchor);
|
||||
tc.setPosition(firstPositionInLine(lineForPosition(range.endPos)+1), KeepAnchor);
|
||||
return tc.selection().toPlainText();
|
||||
}
|
||||
// FIXME: Performance?
|
||||
int beginLine = lineForPosition(range.beginPos);
|
||||
int endLine = lineForPosition(range.endPos);
|
||||
@@ -2536,6 +2560,7 @@ void FakeVimHandler::Private::removeText(const Range &range)
|
||||
case RangeCharMode: {
|
||||
tc.setPosition(range.beginPos, MoveAnchor);
|
||||
tc.setPosition(range.endPos, KeepAnchor);
|
||||
fixMarks(range.beginPos, tc.selectionStart() - tc.selectionEnd());
|
||||
tc.removeSelectedText();
|
||||
return;
|
||||
}
|
||||
@@ -2545,6 +2570,7 @@ void FakeVimHandler::Private::removeText(const Range &range)
|
||||
tc.setPosition(range.endPos, KeepAnchor);
|
||||
tc.movePosition(EndOfLine, KeepAnchor);
|
||||
tc.movePosition(Right, KeepAnchor, 1);
|
||||
fixMarks(range.beginPos, tc.selectionStart() - tc.selectionEnd());
|
||||
tc.removeSelectedText();
|
||||
return;
|
||||
}
|
||||
@@ -2564,6 +2590,7 @@ void FakeVimHandler::Private::removeText(const Range &range)
|
||||
int eCol = qMin(endColumn, block.length() - 1);
|
||||
tc.setPosition(block.position() + bCol, MoveAnchor);
|
||||
tc.setPosition(block.position() + eCol, KeepAnchor);
|
||||
fixMarks(block.position() + bCol, tc.selectionStart() - tc.selectionEnd());
|
||||
tc.removeSelectedText();
|
||||
block = block.previous();
|
||||
}
|
||||
@@ -2582,6 +2609,7 @@ void FakeVimHandler::Private::pasteText(bool afterCursor)
|
||||
for (int i = count(); --i >= 0; ) {
|
||||
if (afterCursor && rightDist() > 0)
|
||||
moveRight();
|
||||
fixMarks(position(), text.length());
|
||||
m_tc.insertText(text);
|
||||
moveLeft();
|
||||
}
|
||||
@@ -2593,6 +2621,7 @@ void FakeVimHandler::Private::pasteText(bool afterCursor)
|
||||
for (int i = count(); --i >= 0; ) {
|
||||
if (afterCursor)
|
||||
moveDown();
|
||||
fixMarks(position(), text.length());
|
||||
m_tc.insertText(text);
|
||||
moveUp(lines.size() - 1);
|
||||
}
|
||||
@@ -2611,16 +2640,19 @@ void FakeVimHandler::Private::pasteText(bool afterCursor)
|
||||
tc.movePosition(StartOfLine, MoveAnchor);
|
||||
if (col >= block.length()) {
|
||||
tc.movePosition(EndOfLine, MoveAnchor);
|
||||
fixMarks(position(), QString(col - line.size() + 1, QChar(' ')).length());
|
||||
tc.insertText(QString(col - line.size() + 1, QChar(' ')));
|
||||
} else {
|
||||
tc.movePosition(Right, MoveAnchor, col);
|
||||
}
|
||||
qDebug() << "INSERT " << line << " AT " << tc.position()
|
||||
<< "COL: " << col;
|
||||
fixMarks(position(), line.length());
|
||||
tc.insertText(line);
|
||||
tc.movePosition(StartOfLine, MoveAnchor);
|
||||
tc.movePosition(Down, MoveAnchor, 1);
|
||||
if (tc.position() >= lastPositionInDocument() - 1) {
|
||||
fixMarks(position(), QString(QChar('\n')).length());
|
||||
tc.insertText(QString(QChar('\n')));
|
||||
tc.movePosition(Up, MoveAnchor, 1);
|
||||
}
|
||||
@@ -2632,6 +2664,21 @@ void FakeVimHandler::Private::pasteText(bool afterCursor)
|
||||
}
|
||||
}
|
||||
|
||||
//FIXME: This needs to called after undo/insert
|
||||
void FakeVimHandler::Private::fixMarks(int positionAction, int positionChange)
|
||||
{
|
||||
QHashIterator<int, int> i(m_marks);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
if (i.value() >= positionAction) {
|
||||
if (i.value() + positionChange > 0)
|
||||
m_marks[i.key()] = i.value() + positionChange;
|
||||
else
|
||||
m_marks.remove(i.key());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int FakeVimHandler::Private::firstPositionInLine(int line) const
|
||||
{
|
||||
return m_tc.document()->findBlockByNumber(line - 1).position();
|
||||
|
||||
@@ -73,7 +73,9 @@ private slots:
|
||||
void command_up();
|
||||
void command_w();
|
||||
void command_yyp();
|
||||
void command_Yp();
|
||||
void command_Gyyp();
|
||||
void command_ma_yank();
|
||||
|
||||
// special tests
|
||||
void test_i_cw_i();
|
||||
@@ -485,6 +487,24 @@ void tst_FakeVim::command_yyp()
|
||||
check("yyp", lmid(0, 4) + "\n" + lmid(4, 1) + "\n@" + lmid(4));
|
||||
}
|
||||
|
||||
void tst_FakeVim::command_Yp()
|
||||
{
|
||||
setup();
|
||||
move("4j", "@int main");
|
||||
check("Yp", lmid(0, 4) + "\n" + lmid(4, 1) + "\n@" + lmid(4));
|
||||
}
|
||||
|
||||
void tst_FakeVim::command_ma_yank()
|
||||
{
|
||||
setup();
|
||||
check("ma", "@" + lmid(0));
|
||||
move("4j", "@int main");
|
||||
check("mb", lmid(0,4) + "\n@" + lmid(4));
|
||||
check("\"ay'a", "@" + lmid(0));
|
||||
check("'b", lmid(0,4) + "\n@" + lmid(4));
|
||||
check("\"ap", lmid(0,5) + "\n@" + lmid(0,4) +"\n" + lmid(4));
|
||||
}
|
||||
|
||||
void tst_FakeVim::command_Gyyp()
|
||||
{
|
||||
qWarning("FIXME");
|
||||
|
||||
Reference in New Issue
Block a user