diff --git a/src/plugins/fakevim/handler.cpp b/src/plugins/fakevim/handler.cpp
index 6a386b02864ca03db7876cf9036a0dd0e0448438..fc927ea99e8202cc501e08eeae12ba21d4aca59e 100644
--- a/src/plugins/fakevim/handler.cpp
+++ b/src/plugins/fakevim/handler.cpp
@@ -150,11 +150,22 @@ public:
 
     bool m_fakeEnd;
 
+    bool isSearchCommand() const
+        { return m_commandCode == '?' || m_commandCode == '/'; }
     int m_commandCode; // ?, /, : ...
+    
     QString m_commandBuffer;
 
     bool m_lastSearchForward;
-    QString m_lastSearchString;
+
+    // History for '/'
+    QString lastSearchString() const;
+    QStringList m_searchHistory;
+    int m_searchHistoryIndex;
+
+    // History for ':'
+    QStringList m_commandHistory;
+    int m_commandHistoryIndex;
 };
 
 FakeVimHandler::Private::Private(FakeVimHandler *parent)
@@ -302,6 +313,13 @@ void FakeVimHandler::Private::handleCommandMode(int key, const QString &text)
     } else if (key == ':' || key == '/' || key == '?') {
         m_commandCode = key;
         m_mode = ExMode;
+        if (isSearchCommand()) {
+            m_searchHistory.append(QString());
+            m_searchHistoryIndex = m_searchHistory.size() - 1;
+        } else {
+            m_commandHistory.append(QString());
+            m_commandHistoryIndex = m_commandHistory.size() - 1;
+        }
         updateCommandBuffer();
     } else if (key == '|') {
         m_tc.movePosition(StartOfLine, KeepAnchor);
@@ -387,9 +405,9 @@ void FakeVimHandler::Private::handleCommandMode(int key, const QString &text)
         moveToFirstNonBlankOnLine();
         finishMovement();
     } else if (key == 'n') {
-        search(m_lastSearchString, m_lastSearchForward);
+        search(lastSearchString(), m_lastSearchForward);
     } else if (key == 'N') {
-        search(m_lastSearchString, !m_lastSearchForward);
+        search(lastSearchString(), !m_lastSearchForward);
     } else if (key == 'p') {
         QString text = m_registers[m_register];
         int n = text.count(QChar(ParagraphSeparator));
@@ -510,14 +528,23 @@ void FakeVimHandler::Private::handleExMode(int key, const QString &text)
         }
         m_commandBuffer.clear();
         m_mode = CommandMode;
-    } else if (key == Key_Return
-            && (m_commandCode == '/' || m_commandCode == '?')) {
+    } else if (key == Key_Return && isSearchCommand()) {
         m_lastSearchForward = (m_commandCode == '/');
-        m_lastSearchString = m_commandBuffer;
-        search(m_lastSearchString, m_lastSearchForward);
+        m_searchHistory.append(m_commandBuffer);
+        search(lastSearchString(), m_lastSearchForward);
         m_commandBuffer.clear();
         m_commandCode = 0;
         m_mode = CommandMode;
+    } else if (key == Key_Up && isSearchCommand()) {
+        if (m_searchHistoryIndex > 0) {
+            --m_searchHistoryIndex;
+            m_commandBuffer = m_searchHistory.at(m_searchHistoryIndex);
+        }
+    } else if (key == Key_Down && isSearchCommand()) {
+        if (m_searchHistoryIndex < m_searchHistory.size() - 1) {
+            ++m_searchHistoryIndex;
+            m_commandBuffer = m_searchHistory.at(m_searchHistoryIndex);
+        }
     } else {
         m_commandBuffer += QChar(key);
     }
@@ -528,7 +555,7 @@ void FakeVimHandler::Private::search(const QString &needle, bool forward)
 {
     //qDebug() << "NEEDLE " << needle << "BACKWARDS" << backwards;
     QTextCursor orig = m_tc;
-    QTextDocument::FindFlags flags;
+    QTextDocument::FindFlags flags = QTextDocument::FindCaseSensitively;
     if (!forward)
         flags = QTextDocument::FindBackward;
 
@@ -538,7 +565,8 @@ void FakeVimHandler::Private::search(const QString &needle, bool forward)
     m_editor->setTextCursor(m_tc);
     if (m_editor->find(needle, flags)) {
         m_tc = m_editor->textCursor();
-        m_tc.movePosition(Left, MoveAnchor, needle.size() - 1);
+        // the qMax seems to be needed for QPlainTextEdit only
+        m_tc.movePosition(Left, MoveAnchor, qMax(1, needle.size() - 1));
         return;
     }
 
@@ -546,7 +574,8 @@ void FakeVimHandler::Private::search(const QString &needle, bool forward)
     m_editor->setTextCursor(m_tc);
     if (m_editor->find(needle, flags)) {
         m_tc = m_editor->textCursor();
-        m_tc.movePosition(Left, MoveAnchor, needle.size() - 1);
+        // the qMax seems to be needed for QPlainTextEdit only
+        m_tc.movePosition(Left, MoveAnchor, qMax(1, needle.size() - 1));
         if (forward)
             showMessage("search hit BOTTOM, continuing at TOP");
         else
@@ -696,6 +725,11 @@ int FakeVimHandler::Private::lastPositionInDocument() const
     return block.position() + block.length();
 }
 
+QString FakeVimHandler::Private::lastSearchString() const
+{
+     return m_searchHistory.empty() ? QString() : m_searchHistory.back();
+}
+
 ///////////////////////////////////////////////////////////////////////
 //
 // FakeVimHandler