Sfoglia il codice sorgente

Fix text editor wrapping so input wraps within the content box.

Constrain NSTextView width and reflow on resize and typing so long text no longer renders as a single horizontal line.

Co-authored-by: Cursor <cursoragent@cursor.com>
AhtashamShahzad1 1 mese fa
parent
commit
0c4ca502c7
1 ha cambiato i file con 24 aggiunte e 3 eliminazioni
  1. 24 3
      gramora/Views/Components/ThinCaretTextEditor.swift

+ 24 - 3
gramora/Views/Components/ThinCaretTextEditor.swift

@@ -18,13 +18,29 @@ private final class TextEditorScrollView: NSScrollView {
 
     private func syncTextContainerWidth() {
         guard let textView = documentView as? NSTextView,
-              let container = textView.textContainer else { return }
+              let container = textView.textContainer,
+              let layoutManager = textView.layoutManager else { return }
 
         let width = contentView.bounds.width
         guard width > 1 else { return }
 
-        container.containerSize = NSSize(width: width, height: .greatestFiniteMagnitude)
-        textView.setFrameSize(NSSize(width: width, height: textView.frame.height))
+        textView.minSize = NSSize(width: width, height: 0)
+        textView.maxSize = NSSize(width: width, height: .greatestFiniteMagnitude)
+        container.lineBreakMode = .byWordWrapping
+
+        if abs(textView.frame.width - width) > 0.5 {
+            textView.setFrameSize(NSSize(width: width, height: textView.frame.height))
+        }
+
+        layoutManager.ensureLayout(for: container)
+
+        let usedHeight = layoutManager.usedRect(for: container).height
+        let insetHeight = textView.textContainerInset.height * 2
+        let newHeight = max(usedHeight + insetHeight, contentView.bounds.height)
+
+        if abs(textView.frame.height - newHeight) > 0.5 {
+            textView.setFrameSize(NSSize(width: width, height: newHeight))
+        }
     }
 }
 
@@ -127,6 +143,7 @@ struct ThinCaretTextEditor: NSViewRepresentable {
         textView.isHorizontallyResizable = false
         textView.autoresizingMask = [.width]
         textView.textContainer?.lineFragmentPadding = 0
+        textView.textContainer?.lineBreakMode = .byWordWrapping
         textView.textContainer?.widthTracksTextView = true
         textView.textContainer?.containerSize = NSSize(
             width: 0,
@@ -205,6 +222,10 @@ struct ThinCaretTextEditor: NSViewRepresentable {
             guard let textView = notification.object as? NSTextView else { return }
             parent.text = textView.string
             textView.needsDisplay = true
+
+            if let scrollView = textView.enclosingScrollView as? TextEditorScrollView {
+                scrollView.syncTextContainerWidthIfNeeded()
+            }
         }
 
         func textView(