-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
/
tagfunc.lua
83 lines (78 loc) · 2.79 KB
/
tagfunc.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
local lsp = vim.lsp
local util = lsp.util
local ms = lsp.protocol.Methods
---@param name string
---@param range lsp.Range
---@param uri string
---@param offset_encoding string
---@return {name: string, filename: string, cmd: string, kind?: string}
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([[/\%%%dl\%%%dc/]], range.start.line + 1, byte),
}
end
---@param pattern string
---@return table[]
local function query_definition(pattern)
local params = util.make_position_params()
local results_by_client, err = lsp.buf_request_sync(0, ms.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(assert(results_by_client)) do
local client = lsp.get_client_by_id(client_id)
local offset_encoding = client and client.offset_encoding or 'utf-16'
local result = lsp_results.result or {}
if result.range then -- Location
add(result.range, result.uri)
else
result = result --[[@as (lsp.Location[]|lsp.LocationLink[])]]
for _, item in pairs(result) do
if item.range then -- Location
add(item.range, item.uri, offset_encoding)
else -- LocationLink
add(item.targetSelectionRange, item.targetUri, offset_encoding)
end
end
end
end
return results
end
---@param pattern string
---@return table[]
local function query_workspace_symbols(pattern)
local results_by_client, err =
lsp.buf_request_sync(0, ms.workspace_symbol, { query = pattern }, 1000)
if err then
return {}
end
local results = {}
for client_id, responses in pairs(assert(results_by_client)) do
local client = lsp.get_client_by_id(client_id)
local offset_encoding = client and client.offset_encoding or 'utf-16'
local symbols = responses.result --[[@as lsp.SymbolInformation[]|nil]]
for _, symbol in pairs(symbols or {}) do
local loc = symbol.location
local item = mk_tag_item(symbol.name, loc.range, loc.uri, 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 = string.match(flags, 'c') and query_definition(pattern)
or query_workspace_symbols(pattern)
-- fall back to tags if no matches
return #matches > 0 and matches or vim.NIL
end
return tagfunc