AI书签管理工具开发全记录(十三):TUI基本框架搭建

文章目录

  • AI书签管理工具开发全记录(十三):TUI基本框架搭建
    • [前言 📝](#前言 📝)
    • [1.TUI介绍 🔍](#1.TUI介绍 🔍)
    • [2. 框架选择 ⚙️](#2. 框架选择 ⚙️)
    • [3. 功能梳理 🎯](#3. 功能梳理 🎯)
    • [4. 基础框架搭建⚙️](#4. 基础框架搭建⚙️)
      • [4.1 安装](#4.1 安装)
      • [4.2 参数设计](#4.2 参数设计)
      • [4.3 绘制ui](#4.3 绘制ui)
        • [4.3.1 设计结构体](#4.3.1 设计结构体)
        • [4.3.2 创建头部](#4.3.2 创建头部)
        • [4.3.3 创建主体](#4.3.3 创建主体)
        • [4.3.4 创建日志栏](#4.3.4 创建日志栏)
        • [4.3.5 创建整体布局](#4.3.5 创建整体布局)
        • [4.3.6 创建启动函数](#4.3.6 创建启动函数)
        • [4.3.6 对接cobra命令行](#4.3.6 对接cobra命令行)
    • [5.效果测试 ✅](#5.效果测试 ✅)

AI书签管理工具开发全记录(十三):TUI基本框架搭建

前言 📝

在上一篇文章中,我们实现了MCP查询集成,集成了常用的查询场景,在支持MCP的客户端如cherry studio中可以查询书签数据了。但有时候,我们需要快速的浏览书签书签,没有比命令行的方式更快速的了,但是命令行操作太繁琐,所以我们本篇文章采用更进一步的TUI。

1.TUI介绍 🔍

TUI(Terminal User Interface) 是命令行工具与图形界面的完美融合体。不同于传统CLI需要记忆复杂指令的操作方式,TUI通过直观的文本界面组件(如菜单、列表、状态栏)实现可视化交互;相较于GUI应用,它又保留了终端操作的高效性与轻量级优势。经典的Linux工具如htopncduvim都证明了TUI在提升生产力方面的价值------无需离开终端窗口,即可实现键盘驱动的快速导航与操作。

在书签管理场景中,TUI能让我们通过方向键即时浏览收藏链接,用快捷键执行搜索/跳转/删除等操作,避免图形界面加载的延迟和命令行输入的低效。

2. 框架选择 ⚙️

在Go语言的TUI框架生态中,rivo/tview 以其组件化的设计强大的布局能力卓越的性能 脱颖而出,成为我们构建书签管理TUI的首选。它提供了一套丰富且高度可定制的基础组件 (如列表 List、表格 Table、文本框 TextView、表单 Form、模态框 Modal 等)和灵活的布局管理器 (如 Flex, Grid, Pages),极大地简化了复杂终端界面的构建过程。其核心优势在于:

  1. 声明式布局:通过组合嵌套布局和组件,可以直观地构建出结构清晰、响应式的界面,适应不同终端尺寸。
  2. 高效渲染与键盘导航tview 采用智能渲染机制,确保界面更新流畅。它内置了强大且可自定义的键盘事件处理系统,让我们能够轻松为书签的浏览、选择、搜索、操作(打开、删除、编辑)定义直观的快捷键,实现真正的"键盘驱动"体验。
  3. 丰富的样式与主题:支持设置文本颜色、背景色、边框样式、标题等,允许我们为书签的不同状态(如已读/未读、分类)设计清晰的视觉区分。
  4. 活跃的社区与成熟度 :作为Go领域最受欢迎的TUI库之一,tview 拥有良好的文档、活跃的社区支持和经过大量项目验证的稳定性。

选择 tview,意味着我们能高效地 实现一个性能出色交互流畅视觉清晰 的书签管理终端应用,完美契合我们追求快速浏览与操作的核心目标。接下来,我们将开始搭建基于 tview 的应用基础框架。

3. 功能梳理 🎯

在开始搭建基础框架前,我们先规划一下tui应用需求和布局

功能列表:

  • 需要搜索功能,可以快速搜索书签
  • 可以快速浏览器分类、书签

ui设计:

  • 最顶层是搜索框,可以输入关键词进行搜索
  • 中间是三栏数据,第一栏分类、第二栏书签、第三栏书签描述
  • 最下层是日志框,可以隐藏

4. 基础框架搭建⚙️

4.1 安装

bash 复制代码
go get -u github.com/rivo/tview

4.2 参数设计

需求:

  1. 启动时可以输入关键词,查询书签
  2. 可以关闭日志栏
go 复制代码
// cmd/root.go:Execute
rootCmd.Flags().StringP("search", "s", "", "Search for a command")
rootCmd.Flags().BoolP("showlog", "l", false, "Show log panel")

4.3 绘制ui

4.3.1 设计结构体
go 复制代码
// internal/tui/app.go

type TuiView struct {
	app             *tview.Application
	searchBox       *tview.InputField
	categoryList    *tview.List
	bookmarkList    *tview.List
	descriptionView *tview.TextView
	logView         *tview.TextView
	main            *tview.Flex
	modal           *tview.Flex
	pages           *tview.Pages
	focusable       []tview.Primitive
	showLog         bool
	focusIndex      int
}
4.3.2 创建头部
go 复制代码
// internal/tui/ui.go

func (t *TuiView) CreateHeader() *tview.TextView {
	return tview.NewTextView().
		SetDynamicColors(true).
		SetTextAlign(tview.AlignCenter).
		SetText("[::b]AiBookMark[::-] [darkcyan] ← →:切换 ↑↓:导航 CTRL+F:搜索 /CTRL+R:重置 Q:退出")
}
4.3.3 创建主体
go 复制代码
// internal/tui/ui.go

func (t *TuiView) CreateCategoryList() *tview.List {
	t.categoryList = tview.NewList().ShowSecondaryText(true)
	t.categoryList.SetBorder(true).SetTitle(" 分类 ")
	t.categoryList.SetBorderColor(tcell.ColorWhite) // 添加默认边框颜色
	return t.categoryList
}

func (t *TuiView) CreateBookmarkList() *tview.List {
	t.bookmarkList = tview.NewList().ShowSecondaryText(true)
	t.bookmarkList.SetBorder(true).SetTitle(" 书签 ")
	t.bookmarkList.SetBorderColor(tcell.ColorWhite) // 添加默认边框颜色
	return t.bookmarkList
}

func (t *TuiView) CreateDescriptionView() *tview.TextView {
	t.descriptionView = tview.NewTextView().
		SetDynamicColors(true).
		SetScrollable(true).
		SetWrap(true)
	t.descriptionView.SetBorder(true).SetTitle(" 描述 ")
	t.descriptionView.SetBorderColor(tcell.ColorWhite) // 添加默认边框颜色
	return t.descriptionView
}


func (t *TuiView) CreateMain() *tview.Flex {
	// 菜单列表
	t.CreateCategoryList()
	// 书签列表
	t.CreateBookmarkList()
	// 书签描述
	t.CreateDescriptionView()

	// 创建布局
	mainFlex := tview.NewFlex()
	mainFlex.AddItem(t.categoryList, 35, 0, true)
	mainFlex.AddItem(tview.NewFlex().
		AddItem(t.bookmarkList, 0, 1, true).
		AddItem(t.descriptionView, 0, 2, false), 0, 1, false)
	return mainFlex
}
4.3.4 创建日志栏
go 复制代码
// internal/tui/ui.go

func (t *TuiView) CreateLogs() *tview.TextView {
	t.logView = tview.NewTextView().
		SetDynamicColors(true).
		SetScrollable(true).
		SetWrap(false)
	t.logView.SetBorder(true).SetTitle(" 日志 ")
	return t.logView
}
4.3.5 创建整体布局
go 复制代码
// internal/tui/ui.go

func (t *TuiView) CreateMainFlex() *tview.Flex {
	mainFlex := tview.NewFlex()
	mainFlex.SetDirection(tview.FlexRow)
	// Header
	mainFlex.AddItem(t.CreateHeader(), 3, 0, false)
	// 搜索框
	mainFlex.AddItem(t.CreateSearchBox(), 3, 0, false)
	// CategoryList
	mainFlex.AddItem(t.CreateMain(), 0, 1, false)
	if t.showLog {
		mainFlex.AddItem(t.CreateLogs(), 8, 10, false)
	}
	return mainFlex
}
4.3.6 创建启动函数
go 复制代码
// internal/tui/app.go
func (t *TuiView) Run(searchKeyWord string, showLog bool) {
	t.showLog = showLog
	// 初始化应用程序
	t.app = tview.NewApplication()
	// enable鼠标
	t.app.EnableMouse(false)
	// 创建mainFlex
	t.main = t.CreateMainFlex()
	// 初始化可聚焦组件列表
	t.focusable = []tview.Primitive{t.categoryList, t.bookmarkList, t.descriptionView}
	t.focusIndex = 0
	// 设置根节点
	t.app.SetRoot(t.main, true)
	// 设置焦点
	t.Focus(t.focusable[t.focusIndex])
	// 设置初始焦点组件的边框颜色
	if focusable, ok := t.focusable[t.focusIndex].(interface{ SetBorderColor(tcell.Color) }); ok {
		focusable.SetBorderColor(tcell.ColorSkyblue)
	}
	if err := t.app.Run(); err != nil {
		fmt.Println("TUI启动失败: " + err.Error())
	}
}
4.3.6 对接cobra命令行
go 复制代码
// internal/tui/app.go

// 获取搜索关键字
searchKeyword, _ := cmd.Flags().GetString("search")
// 是否显示日志
show, _ := cmd.Flags().GetBool("showlog")
tui := tui.TuiView{}
tui.Run(searchKeyword, show)

5.效果测试 ✅

运行

bash 复制代码
go run main.go

带日志启动

基本框架搭建完毕,后续就是从数据库中获取数据,渲染到终端上。


往期系列

相关推荐
油腻中年李大鹅3 小时前
使用scheduler-plugins实现自定义调度器
kubernetes·go
DemonAvenger4 小时前
减少内存分配:Go中值类型与指针类型的选择
性能优化·架构·go
Piper蛋窝8 小时前
我所理解的 Go 的 `panic` / `defer` / `recover` 异常处理机制
后端·go
岁忧11 小时前
(nice!!!)(LeetCode每日一题)2434. 使用机器人打印字典序最小的字符串(贪心+栈)
java·c++·算法·leetcode·职场和发展·go
喵个咪14 小时前
MQTT 协议下的Last Will and Testament(LWT,遗嘱消息)
后端·go
海尔辛1 天前
Unity UI 性能优化--Sprite 篇
ui·unity·性能优化
QQ676580081 天前
基于 PyTorch 的 VGG16 深度学习人脸识别检测系统的实现+ui界面
人工智能·pytorch·python·深度学习·ui·人脸识别
pop_xiaoli1 天前
UI学习—cell的复用和自定义cell
学习·ui·ios
DemonAvenger1 天前
Go并发编程:内存同步与竞态处理
性能优化·架构·go