feat(lsp): wire diagnostic.link_severity through from client config

The broken-link diagnostic severity was already consulted by
collect_diagnostics, but Config.diagnostic was hardcoded to the default and
never populated from initializationOptions/didChangeConfiguration. Parse a
client-supplied `diagnostic.link_severity` ('off'|'hint'|'warn'|'error',
case-insensitive) into LinkSeverity and apply it in both from_init_params and
apply_change. Partial config updates that omit `diagnostic` preserve the
existing severity rather than resetting it.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-30 21:53:46 -03:00
parent b922f0d612
commit 9b6413c3de
2 changed files with 94 additions and 1 deletions
@@ -319,6 +319,54 @@ fn raw_wiki_parses_every_new_key() {
assert!(w.auto_toc);
}
#[test]
fn link_severity_parses_from_client_config() {
for (input, expected) in [
("off", LinkSeverity::Off),
("hint", LinkSeverity::Hint),
("warn", LinkSeverity::Warning),
("warning", LinkSeverity::Warning),
("error", LinkSeverity::Error),
("ERROR", LinkSeverity::Error),
] {
let cfg = config_from_json(json!({
"wiki_root": "/tmp/w",
"diagnostic": { "link_severity": input },
}));
assert_eq!(
cfg.diagnostic.link_severity, expected,
"input {input:?} should map to {expected:?}"
);
}
}
#[test]
fn link_severity_invalid_or_absent_falls_back_to_default() {
// Unknown string → default (Warning).
let bad = config_from_json(json!({
"wiki_root": "/tmp/w",
"diagnostic": { "link_severity": "loud" },
}));
assert_eq!(bad.diagnostic.link_severity, LinkSeverity::Warning);
// No diagnostic key at all → default.
let none = config_from_json(json!({ "wiki_root": "/tmp/w" }));
assert_eq!(none.diagnostic.link_severity, LinkSeverity::Warning);
}
#[test]
fn apply_change_preserves_severity_on_partial_update() {
let mut cfg = config_from_json(json!({
"wiki_root": "/tmp/w",
"diagnostic": { "link_severity": "error" },
}));
assert_eq!(cfg.diagnostic.link_severity, LinkSeverity::Error);
// A later update that omits `diagnostic` must not reset severity.
cfg.apply_change(&json!({ "wiki_root": "/tmp/w2" }));
assert_eq!(cfg.diagnostic.link_severity, LinkSeverity::Error);
}
#[test]
fn vim_flat_and_neovim_wrapped_payloads_desugar_identically() {
// Parity guard for the two client shapes:
@@ -332,6 +380,7 @@ fn vim_flat_and_neovim_wrapped_payloads_desugar_identically() {
"file_extension": ".md",
"syntax": "vimwiki",
"log_level": "debug",
"diagnostic": { "link_severity": "error" },
"wikis": [
{
"name": "personal",
@@ -347,6 +396,11 @@ fn vim_flat_and_neovim_wrapped_payloads_desugar_identically() {
let flat = config_from_json(inner.clone());
let wrapped = config_from_json(json!({ "nuwiki": inner }));
assert_eq!(
flat.diagnostic.link_severity,
wrapped.diagnostic.link_severity
);
assert_eq!(flat.diagnostic.link_severity, LinkSeverity::Error);
assert_eq!(flat.wikis.len(), wrapped.wikis.len());
for (a, b) in flat.wikis.iter().zip(wrapped.wikis.iter()) {
assert_eq!(a.name, b.name);