基本型は,&p
(ポーズ:キー入力待ち)で実行を一旦停止してキー入力を待ち,入力されたキーに応じて分岐するというものになります。次のマクロは文字キーでスクロールを行う例です。
1 ^\ "" ?.
et[-, mp[-,
:L &m("EXRCWZ/[ESC]")
ep[+, &p ep],
(r==#[)?>Z ;終了
(r|32)>!{
('x'){ r=#x, >N }
('e'){ r=#e, >N }
('c'){ r=#c, >N }
('r'){ r=#r, >N }
('z'){ r=#z, >N }
('w'){ r=#w, >N }
}
(r==#r||r==#c||r==#w||r==#z||r==#e||r==#x)?{ ;Page,Line
:N &o(r) >L
}
>L
:Z mp], et],
&m("") #]
さらに詳しい情報を得たい場合は,見米快之氏の「モード型マクロ作法書」(nifty:FGALPK/MES/16/00945 [1994/02/03])という文献を参照するとよいでしょう。
すでにリンクの切れている文献ですので,次に引用しておきます。(引用の範囲を逸脱しているかもしれませんが,再編集を行うと不正確なものとなる可能性があるため,敢えて原文に制御コード変換以外の手を加えておりません。)
モード型マクロの作法 極端な話、キー監視 &p ではユーザーは何を行うか予想できません。ユーザー が何を行っても重大な結果に陥らない作法です。 # ・マクロの実行禁止 mx+ 例えば文字入力しか受け付けたくないようなキー監視では &p の直前で mx+ としましょう。 &p キー監視状態からのマクロ実行が抑止され、これさえ書い ておけば以下の事柄などまったく不要となります。 以下、敢えて mx+ にはしたくない &p 監視での作法です。 # ・&p のネストレベル できるだけ最上位のネストレベルでキー監視を行いましょう。キー監視状態 からユーザーが実行してしまった他のマクロ(以下「他のマクロ」)がマクロ ネストの制限いっぱいを使用していた場合、両者とも道連れにマクロが止まっ てしまいます。 # ・マクロスタックへのプッシュ これもできるだけ行わないようにしましょう。やはり他のマクロの使用でき るスタックを制限してしまいます。必要なら、[ESC] を監視するための ep だ けのプッシュに留めておき、&p 直後に必要な変数待避を行いましょう。 # ・非編集モードへの対応 忘れがちな対策です。他のマクロによっていつの間にか非編集モードへ移動 している可能性に備えなければなりません。 以上をまとめると次のような構造になります。 :A ep[+, &p ep], ; キー監視 (s)?{ &o(r) >A } ; 非編集モード対策 jx[,je[,js[, ; 変数のプッシュ mx=sq+, eu=ew-, (本体処理ルーチン) js],je],jx], ; 変数のポップ >A # ・ep+ 対策 あなたの作成するモード型マクロが [ESC] を監視するつもりがないときで も、(r==#[)?{……} というルーチンは必ず入れておきましょう。 なぜなら、ep+ 状態のキー監視マクロから、あなたのマクロを実行するユー ザーもいるからです。 # ・多重起動対策 一般的には実行フラグを用いるところですが、 1.6ではフラグを用いなく ても多重起動のチェックができます。これにより、[STOP][ESC] でマクロをブ レークしても次にマクロキーを押せば直ちに実行できる安全なマクロを作り上 げることができます。 1 ^KM "ワープロモード" ?. (mg..2-mg+16)?{ ;バックグラウンドにマクロ存在? r=mg..2-2, &Sx(r..0+8,"WD") ;そのマクロは自分自身か? (r)?? &q ;自分自身ならマクロ終了 . ;他のマクロなら起動しない } 1 ^KM "ワープロモード" ?. (mg..2-mg+16)?{ ;バックグラウンドにマクロ存在? r=mg..2-2, &Sx(r..0+8,"WD") ;そのマクロは自分自身か? (r)??{ &q .} ;自分自身ならマクロ終了 } ;他のマクロならかまわず起動する 1 ^KM "ワープロモード" ?. (mg..2-mg+16)?{ ;バックグラウンドにマクロ存在? r=mg..2-2, &Sx(r..0+8,"WD") ;そのマクロは自分自身か? (r)?? . ;自分自身なら起動しない } ;他のマクロならかまわず起動する 1 ^KM "ワープロモード" ?. (mg..2-mg+16)?{ ;バックグラウンドにマクロ存在? r=mg..2-2, &Sx(r..0+8,"WD") ;そのマクロは自分自身か? (r)??{ &q !01 ;自分自身ならメニューで分岐 (r)>?{ >A >B >C } . ;メニューを [ESC] で終了 } } ;他のマクロならかまわず起動する # ・保存変数 他のマクロによって破壊されては困る変数は、マクロ内部にバッファを設けて ポインタ変数として確保しましょう。 2: v3+$,. "$[64]" このようなマクロをコールすれば、 ポインタ v に64バイトのワークが確保さ れます。 v..0 v..1 v..2 などワード値なら 32 個のローカル変数が確保できる わけです。 そしてこのローカルマクロは、 マクロ実行直前はもちろんのこと、&p 直後に も必ずコールします。 他のマクロによって v が破壊されているかもしれないか らです。 以上をまとめると次のようになります。 1 ^KM "ワープロモード" ?. (mg..2-mg+16)?{ ;バックグラウンドにマクロ存在? r=mg..2-2, &Sx(r..0+8,"WD") ;そのマクロは自分自身か? (r)??{ &q .} ;自分自身ならマクロ終了 } &01 ; ポインタアクセス v..0="d:\dat\", ; データディレクトリ v..1+, ; 保存変数初期化 :A &p (s)?{ &o(r) >A } (r==#[)?{ &b(1) >A } ; ep+ 対策 k=r, ; k=キー入力 &01 ; ポインタアクセス &02 ; キー分岐 >A 1: v3+$,. "$[64]" 2: ;--- キー分岐 --- (k==#m)? …… …… …… # ・ユーザー変数の初期値 フラグ変数としてユーザー変数を用いるなら v.0 v.1 などとバイト値でも十 分です。 その際、 初期化命令をマクロ冒頭で v.0-, v.1+, などと行わなくても最初か らワークに書いておくこともできます。 1: v3+$,. "$(1,1,0,0,2,0)" | | | | | +- v.5=0, | | | | +- v.4=2, | | | +- v.3=0, | | +- v.2=0, | +- v.1=1, +- v.0=1, # ・複数のユーザー変数の同時指定 例えばフラグ変数として f.0 〜 f.5 の6つを初期値付きで、そして、文字列 等を格納するためのワード変数を v..0 〜 v..7 の8つ(16バイト)、この2種 を同時に確保するには次のようにします。 1: v6+f3+$,. "$(1,1,0,0,1,0)$[16]" v6+f3+$, は f=3+$, v=6+f, の合成式です。
最も簡単な方法は,!Timerイベントを使用することです。
1 ^\ "!Timer" ?.
mp[-, #c mp], ;表示ページング
(r)?#^ ;ローテート
もうひとつの方法は,モード型と言えないループカウント型です。これは単純なループの内側でカウンタを設置し,カウントされた数に応じた分岐を行うものです。外側のループは (a%1000)??{ … }
というような方法で代用することもできるでしょう。
1 ^\ "" ?.
mp[-,
:o ; ---- outside loop ----
a-,
#c (r)?#^
&m("Scroll mode")
:i ; ---- inside loop ----
a++,
(ks&1)?>z
(a>999)?>o
>i
:z ; ---- exit ----
mp],
&m("Done.")
&d #] .