aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/fakevim
diff options
context:
space:
mode:
authorMarcus Tillmanns <marcus.tillmanns@qt.io>2023-04-27 12:18:07 +0200
committerMarcus Tillmanns <marcus.tillmanns@qt.io>2023-05-02 06:53:54 +0000
commit015d12ccf317443576c286ef87c09ddb01e4d34c (patch)
tree3260928b3f0bb6ed8eb1b2c3f88428ce4232a95b /src/plugins/fakevim
parent8f345bbc35e3d1d7e92fdee25d4f42b1194e9793 (diff)
FakeVim: Accept suggestion with Tab Key
* Changed signals to callbacks as only one receiver was ever added * Added "tabPressedInInsertMode" callback to allow accepting a suggestion with the Tab Key Fixes: QTCREATORBUG-28830 Change-Id: Ie70ba595b8802b6100fff495164d8e0471b1354c Reviewed-by: hjk <hjk@qt.io>
Diffstat (limited to 'src/plugins/fakevim')
-rw-r--r--src/plugins/fakevim/fakevimhandler.cpp20
-rw-r--r--src/plugins/fakevim/fakevimhandler.h85
-rw-r--r--src/plugins/fakevim/fakevimplugin.cpp72
3 files changed, 96 insertions, 81 deletions
diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp
index 05ea400bbb..bd1e035f48 100644
--- a/src/plugins/fakevim/fakevimhandler.cpp
+++ b/src/plugins/fakevim/fakevimhandler.cpp
@@ -5459,16 +5459,18 @@ void FakeVimHandler::Private::handleInsertMode(const Input &input)
} else if (input.isKey(Key_PageUp) || input.isControl('b')) {
movePageUp();
} else if (input.isKey(Key_Tab)) {
- m_buffer->insertState.insertingSpaces = true;
- if (s.expandTab.value()) {
- const int ts = s.tabStop.value();
- const int col = logicalCursorColumn();
- QString str = QString(ts - col % ts, ' ');
- insertText(str);
- } else {
- insertInInsertMode(input.raw());
+ if (q->tabPressedInInsertMode()) {
+ m_buffer->insertState.insertingSpaces = true;
+ if (s.expandTab.value()) {
+ const int ts = s.tabStop.value();
+ const int col = logicalCursorColumn();
+ QString str = QString(ts - col % ts, ' ');
+ insertText(str);
+ } else {
+ insertInInsertMode(input.raw());
+ }
+ m_buffer->insertState.insertingSpaces = false;
}
- m_buffer->insertState.insertingSpaces = false;
} else if (input.isControl('d')) {
// remove one level of indentation from the current line
const int shift = s.shiftWidth.value();
diff --git a/src/plugins/fakevim/fakevimhandler.h b/src/plugins/fakevim/fakevimhandler.h
index 30ee5599ef..b19e257909 100644
--- a/src/plugins/fakevim/fakevimhandler.h
+++ b/src/plugins/fakevim/fakevimhandler.h
@@ -61,23 +61,30 @@ enum MessageLevel
MessageShowCmd // partial command
};
-template <typename Type>
-class Signal
+template<typename>
+class Callback;
+
+template<typename R, typename... Params>
+class Callback<R(Params...)>
{
public:
- using Callable = std::function<Type>;
-
- void connect(const Callable &callable) { m_callables.push_back(callable); }
+ static constexpr auto IsVoidReturnType = std::is_same_v<R, void>;
+ using Function = std::function<R(Params...)>;
+ void set(const Function &callable) { m_callable = callable; }
- template <typename ...Args>
- void operator()(Args ...args) const
+ R operator()(Params... params)
{
- for (const Callable &callable : m_callables)
- callable(args...);
- }
+ if (!m_callable)
+ return R();
+
+ if constexpr (IsVoidReturnType)
+ m_callable(std::forward<Params>(params)...);
+ else
+ return m_callable(std::forward<Params>(params)...);
+ }
private:
- std::vector<Callable> m_callables;
+ Function m_callable;
};
class FakeVimHandler : public QObject
@@ -131,33 +138,35 @@ public:
bool eventFilter(QObject *ob, QEvent *ev) override;
- Signal<void(const QString &msg, int cursorPos, int anchorPos, int messageLevel)> commandBufferChanged;
- Signal<void(const QString &msg)> statusDataChanged;
- Signal<void(const QString &msg)> extraInformationChanged;
- Signal<void(const QList<QTextEdit::ExtraSelection> &selection)> selectionChanged;
- Signal<void(const QString &needle)> highlightMatches;
- Signal<void(bool *moved, bool *forward, QTextCursor *cursor)> moveToMatchingParenthesis;
- Signal<void(bool *result, QChar c)> checkForElectricCharacter;
- Signal<void(int beginLine, int endLine, QChar typedChar)> indentRegion;
- Signal<void(const QString &needle, bool forward)> simpleCompletionRequested;
- Signal<void(const QString &key, int count)> windowCommandRequested;
- Signal<void(bool reverse)> findRequested;
- Signal<void(bool reverse)> findNextRequested;
- Signal<void(bool *handled, const ExCommand &cmd)> handleExCommandRequested;
- Signal<void()> requestDisableBlockSelection;
- Signal<void(const QTextCursor &cursor)> requestSetBlockSelection;
- Signal<void(QTextCursor *cursor)> requestBlockSelection;
- Signal<void(bool *on)> requestHasBlockSelection;
- Signal<void(int depth)> foldToggle;
- Signal<void(bool fold)> foldAll;
- Signal<void(int depth, bool dofold)> fold;
- Signal<void(int count, bool current)> foldGoTo;
- Signal<void(QChar mark, bool backTickMode, const QString &fileName)> requestJumpToLocalMark;
- Signal<void(QChar mark, bool backTickMode, const QString &fileName)> requestJumpToGlobalMark;
- Signal<void()> completionRequested;
- Signal<void()> tabPreviousRequested;
- Signal<void()> tabNextRequested;
- Signal<void(bool insertMode)> modeChanged;
+ Callback<void(const QString &msg, int cursorPos, int anchorPos, int messageLevel)>
+ commandBufferChanged;
+ Callback<void(const QString &msg)> statusDataChanged;
+ Callback<void(const QString &msg)> extraInformationChanged;
+ Callback<void(const QList<QTextEdit::ExtraSelection> &selection)> selectionChanged;
+ Callback<void(const QString &needle)> highlightMatches;
+ Callback<void(bool *moved, bool *forward, QTextCursor *cursor)> moveToMatchingParenthesis;
+ Callback<void(bool *result, QChar c)> checkForElectricCharacter;
+ Callback<void(int beginLine, int endLine, QChar typedChar)> indentRegion;
+ Callback<void(const QString &needle, bool forward)> simpleCompletionRequested;
+ Callback<void(const QString &key, int count)> windowCommandRequested;
+ Callback<void(bool reverse)> findRequested;
+ Callback<void(bool reverse)> findNextRequested;
+ Callback<void(bool *handled, const ExCommand &cmd)> handleExCommandRequested;
+ Callback<void()> requestDisableBlockSelection;
+ Callback<void(const QTextCursor &cursor)> requestSetBlockSelection;
+ Callback<void(QTextCursor *cursor)> requestBlockSelection;
+ Callback<void(bool *on)> requestHasBlockSelection;
+ Callback<void(int depth)> foldToggle;
+ Callback<void(bool fold)> foldAll;
+ Callback<void(int depth, bool dofold)> fold;
+ Callback<void(int count, bool current)> foldGoTo;
+ Callback<void(QChar mark, bool backTickMode, const QString &fileName)> requestJumpToLocalMark;
+ Callback<void(QChar mark, bool backTickMode, const QString &fileName)> requestJumpToGlobalMark;
+ Callback<void()> completionRequested;
+ Callback<void()> tabPreviousRequested;
+ Callback<void()> tabNextRequested;
+ Callback<void(bool insertMode)> modeChanged;
+ Callback<bool()> tabPressedInInsertMode;
public:
class Private;
diff --git a/src/plugins/fakevim/fakevimplugin.cpp b/src/plugins/fakevim/fakevimplugin.cpp
index e41d83be2c..d0c399ac31 100644
--- a/src/plugins/fakevim/fakevimplugin.cpp
+++ b/src/plugins/fakevim/fakevimplugin.cpp
@@ -1586,7 +1586,7 @@ void FakeVimPluginPrivate::editorOpened(IEditor *editor)
new DeferredDeleter(widget, handler);
m_editorToHandler[editor].handler = handler;
- handler->extraInformationChanged.connect([this](const QString &text) {
+ handler->extraInformationChanged.set([this](const QString &text) {
EditorManager::splitSideBySide();
QString title = "stdout.txt";
IEditor *iedit = EditorManager::openEditorWithContents(Id(), &title, text.toUtf8());
@@ -1596,17 +1596,27 @@ void FakeVimPluginPrivate::editorOpened(IEditor *editor)
handler->handleCommand("0");
});
- handler->commandBufferChanged
- .connect([this, handler](const QString &contents, int cursorPos, int anchorPos, int messageLevel) {
- showCommandBuffer(handler, contents, cursorPos, anchorPos, messageLevel);
- });
+ handler->commandBufferChanged.set(
+ [this, handler](const QString &contents, int cursorPos, int anchorPos, int messageLevel) {
+ showCommandBuffer(handler, contents, cursorPos, anchorPos, messageLevel);
+ });
- handler->selectionChanged.connect([tew](const QList<QTextEdit::ExtraSelection> &selection) {
+ handler->selectionChanged.set([tew](const QList<QTextEdit::ExtraSelection> &selection) {
if (tew)
tew->setExtraSelections(TextEditorWidget::FakeVimSelection, selection);
});
- handler->modeChanged.connect([tew, this, editor](bool insertMode) {
+ handler->tabPressedInInsertMode.set([tew]() {
+ auto suggestion = tew->currentSuggestion();
+ if (suggestion) {
+ suggestion->apply();
+ return false;
+ }
+
+ return true;
+ });
+
+ handler->modeChanged.set([tew, this, editor](bool insertMode) {
HandlerAndData &handlerAndData = m_editorToHandler[editor];
// We don't want to show suggestions unless we are in insert mode.
@@ -1617,7 +1627,7 @@ void FakeVimPluginPrivate::editorOpened(IEditor *editor)
tew->clearSuggestion();
});
- handler->highlightMatches.connect([](const QString &needle) {
+ handler->highlightMatches.set([](const QString &needle) {
for (IEditor *editor : EditorManager::visibleEditors()) {
QWidget *w = editor->widget();
if (auto find = Aggregation::query<IFindSupport>(w))
@@ -1625,7 +1635,7 @@ void FakeVimPluginPrivate::editorOpened(IEditor *editor)
}
});
- handler->moveToMatchingParenthesis.connect([](bool *moved, bool *forward, QTextCursor *cursor) {
+ handler->moveToMatchingParenthesis.set([](bool *moved, bool *forward, QTextCursor *cursor) {
*moved = false;
bool undoFakeEOL = false;
@@ -1658,7 +1668,7 @@ void FakeVimPluginPrivate::editorOpened(IEditor *editor)
}
});
- handler->indentRegion.connect([tew](int beginBlock, int endBlock, QChar typedChar) {
+ handler->indentRegion.set([tew](int beginBlock, int endBlock, QChar typedChar) {
if (!tew)
return;
@@ -1691,17 +1701,17 @@ void FakeVimPluginPrivate::editorOpened(IEditor *editor)
}
});
- handler->checkForElectricCharacter.connect([tew](bool *result, QChar c) {
+ handler->checkForElectricCharacter.set([tew](bool *result, QChar c) {
if (tew)
*result = tew->textDocument()->indenter()->isElectricCharacter(c);
});
- handler->requestDisableBlockSelection.connect([tew] {
+ handler->requestDisableBlockSelection.set([tew] {
if (tew)
tew->setTextCursor(tew->textCursor());
});
- handler->requestSetBlockSelection.connect([tew](const QTextCursor &cursor) {
+ handler->requestSetBlockSelection.set([tew](const QTextCursor &cursor) {
if (tew) {
const TabSettings &tabs = tew->textDocument()->tabSettings();
MultiTextCursor mtc;
@@ -1725,7 +1735,7 @@ void FakeVimPluginPrivate::editorOpened(IEditor *editor)
}
});
- handler->requestBlockSelection.connect([tew](QTextCursor *cursor) {
+ handler->requestBlockSelection.set([tew](QTextCursor *cursor) {
if (tew && cursor) {
MultiTextCursor mtc = tew->multiTextCursor();
*cursor = mtc.cursors().first();
@@ -1733,16 +1743,16 @@ void FakeVimPluginPrivate::editorOpened(IEditor *editor)
}
});
- handler->requestHasBlockSelection.connect([tew](bool *on) {
+ handler->requestHasBlockSelection.set([tew](bool *on) {
if (tew && on)
*on = tew->multiTextCursor().hasMultipleCursors();
});
- handler->simpleCompletionRequested.connect([this, handler](const QString &needle, bool forward) {
+ handler->simpleCompletionRequested.set([this, handler](const QString &needle, bool forward) {
runData->wordProvider.setActive(needle, forward, handler);
});
- handler->windowCommandRequested.connect([this, handler](const QString &map, int count) {
+ handler->windowCommandRequested.set([this, handler](const QString &map, int count) {
// normalize mapping
const QString key = map.toUpper();
@@ -1772,22 +1782,22 @@ void FakeVimPluginPrivate::editorOpened(IEditor *editor)
qDebug() << "UNKNOWN WINDOW COMMAND: <C-W>" << map;
});
- handler->findRequested.connect([](bool reverse) {
+ handler->findRequested.set([](bool reverse) {
Find::setUseFakeVim(true);
Find::openFindToolBar(reverse ? Find::FindBackwardDirection
: Find::FindForwardDirection);
});
- handler->findNextRequested.connect([](bool reverse) {
+ handler->findNextRequested.set([](bool reverse) {
triggerAction(reverse ? Core::Constants::FIND_PREVIOUS : Core::Constants::FIND_NEXT);
});
- handler->foldToggle.connect([this, handler](int depth) {
+ handler->foldToggle.set([this, handler](int depth) {
QTextBlock block = handler->textCursor().block();
fold(handler, depth, !TextDocumentLayout::isFolded(block));
});
- handler->foldAll.connect([handler](bool fold) {
+ handler->foldAll.set([handler](bool fold) {
QTextDocument *document = handler->textCursor().document();
auto documentLayout = qobject_cast<TextDocumentLayout*>(document->documentLayout());
QTC_ASSERT(documentLayout, return);
@@ -1802,11 +1812,9 @@ void FakeVimPluginPrivate::editorOpened(IEditor *editor)
documentLayout->emitDocumentSizeChanged();
});
- handler->fold.connect([this, handler](int depth, bool dofold) {
- fold(handler, depth, dofold);
- });
+ handler->fold.set([this, handler](int depth, bool dofold) { fold(handler, depth, dofold); });
- handler->foldGoTo.connect([handler](int count, bool current) {
+ handler->foldGoTo.set([handler](int count, bool current) {
QTextCursor tc = handler->textCursor();
QTextBlock block = tc.block();
@@ -1858,7 +1866,7 @@ void FakeVimPluginPrivate::editorOpened(IEditor *editor)
}
});
- handler->requestJumpToGlobalMark.connect(
+ handler->requestJumpToGlobalMark.set(
[this](QChar mark, bool backTickMode, const QString &fileName) {
if (IEditor *iedit = EditorManager::openEditor(FilePath::fromString(fileName))) {
if (FakeVimHandler *handler = m_editorToHandler.value(iedit, {}).handler)
@@ -1866,19 +1874,15 @@ void FakeVimPluginPrivate::editorOpened(IEditor *editor)
}
});
- handler->handleExCommandRequested.connect([this, handler](bool *handled, const ExCommand &cmd) {
+ handler->handleExCommandRequested.set([this, handler](bool *handled, const ExCommand &cmd) {
handleExCommand(handler, handled, cmd);
});
- handler->tabNextRequested.connect([] {
- triggerAction(Core::Constants::GOTONEXTINHISTORY);
- });
+ handler->tabNextRequested.set([] { triggerAction(Core::Constants::GOTONEXTINHISTORY); });
- handler->tabPreviousRequested.connect([] {
- triggerAction(Core::Constants::GOTOPREVINHISTORY);
- });
+ handler->tabPreviousRequested.set([] { triggerAction(Core::Constants::GOTOPREVINHISTORY); });
- handler->completionRequested.connect([this, tew] {
+ handler->completionRequested.set([this, tew] {
if (tew)
tew->invokeAssist(Completion, &runData->wordProvider);
});