aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorL Lllvvuu <git@llllvvuu.dev>2023-09-13 16:51:54 -0700
committerLewis Russell <me@lewisr.dev>2023-09-16 11:12:06 +0100
commit908843df61fc80f160392edc0af0d1672a8f9a68 (patch)
tree37cd0c2d22e3855a1dd0fd003a63c77a03583fcd
parent40bfca744dd0c87df6ec2ab776f982636e4b0904 (diff)
downloadrneovim-908843df61fc80f160392edc0af0d1672a8f9a68.tar.gz
rneovim-908843df61fc80f160392edc0af0d1672a8f9a68.tar.bz2
rneovim-908843df61fc80f160392edc0af0d1672a8f9a68.zip
fix(languagetree): apply `resolve_lang` to `metadata['injection.language']`
`resolve_lang` is applied to `@injection.language` when it's supplied as a capture: https://github.com/neovim/neovim/blob/f5953edbac14febce9d4f8a3c35bdec1eae26fbe/runtime/lua/vim/treesitter/languagetree.lua#L766-L768 If we want to support `metadata['injection.language']` (as per #22518 and [tree-sitter upstream](https://tree-sitter.github.io/tree-sitter/syntax-highlighting#language-injection)) then the behavior should be consistent. Fixes: nvim-treesitter/nvim-treesitter#4918
-rw-r--r--runtime/lua/vim/treesitter/languagetree.lua17
-rw-r--r--test/functional/treesitter/highlight_spec.lua117
2 files changed, 84 insertions, 50 deletions
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()