forked from qt-creator/qt-creator
LUA: Client and Utils bindings update
Change-Id: Icad01906aa9f9405004ce342399fcb42354e77df Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io> Reviewed-by: <mua@spyro-soft.com>
This commit is contained in:
@@ -26,6 +26,43 @@ using namespace Core;
|
||||
using namespace TextEditor;
|
||||
using namespace ProjectExplorer;
|
||||
|
||||
namespace {
|
||||
|
||||
class RequestWithResponse : public LanguageServerProtocol::JsonRpcMessage
|
||||
{
|
||||
sol::function m_callback;
|
||||
LanguageServerProtocol::MessageId m_id;
|
||||
|
||||
public:
|
||||
RequestWithResponse(const QJsonObject &obj, const sol::function &cb)
|
||||
: LanguageServerProtocol::JsonRpcMessage(obj)
|
||||
, m_callback(cb)
|
||||
{
|
||||
m_id = LanguageServerProtocol::MessageId(obj["id"]);
|
||||
}
|
||||
|
||||
std::optional<LanguageServerProtocol::ResponseHandler> responseHandler() const override
|
||||
{
|
||||
if (!m_id.isValid())
|
||||
qWarning() << "Invalid 'id' in request:" << toJsonObject();
|
||||
return std::nullopt;
|
||||
|
||||
return LanguageServerProtocol::ResponseHandler{
|
||||
m_id, [callback = m_callback](const JsonRpcMessage &msg) {
|
||||
if (!callback.valid()) {
|
||||
qWarning() << "Invalid Lua callback";
|
||||
return;
|
||||
}
|
||||
|
||||
auto result = ::Lua::LuaEngine::void_safe_call(
|
||||
callback, ::Lua::LuaEngine::toTable(callback.lua_state(), msg.toJsonObject()));
|
||||
QTC_CHECK_EXPECTED(result);
|
||||
}};
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace LanguageClient::Lua {
|
||||
|
||||
static void registerLuaApi();
|
||||
@@ -73,14 +110,16 @@ public:
|
||||
}
|
||||
m_process = new Process;
|
||||
m_process->setProcessMode(ProcessMode::Writer);
|
||||
connect(m_process,
|
||||
&Process::readyReadStandardError,
|
||||
this,
|
||||
&LuaLocalSocketClientInterface::readError);
|
||||
connect(m_process,
|
||||
&Process::readyReadStandardOutput,
|
||||
this,
|
||||
&LuaLocalSocketClientInterface::readOutput);
|
||||
connect(
|
||||
m_process,
|
||||
&Process::readyReadStandardError,
|
||||
this,
|
||||
&LuaLocalSocketClientInterface::readError);
|
||||
connect(
|
||||
m_process,
|
||||
&Process::readyReadStandardOutput,
|
||||
this,
|
||||
&LuaLocalSocketClientInterface::readOutput);
|
||||
connect(m_process, &Process::started, this, [this]() {
|
||||
this->LocalSocketClientInterface::startImpl();
|
||||
emit started();
|
||||
@@ -348,15 +387,24 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void sendMessage(const sol::table &message)
|
||||
void sendMessage(const sol::table &message, const sol::function &callback)
|
||||
{
|
||||
const QJsonValue messageValue = ::Lua::LuaEngine::toJson(message);
|
||||
if (!messageValue.isObject())
|
||||
throw sol::error("Message is not an object");
|
||||
const LanguageServerProtocol::JsonRpcMessage jsonrpcmessage(messageValue.toObject());
|
||||
|
||||
auto make_request = [&]() -> std::unique_ptr<LanguageServerProtocol::JsonRpcMessage> {
|
||||
if (callback.valid()) {
|
||||
return std::make_unique<RequestWithResponse>(messageValue.toObject(), callback);
|
||||
}
|
||||
|
||||
return std::make_unique<LanguageServerProtocol::JsonRpcMessage>(messageValue.toObject());
|
||||
};
|
||||
|
||||
auto const request = make_request();
|
||||
for (Client *c : LanguageClientManager::clientsForSettingId(m_settingsTypeId.toString())) {
|
||||
if (c)
|
||||
c->sendMessage(jsonrpcmessage);
|
||||
c->sendMessage(*request);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -545,6 +593,27 @@ static void registerLuaApi()
|
||||
LanguageClientSettings::registerClientType(type);
|
||||
|
||||
return luaClient;
|
||||
},
|
||||
"documentVersion",
|
||||
[](const Utils::FilePath &path) -> int {
|
||||
auto client = LanguageClientManager::clientForFilePath(path);
|
||||
if (!client) {
|
||||
qWarning() << "documentVersion(). No client for file path:" << path;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return client->documentVersion(path);
|
||||
},
|
||||
|
||||
"hostPathToServerUri",
|
||||
[](const Utils::FilePath &path) -> QString {
|
||||
auto client = LanguageClientManager::clientForFilePath(path);
|
||||
if (!client) {
|
||||
qWarning() << "hostPathToServerUri(). No client for file path:" << path;
|
||||
return {};
|
||||
}
|
||||
|
||||
return client->hostPathToServerUri(path).toString();
|
||||
});
|
||||
|
||||
return result;
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#include <utils/hostosinfo.h>
|
||||
|
||||
#include <QTimer>
|
||||
#include <QUuid>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
@@ -25,41 +26,43 @@ void addUtilsModule()
|
||||
|
||||
sol::table utils = lua.create_table();
|
||||
|
||||
utils.set_function("waitms_cb", [guard = pluginSpec->connectionGuard.get()](int ms, const sol::function &cb) {
|
||||
QTimer::singleShot(ms, guard, [cb]() { cb(); });
|
||||
});
|
||||
utils.set_function(
|
||||
"waitms_cb",
|
||||
[guard = pluginSpec->connectionGuard.get()](int ms, const sol::function &cb) {
|
||||
QTimer::singleShot(ms, guard, [cb]() { cb(); });
|
||||
});
|
||||
|
||||
auto dirEntries_cb =
|
||||
[&futureSync, guard = pluginSpec->connectionGuard.get()](
|
||||
const FilePath &p, const sol::table &options, const sol::function &cb) {
|
||||
const QStringList nameFilters = options.get_or<QStringList>("nameFilters", {});
|
||||
QDir::Filters fileFilters
|
||||
= (QDir::Filters) options.get_or<int>("fileFilters", QDir::NoFilter);
|
||||
QDirIterator::IteratorFlags flags
|
||||
= (QDirIterator::IteratorFlags)
|
||||
options.get_or<int>("flags", QDirIterator::NoIteratorFlags);
|
||||
auto dirEntries_cb = [&futureSync, guard = pluginSpec->connectionGuard.get()](
|
||||
const FilePath &p,
|
||||
const sol::table &options,
|
||||
const sol::function &cb) {
|
||||
const QStringList nameFilters = options.get_or<QStringList>("nameFilters", {});
|
||||
QDir::Filters fileFilters
|
||||
= (QDir::Filters) options.get_or<int>("fileFilters", QDir::NoFilter);
|
||||
QDirIterator::IteratorFlags flags
|
||||
= (QDirIterator::IteratorFlags)
|
||||
options.get_or<int>("flags", QDirIterator::NoIteratorFlags);
|
||||
|
||||
FileFilter filter(nameFilters, fileFilters, flags);
|
||||
FileFilter filter(nameFilters, fileFilters, flags);
|
||||
|
||||
QFuture<FilePath> future = Utils::asyncRun(
|
||||
[p, filter](QPromise<FilePath> &promise) {
|
||||
p.iterateDirectory(
|
||||
[&promise](const FilePath &item) {
|
||||
if (promise.isCanceled())
|
||||
return IterationPolicy::Stop;
|
||||
QFuture<FilePath> future = Utils::asyncRun([p, filter](QPromise<FilePath> &promise) {
|
||||
p.iterateDirectory(
|
||||
[&promise](const FilePath &item) {
|
||||
if (promise.isCanceled())
|
||||
return IterationPolicy::Stop;
|
||||
|
||||
promise.addResult(item);
|
||||
return IterationPolicy::Continue;
|
||||
},
|
||||
filter);
|
||||
});
|
||||
promise.addResult(item);
|
||||
return IterationPolicy::Continue;
|
||||
},
|
||||
filter);
|
||||
});
|
||||
|
||||
futureSync.addFuture<FilePath>(future);
|
||||
futureSync.addFuture<FilePath>(future);
|
||||
|
||||
Utils::onFinished<FilePath>(future, guard, [cb](const QFuture<FilePath> &future) {
|
||||
cb(future.results());
|
||||
});
|
||||
};
|
||||
Utils::onFinished<FilePath>(future, guard, [cb](const QFuture<FilePath> &future) {
|
||||
cb(future.results());
|
||||
});
|
||||
};
|
||||
|
||||
auto searchInPath_cb = [&futureSync,
|
||||
guard = pluginSpec->connectionGuard
|
||||
@@ -77,6 +80,8 @@ void addUtilsModule()
|
||||
utils.set_function("__dirEntries_cb__", dirEntries_cb);
|
||||
utils.set_function("__searchInPath_cb__", searchInPath_cb);
|
||||
|
||||
utils.set_function("createUuid", []() { return QUuid::createUuid().toString(); });
|
||||
|
||||
sol::function wrap = async["wrap"].get<sol::function>();
|
||||
|
||||
utils["waitms"] = wrap(utils["waitms_cb"]);
|
||||
|
@@ -32,6 +32,14 @@ function lsp.Client:registerMessage(msg, callback) end
|
||||
---Sends a message to the language server.
|
||||
function lsp.Client:sendMessage(msg, callback) end
|
||||
|
||||
---@param filePath FilePath to get the version of.
|
||||
---@return int Returns -1 on error, otherwise current document version.
|
||||
function lsp.Client:documentVersion(filePath) end
|
||||
---
|
||||
---@param filePath table file path to get the uri of.
|
||||
---@return QString Returns empty string on error, otherwise the server URI string.
|
||||
function lsp.Client:hostPathToServerUri(filePath) end
|
||||
|
||||
---Creates a new Language Client.
|
||||
---@param options ClientOptions
|
||||
---@return Client
|
||||
|
@@ -14,6 +14,10 @@ function utils.waitms(ms) end
|
||||
---@param callback function The callback to call.
|
||||
function utils.waitms_cb(ms, callback) end
|
||||
|
||||
---Creates a UUID.
|
||||
---@return QString Arbitrary UUID string.
|
||||
function utils.createUuid() end
|
||||
|
||||
---@class FilePath
|
||||
utils.FilePath = {}
|
||||
|
||||
|
Reference in New Issue
Block a user