快速目录跳转工具 zoxide 使用指南

前言

以前我在 Mac 上一直使用一个 z 命令的工具,可以通过片段、关键词快速跳转到曾经访问过的目录,在频繁切换项目目录时极其方便。入职新公司后拿到了一台全新的 Mac,当时却一时想不起来当时用的是什么了(后来在自己电脑看了一下,使用的是 zsh-z,是 zsh 的一个插件)。

原本打算安装 autojump,但偶然发现一个 star 数超过 28k 的替代品 ------ zoxide,尝试之后发现它也很不错,使用更简洁、同时能保留我使用 z 命令的习惯,因此决定整理成一篇文档分享。

Zoxide

zoxide 是一个比传统 cd 命令更智能的目录跳转工具,灵感来源于 z 和 autojump,并在它们的基础上做了大量优化。它通过记录你访问过的路径及其频率,构建权重系统,使得你只需输入目录名称的关键词即可完成快速跳转。

与其他类似工具不同的是:

  • 跨平台支持(Linux/macOS/Windows)
  • 支持 多种 shell(bash/zsh/fish/pwsh/elvish)
  • 基于 Rust 实现,性能优异
  • 支持 自动补全 和 交互式模糊查询
  • 简洁一致的语法,几乎无学习成本

安装

由于我个人环境是 Mac + Zsh,如果是其他操作系统和 Shell 需要参考官方文档安装。

1. 安装 zoxide

推荐使用 Homebrew 安装(macOS):

bash 复制代码
brew install zoxide

然后将初始化脚本添加到你的 shell 配置文件中(如 .zshrc):

bash 复制代码
eval "$(zoxide init zsh)"

安装完成后,重启终端或执行 source ~/.zshrc 生效。

2. 安装 FZF(可选但强烈推荐)

FZF 是一个通用命令行模糊查找器,可增强 zoxide 的交互体验:

bash 复制代码
brew install fzf

安装完成后即可使用 zi(zoxide 自带的 fzf 命令)。

快速上手

zoxide 提供了类似 cd 的 z 命令:

bash 复制代码
z foo              # 进入与 foo 匹配度最高的目录
z foo bar          # 进入同时匹配 foo 和 bar 的最高评分目录
z foo /            # 进入以 foo 开头的子目录

z ~/foo            # z 也可以像普通的 cd 命令一样使用
z foo/             # 进入相对路径
z ..               # 返回上一级目录
z -                # 返回上一个目录

zi foo             # 使用交互式选择进入目录(基于 fzf)

z foo<空格><TAB>   # 显示交互式补全(zoxide v0.8.0+,支持 bash 4.4+/fish/zsh)

每次使用 z 或 cd 命令进入目录时,都会自动记录路径。

zoxide + fzf 模糊跳转增强

虽然 zoxide 默认支持子串匹配,但不支持真正意义上的模糊搜索。例如:

bash 复制代码
z open-source    # ✓ 成功跳转
z os             # ✗ 无匹配

这时候就需要用到 fzf 实现交互式模糊跳转。

zi 命令的局限

zi 是 zoxide 自带的 fzf 集成命令,但经测试其模糊搜索效果不生效,我提交了个 issue 询问作者还没有得到回复,但后来在查阅 zoxide 源码时发现明确指定了 zi 中的 fzf 使用严格模式查询。

自定义增强命令 zx

为了弥补 zi 的不足,我参考官方 zi 命令实现了一个 zx 命令,将 zoxide query 与 fzf 手动组合,支持精准模糊过滤,并拥有和官方 zi 命令一样的窗口。

