Explorar el Código

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 hace 1 mes
padre
commit
0c4ca502c7
Se han modificado 1 ficheros con 24 adiciones y 3 borrados
  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(