oh-my-zsh z 插件完全指南:基于 Zsh-z 的 frecency 目录快速跳转
oh-my-zsh z 插件完全指南基于 Zsh-z 的 frecency 目录快速跳转【免费下载链接】ohmyzsh A delightful community-driven (with 2,500 contributors) framework for managing your zsh configuration. Includes 300 optional plugins (rails, git, macOS, hub, docker, homebrew, node, php, python, etc), 140 themes to spice up your morning, and an auto-update tool that makes it easy to keep up with the latest updates from the community.项目地址: https://gitcode.com/gh_mirrors/oh/ohmyzshz 是 oh-my-zsh 内置插件之一其本质是原生 Zsh 实现的 Zsh-z 为核心结合仓库内的完整手册 plugins/z/MANUAL.md 与源码 plugins/z/z.plugin.zsh系统讲解启用方式、全部命令行选项、可调环境变量、底层原理与性能表现帮助你用最少按键完成最高频的目录切换。核心概念frecency频率 新近度Zsh-z 的工作原理是跟踪两个维度的数据你何时进入某个目录以及你在该目录中停留多久。基于这两类数据它会对数据库中的每个目录计算一个frecency分数——frecency 是 frequency频率与 recency新近度的合成词即频繁访问过的目录获得高权重最近访问过的目录同样获得高权重。当你输入一个不完整的路径片段时Zsh-z 会根据这份数据库预测你真正想去的位置。例如z src可能把你带到~/src/zshz zsh也可能到达同一位置而z c/z则可能更精确——最终结果取决于你的使用习惯和数据库积累的时间长短。每次打开新 shell 并切换目录时Zsh-z 都会自动把你当前所在的目录记入数据库即--add操作由precmd钩子在每个提示符出现前后台执行因此无需任何手动初始化用上一段时间后数据库就会自然反映出你的工作流。快速上手在 oh-my-zsh 中启用 z在 oh-my-zsh 中启用 z 插件非常简单编辑~/.zshrc把z加入plugins数组即可参考模板 templates/zshrc.zsh-templateplugins(git z)保存后重新加载配置source ~/.zshrc或重开终端。插件会通过 plugins/z/z.plugin.zsh 定义z命令别名并把插件目录加入fpath以提供 Tab 补全。一个直观示例假设你之前访问过目录~/.oh-my-zsh/plugins。此后从任意目录只需输入一个与该目录匹配的正则片段即可快速到达/usr/bin$ z plug # 甚至 z p 也可能够用 ~/.oh-my-zsh/plugins$这正是 README 中给出的标准用法匹配是部分字符串包含匹配而不是前缀匹配因此z plug能命中~/.oh-my-zsh/plugins。让 Tab 补全更顺手Zsh-z 的补全依赖compinit且补全函数_zshz即 plugins/z/_z必须与插件主文件位于同一目录——oh-my-zsh 已经替你处理了这两个要求。如果你想让补全菜单更美观可以在~/.zshrc中添加zstyle :completion:* menu select使用最新上游版可选oh-my-zsh 内置的 z 插件通常与上游保持同步。如果你希望始终使用agkozak/zsh-z仓库的最新版本也可以将其克隆到自定义插件目录后启用git clone zsh-z 上游仓库地址 ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-z然后在~/.zshrc中把插件名改为zsh-zplugins(git zsh-z)。此方式与内置版本的功能完全等价仅来源更新频率不同。命令行选项z命令内部实现为zshz函数通过alias zzshz 21暴露支持以下选项完整帮助可通过z -h查看选项作用--add把一个目录加入数据库-c只匹配当前目录的子目录-e仅打印最佳匹配路径不实际跳转-h显示帮助信息-l列出所有匹配项不跳转-r按排名rank即停留时间匹配-t按最近访问时间time匹配-x从数据库移除一个目录默认移除当前目录-xR从数据库移除一个目录及其全部子目录默认移除当前目录此外z不带任何参数时会以排名升序列出目录历史等价于z -l。几个值得一提的细节-r与-t是互斥的排序方式v2.0 起二者不可同时使用否则会直接报错而不是像旧版那样让-t静默生效见 plugins/z/z.plugin.zsh。-x/-xR可以带参数删除任意目录而不局限于当前目录且 v2.0 起即使该目录已经从磁盘上删除数据库中的僵尸条目也能正常移除。多个搜索词以空格分隔时会被当作通配符处理例如z us lo bi可能把你带到/usr/local/binTab 补全此类多词命令时命令行会被整理为z /usr/local/bin而非残留中间词。环境变量设置全部ZSHZ_前缀Zsh-z 的所有行为均可通过环境变量调整完整清单见 plugins/z/MANUAL.md 的 Settings 一节源码中的默认值注释见 plugins/z/z.plugin.zsh。如果你之前用过rupa/z其_Z_前缀的旧变量如_Z_DATA同样会被识别平滑迁移。变量默认值说明ZSHZ_CASE空先试大小写敏感匹配再试不敏感匹配ignore表示一律忽略大小写smart表示 Vim 风格 smartcaseZSHZ_CMDz修改命令名ZSHZ_CDbuiltin cd指定目录切换命令ZSHZ_COMPLETIONfrecentfrecent按 frecency 排序补全结果legacy恢复按字母排序ZSHZ_DATA~/.z数据库文件路径ZSHZ_ECHO0设为1时跳转后打印新路径ZSHZ_EXCLUDE_DIRS空数组不进入数据库的目录数组ZSHZ_KEEP_DIRS空数组即使目录当前不可用也不从数据库移除如未挂载的驱动器ZSHZ_LOCK_TIMEOUT1秒等待数据库锁的超时时间ZSHZ_MAX_SCORE9000数据库总分数达到该值后开始老化aging旧条目按 0.99 系数衰减ZSHZ_NO_RESOLVE_SYMLINKS0设为1禁止解析符号链接ZSHZ_OWNER空数据库属主用户名在 root shell 中使用时设为你的登录名ZSHZ_TILDE0设为1时输出中用~显示$HOMEZSHZ_TRAILING_SLASH0设为1时以/结尾的搜索模式可匹配路径末尾元素如z foo/匹配/path/to/fooZSHZ_UNCOMMON0启用实验性的非公共前缀跳转逻辑详见下文以最常用的几个为例# 数据库文件换位置 export ZSHZ_DATA$HOME/.cache/zsh-z-data # 跳转后回显路径 export ZSHZ_ECHO1 # 忽略大小写 export ZSHZ_CASEignore # 某些目录不记录数组变量注意声明方式 typeset -gUa ZSHZ_EXCLUDE_DIRS ZSHZ_EXCLUDE_DIRS(/tmp /var/tmp)从源码结构看ZSHZ_EXCLUDE_DIRS由插件在加载时通过typeset -gUa声明为元素唯一的全局数组因此其他脚本可以直接追加而不必担心重复见 plugins/z/z.plugin.zsh。大小写敏感策略Zsh-z 默认先尝试大小写敏感匹配若无结果再退而求其次做大小写不敏感匹配。如果你偏好彻底忽略大小写ZSHZ_CASEignore如果你喜欢 Vimsmartcase的行为——全小写模式不区分大小写含大写字母的模式严格区分——则设置ZSHZ_CASEsmart该逻辑在 plugins/z/z.plugin.zsh 的_zshz_find_matches中实现smart模式下只有查询串全小写时才走大小写不敏感分支默认模式下先走敏感分支、再走不敏感分支。ZSHZ_UNCOMMON关于公共前缀的取舍这是 Zsh-z及rupa/z一个常被讨论的行为。如果你输入z code而按分数升序排列的最佳匹配是/home/me/code/foo /home/me/code/bar /home/me/code/batZsh-z 发现所有可能匹配共享公共前缀/home/me/code就会直接把你送到这个公共目录——这通常是理想结果。但若匹配集合变成/home/me/.vscode/foo /home/me/code/foo /home/me/code/bar /home/me/code/bat则不存在公共前缀此时z code会把你送到分数最高的/home/me/code/bat。设置ZSHZ_UNCOMMON1可启用另一种实验性行为即使存在公共前缀也不会跳过去而是选择最高分匹配但会剔除其中不包含搜索词的子目录。例如搜索bat且最佳匹配为/home/me/code/bat时你会精确到达该目录而搜索code且最佳匹配仍是/home/me/code/bat时你会到达/home/me/code因为code才是你搜索的词。该功能仍处于开发阶段。ZSHZ_OWNER在 root shell 下使用个人数据库当你在保留个人HOME的前提下使用 root 权限典型场景是sudo -E -s时会出现文件属主冲突root 写入的~/.z会变成 root 属主之后普通用户 shell 就无法正常读写。解决方法是设置ZSHZ_OWNER为你的用户名export ZSHZ_OWNER$USER设置后 Zsh-z 每次写入都会把数据库的属主恢复给你。同时它带来一项更严格的安全行为在特权 shell 写入你控制的路径时Zsh-z 只跟随属主为 root的符号链接例如 BSD 上/home→/usr/home、macOS 上/var→/private/var这类系统级链接否则会拒绝写入并报错。未设置ZSHZ_OWNER时则保持原有行为~/.z即使是指向同步存储的符号链接也能正常跟随见 plugins/z/z.plugin.zsh。让--add为你所用批量导入目录--add不仅是内部记账手段也可以由用户主动调用。一个典型场景是把某个目录树下所有 Git 仓库的工作目录批量加入数据库for i in $(find $PWD -maxdepth 3 -name .git -type d); do z --add ${i:h} doneZsh 用户通常更愿意用**通配而非find但先用find探查目录树深度是更稳妥的做法。数据库格式与底层实现原理数据库文件格式数据库文件默认位于~/.z每行一个条目格式为路径|分数|时间戳例如/home/me/code/bat|42|1727000000从源码看读取时会用正则/*\|[[:digit:]]##[.,]#[[:digit:]]#\|[[:digit:]]##过滤不完整或格式错误的条目见 plugins/z/z.plugin.zsh。由于数据库格式与rupa/z完全一致两个工具可以无缝互换使用。frecency 计分公式源码中 frecency 的计算位于 plugins/z/z.plugin.zsh(( dx now - time_field )) rank$(( 10000 * rank_field * (3.75/( (0.0001 * dx 1) 0.25)) ))其中rank_field是历史累计访问次数频率dx是距上次访问的秒数新近度。3.75 / ((0.0001 * dx 1) 0.25)这一项从刚刚访问时的约 3 逐渐衰减趋近于 0使越久未访问的目录权重越低乘以 10000 是为了把结果放大到适合整数比较的尺度。分数累积超过ZSHZ_MAX_SCORE默认 9000时触发老化所有条目乘以 0.99 系数分数跌到 1 以下的条目在下次写入时被剔除。每个提示符后的后台记账Zsh-z 通过precmd钩子_zshz_precmd见 plugins/z/z.plugin.zsh在每次提示符出现前把当前目录加入数据库。有几点值得注意永远不会添加$HOME本身也不添加ZSHZ_EXCLUDE_DIRS中的目录树写入在后台执行v2.0 起--add一律以单个脱离作业disowned的后台任务!运行——只有一次 fork、无包裹子 shell、无作业控制噪音保证提示符永远不会等待数据库写入。即便在 Cygwin/MSYS2 上写库成本也从随数据量增长的数百毫秒降为约 10–12 ms 的恒定 fork 开销刚执行过z -x的目录在离开之前不会被重新加入由chpwd钩子复位标志。v2.0 的并发写入保护数据库写入的竞态条件曾是rupa/z的顽疾用户偶尔会丢失整个~/.z。Zsh-z v2.0 引入了多重保护专用稳定锁文件基于zsh/system的zsystem flock对~/.z.lock或$ZSHZ_DATA.lock加排他锁锁获取有界等待ZSHZ_LOCK_TIMEOUT默认 1 秒。之所以不直接锁数据库文件是因为写入通过 rename 替换数据文件、每次新文件都有新 inode直接锁数据文件无法真正串行化并发写者见 plugins/z/z.plugin.zsh无zsh/system的降级路径在 MobaXterm 精简版 Cygwin 这类环境退化为用原子mkdir ~/.z.lock.d目录充当锁超过 30 秒的锁目录视为失效并清除数据库文件 600 权限新文件以umask 077创建保证只有你自己能读已有 644 权限的旧文件在下次写入时会被收紧Windows 上的 rename 重试Cygwin/MSYS2 上若病毒扫描器或索引器恰好在写库与 rename 之间打开了文件Windows 会拒绝 renameZsh-z 会短暂重试数次。如果怀疑数据库停止更新可手动执行前台命令z --add .并检查$?退出码2表示锁获取超时存在锁竞争可检查是否有残留进程占用~/.z.lock或调大ZSHZ_LOCK_TIMEOUT1通常是权限或属主问题例如之前sudo -s会话留下的 root 属主文件。性能表现消除对外部工具awk、sort、date、sed、mv、rm、chown的调用并减少子 shell fork是 Zsh-z 相对rupa/z的核心优化目标。在 fork 开销大的平台Cygwin、MSYS2、WSL上收益尤其明显。文档给出了两套基准数据N 200 条数据库记录Core i7-12700 桌面机 WSL2 下七次交错运行的中位数来源见 plugins/z/MANUAL.md 的 Performance 一节现代 Zsh5.9—— Zsh-z vs.rupa/z操作rupa/zz.shZsh-z胜出add6.25 ms/次1.99 ms/次Zsh-z ≈ 3.14xsearch6.51 ms/次3.62 ms/次Zsh-z ≈ 1.80xlist8.93 ms/次4.36 ms/次Zsh-z ≈ 2.05xZsh 4.3.11支持的最老版本—— Zsh-z vs.rupa/z操作rupa/zz.shZsh-z胜出add5.00 ms/次2.92 ms/次Zsh-z ≈ 1.71xsearch4.93 ms/次4.47 ms/次Zsh-z ≈ 1.10xlist7.92 ms/次6.08 ms/次Zsh-z ≈ 1.30x相对上一代 Zsh-zv2.0 的读取路径也大幅提速现代 Zsh 上整库列出约快 2.4 倍、搜索约快 1.6 倍。基准表中未包含-x删除操作因为rupa/z的 per-prompt 钩子在z -x之后会立刻把当前目录重新加回数据库二者删除行为不对等、无法公平对比。相比rupa/z的其他改进除性能与稳定性外Zsh-z 还带来一系列细节改进完整清单见 plugins/z/MANUAL.mdz -x真正生效删除的目录不会被下一个提示符偷偷加回兼容 Solaris使用新一代zshcompsys补全系统而非旧式compctl数据库文件尚未创建时不会报错支持目录名中的特殊字符如[z -l仅返回一个匹配时不打印公共根退出状态码更符合直觉补全支持-c、-r、-t选项~/foo与~/foob同时匹配时~/foo不再被误判为公共根——只有真正的公共父目录才算-x/-xR可带参数删除非当前目录继承rupa/z空格即通配符的搜索习惯且多词命令的补全不会产生视觉残留。从其他工具迁移来自rupa/z或fasd三者数据库格式相同可自由切换。rupa/z的数据库可直接复用默认同为~/.zfasd默认把数据存在~/.fasd迁移只需cp ~/.fasd ~/.z来自 autojumpautojump 的数据库格式不同需要转换。可以先将其导出为文本再转成 Zsh-z 格式path|rank|timestampawk -F \t {printf(%s|%0.f|%s\n, $2, $1, $(date %s))} /path/to/autojump.txt ~/.zCOMPLETE_ALIASES兼容性z或通过ZSHZ_CMD/_Z_CMD改名的命令本质是别名。setopt COMPLETE_ALIASES会把别名的 Tab 补全与底层命令解耦历史上会破坏 Zsh-z 的补全。v2.0 起 Zsh-z 自动处理了这个问题第一次按 Tab 时补全组件会自动把别名注册到_zshz无需任何额外配置。仅当某个后加载的插件在未调用原组件的情况下覆盖了 Tab 绑定自动注册才不会发生。此时可在~/.zshrc的setopt COMPLETE_ALIASES之后手动补一行即使自动注册已生效这行也无害compdef _zshz ${ZSHZ_CMD:-${_Z_CMD:-z}}小结启用方式最简plugins(... z)其余交给 oh-my-zsh。核心价值以 frecency 模型自动跟踪目录访问历史z 几个字符即可跳转且数据库与rupa/z兼容。可调空间大14 个ZSHZ_环境变量覆盖命令名、数据库路径、大小写策略、补全排序、目录排除/保留、锁超时等全部行为。工程上稳健纯 Zsh 实现、后台写入不阻塞提示符、锁文件防并发损坏、600 权限保护隐私、多平台降级路径完善。相关文件速查插件主源码 plugins/z/z.plugin.zsh、补全定义 plugins/z/_z、完整用户手册 plugins/z/MANUAL.md、插件级说明 plugins/z/README.md。【免费下载链接】ohmyzsh A delightful community-driven (with 2,500 contributors) framework for managing your zsh configuration. Includes 300 optional plugins (rails, git, macOS, hub, docker, homebrew, node, php, python, etc), 140 themes to spice up your morning, and an auto-update tool that makes it easy to keep up with the latest updates from the community.项目地址: https://gitcode.com/gh_mirrors/oh/ohmyzsh创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考