mirror of
https://github.com/folke/snacks.nvim
synced 2025-08-04 18:58:12 +00:00
feat(picker.lsp): added lsp_workspace_symbols
. Supports live search. Closes #473
This commit is contained in:
parent
3fb27e7a2b
commit
348307a82e
5 changed files with 34 additions and 11 deletions
|
@ -374,6 +374,7 @@ M.lsp_references = {
|
|||
---@class snacks.picker.lsp.symbols.Config: snacks.picker.Config
|
||||
---@field hierarchy? boolean show symbol hierarchy
|
||||
---@field filter table<string, string[]|boolean>? symbol kind filter
|
||||
---@field workspace? boolean show workspace symbols
|
||||
M.lsp_symbols = {
|
||||
finder = "lsp_symbols",
|
||||
format = "lsp_symbol",
|
||||
|
@ -416,6 +417,14 @@ M.lsp_symbols = {
|
|||
},
|
||||
}
|
||||
|
||||
---@type snacks.picker.lsp.symbols.Config
|
||||
M.lsp_workspace_symbols = vim.tbl_extend("force", {}, M.lsp_symbols, {
|
||||
workspace = true,
|
||||
hierarchy = false,
|
||||
supports_live = true,
|
||||
live = true, -- live by default
|
||||
})
|
||||
|
||||
-- LSP type definitions
|
||||
---@type snacks.picker.lsp.Config
|
||||
M.lsp_type_definitions = {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
---@field all boolean
|
||||
---@field paths {path:string, want:boolean}[]
|
||||
---@field opts snacks.picker.filter.Config
|
||||
---@field current_buf number
|
||||
local M = {}
|
||||
M.__index = M
|
||||
|
||||
|
@ -16,6 +17,7 @@ local uv = vim.uv or vim.loop
|
|||
function M.new(picker)
|
||||
local opts = picker.opts ---@type snacks.picker.Config|{filter?:snacks.picker.filter.Config}
|
||||
local self = setmetatable({}, M)
|
||||
self.current_buf = vim.api.nvim_get_current_buf()
|
||||
self.opts = opts.filter or {}
|
||||
local function gets(v)
|
||||
return type(v) == "function" and v(picker) or v or "" --[[@as string]]
|
||||
|
|
|
@ -152,8 +152,9 @@ function M.git_branch(item, picker)
|
|||
end
|
||||
|
||||
function M.lsp_symbol(item, picker)
|
||||
local opts = picker.opts --[[@as snacks.picker.lsp.symbols.Config]]
|
||||
local ret = {} ---@type snacks.picker.Highlight[]
|
||||
if item.hierarchy then
|
||||
if item.hierarchy and not opts.workspace then
|
||||
local indents = picker.opts.icons.indent
|
||||
local indent = {} ---@type string[]
|
||||
local node = item
|
||||
|
@ -173,12 +174,15 @@ function M.lsp_symbol(item, picker)
|
|||
local kind_hl = "SnacksPickerIcon" .. kind
|
||||
ret[#ret + 1] = { picker.opts.icons.kinds[kind], kind_hl }
|
||||
ret[#ret + 1] = { " " }
|
||||
-- ret[#ret + 1] = { kind:lower() .. string.rep(" ", 10 - #kind), kind_hl }
|
||||
-- ret[#ret + 1] = { " " }
|
||||
local name = vim.trim(item.name:gsub("\r?\n", " "))
|
||||
name = name == "" and item.detail or name
|
||||
Snacks.picker.highlight.format(item, name, ret)
|
||||
-- ret[#ret + 1] = { name }
|
||||
|
||||
if opts.workspace then
|
||||
local offset = Snacks.picker.highlight.offset(ret, { char_idx = true })
|
||||
ret[#ret + 1] = { Snacks.picker.util.align(" ", 40 - offset) }
|
||||
vim.list_extend(ret, M.filename(item, picker))
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
|
|
|
@ -252,7 +252,7 @@ function M.results_to_items(client, results, opts)
|
|||
depth = (parent.depth or 0) + 1,
|
||||
detail = result.detail,
|
||||
name = result.name,
|
||||
text = table.concat({ M.symbol_kind(result.kind), result.name, result.detail }, " "),
|
||||
text = table.concat({ M.symbol_kind(result.kind), result.name, result.detail or "", sym.filename or "" }, " "),
|
||||
file = sym.filename,
|
||||
buf = sym.bufnr,
|
||||
pos = { sym.lnum, sym.col - 1 },
|
||||
|
@ -281,8 +281,9 @@ function M.results_to_items(client, results, opts)
|
|||
end
|
||||
|
||||
---@param opts snacks.picker.lsp.symbols.Config
|
||||
function M.symbols(opts)
|
||||
local buf = vim.api.nvim_get_current_buf()
|
||||
---@param filt snacks.picker.Filter
|
||||
function M.symbols(opts, filt)
|
||||
local buf = filt.current_buf
|
||||
local ft = vim.bo[buf].filetype
|
||||
local filter = opts.filter[ft]
|
||||
if filter == nil then
|
||||
|
@ -294,14 +295,17 @@ function M.symbols(opts)
|
|||
return type(filter) == "boolean" or vim.tbl_contains(filter, kind)
|
||||
end
|
||||
|
||||
local method = opts.workspace and "workspace/symbol" or "textDocument/documentSymbol"
|
||||
local p = opts.workspace and { query = filt.search } or { textDocument = vim.lsp.util.make_text_document_params(buf) }
|
||||
|
||||
---@async
|
||||
---@param cb async fun(item: snacks.picker.finder.Item)
|
||||
return function(cb)
|
||||
M.request(buf, "textDocument/documentSymbol", function()
|
||||
return { textDocument = vim.lsp.util.make_text_document_params(buf) }
|
||||
M.request(buf, method, function()
|
||||
return p
|
||||
end, function(client, result, params)
|
||||
local items = M.results_to_items(client, result, {
|
||||
default_uri = params.textDocument.uri,
|
||||
default_uri = params.textDocument and params.textDocument.uri or nil,
|
||||
filter = function(item)
|
||||
return want(M.symbol_kind(item.kind))
|
||||
end,
|
||||
|
|
|
@ -90,12 +90,16 @@ function M.get_highlights(opts)
|
|||
end
|
||||
|
||||
---@param line snacks.picker.Highlight[]
|
||||
function M.offset(line)
|
||||
---@param opts? {char_idx?:boolean}
|
||||
function M.offset(line, opts)
|
||||
opts = opts or {}
|
||||
local offset = 0
|
||||
for _, t in ipairs(line) do
|
||||
if type(t[1]) == "string" then
|
||||
if t.virtual then
|
||||
offset = offset + vim.api.nvim_strwidth(t[1])
|
||||
elseif opts.char_idx then
|
||||
offset = offset + vim.api.nvim_strwidth(t[1])
|
||||
else
|
||||
offset = offset + #t[1]
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue