fix diagnostic exceprt issues

Smit Barmase and Lukas Wirth created

Co-authored-by: Lukas Wirth <lukas@zed.dev>

Change summary

crates/diagnostics/src/diagnostics.rs   | 15 ++++++-----
crates/multi_buffer/src/multi_buffer.rs | 33 +++++++++++++++++++++++---
2 files changed, 37 insertions(+), 11 deletions(-)

Detailed changes

crates/diagnostics/src/diagnostics.rs 🔗

@@ -192,12 +192,8 @@ impl ProjectDiagnosticsEditor {
                     });
                     cx.emit(EditorEvent::TitleChanged);
 
-                    if this.editor.focus_handle(cx).contains_focused(window, cx) || this.focus_handle.contains_focused(window, cx) {
-                        log::debug!("diagnostics updated for server {language_server_id}, paths {paths:?}. recording change");
-                    } else {
-                        log::debug!("diagnostics updated for server {language_server_id}, paths {paths:?}. updating excerpts");
-                        this.update_stale_excerpts(window, cx);
-                    }
+                    log::debug!("diagnostics updated for server {language_server_id}, paths {paths:?}. updating excerpts");
+                    this.update_stale_excerpts(window, cx);
                 }
                 _ => {}
             });
@@ -241,6 +237,7 @@ impl ProjectDiagnosticsEditor {
                         }
                     }
                     EditorEvent::Blurred => this.update_stale_excerpts(window, cx),
+                    EditorEvent::Saved => this.update_all_excerpts(window, cx),
                     _ => {}
                 }
             },
@@ -520,7 +517,10 @@ impl ProjectDiagnosticsEditor {
         cx: &mut Context<Self>,
     ) -> Task<Result<()>> {
         let was_empty = self.multibuffer.read(cx).is_empty();
-        let buffer_snapshot = buffer.read(cx).snapshot();
+        let buffer_ = buffer.read(cx);
+        let is_dirty = buffer_.is_dirty();
+        let buffer_snapshot = buffer_.snapshot();
+
         let buffer_id = buffer_snapshot.remote_id();
         let max_severity = if self.include_warnings {
             lsp::DiagnosticSeverity::WARNING
@@ -633,6 +633,7 @@ impl ProjectDiagnosticsEditor {
                         buffer.clone(),
                         &buffer_snapshot,
                         excerpt_ranges,
+                        is_dirty,
                         cx,
                     )
                 });

crates/multi_buffer/src/multi_buffer.rs 🔗

@@ -1587,7 +1587,14 @@ impl MultiBuffer {
             };
 
             let buffer_snapshot = buffer.read(cx).snapshot();
-            self.update_path_excerpts(path.clone(), buffer, &buffer_snapshot, merged_ranges, cx);
+            self.update_path_excerpts(
+                path.clone(),
+                buffer,
+                &buffer_snapshot,
+                merged_ranges,
+                false,
+                cx,
+            );
         }
     }
 
@@ -1611,6 +1618,7 @@ impl MultiBuffer {
             &buffer_snapshot,
             new,
             counts,
+            false,
             cx,
         )
     }
@@ -1621,6 +1629,7 @@ impl MultiBuffer {
         buffer: Entity<Buffer>,
         buffer_snapshot: &BufferSnapshot,
         excerpt_ranges: Vec<ExcerptRange<Point>>,
+        keep_excerpts: bool,
         cx: &mut Context<Self>,
     ) -> (Vec<Range<Anchor>>, bool) {
         let (new, counts) = Self::merge_excerpt_ranges(&excerpt_ranges);
@@ -1631,6 +1640,7 @@ impl MultiBuffer {
             buffer_snapshot,
             new,
             counts,
+            keep_excerpts,
             cx,
         )
     }
@@ -1665,6 +1675,7 @@ impl MultiBuffer {
                         &buffer_snapshot,
                         new,
                         counts,
+                        false,
                         cx,
                     );
                     ranges
@@ -1683,10 +1694,11 @@ impl MultiBuffer {
         buffer_snapshot: &BufferSnapshot,
         new: Vec<ExcerptRange<Point>>,
         counts: Vec<usize>,
+        keep_excerpts: bool,
         cx: &mut Context<Self>,
     ) -> (Vec<Range<Anchor>>, bool) {
         let (excerpt_ids, added_a_new_excerpt) =
-            self.update_path_excerpts(path, buffer, buffer_snapshot, new, cx);
+            self.update_path_excerpts(path, buffer, buffer_snapshot, new, keep_excerpts, cx);
 
         let mut result = Vec::new();
         let mut ranges = ranges.into_iter();
@@ -1735,6 +1747,7 @@ impl MultiBuffer {
         buffer: Entity<Buffer>,
         buffer_snapshot: &BufferSnapshot,
         new: Vec<ExcerptRange<Point>>,
+        keep_excerpts: bool,
         cx: &mut Context<Self>,
     ) -> (Vec<ExcerptId>, bool) {
         let mut insert_after = self
@@ -1819,8 +1832,20 @@ impl MultiBuffer {
             match (new, existing) {
                 (None, None) => break,
                 (None, Some((existing_id, _))) => {
-                    existing_iter.next();
-                    to_remove.push(existing_id);
+                    if keep_excerpts {
+                        self.insert_excerpts_with_ids_after(
+                            insert_after,
+                            buffer.clone(),
+                            mem::take(&mut to_insert),
+                            cx,
+                        );
+                        insert_after = existing_iter.next().unwrap();
+                        excerpt_ids.push(insert_after);
+                        new_iter.next();
+                    } else {
+                        existing_iter.next();
+                        to_remove.push(existing_id);
+                    }
                     continue;
                 }
                 (Some(_), None) => {