aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/treesitter/languagetree.lua
diff options
context:
space:
mode:
authorChristian Clason <c.clason@uni-graz.at>2023-08-11 17:05:17 +0200
committerGitHub <noreply@github.com>2023-08-11 17:05:17 +0200
commit31c4ed26bc278282898123ad21bb6fead401fd6f (patch)
treef7bd6c3a1953348ef5980e5e52d35c655d024a3d /runtime/lua/vim/treesitter/languagetree.lua
parent72e64a1afef0df1bd244bfb31dfc8619d91ff709 (diff)
downloadrneovim-31c4ed26bc278282898123ad21bb6fead401fd6f.tar.gz
rneovim-31c4ed26bc278282898123ad21bb6fead401fd6f.tar.bz2
rneovim-31c4ed26bc278282898123ad21bb6fead401fd6f.zip
feat(treesitter): add injection language fallback (#24659)
* feat(treesitter): add injection language fallback Problem: injection languages are often specified via aliases (e.g., filetype or in upper case), requiring custom directives. Solution: include lookup logic (try as parser name, then filetype, then lowercase) in LanguageTree itself and remove `#inject-language` directive. Co-authored-by: Lewis Russell <me@lewisr.dev>
Diffstat (limited to 'runtime/lua/vim/treesitter/languagetree.lua')
-rw-r--r--runtime/lua/vim/treesitter/languagetree.lua27
1 files changed, 25 insertions, 2 deletions
diff --git a/runtime/lua/vim/treesitter/languagetree.lua b/runtime/lua/vim/treesitter/languagetree.lua
index 4b2628609a..7f1d6d1111 100644
--- a/runtime/lua/vim/treesitter/languagetree.lua
+++ b/runtime/lua/vim/treesitter/languagetree.lua
@@ -635,6 +635,29 @@ local function add_injection(t, tree_index, pattern, lang, combined, ranges)
table.insert(t[tree_index][lang][pattern].regions, ranges)
end
+-- TODO(clason): replace by refactored `ts.has_parser` API (without registering)
+---@param lang string parser name
+---@return boolean # true if parser for {lang} exists on rtp
+local has_parser = function(lang)
+ return vim._ts_has_language(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)
+---
+---@param alias string language or filetype name
+---@return string? # resolved parser name
+local function resolve_lang(alias)
+ if has_parser(alias) then
+ return alias
+ end
+
+ local lang = vim.treesitter.language.get_lang(alias)
+ if lang and has_parser(lang) then
+ return lang
+ end
+end
+
---@private
--- Extract injections according to:
--- https://tree-sitter.github.io/tree-sitter/syntax-highlighting#language-injection
@@ -649,10 +672,10 @@ function LanguageTree:_get_injection(match, metadata)
for id, node in pairs(match) do
local name = self._injection_query.captures[id]
-
-- Lang should override any other language tag
if name == 'injection.language' then
- lang = vim.treesitter.get_node_text(node, self._source, { metadata = metadata[id] })
+ local text = vim.treesitter.get_node_text(node, self._source, { metadata = metadata[id] })
+ lang = resolve_lang(text) or resolve_lang(text:lower())
elseif name == 'injection.content' then
ranges = get_node_ranges(node, self._source, metadata[id], include_children)
end