Full interactive terminal via SwiftTerm, About sheet, English docs

This commit is contained in:
x3
2026-09-22 10:19:25 +02:00
parent d0855ab45d
commit c657ec2825
15 changed files with 584 additions and 650 deletions
@@ -0,0 +1,65 @@
import SwiftUI
import AppKit
import SwiftTerm
/// Full terminal emulator view (SwiftTerm): cursor addressing, colors,
/// scrollback, selection, and full-screen apps like vim/htop.
/// Keyboard goes straight to the pty (Tab completion, arrows, Ctrl+C, Esc);
/// pty output is fed in via PTYSession.onData. Dracula themed.
struct SwiftTermView: NSViewRepresentable {
@ObservedObject var term: PTYSession
func makeCoordinator() -> Coordinator {
Coordinator(term: term)
}
func makeNSView(context: Context) -> TerminalView {
let view = TerminalView(frame: .zero,
font: .monospacedSystemFont(ofSize: 13, weight: .regular))
view.terminalDelegate = context.coordinator
view.nativeForegroundColor = Dracula.nsColor(for: nil)
view.nativeBackgroundColor = Dracula.nsBackground
let palette = Dracula.ansiPalette
if palette.count == 16 {
view.installColors(palette)
}
context.coordinator.view = view
term.onData = { [weak view] data in
let bytes = Array(data)
DispatchQueue.main.async {
view?.feed(byteArray: bytes[...])
}
}
// Sync current size once the view exists (later resizes via delegate).
DispatchQueue.main.async {
term.setWinsize(cols: view.terminal.cols, rows: view.terminal.rows)
}
return view
}
func updateNSView(_ view: TerminalView, context: Context) {
context.coordinator.term = term
}
final class Coordinator: NSObject, TerminalViewDelegate {
var term: PTYSession?
weak var view: TerminalView?
init(term: PTYSession) {
self.term = term
}
func send(source: TerminalView, data: ArraySlice<UInt8>) {
term?.sendBytes(Data(data))
}
func sizeChanged(source: TerminalView, newCols: Int, newRows: Int) {
term?.setWinsize(cols: newCols, rows: newRows)
}
func setTerminalTitle(source: TerminalView, title: String) {}
func hostCurrentDirectoryUpdate(source: TerminalView, directory: String?) {}
func scrolled(source: TerminalView, position: Double) {}
func rangeChanged(source: TerminalView, startY: Int, endY: Int) {}
}
}