mirror of
https://github.com/stevearc/aerial.nvim
synced 2024-09-16 14:34:08 +02:00
feat: priority ranking for LSP clients (#222)
This commit is contained in:
parent
8e2cbd32d1
commit
7af6f812e4
7 changed files with 107 additions and 16 deletions
|
@ -461,6 +461,13 @@ require("aerial").setup({
|
|||
-- How long to wait (in ms) after a buffer change before updating
|
||||
-- Only used when diagnostics_trigger_update = false
|
||||
update_delay = 300,
|
||||
|
||||
-- Map of LSP client name to priority. Default value is 10.
|
||||
-- Clients with higher (larger) priority will be used before those with lower priority.
|
||||
-- Set to -1 to never use the client.
|
||||
priority = {
|
||||
-- pyright = 10,
|
||||
},
|
||||
},
|
||||
|
||||
treesitter = {
|
||||
|
|
|
@ -299,6 +299,13 @@ OPTIONS *aerial-option
|
|||
-- How long to wait (in ms) after a buffer change before updating
|
||||
-- Only used when diagnostics_trigger_update = false
|
||||
update_delay = 300,
|
||||
|
||||
-- Map of LSP client name to priority. Default value is 10.
|
||||
-- Clients with higher (larger) priority will be used before those with lower priority.
|
||||
-- Set to -1 to never use the client.
|
||||
priority = {
|
||||
-- pyright = 10,
|
||||
},
|
||||
},
|
||||
|
||||
treesitter = {
|
||||
|
|
|
@ -3,8 +3,8 @@ local M = {}
|
|||
|
||||
---@class aerial.Backend
|
||||
---@field is_supported fun(bufnr: integer): boolean, string?
|
||||
---@field fetch_symbols_sync fun(bufnr: integer, timeout?: integer)
|
||||
---@field fetch_symbols fun(bufnr: integer)
|
||||
---@field fetch_symbols_sync fun(bufnr?: integer, opts?: {timeout?: integer})
|
||||
---@field fetch_symbols fun(bufnr?: integer)
|
||||
---@field attach fun(bufnr: integer)
|
||||
---@field detach fun(bufnr: integer)
|
||||
|
||||
|
@ -146,7 +146,7 @@ end
|
|||
|
||||
---@param bufnr? integer
|
||||
---@param items aerial.Symbol[]
|
||||
---@param context {backend_name: string, lang: string}
|
||||
---@param ctx {backend_name: string, lang: string}
|
||||
M.set_symbols = function(bufnr, items, ctx)
|
||||
if not bufnr or bufnr == 0 then
|
||||
bufnr = vim.api.nvim_get_current_buf()
|
||||
|
@ -164,10 +164,11 @@ M.set_symbols = function(bufnr, items, ctx)
|
|||
if config.post_add_all_symbols then
|
||||
items = config.post_add_all_symbols(bufnr, items, ctx)
|
||||
if items == nil then
|
||||
vim.notify_once(
|
||||
vim.notify(
|
||||
"aerial.config.post_add_all_symbols should return the symbols to display, but you returned nil or didn't return anything.",
|
||||
vim.log.levels.WARN
|
||||
)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
local backends = require("aerial.backends")
|
||||
local config = require("aerial.config")
|
||||
local data = require("aerial.data")
|
||||
local lsp_util = require("aerial.backends.lsp.util")
|
||||
|
||||
local M = {}
|
||||
|
||||
|
@ -191,7 +192,7 @@ M.on_publish_diagnostics = function(_err, result, ctx, _config)
|
|||
not bufnr
|
||||
or not backends.is_backend_attached(bufnr, "lsp")
|
||||
or not config.lsp.diagnostics_trigger_update
|
||||
or not client.server_capabilities.documentSymbolProvider
|
||||
or not lsp_util.client_supports_symbols(client)
|
||||
then
|
||||
return
|
||||
end
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
local backends = require("aerial.backends")
|
||||
local callbacks = require("aerial.backends.lsp.callbacks")
|
||||
local config = require("aerial.config")
|
||||
local lsp_util = require("aerial.backends.lsp.util")
|
||||
local util = require("aerial.backends.util")
|
||||
|
||||
local M = {}
|
||||
|
||||
local function replace_handler(name, callback, preserve_callback)
|
||||
|
@ -30,25 +32,79 @@ local function hook_handlers(preserve_symbol_callback)
|
|||
replace_handler("textDocument/publishDiagnostics", callbacks.on_publish_diagnostics, true)
|
||||
end
|
||||
|
||||
---@param bufnr integer
|
||||
---@return nil|table
|
||||
local function get_client(bufnr)
|
||||
local ret
|
||||
local last_priority = -1
|
||||
for _, client in ipairs(vim.lsp.get_active_clients({ bufnr = bufnr })) do
|
||||
local priority = config.lsp.priority[client.name] or 10
|
||||
if lsp_util.client_supports_symbols(client) and priority > last_priority then
|
||||
ret = client
|
||||
last_priority = priority
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
M.fetch_symbols = function(bufnr)
|
||||
bufnr = bufnr or 0
|
||||
if not bufnr or bufnr == 0 then
|
||||
bufnr = vim.api.nvim_get_current_buf()
|
||||
end
|
||||
local params = { textDocument = vim.lsp.util.make_text_document_params(bufnr) }
|
||||
vim.lsp.buf_request(bufnr, "textDocument/documentSymbol", params, callbacks.symbol_callback)
|
||||
local client = get_client(bufnr)
|
||||
if not client then
|
||||
vim.notify("No LSP client found that supports symbols", vim.log.levels.WARN)
|
||||
return
|
||||
end
|
||||
local request_success =
|
||||
client.request("textDocument/documentSymbol", params, callbacks.symbol_callback, bufnr)
|
||||
if not request_success then
|
||||
vim.notify("Error requesting document symbols", vim.log.levels.WARN)
|
||||
end
|
||||
end
|
||||
|
||||
M.fetch_symbols_sync = function(bufnr, opts)
|
||||
bufnr = bufnr or 0
|
||||
if not bufnr or bufnr == 0 then
|
||||
bufnr = vim.api.nvim_get_current_buf()
|
||||
end
|
||||
opts = vim.tbl_extend("keep", opts or {}, {
|
||||
timeout = 4000,
|
||||
})
|
||||
local params = { textDocument = vim.lsp.util.make_text_document_params(bufnr) }
|
||||
local response_map, err =
|
||||
vim.lsp.buf_request_sync(bufnr, "textDocument/documentSymbol", params, opts.timeout)
|
||||
if err or vim.tbl_isempty(response_map) then
|
||||
vim.notify(string.format("Error fetching document symbols: %s", err), vim.log.levels.ERROR)
|
||||
local client = get_client(bufnr)
|
||||
if not client then
|
||||
vim.notify("No LSP client found that supports symbols", vim.log.levels.WARN)
|
||||
return
|
||||
end
|
||||
local response
|
||||
local request_success = client.request(
|
||||
"textDocument/documentSymbol",
|
||||
params,
|
||||
function(err, result)
|
||||
response = { err = err, result = result }
|
||||
end,
|
||||
bufnr
|
||||
)
|
||||
if not request_success then
|
||||
vim.notify("Error requesting document symbols", vim.log.levels.WARN)
|
||||
end
|
||||
|
||||
local wait_result = vim.wait(opts.timeout, function()
|
||||
return response ~= nil
|
||||
end, 10)
|
||||
|
||||
if wait_result then
|
||||
if response.err then
|
||||
vim.notify(
|
||||
string.format("Error requesting document symbols: %s", response.err),
|
||||
vim.log.levels.WARN
|
||||
)
|
||||
else
|
||||
callbacks.handle_symbols(response.result, bufnr)
|
||||
end
|
||||
else
|
||||
local _, response = next(response_map)
|
||||
callbacks.handle_symbols(response.result, bufnr)
|
||||
vim.notify("Timeout when requesting document symbols", vim.log.levels.WARN)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -57,7 +113,7 @@ end
|
|||
---@return boolean
|
||||
local function is_lsp_attached(bufnr, exclude_id)
|
||||
for _, client in pairs(vim.lsp.get_active_clients({ bufnr = bufnr })) do
|
||||
if client.id ~= exclude_id and client.server_capabilities.documentSymbolProvider then
|
||||
if client.id ~= exclude_id and lsp_util.client_supports_symbols(client) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
@ -82,7 +138,7 @@ M.on_attach = function(client, bufnr, opts)
|
|||
bufnr = 0
|
||||
end
|
||||
opts = opts or {}
|
||||
if client.server_capabilities.documentSymbolProvider then
|
||||
if lsp_util.client_supports_symbols(client) then
|
||||
hook_handlers(opts.preserve_callback)
|
||||
-- This is called from the LspAttach autocmd
|
||||
-- The client isn't fully attached until just after that autocmd completes, so we need to
|
||||
|
|
12
lua/aerial/backends/lsp/util.lua
Normal file
12
lua/aerial/backends/lsp/util.lua
Normal file
|
@ -0,0 +1,12 @@
|
|||
local config = require("aerial.config")
|
||||
|
||||
local M = {}
|
||||
|
||||
---@param client table
|
||||
---@return boolean
|
||||
M.client_supports_symbols = function(client)
|
||||
return client.server_capabilities.documentSymbolProvider
|
||||
and config.lsp.priority[client.name] ~= -1
|
||||
end
|
||||
|
||||
return M
|
|
@ -285,6 +285,13 @@ local default_options = {
|
|||
-- How long to wait (in ms) after a buffer change before updating
|
||||
-- Only used when diagnostics_trigger_update = false
|
||||
update_delay = 300,
|
||||
|
||||
-- Map of LSP client name to priority. Default value is 10.
|
||||
-- Clients with higher (larger) priority will be used before those with lower priority.
|
||||
-- Set to -1 to never use the client.
|
||||
priority = {
|
||||
-- pyright = 10,
|
||||
},
|
||||
},
|
||||
|
||||
treesitter = {
|
||||
|
|
Loading…
Reference in a new issue