From 09b9bd98a31f948b1705be2043410d0b937f5c14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Fr=C3=B3es=20Franco?= Date: Mon, 11 May 2026 22:16:57 +0000 Subject: [PATCH] fix(ftplugin): load on .wiki buffers without manual filetype override MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three reasons the plugin wasn't activating on `nvim --clean -u init.lua foo.wiki`: 1. **File-name mismatch.** Vim's filetype-plugin runtime looks for `ftplugin/.vim` matching the *filetype name*. Our filetype is `vimwiki` (per `ftdetect`) but the file was named `ftplugin/nuwiki.vim` — so `:runtime! ftplugin/vimwiki.vim` from the built-in FileType autocmd never found it, and none of the `:Vimwiki*` / `:Nuwiki*` commands got defined. Same wart on the syntax side. Renamed: - `ftplugin/nuwiki.vim` → `ftplugin/vimwiki.vim` - `syntax/nuwiki.vim` → `syntax/vimwiki.vim` 2. **`setfiletype` deferred to Neovim's bundled rule.** Neovim ships a default `*.wiki → mediawiki` rule via `vim.filetype.add`, and `:setfiletype vimwiki` is a no-op once a filetype has been set. - `ftdetect/nuwiki.vim` now uses `set filetype=vimwiki` (force). - `lua/nuwiki/init.lua`'s `setup()` also calls `vim.filetype.add({ extension = { wiki = 'vimwiki', ... } })` so the modern table-based detection picks us before the bundled rule fires. Honours `config.options.file_extension` so a user with a custom extension gets covered automatically. 3. **`foldmethod`/`foldexpr` are window-local options.** `ftplugin.lua` was setting them with `nvim_set_option_value({ buf = bufnr })`, which threw `'buf' cannot be passed for window-local option 'foldmethod'` and aborted the rest of the per-buffer attach. Switched to `vim.opt_local.*` (window-aware), applied on the current window when the ftplugin fires, and re-applied via a `BufWinEnter` autocmd so `:split` / `:vsplit` keep the fold mode. Verified end-to-end with: nvim --clean -u init.lua sample.wiki → filetype = vimwiki → :VimwikiTOC, :NuwikiIndex, … all defined → foldmethod = expr, foldexpr = v:lua.vim.lsp.foldexpr() → ftdetect, plugin, ftplugin, syntax all in :scriptnames Total 377 tests still pass. Co-Authored-By: Claude Opus 4.7 (1M context) --- ftdetect/nuwiki.vim | 7 +++- ftplugin/{nuwiki.vim => vimwiki.vim} | 0 lua/nuwiki/ftplugin.lua | 53 ++++++++++++++-------------- lua/nuwiki/init.lua | 14 ++++++++ syntax/{nuwiki.vim => vimwiki.vim} | 0 5 files changed, 46 insertions(+), 28 deletions(-) rename ftplugin/{nuwiki.vim => vimwiki.vim} (100%) rename syntax/{nuwiki.vim => vimwiki.vim} (100%) diff --git a/ftdetect/nuwiki.vim b/ftdetect/nuwiki.vim index b858a8c..5f22638 100644 --- a/ftdetect/nuwiki.vim +++ b/ftdetect/nuwiki.vim @@ -3,5 +3,10 @@ " Users who configure a custom `file_extension` in setup() should add their " own `:autocmd BufRead,BufNewFile *.myext setfiletype vimwiki` mapping; " we hardcode `.wiki` since ftdetect runs before any user setup() call. +" +" Use `set filetype=…` (not `setfiletype`) so we override Neovim's bundled +" `*.wiki → mediawiki` rule. Users who actually want MediaWiki on .wiki +" can override this with their own autocmd at a later runtimepath entry, +" or with `vim.filetype.add` in Neovim. -autocmd! BufRead,BufNewFile *.wiki setfiletype vimwiki +autocmd! BufRead,BufNewFile *.wiki set filetype=vimwiki diff --git a/ftplugin/nuwiki.vim b/ftplugin/vimwiki.vim similarity index 100% rename from ftplugin/nuwiki.vim rename to ftplugin/vimwiki.vim diff --git a/lua/nuwiki/ftplugin.lua b/lua/nuwiki/ftplugin.lua index 1b1ab9c..805d706 100644 --- a/lua/nuwiki/ftplugin.lua +++ b/lua/nuwiki/ftplugin.lua @@ -9,34 +9,33 @@ local function setup_folding(bufnr, folding_mode) if folding_mode == 'off' then return end - if folding_mode == 'expr' then - vim.api.nvim_set_option_value('foldmethod', 'expr', { buf = bufnr }) - vim.api.nvim_set_option_value( - 'foldexpr', - 'v:lua.require("nuwiki.folding").expr()', - { buf = bufnr } - ) - vim.api.nvim_set_option_value( - 'foldtext', - 'v:lua.require("nuwiki.folding").foldtext()', - { buf = bufnr } - ) - return - end - -- folding_mode == 'lsp' (default): rely on the server's - -- `foldingRange` capability. Neovim 0.11+ enables it automatically - -- via `vim.lsp.foldexpr`. Older versions get the regex fallback. - if vim.fn.has('nvim-0.11') == 1 and vim.lsp.foldexpr then - vim.api.nvim_set_option_value('foldmethod', 'expr', { buf = bufnr }) - vim.api.nvim_set_option_value( - 'foldexpr', - 'v:lua.vim.lsp.foldexpr()', - { buf = bufnr } - ) - else - -- Pre-0.11 — degrade to the regex fallback so users still get folds. - setup_folding(bufnr, 'expr') + -- `foldmethod` / `foldexpr` / `foldtext` are window-local options. + -- The ftplugin runs during BufRead → FileType, by which time the + -- buffer is displayed in the current window. `vim.opt_local` writes + -- to the current window's view of the option. + local apply = function() + if folding_mode == 'expr' + or not (vim.fn.has('nvim-0.11') == 1 and vim.lsp.foldexpr) + then + vim.opt_local.foldmethod = 'expr' + vim.opt_local.foldexpr = 'v:lua.require("nuwiki.folding").expr()' + vim.opt_local.foldtext = 'v:lua.require("nuwiki.folding").foldtext()' + else + -- LSP-backed folding via Neovim 0.11+'s built-in foldexpr. + vim.opt_local.foldmethod = 'expr' + vim.opt_local.foldexpr = 'v:lua.vim.lsp.foldexpr()' + end end + + -- Set on the current window first (the one that triggered the + -- ftplugin). Also re-apply on any future split that views this + -- buffer, so `v` / `:split` preserves the fold method. + apply() + vim.api.nvim_create_autocmd('BufWinEnter', { + buffer = bufnr, + group = vim.api.nvim_create_augroup('nuwiki_folding_' .. bufnr, { clear = true }), + callback = apply, + }) end function M.attach(bufnr) diff --git a/lua/nuwiki/init.lua b/lua/nuwiki/init.lua index 556e2b8..d11cc32 100644 --- a/lua/nuwiki/init.lua +++ b/lua/nuwiki/init.lua @@ -15,6 +15,20 @@ local lsp = require('nuwiki.lsp') function M.setup(opts) config.apply(opts or {}) + + -- Neovim 0.7+ resolves filetypes via `vim.filetype.match` before any + -- `ftdetect/*.vim` autocmd fires, and its bundled rule for `*.wiki` + -- returns `mediawiki`. Register an authoritative rule here so this + -- plugin's filetype (vimwiki) wins. + if vim.filetype and vim.filetype.add then + local extensions = { wiki = 'vimwiki' } + local ext = (config.options.file_extension or '.wiki'):gsub('^%.', '') + if ext ~= 'wiki' and ext ~= '' then + extensions[ext] = 'vimwiki' + end + vim.filetype.add({ extension = extensions }) + end + lsp.register() end diff --git a/syntax/nuwiki.vim b/syntax/vimwiki.vim similarity index 100% rename from syntax/nuwiki.vim rename to syntax/vimwiki.vim