我有以下 zsh 函数,它允许我使用vared
内置的 ZLE 编辑符号链接。
function lned {
emulate zsh
setopt err_return extended_glob local_options local_traps
local -a data
link_path=${1%%/##}
zstat -A data -L +link $link_path
target=$data[1]
if [[ -z $target ]]; then
print -rl 1>&2 "$link_path: not a symbolic link"
return 2
fi
vared -p "${(q)1} -> " target
if [[ -n $target && "$target" != "$data[1]" ]]; then
# We can't use 'ln -sf' if $link_path is a symlink to a directory, so remove
# it manually first.
# Check that this is still a symlink, in case the file was changed while we
# were editing (this leaves only a very small time interval where we might
# remove a non-symlink).
rm -- $link_path(@)
ln -s -- $target $link_path
fi
}
这很好,但是当我在当前目录以外的目录中编辑相对符号链接时,文件名补全相对于错误的目录。我想解决这个问题。
我可以pushd -- $link_path:h/
在打电话之前vared
和popd
之后跑步。但是,如果用户在错误的时刻按Ctrl+中断 shell,则这不会恢复当前目录。C这可以通过完全正确地设置陷阱来解决,并且可能使用cd
而不是pushd
,这对于避免必须检测链接是否在当前目录中也可能很有用(在这种情况下pushd
不会推送任何内容)。
我想尽量减少目录更改造成的破坏,这意味着还要在本地关闭chpwd
、恢复OLDPWD
,也许还有更多我没有想到的事情。另外,如果我没有权限返回cd
当前目录,我就会陷入困境——这是一种非常罕见的情况,但我更愿意支持它。
如果我可以简单地设置一下,那就更简单了vared
文件在调用过程中相对于不同的目录完成。我怎样才能做到这一点?如果这是不可能的,那么最小化临时目录更改的影响的最佳方法是什么?
答案1
在您的函数中lned
,在调用之前添加以下内容vared
:
local curcontext=lned:::
_lned
将以下内容放入您的名为的文件中$fpath
:
#autoload
_files -W $link_path:h/
然后将其添加到您的~/.zshrc
:
zstyle ':completion:lned:*' completer _lned
现在它按预期工作了。