रैपर फ़ंक्शन तर्कों और मौजूदा कमांड के लिए zsh को स्वत: पूर्ण कैसे संयोजित करें


40

मैं ज्यादातर जिम और कई टर्मिनलों में काम करता हूं। मूल रूप से, मैंने अपनी सभी फ़ाइलों को एक एकल उदाहरण में खोलना पसंद किया। उस अंत तक मैंने वर्तमान 'विम सर्वर' में अपने टर्मिनलों से फाइलें खोलने के लिए एक उपनाम का उपयोग किया।

alias rv="gvim --remote-silent"

लेकिन एक ही उदाहरण में कई परियोजनाओं से कई फाइलें खुली होने से मेरी उत्पादकता प्रभावित होती है, इसलिए मैं अपने उपनाम को एक समारोह में अपग्रेड कर रहा हूं।

# main function
rv() {
    local args options server

    options=$(getopt -o hils:t: -l "help,info,list,set:,target:" -- "$@")

    if [[ $? -ne 0 ]]; then
        echo "Failed to parse options."
        return 1
    fi

    # a little magic, necessary when using getopt
    eval set -- "$options"

    # go through the options with a case and use shift to analyze one option at a time.
    while true; do
        case "$1" in
            -h|--help)
                echo "Usage: $0 [-hil] [--help] [--info] [--list]";
                echo "       $0 {-s | --set} <name> [<file1 file2...>]";
                echo "       $0 {-t | --target} <name>] <file1 file2...>";
                return 0;;
            -i|--info)
                gvim_show_info;
                return 0;;
            -l|--list)
                gvim_list_servers;
                return 0;;
            -s|--set)
                gvim_set_server_name ${2:u};
                shift 2;;
            -t|--target)
                server="$2";
                shift 2;;
            --)
                shift;
                break;;
        esac
    done

    if [[ "$#" -eq 0 ]]; then
        # if no files specified...
        if [[ -n "$server" ]]; then
            # throw error if --target option was specified.
            echo "Error!  --target requires one or more filenames."
            return 1;
        fi
    else
        # if files were specified...
        if [[ -n "$server" ]]; then
            # if --target was specified
            gvim_run_remote $server "$@"
        else
            gvim_run_remote $(gvim_get_default_server) "$@"
        fi
    fi

    return 0;
}

अब इस नए के rvपास अपने विकल्प हैं। मैं इसका उपयोग कर सकता हूं:

  • सूची उपलब्ध विम सर्वर (-l --लिस्ट)
  • वर्तमान शेल (-s --सेट) के लिए डिफ़ॉल्ट विम सर्वर सेट करें
  • डिफ़ॉल्ट विम सर्वर दिखाएं (-i --info)
  • एक विशिष्ट vim सर्वर में फ़ाइलें खोलें (-t --target)
  • डिफ़ॉल्ट विम सर्वर में खुली फाइलें: rv files...

हालाँकि, जब से मैं rvएक उपनाम के बजाय एक फ़ंक्शन का उपयोग कर रहा हूं , मैं पहले से आनंद ले चुके zsh को पूरा करता हूं। मैंने एक पूरा होने वाला फ़ंक्शन बनाने के लिए पढ़ा है _rv, जो कि rvविकल्प दिखाएगा , लेकिन मैं अपने पूर्ण विकल्पों को मौजूदा विम पूर्णता विकल्पों के साथ जोड़ना चाहता हूं। मैं वहाँ के साथ कुछ मतभेद हो सकता है पता rvहै -sऔर vimकी -sहै, लेकिन मैं समझ मैं के साथ सुंदर ढंग से संभाल कर सकते हैं कि --विभाजक।

TLDR; तो, मैं एक पूर्ण स्क्रिप्ट कैसे बनाऊं जो _argumentsदोनों के लिए विकल्पों को जोड़ती है _rvऔर _vim? मुझे _vimलगता है कि यदि यह तर्क सूची में कॉपी-पेस्टिंग के बजाय संभव हो तो पुन: उपयोग करना पसंद करते हैं _rv

यहाँ मेरा है _rvअपडेटेड 2014/6/10 16:10

#compdef rv

_rv() {
    typeset -A opt_args
    local alternatives

    alternatives=(
        'args:rv options:_rv_options'
        'files:file:_vim_files'
    )

    _alternative $alternatives && return 0

    return 1
}

_rv_options() {
    local arguments

    arguments=(
        '(-i -l -s -t --info --list --set --target)'{-h,--help}'[Print usage info.]'
        '(-h -l -s -t --help --list --set --target)'{-i,--info}'[Print default vim server. As stored in $GVIM_SERVER.]'
        '(-i -h -s -t --info --help --set --target)'{-l,--list}'[Print list of existing vim servers.]'
        '(-i -h -l -t --info --help --list --target)'{-s,--set}'[Set default vim server for the current shell.]:vim servers:_rv_vim_servers'
        '(-i -h -l -s --info --help --list --set)'{-t,--target}'[Open files in a particular vim server.]:vim servers:_rv_vim_servers'
        )

    _arguments -s -C $arguments && return 0

    return 1
}

