Skip to content

Instantly share code, notes, and snippets.

@sigboe
Last active November 6, 2023 17:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sigboe/4a9d4f1d5d64019770780a5c876988ad to your computer and use it in GitHub Desktop.
Save sigboe/4a9d4f1d5d64019770780a5c876988ad to your computer and use it in GitHub Desktop.
[[ZSH & Bash (untested) ]] Favorites shell functions to manage symlinks in .local/share/favorites. These functions allow you to easily add and remove symlinks to your favorite directories. The cd command is wrapped to follow symlinks when navigating favorites. Note that it's shell-agnostic at least for zsh and bash, but it hasn't been tested in…
# Favorites
favorites="${HOME}/.local/share/favorites"
if [[ -n "${ZSH_VERSION}" ]]; then
cdpath=("${cdpath[@]}" "${favorites}")
elif [[ -n "${BASH_VERSION}" ]]; then
CDPATH=("${CDPATH[@]}" "${favorites}")
fi
favorite() {
local current_dir="${PWD}"
local favorites_dir="${favorites}"
local basename="$(basename "${current_dir}")"
if [[ ! -d "${favorites_dir}" ]]; then
echo "${favorites_dir} doesn't exist"
elif [ -e "${favorites_dir}/${basename}" ]; then
echo "Favorite already exists: ${basename}"
else
if ln -s "${current_dir}" "${favorites_dir}/"; then
echo "Favorite created: ${basename}"
else
echo "ERROR: unable to created: ${basename}"
fi
fi
}
unfavorite() {
local current_dir="${PWD}"
local favorites_dir="${favorites}"
local basename="$(basename "$current_dir")"
local target="${favorites_dir}/${basename}"
if [[ -L "${target}" ]]; then
if \rm "${target}"; then
echo "Favorite removed: ${target}"
else
echo "ERROR: unable to remove ${target}"
fi
else
echo "${basename} not found in ${favorites_dir}."
fi
}
cd() {
[[ "${1}" == "--" ]] && shift
[[ "$#" -gt 1 ]] && { echo "too many arguments" >&2; return 1 ; }
local target="${1}"
local symlink cd_cmd
local favorites_dir="${favorites}"
if [[ -n "${ZSH_VERSION}" ]]; then
cd_cmd=( "builtin" "cd" )
elif [[ -n "${BASH_VERSION}" ]]; then
local cdpath=("${CDPATH[@]}")
cd_cmd=( "cd" )
fi
case "${target}" in
"-") "${cd_cmd[@]}" - ; return ;;
"") "${cd_cmd[@]}" ; return ;;
esac
for dir in "${cdpath[@]}"; do
if [[ "${dir}/${target}" == "${favorites_dir}"* && -L "${dir}/${target%%/*}" ]]; then
symlink="$(readlink -f "${dir}/${target%%/*}")"
[[ "${target}" == *"/"* ]] && local subdir="${target#*/}"
"${cd_cmd[@]}" "${symlink}/${subdir#*/}"
return
fi
done
if [[ -d "${target}" ]]; then
"${cd_cmd[@]}" "${target}"
elif [[ -e "${target}" ]]; then
"${cd_cmd[@]}" "$(dirname "${target}")"
else
echo "${target}: No such file or directory" >&2
return 1
fi
}
unset favorites
@sigboe
Copy link
Author

sigboe commented Nov 6, 2023

Made changes so it should™ work on bash as well as zsh, still not tested on bash.
Fixed issues where cd lost functionality, like cd -

@sigboe
Copy link
Author

sigboe commented Nov 6, 2023

Fixed more bugs, including cd to non existent targets inside the cdpath, and cd to folders inside symlinks in cdpath and more issues

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment