diff --git a/src/plugins/coreplugin/editormanager/editormanager.h b/src/plugins/coreplugin/editormanager/editormanager.h
index 1a855ab9f27558e876e8c85dcda56f4afb89d331..65112c00aef71e210e607b51c86e985e38992bc1 100644
--- a/src/plugins/coreplugin/editormanager/editormanager.h
+++ b/src/plugins/coreplugin/editormanager/editormanager.h
@@ -210,11 +210,11 @@ private slots:
     void updateEditorHistory();
     void updateActions();
     void revertToSaved();
-    void goBackInNavigationHistory();
-    void goForwardInNavigationHistory();
     void makeCurrentEditorWritable();
 
 public slots:
+    void goBackInNavigationHistory();
+    void goForwardInNavigationHistory();
     void split(Qt::Orientation orientation);
     void split();
     void splitSideBySide();
diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp
index ba81a34cfc471a245f1ea4c8ba850585bf99f68f..3dd6d731046a2381ee5785b5981a45ebadcec692 100644
--- a/src/plugins/fakevim/fakevimhandler.cpp
+++ b/src/plugins/fakevim/fakevimhandler.cpp
@@ -301,6 +301,10 @@ public:
     void endEditBlock() { UNDO_DEBUG("END EDIT BLOCK"); m_tc.endEditBlock(); }
     void joinPreviousEditBlock() { UNDO_DEBUG("JOIN EDIT BLOCK"); m_tc.joinPreviousEditBlock(); }
 
+    // this asks the layer above (e.g. the fake vim plugin or the
+    // stand-alone test application to handle the command)
+    void passUnknownExCommand(const QString &cmd);
+
 public:
     QTextEdit *m_textedit;
     QPlainTextEdit *m_plaintextedit;
@@ -1778,17 +1782,13 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0)
     static QRegExp reSet("^set?( (.*))?$");
     static QRegExp reWrite("^[wx]q?a?!?( (.*))?$");
     static QRegExp reSubstitute("^s(.)(.*)\\1(.*)\\1([gi]*)");
+    
+    enterCommandMode();
+    showBlackMessage(QString());
 
     if (cmd.isEmpty()) {
         setPosition(firstPositionInLine(beginLine));
         showBlackMessage(QString());
-        enterCommandMode();
-    } else if (reQuit.indexIn(cmd) != -1) { // :q
-        showBlackMessage(QString());
-        if (cmd.contains(QChar('a')))
-            q->quitAllRequested(cmd.contains(QChar('!')));
-        else
-            q->quitRequested(cmd.contains(QChar('!')));
     } else if (reDelete.indexIn(cmd) != -1) { // :d
         selectRange(beginLine, endLine);
         QString reg = reDelete.cap(2);
@@ -1796,7 +1796,6 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0)
         if (!reg.isEmpty())
             m_registers[reg.at(0).unicode()] = text;
     } else if (reWrite.indexIn(cmd) != -1) { // :w and :x
-        enterCommandMode();
         bool noArgs = (beginLine == -1);
         if (beginLine == -1)
             beginLine = 0;
@@ -1848,9 +1847,9 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0)
                 .arg(fileName).arg(exists ? " " : " [New] ")
                 .arg(ba.count('\n')).arg(ba.size()));
             if (quitAll)
-                q->quitAllRequested(forced);
+                passUnknownExCommand(forced ? "qa!" : "qa");
             else if (quit)
-                q->quitRequested(forced);
+                passUnknownExCommand(forced ? "q!" : "q");
         } else {
             showRedMessage(tr("Cannot open file '%1' for reading").arg(fileName));
         }
@@ -1861,7 +1860,6 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0)
         QTextStream ts(&file);
         QString data = ts.readAll();
         EDITOR(setPlainText(data));
-        enterCommandMode();
         showBlackMessage(tr("\"%1\" %2L, %3C")
             .arg(m_currentFileName).arg(data.count('\n')).arg(data.size()));
     } else if (cmd.startsWith(QLatin1Char('!'))) {
@@ -1878,7 +1876,6 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0)
         m_tc.insertText(result);
         leaveVisualMode();
         setPosition(firstPositionInLine(beginLine));
