feat(client): add Vim split/tab/back link-follow commands + true tab-drop
The plain-Vim client only defined VimwikiFollowLink; the split/vsplit/
tabnew/tabdrop/back command surface existed only in the Neovim branch.
Add :Vimwiki{Split,VSplit,Tabnew,TabDrop,GoBack}Link (+ :Nuwiki* aliases)
to the Vim branch, backed by a new nuwiki#commands#follow_link_drop()
helper that runs `:tab drop` to reuse an already-open tab.
Both clients now implement real tab-drop: open_uri gains a 'tabdrop'
case and M.follow_link_drop(); the Neovim TabDropLink commands and the
<C-S-CR> mappings (Vim + Lua) are repointed off the old tabnew cheat.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -188,6 +188,47 @@ function! s:badd_from_response(notification) abort
|
|||||||
echom 'nuwiki: added ' . l:path
|
echom 'nuwiki: added ' . l:path
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
" `:VimwikiTabDropLink` — open the link target in a tab, reusing an
|
||||||
|
" existing tab/window if the file is already shown (`:tab drop`). Routes
|
||||||
|
" through vim-lsp's textDocument/definition like `badd_link`.
|
||||||
|
function! nuwiki#commands#follow_link_drop() abort
|
||||||
|
if s:has_vimlsp()
|
||||||
|
call lsp#send_request(s:server, {
|
||||||
|
\ 'method': 'textDocument/definition',
|
||||||
|
\ 'params': s:cursor_position(),
|
||||||
|
\ 'on_notification': function('s:drop_from_response'),
|
||||||
|
\ })
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
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 'tab drop ' . fnameescape(l:path)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
echohl ErrorMsg | echom 'nuwiki: no supported LSP client for follow_link_drop' | echohl None
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:drop_from_response(notification) abort
|
||||||
|
let l:result = get(get(a:notification, 'response', {}), 'result', {})
|
||||||
|
let l:uri = ''
|
||||||
|
if type(l:result) == type({})
|
||||||
|
let l:uri = get(l:result, 'uri', get(l:result, 'targetUri', ''))
|
||||||
|
elseif type(l:result) == type([]) && !empty(l:result)
|
||||||
|
let l:uri = get(l:result[0], 'uri', get(l:result[0], 'targetUri', ''))
|
||||||
|
endif
|
||||||
|
if l:uri ==# ''
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
let l:path = substitute(l:uri, '^file://', '', '')
|
||||||
|
execute 'tab drop ' . fnameescape(l:path)
|
||||||
|
endfunction
|
||||||
|
|
||||||
" ===== Smart <CR>: follow or wrap-then-follow =====
|
" ===== Smart <CR>: follow or wrap-then-follow =====
|
||||||
|
|
||||||
function! s:cursor_inside_wikilink() abort
|
function! s:cursor_inside_wikilink() abort
|
||||||
|
|||||||
+13
-3
@@ -47,6 +47,11 @@ if !has('nvim')
|
|||||||
command! -buffer VimwikiDiaryPrevDay call nuwiki#commands#diary_prev()
|
command! -buffer VimwikiDiaryPrevDay call nuwiki#commands#diary_prev()
|
||||||
command! -buffer VimwikiDiaryGenerateLinks call nuwiki#commands#diary_generate_index()
|
command! -buffer VimwikiDiaryGenerateLinks call nuwiki#commands#diary_generate_index()
|
||||||
command! -buffer VimwikiFollowLink call nuwiki#commands#follow_link_or_create()
|
command! -buffer VimwikiFollowLink call nuwiki#commands#follow_link_or_create()
|
||||||
|
command! -buffer VimwikiSplitLink split | call nuwiki#commands#follow_link_or_create()
|
||||||
|
command! -buffer VimwikiVSplitLink vsplit | call nuwiki#commands#follow_link_or_create()
|
||||||
|
command! -buffer VimwikiTabnewLink tabnew | call nuwiki#commands#follow_link_or_create()
|
||||||
|
command! -buffer VimwikiTabDropLink call nuwiki#commands#follow_link_drop()
|
||||||
|
command! -buffer VimwikiGoBackLink execute "normal! \<C-o>"
|
||||||
command! -buffer VimwikiBacklinks call nuwiki#commands#backlinks()
|
command! -buffer VimwikiBacklinks call nuwiki#commands#backlinks()
|
||||||
command! -buffer VWB call nuwiki#commands#backlinks()
|
command! -buffer VWB call nuwiki#commands#backlinks()
|
||||||
command! -buffer VimwikiNextLink call nuwiki#commands#link_next()
|
command! -buffer VimwikiNextLink call nuwiki#commands#link_next()
|
||||||
@@ -113,6 +118,11 @@ if !has('nvim')
|
|||||||
command! -buffer NuwikiDiaryNext call nuwiki#commands#diary_next()
|
command! -buffer NuwikiDiaryNext call nuwiki#commands#diary_next()
|
||||||
command! -buffer NuwikiDiaryPrev call nuwiki#commands#diary_prev()
|
command! -buffer NuwikiDiaryPrev call nuwiki#commands#diary_prev()
|
||||||
command! -buffer NuwikiFollowLink call nuwiki#commands#follow_link_or_create()
|
command! -buffer NuwikiFollowLink call nuwiki#commands#follow_link_or_create()
|
||||||
|
command! -buffer NuwikiSplitLink split | call nuwiki#commands#follow_link_or_create()
|
||||||
|
command! -buffer NuwikiVSplitLink vsplit | call nuwiki#commands#follow_link_or_create()
|
||||||
|
command! -buffer NuwikiTabnewLink tabnew | call nuwiki#commands#follow_link_or_create()
|
||||||
|
command! -buffer NuwikiTabDropLink call nuwiki#commands#follow_link_drop()
|
||||||
|
command! -buffer NuwikiGoBackLink execute "normal! \<C-o>"
|
||||||
command! -buffer NuwikiBacklinks call nuwiki#commands#backlinks()
|
command! -buffer NuwikiBacklinks call nuwiki#commands#backlinks()
|
||||||
command! -buffer NuwikiDeleteFile call nuwiki#commands#delete_file()
|
command! -buffer NuwikiDeleteFile call nuwiki#commands#delete_file()
|
||||||
command! -buffer NuwikiRenameFile call nuwiki#commands#rename_file()
|
command! -buffer NuwikiRenameFile call nuwiki#commands#rename_file()
|
||||||
@@ -196,7 +206,7 @@ if !has('nvim')
|
|||||||
nnoremap <silent><buffer> <CR> :call nuwiki#commands#follow_link_or_create()<CR>
|
nnoremap <silent><buffer> <CR> :call nuwiki#commands#follow_link_or_create()<CR>
|
||||||
nnoremap <silent><buffer> <S-CR> :split<CR>:call nuwiki#commands#follow_link_or_create()<CR>
|
nnoremap <silent><buffer> <S-CR> :split<CR>:call nuwiki#commands#follow_link_or_create()<CR>
|
||||||
nnoremap <silent><buffer> <C-CR> :vsplit<CR>:call nuwiki#commands#follow_link_or_create()<CR>
|
nnoremap <silent><buffer> <C-CR> :vsplit<CR>:call nuwiki#commands#follow_link_or_create()<CR>
|
||||||
nnoremap <silent><buffer> <C-S-CR> :tabnew<CR>:call nuwiki#commands#follow_link_or_create()<CR>
|
nnoremap <silent><buffer> <C-S-CR> :call nuwiki#commands#follow_link_drop()<CR>
|
||||||
nnoremap <silent><buffer> <BS> <C-o>
|
nnoremap <silent><buffer> <BS> <C-o>
|
||||||
nnoremap <silent><buffer> <Tab> /\[\[<CR>:nohlsearch<CR>
|
nnoremap <silent><buffer> <Tab> /\[\[<CR>:nohlsearch<CR>
|
||||||
nnoremap <silent><buffer> <S-Tab> ?\[\[<CR>:nohlsearch<CR>
|
nnoremap <silent><buffer> <S-Tab> ?\[\[<CR>:nohlsearch<CR>
|
||||||
@@ -357,7 +367,7 @@ command! -buffer VimwikiGoBackLink execute "normal! \<C-o>"
|
|||||||
command! -buffer VimwikiSplitLink split | lua vim.lsp.buf.definition()
|
command! -buffer VimwikiSplitLink split | lua vim.lsp.buf.definition()
|
||||||
command! -buffer VimwikiVSplitLink vsplit | lua vim.lsp.buf.definition()
|
command! -buffer VimwikiVSplitLink vsplit | lua vim.lsp.buf.definition()
|
||||||
command! -buffer VimwikiTabnewLink tabnew | lua vim.lsp.buf.definition()
|
command! -buffer VimwikiTabnewLink tabnew | lua vim.lsp.buf.definition()
|
||||||
command! -buffer VimwikiTabDropLink tabnew | lua vim.lsp.buf.definition()
|
command! -buffer VimwikiTabDropLink lua require('nuwiki.commands').follow_link_drop()
|
||||||
command! -buffer VimwikiNextLink lua require('nuwiki.commands').link_next()
|
command! -buffer VimwikiNextLink lua require('nuwiki.commands').link_next()
|
||||||
command! -buffer VimwikiPrevLink lua require('nuwiki.commands').link_prev()
|
command! -buffer VimwikiPrevLink lua require('nuwiki.commands').link_prev()
|
||||||
command! -buffer VimwikiBaddLink lua require('nuwiki.commands').badd_link()
|
command! -buffer VimwikiBaddLink lua require('nuwiki.commands').badd_link()
|
||||||
@@ -465,7 +475,7 @@ command! -buffer NuwikiGoBackLink execute "normal! \<C-o>"
|
|||||||
command! -buffer NuwikiSplitLink split | lua vim.lsp.buf.definition()
|
command! -buffer NuwikiSplitLink split | lua vim.lsp.buf.definition()
|
||||||
command! -buffer NuwikiVSplitLink vsplit | lua vim.lsp.buf.definition()
|
command! -buffer NuwikiVSplitLink vsplit | lua vim.lsp.buf.definition()
|
||||||
command! -buffer NuwikiTabnewLink tabnew | lua vim.lsp.buf.definition()
|
command! -buffer NuwikiTabnewLink tabnew | lua vim.lsp.buf.definition()
|
||||||
command! -buffer NuwikiTabDropLink tabnew | lua vim.lsp.buf.definition()
|
command! -buffer NuwikiTabDropLink lua require('nuwiki.commands').follow_link_drop()
|
||||||
command! -buffer NuwikiRemoveDone lua require('nuwiki.commands').list_remove_done()
|
command! -buffer NuwikiRemoveDone lua require('nuwiki.commands').list_remove_done()
|
||||||
command! -buffer -range NuwikiRemoveCheckbox lua require('nuwiki.commands').list_remove_checkbox()
|
command! -buffer -range NuwikiRemoveCheckbox lua require('nuwiki.commands').list_remove_checkbox()
|
||||||
command! -buffer NuwikiRemoveCheckboxInList lua require('nuwiki.commands').list_remove_checkbox_in_list()
|
command! -buffer NuwikiRemoveCheckboxInList lua require('nuwiki.commands').list_remove_checkbox_in_list()
|
||||||
|
|||||||
@@ -73,6 +73,10 @@ local function open_uri(uri, tab)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
local path = vim.uri_to_fname(uri)
|
local path = vim.uri_to_fname(uri)
|
||||||
|
if tab == 'tabdrop' then
|
||||||
|
vim.cmd('tab drop ' .. vim.fn.fnameescape(path))
|
||||||
|
return
|
||||||
|
end
|
||||||
local cmd
|
local cmd
|
||||||
if tab == 'split' then
|
if tab == 'split' then
|
||||||
cmd = 'split'
|
cmd = 'split'
|
||||||
@@ -206,6 +210,32 @@ function M.badd_link()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- `:VimwikiTabDropLink` — open the link target in a tab, reusing an
|
||||||
|
--- existing tab/window if the file is already shown (`:tab drop`). Uses
|
||||||
|
--- the LSP definition response to resolve the target file.
|
||||||
|
function M.follow_link_drop()
|
||||||
|
local client = find_client()
|
||||||
|
if not client then
|
||||||
|
vim.notify('nuwiki: language server not attached', vim.log.levels.ERROR)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local params = position_params(client)
|
||||||
|
params.textDocument = { uri = buf_uri() }
|
||||||
|
local req = client.request
|
||||||
|
local handler = function(_, result)
|
||||||
|
local loc
|
||||||
|
if type(result) == 'table' then
|
||||||
|
loc = result[1] or result
|
||||||
|
end
|
||||||
|
local uri = type(loc) == 'table' and (loc.uri or loc.targetUri) or nil
|
||||||
|
open_uri(uri, 'tabdrop')
|
||||||
|
end
|
||||||
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
|
if type(req) == 'function' then
|
||||||
|
client:request('textDocument/definition', params, handler, bufnr)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function M.follow_link_or_create()
|
function M.follow_link_or_create()
|
||||||
if cursor_inside_wikilink() then
|
if cursor_inside_wikilink() then
|
||||||
vim.lsp.buf.definition()
|
vim.lsp.buf.definition()
|
||||||
|
|||||||
@@ -164,8 +164,8 @@ function M.attach(bufnr, mappings)
|
|||||||
{ desc = 'nuwiki: follow link in split' }, bufnr)
|
{ desc = 'nuwiki: follow link in split' }, bufnr)
|
||||||
map('n', '<C-CR>', function() vim.cmd('vsplit'); cmd.follow_link_or_create() end,
|
map('n', '<C-CR>', function() vim.cmd('vsplit'); cmd.follow_link_or_create() end,
|
||||||
{ desc = 'nuwiki: follow link in vsplit' }, bufnr)
|
{ desc = 'nuwiki: follow link in vsplit' }, bufnr)
|
||||||
map('n', '<C-S-CR>', function() vim.cmd('tabnew'); cmd.follow_link_or_create() end,
|
map('n', '<C-S-CR>', cmd.follow_link_drop,
|
||||||
{ desc = 'nuwiki: follow link in new tab' }, bufnr)
|
{ desc = 'nuwiki: follow link in tab (reuse existing)' }, bufnr)
|
||||||
map('n', '<BS>', '<C-o>', { desc = 'nuwiki: go back', remap = true }, bufnr)
|
map('n', '<BS>', '<C-o>', { desc = 'nuwiki: go back', remap = true }, bufnr)
|
||||||
map('n', '<Tab>', link.next, { desc = 'nuwiki: next wikilink' }, bufnr)
|
map('n', '<Tab>', link.next, { desc = 'nuwiki: next wikilink' }, bufnr)
|
||||||
map('n', '<S-Tab>', link.prev, { desc = 'nuwiki: prev wikilink' }, bufnr)
|
map('n', '<S-Tab>', link.prev, { desc = 'nuwiki: prev wikilink' }, bufnr)
|
||||||
|
|||||||
Reference in New Issue
Block a user