_rv_vim_servers() {
    local -a servers
    servers=( ${(f)"$(_call_program servers vim --serverlist 2>/dev/null)"} )
    _wanted servers expl server compadd -M 'm:{a-z}={A-Z}' -a servers && return
}

# invoke the completion command during autoload
_rv "$@"

वर्तमान व्यवहार

वर्तमान में _rvपूरा करना उपयोगी है, लेकिन आदर्श नहीं है।

  • जब मैं टाइप करता हूं rv <TAB>, तो मुझे विम विकल्प दिखाई नहीं देता है। केवल आरवी विकल्प और फ़ाइल पथ प्रदर्शित किए जाते हैं। _vimमेरे लिए फ़ाइल पथ को पूरा कर रहा है, इसलिए उस पर हुर्रे!
  • जब मैं टाइप करता हूं rv -s <TAB>, मैं vim सर्वर की सूची देखता हूं, लेकिन फ़ाइल पथ भी प्रदर्शित होते हैं। कमांड में इस बिंदु पर एक फ़ाइल की अनुमति नहीं है, और स्वत: पूर्ण में प्रकट नहीं होना चाहिए।

अपेक्षित् व्यवहार

  • जब मैं टाइप करता हूं rv <TAB>, मैं देखने की उम्मीद करता हूं: 1) आरवी विकल्प, 2) विम विकल्प, 3) फ़ाइल पथ सूची
  • जब मैं टाइप करता हूं rv -s <TAB>, मैं देखने की उम्मीद करता हूं: 1) vim सर्वर नाम (जैसा कि प्रदान किया गया है) _rv_vim_servers
  • जब मैं टाइप करता हूं rv /valid/file/path/<TAB>, तो मैं केवल एक फ़ाइल पथ सूची देखने की अपेक्षा करता हूं। चूंकि _vimपहले से ही यह क्षमता है, इसलिए मैं इस पर भरोसा करना पसंद करूंगा।

1
यह unix.stackexchange.com/questions/128199/… उपयोगी हो सकता है।
clobrano

1
compdefएक -nविकल्प है जो यह कहता है कि "कमांड या संदर्भ के लिए पहले से परिभाषित किसी भी पूर्णता को अधिलेखित होने से रोकता है"। तो, क्या आपने compdef _vim rvइसके बाद प्रयास किया है compdev -n _rv rv?
लेक्वेर्विग

3
28 upvotes और कोई जवाब नहीं ... और यह zsh के बारे में एक सवाल है ... मैं तुम्हारे लिए @ StéphaneChazelas को आमंत्रित करने की कोशिश करूंगा ^ ^ (मैं इस का दुरुपयोग नहीं करने की कोशिश करता हूं, लेकिन यह मजेदार है। कृपया स्टीफन, मुझे बताएं कि क्या मुझे नहीं करना चाहिए। ऐसा करो ... और मैं इसे हटा दूंगा और फिर कभी ऐसा नहीं करूंगा) ... अगर किसी को इसका जवाब पता चल सकता है, तो उसे होना चाहिए
ओलिवियर दुलक

1
@OlivierDulac मुझे लगता है कि आपको केवल तभी सूचनाएं मिलेंगी यदि आपने पहले ही थ्रेड में पोस्ट कर दिया है। (डुप्लीकेट नामों की अनुमति है, इसलिए यह समझ में आता है।) आप संभवतः उसे चैट में पा सकते हैं।
स्पार्कवॉक

क्या मूल _vim फ़ाइल को स्रोत करना संभव हो सकता है , लेकिन ऐसा करने से पहले _argumentsकस्टम स्थानीय फ़ंक्शन के साथ फ़ंक्शन को अधिलेखित करें ? ऐसा करने से आपको तर्क मिलेंगे _vim। शायद एक अलग zsh प्रक्रिया के साथ।
राफेल एहरेंस

जवाबों:


1

मैंने पाया / usr / share / zsh / फ़ंक्शन / पूर्णता / Unix / _git जिसमें इस तरह के उपनामों के लिए कुछ सुझाव थे और एलियंस के लिए इन कार्यों को परिभाषित करना समाप्त कर दिया:

_git-ls () {
  # Just return the _git-ls-files autocomplete function
  _git-ls-files
}

फिर, एक सीधा कंप G = git करें। स्वतः पूर्ण प्रणाली देखेगा कि आप चल रहे हैं, उदाहरण के लिए, g ls और _git-ls स्वतः पूर्ण फ़ंक्शन का उपयोग करें।

जैसा यहां पाया गया


धन्यवाद, लेकिन काफी नहीं। आपका समाधान मानता है कि मैं केवल ऑटो से पूर्ण चाहता हूं _git-ls-files। इस प्रश्न के git-lsअपने विकल्पों के साथ एक (अपने सम्मेलन के साथ छड़ी करने के लिए) है, और उन विकल्पों में से कुछ के साथ ओवरलैप है git-ls-files। के सभी विकल्पों के लिए स्वत: पूर्ण लिखने के बजाय git-ls, मैं एक स्वत: पूर्ण कैसे लिखूं जो स्वत: पूर्ण लेता है _git-ls-files(जिसमें 90% कहते हैं), और उन्हें शेष (10% कहते हैं) विकल्पों के स्वत: पूर्ण के साथ जोड़ती है?
जस्टिन सी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.