Ign*_*rov 4 terminal haskell pretty-print
有一个程序通过重复覆盖stderr. 操作如下:
当它想s用另一行覆盖一行时s',它s'用空格s填充,直到它至少与“回车”字符一样长:
n <- gets lastLineLength
let s'Padded | 0 < n = '\r': s' ++ replicate (n - length s') ' '
| otherwise = s'
hPutStr stderr s'Padded
Run Code Online (Sandbox Code Playgroud)这工作得很好。(虽然我个人没有在通常的 Linux 终端以外的情况下测试过它。)
我着手改进这个程序,用String一种Doc类型来代替普通的,ansi-wl-pprint这样我就可以用颜色来绘制文本,就像最近的 GHC 运动一样。像这样的库可能有点矫枉过正,因为我只需要一次输出几行,而且没有任何缩进,但我想尝试一下它的抽象着色设施。但是,我认为这个库(或任何漂亮的打印库)不会具有旨在擦除以前打印的Docs 的功能。
我想到的一种解决方案是Doc将 a渲染为 aString并测量其长度。但是,我将不得不为颜色代码打折;此外,这总体上是对库提供的抽象的侵入:具体来说,我将不得不依赖这样一个假设,即我手动执行的渲染将与hPutDoc.
我是否应该完全放弃该库并继续处理Strings,手动输入 ANSI 转义序列和回车?有没有更好的方法来覆盖以前的输出?我欢迎任何建议。
ansi-wl-pprint取决于ansi-terminal,它有一个clearLine方法和其他实用程序可以在控制台中移动和记录位置。
在引擎盖下,clearLine发送特定的ANSI 控制序列以擦除当前行。还有一个控制序列可以将光标倒回到当前行(或任何行,就此而言)的开头。这有点晦涩难懂,但您会惊讶地看到有多少控制序列。
您可以手动操作控制序列。例如,如果你putStr "\ESC[2K\ESC[0G",它应该擦除当前行然后把光标放到开头吗?类似于您的代码正在做什么,但更清晰。但是,如果您依赖ansi-terminal并使用操作hClearLine并hSetCursorColumn在那里定义,它可能会为您提供最好的服务。如果您已经间接依赖ansi-terminalthrough ansi-wl-pprint,则不应产生额外的构建时间成本。