fix(treesitter): normalize language aliases

Hyphenated language names are silently dropped when used as injections
(see #38132).

This combines the normalization of language aliases into `resolve_lang`,
and also adds the normalization of hyphens to underscores, which allows
for handling of injected language tags with hyphens in their names.

Fixes #38132.
This commit is contained in:
Stefan VanBuren
2026-03-03 13:18:55 -05:00
committed by Christian Clason
parent 6535353b6d
commit 01817eb6f3
2 changed files with 20 additions and 1 deletions

View File

@@ -1022,6 +1022,8 @@ end)
---@param alias string language or filetype name
---@return string? # resolved parser name
local function resolve_lang(alias)
-- normalize: treesitter language names are always lower case and use underscores
alias = alias and alias:lower():gsub('-', '_')
-- validate that `alias` is a legal language
if not (alias and alias:match('[%w_]+') == alias) then
return
@@ -1058,7 +1060,7 @@ function LanguageTree:_get_injection(match, metadata)
-- Lang should override any other language tag
if name == 'injection.language' then
local text = vim.treesitter.get_node_text(node, self._source, { metadata = metadata[id] })
lang = resolve_lang(text:lower()) -- language names are always lower case
lang = resolve_lang(text)
elseif name == 'injection.filename' then
local text = vim.treesitter.get_node_text(node, self._source, { metadata = metadata[id] })
local ft = vim.filetype.match({ filename = text })

View File

@@ -938,6 +938,23 @@ int x = INT_MAX;
eq({ 'gsub!', 'offset!', 'set!', 'trim!' }, res_list)
end)
end)
it('normalizes hyphens to underscores in injection.language', function()
exec_lua(function()
-- register "c" as the parser for "shell_session" (normalized form of "shell-session")
vim.treesitter.language.register('c', 'shell_session')
_G.parser = vim.treesitter.get_parser(0, 'c', {
injections = {
c = '(preproc_def (preproc_arg) @injection.content (#set! injection.language "shell-session"))',
},
})
_G.parser:parse(true)
end)
-- injection.language "shell-session" should normalize to "shell_session",
-- which resolves via the registered alias to the "c" parser
eq('table', exec_lua('return type(parser:children().c)'))
end)
end)
it('clips nested injections #34098', function()