diff options
author | Christian Clason <c.clason@uni-graz.at> | 2023-08-11 17:05:17 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-11 17:05:17 +0200 |
commit | 31c4ed26bc278282898123ad21bb6fead401fd6f (patch) | |
tree | f7bd6c3a1953348ef5980e5e52d35c655d024a3d /runtime/lua/vim/treesitter/languagetree.lua | |
parent | 72e64a1afef0df1bd244bfb31dfc8619d91ff709 (diff) | |
download | rneovim-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.lua | 27 |
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 |