diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp index c6a37e9f5b4..8b2d83b9fe3 100644 --- a/src/plugins/debugger/gdbengine.cpp +++ b/src/plugins/debugger/gdbengine.cpp @@ -233,6 +233,8 @@ void GdbEngine::initializeConnections() connect(theDebuggerAction(ExpandStack), SIGNAL(triggered()), this, SLOT(reloadFullStack())); + connect(theDebuggerAction(MaximalStackDepth), SIGNAL(triggered()), + this, SLOT(reloadFullStack())); } void GdbEngine::initializeVariables() diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index 44bb76028f1..f26d0ffcff4 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -278,9 +278,9 @@ public: typedef QTextCursor::MoveMode MoveMode; void moveToEndOfDocument() { m_tc.movePosition(EndOfDocument, MoveAnchor); } void moveToStartOfLine() { m_tc.movePosition(StartOfLine, MoveAnchor); } - void moveToEndOfLine() { m_tc.movePosition(EndOfLine, MoveAnchor); } - void moveUp(int n = 1) { m_tc.movePosition(Up, MoveAnchor, n); } - void moveDown(int n = 1) { m_tc.movePosition(Down, MoveAnchor, n); } + void moveToEndOfLine(); + void moveUp(int n = 1) { moveDown(-n); } + void moveDown(int n = 1); // { m_tc.movePosition(Down, MoveAnchor, n); } void moveRight(int n = 1) { m_tc.movePosition(Right, MoveAnchor, n); } void moveLeft(int n = 1) { m_tc.movePosition(Left, MoveAnchor, n); } void setAnchor() { m_anchor = m_tc.position(); } @@ -289,7 +289,7 @@ public: void handleFfTt(int key); - // helper function for handleCommand. return 1 based line index. + // helper function for handleExCommand. return 1 based line index. int readLineCode(QString &cmd); void selectRange(int beginLine, int endLine); @@ -351,7 +351,7 @@ public: bool m_needMoreUndo; // extra data for '.' - void replay(const QString &text); + void replay(const QString &text, int count); QString m_dotCommand; bool m_inReplay; // true if we are executing a '.' @@ -411,10 +411,13 @@ QStringList FakeVimHandler::Private::m_commandHistory; FakeVimHandler::Private::Private(FakeVimHandler *parent, QWidget *widget) { q = parent; - m_textedit = qobject_cast(widget); m_plaintextedit = qobject_cast(widget); + init(); +} +void FakeVimHandler::Private::init() +{ m_mode = CommandMode; m_submode = NoSubMode; m_subsubmode = NoSubSubMode; @@ -592,7 +595,6 @@ EventResult FakeVimHandler::Private::handleKey(int key, int unmodified, const QString &text) { //qDebug() << "KEY: " << key << text << "POS: " << m_tc.position(); - //qDebug() << "\nUNDO: " << m_undoStack << "\nREDO: " << m_redoStack; if (m_mode == InsertMode) return handleInsertMode(key, unmodified, text); if (m_mode == CommandMode) @@ -603,6 +605,26 @@ EventResult FakeVimHandler::Private::handleKey(int key, int unmodified, return EventUnhandled; } +void FakeVimHandler::Private::moveDown(int n) +{ + // m_tc.movePosition(Down, MoveAnchor, n); does not work for "hidden" + // documents like in the autotests + const QTextBlock &block = m_tc.block(); + const int col = m_tc.position() - block.position(); + const int line = block.blockNumber(); + const int pos = m_tc.document()->findBlockByNumber(line + n).position(); + setPosition(pos + qMin(block.length(), col)); + setPosition(pos); +} + +void FakeVimHandler::Private::moveToEndOfLine() +{ + // m_tc.movePosition(EndOfLine, MoveAnchor) does not work for "hidden" + // documents like in the autotests + const QTextBlock &block = m_tc.block(); + setPosition(block.position() + block.length() - 1); +} + void FakeVimHandler::Private::finishMovement(const QString &dotCommand) { //qDebug() << "ANCHOR: " << position() << anchor(); @@ -1012,7 +1034,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified, qDebug() << "REPEATING" << m_dotCommand; QString savedCommand = m_dotCommand; m_dotCommand.clear(); - replay(savedCommand); + replay(savedCommand, count()); enterCommandMode(); m_dotCommand = savedCommand; } else if (key == '<' && m_visualMode == NoVisualMode) { @@ -1647,6 +1669,7 @@ void FakeVimHandler::Private::selectRange(int beginLine, int endLine) void FakeVimHandler::Private::handleCommand(const QString &cmd) { m_tc = EDITOR(textCursor()); + init(); handleExCommand(cmd); EDITOR(setTextCursor(m_tc)); } @@ -1780,7 +1803,8 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0) updateMiniBuffer(); } else if (reNormal.indexIn(cmd) != -1) { // :normal enterCommandMode(); - replay(reNormal.cap(3)); + //qDebug() << "REPLAY: " << reNormal.cap(3); + replay(reNormal.cap(3), 1); } else if (reSet.indexIn(cmd) != -1) { // :set showBlackMessage(QString()); QString arg = reSet.cap(2); @@ -2353,11 +2377,11 @@ void FakeVimHandler::Private::handleStartOfLine() moveToFirstNonBlankOnLine(); } -void FakeVimHandler::Private::replay(const QString &command) +void FakeVimHandler::Private::replay(const QString &command, int n) { //qDebug() << "REPLAY: " << command; m_inReplay = true; - for (int i = count(); --i >= 0; ) + for (int i = n; --i >= 0; ) foreach (QChar c, command) handleKey(c.unicode(), c.unicode(), QString(c)); m_inReplay = false; diff --git a/tests/auto/fakevim/main.cpp b/tests/auto/fakevim/main.cpp index 700b25d63db..b82f1a13bcb 100644 --- a/tests/auto/fakevim/main.cpp +++ b/tests/auto/fakevim/main.cpp @@ -45,31 +45,35 @@ class tst_FakeVim : public QObject public: tst_FakeVim(); - void setup(); - void send(const QString &command); // send a normal command - void sendEx(const QString &command); // send an ex command - - QString cleaned(QString wanted) { wanted.remove('$'); return wanted; } - public slots: void changeStatusData(const QString &info) { m_statusData = info; } void changeStatusMessage(const QString &info) { m_statusMessage = info; } void changeExtraInformation(const QString &info) { m_infoMessage = info; } -public: - QString m_statusMessage; - QString m_statusData; - QString m_infoMessage; - private slots: void commandI(); void commandDollar(); + void commandDown(); + void commandUp(); private: + void setup(); + void send(const QString &command); // send a normal command + void sendEx(const QString &command); // send an ex command + + bool checkContentsHelper(QString expected, const char* file, int line); + bool checkHelper(bool isExCommand, QString cmd, QString expected, + const char* file, int line); + QString insertCursor(const QString &needle0); + QPlainTextEdit m_editor; FakeVimHandler m_handler; QList m_selection; + QString m_statusMessage; + QString m_statusData; + QString m_infoMessage; + static const QString lines; static const QString escape; }; @@ -91,7 +95,6 @@ const QString tst_FakeVim::escape = QChar(27); tst_FakeVim::tst_FakeVim() : m_handler(&m_editor, this) { - QObject::connect(&m_handler, SIGNAL(commandBufferChanged(QString)), this, SLOT(changeStatusMessage(QString))); QObject::connect(&m_handler, SIGNAL(extraInformationChanged(QString)), @@ -106,6 +109,12 @@ void tst_FakeVim::setup() m_statusData.clear(); m_infoMessage.clear(); m_editor.setPlainText(lines); + QTextCursor tc = m_editor.textCursor(); + tc.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); + m_editor.setTextCursor(tc); + m_editor.setPlainText(lines); + //m_editor.show(); + //qApp->exec(); QCOMPARE(m_editor.toPlainText(), lines); } @@ -119,75 +128,118 @@ void tst_FakeVim::sendEx(const QString &command) m_handler.handleCommand(command); } -#define checkContents(wanted) \ - do { QString want = cleaned(wanted); \ - QString got = m_editor.toPlainText(); \ - QStringList wantlist = want.split('\n'); \ - QStringList gotlist = got.split('\n'); \ - QCOMPARE(gotlist.size(), wantlist.size()); \ - 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 w = QString("line %1: %2").arg(i + 1).arg(wantlist.at(i)); \ - QCOMPARE(g, w); \ - } \ - } while (0) +bool tst_FakeVim::checkContentsHelper(QString want, const char* file, int line) +{ + QString got = m_editor.toPlainText(); + int pos = m_editor.textCursor().position(); + got = got.left(pos) + "@" + got.mid(pos); + QStringList wantlist = want.split('\n'); + QStringList gotlist = got.split('\n'); + if (!QTest::qCompare(gotlist.size(), wantlist.size(), "", "", file, line)) { + qDebug() << "WANT: " << want; + qDebug() << "GOT: " << got; + return false; + } + 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 w = QString("line %1: %2").arg(i + 1).arg(wantlist.at(i)); + if (!QTest::qCompare(g, w, "", "", file, line)) { + qDebug() << "WANT: " << want; + qDebug() << "GOT: " << got; + return false; + } + } + return true; +} -#define checkText(cmd, wanted) \ - do { \ - send(cmd); \ - checkContents(wanted); \ - int p = (wanted).indexOf('$'); \ - QCOMPARE(m_editor.textCursor().position(), p); \ - } while (0) +bool tst_FakeVim::checkHelper(bool ex, QString cmd, QString expected, + const char *file, int line) +{ + if (ex) + sendEx(cmd); + else + send(cmd); + return checkContentsHelper(expected, file, line); +} -#define checkTextEx(cmd, wanted) \ - do { \ - sendEx(cmd); \ - checkContents(wanted); \ - int p = (wanted).indexOf('$'); \ - QCOMPARE(m_editor.textCursor().position(), p); \ - } while (0) -#define checkPosition(cmd, pos) \ - do { \ - send(cmd); \ - QCOMPARE(m_editor.textCursor().position(), pos); \ - } while (0) +#define checkContents(expected) \ + do { if (!checkContentsHelper(expected, __FILE__, __LINE__)) return; } while (0) + +// Runs a "normal" command and checks the result. +// Cursor position is marked by a '@' in the expected contents. +#define check(cmd, expected) \ + do { if (!checkHelper(false, cmd, expected, __FILE__, __LINE__)) \ + return; } while (0) + +// Runs an ex command and checks the result. +// Cursor position is marked by a '@' in the expected contents. +#define checkEx(cmd, expected) \ + do { if (!checkHelper(true, cmd, expected, __FILE__, __LINE__)) \ + return; } while (0) + +QString tst_FakeVim::insertCursor(const QString &needle0) +{ + QString needle = needle0; + needle.remove('@'); + QString lines0 = lines; + lines0.replace(needle, needle0); + //qDebug() << "LINES: " << lines0; + return lines0; +} void tst_FakeVim::commandI() { + return; setup(); // empty insertion at start of document - checkText("i" + escape, "$" + lines); - checkText("u", "$" + lines); + check("i" + escape, "@" + lines); + check("u", "@" + lines); // small insertion at start of document - checkText("ix" + escape, "$x" + lines); - checkText("u", "$" + lines); + check("ix" + escape, "@x" + lines); + check("u", "@" + lines); // small insertion at start of document - checkText("ixxx" + escape, "xx$x" + lines); - checkText("u", "$" + lines); + check("ixxx" + escape, "xx@x" + lines); + check("u", "@" + lines); // combine insertions - checkText("ia" + escape, "$a" + lines); - checkText("ibx" + escape, "b$xa" + lines); - checkText("icyy" + escape, "bcy$yxa" + lines); - checkText("u", "b$xa" + lines); - checkText("u", "$a" + lines); // undo broken - checkTextEx("redo", "b$xa" + lines); - checkText("u", "$a" + lines); - checkText("u", "$" + lines); + check("ia" + escape, "@a" + lines); + check("ibx" + escape, "b@xa" + lines); + check("icyy" + escape, "bcy@yxa" + lines); + check("u", "b@xa" + lines); + check("u", "@a" + lines); // undo broken + checkEx("redo", "b@xa" + lines); + check("u", "@a" + lines); + check("u", "@" + lines); } void tst_FakeVim::commandDollar() { setup(); - checkPosition("$", 0); - checkPosition("j", 2); + check("j$", insertCursor("@")); + //check("j", insertCursor("@")); } +void tst_FakeVim::commandDown() +{ + setup(); + check("j", insertCursor("@#include