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:
resetState();
m_editor->makeBlockVisible(m_editor->textCursor().block());
accept:
ret = true;

View File

@ -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();
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());
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";
}
}

View File

@ -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

View File

@ -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,