Extend --walker-skip to support multi-component patterns

fzf --walker-skip 'foo/bar'

Close #4107
This commit is contained in:
Junegunn Choi 2024-11-26 17:26:16 +09:00
parent bee80a730f
commit 7d9548919e
No known key found for this signature in database
GPG Key ID: 254BC280FEF9C627

View File

@ -7,6 +7,7 @@ import (
"io/fs" "io/fs"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time" "time"
@ -272,6 +273,26 @@ func (r *Reader) readFiles(roots []string, opts walkerOpts, ignores []string) bo
ToSlash: fastwalk.DefaultToSlash(), ToSlash: fastwalk.DefaultToSlash(),
Sort: fastwalk.SortFilesFirst, Sort: fastwalk.SortFilesFirst,
} }
ignoresBase := []string{}
ignoresFull := []string{}
ignoresSuffix := []string{}
sep := string(os.PathSeparator)
for _, ignore := range ignores {
if strings.ContainsRune(ignore, os.PathSeparator) {
if strings.HasPrefix(ignore, sep) {
ignoresSuffix = append(ignoresSuffix, ignore)
} else {
// 'foo/bar' should match match
// * 'foo/bar'
// * 'baz/foo/bar'
// * but NOT 'bazfoo/bar'
ignoresFull = append(ignoresFull, ignore)
ignoresSuffix = append(ignoresSuffix, sep+ignore)
}
} else {
ignoresBase = append(ignoresBase, ignore)
}
}
fn := func(path string, de os.DirEntry, err error) error { fn := func(path string, de os.DirEntry, err error) error {
if err != nil { if err != nil {
return nil return nil
@ -284,11 +305,21 @@ func (r *Reader) readFiles(roots []string, opts walkerOpts, ignores []string) bo
if !opts.hidden && base[0] == '.' && base != ".." { if !opts.hidden && base[0] == '.' && base != ".." {
return filepath.SkipDir return filepath.SkipDir
} }
for _, ignore := range ignores { for _, ignore := range ignoresBase {
if ignore == base { if ignore == base {
return filepath.SkipDir return filepath.SkipDir
} }
} }
for _, ignore := range ignoresFull {
if ignore == path {
return filepath.SkipDir
}
}
for _, ignore := range ignoresSuffix {
if strings.HasSuffix(path, ignore) {
return filepath.SkipDir
}
}
} }
if ((opts.file && !isDir) || (opts.dir && isDir)) && r.pusher(stringBytes(path)) { if ((opts.file && !isDir) || (opts.dir && isDir)) && r.pusher(stringBytes(path)) {
atomic.StoreInt32(&r.event, int32(EvtReadNew)) atomic.StoreInt32(&r.event, int32(EvtReadNew))