-        enterCommandMode();
         //qDebug() << "FILTER: " << command;
         showBlackMessage(tr("%n lines filtered", 0, text.count('\n')));
     } else if (cmd.startsWith(QLatin1Char('>'))) {
@@ -1886,14 +1883,11 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0)
         setPosition(firstPositionInLine(endLine));
         shiftRegionRight(1);
         leaveVisualMode();
-        enterCommandMode();
         showBlackMessage(tr("%n lines >ed %1 time", 0, (endLine - beginLine + 1)).arg(1));
     } else if (cmd == "red" || cmd == "redo") { // :redo
         redo();
-        enterCommandMode();
         updateMiniBuffer();
     } else if (reNormal.indexIn(cmd) != -1) { // :normal
-        enterCommandMode();
         //qDebug() << "REPLAY: " << reNormal.cap(3);
         replay(reNormal.cap(3), 1);
     } else if (reSubstitute.indexIn(cmd) != -1) { // :substitute
@@ -1936,7 +1930,6 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0)
             }
         }
         endEditBlock();
-        enterCommandMode();
     } else if (reSet.indexIn(cmd) != -1) { // :set
         showBlackMessage(QString());
         QString arg = reSet.cap(2);
@@ -1970,7 +1963,6 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0)
         } else {
             showRedMessage(tr("E512: Unknown option: ") + arg);
         }
-        enterCommandMode();
         updateMiniBuffer();
     } else if (reHistory.indexIn(cmd) != -1) { // :history
         QString arg = reSet.cap(3);
@@ -1986,14 +1978,17 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0)
         } else {
             notImplementedYet();
         }
-        enterCommandMode();
         updateMiniBuffer();
     } else {
-        enterCommandMode();
-        showRedMessage(tr("E492: Not an editor command: ") + cmd0);
+        passUnknownExCommand(cmd);
     }
 }
 
+void FakeVimHandler::Private::passUnknownExCommand(const QString &cmd)
+{
+    emit q->handleExCommandRequested(cmd);
+}
+
 static void vimPatternToQtPattern(QString *needle, QTextDocument::FindFlags *flags)
 {
     // FIXME: Rough mapping of a common case
@@ -2043,7 +2038,7 @@ void FakeVimHandler::Private::search(const QString &needle0, bool forward)
             highlightMatches(needle);
         } else {
             m_tc = orig;
-            showRedMessage(tr("E486: Pattern not found: ") + needle);
+            showRedMessage(tr("Pattern not found: ") + needle);
             highlightMatches(QString());
         }
     }
@@ -2600,6 +2595,16 @@ void FakeVimHandler::setCurrentFileName(const QString &fileName)
    d->m_currentFileName = fileName;
 }
 
