From 6deba47106be4886ac63a1484971ec60fe1d82d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Fr=C3=B3es=20Franco?= Date: Wed, 3 Jun 2026 01:28:44 +0000 Subject: [PATCH] fix(search): graceful no-match + NuwikiSearch alias (re-audit follow-up) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Re-audit of the just-landed command work found one real bug I introduced and a convention gap: - VimwikiSearch / VWS raised a raw E480 on a no-match search; upstream reports it gracefully. Both clients now catch it (try/catch in Vim, pcall in Neovim) and emit "nuwiki: no match for ". - Added a NuwikiSearch alias alongside VimwikiSearch/VWS (every other command carries a Nuwiki* form). Gap-doc note corrected: nuwiki's search populates + opens the location list (shows all matches) where upstream jumps to the first match — logged as a minor presentation divergence rather than claiming exact parity. Config + mappings re-audits came back clean (no new gaps, no regressions; table-mapping rewire verified non-recursive, gLH/gLL/gLR present). Tests: cmd.VimwikiSearch_no_match_graceful, surface.{Vimwiki,Nuwiki}Search. Neovim 301, Vim 294/18/21 pass. Co-Authored-By: Claude Opus 4.8 (1M context) --- autoload/nuwiki/commands.vim | 7 ++++++- development/tests/test-keymaps-vim.vim | 14 +++++++++++++- development/tests/test-keymaps.lua | 2 +- development/vimwiki-gap.md | 12 ++++++++---- ftplugin/vimwiki.vim | 2 ++ lua/nuwiki/commands.lua | 6 +++++- 6 files changed, 35 insertions(+), 8 deletions(-) diff --git a/autoload/nuwiki/commands.vim b/autoload/nuwiki/commands.vim index 4842bba..b65b97d 100644 --- a/autoload/nuwiki/commands.vim +++ b/autoload/nuwiki/commands.vim @@ -205,7 +205,12 @@ function! nuwiki#commands#search(args) abort endif let l:ext = l:ext[0] ==# '.' ? l:ext : '.' . l:ext let l:glob = l:root ==# '' ? '**' : fnameescape(l:root) . '**/*' . l:ext - execute 'lvimgrep /' . escape(l:pat, '/') . '/j ' . l:glob + try + execute 'lvimgrep /' . escape(l:pat, '/') . '/j ' . l:glob + catch /E480/ + echohl WarningMsg | echom 'nuwiki: no match for ' . l:pat | echohl None + return + endtry lopen endfunction diff --git a/development/tests/test-keymaps-vim.vim b/development/tests/test-keymaps-vim.vim index 408ad31..c9a7c74 100644 --- a/development/tests/test-keymaps-vim.vim +++ b/development/tests/test-keymaps-vim.vim @@ -112,7 +112,7 @@ let s:both_forms = [ \ 'RebuildTags', '2HTML', '2HTMLBrowse', 'All2HTML', 'Rss', \ 'NormalizeLink', 'RenumberList', 'RenumberAllLists', \ 'ListToggle', 'IncrementListItem', 'DecrementListItem', - \ 'CatUrl', 'ShowVersion', 'Return', 'Var', + \ 'CatUrl', 'ShowVersion', 'Return', 'Var', 'Search', \ ] for s:suffix in s:both_forms for s:prefix in ['Nuwiki', 'Vimwiki'] @@ -692,6 +692,18 @@ call s:record( \ 'cmd.search_and_tablealign_nargs', \ 'err=' . s:attr_err) +" A no-match search must be caught (friendly message), not raise a raw E480. +let s:nm_err = '' +try + VimwikiSearch zzznomatchxyzqqq +catch /E480/ + let s:nm_err = v:exception +catch + " other errors (no wiki files, etc.) are fine — only E480 is the regression. +endtry +call s:record(s:nm_err ==# '' ? 1 : 0, + \ 'cmd.VimwikiSearch_no_match_graceful', 'err=' . s:nm_err) + " ===== :VimwikiGoto -nargs=* ===== " Was -nargs=1, so a page name with a space raised E488 (and the empty-arg " prompt fallback was unreachable). Now -nargs=*: a multi-word arg must parse. diff --git a/development/tests/test-keymaps.lua b/development/tests/test-keymaps.lua index 1d64f72..428931f 100644 --- a/development/tests/test-keymaps.lua +++ b/development/tests/test-keymaps.lua @@ -139,7 +139,7 @@ vim.defer_fn(function() 'RebuildTags', '2HTML', '2HTMLBrowse', 'All2HTML', 'Rss', 'NormalizeLink', 'RenumberList', 'RenumberAllLists', 'ListToggle', 'IncrementListItem', 'DecrementListItem', - 'CatUrl', 'ShowVersion', 'Return', 'Var', + 'CatUrl', 'ShowVersion', 'Return', 'Var', 'Search', } for _, suffix in ipairs(both_forms) do for _, prefix in ipairs({ 'Nuwiki', 'Vimwiki' }) do diff --git a/development/vimwiki-gap.md b/development/vimwiki-gap.md index 89eff18..6abeb0a 100644 --- a/development/vimwiki-gap.md +++ b/development/vimwiki-gap.md @@ -269,10 +269,14 @@ fix site. through `nuwiki#commands#search` / `commands.search` (both clients), which resolves the wiki whose root contains the current file (else the first configured wiki, else CWD) and `lvimgrep`s `/**/*` into the location - list; an empty pattern reuses the last search (`@/`). The `-nargs=*` attr fix - (2026-06-03) is folded in. _(nuwiki uses Vim's `lvimgrep` rather than a bespoke - engine — the same mechanism vimwiki uses — so this is full behavioral parity.)_ - Covered by `cmd.search_and_tablealign_nargs` (`test-keymaps-vim.vim`). + list; an empty pattern reuses the last search (`@/`); a no-match is caught and + reported (no raw `E480`). Added a `NuwikiSearch` alias alongside + `VimwikiSearch`/`VWS`. The `-nargs=*` attr fix (2026-06-03) is folded in. + nuwiki uses Vim's `lvimgrep` — the same mechanism vimwiki uses. **Minor + presentation divergence:** nuwiki populates + opens the location list (`/j`, + then `:lopen`) showing all matches, whereas upstream jumps to the first match + and leaves the list closed. Covered by `cmd.search_and_tablealign_nargs` + (`test-keymaps-vim.vim`). - [x] **`VimwikiChangeSymbolTo` / `VimwikiListChangeSymbolI` lack `-range`** _(new, 2026-05-31 re-audit; fixed same day)_ — upstream both carry `-range -nargs=1`; nuwiki had `-nargs=1` only, so a visual-range invocation diff --git a/ftplugin/vimwiki.vim b/ftplugin/vimwiki.vim index 0137b5e..570168e 100644 --- a/ftplugin/vimwiki.vim +++ b/ftplugin/vimwiki.vim @@ -95,6 +95,7 @@ if !has('nvim') command! -buffer VimwikiPrevLink call nuwiki#commands#link_prev() command! -buffer VimwikiBaddLink call nuwiki#commands#badd_link() command! -buffer -nargs=* VimwikiSearch call nuwiki#commands#search() + command! -buffer -nargs=* NuwikiSearch call nuwiki#commands#search() command! -buffer -nargs=* VWS call nuwiki#commands#search() command! -buffer -nargs=* -complete=customlist,nuwiki#complete#pages VimwikiGoto call nuwiki#commands#wiki_goto_page() @@ -450,6 +451,7 @@ command! -buffer -nargs=* -complete=customlist,nuwiki#complete#pages VimwikiGoto command! -buffer VimwikiBacklinks lua vim.lsp.buf.references() command! -buffer VWB lua vim.lsp.buf.references() command! -buffer -nargs=* VimwikiSearch lua require('nuwiki.commands').search() +command! -buffer -nargs=* NuwikiSearch lua require('nuwiki.commands').search() command! -buffer -nargs=* VWS lua require('nuwiki.commands').search() command! -buffer VimwikiDeleteFile lua require('nuwiki.commands').delete_file() diff --git a/lua/nuwiki/commands.lua b/lua/nuwiki/commands.lua index f95728e..1e3fc6d 100644 --- a/lua/nuwiki/commands.lua +++ b/lua/nuwiki/commands.lua @@ -314,7 +314,11 @@ function M.search(args) end if not ext:match('^%.') then ext = '.' .. ext end local glob = root == '' and '**' or (vim.fn.fnameescape(root) .. '**/*' .. ext) - vim.cmd('lvimgrep /' .. vim.fn.escape(pat, '/') .. '/j ' .. glob) + local ok = pcall(vim.cmd, 'lvimgrep /' .. vim.fn.escape(pat, '/') .. '/j ' .. glob) + if not ok then + vim.notify('nuwiki: no match for ' .. pat, vim.log.levels.WARN) + return + end vim.cmd('lopen') end