Full interactive terminal via SwiftTerm, About sheet, English docs
This commit is contained in:
@@ -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) {}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user