Make script calling fzf
(or any other command) exit when you exit early with Ctrl + C
1. Simple alias
This works:
# command
files_list=$(fzf -m) && vim -p $files_list
# alias
alias fz='$(fzf -m) && vim -p $files_list'
Explanation:
When fzf
exits normally it returns error code 0
(note: you can read the return code after it exits by running echo $?
). When fzf
is killed by Ctrl + C, however, it returns error code 130
. The &&
part means "only do the part on the right if the part on the left is zero"--meaning that the command on the left completed successfully. So, when you hit Ctrl + C while fzf
is running, it returns error code 130
, and the part on the right will never execute.
2. More-robust function
If you need to do anything more-complicated, however, use a function (in your ~/.bashrc
or ~/.bash_aliases
file still if you like) instead of an alias. Here is a more-robust example of the alias above, in function form. The way I've written the alias above, I expect it to fail if you have filenames with whitespace or strange characters in them. However, the below function should work even in those cases I think:
fz() {
files_list="$(fzf -m)"
return_code="$?"
if [ "$return_code" -ne 0 ]; then
echo "Nothing to do; fzf return_code = $return_code"
return "$return_code"
fi
echo "FILES SELECTED:"
echo "$files_list"
# Convert the above list of newline-separated file names into an array
# - See: https://stackoverflow.com/a/24628676/4561887
SAVEIFS=$IFS # Save current IFS (Internal Field Separator)
IFS=$'\n' # Change IFS to newline char
files_array=($files_list) # split this newline-separated string into an array
IFS=$SAVEIFS # Restore original IFS
# Call vim with each member of the array as an argument
vim -p "${files_array[@]}"
}
Note: if you're not familiar with the [
function (yes, that's a function name!), run man [
or man test
for more information. The [
function is also called test
. That's why the arguments after that function name require spaces between them--they are arguments to a function! The ]
symbol is simply the required closing argument to the [
(test
) function.
References:
- My array_practice.sh bash script from my eRCaGuy_hello_world repo. This is where I learned and documented a lot of this stuff.
- How to pass an array of arguments to a command: How can I create and use a backup copy of all input args ("$@") in bash?
- How to parse a newline-separated string into an array of elements: Convert multiline string to array
- Use
return
to exit a bash function early: How to exit a function in bash