Skip to content

Commit cab67cc

Browse files
committed
function scope all variables to reduce side effects
Without passing -f (--function), set commands in functions will clobber same-name shell variables that were already set. For example, if you do 'set commands_selected 1' and then execute _fzf_search_history, commands_selected will change value. I chose -f over -l or a combination of the two to emulate Python's variable scopes, in which all variables declared within a function are function scoped. This makes reasoning about variables easier and more intuitive.
1 parent 63c8f8e commit cab67cc

11 files changed

+37
-37
lines changed

functions/_fzf_preview_changed_file.fish

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ function _fzf_preview_changed_file --argument-names path_status --description "S
77
# remove quotes because they'll be interpreted literally by git diff
88
# no need to requote when referencing $path because fish does not perform word splitting
99
# https://fishshell.com/docs/current/fish_for_bash_users.html
10-
set -l path (string unescape (string sub --start 4 $path_status))
10+
set -f path (string unescape (string sub --start 4 $path_status))
1111
# first letter of short format shows index, second letter shows working tree
1212
# https://git-scm.com/docs/git-status/2.35.0#_short_format
13-
set -l index_status (string sub --length 1 $path_status)
14-
set -l working_tree_status (string sub --start 2 --length 1 $path_status)
13+
set -f index_status (string sub --length 1 $path_status)
14+
set -f working_tree_status (string sub --start 2 --length 1 $path_status)
1515

16-
set diff_opts --color=always
16+
set -f diff_opts --color=always
1717

1818
if test $index_status = '?'
1919
_fzf_report_diff_type Untracked
@@ -32,7 +32,7 @@ function _fzf_preview_changed_file --argument-names path_status --description "S
3232
# https://stackoverflow.com/questions/73954214
3333
if test $index_status = R
3434
# diff the post-rename path with the original path, otherwise the diff will show the entire file as being added
35-
set orig_and_new_path (string split --max 1 -- ' -> ' $path)
35+
set -f orig_and_new_path (string split --max 1 -- ' -> ' $path)
3636
git diff --staged $diff_opts -- $orig_and_new_path[1] $orig_and_new_path[2]
3737
# path currently has the form of "original -> current", so we need to correct it before it's used below
3838
set path $orig_and_new_path[2]

functions/_fzf_preview_file.fish

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
function _fzf_preview_file --description "Print a preview for the given file based on its file type."
33
# because there's no way to guarantee that _fzf_search_directory passes the path to _fzf_preview_file
44
# as one argument, we collect all the arguments into one single variable and treat that as the path
5-
set file_path $argv
5+
set -f file_path $argv
66

77
if test -L "$file_path" # symlink
88
# notify user and recurse on the target of the symlink, which can be any of these file types

functions/_fzf_report_diff_type.fish

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
# ╰────────╯
66
function _fzf_report_diff_type --argument-names diff_type --description "Print a distinct colored header meant to preface a git patch."
77
# number of "-" to draw is the length of the string to box + 2 for padding
8-
set repeat_count (math 2 + (string length $diff_type))
9-
set line (string repeat --count $repeat_count ─)
10-
set top_border ╭$line
11-
set btm_border ╰$line
8+
set -f repeat_count (math 2 + (string length $diff_type))
9+
set -f line (string repeat --count $repeat_count ─)
10+
set -f top_border ╭$line
11+
set -f btm_border ╰$line
1212

1313
set_color yellow
1414
echo $top_border

functions/_fzf_search_directory.fish

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,27 @@ function _fzf_search_directory --description "Search the current directory. Repl
22
# Directly use fd binary to avoid output buffering delay caused by a fd alias, if any.
33
# Debian-based distros install fd as fdfind and the fd package is something else, so
44
# check for fdfind first. Fall back to "fd" for a clear error message.
5-
set fd_cmd (command -v fdfind || command -v fd || echo "fd")
6-
set --append fd_cmd --color=always $fzf_fd_opts
5+
set -f fd_cmd (command -v fdfind || command -v fd || echo "fd")
6+
set -f --append fd_cmd --color=always $fzf_fd_opts
77

88
# $fzf_dir_opts is the deprecated version of $fzf_directory_opts
9-
set fzf_arguments --multi --ansi $fzf_dir_opts $fzf_directory_opts
10-
set token (commandline --current-token)
9+
set -f fzf_arguments --multi --ansi $fzf_dir_opts $fzf_directory_opts
10+
set -f token (commandline --current-token)
1111
# expand any variables or leading tilde (~) in the token
12-
set expanded_token (eval echo -- $token)
12+
set -f expanded_token (eval echo -- $token)
1313
# unescape token because it's already quoted so backslashes will mess up the path
14-
set unescaped_exp_token (string unescape -- $expanded_token)
14+
set -f unescaped_exp_token (string unescape -- $expanded_token)
1515

