vim-mode: make cursor block visible after actions

This commit is contained in:
Le Tan 2017-07-19 20:25:28 +08:00
parent 561cc91069
commit d0bcd7a2c6
4 changed files with 57 additions and 17 deletions

View File

@ -2111,6 +2111,7 @@ bool VVim::handleKeyPressEvent(int key, int modifiers, int *p_autoIndentPos)
clear_accept: clear_accept:
resetState(); resetState();
m_editor->makeBlockVisible(m_editor->textCursor().block());
accept: accept:
ret = true; ret = true;

View File

@ -1168,17 +1168,65 @@ void VEdit::makeBlockVisible(const QTextBlock &p_block)
height -= hbar->height(); height -= hbar->height();
} }
bool moved = false;
QRectF rect = layout->blockBoundingRect(p_block); QRectF rect = layout->blockBoundingRect(p_block);
int y = contentOffsetY() + (int)rect.y(); int y = contentOffsetY() + (int)rect.y();
while (y < 0 && vbar->value() > vbar->minimum()) { 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()); vbar->setValue(vbar->value() - vbar->singleStep());
rect = layout->blockBoundingRect(p_block); 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(); 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()); vbar->setValue(vbar->value() + vbar->singleStep());
rect = layout->blockBoundingRect(p_block); rect = layout->blockBoundingRect(p_block);
rectHeight = (int)rect.height();
y = contentOffsetY() + (int)rect.y(); y = contentOffsetY() + (int)rect.y();
} }
if (moved) {
qDebug() << "scroll page up to make block visible";
}
} }

View File

@ -123,6 +123,12 @@ public:
// LineNumberArea will call this to request paint itself. // LineNumberArea will call this to request paint itself.
void lineNumberAreaPaintEvent(QPaintEvent *p_event); 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: signals:
// Request VEditTab to save and exit edit mode. // Request VEditTab to save and exit edit mode.
void saveAndRead(); void saveAndRead();
@ -259,10 +265,6 @@ private:
bool findTextHelper(const QString &p_text, uint p_options, bool findTextHelper(const QString &p_text, uint p_options,
bool p_forward, int p_start, bool p_forward, int p_start,
bool &p_wrapped, QTextCursor &p_cursor); 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 class LineNumberArea : public QWidget

View File

@ -30,18 +30,7 @@ VMdEdit::VMdEdit(VFile *p_file, VDocument *p_vdoc, MarkdownConverterType p_type,
// in this case. // in this case.
connect(m_mdHighlighter, &HGMarkdownHighlighter::highlightCompleted, connect(m_mdHighlighter, &HGMarkdownHighlighter::highlightCompleted,
this, [this]() { this, [this]() {
QRect rect = this->cursorRect(); makeBlockVisible(textCursor().block());
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();
}
}); });
m_cbHighlighter = new VCodeBlockHighlightHelper(m_mdHighlighter, p_vdoc, m_cbHighlighter = new VCodeBlockHighlightHelper(m_mdHighlighter, p_vdoc,