mirror of
https://github.com/wez/wezterm.git
synced 2024-11-22 22:42:48 +03:00
expose some mux domain stuff to lua
refs: https://github.com/wez/wezterm/issues/2933
This commit is contained in:
parent
d34297cd2c
commit
37055d2fab
1
.gitignore
vendored
1
.gitignore
vendored
@ -22,6 +22,7 @@ dhat-heap.json
|
|||||||
/docs/config/lua/keyassignment/CopyMode/index.md
|
/docs/config/lua/keyassignment/CopyMode/index.md
|
||||||
/docs/config/lua/mux-events/index.md
|
/docs/config/lua/mux-events/index.md
|
||||||
/docs/config/lua/mux-window/index.md
|
/docs/config/lua/mux-window/index.md
|
||||||
|
/docs/config/lua/MuxDomain/index.md
|
||||||
/docs/config/lua/MuxTab/index.md
|
/docs/config/lua/MuxTab/index.md
|
||||||
/docs/config/lua/MuxPane/index.md
|
/docs/config/lua/MuxPane/index.md
|
||||||
/docs/config/lua/pane/index.md
|
/docs/config/lua/pane/index.md
|
||||||
|
@ -391,6 +391,7 @@ TOC = [
|
|||||||
Gen("object: Color", "config/lua/color"),
|
Gen("object: Color", "config/lua/color"),
|
||||||
Page("object: ExecDomain", "config/lua/ExecDomain.md"),
|
Page("object: ExecDomain", "config/lua/ExecDomain.md"),
|
||||||
Page("object: LocalProcessInfo", "config/lua/LocalProcessInfo.md"),
|
Page("object: LocalProcessInfo", "config/lua/LocalProcessInfo.md"),
|
||||||
|
Gen("object: MuxDomain", "config/lua/MuxDomain"),
|
||||||
Gen("object: MuxWindow", "config/lua/mux-window"),
|
Gen("object: MuxWindow", "config/lua/mux-window"),
|
||||||
Gen("object: MuxTab", "config/lua/MuxTab"),
|
Gen("object: MuxTab", "config/lua/MuxTab"),
|
||||||
Page("object: PaneInformation", "config/lua/PaneInformation.md"),
|
Page("object: PaneInformation", "config/lua/PaneInformation.md"),
|
||||||
|
@ -21,6 +21,10 @@ As features stabilize some brief notes about them will accumulate here.
|
|||||||
[#2741](https://github.com/wez/wezterm/issues/2741)
|
[#2741](https://github.com/wez/wezterm/issues/2741)
|
||||||
* macOS: initial cut at macOS native menu bar
|
* macOS: initial cut at macOS native menu bar
|
||||||
[#1485](https://github.com/wez/wezterm/issues/1485)
|
[#1485](https://github.com/wez/wezterm/issues/1485)
|
||||||
|
* mux: exposed [MuxDomain](config/lua/MuxDomain/index.md) to lua, along with
|
||||||
|
[wezterm.mux.get_domain()](config/lua/wezterm.mux/get_domain.md),
|
||||||
|
[wezterm.mux.all_domains()](config/lua/wezterm.mux/all_domains.md) and
|
||||||
|
[wezterm.mux.set_default_domain()](config/lua/wezterm.mux/set_default_domain.md).
|
||||||
|
|
||||||
#### Fixed
|
#### Fixed
|
||||||
* X11: hanging or killing the IME could hang wezterm
|
* X11: hanging or killing the IME could hang wezterm
|
||||||
|
17
docs/config/lua/MuxDomain/attach.md
Normal file
17
docs/config/lua/MuxDomain/attach.md
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# `domain:attach()`
|
||||||
|
|
||||||
|
*Since: nightly builds only*
|
||||||
|
|
||||||
|
Attempts to attach the domain.
|
||||||
|
|
||||||
|
Attaching a domain will attempt to import the windows, tabs and panes from the
|
||||||
|
remote system into those of the local GUI.
|
||||||
|
|
||||||
|
Unlike the [AttachDomain](../keyassignment/AttachDomain.md) key assignment,
|
||||||
|
calling `domain:attach()` will *not* implicitly spawn a new pane into the
|
||||||
|
domain if the domain contains no panes. This is to provide flexibility when
|
||||||
|
used in the [gui-startup](../gui-events/gui-startup.md) event.
|
||||||
|
|
||||||
|
If the domain is already attached, calling this method again has no effect.
|
||||||
|
|
||||||
|
See also: [domain:detach()](detach.md) and [domain:state()](state.md).
|
12
docs/config/lua/MuxDomain/detach.md
Normal file
12
docs/config/lua/MuxDomain/detach.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# `domain:detach()`
|
||||||
|
|
||||||
|
*Since: nightly builds only*
|
||||||
|
|
||||||
|
Attempts to detach the domain.
|
||||||
|
|
||||||
|
Detaching a domain causes it to disconnect and remove its set of windows, tabs
|
||||||
|
and panes from the local GUI. Detaching does not cause those panes to close; if
|
||||||
|
or when you later attach to the domain, they'll still be there.
|
||||||
|
|
||||||
|
Not every domain supports detaching, and will log an error to the error
|
||||||
|
log/debug overlay.
|
6
docs/config/lua/MuxDomain/domain_id.md
Normal file
6
docs/config/lua/MuxDomain/domain_id.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# `domain:domain_id()`
|
||||||
|
|
||||||
|
*Since: nightly builds only*
|
||||||
|
|
||||||
|
Returns the domain id.
|
||||||
|
|
9
docs/config/lua/MuxDomain/has_any_panes.md
Normal file
9
docs/config/lua/MuxDomain/has_any_panes.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# `domain:has_any_panes()`
|
||||||
|
|
||||||
|
*Since: nightly builds only*
|
||||||
|
|
||||||
|
Returns `true` if the mux has any panes that belong to this domain.
|
||||||
|
|
||||||
|
This can be useful when deciding whether to spawn additional panes after
|
||||||
|
attaching to a domain.
|
||||||
|
|
8
docs/config/lua/MuxDomain/index.markdown
Normal file
8
docs/config/lua/MuxDomain/index.markdown
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# MuxDomain
|
||||||
|
|
||||||
|
*Since: nightly builds only*
|
||||||
|
|
||||||
|
`MuxDomain` represents a domain that is managed by the multiplexer.
|
||||||
|
|
||||||
|
It has the following methods:
|
||||||
|
|
9
docs/config/lua/MuxDomain/is_spawnable.md
Normal file
9
docs/config/lua/MuxDomain/is_spawnable.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# `domain:is_spawnable()`
|
||||||
|
|
||||||
|
*Since: nightly builds only*
|
||||||
|
|
||||||
|
Returns `false` if this domain will never be able to spawn a new pane/tab/window, `true` otherwise.
|
||||||
|
|
||||||
|
Serial ports are represented by a serial domain that is not spawnable.
|
||||||
|
|
||||||
|
|
9
docs/config/lua/MuxDomain/label.md
Normal file
9
docs/config/lua/MuxDomain/label.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# `domain:label()`
|
||||||
|
|
||||||
|
*Since: nightly builds only*
|
||||||
|
|
||||||
|
Computes a label describing the name and state of the domain.
|
||||||
|
The label can change depending on the state of the domain.
|
||||||
|
|
||||||
|
See also: [domain:name()](name.md).
|
||||||
|
|
8
docs/config/lua/MuxDomain/name.md
Normal file
8
docs/config/lua/MuxDomain/name.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# `domain:name()`
|
||||||
|
|
||||||
|
*Since: nightly builds only*
|
||||||
|
|
||||||
|
Returns the name of the domain. Domain names are unique; no two domains can
|
||||||
|
have the same name, and the name is fixed for the lifetime of the domain.
|
||||||
|
|
||||||
|
See also: [domain:label()](label.md).
|
10
docs/config/lua/MuxDomain/state.md
Normal file
10
docs/config/lua/MuxDomain/state.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# `domain:state()`
|
||||||
|
|
||||||
|
*Since: nightly builds only*
|
||||||
|
|
||||||
|
Returns whether the domain is attached or not. The result is a string that is either:
|
||||||
|
|
||||||
|
* `"Attached"` - the domain is attached
|
||||||
|
* `"Detached"` - the domain is not attached
|
||||||
|
|
||||||
|
See also: [domain:detach()](detach.md) and [domain:detach()](detach.md).
|
6
docs/config/lua/wezterm.mux/all_domains.md
Normal file
6
docs/config/lua/wezterm.mux/all_domains.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# `wezterm.mux.all_domains()`
|
||||||
|
|
||||||
|
*Since: nightly builds only*
|
||||||
|
|
||||||
|
Returns an array table holding all of the known
|
||||||
|
[MuxDomain](../MuxDomain/index.md) objects.
|
16
docs/config/lua/wezterm.mux/get_domain.md
Normal file
16
docs/config/lua/wezterm.mux/get_domain.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# `wezterm.mux.get_domain(name_or_id)`
|
||||||
|
|
||||||
|
*Since: nightly builds only*
|
||||||
|
|
||||||
|
Resolves `name_or_id` to a domain and returns a
|
||||||
|
[MuxDomain](../MuxDomain/index.md) object representation of it.
|
||||||
|
|
||||||
|
`name_or_id` can be:
|
||||||
|
|
||||||
|
* A domain name string to resolve the domain by name
|
||||||
|
* A domain id to resolve the domain by id
|
||||||
|
* `nil` or omitted to return the current default domain
|
||||||
|
* other lua types will generate a lua error
|
||||||
|
|
||||||
|
If the name or id don't map to a valid domain, this function will return `nil`.
|
||||||
|
|
10
docs/config/lua/wezterm.mux/set_default_domain.md
Normal file
10
docs/config/lua/wezterm.mux/set_default_domain.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# `wezterm.mux.set_default_domain(MuxDomain)`
|
||||||
|
|
||||||
|
*Since: nightly builds only*
|
||||||
|
|
||||||
|
Assign a new default domain in the mux.
|
||||||
|
|
||||||
|
The domain that you assign here will override any configured
|
||||||
|
[default_domain](../config/default_domain.md) or the implicit assignment of the
|
||||||
|
default domain that may have happened as a result of starting wezterm via
|
||||||
|
`wezterm connect` or `wezterm serial`.
|
83
lua-api-crates/mux/src/domain.rs
Normal file
83
lua-api-crates/mux/src/domain.rs
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
use super::*;
|
||||||
|
use mux::domain::{Domain, DomainId, DomainState};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub struct MuxDomain(pub DomainId);
|
||||||
|
|
||||||
|
impl MuxDomain {
|
||||||
|
pub fn resolve<'a>(&self, mux: &'a Arc<Mux>) -> mlua::Result<Arc<dyn Domain>> {
|
||||||
|
mux.get_domain(self.0)
|
||||||
|
.ok_or_else(|| mlua::Error::external(format!("domain id {} not found in mux", self.0)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UserData for MuxDomain {
|
||||||
|
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||||
|
methods.add_meta_method(mlua::MetaMethod::ToString, |_, this, _: ()| {
|
||||||
|
Ok(format!("MuxDomain(pane_id:{}, pid:{})", this.0, unsafe {
|
||||||
|
libc::getpid()
|
||||||
|
}))
|
||||||
|
});
|
||||||
|
methods.add_method("domain_id", |_, this, _: ()| Ok(this.0));
|
||||||
|
|
||||||
|
methods.add_method("is_spawnable", |_, this, _: ()| {
|
||||||
|
let mux = get_mux()?;
|
||||||
|
let domain = this.resolve(&mux)?;
|
||||||
|
Ok(domain.spawnable())
|
||||||
|
});
|
||||||
|
|
||||||
|
methods.add_async_method("attach", |_, this, window: Option<MuxWindow>| async move {
|
||||||
|
let mux = get_mux()?;
|
||||||
|
let domain = this.resolve(&mux)?;
|
||||||
|
domain.attach(window.map(|w| w.0)).await.map_err(|err| {
|
||||||
|
mlua::Error::external(format!(
|
||||||
|
"failed to attach domain {}: {err:#}",
|
||||||
|
domain.domain_name()
|
||||||
|
))
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
methods.add_method("detach", |_, this, _: ()| {
|
||||||
|
let mux = get_mux()?;
|
||||||
|
let domain = this.resolve(&mux)?;
|
||||||
|
domain.detach().map_err(|err| {
|
||||||
|
mlua::Error::external(format!(
|
||||||
|
"failed to detach domain {}: {err:#}",
|
||||||
|
domain.domain_name()
|
||||||
|
))
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
methods.add_method("state", |_, this, _: ()| {
|
||||||
|
let mux = get_mux()?;
|
||||||
|
let domain = this.resolve(&mux)?;
|
||||||
|
Ok(match domain.state() {
|
||||||
|
DomainState::Attached => "Attached",
|
||||||
|
DomainState::Detached => "Detached",
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
methods.add_method("name", |_, this, _: ()| {
|
||||||
|
let mux = get_mux()?;
|
||||||
|
let domain = this.resolve(&mux)?;
|
||||||
|
Ok(domain.domain_name().to_string())
|
||||||
|
});
|
||||||
|
|
||||||
|
methods.add_async_method("label", |_, this, _: ()| async move {
|
||||||
|
let mux = get_mux()?;
|
||||||
|
let domain = this.resolve(&mux)?;
|
||||||
|
Ok(domain.domain_label().await)
|
||||||
|
});
|
||||||
|
|
||||||
|
methods.add_method("has_any_panes", |_, this, _: ()| {
|
||||||
|
let mux = get_mux()?;
|
||||||
|
let domain = this.resolve(&mux)?;
|
||||||
|
let have_panes_in_domain = mux
|
||||||
|
.iter_panes()
|
||||||
|
.iter()
|
||||||
|
.any(|p| p.domain_id() == domain.domain_id());
|
||||||
|
Ok(have_panes_in_domain)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,7 @@ use config::keyassignment::SpawnTabDomain;
|
|||||||
use config::lua::mlua::{self, Lua, UserData, UserDataMethods, Value as LuaValue};
|
use config::lua::mlua::{self, Lua, UserData, UserDataMethods, Value as LuaValue};
|
||||||
use config::lua::{get_or_create_module, get_or_create_sub_module};
|
use config::lua::{get_or_create_module, get_or_create_sub_module};
|
||||||
use luahelper::impl_lua_conversion_dynamic;
|
use luahelper::impl_lua_conversion_dynamic;
|
||||||
use mux::domain::SplitSource;
|
use mux::domain::{DomainId, SplitSource};
|
||||||
use mux::pane::{Pane, PaneId};
|
use mux::pane::{Pane, PaneId};
|
||||||
use mux::tab::{SplitDirection, SplitRequest, SplitSize, Tab, TabId};
|
use mux::tab::{SplitDirection, SplitRequest, SplitSize, Tab, TabId};
|
||||||
use mux::window::{Window, WindowId};
|
use mux::window::{Window, WindowId};
|
||||||
@ -13,10 +13,12 @@ use std::sync::Arc;
|
|||||||
use wezterm_dynamic::{FromDynamic, ToDynamic};
|
use wezterm_dynamic::{FromDynamic, ToDynamic};
|
||||||
use wezterm_term::TerminalSize;
|
use wezterm_term::TerminalSize;
|
||||||
|
|
||||||
|
mod domain;
|
||||||
mod pane;
|
mod pane;
|
||||||
mod tab;
|
mod tab;
|
||||||
mod window;
|
mod window;
|
||||||
|
|
||||||
|
pub use domain::MuxDomain;
|
||||||
pub use pane::MuxPane;
|
pub use pane::MuxPane;
|
||||||
pub use tab::MuxTab;
|
pub use tab::MuxTab;
|
||||||
pub use window::MuxWindow;
|
pub use window::MuxWindow;
|
||||||
@ -107,6 +109,55 @@ pub fn register(lua: &Lua) -> anyhow::Result<()> {
|
|||||||
})?,
|
})?,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
mux_mod.set(
|
||||||
|
"get_domain",
|
||||||
|
lua.create_function(|_, domain: LuaValue| {
|
||||||
|
let mux = get_mux()?;
|
||||||
|
match domain {
|
||||||
|
LuaValue::Nil => Ok(Some(MuxDomain(mux.default_domain().domain_id()))),
|
||||||
|
LuaValue::String(s) => match s.to_str() {
|
||||||
|
Ok(name) => Ok(mux
|
||||||
|
.get_domain_by_name(name)
|
||||||
|
.map(|dom| MuxDomain(dom.domain_id()))),
|
||||||
|
Err(err) => Err(mlua::Error::external(format!(
|
||||||
|
"invalid domain identifier passed to mux.get_domain: {err:#}"
|
||||||
|
))),
|
||||||
|
},
|
||||||
|
LuaValue::Integer(id) => match TryInto::<DomainId>::try_into(id) {
|
||||||
|
Ok(id) => Ok(mux.get_domain(id).map(|dom| MuxDomain(dom.domain_id()))),
|
||||||
|
Err(err) => Err(mlua::Error::external(format!(
|
||||||
|
"invalid domain identifier passed to mux.get_domain: {err:#}"
|
||||||
|
))),
|
||||||
|
},
|
||||||
|
_ => Err(mlua::Error::external(
|
||||||
|
"invalid domain identifier passed to mux.get_domain".to_string(),
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
})?,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
mux_mod.set(
|
||||||
|
"all_domains",
|
||||||
|
lua.create_function(|_, _: ()| {
|
||||||
|
let mux = get_mux()?;
|
||||||
|
Ok(mux
|
||||||
|
.iter_domains()
|
||||||
|
.into_iter()
|
||||||
|
.map(|dom| MuxDomain(dom.domain_id()))
|
||||||
|
.collect::<Vec<MuxDomain>>())
|
||||||
|
})?,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
mux_mod.set(
|
||||||
|
"set_default_domain",
|
||||||
|
lua.create_function(|_, domain: MuxDomain| {
|
||||||
|
let mux = get_mux()?;
|
||||||
|
let domain = domain.resolve(&mux)?;
|
||||||
|
mux.set_default_domain(&domain);
|
||||||
|
Ok(())
|
||||||
|
})?,
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user