summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormsabathier <115698101+msabathier@users.noreply.github.com>2024-11-25 11:25:30 +0100
committerGitHub <noreply@github.com>2024-11-25 19:25:30 +0900
commitbee80a730f945c05ac0167130b9204206371d570 (patch)
tree5b36d16a05f9a35159477987e1bfeb10b6df58a5 /src
parentac3e24c99c221ae2e4e0a8fd6d6d1e0078260ab4 (diff)
downloadfzf-bee80a730f945c05ac0167130b9204206371d570.tar.gz
Allow walking multiple root directories (#4109)
Co-authored-by: Martin Sabathier <martin.sabathier.ext@corys.fr> Co-authored-by: Junegunn Choi <junegunn.c@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/options.go36
-rw-r--r--src/reader.go12
2 files changed, 39 insertions, 9 deletions
diff --git a/src/options.go b/src/options.go
index c42acce3..9238ac69 100644
--- a/src/options.go
+++ b/src/options.go
@@ -145,7 +145,7 @@ Usage: fzf [options]
Directory traversal (Only used when $FZF_DEFAULT_COMMAND is not set)
--walker=OPTS [file][,dir][,follow][,hidden] (default: file,follow,hidden)
- --walker-root=DIR Root directory from which to start walker (default: .)
+ --walker-root=DIR [...] List of directories to walk (default: .)
--walker-skip=DIRS Comma-separated list of directory names to skip
(default: .git,node_modules)
@@ -490,7 +490,7 @@ type Options struct {
Unsafe bool
ClearOnExit bool
WalkerOpts walkerOpts
- WalkerRoot string
+ WalkerRoot []string
WalkerSkip []string
Version bool
Help bool
@@ -594,7 +594,7 @@ func defaultOptions() *Options {
Unsafe: false,
ClearOnExit: true,
WalkerOpts: walkerOpts{file: true, hidden: true, follow: true},
- WalkerRoot: ".",
+ WalkerRoot: []string{"."},
WalkerSkip: []string{".git", "node_modules"},
Help: false,
Version: false}
@@ -626,6 +626,28 @@ func optionalNextString(args []string, i *int) (bool, string) {
return false, ""
}
+func isDir(path string) bool {
+ stat, err := os.Stat(path)
+ return err == nil && stat.IsDir()
+}
+
+func nextDirs(args []string, i *int) ([]string, error) {
+ dirs := []string{}
+ for *i < len(args)-1 {
+ arg := args[*i+1]
+ if isDir(arg) {
+ dirs = append(dirs, arg)
+ *i++
+ } else {
+ break
+ }
+ }
+ if len(dirs) == 0 {
+ return nil, errors.New("no directory specified")
+ }
+ return dirs, nil
+}
+
func atoi(str string) (int, error) {
num, err := strconv.Atoi(str)
if err != nil {
@@ -2487,7 +2509,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
return err
}
case "--walker-root":
- if opts.WalkerRoot, err = nextString(allArgs, &i, "directory required"); err != nil {
+ if opts.WalkerRoot, err = nextDirs(allArgs, &i); err != nil {
return err
}
case "--walker-skip":
@@ -2685,7 +2707,11 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
return err
}
} else if match, value := optString(arg, "--walker-root="); match {
- opts.WalkerRoot = value
+ if !isDir(value) {
+ return errors.New("not a directory: " + value)
+ }
+ dirs, _ := nextDirs(allArgs, &i)
+ opts.WalkerRoot = append([]string{value}, dirs...)
} else if match, value := optString(arg, "--walker-skip="); match {
opts.WalkerSkip = filterNonEmpty(strings.Split(value, ","))
} else if match, value := optString(arg, "--hscroll-off="); match {
diff --git a/src/reader.go b/src/reader.go
index b2531c3a..80387bac 100644
--- a/src/reader.go
+++ b/src/reader.go
@@ -120,7 +120,7 @@ func (r *Reader) readChannel(inputChan chan string) bool {
}
// ReadSource reads data from the default command or from standard input
-func (r *Reader) ReadSource(inputChan chan string, root string, opts walkerOpts, ignores []string, initCmd string, initEnv []string, readyChan chan bool) {
+func (r *Reader) ReadSource(inputChan chan string, roots []string, opts walkerOpts, ignores []string, initCmd string, initEnv []string, readyChan chan bool) {
r.startEventPoller()
var success bool
signalReady := func() {
@@ -137,7 +137,7 @@ func (r *Reader) ReadSource(inputChan chan string, root string, opts walkerOpts,
cmd := os.Getenv("FZF_DEFAULT_COMMAND")
if len(cmd) == 0 {
signalReady()
- success = r.readFiles(root, opts, ignores)
+ success = r.readFiles(roots, opts, ignores)
} else {
success = r.readFromCommand(cmd, initEnv, signalReady)
}
@@ -265,7 +265,7 @@ func trimPath(path string) string {
return byteString(bytes)
}
-func (r *Reader) readFiles(root string, opts walkerOpts, ignores []string) bool {
+func (r *Reader) readFiles(roots []string, opts walkerOpts, ignores []string) bool {
conf := fastwalk.Config{
Follow: opts.follow,
// Use forward slashes when running a Windows binary under WSL or MSYS
@@ -301,7 +301,11 @@ func (r *Reader) readFiles(root string, opts walkerOpts, ignores []string) bool
}
return nil
}
- return fastwalk.Walk(&conf, root, fn) == nil
+ noerr := true
+ for _, root := range roots {
+ noerr = noerr && (fastwalk.Walk(&conf, root, fn) == nil)
+ }
+ return noerr
}
func (r *Reader) readFromCommand(command string, environ []string, signalReady func()) bool {