技术解析

十行代码实现路径书签功能
0
2021-06-21 03:20:43
idczone

路径书签 /别名,用来给目录取个名字,要用时快速跳转,它不是用来代替: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 行的垃圾插件优雅多了。


试了一下感觉不错。
P.S. macOS 上用的话,需要把 `xargs -i` 换成 `xargs -I'{}'`

请问一下补全代码怎么用呀

把补全的代码贴到 m 这个函数后面啊。

数据地带为您的网站提供全球顶级IDC资源
在线咨询
专属客服