You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
5.1 KiB
5.1 KiB
gselect —— 交互式 CLI 单选器
Product Requirements Document (PRD)
1. 产品概述
1.1 产品定位
gselect 是一个 基于 Golang + Bubble Tea 的交互式命令行选择器,
以 单选为核心,用于补全 shell 脚本中缺失的“美观、稳定、可控”的交互选择能力。
其定位类似于 fzf,但目标是:
- 更简单
- 更容易嵌入 shell 脚本
- 更容易维护与二次开发
1.2 目标用户
- 运维工程师
- 后端 / 工具链开发者
- 编写 shell / bash / zsh / fish 脚本的用户
- CLI 工具作者
1.3 非目标
- 不做复杂 TUI 框架
- 不做 REPL
- 不做表格 / 分屏 / 树状 UI
- 不支持鼠标操作
- 不做插件系统
2. 设计原则(强约束)
-
Unix 风格
- stdin 输入
- stdout 输出
- exit code 表达状态
-
单选优先
- 单选是默认行为
- 多选只是可选扩展
-
Shell 友好
- 输出可直接被
$(...)、mapfile、read使用 - 不输出多余日志
- 输出可直接被
-
接口极简
- 参数少
- 行为直观
- 无配置文件依赖
3. 使用方式总览
3.1 基础用法(默认单选)
printf "apple\nbanana\norange\n" | gselect
用户交互:
- ↑ ↓ 移动
- Enter 确认
- Esc / Ctrl+C 取消
stdout:
banana
exit code:
0:成功选择1:用户取消 / 无选择
4. 输入规范(stdin)
4.1 输入格式
- 每行一个选项
- 空行忽略
- 原样显示,不做 trim / escape
option A
option B
option C
4.2 可选 Key-Value 输入(扩展)
Apple|apple
Banana|banana
启用参数:
gselect --kv
- UI 显示:
Apple - 输出结果:
apple
5. 输出规范(stdout)
5.1 默认输出
- 输出 选中项的值
- 单行文本
- 不包含换行以外的任何字符
banana
5.2 输出索引
gselect --index
stdout:
1
(索引从 0 开始)
6. 退出状态(exit code)
| code | 含义 |
|---|---|
| 0 | 用户成功选择 |
| 1 | 用户取消(Esc / Ctrl+C) |
| 2 | 输入为空 / 无可选项 |
| 3 | 参数错误 |
7. 命令行参数设计
7.1 参数一览
| 参数 | 说明 |
|---|---|
--title |
顶部标题 |
--index |
输出索引而非值 |
--default |
默认选中值 |
--default-index |
默认选中索引 |
--no-search |
禁用搜索过滤 |
--kv |
启用 label |
--version |
显示版本 |
--help |
帮助信息 |
7.2 参数示例
设置标题
gselect --title "Select a branch"
默认选中
gselect --default "banana"
gselect --default-index 1
输出索引
gselect --index
禁用搜索
gselect --no-search
8. 交互设计
8.1 键位定义(固定,不可配置)
| 键 | 行为 |
|---|---|
| ↑ / k | 上移 |
| ↓ / j | 下移 |
| Enter | 确认 |
| Esc | 取消 |
| Ctrl+C | 取消 |
| 字符输入 | 搜索过滤(如启用) |
8.2 搜索行为
- 默认启用
- 子串匹配(不要求 fuzzy)
- 实时过滤
- 可通过
--no-search禁用
9. UI 设计规范
9.1 技术选型
bubbleteabubbles/listlipgloss
9.2 UI 元素
- 顶部:标题(可选)
- 中部:列表
- 底部:简要提示(↑↓ Enter Esc)
9.3 风格要求
- 简洁
- 对比清晰
- 不使用 Emoji
- 颜色适配暗色终端
10. 内部模型(设计指导)
10.1 核心数据结构(建议)
type Item struct {
Label string
Value string
Index int
}
type Model struct {
List list.Model
Selected *Item
Cancelled bool
}
10.2 退出逻辑
- Enter → 输出 →
os.Exit(0) - Esc / Ctrl+C →
os.Exit(1) - 无输入 →
os.Exit(2)
11. Shell 使用示例
11.1 基础
choice=$(ls | gselect) || exit 1
echo "$choice"
11.2 Git 分支选择
branch=$(git branch --format='%(refname:short)' | gselect)
git checkout "$branch"
11.3 输出索引
idx=$(printf "a\nb\nc\n" | gselect --index)
12. 非功能性要求
- 启动时间 < 50ms
- 单文件二进制
- 无运行时依赖
- 支持 Linux / macOS
- Go ≥ 1.21
13. 未来扩展(不在本期)
- 多选模式
- 自定义分隔符
- 预览窗
- JSON 输入
14. 成功标准(验收)
- 可在 shell 中稳定使用
- Ctrl+C 不污染终端
- stdout 可直接被脚本消费
- 用户无需文档即可理解基本操作
15. 一句话总结
一个“像 fzf 一样好用,但更简单、更可控、更适合脚本”的 CLI 单选器。