打开网易新闻 查看精彩图片

终端用户每天要在命令行里处理多少文本?Git提交记录、Kubernetes日志、系统手册——这些动辄几千行的输出,90%的人靠less硬撑。但一个写了8年终端工具(TUI,文本用户界面)的开发者发现:现有分页器对现代工作流的适配,像极了用算盘处理Excel。

他最终用Go写了一个叫lore的分页器,现在已经是日常主力。这篇文章是他做技术决策的完整复盘——不是造轮子的浪漫,而是被现实逼到墙角的务实选择。

传统分页器的核心假设是:用户只想"看"和"搜"。但现代终端工作流早就变了味。开发者现在要在日志里跳转到特定时间戳,在配置文件中折叠YAML层级,在错误堆栈里高亮特定关键词——这些动作在less里需要组合键打到手抽筋。

更隐蔽的问题是视觉反馈。less的搜索高亮是全局替换式的,一旦匹配项密集,屏幕会变成红绿灯现场。而终端本身的网格特性(固定行列、等宽字体)本可以支撑更精细的排版控制,却被 legacy 工具白白浪费。

作者之前做过两个TUI工具:kl用于Kubernetes日志,wander用于Nomad调度。两者都需要处理大段文本的交互导航,于是他抽离出一个可复用的viewport组件。这个组件成了lore的骨架——不是从零开始,而是从已有战场沉淀下来的武器。

终端分页器的隐形战场

终端分页器的隐形战场

打开网易新闻 查看精彩图片

要理解lore的设计选择,得先看清终端环境的特殊约束。

终端是网格系统:行列固定,字体等宽。文本填充这个网格时,ANSI转义码负责着色和样式——比如\x1b[31m开启红色前景,\x1b[0m重置。这意味着分页器不能简单地把文本当字符串处理,必须解析这些转义码,否则计算行宽时会错位,红色文字可能突然换行到下一屏。

另一个被忽视的变量是PAGER环境变量。Git、man等工具会检查它,如果设置就把输出管道进去。但这里有个微妙判断:如果stdout不是TTY(比如git diff | grep),就跳过分页器直接输出。很多自定义分页器没处理好这个逻辑,导致在脚本里卡住等用户输入。

lore的viewport组件选择直接处理这些脏活:维护一个虚拟缓冲区,跟踪ANSI状态机,在滚动时重新渲染可见区域。这比把转义码丢给终端模拟器自己解释要重,但换来了精确的像素级控制——比如知道某个关键词在第几行第几列,才能做局部高亮而不是全屏染色。

功能清单背后的取舍

功能清单背后的取舍

作者列出的需求清单很短,但每个都对应具体的使用场景:

鼠标支持不是锦上添花。在iTerm2或Alacritty里,用户已经习惯用滚轮翻页、用cmd+F搜索。如果分页器接管了屏幕却不响应鼠标事件,体验是断裂的。lore的做法是分层:鼠标滚轮触发viewport滚动,同时把点击事件暴露给上层应用——这样kl可以让用户点击某行日志直接跳转到相关Pod详情。

打开网易新闻 查看精彩图片

搜索需要上下文感知less/pattern是全局遍历,但日志场景里用户往往想"从当前位置向下找"或"只在这个折叠区块内匹配"。lore的搜索接口接受范围参数,让调用方决定搜索边界。这个设计牺牲了通用性,换来了场景适配的灵活性。

性能底线是16ms。60fps对应每帧16.6毫秒,这是交互工具的生死线。处理万行日志时, naive 的字符串分割和重新渲染会直接击穿这个预算。lore的优化策略是:只渲染可见区域,用环形缓冲区管理历史内容,ANSI解析结果缓存避免重复计算。这些不是炫技,是终端工具的基本礼仪。

从组件到产品的距离

从组件到产品的距离

viewport组件解决的是"怎么画",但lore作为独立工具还需要回答"怎么用"。

作者的选择是兼容less的核心按键绑定:j/k滚动,/搜索,q退出。这不是保守,是尊重肌肉记忆。但在这个基底上,lore加了几个现代快捷键:g跳转到行号(配合kl的"跳转到第N条日志"),zc折叠当前区块(针对JSON/YAML)。

一个有趣的细节是颜色主题。lore不强制配色方案,而是读取终端模拟器的调色板——在支持true color的终端里用24位色,在老终端里回退到256色或16色。这个适配逻辑写了将近200行,占代码量的15%,但作者认为值得:"终端工具的美学不是皮肤,是不要刺眼。"

现在lore已经是作者的默认PAGER。他用了一个很产品经理的验证标准:有没有某天忘记自己换过工具,自然地按了lore特有的快捷键?答案是第三周开始的某个下午,他试图在less里按g跳转行号,才意识到肌肉记忆已经完成了迁移。

这个工具没有GitHub星数截图,没有性能基准测试对比图。作者在最后留了一个开放的问题:当你每天重复某个操作超过20次,而现有工具让你感到"有点别扭"时,这个别扭的阈值是多少才值得动手造一个?他的答案是10年——但Git的历史只有19年,less已经38岁了。新一代开发者会等这么久吗,还是会在第3年就掀桌?