1616
# If the current token is a directory and has a trailing slash,
1717
# then use it as fd's base directory.
1818
if string match --quiet -- "*/" $unescaped_exp_token && test -d "$unescaped_exp_token"
1919
set --append fd_cmd --base-directory=$unescaped_exp_token
2020
# use the directory name as fzf's prompt to indicate the search is limited to that directory
2121
set --prepend fzf_arguments --prompt="Search Directory $unescaped_exp_token> " --preview="_fzf_preview_file $expanded_token{}"
22-
set file_paths_selected $unescaped_exp_token($fd_cmd 2>/dev/null | _fzf_wrapper $fzf_arguments)
22+
set -f file_paths_selected $unescaped_exp_token($fd_cmd 2>/dev/null | _fzf_wrapper $fzf_arguments)
2323
else
2424
set --prepend fzf_arguments --prompt="Search Directory> " --query="$unescaped_exp_token" --preview='_fzf_preview_file {}'
25-
set file_paths_selected ($fd_cmd 2>/dev/null | _fzf_wrapper $fzf_arguments)
25+
set -f file_paths_selected ($fd_cmd 2>/dev/null | _fzf_wrapper $fzf_arguments)
2626
end
2727

2828

functions/_fzf_search_git_log.fish

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ function _fzf_search_git_log --description "Search the output of git log and pre
44
else
55
if not set --query fzf_git_log_format
66
# %h gives you the abbreviated commit hash, which is useful for saving screen space, but we will have to expand it later below
7-
set fzf_git_log_format '%C(bold blue)%h%C(reset) - %C(cyan)%ad%C(reset) %C(yellow)%d%C(reset) %C(normal)%s%C(reset) %C(dim normal)[%an]%C(reset)'
7+
set -f fzf_git_log_format '%C(bold blue)%h%C(reset) - %C(cyan)%ad%C(reset) %C(yellow)%d%C(reset) %C(normal)%s%C(reset) %C(dim normal)[%an]%C(reset)'
88
end
9-
set selected_log_lines (
9+
set -f selected_log_lines (
1010
git log --no-show-signature --color=always --format=format:$fzf_git_log_format --date=short | \
1111
_fzf_wrapper --ansi \
1212
--multi \
@@ -18,9 +18,9 @@ function _fzf_search_git_log --description "Search the output of git log and pre
1818
)
1919
if test $status -eq 0
2020
for line in $selected_log_lines
21-
set abbreviated_commit_hash (string split --field 1 " " $line)
22-
set full_commit_hash (git rev-parse $abbreviated_commit_hash)
23-
set --append commit_hashes $full_commit_hash
21+
set -f abbreviated_commit_hash (string split --field 1 " " $line)
22+
set -f full_commit_hash (git rev-parse $abbreviated_commit_hash)
23+
set -f --append commit_hashes $full_commit_hash
2424
end
2525
commandline --current-token --replace (string join ' ' $commit_hashes)
2626
end

functions/_fzf_search_git_status.fish

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ function _fzf_search_git_status --description "Search the output of git status.
22
if not git rev-parse --git-dir >/dev/null 2>&1
33
echo '_fzf_search_git_status: Not in a git repository.' >&2
44
else
5-
set selected_paths (
5+
set -f selected_paths (
66
# Pass configuration color.status=always to force status to use colors even though output is sent to a pipe
77
git -c color.status=always status --short |
88
_fzf_wrapper --ansi \
@@ -16,7 +16,7 @@ function _fzf_search_git_status --description "Search the output of git status.
1616
if test $status -eq 0
1717
# git status --short automatically escapes the paths of most files for us so not going to bother trying to handle
1818
# the few edges cases of weird file names that should be extremely rare (e.g. "this;needs;escaping")
19-
set cleaned_paths
19+
set -f cleaned_paths
2020

2121
for path in $selected_paths
2222
if test (string sub --length 1 $path) = R

functions/_fzf_search_history.fish

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ function _fzf_search_history --description "Search command history. Replace the
66
end
77

88
# Delinate commands throughout pipeline using null rather than newlines because commands can be multi-line
9-
set commands_selected (
9+
set -f commands_selected (
1010
# Reference https://devhints.io/strftime to understand strftime format symbols
1111
builtin history --null --show-time="%m-%d %H:%M:%S │ " |
1212
_fzf_wrapper --read0 \

functions/_fzf_search_processes.fish

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
function _fzf_search_processes --description "Search all running processes. Replace the current token with the pid of the selected process."
22
# use all caps to be consistent with ps default format
33
# snake_case because ps doesn't seem to allow spaces in the field names
4-
set ps_preview_fmt (string join ',' 'pid' 'ppid=PARENT' 'user' '%cpu' 'rss=RSS_IN_KB' 'start=START_TIME' 'command')
5-
set processes_selected (
4+
set -f ps_preview_fmt (string join ',' 'pid' 'ppid=PARENT' 'user' '%cpu' 'rss=RSS_IN_KB' 'start=START_TIME' 'command')
5+
set -f processes_selected (
66
ps -A -opid,command | \
77
_fzf_wrapper --multi \
88
--prompt="Search Processes> " \
@@ -18,7 +18,7 @@ function _fzf_search_processes --description "Search all running processes. Repl
1818

1919
if test $status -eq 0
2020
for process in $processes_selected
21-
set --append pids_selected (string split --no-empty --field=1 -- " " $process)
21+
set -f --append pids_selected (string split --no-empty --field=1 -- " " $process)
2222
end
2323

2424
# string join to replace the newlines outputted by string split with spaces

functions/_fzf_search_variables.fish

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ function _fzf_search_variables --argument-names set_show_output set_names_output
1313
# 1. it's not included in $set_names_output
1414
# 2. it tends to be a very large value => increases computation time
1515
# 3._fzf_search_history is a much better way to examine history anyway
16-
set all_variable_names (string match --invert history <$set_names_output)
16+
set -f all_variable_names (string match --invert history <$set_names_output)
1717

18-
set current_token (commandline --current-token)
18+
set -f current_token (commandline --current-token)
1919
# Use the current token to pre-populate fzf's query. If the current token begins
2020
# with a $, remove it from the query so that it will better match the variable names
21-
set cleaned_curr_token (string replace -- '$' '' $current_token)
21+
set -f cleaned_curr_token (string replace -- '$' '' $current_token)
2222

23-
set variable_names_selected (
23+
set -f variable_names_selected (
2424
printf '%s\n' $all_variable_names |
2525
_fzf_wrapper --preview "_fzf_extract_var_info {} $set_show_output" \
2626
--prompt="Search Variables> " \

functions/_fzf_wrapper.fish

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
function _fzf_wrapper --description "Prepares some environment variables before executing fzf."
22
# Make sure fzf uses fish to execute preview commands, some of which
33
# are autoloaded fish functions so don't exist in other shells.
4-
# Use --local so that it doesn't clobber SHELL outside of this function.
5-
set --local --export SHELL (command --search fish)
4+
# Use --function so that it doesn't clobber SHELL outside this function.
5+
set -f --export SHELL (command --search fish)
66

77
# If FZF_DEFAULT_OPTS is not set, then set some sane defaults.
88
# See https://github.com/junegunn/fzf#environment-variables

functions/fzf_configure_bindings.fish

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ function fzf_configure_bindings --description "Installs the default key bindings
44
# no need to install bindings if not in interactive mode or running tests
55
status is-interactive || test "$CI" = true; or return
66

7-
set options_spec h/help 'directory=?' 'git_log=?' 'git_status=?' 'history=?' 'processes=?' 'variables=?'
7+
set -f options_spec h/help 'directory=?' 'git_log=?' 'git_status=?' 'history=?' 'processes=?' 'variables=?'
88
argparse --max-args=0 --ignore-unknown $options_spec -- $argv 2>/dev/null
99
if test $status -ne 0
1010
echo "Invalid option or a positional argument was provided." >&2
@@ -16,7 +16,7 @@ function fzf_configure_bindings --description "Installs the default key bindings
1616
else
1717
# Initialize with default key sequences and then override or disable them based on flags
1818
# index 1 = directory, 2 = git_log, 3 = git_status, 4 = history, 5 = processes, 6 = variables
19-
set key_sequences \e\cf \e\cl \e\cs \cr \e\cp \cv # \c = control, \e = escape
19+
set -f key_sequences \e\cf \e\cl \e\cs \cr \e\cp \cv # \c = control, \e = escape
2020
set --query _flag_directory && set key_sequences[1] "$_flag_directory"
2121
set --query _flag_git_log && set key_sequences[2] "$_flag_git_log"
2222
set --query _flag_git_status && set key_sequences[3] "$_flag_git_status"

0 commit comments

Comments
 (0)