diff --git a/autoload/nuwiki/commands.vim b/autoload/nuwiki/commands.vim index b8a57d4..ba8dee0 100644 --- a/autoload/nuwiki/commands.vim +++ b/autoload/nuwiki/commands.vim @@ -24,21 +24,75 @@ function! s:has_vimlsp() abort return exists('*lsp#send_request') endfunction -function! s:exec(command, arguments, ...) abort - if !s:has_vimlsp() +function! s:has_coc() abort + return exists('*CocActionAsync') +endfunction + +" Adapt a coc.nvim (err, result) callback into the vim-lsp notification +" shape that existing on_notification handlers expect. +function! s:coc_wrap(upstream, err, result) abort + if a:err isnot v:null && a:err !=# 0 echohl ErrorMsg - echom 'nuwiki: vim-lsp not loaded; cannot run ' . a:command + echom 'nuwiki: ' . (type(a:err) == type('') ? a:err : string(a:err)) echohl None return endif - let l:opts = { - \ 'method': 'workspace/executeCommand', - \ 'params': { 'command': a:command, 'arguments': a:arguments }, - \ } - if a:0 >= 1 - let l:opts['on_notification'] = a:1 + call a:upstream({ 'response': { 'result': a:result } }) +endfunction + +function! s:exec(command, arguments, ...) abort + if s:has_vimlsp() + let l:opts = { + \ 'method': 'workspace/executeCommand', + \ 'params': { 'command': a:command, 'arguments': a:arguments }, + \ } + if a:0 >= 1 + let l:opts['on_notification'] = a:1 + endif + call lsp#send_request(s:server, l:opts) + return + endif + + if s:has_coc() + " CocActionAsync('runCommand', cmdid, arg1, arg2, …, callback) + " The arguments list is spread as individual positional args. + let l:args = ['runCommand', a:command] + a:arguments + if a:0 >= 1 + call add(l:args, function('s:coc_wrap', [a:1])) + endif + call call('CocActionAsync', l:args) + return + endif + + echohl ErrorMsg + echom 'nuwiki: no supported LSP client. Install vim-lsp or configure coc.nvim.' + echohl None +endfunction + +" Shared jump-to-definition helper used by follow_link* and the ftplugin. +function! s:jump_definition() abort + if exists(':LspDefinition') == 2 + LspDefinition + elseif s:has_coc() + call CocActionAsync('jumpDefinition') + else + echohl WarningMsg + echom 'nuwiki: no LSP client available for jump-to-definition' + echohl None + endif +endfunction + +" Shared references helper used by the ftplugin. +function! nuwiki#commands#backlinks() abort + if exists(':LspReferences') == 2 + LspReferences + elseif s:has_coc() + call CocActionAsync('references') + else + echohl WarningMsg + echom 'nuwiki: no LSP client available for references' + echohl None endif - call lsp#send_request(s:server, l:opts) endfunction function! s:open_uri_from(response, ...) abort @@ -105,15 +159,27 @@ endfunction " `:VimwikiBaddLink` — add the link target file to the buffer list " without focus. Routes through vim-lsp's textDocument/definition. function! nuwiki#commands#badd_link() abort - if !s:has_vimlsp() - echohl ErrorMsg | echom 'nuwiki: vim-lsp not loaded' | echohl None + if s:has_vimlsp() + call lsp#send_request(s:server, { + \ 'method': 'textDocument/definition', + \ 'params': s:cursor_position(), + \ 'on_notification': function('s:badd_from_response'), + \ }) return endif - call lsp#send_request(s:server, { - \ 'method': 'textDocument/definition', - \ 'params': s:cursor_position(), - \ 'on_notification': function('s:badd_from_response'), - \ }) + if s:has_coc() + let l:locs = CocAction('getDefinition') + if type(l:locs) == type([]) && !empty(l:locs) + let l:uri = get(l:locs[0], 'uri', get(l:locs[0], 'targetUri', '')) + if !empty(l:uri) + let l:path = substitute(l:uri, '^file://', '', '') + execute 'badd ' . fnameescape(l:path) + echom 'nuwiki: added ' . l:path + endif + endif + return + endif + echohl ErrorMsg | echom 'nuwiki: no supported LSP client for badd_link' | echohl None endfunction function! s:badd_from_response(notification) abort @@ -188,23 +254,15 @@ endfunction " 3. Press inside an existing `[[…]]` follows immediately. function! nuwiki#commands#follow_link_or_create() abort if s:cursor_inside_wikilink() - if exists(':LspDefinition') == 2 - LspDefinition - else - echohl WarningMsg - echom 'nuwiki: :LspDefinition unavailable; install vim-lsp' - echohl None - endif + call s:jump_definition() return endif if s:wrap_cword_as_wikilink() " Wrapped — wait for the user's second to follow. return endif - " Nothing to wrap — fall through. - if exists(':LspDefinition') == 2 - LspDefinition - endif + " Nothing to wrap — fall through to plain definition. + call s:jump_definition() endfunction " Pure-VimL bullet-continuation for `o` / `O` — mirrors the Lua side @@ -535,11 +593,13 @@ function! nuwiki#commands#delete_file() abort endfunction function! nuwiki#commands#rename_file() abort - if exists('*lsp#rename') + if exists(':LspRename') == 2 LspRename + elseif s:has_coc() + call CocActionAsync('rename') else echohl WarningMsg - echom 'nuwiki: :LspRename unavailable; install vim-lsp' + echom 'nuwiki: no LSP client available for rename' echohl None endif endfunction diff --git a/ftplugin/vimwiki.vim b/ftplugin/vimwiki.vim index 1d6cf6b..9dccc58 100644 --- a/ftplugin/vimwiki.vim +++ b/ftplugin/vimwiki.vim @@ -39,9 +39,9 @@ if !has('nvim') command! -buffer VimwikiDiaryNextDay call nuwiki#commands#diary_next() command! -buffer VimwikiDiaryPrevDay call nuwiki#commands#diary_prev() command! -buffer VimwikiDiaryGenerateLinks call nuwiki#commands#diary_generate_index() - command! -buffer VimwikiFollowLink LspDefinition - command! -buffer VimwikiBacklinks LspReferences - command! -buffer VWB LspReferences + command! -buffer VimwikiFollowLink call nuwiki#commands#follow_link_or_create() + command! -buffer VimwikiBacklinks call nuwiki#commands#backlinks() + command! -buffer VWB call nuwiki#commands#backlinks() command! -buffer VimwikiNextLink call nuwiki#commands#link_next() command! -buffer VimwikiPrevLink call nuwiki#commands#link_prev() command! -buffer VimwikiBaddLink call nuwiki#commands#badd_link() @@ -88,8 +88,8 @@ if !has('nvim') command! -buffer NuwikiDiaryTomorrow call nuwiki#commands#diary_tomorrow() command! -buffer NuwikiDiaryNext call nuwiki#commands#diary_next() command! -buffer NuwikiDiaryPrev call nuwiki#commands#diary_prev() - command! -buffer NuwikiFollowLink LspDefinition - command! -buffer NuwikiBacklinks LspReferences + command! -buffer NuwikiFollowLink call nuwiki#commands#follow_link_or_create() + command! -buffer NuwikiBacklinks call nuwiki#commands#backlinks() command! -buffer NuwikiDeleteFile call nuwiki#commands#delete_file() command! -buffer NuwikiRenameFile call nuwiki#commands#rename_file() command! -buffer NuwikiNextTask call nuwiki#commands#next_task()