@@ -1536,18 +1536,27 @@ H.get_matched_range_pairs_builtin = function(captures)
15361536 -- Get parser (LanguageTree) at cursor (important for injected languages)
15371537 local pos = vim .api .nvim_win_get_cursor (0 )
15381538 local lang_tree = parser :language_for_range ({ pos [1 ] - 1 , pos [2 ], pos [1 ] - 1 , pos [2 ] })
1539- local lang = lang_tree :lang ()
1540-
1541- -- Get query file depending on the local language
1542- local query = vim .treesitter .query .get (lang , ' textobjects' )
1543- if query == nil then H .error_treesitter (' query' ) end
15441539
1540+ local missing_query_langs = {}
15451541 -- Compute matched ranges for both outer and inner captures
15461542 local outer_ranges , inner_ranges = {}, {}
1547- for _ , tree in ipairs (lang_tree :trees ()) do
1548- local root = tree :root ()
1549- vim .list_extend (outer_ranges , H .get_match_ranges_builtin (root , buf_id , query , captures .outer :sub (2 )))
1550- vim .list_extend (inner_ranges , H .get_match_ranges_builtin (root , buf_id , query , captures .inner :sub (2 )))
1543+ while (vim .tbl_isempty (inner_ranges ) or vim .tbl_isempty (outer_ranges )) and lang_tree ~= nil do
1544+ local lang = lang_tree :lang ()
1545+ -- Get query file depending on the local language
1546+ local query = vim .treesitter .query .get (lang , ' textobjects' )
1547+
1548+ if query ~= nil then
1549+ for _ , tree in ipairs (lang_tree :trees ()) do
1550+ local root = tree :root ()
1551+ vim .list_extend (outer_ranges , H .get_match_ranges_builtin (root , buf_id , query , captures .outer :sub (2 )))
1552+ vim .list_extend (inner_ranges , H .get_match_ranges_builtin (root , buf_id , query , captures .inner :sub (2 )))
1553+ end
1554+ end
1555+ if query == nil then missing_query_langs [lang ] = true end
1556+
1557+ -- `LanguageTree:parent()` was added in Neovim<0.10
1558+ -- TODO: Change to `lang_tree:parent()` after compatibility with Neovim=0.9 is dropped
1559+ lang_tree = lang_tree .parent and lang_tree :parent () or nil
15511560 end
15521561
15531562 -- Match outer and inner ranges: for each outer range pick the biggest inner
@@ -1556,6 +1565,11 @@ H.get_matched_range_pairs_builtin = function(captures)
15561565 for i , outer in ipairs (outer_ranges ) do
15571566 res [i ] = { outer = outer , inner = H .get_biggest_nested_range (inner_ranges , outer ) }
15581567 end
1568+
1569+ if vim .tbl_isempty (res ) and not vim .tbl_isempty (missing_query_langs ) then
1570+ H .error_treesitter (' query' , vim .tbl_keys (missing_query_langs ))
1571+ end
1572+
15591573 return res
15601574end
15611575
@@ -1601,11 +1615,17 @@ H.get_biggest_nested_range = function(ranges, parent)
16011615 return best_range
16021616end
16031617
1604- H .error_treesitter = function (failed_get )
1618+ H .error_treesitter = function (failed_get , langs )
16051619 local buf_id , ft = vim .api .nvim_get_current_buf (), vim .bo .filetype
1606- local has_lang , lang = pcall (vim .treesitter .language .get_lang , ft )
1607- lang = has_lang and lang or ft
1608- local msg = string.format (' Can not get %s for buffer %d and language "%s".' , failed_get , buf_id , lang )
1620+ if langs == nil then
1621+ local ok , ft_lang = pcall (vim .treesitter .language .get_lang , ft )
1622+ -- `vim.treesitter.language.get_lang()` defaults to `ft` only on Neovim>0.11
1623+ -- TODO: Remove `and ft_lang ~= nil` after compatibility with Neovim=0.10 is dropped
1624+ langs = (ok and ft_lang ~= nil ) and { ft_lang } or { ft }
1625+ end
1626+ local langs_str = table.concat (vim .tbl_map (function (lang ) return string.format (' "%s"' , lang ) end , langs ), ' , ' )
1627+ local langs_noun = # langs == 1 and ' language' or ' languages'
1628+ local msg = string.format (' Can not get %s for buffer %d and %s %s.' , failed_get , buf_id , langs_noun , langs_str )
16091629 H .error (msg )
16101630end
16111631
0 commit comments