fix(config): unwrap {nuwiki:{...}} wrapper in apply_change
CI / cargo fmt --check (push) Failing after 22s
CI / cargo clippy (push) Successful in 21s
CI / cargo test (push) Successful in 29s
CI / editor keymaps (push) Successful in 1m19s

workspace/didChangeConfiguration settings from Neovim arrive as
{ "nuwiki": { "wiki_root": ..., "wikis": [...] } } because
server_settings() in lua/nuwiki/lsp.lua wraps the payload in a
"nuwiki" namespace key.  apply_change() was trying to deserialise that
outer object directly as InitOptions, which always succeeded but produced
all-None fields (unknown keys are ignored by serde), so every settings
refresh was silently dropped.

Unwrap single-key objects whose value is also an object before
deserialising — this handles the Neovim wrapper while keeping the flat
VimL shape working unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-21 23:24:51 -03:00
parent 02172d9e25
commit 6ae642dbee
+14 -1
View File
@@ -367,8 +367,21 @@ impl Config {
/// Re-apply settings received via `workspace/didChangeConfiguration`.
/// On parse failure the existing config is returned unchanged.
///
/// Accepts both the flat shape (`{ "wikis": [...] }`) produced by the
/// VimL client, **and** the Neovim-style wrapper (`{ "nuwiki": { ... } }`)
/// that `server_settings()` in `lua/nuwiki/lsp.lua` produces. Any other
/// single-key object whose value is an object is also unwrapped so
/// editors that namespace settings by server name continue to work.
pub fn apply_change(&mut self, value: &serde_json::Value) {
let raw: InitOptions = match serde_json::from_value(value.clone()) {
// Unwrap { "nuwiki": { ... } } → { ... } so both clients work.
let inner = value
.as_object()
.and_then(|m| if m.len() == 1 { m.values().next() } else { None })
.filter(|v| v.is_object())
.unwrap_or(value);
let raw: InitOptions = match serde_json::from_value(inner.clone()) {
Ok(r) => r,
Err(_) => return,
};