履歴に基づいてバインド-xのコマンドパラメータを指定する方法は?

履歴に基づいてバインド-xのコマンドパラメータを指定する方法は?

コマンド名を引数として使用し、その構文を印刷する synopsis というコマンドがあるとします。ここで、要約をキーシーケンスにバインドしたいと思います。現在のコマンドラインから概要にコマンド名を渡すにはどうすればよいですか?以下は、望ましい動作の例です。

1$ bind -x '"\C-h": synopsis !#:0'
2$ ls -F^H 
<ls syntax print out from synopsis> 
3$ ls -F

2でシノプシスが呼び出されますが、歴史的な拡張はありません。 「ls」の代わりに「!#:0」文字列が表示されます。何も動作しないようです:-/

答え1

キーストロークにバインドされた関数では、変数を使用してコマンドラインの現在の内容にアクセスして変更できます。READLINE_LINEそしてREADLINE_POINT。概念証明(テストされていないコード):

synopsis () (
  set -f
  IFS=$'\t\n\r ;&|'
  words=($READLINE_LINE)
  while [[ "${words[1]}" == @([<>]*|[A-Za-z0-9_]##=) ]]; do
    shift words
  done
  command=${words[1]}
  "$command" --help
)
bind -x '"\C-h": synopsis'

試行した履歴拡張方法が機能しません。コマンドラインを実行すると、履歴拡張が実行されます。バインディングが呼び出されたときに拡張可能な履歴はありません。

しかし、あなたの基本的な質問はあなたの殻は十分にクールではありません。この機能はすでにzshに存在し、名前は次のとおりです。run-help

bash$ echo '実行中のヘルプの自動読み込み' >~/.zshrc
bash$ zsh
ダークスター %ls -FAlt+h

答え2

1つの可能性は、行の先頭に挿入してなしでbind使用することです。-xsynopsis

bind "'\C-h": "\C-asynopsis \C-j"

議論をしてください。より複雑なバージョンは次のとおりです。

bind '"\C-h": "\C-e !#:0\e^\e\C-] \C-usynopsis\C-j"'

それを破壊する:

'\C-e '    end-of-line
' !#:0'    insert space and 1st argument of current line
'\e^'      history-expand-line
'\e\C-] '  character-search-backward (to last space)
'\C-u'     unix-line-discard (delete to beginning of line)
'synopsis' insert 'synopsis' in front of the first argument
'\C-j'     accept-line

これはsynopsis、最初の引数としてのみ実行される複数の引数を持つ行を処理します。 ("\C-xh"または代わり"\eh""\C-h"すでに削除/バックスペース/「戻る文字を削除」を使用することもできます。)

関連情報