Lua LSP: Add parameter for async options

Allows using async code to create the options of a
language client. This is useful for instance if you need to get
values from a SecrectAspect

Change-Id: Ica23b7f0df00bff3af7520524905a59ceb5b8e8c
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Marcus Tillmanns
2024-09-26 12:52:11 +02:00
parent d055fb2a06
commit e03aa820b4
2 changed files with 34 additions and 0 deletions

View File

@@ -11,6 +11,8 @@
#include <lua/bindings/inheritance.h>
#include <lua/luaengine.h>
#include <lua/bindings/async.h>
#include <extensionsystem/iplugin.h>
#include <extensionsystem/pluginmanager.h>
@@ -18,6 +20,7 @@
#include <projectexplorer/projectmanager.h>
#include <utils/commandline.h>
#include <utils/guardedcallback.h>
#include <utils/layoutbuilder.h>
#include <QJsonDocument>
@@ -207,6 +210,8 @@ public:
TransportType m_transportType{TransportType::StdIO};
std::function<expected_str<void>(CommandLine &)> m_cmdLineCallback;
std::function<expected_str<void>(QString &)> m_initOptionsCallback;
sol::function m_asyncInitOptions;
bool m_isUpdatingAsyncOptions{false};
AspectContainer *m_aspects{nullptr};
QString m_name;
Utils::Id m_settingsTypeId;
@@ -324,6 +329,13 @@ public:
&LanguageClientManager::clientRemoved,
this,
&LuaClientWrapper::onClientRemoved);
if (auto asyncInit = options.get<sol::optional<sol::function>>(
"initializationOptionsAsync")) {
m_asyncInitOptions = *asyncInit;
QMetaObject::invokeMethod(
this, &LuaClientWrapper::updateAsyncOptions, Qt::QueuedConnection);
}
}
void onClientRemoved(Client *c, bool unexpected)
@@ -462,6 +474,25 @@ public:
clients.front()->sendMessage(request);
}
void updateAsyncOptions()
{
if (m_isUpdatingAsyncOptions)
return;
QTC_ASSERT(m_asyncInitOptions, return);
m_isUpdatingAsyncOptions = true;
std::function<void(sol::object)> cb = guardedCallback(this, [this](sol::object options) {
if (options.is<sol::table>())
m_initializationOptions = ::Lua::toJsonString(options.as<sol::table>());
else if (options.is<QString>())
m_initializationOptions = options.as<QString>();
emit optionsChanged();
m_isUpdatingAsyncOptions = false;
});
::Lua::Async::start<sol::object>(m_asyncInitOptions, cb);
}
void updateOptions()
{
if (m_cmdLineCallback) {
@@ -479,6 +510,8 @@ public:
// optionsChanged() needs to be called for it as well, but only once per updateOptions()
emit optionsChanged();
}
if (m_asyncInitOptions)
updateAsyncOptions();
}
static CommandLine cmdFromTable(const sol::table &tbl)

View File

@@ -11,6 +11,7 @@ local lsp = {}
---@field languageFilter LanguageFilter The language filter deciding which files to open with the language server.
---@field startBehavior? "AlwaysOn"|"RequiresFile"|"RequiresProject"
---@field initializationOptions? function|table|string The initialization options to pass to the language server, either a JSON string, a table, or a function that returns either.
---@field initializationOptionsAsync? function A callback that will return the initialization options as a JSON String or a table. Inside the callback you can use Async functions.
---@field settings? AspectContainer The settings object to associate with the language server.
---@field onStartFailed? function This callback is called when client failed to start.
---@field showInSettings? boolean Whether the client should show up in the general Language Server list.