mirror of
https://github.com/skywind3000/z.lua
synced 2026-03-22 07:39:48 +00:00
Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c3a182c6c9 | ||
|
|
771c72de5f | ||
|
|
4bbd0f1e58 | ||
|
|
db1fb1f256 | ||
|
|
19cb43d1ac | ||
|
|
787da9512c | ||
|
|
3875d774cb | ||
|
|
dff590adc1 | ||
|
|
20c0494d44 | ||
|
|
67405d57e8 | ||
|
|
6e67a32520 | ||
|
|
c334bc1ae5 | ||
|
|
0f6318ce4c | ||
|
|
3b55089ad8 | ||
|
|
c58d31ec1d | ||
|
|
7c890c3645 | ||
|
|
7af012cc35 | ||
|
|
019b2af475 | ||
|
|
ef9a49d73d | ||
|
|
7cd399b30d | ||
|
|
9112f0e9cc | ||
|
|
cb4c9d3c8f | ||
|
|
924f61a48b | ||
|
|
4c05e0d911 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -39,3 +39,4 @@ luac.out
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
/.vscode/*
|
||||
|
||||
25
README.cn.md
25
README.cn.md
@@ -84,6 +84,17 @@ z -b foo # 跳转到父目录中名称以 foo 开头的那一级
|
||||
|
||||
但是第二种方法需要记得在 z.lua 位置改变或者 lua 版本升级后需要重新生成。
|
||||
|
||||
- Nushell:
|
||||
|
||||
在 `env.nu` 中加入如下代码:
|
||||
|
||||
lua /path/to/z.lua --init nushell | save -f ~/.cache/zlua.nu
|
||||
|
||||
然后在 `config.nu` 中加入如下代码:
|
||||
|
||||
source ~/.cache/zlua.nu
|
||||
alias z = _zlua
|
||||
|
||||
- Power Shell:
|
||||
|
||||
在你 Power Shell 的配置文件 `profile.ps1` 中放入下面语句:
|
||||
@@ -112,7 +123,7 @@ z -b foo # 跳转到父目录中名称以 foo 开头的那一级
|
||||
- 设置 `$_ZL_NO_PROMPT_COMMAND` 为 1 来跳过钩子函数初始化(方便自己处理)。
|
||||
- 设置 `$_ZL_EXCLUDE_DIRS` 逗号分隔的路径列表,列表内的路径不会被收集。
|
||||
- 设置 `$_ZL_ADD_ONCE` 为 '1' 时,仅在当前路径 `$PWD` 改变时才更新数据库。
|
||||
- 设置 `$_ZL_MAXAGE` 来确定一个数据老化的阀值 (默认为 5000)。
|
||||
- 设置 `$_ZL_MAXAGE` 来确定一个数据老化的阈值 (默认为 5000)。
|
||||
- 设置 `$_ZL_CD` 用来指定你想用的 cd 命令,比如有人用 cd_func 。
|
||||
- 设置 `$_ZL_ECHO` 为 1 可以在跳转后显示目标路径名称。
|
||||
- 设置 `$_ZL_MATCH_MODE` 为 1 可以打开 “增强匹配模式”。
|
||||
@@ -201,7 +212,7 @@ Frecency 是一个由 'recent' 和 'frequency' 组成的合成词,这个术语
|
||||
|
||||
cd foo
|
||||
|
||||
因此,在增强匹配算法中,你总可以象 cd 命令一样使用 z 命令,而不必当心目标路径是否被记录过。
|
||||
因此,在增强匹配算法中,你总可以像 cd 命令一样使用 z 命令,而不必当心目标路径是否被记录过。
|
||||
|
||||
- 忽略当前路径:
|
||||
|
||||
@@ -214,7 +225,7 @@ Frecency 是一个由 'recent' 和 'frequency' 组成的合成词,这个术语
|
||||
|
||||
我当然可以每次使用`z env gems` 来精确指明,但是每当我输入 `z xxx` 我必然是想进行路径跳转的,而不是呆在原地,所以使用增强匹配模式,即便当前目录是最佳匹配,它也能懂得你想跳转的心思。
|
||||
|
||||
再我最初实现 z.lua 时,只有一个和 z.sh 类似的默认匹配算法,在网友的建议下,我陆续学习了来自 fasd / autojump 中的优秀理念,并加以完善改进,成为如今集三家之长的 “增强匹配算法” ,给它取个昵称,叫做 “更懂你的匹配算法”。
|
||||
在我最初实现 z.lua 时,只有一个和 z.sh 类似的默认匹配算法,在网友的建议下,我陆续学习了来自 fasd / autojump 中的优秀理念,并加以完善改进,成为如今集三家之长的 “增强匹配算法” ,给它取个昵称,叫做 “更懂你的匹配算法”。
|
||||
|
||||
|
||||
## Add once
|
||||
@@ -444,15 +455,13 @@ sys 0m0.030s
|
||||
|
||||
描述力强,可以更好的实现核心功能,同时速度更快,纯 shell 开发的话,太多语句是通过子进程 shell 的模式运行,所以性能很差,而 Python 开发的话启动速度又太慢,我在 Cygwin/msys 下用 z.sh 都觉得很卡,autojump/fasd 卡到不能用。
|
||||
|
||||
最关键的一点,Lua 速度很快 200 KB 的可执行程序,启动速度是 python 的 3倍,perl 的 2 倍,很多命令行工具 go/rust 写成,动不动就 2MB / 3MB,他们都还没有完成加载,lua 脚本可能都运行完了。
|
||||
最关键的一点,Lua 速度很快 200 KB 的可执行程序,启动速度是 python 的 3 倍,perl 的 2 倍,很多命令行工具 go/rust 写成,动不动就 2MB / 3MB,他们都还没有完成加载,lua 脚本可能都运行完了。
|
||||
|
||||
|
||||
## Credit
|
||||
|
||||
Releated projects:
|
||||
|
||||
- [rupa/z](https://github.com/rupa/z): origin z.sh implementation
|
||||
- [JannesMeyer/z.ps](https://github.com/JannesMeyer/z.ps): z for powershell
|
||||
我的推特:https://x.com/skywind3000
|
||||
个人博客: https://skywind.me/blog
|
||||
|
||||
|
||||
## License
|
||||
|
||||
12
README.md
12
README.md
@@ -118,6 +118,17 @@ z -b foo bar # replace foo with bar in cwd and cd there
|
||||
|
||||
into the same file.
|
||||
|
||||
- Nushell
|
||||
|
||||
Put something like this in your `env.nu`:
|
||||
|
||||
lua /path/to/z.lua --init nushell | save -f ~/.cache/zlua.nu
|
||||
|
||||
Then put something like this in your `config.nu`:
|
||||
|
||||
source ~/.cache/zlua.nu
|
||||
alias z = _zlua
|
||||
|
||||
- Power Shell:
|
||||
|
||||
> ⚠️ **WARNING**: users of [Starship Prompt](https://starship.rs/) should add the following command *after* `starship init`.
|
||||
@@ -587,6 +598,7 @@ This project needs help for the tasks below:
|
||||
- Thanks to [@manhong2112](https://github.com/manhong2112) for Power Shell porting.
|
||||
- Thanks to [@BarbUk](https://github.com/BarbUk) for fzf completion in Bash.
|
||||
- Thanks to [@barlik](https://github.com/barlik) for many improvements.
|
||||
- Thanks to [@brglng](https://github.com/brglng) for nushell porting.
|
||||
|
||||
And many others.
|
||||
|
||||
|
||||
172
z.lua
172
z.lua
@@ -4,7 +4,7 @@
|
||||
-- z.lua - a cd command that learns, by skywind 2018-2022
|
||||
-- Licensed under MIT license.
|
||||
--
|
||||
-- Version 1.8.17, Last Modified: 2022/09/29 15:47
|
||||
-- Version 1.8.18, Last Modified: 2024/04/30 17:11
|
||||
--
|
||||
-- * 10x faster than fasd and autojump, 3x faster than z.sh
|
||||
-- * available for posix shells: bash, zsh, sh, ash, dash, busybox
|
||||
@@ -128,6 +128,7 @@ Z_MATCHMODE = 0
|
||||
Z_MATCHNAME = false
|
||||
Z_SKIPPWD = false
|
||||
Z_HYPHEN = "auto"
|
||||
Z_DATA_SEPARATOR = "|"
|
||||
|
||||
os.LOG_NAME = os.getenv('_ZL_LOG_NAME')
|
||||
|
||||
@@ -882,6 +883,7 @@ function os.interpreter()
|
||||
local lua = os.argv[-1]
|
||||
if lua == nil then
|
||||
io.stderr:write("cannot get executable name, recompiled your lua\n")
|
||||
return nil
|
||||
end
|
||||
if os.path.single(lua) then
|
||||
local path = os.path.which(lua)
|
||||
@@ -1061,6 +1063,26 @@ function path_case_insensitive()
|
||||
end
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
-- Read a line of the database and return a list of the 3 fields in it
|
||||
-----------------------------------------------------------------------
|
||||
function read_data_line(line)
|
||||
local part = string.split(line, Z_DATA_SEPARATOR)
|
||||
if #part <= 3 then
|
||||
return part
|
||||
end
|
||||
-- If the part is made of more than 3 elements, it's probably because the
|
||||
-- path element contains '|' that have been split. Thus, we want to
|
||||
-- reconstruct it and keep the 2 last elements of part intact as the end
|
||||
-- of the returned part.
|
||||
local path = part[1]
|
||||
for i=2,#part-2 do
|
||||
path = path .. Z_DATA_SEPARATOR .. part[i]
|
||||
end
|
||||
return {path, part[#part-1], part[#part]}
|
||||
end
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
-- load and split data
|
||||
-----------------------------------------------------------------------
|
||||
@@ -1073,7 +1095,7 @@ function data_load(filename)
|
||||
return {}
|
||||
end
|
||||
for line in fp:lines() do
|
||||
local part = string.split(line, '|')
|
||||
local part = read_data_line(line)
|
||||
local item = {}
|
||||
if part and part[1] and part[2] and part[3] then
|
||||
local key = insensitive and part[1]:lower() or part[1]
|
||||
@@ -1135,7 +1157,7 @@ function data_save(filename, M)
|
||||
end
|
||||
for i = 1, #M do
|
||||
local item = M[i]
|
||||
local text = item.name .. '|' .. item.rank .. '|' .. item.time
|
||||
local text = item.name .. Z_DATA_SEPARATOR .. item.rank .. Z_DATA_SEPARATOR .. item.time
|
||||
fp:write(text .. '\n')
|
||||
end
|
||||
fp:close()
|
||||
@@ -1654,7 +1676,7 @@ function z_cd(patterns)
|
||||
end
|
||||
cmd = cmd .. ' < "' .. tmpname .. '"'
|
||||
else
|
||||
tmpname = os.tmpname():gsub('\\', ''):gsub('%.', '')
|
||||
tmpname = os.tmpname():gsub('[\\:]', ''):gsub('%.', '')
|
||||
tmpname = os.environ('TMP', '') .. '\\zlua_' .. tmpname .. '.txt'
|
||||
cmd = 'type "' .. tmpname .. '" | ' .. cmd
|
||||
end
|
||||
@@ -1851,7 +1873,7 @@ function cd_breadcrumbs(pwd, interactive)
|
||||
if not windows then
|
||||
tmpname = os.tmpname()
|
||||
else
|
||||
tmpname = os.tmpname():gsub('\\', ''):gsub('%.', '')
|
||||
tmpname = os.tmpname():gsub('[\\:]', ''):gsub('%.', '')
|
||||
tmpname = os.environ('TMP', '') .. '\\zlua_' .. tmpname .. '.txt'
|
||||
end
|
||||
fp = io.open(tmpname, 'w')
|
||||
@@ -1979,12 +2001,14 @@ function main(argv)
|
||||
for _, key in ipairs(args) do
|
||||
opts[key] = 1
|
||||
end
|
||||
if windows then
|
||||
if opts.nushell then
|
||||
z_nushell_init(opts)
|
||||
elseif windows then
|
||||
z_windows_init(opts)
|
||||
elseif opts.fish then
|
||||
z_fish_init(opts)
|
||||
elseif opts.powershell then
|
||||
z_windows_init(opts)
|
||||
z_windows_init(opts)
|
||||
else
|
||||
z_shell_init(opts)
|
||||
end
|
||||
@@ -1996,9 +2020,14 @@ function main(argv)
|
||||
z_print(M, true, false)
|
||||
end
|
||||
elseif options['--complete'] then
|
||||
local line = args[1] and args[1] or ''
|
||||
local head = line:sub(Z_CMD:len()+1):gsub('^%s+', '')
|
||||
local M = z_match({head}, Z_METHOD, Z_SUBDIR)
|
||||
local M = {}
|
||||
if options['-m1'] then
|
||||
M = z_match(args and args or {}, Z_METHOD, Z_SUBDIR)
|
||||
else
|
||||
local line = args[1] and args[1] or ''
|
||||
local head = line:sub(Z_CMD:len()+1):gsub('^%s+', '')
|
||||
M = z_match({head}, Z_METHOD, Z_SUBDIR)
|
||||
end
|
||||
for _, item in pairs(M) do
|
||||
print(item.name)
|
||||
end
|
||||
@@ -2166,7 +2195,8 @@ _zlua() {
|
||||
-s) local arg_strip="-s" ;;
|
||||
-i) local arg_inter="-i" ;;
|
||||
-I) local arg_inter="-I" ;;
|
||||
-h|--help) local arg_mode="-h" ;;
|
||||
-h) local arg_mode="-h" ;;
|
||||
--help) local arg_mode="-h" ;;
|
||||
--purge) local arg_mode="--purge" ;;
|
||||
*) break ;;
|
||||
esac
|
||||
@@ -2776,6 +2806,126 @@ function z_windows_init(opts)
|
||||
end
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
-- nushell
|
||||
-----------------------------------------------------------------------
|
||||
local script_zlua_nushell = [[
|
||||
def _zlua --env --wrapped [...args: string] {
|
||||
if ($args | length) != 0 and $args.0 == "--add" {
|
||||
with-env { _ZL_RANDOM: (random int) } { ^$env.ZLUA_LUAEXE $env.ZLUA_SCRIPT --add ...($args | skip 1) }
|
||||
} else if ($args | length) != 0 and $args.0 == "--complete" {
|
||||
^$env.ZLUA_LUAEXE $env.ZLUA_SCRIPT --complete ...($args | skip 1)
|
||||
} else {
|
||||
mut arg_mode = ''
|
||||
mut arg_type = ''
|
||||
mut arg_subdir = ''
|
||||
mut arg_inter = ''
|
||||
mut arg_strip = ''
|
||||
mut count = 0
|
||||
for arg in $args {
|
||||
match $arg {
|
||||
'-l' => { $arg_mode = '-l' },
|
||||
'-e' => { $arg_mode = '-e' },
|
||||
'-x' => { $arg_mode = '-x' },
|
||||
'-t' => { $arg_type = '-t' },
|
||||
'-r' => { $arg_type = '-r' },
|
||||
'-c' => { $arg_subdir = '-c' },
|
||||
'-s' => { $arg_strip = '-s' },
|
||||
'-i' => { $arg_inter = '-i' },
|
||||
'-I' => { $arg_inter = '-I' },
|
||||
'-h' => { $arg_mode = '-h' },
|
||||
'--help' => { $arg_mode = '-h' },
|
||||
'--purge' => { $arg_mode = '--purge' },
|
||||
_ => break
|
||||
}
|
||||
$count += 1
|
||||
}
|
||||
let args = $args | skip $count
|
||||
if $arg_mode == '-h' or $arg_mode == '--purge' {
|
||||
^$env.ZLUA_LUAEXE $env.ZLUA_SCRIPT $arg_mode
|
||||
} else if $arg_mode == '-l' or ($args | length) == 0 {
|
||||
^$env.ZLUA_LUAEXE $env.ZLUA_SCRIPT -l $arg_subdir $arg_type $arg_strip ...$args
|
||||
} else if $arg_mode != '' {
|
||||
^$env.ZLUA_LUAEXE $env.ZLUA_SCRIPT $arg_mode $arg_subdir $arg_type $arg_inter ...$args
|
||||
} else {
|
||||
let zdest = (^$env.ZLUA_LUAEXE $env.ZLUA_SCRIPT --cd $arg_type $arg_subdir $arg_inter ...$args)
|
||||
if $zdest != '' and ($zdest | path exists) {
|
||||
cd $zdest
|
||||
if _ZL_ECHO in $env and $env._ZL_ECHO != '' {
|
||||
pwd
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]]
|
||||
|
||||
local script_init_nushell = [[
|
||||
$env.config = ($env | default {} config).config
|
||||
$env.config = ($env.config | default {} hooks)
|
||||
$env.config = ($env.config | update hooks ($env.config.hooks | default {} env_change))
|
||||
$env.config = ($env.config | update hooks.env_change ($env.config.hooks.env_change | default [] PWD))
|
||||
$env.config = ($env.config | update hooks.env_change.PWD ($env.config.hooks.env_change.PWD | append {|_, dir| _zlua --add $dir }))
|
||||
]]
|
||||
|
||||
local script_complete_nushell = [[
|
||||
let zlua_completer = {|spans| $spans | skip 1 | _zlua --complete -m1 ...$in | lines | where {|x| $x != $env.PWD}}
|
||||
|
||||
$env.config = ($env.config | default {} completions)
|
||||
$env.config = ($env.config | update completions ($env.config.completions | default {} external))
|
||||
$env.config = ($env.config | update completions.external ($env.config.completions.external | default true enable))
|
||||
if completer in $env.config.completions.external {
|
||||
let orig_completer = $env.config.completions.external.completer
|
||||
$env.config = ($env.config | update completions.external.completer {
|
||||
{|spans|
|
||||
match $spans.0 {
|
||||
z => $zlua_completer,
|
||||
_zlua => $zlua_completer,
|
||||
_ => $orig_completer
|
||||
} | do $in $spans
|
||||
}
|
||||
})
|
||||
} else {
|
||||
$env.config = ($env.config | update completions.external.completer {
|
||||
{|spans|
|
||||
match $spans.0 {
|
||||
z => $zlua_completer,
|
||||
_zlua => $zlua_completer,
|
||||
} | do $in $spans
|
||||
}
|
||||
})
|
||||
}
|
||||
]]
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
-- initialize nushell
|
||||
-----------------------------------------------------------------------
|
||||
function z_nushell_init(opts)
|
||||
print('$env.ZLUA_LUAEXE = \'' .. os.interpreter() .. '\'')
|
||||
print('$env.ZLUA_SCRIPT = \'' .. os.scriptname() .. '\'')
|
||||
local prompt_hook = (not os.environ("_ZL_NO_PROMPT_COMMAND", false))
|
||||
if opts.clean ~= nil then
|
||||
prompt_hook = false
|
||||
end
|
||||
print(script_zlua_nushell)
|
||||
if prompt_hook then
|
||||
print(script_init_nushell)
|
||||
end
|
||||
print(script_complete_nushell)
|
||||
if opts.enhanced ~= nil then
|
||||
print('$env._ZL_MATCH_MODE = 1')
|
||||
end
|
||||
if opts.once ~= nil then
|
||||
print('$env._ZL_ADD_ONCE = 1')
|
||||
end
|
||||
if opts.echo ~= nil then
|
||||
print('$env._ZL_ECHO = 1')
|
||||
end
|
||||
if opts.nc ~= nil then
|
||||
print('$env._ZL_NO_CHECK = 1')
|
||||
end
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
-- help
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
@@ -22,9 +22,9 @@ fi
|
||||
export _ZL_FZF_FLAG=${_ZL_FZF_FLAG:-"-e"}
|
||||
|
||||
if [[ -z "$_ZL_ZSH_NO_FZF" ]]; then
|
||||
eval "$($ZLUA_EXEC $ZLUA_SCRIPT --init zsh once enhanced)"
|
||||
else
|
||||
eval "$($ZLUA_EXEC $ZLUA_SCRIPT --init zsh once enhanced fzf)"
|
||||
else
|
||||
eval "$($ZLUA_EXEC $ZLUA_SCRIPT --init zsh once enhanced)"
|
||||
fi
|
||||
|
||||
if [[ -z "$_ZL_NO_ALIASES" ]]; then
|
||||
|
||||
Reference in New Issue
Block a user