dirs-stack
我编写了一个简单的 zsh 函数,它允许我从via中进行选择fzf
。
我的.zshrc
样子
DIRSTACKSIZE='99'
setopt PUSHD_IGNORE_DUPS
# change to directory from the dirs stack
fzf-change-dirstack () {
cd "$(dirs -lv | cut -f2 | fzf )"
}
zle -N fzf-change-dirstack
bindkey '^[p' fzf-change-dirstack # shortcut ALT+P
即使需要进行一些改进,它也能正常工作。唯一对我来说非常烦人的是,当我使用键绑定时,我必须输入Enter两次才能更改到目录。
如何cd
立即修改脚本而无需再次输入两次Enter?
答案1
fzf-change-dirstack () {
local dir
print -rNC1 -- $dirstack |
fzf --read0 --print0 |
IFS= read -rd '' dir &&
cd -- $dir &&
zle -I
}
zle -N fzf-change-dirstack
bindkey '^[p' fzf-change-dirstack # shortcut ALT+P
要点是当当前工作目录更改时zle -I
使I
提示无效,其余部分修复代码中的一些其他问题,以便它可以使用任意目录名称。
尤其:
dirs -lv | cut -f2
如果这些目录名称中的任何一个包含换行符或制表符,则会失败。更一般地,文件路径可以是任何非空字节序列。因此,要传递给fzf
,您需要使用它--read0
并提供一个空分隔列表(此处print
为olumn上的r
awN
ull-delimited )。1
C
- 如果您忘记了
--
,那么任何以 开头的目录-
都会出现问题(如果没有之前的错误,通常不会发生)。忘记它print
甚至会引入命令注入漏洞。 - 不要忘记错误处理!
cd +
Tab 另请注意,当您完成或只是~+
Tab完成 dirstack 元素作为任何命令的参数(而不仅仅是cd
/ pushd
)时,zsh 已经有自己的 dirstack 完成器。
例如,尝试cd +
TabTab以下操作:
zstyle ':completion:*' format 'Completing %d'
zstyle ':completion:*' menu select=2
autoload compinit
compinit
并使用箭头键导航。
(您通常使用这种设置进行调整compinstall
)
cd
不幸的是,For--
并不能解决所有问题。-
,,+1
比如-1
仍然受到特殊对待cd
。这些不会作为 的元素出现,但可能作为like after$dirstack
的输出中某行的第二个制表符分隔字段出现。dirs -lv
cd $'foo\nx\t+1\twhatever'