Cara menggabungkan zsh autocomplete untuk argumen fungsi wrapper dan perintah yang ada


40

Saya kebanyakan bekerja di gvim dan banyak terminal. Awalnya, saya lebih suka membuka semua file saya dalam satu contoh vim. Untuk itu saya menggunakan alias untuk membuka file dari terminal saya di 'vim server' saat ini.

alias rv="gvim --remote-silent"

Tetapi memiliki banyak file dari beberapa proyek yang terbuka dalam satu contoh vim berdampak pada produktivitas saya, jadi saya meningkatkan alias ke suatu fungsi.

# 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;
}

Sekarang ini baru rvmemiliki opsi sendiri. Saya bisa menggunakannya untuk:

  • daftar server vim yang tersedia (-l --list)
  • atur server vim default untuk shell saat ini (-s --set)
  • tampilkan server vim default (-i --info)
  • buka file di server vim tertentu (-t --target)
  • buka file di server vim default: rv files...

Namun, karena saya menggunakan fungsi rvalih - alih alias, saya kehilangan penyelesaian zsh yang sebelumnya saya nikmati. Saya telah membaca tentang cara membuat fungsi penyelesaian _rv,, yang akan menampilkan rvopsi, tetapi saya ingin menggabungkan opsi penyelesaian saya dengan opsi penyelesaian vim yang ada. Aku tahu mungkin ada beberapa konflik dengan rv's -sdan vim' s -s, tapi kupikir aku bisa mengatasinya elegan dengan --pemisah.

TLDR; Jadi, bagaimana cara membuat skrip penyelesaian yang menggabungkan _argumentsopsi untuk keduanya _rvdan _vim? Saya lebih suka menggunakan kembali _vimjika mungkin alih-alih menempelkan daftar argumennya _rv.

Ini milik saya _rv. Diperbarui 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 "$@"

Perilaku Saat Ini

Saat ini _rvpenyelesaian dapat digunakan, tetapi tidak ideal.

  • Saat saya mengetik rv <TAB>, saya tidak melihat opsi vim. Hanya opsi rv dan jalur file yang ditampilkan. _vimsedang menyelesaikan jalur file untuk saya, jadi silakan!
  • Ketika saya mengetik rv -s <TAB>, saya melihat daftar server vim, tetapi juga path file ditampilkan. File tidak diizinkan pada saat ini dalam perintah, dan seharusnya tidak muncul dalam pelengkapan otomatis.

Perilaku yang Diharapkan

  • Saat saya mengetik rv <TAB>, saya berharap melihat: 1) opsi rv, 2) opsi vim, 3) daftar jalur file
  • Saat saya mengetik rv -s <TAB>, saya berharap melihat: 1) nama server vim (seperti yang disediakan oleh _rv_vim_servers.
  • Saat saya mengetik rv /valid/file/path/<TAB>, saya berharap hanya melihat daftar jalur file. Karena _vimsudah memiliki kemampuan ini, saya lebih suka mengandalkannya.


1
compdefmemiliki -nopsi yang mengatakan "mencegah penyelesaian apa pun yang sudah ditetapkan untuk perintah atau konteks agar tidak ditimpa". Jadi, sudahkah Anda mencoba compdef _vim rvdiikuti compdev -n _rv rv?
Lqueryvg

3
28 suara positif dan tidak ada jawaban ... dan ini adalah pertanyaan tentang zsh ... Saya akan mencoba memanggil @ StéphaneChazelas untuk Anda ^^ (Saya mencoba untuk tidak menyalahgunakan ini, tapi itu menyenangkan. Tolong Stephane, beri tahu saya jika saya tidak boleh lakukan ini ... dan saya akan menghapus ini dan tidak pernah melakukannya lagi) ... Jika seseorang di sini mungkin tahu jawabannya, itu pasti dia
Olivier Dulac

1
@OlivierDulac Saya pikir Anda hanya mendapatkan pemberitahuan jika Anda telah memposting di utas. (Nama duplikat diizinkan, jadi ini masuk akal.) Anda mungkin bisa menemukannya di chat.
Sparhawk

Mungkinkah sumber _vim file asli , tetapi sebelum melakukannya menimpa _argumentsfungsi dengan fungsi lokal kustom? Dengan melakukannya, Anda akan mendapatkan argumen dari _vim. Mungkin dengan proses zsh terpisah.
Raphael Ahrens

Jawaban:


1

Saya menemukan / usr / share / zsh / functions / Completion / Unix / _git yang memiliki beberapa tips untuk alias seperti ini dan akhirnya mendefinisikan fungsi-fungsi ini untuk alias:

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

Kemudian, lakukan compdef g = git. Sistem autocomplete akan melihat bahwa Anda sedang menjalankan, misalnya, g ls dan menggunakan fungsi autocomplete _git-ls.

Seperti yang ditemukan di sini


terima kasih, tetapi tidak cukup. solusi Anda mengasumsikan saya hanya ingin melengkapi otomatis dari _git-ls-files. Pertanyaan ini memiliki git-ls(untuk tetap dengan konvensi Anda) dengan opsi sendiri, dan beberapa opsi tersebut tumpang tindih dengan git-ls-files. Alih-alih menulis autocomplete untuk semua opsi git-ls, bagaimana cara menulis autocomplete yang mengambil autocomplete dari _git-ls-files(yang mencakup katakanlah 90%), dan menggabungkannya dengan autocomplete dari opsi yang tersisa (katakanlah 10%)?
Justin C
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.