@@ -54,6 +54,63 @@ local function parse_directives(filename)
5454 return contexts
5555end
5656
57+ --- Install the root treesitter language for the given file and injected languages.
58+ --- @param filename string
59+ --- @param root_lang string
60+ local function install_langs_for_file (filename , root_lang )
61+ cmd (' edit ' .. filename )
62+ local bufnr = api .nvim_get_current_buf ()
63+ local line_count = api .nvim_buf_line_count (bufnr )
64+ --- @type table<string,boolean>
65+ local seen_langs = {}
66+ --- @type string[]
67+ local langs_to_check = { root_lang }
68+ while # langs_to_check > 0 do
69+ local current_lang = table.remove (langs_to_check , 1 )
70+ -- We might encounter recursion, so check if we've traversed this language before.
71+ if seen_langs [current_lang ] then
72+ goto continue
73+ end
74+ install_langs (current_lang )
75+
76+ -- Query for injections in the current language, and queue them for installation.
77+ --- @diagnostic disable-next-line : redefined-local Not actually redefining locals
78+ langs_to_check = exec_lua (function (bufnr , current_lang , line_count , langs_to_check )
79+ local current_parser = vim .treesitter .get_parser (bufnr , current_lang )
80+ if not current_parser then
81+ return langs_to_check
82+ end
83+ -- Parsing the whole file is a simple way to get all injections for the file.
84+ local tree_map = current_parser :parse ({ 0 , line_count })
85+ if not tree_map then
86+ return langs_to_check
87+ end
88+ local injection_query = vim .treesitter .query .get (current_lang , ' injections' )
89+ if not injection_query then
90+ return langs_to_check
91+ end
92+ for _ , tree in pairs (tree_map ) do
93+ local root = tree :root ()
94+ for id , node , metadata in injection_query :iter_captures (root , bufnr , 0 , line_count ) do
95+ -- The name of the injection language is either available through metadata or the text
96+ -- content of the `injection.language` capture.
97+ if metadata [' injection.language' ] then
98+ table.insert (langs_to_check , metadata [' injection.language' ])
99+ end
100+ local capture_name = injection_query .captures [id ]
101+ if capture_name == ' injection.language' then
102+ local node_text = vim .treesitter .get_node_text (node , bufnr )
103+ table.insert (langs_to_check , node_text )
104+ end
105+ end
106+ end
107+ return langs_to_check
108+ end , bufnr , current_lang , line_count , langs_to_check )
109+ seen_langs [current_lang ] = true
110+ :: continue::
111+ end
112+ end
113+
57114local langs = get_langs ()
58115local langs_with_queries = {} --- @type string[]
59116for _ , lang in ipairs (langs ) do
@@ -111,9 +168,9 @@ for _, lang in ipairs(langs_with_queries) do
111168 return
112169 end
113170
114- setup (function ()
171+ lazy_setup (function ()
115172 cmd ([[ let $XDG_CACHE_HOME='scratch/cache']] )
116- install_langs ( lang )
173+ install_langs_for_file ( test_file , lang )
117174 end )
118175
119176 for cursor_row , context_rows in pairs (contexts ) do
0 commit comments