技术解析
路径书签 /别名,用来给目录取个名字,要用时快速跳转,它不是用来代替:z.lua / z.sh / autojump 这类第一梯队的 cd 辅助工具的,而是作为他们的一个补充。
找了一堆类似插件,不但是用麻烦,实现居然有 500+ 行代码,所以我准备写个十多行的版本,更加好用:
function m() {
MARKPATH="${MARKPATH:-$HOME/.local/share/marks}"
[ -d "$MARKPATH" ] || mkdir -p -m 700 "$MARKPATH" 2> /dev/null
case "$1" in
+*)
ln -snf "$(pwd)" "$MARKPATH/${1:1}"
;;
-*)
rm -i "$MARKPATH/${1:1}"
;;
/*)
find "$MARKPATH" -type l -name "*${1:1}*" | \
awk -F "/" '{print $NF}' | MARKPATH="$MARKPATH" xargs -i \
sh -c 'echo "{} ->" $(readlink "$MARKPATH/{}")'
;;
"")
command ls -1 "$MARKPATH/" | MARKPATH="$MARKPATH" xargs -i \
sh -c 'echo "{} ->" $(readlink "$MARKPATH/{}")'
;;
*)
local dest="$(readlink "$MARKPATH/$1" 2> /dev/null)"
[ -d "$dest" ] && cd "$dest" || echo "No such mark: $1"
;;
esac
}
把上面函数保存成 m.sh
然后再你的 shell rc 里加一行:
source /path/to/m.sh
就可以是用了,如果懒得创建文件,把这个函数贴到你的 shell rc 文件里也行,使用方法如下:
m # 列出当前所有书签
m foo # 跳转到名为 foo 的标签
m +foo # 将当前路径添加成书签 foo
m -foo # 删除名为 foo 书签
m /foo # 搜索名称里包含 foo 的书签
是用起来比其他书签插件打字更少,也更符合直觉,当然我们还可以加一段补全功能:
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 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 m
fi
该补全代码写的稍微啰嗦了点,但是主要是同时兼容 bash/zsh,有了这些补全代码,你输入完 m 命令后按 tab,能帮你补全书签名称。
好了,前后代码加起来,不超过 50 行,比其他那些 400-500 行的垃圾插件优雅多了。