diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 8cb5f65..e8fb3aa 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -24,6 +24,17 @@ 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 \ + --output-path ./docs-$target + done + + # Generate CLI umbrella documentation as landing page swift package --allow-writing-to-directory ./docs \ generate-documentation --target CLI \ --disable-indexing \ @@ -31,6 +42,12 @@ jobs: --hosting-base-path swift-cli \ --output-path ./docs + # Merge module docs into main docs folder + for target in ANSI TerminalCore TerminalStyle TerminalInput TerminalLayout TerminalComponents TerminalGraphics TerminalUI; do + cp -r ./docs-$target/data/documentation/* ./docs/data/documentation/ 2>/dev/null || true + cp -r ./docs-$target/documentation/* ./docs/documentation/ 2>/dev/null || true + done + - name: Upload artifact uses: actions/upload-pages-artifact@v3 with: diff --git a/Sources/ANSI/Documentation.docc/ANSI.md b/Sources/ANSI/Documentation.docc/ANSI.md new file mode 100644 index 0000000..1272ee5 --- /dev/null +++ b/Sources/ANSI/Documentation.docc/ANSI.md @@ -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`` diff --git a/Sources/CLI/Documentation.docc/CLI.md b/Sources/CLI/Documentation.docc/CLI.md new file mode 100644 index 0000000..bf413a3 --- /dev/null +++ b/Sources/CLI/Documentation.docc/CLI.md @@ -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`` diff --git a/Sources/TerminalComponents/Documentation.docc/TerminalComponents.md b/Sources/TerminalComponents/Documentation.docc/TerminalComponents.md new file mode 100644 index 0000000..6ca0664 --- /dev/null +++ b/Sources/TerminalComponents/Documentation.docc/TerminalComponents.md @@ -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`` diff --git a/Sources/TerminalCore/Documentation.docc/TerminalCore.md b/Sources/TerminalCore/Documentation.docc/TerminalCore.md new file mode 100644 index 0000000..b827131 --- /dev/null +++ b/Sources/TerminalCore/Documentation.docc/TerminalCore.md @@ -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`` diff --git a/Sources/TerminalGraphics/Documentation.docc/TerminalGraphics.md b/Sources/TerminalGraphics/Documentation.docc/TerminalGraphics.md new file mode 100644 index 0000000..6fde7a5 --- /dev/null +++ b/Sources/TerminalGraphics/Documentation.docc/TerminalGraphics.md @@ -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`` diff --git a/Sources/TerminalInput/Documentation.docc/TerminalInput.md b/Sources/TerminalInput/Documentation.docc/TerminalInput.md new file mode 100644 index 0000000..ab24f02 --- /dev/null +++ b/Sources/TerminalInput/Documentation.docc/TerminalInput.md @@ -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`` diff --git a/Sources/TerminalLayout/Documentation.docc/TerminalLayout.md b/Sources/TerminalLayout/Documentation.docc/TerminalLayout.md new file mode 100644 index 0000000..ee681e3 --- /dev/null +++ b/Sources/TerminalLayout/Documentation.docc/TerminalLayout.md @@ -0,0 +1,58 @@ +# ``TerminalLayout`` + +Boxes, tables, grids, panels, and tree views for structured terminal output. + +## Overview + +TerminalLayout provides components for creating structured, bordered output in the terminal. Build tables, panels, tree views, and decorated boxes with various border styles. + +```swift +import TerminalLayout + +// Simple box +let box = Box("Hello, World!", style: .rounded) +await terminal.render(box) + +// Table +let table = Table( + headers: ["Name", "Age"], + rows: [ + ["Alice", "30"], + ["Bob", "25"] + ] +) +await terminal.render(table) + +// Tree view +let tree = Tree("Root") { + Tree("Child 1") + Tree("Child 2") { + Tree("Grandchild") + } +} +await terminal.render(tree) +``` + +## Topics + +### Boxes and Panels + +- ``Box`` +- ``Panel`` +- ``BoxStyle`` + +### Tables + +- ``Table`` + +### Tree Views + +- ``Tree`` + +### Dividers + +- ``TerminalLayout/Divider`` + +### Rendering Protocol + +- ``Renderable`` diff --git a/Sources/TerminalStyle/Documentation.docc/TerminalStyle.md b/Sources/TerminalStyle/Documentation.docc/TerminalStyle.md new file mode 100644 index 0000000..3123814 --- /dev/null +++ b/Sources/TerminalStyle/Documentation.docc/TerminalStyle.md @@ -0,0 +1,45 @@ +# ``TerminalStyle`` + +Colors, text styles, and chainable styling API for terminal output. + +## Overview + +TerminalStyle provides a fluent API for styling terminal text with colors and text attributes. Chain multiple styles together and apply them to strings for rich, colorful terminal output. + +```swift +import TerminalStyle + +// Chainable styling +let styled = "Hello".red.bold.underline +let warning = "Warning".yellow.on(.black) + +// Gradient text +let gradient = Gradient.rainbow("Rainbow text!") + +// Using StyledText directly +let text = StyledText("Custom") + .foreground(.cyan) + .background(.blue) + .bold() + +// Print styled output +await terminal.writeLine(styled) +``` + +## Topics + +### Styled Text + +- ``StyledText`` + +### Themes + +- ``Theme`` + +### Gradients + +- ``Gradient`` + +### String Extensions + +String styling is available through extensions that add properties like `.red`, `.bold`, `.underline`, etc. diff --git a/Sources/TerminalUI/Documentation.docc/TerminalUI.md b/Sources/TerminalUI/Documentation.docc/TerminalUI.md new file mode 100644 index 0000000..d8e3a51 --- /dev/null +++ b/Sources/TerminalUI/Documentation.docc/TerminalUI.md @@ -0,0 +1,72 @@ +# ``TerminalUI`` + +A SwiftUI-inspired framework for building terminal user interfaces. + +## Overview + +TerminalUI provides a declarative, SwiftUI-like API for building terminal user interfaces. Compose views using familiar patterns like VStack, HStack, and view modifiers. + +```swift +import TerminalUI + +struct MyView: View { + var body: some View { + VStack { + Text("Hello").bold() + HStack { + Text("Left").red() + Text("Right").blue() + } + } + .border(.rounded, title: "Welcome") + .padding() + } +} + +// Render the view +let output = RenderEngine.renderString(MyView(), size: Size(width: 80, height: 24)) +print(output) +``` + +## Topics + +### App Structure + +- ``App`` +- ``View`` +- ``ViewBuilder`` + +### Layout Containers + +- ``VStack`` +- ``HStack`` +- ``ZStack`` + +### Basic Views + +- ``Text`` +- ``EmptyView`` +- ``TerminalUI/Divider`` +- ``Spacer`` +- ``ForEach`` + +### View Modifiers + +- ``Padding`` +- ``Border`` + +### Progress Views + +- ``ProgressView`` +- ``ProgressBarView`` +- ``SpinnerView`` + +### System Information + +- ``SystemMetrics`` + +### Rendering + +- ``RenderEngine`` +- ``RenderBuffer`` +- ``DifferentialRenderer`` diff --git a/Sources/TerminalUI/RenderEngine.swift b/Sources/TerminalUI/RenderEngine.swift index 7edd010..f3738fc 100644 --- a/Sources/TerminalUI/RenderEngine.swift +++ b/Sources/TerminalUI/RenderEngine.swift @@ -18,7 +18,8 @@ public struct RenderEngine: Sendable { private static func renderView(_ view: V, size: Size) -> [String] { // Handle primitive views if let text = view as? Text { - return [text.toStyledText().render()] + let rendered = text.toStyledText().render() + return rendered.split(separator: "\n", omittingEmptySubsequences: false).map(String.init) } if view is EmptyView {