在 Emacs 中使用 zoxide 进行目录跳转
zoxide 是一个智能目录跳转的命令行工具。安装 zoxide 之后,就可以通过 z <dir>
来替代 cd <dir>
进行目录跳转。它的强大之出在于会记录所有到过的路径,自动地生成“书签”,之后想要再次进入这些目录,就只需要输入部分字符,譬如第一次进入 z foo/bar/zoo
,之后只需要 z zoo
就能在任意地方重新回到 foo/bar/zoo
中。
zoxide.el 是一个 emacs 插件,通过它可以与外部 zoxide 进行交互,方便地在 zoxide
记录过的目录中进行跳转。
我的配置如下:
(use-package zoxide
:init
(defun +zoxide-cd ()
(interactive)
(cd (completing-read "path:" (zoxide-query) nil t)))
:config
(defun dired-jump-with-zoxide ()
(interactive)
(if (equal current-prefix-arg nil)
(zoxide-open-with nil (lambda (file) (dired file)) t)
(zoxide-open-with nil (lambda (file) (dired-other-window file)) t)))
:bind
(:map dired-mode-map
("P" . dired-jump-with-zoxide)))
.
配置看似复杂,其实主要实现了两个功能:
- 在
dired
中通过自定义函数dired-jump-with-zoxide
进行目录跳转。如果带了C-u
则在新窗口展示文件目录 - 自定义了
+zoxide-cd
函数,插件虽然自带了相同功能的zoxide-cd
,都用来切换default-directory
,但自带的有 bug ,跳转功能是无效的
那么这两个功能有什么应用场景呢?
在 dired
进行跳转很直观,绑定了快捷键 P
,这样就可以很快速地搜索并跳转目录。在此之前如果要想完成相同的目的我会使用 emacs 自带的 bookmark ,但这种方式无疑很麻烦。如果使用过 yazi 的话就会对这个功能更熟悉了, yazi 是类似于 ranger, lf 的命令行文件管理器,它有一个很方便的功能是内置了对 zoxide 的支持,按下快捷键 z
就可以便捷地跳转到去过的目录,我的配置其实就是对这个功能的模拟。
如果你想要在 emacs 中 clone 一个 github 项目会怎么做呢?除了打开外部终端,也可以用 magit
,但用 magit 会遇到一个克隆目录的问题。现在我想要安装一个不在 elpa/melpa 上的 emacs 插件,比如 lsp-bridge
,我想要把它放在 ~/.emacs.d/git/lsp-bridge
目录下,而如果当前的 default-directory
不在 ~/.emacs.d/git/
那么 magit 就会要求手动输入路径。而使用 +zoxide-cd
,我就能可以在任意目录下将工作目录切换到 git/
(当然前提是 zoxide 记录过这个路径),然后在执行 magit-clone ,这样就不需要再修改路径了,非常方便。
另一个使用 +zoxide-cd
场景是这样的,我在 ~/Documents/org
目录下写这篇博客,然后通过 ox-hugo
将 org 转换成 md 格式并自动移动到 ~/Documents/Blog/content/...
目录下,现在文章写完了,我想要通过 magit 提交,这时就可以用 +zoxide-cd
切换到 Blog
目录,然后再用 magit add/commit/push 就行了,很方便。在以前我会用 C-x p p
随便打开一个文件,然后再打开 magit ,相比之下就很繁琐了。
与 consult-dir 整合
也可以将 zoxide 的数据源添加到 consult-dir
中,以实现更具一致性的目录操作:
(defvar consult-dir--source-zoxide
`(:name "Zoxide"
:narrow ?z
:category file
:face consult-file
:history file-name-history
:enabled ,(lambda () (featurep 'zoxide))
:items ,#'zoxide-query)
"zoxide directory source")
(add-to-list 'consult-dir-sources 'consult-dir--source-zoxide t)