summaryrefslogtreecommitdiff
path: root/src/plugins
diff options
context:
space:
mode:
authorhluk <hluk@email.cz>2014-02-03 20:47:47 +0100
committerhjk <hjk121@nokiamail.com>2014-02-11 11:27:44 +0100
commitd90d6f40b3fec4eabfa81e673225e7333a7229ff (patch)
tree020a6dca44ceeca470b6cd1c40c44f5659d02ef8 /src/plugins
parent33345045bcce187cd0f8a72a7168980363243291 (diff)
downloadqt-creator-d90d6f40b3fec4eabfa81e673225e7333a7229ff.tar.gz
FakeVim: Fixes for insert/change in visual mode
Always limit position of marks to current document (mainly position of '<' and '>' marks for last selection). Command '$' selects end of selected lines in visual block mode. This will require editor support since visual representation of such selection isn't always rectangle. Command 'c' works the same as 's' in visual block mode. Corrected positions for 'I', 'A', 's' and 'c' commands in visual block mode after '<ESC>'. Task-number: QTCREATORBUG-11378 Change-Id: I86582b634eb782829db48fd1b914713f87ac409f Reviewed-by: hjk <hjk121@nokiamail.com>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/fakevim/fakevim_test.cpp115
-rw-r--r--src/plugins/fakevim/fakevimhandler.cpp279
-rw-r--r--src/plugins/fakevim/fakevimplugin.h1
3 files changed, 274 insertions, 121 deletions
diff --git a/src/plugins/fakevim/fakevim_test.cpp b/src/plugins/fakevim/fakevim_test.cpp
index 037eb3ef27..4687c5b76f 100644
--- a/src/plugins/fakevim/fakevim_test.cpp
+++ b/src/plugins/fakevim/fakevim_test.cpp
@@ -644,19 +644,6 @@ void FakeVimPlugin::test_vim_insert()
KEYS("i<bs>XY", "aXY" X "c" N "def");
KEYS("j.", "aXYc" N "dX" X "Yf");
- // insert in visual block mode
- data.setText("abc" N "d" X "ef" N "jkl" N "mno" N "pqr");
- KEYS("<c-v>2j" "2I" "XYZ<esc>", "abc" N "d" X "XYZXYZef" N "jXYZXYZkl" N "mXYZXYZno" N "pqr");
- INTEGRITY(false);
-
- data.setText("abc" N "d" X "ef" N "jkl" N "mno" N "pqr");
- KEYS("<c-v>2j" "2A" "XYZ<esc>", "abc" N "d" X "eXYZXYZf" N "jkXYZXYZl" N "mnXYZXYZo" N "pqr");
- INTEGRITY(false);
-
- data.setText("abc" N "de" X "f" N "" N "jkl" N "mno");
- KEYS("<c-v>2jh" "2I" "XYZ<esc>", "abc" N "d" X "XYZXYZef" N "" N "jXYZXYZkl" N "mno");
- INTEGRITY(false);
-
// insert in visual mode
data.setText(" a" X "bcde" N " fghij" N " klmno");
KEYS("v2l" "2Ixyz<esc>", "xyzxy" X "z abcde" N " fghij" N " klmno");
@@ -1199,12 +1186,36 @@ void FakeVimPlugin::test_vim_change_replace()
INTEGRITY(false);
// insert in visual block mode
- data.setText("abc" N "d" X "ef" N "jkl" N "mno" N "pqr");
- KEYS("<c-v>2j" "2s" "XYZ<esc>", "abc" N "d" X "XYZf" N "jXYZl" N "mXYZo" N "pqr");
+ data.setText(
+ "abc" N
+ "d" X "ef" N
+ "" N
+ "jkl" N
+ "mno" N
+ );
+ KEYS("<c-v>2j2sXYZ<esc>",
+ "abc" N
+ "dXY" X "Zf" N
+ "" N
+ "jXYZl" N
+ "mno" N
+ );
INTEGRITY(false);
- data.setText("abc" N "de" X "f" N "" N "jkl" N "mno");
- KEYS("<c-v>2jh" "2s" "XYZ<esc>", "abc" N "d" X "XYZ" N "" N "jXYZ" N "mno");
+ data.setText(
+ "abc" N
+ "de" X "f" N
+ "" N
+ "jkl" N
+ "mno" N
+ );
+ KEYS("<c-v>2jh2sXYZ<esc>",
+ "abc" N
+ "dXY" X "Z" N
+ "" N
+ "jXYZ" N
+ "mno" N
+ );
INTEGRITY(false);
// change with copy to a register
@@ -1322,6 +1333,76 @@ void FakeVimPlugin::test_vim_block_selection()
KEYS("u", "\"abc\"\"" X "def\"");
}
+void FakeVimPlugin::test_vim_block_selection_insert()
+{
+ TestData data;
+ setup(&data);
+
+ // insert in visual block mode
+ data.setText("abc" N "d" X "ef" N "jkl" N "mno" N "pqr");
+ KEYS("<c-v>2j" "2I" "XYZ<esc>", "abc" N "d" X "XYZXYZef" N "jXYZXYZkl" N "mXYZXYZno" N "pqr");
+ INTEGRITY(false);
+
+ data.setText("abc" N "d" X "ef" N "jkl" N "mno" N "pqr");
+ KEYS("<c-v>2j" "2A" "XYZ<esc>", "abc" N "d" X "eXYZXYZf" N "jkXYZXYZl" N "mnXYZXYZo" N "pqr");
+ INTEGRITY(false);
+
+ data.setText("abc" N "de" X "f" N "" N "jkl" N "mno");
+ KEYS("<c-v>2jh" "2I" "XYZ<esc>", "abc" N "d" X "XYZXYZef" N "" N "jXYZXYZkl" N "mno");
+ INTEGRITY(false);
+
+ /* QTCREATORBUG-11378 */
+ data.setText(
+ " abcd" N
+ " efgh" N
+ " ijkl" N
+ " mnop" N
+ "");
+ KEYS("<C-V>3j$AXYZ<ESC>",
+ X " abcdXYZ" N
+ " efghXYZ" N
+ " ijklXYZ" N
+ " mnopXYZ" N
+ "");
+
+ data.setText(
+ " abcd" N
+ " ef" N
+ " ghijk" N
+ " lm" N
+ "");
+ KEYS("<C-V>3j$AXYZ<ESC>",
+ X " abcdXYZ" N
+ " efXYZ" N
+ " ghijkXYZ" N
+ " lmXYZ" N
+ "");
+
+ data.setText(
+ "a" N
+ "" N
+ "b" N
+ "" N
+ );
+ KEYS("j<C-V>$jAXYZ<ESC>",
+ "a" N
+ "|XYZ" N
+ "bXYZ" N
+ "" N
+ );
+
+ data.setText(
+ "abc" N
+ "" N
+ "def" N
+ );
+ KEYS("l<c-v>2jAXYZ<ESC>",
+ "a" X "bXYZc" N
+ " XYZ" N
+ "deXYZf" N
+ );
+}
+
void FakeVimPlugin::test_vim_repeat()
{
TestData data;
diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp
index 3e508a7cc5..502aa94c06 100644
--- a/src/plugins/fakevim/fakevimhandler.cpp
+++ b/src/plugins/fakevim/fakevimhandler.cpp
@@ -158,6 +158,15 @@ enum Mode
ExMode
};
+enum BlockInsertMode
+{
+ NoneBlockInsertMode,
+ AppendBlockInsertMode,
+ AppendToEndOfLineBlockInsertMode,
+ InsertBlockInsertMode,
+ ChangeBlockInsertMode
+};
+
/*! A \e SubMode is used for things that require one more data item
and are 'nested' behind a \l Mode.
*/
@@ -268,20 +277,45 @@ struct CursorPosition
int column; // Position on line.
};
-struct Mark
+class Mark
{
+public:
Mark(const CursorPosition &pos = CursorPosition(), const QString &fileName = QString())
- : position(pos), fileName(fileName) {}
+ : m_position(pos), m_fileName(fileName) {}
- bool isValid() const { return position.isValid(); }
+ bool isValid() const { return m_position.isValid(); }
bool isLocal(const QString &localFileName) const
{
- return fileName.isEmpty() || fileName == localFileName;
+ return m_fileName.isEmpty() || m_fileName == localFileName;
}
- CursorPosition position;
- QString fileName;
+ /* Return position of mark within given document.
+ * If saved line number is too big, mark position is at the end of document.
+ * If line number is in document but column is too big, mark position is at the end of line.
+ */
+ CursorPosition position(const QTextDocument *document) const
+ {
+ QTextBlock block = document->findBlockByNumber(m_position.line);
+ CursorPosition pos;
+ if (block.isValid()) {
+ pos.line = m_position.line;
+ pos.column = qMax(0, qMin(m_position.column, block.length() - 2));
+ } else if (document->isEmpty()) {
+ pos.line = 0;
+ pos.column = 0;
+ } else {
+ pos.line = document->blockCount() - 1;
+ pos.column = qMax(0, document->lastBlock().length() - 2);
+ }
+ return pos;
+ }
+
+ const QString &fileName() const { return m_fileName; }
+
+private:
+ CursorPosition m_position;
+ QString m_fileName;
};
typedef QHash<QChar, Mark> Marks;
typedef QHashIterator<QChar, Mark> MarksIterator;
@@ -1561,6 +1595,7 @@ public:
EventResult handleInsertOrReplaceMode(const Input &);
void handleInsertMode(const Input &);
void handleReplaceMode(const Input &);
+ void finishInsertMode();
EventResult handleCommandMode(const Input &);
@@ -1755,7 +1790,7 @@ public:
bool handleFfTt(QString key);
- void initVisualInsertMode(QChar command);
+ void enterVisualInsertMode(QChar command);
void enterReplaceMode();
void enterInsertMode();
void enterInsertOrReplaceMode(Mode mode);
@@ -1843,7 +1878,7 @@ public:
int m_oldInternalPosition; // copy from last event to check for external changes
int m_oldInternalAnchor;
int m_register;
- bool m_visualBlockInsert;
+ BlockInsertMode m_visualBlockInsert;
// Insert state to get last inserted text.
struct InsertState {
@@ -1949,6 +1984,8 @@ public:
// update marks on undo/redo
void updateMarks(const Marks &newMarks);
Marks m_marks; // local marks
+ CursorPosition markLessPosition() const { return mark(QLatin1Char('<')).position(document()); }
+ CursorPosition markGreaterPosition() const { return mark(QLatin1Char('>')).position(document()); }
// vi style configuration
QVariant config(int code) const { return theFakeVimSetting(code)->value(); }
@@ -2136,7 +2173,7 @@ void FakeVimHandler::Private::init()
{
m_inFakeVim = false;
m_findStartPosition = -1;
- m_visualBlockInsert = false;
+ m_visualBlockInsert = NoneBlockInsertMode;
m_fakeEnd = false;
m_positionPastEnd = false;
m_anchorPastEnd = false;
@@ -2406,8 +2443,10 @@ void FakeVimHandler::Private::exportSelection()
const int col2 = pos - document()->findBlock(pos).position();
if (col1 > col2)
++anc;
- else
+ else if (!atEndOfLine())
++pos;
+ // FIXME: After '$' command (i.e. m_visualTargetColumn == -1), end of selected lines
+ // should be selected.
setAnchorAndPosition(anc, pos);
commitCursor();
emit q->requestSetBlockSelection(false);
@@ -2435,8 +2474,8 @@ void FakeVimHandler::Private::exportSelection()
setAnchorAndPosition(anc, pos);
- setMark(QLatin1Char('<'), mark(QLatin1Char('<')).position);
- setMark(QLatin1Char('>'), mark(QLatin1Char('>')).position);
+ setMark(QLatin1Char('<'), markLessPosition());
+ setMark(QLatin1Char('>'), markGreaterPosition());
} else {
if (g.subsubmode == SearchSubSubMode && !m_searchCursor.isNull())
m_cursor = m_searchCursor;
@@ -2914,8 +2953,8 @@ void FakeVimHandler::Private::pushUndoState(bool overwrite)
m_redo.clear();
m_lastChangePosition = CursorPosition(document(), pos);
if (isVisualMode()) {
- setMark(QLatin1Char('<'), mark(QLatin1Char('<')).position);
- setMark(QLatin1Char('>'), mark(QLatin1Char('>')).position);
+ setMark(QLatin1Char('<'), markLessPosition());
+ setMark(QLatin1Char('>'), markGreaterPosition());
}
m_undoState = State(revision(), m_lastChangePosition, m_marks, m_lastVisualMode,
m_lastVisualModeInverted);
@@ -3333,7 +3372,7 @@ void FakeVimHandler::Private::updateSelection()
it.next();
QTextEdit::ExtraSelection sel;
sel.cursor = m_cursor;
- setCursorPosition(&sel.cursor, it.value().position);
+ setCursorPosition(&sel.cursor, it.value().position(document()));
sel.cursor.setPosition(sel.cursor.position(), MoveAnchor);
sel.cursor.movePosition(Right, KeepAnchor);
sel.format = m_cursor.blockCharFormat();
@@ -4046,13 +4085,13 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input)
}
} else if ((!isVisualMode() && input.is('a')) || (isVisualMode() && input.is('A'))) {
if (isVisualMode()) {
- initVisualInsertMode(QLatin1Char('A'));
+ enterVisualInsertMode(QLatin1Char('A'));
} else {
setDotCommand(_("%1a"), count());
moveRight(qMin(rightDist(), 1));
+ breakEditBlock();
+ enterInsertMode();
}
- breakEditBlock();
- enterInsertMode();
} else if (input.is('A')) {
breakEditBlock();
moveBehindEndOfLine();
@@ -4076,6 +4115,9 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input)
leaveVisualMode();
g.submode = ChangeSubMode;
finishMovement();
+ } else if ((input.is('c') || input.is('s')) && isVisualBlockMode()) {
+ resetCount();
+ enterVisualInsertMode(input.asChar());
} else if (input.is('C')) {
setAnchor();
moveToEndOfLine();
@@ -4150,7 +4192,7 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input)
moveLeft();
} else if (input.is('I')) {
if (isVisualMode()) {
- initVisualInsertMode(QLatin1Char('I'));
+ enterVisualInsertMode(QLatin1Char('I'));
} else {
if (g.gflag) {
setDotCommand(_("%1gI"), count());
@@ -4159,11 +4201,9 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input)
setDotCommand(_("%1I"), count());
moveToFirstNonBlankOnLine();
}
+ breakEditBlock();
+ enterInsertMode();
}
- pushUndoState();
- breakEditBlock();
- enterInsertMode();
- setTargetColumn();
} else if (input.isControl('i')) {
jump(count());
} else if (input.is('J')) {
@@ -4251,13 +4291,6 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input)
int repeat = count();
while (--repeat >= 0)
redo();
- } else if (input.is('s') && isVisualBlockMode()) {
- resetCount();
- pushUndoState();
- beginEditBlock();
- initVisualInsertMode(QLatin1Char('s'));
- endEditBlock();
- enterInsertMode();
} else if (input.is('s')) {
pushUndoState();
leaveVisualMode();
@@ -4299,8 +4332,8 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input)
scrollToLine(cursorLine() - sline);
} else if (g.gflag && input.is('v')) {
if (m_lastVisualMode != NoVisualMode) {
- CursorPosition from = mark(QLatin1Char('<')).position;
- CursorPosition to = mark(QLatin1Char('>')).position;
+ CursorPosition from = markLessPosition();
+ CursorPosition to = markGreaterPosition();
toggleVisualMode(m_lastVisualMode);
setCursorPosition(m_lastVisualModeInverted ? to : from);
setAnchor();
@@ -4679,6 +4712,7 @@ EventResult FakeVimHandler::Private::handleInsertOrReplaceMode(const Input &inpu
commitInsertState();
invalidateInsertState();
breakEditBlock();
+ m_visualBlockInsert = NoneBlockInsertMode;
} else if (m_oldInternalPosition == position()) {
setTargetColumn();
}
@@ -4724,73 +4758,94 @@ void FakeVimHandler::Private::handleReplaceMode(const Input &input)
}
}
-void FakeVimHandler::Private::handleInsertMode(const Input &input)
+void FakeVimHandler::Private::finishInsertMode()
{
- if (input.isEscape()) {
- bool newLineAfter = m_insertState.newLineAfter;
- bool newLineBefore = m_insertState.newLineBefore;
-
- // Repeat insertion [count] times.
- // One instance was already physically inserted while typing.
- if (!m_breakEditBlock && isInsertStateValid()) {
- commitInsertState();
-
- QString text = m_lastInsertion;
- const QString dotCommand = g.dotCommand;
- const int repeat = count() - 1;
- m_lastInsertion.clear();
- joinPreviousEditBlock();
+ bool newLineAfter = m_insertState.newLineAfter;
+ bool newLineBefore = m_insertState.newLineBefore;
- if (newLineAfter) {
- text.chop(1);
- text.prepend(_("<END>\n"));
- } else if (newLineBefore) {
- text.prepend(_("<END>"));
- }
+ // Repeat insertion [count] times.
+ // One instance was already physically inserted while typing.
+ if (!m_breakEditBlock && isInsertStateValid()) {
+ commitInsertState();
- replay(text, repeat);
-
- if (m_visualBlockInsert && !text.contains(QLatin1Char('\n'))) {
- const CursorPosition lastAnchor = mark(QLatin1Char('<')).position;
- const CursorPosition lastPosition = mark(QLatin1Char('>')).position;
- CursorPosition startPos(lastAnchor.line,
- qMin(lastPosition.column, lastAnchor.column));
- CursorPosition pos = startPos;
- if (dotCommand.endsWith(QLatin1Char('A')))
- pos.column = qMax(lastPosition.column, lastAnchor.column) + 1;
- while (pos.line < lastPosition.line) {
- ++pos.line;
- QTextCursor tc = m_cursor;
- setCursorPosition(&tc, pos);
- if (pos.line != tc.blockNumber())
- break;
- m_cursor = tc;
- if (tc.positionInBlock() == pos.column)
- replay(text, repeat + 1);
- }
+ QString text = m_lastInsertion;
+ const QString dotCommand = g.dotCommand;
+ const int repeat = count() - 1;
+ m_lastInsertion.clear();
+ joinPreviousEditBlock();
- setCursorPosition(startPos);
- } else {
- moveLeft(qMin(1, leftDist()));
+ if (newLineAfter) {
+ text.chop(1);
+ text.prepend(_("<END>\n"));
+ } else if (newLineBefore) {
+ text.prepend(_("<END>"));
+ }
+
+ replay(text, repeat);
+
+ if (m_visualBlockInsert != NoneBlockInsertMode && !text.contains(QLatin1Char('\n'))) {
+ const CursorPosition lastAnchor = markLessPosition();
+ const CursorPosition lastPosition = markGreaterPosition();
+ bool change = m_visualBlockInsert == ChangeBlockInsertMode;
+ const int insertColumn = (m_visualBlockInsert == InsertBlockInsertMode || change)
+ ? qMin(lastPosition.column, lastAnchor.column)
+ : qMax(lastPosition.column, lastAnchor.column) + 1;
+
+ CursorPosition pos(lastAnchor.line, insertColumn);
+
+ if (change)
+ pos.column = m_insertState.pos1 - document()->findBlock(m_insertState.pos1).position();
+
+ // Cursor position after block insert is on the first selected line,
+ // last selected column for 's' command, otherwise first selected column.
+ const int endColumn = change ? qMax(0, m_cursor.positionInBlock() - 1)
+ : qMin(lastPosition.column, lastAnchor.column);
+
+ while (pos.line < lastPosition.line) {
+ ++pos.line;
+ setCursorPosition(&m_cursor, pos);
+ if (m_visualBlockInsert == AppendToEndOfLineBlockInsertMode) {
+ moveToEndOfLine();
+ } else if (m_visualBlockInsert == AppendBlockInsertMode) {
+ // Prepend spaces if necessary.
+ int spaces = pos.column - m_cursor.positionInBlock();
+ if (spaces > 0) {
+ setAnchor();
+ m_cursor.insertText(QString(_(" ")).repeated(spaces));
+ }
+ } else if (m_cursor.positionInBlock() != pos.column) {
+ continue;
+ }
+ replay(text, repeat + 1);
}
- endEditBlock();
- breakEditBlock();
-
- m_lastInsertion = text;
- g.dotCommand = dotCommand;
+ setCursorPosition(CursorPosition(lastAnchor.line, endColumn));
} else {
moveLeft(qMin(1, leftDist()));
}
- if (newLineBefore || newLineAfter)
- m_lastInsertion.remove(0, m_lastInsertion.indexOf(QLatin1Char('\n')) + 1);
- g.dotCommand.append(m_lastInsertion + _("<ESC>"));
+ endEditBlock();
+ breakEditBlock();
- enterCommandMode();
- setTargetColumn();
- m_ctrlVActive = false;
- m_visualBlockInsert = false;
+ m_lastInsertion = text;
+ g.dotCommand = dotCommand;
+ } else {
+ moveLeft(qMin(1, leftDist()));
+ }
+
+ if (newLineBefore || newLineAfter)
+ m_lastInsertion.remove(0, m_lastInsertion.indexOf(QLatin1Char('\n')) + 1);
+ g.dotCommand.append(m_lastInsertion + _("<ESC>"));
+
+ enterCommandMode();
+ setTargetColumn();
+ m_ctrlVActive = false;
+}
+
+void FakeVimHandler::Private::handleInsertMode(const Input &input)
+{
+ if (input.isEscape()) {
+ finishInsertMode();
} else if (m_ctrlVActive) {
insertInInsertMode(input.raw());
} else if (input.isControl('o')) {
@@ -5109,7 +5164,7 @@ int FakeVimHandler::Private::parseLineAddress(QString *cmd)
return -1;
}
cmd->remove(0, 1);
- result = m.position.line;
+ result = m.position(document()).line;
} else if (c.isDigit()) { // line with given number
result = 0;
} else if (c == QLatin1Char('-') || c == QLatin1Char('+')) { // add or subtract from current line number
@@ -5644,8 +5699,8 @@ bool FakeVimHandler::Private::handleExMoveCommand(const ExCommand &cmd)
return true;
}
- CursorPosition lastAnchor = mark(QLatin1Char('<')).position;
- CursorPosition lastPosition = mark(QLatin1Char('>')).position;
+ CursorPosition lastAnchor = markLessPosition();
+ CursorPosition lastPosition = markGreaterPosition();
recordJump();
setPosition(cmd.range.beginPos);
@@ -7397,8 +7452,8 @@ void FakeVimHandler::Private::leaveVisualMode()
if (!isVisualMode())
return;
- setMark(QLatin1Char('<'), mark(QLatin1Char('<')).position);
- setMark(QLatin1Char('>'), mark(QLatin1Char('>')).position);
+ setMark(QLatin1Char('<'), markLessPosition());
+ setMark(QLatin1Char('>'), markGreaterPosition());
m_lastVisualModeInverted = anchor() > position();
if (isVisualLineMode()) {
g.rangemode = RangeLineMode;
@@ -7655,28 +7710,41 @@ void FakeVimHandler::Private::enterInsertOrReplaceMode(Mode mode)
clearLastInsertion();
}
-void FakeVimHandler::Private::initVisualInsertMode(QChar command)
+void FakeVimHandler::Private::enterVisualInsertMode(QChar command)
{
- m_visualBlockInsert = isVisualBlockMode();
+ if (isVisualBlockMode()) {
+ bool append = command == QLatin1Char('A');
+ bool change = command == QLatin1Char('s') || command == QLatin1Char('c');
- if (m_visualBlockInsert) {
setDotCommand(visualDotCommand() + QString::number(count()) + command);
leaveVisualMode();
- const CursorPosition lastAnchor = mark(QLatin1Char('<')).position;
- const CursorPosition lastPosition = mark(QLatin1Char('>')).position;
+ const CursorPosition lastAnchor = markLessPosition();
+ const CursorPosition lastPosition = markGreaterPosition();
CursorPosition pos(lastAnchor.line,
- command == QLatin1Char('A') ? qMax(lastPosition.column, lastAnchor.column) + 1
- : qMin(lastPosition.column, lastAnchor.column));
-
- if (command == QLatin1Char('s')) {
+ append ? qMax(lastPosition.column, lastAnchor.column) + 1
+ : qMin(lastPosition.column, lastAnchor.column));
+
+ if (append) {
+ m_visualBlockInsert = m_visualTargetColumn == -1 ? AppendToEndOfLineBlockInsertMode
+ : AppendBlockInsertMode;
+ } else if (change) {
+ m_visualBlockInsert = ChangeBlockInsertMode;
+ pushUndoState();
+ beginEditBlock();
Range range(position(), anchor(), RangeBlockMode);
yankText(range, m_register);
removeText(range);
+ endEditBlock();
+ } else {
+ m_visualBlockInsert = InsertBlockInsertMode;
}
setCursorPosition(pos);
+ if (m_visualBlockInsert == AppendToEndOfLineBlockInsertMode)
+ moveBehindEndOfLine();
} else {
+ m_visualBlockInsert = NoneBlockInsertMode;
leaveVisualMode();
if (command == QLatin1Char('I')) {
setDotCommand(_("%1i"), count());
@@ -7697,6 +7765,9 @@ void FakeVimHandler::Private::initVisualInsertMode(QChar command)
}
setAnchor();
+ if (m_visualBlockInsert != ChangeBlockInsertMode)
+ breakEditBlock();
+ enterInsertMode();
}
void FakeVimHandler::Private::enterCommandMode(Mode returnToMode)
@@ -8129,14 +8200,14 @@ bool FakeVimHandler::Private::jumpToMark(QChar mark, bool backTickMode)
return false;
}
if (!m.isLocal(m_currentFileName)) {
- emit q->jumpToGlobalMark(mark, backTickMode, m.fileName);
+ emit q->jumpToGlobalMark(mark, backTickMode, m.fileName());
return false;
}
if ((mark == QLatin1Char('\'') || mark == QLatin1Char('`')) && !m_jumpListUndo.isEmpty())
m_jumpListUndo.pop();
recordJump();
- setCursorPosition(m.position);
+ setCursorPosition(m.position(document()));
if (!backTickMode)
moveToFirstNonBlankOnLine();
if (g.submode == NoSubMode)
diff --git a/src/plugins/fakevim/fakevimplugin.h b/src/plugins/fakevim/fakevimplugin.h
index db1ced99f0..c3addea26b 100644
--- a/src/plugins/fakevim/fakevimplugin.h
+++ b/src/plugins/fakevim/fakevimplugin.h
@@ -70,6 +70,7 @@ private slots:
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_repeat();
void test_vim_search();
void test_vim_indent();