Fix panic on paste when editing with auto-indent

Antonio Scandurra created

Instead of accepting text as it's input by the user, we will read it
out of the edit operation after it gets sanitized by the buffer.

Change summary

crates/language/src/buffer.rs |  3 ++-
crates/language/src/tests.rs  | 23 +++++++++++++++++++++++
2 files changed, 25 insertions(+), 1 deletion(-)

Detailed changes

crates/language/src/buffer.rs 🔗

@@ -1233,7 +1233,8 @@ impl Buffer {
 
             let inserted_ranges = edits
                 .into_iter()
-                .filter_map(|(range, new_text)| {
+                .zip(&edit_operation.as_edit().unwrap().new_text)
+                .filter_map(|((range, _), new_text)| {
                     let first_newline_ix = new_text.find('\n')?;
                     let new_text_len = new_text.len();
                     let start = (delta + range.start as isize) as usize + first_newline_ix + 1;

crates/language/src/tests.rs 🔗

@@ -22,6 +22,29 @@ fn init_logger() {
     }
 }
 
+#[gpui::test]
+fn test_line_endings(cx: &mut gpui::MutableAppContext) {
+    cx.add_model(|cx| {
+        let mut buffer =
+            Buffer::new(0, "one\r\ntwo\rthree", cx).with_language(Arc::new(rust_lang()), cx);
+        assert_eq!(buffer.text(), "one\ntwo\nthree");
+        assert_eq!(buffer.line_ending(), LineEnding::Windows);
+
+        buffer.check_invariants();
+        buffer.edit_with_autoindent(
+            [(buffer.len()..buffer.len(), "\r\nfour")],
+            IndentSize::spaces(2),
+            cx,
+        );
+        buffer.edit([(0..0, "zero\r\n")], cx);
+        assert_eq!(buffer.text(), "zero\none\ntwo\nthree\nfour");
+        assert_eq!(buffer.line_ending(), LineEnding::Windows);
+        buffer.check_invariants();
+
+        buffer
+    });
+}
+
 #[gpui::test]
 fn test_select_language() {
     let registry = LanguageRegistry::test();