What to do when a language server doesn't start?
Ensure the executable is on your PATH
Before we start, do you know what is the "PATH"?
If the answer is "No, I don't know what the hell you are talking about?" I'm going to tell you.
The PATH is an environment variable that contains a list of folder locations
that the operating system searches for executable files.
Here are a couple of links that can be useful to you.
Now that you know, we can move on.
You can check if Neovim can find the executable of a language server using the command :LspInfo
, that will show you information about all language servers you have configured with lspconfig
.
Open a file where the language server should be active, then execute the command :LspInfo
. If the executable could not be found it you should get an error message like this one:
- ERROR Failed to run healthcheck for "lspconfig" plugin. Exception:
Vim:E475: Invalid value for argument cmd: 'astro-ls' is not executable
Here I'm using the astro language server as an example. That's why it shows cmd: 'astro-ls' is not executable
.
If you get something like this, try to update your PATH environment variable. Add the folder where the executable of the language server is located.
Inspect the log file
If the language server fails after it starts, look for an error message in the log file. Use this command.
:LspLog
Ensure mason-lspconfig knows about the server
If you are using mason-lspconfig
to handle the automatic setup, the first thing you can do is make sure mason-lspconfig recognizes the server.
Execute this command to inspect the list of installed servers.
:lua = require('mason-lspconfig').get_installed_servers()
If everything is okay you should see a list like this.
{"ts_ls", "eslint"}
If your language server is not on this list execute the command :LspInstall
with the name of the server. For example:
:LspInstall eslint
Ensure the setup function for the language server was called
Open Neovim using this commmand nvim test
. The idea here is that you open Neovim with an empty buffer with no filetype. Why? just in case you are lazy loading lspconfig. Now execute the command :LspInfo
, this will open a new tabpage with some information. You should have something like this.
LSP configs active in this session (globally) ~
- Configured servers: ts_ls, intelephense, rust_analyzer, lua_ls
- OK Deprecated servers: (none)
LSP configs active in this buffer (bufnr: 1) ~
- Language client log: ~/.local/state/nvim/lsp.log
- Detected filetype: ``
- 0 client(s) attached to this buffer
Docs for active configs: ~
Notice it says Configured servers list
, your language server should be there. If it isn't, you need to make sure lspconfig's setup function is being called.
If lua_ls
were missing then you would need to make sure somewhere in your config this function is being called.
require('lspconfig').lua_ls.setup({})
If you used mason-lspconfig
automatic setup then it's being called for you in the handlers
option. You should have something like this.
require('mason-lspconfig').setup({
handlers = {
function(server_name)
require('lspconfig')[server_name].setup({})
end,
}
})
Ensure root_dir can be detected
When you execute the command :LspInfo
inside an existing file you should get more data about the server.
Sometimes you will get something like this.
LSP configs active in this buffer (bufnr: 1) ~
- Language client log: ~/.local/state/nvim/lsp.log
- Detected filetype: `typescript`
- 0 client(s) attached to this buffer
- Other clients that match the "typescript" filetype:
- Config: ts_ls
filetypes: javascript, javascriptreact, typescript, typescriptreact
cmd: ~/.local/bin/typescript-language-server --stdio
version: `4.3.3`
executable: true
autostart: true
root directory: Not found.
In this example the language server for typescript is not active in the current file.
The important bit is this.
root directory: Not found.
This means lspconfig
could not figure out what is the root of your project.
lspconfig will look for some common configuration file in the current directory or the parent directories. If it can't find them the language server doesn't get attached to the file.
How do you know which files lspconfig looks for? Ideally, you would know because you read the documentation. Each server looks for a particular set of files and you can find that information here: configs.md.
Sometimes the documentation in lspconfig just says see source file
in the root_dir
section. In this case what you can do is inspect the source code of lspconfig. If you have lsp-zero installed you can use the command :LspZeroViewConfigSource
with the name of a language server, this will open the configuration file for that server in a split window.
So you can inspect ts_ls
config using this.
:LspZeroViewConfigSource ts_ls
Once there, you can look for a property called root_dir
. This property is usually a lua function, so you might find some amount of logic there, but you can still get an idea of which files lspconfig looks for.