1+ --- This file contains the implementation of the hmts-path? and hmts-inject! predicates.
2+
3+ --- TODO: find a way to properly get these types in scope for the language server
4+ --- @alias TSNode userdata
5+ --- @alias vim.regex userdata
6+
7+ --- Returns a compiled vim regex for the given pattern. The regex is cached in a table to avoid recompilation.
8+ --- @param pattern string
9+ --- @return vim.regex
110local function get_regex (pattern )
211 local magic_prefixes = { [" \\ v" ] = true , [" \\ m" ] = true , [" \\ M" ] = true , [" \\ V" ] = true }
312 local function check_magic (str )
@@ -18,11 +27,20 @@ local function get_regex(pattern)
1827 return compiled_vim_regexes [pattern ]
1928end
2029
30+ --- Checks if the given string matches the given regex pattern.
31+ --- @param pattern string
32+ --- @param str string
33+ --- @return boolean
2134local function regex_match (pattern , str )
2235 local regex = get_regex (pattern )
2336 return regex :match_str (str ) ~= nil
2437end
2538
39+ --- Compares the given nix path with the given target path. The target path is modified in place, with the matching
40+ --- nodes removed.
41+ --- @param target_path string[]
42+ --- @param node_path string[]
43+ --- @return boolean
2644local function path_diff (target_path , node_path )
2745 local is_match = false
2846
@@ -42,6 +60,10 @@ local function path_diff(target_path, node_path)
4260 return is_match
4361end
4462
63+ --- Returns the text of the given path node.
64+ --- @param node TSNode
65+ --- @param bufnr integer
66+ --- @return string | nil
4567local function get_text_from_path_node (node , bufnr )
4668 if node :type () == " identifier" then
4769 return vim .treesitter .get_node_text (node , bufnr )
@@ -52,6 +74,10 @@ local function get_text_from_path_node(node, bufnr)
5274 return nil
5375end
5476
77+ --- Returns the nix path of the given attrpath node as a list of strings.
78+ --- @param attrpath TSNode
79+ --- @param bufnr integer
80+ --- @return string[]
5581local function attrpath_to_strings (attrpath , bufnr )
5682 local path = {}
5783
@@ -63,6 +89,35 @@ local function attrpath_to_strings(attrpath, bufnr)
6389 return path
6490end
6591
92+ --- Returns the filename contained in the parent of the given node.
93+ --- @param path_node TSNode
94+ --- @param bufnr integer
95+ --- @return string | nil
96+ local function find_filename_in_parent_node (path_node , bufnr )
97+ local text = vim .treesitter .get_node_text (path_node , bufnr )
98+ local _ , _ , filename = string.find (text , " (.*)%.text$" )
99+ filename = string.sub (filename , 2 , - 2 )
100+
101+ if filename ~= nil then
102+ return filename
103+ end
104+
105+ local parent = path_node :parent ()
106+ while parent do
107+ if parent :type () == " binding" then
108+ local attrpath = parent :field (" attrpath" )[1 ]
109+ return get_text_from_path_node (attrpath , bufnr )
110+ end
111+ parent = parent :parent ()
112+ end
113+ end
114+
115+ --- Checks if the given capture is located at the end of the given nix path. Every node can be matched by a regex.
116+ --- @param match table<string , TSNode>
117+ --- @param _ string
118+ --- @param bufnr integer
119+ --- @param predicate string[]
120+ --- @return boolean
66121local function hmts_path_handler (match , _ , bufnr , predicate )
67122 local node = match [predicate [2 ]]:parent ()
68123 local target_path = vim .list_slice (predicate , 3 , nil )
@@ -84,25 +139,13 @@ local function hmts_path_handler(match, _, bufnr, predicate)
84139 return false
85140end
86141
87- local function find_filename_in_parent_node (path_node , bufnr )
88- local text = vim .treesitter .get_node_text (path_node , bufnr )
89- local _ , _ , filename = string.find (text , " (.*)%.text$" )
90- filename = string.sub (filename , 2 , - 2 )
91-
92- if filename ~= nil then
93- return filename
94- end
95-
96- local parent = path_node :parent ()
97- while parent do
98- if parent :type () == " binding" then
99- local attrpath = parent :field (" attrpath" )[1 ]
100- return get_text_from_path_node (attrpath , bufnr )
101- end
102- parent = parent :parent ()
103- end
104- end
105-
142+ --- Detects the language of the injection from the file extension of the filename contained in the nix path of the given
143+ --- capture.
144+ --- @param match table<string , TSNode>
145+ --- @param _ string
146+ --- @param bufnr integer
147+ --- @param predicate string[]
148+ --- @param metadata table<string , string>
106149local function hmts_inject_handler (match , _ , bufnr , predicate , metadata )
107150 local path_node = match [predicate [2 ]]
108151 local filename = find_filename_in_parent_node (path_node , bufnr )
0 commit comments