WezTerm Lua API 详解:wezterm.mux.get_domain 域解析与 MuxDomain 对象实战
2026/9/14 19:30:24 网站建设 项目流程

WezTerm Lua API 详解:wezterm.mux.get_domain 域解析与 MuxDomain 对象实战

【免费下载链接】weztermA GPU-accelerated cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust项目地址: https://gitcode.com/GitHub_Trending/we/wezterm

本文围绕 WezTerm 的 Lua 配置接口wezterm.mux.get_domain(name_or_id)展开,讲解如何按名称、按数字 ID 或按默认域三种方式解析多路复用器(Mux)中的 domain,并进一步介绍返回值MuxDomain对象所提供的完整方法集。读完本文,你将掌握在配置脚本、keybinding 与事件回调中安全获取任意 domain、判断其状态并执行 attach/detach 等操作的完整实战方案,并能结合源码理解其底层解析逻辑。

函数签名与引入版本

wezterm.mux.get_domain(name_or_id)

该函数自20230320-124340-559cb7b0版本起随MuxDomain对象一同引入 Lua API。仓库变更日志中明确记载了这次暴露事件:mux: exposed MuxDomain to lua, along with wezterm.mux.get_domain()、wezterm.mux.all_domains() 和 wezterm.mux.set_default_domain()(见 docs/changelog.md 中对应版本条目)。

函数的作用是把传入的name_or_id解析(resolve)为对应的 domain,并返回一个表示该 domain 的 MuxDomain 对象。这里的 "domain" 是 WezTerm 多路复用架构中的核心抽象:它代表一个可承载窗格(pane)的运行域,本地 Shell、SSH 连接、TLS 多路复用远端、WSL 实例、串口设备等都以 domain 的形式被 Mux 统一管理。

参数 name_or_id 的四种合法取值

根据官方文档(docs/config/lua/wezterm.mux/get_domain.md),name_or_id可以接受以下四种形式:

取值含义结果
字符串(domain 名称)按名称解析 domain返回对应的MuxDomain对象
整数(domain id)按数字 ID 解析 domain返回对应的MuxDomain对象
nil或省略不传获取当前默认 domain返回默认 domain 的MuxDomain对象
其他 Lua 类型非法参数抛出 Lua 错误

如果传入的名称或 ID 未能映射到任何有效的 domain,函数会返回nil,而不会抛出异常。

从源码看四种分支的实现

这一行为与 Lua API 注册处的实现完全对应(见 lua-api-crates/mux/src/lib.rs):

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(), )), } })?, )?

从这段代码可以清晰看出其底层解析链路:

  • nil分支:直接调用mux.default_domain()取得当前默认 domain,再取其domain_id()包装成MuxDomain。由于default_domain在 Mux 中始终存在(首个注册的 domain 会被自动设为默认域),该分支理论上总是能返回有效对象。
  • 字符串分支:调用mux.get_domain_by_name(name)按名称查找。查找失败时 Rust 侧的Option::map会得到None,最终以Ok(None)返回给 Lua,即 Lua 侧得到nil
  • 整数分支:先把 Lua 整数通过TryInto::<DomainId>::try_into转换为内部DomainId类型,再调用mux.get_domain(id)按 ID 精确查找。ID 超出DomainId可表示范围等转换失败情况会抛出带invalid domain identifier passed to mux.get_domain前缀的错误。
  • 其他类型分支:布尔值、表、函数等任何其他类型都会直接触发 Lua 错误,错误信息同样以invalid domain identifier passed to mux.get_domain开头。

Mux 内部的两张查找表

名称解析与 ID 解析分别对应 Mux 内部维护的两张索引(见 mux/src/lib.rs):

pub fn default_domain(&self) -> Arc<dyn Domain> { self.default_domain.read().as_ref().map(Arc::clone).unwrap() } pub fn set_default_domain(&self, domain: &Arc<dyn Domain>) { *self.default_domain.write() = Some(Arc::clone(domain)); } pub fn get_domain(&self, id: DomainId) -> Option<Arc<dyn Domain>> { self.domains.read().get(&id).cloned() } pub fn get_domain_by_name(&self, name: &str) -> Option<Arc<dyn Domain>> { self.domains_by_name.read().get(name).cloned() }
  • domains:以DomainId为键的表,支撑按数字 ID 查找;
  • domains_by_name:以名称字符串为键的表,支撑按名称查找;
  • default_domain:保存当前默认 domain 的单独槽位。

当一个 domain 通过add_domain注册时,如果默认域尚未被设置,它会被自动设为默认域;之后即可通过wezterm.mux.set_default_domain()(见 docs/config/lua/wezterm.mux/set_default_domain.md)手动改写默认域。domain 名称在 Mux 中是唯一的——从配置层看,validate_domain_name还额外禁止把内置名称local重定义为自定义 domain(见 config/src/config.rs),这保证了两张查找表在插入时不会发生名称冲突。

返回值:MuxDomain 对象

成功解析后返回的MuxDomain是一个轻量句柄,其 Rust 侧定义为pub struct MuxDomain(pub DomainId)(见 lua-api-crates/mux/src/domain.rs),即内部只保存一个DomainId。每次调用方法时再通过resolve拿回真正的 domain 对象:

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))) }

该对象上注册了下列方法(官方文档见 docs/config/lua/MuxDomain/index.md):

