lsp: get_language_id (#14092)

* Allow specifying a languageId for a lsp

For some languages the filetype might not match the languageId the
language server accepts. In these cases the config for the language
server can contain a function which gets the current buffer and filetype
and returns a languageId. When it isn't provided the filetype is used
instead.

Example:
```lua
require'lspconfig'.sourcekit.setup{
    get_language_id = function(bufnr, ft)
        return 'swift'
    end;
}
```

Closes #13093

* lsp: Change to get_language_id

Co-authored-by: Jan Dammshäuser <mail@jandamm.de>
This commit is contained in:
TJ DeVries 2021-03-10 16:53:23 -05:00 committed by GitHub
parent c29494b719
commit 564dd7d8db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 2 deletions

View File

@ -799,6 +799,8 @@ start_client({config}) *vim.lsp.start_client()*
See `initialize` in the LSP spec. See `initialize` in the LSP spec.
{name} (string, default=client-id) Name in log {name} (string, default=client-id) Name in log
messages. messages.
{get_language_id} function(bufnr, filetype) -> language
ID as string. Defaults to the filetype.
{offset_encoding} (default="utf-16") One of "utf-8", {offset_encoding} (default="utf-16") One of "utf-8",
"utf-16", or "utf-32" which is the "utf-16", or "utf-32" which is the
encoding that the LSP server expects. encoding that the LSP server expects.

View File

@ -228,6 +228,7 @@ local function validate_client_config(config)
before_init = { config.before_init, "f", true }; before_init = { config.before_init, "f", true };
offset_encoding = { config.offset_encoding, "s", true }; offset_encoding = { config.offset_encoding, "s", true };
flags = { config.flags, "t", true }; flags = { config.flags, "t", true };
get_language_id = { config.get_language_id, "f", true };
} }
local cmd, cmd_args = lsp._cmd_parts(config.cmd) local cmd, cmd_args = lsp._cmd_parts(config.cmd)
@ -275,12 +276,13 @@ local function text_document_did_open_handler(bufnr, client)
if not vim.api.nvim_buf_is_loaded(bufnr) then if not vim.api.nvim_buf_is_loaded(bufnr) then
return return
end end
local filetype = nvim_buf_get_option(bufnr, 'filetype')
local params = { local params = {
textDocument = { textDocument = {
version = 0; version = 0;
uri = vim.uri_from_bufnr(bufnr); uri = vim.uri_from_bufnr(bufnr);
-- TODO make sure our filetypes are compatible with languageId names. languageId = client.config.get_language_id(bufnr, filetype);
languageId = nvim_buf_get_option(bufnr, 'filetype');
text = buf_get_full_text(bufnr); text = buf_get_full_text(bufnr);
} }
} }
@ -407,6 +409,9 @@ end
--- ---
--@param name (string, default=client-id) Name in log messages. --@param name (string, default=client-id) Name in log messages.
--- ---
--@param get_language_id function(bufnr, filetype) -> language ID as string.
--- Defaults to the filetype.
---
--@param offset_encoding (default="utf-16") One of "utf-8", "utf-16", --@param offset_encoding (default="utf-16") One of "utf-8", "utf-16",
--- or "utf-32" which is the encoding that the LSP server expects. Client does --- or "utf-32" which is the encoding that the LSP server expects. Client does
--- not verify this is correct. --- not verify this is correct.
@ -466,6 +471,11 @@ function lsp.start_client(config)
config.flags = config.flags or {} config.flags = config.flags or {}
config.settings = config.settings or {} config.settings = config.settings or {}
-- By default, get_language_id just returns the exact filetype it is passed.
-- It is possible to pass in something that will calculate a different filetype,
-- to be sent by the client.
config.get_language_id = config.get_language_id or function(_, filetype) return filetype end
local client_id = next_client_id() local client_id = next_client_id()
local handlers = config.handlers or {} local handlers = config.handlers or {}