web-dev-qa-db-ja.com

前のコマンドからzsh補完に引数を追加します

Zsh(およびbash)では、いくつかの履歴Word展開を使用して、前のコマンドからの引数を示すことができます。

この例は、!:#展開を使用して履歴内の前のコマンドから2番目のパラメーターを取得することを示しています。

% echo foo bar baz
foo bar baz
% echo !:2
echo bar
bar

特定の引数が#パラメータであるかを正確に忘れることがよくあります。また、どの引数であるかを覚えている場合、!:#の入力は必ずしも迅速ではありません。最後の引数を置き換えるためのmeta-.について知っていますが、必要な最後の引数ではない場合があります。

Zshで入力しているコマンドを完了するための提案として、前のコマンドの引数を追加したいと思います。

最後のコマンドから引数の配列(0..N)を作成し、それを特定のコマンドにバインドできるシェル関数を作成する方法を理解できました。

_last_command_args() {
    last_command=$history[$[HISTCMD-1]]
    last_command_array=("${(s/ /)last_command}") 
    _sep_parts last_command_array
}

# trying to get last_command_args to be suggested for any command, this just works for foo
compdef _last_command_args foo

これは、<TAB>でTabキーを押したところのfooだけを完了するとどのように見えるかです。

% echo bar baz qux
bar baz qux
% foo <TAB>
bar   baz   echo  qux 

これは、コマンド「foo」を完了するのに最適ですが、これらを私が実行するすべてのzsh拡張のオプションにしたいと考えています。それはzstyleの補完機能に関係していると思いますが、数時間のハッキングの後で、私は自分の深さを超えていることに気付きました。

Zshの任意のコマンドの推奨される補完として、前のコマンドから引数を取得するにはどうすればよいですか?

私は完全な zshrc compinstall file それが助けになるならbitbucketで共有しています。その多くはさまざまなソースから取得されており、そのうちのいくつかは私が自分でハッキングしたものです。

更新:

@Julien Nicoulaudの答えは私を近づけました、私はそれが私が得る必要があるところに私を連れて行ったのでそれを受け入れられたとマークします。

私の特定の構成で、提案されたものを使用して:

zstyle ':completion:*' completer _last_command_args _complete

タブ補完で最後のコマンドの引数のリストのみが表示されていたため、私にとってはうまくいきませんでした(実際にはファイル名も表示されますが、表示されません)。順序を_complete _last_command_argsに変更すると、逆になります。通常のファイル名は表示されますが、last_command_argsは表示されません

これは、コンプリーターの動作方法と関係があると思います。正常に戻った最初のメソッドからの出力のみが表示されると思いますが、何が起こっているのかを完全に理解するためにzshソースを解析するのに問題があります。メソッドを微調整して_completeへの呼び出しを含めることができたため、最後の引数コマンドと通常のオートコンプリート機能の両方が表示されました。それほど分離されていませんが、私にとっては十分に機能します。

これが私が使っている完全な関数と私が持っている他のzstyleのものです:

# adds the arguments from the last commadn to the autocomplete list
# I wasn't able to get this to work standalone and still print out both regular
# completion plus the last args, but this works well enough.
_complete_plus_last_command_args() {
    last_command=$history[$[HISTCMD-1]]
    last_command_array=("${(s/ /)last_command}") 
    _sep_parts last_command_array
    _complete 
}


_force_rehash() {
  (( CURRENT == 1 )) && rehash
  return 1  # Because we didn't really complete anything
}

zstyle ':completion:::::' completer _force_rehash _complete_plus_last_command_args _approximate 

私が持っている他のzstyleラインは、これが機能するために必要ではありませんが、これが私のために機能する理由に影響を与える可能性があります:

zstyle -e ':completion:*:approximate:*' max-errors 'reply=( $(( ($#PREFIX + $#SUFFIX) / 3 )) )'
zstyle ':completion:*:descriptions' format "- %d -"
zstyle ':completion:*:corrections' format "- %d - (errors %e})"
zstyle ':completion:*:default' list-Prompt '%S%M matches%s'
zstyle ':completion:*' group-name ''
zstyle ':completion:*:manuals' separate-sections true
zstyle ':completion:*' menu select
zstyle ':completion:*' verbose yes

ここで、file1.txtfile2.txtのあるディレクトリにいて、最後のコマンドがecho foo bar bazだった場合、オートコンプリートでこれを取得しました。

% ls
bar   baz   echo  foo 
- files -
file1.txt   file2.txt 
22
Ted Naleid

デフォルトで使用されるコンプリーターのリストにコンプリーターを追加できます。

zstyle ':completion:*' completer _last_command_args _complete
6
nicoulaj