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


21

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

この例は、!:#展開された履歴の前のコマンドから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

これは、タブキーを押すとfooだけを完了すると次のようになります<TAB>

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

これはコマンド「foo」を完了するのに最適ですが、私が行うzsh拡張のオプションにしたいのです。zstyle completerのものと関係があると思いますが、数時間ハックした後、私は自分の深さから外れていることに気付きました。

zshのコマンドの補完候補として以前のコマンドから引数を取得するにはどうすればよいですか?

私の完全なzshrc compinstallファイルがbitbucketで共有されていれば、それが助けになります。その多くはさまざまなソースから収集されており、その一部は私自身が一緒にハッキングしました。

更新:

@Julien Nicoulaudの答えは私に近づきました。私はそれを受け入れなければならないとマークしました。

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

zstyle ':completion:*' completer _last_command_args _complete

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

これはcompleterの動作方法と関係があると思います。正常に返される最初のメソッドからの出力のみを表示すると思いますが、何が起こっているかを完全に理解するために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 

2
これは素晴らしいアイデアです
マイケル・ムロゼク

2
^[ .insert-last-word)を補うためcopy-earlier-wordに、が到達した行の単語間を循環するが好きinsert-last-wordです。あなたのために.zshrcautoload copy-earlier-word && zle -N copy-earlier-word && bindkey '^[,' copy-earlier-word
ジル「SO-悪であるのをやめ

@Gillesありがとう!完全なオートコンプリートを取得できない場合は、機能に近づきます。〜80%の時間、それが最後の引数でなければ、私が望むのは2番目から2番目の引数で、C-です。+ C-、かなり良いです。
テッド・ナレイド

回答:


6

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

zstyle ':completion:*' completer _last_command_args _complete

1
_last_command_args完了がある場合、他は表示されません。通常のものに加えてどのようにそれらを取得しますか?
ジル 'SO-悪である停止

1
答えてくれてありがとう、これは私に何かを働かせるのに十分に近づいたので、私はそれを受け入れています。私が別の方法で行ったことは、上記の質問の更新として記録されています。ソリューションは、最後のコマンドからの引数と通常のコンプリーターからのファイルなどの両方を出力しませんでした。私は、構成_complete私が作成した関数の内部で、それは私がそれを望んでいただけのように動作します。
テッド・ナレイド

あなたは正しい、私の答えは正しくありません。
nicoulaj
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.