nvrim/diagnostics/
filter.rs

1//! High-level diagnostic filtering pipeline.
2//!
3//! Orchestrates buffer path filtering, message blacklist, and related info deduplication, returning
4//! retained diagnostics for display while reporting errors via notifications.
5
6use std::convert::identity;
7
8use nvim_oxi::Dictionary;
9use nvim_oxi::api::Buffer;
10
11use crate::diagnostics::filters::BufferWithPath;
12use crate::diagnostics::filters::DiagnosticsFilter;
13use crate::diagnostics::filters::DiagnosticsFilters;
14use crate::diagnostics::filters::buffer::BufferFilter;
15use crate::diagnostics::filters::buffer::BufferFilterImpl;
16
17/// Filters LSP diagnostics based on configured filters.
18pub fn filter(lsp_diags: Vec<Dictionary>) -> Vec<Dictionary> {
19    let current_buffer = Buffer::current();
20
21    let Ok(buffer_with_path) = BufferWithPath::try_from(current_buffer).inspect_err(|err| {
22        ytil_noxi::notify::error(format!("error creating BufferWithContent | error={err:#?}"));
23    }) else {
24        return vec![];
25    };
26
27    // Keeping this as a separate filter because it short circuits the whole filtering and
28    // does not require any LSP diagnostics to apply its logic, just the [`nvim_oxi::api::Buffer`].
29    let buffer_filter = BufferFilterImpl;
30    if buffer_filter
31        .skip_diagnostic(&buffer_with_path)
32        .inspect_err(|err| {
33            ytil_noxi::notify::error(format!("error getting filter by buffer | error={err:#?}"));
34        })
35        .unwrap_or(false)
36    {
37        return vec![];
38    }
39
40    let Ok(filters) = DiagnosticsFilters::all(&lsp_diags).inspect_err(|err| {
41        ytil_noxi::notify::error(format!("error getting diagnostics filters | error={err:#?}"));
42    }) else {
43        return vec![];
44    };
45
46    let mut out = vec![];
47    for lsp_diag in lsp_diags {
48        if filters
49            .skip_diagnostic(&buffer_with_path, &lsp_diag)
50            .inspect_err(|err| {
51                ytil_noxi::notify::error(format!(
52                    "error filtering diagnostic | buffer={:?} diagnostic={lsp_diag:#?} error={err:#?}",
53                    buffer_with_path.path()
54                ));
55            })
56            .is_ok_and(identity)
57        {
58            continue;
59        }
60        out.push(lsp_diag.clone());
61    }
62    out
63}