Sources/Orgstar/EditorView.swift
47 lines · 1752 bytes
1import AppKit
2import OrgApp
3import OrgEditorAppKit
4import SwiftUI
5
6/// The TextKit 2 editor for the session's file. A new file gets a new editor, which becomes the
7/// session's buffer; reveal requests go to the existing one.
8struct EditorView: NSViewRepresentable {
9 let session: DocumentSession
10
11 final class Coordinator {
12 var editor: OrgEditor?
13 var path: String?
14 var revealID = 0
15 }
16
17 func makeCoordinator() -> Coordinator { Coordinator() }
18
19 func makeNSView(context: Context) -> NSView {
20 NSView()
21 }
22
23 func updateNSView(_ container: NSView, context: Context) {
24 let coordinator = context.coordinator
25 if coordinator.path != session.path {
26 coordinator.path = session.path
27 container.subviews.forEach { $0.removeFromSuperview() }
28 coordinator.editor = nil
29 if let document = session.document {
30 let editor = OrgEditor(document: document, frame: container.bounds, editable: document.isEditable)
31 editor.onChange = { [weak session] in session?.bufferChanged() }
32 let scroll = editor.makeScrollView()
33 scroll.frame = container.bounds
34 scroll.autoresizingMask = [.width, .height]
35 container.addSubview(scroll)
36 container.window?.makeFirstResponder(editor.textView)
37 coordinator.editor = editor
38 session.attach(editor)
39 }
40 }
41 container.window?.isDocumentEdited = session.isDirty
42 if let request = session.revealRequest, request.id != coordinator.revealID {
43 coordinator.revealID = request.id
44 coordinator.editor?.reveal(request.offset)
45 }
46 }
47}