news 2026/9/10 23:57:28

WezTerm MuxDomain Lua API 完全指南:多路复用域的管理、连接与状态控制

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
WezTerm MuxDomain Lua API 完全指南:多路复用域的管理、连接与状态控制

WezTerm MuxDomain Lua API 完全指南:多路复用域的管理、连接与状态控制

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

MuxDomain是 WezTerm 通过多路复用器(mux)管理的域(domain)在 Lua 配置接口中的对象化表示,它让用户可以在gui-startup等事件中编程化地完成域连接、断开、状态查询与标签生成等操作。本文以 MuxDomain/index.markdown 为骨架,结合 lua-api-crates/mux/src/domain.rs 与 mux/src/domain.rs 中的实现,逐一讲解该对象提供的全部方法与底层原理,使读者能够编写可靠的多域启动与恢复脚本。

什么是 MuxDomain

MuxDomain代表一个由多路复用器(multiplexer)管理的域。在 WezTerm 的架构中,domain 是终端会话的容器单元:本地local域、通过 SSH 连接的远端域、串口对应的 serial 域,以及连接其他 WezTerm 实例(connect)形成的域,都属于 mux 管理的范畴。

该 Lua 对象的引入时间是 nightly 版本 20230320-124340-559cb7b0,即从此版本起,Lua 配置脚本可以使用MuxDomain的实例方法。

从源码看,MuxDomain在 Rust 层只是一个轻量句柄:它内部只保存一个DomainIdusize类型),并通过 resolve() 从全局Mux中按 id 查回真实的Arc<dyn Domain>再进行操作。也就是说,MuxDomain本身不持有域状态,真正的连接逻辑都定义在mux::domain::Domaintrait 上(见 mux/src/domain.rs)。

获取 MuxDomain 对象的途径

在调用本文介绍的实例方法之前,需要先拿到一个MuxDomain对象。主要有三种方式:

  • wezterm.mux.get_domain(nil | name | id)nil返回默认域;字符串按名称查找;整数按域 id 查找(见 wezterm.mux.get_domain() 与 lua-api-crates/mux/src/lib.rs);
  • wezterm.mux.all_domains():返回全部域的对象数组(见 wezterm.mux.all_domains());
  • wezterm.mux.default_domain():直接取得默认域对象。

其中mux.all_domains()的 Lua 绑定实现会对每个域执行iter_domains()并逐个封装为MuxDomain(dom.domain_id()),因此返回的是同一时刻所有已注册域的只读快照(见 lua-api-crates/mux/src/lib.rs)。

域的连接与断开:attach()detach()

domain:attach()

domain:attach()

尝试连接(attach)该域。连接一个域会将其远端系统中的窗口(windows)、标签页(tabs)和窗格(panes)导入到本地 GUI 中,这与 SSH 域、连接域的场景直接相关。

关键区别在于:与 AttachDomain 键位绑定不同,调用domain:attach()时,如果域中没有窗格,它不会隐式地新建一个窗格。这一点是为gui-startup事件(见 gui-startup)中的灵活使用而设计的——脚本可以在启动时先连接域,再通过has_any_panes()判断是否有既有窗格,再决定是否要额外 spawn 新的窗格。

如果域已经处于连接状态,再次调用attach()不会有任何副作用(幂等)。

从源码实现看,attach被注册为异步方法add_async_method),它会将可选的MuxWindow(窗口 id)透传给底层的domain.attach(window.map(|w| w.0)),并在失败时产生形如failed to attach domain <name>: <err>的 Lua 错误(见 lua-api-crates/mux/src/domain.rs)。底层 trait 的签名是async fn attach(&self, window_id: Option<WindowId>) -> anyhow::Result<()>(见 mux/src/domain.rs),意味着连接动作可能涉及网络往返与远端状态同步,在 Lua 中需要以异步方式等待完成。

domain:detach()

domain:detach()

尝试断开(detach)该域。断开会使域的窗口、标签页和窗格从本地 GUI 中移除,但不会关闭这些窗格——之后再次attach()时,它们仍然存在。这是多路复用器“断开不销毁”语义的核心体现。

需要注意:并非所有域都支持断开操作。对不支持的域调用detach()会向错误日志或调试浮层(debug overlay)记录错误。从 trait 定义看,Domain提供了fn detachable(&self) -> bool来声明某域是否支持 detach(见 mux/src/domain.rs),detach在 Lua 层是一个同步方法,底层实现失败时返回failed to detach domain <name>: <err>(见 lua-api-crates/mux/src/domain.rs)。

域的查询方法:状态、名称、标识与窗格

domain:state()

domain:state()

返回域当前是已连接还是未连接,结果为字符串:

  • "Attached"—— 域已连接;
  • "Detached"—— 域未连接。

该字符串由 Rust 侧对DomainState::Attached/DomainState::Detachedmatch直接映射得到(见 lua-api-crates/mux/src/domain.rs),而DomainState枚举本身就定义在 mux/src/domain.rs,包含DetachedAttached两个变体。可以用它做启动脚本的状态分支,例如仅在state() == "Detached"时才执行连接逻辑。

domain:name()

domain:name()

