forked from qt-creator/qt-creator
Lua: Allow creating and running user defined scripts
Change-Id: I227d55105fde53f22885793b4bfae69da90e8fa6 Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "corejsextensions.h"
|
||||
|
||||
#include "icore.h"
|
||||
#include "messagemanager.h"
|
||||
|
||||
#include <utils/appinfo.h>
|
||||
@@ -35,6 +36,11 @@ QString UtilsJsExtension::qtCreatorIdeVersion() const
|
||||
return QCoreApplication::applicationVersion();
|
||||
}
|
||||
|
||||
QString UtilsJsExtension::qtCreatorSettingsPath() const
|
||||
{
|
||||
return Core::ICore::userResourcePath().toString();
|
||||
}
|
||||
|
||||
QString UtilsJsExtension::toNativeSeparators(const QString &in) const
|
||||
{
|
||||
return QDir::toNativeSeparators(in);
|
||||
|
@@ -21,6 +21,7 @@ public:
|
||||
Q_INVOKABLE QString qtVersion() const;
|
||||
Q_INVOKABLE QString qtCreatorVersion() const;
|
||||
Q_INVOKABLE QString qtCreatorIdeVersion() const;
|
||||
Q_INVOKABLE QString qtCreatorSettingsPath() const;
|
||||
|
||||
// File name conversions:
|
||||
Q_INVOKABLE QString toNativeSeparators(const QString &in) const;
|
||||
|
@@ -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
|
||||
|
4
src/plugins/lua/wizards/qcscript/script.lua
Normal file
4
src/plugins/lua/wizards/qcscript/script.lua
Normal file
@@ -0,0 +1,4 @@
|
||||
T = require'TextEditor'
|
||||
editor = T.currentEditor()
|
||||
cursor = editor:cursor()
|
||||
cursor:insertText('-- Hello World!')
|
44
src/plugins/lua/wizards/qcscript/wizard.json
Normal file
44
src/plugins/lua/wizards/qcscript/wizard.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"version": 1,
|
||||
"supportedProjectTypes": [],
|
||||
"id": "Q.QCreatorScript",
|
||||
"category": "R.Lua",
|
||||
"trDescription": "Creates a script that can access Qt Creator internals and be triggered by an action.",
|
||||
"trDisplayName": "Qt Creator Script",
|
||||
"trDisplayCategory": "Lua",
|
||||
"iconText": "ts",
|
||||
"enabled": "%{JS: value('Plugins').indexOf('Lua') >= 0}",
|
||||
"options": [
|
||||
{
|
||||
"key": "DefaultSuffix",
|
||||
"value": "%{JS: Util.preferredSuffix('text/x-lua')}"
|
||||
},
|
||||
{
|
||||
"key": "InitialPath",
|
||||
"value": "%{JS: Util.qtCreatorSettingsPath()}/scripts"
|
||||
},
|
||||
{
|
||||
"key": "PathVisible",
|
||||
"value": "false"
|
||||
}
|
||||
],
|
||||
"pages": [
|
||||
{
|
||||
"trDisplayName": "Location",
|
||||
"trShortTitle": "Location",
|
||||
"typeId": "File"
|
||||
}
|
||||
],
|
||||
"generators": [
|
||||
{
|
||||
"typeId": "File",
|
||||
"data": [
|
||||
{
|
||||
"source": "script.lua",
|
||||
"target": "%{JS: Util.fileName(value('TargetPath'), value('DefaultSuffix'))}",
|
||||
"openInEditor": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@@ -1,13 +1,15 @@
|
||||
<RCC>
|
||||
<qresource prefix="/lua/wizards">
|
||||
<file>luafile/wizard.json</file>
|
||||
<file>luafile/script.lua</file>
|
||||
<file>plugin/init.lua.tpl</file>
|
||||
<file>plugin/plugin.lua.tpl</file>
|
||||
<file>plugin/project.json</file>
|
||||
<file>plugin/wizard.json</file>
|
||||
<file>plugin/.luarc.json</file>
|
||||
<file>plugin/icon.png</file>
|
||||
<file>plugin/icon@2x.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/lua/wizards">
|
||||
<file>luafile/wizard.json</file>
|
||||
<file>luafile/script.lua</file>
|
||||
<file>plugin/init.lua.tpl</file>
|
||||
<file>plugin/plugin.lua.tpl</file>
|
||||
<file>plugin/project.json</file>
|
||||
<file>plugin/wizard.json</file>
|
||||
<file>plugin/.luarc.json</file>
|
||||
<file>plugin/icon.png</file>
|
||||
<file>plugin/icon@2x.png</file>
|
||||
<file>qcscript/script.lua</file>
|
||||
<file>qcscript/wizard.json</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
Reference in New Issue
Block a user