Skip to content

Instantly share code, notes, and snippets.

@nicedreams
Last active June 12, 2022 00:58
Show Gist options
  • Save nicedreams/ed7299ee2a5a94063b07144eff042d23 to your computer and use it in GitHub Desktop.
Save nicedreams/ed7299ee2a5a94063b07144eff042d23 to your computer and use it in GitHub Desktop.
Shell Bookmarks
#!/bin/bash
# SHELL BOOKMARKS with Completion
# ----------------------------------------------------------------------------
# Usage: Source this file in your ~/.bashrc - Use `cdb` command
# Help: cdb --help
#
# 2021-09-14 - Ken Bernier <kbernier@gmail.com>
#
# Script manages symlinks of directories to create bookmark function with
# name completion. All bookmarks are symlinks stored in $DIRBOOKMARKS.
#
# Inspired by:
# https://stackoverflow.com/questions/7374534/directory-bookmarking-for-bash
# https://threkk.medium.com/how-to-use-bookmarks-in-bash-zsh-6b8074e40774
# https://twitter.com/mattn_jp/status/1434192554036137995?s=20
#
# ----------------------------------------------------------------------------
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# ----------------------------------------------------------------------------
# Change this variable to your own bookmarks directory location
DIRBOOKMARKS="${HOME}/.bookmarks"
# Create bookmarks directory if not exist along with a couple of symlinks to prevent issues
if [[ ! -d "${DIRBOOKMARKS}" ]]; then
mkdir "${DIRBOOKMARKS}"
ln -s "${DIRBOOKMARKS}" "${DIRBOOKMARKS}"/bookmarks
ln -s "${HOME}" "${DIRBOOKMARKS}"/home
fi
# completion function
_cdb() {
local _script_commands cur
_script_commands=$(ls -1 "${DIRBOOKMARKS}"/)
cur=${COMP_WORDS[COMP_CWORD]}
COMPREPLY=( $(compgen -W "$(/bin/ls -A "${DIRBOOKMARKS}")" -- "$cur") )
}
# Initialize completion
complete -F _cdb cdb
# Main function
cdb() {
local USAGE
USAGE="%sShell Bookmarks with Name Completion
\nUsage: cdb [-c|-d|-r|-s|-l|-f|--help] [bookmark]
\nPress TAB for bookmark name completion.\n
bookmark\t\t- change directory to bookmark
-c new_name\t\t- create bookmark from current directory
-d bookmark\t\t- delete bookmark
-r bookmark new_name\t- rename bookmark
-s bookmark\t\t- show bookmark symlink location
-l\t\t\t- list bookmarks
-f\t\t\t- [fzf] change directory to bookmark
--help\t\t- prints usage help\n"
case $1 in
# create bookmark
-a|-c|--add|--create) shift
if [[ -L "${DIRBOOKMARKS}"/"$1" ]]; then
printf '%s\n' "Bookmark already exists: $1 >> $(readlink -f "${DIRBOOKMARKS}"/"$1")"
elif [[ ! "$1" ]]; then
printf '%s\n' "No bookmark name entered. - Usage: cdb -a <new_bookmark_name>"
elif [[ ! -L "${DIRBOOKMARKS}"/"$1" ]]; then
ln -s "${PWD}" "${DIRBOOKMARKS}"/"$1"
complete -F _cdb cdb
fi
;;
# show bookmark
-s|--show) shift
if [[ -L "${DIRBOOKMARKS}"/$1 ]]; then
readlink -f "${DIRBOOKMARKS}"/"$1"
else
printf '%s\n' "Bookmark not found!"
fi
;;
# delete bookmark
-d|--delete) shift
if [[ -L "${DIRBOOKMARKS}"/"$1" ]]; then
if ! unlink "${DIRBOOKMARKS}"/"$1"; then printf '%s\n' "Issue when deleting bookmark!"; fi
elif [[ ! -L "${DIRBOOKMARKS}"/"$1" ]]; then
printf '%s\n' "Bookmark not found! - Usage: cdb -d <bookmark>"
fi
;;
# rename bookmark
-r|--rename) shift
if ! mv "${DIRBOOKMARKS}"/"$1" "${DIRBOOKMARKS}"/"$2"; then
printf '%s\n' "Issue when renaming bookmark! - Usage: cdb -r <bookmark> <new_name>"; fi
;;
# list bookmarks
-l|--list) shift
ls -1 "${DIRBOOKMARKS}"/
;;
# fzf
-f|--fzf)
if [[ "$(command -v fzf)" ]]; then
cd "${DIRBOOKMARKS}"/"$(/bin/ls -A "${DIRBOOKMARKS}" | fzf)" || return
else
printf '%s\n' "fzf not found!"
fi
;;
--help) printf "$USAGE"
;;
# goto bookmark
*)
if [[ ! "$1" ]]; then
return 0
elif [[ -L "${DIRBOOKMARKS}"/"$1" ]]; then
cd -P "${DIRBOOKMARKS}"/"$1" &>/dev/null || return
elif [[ ! -L "${DIRBOOKMARKS}"/"$1" ]]; then
printf '%s\n' "Bookmark $1 does not exist."
fi
;;
esac
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment