Allow for dynamic resolve of languageId value
asmodeus812 opened this issue · 0 comments
Describe the bug
There is an issue with the way coc handles the languageId
, at the moment one can only have one hard coded predefined language id that is sent to all
running servers, g:coc_filetype_map is not very useful either in this regard, since it is also global for all clients. However this is a problem, because there are scertain servers such as https://github.com/spring-projects/sts4/blob/992a7c742838a381443a5a86ed0327523b1f3086/vscode-extensions/vscode-spring-boot/lib/Main.ts#L25-L30. Which require a very specific name for the languageId
send for the document, we can not simply override yml
or yaml
in this case because that will break other language servers where the ft is expected to be yml
.
Proposition
There should be way to define a custom langugeId resolver per client, so that we can send the correct value for that specific client only. And not affect the globlal ft system.
Other solutions
Below is an example of how neovim does it, each client has the ability to be configured with a custom callback which will be invoked (where needed) to obtain the languge id on the fly or fallback to the default filetype if no callback for get_languge_id
was provided.
local neovim_language_server_config = {
-- cmd = bootls_cmd(),
name = "spring-boot",
filetypes = { "java", "yaml", "jproperties" },
-- root_dir = root_dir,
init_options = {
-- workspaceFolders = root_dir,
enableJdtClasspath = false,
},
settings = {
spring_boot = {},
},
handlers = {},
commands = {},
get_language_id = function(bufnr, filetype)
if filetype == "yaml" then
local filename = vim.api.nvim_buf_get_name(bufnr)
if util.is_application_yml_file(filename) then
return "spring-boot-properties-yaml"
end
elseif filetype == "jproperties" then
local filename = vim.api.nvim_buf_get_name(bufnr)
if util.is_application_properties_file(filename) then
return "spring-boot-properties"
end
end
return filetype
end,
}
From neovim core
function Client:_text_document_did_open_handler(bufnr)
changetracking.init(self, bufnr)
if not vim.tbl_get(self.server_capabilities, 'textDocumentSync', 'openClose') then
return
end
if not api.nvim_buf_is_loaded(bufnr) then
return
end
local filetype = vim.bo[bufnr].filetype
local params = {
textDocument = {
version = 0,
uri = vim.uri_from_bufnr(bufnr),
languageId = self.get_language_id(bufnr, filetype),
text = lsp._buf_get_full_text(bufnr),
},
}
self.notify(ms.textDocument_didOpen, params)
lsp.util.buf_versions[bufnr] = params.textDocument.version
-- Next chance we get, we should re-do the diagnostics
vim.schedule(function()
-- Protect against a race where the buffer disappears
-- between `did_open_handler` and the scheduled function firing.
if api.nvim_buf_is_valid(bufnr) then
local namespace = lsp.diagnostic.get_namespace(self.id)
vim.diagnostic.show(namespace, bufnr)
end
end)
end