Expansion - ryotako/igor-CommandPanel GitHub Wiki

CommandPanelは,入力された文字列を実行する前に規則に従って文字列を展開します. (コマンドの実行後,Igor Proの標準のコマンドウィンドウには展開した結果得られるコマンドが表示されます.)

基本的にはbashのエイリアス展開,ブレース展開,パス名展開に似た振る舞いをします.しかし,bashが入力を複数の単語に展開するのに対して,CommandPanelでは入力を複数の行に展開する点が異なります.Igor Proでは可変個の引数を取る関数を作るのが困難であるため,このような挙動にしています.

bashの展開 (ブレース展開)

expand_shell

CommandPanelの展開 (ブレース展開)

expand_igor

何らかの理由で展開に失敗した場合,展開前の文字列の実行が試みられます.

エスケープ

展開を行いたくない場合は,展開に使われる特殊文字をバックスラッシュ\(フォントによっては円マーク)でエスケープするか,展開させたくない部分全体をバッククォート`で囲ってください.

bashの場合,展開させたくない文字列はシングルクォート'で囲むことになっていますが,Igor Proではシングルクォートが別の役割を持っているため,エスケープにはバッククォートを用います.

展開の流れ

CommandPanelでは,以下の6種の展開が順に行われます.

bashのようなエイリアス展開ブレース展開パス名展開を行うことができます. 行単位での展開を制御するためにセミコロン;による通常のコマンドの分割(弱い行分割)に加え,連続したセミコロン;;による強い行分割を導入しています.

また,Igor Proでのユーザー定義関数の実行を簡単にするために括弧の補完が行われます.

expand_flow

エイリアス展開

以下のような書式で、コマンドの別名(エイリアス)を設定することができます。

alias cp=Duplicate/O // cpをDuplicate/Oの別名に設定
Make wave
cp wave wave_cp // 実際に実行されるコマンドは Duplicate/O wave wave_cp

alias cp= // =の右に何も書かなかった場合,そのエイリアスは削除される

実はこのaliasコマンドもCommandPanel#aliasのエイリアスです. コマンドパネルを初めて作成した際に自動で定義されます. 引数無しでaliasコマンドを実行すると定義されたエイリアスの一覧が表示されます.

ブレース展開

複数の単語をブレース{}の中にカンマ,で区切って並べることにより,bashのようなブレース展開を行います.{a..z}{1..3}{1..9..2}のような書式の,範囲の展開も可能です.

しかし注意すべき点として,Igor Proにおいてはブレース展開はウェーブのリテラルの書式と競合します. そのためCommandPanel上でウェーブリテラルを書く場合には,バックスラッシュ\でブレースをエスケープする必要があります.

Make/O wave={1,2,3} // これは以下のように展開されてしまう.
// Make/O wave=1
// Make/O wave=2
// Make/O wave=3

Make/O wave=\{1,2,3} // 要素数3のウェーブが作成される. 
Make/O `wave={1,2,3}` // バッククォートで囲っても展開は無効になる.

パス名展開

root:あるいは:で始まるIgor Proのパス名の一部に*が含まれる場合,パス名の展開が行われます.例えば,:V_*はカレントフォルダにあるV_で始まる数値変数,文字列変数,ウェーブ,データフォルダのパス名に展開されます.

たとえば,以下のコマンドはカレントフォルダにあるV_で始まる数値変数を一括で削除します.

KillVariables/Z :V_*

また,パスが:**:を含む場合,任意階層での検索が行われます. 以下のコマンドは,root以下任意階層の数値変数V_flagを削除します.言いかえれば,すべてのV_flagが削除されます.

KillVariables/Z root:**:V_flag

強い/弱い行分割

CommandPanelでは,単語単位ではなく行単位の文字列展開を行います.たとえば,以下のブレース展開では;の前のDisplayを含めてコマンドが展開されます.

Dispaly; AppendToGraph :wave{1..3}
// 以下のように展開され,グラフが3枚作成される.
// Dispaly; AppendToGraph :wave1
// Dispaly; AppendToGraph :wave2
// Dispaly; AppendToGraph :wave3

しかし,連続したセミコロン;;でコマンドを区切ると,他の展開が行われる前に行の分割が行われます(強い行分割).

Dispaly;; AppendToGraph :wave{1..3}
// 以下のように展開され,1枚のグラフに3つのウェーブがプロットされる.
// Dispaly 
// AppendToGraph :wave1
// AppendToGraph :wave2
// AppendToGraph :wave3

これに対して,従来のセミコロン;による行分割はエイリアス展開,ブレース展開,パス名展開の後に実行されます(弱い行分割).

括弧の補完

Igor Proでユーザー定義関数を呼び出す際には,引数を受け取るための括弧()の入力が必須です.CommandPanelでは,各行の最初に使われるユーザー定義関数に関して,括弧の入力を省略することができます.

また,各行の最初に使われる関数が文字列一つを引数に取る場合に限り,文字列リテラルを入力するためのダブルクォーテーションの省略が可能です.この際,引数にリテラルでない文字列を与える場合には括弧を省略せずに書く必要があります.

DoSomething // 引数ゼロの関数は,操作関数のように実行できる.
CompareSomething abs(a),MyAbs(b) // 行頭以外でのユーザー定義関数の呼び出しには括弧が必須.

PrintSomething test // PrintSomething("test") が実行される.
PrintSomething( ReplaceString("h","hello","H") ) // 引数が文字列リテラルでない場合は括弧の入力が必要.