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

Rad*_*Rad 16 zsh tab-completion zshrc

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

假设我们有两个脚本(源自 参考资料~/.zshrc),它们为 ZSH 设置一些完成逻辑。现在根据我所了解到的,在脚本中的某个时刻,您需要像这样调用compinitbashcompinit从 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
Run Code Online (Sandbox Code Playgroud)

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

complete -W "hello world" one
one <tab>   # to see autocomplete working
compinit 
one <tab>   # to see autocomplete NOT working
Run Code Online (Sandbox Code Playgroud)

有人提出了(这里)类似下面的方法来解决这个问题(通过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
Run Code Online (Sandbox Code Playgroud)

另一个想法可能是调用compinitbashcompinit不是在自定义完成脚本中,而是在~/.zshrc(这会损害 NVM 等工具的自动安装过程)。

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

谢谢。

Mar*_*ert 23

安装本机 Zsh 补全

\n
\n

假设我们有两个脚本(源自 参考资料~/.zshrc),它们为 ZSH 设置一些完成逻辑。现在根据我所了解到的,在脚本中的某个时刻您需要调用compinitbashcompinit

\n
\n

不,这不是你的脚本应该做的。不是您的脚本,但用户应该compinit(在他们的.zshrc文件中)调用以启用Zsh\ 的更高级完成系统。\n此外,每个 shell 实例只应调用一次。

\n

Zsh 中默认启用一个更基本的、类似 Bash 的补全系统,但它几乎已被弃用不要\xe2\x80\x99打扰它;绝大多数用户都compinit在他们的点文件中,这提供了更好的用户体验,即使默认情况下未启用它。是的,Zsh 以向后兼容性的名义提供了糟糕的、过时的默认设置。不幸的是,几乎所有新功能都是选择加入的。

\n

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

\n
    \n
  1. 检查您是否可以写入该目录,因为默认情况下/usr/local/share/zsh/site-functions每个 Zsh 用户的目录中都有该目录。\n$fpath
      \n
    • 如果可以的话,请在此目录中创建指向每个完成函数的符号链接。
    • \n
    • 如果不能,请告诉用户将以下内容添加到他们的.zshrc文件中:\n
      fpath=(\n    /path/to/dir/containing/your/completion/functions \n    $fpath\n)\n
      Run Code Online (Sandbox Code Playgroud)\n
    • \n
    \n
  2. \n
  3. 告诉用户确保在按照给定的顺序设置,之后从他们的文件(或他们从那里.zshrc编写的脚本)调用以下内容:\nsource$fpath
    fpath=(\n    /path/to/dir/containing/your/completion/functions \n    $fpath\n)\n
    Run Code Online (Sandbox Code Playgroud)\n许多 Zsh 框架和插件管理器都包含启动时的调用compinitcompinit多次调用会显着增加启动时间并擦除以编程方式添加的完成功能。您可能想让您的用户意识到这一点,以避免不必要的错误报告。
  4. \n
\n

compinit然后会自动从 user\xe2\x80\x99s 中获取完成函数$fpath

\n

在 Zsh 中安装 Bash 补全

\n
\n

显然,根据 ZSH 手册,bashcompinit必须在 , 之后调用compinit(不确定是否相关)。

\n
\n

是的,它是相关的,但不是,不是你想象的那样。除其他外,bashcompinit定义了函数complete,它模拟 Bash\xe2\x80\x99scomplete内置功能,可用于将 Bash 补全添加到 Zsh。就像compinit,bashcompinit意味着每个 shell 只能调用一次。

\n

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

\n
    \n
  1. 告诉用户确保按照给定的顺序从他们的 Zsh 点文件中调用以下命令:\n
    autoload -Uz compinit bashcompinit\ncompinit\nbashcompinit\n
    Run Code Online (Sandbox Code Playgroud)\n
  2. \n
  3. 告诉他们然后按照与在 Bash 中安装补全相同的说明进行操作。
  4. \n
\n

不过, Zsh 的补全比 Bash\xe2\x80\x99s 更丰富、更强大。只要有可能,我建议提供原生 Zsh 补全函数。这是关于如何编写 Zsh 补全函数的很好指南。

\n