Skip to content

Commit a589a80

Browse files
authored
fix(cabal): prevent error messages caused by external lsp plugins (#224)
Fixes #223 ###### Things done - [x] Tested, as applicable: - [x] Manually - [ ] Added plenary specs - [x] Updated [CHANGELOG.md](https://github.com/MrcJkb/haskell-tools.nvim/blob/master/CHANGELOG.md) (if applicable). - [x] Fits [CONTRIBUTING.md](https://github.com/MrcJkb/haskell-tools.nvim/blob/master/CONTRIBUTING.md)
1 parent d38c1b6 commit a589a80

File tree

3 files changed

+55
-8
lines changed

3 files changed

+55
-8
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [Unreleased]
9+
### Fixed
10+
- Cabal: Do not advertise `server_capabilities` for `foldingRangeProvider`
11+
and `selectionRangeProvider` ([#223](https://github.com/mrcjkb/haskell-tools.nvim/issues/223)).
12+
Prevents error messages caused by plugins that provide LSP client capabilities that are
13+
not built-in to Neovim.
14+
815
## [1.11.1] - 2023-07-17
916
### Fixed
1017
- Hover: Fix error message when using go-to-definition/typeDefinition hover actions

lua/haskell-tools/lsp.lua

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,12 @@ local commands = {
4545
---GHC can leave behind corrupted files if it does not exit cleanly.
4646
---(https://gitlab.haskell.org/ghc/ghc/-/issues/14533)
4747
---To minimise the risk of this occurring, we attempt to shut down hls cleanly before exiting neovim.
48-
---@param client number The LSP client
48+
---@param client lsp.Client The LSP client
4949
---@param bufnr number The buffer number
5050
---@return nil
5151
local function ensure_clean_exit_on_quit(client, bufnr)
5252
vim.api.nvim_create_autocmd('VimLeavePre', {
53-
group = vim.api.nvim_create_augroup('haskell-tools-hls-clean-exit', { clear = true }),
53+
group = vim.api.nvim_create_augroup('haskell-tools-hls-clean-exit-' .. tostring(client.id), { clear = true }),
5454
callback = function()
5555
ht.log.debug('Stopping LSP client...')
5656
vim.lsp.stop_client(client, false)
@@ -59,6 +59,22 @@ local function ensure_clean_exit_on_quit(client, bufnr)
5959
})
6060
end
6161

62+
---A workaround for #48:
63+
---Some plugins that add LSP client capabilities which are not built-in to neovim
64+
---(like nvim-ufo and nvim-lsp-selection-range) cause error messages, because
65+
---haskell-language-server falsly advertises those server_capabilities for cabal files.
66+
---@param client lsp.Client
67+
---@return nil
68+
local function fix_cabal_client(client)
69+
if client.name == lsp_util.cabal_client_name and client.server_capabilities then
70+
client.server_capabilities = vim.tbl_extend('force', client.server_capabilities, {
71+
foldingRangeProvider = false,
72+
selectionRangeProvider = false,
73+
documentHighlightProvider = false,
74+
})
75+
end
76+
end
77+
6278
---@class LoadHlsSettingsOpts
6379
---@field settings_file_pattern string|nil File name or pattern to search for. Defaults to 'hls.json'
6480

@@ -144,10 +160,11 @@ function lsp.setup()
144160
vim.notify('haskell-tools: ' .. msg, vim.log.levels.ERROR)
145161
return
146162
end
163+
local is_cabal = filetype == 'cabal' or filetype == 'cabalproject'
147164
local project_root = ht.project.root_dir(file)
148165
local hls_settings = type(hls_opts.settings) == 'function' and hls_opts.settings(project_root) or hls_opts.settings
149166
local lsp_start_opts = {
150-
name = lsp_util.client_name,
167+
name = is_cabal and lsp_util.cabal_client_name or lsp_util.haskell_client_name,
151168
cmd = cmd,
152169
root_dir = project_root,
153170
capabilities = hls_opts.capabilities,
@@ -176,12 +193,13 @@ function lsp.setup()
176193
buf_refresh_codeLens()
177194
end
178195
end,
196+
on_init = function(client, _)
197+
ensure_clean_exit_on_quit(client, bufnr)
198+
fix_cabal_client(client)
199+
end,
179200
}
180201
ht.log.debug('LSP start options: lsp_start_opts')
181202
local client_id = vim.lsp.start(lsp_start_opts)
182-
if client_id then
183-
ensure_clean_exit_on_quit(client_id, bufnr)
184-
end
185203
return client_id
186204
end
187205

lua/haskell-tools/lsp/util.lua

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,33 @@ local util = {}
1313
---@diagnostic disable-next-line: deprecated
1414
util.get_clients = vim.lsp.get_clients or vim.lsp.get_active_clients
1515

16-
util.client_name = 'haskell-tools.nvim'
16+
util.haskell_client_name = 'haskell-tools.nvim'
17+
util.cabal_client_name = 'haskell-tools.nvim (cabal)'
1718

1819
---@param bufnr number the buffer to get clients for
20+
---@return lsp.Client[] haskell_clients
21+
---@see util.get_clients
22+
function util.get_active_haskell_clients(bufnr)
23+
return util.get_clients { bufnr = bufnr, name = util.cabal_client_name }
24+
end
25+
26+
---@param bufnr number the buffer to get clients for
27+
---@return lsp.Client[] cabal_clinets
28+
---@see util.get_clients
29+
function util.get_active_cabal_clients(bufnr)
30+
return util.get_clients { bufnr = bufnr, name = util.cabal_client_name }
31+
end
32+
33+
---@param bufnr number the buffer to get clients for
34+
---@return lsp.Client[] ht_clients The haskell + cabal clients
35+
---@see util.get_clients
36+
---@see util.get_active_haskell_clients
37+
---@see util.get_active_cabal_clients
1938
function util.get_active_ht_clients(bufnr)
20-
return util.get_clients { bufnr = bufnr, name = util.client_name }
39+
local clients = {}
40+
vim.list_extend(clients, util.get_active_haskell_clients(bufnr))
41+
vim.list_extend(clients, util.get_active_cabal_clients(bufnr))
42+
return clients
2143
end
2244

2345
return util

0 commit comments

Comments
 (0)