@@ -37,15 +37,23 @@ pub struct SelectionEngine {
3737
3838 /// Cache for performance
3939 cache : HashMap < PathBuf , bool > ,
40+
41+ /// Default behavior when no patterns or user actions match
42+ deselected_by_default : bool ,
4043}
4144
4245impl SelectionEngine {
4346 /// Create a new SelectionEngine with base patterns
44- pub fn new ( include_patterns : Vec < String > , exclude_patterns : Vec < String > ) -> Self {
47+ pub fn new (
48+ include_patterns : Vec < String > ,
49+ exclude_patterns : Vec < String > ,
50+ deselected_by_default : bool ,
51+ ) -> Self {
4552 Self {
4653 filter_engine : FilterEngine :: new ( & include_patterns, & exclude_patterns) ,
4754 user_actions : Vec :: new ( ) ,
4855 cache : HashMap :: new ( ) ,
56+ deselected_by_default,
4957 }
5058 }
5159
@@ -74,9 +82,12 @@ impl SelectionEngine {
7482 // If there are include patterns, use them
7583 self . filter_engine . matches_patterns ( path)
7684 } else {
77- // No include patterns: default behavior is to include all files
78- // (unless excluded by exclude patterns)
79- !self . filter_engine . is_excluded ( path)
85+ // No include patterns: default behavior depends on deselected_by_default
86+ if self . deselected_by_default {
87+ false
88+ } else {
89+ !self . filter_engine . is_excluded ( path)
90+ }
8091 }
8192 }
8293
@@ -241,6 +252,12 @@ impl SelectionEngine {
241252 pub fn filter_engine ( & self ) -> & FilterEngine {
242253 & self . filter_engine
243254 }
255+
256+ /// Set whether the engine should default to deselected
257+ pub fn set_deselected_by_default ( & mut self , value : bool ) {
258+ self . deselected_by_default = value;
259+ self . cache . clear ( ) ;
260+ }
244261}
245262
246263impl std:: fmt:: Debug for SelectionEngine {
@@ -249,6 +266,7 @@ impl std::fmt::Debug for SelectionEngine {
249266 . field ( "filter_engine" , & self . filter_engine )
250267 . field ( "user_actions" , & self . user_actions )
251268 . field ( "cache_size" , & self . cache . len ( ) )
269+ . field ( "deselected_by_default" , & self . deselected_by_default )
252270 . finish ( )
253271 }
254272}
@@ -259,7 +277,7 @@ mod tests {
259277
260278 #[ test]
261279 fn test_specificity_calculation ( ) {
262- let engine = SelectionEngine :: new ( vec ! [ ] , vec ! [ ] ) ;
280+ let engine = SelectionEngine :: new ( vec ! [ ] , vec ! [ ] , false ) ;
263281
264282 assert_eq ! ( engine. calculate_specificity( Path :: new( "file.rs" ) ) , 1 ) ;
265283 assert_eq ! ( engine. calculate_specificity( Path :: new( "src/main.rs" ) ) , 2 ) ;
@@ -271,7 +289,7 @@ mod tests {
271289
272290 #[ test]
273291 fn test_precedence_rules ( ) {
274- let mut engine = SelectionEngine :: new ( vec ! [ ] , vec ! [ ] ) ;
292+ let mut engine = SelectionEngine :: new ( vec ! [ ] , vec ! [ ] , false ) ;
275293
276294 // Add less specific action first
277295 engine. exclude_file ( PathBuf :: from ( "src" ) ) ;
@@ -286,7 +304,7 @@ mod tests {
286304
287305 #[ test]
288306 fn test_recent_wins_over_old ( ) {
289- let mut engine = SelectionEngine :: new ( vec ! [ ] , vec ! [ ] ) ;
307+ let mut engine = SelectionEngine :: new ( vec ! [ ] , vec ! [ ] , false ) ;
290308
291309 // First action
292310 engine. exclude_file ( PathBuf :: from ( "main.rs" ) ) ;
@@ -296,4 +314,18 @@ mod tests {
296314 engine. include_file ( PathBuf :: from ( "main.rs" ) ) ;
297315 assert ! ( engine. is_selected( Path :: new( "main.rs" ) ) ) ;
298316 }
317+
318+ #[ test]
319+ fn test_deselected_by_default ( ) {
320+ let mut engine = SelectionEngine :: new ( vec ! [ ] , vec ! [ ] , true ) ;
321+
322+ // By default everything is deselected
323+ assert ! ( !engine. is_selected( Path :: new( "main.rs" ) ) ) ;
324+ assert ! ( !engine. is_selected( Path :: new( "src/lib.rs" ) ) ) ;
325+
326+ // User action should still work
327+ engine. include_file ( PathBuf :: from ( "main.rs" ) ) ;
328+ assert ! ( engine. is_selected( Path :: new( "main.rs" ) ) ) ;
329+ assert ! ( !engine. is_selected( Path :: new( "src/lib.rs" ) ) ) ;
330+ }
299331}
0 commit comments