forked from qt-creator/qt-creator
FakeVim: Add emulation for argtextobj.vim plugin
Change-Id: I319d2b9fe9f0d145c2560cf03fecc50629c99006 Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -130,6 +130,9 @@
|
||||
\li ["x]grr to replace the current line.
|
||||
\l{https://github.com/tommcdo/vim-exchange}{vim-exchange}
|
||||
\endlist
|
||||
\li \l{https://github.com/vim-scripts/argtextobj.vim}{argtextobj.vim}:
|
||||
Defines the \c ia and \c aa text objects for function parameters.
|
||||
\endlist
|
||||
\endlist
|
||||
|
||||
\section2 Insert Mode
|
||||
|
||||
@@ -4317,6 +4317,30 @@ void FakeVimPlugin::test_vim_exchange_emulation()
|
||||
KEYS(".", "def" N "abc");
|
||||
}
|
||||
|
||||
void FakeVimPlugin::test_vim_arg_text_obj_emulation()
|
||||
{
|
||||
TestData data;
|
||||
setup(&data);
|
||||
data.doCommand("set argtextobj");
|
||||
|
||||
data.setText("foo(int" X " i, double d, float f)");
|
||||
KEYS("dia", "foo(" X ", double d, float f)");
|
||||
KEYS("wdia", "foo(, " X ", float f)");
|
||||
KEYS("wdia", "foo(, , " X ")");
|
||||
|
||||
data.setText("foo(int" X " i, double d, float f, long l)");
|
||||
KEYS("daa", "foo(" X "double d, float f, long l)");
|
||||
KEYS("WWdaa", "foo(double d" X ", long l)");
|
||||
KEYS("Wdaa", "foo(double d)");
|
||||
KEYS("daa", "foo()");
|
||||
|
||||
data.setText("foo(std::map<int" X ", double> map)");
|
||||
KEYS("dia", "foo()");
|
||||
|
||||
data.setText("foo(const C c" X " = C(bar, baz))");
|
||||
KEYS("dia", "foo()");
|
||||
}
|
||||
|
||||
void FakeVimPlugin::test_macros()
|
||||
{
|
||||
TestData data;
|
||||
|
||||
@@ -119,6 +119,7 @@ FakeVimSettings::FakeVimSettings()
|
||||
createAction(ConfigEmulateVimCommentary, false, "commentary");
|
||||
createAction(ConfigEmulateReplaceWithRegister, false, "ReplaceWithRegister");
|
||||
createAction(ConfigEmulateExchange, false, "exchange");
|
||||
createAction(ConfigEmulateArgTextObj, false, "argtextobj");
|
||||
}
|
||||
|
||||
FakeVimSettings::~FakeVimSettings()
|
||||
|
||||
@@ -113,6 +113,7 @@ enum FakeVimSettingsCode
|
||||
ConfigEmulateVimCommentary,
|
||||
ConfigEmulateReplaceWithRegister,
|
||||
ConfigEmulateExchange,
|
||||
ConfigEmulateArgTextObj,
|
||||
|
||||
ConfigBlinkingCursor
|
||||
};
|
||||
|
||||
@@ -2127,6 +2127,7 @@ public:
|
||||
// return true only if cursor is in a block delimited with correct characters
|
||||
bool selectBlockTextObject(bool inner, QChar left, QChar right);
|
||||
bool selectQuotedStringTextObject(bool inner, const QString "e);
|
||||
bool selectArgumentTextObject(bool inner);
|
||||
|
||||
void commitInsertState();
|
||||
void invalidateInsertState();
|
||||
@@ -3925,6 +3926,8 @@ bool FakeVimHandler::Private::handleCommandSubSubMode(const Input &input)
|
||||
handled = selectBlockTextObject(g.subsubdata.is('i'), '{', '}');
|
||||
else if (input.is('"') || input.is('\'') || input.is('`'))
|
||||
handled = selectQuotedStringTextObject(g.subsubdata.is('i'), input.asChar());
|
||||
else if (input.is('a') && hasConfig(ConfigEmulateArgTextObj))
|
||||
handled = selectArgumentTextObject(g.subsubdata.is('i'));
|
||||
else
|
||||
handled = false;
|
||||
g.subsubmode = NoSubSubMode;
|
||||
@@ -8847,6 +8850,89 @@ bool FakeVimHandler::Private::selectQuotedStringTextObject(bool inner,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FakeVimHandler::Private::selectArgumentTextObject(bool inner)
|
||||
{
|
||||
// We are just interested whether we're currently inside angled brackets,
|
||||
// but selectBlockTextObject also moves the cursor, so set it back to
|
||||
// its original position afterwards
|
||||
QTextCursor prevCursor = m_cursor;
|
||||
const bool insideTemplateParameter = selectBlockTextObject(true, '<', '>');
|
||||
m_cursor = prevCursor;
|
||||
|
||||
int openAngleBracketCount = insideTemplateParameter ? 1 : 0;
|
||||
|
||||
QTextCursor tcStart(m_cursor);
|
||||
while (true) {
|
||||
if (tcStart.atStart())
|
||||
return true;
|
||||
|
||||
const QChar currentChar = characterAt(tcStart.position());
|
||||
|
||||
if (openAngleBracketCount == 0
|
||||
&& (currentChar == '(' || currentChar == ','))
|
||||
break;
|
||||
|
||||
if (currentChar == '<')
|
||||
openAngleBracketCount--;
|
||||
else if (currentChar == '>')
|
||||
openAngleBracketCount++;
|
||||
|
||||
tcStart.setPosition(tcStart.position() - 1);
|
||||
}
|
||||
|
||||
QTextCursor tcEnd(m_cursor);
|
||||
openAngleBracketCount = insideTemplateParameter ? 1 : 0;
|
||||
int openParanthesisCount = 0;
|
||||
|
||||
while (true) {
|
||||
if (tcEnd.atEnd()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const QChar currentChar = characterAt(tcEnd.position());
|
||||
if (openAngleBracketCount == 0
|
||||
&& openParanthesisCount == 0
|
||||
&& (currentChar == ')' || currentChar == ','))
|
||||
break;
|
||||
|
||||
if (currentChar == '<')
|
||||
openAngleBracketCount++;
|
||||
else if (currentChar == '>')
|
||||
openAngleBracketCount--;
|
||||
else if (currentChar == '(')
|
||||
openParanthesisCount++;
|
||||
else if (currentChar == ')')
|
||||
openParanthesisCount--;
|
||||
|
||||
|
||||
tcEnd.setPosition(tcEnd.position() + 1);
|
||||
}
|
||||
|
||||
|
||||
if (!inner && characterAt(tcEnd.position()) == ',' && characterAt(tcStart.position()) == '(') {
|
||||
tcEnd.setPosition(tcEnd.position() + 1);
|
||||
if (characterAt(tcEnd.position()) == ' ')
|
||||
tcEnd.setPosition(tcEnd.position() + 1);
|
||||
}
|
||||
|
||||
// Never include the opening paranthesis
|
||||
if (characterAt(tcStart.position()) == '(') {
|
||||
tcStart.setPosition(tcStart.position() + 1);
|
||||
} else if (inner) {
|
||||
tcStart.setPosition(tcStart.position() + 1);
|
||||
if (characterAt(tcStart.position()) == ' ')
|
||||
tcStart.setPosition(tcStart.position() + 1);
|
||||
}
|
||||
|
||||
if (isVisualMode())
|
||||
tcEnd.setPosition(tcEnd.position() - 1);
|
||||
|
||||
g.movetype = MoveExclusive;
|
||||
|
||||
setAnchorAndPosition(tcStart.position(), tcEnd.position());
|
||||
return true;
|
||||
}
|
||||
|
||||
Mark FakeVimHandler::Private::mark(QChar code) const
|
||||
{
|
||||
if (isVisualMode()) {
|
||||
|
||||
@@ -162,6 +162,13 @@
|
||||
<string>Plugin Emulation</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="checkBoxReplaceWithRegister">
|
||||
<property name="text">
|
||||
<string>ReplaceWithRegister</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="checkBoxVimCommentary">
|
||||
<property name="text">
|
||||
@@ -172,10 +179,10 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="checkBoxReplaceWithRegister">
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="checkBoxArgTextObj">
|
||||
<property name="text">
|
||||
<string>ReplaceWithRegister</string>
|
||||
<string>argtextobj.vim</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -432,6 +432,7 @@ QWidget *FakeVimOptionPage::widget()
|
||||
m_group.insert(theFakeVimSetting(ConfigEmulateVimCommentary), m_ui.checkBoxVimCommentary);
|
||||
m_group.insert(theFakeVimSetting(ConfigEmulateReplaceWithRegister), m_ui.checkBoxReplaceWithRegister);
|
||||
m_group.insert(theFakeVimSetting(ConfigEmulateExchange), m_ui.checkBoxExchange);
|
||||
m_group.insert(theFakeVimSetting(ConfigEmulateArgTextObj), m_ui.checkBoxArgTextObj);
|
||||
|
||||
connect(m_ui.pushButtonCopyTextEditorSettings, &QAbstractButton::clicked,
|
||||
this, &FakeVimOptionPage::copyTextEditorSettings);
|
||||
|
||||
@@ -162,6 +162,7 @@ private slots:
|
||||
void test_vim_commentary_file_names();
|
||||
void test_vim_replace_with_register_emulation();
|
||||
void test_vim_exchange_emulation();
|
||||
void test_vim_arg_text_obj_emulation();
|
||||
|
||||
void test_macros();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user