当前位置: 首页 > news >正文

十行代码实现命令行书签

路径书签/别名,用来给目录取个名字,要用时快速跳转,它不是用来代替:z.lua / z.sh / autojump 这类第一梯队的 cd 辅助工具的,而是作为他们的一个补充。

先前我想找个现成的路径书签的小插件,找到这个:pm

把现有目录添加成书签要:

pm add my-project

跳到这个书签对应的目录要:

pm go my-project

然后列出所有书签要:

pm list

删除书签要:

pm remove my-project

我又看了好几个书签软件,都大同小异,又难用,实现又啰嗦,这玩意儿居然写出 500 行以上的代码来,真是匪夷所思。所以我打算用十行代码实现一个更优雅的书签功能。

目标1:少打字

同样一个功能多打一个字母,做一千次就多打了 1K 的内容,能省则省,我不明白为什么这些插件做的都那么啰嗦,输入完命令名还得再输入 add/remove/go/list 之一的参数,然后才是书签名,要我来做,我会把命令名起短一点,比如叫做 m :

m         # 列出当前所有书签
m foo     # 跳转到名为 foo 的标签
m +foo    # 将当前路径添加成书签 foo
m -foo    # 删除名为 foo 书签
m /foo    # 搜索名称里包含 foo 的书签

大部分时候都频率最高的就是 “跳转” 和 “列出所有书签”,所以尽可能的减少他们输入的字符数,m foo 就是跳转到名字为 foo 的书签,比 pm go foo 少打四个字符,m 后面没参数,就是列出所有书签,pm list 少打六个字符。

其他几项功能也比 pm 少打很多字,用 +/- 三个符号代表:增加,搜索和删除,也很直白。

目标2:代码少

我实在不明白一个简单的插件为什么会写成 500-600 行的翔。我们充分利用 shell 的功能,那么把当前目录添加到书签,就是:

ln -snf "$(pwd)" "$MARKPATH/$1" 

其中 $MARKPATH 指向 ~/.local/share/marks 之类的地方,可以自定义,添加书签就是在 $MARKPATH 下面做一个软连接,指向当前目录即可。

删除书签:

rm -i "$MARKPATH/$1" 

删除书签就是删除软连接,还会用 rm 命令的 -i 参数问下你是否真的要删除。

跳转书签:

cd -P "$MARKPATH/$1"

不就完了?使用 -P 参数跳转到实际路径,搞那么多花花绕干嘛?

其他的搜索书签就是 find 命令,列出书签就是 ls 命令格式化一下。

实际代码

实际代码用 case 来判断参数前缀,增加了一些边际情况处理,保存成 m.sh

function m() {MARKPATH="${MARKPATH:-$HOME/.local/share/marks}"[ -d "$MARKPATH" ] || mkdir -p -m 700 "$MARKPATH" 2> /dev/nullcase "$1" in+*)            # m +foo  - add new bookmark for $PWDln -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 bookmarkscommand ls -1 "$MARKPATH/" | MARKPATH="$MARKPATH" xargs -I'{}' \sh -c 'echo "{} ->" $(readlink "$MARKPATH/{}")';;*)             # m foo   - cd to the bookmark directorylocal dest="$(readlink "$MARKPATH/$1" 2> /dev/null)"[ -d "$dest" ] && cd "$dest" || echo "No such mark: $1";;esac
}

就是这么简短,是用的时候在你的 .bashrc / .zshrc 中添加一下:

source /path/to/m.sh

就能用 m foo 进行跳转,m 列出所有书签,m +foo 添加书签了。懒得多弄一个 m.sh 的话,还可以直接把这个函数帖到你的 rc 文件或者 init.sh 里面。

增加补全

上面提到的好几个书签插件都没做补全,咱们代码量虽少,补全方面也不含糊:

if [ -n "$BASH_VERSION" ]; thenfunction _cdmark_complete() {local MARKPATH="${MARKPATH:-$HOME/.local/share/marks}"local curword="${COMP_WORDS[COMP_CWORD]}"if [[ "$curword" == "-"* ]]; thenCOMPREPLY=($(find "$MARKPATH" -type l -name "${curword:1}*" \2> /dev/null | awk -F "/" '{print "-"$NF}'))elseCOMPREPLY=($(find "$MARKPATH" -type l -name "${curword}*" \2> /dev/null | awk -F "/" '{print $NF}'))fi}complete -F _cdmark_complete m
elif [ -n "$ZSH_VERSION" ]; thenfunction _cdmark_complete() {local MARKPATH="${MARKPATH:-$HOME/.local/share/marks}"if [[ "${1}${2}" == "-"* ]]; thenreply=($(command ls -1 "$MARKPATH" 2> /dev/null | \awk '{print "-"$0}'))elsereply=($(command ls -1 "$MARKPATH" 2> /dev/null))fi}compctl -K _cdmark_complete m
fi

该补全代码写的稍微啰嗦了点,但是主要是同时兼容 bash/zsh,有了这些补全代码,你输入完 m 命令后按 tab ,能帮你补全书签名称。

好了,前后代码加起来,不超过 50 行,比其他那些 400-500 行的垃圾插件优雅多了。

所以说,灵活应用各类终端工具,玩得转 awk/xargs/sed 等,就能让你事半功倍。


http://www.mrgr.cn/news/55970.html

相关文章:

  • 炒股VS炒游戏装备,哪个更好做
  • In-place Editor 存储库页面
  • DML语言
  • Mysql数据库 | 第三章 | insert | update | delete | select | 统计函数 | 分组统计
  • 保研推荐信模板
  • Linux:线程及其控制
  • Linux使用nc(netcat)命令检测网络端口是否畅通以及Linux查看CPU架构命令arch及CentOS中取版本的问题
  • Spring AI : Java写人工智能的应用框架
  • 正大金融市场的跨境投资机遇与挑战分析
  • 【数字IC】【低功耗】UPF/CPF
  • 郑州网站制作优化你的网站以吸引流量
  • 机器人学习仿真框架
  • 骨传导耳机哪个牌子最好?真实测评五大年度热门单品机型
  • 【直播回放】达索系统赋能新电池产业链数字仿真一体化协同解决方案
  • 软件源码,招投标管理系统,询价管理系统,供应商管理系统,一体化管理系统,供应链管理(springboot+vue+mysql)
  • 2024年墨西哥金融科技报告解读(上)| 从基础到前沿(附下载)
  • sdads
  • SiLM266x系列SiLM2660CD-DG 可配置的电池组电压检测功能 高压电池组前端充/放电高边NFET驱动器
  • 宠物电商新篇章:SpringBoot驱动的在线交易网站
  • comfyui替换电商模特工作流,模特们要真的要失业了吗?
  • 歌曲伴奏去哪里找?轻松获取你喜欢的伴奏
  • 10.17 多进程编程
  • 2024年9月青少年软件编程Python等级考试(一级)真题试卷及答案
  • 离线安装lrzsz
  • 代购系统搭建涉及到哪几方面❓
  • 电子便签:从偶像剧到职场的实用转变