hsingko


在 Emacs 中使用 zoxide 进行目录跳转

zoxide 是一个智能目录跳转的命令行工具。安装 zoxide 之后,就可以通过 z <dir> 来替代 cd <dir> 进行目录跳转。它的强大之出在于会记录所有到过的路径,自动地生成“书签”,之后想要再次进入这些目录,就只需要输入部分字符,譬如第一次进入 z foo/bar/zoo ,之后只需要 z zoo 就能在任意地方重新回到 foo/bar/zoo 中。

Figure 1: Zoxide 官方示例

Figure 1: Zoxide 官方示例

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 就可以便捷地跳转到去过的目录,我的配置其实就是对这个功能的模拟。

Figure 2: 在这个例子中,我想要将录屏文件拷贝到博客资源目录下。通过 zoxide ,我先用 P 将 dired 目录切换到录屏文件夹,然后 C-u P 在新窗口打开博客资源目录,最后将目标视频文件拷贝到另一个窗口

Figure 2: 在这个例子中,我想要将录屏文件拷贝到博客资源目录下。通过 zoxide ,我先用 P 将 dired 目录切换到录屏文件夹,然后 C-u P 在新窗口打开博客资源目录,最后将目标视频文件拷贝到另一个窗口

如果你想要在 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)