+void FakeVimHandler::showBlackMessage(const QString &msg)
+{
+   d->showBlackMessage(msg);
+}
+
+void FakeVimHandler::showRedMessage(const QString &msg)
+{
+   d->showRedMessage(msg);
+}
+
 QWidget *FakeVimHandler::widget()
 {
     return d->editor();
diff --git a/src/plugins/fakevim/fakevimhandler.h b/src/plugins/fakevim/fakevimhandler.h
index a69c849e109fcec736eb5c237907a5a6d87b16a6..401a8ee01703d3dcda6461560ad10c041de67d6e 100644
--- a/src/plugins/fakevim/fakevimhandler.h
+++ b/src/plugins/fakevim/fakevimhandler.h
@@ -50,6 +50,8 @@ public:
 
 public slots:
     void setCurrentFileName(const QString &fileName);
+    void showBlackMessage(const QString &msg);
+    void showRedMessage(const QString &msg);
 
     // This executes an "ex" style command taking context
     // information from widget;
@@ -65,17 +67,17 @@ signals:
     void commandBufferChanged(const QString &msg);
     void statusDataChanged(const QString &msg);
     void extraInformationChanged(const QString &msg);
-    void quitRequested(bool force);
-    void quitAllRequested(bool force);
     void selectionChanged(const QList<QTextEdit::ExtraSelection> &selection);
     void writeFileRequested(bool *handled,
         const QString &fileName, const QString &contents);
+    void writeAllRequested(QString *error);
     void moveToMatchingParenthesis(bool *moved, bool *forward, QTextCursor *cursor);
     void indentRegion(int *amount, int beginLine, int endLine, QChar typedChar);
     void completionRequested();
     void windowCommandRequested(int key);
     void findRequested(bool reverse);
     void findNextRequested(bool reverse);
+    void handleExCommandRequested(const QString &cmd);
 
 public:
     class Private;
diff --git a/src/plugins/fakevim/fakevimplugin.cpp b/src/plugins/fakevim/fakevimplugin.cpp
index 1910b4905b918509446f32522509140824680430..e56da8d7f84cc046310a9d17c72b70e9a58c5259 100644
--- a/src/plugins/fakevim/fakevimplugin.cpp
+++ b/src/plugins/fakevim/fakevimplugin.cpp
@@ -248,10 +248,16 @@ private slots:
     void showExtraInformation(const QString &msg);
     void changeSelection(const QList<QTextEdit::ExtraSelection> &selections);
     void writeFile(bool *handled, const QString &fileName, const QString &contents);
-    void quitFile(bool forced);
-    void quitAllFiles(bool forced);
     void moveToMatchingParenthesis(bool *moved, bool *forward, QTextCursor *cursor);
     void indentRegion(int *amount, int beginLine, int endLine,  QChar typedChar);
+    void handleExCommand(const QString &cmd);
+
+    void handleDelayedQuitAll(bool forced);
+    void handleDelayedQuit(bool forced, Core::IEditor *editor);
+
+signals:
+    void delayedQuitRequested(bool forced, Core::IEditor *editor);
+    void delayedQuitAllRequested(bool forced);
 
 private:
     FakeVimPlugin *q;
@@ -316,6 +322,12 @@ bool FakeVimPluginPrivate::initialize()
     connect(theFakeVimSetting(ConfigUseFakeVim), SIGNAL(valueChanged(QVariant)),
         this, SLOT(setUseFakeVim(QVariant)));
 
+    // Delayed operatiosn
+    connect(this, SIGNAL(delayedQuitRequested(bool,Core::IEditor*)),
+        this, SLOT(handleDelayedQuit(bool,Core::IEditor*)), Qt::QueuedConnection);
+    connect(this, SIGNAL(delayedQuitAllRequested(bool)),
+        this, SLOT(handleDelayedQuitAll(bool)), Qt::QueuedConnection);
+
     return true;
 }
 
@@ -406,10 +418,6 @@ void FakeVimPluginPrivate::editorOpened(Core::IEditor *editor)
         this, SLOT(showExtraInformation(QString)));
     connect(handler, SIGNAL(commandBufferChanged(QString)),
         this, SLOT(showCommandBuffer(QString)));
-    connect(handler, SIGNAL(quitRequested(bool)),
-        this, SLOT(quitFile(bool)), Qt::QueuedConnection);
-    connect(handler, SIGNAL(quitAllRequested(bool)),
-        this, SLOT(quitAllFiles(bool)), Qt::QueuedConnection);
     connect(handler, SIGNAL(writeFileRequested(bool*,QString,QString)),
         this, SLOT(writeFile(bool*,QString,QString)));
     connect(handler, SIGNAL(selectionChanged(QList<QTextEdit::ExtraSelection>)),
@@ -427,6 +435,9 @@ void FakeVimPluginPrivate::editorOpened(Core::IEditor *editor)
     connect(handler, SIGNAL(findNextRequested(bool)),
         this, SLOT(findNext(bool)));
 
+    connect(handler, SIGNAL(handleExCommandRequested(QString)),
+        this, SLOT(handleExCommand(QString)));
+
     handler->setCurrentFileName(editor->file()->fileName());
     handler->installEventFilter();
     
@@ -471,21 +482,6 @@ void FakeVimPluginPrivate::triggerCompletions()
    //     bt->triggerCompletions();
 }
 
