From 30cccd88bd0fffe1c5e13c23b8ab216788ea0f7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Fr=C3=B3es=20Franco?= Date: Wed, 3 Jun 2026 14:20:14 +0000 Subject: [PATCH] fix(vars): resolve wiki by index in the vimwiki compat shim (R15) `vimwiki#vars#get_wikilocal(key, N)` previously ignored the wiki-index argument and always read the scalar `g:nuwiki_*` globals (the first wiki), so third-party plugins (vimwiki-sync, vim-zettel) got the wrong wiki's path/ext/syntax in a multi-wiki setup. Now: - an explicit numeric index selects that wiki from `g:nuwiki_wikis[N]`, falling back per-key to the scalar globals; - with no index, the wiki owning the current buffer is resolved (matching upstream's `g:vimwiki_current_idx` behaviour); - an out-of-range index clamps to the first wiki. The single-wiki shorthand path is unchanged. Verified with a headless Vim test (by-index, global fallback, clamp, no-arg, shorthand) and the Vim keymap harness (301/18/21, 0 failed). Co-Authored-By: Claude Opus 4.8 --- autoload/vimwiki/vars.vim | 61 +++++++++++++++++++++++++++++--------- development/vimwiki-gap.md | 10 +++++-- 2 files changed, 54 insertions(+), 17 deletions(-) diff --git a/autoload/vimwiki/vars.vim b/autoload/vimwiki/vars.vim index cf291b5..94abc14 100644 --- a/autoload/vimwiki/vars.vim +++ b/autoload/vimwiki/vars.vim @@ -6,6 +6,30 @@ " Values are read from nuwiki's own config variables so users don't have " to duplicate settings. +" Resolve which wiki a `get_wikilocal` call refers to, mirroring upstream: +" - an explicit numeric second argument selects that wiki (0-based); +" - otherwise the wiki owning the current buffer is used +" (upstream's `g:vimwiki_current_idx`); +" - failing that, the first/shorthand wiki (index 0). +function! s:resolve_index(...) abort + if a:0 >= 1 && type(a:1) == type(0) + return a:1 + endif + let l:file = expand('%:p') + if !empty(l:file) + let l:n = 0 + for l:w in nuwiki#commands#wiki_list() + let l:wroot = fnamemodify(expand(l:w.root), ':p') + if l:wroot[len(l:wroot) - 1:] !=# '/' | let l:wroot .= '/' | endif + if a:file !=# '' && l:file[: len(l:wroot) - 1] ==# l:wroot + return l:n + endif + let l:n += 1 + endfor + endif + return 0 +endfunction + " Per-wiki local config values. " " Supported keys: @@ -14,28 +38,37 @@ " ext / extension — file extension (default '.wiki') " syntax — syntax name (default 'vimwiki') " -" LIMITATION: the optional second argument (upstream's wiki index) is -" ignored — values always come from the scalar `g:nuwiki_*` vars, i.e. -" the first/shorthand wiki. Third-party plugins that query a specific -" wiki by index in a multi-wiki setup will get the first wiki's values. -" The shim exists for single-wiki compatibility (vimwiki-sync, vim-zettel); -" extend here with `g:nuwiki_wikis[a:1]` lookups if multi-wiki support is -" needed. +" The optional second argument is the wiki index (upstream's signature); +" when omitted, the wiki owning the current buffer is used. Values are +" pulled from the matching `g:nuwiki_wikis` entry, falling back to the +" scalar `g:nuwiki_*` globals for keys that entry doesn't set. function! vimwiki#vars#get_wikilocal(key, ...) abort + if a:key ==# 'is_temporary_wiki' + return 0 + endif + + let l:idx = call('s:resolve_index', a:000) + let l:wikis = nuwiki#commands#wiki_list() + if l:idx < 0 || l:idx >= len(l:wikis) + let l:idx = 0 + endif + let l:w = l:wikis[l:idx] + if a:key ==# 'path' - let l:root = expand(get(g:, 'nuwiki_wiki_root', '~/vimwiki')) + let l:root = expand(l:w.root) " Ensure trailing slash to match what the original vimwiki returns. return l:root =~# '/$' ? l:root : l:root . '/' - elseif a:key ==# 'is_temporary_wiki' - return 0 - elseif a:key ==# 'ext' || a:key ==# 'extension' - let l:ext = get(g:, 'nuwiki_file_extension', '.wiki') - return l:ext[0] ==# '.' ? l:ext : '.' . l:ext + " wiki_list() already normalises the leading dot. + return l:w.ext elseif a:key ==# 'syntax' - return get(g:, 'nuwiki_syntax', 'vimwiki') + " wiki_list() doesn't carry `syntax`; read the per-wiki entry, then the + " global default. + let l:cfg = (exists('g:nuwiki_wikis') && len(g:nuwiki_wikis) > l:idx) + \ ? g:nuwiki_wikis[l:idx] : {} + return get(l:cfg, 'syntax', get(g:, 'nuwiki_syntax', 'vimwiki')) endif return '' diff --git a/development/vimwiki-gap.md b/development/vimwiki-gap.md index 7430241..1816761 100644 --- a/development/vimwiki-gap.md +++ b/development/vimwiki-gap.md @@ -856,9 +856,13 @@ re-audit confirmed no regressions. single-keypress paths over small inputs — regression risk outweighs the gain.)_ - [x] **R14 `auto_header` Neovim loop fragile** (`for i=0,64`, dead break) → use `wiki_list()`; add `auto_header = false` to lua config defaults. -- [x] **R15 `autoload/vimwiki/vars.vim` shim ignores the wiki index** — - `get_wikilocal(key, N)` always returns wiki 0 (latent multi-wiki bug for - third-party plugins). +- [x] **R15 `autoload/vimwiki/vars.vim` shim ignores the wiki index** + _(fully fixed 2026-06-03)_ — `get_wikilocal(key, N)` now resolves wiki `N` + from `g:nuwiki_wikis[N]` (falling back to the scalar `g:nuwiki_*` globals per + key); with no index it resolves the wiki owning the current buffer, matching + upstream's `g:vimwiki_current_idx` behaviour, and clamps an out-of-range index + to the first wiki. Multi-wiki third-party plugins (vimwiki-sync, vim-zettel) + now get the right wiki's `path`/`ext`/`syntax`. ### P4 — trivial - [x] **R16** `ftplugin/vimwiki.vim` header comment says `ftplugin/nuwiki.vim`.