사용자 정의 명령을위한 동적 zsh 자동 완성


19

필자가 작성한 일부 사용자 정의 함수에 대해 완료 함수를 작성하려고하지만 가장 기본적인 기능조차도 실제로 어려움을 겪고있는 것 같습니다.

예제 기능은 다음과 같습니다.

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 's answer을 기반으로 다음을 사용했습니다.

#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

답변:


23

처음에 zsh Completion System 은 매우 복잡하고 파악하기 어려운 것 같습니다. 예를 들어 보자.

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

print -rl -- $fpath

(당신이 사용하는 경우 오 - 내 - zsh을을 , 거기 .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함수, state변수 에 대한 zsh 완성 시스템 문서를 읽을 수 있습니다 . 또한 당신은 변경할 필요가 (cuonglm test)당신과 함께 sed명령을 변경 prod staging dev하여에 eb_names기능.

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

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로드 된 것입니다)


자세한 답변을 주셔서 감사합니다. 내가 할 수있는 잘 문서화 방법을 찾을 수가 없어 할 수 있지만 문제는 무엇인지 내 완료 옵션은 동적, 또는 내가 원하는 경우 어떻게 귀하의 예제에서 다른 기능 / 스크립트, 즉,에서 오는 경우 cuonglm test에서 온sed -n -E 's/\[([a-zA-Z0-9_\-]+)\]/\1/p' ~/.aws/credentials | tr \\n ' '
zsquare

@zsquare :로 바꾸고 (cuonglm test)($(sed -n -E 's/\[([a-zA-Z0-9_\-]+)\]/\1/p' ~/.aws/credentials | tr \\n ' '))변경 compadd "$@" prod staging dev하십시오 compadd "$@" $(eb_names).
cuonglm

이는 약간의 스트레칭이 될 수 있지만, 내가 언급에 전달이 필요 잊었 eb_names첫 번째 인수를, 즉, productionstaging, 나는 어떻게해야합니까? 고마워요, 이것에 대해 꽤 많은 것들을 얻었습니다.
zsquare

eb_names에 전달하기 위해 첫 번째 인수를 사용하고 싶지 않았습니다. 나는 참조하지 시도 $1하거나 $2,하지만 주사위.
zsquare

2
넌 마법사 야, 해리
모욕적 인
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.