fix(follow-link): create missing page + wrap word on <CR>
Two missing pieces in the previous "follow creates page" fix:
1. **`wiki_root` never reached the server.** The Lua glue (and the
Vim autoload glue) was sending the config under `settings` — that
field is for `workspace/didChangeConfiguration` notifications, not
for `initialize`. The server's `Config::from_init_params` reads
`initialization_options`, so `wiki_root` arrived as `None`, the
`Wiki` aggregate was empty, and `wiki_for_uri` returned `None` →
`resolve_target_uri` bailed before reaching my synthesise path,
leaving `<CR>` with "No Location Found".
Both glues now send the same payload under both keys:
- `lua/nuwiki/lsp.lua` → adds `init_options = init_options()`
alongside the existing `settings = …`.
- `autoload/nuwiki/lsp.vim` → adds `initialization_options` to
the `lsp#register_server` call.
The server keeps reading from `initializationOptions` at startup
*and* honouring `didChangeConfiguration` later (Phase 11 plumbing).
2. **No-wiki fallback in the server.** Even with the glue fix above,
users who launch nuwiki on an ad-hoc `.wiki` file outside any
workspace folder would still get an empty `wikis` list. The
`LinkKind::Wiki` arm now falls back to a new
`synthesise_page_uri_next_to(source_uri, path)` which builds the
future page next to the current file. `<CR>` on `[[NewPage]]`
opens `./NewPage.wiki`, save creates it.
3. **`<CR>` on a plain word now wraps + follows.** Mirrors vimwiki's
`:VimwikiFollowLink`: when the cursor isn't already inside
`[[…]]`, the new `nuwiki.commands.follow_link_or_create` /
`nuwiki#commands#follow_link_or_create` first wraps the word
under cursor as `[[word]]`, places the cursor inside the link,
then dispatches `vim.lsp.buf.definition()` /
`:LspDefinition`. Both editor paths now bind `<CR>` /
`<S-CR>` / `<C-CR>` / `<C-S-CR>` to this smart variant.
Verified end-to-end:
- `[[NewPage]]` with the rebuilt binary: definition returns
`file:///tmp/wiki/NewPage.wiki` as a Location, so the editor
opens an empty buffer for it.
- A bare `MyPage` word becomes `[[MyPage]]` in the buffer before
the follow request fires.
Total 381 tests still pass; fmt + clippy clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -94,6 +94,69 @@ function! s:wiki_pick(notification) abort
|
||||
\ function('s:open_uri_from'))
|
||||
endfunction
|
||||
|
||||
" ===== Smart <CR>: follow or wrap-then-follow =====
|
||||
|
||||
function! s:cursor_inside_wikilink() abort
|
||||
let l:line = getline('.')
|
||||
let l:col = col('.')
|
||||
let l:i = 1
|
||||
let l:open = 0
|
||||
while l:i < strlen(l:line)
|
||||
if strpart(l:line, l:i - 1, 2) ==# '[['
|
||||
let l:open = l:i
|
||||
let l:i += 2
|
||||
elseif strpart(l:line, l:i - 1, 2) ==# ']]'
|
||||
let l:open = 0
|
||||
let l:i += 2
|
||||
else
|
||||
let l:i += 1
|
||||
endif
|
||||
if l:i > l:col
|
||||
break
|
||||
endif
|
||||
endwhile
|
||||
return l:open > 0
|
||||
endfunction
|
||||
|
||||
function! s:wrap_cword_as_wikilink() abort
|
||||
let l:word = expand('<cword>')
|
||||
if l:word ==# ''
|
||||
return 0
|
||||
endif
|
||||
let l:line = getline('.')
|
||||
let l:col = col('.')
|
||||
" Find word boundaries around cursor (1-based).
|
||||
let l:left = l:col
|
||||
while l:left > 1 && strpart(l:line, l:left - 2, 1) =~# '[A-Za-z0-9_-]'
|
||||
let l:left -= 1
|
||||
endwhile
|
||||
let l:right = l:col
|
||||
while l:right <= strlen(l:line) && strpart(l:line, l:right - 1, 1) =~# '[A-Za-z0-9_-]'
|
||||
let l:right += 1
|
||||
endwhile
|
||||
let l:word_real = strpart(l:line, l:left - 1, l:right - l:left)
|
||||
if l:word_real ==# ''
|
||||
return 0
|
||||
endif
|
||||
let l:new_line = strpart(l:line, 0, l:left - 1) . '[[' . l:word_real . ']]' . strpart(l:line, l:right - 1)
|
||||
call setline('.', l:new_line)
|
||||
call cursor(line('.'), l:left + 2)
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
function! nuwiki#commands#follow_link_or_create() abort
|
||||
if !s:cursor_inside_wikilink()
|
||||
call s:wrap_cword_as_wikilink()
|
||||
endif
|
||||
if exists(':LspDefinition') == 2
|
||||
LspDefinition
|
||||
else
|
||||
echohl WarningMsg
|
||||
echom 'nuwiki: :LspDefinition unavailable; install vim-lsp'
|
||||
echohl None
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Pure-VimL bullet-continuation for `o` / `O` — mirrors the Lua side
|
||||
" so re-pressing the key keeps the list marker (and checkbox if any).
|
||||
function! nuwiki#commands#open_below_with_bullet() abort
|
||||
|
||||
@@ -36,6 +36,7 @@ function! nuwiki#lsp#start() abort
|
||||
\ 'name': 'nuwiki',
|
||||
\ 'cmd': {server_info -> [l:bin]},
|
||||
\ 'allowlist': ['vimwiki'],
|
||||
\ 'initialization_options': s:settings(),
|
||||
\ 'config': { 'settings': { 'nuwiki': s:settings() } },
|
||||
\ })
|
||||
" vim-lsp auto-enables servers when 'g:lsp_auto_enable' is on
|
||||
|
||||
Reference in New Issue
Block a user