fakevim: Correct Undo/Redo position for large editing operations

Change-Id: Ie5d354a0e7f59c61646d14da79bf7059821c12e5
Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
Lukas Holecek
2012-09-29 19:09:08 +02:00
committed by hjk
parent 4f0d86b4fe
commit ceaedb0883
2 changed files with 74 additions and 29 deletions

View File

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

View File

@@ -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();
setTargetColumn(); if (lastLine != -1) {
endEditBlock(); State &state = m_undo.top();
state.line = firstLine;
state.position = firstPositionInLine(firstLine);
QTextCursor tc = cursor();
tc.setPosition(firstPositionInLine(lastLine));
setCursor(tc);
moveToFirstNonBlankOnLine();
setTargetColumn();
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)