我对 TUI 的兴趣源于一个名为 LazyGit 的终端命令,它让我只需几次按键即可完成一次 Git 提交,而不是 zsh 的 git 插件那种通过 alias 的方式实现。
不同于 GUI,TUI 低系统资源消耗和高效的全键盘操作,这让我对如何开发这类应用产生了兴趣。
最终,我找到了 Bubbletea 这个框架。
一个月前,还写了一篇基于 Bubbletea 开发 TUI 命令的文章。
请阅读 推荐一个可用于 Go 快速创建 TUI 应用的框架 – Bubble Tea,我用它写了一个贪吃蛇
当时的我对这个框架的认识并不深入,仅限于开发一些简单小程序,如果想开发一个如 LazyGit 般复杂的程序时,就没有那么容易了。
今天的文章重点介绍 bubbletea 的一系列扩展库,和 bubbletea 一样是位于 github.com/charmbracelet 下,由 charmbracelet 团队开发的其他开源库。
这些扩展库 star 数基本都在千甚至万以上。说实在的,很少遇到核心框架之外,扩展库的 star 也基本在千以上的。我觉得主要因为这些库的普适性,基本与 bubbletea 的关系都只是互补关系,而不是强依赖,任意一个库都能拿出来单独介绍。
库有点多,先来个汇总吧。
Name (Star) |
description |
BubbleTea (23k) |
Go 编写的 TUI 框架,灵感源于 Elm 架构,是构建复杂 TUI 应用的基础。 |
Bubbles (4.4k) |
一套标准的TUI组件,如进度条、文本输入等,与 BubbleTea 无缝集成。 |
Lipgloss (7.0k) |
用于终端中创建富文本布局,支持边框、间距、对齐、样式和颜色等。 |
Huh (2.9k) |
一个构建交互式终端表单的 Go 库,简化命令行输入流程。 |
Glamour (2.0k) |
渲染 Markdown 文本的库,使得在 TUI 应用显示格式化的文档变得简单。 |
Glow (14k) |
渲染 Markdown 文件的命令工具,支持多种主题,适合用于终端阅读。 |
Soft Serve (4.6k) |
自托管 Git 服务器,TUI 界面,命令行管理和分享 Git 仓库变得更简洁。 |
Wish (2.8k) |
一个构建 SSH 应用的库,可创建 TUI 版远程应用,通过 SSH 暴露服务。 |
Gum (16k) |
提供了一系列快速创建交互式组件的命令,Shell 脚本即可开发 TUI 应用。 |
Harmonica (0.9k) |
一个简单高效的弹簧动画库,用于创建平滑和自然的动画效果的所需参数。 |
Mods (2.2k) |
将大型语言模型(LLM)的能力引入到命令行和管道工作流中的命令工具。 |
VHS (13k) |
用于录制终端会话的工具,允许捕获命令行操作,便于分享、教学或演示。 |
Pop (2.0k) |
终端邮件发送工具,可通过标准输入传递邮件内容,更易实现自动化邮件。 |
Log (1.9k) |
一个彩色日志库,支持多种日志级别和格式,方便终端的日志展示和追踪。 |
如果对我的文章感兴趣,欢迎关注我的公众号。
Bubble Tea 核心框架
Bubbletea 是这个生态的核心框架,它是我们开发 TUI 应用的起点。
Bubbletea 基于模型-视图-更新(MVU)架构(The Elm Architecture)。具体细节可查看前文介绍,其中对 bubbletea 的基本架构做了相对详细的说明。
官方指南中的 HelloWorld 案例,基于 bubbletea 创建一个简单的计数器。
代码如下所示:
type model int
// 初始化模型,设置计数器的初始值
func initialModel() model {
return 0
}
func (m model) Init() tea.Cmd {
return nil
}
// 更新函数,根据消息更新模型
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.String() {
case "q":
return m, tea.Quit
case "+":
return m + 1, nil
case "-":
return m - 1, nil
}
}
return m, nil
}
func (m model) View() string {
return fmt.Sprintf("Count: %dnPress + to increment, - to decrement, q to quit.n", m)
}
func main() {
p := tea.NewProgram(initialModel())
if _, err := p.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Error running program: %v", err)
os.Exit(1)
}
}
效果如下:
一些基础扩展
随着我对 Bubble Tea 框架的深入,需求也在变多,我开始了解其它 bubbletea 衍生而来的扩展库。我觉得首先是 3 个极可能受到大家关心的库,分别是布局与样式 – Lipgloss,组件库 – bubbles,交互式 form 表单 – huh
Lipgloss,它提供了定义样式和布局的能力。如通过它调整颜色、边框和布局等,轻松实现美观实用的界面。Lipgloss 能极大地提升 TUI 应用的外观和用户体验。
style := lipgloss.NewStyle().
BorderStyle(lipgloss.RoundedBorder()). // 圆角边框
Bold(true). // 加粗
Foreground(lipgloss.Color("#FAFAFA")). // 前景色
Background(lipgloss.Color("#7D56F4")). // 背景色
PaddingTop(2). // 顶部 padding
PaddingLeft(4). // 左侧 padding
AlignVertical(lipgloss.Center). // 垂直居中
Height(5). // 高度
Width(40) // 宽度
// 水平布局
left := style.Render("Hello Left!")
right := style.Render("Hello Right")
fmt.Println(lipgloss.JoinHorizontal(lipgloss.Top, left, right))
// 垂直布局
top := style.Render("Hello Top!")
bottom := style.Render("Hello Bottom!")
fmt.Println(lipgloss.JoinVertical(lipgloss.Top, top, bottom))
Bubbles,它为 Bubbleta 提供了基础组件。让我能轻松添加各种 UI 组件,如进度条和文本输入框,这些都是创建交互式命令行应用不可或缺的元素。
组件的示例代码要结合 bubbletea 框架,我就不粘贴大段的代码了。
文本输入框:
表格:
进度条:
更多就不一一展示了,查看 bubbles 仓库地址即可。
Huh,为 Bubble Tea 提供了构建交互式表单和提示的能力。相对于 bubbles 中的基础组件,它使我们能轻松实现各种用户输入界面,从选择列表到文本输入框,再到确认对话框。
和 Lipgloss 一样,Huh 也是可脱离 bubbletea 使用的。
一个简单案例:
var name string
_ = huh.NewInput().
Title("What's your name?").
Value(&name).
Run() // this is blocking...
fmt.Printf("Hey, %s!n", name)
Huh 官方 README 文档中提供了一个完整的购买汉堡的订单流程。
高级工具库
除了上述的基础库,charmbracelet 下还有一些高级的工具库,如 markdown 渲染器 – glamour 和动画制作 – Harmonica。唯一可惜的是,没找到图表库。
Glamour,它为了终端显示 markdown 文档提供了支持,它支持样式自定义,提供了几种预定义主题风格。
in := `# Hello World
This is a simple example of Markdown rendering with Glamour!
Checkout the [other examples](https://github.com/charmbracelet/glamour/tree/master/examples)
Bye!
`
r, _ := glamour.NewTermRenderer(glamour.WithAutoStyle(), glamour.WithWordWrap(40))
out, err := r.Render(in)
if err != nil {
log.Fatal(err)
}
fmt.Print(out)
诸如 github、gitlab 和 gitee 的官方 CLI 工具,用的都是这个库实现的 markdown 渲染。
他们还提供了一个基于 Glamour 实现的 glow 命令行工具,支持查看本地或远程的 Markdown 文档。
我原本想找一个能和 bubbletea 集成的图表组件库,但只发现了一个名为 Harmonica 的库。
Harmonica 主要是用于模拟弹簧运动,它本身并不提供绘制逻辑,只会生成物理的运动参数(如位置和速度),以实现平滑和自然的动画效果。但它最近已经没更新了。
官方提供的一个案例效果:
SHELL 脚本编写 TUI
我要感慨下,之前看到很多用 rust 写的 CLI 工具,羡慕不已,Go 原来也有这么好用或者说是比之更佳的库。
如果你对 rust 和 Go 都不了解,但想实现一个 TUI 应用,我要推荐这个命令- Gum,它让我们通过 SHELL 脚本即可实现 TUI 应用。
Gum 提供了一系列工具,实现基于 Shell 脚本即可编写一些小巧的 TUI 应用,有助于优化我们的日常工作流。
我们来看看如下是一些简单用法说明:
-
输入(input): 提示用户输入文本。
gum input --placeholder "Enter your name"
-
选择(choose): 创建一个交互式的列表让我们从中选择一个选项。
gum choose "Option 1" "Option 2" "Option 3"
过滤(filter): 从输入的列表中过滤出符合条件的项。
echo -e "onentwonthree" | gum filter
确认(confirm): 弹出一个确认对话框让我们选择确认。
gum confirm "Are you sure?" && echo "I'm sure" || echo "No"
旋转指示器(spin): 在执行耗时长的命令时显示旋转指示器。
gum spin -- sleep 5
表格(table): 渲染一个数据表格。
gum table --header "Name,Email" --rows "Alice,alice@example.comnBob,bob@example.com"
文件选择(file): 从文件系统中选择一个文件。
gum file | xargs glow -p
其他如样式定制,布局等能力都是支持的,就不一一展示了,有兴趣可以看它的 README 文档。
毫无疑问,Gum 增强了 Shell 脚本。通过 Gum 这些命令,可以编写出体验更佳的交互式命令。Gum 的每个命令的帮助信息都可通过 gum <command> --help
查看。
官方案例中有一个交互式的 Git Commit 工作流。
完整脚本实现也很简单。
#!/bin/sh
TYPE=$(gum choose "fix" "feat" "docs" "style" "refactor" "test" "chore" "revert")
SCOPE=$(gum input --placeholder "scope")
# Since the scope is optional, wrap it in parentheses if it has a value.
test -n "$SCOPE" && SCOPE="($SCOPE)"
# Pre-populate the input with the type(scope): so that the user may change it
SUMMARY=$(gum input --value "$TYPE$SCOPE: " --placeholder "Summary of this change")
DESCRIPTION=$(gum write --placeholder "Details of this change (CTRL+D to finish)")
# Commit these changes
gum confirm "Commit changes?" && git commit -m "$SUMMARY" -m "$DESCRIPTION"
SSH 的远程 TUI 应用
你是否想过 TUI 应用也能像 Web 服务那样通过远程访问呢?
通过一款名为 wish 的库,可轻松开发可远程访问的 TUI 应用。wish 的传输协议是 SSH,于用户而言,只要在终端执行一个 SSH 命令,即可访问部署在远程的应用。
如下是远程访问 charmbracelet 团队的 tui 版 Git Server。
ssh git.charm.sh
如果你也想拥有这样的一个 git server,可直接部署 charmbracelet/Soft-Serve 这个项目到你的机器上。或者如果你对开发这样的应用有兴趣,官方提供了一些案例,查看地址 examples[1],其中就有一个 gitserver 的案例。
还有,charmbracelet 团队还开发一个名为 wishlist 的应用,可作为 ssh 应用的展示目录。
它不限制是否是 wish 开发的应用。如上所示,我可以将我的 SSH 机器的绑定其中。
其他
除了上述介绍的这些,charmbracelet 下还有其他的一些值得推荐的库。如:
vhs[2],一个终端操作录制命令,提供了一种简单高效的方式捕捉和分享终端操作。我这篇文章的 GIF 基本都是通过它录制的。
它的使用很简单,创建一个 record.tape 文件,内容如下:
Set TypingSpeed 500ms
Type 'echo "Hello VHS"'
Enter
Sleep 2s
执行如下命令即可生成一个 gif 文件。
$ vhs record.tape
生成效果:
mods[3],一个 LLM GPT 的终端命令,可对接市面主流的大模型 AI,如 openai、grok、localai 等。我用了下体验还不错。
pop[4],一个支持在终端接发邮件的命令,操作起来高效便捷。
注:gif 图片传不上来,估计 gif 太多了,只能静态图了。
Log[5],一个支持彩色输出的 Go 日志库,可提高我们日常的调试体验和阅读的舒适度。
结语
这次深入 BubbleTea 及其生态中的其他组件库,不仅让我学习了如何开发功能丰富的TUI应用,还知道如何使这些应用更加美观与实用。Bubble Tea 生态不仅提供了强大的工具和库,还激发了我对命令行应用新可能性的想象,的确是相对有趣的。
引用链接
[1]
examples: https://github.com/charmbracelet/wish/tree/main/examples[2]
vhs: https://github.com/charmbracelet/vhs[3]
mods: https://github.com/charmbracelet/mods[4]
pop: https://github.com/charmbracelet/pop[5]
Log: https://github.com/charmbracelet/log
如果对我的文章感兴趣,欢迎关注我的公众号。
原文始发于微信公众号(码途漫漫):推荐一些助力 TUI 应用开发的扩展库
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/245869.html