如何在 Golang 中始终将终端输入保持在底部?

use*_*214 2 terminal go

我正在尝试创建一个程序,该程序将从某些数据源进行实时更新。而且我也想像普通终端一样等待用户输入。现在,每当有更新时,我都会打印内容并再次打印输入提示消息,这会创建如下内容:

Enter command > 
This is a live update message

Enter command > 
This is a multi-line li......
......ve update message

Enter command > quit
Bye bye!
Run Code Online (Sandbox Code Playgroud)

问题是,对于我收到的每条实时消息,我都会打印它,并且会一遍又一遍地显示“输入命令>”,这是不希望的。我希望实时更新在终端的主要部分进行更新,而“输入命令>”始终位于底部

我可以在 Github 上找到的最接近的包是https://github.com/gizak/termui,但里面的大多数示例都试图显示文本、仪表和图形。所以我不太确定如何开始。

是否有任何包或 termui 包的示例来实现这一点?谢谢你。

kos*_*tix 5

随着github.com/gizak/termui您朝着正确的方向前进。

了解为什么你不能得到那个

我希望实时更新在终端的主要部分进行更新,而“输入命令>”始终位于底部

部分整理完毕,可以稍微游览一下计算的历史了。;-)

问题是,你的终端模拟器¹默认工作的模式起源于在字母数字显示器出现之前的时代计算机如何与操作员通信——他们将使用行式打印机打印他们的响应。现在想一想:行式打印机的工作原理是这样的:它将发送给它的任何内容打印在一卷纸上。什么是输出,什么是输出。新输出总是在物理上出现在旧输出之下。

当字母数字显示器(屏幕)出现时,它们自然会继续支持这种模式:要输出的行文本呈现在屏幕底部,上面的文本向上滚动。当您在bash仿真器窗口运行的 shell(例如)的命令行中工作时,这就是您在典型终端仿真器中始终看到的内容。终端的这种默认工作模式称为“规范”或“成熟”。

然后是更高级的显示,可以更改屏幕上的各个位置——由它们的列号和行号标识。这改变了信息输出方式的范式:所谓的“全屏应用程序”的概念诞生了。它们的典型例子是文本编辑器,如 Vim 和 Emacs。

为了支持全屏文本输出,终端(和终端仿真器)通过对其协议实施某些扩展来进行调整。

全屏应用程序首先请求终端切换到另一种称为“原始”的模式,在这种模式下,终端将用户输入的大部分内容直接发送给终端上运行的程序。程序处理此输入并命令终端在何处绘制什么内容。您可以阅读 两种模式之间区别的很好的总结

正如您现在怀疑的那样,为了能够在终端文本屏幕的某个固定位置保留一些信息块,您希望您的程序成为全屏程序并使用终端的原始模式及其特殊命令,允许您可以直接修改某些字符单元格处的文本。

现在的问题是不同的终端(和终端模拟器)有不同的命令来做到这一点,所以存在库来将程序与这些血腥的细节隔离开来。他们依靠特殊的“终端信息数据库”来确定终端具有哪些功能以及如何使其执行程序要求的操作。有关man terminfo更多背景信息,请参阅。

最广为人知的此类库(用 C 编写)称为ncurses,并且存在针对 Go 的本机解决方案,其中最明显的解决方案是github.com/nsf/termbox-go.

github.com/gizak/termui利用的termbox-go,但对你来说可能就够直接使用后者。


¹ 很有可能您不是坐在 连接到 UNIX® 机器的真正硬件终端上,而是在 GUI 应用程序中工作,例如 GNOME 终端xterm或 Termial.app 等。这些本身并不是“终端”,而是而是 终端模拟器——即模拟硬件终端的软件。