fix(providers): Ensure working on nvim-0.7
This commit removed the ability to receive symbols from all attached clients in the current buffer. Everything works as before when only one client is attached to a buffer. This also fixes outline LSP finding clients on nvim-0.7
This commit is contained in:
@@ -140,7 +140,7 @@ function M.show_status(ctx)
|
|||||||
if p.get_status then
|
if p.get_status then
|
||||||
table.insert(lines, 'Provider info:')
|
table.insert(lines, 'Provider info:')
|
||||||
table.insert(lines, '')
|
table.insert(lines, '')
|
||||||
for _, line in ipairs(p.get_status()) do
|
for _, line in ipairs(p.get_status(ctx.provider_info)) do
|
||||||
table.insert(lines, indent .. line)
|
table.insert(lines, indent .. line)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -252,19 +252,20 @@ end
|
|||||||
|
|
||||||
---Open a floating window displaying debug information about outline
|
---Open a floating window displaying debug information about outline
|
||||||
function M.show_status()
|
function M.show_status()
|
||||||
local sidebar = M._get_sidebar(false)
|
local sidebar = M._get_sidebar()
|
||||||
local buf, win = 0, 0
|
local buf, win = 0, 0
|
||||||
local is_open, provider
|
local is_open, provider, provider_info
|
||||||
|
|
||||||
if sidebar then
|
if sidebar then
|
||||||
buf = sidebar.code.buf
|
buf = sidebar.code.buf
|
||||||
win = sidebar.code.win
|
win = sidebar.code.win
|
||||||
is_open = sidebar.view:is_open()
|
is_open = sidebar.view:is_open()
|
||||||
provider = sidebar.provider
|
provider = sidebar.provider
|
||||||
|
provider_info = sidebar.provider_info
|
||||||
end
|
end
|
||||||
|
|
||||||
if not is_open then
|
if not is_open then
|
||||||
provider = providers.find_provider()
|
provider, provider_info = providers.find_provider()
|
||||||
end
|
end
|
||||||
|
|
||||||
---@type outline.StatusContext
|
---@type outline.StatusContext
|
||||||
@@ -272,9 +273,10 @@ function M.show_status()
|
|||||||
priority = cfg.o.providers.priority,
|
priority = cfg.o.providers.priority,
|
||||||
outline_open = is_open,
|
outline_open = is_open,
|
||||||
provider = provider,
|
provider = provider,
|
||||||
|
provider_info = provider_info,
|
||||||
}
|
}
|
||||||
|
|
||||||
if vim.api.nvim_buf_is_valid(buf) then
|
if buf and vim.api.nvim_buf_is_valid(buf) then
|
||||||
ctx.ft = vim.api.nvim_buf_get_option(buf, 'ft')
|
ctx.ft = vim.api.nvim_buf_get_option(buf, 'ft')
|
||||||
ctx.filter = cfg.o.symbols.user_config_filter[ctx.ft]
|
ctx.filter = cfg.o.symbols.user_config_filter[ctx.ft]
|
||||||
-- 'else' is handled in help.lua
|
-- 'else' is handled in help.lua
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
local M = {}
|
local M = {}
|
||||||
local import_prefix = 'outline/providers/'
|
local import_prefix = 'outline/providers/'
|
||||||
|
|
||||||
---@return outline.Provider?
|
---@return outline.Provider?, table?
|
||||||
function M.find_provider()
|
function M.find_provider()
|
||||||
if not M.providers then
|
if not M.providers then
|
||||||
M.providers = vim.tbl_map(function(p)
|
M.providers = vim.tbl_map(function(p)
|
||||||
return import_prefix .. p
|
return import_prefix .. p
|
||||||
end, require('outline.config').get_providers())
|
end, require('outline.config').get_providers())
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, path in ipairs(M.providers) do
|
for _, path in ipairs(M.providers) do
|
||||||
local provider = require(path)
|
local provider = require(path)
|
||||||
if provider.supports_buffer(0) then
|
local ok, info = provider.supports_buffer(0)
|
||||||
return provider
|
if ok then
|
||||||
|
return provider, info
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6,52 +6,70 @@ local l = vim.lsp
|
|||||||
|
|
||||||
local M = {
|
local M = {
|
||||||
name = 'lsp',
|
name = 'lsp',
|
||||||
---@type lsp.client
|
|
||||||
client = nil,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
local request_timeout = 2000
|
local request_timeout = 2000
|
||||||
|
|
||||||
function M.get_status()
|
---@param info table? Must be the table received from `supports_buffer`
|
||||||
if not M.client then
|
function M.get_status(info)
|
||||||
|
if not info then
|
||||||
return { 'No clients' }
|
return { 'No clients' }
|
||||||
end
|
end
|
||||||
return { 'client: ' .. M.client.name }
|
return { 'client: ' .. info.client.name }
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_appropriate_client(bufnr, capability)
|
---@param client lsp.client
|
||||||
local clients = l.get_active_clients({ bufnr = bufnr })
|
---@param capability string
|
||||||
local use_client
|
---@return boolean
|
||||||
|
local function _check_client(client, capability)
|
||||||
for _, client in ipairs(clients) do
|
|
||||||
if cfg.is_client_blacklisted(client) then
|
if cfg.is_client_blacklisted(client) then
|
||||||
goto continue
|
return false
|
||||||
else
|
end
|
||||||
if client.server_capabilities[capability] then
|
return client.server_capabilities[capability]
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param bufnr integer
|
||||||
|
---@param capability string
|
||||||
|
---@return lsp.client?
|
||||||
|
local function get_appropriate_client(bufnr, capability)
|
||||||
|
local clients, use_client
|
||||||
|
|
||||||
|
if _G._outline_nvim_has[8] then
|
||||||
|
clients = l.get_active_clients({ bufnr = bufnr })
|
||||||
|
for _, client in ipairs(clients) do
|
||||||
|
if _check_client(client, capability) then
|
||||||
use_client = client
|
use_client = client
|
||||||
M.client = client
|
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
::continue::
|
else
|
||||||
|
-- Returns client_id:client pairs
|
||||||
|
---@diagnostic disable-next-line
|
||||||
|
clients = l.buf_get_clients(bufnr)
|
||||||
|
for _, client in pairs(clients) do
|
||||||
|
if _check_client(client, capability) then
|
||||||
|
use_client = client
|
||||||
|
break
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return use_client
|
return use_client
|
||||||
end
|
end
|
||||||
|
|
||||||
---@return boolean
|
---@return boolean, table?
|
||||||
function M.supports_buffer(bufnr)
|
function M.supports_buffer(bufnr)
|
||||||
local client = get_appropriate_client(bufnr, 'documentSymbolProvider')
|
local client = get_appropriate_client(bufnr, 'documentSymbolProvider')
|
||||||
if not client then
|
if not client then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
return true
|
return true, { client = client }
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param response outline.ProviderSymbol[]
|
---Include JSX symbols if applicable, and merge it with existing symbols
|
||||||
|
---@param symbols outline.ProviderSymbol[]
|
||||||
---@return outline.ProviderSymbol[]
|
---@return outline.ProviderSymbol[]
|
||||||
local function postprocess_symbols(response)
|
local function postprocess_symbols(symbols)
|
||||||
local symbols = lsp_utils.flatten_response(response)
|
|
||||||
|
|
||||||
local jsx_symbols = jsx.get_symbols()
|
local jsx_symbols = jsx.get_symbols()
|
||||||
|
|
||||||
if #jsx_symbols > 0 then
|
if #jsx_symbols > 0 then
|
||||||
@@ -61,16 +79,31 @@ local function postprocess_symbols(response)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- XXX: Only one LSP client is supported here, to prevent checking blacklisting
|
||||||
|
-- over again
|
||||||
---@param on_symbols fun(symbols?:outline.ProviderSymbol[], opts?:table)
|
---@param on_symbols fun(symbols?:outline.ProviderSymbol[], opts?:table)
|
||||||
---@param opts table
|
---@param opts table?
|
||||||
function M.request_symbols(on_symbols, opts)
|
---@param info table? Must be the table received from `supports_buffer`
|
||||||
|
function M.request_symbols(on_symbols, opts, info)
|
||||||
|
if not info then
|
||||||
|
return on_symbols(nil, opts)
|
||||||
|
end
|
||||||
|
|
||||||
local params = {
|
local params = {
|
||||||
textDocument = l.util.make_text_document_params(),
|
textDocument = l.util.make_text_document_params(),
|
||||||
}
|
}
|
||||||
l.buf_request_all(0, 'textDocument/documentSymbol', params, function(response)
|
-- XXX: Is bufnr=0 ok here?
|
||||||
|
local status = info.client.request('textDocument/documentSymbol', params, function(err, response)
|
||||||
|
if err or not response then
|
||||||
|
on_symbols(response, opts)
|
||||||
|
else
|
||||||
response = postprocess_symbols(response)
|
response = postprocess_symbols(response)
|
||||||
on_symbols(response, opts)
|
on_symbols(response, opts)
|
||||||
end)
|
end
|
||||||
|
end, 0)
|
||||||
|
if not status then
|
||||||
|
on_symbols(nil, opts)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- No good way to update outline when LSP action complete for now
|
-- No good way to update outline when LSP action complete for now
|
||||||
@@ -97,6 +130,7 @@ end
|
|||||||
|
|
||||||
---@see rename_symbol
|
---@see rename_symbol
|
||||||
---@param sidebar outline.Sidebar
|
---@param sidebar outline.Sidebar
|
||||||
|
---@param client lsp.client
|
||||||
---@param node outline.FlatSymbol
|
---@param node outline.FlatSymbol
|
||||||
---@return boolean success
|
---@return boolean success
|
||||||
local function legacy_rename(sidebar, client, node)
|
local function legacy_rename(sidebar, client, node)
|
||||||
@@ -141,8 +175,8 @@ function M.rename_symbol(sidebar)
|
|||||||
sidebar:wrap_goto_location(function()
|
sidebar:wrap_goto_location(function()
|
||||||
-- Options table with filter key only added in nvim-0.8
|
-- Options table with filter key only added in nvim-0.8
|
||||||
-- Use vim.lsp's function because it has better support.
|
-- Use vim.lsp's function because it has better support.
|
||||||
l.buf.rename(nil, { filter = function (client)
|
l.buf.rename(nil, { filter = function (cl)
|
||||||
return not cfg.is_client_blacklisted(client)
|
return not cfg.is_client_blacklisted(cl)
|
||||||
end })
|
end })
|
||||||
end)
|
end)
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ local Sidebar = {}
|
|||||||
---@field code outline.SidebarCodeState
|
---@field code outline.SidebarCodeState
|
||||||
---@field augroup integer
|
---@field augroup integer
|
||||||
---@field provider outline.Provider?
|
---@field provider outline.Provider?
|
||||||
|
---@field provider_info table?
|
||||||
---@field preview outline.Preview|outline.LivePreview
|
---@field preview outline.Preview|outline.LivePreview
|
||||||
|
|
||||||
function Sidebar:new(id)
|
function Sidebar:new(id)
|
||||||
@@ -92,6 +93,7 @@ end
|
|||||||
---@param opts outline.OutlineOpts?
|
---@param opts outline.OutlineOpts?
|
||||||
function Sidebar:initial_handler(response, opts)
|
function Sidebar:initial_handler(response, opts)
|
||||||
if response == nil or type(response) ~= 'table' or self.view:is_open() then
|
if response == nil or type(response) ~= 'table' or self.view:is_open() then
|
||||||
|
utils.echo("No response from provider when requesting symbols!")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -311,6 +313,7 @@ end
|
|||||||
---@param response outline.ProviderSymbol[]
|
---@param response outline.ProviderSymbol[]
|
||||||
function Sidebar:refresh_handler(response)
|
function Sidebar:refresh_handler(response)
|
||||||
if response == nil or type(response) ~= 'table' then
|
if response == nil or type(response) ~= 'table' then
|
||||||
|
utils.echo("No response from provider when requesting symbols!")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -340,11 +343,11 @@ function Sidebar:__refresh()
|
|||||||
if ft == 'OutlineHelp' or not listed then
|
if ft == 'OutlineHelp' or not listed then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
self.provider = providers.find_provider()
|
self.provider, self.provider_info = providers.find_provider()
|
||||||
if self.provider then
|
if self.provider then
|
||||||
self.provider.request_symbols(function(res)
|
self.provider.request_symbols(function(res)
|
||||||
self:refresh_handler(res)
|
self:refresh_handler(res)
|
||||||
end)
|
end, nil, self.provider_info)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
-- No provider
|
-- No provider
|
||||||
@@ -583,11 +586,11 @@ function Sidebar:open(opts)
|
|||||||
|
|
||||||
if not self.view:is_open() then
|
if not self.view:is_open() then
|
||||||
self.preview.s = self
|
self.preview.s = self
|
||||||
self.provider = providers.find_provider()
|
self.provider, self.provider_info = providers.find_provider()
|
||||||
if self.provider then
|
if self.provider then
|
||||||
self.provider.request_symbols(function(...)
|
self.provider.request_symbols(function(...)
|
||||||
self:initial_handler(...)
|
self:initial_handler(...)
|
||||||
end, opts)
|
end, opts, self.provider_info)
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
-- No provider
|
-- No provider
|
||||||
|
|||||||
@@ -63,9 +63,9 @@
|
|||||||
|
|
||||||
---@class outline.Provider
|
---@class outline.Provider
|
||||||
---@field name string
|
---@field name string
|
||||||
---@field get_status? fun():string[]
|
---@field get_status? fun(info:table?):string[]
|
||||||
---@field supports_buffer fun(bufnr:integer):boolean
|
---@field supports_buffer fun(bufnr:integer):boolean,table?
|
||||||
---@field request_symbols fun(on_symbols:fun(symbols?:outline.ProviderSymbol[], opts:table?), opts:table?)
|
---@field request_symbols fun(on_symbols:fun(symbols?:outline.ProviderSymbol[], opts:table?, provider_info:table?), opts:table?)
|
||||||
---@field show_hover? fun(sidebar:outline.Sidebar):boolean
|
---@field show_hover? fun(sidebar:outline.Sidebar):boolean
|
||||||
---@field rename_symbol? fun(sidebar:outline.Sidebar):boolean
|
---@field rename_symbol? fun(sidebar:outline.Sidebar):boolean
|
||||||
---@field code_actions? fun(sidebar:outline.Sidebar):boolean
|
---@field code_actions? fun(sidebar:outline.Sidebar):boolean
|
||||||
@@ -80,6 +80,7 @@
|
|||||||
|
|
||||||
---@class outline.StatusContext
|
---@class outline.StatusContext
|
||||||
---@field provider outline.Provider?
|
---@field provider outline.Provider?
|
||||||
|
---@field provider_info table?
|
||||||
---@field outline_open boolean?
|
---@field outline_open boolean?
|
||||||
---@field code_win_active boolean?
|
---@field code_win_active boolean?
|
||||||
---@field ft string?
|
---@field ft string?
|
||||||
|
|||||||
@@ -12,13 +12,14 @@ function M.is_buf_markdown(bufnr)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Merge all client token lists in an LSP response
|
--- Merge all client token lists in an LSP response
|
||||||
function M.flatten_response(response)
|
-- Currentlhy unused because we are only supporting receiving symbols
|
||||||
|
-- from 1 LSP client.
|
||||||
|
function M.merge_responses(responses)
|
||||||
local all_results = {}
|
local all_results = {}
|
||||||
|
|
||||||
-- flatten results to one giant table of symbols
|
-- flatten results to one giant table of symbols
|
||||||
for client_id, client_response in pairs(response) do
|
for client_id, client_response in pairs(responses) do
|
||||||
if config.is_client_blacklisted(client_id) then
|
if config.is_client_blacklisted(client_id) then
|
||||||
print('skipping client ' .. client_id)
|
|
||||||
goto continue
|
goto continue
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user