1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-24 22:01:47 +03:00

add docs for ExecDomain

refs: https://github.com/wez/wezterm/issues/1776
This commit is contained in:
Wez Furlong 2022-07-08 23:25:42 -07:00
parent b103cc3ebb
commit 95229d3334
2 changed files with 207 additions and 0 deletions

View File

@ -182,6 +182,7 @@ TOC = [
"enum: KeyAssignment",
"config/lua/keyassignment",
),
Page("object: ExecDomain", "config/lua/ExecDomain.md"),
Page("object: LocalProcessInfo", "config/lua/LocalProcessInfo.md"),
Gen("object: MuxWindow", "config/lua/mux-window"),
Page("object: MuxTab", "config/lua/MuxTab.md"),

View File

@ -0,0 +1,206 @@
# ExecDomain
*Since: nightly builds only*
An `ExecDomain` defines a local-execution multiplexer domain. In simple terms,
rather than directly executing the requested program, an `ExecDomain` allows
you wrap up that command invocation by passing it through some other process.
For example, if you wanted to make it more convenient to work with tabs and
panes inside a docker container, you might want to define an `ExecDomain` that
causes the commands to be run via `docker exec`. While you could just ask
wezterm to explicitly spawn a command that runs `docker exec`, you would also
need to adjust the default key assignments for splitting panes to know about
that preference. Using an `ExecDomain` allows that preference to be associated
with the pane so that things work more intuitively.
## Defining an ExecDomain
You must use the `wezterm.exec_domain` function to define a domain. It accepts
the following parameters:
```
wezterm.exec_domain(NAME, FIXUP [, LABEL])
```
* *name* - uniquely identifies the domain. Must be different from any other multiplexer domains.
* *fixup* - a lua function that will be called to *fixup* the requested command and return the revised command
* *label* - optional. Can be either a string to serve as a label in the [Launcher Menu](../launch.md#the-launcher-menu), or a lua function that will return the label.
### fixup
The simplest fixup function looks like this:
```lua
function(cmd)
return cmd
end
```
The *cmd* parameter is a [SpawnCommand](SpawnCommand.md) that contains
information about the command that is to be executed. This will either be
something that the user configured as a key assignment or will be an equivalent
generated in response to a request to spawn a new tab or split a pane.
It is expected that your fixup function will adjust the various fields
of the provided command and then return it. The adjusted command is
what wezterm will execute in order to satisfy the user's request to
spawn a new program.
### label
The label is visible in the [Launcher Menu](../launch.md#the-launcher-menu).
You may set it a static string or set it to a lua callback. The default
behavior is equivalent to this callback function definition:
```lua
-- domain_name is the same name you used as the first parameter to
-- wezterm.exec_domain()
function(domain_name)
return domain_name
end
```
Using a callback function allows you to produce an amended label
just in time for the launcher menu to be rendered. That is useful
for example to adjust it to represent some status information.
If you were defining an ExecDomain for a docker container or
VM, then you could have the label reflect whether it is currently
running.
Both the static string and the generated string may include escape sequences
that affect the styling of the text. You may wish to use
[wezterm.format()](wezterm/format.md) to manage that.
## Example: Running commands in their own systemd scope
```lua
local wezterm = require 'wezterm'
-- Equivalent to POSIX basename(3)
-- Given "/foo/bar" returns "bar"
-- Given "c:\\foo\\bar" returns "bar"
local function basename(s)
return string.gsub(s, "(.*[/\\])(.*)", "%2")
end
return {
exec_domains = {
-- Defines a domain called "scoped" that will run the requested
-- command inside its own individual systemd scope.
-- This defines a strong boundary for resource control and can
-- help to avoid OOMs in one pane causing other panes to be
-- killed.
wezterm.exec_domain("scoped", function(cmd)
-- The "cmd" parameter is a SpawnCommand object.
-- You can log it to see what's inside:
wezterm.log_info(cmd)
-- Synthesize a human understandable scope name that is
-- (reasonably) unique. WEZTERM_PANE is the pane id that
-- will be used for the newly spawned pane.
-- WEZTERM_UNIX_SOCKET is associated with the wezterm
-- process id.
local env = cmd.set_environment_variables
local ident = "wezterm-pane-" .. env.WEZTERM_PANE .. "-on-" .. basename(env.WEZTERM_UNIX_SOCKET)
-- Generate a new argument array that will launch a
-- program via systemd-run
local wrapped = {
'/usr/bin/systemd-run',
'--user',
'--scope',
'--description=Shell started by wezterm',
'--same-dir',
'--collect',
'--unit=' .. ident,
}
-- Append the requested command
-- Note that cmd.args may be nil; that indicates that the
-- default program should be used. Here we're using the
-- shell defined by the SHELL environment variable.
for _, arg in ipairs(cmd.args or {os.getenv("SHELL")}) do
table.insert(wrapped, arg)
end
-- replace the requested argument array with our new one
cmd.args = wrapped
-- and return the SpawnCommand that we want to execute
return cmd
end),
},
-- Making the domain the default means that every pane/tab/window
-- spawned by wezterm will have its own scope
default_domain = "scoped",
}
```
## Example: docker domains
Fully working example is yet to be completely fleshed out (volunteers welcome!) but the
gist of it is:
```lua
local wezterm = require 'wezterm'
function docker_list()
-- Use wezterm.run_child_process to run
-- `docker container ls --format '{{.ID}}:{{.Names}}'` and parse
-- the output and return a mapping from ID -> name
end
function make_docker_fixup_func(id)
return function(cmd)
cmd.args = cmd.args or {"/bin/bash"}
local wrapped = {
"docker",
"exec",
"-it",
id,
}
for _, arg in ipairs(cmd.args) do
table.insert(wrapped, arg)
end
cmd.args = wrapped
return cmd
end
end
function make_docker_label_func(id)
return function(name)
-- TODO: query the container state and show info about
-- whether it is running or stopped.
-- If it stopped, you may wish to change the color to red
-- to make it stand out
return wezterm.format{
{Foreground={AnsiColor="Red"}},
{Text="docker container named " .. name}
}
end
end
local exec_domains = {}
for id, name in pairs(docker_list()) do
table.insert(exec_domains,
wezterm.exec_domain("docker: " .. name,
make_docker_fixup_func(id),
make_docker_label_func(id)
)
)
end
return {
exec_domains = exec_domains
}
```
With something like the config above, each time the config is reloaded, the
list of available domains will be updated.
Opening the launcher menu will show them and their status and allow you
to launch programs inside those containers.