Skip to main content

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