diff --git a/crates/agent_ui/src/buffer_codegen.rs b/crates/agent_ui/src/buffer_codegen.rs index 0b7c1f61988979565aa9b55d4bbd245682b680df..3877bede3370589d1b6f74529cfa3c6ca1f34f0a 100644 --- a/crates/agent_ui/src/buffer_codegen.rs +++ b/crates/agent_ui/src/buffer_codegen.rs @@ -491,6 +491,14 @@ impl CodegenAlternative { cx: &mut Context, ) { let start_time = Instant::now(); + + // Make a new snapshot and re-resolve anchor in case the document was modified. + // This can happen often if the editor loses focus and is saved + reformatted, + // as in https://github.com/zed-industries/zed/issues/39088 + self.snapshot = self.buffer.read(cx).snapshot(cx); + self.range = self.snapshot.anchor_after(self.range.start) + ..self.snapshot.anchor_after(self.range.end); + let snapshot = self.snapshot.clone(); let selected_text = snapshot .text_for_range(self.range.start..self.range.end) diff --git a/crates/language/src/buffer_tests.rs b/crates/language/src/buffer_tests.rs index 4f3f760ba8b841c45031cd1a811f6bb1e8fd2534..14475af5984d75de9e166dd1d8a0379c6a66f3fd 100644 --- a/crates/language/src/buffer_tests.rs +++ b/crates/language/src/buffer_tests.rs @@ -3455,6 +3455,25 @@ fn test_contiguous_ranges() { ); } +#[gpui::test] +fn test_insertion_after_deletion(cx: &mut gpui::App) { + let buffer = cx.new(|cx| Buffer::local("struct Foo {\n \n}", cx)); + buffer.update(cx, |buffer, cx| { + let mut anchor = buffer.anchor_after(17); + buffer.edit([(12..18, "")], None, cx); + let snapshot = buffer.snapshot(); + assert_eq!(snapshot.text(), "struct Foo {}"); + if !anchor.is_valid(&snapshot) { + anchor = snapshot.anchor_after(snapshot.offset_for_anchor(&anchor)); + } + buffer.edit([(anchor..anchor, "\n")], None, cx); + buffer.edit([(anchor..anchor, "field1:")], None, cx); + buffer.edit([(anchor..anchor, " i32,")], None, cx); + let snapshot = buffer.snapshot(); + assert_eq!(snapshot.text(), "struct Foo {\nfield1: i32,}"); + }) +} + #[gpui::test(iterations = 500)] fn test_trailing_whitespace_ranges(mut rng: StdRng) { // Generate a random multi-line string containing