Commit 2976345f authored by hluk's avatar hluk Committed by hjk
Browse files

FakeVim: Fix mappings in insert mode

Mapped user input shouldn't break edit block in insert mode.

Change-Id: I47ad449d9f0a2623cfcbdfa6c66626aa876ed76b
Reviewed-by: default avatarhjk <>
parent 99d85671
...@@ -2603,6 +2603,7 @@ void FakeVimPlugin::test_map() ...@@ -2603,6 +2603,7 @@ void FakeVimPlugin::test_map()
data.setText("abc" N "def"); data.setText("abc" N "def");
data.doCommand(QString::fromUtf8("no \xc3\xb8 l|no l k|no k j|no j h")); data.doCommand(QString::fromUtf8("no \xc3\xb8 l|no l k|no k j|no j h"));
KEYS(QString::fromUtf8("\xc3\xb8"), "a" X "bc" N "def"); KEYS(QString::fromUtf8("\xc3\xb8"), "a" X "bc" N "def");
data.doCommand(QString::fromUtf8("unmap \xc3\xb8|unmap l|unmap k|unmap j"));
// Don't handle mapping in sub-modes that are not followed by movement command. // Don't handle mapping in sub-modes that are not followed by movement command.
data.setText("abc" N "def"); data.setText("abc" N "def");
...@@ -2627,6 +2628,16 @@ void FakeVimPlugin::test_map() ...@@ -2627,6 +2628,16 @@ void FakeVimPlugin::test_map()
data.doCommand("onoremap iwwX 3iwX Y"); data.doCommand("onoremap iwwX 3iwX Y");
KEYS("ciwwX Z<esc>", "X Y " X "Z" N "ghi jkl"); KEYS("ciwwX Z<esc>", "X Y " X "Z" N "ghi jkl");
data.doCommand("unmap <SPACE>X"); data.doCommand("unmap <SPACE>X");
// use mapping for <ESC> in insert
data.setText("ab" X "c def" N "ghi jkl");
data.doCommand("inoremap jk <ESC>");
KEYS("<C-V>jll" "I__jk", "ab" X "__c def" N "gh__i jkl");
data.doCommand("unmap jk"); // shouldn't unmap for insert mode
KEYS("ijk", "a" X "b__c def" N "gh__i jkl");
data.doCommand("iunmap jk");
KEYS("ijk<ESC>", "aj" X "kb__c def" N "gh__i jkl");
} }
void FakeVimPlugin::test_vim_command_cc() void FakeVimPlugin::test_vim_command_cc()
...@@ -1495,11 +1495,12 @@ private: ...@@ -1495,11 +1495,12 @@ private:
// state of current mapping // state of current mapping
struct MappingState { struct MappingState {
MappingState() MappingState()
: noremap(false), silent(false) {} : noremap(false), silent(false), editBlock(false) {}
MappingState(bool noremap, bool silent) MappingState(bool noremap, bool silent, bool editBlock)
: noremap(noremap), silent(silent) {} : noremap(noremap), silent(silent), editBlock(editBlock) {}
bool noremap; bool noremap;
bool silent; bool silent;
bool editBlock;
}; };
class FakeVimHandler::Private : public QObject class FakeVimHandler::Private : public QObject
...@@ -2683,9 +2684,13 @@ void FakeVimHandler::Private::prependMapping(const Inputs &inputs) ...@@ -2683,9 +2684,13 @@ void FakeVimHandler::Private::prependMapping(const Inputs &inputs)
++g.mapDepth; ++g.mapDepth;
g.pendingInput.prepend(Input()); g.pendingInput.prepend(Input());
prependInputs(inputs); prependInputs(inputs);
g.mapStates << MappingState(inputs.noremap(), inputs.silent());
g.commandBuffer.setHistoryAutoSave(false); g.commandBuffer.setHistoryAutoSave(false);
// start new edit block (undo/redo) only if necessary
bool editBlock = m_editBlockLevel == 0 && !(isInsertMode() && isInsertStateValid());
if (editBlock)
beginLargeEditBlock(); beginLargeEditBlock();
g.mapStates << MappingState(inputs.noremap(), inputs.silent(), editBlock);
} }
bool FakeVimHandler::Private::expandCompleteMapping() bool FakeVimHandler::Private::expandCompleteMapping()
...@@ -2715,8 +2720,9 @@ void FakeVimHandler::Private::endMapping() ...@@ -2715,8 +2720,9 @@ void FakeVimHandler::Private::endMapping()
--g.mapDepth; --g.mapDepth;
if (g.mapStates.isEmpty()) if (g.mapStates.isEmpty())
return; return;
g.mapStates.pop_back(); if (g.mapStates.last().editBlock)
endEditBlock(); endEditBlock();
if (g.mapStates.isEmpty()) if (g.mapStates.isEmpty())
g.commandBuffer.setHistoryAutoSave(true); g.commandBuffer.setHistoryAutoSave(true);
updateMiniBuffer(); updateMiniBuffer();
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment