autotools-language-server icon indicating copy to clipboard operation
autotools-language-server copied to clipboard

Dual/Split-LSP format is incompatible with commonly used LSP tooling

Open rgambord opened this issue 8 months ago • 4 comments

Working in neovim, "make-language-server 0.0.22" attaches to configure.ac with detected filetype "config" and gives "[: Error" and "]: Error" diagnostics for every single square bracket in the file. I can't find anything in the documentation that would point to why this is happening.

rgambord avatar Mar 18 '25 02:03 rgambord

Investigating this a bit, I found that when installed using pip (via pypi) it generates three identical executable entry scripts, all calling the same main() function from make_language_server. I suspect that this is the problem. If I modify the autotools-language-server file to run autoconf_language_server.main, then it works for configure.ac. I'm not entirely sure how I would set this up so that both autoconf and make language servers work, since nvim (lspconfig) seems to only recognize the indeterminate "autotools-langauge-server" as the installed lsp. I can't manually start either autoconf-language-server or make-language-server in nvim.

$python -m venv --system-site-packages venv && venv/bin/pip install -q autotools-language-server && tail -n+1 venv/bin/*language-server
[notice] A new release of pip is available: 24.3.1 -> 25.0.1
[notice] To update, run: python -m pip install --upgrade pip
==> venv/bin/autoconf-language-server <==
#!/home/ryan/venv/bin/python
# -*- coding: utf-8 -*-
import re
import sys
from make_language_server.__main__ import main
if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
    sys.exit(main())

==> venv/bin/autotools-language-server <==
#!/home/ryan/venv/bin/python
# -*- coding: utf-8 -*-
import re
import sys
from make_language_server.__main__ import main
if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
    sys.exit(main())

==> venv/bin/make-language-server <==
#!/home/ryan/venv/bin/python
# -*- coding: utf-8 -*-
import re
import sys
from make_language_server.__main__ import main
if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
    sys.exit(main())

rgambord avatar Mar 18 '25 16:03 rgambord

The issue is in pyproject.toml,

make-language-server = "make_language_server.__main__:main"
autoconf-language-server = "make_language_server.__main__:main"
autotools-language-server = "make_language_server.__main__:main"

I suggest changing to,

make-language-server = "make_language_server.__main__:main"
autoconf-language-server = "autoconf_language_server.__main__:main"

However this still will cause problems for users, since many tools expect there to be a 1-to-1 relationship between installed packages and language servers.

LSPconfig config files can only return a default_config for one language server, so we'd need to have LSPconfig remove autotools_ls.lua and replace it with automake_ls.lua and autoconf_ls.lua with different registered filetypes.

Additionally, I am using mason-lspconfig, which is designed to configure one language server for one installed mason package. AFAIK, it can't be set up to configure both servers for one package.

It seems to me that the least disruptive solution would be to split this into two packages with two separate configs submitted to LSPconfig.

rgambord avatar Mar 18 '25 17:03 rgambord

Here's my temporary solution for anyone else using nvim with lspconfig and mason-lspconfig,

  1. Install autotools-language-server with Mason
  2. Edit the mason venv/bin/autoconf-language-server to use the correct lsp
  3. Add the following to your mason-lspconfig setup,
require("mason-lspconfig").setup_handlers({
       -- Override autotools_ls and inject configs for autoconf and automake into lspconfig
	["autotools_ls"] = function(server)
		-- Make lspconfig populate configs with autotools_ls entry
		_ = lspconfig[server]
		local configs = require("lspconfig.configs")
		do
			local conf = {
				default_config = {
					cmd = { "autoconf-language-server" },
					filetypes = { "config" },
				},
			}
			configs["autoconf_ls"] = vim.tbl_deep_extend("keep", conf, configs["autotools_ls"].config_def)
			lspconfig["autoconf_ls"].setup({})
		end
		do
			local conf = {
				default_config = {
					cmd = { "make-language-server" },
					filetypes = { "make", "automake" },
				},
			}
			configs["automake_ls"] = vim.tbl_deep_extend("keep", conf, configs["autotools_ls"].config_def)
			lspconfig["automake_ls"].setup({})
		end
	end,
})

rgambord avatar Mar 18 '25 18:03 rgambord

AFAIK, it can't be set up to configure both servers for one package.

I project to rewrite make-language-server based on https://github.com/google/kati . After then, you can use this language server for autoconf, and use new language server for makefile. However, I am busy with postgraduation so I don't have enough time for open source project within a long time :cry:.

Freed-Wu avatar Mar 31 '25 16:03 Freed-Wu