如何在 zsh 中正确调用 compinit(和 bashcompinit)

问题描述 投票: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个回答
14
投票

安装本机 Zsh 补全

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

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

不,那不是你的脚本应该做的。不是您的脚本,而是 user 应该调用

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


旁注

Zsh 中默认启用了一个更基本的、类似 Bash 的完成系统,但它几乎已被弃用烦它;绝大多数用户的点文件中都有

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


是向 Zsh 添加本机完成功能的正确方法:

  1. /usr/local/share/zsh/site-functions
    (默认情况下在每个Zsh用户的
    $fpath
    中),为每个完成函数创建符号链接。
  2. 告诉用户确保按照给定的顺序从他们的 Zsh 点文件中调用以下内容:
    autoload -Uz compinit
    compinit
    

compinit
然后会自动从用户的
$fpath
中获取您的完成功能。

在 Zsh 中安装 Bash 补全

显然,根据 ZSH 手册,

bashcompinit
必须在
compinit
之后调用,(不确定是否相关)。

是的,它是相关的,但不,不是你认为的那样。除其他事项外,

bashcompinit
定义了函数
complete
,它模拟 Bash 的
complete
内置函数,可用于将 Bash 补全添加到 Zsh。像
compinit
一样,
bashcompinit
意味着每个 shell 只调用一次。

如果您的软件包仅提供 Bash 补全,那么您可以执行以下操作在 Zsh 中安装它们:

  1. 告诉用户确保按照给定的顺序从他们的 Zsh 点文件中调用以下内容:
    autoload -Uz compinit bashcompinit
    compinit
    bashcompinit
    
  2. 告诉他们然后按照与在 Bash 中安装完成的相同说明进行操作。

然而, Zsh 的完成比 Bash 的丰富和强大得多。只要有可能,我建议提供一个本地 Zsh 完成函数。这是关于 如何编写 Zsh 完成函数.

的好指南
© www.soinside.com 2019 - 2024. All rights reserved.