사용자 정의 명령에 대한 동적 zsh 자동 완성

사용자 정의 명령에 대한 동적 zsh 자동 완성

제가 작성한 몇몇 사용자 정의 함수에 대한 완성 함수를 작성하려고 하는데, 가장 기본적인 것조차 하기가 정말 어려운 것 같습니다.

예제 함수는 다음과 같습니다:

function eb_instances() {
    if [ "$#" -ne 2 ]; then
        echo "Usage eb_instances <aws profile name> <environment name>"
        echo "e.g.:"
        echo " eb_instances production kraken-prod-api"
        return 1
    fi

    aws ec2 describe-instances --filters  "Name=instance-state-name,Values=running"   "Name=tag:Name,Values=$2" --profile=$1 --output=json | jq -r ".Reservations[].Instances[].PrivateIpAddress"
}

이는 두 개의 위치 매개변수를 사용하며 <aws profile name>,<environment name>

<aws profile name>완료 옵션을 실행하여 동적으로 사용하고, 완료 옵션을 호출하는 다른 함수를 실행하여 동적으로 사용하고 싶습니다 sed -n -E 's/\[([a-zA-Z0-9_\-]+)\]/\1/p' ~/.aws/credentials | tr \\n ' '.<environment name>eb_names

문서가 매우 부족하고 이해하기 어렵다는 것을 알았습니다. 비슷한 명령에 대한 zsh-completions 저장소도 보았지만 필요한 것과 비슷한 것을 찾을 수 없는 것 같습니다.

시작하는 데 도움을 주시면 대단히 감사하겠습니다!

고쳐 쓰다

기반으로@cuonglm의 답변, 나는 다음을 사용했습니다 :

#compdef ebinstances

_ebinstances() {
  local state

  _arguments \
    '1: :->aws_profile'\
    '*: :->eb_name'

  case $state in
    (aws_profile) _arguments '1:profiles:($(sed -n -E "s/\[([a-zA-Z0-9_\-]+)\]/\1/p" ~/.aws/credentials | tr \\n " "))' ;;
              (*) compadd "$@" foo bar
  esac
}

_ebinstances "$@"

원래 질문에서 언급하지 않은 것은 두 번째 매개변수의 완성이 첫 번째 매개변수에 따라 달라지기를 원한다는 것입니다(둘 다 일부 코드를 동적으로 실행하는 것을 기반으로 함). 예를 들면 다음과 같습니다.

$ eb_instances <cursor>TAB
cuonglm  test

내가 원하는 마무리를 얻으세요. 첫 번째 항목을 선택하고 자동 완성을 시도하면 다음과 같습니다.

$ eb_instances cuonglm <cursor>TAB

실행을 통해 완료 옵션을 생성하고 싶습니다. eb_names cuonglm가능한 경우 완료를 자세히 살펴보겠습니다. 예를 들어 올바른 후보가 다음과 같은 경우입니다 foo-bar.

$ eb_instances cuonglm foo<cursor>TAB

실행하여 완료 옵션을 생성하고 싶습니다.eb_names cuonglm foo

답변1

처음에는,zsh 완성 시스템매우 복잡하고 마스터하기 어려운 것 같습니다. 예를 들어 보겠습니다.

가장 먼저 알아야 할 것은 zsh완성 시스템이 완성 기능을 로드한다는 것입니다 $fpath. 완료 디렉토리가 다음에 나타나는지 확인하십시오.

print -rl -- $fpath

(사용중인 경우아 맙소사, .oh-my-zsh/completions은 에 있습니다 $fpath. 그것을 만들고 거기에 완성 기능을 넣기만 하면 됩니다. )

이제 함수에 대한 완료 파일을 생성해야 합니다. 이름은 _밑줄( )과 함수 이름으로 시작해야 합니다. 귀하의 예에서 이름은 입니다 _eb_instances.

_eb_instances파일 에 다음 줄을 추가합니다 .

#compdef eb_instances

_eb_instances() {
  local state

  _arguments \
    '1: :->aws_profile'\
    '*: :->eb_name'

  case $state in
    (aws_profile) _arguments '1:profiles:(cuonglm test)' ;;
              (*) compadd "$@" prod staging dev
  esac
}

_eb_instances "$@"

이제 끝났습니다. 파일을 저장하고 새 세션을 시작하여 완료를 테스트합니다. 다음과 같은 내용이 표시됩니다.

$ eb_instances <cursor>TAB
cuonglm  test

$ eb_instances cuonglm <cursor>TAB
dev      prod     staging

_arguments함수 및 변수에 대한 zsh 완성 시스템 문서를 읽을 수 있습니다 state. 또한 (cuonglm test)명령 을 변경하고 기능 을 sed변경 해야 합니다 .prod staging deveb_names

전달된 첫 번째 매개변수를 기반으로 두 번째 매개변수를 생성하려면 다음 $words[2]변수를 사용할 수 있습니다.

case $state in
  (aws_profile) _arguments '1:profiles:(cuonglm test)' ;;
            (*) compadd "$@" $(echo $words[2]) ;;
esac

echo실제 기능으로 바꾸십시오 . 당신이 생각하는 한 그것은 입니다 $(eb_names $words[2]).

여전히 문제가 있는 경우 호출 완료의 합계를 다음 _eb_instances과 같이 정의하세요.eb_instances.zshrc

compdef _eb_instances eb_instances

다음 명령을 사용하여 시스템을 초기화해야 합니다.

autoload -U compinit
compinit

(사용하신 경우 oh-my-zsh이미 로드되어 있습니다.)

관련 정보