diff --git a/runtime/lua/vim/treesitter/languagetree.lua b/runtime/lua/vim/treesitter/languagetree.lua index 79f36a27fd..4dd5a18396 100644 --- a/runtime/lua/vim/treesitter/languagetree.lua +++ b/runtime/lua/vim/treesitter/languagetree.lua @@ -734,7 +734,8 @@ local has_parser = function(lang) or #vim.api.nvim_get_runtime_file('parser/' .. lang .. '.*', false) > 0 end ---- Return parser name for language (if exists) or filetype (if registered and exists) +--- Return parser name for language (if exists) or filetype (if registered and exists). +--- Also attempts with the input lower-cased. --- ---@param alias string language or filetype name ---@return string? # resolved parser name @@ -743,10 +744,19 @@ local function resolve_lang(alias) return alias end + if has_parser(alias:lower()) then + return alias:lower() + end + local lang = vim.treesitter.language.get_lang(alias) if lang and has_parser(lang) then return lang end + + lang = vim.treesitter.language.get_lang(alias:lower()) + if lang and has_parser(lang) then + return lang + end end ---@private @@ -758,9 +768,10 @@ end function LanguageTree:_get_injection(match, metadata) local ranges = {} ---@type Range6[] local combined = metadata['injection.combined'] ~= nil + local injection_lang = metadata['injection.language'] --[[@as string?]] local lang = metadata['injection.self'] ~= nil and self:lang() or metadata['injection.parent'] ~= nil and self._parent_lang - or metadata['injection.language'] --[[@as string?]] + or (injection_lang and resolve_lang(injection_lang)) local include_children = metadata['injection.include-children'] ~= nil for id, node in pairs(match) do @@ -768,7 +779,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) or resolve_lang(text:lower()) + lang = resolve_lang(text) elseif name == 'injection.content' then ranges = get_node_ranges(node, self._source, metadata[id], include_children) end diff --git a/test/functional/treesitter/highlight_spec.lua b/test/functional/treesitter/highlight_spec.lua index 0528370e2a..0aa0cdd6d6 100644 --- a/test/functional/treesitter/highlight_spec.lua +++ b/test/functional/treesitter/highlight_spec.lua @@ -85,6 +85,56 @@ void ui_refresh(void) } }]] +local injection_text_c = [[ +int x = INT_MAX; +#define READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) +#define foo void main() { \ + return 42; \ + } +]] + +local injection_grid_c = [[ + int x = INT_MAX; | + #define READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) | + #define foo void main() { \ | + return 42; \ | + } | + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + | +]] + +local injection_grid_expected_c = [[ + {3:int} x = {5:INT_MAX}; | + #define {5:READ_STRING}(x, y) ({3:char} *)read_string((x), ({3:size_t})(y)) | + #define foo {3:void} main() { \ | + {4:return} {5:42}; \ | + } | + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + | +]] + describe('treesitter highlighting (C)', function() local screen @@ -411,34 +461,9 @@ describe('treesitter highlighting (C)', function() end) it("supports injected languages", function() - insert([[ - int x = INT_MAX; - #define READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) - #define foo void main() { \ - return 42; \ - } - ]]) + insert(injection_text_c) - screen:expect{grid=[[ - int x = INT_MAX; | - #define READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) | - #define foo void main() { \ | - return 42; \ | - } | - ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - | - ]]} + screen:expect{grid=injection_grid_c} exec_lua [[ local parser = vim.treesitter.get_parser(0, "c", { @@ -448,26 +473,24 @@ describe('treesitter highlighting (C)', function() test_hl = highlighter.new(parser, {queries = {c = hl_query}}) ]] - screen:expect{grid=[[ - {3:int} x = {5:INT_MAX}; | - #define {5:READ_STRING}(x, y) ({3:char} *)read_string((x), ({3:size_t})(y)) | - #define foo {3:void} main() { \ | - {4:return} {5:42}; \ | - } | - ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - | - ]]} + screen:expect{grid=injection_grid_expected_c} + end) + + it("supports injecting by ft name in metadata['injection.language']", function() + insert(injection_text_c) + + screen:expect{grid=injection_grid_c} + + exec_lua [[ + vim.treesitter.language.register("c", "foo") + local parser = vim.treesitter.get_parser(0, "c", { + injections = {c = '(preproc_def (preproc_arg) @injection.content (#set! injection.language "fOO")) (preproc_function_def value: (preproc_arg) @injection.content (#set! injection.language "fOO"))'} + }) + local highlighter = vim.treesitter.highlighter + test_hl = highlighter.new(parser, {queries = {c = hl_query}}) + ]] + + screen:expect{grid=injection_grid_expected_c} end) it("supports overriding queries, like ", function()