diff --git a/src/plugins/fakevim/fakevimactions.cpp b/src/plugins/fakevim/fakevimactions.cpp
index 183ff884ac2d1f7ff1b309862879111600164860..8cce9a9c02d518e000904bcbe2b053dfcc327388 100644
--- a/src/plugins/fakevim/fakevimactions.cpp
+++ b/src/plugins/fakevim/fakevimactions.cpp
@@ -198,6 +198,7 @@ FakeVimSettings *theFakeVimSettings()
     createAction(s, ConfigWrapScan,       true,  _("WrapScan"),      _("ws"));
     createAction(s, ConfigTildeOp,        false, _("TildeOp"),       _("top"));
     createAction(s, ConfigShowCmd,        true,  _("ShowCmd"),       _("sc"));
+    createAction(s, ConfigRelativeNumber, false, _("RelativeNumber"),_("rnu"));
     createAction(s, ConfigScrollOff,      0,     _("ScrollOff"),     _("so"));
     createAction(s, ConfigBackspace,      _("indent,eol,start"), _("ConfigBackspace"), _("bs"));
     createAction(s, ConfigIsKeyword,      _("@,48-57,_,192-255,a-z,A-Z"), _("IsKeyword"), _("isk"));
diff --git a/src/plugins/fakevim/fakevimactions.h b/src/plugins/fakevim/fakevimactions.h
index dc56976b50931ea6af888ccd2eac70c1fdfa33e4..8651604790640f23225c582b37e0886386a41104 100644
--- a/src/plugins/fakevim/fakevimactions.h
+++ b/src/plugins/fakevim/fakevimactions.h
@@ -98,7 +98,8 @@ enum FakeVimSettingsCode
     ConfigPassKeys,
     ConfigClipboard,
     ConfigShowCmd,
-    ConfigScrollOff
+    ConfigScrollOff,
+    ConfigRelativeNumber
 };
 
 class FakeVimSettings : public QObject
diff --git a/src/plugins/fakevim/fakevimoptions.ui b/src/plugins/fakevim/fakevimoptions.ui
index 6f5d21d6b19bfe9972e4d8a768536951b57eda2f..aa14acedb47985ed602151d4a76096ceee346636 100644
--- a/src/plugins/fakevim/fakevimoptions.ui
+++ b/src/plugins/fakevim/fakevimoptions.ui
@@ -137,6 +137,16 @@
           </property>
          </widget>
         </item>
+        <item row="7" column="1">
+         <widget class="QCheckBox" name="checkBoxRelativeNumber">
+          <property name="toolTip">
+           <string>Display line numbers relative to the line containing text cursor.</string>
+          </property>
+          <property name="text">
+           <string>Show line numbers relative to cursor</string>
+          </property>
+         </widget>
+        </item>
        </layout>
       </item>
       <item>
@@ -372,6 +382,7 @@
   <tabstop>checkBoxWrapScan</tabstop>
   <tabstop>checkBoxShowMarks</tabstop>
   <tabstop>checkBoxPassControlKey</tabstop>
+  <tabstop>checkBoxRelativeNumber</tabstop>
   <tabstop>spinBoxShiftWidth</tabstop>
   <tabstop>spinBoxTabStop</tabstop>
   <tabstop>spinBoxScrollOff</tabstop>
diff --git a/src/plugins/fakevim/fakevimplugin.cpp b/src/plugins/fakevim/fakevimplugin.cpp
index 7a7cc9027138d3b7f648459211389712ba3c8aca..a7ed73ab840f8c5b8a6ad892ed0504beeb19a921 100644
--- a/src/plugins/fakevim/fakevimplugin.cpp
+++ b/src/plugins/fakevim/fakevimplugin.cpp
@@ -86,8 +86,10 @@
 #include <QFileDialog>
 #include <QtPlugin>
 #include <QObject>
+#include <QPainter>
 #include <QPointer>
 #include <QSettings>
+#include <QScrollBar>
 #include <QStackedWidget>
 #include <QTextStream>
 
@@ -231,6 +233,127 @@ private:
     int m_lastMessageLevel;
 };
 
