一个致力于实用且有趣的 Shell 技巧分享系列 🌝
前言
作为一个日常习惯使用命令行的开发来说,每天在命令行里通过 cd 这 cd 那切换路径的需求很常见。这么常见的需求,如果日常仅仅使用 cd,就会有以下不少的痛点。
第一点,有时候切换的目录层级过深,就会十分头疼。如下:
为了从目录 rslv 切换到目录 react。硬是需要打出一长串路径。上面是写了绝对路径,当然我们也可以写相对路径:
也一样麻烦。
第二点,切换工作路径,然后再干一些其他事情,得分开两个命令,也有点麻烦。(当然这个可能只是痒点)
嗯哼。有没有更简短的方式呢?
还有最后一点,并行项目千千万,哪里记得住这么多工作路径呢?而且万一拼写错误,就很难过的发现只能浪费很多时间去寻找了。
于是,忍不住思考,会有更好、更人性化的方式么?🤔
疯狂的逗号 - commacd
有一天看到了一个解决方案 commacd:github.com/shyiko/comm…
通过使用疯狂的逗号去完成切换路径。🤣
它提供了三个命令用来在终端中漫游,十分便利。分别是:
- 「,」单个逗号,用来向前模糊匹配路径漫游。
- 「,,」两个逗号,用来向后模糊匹配路径漫游。
- 「,,,」三个逗号,则可以前与后均进行模糊匹配漫游。
一个逗号向前找
简单来说。单个逗号使用示例如下:
一个逗号,加部分路径,commacd 就会模糊搜索匹配到对应的路径并切换过去。可以说十分方便了。
当然,更神奇的来了。输入仅仅 des/w/p/r 很少的信息,commacd 也十分精确的降落了对于工作路径。示例如下:
当然如果它遇到了不太确定的多个匹配结果。它也不会擅自决定,而会提供选项给到用户选择。示例如下:
两个逗号往后找
有前就有后。两个逗号加上目标路径部分就可以向后切换。这时候会匹配到最近的、最匹配 des 的父级目录。
在没有指定目标路径的时候,就会往回切换到项目根路径。当然一般是指有 .git 的工作路径。
三个逗号前后找
当然,如果想更加简单点,就可以使用三个逗号。
逗号的更多可能性
对于命令行来说,命令都是可以组合的。这里可以参考我之前介绍的文件查找和预览 fzf 命令一样。使用:
command `, path`
或者使用更现代化的方式:
command $(, path)
当然 command 可以是 open、code 等之类的都可以,本质上
$(, path) 会开启一个 subshell 执行完 , path 命令后,展开置换到原有命令中。再举个例子就是,与 echo 命令组合:
求磁盘体积如下:
同理可以组合出更多命令,等你发现。
任意门 - rslv
有了疯狂的逗号命令,但是有时候也不能解决我偶尔失忆的痛点:想不起甚至关于目标路径半点蛛丝马迹的一个惭愧真相。
于是,我就在想,有没有更好的方式呢?某一天在修改 webpack 配置的时候,看到 resolve alias 的时候,突然激发了灵感,命令行为什么没有可以给常用的工作路径设置 alias,然后通过 alias 快速切换的工具命令呢?
这就有点像记不住 ip 地址,人类发明了「域名」;为了减少重复操作,App 发明了「收藏」的功能;解决找不到常用的桌面应用,Windows 发明了「发送快捷方式到桌面」。
那么命令行也应该可以一样。实现将 /Users/yanguangjie/Desktop/workspace/projects/react 注册为 @react,然后 cd @react 这样直接切换过去。
说干就干!
通过整理需求,我实现了一个 rslv:github.com/sulirc/rslv 工具命令。实现了 CLI 任意门的功能。
实现
当然任意门实现起来很简单,这里简述一下实现原理。通过一个数据库文件存储记录注册的 alias(别名) 和 path (路径)的映射关系,格式可以是这样:
@rslv => /Users/yanguangjie/Desktop/rslv
@react => /Users/yanguangjie/Desktop/workspace/projects/react
实现一个 rslv 命令用以注册、展开 alias。命令手册如下:
别名注册
注册 alias 时写入数据库文件。展开 alias 时从数据库文件中查询,并展开输入到标准输出流中:
注册完后可以查看已注册的别名列表:
别名跳跃
最重要的步骤来了。结合之前介绍的 $() 命令。最朴素的调用方式就是如下:
虽然貌似达成了我想要的效果。但是感觉很啰嗦,一点也不省事。
导出命令组合
shell 的需求,最终还是回到 shell 里解决。在 .zshrc 或者 .bashrc 里增加一行函数:
export rcd() { cd $(rslv -e "$1"); }
重启终端。
至此我的任意门梦想实现了。一键快速切换工作路径。
除了 cd,还有很多我常用的命令,比如 code、less、cat、open 等,都可以照此处理。
export rcd() { cd $(rslv -e "$1"); }
export rcode() { code $(rslv -e "$1"); }
export rless() { less $(rslv -e "$1"); }
export rcat() { cat $(rslv -e "$1"); }
export ropen() { open $(rslv -e "$1"); }
更多
最后补充一下。除了上述的两种方法,也存在许许多多其他方法。比如在 vscode 中打开终端,默认就是当前项目的工作路径。
不过,左手疯狂逗号,右手任意门,我们就是 CLI 里的闪电侠 ⚡️。