@@ -56,6 +56,12 @@ pub struct Config {
5656 #[ serde( default = "default_symbol_index_max_locations" ) ]
5757 pub symbol_index_max_locations : usize ,
5858
59+ #[ serde( default = "default_symbol_index_graph_hops" ) ]
60+ pub symbol_index_graph_hops : usize ,
61+
62+ #[ serde( default = "default_symbol_index_graph_max_files" ) ]
63+ pub symbol_index_graph_max_files : usize ,
64+
5965 #[ serde( default ) ]
6066 pub symbol_index_lsp_command : Option < String > ,
6167
@@ -83,6 +89,9 @@ pub struct Config {
8389
8490 #[ serde( default ) ]
8591 pub custom_context : Vec < CustomContextConfig > ,
92+
93+ #[ serde( default ) ]
94+ pub pattern_repositories : Vec < PatternRepositoryConfig > ,
8695}
8796
8897#[ derive( Debug , Clone , Serialize , Deserialize , Default ) ]
@@ -116,6 +125,23 @@ pub struct CustomContextConfig {
116125 pub files : Vec < String > ,
117126}
118127
128+ #[ derive( Debug , Clone , Serialize , Deserialize , Default ) ]
129+ pub struct PatternRepositoryConfig {
130+ pub source : String ,
131+
132+ #[ serde( default ) ]
133+ pub scope : Option < String > ,
134+
135+ #[ serde( default ) ]
136+ pub include_patterns : Vec < String > ,
137+
138+ #[ serde( default = "default_pattern_repo_max_files" ) ]
139+ pub max_files : usize ,
140+
141+ #[ serde( default = "default_pattern_repo_max_lines" ) ]
142+ pub max_lines : usize ,
143+ }
144+
119145#[ derive( Debug , Clone , Serialize , Deserialize , Default ) ]
120146pub struct PluginConfig {
121147 #[ serde( default = "default_true" ) ]
@@ -148,6 +174,8 @@ impl Default for Config {
148174 symbol_index_max_files : default_symbol_index_max_files ( ) ,
149175 symbol_index_max_bytes : default_symbol_index_max_bytes ( ) ,
150176 symbol_index_max_locations : default_symbol_index_max_locations ( ) ,
177+ symbol_index_graph_hops : default_symbol_index_graph_hops ( ) ,
178+ symbol_index_graph_max_files : default_symbol_index_graph_max_files ( ) ,
151179 symbol_index_lsp_command : None ,
152180 symbol_index_lsp_languages : default_symbol_index_lsp_languages ( ) ,
153181 feedback_path : default_feedback_path ( ) ,
@@ -159,6 +187,7 @@ impl Default for Config {
159187 exclude_patterns : Vec :: new ( ) ,
160188 paths : HashMap :: new ( ) ,
161189 custom_context : Vec :: new ( ) ,
190+ pattern_repositories : Vec :: new ( ) ,
162191 }
163192 }
164193}
@@ -226,6 +255,12 @@ impl Config {
226255 if self . symbol_index_max_locations == 0 {
227256 self . symbol_index_max_locations = default_symbol_index_max_locations ( ) ;
228257 }
258+ if self . symbol_index_graph_hops == 0 {
259+ self . symbol_index_graph_hops = default_symbol_index_graph_hops ( ) ;
260+ }
261+ if self . symbol_index_graph_max_files == 0 {
262+ self . symbol_index_graph_max_files = default_symbol_index_graph_max_files ( ) ;
263+ }
229264
230265 let provider = self . symbol_index_provider . trim ( ) . to_lowercase ( ) ;
231266 if provider. is_empty ( ) || !matches ! ( provider. as_str( ) , "regex" | "lsp" ) {
@@ -304,6 +339,40 @@ impl Config {
304339 normalized_custom_context. push ( entry) ;
305340 }
306341 self . custom_context = normalized_custom_context;
342+
343+ let mut normalized_pattern_repositories = Vec :: new ( ) ;
344+ for mut repo in std:: mem:: take ( & mut self . pattern_repositories ) {
345+ repo. source = repo. source . trim ( ) . to_string ( ) ;
346+ if repo. source . is_empty ( ) {
347+ continue ;
348+ }
349+ repo. scope = repo. scope . and_then ( |scope| {
350+ let trimmed = scope. trim ( ) . to_string ( ) ;
351+ if trimmed. is_empty ( ) {
352+ None
353+ } else {
354+ Some ( trimmed)
355+ }
356+ } ) ;
357+ repo. include_patterns = repo
358+ . include_patterns
359+ . into_iter ( )
360+ . map ( |pattern| pattern. trim ( ) . to_string ( ) )
361+ . filter ( |pattern| !pattern. is_empty ( ) )
362+ . collect ( ) ;
363+ if repo. include_patterns . is_empty ( ) {
364+ repo. include_patterns . push ( "**/*" . to_string ( ) ) ;
365+ }
366+ if repo. max_files == 0 {
367+ repo. max_files = default_pattern_repo_max_files ( ) ;
368+ }
369+ if repo. max_lines == 0 {
370+ repo. max_lines = default_pattern_repo_max_lines ( ) ;
371+ }
372+
373+ normalized_pattern_repositories. push ( repo) ;
374+ }
375+ self . pattern_repositories = normalized_pattern_repositories;
307376 }
308377
309378 pub fn get_path_config ( & self , file_path : & Path ) -> Option < & PathConfig > {
@@ -366,6 +435,17 @@ impl Config {
366435 self . min_confidence . max ( strictness_floor) . clamp ( 0.0 , 1.0 )
367436 }
368437
438+ pub fn matching_pattern_repositories ( & self , file_path : & Path ) -> Vec < & PatternRepositoryConfig > {
439+ let file_path_str = file_path. to_string_lossy ( ) ;
440+ self . pattern_repositories
441+ . iter ( )
442+ . filter ( |repo| match repo. scope . as_deref ( ) {
443+ Some ( scope) => self . path_matches ( & file_path_str, scope) ,
444+ None => true ,
445+ } )
446+ . collect ( )
447+ }
448+
369449 fn path_matches ( & self , path : & str , pattern : & str ) -> bool {
370450 // Simple glob matching
371451 if pattern. contains ( '*' ) {
@@ -470,6 +550,14 @@ fn default_symbol_index_max_locations() -> usize {
470550 5
471551}
472552
553+ fn default_symbol_index_graph_hops ( ) -> usize {
554+ 2
555+ }
556+
557+ fn default_symbol_index_graph_max_files ( ) -> usize {
558+ 12
559+ }
560+
473561fn default_symbol_index_provider ( ) -> String {
474562 "regex" . to_string ( )
475563}
@@ -484,6 +572,14 @@ fn default_feedback_path() -> PathBuf {
484572 PathBuf :: from ( ".diffscope.feedback.json" )
485573}
486574
575+ fn default_pattern_repo_max_files ( ) -> usize {
576+ 8
577+ }
578+
579+ fn default_pattern_repo_max_lines ( ) -> usize {
580+ 200
581+ }
582+
487583fn default_true ( ) -> bool {
488584 true
489585}
0 commit comments