golang构建强大交互式命令行工具插件库go-prompt的使用
Golang构建强大交互式命令行工具插件库go-prompt的使用
go-prompt是一个受python-prompt-toolkit启发的库,用于构建强大的交互式提示,使使用Go构建跨平台命令行工具变得更加容易。
基本使用示例
下面是一个使用go-prompt的基本示例:
package main
import (
"fmt"
"github.com/c-bata/go-prompt"
)
// completer函数提供自动补全建议
func completer(d prompt.Document) []prompt.Suggest {
s := []prompt.Suggest{
{Text: "users", Description: "Store the username and age"},
{Text: "articles", Description: "Store the article text posted by user"},
{Text: "comments", Description: "Store the text commented to articles"},
}
return prompt.FilterHasPrefix(s, d.GetWordBeforeCursor(), true)
}
func main() {
fmt.Println("Please select table.")
// 启动prompt,显示"> "提示符,并使用completer提供补全
t := prompt.Input("> ", completer)
fmt.Println("You selected " + t)
}
主要特性
强大的自动补全功能
go-prompt提供了强大的自动补全功能,可以轻松实现命令、参数等的智能提示。
灵活的选项配置
go-prompt提供了许多配置选项,可以自定义提示符的行为和外观。
键盘快捷键支持
默认支持以下Emacs风格的键盘快捷键(这些也是Bash shell中的默认快捷键):
快捷键 | 描述 |
---|---|
Ctrl + A | 移动到行首(Home) |
Ctrl + E | 移动到行尾(End) |
Ctrl + P | 上一条命令(上箭头) |
Ctrl + N | 下一条命令(下箭头) |
Ctrl + F | 向前移动一个字符 |
Ctrl + B | 向后移动一个字符 |
Ctrl + D | 删除光标下的字符 |
Ctrl + H | 删除光标前的字符(Backspace) |
Ctrl + W | 剪切光标前的单词到剪贴板 |
Ctrl + K | 剪切光标后的行到剪贴板 |
Ctrl + U | 剪切光标前的行到剪贴板 |
Ctrl + L | 清屏 |
命令历史记录
可以使用上箭头和下箭头键浏览和执行过的命令历史。
多平台支持
go-prompt已在以下终端中测试通过:
- iTerm2 (macOS)
- Terminal.app (macOS)
- Command Prompt (Windows)
- gnome-terminal (Ubuntu)
使用go-prompt的项目
一些使用go-prompt的项目包括:
- kube-prompt:交互式Kubernetes客户端
- rancher/cli:Rancher命令行界面
- kubicorn/kubicorn:Kubernetes的云原生基础设施
- evans:更通用的gRPC客户端
- docker-slim:优化Docker容器镜像的工具
许可证
go-prompt采用MIT许可证。
更多关于golang构建强大交互式命令行工具插件库go-prompt的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang构建强大交互式命令行工具插件库go-prompt的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Go-Prompt: 构建强大交互式命令行工具
Go-Prompt 是一个用于 Go 语言的交互式命令行输入库,它提供了类似现代 Shell 的自动补全、语法高亮和历史记录等功能。下面我将详细介绍如何使用 go-prompt 构建强大的交互式 CLI 工具。
基本安装
首先安装 go-prompt 库:
go get github.com/c-bata/go-prompt
基础用法示例
package main
import (
"fmt"
"github.com/c-bata/go-prompt"
)
func executor(in string) {
fmt.Printf("你输入了: %s\n", in)
}
func completer(in prompt.Document) []prompt.Suggest {
s := []prompt.Suggest{
{Text: "help", Description: "显示帮助信息"},
{Text: "exit", Description: "退出程序"},
{Text: "list", Description: "列出所有项目"},
{Text: "add", Description: "添加新项目"},
}
return prompt.FilterHasPrefix(s, in.GetWordBeforeCursor(), true)
}
func main() {
p := prompt.New(
executor,
completer,
prompt.OptionPrefix(">>> "),
prompt.OptionTitle("我的CLI工具"),
)
p.Run()
}
核心功能详解
1. 执行器(Executor)
执行器函数处理用户输入的命令:
func executor(in string) {
switch in {
case "help":
fmt.Println("帮助信息...")
case "exit":
fmt.Println("再见!")
os.Exit(0)
default:
fmt.Printf("未知命令: %s\n", in)
}
}
2. 自动补全(Completer)
补全函数提供建议列表:
func completer(d prompt.Document) []prompt.Suggest {
commands := []prompt.Suggest{
{Text: "create", Description: "创建新资源"},
{Text: "delete", Description: "删除资源"},
{Text: "update", Description: "更新资源"},
}
// 根据当前输入过滤建议
return prompt.FilterHasPrefix(commands, d.GetWordBeforeCursor(), true)
}
3. 高级选项配置
go-prompt 提供了丰富的配置选项:
p := prompt.New(
executor,
completer,
prompt.OptionPrefix("my-cli> "),
prompt.OptionTitle("交互式CLI工具"),
prompt.OptionPrefixTextColor(prompt.Yellow),
prompt.OptionPreviewSuggestionTextColor(prompt.Blue),
prompt.OptionSelectedSuggestionBGColor(prompt.LightGray),
prompt.OptionSuggestionBGColor(prompt.DarkGray),
prompt.OptionMaxSuggestion(10),
prompt.OptionHistory([]string{"help", "exit"}),
)
实战示例:构建一个简单的文件管理器
package main
import (
"fmt"
"os"
"strings"
"github.com/c-bata/go-prompt"
)
var currentDir = "."
func executor(in string) {
args := strings.Fields(in)
if len(args) == 0 {
return
}
switch args[0] {
case "cd":
if len(args) < 2 {
fmt.Println("用法: cd <目录>")
return
}
if err := os.Chdir(args[1]); err != nil {
fmt.Printf("错误: %v\n", err)
} else {
currentDir, _ = os.Getwd()
}
case "ls":
files, err := os.ReadDir(currentDir)
if err != nil {
fmt.Printf("错误: %v\n", err)
return
}
for _, file := range files {
fmt.Println(file.Name())
}
case "exit":
os.Exit(0)
default:
fmt.Printf("未知命令: %s\n", args[0])
}
}
func completer(d prompt.Document) []prompt.Suggest {
commands := []prompt.Suggest{
{Text: "cd", Description: "更改目录"},
{Text: "ls", Description: "列出文件"},
{Text: "exit", Description: "退出程序"},
}
// 如果是cd命令,提供目录补全
if strings.HasPrefix(d.TextBeforeCursor(), "cd ") {
dirs := getDirSuggestions()
return prompt.FilterHasPrefix(dirs, d.GetWordBeforeCursor(), true)
}
return prompt.FilterHasPrefix(commands, d.GetWordBeforeCursor(), true)
}
func getDirSuggestions() []prompt.Suggest {
files, err := os.ReadDir(currentDir)
if err != nil {
return nil
}
var dirs []prompt.Suggest
for _, file := range files {
if file.IsDir() {
dirs = append(dirs, prompt.Suggest{
Text: file.Name(),
Description: "目录",
})
}
}
return dirs
}
func main() {
currentDir, _ = os.Getwd()
p := prompt.New(
executor,
completer,
prompt.OptionPrefix(currentDir+"> "),
prompt.OptionTitle("简单文件管理器"),
)
p.Run()
}
高级特性
1. 自定义键绑定
p := prompt.New(
executor,
completer,
prompt.OptionAddKeyBind(prompt.KeyBind{
Key: prompt.ControlC,
Fn: func(buf *prompt.Buffer) {
fmt.Println("\n按Ctrl+C退出")
os.Exit(0)
},
}),
)
2. 实时前缀更新
func livePrefix() (string, bool) {
dir, _ := os.Getwd()
return dir + "> ", true
}
p := prompt.New(
executor,
completer,
prompt.OptionLivePrefix(livePrefix),
)
3. 多行输入支持
p := prompt.New(
executor,
completer,
prompt.OptionMultiLine(true),
)
最佳实践
- 清晰的命令结构:设计清晰的命令层次结构
- 丰富的补全提示:为每个命令提供详细的描述
- 错误处理:优雅地处理用户输入错误
- 性能考虑:对于大量补全项,考虑延迟加载
- 测试:编写测试确保交互行为符合预期
总结
go-prompt 是一个功能强大且灵活的库,可以帮助你快速构建具有现代 Shell 特性的交互式命令行工具。通过合理使用其自动补全、历史记录和自定义样式等功能,可以显著提升用户体验。