forked from qt-creator/qt-creator
FakeVim: Add emulation for ReplaceWithRegister plugin
Change-Id: Iaaeef6ff51fe858b759c10adaac582f5858b6210 Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -120,6 +120,13 @@
|
|||||||
\list
|
\list
|
||||||
\li \l{https://github.com/tpope/vim-commentary}{vim-commentary}: \c gc
|
\li \l{https://github.com/tpope/vim-commentary}{vim-commentary}: \c gc
|
||||||
action to comment code regions. For example, \c gcc, \c gc2j, \c gcip
|
action to comment code regions. For example, \c gcc, \c gc2j, \c gcip
|
||||||
|
\li
|
||||||
|
\l{https://github.com/vim-scripts/ReplaceWithRegister}{ReplaceWithRegister}:
|
||||||
|
\list
|
||||||
|
\li \c [count]["x]gr{motion} to replace \c {motion} with the contents of
|
||||||
|
register \c x.
|
||||||
|
\li ["x]grr to replace the current line.
|
||||||
|
\endlist
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
\section2 Insert Mode
|
\section2 Insert Mode
|
||||||
|
@@ -4231,6 +4231,53 @@ void FakeVimPlugin::test_vim_commentary_file_names()
|
|||||||
KEYS("gcc", X "// abc");
|
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()
|
void FakeVimPlugin::test_macros()
|
||||||
{
|
{
|
||||||
TestData data;
|
TestData data;
|
||||||
|
@@ -116,6 +116,7 @@ FakeVimSettings::FakeVimSettings()
|
|||||||
|
|
||||||
// Emulated plugins
|
// Emulated plugins
|
||||||
createAction(ConfigEmulateVimCommentary, false, "commentary");
|
createAction(ConfigEmulateVimCommentary, false, "commentary");
|
||||||
|
createAction(ConfigEmulateReplaceWithRegister, false, "ReplaceWithRegister");
|
||||||
}
|
}
|
||||||
|
|
||||||
FakeVimSettings::~FakeVimSettings()
|
FakeVimSettings::~FakeVimSettings()
|
||||||
|
@@ -110,6 +110,7 @@ enum FakeVimSettingsCode
|
|||||||
|
|
||||||
// Plugin emulation
|
// Plugin emulation
|
||||||
ConfigEmulateVimCommentary,
|
ConfigEmulateVimCommentary,
|
||||||
|
ConfigEmulateReplaceWithRegister,
|
||||||
|
|
||||||
ConfigBlinkingCursor
|
ConfigBlinkingCursor
|
||||||
};
|
};
|
||||||
|
@@ -166,26 +166,27 @@ enum BlockInsertMode
|
|||||||
enum SubMode
|
enum SubMode
|
||||||
{
|
{
|
||||||
NoSubMode,
|
NoSubMode,
|
||||||
ChangeSubMode, // Used for c
|
ChangeSubMode, // Used for c
|
||||||
DeleteSubMode, // Used for d
|
DeleteSubMode, // Used for d
|
||||||
FilterSubMode, // Used for !
|
FilterSubMode, // Used for !
|
||||||
IndentSubMode, // Used for =
|
IndentSubMode, // Used for =
|
||||||
RegisterSubMode, // Used for "
|
RegisterSubMode, // Used for "
|
||||||
ShiftLeftSubMode, // Used for <
|
ShiftLeftSubMode, // Used for <
|
||||||
ShiftRightSubMode, // Used for >
|
ShiftRightSubMode, // Used for >
|
||||||
CommentSubMode, // Used for gc
|
CommentSubMode, // Used for gc
|
||||||
InvertCaseSubMode, // Used for g~
|
ReplaceWithRegisterSubMode, // Used for gr
|
||||||
DownCaseSubMode, // Used for gu
|
InvertCaseSubMode, // Used for g~
|
||||||
UpCaseSubMode, // Used for gU
|
DownCaseSubMode, // Used for gu
|
||||||
WindowSubMode, // Used for Ctrl-w
|
UpCaseSubMode, // Used for gU
|
||||||
YankSubMode, // Used for y
|
WindowSubMode, // Used for Ctrl-w
|
||||||
ZSubMode, // Used for z
|
YankSubMode, // Used for y
|
||||||
CapitalZSubMode, // Used for Z
|
ZSubMode, // Used for z
|
||||||
ReplaceSubMode, // Used for r
|
CapitalZSubMode, // Used for Z
|
||||||
MacroRecordSubMode, // Used for q
|
ReplaceSubMode, // Used for r
|
||||||
MacroExecuteSubMode, // Used for @
|
MacroRecordSubMode, // Used for q
|
||||||
CtrlVSubMode, // Used for Ctrl-v in insert mode
|
MacroExecuteSubMode, // Used for @
|
||||||
CtrlRSubMode // Used for Ctrl-r in insert mode
|
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
|
/*! A \e SubSubMode is used for things that require one more data item
|
||||||
@@ -1345,6 +1346,8 @@ QString dotCommandFromSubMode(SubMode submode)
|
|||||||
return QLatin1String("d");
|
return QLatin1String("d");
|
||||||
if (submode == CommentSubMode)
|
if (submode == CommentSubMode)
|
||||||
return QLatin1String("gc");
|
return QLatin1String("gc");
|
||||||
|
if (submode == ReplaceWithRegisterSubMode)
|
||||||
|
return QLatin1String("gr");
|
||||||
if (submode == InvertCaseSubMode)
|
if (submode == InvertCaseSubMode)
|
||||||
return QLatin1String("g~");
|
return QLatin1String("g~");
|
||||||
if (submode == DownCaseSubMode)
|
if (submode == DownCaseSubMode)
|
||||||
@@ -1826,6 +1829,7 @@ public:
|
|||||||
void handleChangeDeleteYankSubModes();
|
void handleChangeDeleteYankSubModes();
|
||||||
bool handleReplaceSubMode(const Input &);
|
bool handleReplaceSubMode(const Input &);
|
||||||
bool handleCommentSubMode(const Input &);
|
bool handleCommentSubMode(const Input &);
|
||||||
|
bool handleReplaceWithRegisterSubMode(const Input &);
|
||||||
bool handleFilterSubMode(const Input &);
|
bool handleFilterSubMode(const Input &);
|
||||||
bool handleRegisterSubMode(const Input &);
|
bool handleRegisterSubMode(const Input &);
|
||||||
bool handleShiftSubMode(const Input &);
|
bool handleShiftSubMode(const Input &);
|
||||||
@@ -2089,6 +2093,7 @@ public:
|
|||||||
return g.submode == ChangeSubMode
|
return g.submode == ChangeSubMode
|
||||||
|| g.submode == DeleteSubMode
|
|| g.submode == DeleteSubMode
|
||||||
|| g.submode == CommentSubMode
|
|| g.submode == CommentSubMode
|
||||||
|
|| g.submode == ReplaceWithRegisterSubMode
|
||||||
|| g.submode == FilterSubMode
|
|| g.submode == FilterSubMode
|
||||||
|| g.submode == IndentSubMode
|
|| g.submode == IndentSubMode
|
||||||
|| g.submode == ShiftLeftSubMode
|
|| g.submode == ShiftLeftSubMode
|
||||||
@@ -2166,6 +2171,8 @@ public:
|
|||||||
|
|
||||||
void toggleComment(const Range &range);
|
void toggleComment(const Range &range);
|
||||||
|
|
||||||
|
void replaceWithRegister(const Range &range);
|
||||||
|
|
||||||
void upCase(const Range &range);
|
void upCase(const Range &range);
|
||||||
|
|
||||||
void downCase(const Range &range);
|
void downCase(const Range &range);
|
||||||
@@ -3590,6 +3597,7 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement)
|
|||||||
if (g.submode == ChangeSubMode
|
if (g.submode == ChangeSubMode
|
||||||
|| g.submode == DeleteSubMode
|
|| g.submode == DeleteSubMode
|
||||||
|| g.submode == CommentSubMode
|
|| g.submode == CommentSubMode
|
||||||
|
|| g.submode == ReplaceWithRegisterSubMode
|
||||||
|| g.submode == YankSubMode
|
|| g.submode == YankSubMode
|
||||||
|| g.submode == InvertCaseSubMode
|
|| g.submode == InvertCaseSubMode
|
||||||
|| g.submode == DownCaseSubMode
|
|| g.submode == DownCaseSubMode
|
||||||
@@ -3621,6 +3629,12 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement)
|
|||||||
beginEditBlock();
|
beginEditBlock();
|
||||||
toggleComment(currentRange());
|
toggleComment(currentRange());
|
||||||
endEditBlock();
|
endEditBlock();
|
||||||
|
} else if (g.submode == ReplaceWithRegisterSubMode
|
||||||
|
&& hasConfig(ConfigEmulateReplaceWithRegister)) {
|
||||||
|
pushUndoState(false);
|
||||||
|
beginEditBlock();
|
||||||
|
replaceWithRegister(currentRange());
|
||||||
|
endEditBlock();
|
||||||
} else if (g.submode == DeleteSubMode) {
|
} else if (g.submode == DeleteSubMode) {
|
||||||
pushUndoState(false);
|
pushUndoState(false);
|
||||||
beginEditBlock();
|
beginEditBlock();
|
||||||
@@ -3679,9 +3693,13 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!dotCommandMovement.isEmpty()) {
|
if (!dotCommandMovement.isEmpty()) {
|
||||||
const QString dotCommand = dotCommandFromSubMode(g.submode);
|
QString dotCommand = dotCommandFromSubMode(g.submode);
|
||||||
if (!dotCommand.isEmpty())
|
if (!dotCommand.isEmpty()) {
|
||||||
|
if (g.submode == ReplaceWithRegisterSubMode)
|
||||||
|
dotCommand = QString("\"%1%2").arg(QChar(m_register)).arg(dotCommand);
|
||||||
|
|
||||||
setDotCommand(dotCommand + dotCommandMovement);
|
setDotCommand(dotCommand + dotCommandMovement);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change command continues in insert mode.
|
// Change command continues in insert mode.
|
||||||
@@ -4269,6 +4287,9 @@ EventResult FakeVimHandler::Private::handleCommandMode(const Input &input)
|
|||||||
handled = handleChangeDeleteYankSubModes(input);
|
handled = handleChangeDeleteYankSubModes(input);
|
||||||
} else if (g.submode == CommentSubMode && hasConfig(ConfigEmulateVimCommentary)) {
|
} else if (g.submode == CommentSubMode && hasConfig(ConfigEmulateVimCommentary)) {
|
||||||
handled = handleCommentSubMode(input);
|
handled = handleCommentSubMode(input);
|
||||||
|
} else if (g.submode == ReplaceWithRegisterSubMode
|
||||||
|
&& hasConfig(ConfigEmulateReplaceWithRegister)) {
|
||||||
|
handled = handleReplaceWithRegisterSubMode(input);
|
||||||
} else if (g.submode == ReplaceSubMode) {
|
} else if (g.submode == ReplaceSubMode) {
|
||||||
handled = handleReplaceSubMode(input);
|
handled = handleReplaceSubMode(input);
|
||||||
} else if (g.submode == FilterSubMode) {
|
} else if (g.submode == FilterSubMode) {
|
||||||
@@ -4435,6 +4456,14 @@ bool FakeVimHandler::Private::handleNoSubMode(const Input &input)
|
|||||||
pushUndoState();
|
pushUndoState();
|
||||||
setAnchor();
|
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()) {
|
} else if ((input.is('c') || input.is('d') || input.is('y')) && isNoVisualMode()) {
|
||||||
setAnchor();
|
setAnchor();
|
||||||
g.opcount = g.mvcount;
|
g.opcount = g.mvcount;
|
||||||
@@ -4794,6 +4823,25 @@ bool FakeVimHandler::Private::handleCommentSubMode(const Input &input)
|
|||||||
return true;
|
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 &)
|
bool FakeVimHandler::Private::handleFilterSubMode(const Input &)
|
||||||
{
|
{
|
||||||
return false;
|
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)
|
void FakeVimHandler::Private::replaceText(const Range &range, const QString &str)
|
||||||
{
|
{
|
||||||
transformText(range, [&str](const QString &) { return str; } );
|
transformText(range, [&str](const QString &) { return str; } );
|
||||||
@@ -7452,7 +7505,7 @@ void FakeVimHandler::Private::pasteText(bool afterCursor)
|
|||||||
bool pasteAfter = isVisualMode() ? false : afterCursor;
|
bool pasteAfter = isVisualMode() ? false : afterCursor;
|
||||||
|
|
||||||
if (isVisualMode())
|
if (isVisualMode())
|
||||||
cutSelectedText('"');
|
cutSelectedText(g.submode == ReplaceWithRegisterSubMode ? '-' : '"');
|
||||||
|
|
||||||
switch (rangeMode) {
|
switch (rangeMode) {
|
||||||
case RangeCharMode: {
|
case RangeCharMode: {
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>580</width>
|
<width>580</width>
|
||||||
<height>531</height>
|
<height>543</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
@@ -172,6 +172,13 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QCheckBox" name="checkBoxReplaceWithRegister">
|
||||||
|
<property name="text">
|
||||||
|
<string>ReplaceWithRegister</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@@ -430,6 +430,7 @@ QWidget *FakeVimOptionPage::widget()
|
|||||||
m_group.insert(theFakeVimSetting(ConfigBlinkingCursor), m_ui.checkBoxBlinkingCursor);
|
m_group.insert(theFakeVimSetting(ConfigBlinkingCursor), m_ui.checkBoxBlinkingCursor);
|
||||||
|
|
||||||
m_group.insert(theFakeVimSetting(ConfigEmulateVimCommentary), m_ui.checkBoxVimCommentary);
|
m_group.insert(theFakeVimSetting(ConfigEmulateVimCommentary), m_ui.checkBoxVimCommentary);
|
||||||
|
m_group.insert(theFakeVimSetting(ConfigEmulateReplaceWithRegister), m_ui.checkBoxReplaceWithRegister);
|
||||||
|
|
||||||
connect(m_ui.pushButtonCopyTextEditorSettings, &QAbstractButton::clicked,
|
connect(m_ui.pushButtonCopyTextEditorSettings, &QAbstractButton::clicked,
|
||||||
this, &FakeVimOptionPage::copyTextEditorSettings);
|
this, &FakeVimOptionPage::copyTextEditorSettings);
|
||||||
|
@@ -160,6 +160,7 @@ private slots:
|
|||||||
// Plugin emulation
|
// Plugin emulation
|
||||||
void test_vim_commentary_emulation();
|
void test_vim_commentary_emulation();
|
||||||
void test_vim_commentary_file_names();
|
void test_vim_commentary_file_names();
|
||||||
|
void test_vim_replace_with_register_emulation();
|
||||||
|
|
||||||
void test_macros();
|
void test_macros();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user