Sarıcı işlevi bağımsız değişkenleri ve varolan komut için zsh autocomplete nasıl birleştirilir


40

Ben çoğunlukla gvim ve birçok terminalde çalışıyorum. Aslında, tüm dosyalarımı tek bir vim örneğinde açmayı tercih ettim. Bu amaçla, mevcut 'vim sunucusundaki' terminallerimdeki dosyaları açmak için bir takma ad kullandım.

alias rv="gvim --remote-silent"

Ancak, tek bir vim örneğinde birden fazla projeden birçok dosyanın açılması verimliliğimi etkiler, bu nedenle diğer adını bir işleve yükseltirim.

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

Şimdi bu yeni rvkendine özgü seçeneklere sahip. Bunu için kullanabilirim:

  • kullanılabilir vim sunucularını listeler (-l - list)
  • geçerli kabuk için varsayılan vim sunucusunu ayarla (-s --set)
  • varsayılan vim sunucusunu göster (-i --info)
  • dosyaları belirli bir vim sunucusunda aç (-t --target)
  • dosyaları varsayılan vim sunucusunda aç: rv files...

Ancak, rvtakma ad yerine bir işlev kullandığımdan , daha önce zevk aldığım zsh tamamlama işlemini kaybediyorum. Bir tamamlama işlevi yaratmayı okudum _rv, bu rvseçenekleri gösterecek , ancak tamamlama seçeneklerimi mevcut vim tamamlama seçenekleri ile birleştirmek istiyorum. Biliyorum rv' -sve vim' larla bazı çelişkiler olabileceğini biliyorum -s, ama bunu --ayırıcı ile zarif bir şekilde idare edebileceğimi düşünüyorum .

TLDR; Yani, nasıl bir tamamlama komut dosyası oluşturmak anlamına birleştirir _argumentshem seçenekleri _rvve _vim? _vimMümkünse, onun argüman listesini kopyalayıp yapıştırmak yerine yeniden kullanmayı tercih ederim _rv.

İşte benim _rv. Güncellenme tarihi: 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 "$@"

Mevcut davranış

Şu anda _rvtamamlanma kullanılabilir, ancak ideal değil.

  • Ben yazarken rv <TAB>, ben vim seçeneklerini görmez. Yalnızca rv seçenekleri ve dosya yolları görüntülenir. _vimbenim için dosya yollarını tamamlıyor, bu yüzden yaşasın!
  • Ben yazarken rv -s <TAB>, ben vim sunucuların listesini görmek değil, aynı zamanda dosya yolları gösterilir. Komutta bu noktada bir dosyaya izin verilmez ve otomatik tamamlamada görünmemelidir.

Beklenen davranış

  • Ben yazarken rv <TAB>, 3) dosya yolu liste 1) rv mekanı, 2) vim seçenekleri: Ben görmeyi bekleyebilirsiniz
  • Ben yazarken rv -s <TAB>1) vim sunucu adlarını (tarafından sağlanan: Ben görmeyi bekliyoruz _rv_vim_servers.
  • Yazarken rv /valid/file/path/<TAB>, sadece bir dosya yolu listesi görmeyi bekliyorum. Beri _vimzaten bu yeteneğine sahiptir, bunu güvenmek tercih ediyorum.


1
compdef-n"komut veya içerik için önceden tanımlanmış herhangi bir tamamlamanın üzerine yazılmasını engellediğini" belirten bir seçeneğe sahiptir. Peki, compdef _vim rvardından denediniz compdev -n _rv rvmi?
Lqueryvg

3
28 yorum ve cevap yok ... ve bu zsh hakkında bir soru ... Sizin için @ StéphaneChazelas'ı çağırmaya çalışacağım ^^ (Bunu suistimal etmemeye çalışıyorum ama eğlenceli. Lütfen Stephane, söylememeliyim bunu yap ... ve bunu sildim ve bir daha asla yapmam.) ... Eğer biri cevabı biliyorsa, o olmalı
Olivier Dulac

1
@OlivierDulac Ben sadece konuya zaten gönderdiyseniz bildirimleri olsun düşünüyorum. (Yinelenen adlara izin verilir, bu nedenle mantıklıdır.) Onu yine de sohbette bulabilirsiniz.
Sparhawk

Orijinal _vim dosyayı kaynaklamak mümkün olabilir , ancak bunu yapmadan önce _argumentsözel bir yerel işlevle işlevin üzerine yazılabilir mi? Bunu yaparak argümanları alırsınız _vim. Belki ayrı bir zsh işlemi ile.
Raphael Ahrens

Yanıtlar:


1

Bunun gibi takma adlar için bazı ipuçlarına sahip olan ve takma adlar için bu fonksiyonları tanımlayan / usr / share / zsh / functions / Completion / Unix / _git'i buldum:

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

Sonra düz bir compdef g = git yapın. Otomatik tamamlama sistemi, çalıştığınızı görür, örneğin, gs ve _git-ls otomatik tamamlama işlevini kullanır.

As bulundu Burada


teşekkürler, ama tam değil. Çözümün sadece oto tamamlamanın yapılmasını istediğimi varsayıyor _git-ls-files. Bu sorunun git-ls(konvansiyonunuza sadık kalmanız) kendi seçenekleriyle bir de var ve bu seçeneklerin bazıları birbiriyle örtüşüyor git-ls-files. Tüm seçenekleri için otomatik tamamlama yazmak yerine, otomatik git-lstamamlamayı alan _git-ls-files(% 90'ı kapsar) alan ve bunları kalanların% 10'u otomatik tamamlama seçenekleriyle birleştiren bir otomatik tamamlamayı nasıl yazarım ?
Justin C,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.