Commit c172e9b1 authored by hjk's avatar hjk
Browse files

fakevim: autotests for 'e', 'dd', 'w', 'cc'

parent ef1311d0
fakevim is based on eventFilters installed on a QTextEdit or a QPlainTextEdit.
It basically catches all keystrokes and modifies some internal state that
make the resulting text in the editor look like it was using vim.
There are only a few files in here:
fakevimplugin.{h,cpp} - interaction with the rest of Creator
fakevimactions.{h,cpp} - settings
fakevimhandler.{h,cpp} - the "real" event
There are some more hints for developers in fakevimhandler.cpp
...@@ -29,28 +29,33 @@ ...@@ -29,28 +29,33 @@
#include "fakevimhandler.h" #include "fakevimhandler.h"
// Please do not add any direct dependencies to other Qt Creator code here.
// Instead emit signals and let the FakeVimPlugin channel the information to
// Qt Creator. The idea is to keep this file here in a "clean" state that
// allows easy reuse with any QTextEdit or QPlainTextEdit derived class.
// Some conventions:
// //
// Use 1 based line numbers and 0 based column numbers. Even though // ATTENTION:
// the 1 based line are not nice it matches vim's and QTextEdit's 'line' //
// concepts. // 1 Please do not add any direct dependencies to other Qt Creator code here.
// Instead emit signals and let the FakeVimPlugin channel the information to
// Qt Creator. The idea is to keep this file here in a "clean" state that
// allows easy reuse with any QTextEdit or QPlainTextEdit derived class.
//
// 2 There are a few auto tests located in ../../../tests/auto/fakevim.
// Commands that are covered there are marked as "// tested" below.
//
// 3 Some conventions:
// //
// Do not pass QTextCursor etc around unless really needed. Convert // Use 1 based line numbers and 0 based column numbers. Even though
// early to line/column. // the 1 based line are not nice it matches vim's and QTextEdit's 'line'
// concepts.
// //
// There is always a "current" cursor (m_tc). A current "region of interest" // Do not pass QTextCursor etc around unless really needed. Convert
// spans between m_anchor (== anchor()) and m_tc.position() (== position()) // early to line/column.
// The value of m_tc.anchor() is not used. //
// There is always a "current" cursor (m_tc). A current "region of interest"
// spans between m_anchor (== anchor()) and m_tc.position() (== position())
// The value of m_tc.anchor() is not used.
//
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <QtCore/QDebug> #include <QtCore/QDebug>
#include <QtCore/QFile> #include <QtCore/QFile>
#include <QtCore/QObject> #include <QtCore/QObject>
...@@ -278,7 +283,7 @@ public: ...@@ -278,7 +283,7 @@ public:
typedef QTextCursor::MoveOperation MoveOperation; typedef QTextCursor::MoveOperation MoveOperation;
typedef QTextCursor::MoveMode MoveMode; typedef QTextCursor::MoveMode MoveMode;
void moveToEndOfDocument() { m_tc.movePosition(EndOfDocument, MoveAnchor); } void moveToEndOfDocument() { m_tc.movePosition(EndOfDocument, MoveAnchor); }
void moveToStartOfLine() { m_tc.movePosition(StartOfLine, MoveAnchor); } void moveToStartOfLine();
void moveToEndOfLine(); void moveToEndOfLine();
void moveUp(int n = 1) { moveDown(-n); } void moveUp(int n = 1) { moveDown(-n); }
void moveDown(int n = 1); // { m_tc.movePosition(Down, MoveAnchor, n); } void moveDown(int n = 1); // { m_tc.movePosition(Down, MoveAnchor, n); }
...@@ -353,6 +358,8 @@ public: ...@@ -353,6 +358,8 @@ public:
// extra data for '.' // extra data for '.'
void replay(const QString &text, int count); void replay(const QString &text, int count);
void setDotCommand(const QString &cmd) { m_dotCommand = cmd; }
void setDotCommand(const QString &cmd, int n) { m_dotCommand = cmd.arg(n); }
QString m_dotCommand; QString m_dotCommand;
bool m_inReplay; // true if we are executing a '.' bool m_inReplay; // true if we are executing a '.'
...@@ -632,6 +639,17 @@ void FakeVimHandler::Private::moveToEndOfLine() ...@@ -632,6 +639,17 @@ void FakeVimHandler::Private::moveToEndOfLine()
#endif #endif
} }
void FakeVimHandler::Private::moveToStartOfLine()
{
#if 0
// does not work for "hidden" documents like in the autotests
m_tc.movePosition(StartOfLine, MoveAnchor);
#else
const QTextBlock &block = m_tc.block();
setPosition(block.position());
#endif
}
void FakeVimHandler::Private::finishMovement(const QString &dotCommand) void FakeVimHandler::Private::finishMovement(const QString &dotCommand)
{ {
//qDebug() << "ANCHOR: " << position() << anchor(); //qDebug() << "ANCHOR: " << position() << anchor();
...@@ -656,7 +674,7 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand) ...@@ -656,7 +674,7 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand)
if (anchor() >= position()) if (anchor() >= position())
m_anchor++; m_anchor++;
if (!dotCommand.isEmpty()) if (!dotCommand.isEmpty())
m_dotCommand = "c" + dotCommand; setDotCommand("c" + dotCommand);
QString text = removeSelectedText(); QString text = removeSelectedText();
//qDebug() << "CHANGING TO INSERT MODE" << text; //qDebug() << "CHANGING TO INSERT MODE" << text;
m_registers[m_register] = text; m_registers[m_register] = text;
...@@ -668,7 +686,7 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand) ...@@ -668,7 +686,7 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand)
if (anchor() >= position()) if (anchor() >= position())
m_anchor++; m_anchor++;
if (!dotCommand.isEmpty()) if (!dotCommand.isEmpty())
m_dotCommand = "d" + dotCommand; setDotCommand("d" + dotCommand);
m_registers[m_register] = removeSelectedText(); m_registers[m_register] = removeSelectedText();
m_submode = NoSubMode; m_submode = NoSubMode;
if (atEndOfLine()) if (atEndOfLine())
...@@ -694,8 +712,6 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand) ...@@ -694,8 +712,6 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand)
updateMiniBuffer(); updateMiniBuffer();
} }
moveToTargetColumn();
m_moveType = MoveInclusive; m_moveType = MoveInclusive;
m_mvcount.clear(); m_mvcount.clear();
m_opcount.clear(); m_opcount.clear();
...@@ -847,13 +863,19 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified, ...@@ -847,13 +863,19 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
} else if (m_submode == RegisterSubMode) { } else if (m_submode == RegisterSubMode) {
m_register = key; m_register = key;
m_submode = NoSubMode; m_submode = NoSubMode;
} else if (m_submode == ChangeSubMode && key == 'c') { } else if (m_submode == ChangeSubMode && key == 'c') { // tested
moveToStartOfLine(); moveDown(count() - 1);
moveToEndOfLine();
moveLeft();
setAnchor(); setAnchor();
moveDown(count()); moveToStartOfLine();
setTargetColumn();
moveUp(count() - 1);
m_moveType = MoveLineWise; m_moveType = MoveLineWise;
finishMovement("c"); m_lastInsertion.clear();
} else if (m_submode == DeleteSubMode && key == 'd') { setDotCommand("%1cc", count());
finishMovement();
} else if (m_submode == DeleteSubMode && key == 'd') { // tested
moveToStartOfLine(); moveToStartOfLine();
setAnchor(); setAnchor();
moveDown(count()); moveDown(count());
...@@ -869,19 +891,19 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified, ...@@ -869,19 +891,19 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
setAnchor(); setAnchor();
moveDown(count() - 1); moveDown(count() - 1);
m_moveType = MoveLineWise; m_moveType = MoveLineWise;
m_dotCommand = QString("%1<<").arg(count()); setDotCommand("%1<<", count());
finishMovement(); finishMovement();
} else if (m_submode == ShiftRightSubMode && key == '>') { } else if (m_submode == ShiftRightSubMode && key == '>') {
setAnchor(); setAnchor();
moveDown(count() - 1); moveDown(count() - 1);
m_moveType = MoveLineWise; m_moveType = MoveLineWise;
m_dotCommand = QString("%1>>").arg(count()); setDotCommand("%1>>", count());
finishMovement(); finishMovement();
} else if (m_submode == IndentSubMode && key == '=') { } else if (m_submode == IndentSubMode && key == '=') {
setAnchor(); setAnchor();
moveDown(count() - 1); moveDown(count() - 1);
m_moveType = MoveLineWise; m_moveType = MoveLineWise;
m_dotCommand = QString("%1>>").arg(count()); setDotCommand("%1>>", count());
finishMovement(); finishMovement();
} else if (m_submode == ZSubMode) { } else if (m_submode == ZSubMode) {
//qDebug() << "Z_MODE " << cursorLineInDocument() << linesOnScreen(); //qDebug() << "Z_MODE " << cursorLineInDocument() << linesOnScreen();
...@@ -928,7 +950,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified, ...@@ -928,7 +950,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
m_tc.insertText(QString(count(), text.at(0))); m_tc.insertText(QString(count(), text.at(0)));
m_moveType = MoveExclusive; m_moveType = MoveExclusive;
m_submode = NoSubMode; m_submode = NoSubMode;
m_dotCommand = QString("%1r%2").arg(count()).arg(text); setDotCommand("%1r" + text, count());
finishMovement(); finishMovement();
} else { } else {
m_submode = NoSubMode; m_submode = NoSubMode;
...@@ -1125,7 +1147,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified, ...@@ -1125,7 +1147,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
handleStartOfLine(); handleStartOfLine();
scrollToLineInDocument(cursorLineInDocument() - sline); scrollToLineInDocument(cursorLineInDocument() - sline);
finishMovement(); finishMovement();
} else if (key == 'e') { } else if (key == 'e') { // tested
m_moveType = MoveInclusive; m_moveType = MoveInclusive;
moveToWordBoundary(false, true); moveToWordBoundary(false, true);
finishMovement(); finishMovement();
...@@ -1175,13 +1197,13 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified, ...@@ -1175,13 +1197,13 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
handleStartOfLine(); handleStartOfLine();
finishMovement(); finishMovement();
} else if (key == 'i') { } else if (key == 'i') {
m_dotCommand = "i"; //QString("%1i").arg(count()); setDotCommand("i"); // setDotCommand("%1i", count());
enterInsertMode(); enterInsertMode();
updateMiniBuffer(); updateMiniBuffer();
if (atEndOfLine()) if (atEndOfLine())
moveLeft(); moveLeft();
} else if (key == 'I') { } else if (key == 'I') {
m_dotCommand = "I"; //QString("%1I").arg(count()); setDotCommand("I"); // setDotCommand("%1I", count());
enterInsertMode(); enterInsertMode();
if (m_gflag) if (m_gflag)
moveToStartOfLine(); moveToStartOfLine();
...@@ -1256,7 +1278,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified, ...@@ -1256,7 +1278,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
search(lastSearchString(), !m_lastSearchForward); search(lastSearchString(), !m_lastSearchForward);
recordJump(); recordJump();
} else if (key == 'o' || key == 'O') { } else if (key == 'o' || key == 'O') {
m_dotCommand = QString("%1o").arg(count()); setDotCommand("%1o", count());
enterInsertMode(); enterInsertMode();
moveToFirstNonBlankOnLine(); moveToFirstNonBlankOnLine();
if (key == 'O') if (key == 'O')
...@@ -1293,18 +1315,18 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified, ...@@ -1293,18 +1315,18 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
moveLeft(); moveLeft();
} }
} }
m_dotCommand = QString("%1p").arg(count()); setDotCommand("%1p", count());
finishMovement(); finishMovement();
} else if (key == 'r') { } else if (key == 'r') {
m_submode = ReplaceSubMode; m_submode = ReplaceSubMode;
m_dotCommand = "r"; setDotCommand("r");
} else if (key == 'R') { } else if (key == 'R') {
// FIXME: right now we repeat the insertion count() times, // FIXME: right now we repeat the insertion count() times,
// but not the deletion // but not the deletion
m_lastInsertion.clear(); m_lastInsertion.clear();
m_mode = InsertMode; m_mode = InsertMode;
m_submode = ReplaceSubMode; m_submode = ReplaceSubMode;
m_dotCommand = "R"; setDotCommand("R");
} else if (key == control('r')) { } else if (key == control('r')) {
redo(); redo();
} else if (key == 's') { } else if (key == 's') {
...@@ -1313,7 +1335,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified, ...@@ -1313,7 +1335,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
setAnchor(); setAnchor();
moveRight(qMin(count(), rightDist())); moveRight(qMin(count(), rightDist()));
m_registers[m_register] = removeSelectedText(); m_registers[m_register] = removeSelectedText();
m_dotCommand = "s"; //QString("%1s").arg(count()); setDotCommand("s"); // setDotCommand("%1s", count());
m_opcount.clear(); m_opcount.clear();
m_mvcount.clear(); m_mvcount.clear();
enterInsertMode(); enterInsertMode();
...@@ -1340,7 +1362,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified, ...@@ -1340,7 +1362,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
enterVisualMode(VisualLineMode); enterVisualMode(VisualLineMode);
} else if (key == control('v')) { } else if (key == control('v')) {
enterVisualMode(VisualBlockMode); enterVisualMode(VisualBlockMode);
} else if (key == 'w') { } else if (key == 'w') { // tested
// Special case: "cw" and "cW" work the same as "ce" and "cE" if the // Special case: "cw" and "cW" work the same as "ce" and "cE" if the
// cursor is on a non-blank. // cursor is on a non-blank.
if (m_submode == ChangeSubMode) { if (m_submode == ChangeSubMode) {
...@@ -1369,7 +1391,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified, ...@@ -1369,7 +1391,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
setAnchor(); setAnchor();
m_submode = DeleteSubMode; m_submode = DeleteSubMode;
moveRight(qMin(count(), rightDist())); moveRight(qMin(count(), rightDist()));
m_dotCommand = QString("%1x").arg(count()); setDotCommand("%1x", count());
finishMovement(); finishMovement();
} else if (key == 'X') { } else if (key == 'X') {
if (leftDist() > 0) { if (leftDist() > 0) {
...@@ -1957,16 +1979,16 @@ void FakeVimHandler::Private::highlightMatches(const QString &needle0) ...@@ -1957,16 +1979,16 @@ void FakeVimHandler::Private::highlightMatches(const QString &needle0)
void FakeVimHandler::Private::moveToFirstNonBlankOnLine() void FakeVimHandler::Private::moveToFirstNonBlankOnLine()
{ {
QTextBlock block = m_tc.block();
QTextDocument *doc = m_tc.document(); QTextDocument *doc = m_tc.document();
m_tc.movePosition(StartOfLine, KeepAnchor); const QTextBlock &block = m_tc.block();
int firstPos = m_tc.position(); int firstPos = block.position();
for (int i = firstPos, n = firstPos + block.length(); i < n; ++i) { for (int i = firstPos, n = firstPos + block.length(); i < n; ++i) {
if (!doc->characterAt(i).isSpace()) { if (!doc->characterAt(i).isSpace()) {
m_tc.setPosition(i, KeepAnchor); setPosition(i);
return; return;
} }
} }
setPosition(block.position());
} }
void FakeVimHandler::Private::indentRegion(QChar typedChar) void FakeVimHandler::Private::indentRegion(QChar typedChar)
...@@ -1978,7 +2000,7 @@ void FakeVimHandler::Private::indentRegion(QChar typedChar) ...@@ -1978,7 +2000,7 @@ void FakeVimHandler::Private::indentRegion(QChar typedChar)
qSwap(beginLine, endLine); qSwap(beginLine, endLine);
int amount = 0; int amount = 0;
emit q->indentRegion(&amount, beginLine, endLine, typedChar); emit q->indentRegion(&amount, beginLine, endLine, typedChar);
m_dotCommand = QString("%1==").arg(endLine - beginLine + 1); setDotCommand("%1==", endLine - beginLine + 1);
} }
void FakeVimHandler::Private::shiftRegionRight(int repeat) void FakeVimHandler::Private::shiftRegionRight(int repeat)
...@@ -2000,7 +2022,7 @@ void FakeVimHandler::Private::shiftRegionRight(int repeat) ...@@ -2000,7 +2022,7 @@ void FakeVimHandler::Private::shiftRegionRight(int repeat)
setPosition(firstPos); setPosition(firstPos);
moveToFirstNonBlankOnLine(); moveToFirstNonBlankOnLine();
m_dotCommand = QString("%1>>").arg(endLine - beginLine + 1); setDotCommand("%1>>", endLine - beginLine + 1);
} }
void FakeVimHandler::Private::shiftRegionLeft(int repeat) void FakeVimHandler::Private::shiftRegionLeft(int repeat)
...@@ -2037,17 +2059,20 @@ void FakeVimHandler::Private::shiftRegionLeft(int repeat) ...@@ -2037,17 +2059,20 @@ void FakeVimHandler::Private::shiftRegionLeft(int repeat)
setPosition(firstPos); setPosition(firstPos);
moveToFirstNonBlankOnLine(); moveToFirstNonBlankOnLine();
m_dotCommand = QString("%1<<").arg(endLine - beginLine + 1); setDotCommand("%1<<", endLine - beginLine + 1);
} }
void FakeVimHandler::Private::moveToTargetColumn() void FakeVimHandler::Private::moveToTargetColumn()
{ {
if (m_targetColumn == -1 || m_tc.block().length() <= m_targetColumn) { const QTextBlock &block = m_tc.block();
const QTextBlock &block = m_tc.block(); int col = m_tc.position() - m_tc.block().position();
if (col == m_targetColumn)
return;
//qDebug() << "CORRECTING COLUMN FROM: " << col << "TO" << m_targetColumn;
if (m_targetColumn == -1 || m_tc.block().length() <= m_targetColumn)
m_tc.setPosition(block.position() + block.length() - 1, KeepAnchor); m_tc.setPosition(block.position() + block.length() - 1, KeepAnchor);
} else { else
m_tc.setPosition(m_tc.block().position() + m_targetColumn, KeepAnchor); m_tc.setPosition(m_tc.block().position() + m_targetColumn, KeepAnchor);
}
} }
/* if simple is given: /* if simple is given:
...@@ -2075,7 +2100,7 @@ void FakeVimHandler::Private::moveToWordBoundary(bool simple, bool forward) ...@@ -2075,7 +2100,7 @@ void FakeVimHandler::Private::moveToWordBoundary(bool simple, bool forward)
int lastClass = -1; int lastClass = -1;
while (true) { while (true) {
QChar c = doc->characterAt(m_tc.position() + (forward ? 1 : -1)); QChar c = doc->characterAt(m_tc.position() + (forward ? 1 : -1));
qDebug() << "EXAMINING: " << c << " AT " << position(); //qDebug() << "EXAMINING: " << c << " AT " << position();
int thisClass = charClass(c, simple); int thisClass = charClass(c, simple);
if (thisClass != lastClass && lastClass != 0) if (thisClass != lastClass && lastClass != 0)
--repeat; --repeat;
...@@ -2319,6 +2344,7 @@ QString FakeVimHandler::Private::removeSelectedText() ...@@ -2319,6 +2344,7 @@ QString FakeVimHandler::Private::removeSelectedText()
m_tc.setPosition(pos, KeepAnchor); m_tc.setPosition(pos, KeepAnchor);
QString from = m_tc.selection().toPlainText(); QString from = m_tc.selection().toPlainText();
m_tc.removeSelectedText(); m_tc.removeSelectedText();
setAnchor();
return from; return from;
} }
......
...@@ -55,13 +55,17 @@ public slots: ...@@ -55,13 +55,17 @@ public slots:
void changeExtraInformation(const QString &info) { m_infoMessage = info; } void changeExtraInformation(const QString &info) { m_infoMessage = info; }
private slots: private slots:
void commandDollar(); // command mode
void commandDown(); void command_cc();
void commandLeft(); void command_dd();
void commandRight(); void command_dollar();
void commandI(); void command_down();
void commandUp(); void command_e();
void commandW(); void command_i();
void command_left();
void command_right();
void command_up();
void command_w();
private: private:
void setup(); void setup();
...@@ -73,6 +77,9 @@ private: ...@@ -73,6 +77,9 @@ private:
const char* file, int line); const char* file, int line);
QString insertCursor(const QString &needle0); QString insertCursor(const QString &needle0);
QString lmid(int i, int n = -1) const
{ return QStringList(l.mid(i, n)).join("\n"); }
QTextEdit *m_textedit; QTextEdit *m_textedit;
QPlainTextEdit *m_plaintextedit; QPlainTextEdit *m_plaintextedit;
FakeVimHandler *m_handler; FakeVimHandler *m_handler;
...@@ -82,6 +89,8 @@ private: ...@@ -82,6 +89,8 @@ private:
QString m_statusData; QString m_statusData;
QString m_infoMessage; QString m_infoMessage;
// the individual lines
static const QStringList l; // identifier intentionally kept short
static const QString lines; static const QString lines;
static const QString escape; static const QString escape;
}; };
...@@ -100,8 +109,11 @@ const QString tst_FakeVim::lines = ...@@ -100,8 +109,11 @@ const QString tst_FakeVim::lines =
" return app.exec();\n" " return app.exec();\n"
"}\n"; "}\n";
const QStringList tst_FakeVim::l = tst_FakeVim::lines.split('\n');
const QString tst_FakeVim::escape = QChar(27); const QString tst_FakeVim::escape = QChar(27);
tst_FakeVim::tst_FakeVim(bool usePlainTextEdit) tst_FakeVim::tst_FakeVim(bool usePlainTextEdit)
{ {
if (usePlainTextEdit) { if (usePlainTextEdit) {
...@@ -170,16 +182,16 @@ bool tst_FakeVim::checkContentsHelper(QString want, const char* file, int line) ...@@ -170,16 +182,16 @@ bool tst_FakeVim::checkContentsHelper(QString want, const char* file, int line)
QStringList wantlist = want.split('\n'); QStringList wantlist = want.split('\n');
QStringList gotlist = got.split('\n'); QStringList gotlist = got.split('\n');
if (!QTest::qCompare(gotlist.size(), wantlist.size(), "", "", file, line)) { if (!QTest::qCompare(gotlist.size(), wantlist.size(), "", "", file, line)) {
qDebug() << "WANT: " << want; qDebug() << "0 WANT: " << want;
qDebug() << "GOT: " << got; qDebug() << "0 GOT: " << got;
return false; return false;
} }
for (int i = 0; i < wantlist.size() && i < gotlist.size(); ++i) { for (int i = 0; i < wantlist.size() && i < gotlist.size(); ++i) {
QString g = QString("line %1: %2").arg(i + 1).arg(gotlist.at(i)); QString g = QString("line %1: %2").arg(i + 1).arg(gotlist.at(i));
QString w = QString("line %1: %2").arg(i + 1).arg(wantlist.at(i)); QString w = QString("line %1: %2").arg(i + 1).arg(wantlist.at(i));
if (!QTest::qCompare(g, w, "", "", file, line)) { if (!QTest::qCompare(g, w, "", "", file, line)) {
qDebug() << "WANT: " << want; qDebug() << "1 WANT: " << want;
qDebug() << "GOT: " << got; qDebug() << "1 GOT: " << got;
return false; return false;
} }
} }
...@@ -222,11 +234,77 @@ QString tst_FakeVim::insertCursor(const QString &needle0) ...@@ -222,11 +234,77 @@ QString tst_FakeVim::insertCursor(const QString &needle0)
needle.remove('@'); needle.remove('@');
QString lines0 = lines; QString lines0 = lines;
int pos = lines0.indexOf(needle); int pos = lines0.indexOf(needle);
if (pos == -1)
qDebug() << "Cannot find: \n----\n" + needle + "\n----\n";
lines0.replace(pos, needle.size(), needle0); lines0.replace(pos, needle.size(), needle0);
return lines0; return lines0;
} }
void tst_FakeVim::commandI()
//////////////////////////////////////////////////////////////////////////
//