autoload/lsp/diag.vim | 1 + autoload/lsp/symbol.vim | 21 ++++++++++++++++++++- autoload/lsp/util.vim | 1 + test/clangd_tests.vim | 12 ++++++++++++ diff --git a/autoload/lsp/diag.vim b/autoload/lsp/diag.vim index 30b1b7d095dda5364b12446afa85b46a444852b3..05dd44e65ffe2d15841033c0357f9c47d82e42cc 100644 --- a/autoload/lsp/diag.vim +++ b/autoload/lsp/diag.vim @@ -638,6 +638,7 @@ def JumpDiag(diag: dict) var startPos: dict = diag.range.start setcursorcharpos(startPos.line + 1, util.GetCharIdxWithoutCompChar(bufnr(), startPos) + 1) + :normal! zv if !opt.lspOptions.showDiagWithVirtualText :redraw DisplayDiag(diag) diff --git a/autoload/lsp/symbol.vim b/autoload/lsp/symbol.vim index b4d92e2de5b485e0e1cf3083dcaa677a1eb1539a..0be5300e360916d7c72a02774b8c87fe7db119ae 100644 --- a/autoload/lsp/symbol.vim +++ b/autoload/lsp/symbol.vim @@ -142,6 +142,7 @@ :normal m' setcursorcharpos(symTbl[result - 1].pos.line + 1, util.GetCharIdxWithoutCompChar(bufnr(), symTbl[result - 1].pos) + 1) + :normal! zv catch # ignore exceptions endtry @@ -360,6 +361,9 @@ var w: number = &columns var fnamelen = float2nr(w * 0.4) + var curlnum = line('.') + var symIdx = 1 + var curSymIdx = 1 var menuItems: list = [] for loc in locations var [uri, range] = util.LspLocationParse(loc) @@ -373,6 +377,11 @@ var lnum = range.start.line + 1 var text: string = bnr->getbufline(lnum)->get(0, '') menuItems->add($'{lnum}: {text}') + + if lnum == curlnum + curSymIdx = symIdx + endif + symIdx += 1 endfor var popupAttrs = { @@ -391,6 +400,11 @@ filter: function(LocPopupFilter, [lspserver, locations]), callback: function(LocPopupCallback, [lspserver, locations]) } lspserver.peekSymbolPopup = popup_menu(menuItems, popupAttrs) + # Select the current symbol in the menu + var cmds =<< trim eval END + [{curSymIdx}, 1]->cursor() + END + win_execute(lspserver.peekSymbolPopup, cmds, 'silent!') UpdatePeekFilePopup(lspserver, locations) enddef @@ -765,8 +779,13 @@ :normal m' # Jump to the selected symbol location var r = symTblFiltered[result - 1].selectionRange + if r->empty() + # SymbolInformation doesn't have the selectionRange field + r = symTblFiltered[result - 1].range + endif setcursorcharpos(r.start.line + 1, - util.GetCharIdxWithoutCompChar(bufnr(), r.start) + 1) + util.GetCharIdxWithoutCompChar(bufnr(), r.start) + 1) + :normal! zv endif symInputPopup->popup_close() prop_remove({type: 'LspSymbolNameProp', all: true}) diff --git a/autoload/lsp/util.vim b/autoload/lsp/util.vim index c7b0d794f121b57643273ce9b119638a023b8e9f..aefe7662ab58d0788e871c5cbd39ea69a261ef80 100644 --- a/autoload/lsp/util.vim +++ b/autoload/lsp/util.vim @@ -303,6 +303,7 @@ endif endif setcursorcharpos(range.start.line + 1, GetCharIdxWithoutCompChar(bufnr(), range.start) + 1) + :normal! zv enddef # indexof() function is not present in older Vim 9 versions. So use this diff --git a/test/clangd_tests.vim b/test/clangd_tests.vim index 443ff987664667bb4d50df8ef1999ef029e9f361..2ee69e040b4a31bb76a7a68614b4538710235b3b 100644 --- a/test/clangd_tests.vim +++ b/test/clangd_tests.vim @@ -237,10 +237,22 @@ var refPopupAttrs = ids[1]->popup_getoptions() assert_match('XshowRefs', filePopupAttrs.title) assert_equal('Symbol References', refPopupAttrs.title) assert_equal(10, line('.', ids[0])) + assert_equal(1, line('.', ids[1])) assert_equal(3, line('$', ids[1])) feedkeys("jj\", 'xt') assert_equal(12, line('.')) assert_equal([], popup_list()) + popup_clear() + + # LspShowReferences should start with the current symbol + cursor(12, 6) + :LspPeekReferences + sleep 50m + ids = popup_list() + assert_equal(2, ids->len()) + assert_equal(12, line('.', ids[0])) + assert_equal(3, line('.', ids[1])) + feedkeys("\", 'xt') popup_clear() bw!