- add README and public API boundary documentation - configure package metadata and CI validation
4.7 KiB
TinyTUI
TinyTUI 是一个面向 .NET 的轻量终端 UI 框架。当前版本已经具备组件树、终端会话、输入解析、keybinding、差分渲染、overlay、ANSI 感知文本工具、自动补全基础、终端图像 fallback 和 xUnit 回归测试基础。
它的设计目标是让应用代码只描述组件和状态变化,框架负责把组件输出合成为终端行数组,并通过渲染器同步到真实终端。
快速开始
当前仓库使用 .NET 10。
dotnet restore ttui.slnx
dotnet run --project src/Example/Example.csproj
最小应用结构如下:
using TinyTUI.Components;
using TinyTUI.Input;
using TinyTUI.Rendering;
using TinyTUI.Runtime;
using TinyTUI.Terminal;
using TinyTUI.Text;
using var terminal = new ConsoleTerminalSession();
var parser = new DefaultInputParser();
var textMeasurer = new TerminalTextMeasurer();
var renderer = new DifferentialRenderer(terminal, textMeasurer);
using var runtime = new TuiRuntime(terminal, parser, renderer);
var input = new Input(textMeasurer) { Prompt = "> " };
var done = new ManualResetEventSlim();
input.OnSubmitted = value =>
{
runtime.Add(new Text($"submitted: {value}"));
input.Clear();
};
input.OnCanceled = done.Set;
runtime.Add(new Text("TinyTUI demo"));
runtime.Add(input);
runtime.SetFocus(input);
runtime.Start();
done.Wait();
runtime.Stop();
核心 API
ITerminalSession 是终端生命周期入口,负责输入事件、输出、尺寸、bracketed paste、光标和终端状态恢复。真实程序通常使用 ConsoleTerminalSession,测试可以实现同一个接口。
TuiRuntime 管理组件树、焦点、overlay、输入分发和渲染请求。应用通过 Add、Remove、SetFocus、ShowOverlay、HideOverlay 和 RequestRender 驱动界面。
IComponent 是最小组件接口,Render(int width) 返回终端行数组。组件输出的每一行都应该控制在 width 内;如果需要截断、切片或换行,优先使用 ITextMeasurer。
IInputComponent 表示可接收输入的组件,IFocusableComponent 表示渲染时可能输出硬件光标 marker 的组件。焦点由 runtime 统一设置,组件只根据 Focused 决定是否输出 marker。
DifferentialRenderer 维护上一帧、视口和变化范围,默认使用 synchronized output、行尾 SGR reset 和 OSC 8 reset 降低闪烁和样式泄漏。FullScreenRenderer 适合需要全量刷新策略的场景。
组件和能力
内置组件包括 Text、Markdown、Box、Spacer、TruncatedText、Input、Editor、SelectList、Loader、CancellableLoader 和 Image。
Overlay 通过 runtime.ShowOverlay(component, options) 显示,支持 anchor、百分比宽度、最大高度、margin 和 non-capturing tooltip。Overlay 在虚拟行数组阶段合成,因此仍复用同一套差分渲染路径。
Keybinding 通过 KeybindingRegistry 和 TuiKeybindings 描述动作到按键的映射。组件内部优先匹配动作名,而不是直接散落比较具体按键字符串。
文本工具集中在 TerminalTextMeasurer,提供 ANSI/OSC 感知的宽度计算、截断、按列切片和换行。自定义组件不要使用 string.Length 判断终端宽度。
自动补全通过 IAutocompleteProvider 扩展。当前 Editor 已支持 slash command provider,并复用 SelectList 展示候选。
图像能力通过 ITerminalImageService 选择 Kitty、iTerm2 或文本 fallback。渲染管线会识别图像行,避免把大段协议序列当普通文本截断。
自定义组件约束
自定义组件应该只返回行数组,不要直接写 stdout。终端写入、清屏、光标移动和 synchronized output 都应该交给 renderer。
如果组件会缓存渲染结果,需要实现 Invalidate() 并在内容、宽度、主题或焦点变化后清理缓存。
如果组件包含输入框或编辑器并需要 IME 光标定位,容器组件应该实现 IFocusableComponent 并把 Focused 传给内部输入组件。
工程命令
dotnet restore ttui.slnx
dotnet build ttui.slnx --configuration Release --no-restore
dotnet format ttui.slnx --verify-no-changes --no-restore
dotnet test ttui.slnx --configuration Release --no-build
dotnet pack src/TinyTUI/TinyTUI.csproj --configuration Release --no-build
test/TinyTUI.Tests 是正式 xUnit 回归测试项目。test/TinyTUI.TextChecks 和 test/TinyTUI.ComponentChecks 是早期最小 smoke check,后续会逐步收敛到正式测试项目。
调试
渲染器支持环境变量调试日志:
$env:TINYTUI_DEBUG_REDRAW = "1"
$env:TINYTUI_DEBUG_RENDER = "1"
dotnet run --project src/Example/Example.csproj
日志默认写入临时目录下的 tinytui 子目录。