WezTerm Lua API 实战:wezterm.mux.all_windows() 遍历与管理多路复用窗口
【免费下载链接】weztermA GPU-accelerated cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust项目地址: https://gitcode.com/GitHub_Trending/we/wezterm
导读
wezterm.mux.all_windows()是 WezTerm 多路复用层(mux)暴露给 Lua 配置的核心 API 之一,用于一次性获取当前会话中所有已知的 MuxWindow 对象。它常被用于启动脚本(gui-startup/gui-attached事件)或键盘快捷键处理器中,实现批量操作窗口——例如启动时最大化所有窗口、统一设置窗口标题、按工作区(workspace)筛选窗口并施加布局。读完本文,你将掌握该 API 的返回值结构、底层实现原理,以及结合MuxWindow方法、workspace 机制编写实战配置的能力。
一、函数签名与基本语义
wezterm.mux.all_windows()于版本20220807-113146-c2fee766引入,其签名与用途如下:
wezterm.mux.all_windows()返回值:一个数组表(array table),其中每个元素都是一个MuxWindow对象,代表多路复用器当前已知的每一个窗口。窗口的列举不区分所在 workspace——无论窗口属于默认工作区还是自定义工作区,都会出现在返回表中。文档原文定义见 all_windows.md,对象类型定义见 MuxWindow 对象。
在使用前,需要在配置文件中取得mux模块的引用,惯用写法与 wezterm.mux 模块说明 中给出的一致:
local wezterm = require 'wezterm' local mux = wezterm.mux随后即可在事件回调、快捷键处理函数等任何合适的作用域中调用:
local windows = mux.all_windows() for _, window in ipairs(windows) do print('found window: ' .. window:window_id()) end二、源码级解析:从 Lua 调用到 Mux 核心
all_windows的 Lua 绑定实现在 lua-api-crates/mux/src/lib.rs,这段 Rust 代码完整展示了"Lua 表 ← Rust 向量 ← 全局 Mux 注册表"的数据流:
mux_mod.set( "all_windows", lua.create_function(|_, _: ()| { let mux = get_mux()?; Ok(mux .iter_windows() .into_iter() .map(MuxWindow) .collect::<Vec<MuxWindow>>()) })?, )?;其执行步骤可以拆解为:
- 通过
Mux::try_get()(即get_mux())拿到全局唯一的多路复用器句柄;若当前进程没有可用的 Mux 实例,则直接返回 Lua 错误cannot get Mux!?——这提示我们,该 API 只在 WezTerm 运行时环境中可用,脱离终端进程的纯脚本环境无法调用。 - 调用
mux.iter_windows()获取全部窗口 ID 列表。 - 将每个
WindowId包装为MuxWindow(window_id)结构体,收集成Vec<MuxWindow>,最后由 mlua 自动转换为 Lua 数组表返回。
底层的iter_windows()定义在 mux/src/lib.rs,它是对 Mux 内部windows哈希表键集合的一次只读快照:
pub fn iter_windows(&self) -> Vec<WindowId> { self.windows.read().keys().cloned().collect() }值得注意的是MuxWindow是#[derive(Clone, Copy, Debug)]的轻量包装类型(见 lua-api-crates/mux/src/window.rs),本身只携带WindowId,真正的Window数据仍保存在 Mux 中。因此all_windows()返回的对象在 Lua 侧是"句柄"而非"快照副本"——你拿到的是指向多路复用器内实际窗口的引用,后续调用其方法时,仍会实时解析到最新的窗口状态(例如活跃标签页的变化)。
三、理解返回对象:MuxWindow 的核心方法
all_windows()的价值体现在返回的MuxWindow对象上。在 lua-api-crates/mux/src/window.rs 中,该对象通过UserDatatrait 注册了以下方法,实战中常用:
| 方法 | 类型 | 说明 |
|---|---|---|
window:window_id() | 同步 | 返回窗口的数字 ID(即WindowId) |
window:get_workspace() | 同步 | 返回该窗口所属 workspace 的名称 |
window:set_workspace(name) | 同步 | 将窗口移动到指定 workspace |
window:get_title()/window:set_title(title) | 同步 | 读取 / 设置窗口标题 |
window:tabs() | 同步 | 返回该窗口内的MuxTab对象数组 |
window:tabs_with_info() | 同步 | 返回带index、is_active等信息的标签页表 |
window:active_tab() | 同步 | 返回当前活跃标签页的MuxTab,无则返回 nil |
window:active_pane() | 同步 | 返回当前活跃窗格的MuxPane,无则返回 nil |
window:spawn_tab(...) | 异步 | 在该窗口中创建新标签页 |
window:gui_window() | 异步 | 获取对应的 GUI 窗口对象(GuiWindow),进而可调用maximize()、set_position()等图形层方法 |
其中gui_window()的实现采用运行时模块解析——mux crate 不直接依赖 wezterm-gui,而是通过 Lua 模块wezterm.gui.gui_window_for_mux_window间接调用(见 lua-api-crates/mux/src/window.rs),这也是window:gui_window()被标记为 async 方法、在纯 headless 的 mux-server 进程中不可用的原因。如果要在无 GUI 的复用器上下文中获取窗口信息,应优先使用get_title()、tabs()等方法。
四、实战示例
4.1 启动时最大化所有窗口
all_windows()最典型的应用是配合gui-attached事件,在 GUI 启动后批量调整窗口。完整可运行的配置示例见 gui-attached 事件文档:
local wezterm = require 'wezterm' local mux = wezterm.mux wezterm.on('gui-attached', function(domain) -- 启动时将当前 workspace 的所有窗口最大化 local workspace = mux.get_active_workspace() for _, window in ipairs(mux.all_windows()) do if window:get_workspace() == workspace then window:gui_window():maximize() end end end) local config = wezterm.config_builder() return config这个例子展示了all_windows()与 workspace 过滤的经典组合:mux.get_active_workspace()拿到当前工作区名称,遍历全部窗口后用window:get_workspace()比对筛选,只对属于当前工作区的窗口调用gui_window():maximize()。
4.2 在 gui-startup 中批量设置窗口标题
gui-startup事件是另一个适合使用all_windows()的入口(参见 gui-startup 事件文档)。例如遍历所有窗口并统一设置标题:
local wezterm = require 'wezterm' local mux = wezterm.mux wezterm.on('gui-startup', function(cmd) local windows = mux.all_windows() for _, window in ipairs(windows) do if window:get_title() == '' then window:set_title('wezterm') end end end)4.3 按工作区统计与操作窗口
结合 workspace 相关 API(mux.get_workspace_names()、mux.get_active_workspace()、mux.set_active_workspace(),分别见 get_workspace_names.md、get_active_workspace.md),可以实现跨工作区的批量管理,例如将某个工作区下的所有窗口移动合并:
local function merge_workspace_into(target) for _, window in ipairs(mux.all_windows()) do if window:get_workspace() ~= target then window:set_workspace(target) end end end4.4 与其他 mux 查询 API 配合
all_windows()与mux.get_window(window_id)是互补的两种取窗口方式:前者做全量遍历,后者按 ID 精确取用(见 get_window.md)。例如来自wezterm cli list或其他外部来源的窗口 ID,可以直接用get_window解析为对象再调用相同的方法集:
local win = mux.get_window(win_id_from_cli) if win then print('title: ' .. win:get_title()) end五、重要注意事项
不要在配置文件顶层作用域调用会创建新 split / tab / window 的 mux 函数。配置文件可能在多种上下文中被多次求值,顶层副作用会导致重复创建。如需在启动时生成窗口,务必把逻辑放进
gui-startup(GUI 启动后触发)或mux-startup(无 GUI 复用器启动后触发)事件回调中。all_windows()本身是只读查询,在顶层调用虽不产生副作用,但最佳实践仍是在事件回调或快捷键处理函数中使用。GUI 相关方法有运行环境限制。
window:gui_window()依赖运行时解析 GUI 模块,在 headless 的 mux-server 或纯 CLI 上下文中不可用;此时应改用get_title()、get_workspace()、tabs()等不依赖图形栈的方法。这从侧面印证了 wezterm.mux 模块说明 中"复用器可能未连接 GUI,某些需要窗口管理系统才能执行的操作不会出现在该模块接口中"的约束。返回表是运行时快照。
all_windows()在调用瞬间对 Mux 的窗口注册表做一次收集,之后新建或关闭窗口不会自动反映到已有的 Lua 表变量中;如需最新状态,应在事件发生时重新调用。与
quit_when_all_windows_are_closed的联动:WezTerm 提供quit_when_all_windows_are_closed = true配置(见 quit_when_all_windows_are_closed.md),控制所有窗口关闭后是否退出进程。结合all_windows()可以在窗口层面自主决定程序的存续逻辑,实现更精细的窗口生命周期管理。
六、相关 API 速查
- wezterm.mux.all_domains():返回所有 mux domain
- wezterm.mux.get_window(WINDOW_ID):按 ID 获取单个窗口
- wezterm.mux.get_tab(TAB_ID) / wezterm.mux.get_pane(PANE_ID):按 ID 获取标签页 / 窗格
- MuxWindow 对象完整方法列表
- gui-attached 事件 / gui-startup 事件:
all_windows()的主要挂载点
【免费下载链接】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),仅供参考