कस्टम आदेशों के लिए डायनामिक 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- पूर्ण रेपो देखा है, लेकिन मैं क्या जरूरत के समान कुछ खोजने के लिए प्रतीत नहीं कर सकते।

किसी भी मदद की शुरुआत की बहुत सराहना की जाएगी!

अपडेट करें

@ Congonglm के उत्तर के आधार पर , मैंने उपयोग किया:

#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 कम्प्लीटेशन सिस्टम बहुत जटिल और समझ से मुश्किल लगता है। एक उदाहरण की कोशिश करते हैं।

पहली बात जो आपको जानना जरूरी है, 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फ़ंक्शन, stateवैरिएबल के बारे में zsh पूरा करने वाले सिस्टम डॉक्यूमेंटेशन पढ़ सकते हैं । इसके अलावा, आपको (cuonglm test)अपनी sedकमांड के साथ बदलने prod staging devऔर अपने eb_namesफ़ंक्शन को बदलने की आवश्यकता है ।

यदि आप 1 तर्क पारित होने के बाद 2 तर्क आधार उत्पन्न करना चाहते हैं, तो आप $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, तो इसे लोड किया गया है)


विस्तृत प्रतिक्रिया के लिए बहुत बहुत धन्यवाद। समस्या यह है कि मैं करने के लिए एक अच्छी तरह से प्रलेखित रास्ता खोजने के लिए प्रतीत नहीं कर सकते हैं, क्या है अगर मेरे पूरा विकल्प गतिशील हैं, या अन्य कार्यों / लिपियों से आते हैं, यानी, उदाहरण में, अगर मैं 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)
6ong

यह इसे थोड़ा खींच सकता है, लेकिन, मैं यह उल्लेख करना भूल गया, कि eb_namesपहले तर्क को पारित करने की आवश्यकता है , productionया staging, मुझे यह कैसे करना चाहिए? बहुत बहुत धन्यवाद, मैं इस के साथ हल बहुत कुछ मिल गया है।
zsquare

मेरा मतलब है कि मैं eb_names को पास करने के लिए पहले तर्क का उपयोग नहीं करना चाहता था। मैंने संदर्भित करने की कोशिश की $1या $2, लेकिन कोई पासा नहीं।
zsquare 18

2
हैरी तुम एक जादूगर हो।
cambunctious
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.