diff --git a/src/plugins/find/basetextfind.cpp b/src/plugins/find/basetextfind.cpp
index bff4f835fe07b1362eecff3e9f1aac2a98bfb574..beb714b52d5d6a4418c2c6f3bbffde18d4f5acc9 100644
--- a/src/plugins/find/basetextfind.cpp
+++ b/src/plugins/find/basetextfind.cpp
@@ -215,7 +215,7 @@ int BaseTextFind::replaceAll(const QString &before, const QString &after,
     QRegExp regexp(before);
     regexp.setPatternSyntax(usesRegExp ? QRegExp::RegExp : QRegExp::FixedString);
     regexp.setCaseSensitivity((findFlags & IFindSupport::FindCaseSensitively) ? Qt::CaseSensitive : Qt::CaseInsensitive);
-    QTextCursor found = document()->find(regexp, editCursor, IFindSupport::textDocumentFlagsForFindFlags(findFlags));
+    QTextCursor found = findOne(regexp, editCursor, IFindSupport::textDocumentFlagsForFindFlags(findFlags));
     while (!found.isNull() && found.selectionStart() < found.selectionEnd()
             && inScope(found.selectionStart(), found.selectionEnd())) {
         ++count;
@@ -224,7 +224,7 @@ int BaseTextFind::replaceAll(const QString &before, const QString &after,
         regexp.exactMatch(found.selectedText());
         QString realAfter = usesRegExp ? expandRegExpReplacement(after, regexp) : after;
         editCursor.insertText(realAfter);
-        found = document()->find(regexp, editCursor, IFindSupport::textDocumentFlagsForFindFlags(findFlags));
+        found = findOne(regexp, editCursor, IFindSupport::textDocumentFlagsForFindFlags(findFlags));
     }
     editCursor.endEditBlock();
     return count;
@@ -241,7 +241,7 @@ bool BaseTextFind::find(const QString &txt,
     QRegExp regexp(txt);
     regexp.setPatternSyntax((findFlags&IFindSupport::FindRegularExpression) ? QRegExp::RegExp : QRegExp::FixedString);
     regexp.setCaseSensitivity((findFlags&IFindSupport::FindCaseSensitively) ? Qt::CaseSensitive : Qt::CaseInsensitive);
-    QTextCursor found = document()->find(regexp, start, IFindSupport::textDocumentFlagsForFindFlags(findFlags));
+    QTextCursor found = findOne(regexp, start, IFindSupport::textDocumentFlagsForFindFlags(findFlags));
 
     if (!m_findScope.isNull()) {
 
@@ -251,7 +251,7 @@ bool BaseTextFind::find(const QString &txt,
                 start.setPosition(m_findScope.selectionStart());
             else
                 start.setPosition(m_findScope.selectionEnd());
-            found = document()->find(regexp, start, IFindSupport::textDocumentFlagsForFindFlags(findFlags));
+            found = findOne(regexp, start, IFindSupport::textDocumentFlagsForFindFlags(findFlags));
             if (found.isNull() || !inScope(found.selectionStart(), found.selectionEnd()))
                 return false;
         }
@@ -263,7 +263,7 @@ bool BaseTextFind::find(const QString &txt,
                 start.movePosition(QTextCursor::Start);
             else
                 start.movePosition(QTextCursor::End);
-            found = document()->find(regexp, start, IFindSupport::textDocumentFlagsForFindFlags(findFlags));
+            found = findOne(regexp, start, IFindSupport::textDocumentFlagsForFindFlags(findFlags));
             if (found.isNull()) {
                 return false;
             }
@@ -275,6 +275,28 @@ bool BaseTextFind::find(const QString &txt,
     return true;
 }
 
+
+// helper function. Works just like QTextDocument::find() but supports vertical block selection
+QTextCursor BaseTextFind::findOne(const QRegExp &expr, const QTextCursor &from, QTextDocument::FindFlags options) const
+{
+    QTextCursor candidate = document()->find(expr, from, options);
+    if (!m_findScopeVerticalBlockSelection)
+        return candidate;
+    forever {
+        if (!inScope(candidate.selectionStart(), candidate.selectionEnd()))
+            return candidate;
+        QTextCursor b = candidate;
+        b.setPosition(candidate.selectionStart());
+        QTextCursor e = candidate;
+        e.setPosition(candidate.selectionEnd());
+        if (b.positionInBlock() >= m_findScopeFromColumn
+            && e.positionInBlock() <= m_findScopeToColumn)
+            return candidate;
+        candidate = document()->find(expr, candidate, options);
+    }
+    return candidate;
+}
+
 bool BaseTextFind::inScope(int startPosition, int endPosition) const
 {
     if (m_findScope.isNull())
@@ -288,8 +310,25 @@ void BaseTextFind::defineFindScope()
     QTextCursor cursor = textCursor();
     if (cursor.hasSelection() && cursor.block() != cursor.document()->findBlock(cursor.anchor())) {
         m_findScope = cursor;
-        emit findScopeChanged(m_findScope);
-        cursor.setPosition(cursor.selectionStart());
+        m_findScopeVerticalBlockSelection = false;
+
+        int verticalBlockSelection = 0;
+        if (m_plaineditor && m_plaineditor->metaObject()->indexOfProperty("verticalBlockSelection") >= 0)
+            verticalBlockSelection = m_plaineditor->property("verticalBlockSelection").toInt();
+
+        if (verticalBlockSelection) {
+            QTextDocument *doc = document();
+            QTextCursor b(doc->docHandle(), cursor.selectionStart());
+            QTextCursor e(doc->docHandle(), cursor.selectionEnd());
+            m_findScopeFromColumn = qMin(b.positionInBlock(), e.positionInBlock());
+            m_findScopeToColumn = m_findScopeFromColumn + verticalBlockSelection;
+            m_findScope.setPosition(b.block().position() + m_findScopeFromColumn);
+            m_findScope.setPosition(e.block().position() + qMin(e.block().length()-1, m_findScopeToColumn),
+                                    QTextCursor::KeepAnchor);
+            m_findScopeVerticalBlockSelection = verticalBlockSelection;
+        }
+        emit findScopeChanged(m_findScope, m_findScopeVerticalBlockSelection);
+        cursor.setPosition(m_findScope.selectionStart());
         setTextCursor(cursor);
     } else {
         clearFindScope();
@@ -299,5 +338,6 @@ void BaseTextFind::defineFindScope()
 void BaseTextFind::clearFindScope()
 {
     m_findScope = QTextCursor();
-    emit findScopeChanged(m_findScope);
+    m_findScopeVerticalBlockSelection = 0;
+    emit findScopeChanged(m_findScope, m_findScopeVerticalBlockSelection);
 }
diff --git a/src/plugins/find/basetextfind.h b/src/plugins/find/basetextfind.h
index 7ed4b0f32b34aaf34b50d3869157355840941970..0c5c777b8eaf3b9bcdfc07b2a78e5f32c904198f 100644
--- a/src/plugins/find/basetextfind.h
+++ b/src/plugins/find/basetextfind.h
@@ -70,7 +70,7 @@ public:
 
 signals:
     void highlightAll(const QString &txt, Find::IFindSupport::FindFlags findFlags);
-    void findScopeChanged(const QTextCursor &);
+    void findScopeChanged(const QTextCursor &, int = 0);
 
 private:
     bool find(const QString &txt,
@@ -84,7 +84,11 @@ private:
     QPointer<QTextEdit> m_editor;
     QPointer<QPlainTextEdit> m_plaineditor;
     QTextCursor m_findScope;
+    int m_findScopeVerticalBlockSelection;
+    int m_findScopeFromColumn;
+    int m_findScopeToColumn;
     bool inScope(int startPosition, int endPosition) const;
+    QTextCursor findOne(const QRegExp &expr, const QTextCursor &from, QTextDocument::FindFlags options) const;
     int m_incrementalStartPos;
 };
 
diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp
index a83684b7cc1fd79bdaefcbd9cbd8793de5362d5d..239df6c1ad0ea5daf3628bcf248aa5adb1463aa1 100644
--- a/src/plugins/texteditor/basetexteditor.cpp
+++ b/src/plugins/texteditor/basetexteditor.cpp
@@ -2195,6 +2195,15 @@ void BaseTextEditorPrivate::highlightSearchResults(const QTextBlock &block,
     text.replace(QChar::Nbsp, QLatin1Char(' '));
     int idx = -1;
     int l = 1;
+
+    int m_findScopeFirstColumn = 0;
+    if (!m_findScope.isNull() && m_findScopeVerticalBlockSelection)  {
+        QTextCursor b = cursor;
+        cursor.setPosition(m_findScope.selectionStart());
+        m_findScopeFirstColumn = cursor.positionInBlock();
+    }
+
+
     while (idx < text.length()) {
         idx = m_searchExpr.indexIn(text, idx + l);
         if (idx < 0)
@@ -2205,19 +2214,26 @@ void BaseTextEditorPrivate::highlightSearchResults(const QTextBlock &block,
                 || (idx + l < text.length() && text.at(idx + l).isLetterOrNumber())))
             continue;
 
-        if (m_findScope.isNull()
-            || (blockPosition + idx >= m_findScope.selectionStart()
-                && blockPosition + idx + l <= m_findScope.selectionEnd())) {
+        if (!m_findScope.isNull()) {
+            if (blockPosition + idx < m_findScope.selectionStart()
+                || blockPosition + idx + l > m_findScope.selectionEnd())
+                continue;
+            if (m_findScopeVerticalBlockSelection) {
+                if (idx < m_findScopeFirstColumn
+                    || idx + l > m_findScopeFirstColumn + m_findScopeVerticalBlockSelection)
+                    continue;
+            }
+        }
+
 
-            overlay->addOverlaySelection(blockPosition + idx,
-                                         blockPosition + idx + l,
-                                         m_searchResultFormat.background().color().darker(120),
-                                         QColor(),
-                                         (idx == cursor.selectionStart() - blockPosition
-                                          && idx + l == cursor.selectionEnd() - blockPosition)?
-                                         TextEditorOverlay::DropShadow : 0);
+        overlay->addOverlaySelection(blockPosition + idx,
+                                     blockPosition + idx + l,
+                                     m_searchResultFormat.background().color().darker(120),
+                                     QColor(),
+                                     (idx == cursor.selectionStart() - blockPosition
+                                      && idx + l == cursor.selectionEnd() - blockPosition)?
+                                     TextEditorOverlay::DropShadow : 0);
 
-        }
     }
 }
 
@@ -2475,7 +2491,9 @@ void BaseTextEditor::paintEvent(QPaintEvent *e)
 
         TextEditorOverlay *overlay = new TextEditorOverlay(this);
         overlay->addOverlaySelection(d->m_findScope, d->m_searchScopeFormat.background().color().darker(120),
-                                     d->m_searchScopeFormat.background().color());
+                                     d->m_searchScopeFormat.background().color(),
+                                     0,
+                                     d->m_findScopeVerticalBlockSelection);
         overlay->setAlpha(false);
         overlay->paint(&painter, e->rect());
         delete overlay;
@@ -4674,10 +4692,23 @@ void BaseTextEditor::highlightSearchResults(const QString &txt, Find::IFindSuppo
     d->m_delayedUpdateTimer->start(10);
 }
 
-void BaseTextEditor::setFindScope(const QTextCursor &scope)
+int BaseTextEditor::verticalBlockSelection() const
+{
+    if (!d->m_inBlockSelectionMode)
+        return 0;
+    QTextCursor b = textCursor();
+    QTextCursor e = b;
+    b.setPosition(b.selectionStart());
+    e.setPosition(e.selectionEnd());
+
+    return qAbs(b.positionInBlock() - e.positionInBlock()) + d->m_blockSelectionExtraX;
+}
+
+void BaseTextEditor::setFindScope(const QTextCursor &scope, int verticalBlockSelection)
 {
     if (scope.isNull() != d->m_findScope.isNull()) {
         d->m_findScope = scope;
+        d->m_findScopeVerticalBlockSelection = verticalBlockSelection;
         viewport()->update();
     }
 }
@@ -5628,7 +5659,7 @@ BaseTextEditorEditable::BaseTextEditorEditable(BaseTextEditor *editor)
     BaseTextFind *baseTextFind = new BaseTextFind(editor);
     connect(baseTextFind, SIGNAL(highlightAll(QString, Find::IFindSupport::FindFlags)),
             editor, SLOT(highlightSearchResults(QString, Find::IFindSupport::FindFlags)));
-    connect(baseTextFind, SIGNAL(findScopeChanged(QTextCursor)), editor, SLOT(setFindScope(QTextCursor)));
+    connect(baseTextFind, SIGNAL(findScopeChanged(QTextCursor, int)), editor, SLOT(setFindScope(QTextCursor, int)));
     aggregate->add(baseTextFind);
     aggregate->add(editor);
 
diff --git a/src/plugins/texteditor/basetexteditor.h b/src/plugins/texteditor/basetexteditor.h
index e884b8c93d4d886735b6409f2d1ceb6dd7b09b2b..cb6bea2ba64cdc014f3266a7f6cd5e721f6f91f6 100644
--- a/src/plugins/texteditor/basetexteditor.h
+++ b/src/plugins/texteditor/basetexteditor.h
@@ -285,6 +285,7 @@ private:
 class TEXTEDITOR_EXPORT BaseTextEditor : public QPlainTextEdit
 {
     Q_OBJECT
+    Q_PROPERTY(int verticalBlockSelection READ verticalBlockSelection)
 
 public:
     BaseTextEditor(QWidget *parent);
@@ -382,6 +383,9 @@ public:
 
     void insertCodeSnippet(const QTextCursor &cursor, const QString &snippet);
 
+
+    int verticalBlockSelection() const;
+
 public slots:
     void setDisplayName(const QString &title);
 
@@ -457,7 +461,7 @@ private slots:
     void memorizeCursorPosition();
     void restoreCursorPosition();
     void highlightSearchResults(const QString &txt, Find::IFindSupport::FindFlags findFlags);
-    void setFindScope(const QTextCursor &);
+    void setFindScope(const QTextCursor &, int);
     void currentEditorChanged(Core::IEditor *editor);
     void maybeEmitContentsChangedBecauseOfUndo();
 
diff --git a/src/plugins/texteditor/basetexteditor_p.h b/src/plugins/texteditor/basetexteditor_p.h
index 80eb0e929525a43808790d6536b03a99ebdfdeff..2dacf3470155e31fb028deb6d9596456f64d1389 100644
--- a/src/plugins/texteditor/basetexteditor_p.h
+++ b/src/plugins/texteditor/basetexteditor_p.h
@@ -250,6 +250,7 @@ public:
     bool m_moveLineUndoHack;
 
     QTextCursor m_findScope;
+    int m_findScopeVerticalBlockSelection;
     QTextCursor m_selectBlockAnchor;
 
     void moveCursorVisible(bool ensureVisible = true);
diff --git a/src/plugins/texteditor/texteditoroverlay.cpp b/src/plugins/texteditor/texteditoroverlay.cpp
index 07227fc52f19fe2f446fbff8bb30e53219fd612f..044d018c6463b738fd253605eb1243c91b7853a3 100644
--- a/src/plugins/texteditor/texteditoroverlay.cpp
+++ b/src/plugins/texteditor/texteditoroverlay.cpp
@@ -71,7 +71,8 @@ void TextEditorOverlay::clear()
 
 void TextEditorOverlay::addOverlaySelection(int begin, int end,
                                             const QColor &fg, const QColor &bg,
-                                            uint overlaySelectionFlags)
+                                            uint overlaySelectionFlags,
+                                            int verticalBlockSelection)
 {
     if (end < begin)
         return;
@@ -97,6 +98,8 @@ void TextEditorOverlay::addOverlaySelection(int begin, int end,
 
     selection.m_dropShadow = (overlaySelectionFlags & DropShadow);
 
+    selection.m_verticalBlockSelection = verticalBlockSelection;
+
     m_selections.append(selection);
     update();
 }
@@ -104,9 +107,11 @@ void TextEditorOverlay::addOverlaySelection(int begin, int end,
 
 void TextEditorOverlay::addOverlaySelection(const QTextCursor &cursor,
                                             const QColor &fg, const QColor &bg,
-                                            uint overlaySelectionFlags)
+                                            uint overlaySelectionFlags,
+                                            int verticalBlockSelection)
 {
-    addOverlaySelection(cursor.selectionStart(), cursor.selectionEnd(), fg, bg, overlaySelectionFlags);
+    addOverlaySelection(cursor.selectionStart(), cursor.selectionEnd(), fg, bg, overlaySelectionFlags,
+                        verticalBlockSelection);
 }
 
 QRect TextEditorOverlay::rect() const
@@ -115,7 +120,7 @@ QRect TextEditorOverlay::rect() const
 }
 
 QPainterPath TextEditorOverlay::createSelectionPath(const QTextCursor &begin, const QTextCursor &end,
-                                                    const QRect &clip)
+                                                    const QRect &clip, int verticalBlockSelection)
 {
     if (begin.isNull() || end.isNull() || begin.position() > end.position())
         return QPainterPath();
@@ -129,6 +134,7 @@ QPainterPath TextEditorOverlay::createSelectionPath(const QTextCursor &begin, co
         )
         return QPainterPath(); // nothing of the selection is visible
 
+
     QTextBlock block = begin.block();
 
     bool inSelection = false;
@@ -159,10 +165,12 @@ QPainterPath TextEditorOverlay::createSelectionPath(const QTextCursor &begin, co
 
             int beginChar = 0;
             if (!inSelection) {
-                beginChar = begin.position() - begin.block().position();
+                beginChar = begin.positionInBlock();
                 line = blockLayout->lineForTextPosition(beginChar);
                 inSelection = true;
                 firstOrLastBlock = true;
+            } else if (verticalBlockSelection) {
+                beginChar = qMin(block.length()-1, begin.positionInBlock());
             } else {
                 while (beginChar < block.length() && document->characterAt(block.position() + beginChar).isSpace())
                     ++beginChar;
@@ -173,10 +181,12 @@ QPainterPath TextEditorOverlay::createSelectionPath(const QTextCursor &begin, co
             int lastLine = blockLayout->lineCount()-1;
             int endChar = -1;
             if (block == end.block()) {
-                endChar = end.position()  - end.block().position();
+                endChar = end.positionInBlock();
                 lastLine = blockLayout->lineForTextPosition(endChar).lineNumber();
                 inSelection = false;
                 firstOrLastBlock = true;
+            } else if (verticalBlockSelection) {
+                endChar = qMin(block.length()-1, begin.positionInBlock() + verticalBlockSelection);
             } else {
                 endChar = block.length();
                 while (endChar > beginChar && document->characterAt(block.position() + endChar - 1).isSpace())
@@ -197,7 +207,7 @@ QPainterPath TextEditorOverlay::createSelectionPath(const QTextCursor &begin, co
                         lineRect.setRight(line.cursorToX(endChar));
                     selection += lineRect.translated(blockGeometry.topLeft());
                 }
-            } else { // empty lines
+            } else if (!verticalBlockSelection){ // empty lines
                 const int emptyLineSelectionSize = 16;
                 if (!firstOrLastBlock && !selection.isEmpty()) { // middle
                     lineRect.setLeft(selection.last().left());
@@ -314,7 +324,8 @@ void TextEditorOverlay::paintSelection(QPainter *painter,
         || begin.position() > end.position())
         return;
 
-    QPainterPath path = createSelectionPath(begin, end, m_editor->viewport()->rect());
+    QPainterPath path = createSelectionPath(begin, end, m_editor->viewport()->rect(),
+                                            selection.m_verticalBlockSelection);
 
     painter->save();
     QColor penColor = fg;
@@ -374,7 +385,8 @@ void TextEditorOverlay::fillSelection(QPainter *painter,
     if (begin.isNull() || end.isNull() || begin.position() > end.position())
         return;
 
-    QPainterPath path = createSelectionPath(begin, end, m_editor->viewport()->rect());
+    QPainterPath path = createSelectionPath(begin, end, m_editor->viewport()->rect(),
+                                            selection.m_verticalBlockSelection);
 
     painter->save();
     painter->translate(-.5, -.5);
diff --git a/src/plugins/texteditor/texteditoroverlay.h b/src/plugins/texteditor/texteditoroverlay.h
index 2730a63d01e05252f2b5786184d8f1453c666b00..7cc9593c6d15a8776783c52a7fe04c9df6c5b6fa 100644
--- a/src/plugins/texteditor/texteditoroverlay.h
+++ b/src/plugins/texteditor/texteditoroverlay.h
@@ -37,7 +37,8 @@ namespace TextEditor {
 namespace Internal {
 
 struct TEXTEDITOR_EXPORT OverlaySelection {
-    OverlaySelection():m_fixedLength(-1), m_dropShadow(false), m_expandBegin(false){}
+    OverlaySelection():m_fixedLength(-1), m_dropShadow(false),
+    m_expandBegin(false), m_verticalBlockSelection(0){}
     QTextCursor m_cursor_begin;
     QTextCursor m_cursor_end;
     QColor m_fg;
@@ -45,6 +46,7 @@ struct TEXTEDITOR_EXPORT OverlaySelection {
     int m_fixedLength;
     bool m_dropShadow;
     bool m_expandBegin;
+    int m_verticalBlockSelection;
 };
 
 class TEXTEDITOR_EXPORT TextEditorOverlay : public QObject
@@ -90,9 +92,9 @@ public:
     };
 
     void addOverlaySelection(const QTextCursor &cursor, const QColor &fg, const QColor &bg,
-                             uint overlaySelectionFlags = 0);
+                             uint overlaySelectionFlags = 0, int verticalBlockSelection = 0);
     void addOverlaySelection(int begin, int end, const QColor &fg, const QColor &bg,
-                             uint overlaySelectionFlags = 0);
+                             uint overlaySelectionFlags = 0, int verticalBlockSelection = 0);
 
     inline bool isEmpty() const { return m_selections.isEmpty(); }
 
@@ -101,7 +103,8 @@ public:
     bool hasCursorInSelection(const QTextCursor &cursor) const;
 
 private:
-    QPainterPath createSelectionPath(const QTextCursor &begin, const QTextCursor &end, const QRect& clip);
+    QPainterPath createSelectionPath(const QTextCursor &begin, const QTextCursor &end, const QRect& clip,
+                                     int verticalBlockSelection);
     void paintSelection(QPainter *painter, const OverlaySelection &selection);
     void fillSelection(QPainter *painter, const OverlaySelection &selection, const QColor &color);