Skip to content

Commit

Permalink
feat(lsp): auto-detect some extra plugin client capabilities
Browse files Browse the repository at this point in the history
  • Loading branch information
mrcjkb committed Mar 26, 2024
1 parent d6fd0b7 commit d104ab2
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 40 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- LSP: Automatically detect and register client capabilities for the following plugins,
if installed:
- [cmp-nvim-lsp](https://github.com/hrsh7th/cmp-nvim-lsp)
- [nvim-lsp-selection-range](https://github.com/camilledejoye/nvim-lsp-selection-range)
- [nvim-ufo](https://github.com/kevinhwang91/nvim-ufo)

### Fixed

- Neotest: Correctly mark passed and skipped tests when running a
Expand Down
8 changes: 4 additions & 4 deletions lua/rustaceanvim/config/internal.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ local compat = require('rustaceanvim.compat')
local config = require('rustaceanvim.config')
local executors = require('rustaceanvim.executors')
local os = require('rustaceanvim.os')
local server_config = require('rustaceanvim.config.server')

local RustaceanConfig

Expand Down Expand Up @@ -263,6 +264,8 @@ local RustaceanDefaultConfig = {
---@diagnostic disable-next-line: undefined-doc-class
---@class RustaceanLspClientConfig: vim.lsp.ClientConfig
server = {
---@type rustaceanvim.ClientCapabilities
capabilities = server_config.create_client_capabilities(),
---@type boolean | fun(bufnr: integer):boolean Whether to automatically attach the LSP client.
---Defaults to `true` if the `rust-analyzer` executable is found.
auto_attach = function(bufnr)
Expand Down Expand Up @@ -292,10 +295,7 @@ local RustaceanDefaultConfig = {

---@type table | (fun(project_root:string|nil, default_settings: table|nil):table) -- The rust-analyzer settings or a function that creates them.
settings = function(project_root, default_settings)
return require('rustaceanvim.config.server').load_rust_analyzer_settings(
project_root,
{ default_settings = default_settings }
)
return server_config.load_rust_analyzer_settings(project_root, { default_settings = default_settings })
end,

--- @type table
Expand Down
85 changes: 85 additions & 0 deletions lua/rustaceanvim/config/server.lua
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,89 @@ function server.load_rust_analyzer_settings(project_root, opts)
return default_settings
end

---@return rustaceanvim.ClientCapabilities
local function make_rustaceanvim_capabilities()
---@class rustaceanvim.ClientCapabilities: lsp.ClientCapabilities
local capabilities = vim.lsp.protocol.make_client_capabilities()

-- snippets
capabilities.textDocument.completion.completionItem.snippetSupport = true

-- send actions with hover request
---@class rustaceanvim.ExperimentalCapabilities
capabilities.experimental = {
hoverActions = true,
hoverRange = true,
serverStatusNotification = true,
snippetTextEdit = true,
codeActionGroup = true,
ssr = true,
}

-- enable auto-import
capabilities.textDocument.completion.completionItem.resolveSupport = {
properties = { 'documentation', 'detail', 'additionalTextEdits' },
}

-- rust analyzer goodies
local experimental_commands = {
'rust-analyzer.runSingle',
'rust-analyzer.showReferences',
'rust-analyzer.gotoLocation',
'editor.action.triggerParameterHints',
}
if package.loaded['dap'] ~= nil then
table.insert(experimental_commands, 'rust-analyzer.debugSingle')
end

---@class rustaceanvim.ExperimentalCommandCapabilities
capabilities.experimental.commands = {
commands = experimental_commands,
}

return capabilities
end

---@param mod_name string
---@param callback fun(mod: table): lsp.ClientCapabilities
---@return lsp.ClientCapabilities
local function mk_capabilities_if_available(mod_name, callback)
local available, mod = pcall(require, mod_name)
if available and type(mod) == 'table' then
local ok, capabilities = pcall(callback, mod)
if ok then
return capabilities
end
end
return {}
end

---@return rustaceanvim.ClientCapabilities
function server.create_client_capabilities()
local rs_capabilities = make_rustaceanvim_capabilities()
local cmp_capabilities = mk_capabilities_if_available('cmp_nvim_lsp', function(cmp_nvim_lsp)
return cmp_nvim_lsp.default_capabilities()
end)
local selection_range_capabilities = mk_capabilities_if_available('lsp-selection-range', function(lsp_selection_range)
return lsp_selection_range.update_capabilities {}
end)
local folding_range_capabilities = mk_capabilities_if_available('ufo', function(_)
return {
textDocument = {
foldingRange = {
dynamicRegistration = false,
lineFoldingOnly = true,
},
},
}
end)
return vim.tbl_deep_extend(
'keep',
rs_capabilities,
cmp_capabilities,
selection_range_capabilities,
folding_range_capabilities
)
end

return server
36 changes: 0 additions & 36 deletions lua/rustaceanvim/lsp.lua
Original file line number Diff line number Diff line change
Expand Up @@ -135,42 +135,6 @@ M.start = function(bufnr)
lsp_start_config.cmd = rust_analyzer_cmd
lsp_start_config.name = 'rust-analyzer'
lsp_start_config.filetypes = { 'rust' }
local capabilities = vim.lsp.protocol.make_client_capabilities()

-- snippets
capabilities.textDocument.completion.completionItem.snippetSupport = true

-- send actions with hover request
capabilities.experimental = {
hoverActions = true,
hoverRange = true,
serverStatusNotification = true,
snippetTextEdit = true,
codeActionGroup = true,
ssr = true,
}

-- enable auto-import
capabilities.textDocument.completion.completionItem.resolveSupport = {
properties = { 'documentation', 'detail', 'additionalTextEdits' },
}

-- rust analyzer goodies
local experimental_commands = {
'rust-analyzer.runSingle',
'rust-analyzer.showReferences',
'rust-analyzer.gotoLocation',
'editor.action.triggerParameterHints',
}
if package.loaded['dap'] ~= nil then
table.insert(experimental_commands, 'rust-analyzer.debugSingle')
end

capabilities.experimental.commands = {
commands = experimental_commands,
}

lsp_start_config.capabilities = vim.tbl_deep_extend('force', capabilities, lsp_start_config.capabilities or {})

local custom_handlers = {}
custom_handlers['experimental/serverStatus'] = server_status.handler
Expand Down

0 comments on commit d104ab2

Please sign in to comment.