方法返回说明
domain:domain_id()整数返回该 domain 的数字 ID
domain:name()字符串返回 domain 名称;名称全局唯一且在 domain 生命周期内固定(见 docs/config/lua/MuxDomain/name.md)
domain:label()字符串(异步)返回更适合展示的标签文本
domain:state()字符串返回"Attached""Detached",表示 domain 当前是否处于连接状态(见 docs/config/lua/MuxDomain/state.md)
domain:is_spawnable()布尔该 domain 当前是否可以在其中生成新的 pane
domain:attach(window?)异步将(已断开的)domain 重新连接;可传入一个MuxWindow以把新窗格关联到指定窗口
domain:detach()断开该 domain,其下所有 pane 将随之终止
domain:has_any_panes()布尔该 domain 下当前是否存在任何 pane

state()的取值与内部枚举DomainState::{Attached, Detached}一一对应;name()label()的区别在于:name 是唯一且固定的标识符,label 则是面向用户界面的可读展示文本(例如 SSH domain 可能显示连接地址)。

典型使用场景与代码示例

场景一:获取默认 domain

不传参数或显式传nil都能拿到当前默认 domain:

local default_domain = wezterm.mux.get_domain() -- 等价写法: -- local default_domain = wezterm.mux.get_domain(nil) wezterm.log_info("default domain id = " .. default_domain:domain_id()) wezterm.log_info("default domain name = " .. default_domain:name())

这在编写需要"落到当前活动域"的通用逻辑时非常实用,例如在按键绑定中动态生成新窗格时读取默认域的属性。

场景二:按名称解析

-- 假设配置中定义了名为 "myserver" 的 SSH domain local dom = wezterm.mux.get_domain("myserver") if dom == nil then wezterm.log_error("domain myserver not found") else wezterm.log_info("domain state: " .. dom:state()) if dom:state() == "Detached" then dom:attach() end end

注意名称解析失败时返回的是nil而非异常,因此必须先判空再使用方法。名称可以是local(内置本地 domain)、配置中声明的 SSH/TLS/Unix/WSL/串口 domain 名称,也可以是插件运行时注册的动态 domain(见 config/src/exec_domain.rs 中的ExecDomain及其fixup_command机制)。

场景三:按 ID 解析并与 all_domains 联动

wezterm.mux.get_domain与 wezterm.mux.all_domains() 通常成对使用:先用all_domains()枚举全部已知 domain,再按 ID 精确取回某个特定对象:

-- 打印所有 domain,并把第一个可 spawn 的 detached domain 重新连接 local domains = wezterm.mux.all_domains() for _, dom in ipairs(domains) do local id = dom:domain_id() local resolved = wezterm.mux.get_domain(id) wezterm.log_info(string.format("id=%d name=%s state=%s", id, resolved:name(), resolved:state())) if resolved:is_spawnable() and resolved:state() == "Detached" then resolved:attach() end end

错误处理与注意事项

  1. 返回nil不等于报错:名称或 ID 不存在时函数安静地返回nil,不会抛出 Lua 错误,务必对返回值判空。
  2. 非法类型会抛错:传入布尔、表、函数等其他 Lua 类型会直接产生运行时错误,错误消息为invalid domain identifier passed to mux.get_domain。因此在动态拼接参数时,建议先做类型检查或type()判断。
  3. attach是异步方法:Lua 侧对应domain:attach()需要配合异步上下文使用(例如在wezterm.on事件回调中调用);从源码看其实现是add_async_method(见 lua-api-crates/mux/src/domain.rs),内部await连接完成后才会返回。
  4. local是保留名称:配置中不能把自定义 domain 命名为local,因为它代表内置的本地域,这也意味着wezterm.mux.get_domain("local")永远指向内置本地域。
  5. domain 状态受生命周期影响detach之后其下 pane 会被终止,再次使用该MuxDomain对象调用需要解析的方法前,应先通过state()确认其仍处于"Attached"状态。

与其他 Mux API 的关系

wezterm.mux.get_domain只是 wezterm.mux 模块中的一员,它与其他函数共同构成完整的 domain 管理链路:

  • 枚举wezterm.mux.all_domains()返回全部 domain 的MuxDomain对象数组,是get_domain的主要数据来源之一;
  • 写入默认域wezterm.mux.set_default_domain(dom)可将某个已解析出的MuxDomain设为新的默认域,覆盖配置项default_domain以及在wezterm connectwezterm serial等启动方式下隐式产生的默认域(见 docs/config/lua/wezterm.mux/set_default_domain.md);
  • 域内对象wezterm.mux.get_pane()get_tab()get_window()spawn_window()负责在 domain 之上继续操作 pane、tab 与窗口层级。

实际使用时,典型的组合套路是:all_domains()(或get_domain)拿到目标 domain → 用name()/state()/is_spawnable()判断状态 → 必要时attach()/detach()管理连接 → 再用wezterm.mux.spawn_window{ domain = name }在该域中拉起新窗口(SpawnWindowdomain字段类型为SpawnTabDomain,见 lua-api-crates/mux/src/lib.rs)。

综上,wezterm.mux.get_domain是一个体积虽小却承担"域解析枢纽"作用的 API:它把名称、ID、默认域三种寻址方式统一收敛为MuxDomain对象,从而让 Lua 脚本可以在多路复用体系中对任何 domain 进行统一、安全的后续操作。

【免费下载链接】weztermA GPU-accelerated cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust项目地址: https://gitcode.com/GitHub_Trending/we/wezterm

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询