Categorygithub.com/aggronmagi/promptx
repositorypackage
1.0.3
Repository: https://github.com/aggronmagi/promptx.git
Documentation: pkg.go.dev

# Packages

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# README

  • promptx

promptx是可定制化的交互式 cli 应用程序的库。从[[https://github.com/c-bata/go-prompt/][go-prompt]]复制了部分文件.初版实现时候也有参考 [[https://github.com/abiosoft/ishell][ishell]].

支持简单命令以及命令集.

简单命令就是所有命令初始都显示出来.

命令集是根据需要将命令拆分成不同的组,只有处在某个状态下的时候才会显示.不同命令集下不共享操作的历史记录.

所有交互式命令都使用链式调用创建.

默认 Control-C 放弃输入, Control-D 退出进程.

允许异步打印日志.例: #+begin_src go p := promptx.NewPromptx() log.SetOutput(p.Stdout()) #+end_src 这样即使在其他gorountine使用 log 打印日志也不会影响正在输入的的选项.

zap日志需要通过 p.Stdout() 定制实现zapcore.

** 安装 #+begin_src shell go get github.com/aggronmagi/promptx@latest #+end_src ** 简单命令 #+begin_src go func loginCommand() *promptx.Cmd { return promptx.NewCommand("login", "登录游戏", promptx.WithArgSelect("选择登录的游戏服务器", []string{"开发服", "测试服", "体验服"}), promptx.WithArgsInput("账号:", promptx.InputNotEmpty()), ).ExecFunc(func(ctx promptx.CommandContext) { // 选择的登录服索引 index := ctx.CheckSelectIndex(0) // 登录的服务字符串 svcName := ctx.CheckString(0) // 输入的账号 account := ctx.CheckString(1)

	// custom logic
	// ....

	//
	ctx.Println("login success")
})

}

