1
0
mirror of https://github.com/skywind3000/z.lua synced 2026-03-19 06:09:48 +00:00
Files
z.lua/README.cn.md
2019-01-31 22:32:48 +08:00

10 KiB
Raw Blame History

z.lua

快速路径切换工具(类似 z.sh / autojump / fasd兼容 Windows 和所有 Posix Shell 以及 Fish Shell同时包含了众多功能改进。

Description

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

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

Features

  • 性能比 z.sh 快三倍,比 fasd / autojump 快十倍以上。
  • 支持 Posix Shellbash, zsh, dash, sh, ash, busybox及 Fish Shell。
  • 支持 Windows cmd 终端 (使用 clink)cmder 和 ConEmu。
  • 无依赖,不会像 fasd/z.sh 那样对 awk/gawk 有特殊的版本要求。
  • 兼容 lua 5.1, 5.2 和 5.3 以上版本。
  • 新增:环境变量 "$_ZL_ADD_ONCE" 设成 1 的话性仅当前路径改变时才更新数据库。
  • 新增:增强匹配模式,将环境变量 "$_ZL_MATCH_MODE" 设置成 1 可以启用。
  • 新增:交互选择模式,如果有多个匹配结果的话,跳转前允许你进行选择。

Examples

z foo       # 跳转到包含 foo 并且权重Frecent最高的路径
z foo bar   # 跳转到同时包含 foo 和 bar 并且权重最高的路径
z -r foo    # 跳转到包含 foo 并且访问次数最高的路径
z -t foo    # 跳转到包含 foo 并且最近访问过的路径
z -l foo    # 不跳转,只是列出所有匹配 foo 的路径
z -c foo    # 跳转到包含 foo 并且是当前路径的子路径的权重最高的路径
z -e foo    # 不跳转,只是打印出匹配 foo 并且权重最高的路径
z -i foo    # 就进入交互式选择模式,让你自己挑选去哪里(多个结果的话)

Install

  • Posix ShellsBash、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 语句之前)。

  • Fish Shell:

    新建 ~/.config/fish/conf.d/z.fish 文件,并包含如下代码:

    lua /path/to/z.lua --init fish | source
    

    Fish version 2.4.0 或者以上版本都支持,还有一种初始化方法:

    lua /path/to/z.lua --init fish > ~/.config/fish/conf.d/z.fish
    

    但是第二种方法需要记得在 z.lua 位置改变或者 lua 版本升级后需要重新生成。

  • Windows (with clink):

    • 将 z.lua 和 z.cmd 拷贝到 clink 的安装目录。
    • 将 clink 的安装目录添加到 %PATH% (z.cmd 可以被任意位置调用到)。
    • 保证 lua 命令在你的 %PATH% 环境变量中。
  • Windows cmder:

    • 将 z.lua 和 z.cmd 拷贝到 cmder/vendor 目录中。
    • 将 cmder/vendor 添加到环境变量 %PATH% 里面。
    • 保证 lua 命令在你的 %PATH% 环境变量中。

Options

  • 设置 $_ZL_CMD 来改变命令名称 (默认为 z)。
  • 设置 $_ZL_DATA 来改变数据文件 (default ~/.zlua)。
  • 设置 $_ZL_NO_PROMPT_COMMAND 为 1 来跳过钩子函数初始化(方便自己处理)。
  • 设置 $_ZL_EXCLUDE_DIRS 来确定一个你不想收集的路径数组。
  • 设置 $_ZL_ADD_ONCE 为 '1' 时,仅在当前路径 $PWD 改变时才更新数据库。
  • 设置 $_ZL_MAXAGE 来确定一个数据老化的阀值 (默认为 5000)。
  • 设置 $_ZL_CD 用来指定你想用的 cd 命令,比如有人用 cd_func 。
  • 设置 $_ZL_ECHO 为 1 可以在跳转后显示目标路径名称。
  • 设置 $_ZL_MATCH_MODE 为 1 可以打开 “增强匹配模式”。

Aging

The rank of directories maintained by z.lua undergoes aging based on a simple formula. The rank of each entry is incremented every time it is accessed. When the sum of ranks is over 5000 ($_ZL_MAXAGE), all ranks are multiplied by 0.9. Entries with a rank lower than 1 are forgotten.

