TermKit Documentation

repository·main·Indexed 20 days ago

https://github.com/migueldeicaza/termkit

A Swift-based Terminal UI (TUI) toolkit for building rich, desktop-like interfaces on macOS, Linux, and Windows. It features a layer-backed composition model, a wide range of controls including windows, menus, and a command palette, and supports multiple drivers such as curses, unix, tty, and windows.

Tokens
39.6K
Snippets
142
Records
171
Agent score
68%

What's inside TermKit

  1. What is a ColorScheme and how to create one

    main

    A ColorScheme defines the visual appearance of a view across different states. You create a custom scheme by instantiating ColorScheme() and assigning Attribute objects to its state properties.

    Key properties of ColorScheme:

    • normal: Default appearance.
    • focus: When the view has focus.
    • hotNormal: Appearance of hotkey characters when the view is not focused.
    • hotFocus: Appearance of hotkey characters when the view is focused.
    • disabled: When the view is disabled.
    let scheme = ColorScheme()
    scheme.normal = Application.makeAttribute(fore: .white, back: .blue)
    scheme.focus = Application.makeAttribute(fore: .black, back: .cyan)
    scheme.hotNormal = Application.makeAttribute(fore: .yellow, back: .blue)
    scheme.hotFocus = Application.makeAttribute(fore: .yellow, back: .cyan)
    scheme.disabled = Application.makeAttribute(fore: .brightBlack, back: .blue)
  2. Handle terminal color and cell flag compatibility

    main

    When building cross-platform UIs, be aware of varying terminal capabilities regarding colors and text decorations.

    Color Support

    • Standard Colors: 16 standard colors (e.g., .white, .blue) are safe and work everywhere.
    • Bright Colors: Most modern terminals support bright variants (e.g., .brightWhite, .brightBlue).

    Cell Flags

    • Universal Support: CellFlags.bold, CellFlags.underline, and CellFlags.inverse are widely supported.
    • Variable Support: CellFlags.italic and CellFlags.strikethrough may not render on all terminals. CellFlags.blink is often disabled by terminal emulators.
    // Safe: 16 standard colors work everywhere
    let safeAttr = Application.makeAttribute(
        fore: .white,
        back: .blue
    )
    
    // Bright colors: most terminals
    let brightAttr = Application.makeAttribute(
        fore: .brightWhite,
        back: .brightBlue
    )
  3. How TermKit's layout system works

    main

    TermKit uses a responsive layout system based on Pos (position) and Dim (dimension) objects. Instead of manual pixel-perfect calculations, you define how views should be placed and sized relative to their container or other views. This allows the interface to adapt automatically when the terminal window is resized.

    There are two primary layout styles:

    1. Fixed Layout: Created using View(frame:) with a Rect. Positions are absolute and do not change automatically.
    2. Computed Layout: Created using the default View() initializer. You set x, y, width, and height using Pos and Dim objects. These are recomputed whenever the container resizes.

    TermKit resolves layout dependencies (e.g., View B is positioned relative to View A) using topological sorting, meaning you can define relationships regardless of the order in which views are instantiated, provided there are no circular dependencies.

    // Computed Layout Example
    let button = Button("Click Me")
    button.x = Pos.center()
    button.y = Pos.at(5)
    button.width = Dim.sized(15)
    button.height = Dim.sized(1)
  4. Common UI Patterns: Form, Master-Detail, and Tabbed Preferences

    main

    TermKit supports several common UI layout patterns:

    Form Section

    Use a Frame with Dim.fill() for width to group related input fields like labels and text fields.

    Master-Detail

    Use a SplitView (usually .horizontal) with a ListView in one panel and a Frame (the detail view) in the other.

    Tabbed Preferences

    Use a TabView to organize settings into logical groups like "General" and "Advanced".

    // Master-Detail Pattern Example
    let split = SplitView()
    split.orientation = .horizontal
    split.position = 0.3
    
    let masterList = ListView(items: items)
    let detailView = Frame("Details")
    
    split.addArrangedSubview(masterList)
    split.addArrangedSubview(detailView)
  5. Use the Painter class for custom rendering

    main

    The Painter class is the primary API for custom drawing in TermKit. You access it when overriding drawContent(in:painter:) or redraw within a View. It provides methods for positioning the cursor, adding text, drawing lines, shapes, and managing colors via attributes.

    override func drawContent(in region: Rect, painter: Painter) {
        // Draw using painter
    }
  6. Core Classes in TermKit

    main

    TermKit's architecture is built around several fundamental classes that manage the application lifecycle and view hierarchy:

    • Application: The central entry point used to prepare the environment (prepare()), access the top-level view (top), and start the execution loop (run()).
    • View: The base class for all UI elements, supporting nested subviews.
    • Toplevel: Represents the highest level in the view hierarchy.
    • Window: A container for views, typically representing a distinct UI area.
    • Responder: The base class for handling input events through a responder chain.