From abb2cdce8f490ffdac2520b80ceca6bc1e58cd22 Mon Sep 17 00:00:00 2001 From: Khan Winter <35942988+thecoolwinter@users.noreply.github.com> Date: Mon, 20 May 2024 16:57:44 -0500 Subject: [PATCH 1/3] Add NSTextStorage init API --- .../CodeEditSourceEditor.swift | 153 +++++++++++++++--- .../Controller/TextViewController.swift | 54 +++++++ .../Coordinators/CombineCoordinator.swift | 32 ++++ .../TextViewCoordinator.swift | 4 +- 4 files changed, 216 insertions(+), 27 deletions(-) create mode 100644 Sources/CodeEditSourceEditor/Coordinators/CombineCoordinator.swift diff --git a/Sources/CodeEditSourceEditor/CodeEditSourceEditor.swift b/Sources/CodeEditSourceEditor/CodeEditSourceEditor.swift index 99221d9b1..b4717d973 100644 --- a/Sources/CodeEditSourceEditor/CodeEditSourceEditor.swift +++ b/Sources/CodeEditSourceEditor/CodeEditSourceEditor.swift @@ -5,11 +5,16 @@ // Created by Lukas Pistrol on 24.05.22. // +import AppKit import SwiftUI import CodeEditTextView import CodeEditLanguages public struct CodeEditSourceEditor: NSViewControllerRepresentable { + private enum TextAPI { + case binding(Binding) + case storage(NSTextStorage) + } /// Initializes a Text Editor /// - Parameters: @@ -22,7 +27,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable { /// - lineHeight: The line height multiplier (e.g. `1.2`) /// - wrapLines: Whether lines wrap to the width of the editor /// - editorOverscroll: The distance to overscroll the editor by. - /// - cursorPosition: The cursor's position in the editor, measured in `(lineNum, columnNum)` + /// - cursorPositions: The cursor's position in the editor, measured in `(lineNum, columnNum)` /// - useThemeBackground: Determines whether the editor uses the theme's background color, or a transparent /// background color /// - highlightProvider: A class you provide to perform syntax highlighting. Leave this as `nil` to use the @@ -37,6 +42,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable { /// - bracketPairHighlight: The type of highlight to use to highlight bracket pairs. /// See `BracketPairHighlight` for more information. Defaults to `nil` /// - undoManager: The undo manager for the text view. Defaults to `nil`, which will create a new CEUndoManager + /// - coordinators: Any text coordinators for the textview to use. See ``TextViewCoordinator`` for more information. public init( _ text: Binding, language: CodeLanguage, @@ -58,7 +64,76 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable { undoManager: CEUndoManager? = nil, coordinators: [any TextViewCoordinator] = [] ) { - self._text = text + self.text = .binding(text) + self.language = language + self.theme = theme + self.useThemeBackground = useThemeBackground + self.font = font + self.tabWidth = tabWidth + self.indentOption = indentOption + self.lineHeight = lineHeight + self.wrapLines = wrapLines + self.editorOverscroll = editorOverscroll + self._cursorPositions = cursorPositions + self.highlightProvider = highlightProvider + self.contentInsets = contentInsets + self.isEditable = isEditable + self.isSelectable = isSelectable + self.letterSpacing = letterSpacing + self.bracketPairHighlight = bracketPairHighlight + self.undoManager = undoManager + self.coordinators = coordinators + } + + /// Initializes a Text Editor + /// - Parameters: + /// - text: The text content + /// - language: The language for syntax highlighting + /// - theme: The theme for syntax highlighting + /// - font: The default font + /// - tabWidth: The visual tab width in number of spaces + /// - indentOption: The behavior to use when the tab key is pressed. Defaults to 4 spaces. + /// - lineHeight: The line height multiplier (e.g. `1.2`) + /// - wrapLines: Whether lines wrap to the width of the editor + /// - editorOverscroll: The distance to overscroll the editor by. + /// - cursorPositions: The cursor's position in the editor, measured in `(lineNum, columnNum)` + /// - useThemeBackground: Determines whether the editor uses the theme's background color, or a transparent + /// background color + /// - highlightProvider: A class you provide to perform syntax highlighting. Leave this as `nil` to use the + /// built-in `TreeSitterClient` highlighter. + /// - contentInsets: Insets to use to offset the content in the enclosing scroll view. Leave as `nil` to let the + /// scroll view automatically adjust content insets. + /// - isEditable: A Boolean value that controls whether the text view allows the user to edit text. + /// - isSelectable: A Boolean value that controls whether the text view allows the user to select text. If this + /// value is true, and `isEditable` is false, the editor is selectable but not editable. + /// - letterSpacing: The amount of space to use between letters, as a percent. Eg: `1.0` = no space, `1.5` = 1/2 a + /// character's width between characters, etc. Defaults to `1.0` + /// - bracketPairHighlight: The type of highlight to use to highlight bracket pairs. + /// See `BracketPairHighlight` for more information. Defaults to `nil` + /// - undoManager: The undo manager for the text view. Defaults to `nil`, which will create a new CEUndoManager + /// - coordinators: Any text coordinators for the textview to use. See ``TextViewCoordinator`` for more information. + public init( + _ text: NSTextStorage, + language: CodeLanguage, + theme: EditorTheme, + font: NSFont, + tabWidth: Int, + indentOption: IndentOption = .spaces(count: 4), + lineHeight: Double, + wrapLines: Bool, + editorOverscroll: CGFloat = 0, + cursorPositions: Binding<[CursorPosition]>, + useThemeBackground: Bool = true, + highlightProvider: HighlightProviding? = nil, + contentInsets: NSEdgeInsets? = nil, + isEditable: Bool = true, + isSelectable: Bool = true, + letterSpacing: Double = 1.0, + bracketPairHighlight: BracketPairHighlight? = nil, + undoManager: CEUndoManager? = nil, + coordinators: [any TextViewCoordinator] = [] + ) { + self.text = .storage(text) self.language = language self.theme = theme self.useThemeBackground = useThemeBackground @@ -79,7 +154,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable { self.coordinators = coordinators } - @Binding private var text: String + private var text: TextAPI private var language: CodeLanguage private var theme: EditorTheme private var font: NSFont @@ -102,26 +177,51 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable { public typealias NSViewControllerType = TextViewController public func makeNSViewController(context: Context) -> TextViewController { - let controller = TextViewController( - string: text, - language: language, - font: font, - theme: theme, - tabWidth: tabWidth, - indentOption: indentOption, - lineHeight: lineHeight, - wrapLines: wrapLines, - cursorPositions: cursorPositions, - editorOverscroll: editorOverscroll, - useThemeBackground: useThemeBackground, - highlightProvider: highlightProvider, - contentInsets: contentInsets, - isEditable: isEditable, - isSelectable: isSelectable, - letterSpacing: letterSpacing, - bracketPairHighlight: bracketPairHighlight, - undoManager: undoManager - ) + let controller: TextViewController + switch text { + case .binding(let binding): + controller = TextViewController( + string: binding.wrappedValue, + language: language, + font: font, + theme: theme, + tabWidth: tabWidth, + indentOption: indentOption, + lineHeight: lineHeight, + wrapLines: wrapLines, + cursorPositions: cursorPositions, + editorOverscroll: editorOverscroll, + useThemeBackground: useThemeBackground, + highlightProvider: highlightProvider, + contentInsets: contentInsets, + isEditable: isEditable, + isSelectable: isSelectable, + letterSpacing: letterSpacing, + bracketPairHighlight: bracketPairHighlight, + undoManager: undoManager + ) + case .storage(let textStorage): + controller = TextViewController( + storage: textStorage, + language: language, + font: font, + theme: theme, + tabWidth: tabWidth, + indentOption: indentOption, + lineHeight: lineHeight, + wrapLines: wrapLines, + cursorPositions: cursorPositions, + editorOverscroll: editorOverscroll, + useThemeBackground: useThemeBackground, + highlightProvider: highlightProvider, + contentInsets: contentInsets, + isEditable: isEditable, + isSelectable: isSelectable, + letterSpacing: letterSpacing, + bracketPairHighlight: bracketPairHighlight, + undoManager: undoManager + ) + } if controller.textView == nil { controller.loadView() } @@ -245,13 +345,16 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable { @objc func textViewDidChangeText(_ notification: Notification) { guard let textView = notification.object as? TextView, + let ranges = notification.userInfo?[TextView.textDidChangeRangeKey] as? [NSRange], let controller, controller.textView === textView else { return } - parent.text = textView.string + if case .binding(let binding) = parent.text { + binding.wrappedValue = textView.string + } parent.coordinators.forEach { - $0.textViewDidChangeText(controller: controller) + $0.textViewDidChangeText(controller: controller, editedRanges: ranges) } } diff --git a/Sources/CodeEditSourceEditor/Controller/TextViewController.swift b/Sources/CodeEditSourceEditor/Controller/TextViewController.swift index b1bf93b87..fac690ba2 100644 --- a/Sources/CodeEditSourceEditor/Controller/TextViewController.swift +++ b/Sources/CodeEditSourceEditor/Controller/TextViewController.swift @@ -233,6 +233,60 @@ public class TextViewController: NSViewController { ) } + init( + storage: NSTextStorage, + language: CodeLanguage, + font: NSFont, + theme: EditorTheme, + tabWidth: Int, + indentOption: IndentOption, + lineHeight: CGFloat, + wrapLines: Bool, + cursorPositions: [CursorPosition], + editorOverscroll: CGFloat, + useThemeBackground: Bool, + highlightProvider: HighlightProviding?, + contentInsets: NSEdgeInsets?, + isEditable: Bool, + isSelectable: Bool, + letterSpacing: Double, + bracketPairHighlight: BracketPairHighlight?, + undoManager: CEUndoManager? = nil + ) { + self.language = language + self.font = font + self.theme = theme + self.tabWidth = tabWidth + self.indentOption = indentOption + self.lineHeightMultiple = lineHeight + self.wrapLines = wrapLines + self.cursorPositions = cursorPositions + self.editorOverscroll = editorOverscroll + self.useThemeBackground = useThemeBackground + self.highlightProvider = highlightProvider + self.contentInsets = contentInsets + self.isEditable = isEditable + self.isSelectable = isSelectable + self.letterSpacing = letterSpacing + self.bracketPairHighlight = bracketPairHighlight + self._undoManager = undoManager + + super.init(nibName: nil, bundle: nil) + + self.textView = TextView( + string: "", + font: font, + textColor: theme.text, + lineHeightMultiplier: lineHeightMultiple, + wrapLines: wrapLines, + isEditable: isEditable, + isSelectable: isSelectable, + letterSpacing: letterSpacing, + delegate: self + ) + self.textView.setTextStorage(storage) + } + required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } diff --git a/Sources/CodeEditSourceEditor/Coordinators/CombineCoordinator.swift b/Sources/CodeEditSourceEditor/Coordinators/CombineCoordinator.swift new file mode 100644 index 000000000..bf300a736 --- /dev/null +++ b/Sources/CodeEditSourceEditor/Coordinators/CombineCoordinator.swift @@ -0,0 +1,32 @@ +// +// CombineCoordinator.swift +// CodeEditSourceEditor +// +// Created by Khan Winter on 5/19/24. +// + +import Foundation +import Combine +import CodeEditTextView + +public class CombineCoordinator: TextViewCoordinator { + public let updateSubject: PassthroughSubject<[NSRange], Never> = .init() + public let selectionSubject: CurrentValueSubject<[CursorPosition], Never> = .init([]) + + public init() { } + + public func prepareCoordinator(controller: TextViewController) { } + + public func textViewDidChangeText(controller: TextViewController, editedRanges: [NSRange]) { + updateSubject.send(editedRanges) + } + + public func textViewDidChangeSelection(controller: TextViewController, newPositions: [CursorPosition]) { + selectionSubject.send(newPositions) + } + + public func destroy() { + updateSubject.send(completion: .finished) + selectionSubject.send(completion: .finished) + } +} diff --git a/Sources/CodeEditSourceEditor/TextViewCoordinator.swift b/Sources/CodeEditSourceEditor/TextViewCoordinator.swift index 98c553cd5..ca4c49109 100644 --- a/Sources/CodeEditSourceEditor/TextViewCoordinator.swift +++ b/Sources/CodeEditSourceEditor/TextViewCoordinator.swift @@ -22,7 +22,7 @@ public protocol TextViewCoordinator: AnyObject { /// Called when the text view's text changed. /// - Parameter controller: The text controller. - func textViewDidChangeText(controller: TextViewController) + func textViewDidChangeText(controller: TextViewController, editedRanges: [NSRange]) /// Called after the text view updated it's cursor positions. /// - Parameter newPositions: The new positions of the cursors. @@ -34,7 +34,7 @@ public protocol TextViewCoordinator: AnyObject { /// Default implementations public extension TextViewCoordinator { - func textViewDidChangeText(controller: TextViewController) { } + func textViewDidChangeText(controller: TextViewController, editedRanges: [NSRange]) { } func textViewDidChangeSelection(controller: TextViewController, newPositions: [CursorPosition]) { } func destroy() { } } From a3f95a9865389490cf803fb9a5ec3ca6647768db Mon Sep 17 00:00:00 2001 From: Khan Winter <35942988+thecoolwinter@users.noreply.github.com> Date: Mon, 20 May 2024 17:53:30 -0500 Subject: [PATCH 2/3] Documentation, Organization --- .../CodeEditSourceEditor+Coordinator.swift | 74 +++++++++ .../CodeEditSourceEditor.swift | 148 ++++-------------- .../Controller/TextViewController.swift | 54 ------- .../Coordinators/CombineCoordinator.swift | 32 ---- ...ditTextView.md => CodeEditSourceEditor.md} | 0 .../Documentation.docc/Documentation.md | 36 +++-- .../TextViewCoordinators.md | 66 ++++++++ .../CombineCoordinator.swift | 48 ++++++ .../TextViewCoordinator.swift | 4 +- 9 files changed, 246 insertions(+), 216 deletions(-) create mode 100644 Sources/CodeEditSourceEditor/CodeEditSourceEditor/CodeEditSourceEditor+Coordinator.swift rename Sources/CodeEditSourceEditor/{ => CodeEditSourceEditor}/CodeEditSourceEditor.swift (72%) delete mode 100644 Sources/CodeEditSourceEditor/Coordinators/CombineCoordinator.swift rename Sources/CodeEditSourceEditor/Documentation.docc/{CodeEditTextView.md => CodeEditSourceEditor.md} (100%) create mode 100644 Sources/CodeEditSourceEditor/Documentation.docc/TextViewCoordinators.md create mode 100644 Sources/CodeEditSourceEditor/TextViewCoordinator/CombineCoordinator.swift rename Sources/CodeEditSourceEditor/{ => TextViewCoordinator}/TextViewCoordinator.swift (89%) diff --git a/Sources/CodeEditSourceEditor/CodeEditSourceEditor/CodeEditSourceEditor+Coordinator.swift b/Sources/CodeEditSourceEditor/CodeEditSourceEditor/CodeEditSourceEditor+Coordinator.swift new file mode 100644 index 000000000..645c13de3 --- /dev/null +++ b/Sources/CodeEditSourceEditor/CodeEditSourceEditor/CodeEditSourceEditor+Coordinator.swift @@ -0,0 +1,74 @@ +// +// CodeEditSourceEditor+Coordinator.swift +// CodeEditSourceEditor +// +// Created by Khan Winter on 5/20/24. +// + +import Foundation +import CodeEditTextView + +extension CodeEditSourceEditor { + @MainActor + public class Coordinator: NSObject { + var parent: CodeEditSourceEditor + weak var controller: TextViewController? + var isUpdatingFromRepresentable: Bool = false + var isUpdateFromTextView: Bool = false + + init(parent: CodeEditSourceEditor) { + self.parent = parent + super.init() + + NotificationCenter.default.addObserver( + self, + selector: #selector(textViewDidChangeText(_:)), + name: TextView.textDidChangeNotification, + object: nil + ) + + NotificationCenter.default.addObserver( + self, + selector: #selector(textControllerCursorsDidUpdate(_:)), + name: TextViewController.cursorPositionUpdatedNotification, + object: nil + ) + } + + @objc func textViewDidChangeText(_ notification: Notification) { + guard let textView = notification.object as? TextView, + let controller, + controller.textView === textView else { + return + } + if case .binding(let binding) = parent.text { + binding.wrappedValue = textView.string + } + parent.coordinators.forEach { + $0.textViewDidChangeText(controller: controller) + } + } + + @objc func textControllerCursorsDidUpdate(_ notification: Notification) { + guard !isUpdatingFromRepresentable else { return } + self.isUpdateFromTextView = true + self.parent.cursorPositions.wrappedValue = self.controller?.cursorPositions ?? [] + if self.controller != nil { + self.parent.coordinators.forEach { + $0.textViewDidChangeSelection( + controller: self.controller!, + newPositions: self.controller!.cursorPositions + ) + } + } + } + + deinit { + parent.coordinators.forEach { + $0.destroy() + } + parent.coordinators.removeAll() + NotificationCenter.default.removeObserver(self) + } + } +} diff --git a/Sources/CodeEditSourceEditor/CodeEditSourceEditor.swift b/Sources/CodeEditSourceEditor/CodeEditSourceEditor/CodeEditSourceEditor.swift similarity index 72% rename from Sources/CodeEditSourceEditor/CodeEditSourceEditor.swift rename to Sources/CodeEditSourceEditor/CodeEditSourceEditor/CodeEditSourceEditor.swift index b4717d973..cf1f5e4dd 100644 --- a/Sources/CodeEditSourceEditor/CodeEditSourceEditor.swift +++ b/Sources/CodeEditSourceEditor/CodeEditSourceEditor/CodeEditSourceEditor.swift @@ -10,8 +10,9 @@ import SwiftUI import CodeEditTextView import CodeEditLanguages +/// A SwiftUI View that provides source editing functionality. public struct CodeEditSourceEditor: NSViewControllerRepresentable { - private enum TextAPI { + package enum TextAPI { case binding(Binding) case storage(NSTextStorage) } @@ -42,7 +43,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable { /// - bracketPairHighlight: The type of highlight to use to highlight bracket pairs. /// See `BracketPairHighlight` for more information. Defaults to `nil` /// - undoManager: The undo manager for the text view. Defaults to `nil`, which will create a new CEUndoManager - /// - coordinators: Any text coordinators for the textview to use. See ``TextViewCoordinator`` for more information. + /// - coordinators: Any text coordinators for the view to use. See ``TextViewCoordinator`` for more information. public init( _ text: Binding, language: CodeLanguage, @@ -74,7 +75,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable { self.lineHeight = lineHeight self.wrapLines = wrapLines self.editorOverscroll = editorOverscroll - self._cursorPositions = cursorPositions + self.cursorPositions = cursorPositions self.highlightProvider = highlightProvider self.contentInsets = contentInsets self.isEditable = isEditable @@ -111,7 +112,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable { /// - bracketPairHighlight: The type of highlight to use to highlight bracket pairs. /// See `BracketPairHighlight` for more information. Defaults to `nil` /// - undoManager: The undo manager for the text view. Defaults to `nil`, which will create a new CEUndoManager - /// - coordinators: Any text coordinators for the textview to use. See ``TextViewCoordinator`` for more information. + /// - coordinators: Any text coordinators for the view to use. See ``TextViewCoordinator`` for more information. public init( _ text: NSTextStorage, language: CodeLanguage, @@ -143,7 +144,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable { self.lineHeight = lineHeight self.wrapLines = wrapLines self.editorOverscroll = editorOverscroll - self._cursorPositions = cursorPositions + self.cursorPositions = cursorPositions self.highlightProvider = highlightProvider self.contentInsets = contentInsets self.isEditable = isEditable @@ -154,7 +155,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable { self.coordinators = coordinators } - private var text: TextAPI + package var text: TextAPI private var language: CodeLanguage private var theme: EditorTheme private var font: NSFont @@ -163,7 +164,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable { private var lineHeight: Double private var wrapLines: Bool private var editorOverscroll: CGFloat - @Binding private var cursorPositions: [CursorPosition] + package var cursorPositions: Binding<[CursorPosition]> private var useThemeBackground: Bool private var highlightProvider: HighlightProviding? private var contentInsets: NSEdgeInsets? @@ -172,61 +173,42 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable { private var letterSpacing: Double private var bracketPairHighlight: BracketPairHighlight? private var undoManager: CEUndoManager? - private var coordinators: [any TextViewCoordinator] + package var coordinators: [any TextViewCoordinator] public typealias NSViewControllerType = TextViewController public func makeNSViewController(context: Context) -> TextViewController { - let controller: TextViewController + let controller = TextViewController( + string: "", + language: language, + font: font, + theme: theme, + tabWidth: tabWidth, + indentOption: indentOption, + lineHeight: lineHeight, + wrapLines: wrapLines, + cursorPositions: cursorPositions.wrappedValue, + editorOverscroll: editorOverscroll, + useThemeBackground: useThemeBackground, + highlightProvider: highlightProvider, + contentInsets: contentInsets, + isEditable: isEditable, + isSelectable: isSelectable, + letterSpacing: letterSpacing, + bracketPairHighlight: bracketPairHighlight, + undoManager: undoManager + ) switch text { case .binding(let binding): - controller = TextViewController( - string: binding.wrappedValue, - language: language, - font: font, - theme: theme, - tabWidth: tabWidth, - indentOption: indentOption, - lineHeight: lineHeight, - wrapLines: wrapLines, - cursorPositions: cursorPositions, - editorOverscroll: editorOverscroll, - useThemeBackground: useThemeBackground, - highlightProvider: highlightProvider, - contentInsets: contentInsets, - isEditable: isEditable, - isSelectable: isSelectable, - letterSpacing: letterSpacing, - bracketPairHighlight: bracketPairHighlight, - undoManager: undoManager - ) + controller.textView.setText(binding.wrappedValue) case .storage(let textStorage): - controller = TextViewController( - storage: textStorage, - language: language, - font: font, - theme: theme, - tabWidth: tabWidth, - indentOption: indentOption, - lineHeight: lineHeight, - wrapLines: wrapLines, - cursorPositions: cursorPositions, - editorOverscroll: editorOverscroll, - useThemeBackground: useThemeBackground, - highlightProvider: highlightProvider, - contentInsets: contentInsets, - isEditable: isEditable, - isSelectable: isSelectable, - letterSpacing: letterSpacing, - bracketPairHighlight: bracketPairHighlight, - undoManager: undoManager - ) + controller.textView.setTextStorage(textStorage) } if controller.textView == nil { controller.loadView() } if !cursorPositions.isEmpty { - controller.setCursorPositions(cursorPositions) + controller.setCursorPositions(cursorPositions.wrappedValue) } context.coordinator.controller = controller @@ -244,7 +226,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable { if !context.coordinator.isUpdateFromTextView { // Prevent infinite loop of update notifications context.coordinator.isUpdatingFromRepresentable = true - controller.setCursorPositions(cursorPositions) + controller.setCursorPositions(cursorPositions.wrappedValue) context.coordinator.isUpdatingFromRepresentable = false } else { context.coordinator.isUpdateFromTextView = false @@ -316,70 +298,6 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable { controller.letterSpacing == letterSpacing && controller.bracketPairHighlight == bracketPairHighlight } - - @MainActor - public class Coordinator: NSObject { - var parent: CodeEditSourceEditor - weak var controller: TextViewController? - var isUpdatingFromRepresentable: Bool = false - var isUpdateFromTextView: Bool = false - - init(parent: CodeEditSourceEditor) { - self.parent = parent - super.init() - - NotificationCenter.default.addObserver( - self, - selector: #selector(textViewDidChangeText(_:)), - name: TextView.textDidChangeNotification, - object: nil - ) - - NotificationCenter.default.addObserver( - self, - selector: #selector(textControllerCursorsDidUpdate(_:)), - name: TextViewController.cursorPositionUpdatedNotification, - object: nil - ) - } - - @objc func textViewDidChangeText(_ notification: Notification) { - guard let textView = notification.object as? TextView, - let ranges = notification.userInfo?[TextView.textDidChangeRangeKey] as? [NSRange], - let controller, - controller.textView === textView else { - return - } - if case .binding(let binding) = parent.text { - binding.wrappedValue = textView.string - } - parent.coordinators.forEach { - $0.textViewDidChangeText(controller: controller, editedRanges: ranges) - } - } - - @objc func textControllerCursorsDidUpdate(_ notification: Notification) { - guard !isUpdatingFromRepresentable else { return } - self.isUpdateFromTextView = true - self.parent._cursorPositions.wrappedValue = self.controller?.cursorPositions ?? [] - if self.controller != nil { - self.parent.coordinators.forEach { - $0.textViewDidChangeSelection( - controller: self.controller!, - newPositions: self.controller!.cursorPositions - ) - } - } - } - - deinit { - parent.coordinators.forEach { - $0.destroy() - } - parent.coordinators.removeAll() - NotificationCenter.default.removeObserver(self) - } - } } // swiftlint:disable:next line_length diff --git a/Sources/CodeEditSourceEditor/Controller/TextViewController.swift b/Sources/CodeEditSourceEditor/Controller/TextViewController.swift index fac690ba2..b1bf93b87 100644 --- a/Sources/CodeEditSourceEditor/Controller/TextViewController.swift +++ b/Sources/CodeEditSourceEditor/Controller/TextViewController.swift @@ -233,60 +233,6 @@ public class TextViewController: NSViewController { ) } - init( - storage: NSTextStorage, - language: CodeLanguage, - font: NSFont, - theme: EditorTheme, - tabWidth: Int, - indentOption: IndentOption, - lineHeight: CGFloat, - wrapLines: Bool, - cursorPositions: [CursorPosition], - editorOverscroll: CGFloat, - useThemeBackground: Bool, - highlightProvider: HighlightProviding?, - contentInsets: NSEdgeInsets?, - isEditable: Bool, - isSelectable: Bool, - letterSpacing: Double, - bracketPairHighlight: BracketPairHighlight?, - undoManager: CEUndoManager? = nil - ) { - self.language = language - self.font = font - self.theme = theme - self.tabWidth = tabWidth - self.indentOption = indentOption - self.lineHeightMultiple = lineHeight - self.wrapLines = wrapLines - self.cursorPositions = cursorPositions - self.editorOverscroll = editorOverscroll - self.useThemeBackground = useThemeBackground - self.highlightProvider = highlightProvider - self.contentInsets = contentInsets - self.isEditable = isEditable - self.isSelectable = isSelectable - self.letterSpacing = letterSpacing - self.bracketPairHighlight = bracketPairHighlight - self._undoManager = undoManager - - super.init(nibName: nil, bundle: nil) - - self.textView = TextView( - string: "", - font: font, - textColor: theme.text, - lineHeightMultiplier: lineHeightMultiple, - wrapLines: wrapLines, - isEditable: isEditable, - isSelectable: isSelectable, - letterSpacing: letterSpacing, - delegate: self - ) - self.textView.setTextStorage(storage) - } - required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } diff --git a/Sources/CodeEditSourceEditor/Coordinators/CombineCoordinator.swift b/Sources/CodeEditSourceEditor/Coordinators/CombineCoordinator.swift deleted file mode 100644 index bf300a736..000000000 --- a/Sources/CodeEditSourceEditor/Coordinators/CombineCoordinator.swift +++ /dev/null @@ -1,32 +0,0 @@ -// -// CombineCoordinator.swift -// CodeEditSourceEditor -// -// Created by Khan Winter on 5/19/24. -// - -import Foundation -import Combine -import CodeEditTextView - -public class CombineCoordinator: TextViewCoordinator { - public let updateSubject: PassthroughSubject<[NSRange], Never> = .init() - public let selectionSubject: CurrentValueSubject<[CursorPosition], Never> = .init([]) - - public init() { } - - public func prepareCoordinator(controller: TextViewController) { } - - public func textViewDidChangeText(controller: TextViewController, editedRanges: [NSRange]) { - updateSubject.send(editedRanges) - } - - public func textViewDidChangeSelection(controller: TextViewController, newPositions: [CursorPosition]) { - selectionSubject.send(newPositions) - } - - public func destroy() { - updateSubject.send(completion: .finished) - selectionSubject.send(completion: .finished) - } -} diff --git a/Sources/CodeEditSourceEditor/Documentation.docc/CodeEditTextView.md b/Sources/CodeEditSourceEditor/Documentation.docc/CodeEditSourceEditor.md similarity index 100% rename from Sources/CodeEditSourceEditor/Documentation.docc/CodeEditTextView.md rename to Sources/CodeEditSourceEditor/Documentation.docc/CodeEditSourceEditor.md diff --git a/Sources/CodeEditSourceEditor/Documentation.docc/Documentation.md b/Sources/CodeEditSourceEditor/Documentation.docc/Documentation.md index 7b86601cd..c9aa13d78 100644 --- a/Sources/CodeEditSourceEditor/Documentation.docc/Documentation.md +++ b/Sources/CodeEditSourceEditor/Documentation.docc/Documentation.md @@ -4,36 +4,46 @@ A code editor with syntax highlighting powered by tree-sitter. ## Overview -![logo](codeedittextview-logo) - An Xcode-inspired code editor view written in Swift powered by tree-sitter for [CodeEdit](https://github.com/CodeEditApp/CodeEdit). Features include syntax highlighting (based on the provided theme), code completion, find and replace, text diff, validation, current line highlighting, minimap, inline messages (warnings and errors), bracket matching, and more. -This package includes both `AppKit` and `SwiftUI` components. It also relies on the `CodeEditLanguages` and `Theme` module. - -![banner](preview) +This package includes both `AppKit` and `SwiftUI` components. It also relies on the [`CodeEditLanguages`](https://github.com/CodeEditApp/CodeEditLanguages) for optional syntax highlighting using tree-sitter. -## Syntax Highlighting +> **CodeEditSourceEditor is currently in development and it is not ready for production use.**
Please check back later for updates on this project. Contributors are welcome as we build out the features mentioned above! -``CodeEditSourceEditor`` uses `tree-sitter` for syntax highlighting. A list of already supported languages can be found [here](https://github.com/CodeEditApp/CodeEditSourceEditor/issues/15). +## Currently Supported Languages -New languages need to be added to the [CodeEditLanguages](https://github.com/CodeEditApp/CodeEditLanguages) repo. +See this issue [CodeEditLanguages#10](https://github.com/CodeEditApp/CodeEditLanguages/issues/10) on `CodeEditLanguages` for more information on supported languages. ## Dependencies -Special thanks to both [Marcin Krzyzanowski](https://twitter.com/krzyzanowskim) & [Matt Massicotte](https://twitter.com/mattie) for the great work they've done! +Special thanks to [Matt Massicotte](https://twitter.com/mattie) for the great work he's done! | Package | Source | Author | -| - | - | - | -| `STTextView` | [GitHub](https://github.com/krzyzanowskim/STTextView) | [Marcin Krzyzanowski](https://twitter.com/krzyzanowskim) | +| :- | :- | :- | | `SwiftTreeSitter` | [GitHub](https://github.com/ChimeHQ/SwiftTreeSitter) | [Matt Massicotte](https://twitter.com/mattie) | +## License + +Licensed under the [MIT license](https://github.com/CodeEditApp/CodeEdit/blob/main/LICENSE.md). + ## Topics ### Text View - ``CodeEditSourceEditor/CodeEditSourceEditor`` -- ``CodeEditSourceEditor/TextViewController`` +- ``TextViewController`` +- ``GutterView`` -### Theme +### Themes - ``EditorTheme`` + +### Text Coordinators + +- +- ``TextViewCoordinator`` +- ``CombineCoordinator`` + +### Cursors + +- ``CursorPosition`` diff --git a/Sources/CodeEditSourceEditor/Documentation.docc/TextViewCoordinators.md b/Sources/CodeEditSourceEditor/Documentation.docc/TextViewCoordinators.md new file mode 100644 index 000000000..8c4b0931d --- /dev/null +++ b/Sources/CodeEditSourceEditor/Documentation.docc/TextViewCoordinators.md @@ -0,0 +1,66 @@ +# TextView Coordinators + +Add advanced functionality to CodeEditSourceEditor. + +## Overview + +CodeEditSourceEditor provides an API to add more advanced functionality to the editor than SwiftUI allows. For instance, a + +### Make a Coordinator + +To create a coordinator, first create a class that conforms to the ``TextViewCoordinator`` protocol. + +```swift +class MyCoordinator { + func prepareCoordinator(controller: TextViewController) { + // Do any setup, such as keeping a (weak) reference to the controller or adding a text storage delegate. + } +} +``` + +Add any methods required for your coordinator to work, such as receiving notifications when text is edited, or + +```swift +class MyCoordinator { + func prepareCoordinator(controller: TextViewController) { /* ... */ } + + func textViewDidChangeText(controller: TextViewController) { + // Text was updated. + } + + func textViewDidChangeSelection(controller: TextViewController, newPositions: [CursorPosition]) { + // Selections were changed + } +} +``` + +If your coordinator keeps any references to anything in CodeEditSourceEditor, make sure to dereference them using the ``TextViewCoordinator/destroy()-9nzfl`` method. + +```swift +class MyCoordinator { + func prepareCoordinator(controller: TextViewController) { /* ... */ } + func textViewDidChangeText(controller: TextViewController) { /* ... */ } + func textViewDidChangeSelection(controller: TextViewController, newPositions: [CursorPosition]) { /* ... */ } + + func destroy() { + // Release any resources, `nil` any weak variables, remove delegates, etc. + } +} +``` + +### Coordinator Lifecycle + +A coordinator makes no assumptions about initialization, leaving the developer to pass any init parameters to the coordinator. + +The lifecycle looks like this: +- Coordinator initialized (by user, not CodeEditSourceEditor). +- Coordinator given to CodeEditSourceEditor. + - ``TextViewCoordinator/prepareCoordinator(controller:)`` is called. +- Events occur, coordinators are notified in the order they were passed to CodeEditSourceEditor. +- CodeEditSourceEditor is being closed. + - ``TextViewCoordinator/destroy()-9nzfl`` is called. + - CodeEditSourceEditor stops referencing the coordinator. + +### Example + +To see an example of a coordinator and they're use case, see the ``CombineCoordinator`` class. This class creates a coordinator that passes notifications on to a Combine stream. diff --git a/Sources/CodeEditSourceEditor/TextViewCoordinator/CombineCoordinator.swift b/Sources/CodeEditSourceEditor/TextViewCoordinator/CombineCoordinator.swift new file mode 100644 index 000000000..3474c3fd5 --- /dev/null +++ b/Sources/CodeEditSourceEditor/TextViewCoordinator/CombineCoordinator.swift @@ -0,0 +1,48 @@ +// +// CombineCoordinator.swift +// CodeEditSourceEditor +// +// Created by Khan Winter on 5/19/24. +// + +import Foundation +import Combine +import CodeEditTextView + +/// A ``TextViewCoordinator`` class that publishes text changes and selection changes using Combine publishers. +/// +/// This class provides two publisher streams: ``textUpdatePublisher`` and ``selectionUpdatePublisher``. +/// Both streams will receive any updates for text edits or selection changes and a `.finished` completion when the +/// source editor is destroyed. +public class CombineCoordinator: TextViewCoordinator { + /// Publishes edit notifications as the text is changed in the editor. + public var textUpdatePublisher: AnyPublisher { + updateSubject.eraseToAnyPublisher() + } + + /// Publishes cursor changes as the user types or selects text. + public var selectionUpdatePublisher: AnyPublisher<[CursorPosition], Never> { + selectionSubject.eraseToAnyPublisher() + } + + private let updateSubject: PassthroughSubject = .init() + private let selectionSubject: CurrentValueSubject<[CursorPosition], Never> = .init([]) + + /// Initializes the coordinator. + public init() { } + + public func prepareCoordinator(controller: TextViewController) { } + + public func textViewDidChangeText(controller: TextViewController) { + updateSubject.send() + } + + public func textViewDidChangeSelection(controller: TextViewController, newPositions: [CursorPosition]) { + selectionSubject.send(newPositions) + } + + public func destroy() { + updateSubject.send(completion: .finished) + selectionSubject.send(completion: .finished) + } +} diff --git a/Sources/CodeEditSourceEditor/TextViewCoordinator.swift b/Sources/CodeEditSourceEditor/TextViewCoordinator/TextViewCoordinator.swift similarity index 89% rename from Sources/CodeEditSourceEditor/TextViewCoordinator.swift rename to Sources/CodeEditSourceEditor/TextViewCoordinator/TextViewCoordinator.swift index ca4c49109..98c553cd5 100644 --- a/Sources/CodeEditSourceEditor/TextViewCoordinator.swift +++ b/Sources/CodeEditSourceEditor/TextViewCoordinator/TextViewCoordinator.swift @@ -22,7 +22,7 @@ public protocol TextViewCoordinator: AnyObject { /// Called when the text view's text changed. /// - Parameter controller: The text controller. - func textViewDidChangeText(controller: TextViewController, editedRanges: [NSRange]) + func textViewDidChangeText(controller: TextViewController) /// Called after the text view updated it's cursor positions. /// - Parameter newPositions: The new positions of the cursors. @@ -34,7 +34,7 @@ public protocol TextViewCoordinator: AnyObject { /// Default implementations public extension TextViewCoordinator { - func textViewDidChangeText(controller: TextViewController, editedRanges: [NSRange]) { } + func textViewDidChangeText(controller: TextViewController) { } func textViewDidChangeSelection(controller: TextViewController, newPositions: [CursorPosition]) { } func destroy() { } } From 3e1d93c6faafbfcca15689f1099307f5a42367d8 Mon Sep 17 00:00:00 2001 From: Khan Winter <35942988+thecoolwinter@users.noreply.github.com> Date: Mon, 20 May 2024 18:04:26 -0500 Subject: [PATCH 3/3] Documentation Improvements pt 2 --- .../Documentation.docc/Documentation.md | 4 ++++ .../Resources/codeeditsourceeditor-logo@2x.png | Bin 0 -> 48211 bytes .../Resources/codeedittextview-logo.png | Bin 40118 -> 0 bytes 3 files changed, 4 insertions(+) create mode 100644 Sources/CodeEditSourceEditor/Documentation.docc/Resources/codeeditsourceeditor-logo@2x.png delete mode 100644 Sources/CodeEditSourceEditor/Documentation.docc/Resources/codeedittextview-logo.png diff --git a/Sources/CodeEditSourceEditor/Documentation.docc/Documentation.md b/Sources/CodeEditSourceEditor/Documentation.docc/Documentation.md index c9aa13d78..39f1102e6 100644 --- a/Sources/CodeEditSourceEditor/Documentation.docc/Documentation.md +++ b/Sources/CodeEditSourceEditor/Documentation.docc/Documentation.md @@ -4,8 +4,12 @@ A code editor with syntax highlighting powered by tree-sitter. ## Overview +![logo](codeeditsourceeditor-logo) + An Xcode-inspired code editor view written in Swift powered by tree-sitter for [CodeEdit](https://github.com/CodeEditApp/CodeEdit). Features include syntax highlighting (based on the provided theme), code completion, find and replace, text diff, validation, current line highlighting, minimap, inline messages (warnings and errors), bracket matching, and more. +![banner](preview) + This package includes both `AppKit` and `SwiftUI` components. It also relies on the [`CodeEditLanguages`](https://github.com/CodeEditApp/CodeEditLanguages) for optional syntax highlighting using tree-sitter. > **CodeEditSourceEditor is currently in development and it is not ready for production use.**
Please check back later for updates on this project. Contributors are welcome as we build out the features mentioned above! diff --git a/Sources/CodeEditSourceEditor/Documentation.docc/Resources/codeeditsourceeditor-logo@2x.png b/Sources/CodeEditSourceEditor/Documentation.docc/Resources/codeeditsourceeditor-logo@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..6bb503b9bebde64ea7c1bc7fd835250666d798f5 GIT binary patch literal 48211 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%0A)4zM3Yr$CfpDT}{G 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 literal 0 HcmV?d00001 diff --git a/Sources/CodeEditSourceEditor/Documentation.docc/Resources/codeedittextview-logo.png b/Sources/CodeEditSourceEditor/Documentation.docc/Resources/codeedittextview-logo.png deleted file mode 100644 index 8a457f7a0f3ba2defbcdfecfb1542331021b51b7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40118 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