Private/Filtering.ps1
|
# ShowTree\Private\Filtering.ps1 # Filtering <# .SYNOPSIS Returns a filtered subset of tree items using Hidden/System attributes and PowerShell-style Include/Exclude glob patterns while preserving original order. .DESCRIPTION Get-FilteredTreeItems applies all Show-Tree filtering rules to a collection of filesystem items and returns the resulting subset in stable, original order. Filtering supports: • Hidden and System attribute removal (-HideHidden, -HideSystem) • PowerShell-style glob patterns for -Include and -Exclude • Exact-match and glob-match precedence rules • Include selectively overriding Exclude, Hidden, and System • Exclude exact-match patterns taking precedence over globbed Include patterns The function evaluates each item against four independent removal sets: Hidden, System, ExcludedExact, and ExcludedGlob. It also computes two inclusion sets: IncludedExact and IncludedGlob. Final item selection follows these rules: 1. Exact Include always wins. 2. Exact Exclude always wins, even if the item matches a broader Include glob. 3. Glob Include resurrects items removed by Hidden, System, or glob Exclude. 4. Hidden and System remove items unless resurrected by Include. 5. Glob Exclude removes items unless resurrected by Include. 6. Items not affected by any rule are kept. This produces intuitive, PowerShell-like filtering behavior while maintaining the original enumeration order required for correct tree rendering. .PARAMETER Items The collection of file or directory objects to filter. The function preserves the original ordering of this list. #> function Get-FilteredTreeItems { param( [array]$Items, [string[]]$Include, [string[]]$Exclude, [switch]$HideHidden, [switch]$HideSystem ) if (-not $Items) { return @() } # # Capture original order # $orig = $Items # # Hidden/System sets # $hidden = $HideHidden ? ($orig | Where-Object { $_.Attributes -band [IO.FileAttributes]::Hidden }) : @() $system = $HideSystem ? ($orig | Where-Object { $_.Attributes -band [IO.FileAttributes]::System }) : @() # # Exclude sets (exact + glob) # $excludedExact = @() $excludedGlob = @() if ($Exclude) { foreach ($item in $orig) { $name = $item.Name if ($Exclude -contains $name) { $excludedExact += $item; continue } if ($Exclude | Where-Object { $name -like $_ }) { $excludedGlob += $item } } } # # Include sets (exact + glob) # $includedExact = @() $includedGlob = @() if ($Include) { foreach ($item in $orig) { $name = $item.Name if ($Include -contains $name) { $includedExact += $item; continue } if ($Include | Where-Object { $name -like $_ }) { $includedGlob += $item } } } # # Final filtering (stable order) # $final = foreach ($item in $orig) { $name = $item.Name $isHidden = $hidden -contains $item $isSystem = $system -contains $item $isExcludedExact = $excludedExact -contains $item $isExcludedGlob = $excludedGlob -contains $item $isIncludedExact = $includedExact -contains $item $isIncludedGlob = $includedGlob -contains $item # # Decision logic # if ($isIncludedExact) { $item; continue } # exact include wins if ($isExcludedExact) { continue } # exact exclude wins if ($isIncludedGlob) { $item; continue } # glob include resurrects if ($isHidden) { continue } # hidden removes unless included if ($isSystem) { continue } # system removes unless included if ($isExcludedGlob) { continue } # glob exclude removes unless included $item } return $final } |