func main() { p := promptx.NewCommandPromptx( loginCommand, // other command ... ) p.Run() } #+end_src 完整例子 [[./_example/demo/main.go][Common Command]] ** 命令集 #+begin_src go

func loginCommand() *promptx.Cmd { return promptx.NewCommand("login", "登录游戏", promptx.WithArgSelect("选择登录的游戏服务器", []string{"开发服", "测试服", "体验服"}), promptx.WithArgsInput("账号:", promptx.InputNotEmpty()), ).ExecFunc(func(ctx promptx.CommandContext) { // 输入的string id := ctx.CheckString(1) ctx.Println(id, "login success") state = 1 // ctx.SwitchCommandSet("linked") }) }

func logoutCommand() *promptx.Cmd { return promptx.NewCommand("logout", "退出游戏").ExecFunc(func(ctx promptx.CommandContext) { state = 0 ctx.SwitchCommandSet("") }) }

func main() { p := promptx.NewPromptx() // default set p.AddCommandSet("", []*promptx.Cmd{ loginCommand(), },promptx.WithCommandSetOptionPrompt("not login >> ")) // p.AddCommandSet("linked", []*promptx.Cmd{ logoutCommand(), }, promptx.WithCommandSetOptionPrompt("linked >> "))

p.Run()

} #+end_src 完整例子 [[./_example/commandset/main.go][Command Set]] ** API *** 创建命令 #+begin_src go // NewCommand 创建交互式命令 name:命令名称 help:提示信息 args 命令参数 func NewCommand(name, help string, args ...CommandParameter) *Cmd // 设置命令执行函数 func (c *Cmd) ExecFunc(f func(ctx CommandContext)) *Cmd // 设置命令别名
func (c *Cmd) Aliases(aliases ...string) *Cmd // SubCommands 添加子命令 func (c *Cmd) SubCommands(cmds ...*Cmd) *Cmd #+end_src *** 命令参数 需要设置提示信息,如果用户没有一次性输入完整,提示用户输入. #+begin_src go // 手动输入string作为参数 func WithArgsInput(tip string, check InputChecker, opts ...InputOption) CommandParameter // 单选参数 多选一 func WithArgSelect(tip string, list []string, opts ...SelectOption) CommandParameter #+end_src *** Input类型参数的检测 #+begin_src go // 检测输入必须是非空字符串 func InputNotEmpty() InputChecker // 检测输入必须是数值类型 func InputInteger() InputChecker // 检测输入必须是非0数字 func InputNotZeroInteger() InputChecker // 检测输入必须是自然数 (1,2,3....) func InputNaturalNumber() InputChecker // 检测输入必须是在min,max区间的数字 func InputIntegerRange(min, max int64) InputChecker // 检测输入必须是IP端口(例 127.0.0.1:8080) func InputIPPort() InputChecker // 检测输入必须是IP端口数组,使用","分隔 func InputAddrsArray() InputChecker #+end_src *** 命令执行函数的签名 #+begin_src go // 函数签名 func xx(ctx CommandContext) { } #+end_src *** 命令上下文 CommandContext 命令执行函数内 使用 CommandContext 提供的 Check... 方法获取参数.

所有Check方法,如果没有用户没有输入,会通过panic打断流程.或者是输入了不符合预期的值,也会通过panic打断流程.

Check 函数的调用应该和创建命令时候输入的 CommandParameter 一一匹配.

Check 函数的Index参数从0开始.

CommandParameter 检测通过之后,内部保留的玩家输入都是string类型.所以 CheckString 只要索引位置输入了值,都是有效的.

CheckSelectIndex 仅用于 WithArgSelect 对应的参数,获取玩家输入的是第几个选项(从0开始) #+begin_src go // CommandContext type CommandContext interface { Context

CheckString(index int) string
CheckInteger(index int) int64
CheckIPPort(index int) (ip, port string)
CheckAddrs(index int) (addrs []string)
CheckSelectIndex(index int) int

} #+end_src *** 命令集 可以添加不同的命令集合,首次添加的命令集合会设置为默认的命令集. #+begin_src go type Context interface { // others interface function ... // AddCommandSet 添加命令集,首次添加命令集时会自动切换。 AddCommandSet(name string, cmds []*Cmd, opts ...CommandSetOption) // SwitchCommandSet 切换到指定命令集,参数会传递给 ChangeNotify 函数 SwitchCommandSet(name string, args ...interface{}) } #+end_src **** 选项 命令集添加时候,允许设置以下选项: #+begin_src go // 设置当前命令集的操作记录持久化保存的文件.如果不设置,每次切换命令集都会清空历史操作记录. func WithCommandSetOptionHistoryFile(v string) CommandSetOption // 设置当前命令集内所有命令执行的前置检测函数 func WithCommandSetOptionPreCheck(v func(ctx Context) error) CommandSetOption // 设置切换到命令集时的提示字符串(自定义文字颜色) func WithCommandSetOptionPromptWords(v ...*Word) CommandSetOption // 设置切换到命令集时的提示字符串(默认颜色) func WithCommandSetOptionPrompt(prompt string) CommandSetOption // 设置切换到命令集时候的通知函数,args为 SwitchCommandSet 传递的参数. func WithCommandSetOptionChangeNotify(v func(ctx Context, args []interface{})) CommandSetOption #+end_src

*** Word 彩色文字 #+begin_src go // WordDefault color text func WordDefault(str string) *Word // WordBlue color text func WordBlue(str string) *Word // WordBrown color text func WordBrown(str string) *Word // WordCyan color text func WordCyan(str string) *Word // WordGreen color text func WordGreen(str string) *Word // WordPurple color text func WordPurple(str string) *Word // WordRed color text func WordRed(str string) *Word // WordTurquoise color text func WordTurquoise(str string) *Word // WordWhite color text func WordWhite(str string) *Word // WordYellow color text func WordYellow(str string) *Word #+end_src ** 完整例子 [[./_example/demo/main.go][Common Command]]

[[./_example/commandset/main.go][Command Set]]

** 从[[https://github.com/c-bata/go-prompt/][go-prompt]]复制文件列表 | dir-or-files | source-repo | modify | |-----------------------------------------+-------------+--------| | internal/ debug,strings,bisect | [[https://github.com/c-bata/go-prompt/][go-prompt]] | | | output/input/terminal/completion/buffer | [[https://github.com/c-bata/go-prompt/][go-prompt]] | |

** 编辑快捷键 *** emacs key bind

Moving the cursor

| ok | key | description | |-----+-----------+--------------------------------------------------------------| | [x] | Ctrl + a | Go to the beginning of the line (Home) | | [x] | Ctrl + e | Go to the End of the line (End) | | [x] | Ctrl + p | Previous command (Up arrow) | | [x] | Ctrl + n | Next command (Down arrow) | | [x] | Ctrl + f | Forward one character | | [x] | Ctrl + b | Backward one character | | [x] | Meta + B | | | [x] | Meta + F | |

Editing

| ok | key | description | |-----+----------+---------------------------------------------------------| | [x] | Ctrl + L | Clear the Screen, similar to the clear command | | [x] | Ctrl + d | Delete character under the cursor | | [x] | Ctrl + h | Delete character before the cursor (Backspace) | | [x] | Ctrl + w | Cut the Word before the cursor to the clipboard. | | [x] | Ctrl + k | Cut the Line after the cursor to the clipboard. | | [x] | Ctrl + u | Cut/delete the Line before the cursor to the clipboard. | | [ ] | Ctrl + t | Swap the last two characters before the cursor (typo). | | [ ] | Esc + t | Swap the last two words before the cursor. | | [ ] | ctrl + y | Paste the last thing to be cut (yank) | | [ ] | ctrl + _ | Undo | ** 定制化 promptx 将很多逻辑都做成了可配置项. 查看 "gen_options_*.go"