如何在zsh中正确安装新的补全?

问题描述 投票:0回答:1

整个问题在这里这里讨论。由于参与这些讨论的人都没有 100% 确定这个问题,因此我在此寻求帮助。 (为了完整起见,我将从头开始。)

假设我们有两个脚本(源自

~/.zshrc
)为 ZSH 设置一些完成逻辑。现在根据我所了解到的,在脚本中的某个时刻,您需要像这样调用
compinit
bashcompinit
(从 NVM 完成脚本复制)

if [[ -n ${ZSH_VERSION-} ]]; then
  autoload -U +X compinit && if [[ ${ZSH_DISABLE_COMPFIX-} = true ]]; then
    compinit -u
  else
    compinit
  fi
  autoload -U +X bashcompinit && bashcompinit
fi

显然,根据ZSH手册,

bashcompinit
必须在
compinit
之后调用,(不确定是否相关)。现在的问题是,当第二个脚本调用
compinit
时,来自第一个脚本的逻辑就消失了(即第一个脚本的完成不可用)。重现此问题的一个简单片段是(从here复制):

complete -W "hello world" one
one <tab>   # to see autocomplete working
compinit 
one <tab>   # to see autocomplete NOT working

有人提出(here)类似下面的方法来解决问题(通过在调用之前检查

compinit
是否已经被调用):

if [[ -n ${ZSH_VERSION-} ]]; then
  if ! command -v compinit > /dev/null; then
    autoload -U +X compinit && if [[ ${ZSH_DISABLE_COMPFIX-} = true ]]; then
      compinit -u
    else
      compinit
    fi
  fi
  autoload -U +X bashcompinit && bashcompinit
fi

另一个想法可能是不在自定义完成脚本中调用

compinit
bashcompinit
,而是在
~/.zshrc
中调用(这会损害 NVM 等工具的自动化安装过程)。

我想知道一般情况下设置完成的正确方法是什么(或者特别是关于调用

compinit
)。

谢谢。

zsh zshrc tab-completion
1个回答
19
投票

安装原生 Zsh 补全

假设我们有两个脚本(源自

~/.zshrc
)为 ZSH 设置一些完成逻辑。现在根据我所了解到的,在脚本中的某个时刻您需要调用
compinit
bashcompinit

不,这不是你的脚本应该做的。不是您的脚本,但用户应该调用

compinit
(在他们的
.zshrc
文件中)以启用Zsh更高级的完成系统。 此外,对于每个 shell 实例,应该“仅调用一次”。

旁注
Zsh 中默认启用更基本的、类似 Bash 的补全系统,但它已经被弃用了。

打扰它;绝大多数用户的点文件中都有 compinit,这提供了更好的用户体验,即使默认情况下未启用它。是的,Zsh 以向后兼容性的名义提供了糟糕的、过时的默认值。不幸的是,几乎所有新功能都是可选的。

是将本机补全功能添加到 Zsh 的正确方法:

检查您是否可以写入目录
    /usr/local/share/zsh/site-functions
  1. ,因为默认情况下每个 Zsh 用户的

    $fpath

     中都有该目录。
    如果可以的话,请在此目录中创建指向每个补全函数的符号链接。

      如果不能,请告诉用户将以下内容添加到他们的
    • .zshrc
    • 文件中:
    • fpath=( /path/to/dir/containing/your/completion/functions $fpath )
      
      
      
      
    告诉用户确保从他们的 Zsh 点文件中调用以下内容(按照给定的顺序):
  2. autoload -Uz compinit compinit

    旁注
    许多 Zsh 框架和插件管理器在启动时都会调用
    compinit。多次调用

    compinit

     会显着增加启动时间,并删除以编程方式添加的完成功能。您可能想让您的用户意识到这一点,以避免不必要的错误报告。

    然后,

  3. compinit
会自动从用户的

$fpath

 中获取您的补全功能。
在 Zsh 中安装 Bash 补全

显然,根据ZSH手册,

bashcompinit
必须在

compinit

之后调用,(不确定是否相关)。
是的,它是相关的,但不,不是你想象的那样。除此之外,

bashcompinit
定义了函数

complete

,它模拟 Bash 的 
complete
 内置函数,可用于将 Bash 补全添加到 Zsh。与 
compinit
 一样,
bashcompinit
 每个 shell 只能调用一次。
如果您的软件包仅提供 Bash 补全,那么您可以执行以下操作将它们安装在 Zsh 中:

告诉用户确保按照给定的顺序从他们的 Zsh 点文件中调用以下内容:

autoload -Uz compinit bashcompinit compinit bashcompinit
  1. 告诉他们然后按照与在 Bash 中安装补全相同的说明进行操作。
  2. 但是,
Zsh 的完成度比 Bash 更丰富、更强大。只要有可能,我建议提供原生 Zsh 补全函数。这是关于

如何编写 Zsh 补全函数的很好指南。

© www.soinside.com 2019 - 2024. All rights reserved.