+class RelativeNumbersColumn : public QWidget
+{
+    Q_OBJECT
+
+public:
+    RelativeNumbersColumn(BaseTextEditorWidget *baseTextEditor)
+        : QWidget(baseTextEditor)
+        , m_currentPos(0)
+        , m_lineSpacing(0)
+        , m_editor(baseTextEditor)
+    {
+        setAttribute(Qt::WA_TransparentForMouseEvents, true);
+
+        m_timerUpdate.setSingleShot(true);
+        m_timerUpdate.setInterval(0);
+        connect(&m_timerUpdate, SIGNAL(timeout()), SLOT(followEditorLayout()));
+        updateOnSignal(m_editor, SIGNAL(cursorPositionChanged()));
+        updateOnSignal(m_editor->verticalScrollBar(), SIGNAL(valueChanged(int)));
+        updateOnSignal(m_editor->document(), SIGNAL(contentsChanged()));
+        updateOnSignal(TextEditorSettings::instance(),
+                       SIGNAL(displaySettingsChanged(TextEditor::DisplaySettings)));
+
+        m_editor->installEventFilter(this);
+
+        followEditorLayout();
+    }
+
+protected:
+    void paintEvent(QPaintEvent *event)
+    {
+        QTextCursor firstVisibleCursor = m_editor->cursorForPosition(QPoint(0, 0));
+        QTextBlock firstVisibleBlock = firstVisibleCursor.block();
+        if (firstVisibleCursor.positionInBlock() > 0) {
+            firstVisibleBlock = firstVisibleBlock.next();
+            firstVisibleCursor.setPosition(firstVisibleBlock.position());
+        }
+
+        // Find relative number for the first visible line.
+        QTextBlock block = m_editor->textCursor().block();
+        bool forward = firstVisibleBlock.blockNumber() > block.blockNumber();
+        int n = 0;
+        while (block.isValid() && block != firstVisibleBlock) {
+            block = forward ? block.next() : block.previous();
+            if (block.isVisible())
+                n += forward ? 1 : -1;
+        }
+
+        // Copy colors from extra area palette.
+        QPainter p(this);
+        QPalette pal = m_editor->extraArea()->palette();
+        const QColor fg = pal.color(QPalette::Dark);
+        const QColor bg = pal.color(QPalette::Background);
+        p.setPen(fg);
+
+        // Draw relative line numbers.
+        QRect rect(0, m_editor->cursorRect(firstVisibleCursor).y(), width(), m_lineSpacing);
+        bool hideLineNumbers = m_editor->lineNumbersVisible();
+        while (block.isValid()) {
+            if (block.isVisible()) {
+                if (n != 0 && rect.intersects(event->rect())) {
+                    const int line = qAbs(n);
+                    const QString number = QString::number(line);
+                    if (hideLineNumbers)
+                        p.fillRect(rect, bg);
+                    if (hideLineNumbers || line < 100)
+                        p.drawText(rect, Qt::AlignRight | Qt::AlignVCenter, number);
+                }
+
+                rect.translate(0, m_lineSpacing * block.lineCount());
+                if (rect.y() > height())
+                    break;
+
+                ++n;
+            }
+
+            block = block.next();
+        }
+    }
+
+    bool eventFilter(QObject *, QEvent *event)
+    {
+        if (event->type() == QEvent::Resize || event->type() == QEvent::Move)
+            m_timerUpdate.start();
+        return false;
+    }
+
+private slots:
+    void followEditorLayout()
+    {
+        QTextCursor tc = m_editor->textCursor();
+        m_currentPos = tc.position();
+        m_lineSpacing = m_editor->cursorRect(tc).height();
+        setFont(m_editor->extraArea()->font());
+
+        // Follow geometry of normal line numbers if visible,
+        // otherwise follow geometry of marks (breakpoints etc.).
+        QRect rect = m_editor->extraArea()->geometry().adjusted(0, 0, -3, 0);
+        bool marksVisible = m_editor->marksVisible();
+        bool lineNumbersVisible = m_editor->lineNumbersVisible();
+        bool foldMarksVisible = m_editor->codeFoldingVisible();
+        if (marksVisible && lineNumbersVisible)
+            rect.setLeft(m_lineSpacing);
+        if (foldMarksVisible && (marksVisible || lineNumbersVisible))
+            rect.setRight(rect.right() - (m_lineSpacing + m_lineSpacing % 2));
+        setGeometry(rect);
+
+        update();
+    }
+
+    void updateOnSignal(QObject *object, const char *signal)
+    {
+        connect(object, signal, &m_timerUpdate, SLOT(start()));
+    }
+
+private:
+    int m_currentPos;
+    int m_lineSpacing;
+    BaseTextEditorWidget *m_editor;
+    QTimer m_timerUpdate;
+};
+
 ///////////////////////////////////////////////////////////////////////
 //
 // FakeVimOptionPage
