Skip to content

Instantly share code, notes, and snippets.

@bindreams
Last active March 26, 2025 12:22
Show Gist options
  • Save bindreams/3022fa6b957d57b66d658b245d9f5140 to your computer and use it in GitHub Desktop.
Save bindreams/3022fa6b957d57b66d658b245d9f5140 to your computer and use it in GitHub Desktop.
rwhere() {(
# Perform a recursive `where` (zsh only).
#
# Recursively resolve each alias and symbolic link until done, and do it for each potential match in PATH.
absolute-path() {(
# get absolute directory for an existing file without resolving symlinks
echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")"
)}
query="$1"
if [[ ! -v RWHERE_INDENT ]]; then
RWHERE_INDENT=""
fi
if [[ "$query" =~ "^/" ]]; then
# Handle absolute paths ========================================================================================
if link="$(readlink "$query")"; then
# path is a symlink
absolute_link="$link"
if [[ ! "$link" =~ "^/" ]]; then
absolute_link="$(absolute-path "$(dirname "$query")/$link")"
fi
echo "$RWHERE_INDENT$query is a link to $link"
RWHERE_INDENT="$RWHERE_INDENT " rwhere "$absolute_link"
elif resolved_path="$(realpath -q "$query")"; then
# path exists
echo "$RWHERE_INDENT$resolved_path found"
else
# path does not exist
echo "$RWHERE_INDENT$query not found"
fi
else
# Handle other commands ========================================================================================
whence -av "$query" | while read -r line ; do
if [[ "$line" =~ "^$query is an alias for (.+)$" ]]; then
echo "$RWHERE_INDENT$line"
arg0=$(python3 -c "import shlex; print(shlex.split(input())[0])" <<< "$match[1]")
if [[ "$query" != "$arg0" ]]; then
# only recurse if the alias was not to the same command with flags
RWHERE_INDENT="$RWHERE_INDENT " rwhere "$arg0"
fi
elif [[ "$line" =~ "$query is (/.+)" ]]; then
# When an absolute path is first reported by whence, it is now processing PATH, which we do better
# manually because we can find broken symlinks.
break
else
# Other boring cases: reserved words, etc.
echo "$RWHERE_INDENT$line"
fi
done
echo -n "$PATH" |\
tr : "\0" |\
xargs -I{} --null find {} -name "$query" 2>/dev/null |\
while read -r found_path
do
echo "$RWHERE_INDENT$query is $found_path"
RWHERE_INDENT="$RWHERE_INDENT " rwhere "$found_path"
done
fi
)}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment