mirror of
https://github.com/skywind3000/z.lua
synced 2026-03-22 07:39:48 +00:00
Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a245db0d93 | ||
|
|
dd721703c3 | ||
|
|
7920d56c89 | ||
|
|
645818ccc8 | ||
|
|
b98911a227 | ||
|
|
671830059b | ||
|
|
0fad96124b | ||
|
|
465f2b8e62 | ||
|
|
ff9d874ef4 | ||
|
|
86120d206e | ||
|
|
1e0e3523b0 | ||
|
|
7eee4e4b13 | ||
|
|
edd71f7a6e | ||
|
|
f63a832921 | ||
|
|
f92ad79e2c | ||
|
|
38c1741f4f | ||
|
|
fdff5c5e1e | ||
|
|
b691d537f2 | ||
|
|
472925ac92 | ||
|
|
5ba0e50894 | ||
|
|
c769dba4dd | ||
|
|
bbca83c9a5 | ||
|
|
53c127a4a2 | ||
|
|
5f7fa928b6 | ||
|
|
68de23ecef | ||
|
|
5ea08c5dac | ||
|
|
9dd0fec7ed | ||
|
|
fe11dd30c5 | ||
|
|
db92fa0a1c | ||
|
|
b1702839d2 | ||
|
|
1a0428f54e | ||
|
|
31e9d42d08 | ||
|
|
14b942634c | ||
|
|
6cfe2150e9 |
13
README.cn.md
13
README.cn.md
@@ -269,7 +269,7 @@ PS:你可以使用 `$_ZL_FZF` 环境变量来精确指明 fzf 的可执行路
|
|||||||
- **(单个参数)**:`cd` 到离当前目录最近的以关键字开头的父目录,如果找不到就尝试跳到包含关键字的父目录。
|
- **(单个参数)**:`cd` 到离当前目录最近的以关键字开头的父目录,如果找不到就尝试跳到包含关键字的父目录。
|
||||||
- **(两个参数)**:将当前路径中的第一个关键词替换为第二个关键词。
|
- **(两个参数)**:将当前路径中的第一个关键词替换为第二个关键词。
|
||||||
|
|
||||||
为了使用简便,我们继续将 `z -b` 取个别名成 `zb`:
|
先将 `z -b` 别名成 `zb`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 一直向上退到项目根目录(就是里面有一个 .git 目录的地方)
|
# 一直向上退到项目根目录(就是里面有一个 .git 目录的地方)
|
||||||
@@ -350,23 +350,22 @@ $ z -
|
|||||||
=> cd -
|
=> cd -
|
||||||
```
|
```
|
||||||
|
|
||||||
这个 `dirstack` 是根据 z.lua 的路径历史数据库计算的出来的,所以和具体的 shell 或者操作系统都没有关系。你退出再登陆不会丢失这些路径历史,不同的 shell 之间也可以共享同一份历史数据。
|
这个 `dirstack` 是根据 z.lua 的路径历史数据库计算的出来的,和具体的 shell 或者操作系统无关。你退出再登陆不会丢失这些记录,不同的 shell 之间也可以共享同一份记录。
|
||||||
|
|
||||||
此外,还有另外一种方法,通过使用前面提到的 `-I` 和 `-t` 参数组和,可以使用 fzf 进行交互式选择:
|
此外,还能通过前面提到的 `-I` 和 `-t` 参数组和,使用 fzf 选择最近去过的目录:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
alias zh='z -I -t .'
|
alias zh='z -I -t .'
|
||||||
```
|
```
|
||||||
|
|
||||||
首先定义个新的别名 `zh`(回到历史路径的意思),我们使用了 `-t` 参数来告诉 `z.lua` 按照时间戳作为权重进行排序,同时 `-I` 启用 fzf 进行搜索,最后的句号代表任意路径。
|
方便起见,定义个新的别名 `zh`(回到历史路径的意思),我们用 `-t` 参数来告诉 `z.lua` 按时间戳为权重排序,同时 `-I` 启用 fzf 搜索,最后句号代表任意路径。
|
||||||
|
|
||||||
那么当我们在命令行敲入 zh 时,就可以用 fzf 选择最近呆过的路径了:
|
那么当我们在命令行敲入 zh 时,就可以用 fzf 进行历史路径操作了:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
第一列数据代表该路径多少秒以前访问过,第二列是路径名称。此时,你可以试着敲几个字母,用 fzf 的字符串模糊匹配进行定位,或者用光标键的上和下(CTRL+J/K 也可以)来上下移动,最后按回车 cd 过去,或者 ESC 放弃。
|
第一列上次访问距今多少秒,第二列是目录名。你可以试着敲几个字母,用 fzf 的字符串模糊匹配进行定位,或者用光标键的上和下(CTRL+J/K 也可以)来上下移动,最后按回车 cd 过去,或者 ESC 放弃。
|
||||||
|
|
||||||
注意:最好把增强匹配模式打开,这样查看历史路径时可以把当前路径过滤掉。
|
|
||||||
|
|
||||||
|
|
||||||
## Tips
|
## Tips
|
||||||
|
|||||||
15
README.md
15
README.md
@@ -275,9 +275,9 @@ Now you can input some space separated keywords (no order required) or use `CTRL
|
|||||||
|
|
||||||
Of course, you can always give more keywords to `z` command to match your destination precisely. `"z -I"` is similar to `"z -i"`, but use fzf. Both `"-i"` and `"-I"` provide you another way for path navigation.
|
Of course, you can always give more keywords to `z` command to match your destination precisely. `"z -I"` is similar to `"z -i"`, but use fzf. Both `"-i"` and `"-I"` provide you another way for path navigation.
|
||||||
|
|
||||||
Usually, `z -I` can be aliased to `zf` (z + fuzzy finder) for convenience. If there are only one path matched, `z -I` will jump to it directly, fzf will only be invoked for multiple matches.
|
Usually, `z -I` can be aliased to `zf` (z + fuzzy finder) for convenience. If there are only one path matched, `z -I` will jump to it directly, fzf will only be invoked for multiple matches. `"z -I ."` or `"zf ."` can be used to use fzf select from entire database.
|
||||||
|
|
||||||
`"z -I ."` or `"zf ."` can be used to use fzf select from entire database. Environment variable `_ZL_FZF_FLAG` is for passing additional arguments to fzf.
|
For more information about this, please visit [wiki - effective with fzf](https://github.com/skywind3000/z.lua/wiki/Effective-with-fzf).
|
||||||
|
|
||||||
NOTE: For fish shell, this feature requires fish 2.7.0 or above. You can specify fzf executable in `$_ZL_FZF` environment variable, `"fzf"` will be called by default.
|
NOTE: For fish shell, this feature requires fish 2.7.0 or above. You can specify fzf executable in `$_ZL_FZF` environment variable, `"fzf"` will be called by default.
|
||||||
|
|
||||||
@@ -458,6 +458,16 @@ As you see, z.lua is the fastest one and requires less resource.
|
|||||||
|
|
||||||
## History
|
## History
|
||||||
|
|
||||||
|
- 1.7.2 (2019-08-01): Improve bash/zsh shell compatibility by [@barlik](https://github.com/barlik).
|
||||||
|
- 1.7.1 (2019-06-07): Fixed: `$_ZL_DATA` failure on Linux sometimes.
|
||||||
|
- 1.7.0 (2019-03-09): Support [ranger](https://github.com/skywind3000/z.lua/wiki/FAQ#how-to-integrate-zlua-to-ranger-), fix ReplaceFile issue in luajit (windows).
|
||||||
|
- 1.6.0 (2019-03-04): optimize with ffi module (luajit builtin module).
|
||||||
|
- 1.5.11 (2019-03-02): fixed: os.path.isdir doesn't work for symbol link folders.
|
||||||
|
- 1.5.10 (2019-03-01): Prevent writing file racing.
|
||||||
|
- 1.5.9 (2019-02-25): `z -b` should not match current directory (close #56).
|
||||||
|
- 1.5.8 (2019-02-21): new `$_ZL_FZF_HEIGHT` to control `--height` parameter in fzf.
|
||||||
|
- 1.5.7 (2019-02-21): rename `$_ZL_FZF_SORT` to `$_ZL_INT_SORT` it will affect both `-i` and `-I`.
|
||||||
|
- 1.5.6 (2019-02-20): set `$_ZL_FZF_SORT` to 1 to sort directories by alphabet in fzf.
|
||||||
- 1.5.5 (2019-02-20): `$_ZL_FZF_FLAG` can be used to override fzf flags, default to "+s -e".
|
- 1.5.5 (2019-02-20): `$_ZL_FZF_FLAG` can be used to override fzf flags, default to "+s -e".
|
||||||
- 1.5.4 (2019-02-19): fixed: file/path existence detection fails on read-only fs (closed [#49](https://github.com/skywind3000/z.lua/issues/49) by [@contrun](https://github.com/contrun)).
|
- 1.5.4 (2019-02-19): fixed: file/path existence detection fails on read-only fs (closed [#49](https://github.com/skywind3000/z.lua/issues/49) by [@contrun](https://github.com/contrun)).
|
||||||
- 1.5.3 (2019-02-17): new `$_ZL_FZF_FLAG` for passing additional flags to fzf, add `-e` argument to fzf.
|
- 1.5.3 (2019-02-17): new `$_ZL_FZF_FLAG` for passing additional flags to fzf, add `-e` argument to fzf.
|
||||||
@@ -488,6 +498,7 @@ As you see, z.lua is the fastest one and requires less resource.
|
|||||||
|
|
||||||
This project needs help for the tasks below:
|
This project needs help for the tasks below:
|
||||||
|
|
||||||
|
- [ ] Support csh/tcsh.
|
||||||
- [ ] Completion: Actually I got little knowledge in completion, and need help to improve it.
|
- [ ] Completion: Actually I got little knowledge in completion, and need help to improve it.
|
||||||
- [ ] Completion: Implement completion for Power Shell.
|
- [ ] Completion: Implement completion for Power Shell.
|
||||||
- [ ] Completion: Implement completion for different arguments.
|
- [ ] Completion: Implement completion for different arguments.
|
||||||
|
|||||||
BIN
images/step1.png
Normal file
BIN
images/step1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
BIN
images/step2.png
Normal file
BIN
images/step2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
BIN
images/step3.png
Normal file
BIN
images/step3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.6 KiB |
BIN
images/step4.png
Normal file
BIN
images/step4.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.8 KiB |
91
ranger_zlua.py
Normal file
91
ranger_zlua.py
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
import time, sys, os
|
||||||
|
import ranger.api
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
old_hook_init = ranger.api.hook_init
|
||||||
|
|
||||||
|
PATH_LUA = os.environ.get('RANGER_LUA')
|
||||||
|
PATH_ZLUA = os.environ.get('RANGER_ZLUA')
|
||||||
|
|
||||||
|
if not PATH_LUA:
|
||||||
|
for path in os.environ.get('PATH', '').split(os.path.pathsep):
|
||||||
|
for name in ('lua', 'luajit', 'lua5.3', 'lua5.2', 'lua5.1'):
|
||||||
|
test = os.path.join(path, name)
|
||||||
|
test = test + (sys.platform[:3] == 'win' and ".exe" or "")
|
||||||
|
if os.path.exists(test):
|
||||||
|
PATH_LUA = test
|
||||||
|
break
|
||||||
|
|
||||||
|
if not PATH_LUA:
|
||||||
|
sys.stderr.write('Please install lua or set $RANGER_LUA.\n')
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
if (not PATH_ZLUA) or (not os.path.exists(PATH_ZLUA)):
|
||||||
|
sys.stderr.write('Not find z.lua, please set $RANGER_ZLUA to absolute path of z.lua.\n')
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
|
||||||
|
def hook_init(fm):
|
||||||
|
def update_zlua(signal):
|
||||||
|
import os, random
|
||||||
|
os.environ['_ZL_RANDOM'] = str(random.randint(0, 0x7fffffff))
|
||||||
|
p = subprocess.Popen([PATH_LUA, PATH_ZLUA, "--add", signal.new.path])
|
||||||
|
p.wait()
|
||||||
|
if PATH_ZLUA and PATH_LUA and os.path.exists(PATH_ZLUA):
|
||||||
|
fm.signal_bind('cd', update_zlua)
|
||||||
|
return old_hook_init(fm)
|
||||||
|
|
||||||
|
ranger.api.hook_init = hook_init
|
||||||
|
|
||||||
|
class z(ranger.api.commands.Command):
|
||||||
|
def execute (self):
|
||||||
|
import sys, os, time
|
||||||
|
args = self.args[1:]
|
||||||
|
if args:
|
||||||
|
mode = ''
|
||||||
|
for arg in args:
|
||||||
|
if arg in ('-l', '-e', '-x', '-h', '--help', '--'):
|
||||||
|
mode = arg
|
||||||
|
break
|
||||||
|
elif arg in ('-I', '-i'):
|
||||||
|
mode = arg
|
||||||
|
elif arg[:1] != '-':
|
||||||
|
break
|
||||||
|
if mode:
|
||||||
|
cmd = '"%s" "%s" '%(PATH_LUA, PATH_ZLUA)
|
||||||
|
if mode in ('-I', '-i', '--'):
|
||||||
|
cmd += ' --cd'
|
||||||
|
for arg in args:
|
||||||
|
cmd += ' "%s"'%arg
|
||||||
|
if mode in ('-e', '-x'):
|
||||||
|
path = subprocess.check_output([PATH_LUA, PATH_ZLUA, '--cd'] + args)
|
||||||
|
path = path.decode("utf-8", "ignore")
|
||||||
|
path = path.rstrip('\n')
|
||||||
|
self.fm.notify(path)
|
||||||
|
elif mode in ('-h', '-l', '--help'):
|
||||||
|
p = self.fm.execute_command(cmd + '| less +G', universal_newlines=True)
|
||||||
|
stdout, stderr = p.communicate()
|
||||||
|
elif mode == '--':
|
||||||
|
p = self.fm.execute_command(cmd + ' 2>&1 | less +G', universal_newlines=True)
|
||||||
|
stdout, stderr = p.communicate()
|
||||||
|
else:
|
||||||
|
if mode == '-I':
|
||||||
|
os.environ['_ZL_FZF_HEIGHT'] = '0'
|
||||||
|
path = subprocess.check_output([PATH_LUA, PATH_ZLUA, '--cd'] + args)
|
||||||
|
self.fm.execute_console('redraw_window')
|
||||||
|
else:
|
||||||
|
p = self.fm.execute_command(cmd, universal_newlines=True, stdout=subprocess.PIPE)
|
||||||
|
stdout, stderr = p.communicate()
|
||||||
|
path = stdout.rstrip('\n')
|
||||||
|
if path and os.path.exists(path):
|
||||||
|
self.fm.cd(path)
|
||||||
|
else:
|
||||||
|
path = subprocess.check_output([PATH_LUA, PATH_ZLUA, '--cd'] + args)
|
||||||
|
path = path.decode("utf-8", "ignore")
|
||||||
|
path = path.rstrip('\n')
|
||||||
|
if path and os.path.exists(path):
|
||||||
|
self.fm.cd(path)
|
||||||
|
else:
|
||||||
|
self.fm.notify('No matching found', bad = True)
|
||||||
|
return True
|
||||||
|
|
||||||
198
z.lua
198
z.lua
@@ -4,7 +4,7 @@
|
|||||||
-- z.lua - a cd command that learns, by skywind 2018, 2019
|
-- z.lua - a cd command that learns, by skywind 2018, 2019
|
||||||
-- Licensed under MIT license.
|
-- Licensed under MIT license.
|
||||||
--
|
--
|
||||||
-- Version 1.5.5, Last Modified: 2019/02/20 12:07
|
-- Version 1.7.2, Last Modified: 2019/08/01 19:45
|
||||||
--
|
--
|
||||||
-- * 10x faster than fasd and autojump, 3x faster than z.sh
|
-- * 10x faster than fasd and autojump, 3x faster than z.sh
|
||||||
-- * available for posix shells: bash, zsh, sh, ash, dash, busybox
|
-- * available for posix shells: bash, zsh, sh, ash, dash, busybox
|
||||||
@@ -302,10 +302,107 @@ function os.log(text)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
-- ffi optimize (luajit has builtin ffi module)
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
os.native = {}
|
||||||
|
os.native.status, os.native.ffi = pcall(require, "ffi")
|
||||||
|
if os.native.status then
|
||||||
|
local ffi = os.native.ffi
|
||||||
|
if windows then
|
||||||
|
ffi.cdef[[
|
||||||
|
int GetFullPathNameA(const char *name, uint32_t size, char *out, char **name);
|
||||||
|
int ReplaceFileA(const char *dstname, const char *srcname, void *, uint32_t, void *, void *);
|
||||||
|
uint32_t GetTickCount(void);
|
||||||
|
uint32_t GetFileAttributesA(const char *name);
|
||||||
|
uint32_t GetCurrentDirectoryA(uint32_t size, char *ptr);
|
||||||
|
]]
|
||||||
|
local kernel32 = ffi.load('kernel32.dll')
|
||||||
|
local buffer = ffi.new('char[?]', 300)
|
||||||
|
local INVALID_FILE_ATTRIBUTES = 0xffffffff
|
||||||
|
local FILE_ATTRIBUTE_DIRECTORY = 0x10
|
||||||
|
os.native.kernel32 = kernel32
|
||||||
|
function os.native.GetFullPathName(name)
|
||||||
|
local hr = kernel32.GetFullPathNameA(name, 290, buffer, nil)
|
||||||
|
return (hr > 0) and ffi.string(buffer, hr) or nil
|
||||||
|
end
|
||||||
|
function os.native.ReplaceFile(replaced, replacement)
|
||||||
|
local hr = kernel32.ReplaceFileA(replaced, replacement, nil, 2, nil, nil)
|
||||||
|
return (hr ~= 0) and true or false
|
||||||
|
end
|
||||||
|
function os.native.GetTickCount()
|
||||||
|
return kernel32.GetTickCount()
|
||||||
|
end
|
||||||
|
function os.native.GetFileAttributes(name)
|
||||||
|
return kernel32.GetFileAttributesA(name)
|
||||||
|
end
|
||||||
|
function os.native.exists(name)
|
||||||
|
local attr = os.native.GetFileAttributes(name)
|
||||||
|
return attr ~= INVALID_FILE_ATTRIBUTES
|
||||||
|
end
|
||||||
|
function os.native.isdir(name)
|
||||||
|
local attr = os.native.GetFileAttributes(name)
|
||||||
|
local isdir = FILE_ATTRIBUTE_DIRECTORY
|
||||||
|
if attr == INVALID_FILE_ATTRIBUTES then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return (attr % (2 * isdir)) >= isdir
|
||||||
|
end
|
||||||
|
function os.native.getcwd()
|
||||||
|
local hr = kernel32.GetCurrentDirectoryA(299, buffer)
|
||||||
|
if hr <= 0 then return nil end
|
||||||
|
return ffi.string(buffer, hr)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
ffi.cdef[[
|
||||||
|
typedef struct { long tv_sec; long tv_usec; } timeval;
|
||||||
|
int gettimeofday(timeval *tv, void *tz);
|
||||||
|
int access(const char *name, int mode);
|
||||||
|
char *realpath(const char *path, char *resolve);
|
||||||
|
char *getcwd(char *buf, size_t size);
|
||||||
|
]]
|
||||||
|
local timeval = ffi.new('timeval[?]', 1)
|
||||||
|
local buffer = ffi.new('char[?]', 4100)
|
||||||
|
function os.native.gettimeofday()
|
||||||
|
local hr = ffi.C.gettimeofday(timeval, nil)
|
||||||
|
local sec = tonumber(timeval[0].tv_sec)
|
||||||
|
local usec = tonumber(timeval[0].tv_usec)
|
||||||
|
return sec + (usec * 0.000001)
|
||||||
|
end
|
||||||
|
function os.native.access(name, mode)
|
||||||
|
return ffi.C.access(name, mode)
|
||||||
|
end
|
||||||
|
function os.native.realpath(name)
|
||||||
|
local path = ffi.C.realpath(name, buffer)
|
||||||
|
return (path ~= nil) and ffi.string(buffer) or nil
|
||||||
|
end
|
||||||
|
function os.native.getcwd()
|
||||||
|
local hr = ffi.C.getcwd(buffer, 4099)
|
||||||
|
return hr ~= nil and ffi.string(buffer) or nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function os.native.tickcount()
|
||||||
|
if windows then
|
||||||
|
return os.native.GetTickCount()
|
||||||
|
else
|
||||||
|
return math.floor(os.native.gettimeofday() * 1000)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
os.native.init = true
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
||||||
-- get current path
|
-- get current path
|
||||||
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
||||||
function os.pwd()
|
function os.pwd()
|
||||||
|
if os.native and os.native.getcwd then
|
||||||
|
local hr = os.native.getcwd()
|
||||||
|
if hr then return hr end
|
||||||
|
end
|
||||||
|
if os.getcwd then
|
||||||
|
return os.getcwd()
|
||||||
|
end
|
||||||
if windows then
|
if windows then
|
||||||
local fp = io.popen('cd')
|
local fp = io.popen('cd')
|
||||||
if fp == nil then
|
if fp == nil then
|
||||||
@@ -372,6 +469,10 @@ end
|
|||||||
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
||||||
function os.path.abspath(path)
|
function os.path.abspath(path)
|
||||||
if path == '' then path = '.' end
|
if path == '' then path = '.' end
|
||||||
|
if os.native and os.native.GetFullPathName then
|
||||||
|
local test = os.native.GetFullPathName(path)
|
||||||
|
if test then return test end
|
||||||
|
end
|
||||||
if windows then
|
if windows then
|
||||||
local script = 'FOR /f "delims=" %%i IN ("%s") DO @echo %%~fi'
|
local script = 'FOR /f "delims=" %%i IN ("%s") DO @echo %%~fi'
|
||||||
local script = string.format(script, path)
|
local script = string.format(script, path)
|
||||||
@@ -427,13 +528,17 @@ function os.path.isdir(pathname)
|
|||||||
elseif windows then
|
elseif windows then
|
||||||
if pathname == '\\' then
|
if pathname == '\\' then
|
||||||
return true
|
return true
|
||||||
elseif pathname:match('^%a:[/\\]$') then
|
|
||||||
return true
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if os.native and os.native.isdir then
|
||||||
|
return os.native.isdir(pathname)
|
||||||
|
end
|
||||||
|
if clink and os.isdir then
|
||||||
|
return os.isdir(pathname)
|
||||||
|
end
|
||||||
local name = pathname
|
local name = pathname
|
||||||
if (not name:endswith('/')) and (not name:endswith('\\')) then
|
if (not name:endswith('/')) and (not name:endswith('\\')) then
|
||||||
name = name .. '/'
|
name = name .. os.path.sep
|
||||||
end
|
end
|
||||||
return os.path.exists(name)
|
return os.path.exists(name)
|
||||||
end
|
end
|
||||||
@@ -453,6 +558,12 @@ function os.path.exists(name)
|
|||||||
io.close(f)
|
io.close(f)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
elseif name:sub(-1) == '/' and code == 20 and (not windows) then
|
||||||
|
local test = name .. '.'
|
||||||
|
ok, err, code = os.rename(test, test)
|
||||||
|
if code == 16 or code == 13 or code == 22 then
|
||||||
|
return true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
@@ -770,6 +881,10 @@ end
|
|||||||
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
||||||
function os.environ(name, default)
|
function os.environ(name, default)
|
||||||
local value = os.getenv(name)
|
local value = os.getenv(name)
|
||||||
|
if os.envmap ~= nil and type(os.envmap) == 'table' then
|
||||||
|
local t = os.envmap[name]
|
||||||
|
value = (t ~= nil and type(t) == 'string') and t or value
|
||||||
|
end
|
||||||
if value == nil then
|
if value == nil then
|
||||||
return default
|
return default
|
||||||
elseif type(default) == 'boolean' then
|
elseif type(default) == 'boolean' then
|
||||||
@@ -863,6 +978,9 @@ function math.random_init()
|
|||||||
seed = seed .. rnd
|
seed = seed .. rnd
|
||||||
end
|
end
|
||||||
seed = seed .. tostring(os.clock() * 10000000)
|
seed = seed .. tostring(os.clock() * 10000000)
|
||||||
|
if os.native and os.native.tickcount then
|
||||||
|
seed = seed .. tostring(os.native.tickcount())
|
||||||
|
end
|
||||||
local number = 0
|
local number = 0
|
||||||
for i = 1, seed:len() do
|
for i = 1, seed:len() do
|
||||||
local k = string.byte(seed:sub(i, i))
|
local k = string.byte(seed:sub(i, i))
|
||||||
@@ -952,15 +1070,29 @@ function data_save(filename, M)
|
|||||||
local tmpname = nil
|
local tmpname = nil
|
||||||
local i
|
local i
|
||||||
filename = os.path.expand(filename)
|
filename = os.path.expand(filename)
|
||||||
if windows then
|
math.random_init()
|
||||||
fp = io.open(filename, 'w')
|
while true do
|
||||||
else
|
|
||||||
math.random_init()
|
|
||||||
tmpname = filename .. '.' .. tostring(os.time())
|
tmpname = filename .. '.' .. tostring(os.time())
|
||||||
tmpname = tmpname .. math.random_string(8)
|
if os.native and os.native.tickcount then
|
||||||
local rnd = os.getenv('_ZL_RANDOM')
|
local key = os.native.tickcount() % 1000
|
||||||
tmpname = tmpname .. '' .. (rnd and rnd or '')
|
tmpname = tmpname .. string.format('%03d', key)
|
||||||
-- print('tmpname: '..tmpname)
|
tmpname = tmpname .. math.random_string(5)
|
||||||
|
else
|
||||||
|
tmpname = tmpname .. math.random_string(8)
|
||||||
|
end
|
||||||
|
if not os.path.exists(tmpname) then
|
||||||
|
-- print('tmpname: '..tmpname)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if windows then
|
||||||
|
if os.native and os.native.ReplaceFile then
|
||||||
|
fp = io.open(tmpname, 'w')
|
||||||
|
else
|
||||||
|
fp = io.open(filename, 'w')
|
||||||
|
tmpname = nil
|
||||||
|
end
|
||||||
|
else
|
||||||
fp = io.open(tmpname, 'w')
|
fp = io.open(tmpname, 'w')
|
||||||
end
|
end
|
||||||
if fp == nil then
|
if fp == nil then
|
||||||
@@ -973,7 +1105,14 @@ function data_save(filename, M)
|
|||||||
end
|
end
|
||||||
fp:close()
|
fp:close()
|
||||||
if tmpname ~= nil then
|
if tmpname ~= nil then
|
||||||
os.rename(tmpname, filename)
|
if windows then
|
||||||
|
local ok, err, code = os.rename(tmpname, filename)
|
||||||
|
if not ok then
|
||||||
|
os.native.ReplaceFile(filename, tmpname)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
os.rename(tmpname, filename)
|
||||||
|
end
|
||||||
os.remove(tmpname)
|
os.remove(tmpname)
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
@@ -1427,6 +1566,9 @@ function z_cd(patterns)
|
|||||||
elseif Z_INTERACTIVE == 0 then
|
elseif Z_INTERACTIVE == 0 then
|
||||||
return M[1].name
|
return M[1].name
|
||||||
end
|
end
|
||||||
|
if os.environ('_ZL_INT_SORT', false) then
|
||||||
|
table.sort(M, function (a, b) return a.name < b.name end)
|
||||||
|
end
|
||||||
local retval = nil
|
local retval = nil
|
||||||
if Z_INTERACTIVE == 1 then
|
if Z_INTERACTIVE == 1 then
|
||||||
PRINT_MODE = '<stderr>'
|
PRINT_MODE = '<stderr>'
|
||||||
@@ -1454,8 +1596,9 @@ function z_cd(patterns)
|
|||||||
cmd = ((fzf == '') and 'fzf' or fzf) .. ' ' .. cmd .. ' ' .. flag
|
cmd = ((fzf == '') and 'fzf' or fzf) .. ' ' .. cmd .. ' ' .. flag
|
||||||
if not windows then
|
if not windows then
|
||||||
tmpname = os.tmpname()
|
tmpname = os.tmpname()
|
||||||
if not os.environ('_ZL_FZF_FULLSCR', false) then
|
local height = os.environ('_ZL_FZF_HEIGHT', '35%')
|
||||||
cmd = cmd .. ' --height 35%'
|
if height ~= nil and height ~= '' and height ~= '0' then
|
||||||
|
cmd = cmd .. ' --height ' .. height
|
||||||
end
|
end
|
||||||
cmd = cmd .. ' < "' .. tmpname .. '"'
|
cmd = cmd .. ' < "' .. tmpname .. '"'
|
||||||
else
|
else
|
||||||
@@ -1547,6 +1690,7 @@ function cd_backward(args, options, pwd)
|
|||||||
end
|
end
|
||||||
return os.path.normpath(path)
|
return os.path.normpath(path)
|
||||||
else
|
else
|
||||||
|
pwd = os.path.split(pwd)
|
||||||
local test = windows and pwd:gsub('\\', '/') or pwd
|
local test = windows and pwd:gsub('\\', '/') or pwd
|
||||||
local key = windows and args[1]:lower() or args[1]
|
local key = windows and args[1]:lower() or args[1]
|
||||||
if not key:match('%u') then
|
if not key:match('%u') then
|
||||||
@@ -1725,11 +1869,8 @@ function z_init()
|
|||||||
DATA_FILE = _zl_data
|
DATA_FILE = _zl_data
|
||||||
else
|
else
|
||||||
-- avoid windows environments affect cygwin & msys
|
-- avoid windows environments affect cygwin & msys
|
||||||
if _zl_data:sub(2, 2) ~= ':' then
|
if not string.match(_zl_data, '^%a:[/\\]') then
|
||||||
local t = _zl_data:sub(3, 3)
|
DATA_FILE = _zl_data
|
||||||
if t ~= '/' and t ~= "\\" then
|
|
||||||
DATA_FILE = _zl_data
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -1869,14 +2010,14 @@ alias ${_ZL_CMD:-z}='_zlua'
|
|||||||
local script_init_bash = [[
|
local script_init_bash = [[
|
||||||
case "$PROMPT_COMMAND" in
|
case "$PROMPT_COMMAND" in
|
||||||
*_zlua?--add*) ;;
|
*_zlua?--add*) ;;
|
||||||
*) PROMPT_COMMAND="(_zlua --add \"\$(command pwd 2>/dev/null)\" &);$PROMPT_COMMAND" ;;
|
*) PROMPT_COMMAND="(_zlua --add \"\$(command pwd 2>/dev/null)\" &)${PROMPT_COMMAND:+;$PROMPT_COMMAND}" ;;
|
||||||
esac
|
esac
|
||||||
]]
|
]]
|
||||||
|
|
||||||
local script_init_bash_fast = [[
|
local script_init_bash_fast = [[
|
||||||
case "$PROMPT_COMMAND" in
|
case "$PROMPT_COMMAND" in
|
||||||
*_zlua?--add*) ;;
|
*_zlua?--add*) ;;
|
||||||
*) PROMPT_COMMAND="(_zlua --add \"\$PWD\" &);$PROMPT_COMMAND" ;;
|
*) PROMPT_COMMAND="(_zlua --add \"\$PWD\" &)${PROMPT_COMMAND:+;$PROMPT_COMMAND}" ;;
|
||||||
esac
|
esac
|
||||||
]]
|
]]
|
||||||
|
|
||||||
@@ -1888,7 +2029,7 @@ _zlua_precmd() {
|
|||||||
}
|
}
|
||||||
case "$PROMPT_COMMAND" in
|
case "$PROMPT_COMMAND" in
|
||||||
*_zlua_precmd*) ;;
|
*_zlua_precmd*) ;;
|
||||||
*) PROMPT_COMMAND="_zlua_precmd;$PROMPT_COMMAND" ;;
|
*) PROMPT_COMMAND="_zlua_precmd${PROMPT_COMMAND:+;$PROMPT_COMMAND}" ;;
|
||||||
esac
|
esac
|
||||||
]]
|
]]
|
||||||
|
|
||||||
@@ -1915,7 +2056,7 @@ local script_init_zsh = [[
|
|||||||
_zlua_precmd() {
|
_zlua_precmd() {
|
||||||
(_zlua --add "${PWD:a}" &)
|
(_zlua --add "${PWD:a}" &)
|
||||||
}
|
}
|
||||||
typeset -gaU precmd_functions
|
typeset -ga precmd_functions
|
||||||
[ -n "${precmd_functions[(r)_zlua_precmd]}" ] || {
|
[ -n "${precmd_functions[(r)_zlua_precmd]}" ] || {
|
||||||
precmd_functions[$(($#precmd_functions+1))]=_zlua_precmd
|
precmd_functions[$(($#precmd_functions+1))]=_zlua_precmd
|
||||||
}
|
}
|
||||||
@@ -1925,7 +2066,7 @@ local script_init_zsh_once = [[
|
|||||||
_zlua_precmd() {
|
_zlua_precmd() {
|
||||||
(_zlua --add "${PWD:a}" &)
|
(_zlua --add "${PWD:a}" &)
|
||||||
}
|
}
|
||||||
typeset -gaU chpwd_functions
|
typeset -ga chpwd_functions
|
||||||
[ -n "${chpwd_functions[(r)_zlua_precmd]}" ] || {
|
[ -n "${chpwd_functions[(r)_zlua_precmd]}" ] || {
|
||||||
chpwd_functions[$(($#chpwd_functions+1))]=_zlua_precmd
|
chpwd_functions[$(($#chpwd_functions+1))]=_zlua_precmd
|
||||||
}
|
}
|
||||||
@@ -1997,9 +2138,10 @@ function z_shell_init(opts)
|
|||||||
end
|
end
|
||||||
print(script_complete_bash)
|
print(script_complete_bash)
|
||||||
if opts.fzf ~= nil then
|
if opts.fzf ~= nil then
|
||||||
fzf_cmd = "fzf --nth 2 --reverse --inline-info --tac "
|
fzf_cmd = "fzf --nth 2.. --reverse --inline-info --tac "
|
||||||
if not os.environ('_ZL_FZF_FULLSCR', false) then
|
local height = os.environ('_ZL_FZF_HEIGHT', '35%')
|
||||||
fzf_cmd = fzf_cmd .. ' --height 35%'
|
if height ~= nil and height ~= '' and height ~= '0' then
|
||||||
|
fzf_cmd = fzf_cmd .. ' --height ' .. height .. ' '
|
||||||
end
|
end
|
||||||
local flag = os.environ('_ZL_FZF_FLAG', '')
|
local flag = os.environ('_ZL_FZF_FLAG', '')
|
||||||
flag = (flag == '' or flag == nil) and '+s -e' or flag
|
flag = (flag == '' or flag == nil) and '+s -e' or flag
|
||||||
|
|||||||
@@ -6,14 +6,14 @@ ZLUA_SCRIPT="${0:A:h}/z.lua"
|
|||||||
|
|
||||||
# search lua executable
|
# search lua executable
|
||||||
if [[ -z "$ZLUA_EXEC" ]]; then
|
if [[ -z "$ZLUA_EXEC" ]]; then
|
||||||
if [[ -x "$(which lua)" ]]; then
|
if [[ -x "$(command which lua)" ]]; then
|
||||||
ZLUA_EXEC="$(which lua)"
|
ZLUA_EXEC="$(command which lua)"
|
||||||
elif [[ -x "$(which lua5.3)" ]]; then
|
elif [[ -x "$(command which lua5.3)" ]]; then
|
||||||
ZLUA_EXEC="$(which lua5.3)"
|
ZLUA_EXEC="$(command which lua5.3)"
|
||||||
elif [[ -x "$(which lua5.2)" ]]; then
|
elif [[ -x "$(command which lua5.2)" ]]; then
|
||||||
ZLUA_EXEC="$(which lua5.2)"
|
ZLUA_EXEC="$(command which lua5.2)"
|
||||||
elif [[ -x "$(which lua5.1)" ]]; then
|
elif [[ -x "$(command which lua5.1)" ]]; then
|
||||||
ZLUA_EXEC="$(which lua5.1)"
|
ZLUA_EXEC="$(command which lua5.1)"
|
||||||
else
|
else
|
||||||
echo "Not find lua in your $PATH, please install it."
|
echo "Not find lua in your $PATH, please install it."
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user