diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core.go | 4 | ||||
-rw-r--r-- | src/options.go | 65 | ||||
-rw-r--r-- | src/reader.go | 24 |
3 files changed, 83 insertions, 10 deletions
diff --git a/src/core.go b/src/core.go index 56a2198e..3abda89c 100644 --- a/src/core.go +++ b/src/core.go @@ -117,7 +117,7 @@ func Run(opts *Options, version string, revision string) { reader = NewReader(func(data []byte) bool { return chunkList.Push(data) }, eventBox, opts.ReadZero, opts.Filter == nil) - go reader.ReadSource() + go reader.ReadSource(opts.WalkerRoot, opts.WalkerOpts, opts.WalkerSkip) } // Matcher @@ -165,7 +165,7 @@ func Run(opts *Options, version string, revision string) { } return false }, eventBox, opts.ReadZero, false) - reader.ReadSource() + reader.ReadSource(opts.WalkerRoot, opts.WalkerOpts, opts.WalkerSkip) } else { eventBox.Unwatch(EvtReadNew) eventBox.WaitFor(EvtReadFin) diff --git a/src/options.go b/src/options.go index 84e1c888..fdad058d 100644 --- a/src/options.go +++ b/src/options.go @@ -124,6 +124,12 @@ const usage = `usage: fzf [options] (To allow remote process execution, use --listen-unsafe) --version Display version information and exit + 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-skip=DIRS Comma-separated list of directory names to skip + (default: .git,node_modules) + Environment variables FZF_DEFAULT_COMMAND Default command to use when input is tty FZF_DEFAULT_OPTS Default options (e.g. '--layout=reverse --info=inline') @@ -274,6 +280,13 @@ func firstLine(s string) string { return strings.SplitN(s, "\n", 2)[0] } +type walkerOpts struct { + file bool + dir bool + hidden bool + follow bool +} + // Options stores the values of command-line options type Options struct { Fuzzy bool @@ -342,9 +355,22 @@ type Options struct { ListenAddr *listenAddress Unsafe bool ClearOnExit bool + WalkerOpts walkerOpts + WalkerRoot string + WalkerSkip []string Version bool } +func filterNonEmpty(input []string) []string { + output := make([]string, 0, len(input)) + for _, str := range input { + if len(str) > 0 { + output = append(output, str) + } + } + return output +} + func defaultPreviewOpts(command string) previewOpts { return previewOpts{command, posRight, sizeSpec{50, true}, "", false, false, false, false, tui.DefaultBorderShape, 0, 0, nil} } @@ -413,6 +439,9 @@ func defaultOptions() *Options { PreviewLabel: labelOpts{}, Unsafe: false, ClearOnExit: true, + WalkerOpts: walkerOpts{file: true, hidden: true, follow: true}, + WalkerRoot: ".", + WalkerSkip: []string{".git", "node_modules"}, Version: false} } @@ -966,6 +995,30 @@ func parseTheme(defaultTheme *tui.ColorTheme, str string) *tui.ColorTheme { return theme } +func parseWalkerOpts(str string) walkerOpts { + opts := walkerOpts{} + for _, str := range strings.Split(strings.ToLower(str), ",") { + switch str { + case "file": + opts.file = true + case "dir": + opts.dir = true + case "hidden": + opts.hidden = true + case "follow": + opts.follow = true + case "": + // Ignored + default: + errorExit("invalid walker option: " + str) + } + } + if !opts.file && !opts.dir { + errorExit("at least one of 'file' or 'dir' should be specified") + } + return opts +} + var ( executeRegexp *regexp.Regexp splitRegexp *regexp.Regexp @@ -1880,6 +1933,12 @@ func parseOptions(opts *Options, allArgs []string) { opts.ClearOnExit = true case "--no-clear": opts.ClearOnExit = false + case "--walker": + opts.WalkerOpts = parseWalkerOpts(nextString(allArgs, &i, "walker options required [file][,dir][,follow][,hidden]")) + case "--walker-root": + opts.WalkerRoot = nextString(allArgs, &i, "directory required") + case "--walker-skip": + opts.WalkerSkip = filterNonEmpty(strings.Split(nextString(allArgs, &i, "directory names to ignore required"), ",")) case "--version": opts.Version = true case "--": @@ -1977,6 +2036,12 @@ func parseOptions(opts *Options, allArgs []string) { } opts.ListenAddr = &addr opts.Unsafe = true + } else if match, value := optString(arg, "--walker="); match { + opts.WalkerOpts = parseWalkerOpts(value) + } else if match, value := optString(arg, "--walker-root="); match { + opts.WalkerRoot = value + } else if match, value := optString(arg, "--walker-skip="); match { + opts.WalkerSkip = filterNonEmpty(strings.Split(value, ",")) } else if match, value := optString(arg, "--hscroll-off="); match { opts.HscrollOff = atoi(value) } else if match, value := optString(arg, "--scroll-off="); match { diff --git a/src/reader.go b/src/reader.go index fb45c7b9..47102ec1 100644 --- a/src/reader.go +++ b/src/reader.go @@ -93,13 +93,13 @@ func (r *Reader) restart(command string, environ []string) { } // ReadSource reads data from the default command or from standard input -func (r *Reader) ReadSource() { +func (r *Reader) ReadSource(root string, opts walkerOpts, ignores []string) { r.startEventPoller() var success bool if util.IsTty() { cmd := os.Getenv("FZF_DEFAULT_COMMAND") if len(cmd) == 0 { - success = r.readFiles() + success = r.readFiles(root, opts, ignores) } else { // We can't export FZF_* environment variables to the default command success = r.readFromCommand(cmd, nil) @@ -145,9 +145,9 @@ func (r *Reader) readFromStdin() bool { return true } -func (r *Reader) readFiles() bool { +func (r *Reader) readFiles(root string, opts walkerOpts, ignores []string) bool { r.killed = false - conf := fastwalk.Config{Follow: true} + conf := fastwalk.Config{Follow: opts.follow} fn := func(path string, de os.DirEntry, err error) error { if err != nil { return nil @@ -155,10 +155,18 @@ func (r *Reader) readFiles() bool { path = filepath.Clean(path) if path != "." { isDir := de.IsDir() - if isDir && filepath.Base(path)[0] == '.' { - return filepath.SkipDir + if isDir { + base := filepath.Base(path) + if !opts.hidden && base[0] == '.' { + return filepath.SkipDir + } + for _, ignore := range ignores { + if ignore == base { + return filepath.SkipDir + } + } } - if !isDir && r.pusher([]byte(path)) { + if ((opts.file && !isDir) || (opts.dir && isDir)) && r.pusher([]byte(path)) { atomic.StoreInt32(&r.event, int32(EvtReadNew)) } } @@ -169,7 +177,7 @@ func (r *Reader) readFiles() bool { } return nil } - return fastwalk.Walk(&conf, ".", fn) == nil + return fastwalk.Walk(&conf, root, fn) == nil } func (r *Reader) readFromCommand(command string, environ []string) bool { |