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

Nic*_*las 2 bash zsh bash-completion oh-my-zsh

我正在编写一个 bash 命令行工具,我想使用完全启用 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
Run Code Online (Sandbox Code Playgroud)

然而,它们在 ZSH 中无法正常工作。我发现问题在于,COMP_WORDS当我在 ZSH 中时,它不是一个数组,而是在 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
Run Code Online (Sandbox Code Playgroud)

我尝试过设置setopt shwordsplit,希望这会导致COMP_WORDS被视为数组,但没有效果。

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

Dan*_*nyB 6

此 Github 票证中讨论了此问题。

当 ZSH 配置为通过在以下位置添加以下两行来处理 bash 完成时,它应该完全能够处理 bash 完成~/.zshrc

# Load bash completion functions
autoload -Uz +X compinit && compinit
autoload -Uz +X bashcompinit && bashcompinit
Run Code Online (Sandbox Code Playgroud)

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

在下面的行中替换*@似乎使其在 bash 和 zsh 上都可以工作。

local comp_line="${COMP_WORDS[*]:1}"   # broken
local comp_line="${COMP_WORDS[@]:1}"   # works
Run Code Online (Sandbox Code Playgroud)

此更改现在是 bashly 和完全宝石的一部分。