bash 复制代码
# ~/.zshrc 中添加:
zx() {
  local query="${*}"
  local dir

  dir=$(zoxide query --list --score | \
    fzf --filter="$query" --no-sort | \
    fzf \
      --prompt="zoxide > " \
      --nth=2.. \
      --ansi \
      --height=60% \
      --info=inline \
      --border=rounded \
      --layout=reverse \
      --preview-window=down:40%:wrap \
      --preview='ls -F -C --color=always {2..}' \
	  --bind 'ctrl-z:ignore,btab:up,tab:down,enter:become:echo {2..}' \
      --cycle \
      --keep-right \
      --tabstop=1
  )

  [[ -n "$dir" ]] && cd "$dir"
}

使用方式:

bash 复制代码
zx                # 打开所有路径模糊搜索界面
zx foo            # 模糊过滤包含 foo 的路径

示例效果图:

工作原理简介

zoxide 的排名算法结合了频率 (访问次数)和时效性(最近访问时间)来为每个目录计算分数

核心评分机制

每个目录条目包含三个关键字段:

  • path: 目录路径
  • rank: 基础排名分数(浮点数)
  • last_accessed: 最后访问时间戳

当访问目录时,系统会增加其基础排名分数并更新访问时间

rust 复制代码
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Dir<'a> {
    #[serde(borrow)]
    pub path: Cow<'a, str>,
    pub rank: Rank,
    pub last_accessed: Epoch,
}

时效性加权

查询时,系统根据最后访问时间应用不同的乘数 :

  • 1小时内: 4倍乘数
  • 1天内: 2倍乘数
  • 1周内: 0.5倍乘数
  • 超过1周: 0.25倍乘数

确保最近使用的目录在搜索结果中获得更高优先级。

rust 复制代码
pub fn score(&self, now: Epoch) -> Rank {
	// The older the entry, the lesser its importance.
	let duration = now.saturating_sub(self.last_accessed);
	if duration < HOUR {
		self.rank * 4.0
	} else if duration < DAY {
		self.rank * 2.0
	} else if duration < WEEK {
		self.rank * 0.5
	} else {
		self.rank * 0.25
	}
}

与其他工具对比

工具名 是否维护 特点 模糊搜索 平台支持
z ❌ 停止维护 shell 实现,体积小,功能少 部分支持 类 Unix
autojump ⚠️ 缺乏维护 Python 实现,功能较少 ❌ 官方仅支持类 Unix / 由社区支持 Windows、BSD
zoxide ✅ 活跃维护 Rust 实现,高性能,支持 FZF ✅ 全平台支持

使用建议

  • 代替所有 cd 命令:越用越准,路径跳转体验越顺滑
  • 搭配 zx 命令做模糊搜索、目录浏览,非常适合多项目工作流
  • zoxide 提供了内置的别名设置,在初始化命令指定 --cmd:
bash 复制代码
zoxide init zsh --cmd j   # 习惯 `j` 命令可以这么定义
zoxide init zsh --cmd cd  # 或者直接代替 cd 命令
  • 如果你之前使用 autojump、z、fasd 等命令,可以导入数据,例如:
bash 复制代码
zoxide import --merge --from=z "~/.z"

参考链接

相关推荐
子兮曰3 小时前
把 649 种文件格式塞进一个网页里:一个「文件不出浏览器」的预览器
前端·javascript·后端
全栈弄潮儿6 小时前
Python实战第2期: 变量与数据类型
后端·python·agent
sm_926787056 小时前
RFID 标签打印的技术实现要点与二次开发实践
java·大数据·前端·c++·编辑器
IMPYLH6 小时前
HTML 的 <video> 元素
前端·html
码事漫谈7 小时前
五道题,测测你有没有真的入门 AI
后端
溪语流沙7 小时前
【每天一个CSS | Day19】流光文字与一笔写成的手写签名
前端·javascript·css
蜗牛互联网7 小时前
Python + JSON Schema 实现工单结构化输出与本地复核
java·人工智能·后端
逐光者9337 小时前
STM32——SPI 屏 · Flash · 高速
java·前端·stm32
To_OC7 小时前
同样是让 AI 写全栈,为什么别人一句话就够了
前端·前端框架·next.js