web-dev-qa-db-ja.com

ラッパー関数の引数と既存のコマンドのzshオートコンプリートを組み合わせる方法

私は主にgvimと多くの端末で働いています。元々、私はすべてのファイルを単一のvimインスタンスで開くことを好みました。そのために、エイリアスを使用して、現在の「vimサーバー」の端末からファイルを開きました。

alias rv="gvim --remote-silent"

しかし、単一のvimインスタンスで複数のプロジェクトから多くのファイルを開くと、私の生産性に影響を与えるため、エイリアスを関数にアップグレードします。

# 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には独自のオプションがあります。私はそれを使うことができます:

  • 使用可能なvimサーバーをリストします(-l --list)
  • 現在のシェルのデフォルトのvimサーバーを設定します(-s --set)
  • デフォルトのvimサーバーを表示(-i --info)
  • 特定のvimサーバーでファイルを開く(-t --target)
  • デフォルトのvimサーバーでファイルを開く:rv files...

ただし、エイリアスの代わりにrvの関数を使用しているため、以前楽しんだzshの補完機能が失われます。私は、rvのオプションを表示する補完関数_rvの作成について読みましたが、自分の補完オプションを既存のvim補完オプションと組み合わせたいと思います。 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オプションとファイルパスのみが表示されます。 _vimがファイルパスを補完しています。これで完了です。
  • rv -s <TAB>と入力すると、vimサーバーのリストが表示されますが、ファイルパスも表示されます。コマンドのこの時点ではファイルは許可されておらず、オートコンプリートに表示されません。

予想される動作

  • rv <TAB>と入力すると、1)rvオプション、2)vimオプション、3)ファイルパスリストが表示されます。
  • rv -s <TAB>」と入力すると、次のように表示されます。1)vimサーバー名(_rv_vim_serversで提供されるもの)。
  • rv /valid/file/path/<TAB>と入力すると、ファイルパスリストのみが表示されることを期待しています。 _vimにはすでにこの機能があるため、私はそれを利用したいと思います。
40
Justin C

私は/ usr/share/zsh/functions/Completion/Unix/_gitを見つけましたが、このようなエイリアスに関するいくつかのヒントがあり、これらの関数をエイリアスに定義することになりました。

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

次に、直接compdef g = gitを実行します。オートコンプリートシステムは、たとえばg lsを実行していることを確認し、_git-ls autocomplete関数を使用します。

見つかりました ここ

1
Adedoyin Akande