使用 Go 制作全屏终端应用程序

Making a full screen Terminal application with Go

我正在尝试构建一个全屏终端应用程序。我使用 Go 作为我选择的语言。我已经弄清楚如何从 os.Stdin 读取,但我不清楚如何清除终端 window 和操纵光标位置。我还想在不打印(回显)的情况下捕获终端输入。

我的问题是:

  1. 如何有效清除并打印到坐标为column/row的终端?
  2. 如何阻止终端打印按下的键

我的意图:

我想创建一个全屏终端应用程序,呈现它自己的 UI 并在内部处理输入(热 keys/navigation/etc...)。

如果有任何库涵盖此类用例,请随时提出建议。

清除终端和设置位置的最简单方法是通过 ansi 转义码。但是,这可能不是理想的方式,因为终端的变化可能会反噬您。

fmt.Print("3[2J") //Clear screen
fmt.Printf("3[%d;%dH", line, col) // Set cursor position

更好的选择是使用像 goncurses or termbox-go 这样的库(来源:第二个来自 Tim Cooper 的评论)。

有了这样的库,你可以做这样的事情:

import (
    gc "code.google.com/p/goncurses"
)

func main() {
    s, err := gc.Init()
    if err != nil {
        panic(err)
    }
    defer gc.End()
    s.Move(5, 2)
    s.Println("Hello")
    s.GetChar()
}

以上代码复制自Rosetta Code

要停止终端打印按下的键,您可以使用以下代码:

    import (
        "fmt"
        "syscall"
        "golang.org/x/crypto/ssh/terminal"
    )

    func main(){
        fmt.Print("Enter Value: ")
        byteInput, _ := terminal.ReadPassword(int(syscall.Stdin))
        input:= string(byteInput)
        fmt.Println() // it's necessary to add a new line after user's input
        fmt.Printf("Your input is '%s'", input)
    }

截至 2019 年 12 月,我建议使用 rivo/tview 库。

goncurses mentioned by @vastlysuperiorman has not been updated since June 2019 and termbox-go 明确声明为未维护)。


这是 "hello world" 应用程序,取自项目的自述文件(为了便于阅读而重新格式化):

package main

import (
    "github.com/rivo/tview"
)

func main() {

    box := tview.NewBox().
        SetBorder(true).
        SetTitle("Hello, world!")

    if err := tview.NewApplication().SetRoot(box, true).Run(); err != nil {
        panic(err)
    }
}


tview 提供 screenshots and example code as well as the standard godoc reference.