phranck/TUIkit

GitHub: phranck/TUIkit

一个采用 SwiftUI 声明式语法的纯 Swift 终端 UI 框架,无需 ncurses 依赖,支持 macOS 和 Linux 跨平台开发。

Stars: 252 | Forks: 8

[![CI](https://github.com/phranck/TUIkit/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/phranck/TUIkit/actions/workflows/ci.yml) ![Tests](https://img.shields.io/badge/Tests-1172%2B_passing-brightgreen) [![Release](https://img.shields.io/github/v/release/phranck/TUIkit?label=Release)](https://github.com/phranck/TUIkit/releases/latest) ![Swift 6.0](https://img.shields.io/badge/Swift-6.0-F05138?logo=swift&logoColor=white) ![Platforms](https://img.shields.io/badge/Platforms-macOS%20%7C%20Linux-blue) ![License](https://img.shields.io/badge/License-MIT-lightgrey?style=flat) ![i18n](https://img.shields.io/badge/i18n-5%20Languages-orange) ![TUIkit Banner](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/b786f4a542135035.png) # TUIkit 一个用于在 Swift 中构建终端用户界面 (TUI) 的类 SwiftUI 框架:无需 ncurses,无需 C 依赖,仅使用纯 Swift。 ## 这是什么? TUIkit 让你能够使用已在 SwiftUI 中熟知的相同声明式语法来构建 TUI 应用。使用 `View` 定义 UI,通过 `VStack`、`HStack` 和 `ZStack` 组合视图,使用 `.bold()` 和 `.foregroundColor(.red)` 等修饰符设置文本样式,并在终端中运行这一切。 ``` import TUIkit @main struct MyApp: App { var body: some Scene { WindowGroup { ContentView() } } } struct ContentView: View { @State var count = 0 var body: some View { VStack(spacing: 1) { Text("Hello, TUIkit!") .bold() .foregroundColor(.cyan) Text("Count: \(count)") Button("Increment") { count += 1 } } .statusBarItems { StatusBarItem(shortcut: "q", label: "quit") } } } ``` ## 功能特性 ### 核心 - **`View` 协议**:核心构建块,镜像了 SwiftUI 的 `View` - **`@ViewBuilder`**:用于声明式视图组合的结果构建器 - **`@State`**:具有自动重新渲染功能的响应式状态管理 - **`@Environment`**:用于主题、焦点管理器和状态栏的依赖注入 - **`App` 协议**:具有信号处理和运行循环的应用生命周期 ### 视图与组件 - **基础视图**:`Text`、`EmptyView`、`Spacer`、`Divider`、`Image`(ASCII 艺术渲染,多种颜色模式,异步加载) - **布局容器**:`VStack`、`HStack`、`ZStack`、`LazyVStack`、`LazyHStack`,支持对齐和间距 - **交互组件**:`Button`、`Toggle`、`Menu`、`TextField`、`SecureField`、`Slider`、`Stepper`、`RadioButtonGroup`,支持键盘导航 - **数据视图**:`List`、`Table`、`Section`、`ForEach`、`NavigationSplitView` - **容器**:`Alert`、`Dialog`、`Panel`、`Box`、`Card` - **反馈**:`ProgressView`(5 种进度条样式)、`Spinner`(动画) - **`StatusBar`**:上下文敏感的键盘快捷键 ### 样式 - **文本样式**:粗体、斜体、下划线、删除线、暗淡、闪烁、反色 - **全彩色支持**:ANSI 颜色、256 色调色板、24 位 RGB、十六进制值、HSL - **主题**:6 种预定义调色板(绿、琥珀、红、紫、蓝、白) - **边框样式**:圆角、单线、双线、粗体、ASCII 等 - **列表样式**:`PlainListStyle`、`InsetGroupedListStyle`,带交替行 - **徽章**:`.badge()` 修饰符,用于在列表行上显示计数和标签 ### 通知 - **Toast 风格通知**:通过 `.notificationHost()` 修饰符实现的瞬态警报 ### 国际化 (i18n) - **内置 5 种语言**:英语、德语、法语、意大利语、西班牙语 - **类型安全的字符串常量**:编译时验证的 `LocalizationKey` 枚举 - **持久化语言选择**:使用 XDG 路径自动存储 - **回退链**:当前语言 → 英语 → 键名本身 - **线程安全操作**:运行时安全切换语言 ### 高级 - **生命周期修饰符**:`.onAppear()`、`.onDisappear()`、`.task()` - **按键处理**:`.onKeyPress()` 修饰符,用于自定义键盘快捷键 - **存储**:`@AppStorage`、`@SceneStorage`,带 JSON 后端 - **偏好设置**:使用 `PreferenceKey` 的自下而上数据流 - **焦点系统**:Tab/Shift+Tab 导航,`.focusSection()` 用于分组区域 - **渲染缓存**:`.equatable()` 用于子树记忆化 ## 运行示例应用 ``` swift run TUIkitExample ``` 按 `q` 或 `ESC` 退出。 ## 安装 ### 使用 CLI 快速开始 安装 `tuikit` 命令并创建一个新项目: ``` curl -fsSL https://raw.githubusercontent.com/phranck/TUIkit/main/project-template/install.sh | bash tuikit init MyApp cd MyApp && swift run ``` 有关更多选项(SQLite, Swift Testing),请参阅 [project-template/README.md](project-template/README.md)。 ### 手动设置 将 TUIkit 添加到你的 `Package.swift`: ``` dependencies: [ .package(url: "https://github.com/phranck/TUIkit.git", branch: "main") ] ``` 然后将其添加到你的目标: ``` .target( name: "YourApp", dependencies: ["TUIkit"] ) ``` ## 主题 TUIkit 包含受经典终端启发的预定义调色板: ``` @main struct MyApp: App { var body: some Scene { WindowGroup { ContentView() } .palette(SystemPalette(.green)) // Classic green terminal } } ``` 可用的调色板(均通过 `SystemPalette` 访问): - `.green`:经典 P1 荧光粉 CRT(默认) - `.amber`:P3 荧光粉单色 - `.red`:IBM 3279 等离子 - `.violet`:复古科幻终端 - `.blue`:VFD/LCD 显示器 - `.white`:DEC VT100/VT220(P4 荧光粉) ## 国际化 TUIkit 包含全面的 i18n 支持,拥有 5 种语言和类型安全的字符串常量: ``` import TUIkit struct MyView: View { var body: some View { VStack { // Type-safe localized strings Text(localized: LocalizationKey.Button.ok) LocalizedString(LocalizationKey.Error.notFound) // Switch language at runtime Button("Deutsch") { AppState.shared.setLanguage(.german) } } } } ``` **支持的语言**:English, Deutsch, Français, Italiano, Español 有关完整文档,请参阅 DocC 文档中的 [Localization Guide](https://github.com/phranck/TUIkit/blob/main/Sources/TUIkit/TUIkit.docc/Articles/Localization.md)。 ## 架构 - **模块化包**:5 个 Swift 模块 + 1 个 C 目标(见下方项目结构) - **状态无单例**:所有状态都通过 Environment 系统流转 - **纯 ANSI 渲染**:无 ncurses 或其他 C 依赖 - **Linux 兼容**:适用于 macOS 和 Linux(支持 XDG 路径) - **值类型**:视图是结构体,就像 SwiftUI 一样 ## 项目结构 ``` Sources/ ├── CSTBImage/ C bindings for stb_image (PNG/JPEG decoding) ├── TUIkitCore/ Primitives, key events, frame buffer, concurrency helpers ├── TUIkitStyling/ Color, theme palettes, border styles ├── TUIkitView/ View protocol, ViewBuilder, State, Environment, Renderable ├── TUIkitImage/ ASCII art converter, image loading (depends on CSTBImage) ├── TUIkit/ Main module: App, Views, Modifiers, Focus, StatusBar, Notification │ ├── App/ App, Scene, WindowGroup │ ├── Environment/ Environment keys, service configuration │ ├── Focus/ Focus system and keyboard navigation │ ├── Localization/ i18n service, type-safe keys, translation files (5 languages) │ ├── Modifiers/ Border, Frame, Padding, Overlay, Lifecycle, KeyPress │ ├── Notification/ Toast-style notification system │ ├── Rendering/ Terminal, ANSIRenderer, ViewRenderer │ ├── StatusBar/ Context-sensitive keyboard shortcuts │ └── Views/ Text, Stacks, Button, TextField, Slider, List, Image, ... └── TUIkitExample/ Example app (executable target) Tests/ └── TUIkitTests/ 1100+ tests across 150+ test suites (including i18n consistency & localization tests) ``` ## 系统要求 - Swift 6.0+ - macOS 14+ 或 Linux ## 开发者笔记 - 测试使用 Swift Testing(`@Test`、`#expect`):使用 `swift test` 运行 - 所有 1172 个测试并行运行 - `Terminal` 类通过 POSIX `termios` 处理原始模式和光标控制 ## 贡献 ## 许可证 本仓库已在 [MIT](https://mit-license.org) 许可证下发布。
标签:Swift, Swift 6, SwiftUI, TUI, UI框架, 图形界面, 声明式UI, 开发框架, 开源库, 搜索引擎爬虫, 状态管理, 纯Swift, 终端用户界面, 视图构建