diff --git a/src/utils/vvim.cpp b/src/utils/vvim.cpp index 3f59449f..8bfb2d98 100644 --- a/src/utils/vvim.cpp +++ b/src/utils/vvim.cpp @@ -2111,6 +2111,7 @@ bool VVim::handleKeyPressEvent(int key, int modifiers, int *p_autoIndentPos) clear_accept: resetState(); + m_editor->makeBlockVisible(m_editor->textCursor().block()); accept: ret = true; diff --git a/src/vedit.cpp b/src/vedit.cpp index 13c014b9..f66c9588 100644 --- a/src/vedit.cpp +++ b/src/vedit.cpp @@ -1168,17 +1168,65 @@ void VEdit::makeBlockVisible(const QTextBlock &p_block) height -= hbar->height(); } + bool moved = false; + QRectF rect = layout->blockBoundingRect(p_block); int y = contentOffsetY() + (int)rect.y(); + int rectHeight = (int)rect.height(); + + // Handle the case rectHeight >= height. + if (rectHeight >= height) { + if (y <= 0) { + if (y + rectHeight < height) { + // Need to scroll up. + while (y + rectHeight < height && vbar->value() > vbar->minimum()) { + moved = true; + vbar->setValue(vbar->value() - vbar->singleStep()); + rect = layout->blockBoundingRect(p_block); + rectHeight = (int)rect.height(); + y = contentOffsetY() + (int)rect.y(); + } + } + } else { + // Need to scroll down. + while (y > 0 && vbar->value() < vbar->maximum()) { + moved = true; + vbar->setValue(vbar->value() + vbar->singleStep()); + rect = layout->blockBoundingRect(p_block); + rectHeight = (int)rect.height(); + y = contentOffsetY() + (int)rect.y(); + } + } + + if (moved) { + qDebug() << "scroll to make huge block visible"; + } + + return; + } + while (y < 0 && vbar->value() > vbar->minimum()) { + moved = true; vbar->setValue(vbar->value() - vbar->singleStep()); rect = layout->blockBoundingRect(p_block); + rectHeight = (int)rect.height(); y = contentOffsetY() + (int)rect.y(); } - while (y + (int)rect.height() > height && vbar->value() < vbar->maximum()) { + if (moved) { + qDebug() << "scroll page down to make block visible"; + return; + } + + while (y + rectHeight > height && vbar->value() < vbar->maximum()) { + moved = true; vbar->setValue(vbar->value() + vbar->singleStep()); rect = layout->blockBoundingRect(p_block); + rectHeight = (int)rect.height(); y = contentOffsetY() + (int)rect.y(); } + + if (moved) { + qDebug() << "scroll page up to make block visible"; + } } diff --git a/src/vedit.h b/src/vedit.h index 625d080a..8f78edee 100644 --- a/src/vedit.h +++ b/src/vedit.h @@ -123,6 +123,12 @@ public: // LineNumberArea will call this to request paint itself. void lineNumberAreaPaintEvent(QPaintEvent *p_event); + // Scroll the content to make @p_block visible. + // If the @p_block is too long to hold in one page, just let it occupy the + // whole page. + // Will not change current cursor. + void makeBlockVisible(const QTextBlock &p_block); + signals: // Request VEditTab to save and exit edit mode. void saveAndRead(); @@ -259,10 +265,6 @@ private: bool findTextHelper(const QString &p_text, uint p_options, bool p_forward, int p_start, bool &p_wrapped, QTextCursor &p_cursor); - - // Scroll the content to make @p_block visible. - // Will not change current cursor. - void makeBlockVisible(const QTextBlock &p_block); }; class LineNumberArea : public QWidget diff --git a/src/vmdedit.cpp b/src/vmdedit.cpp index 4e5dee55..37797e8b 100644 --- a/src/vmdedit.cpp +++ b/src/vmdedit.cpp @@ -30,18 +30,7 @@ VMdEdit::VMdEdit(VFile *p_file, VDocument *p_vdoc, MarkdownConverterType p_type, // in this case. connect(m_mdHighlighter, &HGMarkdownHighlighter::highlightCompleted, this, [this]() { - QRect rect = this->cursorRect(); - int height = this->rect().height(); - QScrollBar *sbar = this->horizontalScrollBar(); - if (sbar && sbar->isVisible()) { - height -= sbar->height(); - } - - if ((rect.y() < height - && rect.y() + rect.height() > height) - || (rect.y() < 0 && rect.y() + rect.height() > 0)) { - this->ensureCursorVisible(); - } + makeBlockVisible(textCursor().block()); }); m_cbHighlighter = new VCodeBlockHighlightHelper(m_mdHighlighter, p_vdoc,