Skip to content

Commit

Permalink
fix: support compound file-types
Browse files Browse the repository at this point in the history
Vim supports compound filetypes (see |'filetype'|):

> When a dot appears in the value then this separates two filetype names.
> This works both for filetype plugins and for syntax files. More than one dot may appear.

nvim-lspconfig currently always compares the full 'filetype' option
against the configured filetypes. So buffers set to multiple filetypes
will not match at all.

Fix utility functions to match against each individual filetype
  • Loading branch information
baodrate committed May 9, 2024
1 parent a3d9395 commit ba97875
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 13 deletions.
2 changes: 1 addition & 1 deletion lua/lspconfig/server_configurations/elmls.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ return {
filetypes = { 'elm' },
root_dir = function(fname)
local filetype = api.nvim_buf_get_option(0, 'filetype')
if filetype == 'elm' or (filetype == 'json' and fname:match 'elm%.json$') then
if util.ft_matches(filetype, 'elm') or (util.ft_matches(filetype, 'json') and fname:match 'elm%.json$') then
return elm_root_pattern(fname)
end
end,
Expand Down
33 changes: 21 additions & 12 deletions lua/lspconfig/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,21 @@ M.default_config = {
-- global on_setup hook
M.on_setup = nil

---@param filetype string the filetype to check (can be a compound, dot-separated filetype; see |'filetype'|)
---@param expected string|string[] the filetype(s) to match against
---@return boolean
function M.ft_matches(filetype, expected)
expected = type(expected) == 'table' and expected or { expected }
for ft in filetype:gmatch '([^.]+)' do
for _, expected_ft in ipairs(expected) do
if ft == expected_ft then
return true
end
end
end
return false
end

function M.bufname_valid(bufname)
if bufname:match '^/' or bufname:match '^[a-zA-Z]:' or bufname:match '^zipfile://' or bufname:match '^tarfile:' then
return true
Expand Down Expand Up @@ -337,10 +352,8 @@ function M.get_active_clients_list_by_ft(filetype)
local clients_list = {}
for _, client in pairs(clients) do
local filetypes = client.config.filetypes or {}
for _, ft in pairs(filetypes) do
if ft == filetype then
table.insert(clients_list, client.name)
end
if M.ft_matches(filetype, filetypes) then
table.insert(clients_list, client.name)
end
end
return clients_list
Expand All @@ -353,10 +366,8 @@ function M.get_other_matching_providers(filetype)
for _, config in pairs(configs) do
if not vim.tbl_contains(active_clients_list, config.name) then
local filetypes = config.filetypes or {}
for _, ft in pairs(filetypes) do
if ft == filetype then
table.insert(other_matching_configs, config)
end
if M.ft_matches(filetype, filetypes) then
table.insert(other_matching_configs, config)
end
end
end
Expand All @@ -368,10 +379,8 @@ function M.get_config_by_ft(filetype)
local matching_configs = {}
for _, config in pairs(configs) do
local filetypes = config.filetypes or {}
for _, ft in pairs(filetypes) do
if ft == filetype then
table.insert(matching_configs, config)
end
if M.ft_matches(filetype, filetypes) then
table.insert(matching_configs, config)
end
end
return matching_configs
Expand Down

0 comments on commit ba97875

Please sign in to comment.