mirror of
https://github.com/Llewellynvdm/fzf.git
synced 2024-12-22 10:58:59 +00:00
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>
This commit is contained in:
parent
ac3e24c99c
commit
bee80a730f
@ -1005,8 +1005,8 @@ Determines the behavior of the built-in directory walker that is used when
|
|||||||
.br
|
.br
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B "\-\-walker\-root=DIR"
|
.B "\-\-walker\-root=DIR [...]"
|
||||||
The root directory from which to start the built-in directory walker.
|
List of directory names to start the built-in directory walker.
|
||||||
The default value is the current working directory.
|
The default value is the current working directory.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
|
@ -145,7 +145,7 @@ Usage: fzf [options]
|
|||||||
|
|
||||||
Directory traversal (Only used when $FZF_DEFAULT_COMMAND is not set)
|
Directory traversal (Only used when $FZF_DEFAULT_COMMAND is not set)
|
||||||
--walker=OPTS [file][,dir][,follow][,hidden] (default: file,follow,hidden)
|
--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
|
--walker-skip=DIRS Comma-separated list of directory names to skip
|
||||||
(default: .git,node_modules)
|
(default: .git,node_modules)
|
||||||
|
|
||||||
@ -490,7 +490,7 @@ type Options struct {
|
|||||||
Unsafe bool
|
Unsafe bool
|
||||||
ClearOnExit bool
|
ClearOnExit bool
|
||||||
WalkerOpts walkerOpts
|
WalkerOpts walkerOpts
|
||||||
WalkerRoot string
|
WalkerRoot []string
|
||||||
WalkerSkip []string
|
WalkerSkip []string
|
||||||
Version bool
|
Version bool
|
||||||
Help bool
|
Help bool
|
||||||
@ -594,7 +594,7 @@ func defaultOptions() *Options {
|
|||||||
Unsafe: false,
|
Unsafe: false,
|
||||||
ClearOnExit: true,
|
ClearOnExit: true,
|
||||||
WalkerOpts: walkerOpts{file: true, hidden: true, follow: true},
|
WalkerOpts: walkerOpts{file: true, hidden: true, follow: true},
|
||||||
WalkerRoot: ".",
|
WalkerRoot: []string{"."},
|
||||||
WalkerSkip: []string{".git", "node_modules"},
|
WalkerSkip: []string{".git", "node_modules"},
|
||||||
Help: false,
|
Help: false,
|
||||||
Version: false}
|
Version: false}
|
||||||
@ -626,6 +626,28 @@ func optionalNextString(args []string, i *int) (bool, string) {
|
|||||||
return false, ""
|
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) {
|
func atoi(str string) (int, error) {
|
||||||
num, err := strconv.Atoi(str)
|
num, err := strconv.Atoi(str)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -2487,7 +2509,7 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case "--walker-root":
|
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
|
return err
|
||||||
}
|
}
|
||||||
case "--walker-skip":
|
case "--walker-skip":
|
||||||
@ -2685,7 +2707,11 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else if match, value := optString(arg, "--walker-root="); match {
|
} 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 {
|
} else if match, value := optString(arg, "--walker-skip="); match {
|
||||||
opts.WalkerSkip = filterNonEmpty(strings.Split(value, ","))
|
opts.WalkerSkip = filterNonEmpty(strings.Split(value, ","))
|
||||||
} else if match, value := optString(arg, "--hscroll-off="); match {
|
} else if match, value := optString(arg, "--hscroll-off="); match {
|
||||||
|
@ -120,7 +120,7 @@ func (r *Reader) readChannel(inputChan chan string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ReadSource reads data from the default command or from standard input
|
// 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()
|
r.startEventPoller()
|
||||||
var success bool
|
var success bool
|
||||||
signalReady := func() {
|
signalReady := func() {
|
||||||
@ -137,7 +137,7 @@ func (r *Reader) ReadSource(inputChan chan string, root string, opts walkerOpts,
|
|||||||
cmd := os.Getenv("FZF_DEFAULT_COMMAND")
|
cmd := os.Getenv("FZF_DEFAULT_COMMAND")
|
||||||
if len(cmd) == 0 {
|
if len(cmd) == 0 {
|
||||||
signalReady()
|
signalReady()
|
||||||
success = r.readFiles(root, opts, ignores)
|
success = r.readFiles(roots, opts, ignores)
|
||||||
} else {
|
} else {
|
||||||
success = r.readFromCommand(cmd, initEnv, signalReady)
|
success = r.readFromCommand(cmd, initEnv, signalReady)
|
||||||
}
|
}
|
||||||
@ -265,7 +265,7 @@ func trimPath(path string) string {
|
|||||||
return byteString(bytes)
|
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{
|
conf := fastwalk.Config{
|
||||||
Follow: opts.follow,
|
Follow: opts.follow,
|
||||||
// Use forward slashes when running a Windows binary under WSL or MSYS
|
// 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 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 {
|
func (r *Reader) readFromCommand(command string, environ []string, signalReady func()) bool {
|
||||||
|
Loading…
Reference in New Issue
Block a user