-
Notifications
You must be signed in to change notification settings - Fork 0
Fix multiline Text rendering bug and add DocC documentation #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -24,13 +24,30 @@ jobs: | |||||
|
|
||||||
| - name: Build Documentation | ||||||
| run: | | ||||||
| # Generate documentation for each module | ||||||
| for target in ANSI TerminalCore TerminalStyle TerminalInput TerminalLayout TerminalComponents TerminalGraphics TerminalUI; do | ||||||
| swift package --allow-writing-to-directory ./docs-$target \ | ||||||
| generate-documentation --target $target \ | ||||||
| --disable-indexing \ | ||||||
| --transform-for-static-hosting \ | ||||||
| --hosting-base-path swift-cli/$target \ | ||||||
|
||||||
| --hosting-base-path swift-cli/$target \ | |
| --hosting-base-path swift-cli \ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| # ``ANSI`` | ||
|
|
||
| Pure ANSI escape code generation with zero dependencies. | ||
|
|
||
| ## Overview | ||
|
|
||
| The ANSI module provides type-safe generation of ANSI escape sequences for terminal control. It handles cursor movement, screen clearing, colors, styles, and more - all as pure string generation with no I/O operations. | ||
|
|
||
| ```swift | ||
| import ANSI | ||
|
|
||
| // Control sequences | ||
| let up = ANSI.Cursor.up(5) // Move cursor up 5 lines | ||
| let clear = ANSI.Erase.screen // Clear entire screen | ||
|
|
||
| // Colors and styles | ||
| let red = ANSI.Style.foreground(.red) | ||
| let bold = ANSI.Style.bold | ||
| let reset = ANSI.Style.reset | ||
|
|
||
| // Compose escape sequences | ||
| print("\(red)\(bold)Error!\(reset)") | ||
| ``` | ||
|
|
||
| ## Topics | ||
|
|
||
| ### Escape Sequences | ||
|
|
||
| - ``ANSI`` | ||
|
|
||
| ### Cursor Control | ||
|
|
||
| - ``ANSI/Cursor`` | ||
|
|
||
| ### Screen and Line Erasing | ||
|
|
||
| - ``ANSI/Erase`` | ||
|
|
||
| ### Colors and Styles | ||
|
|
||
| - ``ANSI/Style`` | ||
| - ``ANSI/Color`` | ||
|
|
||
| ### Screen Control | ||
|
|
||
| - ``ANSI/Screen`` | ||
|
|
||
| ### Box Drawing | ||
|
|
||
| - ``ANSI/Box`` | ||
|
|
||
| ### Hyperlinks | ||
|
|
||
| - ``ANSI/Hyperlink`` | ||
|
|
||
| ### Terminal Reports | ||
|
|
||
| - ``ANSI/Report`` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| # ``CLI`` | ||
|
|
||
| A comprehensive Swift toolkit for building beautiful command-line interfaces. | ||
|
|
||
| ## Overview | ||
|
|
||
| SwiftCLI provides a modular architecture for building terminal applications, from simple styled output to full-featured TUI frameworks. Import just what you need, or use the `CLI` umbrella module to access everything. | ||
|
|
||
| ```swift | ||
| import CLI | ||
|
|
||
| @main | ||
| struct MyCLI { | ||
| static func main() async throws { | ||
| let terminal = Terminal.shared | ||
|
|
||
| // Styled output | ||
| await terminal.writeLine("Hello".green.bold + " World!".cyan) | ||
|
|
||
| // Interactive prompts | ||
| let name = try await terminal.input("What's your name?") | ||
| await terminal.success("Hello, \(name)!") | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## Architecture | ||
|
|
||
| SwiftCLI is organized in layers: | ||
|
|
||
| **Foundation Layer** | ||
| - `ANSI` - Pure escape code generation with zero dependencies | ||
|
|
||
| **Core Layer** | ||
| - `TerminalCore` - Low-level terminal I/O, raw mode, capabilities | ||
|
|
||
| **Feature Packages** | ||
| - `TerminalStyle` - Colors, text styles, chainable styling | ||
| - `TerminalInput` - Keyboard input, mouse events, line editing | ||
| - `TerminalLayout` - Boxes, tables, grids, panels | ||
| - `TerminalComponents` - Progress bars, spinners, prompts | ||
| - `TerminalGraphics` - Terminal images (iTerm2, Kitty, Sixel) | ||
|
|
||
| **High-Level Framework** | ||
| - `TerminalUI` - Full TUI framework with SwiftUI-like API | ||
|
|
||
| ## Topics | ||
|
|
||
| ### Terminal | ||
|
|
||
| - ``Terminal`` | ||
| - ``TerminalSize`` | ||
| - ``TerminalCapabilities`` | ||
| - ``TerminalConfiguration`` | ||
| - ``TerminalError`` | ||
|
|
||
| ### Styling | ||
|
|
||
| - ``StyledText`` | ||
| - ``Theme`` | ||
| - ``Gradient`` | ||
|
|
||
| ### Input | ||
|
|
||
| - ``InputEvent`` | ||
| - ``KeyCode`` | ||
| - ``MouseEvent`` | ||
| - ``Modifiers`` | ||
| - ``LineEditor`` | ||
|
|
||
| ### Layout | ||
|
|
||
| - ``Box`` | ||
| - ``Table`` | ||
| - ``Panel`` | ||
| - ``Tree`` | ||
| - ``BoxStyle`` | ||
|
|
||
| ### Components | ||
|
|
||
| - ``Spinner`` | ||
| - ``ProgressBar`` | ||
|
|
||
| ### Graphics | ||
|
|
||
| - ``TerminalImage`` | ||
| - ``ITerm2Image`` | ||
| - ``KittyImage`` | ||
| - ``SixelImage`` | ||
|
|
||
| ### TUI Framework | ||
|
|
||
| - ``View`` | ||
| - ``App`` | ||
| - ``Text`` | ||
| - ``VStack`` | ||
| - ``HStack`` | ||
| - ``ZStack`` | ||
| - ``RenderEngine`` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| # ``TerminalComponents`` | ||
|
|
||
| Progress bars, spinners, prompts, and selection menus for interactive CLI applications. | ||
|
|
||
| ## Overview | ||
|
|
||
| TerminalComponents provides interactive UI components for building rich command-line interfaces. Display progress with animated spinners and progress bars, and gather user input with various prompt types. | ||
|
|
||
| ```swift | ||
| import TerminalComponents | ||
|
|
||
| // Spinner | ||
| let spinner = Spinner(style: .dots, message: "Loading...") | ||
| await spinner.start() | ||
| try await Task.sleep(for: .seconds(2)) | ||
| await spinner.success("Done!") | ||
|
|
||
| // Progress bar | ||
| let progress = ProgressBar(total: 100) | ||
| for i in 0...100 { | ||
| await progress.update(i) | ||
| } | ||
|
|
||
| // Prompts | ||
| let name = try await terminal.input("What's your name?") | ||
| let confirmed = try await terminal.confirm("Continue?") | ||
| let choice = try await terminal.select("Pick one:", options: ["A", "B", "C"]) | ||
| ``` | ||
|
|
||
| ## Topics | ||
|
|
||
| ### Progress Indicators | ||
|
|
||
| - ``Spinner`` | ||
| - ``ProgressBar`` | ||
|
|
||
| ### User Prompts | ||
|
|
||
| - ``Input`` | ||
| - ``Confirm`` | ||
| - ``Select`` | ||
| - ``MultiSelect`` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| # ``TerminalCore`` | ||
|
|
||
| Low-level terminal I/O operations, raw mode, and capability detection. | ||
|
|
||
| ## Overview | ||
|
|
||
| TerminalCore provides the foundation for terminal interaction, including raw mode for character-by-character input, terminal size detection, capability detection, and error handling. It serves as the base layer that other modules build upon. | ||
|
|
||
| ```swift | ||
| import TerminalCore | ||
|
|
||
| let terminal = Terminal.shared | ||
|
|
||
| // Get terminal size | ||
| let size = await terminal.size | ||
| print("Terminal is \(size.width)x\(size.height)") | ||
|
|
||
| // Check capabilities | ||
| let caps = await terminal.capabilities | ||
| if caps.supportsColor { | ||
| print("Color is supported!") | ||
| } | ||
|
|
||
| // Write output | ||
| await terminal.write("Hello, Terminal!") | ||
| await terminal.writeLine("With newline") | ||
| ``` | ||
|
|
||
| ## Topics | ||
|
|
||
| ### Terminal Actor | ||
|
|
||
| - ``Terminal`` | ||
|
|
||
| ### Configuration | ||
|
|
||
| - ``TerminalConfiguration`` | ||
| - ``TerminalCapabilities`` | ||
|
|
||
| ### Size and Dimensions | ||
|
|
||
| - ``TerminalSize`` | ||
| - ``Size`` | ||
|
|
||
| ### Error Handling | ||
|
|
||
| - ``TerminalError`` | ||
|
|
||
| ### Logging | ||
|
|
||
| - ``Logger`` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| # ``TerminalGraphics`` | ||
|
|
||
| Terminal image display using iTerm2, Kitty, and Sixel protocols. | ||
|
|
||
| ## Overview | ||
|
|
||
| TerminalGraphics enables displaying images directly in supported terminal emulators. It supports multiple image protocols including iTerm2's inline images, Kitty's graphics protocol, and the Sixel format. | ||
|
|
||
| ```swift | ||
| import TerminalGraphics | ||
|
|
||
| // Auto-detect best protocol | ||
| let image = try TerminalImage(path: "photo.png") | ||
| await terminal.render(image) | ||
|
|
||
| // Use specific protocol | ||
| let iterm = try ITerm2Image(path: "photo.png") | ||
| let kitty = try KittyImage(path: "photo.png") | ||
| let sixel = try SixelImage(path: "photo.png") | ||
| ``` | ||
|
|
||
| ## Topics | ||
|
|
||
| ### Terminal Images | ||
|
|
||
| - ``TerminalImage`` | ||
|
|
||
| ### Protocol Implementations | ||
|
|
||
| - ``ITerm2Image`` | ||
| - ``KittyImage`` | ||
| - ``SixelImage`` | ||
|
|
||
| ### Image Protocol | ||
|
|
||
| - ``ImageProtocol`` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| # ``TerminalInput`` | ||
|
|
||
| Keyboard input, mouse events, and line editing for interactive terminal applications. | ||
|
|
||
| ## Overview | ||
|
|
||
| TerminalInput handles all forms of user input in terminal applications. It provides keyboard event parsing, mouse event support, modifier key detection, and a full-featured line editor for text input. | ||
|
|
||
| ```swift | ||
| import TerminalInput | ||
|
|
||
| // Read keyboard input | ||
| let event = try await terminal.readEvent() | ||
| switch event { | ||
| case .key(let key, let modifiers): | ||
| if key == .enter { | ||
| print("Enter pressed!") | ||
| } | ||
| case .mouse(let mouse): | ||
| print("Mouse at \(mouse.x), \(mouse.y)") | ||
| } | ||
|
|
||
| // Line editing | ||
| let editor = LineEditor() | ||
| let input = try await editor.readline(prompt: "> ") | ||
| ``` | ||
|
|
||
| ## Topics | ||
|
|
||
| ### Input Events | ||
|
|
||
| - ``InputEvent`` | ||
| - ``KeyCode`` | ||
| - ``Modifiers`` | ||
|
|
||
| ### Mouse Support | ||
|
|
||
| - ``MouseEvent`` | ||
|
|
||
| ### Line Editing | ||
|
|
||
| - ``LineEditor`` | ||
|
|
||
| ### Input Reading | ||
|
|
||
| - ``InputReader`` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The list of targets is duplicated in lines 28 and 46. Consider defining this list once as a variable at the start of the script to avoid maintenance issues if modules are added or removed. For example: