feat: add filtering by symbol(s) to lsp_{document,workspace}_symbols (#903)
This commit is contained in:
@@ -82,6 +82,75 @@ utils.quickfix_items_to_entries = function(locations)
|
||||
return results
|
||||
end
|
||||
|
||||
utils.filter_symbols = function(results, opts)
|
||||
if opts.symbols == nil then
|
||||
return results
|
||||
end
|
||||
local valid_symbols = vim.tbl_map(string.lower, vim.lsp.protocol.SymbolKind)
|
||||
|
||||
local filtered_symbols = {}
|
||||
if type(opts.symbols) == "string" then
|
||||
opts.symbols = string.lower(opts.symbols)
|
||||
if vim.tbl_contains(valid_symbols, opts.symbols) then
|
||||
for _, result in ipairs(results) do
|
||||
if string.lower(result.kind) == opts.symbols then
|
||||
table.insert(filtered_symbols, result)
|
||||
end
|
||||
end
|
||||
else
|
||||
print(string.format("%s is not a valid symbol per `vim.lsp.protocol.SymbolKind`", opts.symbols))
|
||||
end
|
||||
elseif type(opts.symbols) == "table" then
|
||||
opts.symbols = vim.tbl_map(string.lower, opts.symbols)
|
||||
local mismatched_symbols = {}
|
||||
for _, symbol in ipairs(opts.symbols) do
|
||||
if vim.tbl_contains(valid_symbols, symbol) then
|
||||
for _, result in ipairs(results) do
|
||||
if string.lower(result.kind) == symbol then
|
||||
table.insert(filtered_symbols, result)
|
||||
end
|
||||
end
|
||||
else
|
||||
table.insert(mismatched_symbols, symbol)
|
||||
mismatched_symbols = table.concat(mismatched_symbols, ", ")
|
||||
print(string.format("%s are not valid symbols per `vim.lsp.protocol.SymbolKind`", mismatched_symbols))
|
||||
end
|
||||
end
|
||||
else
|
||||
print("Please pass filtering symbols as either a string or a list of strings")
|
||||
return
|
||||
end
|
||||
|
||||
local current_buf = vim.api.nvim_get_current_buf()
|
||||
if not vim.tbl_isempty(filtered_symbols) then
|
||||
-- filter adequately for workspace symbols
|
||||
local filename_to_bufnr = {}
|
||||
for _, symbol in ipairs(filtered_symbols) do
|
||||
if filename_to_bufnr[symbol.filename] == nil then
|
||||
filename_to_bufnr[symbol.filename] = vim.uri_to_bufnr(vim.uri_from_fname(symbol.filename))
|
||||
end
|
||||
symbol['bufnr'] = filename_to_bufnr[symbol.filename]
|
||||
end
|
||||
table.sort(filtered_symbols, function(a, b)
|
||||
if a.bufnr == b.bufnr then
|
||||
return a.lnum < b.lnum
|
||||
end
|
||||
if a.bufnr == current_buf then
|
||||
return true
|
||||
end
|
||||
if b.bufnr == current_buf then
|
||||
return false
|
||||
end
|
||||
return a.bufnr < b.bufnr
|
||||
end)
|
||||
return filtered_symbols
|
||||
end
|
||||
-- only account for string|table as function otherwise already printed message and returned nil
|
||||
local symbols = type(opts.symbols) == 'string' and opts.symbols or table.concat(opts.symbols, ', ')
|
||||
print(string.format("%s symbol(s) were not part of the query results", symbols))
|
||||
return
|
||||
end
|
||||
|
||||
local convert_diagnostic_type = function(severity)
|
||||
-- convert from string to int
|
||||
if type(severity) == 'string' then
|
||||
@@ -115,7 +184,7 @@ utils.diagnostics_to_tbl = function(opts)
|
||||
opts.severity_bound = convert_diagnostic_type(opts.severity_bound)
|
||||
|
||||
local validate_severity = 0
|
||||
for _, v in pairs({opts.severity, opts.severity_limit, opts.severity_bound}) do
|
||||
for _, v in ipairs({opts.severity, opts.severity_limit, opts.severity_bound}) do
|
||||
if v ~= nil then
|
||||
validate_severity = validate_severity + 1
|
||||
end
|
||||
@@ -149,7 +218,7 @@ utils.diagnostics_to_tbl = function(opts)
|
||||
local buffer_diags = opts.get_all and vim.lsp.diagnostic.get_all() or
|
||||
{[current_buf] = vim.lsp.diagnostic.get(current_buf, opts.client_id)}
|
||||
for bufnr, diags in pairs(buffer_diags) do
|
||||
for _, diag in pairs(diags) do
|
||||
for _, diag in ipairs(diags) do
|
||||
-- workspace diagnostics may include empty tables for unused bufnr
|
||||
if not vim.tbl_isempty(diag) then
|
||||
if filter_diag_severity(opts, diag.severity) then
|
||||
|
||||
Reference in New Issue
Block a user