更懂你的路径切换工具 - z.lua(集 autojump / z / fasd 大成)

2019-02-01 01:00:33 +08:00
 skywind3000

z.lua 是一个快速路径切换工具,它会跟踪你在 shell 下访问过的路径,通过一套称为 Frecent 的机制(源自 FireFox ),经过一段简短的学习之后,z.lua 会帮你跳转到所有匹配正则关键字的路径里 Frecent 值最高的那条路径去。

正则将按顺序进行匹配,"z foo bar" 可以匹配到 /foo/bar,但是不能匹配 /bar/foo。

项目地址:skywind3000/z.lua

有啥特点?

如何安装?

Posix Shells ( Bash、zsh、dash、sh 或 BusyBox 等)中,在你的 .bashrc, .zshrc 或者 .profile 文件中按 shell 类型添加对应语句:

  eval "$(lua /path/to/z.lua  --init bash)"   # BASH 初始化
  eval "$(lua /path/to/z.lua  --init zsh)"    # ZSH 初始化
  eval "$(lua /path/to/z.lua  --init posix)"  # Posix shell 初始化

用下面参数初始化会进入“增强匹配模式”:

  eval "$(lua /path/to/z.lua  --init bash once enhanced)"   # BASH 初始化
  eval "$(lua /path/to/z.lua  --init zsh once enhanced)"    # ZSH 初始化
  eval "$(lua /path/to/z.lua  --init posix once enhanced)"  # Posix shell 初始化

同时 zsh 支持 antigen/oh-my-zsh 等包管理器,可以用下面路径:

  skywind3000/z.lua

进行安装,比如 antigen 的话,在 .zshrc 中加入:

  antigen bundle skywind3000/z.lua

就可以了(主要要放在 antigen apply 语句之前)。Windows 和 Fish Shell 的初始化见文档。

Matching

z.lua 提供两种路径匹配算法:

除了设置环境变量外,还可以通过:

eval "$(lua /path/to/z.lua --init bash enhanced)"

来进入增强模式。

默认匹配

默认情况下 z.lua 使用和 z.sh 类似的匹配算法,成为默认匹配法。给定路径会按顺序匹配各个正则表达式。

增强匹配

你可以通过设置环境变量来启用增强匹配模式:

export _ZL_MATCH_MODE=1

或者使用下面语句:

eval "$(lua /path/to/z.lua --init bash enhanced)"

进行初始化,他们是等效的,记得把上面的 bash 可以根据你的 shell 改为 zsh 或者 posix

对于一个给定的正则关键字序列(即 z 命令后面的参数),某路径有且只有满足下面两个条件才算作 “匹配成功”:

  1. 正则关键字将按顺序进行匹配(这条和默认匹配法相同)。
  2. 最后一个关键字可以和路径名的最后一段相匹配。

如果两条规则同时启用找不到任何结果,那么将会退回到只用规则 1 进行筛选,这两条规则是参考 fasd 引入的。

再我最初实现 z.lua 时,只有一个和 z.sh 类似的默认匹配算法,在网友的建议下,我陆续学习了来自 fasd / autojump 中的优秀理念,并加以完善改进,成为如今集三家之长的 “增强匹配算法” ,给它取个昵称,叫做 “更懂你的匹配算法”。

更新数据库的时机

何时更新数据呢?默认情况下,z.lua 会在每次显示命令提示符时记录当前路径(和 z.sh 一致),但是还提供了一个 $_ZL_ADD_ONCE 的环境变量选项,设置成 1 的话,只有当前路径改变,才会将新路径添加到数据库。

除了设置环境变量外,不同的 shell 下还可以在初始化时增加 "once" 参数来达到相同目的,比如:

eval "$(lua /path/to/z.lua --init bash once enhanced)"
eval "$(lua /path/to/z.lua --init zsh once enhanced)"
lua /path/to/z.lua --init fish once enhanced | source

将会同时启用增强匹配算法和 once 机制,在一些比较慢的硬件下(路由器,cygwin,msys ),使用该机制将有效的提升性能。其实 autojump 在 zsh 下会使用类似 once 的机制,而 bash 下则和 z.sh 类似。

从效果上来讲,z.sh 的模式(关闭 once )强调的是 “在某路径下工作的时间长短”,而 autojump 的模式(启用 once )则强调 “进入某路径的次数多少”。

交互式选择模式

使用 -i 参数进行跳转时, 如果有多个匹配结果,那么 z.lua 会给你显示一个列表:

$ z -i soft
3:  0.25        /home/data/software
2:  3.75        /home/skywind/tmp/comma/software
1:  21          /home/skywind/software
> {光标位置}

然后你按照最前面的序号输入你想要去的地方,比如输入 3 就会进入 /home/data/software。如果你不输入任何东西直接按回车,那么将会直接退出而不进行任何跳转。

Tips

推荐一些常用的命令别名:

alias zc='z -c'      # 严格匹配当前路径的子路径
alias zz='z -i'      # 使用交互式选择模式

同时你可以定义一个名为 zf 的命令,搭配 fzf 进行历史路径模糊匹配:

alias zf='cd "$(z -l -s | fzf --reverse --height 35%)"'

性能评测

最慢的部分当然是添加当前路径到数据库。该操作会在每次你按回车时执行,所以我在我的 Nas 上做了个对比:

