当我向命令添加包装器时,Zsh 自动完成功能会中断

当我向命令添加包装器时,Zsh 自动完成功能会中断

例如我有一个测试app可执行文件

#!/bin/bash
case $1 in
  (foo)
    echo "selected foo"
    ;;
  (bar)
    echo "selected bar"
    ;;
esac

fpath 中包含了一个简单的补全功能

#compdef app
local -a subcmds
subcmds=('foo:show foo' 'bar:show bar')
_describe 'app' subcmds

运行正常。现在我想制作一个包装器,将子命令添加到应用程序

__app_wrapper () {
    if [[ "$1" == baz ]]; then
        echo "selected baz"
    else
        command app "$@"
    fi
}

alias app=__app_wrapper

一旦我source这样做了,子命令就可以正常工作,但自动完成会切换到使用当前目录中的文件完成,而不是我的完成脚本提供的文件。为什么会这样,如何修复它?是因为应用程序现在是函数而不是可执行文件吗?

我实际上正在尝试使用一种更复杂的完成脚本,docker-machine但我能够将我的问题简化为这个例子。

答案1

解决方案是使用compdef,这是我最终得到的结果(针对我的真实情况):

#
# Function wrapper to docker-machine that adds a use subcommand.
#
# The use subcommand runs `eval "$(docker-machine env [args])"`, which is a lot
# less typing.
#
# To enable:
#  1a. Copy this file somewhere and source it in your .bashrc
#      source /some/where/docker-machine-wrapper.bash
#  1b. Alternatively, just copy this file into into /etc/bash_completion.d
#
# Configuration:
#
# DOCKER_MACHINE_WRAPPED
#   When set to a value other than true, this will disable the alias wrapper
#   alias for docker-machine. This is useful if you don't want the wrapper,
#   but it is installed by default by your installation.
#

: ${DOCKER_MACHINE_WRAPPED:=true}

__docker_machine_wrapper () {
    if [[ "$1" == use ]]; then
        # Special use wrapper
        shift 1
        case "$1" in
            -h|--help|"")
                cat <<EOF
Usage: docker-machine use [OPTIONS] [arg...]
Evaluate the commands to set up the environment for the Docker client
Description:
   Argument is a machine name.
Options:
   --swarm  Display the Swarm config instead of the Docker daemon
   --unset, -u  Unset variables instead of setting them
EOF
                ;;
            *)
                eval "$(docker-machine env "$@")"
                echo "Active machine: ${DOCKER_MACHINE_NAME}"
                ;;
        esac
    elif [[ "$1" == "--help" || "$1" == "-h" ]]; then
    command docker-machine "$@"
        echo "  use         Get the URL of a machine"
    else
        # Just call the actual docker-machine app
        command docker-machine "$@"
    fi
}

if [[ ${DOCKER_MACHINE_WRAPPED} = true ]]; then
    alias docker-machine=__docker_machine_wrapper
    compdef __docker_machine_wrapper=docker-machine
fi

此外,我还编辑了实际的完成文件以显示机器名称

相关内容