尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

WezTerm Lua API 详解:使用 `pane:get_logical_lines_as_text()` 获取逻辑行文本

WezTerm Lua API 详解:使用 `pane:get_logical_lines_as_text()` 获取逻辑行文本 WezTerm Lua API 详解使用pane:get_logical_lines_as_text()获取逻辑行文本【免费下载链接】weztermA GPU-accelerated cross-platform terminal emulator and multiplexer written by wez and implemented in Rust项目地址: https://gitcode.com/GitHub_Trending/we/weztermpane:get_logical_lines_as_text([nlines])是 WezTerm 终端仿真器提供的 Lua 面板PaneAPI用于把当前视口viewport内的文本按逻辑行还原成纯文本字符串。本文围绕该 API 的签名、返回值规则、源码级重排原理展开并结合get_dimensions()给出获取整个回滚缓冲区scrollback文本的实战方案。读完本文你将掌握逻辑行与物理行的区别、该 API 的边界行为尾随空格、空行剥离、超长行强制换行以及如何写出可靠的导出滚动区文本的 Lua 配置。逻辑行与物理行理解 API 的数据模型终端显示本质上是一个二维字符矩阵。当一行文本超过终端宽度时WezTerm 会把它自动折行到下一行以便放入显示矩阵。由此产生两种行概念物理行physical line终端显示矩阵中的一行可能是被折行后的片段也可能原本就是独立的一行。逻辑行logical line程序输出时的原始输入行即折行发生之前的完整文本。一个逻辑行可能跨越多个物理行。例如在终端里输入一段 200 个字符的长文本而窗口宽度只有 80 列那么这段文本会被切成 3 个物理行但逻辑上它仍然是 1 个逻辑行。直接按物理行复制会得到被硬切断的 3 段文本而按逻辑行获取则能得到完整的一段。文档明确说明WezTerm 并不存储逻辑行而是在需要时从物理行中保存的元数据即每行是否由上一行换行而来的续行标记重新计算还原。这一点在源码中得到了印证——mux/src/pane.rs的LogicalLine结构体由三部分组成pub struct LogicalLine { pub physical_lines: VecLine, // 组成该逻辑行的物理行列表 pub logical: Line, // 重排还原后的完整逻辑行 pub first_row: StableRowIndex, // 逻辑行起始的稳定行号 }这段结构mux/src/pane.rs清晰展示了逻辑行 多个物理行的拼接 还原后的完整行这一数据模型后续的impl_get_logical_lines_via_get_lines正是把若干物理行按续行标记合并、生成logical字段的过程。API 签名与参数说明pane:get_logical_lines_as_text([nlines])该 API 自版本20220101-133340-7edc5b5a起可用文档开头的since标记。返回值一个字符串包含视口内逻辑行文本的纯文本表示不含颜色或其他属性无转义序列。参数nlines可选指定要取回的行数。省略时默认取回视口高度即面板可视区域的行数指定时取回最近nlines行范围内的文本。不支持nlines参数的情况无。nlines是唯一的可选参数传入0或负值在语义上没有意义实际应传入正整数或省略。如果希望按物理行操作请使用姊妹 API pane:get_lines_as_text如果需要带转义序列颜色、样式等的输出可以参考 pane:get_lines_as_escapes。返回字符串的格式化规则文档对返回值给出了三条精确的格式化规则直接决定了解析结果逐行去除尾随空格每一行的尾部空格都会被移除因此返回文本不会因折行而残留右侧填充空格。以\n连接各行所有行拼接为一个字符串行与行之间以换行符分隔。剥离尾部空行末尾的空行会被去除因此当面板只有少量输出时返回的行数可能少于nlines预期值。这三条规则在 Lua 绑定源码 lua-api-crates/mux/src/pane.rs 中逐条体现methods.add_method(get_logical_lines_as_text, |_, this, nlines: Optionusize| { let mux get_mux()?; let pane this.resolve(mux)?; let dims pane.get_dimensions(); let nlines nlines.unwrap_or(dims.viewport_rows); let bottom_row dims.physical_top dims.viewport_rows as isize; let top_row bottom_row.saturating_sub(nlines as isize); let lines pane.get_logical_lines(top_row..bottom_row); let mut text String::new(); for line in lines { for cell in line.logical.visible_cells() { text.push_str(cell.str()); } let trimmed text.trim_end().len(); text.truncate(trimmed); text.push(\n); } let trimmed text.trim_end().len(); text.truncate(trimmed); Ok(text) });从实现可以确认几个关键事实nlines省略时使用dims.viewport_rows视口行数行范围的计算方式为bottom_row physical_top viewport_rows、top_row bottom_row - nlines使用saturating_sub防止下溢即从底部向上取 nlines 行每行遍历line.logical.visible_cells()提取可见单元格文本随后立即trim_end()去除该行尾随空格并补\n最终对整个字符串再次trim_end()实现剥离尾部空行。viewport_rows与scrollback_rows的定义可参见 pane:get_dimensions前者是可视区域的行数后者是滚动缓冲区与视口的总行数。核心应用获取整个回滚缓冲区的文本文档给出的标准用法是传入get_dimensions().scrollback_rows这样即可把滚动缓冲区 可视区域的全部文本一次性取回pane:get_logical_lines_as_text(pane:get_dimensions().scrollback_rows)pane:get_dimensions()返回一个包含scrollback_rows、viewport_rows、physical_top等字段的表其中scrollback_rows表示滚动缓冲区和视口中的总行数。将其作为nlines传入等价于告诉 API从最底部向上取全部行从而拿到完整回滚文本。适用场景程序输出的长行如 JSON、日志、SQL 结果被终端折行后逻辑行模式能还原出原始完整行非常适合日志导出、全文搜索、行级数据处理等场景。实战示例一键把整个回滚区发送到 vim下面这个完整的配置示例取自姊妹文档 pane:get_lines_as_text 的经典用例此处将其改造为使用逻辑行模式使折行后的长文本在 vim 中还原为完整行按下CTRLE时将当前面板的整个回滚缓冲区写入临时文件并在新窗口中用 vim 打开local wezterm require wezterm local io require io local os require os local act wezterm.action wezterm.on(trigger-vim-with-scrollback, function(window, pane) -- 以逻辑行模式取回整个回滚缓冲区文本折行长行会被还原为完整行 local text pane:get_logical_lines_as_text(pane:get_dimensions().scrollback_rows) -- 创建临时文件供 vim 读取 local name os.tmpname() local f io.open(name, w) f:write(text) f:flush() f:close() -- 在新窗口运行 vim 打开该文件 window:perform_action( act.SpawnCommandInNewWindow { args { vim, name }, }, pane ) -- 窗口创建与进程派生是异步的无法 await等待足够时间后再删除临时文件 wezterm.sleep_ms(1000) os.remove(name) end) return { keys { { key E, mods CTRL, action act.EmitEvent trigger-vim-with-scrollback, }, }, }说明wezterm.on(trigger-vim-with-scrollback, ...)注册事件回调window与pane是回调自动注入的两个参数pane:get_logical_lines_as_text(pane:get_dimensions().scrollback_rows)是全文取回的核心调用事件通过act.EmitEvent与按键绑定关联mods CTRL表示CtrlE组合键临时文件的清理是尽力而为的wezterm.sleep_ms(1000)后os.remove即使残留也不影响功能只是避免污染临时目录。源码深度逻辑行是如何被重新计算的文档提到WezTerm 不存储逻辑行但可以从物理行中保存的元数据重新计算。这一重排算法位于 mux/src/pane.rs 的impl_get_logical_lines_via_get_lines中整体分为三步向后回溯找逻辑行起点从目标范围的第一行起只要上一行的last_cell_was_wrapped()为真即该行是折行续行就继续向前并入直到遇到一个非续行行即逻辑行的真正开头。向前扩展找逻辑行终点从范围的最后一行起若其last_cell_was_wrapped()为真就继续取下一行并入直到遇到非续行行或行号不连续为止。合并成逻辑行遍历收集到的物理行对连续的续行通过append_line合并为一个LogicalLine并记录其first_row。其中Panetrait 的抽象方法定义在 mux/src/pane.rsfn get_logical_lines(self, lines: RangeStableRowIndex) - VecLogicalLine而 mux/src/termwiztermtab.rs 等实现类正是通过impl_get_logical_lines_via_get_lines复用了上述算法因此所有类型的面板本地终端、远程 mux 客户端等在逻辑行语义上保持一致。超长逻辑行的强制换行MAX_LOGICAL_LINE_LEN算法中有一个值得注意的常量——MAX_LOGICAL_LINE_LEN: usize 1024mux/src/pane.rs。文档明确说明了它的动机过长的逻辑行会被强制换行以约束在调整窗口大小resize和选择selection操作时重新换行的成本。也就是说如果某个逻辑行极其长例如 1.5MB 的 JSON 单行输出在初次写入时就会被强制折成多个物理行而在重排时一旦检测到候选物理行长度超过 1024就停止回溯/扩展避免解包 → 扫描 → 重新换行这一病态循环。注释原文也指出这是一个不完美的长度约束用于部分性地管控开销参见 mux/src/pane.rs。从源码结构看这意味着使用逻辑行模式时超长行超过约 1024 个字符的物理行片段可能不会被无限度地合并还原这是重排成本与还原完整性之间的工程权衡。逻辑行机制在 GUI 内部的典型用途逻辑行机制并不仅服务于 Lua API它在 WezTerm GUI 内部也被广泛复用可作为理解该 API 应用场景的旁证文本选择与复制wezterm-gui/src/termwindow/selection.rs 在渲染选区文本时调用pane.get_logical_lines(sel.rows())这正是跨行选中时复制出完整逻辑行的实现基础复制模式与快速选择wezterm-gui/src/overlay/copy.rs 与 wezterm-gui/src/overlay/quickselect.rs 同样依赖get_logical_lines处理选区文本。换句话说当你用鼠标选中一段折行文本并复制时得到的是完整逻辑行——与 Lua API 返回的语义完全一致。相关 API 对比与选型建议API行粒度输出形式典型用途pane:get_logical_lines_as_text([nlines])逻辑行还原折行纯文本无属性导出完整回滚、跨行文本处理pane:get_lines_as_text([nlines])物理行含折行片段纯文本无属性按显示行原样取文本如逐屏查看pane:get_lines_as_escapes([nlines])物理行含转义序列保留颜色/样式的高保真导出选型建议需要还原原始输出行如把终端内容送到编辑器、解析日志中的长 JSON→ 用get_logical_lines_as_text需要按屏幕显示逐行处理、或对返回行数有精确预期 → 用get_lines_as_text需要保留颜色与样式→ 用get_lines_as_escapes文档见此处。三个 API 的 Lua 绑定都位于 lua-api-crates/mux/src/pane.rs实现模式一致按nlines计算行范围、逐行取可见单元格、trim_end后以\n拼接、最后整体再裁剪一次。区别仅在于物理行直接取自pane.get_lines()而逻辑行经过pane.get_logical_lines()的重排还原。小结pane:get_logical_lines_as_text([nlines])是 WezTerm Lua 脚本中处理跨行文本的核心 API它以逻辑行为粒度返回去除颜色、修剪尾随空格、以\n连接、剥离尾部空行的纯文本。掌握其默认取视口行数、结合pane:get_dimensions().scrollback_rows可一次取回整个滚动区文本以及底层MAX_LOGICAL_LINE_LEN1024 字符带来的超长行强制折行限制你就能写出可预测、可维护的导出终端文本类配置脚本。【免费下载链接】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),仅供参考
返回列表