如果我想使用漂亮的打印库来添加颜色,我如何 "refresh" 终端输出的最后一行?

How can I "refresh" the last line of output in terminal, if I want to use a pretty-printing library to add colours?

有一个程序通过重复覆盖stderr中的最后一行文本来与用户交互。完成方式如下:

这很好用。 (虽然我个人没有在通常的 Linux 终端以外的环境下测试它。)

我着手改进这个程序,将普通的 String 替换为 ansi-wl-pprint 中的 Doc 类型,这样我就可以用颜色来绘制文本,就像最近的GHC体育。像这样的库可能有点矫枉过正,因为我只需要一次输出几行,而且没有任何缩进,但我想尝试一下它的抽象着色功能。但是,我认为这个库(或任何漂亮的打印库)不会具有旨在擦除以前打印的 Docs.

的功能

我想到的一个解决方案是将 Doc 渲染为 String 并测量其长度。但是,我将不得不为颜色代码打折;此外,这总体上是对库提供的抽象的入侵:具体来说,我将不得不依赖这样的假设,即我手动进行的渲染将匹配 hPutDoc.

隐式完成的渲染。

我是否应该完全放弃库并继续处理 Strings,手动输入 ANSI 转义序列和回车符 returns?有没有更好的方法来覆盖以前的输出?我欢迎任何建议。

ansi-wl-pprint 依赖于 ansi-terminal,它有一个 clearLine 方法和其他实用程序来四处移动并在控制台中记录位置。

在后台,clearLine 发送一个特定的 ANSI 控制序列 来擦除当前行。还有一个控制序列可以将光标倒回到当前行(或任何行,就此而言)的开头。这有点晦涩难懂,但您会惊讶地发现 how many control sequences 有。

您可以手动操作控制序列。例如,如果你 putStr "\ESC[2K\ESC[0G",它应该擦除当前行,然后将光标放在它的开头 - 类似于你的代码正在做的事情,但更清晰。但是,如果您依赖 ansi-terminal 并使用那里定义的操作 hClearLinehSetCursorColumn,它可能最适合您。如果您已经通过 ansi-wl-pprint 间接依赖 ansi-terminal,则不应产生额外的构建时间成本。