为什么我需要使用“cdablevars”变量才能完成制表符?

为什么我需要使用“cdablevars”变量才能完成制表符?

我正在尝试使用cdablevars,将其设置在我的.zshrc文件中

# Set directory variables
setopt cdablevars
Home=/Users/benjamin

但是,我需要先执行cd Home,或者简单地假装使用它而不执行(例如,仅键入cd Home/Desktop/),然后才能完成制表符。

在此输入图像描述

在第一个终端窗口中Home无法使用制表符完成。只有在我执行之后cd Home。我可以设置变量以便自动识别制表符补全吗?

答案1

/内置函数_cd的完成者将提供cdpushd命名目录已添加到命名目录哈希表(参见hash -d$nameddirs关联数组)。

当您引用那些命名的目录时,这些内容就会被填充。即使您运行hash -df完全构建命名目录散列,它也只会添加~user条目(如文档所述)。

典型的zsh交互式会话将具有数百个全局变量,其中大多数并不意味着包含目录。提供它们作为完成会适得其反。

另请注意,这cdablevars更多的是历史文物,主要是为了容纳来自tcsh并导致许多问题(包括超出预期)的用户。我个人会远离它。看zsh 对路径进行评估时速度很慢了解更多相关信息。

但无论如何,即使cd ~HoTab(使用~... 明确地IMO 更好)无论有或没有cdablevars都不会完成,除非Home添加到命名目录哈希表。

尽管如此,如果您愿意,您仍然可以使用hash -d包含hash -d ${(k)parameters}.

答案2

为什么完成并不总是有效

具体效果是cdable_vars是它允许cd foo作为 的快捷方式cd ~foo波形符扩展是什么允许~foo代表$foowhenfoo是一个值以斜线开头的变量。

完成代码~foo实际上并不识别参数。您可以在不使用命令的情况下重现问题cd:第一次echo ~fTab不会完成~foo,但是一旦运行此命令,它就会完成。

它第二次起作用的原因是成功使用~foo添加foo命名目录哈希表(可通过以下方式访问nameddirs大批),这就是完成代码所~foo查找的内容。

如何使其适用于特定变量

foo定义包含绝对路径的变量后,运行

hash -d foo=$foo

如果值发生变化,则无需再次运行此命令foo

如何让它自动工作

我能想到的唯一方法是修补_tilde以支持参数名称作为命名目录,通过完成代码或强制将它们添加到命名目录哈希表中。

未经测试:修改_tilde以强制将条目添加到nameddirs

if [[ -o cdable_vars ]]; then
  local p
  for p in ${(k)parameters[(R)scalar*]}; do
    if [[ ${(P)p} == /* ]]; then : ~$p 2>/dev/null; fi
  done
fi

相关内容