forked from qt-creator/qt-creator
fakevim: Correct Undo/Redo position for large editing operations
Change-Id: Ie5d354a0e7f59c61646d14da79bf7059821c12e5 Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
@@ -714,20 +714,19 @@ void FakeVimPlugin::test_vim_undo_redo()
|
|||||||
|
|
||||||
void FakeVimPlugin::test_advanced_commands()
|
void FakeVimPlugin::test_advanced_commands()
|
||||||
{
|
{
|
||||||
// TODO: Fix undo/redo position for substitute command.
|
|
||||||
TestData data;
|
TestData data;
|
||||||
setup(&data);
|
setup(&data);
|
||||||
|
|
||||||
// subcommands
|
// subcommands
|
||||||
data.setText("abc" N " xxx" N "def");
|
data.setText("abc" N " xxx" N " xxx" N "def");
|
||||||
COMMAND("%s/xxx/ZZZ/g|%s/ZZZ/OOO/g", "abc" N " OOO" N "def");
|
COMMAND("%s/xxx/ZZZ/g|%s/ZZZ/OOO/g", "abc" N " OOO" N " " X "OOO" N "def");
|
||||||
|
|
||||||
// undo/redo all subcommands
|
// undo/redo all subcommands
|
||||||
COMMAND(":undo", "abc" N " xxx" N "def");
|
COMMAND(":undo", "abc" N X " xxx" N " xxx" N "def");
|
||||||
COMMAND(":redo", "abc" N " OOO" N "def");
|
COMMAND(":redo", "abc" N X " OOO" N " OOO" N "def");
|
||||||
|
|
||||||
// redundant characters
|
// redundant characters
|
||||||
COMMAND("::: %s/\\S\\S\\S/ZZZ/g | :::: %s/ZZZ/XXX/g ", "XXX" N " XXX" N "XXX");
|
COMMAND("::: %s/\\S\\S\\S/ZZZ/g | :::: %s/ZZZ/XXX/g ", "XXX" N " XXX" N " XXX" N X "XXX");
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeVimPlugin::test_map()
|
void FakeVimPlugin::test_map()
|
||||||
@@ -840,6 +839,20 @@ void FakeVimPlugin::test_map()
|
|||||||
KEYS("<C-r>", X "def xyz ghi");
|
KEYS("<C-r>", X "def xyz ghi");
|
||||||
data.doCommand("unmap X");
|
data.doCommand("unmap X");
|
||||||
|
|
||||||
|
data.setText("abc" N " def" N " ghi");
|
||||||
|
data.doCommand("map X jdd");
|
||||||
|
KEYS("X", "abc" N " " X "ghi");
|
||||||
|
KEYS("u", "abc" N X " def" N " ghi");
|
||||||
|
KEYS("<c-r>", "abc" N X " ghi");
|
||||||
|
data.doCommand("unmap X");
|
||||||
|
|
||||||
|
data.setText("abc" N "def" N "ghi");
|
||||||
|
data.doCommand("map X jAxxx<cr>yyy<esc>");
|
||||||
|
KEYS("X", "abc" N "defxxx" N "yy" X "y" N "ghi");
|
||||||
|
KEYS("u", "abc" N "de" X "f" N "ghi");
|
||||||
|
KEYS("<c-r>", "abc" N "def" X "xxx" N "yyy" N "ghi");
|
||||||
|
data.doCommand("unmap X");
|
||||||
|
|
||||||
NOT_IMPLEMENTED
|
NOT_IMPLEMENTED
|
||||||
// <C-o>
|
// <C-o>
|
||||||
data.setText("abc def");
|
data.setText("abc def");
|
||||||
|
|||||||
@@ -1315,21 +1315,11 @@ public:
|
|||||||
QTextDocument *document() const { return EDITOR(document()); }
|
QTextDocument *document() const { return EDITOR(document()); }
|
||||||
QChar characterAtCursor() const
|
QChar characterAtCursor() const
|
||||||
{ return document()->characterAt(position()); }
|
{ return document()->characterAt(position()); }
|
||||||
void joinPreviousEditBlock() {
|
|
||||||
UNDO_DEBUG("JOIN");
|
void joinPreviousEditBlock();
|
||||||
if (m_breakEditBlock)
|
void beginEditBlock(bool rememberPosition = true);
|
||||||
beginEditBlock();
|
void beginLargeEditBlock() { beginEditBlock(false); }
|
||||||
else
|
void endEditBlock();
|
||||||
cursor().joinPreviousEditBlock();
|
|
||||||
}
|
|
||||||
void beginEditBlock() {
|
|
||||||
UNDO_DEBUG("BEGIN EDIT BLOCK");
|
|
||||||
cursor().beginEditBlock();
|
|
||||||
setUndoPosition(false);
|
|
||||||
m_breakEditBlock = false;
|
|
||||||
}
|
|
||||||
void endEditBlock()
|
|
||||||
{ UNDO_DEBUG("END EDIT BLOCK"); cursor().endEditBlock(); }
|
|
||||||
void breakEditBlock() { m_breakEditBlock = true; }
|
void breakEditBlock() { m_breakEditBlock = true; }
|
||||||
|
|
||||||
bool isVisualMode() const { return m_visualMode != NoVisualMode; }
|
bool isVisualMode() const { return m_visualMode != NoVisualMode; }
|
||||||
@@ -2005,7 +1995,7 @@ void FakeVimHandler::Private::handleMappedKeys()
|
|||||||
g.pendingInput << inputs << Input() << rest;
|
g.pendingInput << inputs << Input() << rest;
|
||||||
g.mapStates << MappingState(maxMapDepth, inputs.noremap(), inputs.silent());
|
g.mapStates << MappingState(maxMapDepth, inputs.noremap(), inputs.silent());
|
||||||
g.commandBuffer.setHistoryAutoSave(false);
|
g.commandBuffer.setHistoryAutoSave(false);
|
||||||
beginEditBlock();
|
beginLargeEditBlock();
|
||||||
}
|
}
|
||||||
g.currentMap.reset();
|
g.currentMap.reset();
|
||||||
}
|
}
|
||||||
@@ -4001,8 +3991,6 @@ bool FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd)
|
|||||||
replacement = line.mid(pos1 + 1, pos2 - pos1 - 1);
|
replacement = line.mid(pos1 + 1, pos2 - pos1 - 1);
|
||||||
flags = line.mid(pos2 + 1);
|
flags = line.mid(pos2 + 1);
|
||||||
|
|
||||||
needle.replace('$', '\n');
|
|
||||||
needle.replace("\\\n", "\\$");
|
|
||||||
pattern = vimPatternToQtPattern(needle, hasConfig(ConfigSmartCase));
|
pattern = vimPatternToQtPattern(needle, hasConfig(ConfigSmartCase));
|
||||||
|
|
||||||
m_lastSubstituteFlags = flags;
|
m_lastSubstituteFlags = flags;
|
||||||
@@ -4016,7 +4004,8 @@ bool FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd)
|
|||||||
if (flags.contains('i'))
|
if (flags.contains('i'))
|
||||||
pattern.setCaseSensitivity(Qt::CaseInsensitive);
|
pattern.setCaseSensitivity(Qt::CaseInsensitive);
|
||||||
|
|
||||||
beginEditBlock();
|
int lastLine = -1;
|
||||||
|
int firstLine = -1;
|
||||||
const bool global = flags.contains('g');
|
const bool global = flags.contains('g');
|
||||||
for (int a = 0; a != count; ++a) {
|
for (int a = 0; a != count; ++a) {
|
||||||
const Range range = cmd.range.endPos == 0 ? rangeFromCurrentLine() : cmd.range;
|
const Range range = cmd.range.endPos == 0 ? rangeFromCurrentLine() : cmd.range;
|
||||||
@@ -4046,6 +4035,13 @@ bool FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd)
|
|||||||
repl.replace("\\&", "&");
|
repl.replace("\\&", "&");
|
||||||
text = text.left(pos) + repl + text.mid(pos + matched.size());
|
text = text.left(pos) + repl + text.mid(pos + matched.size());
|
||||||
pos += repl.size();
|
pos += repl.size();
|
||||||
|
|
||||||
|
firstLine = line;
|
||||||
|
if (lastLine == -1) {
|
||||||
|
lastLine = line;
|
||||||
|
beginEditBlock();
|
||||||
|
}
|
||||||
|
|
||||||
if (!global)
|
if (!global)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -4053,9 +4049,21 @@ bool FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd)
|
|||||||
setLineContents(line, text);
|
setLineContents(line, text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
moveToStartOfLine();
|
|
||||||
|
if (lastLine != -1) {
|
||||||
|
State &state = m_undo.top();
|
||||||
|
state.line = firstLine;
|
||||||
|
state.position = firstPositionInLine(firstLine);
|
||||||
|
|
||||||
|
QTextCursor tc = cursor();
|
||||||
|
tc.setPosition(firstPositionInLine(lastLine));
|
||||||
|
setCursor(tc);
|
||||||
|
moveToFirstNonBlankOnLine();
|
||||||
setTargetColumn();
|
setTargetColumn();
|
||||||
|
|
||||||
endEditBlock();
|
endEditBlock();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4530,7 +4538,7 @@ void FakeVimHandler::Private::handleExCommand(const QString &line0)
|
|||||||
cmd.setContentsFromLine(line);
|
cmd.setContentsFromLine(line);
|
||||||
//qDebug() << "CMD: " << cmd;
|
//qDebug() << "CMD: " << cmd;
|
||||||
|
|
||||||
beginEditBlock();
|
beginLargeEditBlock();
|
||||||
while (cmd.nextSubcommand()) {
|
while (cmd.nextSubcommand()) {
|
||||||
if (!handleExCommandHelper(cmd)) {
|
if (!handleExCommandHelper(cmd)) {
|
||||||
showMessage(MessageError,
|
showMessage(MessageError,
|
||||||
@@ -5668,6 +5676,30 @@ QWidget *FakeVimHandler::Private::editor() const
|
|||||||
: static_cast<QWidget *>(m_plaintextedit);
|
: static_cast<QWidget *>(m_plaintextedit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FakeVimHandler::Private::joinPreviousEditBlock()
|
||||||
|
{
|
||||||
|
UNDO_DEBUG("JOIN");
|
||||||
|
if (m_breakEditBlock)
|
||||||
|
beginEditBlock();
|
||||||
|
else
|
||||||
|
cursor().joinPreviousEditBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FakeVimHandler::Private::beginEditBlock(bool rememberPosition)
|
||||||
|
{
|
||||||
|
UNDO_DEBUG("BEGIN EDIT BLOCK");
|
||||||
|
cursor().beginEditBlock();
|
||||||
|
if (rememberPosition)
|
||||||
|
setUndoPosition(false);
|
||||||
|
m_breakEditBlock = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FakeVimHandler::Private::endEditBlock()
|
||||||
|
{
|
||||||
|
UNDO_DEBUG("END EDIT BLOCK");
|
||||||
|
cursor().endEditBlock();
|
||||||
|
}
|
||||||
|
|
||||||
char FakeVimHandler::Private::currentModeCode() const
|
char FakeVimHandler::Private::currentModeCode() const
|
||||||
{
|
{
|
||||||
if (m_mode == ExMode)
|
if (m_mode == ExMode)
|
||||||
|
|||||||
Reference in New Issue
Block a user