import SwiftUI struct CustomTextEditor: NSViewRepresentable { func makeCoordinator() -> Coordinator { Coordinator(self) } @Binding var text: String let font: NSFont let onSubmit: () -> Void func makeNSView(context: Context) -> NSScrollView { let textView = (context.coordinator.theTextView.documentView as! NSTextView) textView.delegate = context.coordinator textView.string = text textView.font = font textView.allowsUndo = true textView.drawsBackground = false return context.coordinator.theTextView } func updateNSView(_ nsView: NSScrollView, context: Context) { let textView = (context.coordinator.theTextView.documentView as! NSTextView) textView.string = text } } extension CustomTextEditor { class Coordinator: NSObject, NSTextViewDelegate { var view: CustomTextEditor var theTextView = NSTextView.scrollableTextView() var affectedCharRange: NSRange? init(_ view: CustomTextEditor) { self.view = view } func textDidChange(_ notification: Notification) { guard let textView = notification.object as? NSTextView else { return } view.text = textView.string } func textView(_ textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool { if commandSelector == #selector(NSTextView.insertNewline(_:)) { if let event = NSApplication.shared.currentEvent, !event.modifierFlags.contains(.shift), event.keyCode == 36 { view.onSubmit() return true } } return false } func textView( _ textView: NSTextView, shouldChangeTextIn affectedCharRange: NSRange, replacementString: String? ) -> Bool { return true } } }