Frecency

Frecency is a portmanteau of 'recent' and 'frequency'. It is a weighted rank that depends on how often and how recently something occurred. As far as I know, Mozilla came up with the term.

To z.lua, a directory that has low ranking but has been accessed recently will quickly have higher rank than a directory accessed frequently a long time ago. Frecency is determined at runtime.

Matching

z.lua has two different matching methods: 0 for default, 1 for enhanced:

Default matching

By default, z.lua uses default matching method similar to the original z.sh. Paths must be match all of the regexes in order.

  • cd to a directory contains foo:

    z foo
    
  • cd to a directory ends with foo:

    z foo$
    
  • use multiple arguments:

    Assuming the following database:

    30   /home/user/mail/inbox
    10   /home/user/work/inbox
    

    "z in" would cd into /home/user/mail/inbox as the higher weighted entry. However you can pass multiple arguments to z.lua to prefer a different entry. In the above example, "z w in" would then change directory to /home/user/work/inbox.

Enhanced matching

Enhanced matching can be enabled by export the environment:

export _ZL_MATCH_MODE=1

For a given set of queries (the set of command-line arguments passed to z.lua), a path is a match if and only if:

  1. Queries match the path in order (same as default method).
  2. The last query matches the last segment of the path.

If no match is found, it will fall back to default matching method.

  • match the last segment of the path:

    Assuming the following database:

    10   /home/user/workspace
    20   /home/user/workspace/project1
    30   /home/user/workspace/project2
    40   /home/user/workspace/project3
    

    If you use "z wo" in enhanced matching mode, only the /home/user/work will be matched, because according to rule No.2 it is the only path whose last segment matches "wo".

    Since the last segment of a path is always easier to be recalled, it is sane to give it higher priority. You can also achieve this by typing "z space$" in both methods, but "z wo" is easier to type.

    Tips for rule No.2:

    • If you want your last query not only to match the last segment of the path, append '$' as the last query. eg. "z wo $".
    • If you want your last query not to match the last segment of the path, append '/' as the last query. eg. "z wo /".
  • cd to the existent path if there is no match:

    Sometimes if you use:

    z foo
    

    And there is no matching result in the database, but there is an existent directory which can be accessed with the name "foo" from current directory, "z foo" will just work as:

    cd foo
    

    So, in the enhanced matching method, you can always use z like cd to change directory even if the new directory is untracked (haven't been accessed).

  • Skip the current directory:

    when you are calling z xxx but the best match is the current directory, z.lua will choose the 2nd best match result for you. Assuming the database:

    10   /Users/Great_Wall/.rbenv/versions/2.4.1/lib/ruby/gems
    20   /Library/Ruby/Gems/2.0.0/gems
    

    When I use z gems by default, it will take me to /Library/Ruby/Gems/2.0.0/gems, but it's not what I want, so I press up arrow and execute z gems again, it will take me to /Users/Great_Wall/.rbenv/versions/2.4.1/lib/ruby/gems and this what I want.

    Of course I can always use z env gems to indicate what I want precisely. Skip the current directory means when you use z xxx you always want to change directory instead of stay in the same directory and do nothing if current directory is the best match.

The default matching method is designed to be compatible with original z.sh, but the enhanced matching method is much more handy and exclusive to z.lua.

Add once

By default, z.lua will add current directory to database each time before display command prompt (correspond with z.sh). But there is an option to allow z.lua add path only if current working directory changed.

To enable this, you can set $_ZL_ADD_ONCE to 1 before init z.lua. Or you can init z.lua on linux like this:

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

It could be much faster on slow hardware or Cygwin/MSYS.

Tips

Recommended aliases you may find useful:

alias zc='z -c'      # restrict matches to subdirs of $PWD
alias zz='z -i'      # cd with interactive selection

And you can define a zf command to select history path with fzf:

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

Benchmark

The slowest part is adding path to history data file. It will run every time when you press enter (installed in $PROMPT_COMMAND). so I profile it on my 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

As you see, z.lua is the fastest one and requires less resource.

Credit

Releated projects:

License

Licensed under MIT license.