Skip to content

Commit

Permalink
feat(source): added lsp source
Browse files Browse the repository at this point in the history
  • Loading branch information
folke committed May 30, 2024
1 parent 0bc21f5 commit 3969907
Showing 1 changed file with 92 additions and 47 deletions.
139 changes: 92 additions & 47 deletions lua/trouble/sources/lsp.lua
Original file line number Diff line number Diff line change
@@ -1,59 +1,104 @@
---@diagnostic disable: inject-field
local methods = vim.lsp.protocol.Methods
local Item = require("trouble.item")
local get_col = vim.lsp.util._get_line_byte_from_position

---@type trouble.Source
local M = {}

function M.document_symbols()
local bufnr = vim.api.nvim_get_current_buf()
local params = { textDocument = vim.lsp.util.make_text_document_params(bufnr) }
vim.lsp.buf_request(bufnr, "textDocument/documentSymbol", params, function(_, result, ctx)
local symbols = vim.lsp.util.symbols_to_items(result, bufnr)
dd(symbols)
end)
M.modes = {}
for _, mode in ipairs({ "definitions", "references", "implementations", "type_definitions" }) do
M.modes["lsp_" .. mode] = {
events = { "CursorHold" },
sections = {
{
source = "lsp." .. mode,
groups = {
{ "filename", format = "{file_icon} {filename} {count}" },
},
sort = { { buf = 0 }, "filename", "pos", "text" },
format = "{text:ts} ({item.client}) {pos}",
},
},
}
end
err()

function M._get_symbol_kind_name(symbol_kind)
return vim.lsp.protocol.SymbolKind[symbol_kind] or "Unknown"
end
---@param method string
---@param cb trouble.Source.Callback
---@param context? any lsp params context
function M.get_locations(method, cb, context)
local win = vim.api.nvim_get_current_win()
local buf = vim.api.nvim_get_current_buf()
---@type lsp.TextDocumentPositionParams
local params = vim.lsp.util.make_position_params(win)
---@diagnostic disable-next-line: inject-field
params.context = context

--- Converts symbols to quickfix list items.
---
---@param symbols table DocumentSymbol[] or SymbolInformation[]
function M.symbols_to_items(symbols, bufnr)
local function _symbols_to_items(_symbols, _items, _bufnr)
for _, symbol in ipairs(_symbols) do
if symbol.location then -- SymbolInformation type
local range = symbol.location.range
local kind = M._get_symbol_kind_name(symbol.kind)
table.insert(_items, {
filename = vim.uri_to_fname(symbol.location.uri),
lnum = range.start.line + 1,
col = range.start.character + 1,
kind = kind,
text = "[" .. kind .. "] " .. symbol.name,
})
elseif symbol.selectionRange then -- DocumentSymbole type
local kind = M._get_symbol_kind_name(symbol.kind)
table.insert(_items, {
-- bufnr = _bufnr,
filename = api.nvim_buf_get_name(_bufnr),
lnum = symbol.selectionRange.start.line + 1,
col = symbol.selectionRange.start.character + 1,
kind = kind,
text = "[" .. kind .. "] " .. symbol.name,
})
if symbol.children then
for _, v in ipairs(_symbols_to_items(symbol.children, _items, _bufnr)) do
for _, s in ipairs(v) do
table.insert(_items, s)
end
end
end
vim.lsp.buf_request_all(buf, method, params, function(results)
local items = {} ---@type trouble.Item[]
for client_id, result in pairs(results) do
if result and result.result then
local client = assert(vim.lsp.get_client_by_id(client_id))
vim.list_extend(items, M.get_items(client, result.result))
end
end
return _items
cb(items)
end)
end

---@param client lsp.Client
---@param locations? lsp.Location[]|lsp.LocationLink[]|lsp.Location
function M.get_items(client, locations)
locations = locations or {}
locations = vim.tbl_islist(locations) and locations or { locations }
---@cast locations (lsp.Location|lsp.LocationLink)[]
local items = {} ---@type trouble.Item[]

for _, loc in ipairs(locations) do
local range = loc.range or loc.targetSelectionRange
local uri = loc.uri or loc.targetUri
local buf = vim.uri_to_bufnr(uri)
local pos = { range.start.line + 1, get_col(buf, range.start, client.offset_encoding) }
local end_pos = { range["end"].line + 1, get_col(buf, range["end"], client.offset_encoding) }
items[#items + 1] = Item.new({
buf = buf,
filename = vim.uri_to_fname(uri),
pos = pos,
end_pos = end_pos,
item = {
client_id = client.id,
client = client.name,
location = loc,
},
source = "lsp",
})
end
return _symbols_to_items(symbols, {}, bufnr or 0)

Item.add_text(items)
return items
end

M.document_symbols()
M.get = {}

---@param cb trouble.Source.Callback
function M.get.references(cb)
M.get_locations(methods.textDocument_references, cb, { includeDeclaration = true })
end

---@param cb trouble.Source.Callback
function M.get.definitions(cb)
M.get_locations(methods.textDocument_definition, cb)
end

---@param cb trouble.Source.Callback
function M.get.implementations(cb)
M.get_locations(methods.textDocument_implementation, cb)
end

-- Type Definitions
---@param cb trouble.Source.Callback
function M.get.type_definitions(cb)
M.get_locations(methods.textDocument_typeDefinition, cb)
end

return M

0 comments on commit 3969907

Please sign in to comment.