Terminal Surface
TerminalViewState
Main SwiftUI state container. Available on iOS 15, macOS 13, Mac Catalyst 15, and visionOS 1.
@MainActor
public final class TerminalViewState: ObservableObject {
public convenience init()
public convenience init(configFilePath: String?)
public init(
configSource: TerminalController.ConfigSource = .none,
theme: TerminalTheme = .default,
terminalConfiguration: TerminalConfiguration = .init()
)
public init(controller: TerminalController)
@Published public internal(set) var title: String { get }
@Published public internal(set) var surfaceSize: TerminalGridMetrics? { get }
@Published public internal(set) var isFocused: Bool { get }
@Published public internal(set) var bellCount: Int { get }
@Published public internal(set) var lastBellAt: Date? { get }
@Published public internal(set) var lastDesktopNotificationTitle: String? { get }
@Published public internal(set) var lastDesktopNotificationBody: String? { get }
@Published public internal(set) var lastDesktopNotificationAt: Date? { get }
@Published public internal(set) var workingDirectory: String? { get }
@Published public internal(set) var lastCommandExitCode: Int? { get }
@Published public internal(set) var lastCommandDurationNanos: UInt64? { get }
@Published public internal(set) var scrollbar: TerminalScrollbar? { get }
public internal(set) weak var surface: TerminalSurface? { get }
@Published public var configuration: TerminalSurfaceOptions
/// False stops rendering for a surface kept mounted but hidden; the
/// grid, scrollback, and session are kept.
@Published public var isSurfaceVisible: Bool
public var onClose: ((Bool) -> Void)?
@Published public internal(set) var controller: TerminalController { get }
/// The platform view presenting this state; nil while none does.
public var attachedPlatformView: TerminalView? { get }
/// Factory for a TerminalView subclass; read once, when the surface
/// view is made.
public var makePlatformView: (@MainActor () -> TerminalView)?
#if canImport(UIKit)
#if !targetEnvironment(macCatalyst)
/// nil shows TerminalInputAccessoryItem.defaultItems; [] hides the bar.
@Published public var inputAccessoryItems: [TerminalInputAccessoryItem]?
#endif
#endif
/// Opt-in for the iOS long-press text-selection flow.
public var onTextSelectionRequest: ((TerminalTextSelectionRequest) -> Void)?
/// Presents OSC 52 reads/writes and flagged pastes; nil denies a
/// program's request silently and allows a user paste.
public var onClipboardConfirmationRequest: ((TerminalClipboardConfirmationRequest) -> Void)?
public var renderedConfig: String { get }
public var effectiveColorScheme: TerminalColorScheme { get }
public var theme: TerminalTheme { get }
public var terminalConfiguration: TerminalConfiguration { get }
public func paste(text: String) -> Bool
public func sendKey(_ press: TerminalKeyPress) -> Bool
public func sendKey(_ key: TerminalKey, modifiers: TerminalInputModifiers = []) -> Bool
@available(*, deprecated, renamed: "paste(text:)")
public func send(_ text: String) -> Bool
public func requestFocus()
public func performBindingAction(_ action: String) -> Bool
public func jumpToPrompt(by offset: Int16) -> Bool
public func scrollToRow(_ row: UInt) -> Bool
public var isMouseCaptured: Bool { get }
public func sendMousePos(x: Double, y: Double, modifiers: TerminalInputModifiers = [])
public func sendMouseButton(
state: ghostty_input_mouse_state_e,
button: ghostty_input_mouse_button_e,
modifiers: TerminalInputModifiers = []
) -> Bool
public func sendMouseScroll(
x: Double,
y: Double,
mods: TerminalScrollModifiers = TerminalScrollModifiers(precision: true)
)
public func adopt(colorScheme: ColorScheme)
public func adopt(terminalColorScheme colorScheme: TerminalColorScheme)
public func setTheme(_ theme: TerminalTheme) -> Bool
public func setTerminalConfiguration(_ configuration: TerminalConfiguration) -> Bool
}
controller exposes a projected publisher for source compatibility. SwiftUI integrations should observe configuration changes through TerminalViewState and mutate the view state rather than the controller.
TerminalSurfaceView
public struct TerminalSurfaceView: View {
public init(context: TerminalViewState)
}
TerminalView
#if canImport(UIKit)
public typealias TerminalView = UITerminalView
#elseif canImport(AppKit)
public typealias TerminalView = AppTerminalView
#endif
TerminalController
@MainActor
public final class TerminalController {
public enum ConfigSource: Sendable, Hashable {
case none
case file(String)
case generated(String)
}
public var currentConfigSource: ConfigSource { get }
public var renderedConfig: String { get }
public private(set) var terminalConfiguration: TerminalConfiguration { get }
public private(set) var theme: TerminalTheme { get }
public private(set) var effectiveColorScheme: TerminalColorScheme { get }
public internal(set) var lastConfigurationIssue: String? { get }
public static let shared: TerminalController
/// The default configuration.
public convenience init()
/// A fully custom configuration, rendered as the config source.
public convenience init(
configuration: TerminalConfiguration,
theme: TerminalTheme = .default
)
/// Commands composed on top of the default configuration.
public convenience init(
theme: TerminalTheme = .default,
configure: (inout TerminalConfiguration.Builder) -> Void
)
/// Loads the configuration from a file; nil means no file.
public convenience init(
configFilePath: String?,
theme: TerminalTheme = .default
)
/// Low-level initialiser for full control over the config source.
public init(
configSource: ConfigSource = .none,
theme: TerminalTheme = .default,
terminalConfiguration: TerminalConfiguration = .init()
)
public func setColorScheme(_ scheme: TerminalColorScheme)
public func setTheme(_ theme: TerminalTheme) -> Bool
public func setTerminalConfiguration(_ configuration: TerminalConfiguration) -> Bool
public func tick()
}
InMemoryTerminalSession
public final class InMemoryTerminalSession: @unchecked Sendable {
public init(
write: @escaping @Sendable (Data) -> Void,
resize: @escaping @Sendable (InMemoryTerminalViewport) -> Void
)
public func readViewportText() -> String?
public func receive(_ data: Data)
public func receive(_ string: String)
public func sendInput(_ data: Data)
public func finish(exitCode: UInt32, runtimeMilliseconds: UInt64)
}
Delegates
@MainActor public protocol TerminalSurfaceTitleDelegate {
func terminalDidChangeTitle(_ title: String)
}
@MainActor public protocol TerminalSurfaceGridResizeDelegate {
func terminalDidResize(_ size: TerminalGridMetrics)
}
@MainActor public protocol TerminalSurfaceBellDelegate {
func terminalDidRingBell()
}
@MainActor public protocol TerminalSurfaceCloseDelegate {
func terminalDidClose(processAlive: Bool)
}
@MainActor public protocol TerminalSurfaceTextSelectionRequestDelegate {
func terminalDidRequestTextSelection(_ request: TerminalTextSelectionRequest)
}
@MainActor public protocol TerminalSurfaceLifecycleDelegate {
func terminalDidAttachSurface(_ surface: TerminalSurface)
func terminalDidDetachSurface()
}