シェル関数でzshの既存のオートコンプリートを利用するにはどうすればよいですか?


10

いくつかのシェル関数が自分.zshrcで定義されており、入力を省略して画面との統合を可能にします。例えば:

function s()
{
     screen -t "$1" ssh "$@"
}

ただし、これらのシェル関数を使用すると、zshに組み込まれているコマンド補完機能を利用できません。(SSHの場合、known_hostsおよびssh_configに基づいてホスト名を自動的に補完します)。ラッパーを作成したコマンドの既存の補完メカニズムにフックするための好ましい方法は何ですか?

編集:

以下の答えをくれたGillesに感謝します。これを行うにはcompdefを使用する方法のように見えますが、興味深いことに、均一に機能するようには見えません。この場合、私は次の設定をしています:

function s()
{
    screen -t "$1" ssh "$@"
}

function m()
{
    screen -t "man.$1" man "$1"
}

compdef $_comps[man] m
compdef $_comps[ssh] s

ラッパー関数「m」の補完は期待どおりに機能しますが、関数「s」の補完は機能しません。ホスト名を完成させるのではなく、「タブ」を押すとファイルのリストが表示されるため、デフォルトのオートコンプリートにフォールバックするようです。SSH完了の処理方法に奇妙な点がありますか?これは、さらに何かをする必要があることを意味しますか?

回答:


9

次の関数を使用して、関数、エイリアス、またはラッパースクリプト(例s)が既存のコマンド(例:)のように完成することを示しますssh

compdefas () {
  local a
  a="$1"
  shift
  compdef "$_comps[$a]" "${(@)*}=$a"
}
compdefas xterm cxterm uxterm xterm-color

一部の補完コマンドは、一連の関数に適用され、コマンドラインの最初の単語を読み取って、補完する特定のコマンドを決定します。例えば、コマンドsshscpsftpそしてさらにいくつかは、すべての機能によって完成されています_ssh。その場合、あなたの関数がどのような「サービス」であるかを補完関数に伝える必要があります(デフォルトでは、サービスは実行可能ファイル名、ここでは関数の名前です)。

_s () {
  local service=ssh
  _ssh "$@"
}
compdef _s s

ありがとう-compdefを使いたいと思っていました。興味深いことに、compdefの呼び出しで$ 1と$ 2を参照するのではなく、ローカル変数を作成してシフトする理由はありますか?
Murali Suriar 2011年

@Murali:それで、のようなものを書くことができますcompdefas xterm cxterm uxterm xterm-color
ジル 'SO-悪をやめる'

1
興味深い-だから私は2つのラッパーを定義しました。compdefを使用すると、「man」ラッパーの補完は機能しますが、「ssh」ラッパーの補完は機能しません。以前にこのような問題に遭遇したことがありますか?_sshがエイリアス/ラッパーで機能するために、他に何か突く必要がありますか?
Murali Suriar 2011年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.