英文:
In Go, is it possible to write to the console and read back?
问题
我正在为Go语言的CLI编写一个向导。我想要做的是询问用户想要做什么,准备相应的CLI命令,并将其写入控制台。然后用户可以通过按下Enter键将命令提交给CLI,可能在此之前会对其进行编辑。换句话说,我希望将输出写入stdout,当用户按下Enter键时,它成为stdin的输入。在Go语言中有没有实现这个功能的方法?
英文:
I'm writing a wizard for a CLI in Go. What I'd like to do is ask the user what he wants to do, prepare the appropriate CLI command, and write it to the console. The user then would submit the command to the CLI by pressing Enter, possibly after editing it first. In other words, I want to write output to stdout that becomes input to stdin when the user presses Enter. Is there a way to do this in Go?
答案1
得分: 1
获取用户直接输入的方法:
var s string
_, err := fmt.Scanf("%s", &s)
对于类似 curses 的应用程序,请参考以下链接:
https://github.com/rthornton128/goncurses/blob/master/ncurses.go
它具有 C 绑定。
英文:
For getting input directly from user:
var s string
_, err := fmt.Scanf("%s", &s)
For curses-like application, look here:
https://github.com/rthornton128/goncurses/blob/master/ncurses.go
It has C bindings.
答案2
得分: 0
我找到了一个Go命令行编辑器包,https://github.com/peterh/liner,它包含了所需的功能以及更多功能。它允许你编写一个带有历史记录和命令补全的命令行界面,其中命令补全功能正是你在问题中提到的:它会呈现给用户可以编辑并提交到命令行界面的文本。它支持Windows、Linux和Mac。下面是它 README 中一个稍作修改的示例,可以运行一个带有命令补全的简单命令行界面。例如,用户可以输入"j",然后按Tab键来循环显示一个名称列表,编辑其中一个名称,然后按Enter键提交。
package main
import (
"fmt"
"log"
"os"
"strings"
"github.com/peterh/liner"
)
var (
history_fn = ".liner_history"
names = []string{"jack", "john", "james", "mary", "mike", "nancy"}
)
func main() {
line := liner.NewLiner()
defer line.Close()
line.SetCompleter(func(line string) (c []string) {
for _, n := range names {
if strings.HasPrefix(n, strings.ToLower(line)) {
c = append(c, n)
}
}
return
})
if f, err := os.Open(history_fn); err == nil {
line.ReadHistory(f)
f.Close()
}
line.SetCtrlCAborts(true)
for true {
if name, err := line.Prompt("What is your name? "); err != nil {
if err.Error() == "EOF" || err == liner.ErrPromptAborted {
break
}
log.Print("Error reading line: ", err)
} else {
log.Print("Got: ", name)
line.AppendHistory(name)
}
}
fmt.Printf("End of test\n")
if f, err := os.Create(history_fn); err != nil {
log.Print("Error writing history file: ", err)
} else {
line.WriteHistory(f)
f.Close()
}
}
这段代码是一个简单的命令行界面,具有命令补全功能。用户可以输入"j",然后按Tab键来循环显示一个名称列表,编辑其中一个名称,然后按Enter键提交。
英文:
I've found a Go command line editor package, https://github.com/peterh/liner, that incorporates the capability requested and a good deal more. It allows you to write a CLI with history and command completion, with the command completion feature providing exactly what I asked for in the question: it presents text that the user can edit and submit to the CLI. It supports Windows, Linux, and Mac. Here's a slightly modified version of the example in its README that runs a simple CLI with command completion. For example, the user can type "j" and press Tab to cycle through a list of names, edit one to taste, and press Enter to submit.
package main
import (
"fmt"
"log"
"os"
"strings"
"github.com/peterh/liner"
)
var (
history_fn = ".liner_history"
names = []string{"jack", "john", "james", "mary", "mike", "nancy"}
)
func main() {
line := liner.NewLiner()
defer line.Close()
line.SetCompleter(func(line string) (c []string) {
for _, n := range names {
if strings.HasPrefix(n, strings.ToLower(line)) {
c = append(c, n)
}
}
return
})
if f, err := os.Open(history_fn); err == nil {
line.ReadHistory(f)
f.Close()
}
line.SetCtrlCAborts(true)
for true {
if name, err := line.Prompt("What is your name? "); err != nil {
if err.Error() == "EOF" || err == liner.ErrPromptAborted {
break
}
log.Print("Error reading line: ", err)
} else {
log.Print("Got: ", name)
line.AppendHistory(name)
}
}
fmt.Printf("End of test\n")
if f, err := os.Create(history_fn); err != nil {
log.Print("Error writing history file: ", err)
} else {
line.WriteHistory(f)
f.Close()
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论