Bash 补全在 ZSH/Oh-My-ZSH 中不起作用,因为 COMP_WORDS 不是数组

Bash completion does not work in ZSH/Oh-My-ZSH because COMP_WORDS is not an array

我正在编写一个 bash 命令行工具,我想使用 completely.

为其启用 bash 完成

我有以下 bash 完成。在我 eval "$(./cli completion)" (输出以下内容)之后,完成在 bash:

中工作正常
#!/usr/bin/env bash

# This bash completions script was generated by
# completely (https://github.com/dannyben/completely)
# Modifying it manually is not recommended
_cli_completions() {
  local cur=${COMP_WORDS[COMP_CWORD]}
  local comp_line="${COMP_WORDS[*]:1}"

  case "$comp_line" in
    'completions'*) COMPREPLY=($(compgen -W "--help -h" -- "$cur")) ;;
    'download'*) COMPREPLY=($(compgen -W "--force --help -f -h" -- "$cur")) ;;
    ''*) COMPREPLY=($(compgen -W "--help --version -h -v completions download" -- "$cur")) ;;
  esac
}

complete -F _cli_completions cli

但是,它们在 ZSH 中无法正常工作。我发现问题是当我在 ZSH 中时 COMP_WORDS 不是数组,但它在 bash 中。这然后打破行 local comp_line="${COMP_WORDS[*]:1}".

例如在 ./cli download <tab> 的情况下,comp_line 应该是 download,但在 ZSH 中它是 /cli download(只有 . 被删除),所以我总是在最后一个案例 ''*.

我将 ZSH 5.8 与 Oh-My-ZSH 一起使用。 Bash 补全通常似乎在 ZSH 中有效。 Oh-My-ZSH 使用

设置补全
fpath=($ZSH/functions $ZSH/completions $fpath)
autoload -U compaudit compinit

我试过设置setopt shwordsplit,希望这样会使COMP_WORDS被当作一个数组来处理,但是没有效果。

是否有我可以更改的 ZSH 配置以使此完成脚本工作? 或者是否对完成脚本进行了 bash 兼容的更改,使其在两个 shell 中都能正常工作?

此问题在 this Github ticket 中讨论。

ZSH 应该完全能够处理 bash 完成,当它被配置为通过在 ~/.zshrc:

中添加这两行时
# Load bash completion functions
autoload -Uz +X compinit && compinit
autoload -Uz +X bashcompinit && bashcompinit

此外,完全gem生成的问题脚本似乎有问题。

在下面的行中用 @ 替换 * 似乎可以让它在 bash 和 zsh 上工作。

local comp_line="${COMP_WORDS[*]:1}"   # broken
local comp_line="${COMP_WORDS[@]:1}"   # works