@@ -334,6 +457,9 @@ QWidget *FakeVimOptionPage::widget()
         m_group.insert(theFakeVimSetting(ConfigShowCmd),
                        m_ui.checkBoxShowCmd);
 
+        m_group.insert(theFakeVimSetting(ConfigRelativeNumber),
+                       m_ui.checkBoxRelativeNumber);
+
         connect(m_ui.pushButtonCopyTextEditorSettings, SIGNAL(clicked()),
                 SLOT(copyTextEditorSettings()));
         connect(m_ui.pushButtonSetQtStyle, SIGNAL(clicked()),
@@ -901,6 +1027,7 @@ private slots:
     void maybeReadVimRc();
     void setBlockSelection(bool);
     void hasBlockSelection(bool*);
+    void setShowRelativeLineNumbers(const QVariant &value);
 
     void resetCommandBuffer();
     void showCommandBuffer(const QString &contents, int cursorPos, int anchorPos,
@@ -923,6 +1050,8 @@ private slots:
     void switchToFile(int n);
     int currentFile() const;
 
+    void createRelativeNumberWidget(IEditor *editor);
+
 signals:
     void delayedQuitRequested(bool forced, Core::IEditor *editor);
     void delayedQuitAllRequested(bool forced);
@@ -1104,6 +1233,8 @@ bool FakeVimPluginPrivate::initialize()
         this, SLOT(maybeReadVimRc()));
     connect(theFakeVimSetting(ConfigVimRcPath), SIGNAL(valueChanged(QVariant)),
         this, SLOT(maybeReadVimRc()));
+    connect(theFakeVimSetting(ConfigRelativeNumber), SIGNAL(valueChanged(QVariant)),
+        this, SLOT(setShowRelativeLineNumbers(QVariant)));
 
     // Delayed operations.
     connect(this, SIGNAL(delayedQuitRequested(bool,Core::IEditor*)),
@@ -1143,6 +1274,15 @@ void FakeVimPluginPrivate::userActionTriggered()
     }
 }
 
+void FakeVimPluginPrivate::createRelativeNumberWidget(IEditor *editor)
+{
+    if (BaseTextEditorWidget *textEditor = qobject_cast<BaseTextEditorWidget *>(editor->widget())) {
+        RelativeNumbersColumn *relativeNumbers = new RelativeNumbersColumn(textEditor);
+        connect(theFakeVimSetting(ConfigRelativeNumber), SIGNAL(valueChanged(QVariant)),
+                relativeNumbers, SLOT(deleteLater()));
+        relativeNumbers->show();
+    }
+}
 
 const char exCommandMapGroup[] = "FakeVimExCommand";
 const char userCommandMapGroup[] = "FakeVimUserCommand";
@@ -1673,6 +1813,9 @@ void FakeVimPluginPrivate::editorOpened(IEditor *editor)
        resetCommandBuffer();
        handler->setupWidget();
     }
+
+    if (theFakeVimSetting(ConfigRelativeNumber)->value().toBool())
+        createRelativeNumberWidget(editor);
 }
 
 void FakeVimPluginPrivate::editorAboutToClose(IEditor *editor)
@@ -1746,6 +1889,14 @@ void FakeVimPluginPrivate::hasBlockSelection(bool *on)
         *on = bt->hasBlockSelection();
 }
 
+void FakeVimPluginPrivate::setShowRelativeLineNumbers(const QVariant &value)
+{
+    if (value.toBool()) {
+        foreach (IEditor *editor, m_editorToHandler.keys())
+            createRelativeNumberWidget(editor);
+    }
+}
+
 void FakeVimPluginPrivate::checkForElectricCharacter(bool *result, QChar c)
 {
     FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender());