Lua: Allow creating and running user defined scripts

Change-Id: I227d55105fde53f22885793b4bfae69da90e8fa6
Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
This commit is contained in:
David Schulz
2024-10-10 14:58:11 +02:00
parent af44a93f35
commit 5d1d4d9f54
6 changed files with 159 additions and 11 deletions

View File

@@ -5,6 +5,8 @@
#include "luapluginspec.h"
#include "luatr.h"
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/icore.h>
#include <coreplugin/ioutputpane.h>
#include <coreplugin/jsexpander.h>
@@ -14,6 +16,7 @@
#include <extensionsystem/pluginmanager.h>
#include <utils/algorithm.h>
#include <utils/fileutils.h>
#include <utils/layoutbuilder.h>
#include <utils/macroexpander.h>
#include <utils/qtcprocess.h>
@@ -25,6 +28,7 @@
#include <QLineEdit>
#include <QListView>
#include <QPainter>
#include <QMenu>
#include <QStringListModel>
#include <QStyledItemDelegate>
@@ -34,6 +38,11 @@ using namespace ExtensionSystem;
namespace Lua::Internal {
const char M_SCRIPT[] = "Lua.Script";
const char G_SCRIPTS[] = "Lua.Scripts";
const char ACTION_SCRIPTS_BASE[] = "Lua.Scripts.";
const char ACTION_NEW_SCRIPT[] = "Lua.NewScript";
void setupActionModule();
void setupCoreModule();
void setupFetchModule();
@@ -270,6 +279,7 @@ class LuaPlugin : public IPlugin
private:
LuaPane *m_pane = nullptr;
std::unique_ptr<FilePathWatcher> m_userScriptsWatcher;
public:
LuaPlugin() {}
@@ -319,6 +329,44 @@ public:
});
m_pane = new LuaPane(this);
//register actions
ActionContainer *toolsContainer = ActionManager::actionContainer(Core::Constants::M_TOOLS);
ActionContainer *scriptContainer = ActionManager::createMenu(M_SCRIPT);
Command *newScriptCommand = ActionBuilder(this, ACTION_NEW_SCRIPT)
.setScriptable(true)
.setText(tr("New Script..."))
.addToContainer(M_SCRIPT)
.addOnTriggered([](){
auto command = Core::ActionManager::command(Utils::Id("Wizard.Impl.Q.QCreatorScript"));
if (command && command->action())
command->action()->trigger();
else
qWarning("Failed to get wizard command. UI changed?");
})
.command();
scriptContainer->addAction(newScriptCommand);
scriptContainer->addSeparator();
scriptContainer->appendGroup(G_SCRIPTS);
scriptContainer->menu()->setTitle(Tr::tr("Scripting"));
toolsContainer->addMenu(scriptContainer);
const Utils::FilePath userScriptsPath = Core::ICore::userResourcePath("scripts");
userScriptsPath.ensureWritableDir();
if (auto watch = userScriptsPath.watch()) {
m_userScriptsWatcher.swap(*watch);
connect(
m_userScriptsWatcher.get(),
&FilePathWatcher::pathChanged,
this,
&LuaPlugin::scanForScripts);
}
scanForScripts();
}
bool delayedInitialize() final
@@ -355,6 +403,49 @@ public:
PluginManager::addPlugins({plugins.begin(), plugins.end()});
PluginManager::loadPluginsAtRuntime(plugins);
}
void scanForScripts()
{
const FilePath scriptsPath = Core::ICore::userResourcePath("scripts");
if (!scriptsPath.exists())
return;
ActionContainer *scriptContainer = ActionManager::actionContainer(M_SCRIPT);
const FilePaths scripts = scriptsPath.dirEntries(FileFilter({"*.lua"}, QDir::Files));
for (const FilePath &script : scripts) {
const Id base = Id(ACTION_SCRIPTS_BASE).withSuffix(script.baseName());
const Id menuId = base.withSuffix(".Menu");
if (!ActionManager::actionContainer(menuId)) {
ActionContainer *container = ActionManager::createMenu(menuId);
scriptContainer->addMenu(container);
auto menu = container->menu();
menu->setTitle(script.baseName());
ActionBuilder(this, base)
.setText(Tr::tr("%1").arg(script.baseName()))
.setToolTip(Tr::tr("Run script '%1'").arg(script.toUserOutput()))
.addOnTriggered([this, script]() { runScript(script); });
connect(menu->addAction(Tr::tr("Run")), &QAction::triggered, this, [this, script]() {
runScript(script);
});
connect(menu->addAction(Tr::tr("Edit")), &QAction::triggered, this, [script]() {
Core::EditorManager::openEditor(script);
});
}
}
}
void runScript(const FilePath &script)
{
expected_str<QByteArray> content = script.fileContents();
if (content) {
Lua::runScript(QString::fromUtf8(*content), script.fileName());
} else {
MessageManager::writeFlashing(Tr::tr("Failed to read script %1: %2")
.arg(script.toUserOutput())
.arg(content.error()));
}
}
};
} // namespace Lua::Internal