$ time autojump --add /tmp
real    0m0.352s
user    0m0.077s
sys     0m0.185s

$ time fasd -A /tmp
real    0m0.618s
user    0m0.076s
sys     0m0.242s

$ time _z --add /tmp
real    0m0.194s
user    0m0.046s
sys     0m0.154s

$ time _zlua --add /tmp
real    0m0.052s
user    0m0.015s
sys     0m0.030s

可以看出,z.lua 是消耗资源最少,并且最快的,可以更流畅的在性能不好的环境中使用。

结论

真的可以卸载 autojump / z / fasd 了。

9968 次点击
所在节点    Linux
41 条回复
Chingim
2019-02-01 01:31:29 +08:00
看起来不错,没想到我用的 fasd 这么不能打
这个快是因为 lua 语言(fasd 应该是 shell script 实现)带来的吧?
Chingim
2019-02-01 01:35:39 +08:00
我找到一个能打的 https://github.com/xen0n/autojump-rs/blob/develop/README.md

能加入比较么
zhs227
2019-02-01 01:41:48 +08:00
最近在尝试楼主的这个东西,用 luajit 加持一般进入目录的时间在个位数毫秒级别,非常好用
yuikns
2019-02-01 03:44:29 +08:00
点开工程发现用户名有点熟悉。原来好久前就关注了。
膜大佬
ynyounuo
2019-02-01 03:57:11 +08:00
@Chingim fasd 基本上没有后续支持了,作者感觉忘记了这个项目
skywind3000
2019-02-01 05:23:06 +08:00
@Chingim z.lua 更快,切换路径只要 0.017 秒,你看他的评测他居然需要 0.050 秒。其实也不奇怪,lua 的可执行也才 200 多 KB,它可执行 5MB,strip 过后也有 1.5MB ,启动速度它就拜下来了,他还没启动完,z.lua 可能都运行完了。
yuikns
2019-02-01 05:30:19 +08:00
好奇怪,我 mac 的 bash 使用了下, lua 5.3.5,随便 cd 几下后,在 /tmp 下产生了大量 lua_xxxxxx 空文件。

data_save 那个 function 好像会删除文件,但是失败了?

请问发 issue 还需要什么信息?
wweir
2019-02-01 05:32:19 +08:00
@skywind3000 可执行文件在文件系统是有缓存的,以这点文件大小来说事并不科学。
如果想从文件大小来说明比 rust 的实现快,至少得冷热启动分别给一下数据
wzw
2019-02-01 07:39:51 +08:00
看了就想试试,稳定性如何
skywind3000
2019-02-01 09:06:04 +08:00
@wweir 不是说它要载入这个大文件费时间,而是文件那么大,初始化一定很多代码要跑。
wweir
2019-02-01 09:24:53 +08:00
@skywind3000 同样,进程自身在内核中也是有缓存的,重置一下上下文就好

不想去扣这些底层,对普通人来说,就是玄学。要表述一个违反常规认知的观点,那就来点实际的吧,比如:bench 数据
congeec
2019-02-01 09:28:21 +08:00
为嘛用 lua 呢?为了性能?
Yggdroot
2019-02-01 09:29:51 +08:00
正在使用,很好用。z.lua 还有个优点,就是有什么好的想法作者都会很快做出反馈,其它的工具就未必。
guanhui07
2019-02-01 10:05:03 +08:00
不错
clown139880
2019-02-01 10:48:44 +08:00
mac 用 antigen 安装之后报错
skywind3000/z.lua/z.lua:1414: attempt to concatenate a nil value
屏蔽两行后使用 z 提示_zlua:33: permission denied
是我 lua 的问题么,我用 brew install lua 安装的
使用 z.sh 时没有出现过任何问题
dltsgl
2019-02-01 11:19:30 +08:00
centos6 报错:
lua: /home/v33491/download/lua/z.lua:7: unexpected symbol near '<'

lua version 是: Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio

用的 bash

不太懂,请教一下什么原因
lihongjie0209
2019-02-01 11:23:52 +08:00
这种交互式的工具性能倒是其次, 关键是易用性
skywind3000
2019-02-01 13:27:11 +08:00
@clown139880 重新按默认参数编译个 lua 吧,brew 的版本有问题。
skywind3000
2019-02-01 13:30:45 +08:00
@wweir 如你所愿,我做了个测试:

原版本 autojump:

skywind@weilin0:~/.vim$ time j vim
/home/skywind/software/vim

real 0m0.149s
user 0m0.047s
sys 0m0.063s

autojump-rs:

skywind@weilin0:~/software/vim$ time j vim
/home/skywind/.vim

real 0m0.075s
user 0m0.000s
sys 0m0.031s

z.lua:

skywind@weilin0:~/.vim$ time z vim

real 0m0.019s
user 0m0.016s
sys 0m0.016s

够明白了么?我说的启动时间不仅指操作系统层的启动时间,还指应用程序自身的初始化时间,程序越庞大越复杂,模块越多,自然涉及到越复杂的启动过程,举个例子,就像 C++ 全局对象多了以后,进入主程序之前,都有一大堆构造函数要调用。
wweir
2019-02-01 14:36:06 +08:00
@skywind3000 数据依然不够全面,benchmark test 报告,可不是这么简单就行的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/532304

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX