From 62f82d11c985d45eec9d0b97cd849428ad89820f Mon Sep 17 00:00:00 2001
From: Marcin Krzyzanowski <marcin.krzyzanowski@gmail.com>
Date: Tue, 13 Feb 2024 01:12:41 +0100
Subject: [PATCH] More relying on layout manager content manager

---
 Sources/STTextView/STTextFinderClient.swift    | 18 ++++++++++--------
 .../STTextView/STTextViewDelegateProxy.swift   |  6 +++++-
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/Sources/STTextView/STTextFinderClient.swift b/Sources/STTextView/STTextFinderClient.swift
index ed73507..dda25aa 100644
--- a/Sources/STTextView/STTextFinderClient.swift
+++ b/Sources/STTextView/STTextFinderClient.swift
@@ -29,13 +29,15 @@ final class STTextFinderClient: NSObject, NSTextFinderClient {
     }
 
     func shouldReplaceCharacters(inRanges ranges: [NSValue], with strings: [String]) -> Bool {
-        guard let textView = textView else {
+        guard let textView = textView,
+              let textContentManager = textView.textLayoutManager.textContentManager
+        else {
             return false
         }
 
         var result = true
         for (range, string) in zip(ranges.map(\.rangeValue), strings) {
-            if let textRange = NSTextRange(range, in: textView.textContentManager) {
+            if let textRange = NSTextRange(range, in: textContentManager) {
                 result = result && textView.shouldChangeText(in: textRange, replacementString: string)
             }
         }
@@ -44,7 +46,7 @@ final class STTextFinderClient: NSObject, NSTextFinderClient {
     }
 
     func replaceCharacters(in range: NSRange, with string: String) {
-        guard let textContentManager = textView?.textContentManager,
+        guard let textContentManager = textView?.textLayoutManager.textContentManager,
               let textRange = NSTextRange(range, in: textContentManager),
               let textView = textView
         else {
@@ -89,8 +91,8 @@ final class STTextFinderClient: NSObject, NSTextFinderClient {
 
         get {
             guard let textLayoutManager = textView?.textLayoutManager,
-                  let textContentManager = textLayoutManager.textContentManager,
-                  !textLayoutManager.textSelections.isEmpty
+                  !textLayoutManager.textSelections.isEmpty,
+                  let textContentManager = textLayoutManager.textContentManager
             else {
                 return []
             }
@@ -108,7 +110,8 @@ final class STTextFinderClient: NSObject, NSTextFinderClient {
 
     func scrollRangeToVisible(_ range: NSRange) {
         guard let textView = textView,
-              let textRange = NSTextRange(range, in: textView.textContentManager)
+              let textContentManager = textView.textLayoutManager.textContentManager,
+              let textRange = NSTextRange(range, in: textContentManager)
         else {
             return
         }
@@ -128,8 +131,7 @@ final class STTextFinderClient: NSObject, NSTextFinderClient {
     }
 
     func rects(forCharacterRange range: NSRange) -> [NSValue]? {
-        guard let textLayoutManager = textView?.textLayoutManager,
-              let textContentManager = textLayoutManager.textContentManager,
+        guard let textContentManager = textView?.textLayoutManager.textContentManager,
               let textRange = NSTextRange(range, in: textContentManager)
         else {
             return nil
diff --git a/Sources/STTextView/STTextViewDelegateProxy.swift b/Sources/STTextView/STTextViewDelegateProxy.swift
index 4ff8a85..774b005 100644
--- a/Sources/STTextView/STTextViewDelegateProxy.swift
+++ b/Sources/STTextView/STTextViewDelegateProxy.swift
@@ -54,11 +54,15 @@ class STTextViewDelegateProxy: STTextViewDelegate {
     }
 
     func textView(_ textView: STTextView, menu: NSMenu, for event: NSEvent, at location: NSTextLocation) -> NSMenu? {
+        guard let textContentManager = textView.textLayoutManager.textContentManager else {
+            return nil
+        }
+
         let effectiveMenu = source?.textView(textView, menu: menu, for: event, at: location)
 
         // Append plugins menus
         let pluginMenus = textView.plugins.events.compactMap { events in
-            events.onContextMenuHandler?(location, textView.textContentManager)
+            events.onContextMenuHandler?(location, textContentManager)
         }
 
         if let effectiveMenu, !pluginMenus.isEmpty {