This is a small bash script, save it as m.sh
:
# bash directory bookmark
function cd_mark() {
MARKPATH="${MARKPATH:-$HOME/.local/share/marks}"
[ -d "$MARKPATH" ] || mkdir -p -m 700 "$MARKPATH" 2> /dev/null
case "$1" in
+*) # m +foo - add new bookmark for $PWD
ln -snf "$(pwd)" "$MARKPATH/${1:1}"
;;
-*) # m -foo - delete a bookmark named "foo"
rm -i "$MARKPATH/${1:1}"
;;
/*) # m /bar - search bookmarks matching "bar"
find "$MARKPATH" -type l -name "*${1:1}*" | \
awk -F "/" '{print $NF}' | MARKPATH="$MARKPATH" xargs -I'{}'\
sh -c 'echo "{} ->" $(readlink "$MARKPATH/{}")'
;;
"") # m - list all bookmarks
command ls -1 "$MARKPATH/" | MARKPATH="$MARKPATH" xargs -I'{}' \
sh -c 'echo "{} ->" $(readlink "$MARKPATH/{}")'
;;
*) # m foo - cd to the bookmark directory
local dest="$(readlink "$MARKPATH/$1" 2> /dev/null)"
[ -d "$dest" ] && cd "$dest" || echo "No such mark: $1"
;;
esac
}
# by default, alias cd_mark to m
alias ${MARKCMD:-m}='cd_mark'
Then put a single line in your .bashrc
or .zshrc
:
source /path/to/m.sh
Or, you can simply copy & paste the content to your .bashrc
or .zshrc
.
Now you can have your m
command to manipulate the directory bookmarks:
-
m +foo
: add a new bookmark for your current working directory -
m -foo
: delete a bookmark -
m foo
: cd to the given bookmark directory -
m /bar
: search bookmarks matching "bar" -
m
: print a list of all bookmarks
cd
to your most recently accessed directories and use m +foo
to create a bookmark named foo
, and use m foo
to go back at anytime.
Let's polish it a little, for example, add a completion function for bash/zsh:
if [ -n "$BASH_VERSION" ]; then
function _cdmark_complete() {
local MARKPATH="${MARKPATH:-$HOME/.local/share/marks}"
local curword="${COMP_WORDS[COMP_CWORD]}"
if [[ "$curword" == "-"* ]]; then
COMPREPLY=($(find "$MARKPATH" -type l -name "${curword:1}*" \
2> /dev/null | awk -F "/" '{print "-"$NF}'))
else
COMPREPLY=($(find "$MARKPATH" -type l -name "${curword}*" \
2> /dev/null | awk -F "/" '{print $NF}'))
fi
}
complete -F _cdmark_complete ${MARKCMD:-m}
elif [ -n "$ZSH_VERSION" ]; then
function _cdmark_complete() {
local MARKPATH="${MARKPATH:-$HOME/.local/share/marks}"
if [[ "${1}${2}" == "-"* ]]; then
reply=($(command ls -1 "$MARKPATH" 2> /dev/null | \
awk '{print "-"$0}'))
else
reply=($(command ls -1 "$MARKPATH" 2> /dev/null))
fi
}
compctl -K _cdmark_complete cd_mark
fi
After that, when you press tab after m
command, you can get suggestions from the completion function.
Top comments (0)