mirror of
https://github.com/neovim/neovim
synced 2025-07-20 21:32:16 +00:00
feat(lsp): add tagfunc (#16103)
This commit is contained in:
committed by
GitHub
parent
36538417f0
commit
f940e7a5b9
@ -1587,6 +1587,13 @@ function lsp.formatexpr(opts)
|
|||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Provides an interface between the built-in client and `tagfunc`
|
||||||
|
--
|
||||||
|
-- Used via `set tagfunc=v:lua.vim.lsp.tagfunc`
|
||||||
|
function lsp.tagfunc(...)
|
||||||
|
return require('vim.lsp.tagfunc')(...)
|
||||||
|
end
|
||||||
|
|
||||||
---Checks whether a client is stopped.
|
---Checks whether a client is stopped.
|
||||||
---
|
---
|
||||||
---@param client_id (Number)
|
---@param client_id (Number)
|
||||||
|
72
runtime/lua/vim/lsp/tagfunc.lua
Normal file
72
runtime/lua/vim/lsp/tagfunc.lua
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
local lsp = vim.lsp
|
||||||
|
local util = vim.lsp.util
|
||||||
|
|
||||||
|
local function mk_tag_item(name, range, uri, offset_encoding)
|
||||||
|
local bufnr = vim.uri_to_bufnr(uri)
|
||||||
|
-- This is get_line_byte_from_position is 0-indexed, call cursor expects a 1-indexed position
|
||||||
|
local byte = util._get_line_byte_from_position(bufnr, range.start, offset_encoding) + 1
|
||||||
|
return {
|
||||||
|
name = name,
|
||||||
|
filename = vim.uri_to_fname(uri),
|
||||||
|
cmd = string.format('call cursor(%d, %d)|', range.start.line + 1, byte),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local function query_definition(pattern)
|
||||||
|
local params = lsp.util.make_position_params()
|
||||||
|
local results_by_client, err = lsp.buf_request_sync(0, 'textDocument/definition', params, 1000)
|
||||||
|
if err then
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
local results = {}
|
||||||
|
local add = function(range, uri, offset_encoding)
|
||||||
|
table.insert(results, mk_tag_item(pattern, range, uri, offset_encoding))
|
||||||
|
end
|
||||||
|
for client_id, lsp_results in pairs(results_by_client) do
|
||||||
|
local client = lsp.get_client_by_id(client_id)
|
||||||
|
local result = lsp_results.result or {}
|
||||||
|
if result.range then -- Location
|
||||||
|
add(result.range, result.uri)
|
||||||
|
else -- Location[] or LocationLink[]
|
||||||
|
for _, item in pairs(result) do
|
||||||
|
if item.range then -- Location
|
||||||
|
add(item.range, item.uri, client.offset_encoding)
|
||||||
|
else -- LocationLink
|
||||||
|
add(item.targetSelectionRange, item.targetUri, client.offset_encoding)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return results
|
||||||
|
end
|
||||||
|
|
||||||
|
local function query_workspace_symbols(pattern)
|
||||||
|
local results_by_client, err = lsp.buf_request_sync(0, 'workspace/symbol', { query = pattern }, 1000)
|
||||||
|
if err then
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
local results = {}
|
||||||
|
for client_id, symbols in pairs(results_by_client) do
|
||||||
|
local client = lsp.get_client_by_id(client_id)
|
||||||
|
for _, symbol in pairs(symbols.result or {}) do
|
||||||
|
local loc = symbol.location
|
||||||
|
local item = mk_tag_item(symbol.name, loc.range, loc.uri, client.offset_encoding)
|
||||||
|
item.kind = lsp.protocol.SymbolKind[symbol.kind] or 'Unknown'
|
||||||
|
table.insert(results, item)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return results
|
||||||
|
end
|
||||||
|
|
||||||
|
local function tagfunc(pattern, flags)
|
||||||
|
local matches
|
||||||
|
if string.match(flags, 'c') then
|
||||||
|
matches = query_definition(pattern)
|
||||||
|
else
|
||||||
|
matches = query_workspace_symbols(pattern)
|
||||||
|
end
|
||||||
|
-- fall back to tags if no matches
|
||||||
|
return #matches > 0 and matches or vim.NIL
|
||||||
|
end
|
||||||
|
|
||||||
|
return tagfunc
|
Reference in New Issue
Block a user