forked from qt-creator/qt-creator
FakeVim: More precise scrolling
Emulate Vim scrolling behavior. Consider only fully visible lines in editor widget. Don't ignore last empty line in document. Change-Id: Id2c4fd744fb3c4c69324ea6456db424186563bc9 Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
@@ -2487,7 +2487,7 @@ void FakeVimPlugin::test_vim_command_dgg()
|
|||||||
setup(&data);
|
setup(&data);
|
||||||
|
|
||||||
data.setText(testLines);
|
data.setText(testLines);
|
||||||
KEYS("G", lmid(0, l.size()-2)+'\n' + '|'+lmid(l.size()-2));
|
KEYS("Gk", lmid(0, l.size()-2)+'\n' + '|'+lmid(l.size()-2));
|
||||||
KEYS("dgg", "|");
|
KEYS("dgg", "|");
|
||||||
KEYS("u", '|' + lmid(0));
|
KEYS("u", '|' + lmid(0));
|
||||||
}
|
}
|
||||||
@@ -2501,9 +2501,9 @@ void FakeVimPlugin::test_vim_command_dG()
|
|||||||
KEYS("dG", "|");
|
KEYS("dG", "|");
|
||||||
KEYS("u", '|' + lmid(0));
|
KEYS("u", '|' + lmid(0));
|
||||||
KEYS("j", cursor(1, 0));
|
KEYS("j", cursor(1, 0));
|
||||||
KEYS("dG", lmid(0,1)+'\n' + '|');
|
KEYS("dG", "|");
|
||||||
KEYS("u", l[0]+'\n' + '|' + lmid(1));
|
KEYS("u", l[0]+'\n' + '|' + lmid(1));
|
||||||
KEYS("G", lmid(0, l.size()-2)+'\n' + '|'+lmid(l.size()-2));
|
KEYS("Gk", lmid(0, l.size()-2)+'\n' + '|'+lmid(l.size()-2));
|
||||||
|
|
||||||
NOT_IMPLEMENTED
|
NOT_IMPLEMENTED
|
||||||
// include movement to first column, as otherwise the result depends on the 'startofline' setting
|
// include movement to first column, as otherwise the result depends on the 'startofline' setting
|
||||||
@@ -2776,7 +2776,7 @@ void FakeVimPlugin::test_vim_command_Gyyp()
|
|||||||
setup(&data);
|
setup(&data);
|
||||||
|
|
||||||
data.setText(testLines);
|
data.setText(testLines);
|
||||||
KEYS("G", lmid(0, l.size()-2) + "\n|" + lmid(l.size()-2));
|
KEYS("Gk", lmid(0, l.size()-2) + "\n|" + lmid(l.size()-2));
|
||||||
KEYS("yyp", lmid(0) + '|' + lmid(9, 1)+'\n');
|
KEYS("yyp", lmid(0) + '|' + lmid(9, 1)+'\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2833,10 +2833,9 @@ void FakeVimPlugin::test_vim_command_oO()
|
|||||||
KEYS("Ol1<Esc>", "l|1\n" + lmid(0));
|
KEYS("Ol1<Esc>", "l|1\n" + lmid(0));
|
||||||
KEYS("gg", "|l1\n" + lmid(0));
|
KEYS("gg", "|l1\n" + lmid(0));
|
||||||
KEYS("ol2<Esc>", "l1\n" "l|2\n" + lmid(0));
|
KEYS("ol2<Esc>", "l1\n" "l|2\n" + lmid(0));
|
||||||
KEYS("G", "l1\n" "l2\n" + lmid(0,l.size()-2)+'\n' + '|'+lmid(l.size()-2));
|
KEYS("Gk$", "l1\n" "l2\n" + lmid(0,l.size()-2)+'\n' + '|'+lmid(l.size()-2));
|
||||||
KEYS("G$", "l1\n" "l2\n" + lmid(0,l.size()-2)+'\n' + '|'+lmid(l.size()-2));
|
|
||||||
KEYS("ol-1<Esc>", "l1\n" "l2\n" + lmid(0) + "l-|1\n");
|
KEYS("ol-1<Esc>", "l1\n" "l2\n" + lmid(0) + "l-|1\n");
|
||||||
KEYS("G", "l1\n" "l2\n" + lmid(0) + "|l-1\n");
|
KEYS("Gk", "l1\n" "l2\n" + lmid(0) + "|l-1\n");
|
||||||
KEYS("Ol-2<Esc>", "l1\n" "l2\n" + lmid(0) + "l-|2\n" + "l-1\n");
|
KEYS("Ol-2<Esc>", "l1\n" "l2\n" + lmid(0) + "l-|2\n" + "l-1\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1530,6 +1530,7 @@ public:
|
|||||||
int logicalCursorColumn() const; // as visible on screen
|
int logicalCursorColumn() const; // as visible on screen
|
||||||
int physicalToLogicalColumn(int physical, const QString &text) const;
|
int physicalToLogicalColumn(int physical, const QString &text) const;
|
||||||
int logicalToPhysicalColumn(int logical, const QString &text) const;
|
int logicalToPhysicalColumn(int logical, const QString &text) const;
|
||||||
|
int windowScrollOffset() const; // return scrolloffset but max half the current window height
|
||||||
Column cursorColumn() const; // as visible on screen
|
Column cursorColumn() const; // as visible on screen
|
||||||
int firstVisibleLine() const;
|
int firstVisibleLine() const;
|
||||||
void setScrollBarValue(int line);
|
void setScrollBarValue(int line);
|
||||||
@@ -1577,6 +1578,8 @@ public:
|
|||||||
void moveBehindEndOfLine();
|
void moveBehindEndOfLine();
|
||||||
void moveUp(int n = 1) { moveDown(-n); }
|
void moveUp(int n = 1) { moveDown(-n); }
|
||||||
void moveDown(int n = 1);
|
void moveDown(int n = 1);
|
||||||
|
void movePageDown(int count);
|
||||||
|
void movePageUp(int count) { movePageDown(-count); }
|
||||||
void dump(const char *msg) const {
|
void dump(const char *msg) const {
|
||||||
qDebug() << msg << "POS: " << anchor() << position()
|
qDebug() << msg << "POS: " << anchor() << position()
|
||||||
<< "EXT: " << m_oldExternalAnchor << m_oldExternalPosition
|
<< "EXT: " << m_oldExternalAnchor << m_oldExternalPosition
|
||||||
@@ -2690,6 +2693,20 @@ void FakeVimHandler::Private::moveDown(int n)
|
|||||||
updateScrollOffset();
|
updateScrollOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FakeVimHandler::Private::movePageDown(int count)
|
||||||
|
{
|
||||||
|
const int scrollOffset = windowScrollOffset();
|
||||||
|
const int screenLines = linesOnScreen();
|
||||||
|
const int offset = count > 0 ? scrollOffset - 2 : screenLines - scrollOffset + 2;
|
||||||
|
const int value = count * screenLines - cursorLineOnScreen() + offset;
|
||||||
|
moveDown(value);
|
||||||
|
|
||||||
|
if (count > 0)
|
||||||
|
scrollToLine(cursorLine());
|
||||||
|
else
|
||||||
|
scrollToLine(qMax(0, cursorLine() - screenLines));
|
||||||
|
}
|
||||||
|
|
||||||
bool FakeVimHandler::Private::moveToNextParagraph(int count)
|
bool FakeVimHandler::Private::moveToNextParagraph(int count)
|
||||||
{
|
{
|
||||||
const bool forward = count > 0;
|
const bool forward = count > 0;
|
||||||
@@ -3465,13 +3482,11 @@ bool FakeVimHandler::Private::handleMovement(const Input &input)
|
|||||||
} else if (input.is(']')) {
|
} else if (input.is(']')) {
|
||||||
m_subsubmode = CloseSquareSubSubMode;
|
m_subsubmode = CloseSquareSubSubMode;
|
||||||
} else if (input.isKey(Key_PageDown) || input.isControl('f')) {
|
} else if (input.isKey(Key_PageDown) || input.isControl('f')) {
|
||||||
moveDown(count * (linesOnScreen() - 2));
|
movePageDown(count);
|
||||||
scrollToLine(cursorLine());
|
|
||||||
handleStartOfLine();
|
handleStartOfLine();
|
||||||
movement = _("f");
|
movement = _("f");
|
||||||
} else if (input.isKey(Key_PageUp) || input.isControl('b')) {
|
} else if (input.isKey(Key_PageUp) || input.isControl('b')) {
|
||||||
moveUp(count * (linesOnScreen() - 2));
|
movePageUp(count);
|
||||||
scrollToLine(qMax(0, cursorLine() - linesOnScreen()));
|
|
||||||
handleStartOfLine();
|
handleStartOfLine();
|
||||||
movement = _("b");
|
movement = _("b");
|
||||||
} else if (input.isKey(Key_BracketLeft) || input.isKey(Key_BracketRight)) {
|
} else if (input.isKey(Key_BracketLeft) || input.isKey(Key_BracketRight)) {
|
||||||
@@ -4467,10 +4482,10 @@ EventResult FakeVimHandler::Private::handleInsertMode(const Input &input)
|
|||||||
}
|
}
|
||||||
} else if (input.isKey(Key_PageDown) || input.isControl('f')) {
|
} else if (input.isKey(Key_PageDown) || input.isControl('f')) {
|
||||||
removeAutomaticIndentation();
|
removeAutomaticIndentation();
|
||||||
moveDown(count() * (linesOnScreen() - 2));
|
movePageDown(count());
|
||||||
} else if (input.isKey(Key_PageUp) || input.isControl('b')) {
|
} else if (input.isKey(Key_PageUp) || input.isControl('b')) {
|
||||||
removeAutomaticIndentation();
|
removeAutomaticIndentation();
|
||||||
moveUp(count() * (linesOnScreen() - 2));
|
movePageUp(count());
|
||||||
} else if (input.isKey(Key_Tab)) {
|
} else if (input.isKey(Key_Tab)) {
|
||||||
m_justAutoIndented = 0;
|
m_justAutoIndented = 0;
|
||||||
if (hasConfig(ConfigExpandTab)) {
|
if (hasConfig(ConfigExpandTab)) {
|
||||||
@@ -6148,7 +6163,7 @@ int FakeVimHandler::Private::linesOnScreen() const
|
|||||||
if (!editor())
|
if (!editor())
|
||||||
return 1;
|
return 1;
|
||||||
QRect rect = EDITOR(cursorRect());
|
QRect rect = EDITOR(cursorRect());
|
||||||
return EDITOR(height()) / rect.height();
|
return EDITOR(viewport()->height()) / rect.height();
|
||||||
}
|
}
|
||||||
|
|
||||||
int FakeVimHandler::Private::columnsOnScreen() const
|
int FakeVimHandler::Private::columnsOnScreen() const
|
||||||
@@ -6157,7 +6172,7 @@ int FakeVimHandler::Private::columnsOnScreen() const
|
|||||||
return 1;
|
return 1;
|
||||||
QRect rect = EDITOR(cursorRect());
|
QRect rect = EDITOR(cursorRect());
|
||||||
// qDebug() << "WID: " << EDITOR(width()) << "RECT: " << rect;
|
// qDebug() << "WID: " << EDITOR(width()) << "RECT: " << rect;
|
||||||
return EDITOR(width()) / rect.width();
|
return EDITOR(viewport()->width()) / rect.width();
|
||||||
}
|
}
|
||||||
|
|
||||||
int FakeVimHandler::Private::cursorLine() const
|
int FakeVimHandler::Private::cursorLine() const
|
||||||
@@ -6211,6 +6226,11 @@ int FakeVimHandler::Private::logicalToPhysicalColumn
|
|||||||
return physical;
|
return physical;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int FakeVimHandler::Private::windowScrollOffset() const
|
||||||
|
{
|
||||||
|
return qMin(theFakeVimSetting(ConfigScrollOff)->value().toInt(), linesOnScreen() / 2);
|
||||||
|
}
|
||||||
|
|
||||||
int FakeVimHandler::Private::logicalCursorColumn() const
|
int FakeVimHandler::Private::logicalCursorColumn() const
|
||||||
{
|
{
|
||||||
const int physical = physicalCursorColumn();
|
const int physical = physicalCursorColumn();
|
||||||
@@ -6227,10 +6247,7 @@ int FakeVimHandler::Private::linesInDocument() const
|
|||||||
{
|
{
|
||||||
if (cursor().isNull())
|
if (cursor().isNull())
|
||||||
return 0;
|
return 0;
|
||||||
const int count = document()->blockCount();
|
return document()->blockCount();
|
||||||
// Qt inserts an empty line if the last character is a '\n',
|
|
||||||
// but that's not how vi does it.
|
|
||||||
return document()->lastBlock().length() <= 1 ? count - 1 : count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeVimHandler::Private::setScrollBarValue(int line)
|
void FakeVimHandler::Private::setScrollBarValue(int line)
|
||||||
@@ -6271,17 +6288,16 @@ void FakeVimHandler::Private::scrollUp(int count)
|
|||||||
void FakeVimHandler::Private::updateScrollOffset()
|
void FakeVimHandler::Private::updateScrollOffset()
|
||||||
{
|
{
|
||||||
// Precision of scroll offset depends on singleStep property of vertical scroll bar.
|
// Precision of scroll offset depends on singleStep property of vertical scroll bar.
|
||||||
const int screenLines = linesOnScreen();
|
const int offset = windowScrollOffset();
|
||||||
const int offset = qMin(theFakeVimSetting(ConfigScrollOff)->value().toInt(), screenLines / 2);
|
|
||||||
const int line = cursorLine();
|
const int line = cursorLine();
|
||||||
const int scrollLine = firstVisibleLine();
|
const int scrollLine = firstVisibleLine();
|
||||||
int d = line - scrollLine;
|
int d = line - scrollLine;
|
||||||
if (d < offset) {
|
if (d <= offset) {
|
||||||
setScrollBarValue(scrollLine - offset + d);
|
setScrollBarValue(scrollLine - offset + d);
|
||||||
} else {
|
} else {
|
||||||
d = screenLines - d;
|
d = linesOnScreen() - d;
|
||||||
if (d <= offset)
|
if (d <= offset)
|
||||||
setScrollBarValue(scrollLine + offset - d);
|
setScrollBarValue(scrollLine + offset - d + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user