dense-analysis / ale

Check syntax in Vim/Neovim asynchronously and fix files, with Language Server Protocol (LSP) support
BSD 2-Clause "Simplified" License
13.57k stars 1.44k forks source link

Automatically disable ALE language servers if configured via nvim-lspconfig #4607

Closed w0rp closed 1 year ago

w0rp commented 1 year ago

nvim-lspconfig is a popular and officially recommended way to configure language servers for Neovim. Users can either choose to use ALE to run language servers, or configure them via nvim-lspconfig and use Neovim's built-in LSP functionality. ALE now by default sends diagnostics from linters to Neovim's diagnostics in Neovim 0.6+.

We can go a step further and change the default for g:ale_disable_lsp to 'auto'. In this new mode, we can apply the following. We can check if lspconfig is installed and enabled.

if ale#Var(a:buffer, 'disable_lsp') is# 'auto' && get(g:, 'lspconfig', 0)
    " Perform logic to detect if we should automatically skip loading LSP linters.
endif

We can provide a Lua function to check which servers are configure for nvim-lspconfig.

-- In  lua/ale/util.lua
local M = {}

function M.configured_lspconfig_servers()
    local configs = require 'lspconfig.configs'
    local keys = {}

    for key, _ in pairs(configs) do
        table.insert(keys, key)
    end

    return keys
end

return M

We can then get access to a List of those values in Vim.

" May be a Dictionary when empty
let l:lspconfig_servers = luaeval('require ''ale.util''.configured_lspconfig_servers()')

if !empty(l:lspconfig_servers)
    " Handle servers
endif

Internally we can hold a mapping from lspconfig names to ALE linter names, where they differ, and use the list to filter our linters to return in ale#linter#RemoveIgnored and ale#engine#ignore#Exclude. The ignored linters will automatically appear as ignored in :ALEInfo by virtue of how :ALEInfo already works.

We should also move lua/diagnostics.lua to lua/ale/diagnostics.lua while we're at it, as it's in the wrong place.

The above should establish a very reliable means of just turning our linters off automatically when they are set up with nvim-lspconfig.

w0rp commented 1 year ago

I have implemented this now. The behavior is as described in the description of the issue. ALE will now by default check if nvim-lspconfig is installed, look at which tools are configured via nvim-lspconfig, and automatically disable LSP linters if they are already configured via nvim-lspconfig. You can set g:ale_disable_lsp to 0 to turn this off globally, and it shouldn't change anything for anyone who doesn't have that plugin installed.

I had to rename and add aliases for a number of ALE linters, and set up a mapping from less desirable lspconfig names to better names in ALE so the equivalent ALE linters can be found. Some linters, such as rubocop, will be disabled on our end if configured via nvim-lspconfig, even though we don't currently run them with a language server. The rationale is that some tools are able to run with a language server mode, and we just haven't implemented it yet in ALE.