diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp
index 5e4694440bf1644b140827a54b267c81aff2c550..3b3b549df98b0124af4875ef169dd623431c65a8 100644
--- a/src/plugins/fakevim/fakevimhandler.cpp
+++ b/src/plugins/fakevim/fakevimhandler.cpp
@@ -141,6 +141,10 @@ enum {
 const int ParagraphSeparator = 0x00002029;
 typedef QLatin1String _;
 
+/* Clipboard MIME types used by Vim. */
+static const QString vimMimeText = "_VIM_TEXT";
+static const QString vimMimeTextEncoded = "_VIMENC_TEXT";
+
 using namespace Qt;
 
 /*! A \e Mode represents one of the basic modes of operation of FakeVim.
@@ -406,6 +410,29 @@ static QRegExp vimPatternToQtPattern(QString needle, bool smartcase)
     return QRegExp(pattern);
 }
 
+static void setClipboardData(const QString &content, RangeMode mode,
+    QClipboard::Mode clipboardMode)
+{
+    QClipboard *clipboard = QApplication::clipboard();
+    char vimRangeMode = mode;
+
+    QByteArray bytes1;
+    bytes1.append(vimRangeMode);
+    bytes1.append(content.toUtf8());
+
+    QByteArray bytes2;
+    bytes2.append(vimRangeMode);
+    bytes2.append("utf-8");
+    bytes2.append('\0');
+    bytes2.append(content.toUtf8());
+
+    QMimeData *data = new QMimeData;
+    data->setText(content);
+    data->setData(vimMimeText, bytes1);
+    data->setData(vimMimeTextEncoded, bytes2);
+    clipboard->setMimeData(data, clipboardMode);
+}
+
 
 Range::Range()
     : beginPos(-1), endPos(-1), rangemode(RangeCharMode)
@@ -1141,9 +1168,8 @@ public:
 
     // register handling
     QString registerContents(int reg) const;
-    void setRegisterContents(int reg, const QString &contents);
+    void setRegister(int reg, const QString &contents, RangeMode mode);
     RangeMode registerRangeMode(int reg) const;
-    void setRegisterRangeMode(int reg, RangeMode mode);
     void getRegisterType(int reg, bool *isClipboard, bool *isSelection) const;
 
     void recordJump();
@@ -1710,7 +1736,7 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand)
         if (m_submode != TransformSubMode) {
             yankText(currentRange(), m_register);
             if (m_movetype == MoveLineWise)
-                setRegisterRangeMode(m_register, RangeLineMode);
+                setRegister(m_register, registerContents(m_register), RangeLineMode);
         }
 
         m_positionPastEnd = m_anchorPastEnd = false;
@@ -3744,8 +3770,7 @@ bool FakeVimHandler::Private::handleExDeleteCommand(const ExCommand &cmd)
     removeText(currentRange());
     if (!reg.isEmpty()) {
         const int r = reg.at(0).unicode();
-        setRegisterContents(r, text);
-        setRegisterRangeMode(r, RangeLineMode);
+        setRegister(r, text, RangeLineMode);
     }
     return true;
 }
@@ -4648,8 +4673,7 @@ QString FakeVimHandler::Private::selectText(const Range &range) const
 
 void FakeVimHandler::Private::yankText(const Range &range, int reg)
 {
-    setRegisterContents(reg, selectText(range));
-    setRegisterRangeMode(reg, range.rangemode);
+    setRegister(reg, selectText(range), range.rangemode);
 }
 
 void FakeVimHandler::Private::transformText(const Range &range,
@@ -5387,43 +5411,48 @@ void FakeVimHandler::Private::setMark(int code, int position)
     m_marks[code] = tc;
 }
 
-void FakeVimHandler::Private::setRegisterRangeMode(int reg, RangeMode mode)
-{
-    g.registers[reg].rangemode = mode;
-}
-
 RangeMode FakeVimHandler::Private::registerRangeMode(int reg) const
 {
     bool isClipboard;
     bool isSelection;
     getRegisterType(reg, &isClipboard, &isSelection);
 
-    // If register content is clipboard:
-    //  - return RangeLineMode if text ends with new line char,
-    //  - return RangeCharMode otherwise.
     if (isClipboard || isSelection) {
-        QString text = QApplication::clipboard()->text(
-            isClipboard ? QClipboard::Clipboard : QClipboard::Selection);
+        QClipboard *clipboard = QApplication::clipboard();
+        QClipboard::Mode mode = isClipboard ? QClipboard::Clipboard : QClipboard::Selection;
+
+        // Use range mode from Vim's clipboard data if available.
+        const QMimeData *data = clipboard->mimeData(mode);
+        if (data != 0 && data->hasFormat(vimMimeText)) {
+            QByteArray bytes = data->data(vimMimeText);
+            if (bytes.length() > 0)
+                return static_cast<RangeMode>(bytes.at(0));
+        }
+
+        // If register content is clipboard:
+        //  - return RangeLineMode if text ends with new line char,
+        //  - return RangeCharMode otherwise.
+        QString text = clipboard->text(mode);
         return (text.endsWith('\n') || text.endsWith('\r')) ? RangeLineMode : RangeCharMode;
     }
 
     return g.registers[reg].rangemode;
 }
 
-void FakeVimHandler::Private::setRegisterContents(int reg, const QString &contents)
+void FakeVimHandler::Private::setRegister(int reg, const QString &contents, RangeMode mode)
 {
     bool copyToClipboard;
     bool copyToSelection;
     getRegisterType(reg, &copyToClipboard, &copyToSelection);
 
     if (copyToClipboard || copyToSelection) {
-        QClipboard *clipboard = QApplication::clipboard();
         if (copyToClipboard)
-            clipboard->setText(contents, QClipboard::Clipboard);
+            setClipboardData(contents, mode, QClipboard::Clipboard);
         if (copyToSelection)
-            clipboard->setText(contents, QClipboard::Selection);
+            setClipboardData(contents, mode, QClipboard::Selection);
     } else {
         g.registers[reg].contents = contents;
+        g.registers[reg].rangemode = mode;
     }
 }
 
diff --git a/src/plugins/fakevim/fakevimhandler.h b/src/plugins/fakevim/fakevimhandler.h
index 1e6d5a2142b77d5d2742eba706c09d7ee8923762..7ef0d1afbf1740c8a866f909cc67e66d0005fa55 100644
--- a/src/plugins/fakevim/fakevimhandler.h
+++ b/src/plugins/fakevim/fakevimhandler.h
@@ -41,10 +41,12 @@ namespace Internal {
 
 enum RangeMode
 {
+    // Reordering first three enum items here will break
+    // compatibility with clipboard format stored by Vim.
     RangeCharMode,         // v
     RangeLineMode,         // V
-    RangeLineModeExclusive,
     RangeBlockMode,        // Ctrl-v
+    RangeLineModeExclusive,
     RangeBlockAndTailMode // Ctrl-v for D and X
 };