aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/fakevim
diff options
context:
space:
mode:
authorTom Praschan <tom@praschan.de>2021-02-06 19:22:26 +0100
committerTom Praschan <tom@praschan.de>2021-02-09 07:33:03 +0000
commitb6f26ed67a1db02898b7d9fd871022038c64fa17 (patch)
tree7539e37a94568210dac57641888c68fac4296672 /src/plugins/fakevim
parente124ca962d20670d2f588352a129e73e72da099f (diff)
FakeVim: Add emulation for ReplaceWithRegister plugin
Change-Id: Iaaeef6ff51fe858b759c10adaac582f5858b6210 Reviewed-by: hjk <hjk@qt.io>
Diffstat (limited to 'src/plugins/fakevim')
-rw-r--r--src/plugins/fakevim/fakevim_test.cpp47
-rw-r--r--src/plugins/fakevim/fakevimactions.cpp1
-rw-r--r--src/plugins/fakevim/fakevimactions.h1
-rw-r--r--src/plugins/fakevim/fakevimhandler.cpp99
-rw-r--r--src/plugins/fakevim/fakevimoptions.ui9
-rw-r--r--src/plugins/fakevim/fakevimplugin.cpp1
-rw-r--r--src/plugins/fakevim/fakevimplugin.h1
7 files changed, 135 insertions, 24 deletions
diff --git a/src/plugins/fakevim/fakevim_test.cpp b/src/plugins/fakevim/fakevim_test.cpp
index dd7accfe1fd..b5fd9c41691 100644
--- a/src/plugins/fakevim/fakevim_test.cpp
+++ b/src/plugins/fakevim/fakevim_test.cpp
@@ -4231,6 +4231,53 @@ void FakeVimPlugin::test_vim_commentary_file_names()
KEYS("gcc", X "// abc");
}
+void FakeVimPlugin::test_vim_replace_with_register_emulation()
+{
+ TestData data;
+ setup(&data);
+ data.doCommand("set replacewithregister");
+
+ // Simple replace
+ data.setText("abc def ghi");
+ KEYS("yw", "abc def ghi");
+ KEYS("w", "abc " X "def ghi");
+ KEYS("grw", "abc " X "abc ghi");
+ KEYS("w", "abc abc " X "ghi");
+ KEYS(".", "abc abc " X "abc ");
+
+ // Registers
+ data.setText("abc def ghi jkl mno");
+ KEYS("\"xyiw", "abc def ghi jkl mno");
+ KEYS("w", "abc " X "def ghi jkl mno");
+ KEYS("yiw", "abc " X "def ghi jkl mno");
+ KEYS("w", "abc def " X "ghi jkl mno");
+ KEYS("griw", "abc def " X "def jkl mno");
+ KEYS("w", "abc def def " X "jkl mno");
+ KEYS("\"xgriw", "abc def def " X "abc mno");
+ KEYS("w", "abc def def abc " X "mno");
+ KEYS(".", "abc def def abc " X "abc");
+
+ // Replace entire line
+ data.setText("abc" N "def" N "ghi" N "jkhl");
+ KEYS("yyj", "abc" N X "def" N "ghi" N "jkhl");
+ KEYS("grr", "abc" N X "abc" N "ghi" N "jkhl");
+ KEYS("j", "abc" N "abc" N X "ghi" N "jkhl");
+ KEYS(".", "abc" N "abc" N X "abc" N "jkhl");
+
+ // Visual line mode
+ data.setText("abc" N "def" N "ghi" N "jkhl");
+ KEYS("yyj", "abc" N X "def" N "ghi" N "jkhl");
+ KEYS("Vgr", "abc" N X "abc" N "ghi" N "jkhl");
+ KEYS("j", "abc" N "abc" N X "ghi" N "jkhl");
+ KEYS(".", "abc" N "abc" N X "abc" N "jkhl");
+
+ // Visual char mode
+ data.setText("abc defghi");
+ KEYS("yiw", "abc defghi");
+ KEYS("w", "abc defghi");
+ KEYS("v4lgr", "abc abci");
+}
+
void FakeVimPlugin::test_macros()
{
TestData data;
diff --git a/src/plugins/fakevim/fakevimactions.cpp b/src/plugins/fakevim/fakevimactions.cpp
index 0368afd0f26..edd40a7bea4 100644
--- a/src/plugins/fakevim/fakevimactions.cpp
+++ b/src/plugins/fakevim/fakevimactions.cpp
@@ -116,6 +116,7 @@ FakeVimSettings::FakeVimSettings()
// Emulated plugins
createAction(ConfigEmulateVimCommentary, false, "commentary");
+ createAction(ConfigEmulateReplaceWithRegister, false, "ReplaceWithRegister");
}
FakeVimSettings::~FakeVimSettings()
diff --git a/src/plugins/fakevim/fakevimactions.h b/src/plugins/fakevim/fakevimactions.h
index 138023d2a63..95f1ff4dd24 100644
--- a/src/plugins/fakevim/fakevimactions.h
+++ b/src/plugins/fakevim/fakevimactions.h
@@ -110,6 +110,7 @@ enum FakeVimSettingsCode
// Plugin emulation
ConfigEmulateVimCommentary,
+ ConfigEmulateReplaceWithRegister,
ConfigBlinkingCursor
};
diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp
index caaf9dbda26..a442b1b9384 100644
--- a/src/plugins/fakevim/fakevimhandler.cpp
+++ b/src/plugins/fakevim/fakevimhandler.cpp
@@ -166,26 +166,27 @@ enum BlockInsertMode
enum SubMode
{
NoSubMode,
- ChangeSubMode, // Used for c
- DeleteSubMode, // Used for d
- FilterSubMode, // Used for !
- IndentSubMode, // Used for =
- RegisterSubMode, // Used for "
- ShiftLeftSubMode, // Used for <
- ShiftRightSubMode, // Used for >
- CommentSubMode, // Used for gc
- InvertCaseSubMode, // Used for g~
- DownCaseSubMode, // Used for gu
- UpCaseSubMode, // Used for gU
- WindowSubMode, // Used for Ctrl-w
- YankSubMode, // Used for y
- ZSubMode, // Used for z
- CapitalZSubMode, // Used for Z
- ReplaceSubMode, // Used for r
- MacroRecordSubMode, // Used for q
- MacroExecuteSubMode, // Used for @
- CtrlVSubMode, // Used for Ctrl-v in insert mode
- CtrlRSubMode // Used for Ctrl-r in insert mode
+ ChangeSubMode, // Used for c
+ DeleteSubMode, // Used for d
+ FilterSubMode, // Used for !
+ IndentSubMode, // Used for =
+ RegisterSubMode, // Used for "
+ ShiftLeftSubMode, // Used for <
+ ShiftRightSubMode, // Used for >
+ CommentSubMode, // Used for gc
+ ReplaceWithRegisterSubMode, // Used for gr
+ InvertCaseSubMode, // Used for g~
+ DownCaseSubMode, // Used for gu
+ UpCaseSubMode, // Used for gU
+ WindowSubMode, // Used for Ctrl-w
+ YankSubMode, // Used for y
+ ZSubMode, // Used for z
+ CapitalZSubMode, // Used for Z
+ ReplaceSubMode, // Used for r
+ MacroRecordSubMode, // Used for q
+ MacroExecuteSubMode, // Used for @
+ CtrlVSubMode, // Used for Ctrl-v in insert mode
+ CtrlRSubMode // Used for Ctrl-r in insert mode
};
/*! A \e SubSubMode is used for things that require one more data item
@@ -1345,6 +1346,8 @@ QString dotCommandFromSubMode(SubMode submode)
return QLatin1String("d");
if (submode == CommentSubMode)
return QLatin1String("gc");
+ if (submode == ReplaceWithRegisterSubMode)
+ return QLatin1String("gr");
if (submode == InvertCaseSubMode)
return QLatin1String("g~");
if (submode == DownCaseSubMode)
@@ -1826,6 +1829,7 @@ public:
void handleChangeDeleteYankSubModes();
bool handleReplaceSubMode(const Input &);
bool handleCommentSubMode(const Input &);
+ bool handleReplaceWithRegisterSubMode(const Input &);
bool handleFilterSubMode(const Input &);
bool handleRegisterSubMode(const Input &);
bool handleShiftSubMode(const Input &);
@@ -2089,6 +2093,7 @@ public:
return g.submode == ChangeSubMode
|| g.submode == DeleteSubMode
|| g.submode == CommentSubMode
+ || g.submode == ReplaceWithRegisterSubMode
|| g.submode == FilterSubMode
|| g.submode == IndentSubMode
|| g.submode == ShiftLeftSubMode
@@ -2166,6 +2171,8 @@ public:
void toggleComment(const Range &range);
+ void replaceWithRegister(const Range &range);
+
void upCase(const Range &range);
void downCase(const Range &range);
@@ -3590,6 +3597,7 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement)
if (g.submode == ChangeSubMode
|| g.submode == DeleteSubMode
|| g.submode == CommentSubMode
+ || g.submode == ReplaceWithRegisterSubMode
|| g.submode == YankSubMode
|| g.submode == InvertCaseSubMode
|| g.submode == DownCaseSubMode
@@ -3621,6 +3629,12 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement)
beginEditBlock();
toggleComment(currentRange());
endEditBlock();
+ } else if (g.submode == ReplaceWithRegisterSubMode
+ && hasConfig(ConfigEmulateReplaceWithRegister)) {
+ pushUndoState(false);
+ beginEditBlock();
+ replaceWithRegister(currentRange());
+ endEditBlock();
} else if (g.submode == DeleteSubMode) {
pushUndoState(false);
beginEditBlock();
@@ -3679,9 +3693,13 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement)
}
if (!dotCommandMovement.isEmpty()) {
- const QString dotCommand = dotCommandFromSubMode(g.submode);
- if (!dotCommand.isEmpty())
+ QString dotCommand = dotCommandFromSubMode(g.submode);
+ if (!dotCommand.isEmpty()) {
+ if (g.submode == ReplaceWithRegisterSubMode)
+ dotCommand = QString("\"%1%2").arg(QChar(m_register)).arg(dotCommand);
+
setDotCommand(dotCommand + dotCommandMovement);
+ }
}
// Change command continues in insert mode.
@@ -4269,6 +4287,9 @@ EventResult FakeVimHandler::Private::handleCommandMode(const Input &input)
handled = handleChangeDeleteYankSubModes(input);
} else if (g.submode == CommentSubMode && hasConfig(ConfigEmulateVimCommentary)) {
handled = handleCommentSubMode(input);
+ } else if (g.submode == ReplaceWithRegisterSubMode
+ && hasConfig(ConfigEmulateReplaceWithRegister)) {
+ handled = handleReplaceWithRegisterSubMode(input);
} else if (g.submode == ReplaceSubMode) {
handled = handleReplaceSubMode(input);
} else if (g.submode == FilterSubMode) {
@@ -4435,6 +4456,14 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input)
pushUndoState();
setAnchor();
}
+ } else if (g.gflag && input.is('r') && hasConfig(ConfigEmulateReplaceWithRegister)) {
+ g.submode = ReplaceWithRegisterSubMode;
+ if (isVisualMode()) {
+ dotCommand = visualDotCommand() + QString::number(count()) + "gr";
+ pasteText(true);
+ } else {
+ setAnchor();
+ }
} else if ((input.is('c') || input.is('d') || input.is('y')) && isNoVisualMode()) {
setAnchor();
g.opcount = g.mvcount;
@@ -4794,6 +4823,25 @@ bool FakeVimHandler::Private::handleCommentSubMode(const Input &input)
return true;
}
+bool FakeVimHandler::Private::handleReplaceWithRegisterSubMode(const Input &input)
+{
+ if (!input.is('r'))
+ return false;
+
+ pushUndoState(false);
+ beginEditBlock();
+
+ const QString movement = (count() == 1)
+ ? QString() : (QString::number(count() - 1) + "j");
+
+ g.dotCommand = "V" + movement + "gr";
+ replay(g.dotCommand);
+
+ endEditBlock();
+
+ return true;
+}
+
bool FakeVimHandler::Private::handleFilterSubMode(const Input &)
{
return false;
@@ -7436,6 +7484,11 @@ void FakeVimHandler::Private::toggleComment(const Range &range)
});
}
+void FakeVimHandler::Private::replaceWithRegister(const Range &range)
+{
+ replaceText(range, registerContents(m_register));
+}
+
void FakeVimHandler::Private::replaceText(const Range &range, const QString &str)
{
transformText(range, [&str](const QString &) { return str; } );
@@ -7452,7 +7505,7 @@ void FakeVimHandler::Private::pasteText(bool afterCursor)
bool pasteAfter = isVisualMode() ? false : afterCursor;
if (isVisualMode())
- cutSelectedText('"');
+ cutSelectedText(g.submode == ReplaceWithRegisterSubMode ? '-' : '"');
switch (rangeMode) {
case RangeCharMode: {
diff --git a/src/plugins/fakevim/fakevimoptions.ui b/src/plugins/fakevim/fakevimoptions.ui
index 8dd4b534db9..d8e26e2c509 100644
--- a/src/plugins/fakevim/fakevimoptions.ui
+++ b/src/plugins/fakevim/fakevimoptions.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>580</width>
- <height>531</height>
+ <height>543</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
@@ -172,6 +172,13 @@
</property>
</widget>
</item>
+ <item row="1" column="0">
+ <widget class="QCheckBox" name="checkBoxReplaceWithRegister">
+ <property name="text">
+ <string>ReplaceWithRegister</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
diff --git a/src/plugins/fakevim/fakevimplugin.cpp b/src/plugins/fakevim/fakevimplugin.cpp
index bd611bc14ed..e11310d7de6 100644
--- a/src/plugins/fakevim/fakevimplugin.cpp
+++ b/src/plugins/fakevim/fakevimplugin.cpp
@@ -430,6 +430,7 @@ QWidget *FakeVimOptionPage::widget()
m_group.insert(theFakeVimSetting(ConfigBlinkingCursor), m_ui.checkBoxBlinkingCursor);
m_group.insert(theFakeVimSetting(ConfigEmulateVimCommentary), m_ui.checkBoxVimCommentary);
+ m_group.insert(theFakeVimSetting(ConfigEmulateReplaceWithRegister), m_ui.checkBoxReplaceWithRegister);
connect(m_ui.pushButtonCopyTextEditorSettings, &QAbstractButton::clicked,
this, &FakeVimOptionPage::copyTextEditorSettings);
diff --git a/src/plugins/fakevim/fakevimplugin.h b/src/plugins/fakevim/fakevimplugin.h
index 74ca665c9ee..ad5d64fb2fb 100644
--- a/src/plugins/fakevim/fakevimplugin.h
+++ b/src/plugins/fakevim/fakevimplugin.h
@@ -160,6 +160,7 @@ private slots:
// Plugin emulation
void test_vim_commentary_emulation();
void test_vim_commentary_file_names();
+ void test_vim_replace_with_register_emulation();
void test_macros();