summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJunegunn Choi <junegunn.c@gmail.com>2024-02-29 09:49:33 +0900
committerGitHub <noreply@github.com>2024-02-29 09:49:33 +0900
commit1833670fb91dfa17047af320ce7f015e0d500ba6 (patch)
treec202dd6107c1139e9082dc7852014a780fa60efa
parent3dd42f5aa2d7fc6f508f2b21408730a8678c0a19 (diff)
Add $FZF_DEFAULT_OPTS_FILE (#3618)
For those who prefer to manage default options in a file. If the file is not found, fzf will exit with an error. We're not setting a default value for it because: 1. it's hard to find a default value that can be universally agreed upon 2. to avoid fzf having to check for the existence of the file even when it's not used
-rw-r--r--CHANGELOG.md6
-rw-r--r--README.md4
-rw-r--r--man/man1/fzf.19
-rw-r--r--src/options.go37
-rwxr-xr-xtest/test_go.rb1
5 files changed, 50 insertions, 7 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 19594f4f..f2d9354c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,12 @@ CHANGELOG
- You would wonder why fzf implements directory traversal anyway when it's a filter program following the Unix philosophy.
But fzf has had [the traversal code for years][walker] to tackle the performance problem on Windows. And I decided to use the same approach on different platforms as well for the benefits listed above.
- Built-in traversal is now done using the excellent [charlievieth/fastwalk][fastwalk] library, which easily outperforms its competitors and supports safely following symlinks.
+- Added `$FZF_DEFAULT_OPTS_FILE` to allow managing default options in a file
+ - See [#3618](https://github.com/junegunn/fzf/pull/3618)
+ - Option precedence from lower to higher
+ 1. Options read from `$FZF_DEFAULT_OPTS_FILE`
+ 1. Options from `$FZF_DEFAULT_OPTS`
+ 1. Options from command-line arguments
[find]: https://github.com/junegunn/fzf/blob/0.46.1/src/constants.go#L60-L64
[walker]: https://github.com/junegunn/fzf/pull/1847
diff --git a/README.md b/README.md
index 4c9b01fd..e0b367b6 100644
--- a/README.md
+++ b/README.md
@@ -329,6 +329,10 @@ or `py`.
- `FZF_DEFAULT_OPTS`
- Default options
- e.g. `export FZF_DEFAULT_OPTS="--layout=reverse --inline-info"`
+- `FZF_DEFAULT_OPTS_FILE`
+ - If you prefer to manage default options in a file, set this variable to
+ point to the location of the file
+ - e.g. `export FZF_DEFAULT_OPTS_FILE=~/.fzfrc`
### Options
diff --git a/man/man1/fzf.1 b/man/man1/fzf.1
index c10f334e..76bfa648 100644
--- a/man/man1/fzf.1
+++ b/man/man1/fzf.1
@@ -865,7 +865,14 @@ with \fB$SHELL -c\fR if \fBSHELL\fR is set, otherwise with \fBsh -c\fR, so in
this case make sure that the command is POSIX-compliant.
.TP
.B FZF_DEFAULT_OPTS
-Default options. e.g. \fBexport FZF_DEFAULT_OPTS="--extended --cycle"\fR
+Default options.
+.br
+e.g. \fBexport FZF_DEFAULT_OPTS="--layout=reverse --border --cycle"\fR
+.TP
+.B FZF_DEFAULT_OPTS_FILE
+The location of the file that contains the default options.
+.br
+e.g. \fBexport FZF_DEFAULT_OPTS_FILE=~/.fzfrc\fR
.TP
.B FZF_API_KEY
Can be used to require an API key when using \fB--listen\fR option. If not set,
diff --git a/src/options.go b/src/options.go
index dcb70dcb..09787a44 100644
--- a/src/options.go
+++ b/src/options.go
@@ -126,8 +126,8 @@ const usage = `usage: fzf [options]
Environment variables
FZF_DEFAULT_COMMAND Default command to use when input is tty
- FZF_DEFAULT_OPTS Default options
- (e.g. '--layout=reverse --inline-info')
+ FZF_DEFAULT_OPTS Default options (e.g. '--layout=reverse --info=inline')
+ FZF_DEFAULT_OPTS_FILE Location of the file to read default options from
FZF_API_KEY X-API-Key header for HTTP server (--listen)
`
@@ -421,8 +421,10 @@ func help(code int) {
os.Exit(code)
}
+var errorContext = ""
+
func errorExit(msg string) {
- os.Stderr.WriteString(msg + "\n")
+ os.Stderr.WriteString(errorContext + msg + "\n")
os.Exit(exitError)
}
@@ -2167,13 +2169,36 @@ func ParseOptions() *Options {
}
}
- // Options from Env var
- words, _ := shellwords.Parse(os.Getenv("FZF_DEFAULT_OPTS"))
+ // 1. Options from $FZF_DEFAULT_OPTS_FILE
+ if path := os.Getenv("FZF_DEFAULT_OPTS_FILE"); path != "" {
+ bytes, err := os.ReadFile(path)
+ if err != nil {
+ errorContext = "$FZF_DEFAULT_OPTS_FILE: "
+ errorExit(err.Error())
+ }
+
+ words, parseErr := shellwords.Parse(string(bytes))
+ if parseErr != nil {
+ errorContext = path + ": "
+ errorExit(parseErr.Error())
+ }
+ if len(words) > 0 {
+ parseOptions(opts, words)
+ }
+ }
+
+ // 2. Options from $FZF_DEFAULT_OPTS string
+ words, parseErr := shellwords.Parse(os.Getenv("FZF_DEFAULT_OPTS"))
+ errorContext = "$FZF_DEFAULT_OPTS: "
+ if parseErr != nil {
+ errorExit(parseErr.Error())
+ }
if len(words) > 0 {
parseOptions(opts, words)
}
- // Options from command-line arguments
+ // 3. Options from command-line arguments
+ errorContext = ""
parseOptions(opts, os.Args[1:])
postProcessOptions(opts)
diff --git a/test/test_go.rb b/test/test_go.rb
index ecc111db..599d5442 100755
--- a/test/test_go.rb
+++ b/test/test_go.rb
@@ -2582,6 +2582,7 @@ class TestGoFZF < TestBase
def test_change_preview_window_rotate
tmux.send_keys "seq 100 | #{FZF} --preview-window left,border-none --preview 'echo hello' --bind '" \
"a:change-preview-window(right|down|up|hidden|)'", :Enter
+ tmux.until { |lines| assert(lines.any? { _1.include?('100/100') }) }
3.times do
tmux.until { |lines| lines[0].start_with?('hello') }
tmux.send_keys 'a'