forked from qt-creator/qt-creator
FakeVim: Select and modify paragraph object
Change-Id: Ib528fa2914bfcb17caed114d7da2d201079b0725 Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
@@ -1576,6 +1576,432 @@ void FakeVimPlugin::test_vim_block_selection_insert()
|
||||
);
|
||||
}
|
||||
|
||||
void FakeVimPlugin::test_vim_delete_inner_paragraph()
|
||||
{
|
||||
TestData data;
|
||||
setup(&data);
|
||||
|
||||
data.setText(
|
||||
"abc" N
|
||||
"def" N
|
||||
"" N
|
||||
"" N
|
||||
"ghi" N
|
||||
"" N
|
||||
"jkl" N
|
||||
);
|
||||
|
||||
KEYS("dip",
|
||||
X "" N
|
||||
"" N
|
||||
"ghi" N
|
||||
"" N
|
||||
"jkl" N
|
||||
);
|
||||
KEYS("dip",
|
||||
X "ghi" N
|
||||
"" N
|
||||
"jkl" N
|
||||
);
|
||||
KEYS("2dip",
|
||||
X "jkl" N
|
||||
);
|
||||
}
|
||||
|
||||
void FakeVimPlugin::test_vim_delete_a_paragraph()
|
||||
{
|
||||
TestData data;
|
||||
setup(&data);
|
||||
|
||||
data.setText(
|
||||
"abc" N
|
||||
"def" N
|
||||
"" N
|
||||
"" N
|
||||
"ghi" N
|
||||
"" N
|
||||
"jkl" N
|
||||
);
|
||||
|
||||
KEYS("dap",
|
||||
X "ghi" N
|
||||
"" N
|
||||
"jkl" N
|
||||
);
|
||||
KEYS("dap",
|
||||
X "jkl" N
|
||||
);
|
||||
KEYS("u",
|
||||
X "ghi" N
|
||||
"" N
|
||||
"jkl" N
|
||||
);
|
||||
|
||||
data.setText(
|
||||
"abc" N
|
||||
"" N
|
||||
"" N
|
||||
"def"
|
||||
);
|
||||
KEYS("Gdap",
|
||||
X "abc"
|
||||
);
|
||||
}
|
||||
|
||||
void FakeVimPlugin::test_vim_change_inner_paragraph()
|
||||
{
|
||||
TestData data;
|
||||
setup(&data);
|
||||
|
||||
data.setText(
|
||||
"abc" N
|
||||
"def" N
|
||||
"" N
|
||||
"" N
|
||||
"ghi" N
|
||||
"" N
|
||||
"jkl" N
|
||||
);
|
||||
|
||||
KEYS("cipXXX<ESC>",
|
||||
"XX" X "X" N
|
||||
"" N
|
||||
"" N
|
||||
"ghi" N
|
||||
"" N
|
||||
"jkl" N
|
||||
);
|
||||
KEYS("3j" "cipYYY<ESC>",
|
||||
"XXX" N
|
||||
"" N
|
||||
"" N
|
||||
"YY" X "Y" N
|
||||
"" N
|
||||
"jkl" N
|
||||
);
|
||||
}
|
||||
|
||||
void FakeVimPlugin::test_vim_change_a_paragraph()
|
||||
{
|
||||
TestData data;
|
||||
setup(&data);
|
||||
|
||||
data.setText(
|
||||
"abc" N
|
||||
"def" N
|
||||
"" N
|
||||
"" N
|
||||
"ghi" N
|
||||
"" N
|
||||
"jkl" N
|
||||
);
|
||||
|
||||
KEYS("4j" "capXXX<ESC>",
|
||||
"abc" N
|
||||
"def" N
|
||||
"" N
|
||||
"" N
|
||||
"XX" X "X" N
|
||||
"jkl" N
|
||||
);
|
||||
KEYS("gg" "capYYY<ESC>",
|
||||
"YY" X "Y" N
|
||||
"XXX" N
|
||||
"jkl" N
|
||||
);
|
||||
|
||||
data.setText(
|
||||
"abc" N
|
||||
"" N
|
||||
"" N
|
||||
"def"
|
||||
);
|
||||
KEYS("GcapXXX<ESC>",
|
||||
"abc" N
|
||||
"XX" X "X"
|
||||
);
|
||||
}
|
||||
|
||||
void FakeVimPlugin::test_vim_select_inner_paragraph()
|
||||
{
|
||||
TestData data;
|
||||
setup(&data);
|
||||
|
||||
data.setText(
|
||||
"" N
|
||||
X "abc" N
|
||||
"def" N
|
||||
"" N
|
||||
"ghi"
|
||||
);
|
||||
KEYS("vip" "r-",
|
||||
"" N
|
||||
X "---" N
|
||||
"---" N
|
||||
"" N
|
||||
"ghi"
|
||||
);
|
||||
|
||||
data.setText(
|
||||
"" N
|
||||
X "abc" N
|
||||
"def" N
|
||||
"" N
|
||||
"ghi"
|
||||
);
|
||||
KEYS("vip" ":s/^/-<CR>",
|
||||
"" N
|
||||
"-abc" N
|
||||
X "-def" N
|
||||
"" N
|
||||
"ghi"
|
||||
);
|
||||
|
||||
data.setText(
|
||||
"" N
|
||||
X "abc" N
|
||||
"def" N
|
||||
"" N
|
||||
"ghi"
|
||||
);
|
||||
KEYS("v2ip" ":s/^/-<CR>",
|
||||
"" N
|
||||
"-abc" N
|
||||
"-def" N
|
||||
X "-" N
|
||||
"ghi"
|
||||
);
|
||||
|
||||
data.setText(
|
||||
"" N
|
||||
X "abc" N
|
||||
"def" N
|
||||
"" N
|
||||
"ghi"
|
||||
);
|
||||
KEYS("Vj" "ip" ":s/^/-<CR>",
|
||||
"" N
|
||||
"-abc" N
|
||||
"-def" N
|
||||
X "-" N
|
||||
"ghi"
|
||||
);
|
||||
|
||||
data.setText(
|
||||
"" N
|
||||
X "abc" N
|
||||
"def" N
|
||||
"" N
|
||||
"ghi"
|
||||
);
|
||||
KEYS("vj" "ip" ":s/^/-<CR>",
|
||||
"" N
|
||||
"-abc" N
|
||||
"-def" N
|
||||
"-" N
|
||||
"ghi"
|
||||
);
|
||||
|
||||
data.setText(
|
||||
"" N
|
||||
X "abc" N
|
||||
"def" N
|
||||
"ghi" N
|
||||
"" N
|
||||
"jkl"
|
||||
);
|
||||
KEYS("vj" "ip" ":s/^/-<CR>",
|
||||
"" N
|
||||
"-abc" N
|
||||
"-def" N
|
||||
"-ghi" N
|
||||
"" N
|
||||
"jkl"
|
||||
);
|
||||
|
||||
data.setText(
|
||||
"" N
|
||||
X "abc" N
|
||||
"def" N
|
||||
"" N
|
||||
"ghi"
|
||||
);
|
||||
KEYS("vip" "r-",
|
||||
"" N
|
||||
X "---" N
|
||||
"---" N
|
||||
"" N
|
||||
"ghi"
|
||||
);
|
||||
|
||||
data.setText(
|
||||
"abc" N
|
||||
"" N
|
||||
"def"
|
||||
);
|
||||
KEYS("G" "vip" "r-",
|
||||
"abc" N
|
||||
"" N
|
||||
"---"
|
||||
);
|
||||
|
||||
data.setText(
|
||||
"" N
|
||||
"" N
|
||||
"ghi"
|
||||
);
|
||||
KEYS("vip" ":s/^/-<CR>",
|
||||
"-" N
|
||||
"-" N
|
||||
"ghi"
|
||||
);
|
||||
|
||||
data.setText(
|
||||
"" N
|
||||
"ghi"
|
||||
);
|
||||
KEYS("vip" "ip" ":s/^/-<CR>",
|
||||
"-" N
|
||||
X "-ghi"
|
||||
);
|
||||
|
||||
data.setText(
|
||||
"abc" N
|
||||
"" N
|
||||
""
|
||||
);
|
||||
KEYS("j" "vip" ":s/^/-<CR>",
|
||||
"abc" N
|
||||
"-" N
|
||||
"-"
|
||||
);
|
||||
|
||||
// Don't move anchor if it's on different line.
|
||||
data.setText(
|
||||
"" N
|
||||
"abc" N
|
||||
X "def" N
|
||||
"ghi" N
|
||||
"" N
|
||||
"jkl"
|
||||
);
|
||||
KEYS("vj" "ip" ":s/^/-<CR>",
|
||||
"" N
|
||||
"abc" N
|
||||
"-def" N
|
||||
"-ghi" N
|
||||
X "-" N
|
||||
"jkl"
|
||||
);
|
||||
|
||||
// Don't change selection mode if anchor is on different line.
|
||||
data.setText(
|
||||
"" N
|
||||
"abc" N
|
||||
X "def" N
|
||||
"ghi" N
|
||||
"" N
|
||||
"jkl"
|
||||
);
|
||||
KEYS("vj" "2ip" "r-",
|
||||
"" N
|
||||
"abc" N
|
||||
X "---" N
|
||||
"---" N
|
||||
"" N
|
||||
"-kl"
|
||||
);
|
||||
KEYS("gv" ":s/^/X<CR>",
|
||||
"" N
|
||||
"abc" N
|
||||
"X---" N
|
||||
"X---" N
|
||||
"X" N
|
||||
X "X-kl"
|
||||
);
|
||||
|
||||
data.setText(
|
||||
"" N
|
||||
"abc" N
|
||||
X "def" N
|
||||
"ghi" N
|
||||
"" N
|
||||
"jkl"
|
||||
);
|
||||
KEYS("<C-V>j" "2ip" "r-",
|
||||
"" N
|
||||
"abc" N
|
||||
X "-ef" N
|
||||
"-hi" N
|
||||
"" N
|
||||
"-kl"
|
||||
);
|
||||
KEYS("gv" "IX<ESC>",
|
||||
"" N
|
||||
"abc" N
|
||||
"X-ef" N
|
||||
"X-hi" N
|
||||
"X" N
|
||||
"X-kl"
|
||||
);
|
||||
}
|
||||
|
||||
void FakeVimPlugin::test_vim_select_a_paragraph()
|
||||
{
|
||||
TestData data;
|
||||
setup(&data);
|
||||
|
||||
data.setText(
|
||||
"abc" N
|
||||
"def" N
|
||||
"" N
|
||||
"ghi"
|
||||
);
|
||||
KEYS("vap" ":s/^/-<CR>",
|
||||
"-abc" N
|
||||
"-def" N
|
||||
"-" N
|
||||
"ghi"
|
||||
);
|
||||
|
||||
data.setText(
|
||||
"" N
|
||||
"abc" N
|
||||
"def" N
|
||||
"" N
|
||||
"ghi"
|
||||
);
|
||||
KEYS("vap" ":s/^/-<CR>",
|
||||
"-" N
|
||||
"-abc" N
|
||||
"-def" N
|
||||
"" N
|
||||
"ghi"
|
||||
);
|
||||
|
||||
data.setText(
|
||||
"abc" N
|
||||
"def" N
|
||||
""
|
||||
);
|
||||
KEYS("j" "vap" ":s/^/-<CR>",
|
||||
"-abc" N
|
||||
"-def" N
|
||||
"-"
|
||||
);
|
||||
|
||||
data.setText(
|
||||
"" N
|
||||
"abc" N
|
||||
"def"
|
||||
);
|
||||
KEYS("j" "vap" ":s/^/-<CR>",
|
||||
"-" N
|
||||
"-abc" N
|
||||
"-def"
|
||||
);
|
||||
}
|
||||
|
||||
void FakeVimPlugin::test_vim_repeat()
|
||||
{
|
||||
TestData data;
|
||||
|
||||
@@ -1776,6 +1776,7 @@ public:
|
||||
int lineNumber(const QTextBlock &block) const;
|
||||
|
||||
int columnAt(int pos) const;
|
||||
int blockNumberAt(int pos) const;
|
||||
QTextBlock blockAt(int pos) const;
|
||||
QTextBlock nextLine(const QTextBlock &block) const; // following line (respects wrapped parts)
|
||||
QTextBlock previousLine(const QTextBlock &block) const; // previous line (respects wrapped parts)
|
||||
@@ -1916,8 +1917,9 @@ public:
|
||||
QTextCursor m_cursor;
|
||||
bool m_cursorNeedsUpdate;
|
||||
|
||||
bool moveToPreviousParagraph(int count) { return moveToNextParagraph(-count); }
|
||||
bool moveToNextParagraph(int count);
|
||||
bool moveToPreviousParagraph(int count = 1) { return moveToNextParagraph(-count); }
|
||||
bool moveToNextParagraph(int count = 1);
|
||||
void moveToParagraphStartOrEnd(int direction = 1);
|
||||
|
||||
bool handleFfTt(const QString &key, bool repeats = false);
|
||||
|
||||
@@ -3197,7 +3199,6 @@ bool FakeVimHandler::Private::moveToNextParagraph(int count)
|
||||
{
|
||||
const bool forward = count > 0;
|
||||
int repeat = forward ? count : -count;
|
||||
int pos = position();
|
||||
QTextBlock block = this->block();
|
||||
|
||||
if (block.isValid() && block.length() == 1)
|
||||
@@ -3209,23 +3210,39 @@ bool FakeVimHandler::Private::moveToNextParagraph(int count)
|
||||
break;
|
||||
while (block.isValid() && block.length() == 1)
|
||||
block = forward ? block.next() : block.previous();
|
||||
if (!block.isValid())
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (repeat == 0)
|
||||
setPosition(block.position());
|
||||
else if (repeat == 1)
|
||||
setPosition(forward ? lastPositionInDocument() : 0);
|
||||
else
|
||||
if (!block.isValid())
|
||||
--repeat;
|
||||
|
||||
if (repeat > 0)
|
||||
return false;
|
||||
|
||||
recordJump(pos);
|
||||
setTargetColumn();
|
||||
g.movetype = MoveExclusive;
|
||||
if (block.isValid())
|
||||
setPosition(block.position());
|
||||
else
|
||||
setPosition(forward ? lastPositionInDocument() : 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FakeVimHandler::Private::moveToParagraphStartOrEnd(int direction)
|
||||
{
|
||||
bool emptyLine = atEmptyLine();
|
||||
int oldPos = -1;
|
||||
|
||||
while (atEmptyLine() == emptyLine && oldPos != position()) {
|
||||
oldPos = position();
|
||||
moveDown(direction);
|
||||
}
|
||||
|
||||
if (oldPos != position())
|
||||
moveUp(direction);
|
||||
}
|
||||
|
||||
void FakeVimHandler::Private::moveToEndOfLine()
|
||||
{
|
||||
// Additionally select (in visual mode) or apply current command on hidden lines following
|
||||
@@ -3836,10 +3853,16 @@ bool FakeVimHandler::Private::handleMovement(const Input &input)
|
||||
moveRight(qMin(column, rightDist() - 1));
|
||||
m_targetColumn = column;
|
||||
m_visualTargetColumn = column;
|
||||
} else if (input.is('}')) {
|
||||
handled = moveToNextParagraph(count);
|
||||
} else if (input.is('{')) {
|
||||
handled = moveToPreviousParagraph(count);
|
||||
} else if (input.is('{') || input.is('}')) {
|
||||
const int oldPosition = position();
|
||||
handled = input.is('}')
|
||||
? moveToNextParagraph(count)
|
||||
: moveToPreviousParagraph(count);
|
||||
if (handled) {
|
||||
recordJump(oldPosition);
|
||||
setTargetColumn();
|
||||
g.movetype = MoveExclusive;
|
||||
}
|
||||
} else if (input.isReturn()) {
|
||||
moveToStartOfLine();
|
||||
moveDown();
|
||||
@@ -7333,6 +7356,11 @@ int FakeVimHandler::Private::columnAt(int pos) const
|
||||
return pos - blockAt(pos).position();
|
||||
}
|
||||
|
||||
int FakeVimHandler::Private::blockNumberAt(int pos) const
|
||||
{
|
||||
return blockAt(pos).blockNumber();
|
||||
}
|
||||
|
||||
QTextBlock FakeVimHandler::Private::blockAt(int pos) const
|
||||
{
|
||||
return document()->findBlock(pos);
|
||||
@@ -8044,7 +8072,81 @@ void FakeVimHandler::Private::selectSentenceTextObject(bool inner)
|
||||
|
||||
void FakeVimHandler::Private::selectParagraphTextObject(bool inner)
|
||||
{
|
||||
Q_UNUSED(inner);
|
||||
const QTextCursor oldCursor = m_cursor;
|
||||
const VisualMode oldVisualMode = g.visualMode;
|
||||
|
||||
const int anchorBlock = blockNumberAt(anchor());
|
||||
const int positionBlock = blockNumberAt(position());
|
||||
const bool setupAnchor = anchorBlock == positionBlock;
|
||||
int repeat = count();
|
||||
|
||||
// If anchor and position are in the same block,
|
||||
// start line selection at beginning of current paragraph.
|
||||
if (setupAnchor) {
|
||||
moveToParagraphStartOrEnd(-1);
|
||||
setAnchor();
|
||||
|
||||
if (!isVisualLineMode() && isVisualMode())
|
||||
toggleVisualMode(VisualLineMode);
|
||||
}
|
||||
|
||||
const bool forward = anchor() <= position();
|
||||
const int d = forward ? 1 : -1;
|
||||
|
||||
bool startsAtParagraph = !atEmptyLine(position());
|
||||
|
||||
moveToParagraphStartOrEnd(d);
|
||||
|
||||
// If selection already changed, decreate count.
|
||||
if ((setupAnchor && g.submode != NoSubMode)
|
||||
|| oldVisualMode != g.visualMode
|
||||
|| m_cursor != oldCursor)
|
||||
{
|
||||
--repeat;
|
||||
if (!inner) {
|
||||
moveDown(d);
|
||||
moveToParagraphStartOrEnd(d);
|
||||
startsAtParagraph = !startsAtParagraph;
|
||||
}
|
||||
}
|
||||
|
||||
if (repeat > 0) {
|
||||
bool isCountEven = repeat % 2 == 0;
|
||||
bool endsOnParagraph =
|
||||
inner ? isCountEven == startsAtParagraph : startsAtParagraph;
|
||||
|
||||
if (inner) {
|
||||
repeat = repeat / 2;
|
||||
if (!isCountEven || endsOnParagraph)
|
||||
++repeat;
|
||||
} else {
|
||||
if (endsOnParagraph)
|
||||
++repeat;
|
||||
}
|
||||
|
||||
if (!moveToNextParagraph(d * repeat)) {
|
||||
m_cursor = oldCursor;
|
||||
g.visualMode = oldVisualMode;
|
||||
return;
|
||||
}
|
||||
|
||||
if (endsOnParagraph && atEmptyLine())
|
||||
moveUp(d);
|
||||
else
|
||||
moveToParagraphStartOrEnd(d);
|
||||
}
|
||||
|
||||
if (!inner && setupAnchor && !atEmptyLine() && !atEmptyLine(anchor())) {
|
||||
// If position cannot select empty lines, try to select them with anchor.
|
||||
setAnchorAndPosition(position(), anchor());
|
||||
moveToNextParagraph(-d);
|
||||
moveToParagraphStartOrEnd(-d);
|
||||
setAnchorAndPosition(position(), anchor());
|
||||
}
|
||||
|
||||
recordJump(oldCursor.position());
|
||||
setTargetColumn();
|
||||
g.movetype = MoveLineWise;
|
||||
}
|
||||
|
||||
bool FakeVimHandler::Private::selectBlockTextObject(bool inner,
|
||||
|
||||
@@ -61,23 +61,37 @@ private:
|
||||
#ifdef WITH_TESTS
|
||||
private slots:
|
||||
void cleanup();
|
||||
|
||||
void test_vim_movement();
|
||||
|
||||
void test_vim_target_column_normal();
|
||||
void test_vim_target_column_visual_char();
|
||||
void test_vim_target_column_visual_block();
|
||||
void test_vim_target_column_visual_line();
|
||||
void test_vim_target_column_insert();
|
||||
void test_vim_target_column_replace();
|
||||
|
||||
void test_vim_insert();
|
||||
void test_vim_fFtT();
|
||||
void test_vim_transform_numbers();
|
||||
void test_vim_delete();
|
||||
|
||||
void test_vim_delete_inner_word();
|
||||
void test_vim_delete_a_word();
|
||||
void test_vim_change_a_word();
|
||||
|
||||
void test_vim_change_replace();
|
||||
|
||||
void test_vim_block_selection();
|
||||
void test_vim_block_selection_insert();
|
||||
|
||||
void test_vim_delete_inner_paragraph();
|
||||
void test_vim_delete_a_paragraph();
|
||||
void test_vim_change_inner_paragraph();
|
||||
void test_vim_change_a_paragraph();
|
||||
void test_vim_select_inner_paragraph();
|
||||
void test_vim_select_a_paragraph();
|
||||
|
||||
void test_vim_repeat();
|
||||
void test_vim_search();
|
||||
void test_vim_indent();
|
||||
|
||||
Reference in New Issue
Block a user