@@ -22,8 +22,10 @@ pub struct LuaModuleIndex {
2222 module_root_id : ModuleNodeId ,
2323 module_nodes : HashMap < ModuleNodeId , ModuleNode > ,
2424 file_module_map : HashMap < FileId , ModuleInfo > ,
25+ module_name_to_file_ids : HashMap < String , Vec < FileId > > ,
2526 workspace_root : Vec < PathBuf > ,
2627 id_counter : u32 ,
28+ fuzzy_search : bool ,
2729}
2830
2931impl LuaModuleIndex {
@@ -33,8 +35,10 @@ impl LuaModuleIndex {
3335 module_root_id : ModuleNodeId { id : 0 } ,
3436 module_nodes : HashMap :: new ( ) ,
3537 file_module_map : HashMap :: new ( ) ,
38+ module_name_to_file_ids : HashMap :: new ( ) ,
3639 workspace_root : Vec :: new ( ) ,
3740 id_counter : 1 ,
41+ fuzzy_search : false ,
3842 } ;
3943
4044 let root_node = ModuleNode :: default ( ) ;
@@ -122,18 +126,24 @@ impl LuaModuleIndex {
122126
123127 let node = self . module_nodes . get_mut ( & parent_node_id) . unwrap ( ) ;
124128 node. file_ids . push ( file_id) ;
125-
129+ let module_name = module_parts . last ( ) . unwrap ( ) . to_string ( ) ;
126130 let module_info = ModuleInfo {
127131 file_id,
128132 full_module_name : module_parts. join ( "." ) ,
129- name : module_parts . last ( ) . unwrap ( ) . to_string ( ) ,
133+ name : module_name . clone ( ) ,
130134 module_id : parent_node_id,
131135 visible : true ,
132136 export_type : None ,
133137 version_conds : None ,
134138 } ;
135139
136140 self . file_module_map . insert ( file_id, module_info) ;
141+ if self . fuzzy_search {
142+ self . module_name_to_file_ids
143+ . entry ( module_name)
144+ . or_insert ( Vec :: new ( ) )
145+ . push ( file_id) ;
146+ }
137147
138148 Some ( ( ) )
139149 }
@@ -169,10 +179,23 @@ impl LuaModuleIndex {
169179 return None ;
170180 }
171181
182+ let result = self . exact_find_module ( & module_parts) ;
183+ if result. is_some ( ) {
184+ return result;
185+ }
186+
187+ if self . fuzzy_search {
188+ return self . fuzzy_find_module ( & module_path, module_parts. last ( ) . unwrap ( ) ) ;
189+ }
190+
191+ None
192+ }
193+
194+ fn exact_find_module ( & self , module_parts : & Vec < & str > ) -> Option < & ModuleInfo > {
172195 let mut parent_node_id = self . module_root_id ;
173196 for part in module_parts {
174197 let parent_node = self . module_nodes . get ( & parent_node_id) ?;
175- let child_id = match parent_node. children . get ( part) {
198+ let child_id = match parent_node. children . get ( * part) {
176199 Some ( id) => * id,
177200 None => return None ,
178201 } ;
@@ -184,6 +207,23 @@ impl LuaModuleIndex {
184207 self . file_module_map . get ( file_id)
185208 }
186209
210+ fn fuzzy_find_module ( & self , module_path : & str , last_name : & str ) -> Option < & ModuleInfo > {
211+ let file_ids = self . module_name_to_file_ids . get ( last_name) ?;
212+ if file_ids. len ( ) == 1 {
213+ return self . file_module_map . get ( & file_ids[ 0 ] ) ;
214+ }
215+
216+ // find the first matched module
217+ for file_id in file_ids {
218+ let module_info = self . file_module_map . get ( file_id) ?;
219+ if module_info. full_module_name . ends_with ( module_path) {
220+ return Some ( module_info) ;
221+ }
222+ }
223+
224+ None
225+ }
226+
187227 /// Find a module node by module path.
188228 /// The module path is a string separated by dots.
189229 /// For example, "a.b.c" represents the module "c" in the module "b" in the module "a".
@@ -281,6 +321,8 @@ impl LuaModuleIndex {
281321 }
282322
283323 self . set_module_patterns ( patterns) ;
324+
325+ self . fuzzy_search = !config. strict . require_path ;
284326 }
285327}
286328
@@ -322,5 +364,23 @@ impl LuaIndex for LuaModuleIndex {
322364 break ;
323365 }
324366 }
367+
368+ if !self . module_name_to_file_ids . is_empty ( ) {
369+ let mut module_name = String :: new ( ) ;
370+ for ( name, file_ids) in & self . module_name_to_file_ids {
371+ if file_ids. contains ( & file_id) {
372+ module_name = name. clone ( ) ;
373+ break ;
374+ }
375+ }
376+
377+ if !module_name. is_empty ( ) {
378+ let file_ids = self . module_name_to_file_ids . get_mut ( & module_name) . unwrap ( ) ;
379+ file_ids. retain ( |id| * id != file_id) ;
380+ if file_ids. is_empty ( ) {
381+ self . module_name_to_file_ids . remove ( & module_name) ;
382+ }
383+ }
384+ }
325385 }
326386}
0 commit comments