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.")
	// 启动交互式提示,"> "是提示符,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的功能:

package main

import (
	"fmt"
	"strings"
	
	"github.com/c-bata/go-prompt"
)

var commands = []prompt.Suggest{
	{Text: "exit", Description: "Exit the program"},
	{Text: "help", Description: "Show help"},
	{Text: "show", Description: "Show information"},
	{Text: "create", Description: "Create new item"},
	{Text: "delete", Description: "Delete item"},
}

func completer(d prompt.Document) []prompt.Suggest {
	// 根据输入过滤建议
	if d.TextBeforeCursor() == "" {
		return []prompt.Suggest{}
	}
	
	// 分割命令行参数
	args := strings.Split(d.TextBeforeCursor(), " ")
	
	// 如果是第一个单词,返回主命令建议
	if len(args) <= 1 {
		return prompt.FilterHasPrefix(commands, d.GetWordBeforeCursor(), true)
	}
	
	// 处理子命令建议
	switch args[0] {
	case "show":
		subCommands := []prompt.Suggest{
			{Text: "users", Description: "Show all users"},
			{Text: "config", Description: "Show configuration"},
		}
		if len(args) == 2 {
			return prompt.FilterHasPrefix(subCommands, args[1], true)
		}
	case "create":
		// 创建命令的子命令建议
		subCommands := []prompt.Suggest{
			{Text: "user", Description: "Create new user"},
			{Text: "group", Description: "Create new group"},
		}
		if len(args) == 2 {
			return prompt.FilterHasPrefix(subCommands, args[1], true)
		}
	}
	
	return []prompt.Suggest{}
}

func executor(t string) {
	t = strings.TrimSpace(t)
	if t == "" {
		return
	} else if t == "exit" {
		fmt.Println("Goodbye!")
		return
	}
	
	fmt.Printf("You entered: %q\n", t)
}

func main() {
	fmt.Println("Welcome to the interactive prompt!")
	fmt.Println("Type 'help' for available commands, 'exit' to quit.")
	
	// 启动交互式提示
	p := prompt.New(
		executor,
		completer,
		prompt.OptionPrefix(">>> "),
		prompt.OptionTitle("Interactive Prompt"),
		prompt.OptionMaxSuggestion(10),
	)
	p.Run()
}

这个示例展示了:

  1. 更复杂的命令补全逻辑
  2. 使用executor函数处理用户输入
  3. 自定义提示选项(前缀、标题、最大建议数等)

go-prompt是一个功能强大且灵活的库,可以帮助开发者快速构建具有丰富交互功能的命令行工具。


更多关于golang构建强大交互式命令行提示插件库go-prompt的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang构建强大交互式命令行提示插件库go-prompt的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Go-Prompt: 构建强大交互式命令行工具

Go-Prompt 是一个用于 Go 语言的交互式命令行提示库,它提供了类似 Python 的 prompt-toolkit 的功能,可以帮助开发者快速构建功能丰富的命令行界面(CLI)工具。

主要特性

  • 自动补全
  • 语法高亮
  • 多行输入支持
  • 历史命令记录
  • 自定义提示符
  • 异步执行支持

安装

go get github.com/c-bata/go-prompt

基础使用示例

package main

import (
	"fmt"
	"github.com/c-bata/go-prompt"
)

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"},
		{Text: "groups", Description: "Store the user group info"},
	}
	return prompt.FilterHasPrefix(s, d.GetWordBeforeCursor(), true)
}

func main() {
	fmt.Println("Please select table.")
	t := prompt.Input("> ", completer)
	fmt.Println("You selected " + t)
}

高级功能实现

1. 自定义提示符和颜色

func main() {
	p := prompt.New(
		executor,
		completer,
		prompt.OptionPrefix(">>> "),
		prompt.OptionPrefixTextColor(prompt.Yellow),
		prompt.OptionTitle("My Awesome CLI"),
	)
	p.Run()
}

2. 多行输入支持

func main() {
	p := prompt.New(
		executor,
		completer,
		prompt.OptionMultiLine(true),
		prompt.OptionPrefix(">>> "),
	)
	p.Run()
}

3. 历史命令记录

func main() {
	history := []string{"ls -la", "cd ~", "exit"}
	p := prompt.New(
		executor,
		completer,
		prompt.OptionHistory(history),
	)
	p.Run()
}

4. 自定义快捷键绑定

func main() {
	p := prompt.New(
		executor,
		completer,
		prompt.OptionAddKeyBind(
			prompt.KeyBind{
				Key: prompt.ControlC,
				Fn: func(buf *prompt.Buffer) {
					fmt.Println("\nCtrl+C pressed!")
				},
			},
		),
	)
	p.Run()
}

实际应用示例:构建一个简单的数据库CLI

package main

import (
	"fmt"
	"strings"
	"github.com/c-bata/go-prompt"
)

var livePrefixState struct {
	livePrefix string
	isEnable   bool
}

func changeLivePrefix() (string, bool) {
	return livePrefixState.livePrefix, livePrefixState.isEnable
}

func executor(in string) {
	in = strings.TrimSpace(in)
	
	if in == "" {
		livePrefixState.isEnable = false
		livePrefixState.livePrefix = in
		return
	}
	
	blocks := strings.Split(in, " ")
	switch blocks[0] {
	case "select":
		if len(blocks) < 2 {
			fmt.Println("select [table_name]")
			return
		}
		fmt.Printf("Querying data from %s...\n", blocks[1])
	case "insert":
		if len(blocks) < 2 {
			fmt.Println("insert [table_name] [data]")
			return
		}
		fmt.Printf("Inserting data into %s: %s\n", blocks[1], strings.Join(blocks[2:], " "))
	case "exit", "quit":
		fmt.Println("Bye!")
		return
	default:
		fmt.Println("Unknown command")
	}
	
	livePrefixState.livePrefix = in + " > "
	livePrefixState.isEnable = true
}

func completer(d prompt.Document) []prompt.Suggest {
	s := []prompt.Suggest{
		{Text: "select", Description: "Query data from table"},
		{Text: "insert", Description: "Insert data into table"},
		{Text: "update", Description: "Update table data"},
		{Text: "delete", Description: "Delete data from table"},
		{Text: "exit", Description: "Exit the program"},
		{Text: "quit", Description: "Exit the program"},
	}
	
	if d.TextBeforeCursor() == "" {
		return s
	}
	
	return prompt.FilterHasPrefix(s, d.GetWordBeforeCursor(), true)
}

func main() {
	fmt.Println("Welcome to SimpleDB CLI. Type 'exit' or 'quit' to exit.")
	p := prompt.New(
		executor,
		completer,
		prompt.OptionPrefix("> "),
		prompt.OptionLivePrefix(changeLivePrefix),
		prompt.OptionTitle("SimpleDB CLI"),
	)
	p.Run()
}

性能优化建议

  1. 异步补全:对于耗时较长的补全操作,使用异步方式
  2. 缓存补全结果:对频繁使用的补全结果进行缓存
  3. 精简补全列表:避免返回过长的补全列表
  4. 延迟加载:对于大型数据集,考虑延迟加载补全项

总结

Go-Prompt 提供了构建交互式命令行工具所需的核心功能,通过合理使用其API,可以创建出用户体验良好的CLI应用。它的主要优势在于:

  • 简单易用的API设计
  • 高度可定制化的界面
  • 良好的性能表现
  • 活跃的社区支持

对于需要构建复杂命令行工具的项目,Go-Prompt 是一个值得考虑的选择。

回到顶部