返回域名。域名是唯一的:任何两个域都不会重名,且名字在域的生命周期内保持不变。底层对应 trait 的fn domain_name(&self) -> &str,文档注释也明确要求它“应当是一个短标识符”(见 mux/src/domain.rs),因此可以放心地把name()当作域的稳定 key 来使用。

domain:domain_id()

domain:domain_id()

返回域的 id。底层就是直接返回MuxDomain内部保存的DomainId(见 lua-api-crates/mux/src/domain.rs),id 由alloc_domain_id()通过原子计数器分配(见 mux/src/domain.rs)。配合wezterm.mux.get_domain(id)可以在脚本中保存 id、稍后重新取回同一个域对象。

domain:has_any_panes()

domain:has_any_panes()

当 mux 中存在属于该域的任何窗格时返回true,否则返回false。实现上会遍历mux.iter_panes()并检查任一窗格的domain_id()是否与当前域一致(见 lua-api-crates/mux/src/domain.rs)。

官方文档特别指出,这个方法是“在连接域后决定是否要额外生成窗格”时的有力工具。结合attach()不会隐式 spawn 窗格的设计,常见的恢复场景就是:

local wezterm = require 'wezterm' local function attach_and_spawn(domain_name) local dom = wezterm.mux.get_domain(domain_name) if dom == nil then return end dom:attach() if not dom:has_any_panes() then -- 域里没有既有窗格,说明可能是全新域,spawn 一个初始窗格 wezterm.mux.spawn_window { workspace = { name = domain_name } } end end

domain:is_spawnable()

domain:is_spawnable()

如果该域永远无法生成新的窗格/标签页/窗口,则返回false,否则返回true。文档给出的典型例子是串口域(serial domain):串口设备只有一个会话,不能在其中再 spawn 新窗格。底层对应 trait 的fn spawnable(&self) -> bool,默认实现返回true,需要禁用的域会覆盖该方法(见 mux/src/domain.rs)。

域标签:domain:label()

domain:label()

计算一个描述域名与状态的标签(label),标签会随域状态的变化而改变——例如一个已连接的 SSH 域,其标签可能反映连接地址与状态信息,而断开后标签也会随之变化。底层调用 trait 的异步方法async fn domain_label(&self) -> String,默认实现仅返回域名本身,各具体域类型可以覆盖以返回更丰富的描述(见 mux/src/domain.rs 与 lua-api-crates/mux/src/domain.rs)。

label()name()的区别在于:name()是稳定唯一、生命周期内不变的标识符;label()是面向展示的、随状态变化的描述文本。需要稳定 key 时用name(),需要给人看的状态摘要时用label()

实战:在 gui-startup 中编排多域启动

将上述方法组合起来,就可以在gui-startup事件中实现一个完整的“多域恢复 + 按需建窗”流程,这也是attach()特意不隐式 spawn 窗格的设计初衷:

local wezterm = require 'wezterm' return { gui_startup = function() local mux = wezterm.mux -- 枚举所有已注册域,打印状态概览 for _, dom in ipairs(mux.all_domains()) do wezterm.log_info(string.format( 'domain: name=%s id=%s state=%s label=%s spawnable=%s has_panes=%s', dom:name(), dom:domain_id(), dom:state(), dom:label(), dom:is_spawnable(), dom:has_any_panes() )) end -- 只对未连接且支持 spawn 的域执行连接 local target = mux.get_domain('myserver') if target and target:state() == 'Detached' and target:is_spawnable() then target:attach() -- 域是空的,需要补一个初始窗格 if not target:has_any_panes() then mux.spawn_window {} end end end, }

这段脚本用到了本文介绍的全部方法:all_domains()枚举、name()/domain_id()做稳定标识、state()判断连接状态、label()生成展示文本、is_spawnable()排除不可 spawn 的域、attach()恢复会话、has_any_panes()决定是否补建窗格。错误处理方面,attach()失败会以 Lua 错误形式抛出,可在pcall中包裹以进行降级处理。

相关参考

  • 对象索引页:MuxDomain/index.markdown
  • 域注册与查询:wezterm.mux.get_domain()、wezterm.mux.all_domains()
  • 键位绑定中的连接方式:AttachDomain
  • 事件入口:gui-startup
  • Lua 绑定实现:lua-api-crates/mux/src/domain.rs
  • 底层 Domain trait 与状态定义:mux/src/domain.rs

【免费下载链接】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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 23:57:01

永磁同步电机无位置传感器控制:IF开环启动到SMO闭环的仿真与实现

简介&#xff1a;面向电机控制与嵌入式开发者的无传感器滑模观测器&#xff08;SMO&#xff09;完整实现资料&#xff0c;覆盖从Simulink建模仿真、代码生成到开发板实际运行的整个链路。内容按反电动势观测、LPF低通滤波、角度与速度计算、自适应滤波及角度补偿的顺序逐步展开…

作者头像 李华
网站建设 2026/9/10 23:54:32

生物医学SCI三区期刊投稿策略与高录用率期刊推荐

1. 生物医学领域投稿策略解析 在科研论文发表的道路上&#xff0c;选择合适的期刊往往是决定成败的关键一步。作为一名在生物医学领域发表过十余篇SCI论文的研究者&#xff0c;我深知投稿过程中的焦虑与期待。今天我要分享的这个期刊选择策略&#xff0c;可能会颠覆你对SCI期刊…

作者头像 李华