-void FakeVimPluginPrivate::quitFile(bool forced)
-{
-    FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender());
-    if (!handler)
-        return;
-    QList<Core::IEditor *> editors;
-    editors.append(m_editorToHandler.key(handler));
-    Core::EditorManager::instance()->closeEditors(editors, !forced);
-}
-
-void FakeVimPluginPrivate::quitAllFiles(bool forced)
-{
-    Core::EditorManager::instance()->closeAllEditors(!forced);
-}
-
 void FakeVimPluginPrivate::writeFile(bool *handled,
     const QString &fileName, const QString &contents)
 {
@@ -506,6 +502,63 @@ void FakeVimPluginPrivate::writeFile(bool *handled,
     } 
 }
 
+void FakeVimPluginPrivate::handleExCommand(const QString &cmd)
+{
+    static QRegExp reNextFile("^n(ext)?!?( (.*))?$");
+    static QRegExp rePreviousFile("^(N(ext)?|prev(ious)?)!?( (.*))?$");
+    static QRegExp reWriteAll("^wa(ll)?!?$");
+    static QRegExp reQuit("^q!?$");
+    static QRegExp reQuitAll("^qa!?$");
+
+    using namespace Core;
+
+    FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender());
+    if (!handler)
+        return;
+
+    EditorManager *editorManager = EditorManager::instance();
+    QTC_ASSERT(editorManager, return);
+
+    if (reNextFile.indexIn(cmd) != -1) {
+        // :n
+        editorManager->goForwardInNavigationHistory();
+    } else if (rePreviousFile.indexIn(cmd) != -1) {
+        // :N, :prev
+        editorManager->goBackInNavigationHistory();
+    } else if (reWriteAll.indexIn(cmd) != -1) {
+        // :wa
+        FileManager *fm = ICore::instance()->fileManager();
+        QList<IFile *> toSave = fm->modifiedFiles();
+        QList<IFile *> failed = fm->saveModifiedFilesSilently(toSave);
+        if (failed.isEmpty())
+            handler->showBlackMessage(tr("Saving succeeded"));
+        else
+            handler->showRedMessage(tr("%1 files not saaved").arg(failed.size()));
+    } else if (reQuit.indexIn(cmd) != -1) {
+        // :q
+        bool forced = cmd.contains(QChar('!'));
+        emit delayedQuitRequested(forced, m_editorToHandler.key(handler));
+    } else if (reQuitAll.indexIn(cmd) != -1) {
+        // :qa
+        bool forced = cmd.contains(QChar('!'));
+        emit delayedQuitAllRequested(forced);
+    } else {
+        handler->showRedMessage(tr("Not an editor command: ") + cmd);
+    }
+}
+
+void FakeVimPluginPrivate::handleDelayedQuit(bool forced, Core::IEditor *editor)
+{
+    QList<Core::IEditor *> editors;
+    editors.append(editor);
+    Core::EditorManager::instance()->closeEditors(editors, !forced);
+}
+
+void FakeVimPluginPrivate::handleDelayedQuitAll(bool forced)
+{
+    Core::EditorManager::instance()->closeAllEditors(!forced);
+}
+
 void FakeVimPluginPrivate::moveToMatchingParenthesis(bool *moved, bool *forward,
         QTextCursor *cursor)
 {
@@ -521,7 +574,7 @@ void FakeVimPluginPrivate::moveToMatchingParenthesis(bool *moved, bool *forward,
     if (match == TextEditor::TextBlockUserData::Match) {
         *moved = true;
         *forward = true;
-   } else {
+    } else {
         if (undoFakeEOL)
             cursor->movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, 1);
         if (match == TextEditor::TextBlockUserData::NoMatch) {