From 8ee599942a0e5ff6fa1a908ca076785e0d2bd0c7 Mon Sep 17 00:00:00 2001
From: Philipp Mildenberger <philipp@mildenberger.me>
Date: Mon, 20 Mar 2023 00:51:41 +0100
Subject: [PATCH] Optimize gutter diagnostics and simplify shown_diagnostics

---
 helix-view/src/document.rs | 15 +++------------
 helix-view/src/gutter.rs   | 16 +++++++++++++---
 2 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs
index 27f5d279..bc81567e 100644
--- a/helix-view/src/document.rs
+++ b/helix-view/src/document.rs
@@ -179,7 +179,7 @@ pub struct Document {
     version: i32, // should be usize?
     pub(crate) modified_since_accessed: bool,
 
-    diagnostics: Vec<Diagnostic>,
+    pub(crate) diagnostics: Vec<Diagnostic>,
     pub(crate) language_servers: HashMap<LanguageServerName, Arc<Client>>,
 
     diff_handle: Option<DiffHandle>,
@@ -1605,17 +1605,8 @@ impl Document {
 
     pub fn shown_diagnostics(&self) -> impl Iterator<Item = &Diagnostic> + DoubleEndedIterator {
         self.diagnostics.iter().filter(|d| {
-            self.language_servers()
-                .find(|ls| ls.id() == d.language_server_id)
-                .and_then(|ls| {
-                    let config = self.language_config()?;
-                    let features = config
-                        .language_servers
-                        .iter()
-                        .find(|features| features.name == ls.name())?;
-                    Some(features.has_feature(LanguageServerFeature::Diagnostics))
-                })
-                == Some(true)
+            self.language_servers_with_feature(LanguageServerFeature::Diagnostics)
+                .any(|ls| ls.id() == d.language_server_id)
         })
     }
 
diff --git a/helix-view/src/gutter.rs b/helix-view/src/gutter.rs
index 78f879c9..8c8abcc3 100644
--- a/helix-view/src/gutter.rs
+++ b/helix-view/src/gutter.rs
@@ -1,5 +1,7 @@
 use std::fmt::Write;
 
+use helix_core::{syntax::LanguageServerFeature, Diagnostic};
+
 use crate::{
     editor::GutterType,
     graphics::{Style, UnderlineStyle},
@@ -55,7 +57,7 @@ pub fn diagnostic<'doc>(
     let error = theme.get("error");
     let info = theme.get("info");
     let hint = theme.get("hint");
-    let diagnostics = doc.shown_diagnostics().collect::<Vec<_>>();
+    let diagnostics = &doc.diagnostics;
 
     Box::new(
         move |line: usize, _selected: bool, first_visual_line: bool, out: &mut String| {
@@ -64,12 +66,20 @@ pub fn diagnostic<'doc>(
             }
             use helix_core::diagnostic::Severity;
             if let Ok(index) = diagnostics.binary_search_by_key(&line, |d| d.line) {
-                let after = diagnostics[index..].iter().take_while(|d| d.line == line);
+                let on_line_and_is_visible = |d: &&Diagnostic| {
+                    d.line == line
+                        && doc
+                            .language_servers_with_feature(LanguageServerFeature::Diagnostics)
+                            .any(|ls| ls.id() == d.language_server_id)
+                };
+                let after = diagnostics[index..]
+                    .iter()
+                    .take_while(on_line_and_is_visible);
 
                 let before = diagnostics[..index]
                     .iter()
                     .rev()
-                    .take_while(|d| d.line == line);
+                    .take_while(on_line_and_is_visible);
 
                 let diagnostics_on_line = after.chain(before);