### Create a Basic Coordinator Source: https://github.com/codeeditapp/codeeditsourceeditor/blob/main/Sources/CodeEditSourceEditor/Documentation.docc/TextViewCoordinators.md Create a class conforming to the TextViewCoordinator protocol. Implement the prepareCoordinator method for setup, such as keeping a weak reference to the controller or adding a text storage delegate. ```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. } } ``` -------------------------------- ### SwiftUI Source Editor Configuration Source: https://github.com/codeeditapp/codeeditsourceeditor/blob/main/Sources/CodeEditSourceEditor/Documentation.docc/SourceEditorView.md Configures a SwiftUI Source Editor with various appearance, behavior, layout, and peripheral settings. Includes an example of a custom AutoCompleteCoordinator for text manipulation. ```swift import CodeEditSourceEditor struct ContentView: View { @State var text = "let x = 1.0" // For large documents use a text storage object (avoids SwiftUI comparisons) // var text: NSTextStorage /// Automatically updates with cursor positions, scroll position, find panel text. /// Everything in this object is two-way, use it to update cursor positions, scroll position, etc. @State var editorState = SourceEditorState() /// Configure the editor's appearance, features, and editing behavior... @State var theme = EditorTheme(...) @State var font = NSFont.monospacedSystemFont(ofSize: 11, weight: .regular) @State var indentOption = .spaces(count: 4) @State var editorOverscroll = 0.3 @State var showMinimap = true /// *Powerful* customization options with text coordinators @State var autoCompleteCoordinator = AutoCompleteCoordinator() var body: some View { SourceEditor( $text, language: language, configuration: SourceEditorConfiguration( appearance: .init(theme: theme, font: font), behavior: .init(indentOption: indentOption), layout: .init(editorOverscroll: editorOverscroll), peripherals: .init(showMinimap: showMinimap) ), state: $editorState, coordinators: [autoCompleteCoordinator] ) } /// Autocompletes "Hello" to "Hello world!" whenever it's typed. class AutoCompleteCoordinator: TextViewCoordinator { func prepareCoordinator(controller: TextViewController) { } func textViewDidChangeText(controller: TextViewController) { for cursorPosition in controller.cursorPositions.reversed() where cursorPosition.range.location >= 5 { let location = cursorPosition.range.location let previousRange = NSRange(start: location - 5, end: location) let string = (controller.text as NSString).substring(with: previousRange) if string.lowercased() == "hello" { controller.textView.replaceCharacters(in: NSRange(location: location, length: 0), with: " world!") } } } } } ``` -------------------------------- ### Implement Custom Syntax Highlighter Source: https://context7.com/codeeditapp/codeeditsourceeditor/llms.txt Implement the HighlightProviding protocol to create custom syntax highlighters. The default uses tree-sitter. Requires importing CodeEditSourceEditor, CodeEditTextView, and CodeEditLanguages. ```swift import CodeEditSourceEditor import CodeEditTextView import CodeEditLanguages class CustomHighlighter: HighlightProviding { @MainActor func setUp(textView: TextView, codeLanguage: CodeLanguage) { // Initialize highlighter with text view and language } @MainActor func willApplyEdit(textView: TextView, range: NSRange) { // Optional: Called before an edit is applied } @MainActor func applyEdit( textView: TextView, range: NSRange, delta: Int, completion: @escaping @MainActor (Result) -> Void ) { // Return indices that need re-highlighting after an edit let invalidatedRange = IndexSet(integersIn: range.location..<(range.location + range.length + delta)) completion(.success(invalidatedRange)) } @MainActor func queryHighlightsFor( textView: TextView, range: NSRange, completion: @escaping @MainActor (Result<[HighlightRange], Error>) -> Void ) { // Return highlight ranges for the queried range // HighlightRange contains the range and capture name (keyword, string, comment, etc.) completion(.success([])) } } ``` -------------------------------- ### Initialize SourceEditorConfiguration Source: https://context7.com/codeeditapp/codeeditsourceeditor/llms.txt Configure the appearance, behavior, layout, and peripherals of the Source Editor. Customize theme, fonts, line wrapping, editing permissions, indentation, and gutter visibility. ```swift import CodeEditSourceEditor let configuration = SourceEditorConfiguration( appearance: SourceEditorConfiguration.Appearance( theme: myTheme, // EditorTheme for syntax highlighting useThemeBackground: true, // Use theme background vs transparent font: NSFont.monospacedSystemFont(ofSize: 13, weight: .regular), lineHeightMultiple: 1.2, // Line height multiplier letterSpacing: 1.0, // Character spacing (1.0 = normal) wrapLines: true, // Enable line wrapping useSystemCursor: true, // Use macOS 14+ system cursor tabWidth: 4, // Visual tab width in spaces bracketPairEmphasis: .flash // Bracket matching style ), behavior: SourceEditorConfiguration.Behavior( isEditable: true, // Allow editing isSelectable: true, // Allow selection indentOption: .spaces(count: 4), // Tab key behavior reformatAtColumn: 80 // Reformatting guide column ), layout: SourceEditorConfiguration.Layout( editorOverscroll: 0.3, // Overscroll as % of view height contentInsets: NSEdgeInsets(top: 0, left: 0, bottom: 28, right: 0), additionalTextInsets: NSEdgeInsets(top: 1, left: 0, bottom: 1, right: 0) ), peripherals: SourceEditorConfiguration.Peripherals( showGutter: true, // Show line numbers showMinimap: true, // Show code minimap showReformattingGuide: false, // Show column guide showFoldingRibbon: true, // Show code folding ribbon invisibleCharactersConfiguration: .empty, warningCharacters: [] // Characters to highlight as warnings ) ) ``` -------------------------------- ### Initialize TextViewController (AppKit) Source: https://context7.com/codeeditapp/codeeditsourceeditor/llms.txt Direct initialization of TextViewController for AppKit usage. Requires importing CodeEditSourceEditor and CodeEditLanguages. Customize appearance, language, and initial cursor positions. ```swift import CodeEditSourceEditor import CodeEditLanguages // Direct initialization (AppKit usage) let controller = TextViewController( string: "let x = 42", language: .swift, configuration: SourceEditorConfiguration( appearance: .init( theme: myTheme, font: NSFont.monospacedSystemFont(ofSize: 13, weight: .regular), wrapLines: true ) ), cursorPositions: [CursorPosition(line: 1, column: 1)], highlightProviders: [TreeSitterClient()], coordinators: [] ) ``` -------------------------------- ### CursorPosition Initialization and Usage Source: https://context7.com/codeeditapp/codeeditsourceeditor/llms.txt Illustrates various ways to initialize and use the CursorPosition struct, including by line/column, character range, and start/end positions for selections. Requires importing CodeEditSourceEditor. ```swift import CodeEditSourceEditor // Initialize with line and column (1-indexed) let cursorByPosition = CursorPosition(line: 10, column: 5) // Initialize with character range let cursorByRange = CursorPosition(range: NSRange(location: 100, length: 0)) // Initialize with start and end positions for selections let selection = CursorPosition( start: CursorPosition.Position(line: 5, column: 1), end: CursorPosition.Position(line: 5, column: 20) ) // Access cursor information if cursorByPosition.start.line > 0 { print("Line: \(cursorByPosition.start.line)") print("Column: \(cursorByPosition.start.column)") } // Check if it's a selection (has end position) if let endPosition = selection.end { print("Selection from line \(selection.start.line) to line \(endPosition.line)") } ``` -------------------------------- ### Implement CodeSuggestionDelegate Protocol Source: https://context7.com/codeeditapp/codeeditsourceeditor/llms.txt Implement this delegate to provide custom completion suggestions. Define custom suggestion types and handle suggestion requests, cursor movements, and completion application. ```swift import SwiftUI import CodeEditSourceEditor class MyCompletionDelegate: CodeSuggestionDelegate, ObservableObject { // Define custom suggestion type class MySuggestion: CodeSuggestionEntry { var label: String var detail: String? var documentation: String? var pathComponents: [String]? var targetPosition: CursorPosition? var sourcePreview: String? var image: Image var imageColor: Color var deprecated: Bool init(label: String, detail: String?, image: Image, color: Color) { self.label = label self.detail = detail self.documentation = nil self.pathComponents = nil self.targetPosition = nil self.sourcePreview = nil self.image = image self.imageColor = color self.deprecated = false } } func completionTriggerCharacters() -> Set { return [".", "(", "["] } func completionSuggestionsRequested( textView: TextViewController, cursorPosition: CursorPosition ) async -> (windowPosition: CursorPosition, items: [CodeSuggestionEntry])? { // Fetch or compute suggestions asynchronously let suggestions: [MySuggestion] = [ MySuggestion(label: "print", detail: "Function", image: Image(systemName: "function"), color: .purple), MySuggestion(label: "String", detail: "Type", image: Image(systemName: "t.square"), color: .blue), MySuggestion(label: "count", detail: "Property", image: Image(systemName: "number"), color: .green) ] return (cursorPosition, suggestions) } func completionOnCursorMove( textView: TextViewController, cursorPosition: CursorPosition ) -> [CodeSuggestionEntry]? { // Return filtered suggestions synchronously (must be fast) return nil // Return nil to dismiss, or filtered array to update } func completionWindowApplyCompletion( item: CodeSuggestionEntry, textView: TextViewController, cursorPosition: CursorPosition? ) { guard let suggestion = item as? MySuggestion, let cursor = cursorPosition else { return } textView.textView.undoManager?.beginUndoGrouping() textView.textView.selectionManager.setSelectedRange(cursor.range) textView.textView.insertText(suggestion.label) textView.textView.undoManager?.endUndoGrouping() } func completionWindowDidSelect(item: CodeSuggestionEntry) { // Optional: Called when user highlights a suggestion } func completionWindowDidClose() { // Optional: Called when completion window closes } } // Using the completion delegate struct EditorWithCompletion: View { @State private var text = "" @State private var editorState = SourceEditorState() @StateObject private var completionDelegate = MyCompletionDelegate() var body: some View { SourceEditor( $text, language: .swift, configuration: SourceEditorConfiguration(appearance: .init(theme: myTheme, font: .monospacedSystemFont(ofSize: 12, weight: .regular), wrapLines: true)), state: $editorState, completionDelegate: completionDelegate ) } } ``` -------------------------------- ### AppKit TextViewController Initialization Source: https://github.com/codeeditapp/codeeditsourceeditor/blob/main/Sources/CodeEditSourceEditor/Documentation.docc/SourceEditorView.md Initializes an AppKit TextViewController with basic configuration, language, and cursor positions. This is a foundational step for integrating the editor into an AppKit application. ```swift var theme = EditorTheme(...) var font = NSFont.monospacedSystemFont(ofSize: 11, weight: .regular) var indentOption = .spaces(count: 4) var editorOverscroll = 0.3 var showMinimap = true let editorController = TextViewController( string: "let x = 10;", language: .swift, config: SourceEditorConfiguration( appearance: .init(theme: theme, font: font), behavior: .init(indentOption: indentOption), layout: .init(editorOverscroll: editorOverscroll), peripherals: .init(showMinimap: showMinimap) ), cursorPositions: [CursorPosition(line: 0, column: 0)], highlightProviders: [], // Use the tree-sitter syntax highlighting provider by default undoManager: nil, coordinators: [], // Optionally inject editing behavior or other plugins. completionDelegate: nil, // Provide code suggestions while typing via a delegate object. jumpToDefinitionDelegate // Allow users to perform the 'jump to definition' using a delegate object. ) ``` -------------------------------- ### Define Dark and Light Editor Themes Source: https://context7.com/codeeditapp/codeeditsourceeditor/llms.txt Defines custom color themes for syntax highlighting in the editor. Includes attributes for text, keywords, comments, and more. ```swift import CodeEditSourceEditor import AppKit let darkTheme = EditorTheme( text: EditorTheme.Attribute(color: NSColor(hex: "FFFFFF")), insertionPoint: NSColor(hex: "007AFF"), invisibles: EditorTheme.Attribute(color: NSColor(hex: "53606E")), background: NSColor(hex: "292A30"), lineHighlight: NSColor(hex: "2F3239"), selection: NSColor(hex: "646F83"), keywords: EditorTheme.Attribute(color: NSColor(hex: "FF7AB2"), bold: true), commands: EditorTheme.Attribute(color: NSColor(hex: "78C2B3")), types: EditorTheme.Attribute(color: NSColor(hex: "6BDFFF")), attributes: EditorTheme.Attribute(color: NSColor(hex: "CC9768")), variables: EditorTheme.Attribute(color: NSColor(hex: "4EB0CC")), values: EditorTheme.Attribute(color: NSColor(hex: "B281EB")), numbers: EditorTheme.Attribute(color: NSColor(hex: "D9C97C")), strings: EditorTheme.Attribute(color: NSColor(hex: "FF8170")), characters: EditorTheme.Attribute(color: NSColor(hex: "D9C97C")), comments: EditorTheme.Attribute(color: NSColor(hex: "7F8C98")) ) let lightTheme = EditorTheme( text: EditorTheme.Attribute(color: NSColor(hex: "000000")), insertionPoint: NSColor(hex: "000000"), invisibles: EditorTheme.Attribute(color: NSColor(hex: "D6D6D6")), background: NSColor(hex: "FFFFFF"), lineHighlight: NSColor(hex: "ECF5FF"), selection: NSColor(hex: "B2D7FF"), keywords: EditorTheme.Attribute(color: NSColor(hex: "9B2393"), bold: true), commands: EditorTheme.Attribute(color: NSColor(hex: "326D74")), types: EditorTheme.Attribute(color: NSColor(hex: "0B4F79")), attributes: EditorTheme.Attribute(color: NSColor(hex: "815F03")), variables: EditorTheme.Attribute(color: NSColor(hex: "0F68A0")), values: EditorTheme.Attribute(color: NSColor(hex: "6C36A9")), numbers: EditorTheme.Attribute(color: NSColor(hex: "1C00CF")), strings: EditorTheme.Attribute(color: NSColor(hex: "C41A16")), characters: EditorTheme.Attribute(color: NSColor(hex: "1C00CF")), comments: EditorTheme.Attribute(color: NSColor(hex: "267507")) ) ``` -------------------------------- ### Implement Coordinator Cleanup Source: https://github.com/codeeditapp/codeeditsourceeditor/blob/main/Sources/CodeEditSourceEditor/Documentation.docc/TextViewCoordinators.md Ensure proper resource management by implementing the destroy method. This method should release any resources, nil out weak variables, and remove delegates to prevent memory leaks. ```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. } } ``` -------------------------------- ### Configure Indentation Options Source: https://context7.com/codeeditapp/codeeditsourceeditor/llms.txt Define how the tab key should behave, supporting either spaces or actual tab characters for indentation. Configure this within the `SourceEditorConfiguration`. ```swift import CodeEditSourceEditor // Use 4 spaces for indentation let spacesIndent = IndentOption.spaces(count: 4) // Use 2 spaces for indentation let twoSpacesIndent = IndentOption.spaces(count: 2) // Use actual tab character let tabIndent = IndentOption.tab // Use in configuration let config = SourceEditorConfiguration( appearance: .init(theme: myTheme, font: .monospacedSystemFont(ofSize: 12, weight: .regular), wrapLines: true), behavior: .init(indentOption: .spaces(count: 4)) ) ``` -------------------------------- ### Initialize SourceEditorState Source: https://context7.com/codeeditapp/codeeditsourceeditor/llms.txt Initialize the editor state with specific cursor positions and scroll position. All properties are optional and support real-time updates. ```swift import CodeEditSourceEditor // Initialize with specific cursor position var state = SourceEditorState( cursorPositions: [CursorPosition(line: 1, column: 1)], scrollPosition: CGPoint(x: 0, y: 0), findText: nil, replaceText: nil, findPanelVisible: false ) ``` -------------------------------- ### Reactive Editor View with CombineCoordinator Source: https://context7.com/codeeditapp/codeeditsourceeditor/llms.txt Demonstrates how to integrate CombineCoordinator into a SwiftUI view to enable reactive handling of text and selection changes. Requires importing SwiftUI, Combine, and CodeEditSourceEditor. ```swift import SwiftUI import Combine import CodeEditSourceEditor struct ReactiveEditorView: View { @State private var text = "" @State private var editorState = SourceEditorState() @StateObject private var combineCoordinator = CombineCoordinator() @State private var lastCursorPosition: CursorPosition? var body: some View { VStack { SourceEditor( $text, language: .swift, configuration: SourceEditorConfiguration(appearance: .init(theme: myTheme, font: .monospacedSystemFont(ofSize: 12, weight: .regular), wrapLines: true)), state: $editorState, coordinators: [combineCoordinator] ) if let position = lastCursorPosition { Text("Cursor at line \(position.start.line), column \(position.start.column)") } } .onReceive(combineCoordinator.textUpdatePublisher) { print("Text was updated") } .onReceive(combineCoordinator.selectionUpdatePublisher) { lastCursorPosition = positions.first } } } ``` -------------------------------- ### SwiftUI Source Editor with NSTextStorage Source: https://context7.com/codeeditapp/codeeditsourceeditor/llms.txt This SwiftUI view initializer accepts NSTextStorage directly, suitable for shared text storage or custom management. It requires importing SwiftUI, CodeEditSourceEditor, and CodeEditLanguages. ```swift import SwiftUI import CodeEditSourceEditor import CodeEditLanguages struct SharedStorageEditor: View { let textStorage: NSTextStorage @State private var editorState = SourceEditorState() var body: some View { SourceEditor( textStorage, language: .python, configuration: SourceEditorConfiguration( appearance: .init( theme: darkTheme, font: NSFont(name: "SF Mono", size: 12) ?? .monospacedSystemFont(ofSize: 12, weight: .regular), wrapLines: false, tabWidth: 4 ) ), state: $editorState ) } } ``` -------------------------------- ### Use Custom Highlighter in SwiftUI Editor Source: https://context7.com/codeeditapp/codeeditsourceeditor/llms.txt Integrate a custom highlighter into a SwiftUI SourceEditor view. Requires state management for text, editor state, and the custom highlighter instance. ```swift // Use custom highlighter struct CustomHighlightedEditor: View { @State private var text = "" @State private var editorState = SourceEditorState() @State private var customHighlighter = CustomHighlighter() var body: some View { SourceEditor( $text, language: .swift, configuration: SourceEditorConfiguration(appearance: .init(theme: myTheme, font: .monospacedSystemFont(ofSize: 12, weight: .regular), wrapLines: true)), state: $editorState, highlightProviders: [customHighlighter] ) } } ``` -------------------------------- ### SwiftUI Source Editor Configuration Source: https://context7.com/codeeditapp/codeeditsourceeditor/llms.txt Use this SwiftUI view to create a source code editor with customizable appearance, behavior, layout, and peripherals. It requires importing SwiftUI, CodeEditSourceEditor, and CodeEditLanguages. ```swift import SwiftUI import CodeEditSourceEditor import CodeEditLanguages struct EditorView: View { @State private var text = "func hello() { print(\"Hello, World!\") }" @State private var editorState = SourceEditorState( cursorPositions: [CursorPosition(line: 1, column: 1)] ) var body: some View { SourceEditor( $text, language: .swift, configuration: SourceEditorConfiguration( appearance: .init( theme: myTheme, font: NSFont.monospacedSystemFont(ofSize: 13, weight: .regular), wrapLines: true ), behavior: .init( indentOption: .spaces(count: 4), reformatAtColumn: 80 ), layout: .init( editorOverscroll: 0.3, contentInsets: NSEdgeInsets(top: 0, left: 0, bottom: 28, right: 0) ), peripherals: .init( showGutter: true, showMinimap: true, showReformattingGuide: false, showFoldingRibbon: true ) ), state: $editorState ) } } ``` -------------------------------- ### Implement Coordinator Notification Methods Source: https://github.com/codeeditapp/codeeditsourceeditor/blob/main/Sources/CodeEditSourceEditor/Documentation.docc/TextViewCoordinators.md Add methods to your coordinator class to receive notifications for text changes and selection updates. These methods are called when the corresponding events occur in the editor. ```swift class MyCoordinator { func prepareCoordinator(controller: TextViewController) { /* ... */ } func textViewDidChangeText(controller: TextViewController) { // Text was updated. } func textViewDidChangeSelection(controller: TextViewController, newPositions: [CursorPosition]) { // Selections were changed } } ``` -------------------------------- ### Implement AutoCompleteCoordinator for Editor Events Source: https://context7.com/codeeditapp/codeeditsourceeditor/llms.txt A custom coordinator that implements the TextViewCoordinator protocol to respond to text and selection changes. It can inject custom behavior, such as auto-completion. ```swift import CodeEditSourceEditor import CodeEditTextView final class AutoCompleteCoordinator: TextViewCoordinator { weak var controller: TextViewController? // Store weak reference for later use func prepareCoordinator(controller: TextViewController) { self.controller = controller } func textViewDidChangeText(controller: TextViewController) { // Called when text content changes for cursorPosition in controller.cursorPositions where cursorPosition.range.location >= 5 { let location = cursorPosition.range.location let previousRange = NSRange(location: location - 5, length: 5) let string = (controller.text as NSString).substring(with: previousRange) if string.lowercased() == "hello" { controller.textView.replaceCharacters( in: NSRange(location: location, length: 0), with: " world!" ) } } } func textViewDidChangeSelection(controller: TextViewController, newPositions: [CursorPosition]) { // Called when cursor position or selection changes print("New cursor positions: \(newPositions)") } func controllerDidAppear(controller: TextViewController) { // Called when the editor view appears } func controllerDidDisappear(controller: TextViewController) { // Called when the editor view disappears } func destroy() { // Release resources when coordinator is destroyed controller = nil } } // Using the coordinator struct EditorWithCoordinator: View { @State private var text = "" @State private var editorState = SourceEditorState() @State private var autoCompleteCoordinator = AutoCompleteCoordinator() var body: some View { SourceEditor( $text, language: .swift, configuration: SourceEditorConfiguration(appearance: .init(theme: myTheme, font: .monospacedSystemFont(ofSize: 12, weight: .regular), wrapLines: true)), state: $editorState, coordinators: [autoCompleteCoordinator] ) } } ``` -------------------------------- ### Embedding AppKit TextViewController in NSViewController Source: https://github.com/codeeditapp/codeeditsourceeditor/blob/main/Sources/CodeEditSourceEditor/Documentation.docc/SourceEditorView.md Demonstrates how to add a TextViewController as a child view controller and integrate its view into the view hierarchy of an NSViewController. ```swift final class MyController: NSViewController { override func loadView() { super.loadView() let editorController: TextViewController = /**/ addChild(editorController) view.addSubview(editorController.view) editorController.view.viewDidMoveToSuperview() } } ``` -------------------------------- ### Manage Cursor Positions in TextViewController Source: https://context7.com/codeeditapp/codeeditsourceeditor/llms.txt Retrieve and set cursor positions programmatically using TextViewController. Requires importing CodeEditSourceEditor. ```swift // Access cursor positions let cursors = controller.cursorPositions // Set cursor positions programmatically controller.setCursorPositions([CursorPosition(line: 5, column: 10)]) ``` -------------------------------- ### Access and Modify Text in TextViewController Source: https://context7.com/codeeditapp/codeeditsourceeditor/llms.txt Access the current text content and set new text programmatically using TextViewController. Ensure necessary imports. ```swift // Access text content let currentText = controller.text // Set new text controller.setText("print(\"Hello\")") ``` -------------------------------- ### Access Underlying Text View and Scroll View Source: https://context7.com/codeeditapp/codeeditsourceeditor/llms.txt Access the underlying AppKit text view and scroll view from TextViewController for advanced operations. Ensure necessary imports. ```swift // Access underlying text view for advanced operations let textView = controller.textView textView?.insertText("new text") // Access scroll view let scrollView = controller.scrollView ``` -------------------------------- ### Add CodeEditSourceEditor via Swift Package Manager Source: https://context7.com/codeeditapp/codeeditsourceeditor/llms.txt Integrate CodeEditSourceEditor into your project using Swift Package Manager by adding the repository URL to your Package.swift dependencies. ```swift // Package.swift import PackageDescription let package = Package( name: "MyApp", platforms: [.macOS(.v13)], dependencies: [ .package( url: "https://github.com/CodeEditApp/CodeEditSourceEditor.git", from: "0.12.0" ) ], targets: [ .target( name: "MyApp", dependencies: ["CodeEditSourceEditor"]) ] ) ``` -------------------------------- ### TextViewDelegate Forwarded Messages Source: https://github.com/codeeditapp/codeeditsourceeditor/blob/main/Sources/CodeEditSourceEditor/Documentation.docc/TextViewCoordinators.md When a coordinator conforms to the TextViewDelegate protocol, it receives forwarded delegate messages for the editor's text view. These include notifications for replacing content. ```swift func textView(_ textView: TextView, willReplaceContentsIn range: NSRange, with string: String) func textView(_ textView: TextView, didReplaceContentsIn range: NSRange, with string: String) ``` -------------------------------- ### Use SourceEditorState with SwiftUI Binding Source: https://context7.com/codeeditapp/codeeditsourceeditor/llms.txt Bind SourceEditorState to a SwiftUI view for two-way updates of editor state, including cursor positions and visibility of the find panel. ```swift import CodeEditSourceEditor // Use in SwiftUI view with binding struct EditorWithState: View { @State private var editorState = SourceEditorState() @State private var text = "" var body: some View { VStack { SourceEditor( $text, language: .swift, configuration: SourceEditorConfiguration(appearance: .init(theme: myTheme, font: .monospacedSystemFont(ofSize: 12, weight: .regular), wrapLines: true)), state: $editorState ) // Display current cursor position from state if let positions = editorState.cursorPositions, let first = positions.first { Text("Line: \(first.start.line), Column: \(first.start.column)") } } } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.