「zsh」でエイリアスを拡張する機能のより良い理解

「zsh」でエイリアスを拡張する機能のより良い理解

zshこのウィジェットがどのように機能するかを理解しようとしています。

expand-aliases() {
  unset 'functions[_expand-aliases]'
  functions[_expand-aliases]=$BUFFER
  (($+functions[_expand-aliases])) &&
    BUFFER=${functions[_expand-aliases]#$'\t'} &&
    CURSOR=$#BUFFER
}

zle -N expand-aliases
bindkey '\e^E' expand-aliases

ここでコードを見つけました。回答。その目的は、コマンドラインでエイリアスをクリックしたときにすべてのエイリアスを拡張することですC-M-e

動作しますが、コードに私が理解していないいくつかのことがあります。

私が理解しているものと理解していないものは次のとおりです。

zle -N expand-aliases

expand-aliasesこの行は、同じ名前の関数を呼び出すウィジェットをインストールします。

bindkey '\e^E' expand-aliases

この行はウィジェットをキーコードにバインドしますC-M-e

unset 'functions[_expand-aliases]'

functions配列がどのように入力されるのかわからないため、この行は理解できません。

functions[_expand-aliases]=$BUFFER

functionsこの行はキーを使用して連想配列に現在のコマンドラインの内容を格納します_expand-aliases

(($+functions[_expand-aliases])) &&

この行の仕組みをよりよく理解するために、次のコマンドを実行しました。

alias ls='ls --color=auto'
alias -g V='|vipe'
functions[_expand-aliases]='ls V'
echo $functions[_expand-aliases]           →  ls --color=auto | vipe
echo $+functions[_expand-aliases]          →  1
(($+functions[_expand-aliases])); echo $?  →  0

わかりませんが、この結果を見ると、$functions[_expand-aliases]現在のコマンドラインのエイリアスを何とか拡張し、コマンドラインが構文的$+functions[_expand-aliases]に有効であることを確認するために使用されるブールフラグを返すと思います。

しかし、トークンを理解していません$+。すべてのマニュアルページで検索しましたが、zsh見つかりませんでした。

BUFFER=${functions[_expand-aliases]#$'\t'} &&

この行は、コマンドラインの内容と拡張を上書きできます。

CURSOR=$#BUFFER

この行はカーソルをコマンドの最後に置きます。


誰かがこのコードがどのように機能するかをよりよく説明できますか?または、少なくともトークンと配列をzsh説明するマニュアルページの一部を引用しますか?$+functions

答え1

$+functions[_expand-aliases]連想配列にfunctionsキーが含まれている場合は1 _expand-aliases、それ以外の場合は0です。これは手動のように。項目の下のマニュアルには、支柱がオプションと記載されています。ドキュメントには使用できると明示的に記載されていないようです。${+name}${name}添字配列名名前の代わりに。 zsh マニュアルは読みやすくありません。

このfunctions配列は、関数定義に関連する「魔法の」連想配列です。関数を定義すると、この配列に要素が追加されます。ここで、キーは関数名、値は正規化された関数本体です。代わりに、配列に要素を追加すると、与えられた名前と本文を持つ関数が定義されます。

unset 'functions[_expand-aliases]'               # unset any previous function
functions[_expand-aliases]=$BUFFER               # define a function whose body is the content of the command line
(($+functions[_expand-aliases])) &&              # if the command line is a syntactically correct function body, then …
BUFFER=${functions[_expand-aliases]#$'\t'} &&    # set the command line to the normalized function definition
CURSOR=$#BUFFER                                  # move the cursor to the end of the command line

通常の配列の場合、functions値は変更されずBUFFER(先行タブ文字の削除を除く)、3行目のテストは常にtrueです。ただし、「魔法」の性質のために入力したものでfunctionsはなく、特にエイリアスが拡張されたフルバージョンです。関数定義の構文が正しくない場合、3行目のテストは失敗します。

関連情報