|
@@ -11,7 +11,7 @@ You can create custom menu items and editor lifecycle hooks using Lua files with
|
|
|
|
|
|
Editor scripts run inside an editor, in a Lua VM emulated by Java VM. All scripts share the same single environment, which means they can interact with each other. You can require Lua modules, just as with `.script` files, but Lua version that is running inside the editor is different, so make sure your shared code is compatible. Editor uses Lua version 5.2.x, more specifically [luaj](https://github.com/luaj/luaj) runtime, which is currently the only viable solution to run Lua on JVM. Besides that, there are some restrictions:
|
|
Editor scripts run inside an editor, in a Lua VM emulated by Java VM. All scripts share the same single environment, which means they can interact with each other. You can require Lua modules, just as with `.script` files, but Lua version that is running inside the editor is different, so make sure your shared code is compatible. Editor uses Lua version 5.2.x, more specifically [luaj](https://github.com/luaj/luaj) runtime, which is currently the only viable solution to run Lua on JVM. Besides that, there are some restrictions:
|
|
- there is no `debug` and `coroutine` packages;
|
|
- there is no `debug` and `coroutine` packages;
|
|
-- there is no `os.execute` — we provide a more user-friendly and secure way to execute shell scripts in [actions](#_actions) section;
|
|
|
|
|
|
+- there is no `os.execute` — we provide a more user-friendly and secure way to execute shell scripts in [actions](#actions) section;
|
|
- there is no `os.tmpname` and `io.tmpfile` — currently editor scripts can access files only inside the project directory;
|
|
- there is no `os.tmpname` and `io.tmpfile` — currently editor scripts can access files only inside the project directory;
|
|
- there is currently no `os.rename`, although we want to add it;
|
|
- there is currently no `os.rename`, although we want to add it;
|
|
- there is no `os.exit` and `os.setlocale`.
|
|
- there is no `os.exit` and `os.setlocale`.
|
|
@@ -24,13 +24,13 @@ Every editor script should return a module, like that:
|
|
```lua
|
|
```lua
|
|
local M = {}
|
|
local M = {}
|
|
|
|
|
|
-function M.get_commands()
|
|
|
|
|
|
+function M.get_commands()
|
|
-- TODO
|
|
-- TODO
|
|
end
|
|
end
|
|
|
|
|
|
return M
|
|
return M
|
|
```
|
|
```
|
|
-Editor then collects all editor scripts defined in project and libraries, loads them into single Lua VM and calls into them when needed (more on that in [commands](#_commands) and [lifecycle hooks](#_lifecycle_hooks) sections).
|
|
|
|
|
|
+Editor then collects all editor scripts defined in project and libraries, loads them into single Lua VM and calls into them when needed (more on that in [commands](#commands) and [lifecycle hooks](#lifecycle-hooks) sections).
|
|
|
|
|
|
## Editor API
|
|
## Editor API
|
|
|
|
|
|
@@ -45,7 +45,7 @@ You can interact with the editor using `editor` package that defines this API:
|
|
- numbers
|
|
- numbers
|
|
- vec2/vec3/vec4
|
|
- vec2/vec3/vec4
|
|
- resources
|
|
- resources
|
|
-
|
|
|
|
|
|
+
|
|
Please note that some of these properties might be read-only, and some might be unavailable in different contexts, so you should use `editor.can_get` before reading them and `editor.can_set` before making editor set them. Hover over property name in Properties view to see a tooltip with information about how this property is named in editor scripts. You can set resource properties to nil by supplying `""` value.
|
|
Please note that some of these properties might be read-only, and some might be unavailable in different contexts, so you should use `editor.can_get` before reading them and `editor.can_set` before making editor set them. Hover over property name in Properties view to see a tooltip with information about how this property is named in editor scripts. You can set resource properties to nil by supplying `""` value.
|
|
- `editor.can_get(node_id, property)` — check if you can get this property so `editor.get()` won't throw an error
|
|
- `editor.can_get(node_id, property)` — check if you can get this property so `editor.get()` won't throw an error
|
|
- `editor.can_set(node_id, property)` — check if `"set"` action with this property won't throw an error
|
|
- `editor.can_set(node_id, property)` — check if `"set"` action with this property won't throw an error
|
|
@@ -72,13 +72,13 @@ function M.get_commands()
|
|
local text = editor.get(opts.selection, "text")
|
|
local text = editor.get(opts.selection, "text")
|
|
return {
|
|
return {
|
|
{
|
|
{
|
|
- action = "set",
|
|
|
|
- node_id = opts.selection,
|
|
|
|
- property = "text",
|
|
|
|
|
|
+ action = "set",
|
|
|
|
+ node_id = opts.selection,
|
|
|
|
+ property = "text",
|
|
value = strip_comments(text)
|
|
value = strip_comments(text)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- end
|
|
|
|
|
|
+ end
|
|
},
|
|
},
|
|
{
|
|
{
|
|
label = "Minify JSON"
|
|
label = "Minify JSON"
|
|
@@ -93,7 +93,7 @@ function M.get_commands()
|
|
local path = editor.get(opts.selection, "path")
|
|
local path = editor.get(opts.selection, "path")
|
|
return {
|
|
return {
|
|
{
|
|
{
|
|
- action = "shell",
|
|
|
|
|
|
+ action = "shell",
|
|
command = {"./scripts/minify-json.sh", path:sub(2)}
|
|
command = {"./scripts/minify-json.sh", path:sub(2)}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -115,11 +115,11 @@ Editor expects `get_commands()` to return an array of tables, each describing a
|
|
- `"outline"` — something that can be shown in the Outline. In Outline it's a selected item, in menu bar it's a currently open file;
|
|
- `"outline"` — something that can be shown in the Outline. In Outline it's a selected item, in menu bar it's a currently open file;
|
|
- `cardinality` defines how many selected items there should be. If `"one"`, selection passed to command callback will be a single node id. If `"many"`, selection passed to command callback will be an array of one or more node ids.
|
|
- `cardinality` defines how many selected items there should be. If `"one"`, selection passed to command callback will be a single node id. If `"many"`, selection passed to command callback will be an array of one or more node ids.
|
|
- `active` - a callback that is executed to check that command is active, expected to return boolean. If `locations` include `"Assets"` or `"Outline"`, `active` will be called when showing context menu. If locations include `"Edit"` or `"View"`, active will be called on every user interaction, such as typing on keyboard or clicking with mouse, so be sure that `active` is relatively fast.
|
|
- `active` - a callback that is executed to check that command is active, expected to return boolean. If `locations` include `"Assets"` or `"Outline"`, `active` will be called when showing context menu. If locations include `"Edit"` or `"View"`, active will be called on every user interaction, such as typing on keyboard or clicking with mouse, so be sure that `active` is relatively fast.
|
|
-- `run` - a callback that is executed when user selects menu item, expected to return an array of [actions](#_actions).
|
|
|
|
|
|
+- `run` - a callback that is executed when user selects menu item, expected to return an array of [actions](#actions).
|
|
|
|
|
|
## Actions
|
|
## Actions
|
|
|
|
|
|
-Action is a table describing what editor should do. Every action has an `action` key. Actions come in 2 flavors: undoable and non-undoable.
|
|
|
|
|
|
+Action is a table describing what editor should do. Every action has an `action` key. Actions come in 2 flavors: undoable and non-undoable.
|
|
|
|
|
|
### Undoable actions
|
|
### Undoable actions
|
|
|
|
|
|
@@ -150,7 +150,7 @@ Existing non-undoable actions:
|
|
{
|
|
{
|
|
action = "shell",
|
|
action = "shell",
|
|
command = {
|
|
command = {
|
|
- "./scripts/minify-json.sh",
|
|
|
|
|
|
+ "./scripts/minify-json.sh",
|
|
editor.get(opts.selection, "path"):sub(2) -- trim leading "/"
|
|
editor.get(opts.selection, "path"):sub(2) -- trim leading "/"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -161,7 +161,7 @@ Existing non-undoable actions:
|
|
|
|
|
|
You can mix undoable and non-undoable actions. Actions are executed sequentially, hence depending on an order of actions you will end up losing ability to undo parts of that command.
|
|
You can mix undoable and non-undoable actions. Actions are executed sequentially, hence depending on an order of actions you will end up losing ability to undo parts of that command.
|
|
|
|
|
|
-Instead of returning actions from functions that expect them, you can just read and write to files directly using `io.open()`. This will trigger a resource reload that will clear undo history.
|
|
|
|
|
|
+Instead of returning actions from functions that expect them, you can just read and write to files directly using `io.open()`. This will trigger a resource reload that will clear undo history.
|
|
|
|
|
|
## Lifecycle hooks
|
|
## Lifecycle hooks
|
|
|
|
|
|
@@ -169,7 +169,7 @@ There is a specially treated editor script file: `hooks.editor_script`, located
|
|
```lua
|
|
```lua
|
|
local M = {}
|
|
local M = {}
|
|
|
|
|
|
-function M.on_build_started(opts)
|
|
|
|
|
|
+function M.on_build_started(opts)
|
|
local file = io.open("assets/build.json", "w")
|
|
local file = io.open("assets/build.json", "w")
|
|
file:write("{\"build_time\": \"".. os.date() .."\"}")
|
|
file:write("{\"build_time\": \"".. os.date() .."\"}")
|
|
file:close()
|
|
file:close()
|
|
@@ -201,4 +201,4 @@ Please note that lifecycle hooks currently are an editor-only feature, and they
|
|
|
|
|
|
You can publish libraries for other people to use that contain commands, and they will be automatically picked up by editor. Hooks, on the other hand, can't be picked up automatically, since they have to be defined in a file that is in a root folder of a project, but libraries expose only subfolders. This is intended to give more control over build process: you still can create lifecycle hooks as simple functions in `.lua` files, so users of your library can require and use them in their `/hooks.editor_script`.
|
|
You can publish libraries for other people to use that contain commands, and they will be automatically picked up by editor. Hooks, on the other hand, can't be picked up automatically, since they have to be defined in a file that is in a root folder of a project, but libraries expose only subfolders. This is intended to give more control over build process: you still can create lifecycle hooks as simple functions in `.lua` files, so users of your library can require and use them in their `/hooks.editor_script`.
|
|
|
|
|
|
-Also note that although dependencies are shown in Assets view, they do not exist as files (they are entries in a zip archive), so there is currently no easy way to execute a shell script you provide in a dependency. If you absolutely need it, you'll have to extract provided scripts by getting their text using `editor.get()` and then writing them somewhere with `file:write()`, for example in a `build/editor-scripts/your-extension-name` folder.
|
|
|
|
|
|
+Also note that although dependencies are shown in Assets view, they do not exist as files (they are entries in a zip archive), so there is currently no easy way to execute a shell script you provide in a dependency. If you absolutely need it, you'll have to extract provided scripts by getting their text using `editor.get()` and then writing them somewhere with `file:write()`, for example in a `build/editor-scripts/your-extension-name` folder.
|