Lua: Add TextDocument bindings

Change-Id: Ib713993a548f76f50c4b29fb11c445d2e38b16b3
Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
This commit is contained in:
Lukasz Papierkowski
2024-07-10 12:47:23 +02:00
committed by lie
parent 822e5a30bc
commit d298244c10
7 changed files with 123 additions and 22 deletions

View File

@@ -1,13 +1,14 @@
add_qtc_plugin(Lua
PLUGIN_DEPENDS Core
PUBLIC_DEPENDS lua546 sol2
PUBLIC_DEPENDS lua546 sol2 TextEditor
PUBLIC_DEFINES LUA_AVAILABLE
SOURCES
wizards/wizards.qrc
bindings/action.cpp
bindings/async.cpp
bindings/core.cpp
bindings/documents.cpp
bindings/documents.h
bindings/fetch.cpp
bindings/gui.cpp
bindings/hook.cpp
@@ -40,6 +41,7 @@ add_qtc_plugin(Lua
meta/simpletypes.lua
meta/utils.lua
meta/widgets.lua
wizards/wizards.qrc
# generateqtbindings.cpp # Use this if you need to generate some code.
)

View File

@@ -0,0 +1,30 @@
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "../luaengine.h"
#include "sol/sol.hpp"
#include "documents.h"
#include <texteditor/textdocument.h>
namespace Lua::Internal {
void addDocumentsModule()
{
LuaEngine::registerProvider("Documents", [](sol::state_view lua) -> sol::object {
sol::table documents = lua.create_table();
documents.new_usertype<LuaTextDocument>(
"LuaTextDocument",
sol::no_constructor,
"setChangedCallback",
[](LuaTextDocument &self, sol::function callback) {
self.setChangedCallback(callback);
});
return documents;
});
}
} // namespace Lua::Internal

View File

@@ -0,0 +1,40 @@
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
#include "sol/sol.hpp"
#include <texteditor/textdocument.h>
namespace Lua {
class LuaTextDocument : public QObject
{
Q_OBJECT
public:
LuaTextDocument(TextEditor::TextDocument *document)
: m_document(document)
{
connect(
m_document,
&TextEditor::TextDocument::contentsChanged,
this,
&LuaTextDocument::contentsChanged);
return;
}
void setChangedCallback(sol::function lua_function) { m_changedCallback = lua_function; }
void contentsChanged()
{
if (m_changedCallback)
m_changedCallback();
}
private:
TextEditor::TextDocument *m_document;
sol::function m_changedCallback;
};
} // namespace Lua

View File

@@ -3,7 +3,9 @@
#include "../luaengine.h"
#include "documents.h"
#include <coreplugin/editormanager/editormanager.h>
#include <texteditor/textdocument.h>
namespace Lua {
@@ -27,8 +29,8 @@ namespace Internal {
void addHookModule()
{
LuaEngine::autoRegister([](sol::state_view lua) {
auto connection = lua.new_usertype<QMetaObject::Connection>("QMetaConnection",
sol::no_constructor);
auto connection
= lua.new_usertype<QMetaObject::Connection>("QMetaConnection", sol::no_constructor);
auto hook = lua.new_usertype<Hook>(
"Hook",
@@ -51,15 +53,24 @@ void addHookModule()
Core::EditorManager::instance(),
&Core::EditorManager::documentOpened,
[func](Core::IDocument *document) {
QTC_CHECK_EXPECTED(LuaEngine::void_safe_call(func, document));
auto text_document = qobject_cast<TextEditor::TextDocument *>(document);
if (text_document) {
QTC_CHECK_EXPECTED(LuaEngine::void_safe_call(
func, std::make_unique<LuaTextDocument>(text_document)));
}
});
});
LuaEngine::registerHook("editors.documentClosed", [](const sol::protected_function &func) {
QObject::connect(
Core::EditorManager::instance(),
&Core::EditorManager::documentClosed,
[func](Core::IDocument *document) {
QTC_CHECK_EXPECTED(LuaEngine::void_safe_call(func, document));
auto text_document = qobject_cast<TextEditor::TextDocument *>(document);
if (text_document) {
QTC_CHECK_EXPECTED(LuaEngine::void_safe_call(
func, std::make_unique<LuaTextDocument>(text_document)));
}
});
});
}

View File

@@ -8,6 +8,7 @@ QtcPlugin {
Depends { name: "lua546" }
Depends { name: "sol2" }
Depends { name: "TextEditor" }
files: [
// "generateqtbindings.cpp", // use this if you need to generate some code
@@ -32,6 +33,8 @@ QtcPlugin {
"action.cpp",
"async.cpp",
"core.cpp",
"documents.cpp",
"documents.h",
"fetch.cpp",
"gui.cpp",
"hook.cpp",

View File

@@ -22,6 +22,8 @@ using namespace Utils;
namespace Lua {
static Q_LOGGING_CATEGORY(LOGLSPLUA, "qtc.lua.engine", QtWarningMsg);
class LuaInterfaceImpl : public Utils::LuaInterface
{
LuaEngine *m_engine;
@@ -161,11 +163,15 @@ void LuaEngine::registerHook(QString name, const std::function<void(sol::functio
expected_str<void> LuaEngine::connectHooks(
sol::state_view lua, const sol::table &table, const QString &path)
{
qCDebug(LOGLSPLUA) << "connectHooks called with path: " << path;
for (const auto &[k, v] : table) {
qCDebug(LOGLSPLUA) << "Processing key: " << k.as<QString>();
if (v.get_type() == sol::type::table) {
return connectHooks(lua, v.as<sol::table>(), QStringList{path, k.as<QString>()}.join("."));
} else if (v.get_type() == sol::type::function) {
QString hookName = QStringList{path, k.as<QString>()}.join(".");
qCDebug(LOGLSPLUA) << "Connecting function to hook: " << hookName;
auto it = d->m_hooks.find(hookName);
if (it == d->m_hooks.end())
return make_unexpected(Tr::tr("No hook with the name \"%1\" found.").arg(hookName));
@@ -271,8 +277,15 @@ expected_str<sol::protected_function> LuaEngine::prepareSetup(
if (!pluginTable)
return make_unexpected(Tr::tr("Script did not return a table."));
qCDebug(LOGLSPLUA) << "Script returned table with keys:";
for (const auto &pair : *pluginTable) {
qCDebug(LOGLSPLUA) << "Key:" << pair.first.as<std::string>();
qCDebug(LOGLSPLUA) << "Value:" << pair.second.as<std::string>();
}
auto hookTable = pluginTable->get<sol::optional<sol::table>>("hooks");
qCDebug(LOGLSPLUA) << "Hooks table found: " << hookTable.has_value();
if (hookTable) {
auto connectResult = connectHooks(lua, *hookTable, {});
if (!connectResult)

View File

@@ -32,18 +32,19 @@ using namespace ExtensionSystem;
namespace Lua::Internal {
void addAsyncModule();
void addFetchModule();
void addActionModule();
void addUtilsModule();
void addMessageManagerModule();
void addProcessModule();
void addSettingsModule();
void addGuiModule();
void addQtModule();
void addAsyncModule();
void addCoreModule();
void addDocumentsModule();
void addFetchModule();
void addGuiModule();
void addHookModule();
void addInstallModule();
void addMessageManagerModule();
void addProcessModule();
void addQtModule();
void addSettingsModule();
void addUtilsModule();
class LuaJsExtension : public QObject
{
@@ -245,18 +246,19 @@ public:
{
m_luaEngine.reset(new LuaEngine());
addAsyncModule();
addFetchModule();
addActionModule();
addUtilsModule();
addMessageManagerModule();
addProcessModule();
addSettingsModule();
addGuiModule();
addQtModule();
addAsyncModule();
addCoreModule();
addDocumentsModule();
addFetchModule();
addGuiModule();
addHookModule();
addInstallModule();
addMessageManagerModule();
addProcessModule();
addQtModule();
addSettingsModule();
addUtilsModule();
Core::JsExpander::registerGlobalObject("Lua", [] { return new LuaJsExtension(); });