krz/orgstar

A native macOS editor for org-mode files. editor org-mode swift

Sources/Orgstar/EditorView.swift

056befa97fffa110959cb6010c1986461c09dc0b
orgstar/Sources/Orgstar/EditorView.swift history · blame · raw

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}