@@ -19,10 +19,39 @@ type Selection struct {
1919
2020func NewSelection (lines []string ) * Selection {
2121 return & Selection {
22- lines : lines ,
22+ lines : removeNestedSelections ( lines ) ,
2323 }
2424}
2525
26+ func removeNestedSelections (lines []string ) []string {
27+ slices .Sort (lines )
28+
29+ result := make ([]string , 0 )
30+
31+ // FIXME: this is O(n^2).
32+ for _ , line := range lines {
33+ foundIndex := slices .IndexFunc (lines , func (otherLine string ) bool {
34+ return otherLine != line && strings .HasPrefix (line , otherLine )
35+ })
36+
37+ // foundIndex, found := slices.BinarySearchFunc(lines, func(otherLine string) int {
38+ // if otherLine != line && strings.HasPrefix(otherLine, line) {
39+ // return 0
40+ // }
41+ // return strings.Compare(otherLine, line)
42+ // })
43+
44+ if foundIndex >= 0 {
45+ // Some other line has this line as a prefix; skip it
46+ slog .Warn ("selection contains a path that is also selected by a parent; removing" , "prefix" , lines [foundIndex ], "path" , line )
47+ continue
48+ }
49+
50+ result = append (result , line )
51+ }
52+ return result
53+ }
54+
2655// Returns whether the provided set of ignore lines are valid for 'selective' mode
2756func (sel * Selection ) isSelectiveIgnore () bool {
2857 if len (sel .lines ) == 0 {
@@ -46,7 +75,7 @@ func (sel *Selection) isSelectiveIgnore() bool {
4675}
4776
4877func (sel * Selection ) Lines () []string {
49- return sel .lines
78+ return removeNestedSelections ( sel .lines )
5079}
5180
5281func (sel * Selection ) SetExplicitlySelected (paths map [string ]bool ) error {
@@ -55,12 +84,20 @@ func (sel *Selection) SetExplicitlySelected(paths map[string]bool) error {
5584 slog .Info ("Edit ignore line" , "selected" , selected , "line" , line )
5685
5786 // Is this entry currently selected explicitly?
58- currentlySelected := slices .Contains (sel .lines , line )
59- if currentlySelected == selected {
87+ currentlySelectedExplicitly := slices .Contains (sel .lines , line )
88+ if currentlySelectedExplicitly == selected {
6089 // not changing selecting status for path, it is the status quo
6190 continue
6291 }
6392
93+ // Is this entry currently selected implicitly? (i.e. due to a parent path being selected)
94+ currentlySelectedImplicitly := slices .ContainsFunc (sel .lines , func (existingLine string ) bool {
95+ return existingLine != line && strings .HasPrefix (line , existingLine )
96+ })
97+ if currentlySelectedImplicitly {
98+ return errors .New ("cannot change selection: the path is already implicitly selected" )
99+ }
100+
64101 // To deselect, remove the relevant ignore line
65102 countBefore := len (sel .lines )
66103 if ! selected {
0 commit comments