第3章 システム関数とコマンド関数
システム関数
&a
問い合わせ(ask)
- 【書式】
&a("問い合わせ") または &a(n), &a(p)
- 【解説】
指定した文字列に「か? (Y/N)」を付加して、画面最下行に問い合わせのメッセージをだします。どう応答したか返り値に入ります。
- 【返り値】
-
応答 返り値 [Y]:Yes 1 [N]:No 0 [ESC]:キャンセル -1
【使用例】
======== osu_mesu.def by I.KAMIMURA ========
* M
80 ^\ "♂♀チェック"
a='♂', ; aに「♂」の文字コードを代入
b='♀', ; bに「♀」の文字コードを代入
c="あなたは%cが好きです", ; 書式制御「%c」は文字コードに対応
&a("あなたは%cです",a) ;「あなたは♂ですか? (Y/N)」
(r==-1)? { &b(3) >^ } ; [ESC]は許さない
(r)? >A ? >B ; [Y]なら「:A」。[N]なら「:B」
:A &a(c,a) ;「あなたは♀が好きですか? (Y/N)」
(r>0)? >C ? >D ; [Y]なら「:C」。[N][ESC]なら「:D」
:B &a(c,b) ;「あなたは♂が好きですか? (Y/N)」
(r>0)? >C ? >D ; [Y]なら「:C」。[N][ESC]なら「:D」
:C &m(24). ;「一致しました」(よかった)
:D &m(28) ;「マークしました」(なにを?)
*
======== End of osu_mesu.def ========
書式制御(&m
,&?
参照)を使っているので、わかりにくいかもしれません。素直に書くと次のようになります。
======== osu_mesu.def by I.KAMIMURA ========
* M
80 ^\ "♂♀チェック"
&a("あなたは♂です") ;「あなたは♂ですか? (Y/N)」
(r==-1)? { &b(3) >^ } ; [ESC]は許さない
(r)? >A ? >B ; [Y]なら「:A」。[N]なら「:B」
:A &a("あなたは♀が好きです") ;「あなたは♀が好きですか? (Y/N)」
(r>0)? >C ? >D ; [Y]なら「:C」。[N][ESC]なら「:D」
:B &a("あなたは♂が好きです") ;「あなたは♂が好きですか? (Y/N)」
(r>0)? >C ? >D ; [Y]なら「:C」。[N][ESC]なら「:D」
:C &m(24). ;「一致しました」(よかった)
:D &m(28) ;「マークしました」(なにを?)
*
======== End of osu_mesu.def ========
システムメッセージの利用
文字列の代わりにシステムメッセージ番号をあたえると、VZが内蔵しているメッセージをだすことができます(別表参照)。&a
の場合「か? (Y/N)」が付加されるのを忘れないでください。
ポインタ、書式制御の利用
&a(p)でpの示す文字列をメッセージにだすことができます。
======== pointer.def by I.KAMIMURA ========
* M
80 ^\ "ポインタとは?"
p="ポインタは犬です",
&a(p) ;「ポインタは犬ですか? (Y/N)」
(r<0)?. ; [ESC]でキャンセル
(r)
? &m("あなたにマクロは無理です") ; [Y]
? &m(24) ; [N]
*
======== End of pointer.def ========
osu_mesu.defの
&a("あなたは%cです",a)
&a(c,a)
を見比べればわかるように、書式制御(%c
など)が含まれる文字列もポインタで指し示すことができます。書式制御については、「&m
」「&?
」の項で詳しく述べます。
システムメッセージ一覧
1 | ^Bは見つかりません. 新規ファイルです |
2 | ^Bは入力できません |
3 | ^Cは出力できません |
4 | テンポラリファイルエラー |
5 | ラインバッファがいっぱいです |
6 | オープンできません |
7 | ディスクがいっぱいです |
8 | テキスト領域がいっぱいです |
9 | ブロックが大きすぎます |
10 | メモリが足りません |
11 | バッファがいっぱいです |
12 | COMMAND.COMを起動できません |
13 | カスタマイズエラー |
14 | ^Bを出力します |
15 | ^Cを出力中... |
16 | 修正テキストを出力します |
17 | テキストスタックを消去します |
18 | エディタを終了します |
19 | 文字列が見つかりません |
20 | 全部一度に置換します |
21 | 置換します |
22 | ^A%5u 個の文字列を置換しました |
23 | カーソルキーで位置を移動して[CR] |
24 | 一致しました |
25 | 相違があります |
26 | 括弧が見つかりません |
27 | ^Bはオープンされています |
28 | マークしました |
29 | ^A%5u 項目読み込みました.(%d bytes free) |
30 | ^Bはすでに存在します |
31 | ^Bは無効なパス名です |
32 | ^Bはリードオンリーです |
33 | 新規ファイルです |
34 | ^Cはすでに存在します. 出力します |
35 | ^Cは存在しません 新たに作成します |
36 | 変更できません |
37 | 編集テキストを放棄します |
38 | OFF ON |
39 | EXITでエディタへ戻ります |
40 | 指定が違います |
41 | 準備ができていません |
※ 「^A」~「^C」、「%5u」「%d」はVZ内部の制御コード
&b
ビープ音(beep)
- 【書式】
&b(time)
- 【返り値】
- なし(rは保存)
- 【解説】
time(数値)で指定した時間、ビープ音を鳴らします。
「&b(60)
」で約1秒間ビープ音が鳴ります。
軽く注意をうながす程度なら「&b(3)
」。ちょっと長めに鳴らすなら「&b(9)
」ぐらいがよいでしょう。2進法で物を考える人には「&b(2)
」「&b(8)
」がおすすめです。
&c
1文字または1コマンドの入力を待つ(char)
- 【書式】
&c
- 【返り値】
- なし(rは破壊)
- 【解説】
キー入力を1回待ちます。YES/NOの応答を待ったり、文字列入力ウィンドウでのキー入力を受け付けるときに利用します。
使用例1
======== closeall.def by I.KAMIMURA ========
* M
9 [ESC]X "全ファイルのクローズ"
?.
:A #C ; ファイルのクローズ
:B (s)>?{ >A . . . } ; s が 0 なら「:A」へループ
&c ; [Y]/[N]/[ESC]の入力を待つ
(r<0)?. ; [ESC]でキャンセルなら中断
>B
*
======== End of closeall.def ========
VZ標準のマクロをすこし改変したマクロです。
「#C
」(ファイルのクローズ)で、修正ファイルの場合は「~を出力しますか? (Y/N)」と問い合わせるメニューモード(s=4
)になります。多重分岐の中身は0~3しか用意されていないので、スキップして「&c
」の部分で止まり、[Y][N][ESC]の入力を待ちます。[Y]と[N]のどちらで応答しようと、「ファイルのクローズ」の仕様そのままに処理されます。[ESC]でキャンセル(返り値が-1)した場合にだけ中断します。
&a | 指定したメッセージで問い合わせをおこなう |
&c | VZが発する問い合わせに1回キー入力をおこなう |
この2つを混同しないでください。
使用例2
======== replace.def by I.KAMIMURA ========
【一括置換】
* M
80 ^QA "Replace String"
?. ; #56…文字列の置換
(ks&1) #56 ?. ; シフト実行ならすぐ終了
&b(3) ; 一括置換を知らせるビープ音
:A (s==1)? { &c >A } ; 文字入力窓にいるあいだループ
(s)? "ay" ; 「A テキスト全体」「全部一度に置換」
*
======== End of replace.def ========
- 問い合わせなしに「A テキスト全体」を「全部一度に置換」します。
- シフト実行すると、基本機能のままです。
文字列入力ウィンドウ(s=1
)にいるあいだループして「&c
」でキー入力を受け付けます。文字列入力ウィンドウから抜けて、メニュー(s=4
)だったら「"ay"
」を実行します。この場合「(s==4)? "ay"
」と律儀に記述しなくても大丈夫でしょう。文字列入力ウィンドウを[ESC]でキャンセルすると、編集モード(s=0
)に戻るだけですから、何も実行せずに終了します。置換範囲をブロックモードで指定していた場合、「"ay"
」の「a
」は無効になりますが、動作に支障はありません。
&d
全画面の再表示(display)
- 【書式】
&d
- 【解説】
- 「
&s
」で停止した画面出力を再開して、全画面を再表示します。 - 【返り値】
- なし(rは保存)
silentフラグ(未公開システム変数ss)は0(OFF)になります。ky(保存したカーソルのY位置)をいじった直後などには「&d
」だけではカーソル行の表示がうまくいかないので、「&d #]
」としてください。
また、編集モード以外でいきなり「&d
」を実行しても、再表示がうまくいきません。たとえば、「&c
」の使用例「全ファイルのクローズ」の画面表示を消して、修正ファイルのときだけ問い合わせようと、
9 [ESC]X "全ファイルのクローズ"
?.
:A &s ; silent
#C ; ファイルのクローズ
:B (s)>?{ >A . . . } ; s が 0 なら「:A」へループ
&d ; display
&c ; [Y]/[N]/[ESC]の入力を待つ
(r<0)?. ; [ESC]でキャンセルなら中断
>B
としても、メッセージが表示されません。メッセージが出てから「&d
」を実行しても遅いのです。
9 [ESC]X "全ファイルのクローズ"
?.
:A &s ; silent
(mr==1||wc==1)? &d ; 修正または最後のファイルなら display
#C ; ファイルのクローズ
:B (s)>?{ >A . . . } ; s が 0 なら「:A」へループ
&c ; [Y]/[N]/[ESC]の入力を待つ
(r<0)?. ; [ESC]でキャンセルなら中断
>B
このように「#C
」の前に条件付きで「&d
」を実行するとよいでしょう。
&e
マクロ文字列の実行(extern)
- 【書式】
&e
("マクロ文字列") または&e(p)
- 【返り値】
- 実行したマクロの返り値
- 【解説】
- ポインタで示される)文字列をマクロコードとして実行します。
VZ標準の[ESC]@「マクロ文の実行」で使われています。
ここでは激辛マクロ師の超絶技をご覧いただきましょう。
11 [ESC]@ "Macro statement:" ; by BabeChin GCD00414@Nifty Serve
&g($-21) (r<0)?. (r)?? &e(pw) (pw.0=='&')?.
pv[, r[, pv"%16s %04xh %d %u 0000 0000 0000 0000 '%c'%-20s",
(16){ pv.35 = r&1|'0', r=r>>1, pv--, (pv.35==' ')?pv--,}
&m(pv+20, pw, r], r, r, r, r) pv],
┌ Macro statement: ┐ │ │ └─────────┘
という1行ウィンドウがあらわれます。
たとえば「256」と入力すると、
256 0100h 256 256 0000 0001 0000 0000 '^A
とメッセージにでます。ビット表示「0000 0001 0000 0000」が感涙物です。
演算部分の解説はしません。(できません)
&g
で取得した文字列はワーク用ヒストリーバッファ(ポインタ変数pw)に格納されるので、「&e(pw)
」で実行します。
&f
文字列内で文字を検索(find)
- 【書式】
&f(c.str)
- 【解説】
- 文字列str内で文字cを検索して、見つかった位置をrに返します。
- 【返り値】
-
見つかった位置 r>=0 見つからなかった r=-1
ここでいう検索とは、テキスト上の検索ではありません。文字列strはマクロコード内の文字列(あるいはポインタ)と考えたほうがよいでしょう。
======== monogusa.def by I.KAMIMURA ========
【ものぐさスクロール】
* M
80 ^\ "珈琲は右手に"
?.
&j(0) ; FEPをOFFする
:A &m("[E][X][R][C][W][Z] [ESC]:Quit")
:B ep[, ep+, &p ep], ; ep+,… [ESC]を1打で有効にする
(s)? { &o(r) >B } ; 編集モード以外ならそのまま実行
(r==#[)? >C ; [ESC]なら終了
(r>$FF)? { &o(r) >A } ; コマンドならそのまま実行
&f(r,"EXRCWZexrcwzイサスソテツ") ; 入力キーを文字列と比較する
(r%6)>? { #e #x #r #c #w #z } ; 見つかった位置に対応するコマンド
>A ; 見つからなければ何もせずループ
:C &j(-1) ; FEPをOFFする前の状態に戻す
&m("Quit")
*
======== End of monogusa.def ========
このマクロを実行すると、
[E][X][R][C][W][Z] [ESC]:Quit
とメッセージがでます。[ESC]を押して終了させるまで、[E][X][R][C][W][Z]のいずれかの文字キーを押してスクロールできます。
[E][e][イ]……[↑] [X][x][サ]……[↓] [R][r][ス]……ページアップ [C][c][ソ]……ページダウン [W][w][テ]……ロールダウン [Z][z][ツ]……ロールアップ
このマクロは「モード型マクロ」なので、「&p
」「&o
」の項も参照してください。「&p
」の返り値(文字コード)を「"EXRCWZexrcwzイサスソテツ"」内で検索して、見つかった位置をrに返します。「&j(0)
」でFEPをOFFにしていますが、[CAPS]や[カナ]は制御できないので、「exrcwzイサスソテツ」も含めています。r(0~17)を「r%6
」(6で割った余り)で0~5に丸めます。たとえば[C][c][ソ]のいずれを押しても3になります。その値をもとに多重分岐して、対応するコマンドを実行します。
文字列は「p="EXRCWZexrcwzイサスソテツ"
」と変数に代入しておいて、「&f(r,p)
」と記述することもできます。
&g
1行ウィンドウで文字入力をうながす(get string)
- 【書式】
&g("タイトル")
- 【解説】
- 指定のタイトルで1行ウィンドウをだして、文字列の入力をうながします。
- 【返り値】
-
応答 入力例 返り値 (pw) 文字列を入力 平成4年 r=0 平成4年 数値を入力 2001年 r=2001 2001年(rは0,-1,-2以外) [ESC]でキャンセル - r=-1 - [CR]のみ入力 - r=-2 -
- 「-1」「-2」を入力すると、[ESC][CR]と区別がつきません。
- 入力できる文字列の長さは半角62文字までです。
入力された文字列はポインタ変数pwで指し示されるワーク用ヒストリーバッファに格納されます。
======== chgtitle.def by I.KAMIMURA ========
* M
80 ^\ "タイトル変更"
a="タイトル変更", ;(1)ノーマル
; a="$!タイトル変更", ;(2)反転表示
; a=$-16, ;(3)マクロタイトルを利用
:A &g(a)
(r==-1)? { &m("[ESC]でキャンセル"). }
(r==-2)? { &m("[CR]のみ入力"). }
(r)? { &m("10進数:%d 16進数:%02xh",r,r). }
a=pw, >A ; 文字入力(r=0)ならタイトルを変更
*
======== End of chgtitle.def ========
┌ タイトル変更 ┐ │ │ └───────┘
という1行ウィンドウがあらわれます。
このタイトルが、入力した文字列に変わります。文字列の先頭に数値(あるいは'$')があると、数値を入力したとみなされるので気をつけてください。
(1)の行を(2)あるいは(3)と差し替えるとなかなか楽しめますので、どうぞお試しください。
======== macfmt.def by I.KAMIMURA ========
【マクロ書式作成】
* M
80 ^\ "Macro Format"
?.
(wc==tc)? { &m(8). } ; テキスト数チェック
&g("name") ; マクロの主ファイル名を入力
(r<0)?. ; [ESC]あるいは[CR]のみなら終了
#J #e (lx>8) #[ ? { &m(40). } ; 8バイト以内かチェック
&s
#N &?("%s%s.def",pi,pw) #m ; 【新規ファイル】オープン
&?("======== %s.def by I.KAMIMURA ========",pw) #m
"* M" #m
&?("80 ^\%c$"%s$"",9,pw) #m ; 主ファイル名を仮タイトルにする
#n &?("======== End of %s.def ========",pw)
#n '*' #n #21
&d #]
*
======== End of macfmt.def ========
マクロファイルを新規作成するマクロです。「name」の1行ウィンドウに主ファイル名を入力してください。その文字列にVZ.DEFのディレクトリ(pi)と拡張子「.DEF」を付加して、ファイルを新規作成します。「キーアサイン」や「作者名」は適当に書き換えてください。
入力した文字列が8バイト以内かどうかチェックしています。【行番号】の1行ウィンドウもワーク用ヒストリーバッファを利用しているので、「&g
」で取得した文字列を「#J #e
」で呼び出して「lx>8
」で判定できます。1行ウィンドウの中でlx(表示カーソルのカラム位置)が有効なのがミソです。
&h
16進数の取得(hexa)
- 【書式】
&h
- 【解説】
- カーソル位置の文字列を16進数とみなして、その値をrに返します。
- 【返り値】
- 0~FFFF
カーソル位置の文字列 | 返り値 |
'0'~'9','A'~'F','a'~'f' | 数値 |
上記以外 | -1 |
※「FFFF」は「-1」と同じ意味なので、16進数とみなされません。
======== &h_&n.def by I.KAMIMURA ========
【10進数/16進数】
* M
80 ^\ "&h,&n テスト"
&n n=r, ; 10進数とみなして取得
&h h=r, ; 16進数とみなして取得
&m("&n=10進数:%d 16進数:%x &h=10進数:%d 16進数:%x",n,n,h,h)
*
======== End of &h_&n.def ========
書式制御「%d
」「%x
」とのカラミもあるので注意して使ってください。
&i
ソフトウェア割り込み(interrupt)
- 【書式】
&i(n)
または&i("機械語")
- 【解説】
- n番のソフトウェア割り込みを実行します。
- 【返り値】
- フラグレジスタの値
CPUのレジスタと同名のシステム変数ax,bx,cx,dx,si,diに値をセットして、「&i($21)
」でファンクションコールを実行します。セグメントレジスタcs,ds,es,ssには、VZのコードセグメントczがセットされます。実行結果は同じくax,bx,cx,dx,si,diに返ってきます。システム変数rにはフラグレジスタの値(正常に終了したら0)が入ります。
アセンブリ言語に通じている人でないと理解できませんが、簡単なファンクションコールならその方面の書籍を参考にして、見よう見真似で作成できます。
======== subdir.def by I.KAMIMURA ========
* M
80 ^\ "サブディレクトリ作成/削除"
(ks&1)? >B ; シフト実行か?
:A &g("make sub dir") ; 通常実行ならディレクトリ作成
(r<0)?. ; [ESC]なら終了
ax=$3900, ; AH←39h AL←00h
dx=pw, ; DS:DX←パス名の位置
&i($21) >C ; int 21h : MS-DOS ファンクションコール
:B &g("del sub dir") ; シフト実行ならディレクトリ削除
(r<0)?. ; [ESC]なら終了
ax=$3A00, ; AH←3Ah, AL←00h
dx=pw, ; DS:DX←パス名の位置
&i($21) >C ; int 21h : MS-DOS ファンクションコール
:C (r)??. ; r=0 なら正常終了
&b(3) &m(40) ; r!=0 なら「指定が違います」
*
======== End of subdir.def ========
コマンドラインにおりることなく、ディレクトリを作成/削除します。無効なパスを入力すると返り値が非ゼロになるので、「指定が違います」とエラーメッセージを出します。
「&i("機械語")
」でバイナリコードを記述する(実際には「$(hh,ee,xx)
」で16進コードを埋め込む)方法はアセンブリ言語そのものなので、立ち入りません。
&j
日本語FEPの制御(Japanese)
- 【書式】
&j(n)
- 【解説】
- nで指定した値によって、日本語FEPを制御します。
- 【返り値】
- なし(rは保存)
n=0 | FEPをOFF |
n>0 | FEPを強制ON(FRオプションと同じ値を指定) |
n=-1 | FEPをOFFの前の状態に戻す |
このシステム関数はver 1.57で新設されました。
&k
BIOSによるキー入力(key in)
- 【書式】
&k
- 【返り値】
-
キー入力なし r=0 通常キー r=アスキーコード 特殊キー r=機種依存
ASKIIコードの例
- [CTRL]+[A]→01h
- [A]→41h
次のマクロで、いろいろなキーの返り値を調べてください。
======== &k.def by I.KAMIMURA ========
* M
80 ^\ "&k の返り値"
:A &m(" r=%04xh [ESC]:Quit",r)
:B &k
(r==$1B)? { &m("Quit"). } ; [ESC]なら終了
(r)? >A >B
*
======== End of &k.def ========
「&f
」の項で示したmonogusa.defを、「&p
」ではなく「&k
」で書き直すと、次のようになります。
80 ^\ "珈琲は右手に"
?.
&j(0) ; FEPをOFFする
:A &m("[E][X][R][C][W][Z] [ESC]:Quit")
:B &k
(r)?? >B ; キー入力がなければループ
(r==$1B)? >C ; [ESC]なら終了
&f(r,"EXRCWZexrcwz") ; 入力キーを文字列と比較する
(r%6)>? { #e #x #r #c #w #z } ; 見つかった位置に対応するコマンド
>A ; 見つからなければ何もせずループ
:C &j(-1) ; FEPをOFFする前の状態に戻す
&m("Quit")
「&p
」は「pause」という呼び名が示すように、キー入力があるまで待つのに対して、「&k
」はキー入力があってもなくても先へ進みます。「(r)?? >B
」を削除するか、あるいは「(r)?? >A
」と書き換えると、メッセージがせわしなくチラつきます。目にはさやかに見えねども、キー入力があるまで延々とループしているのです。
[CTRL]+[英字]は押しにくいですし、ファンクションキーや矢印キーは機種依存するので、文字キーを使うのが簡単です。[ESC]はPC-9801とIBM系で共通ですが、
(r=='Q'||r=='q')? >C ; [Q][q]なら終了
または、
&f(r,"EXRCWZQexrcwzq")
(r%7)>? { #e #x #r #c #w #z >C }
として、[Q][q]で終了してもよいでしょう。ちなみに、[カナ]がONになっていてもカタカナではなく英字とみなされるので、「イサスソテツ」(半角)は不要です。
一括処理の中断
「&k
」は一括処理を中断するのに便利です。
tool.defの「指定桁折」を見てみましょう。
:A &k (r==$1B)? >Z ; [ESC]が押されたら中断
文章が桁折りされる過程を眺めていて、なんらかの理由で中断したくなったときに、[ESC]を押すと一括処理のループから抜けます。「&k
」の返り値はここ以外では使われていないので、
:A &k (r)? >Z ; なにかキーが押されたら中断
でもよいでしょう。
【&kの主な返り値】
┌─────────┐ │PC-9801,IBM系共通 │ ├────┬────┤ │^A │$1 │ │^B │$2 │ │^C │$3 │ ~~~~~~~~~~~ │^X │$18 │ │^Y │$19 │ │^Z │$1A │ ├────┼────┤ │A │$41 │ │B │$42 │ │C │$43 │ ~~~~~~~~~~~ │x │$78 │ │y │$79 │ │z │$7A │ ├────┼────┤ │リターン│$D │ │[BS] │$8 │ │[TAB] │$9 │ │[ESC] │$1B │ └────┴────┘
┌────┬────┬────┐ │ key │PC-9801 │IBM系 │ ├────┼────┼────┤ │\[Tab] │ │$F00 │ ├────┼────┼────┤ │[INS] │$3800 │$5200 │ │[DEL] │$3900 │$5300 │ ├────┼────┼────┤ │[↑] │$3A00 │$4800 │ │[↓] │$3D00 │$5000 │ │[←] │$3B00 │$4B00 │ │[→] │$3C00 │$4D00 │ ├────┼────┼────┤ │[PgUp] │ │$4900 │ │[PgDn] │ │$5100 │ │\[PgUp] │ │$4900 │ │\[PgDn] │ │$5100 │ │^[PgUp] │ │$8400 │ │^[PgDn] │ │$7600 │ ├────┼────┼────┤ │[Rlup] │$3600 │ │ │[RlDn] │$3700 │ │ │\[Rlup] │$3600 │ │ │\[RlDn] │$3700 │ │ │^[RlUp] │$3600 │ │ │^[RlDn] │$3700 │ │ ├────┼────┼────┤ │[End] │ │$4F00 │ │\[End] │ │$4F00 │ │^[End] │ │$7500 │ ├────┼────┼────┤ │[Home] │ │$4700 │ │\[Home] │ │$4700 │ │^[Home] │ │$7700 │ ├────┼────┼────┤ │[HELP] │$3F00 │ │ ├────┼────┼────┤ │[F1] │$6200 │$3B00 │ │[F2] │$6300 │$3C00 │ │[F3] │$6400 │$3D00 │ │[F4] │$6500 │$3E00 │ │[F5] │$6600 │$3F00 │ │[F6] │$6700 │$4000 │ │[F7] │$6800 │$4100 │ │[F8] │$6900 │$4200 │ │[F9] │$6A00 │$4300 │ │[F10] │$6B00 │$4400 │ ├────┼────┼────┤ │\[F1] │$8200 │$5400 │ │\[F2] │$8300 │$5500 │ │\[F3] │$8400 │$5600 │ │\[F4] │$8500 │$5700 │ │\[F5] │$8600 │$5800 │ │\[F6] │$8700 │$5900 │ │\[F7] │$8800 │$5A00 │ │\[F8] │$8900 │$5B00 │ │\[F9] │$8A00 │$5C00 │ │\[F10] │$8B00 │$5D00 │ ├────┼────┼────┤ │^[F1] │$9200 │$5E00 │ │^[F2] │$9300 │$5F00 │ │^[F3] │$9400 │$6000 │ │^[F4] │$9500 │$6100 │ │^[F5] │$9600 │$6200 │ │^[F6] │$9700 │$6300 │ │^[F7] │$9800 │$6400 │ │^[F8] │$9900 │$6500 │ │^[F9] │$9A00 │$6600 │ │^[F10] │$9B00 │$6700 │ ├────┼────┼────┤ │@[F1] │ │$6800 │ │@[F2] │ │$6900 │ │@[F3] │ │$6A00 │ │@[F4] │ │$6B00 │ │@[F5] │ │$6C00 │ │@[F6] │ │$6D00 │ │@[F7] │ │$6E00 │ │@[F8] │ │$6F00 │ │@[F9] │ │$7000 │ │@[F10] │ │$7100 │ └────┴────┴────┘
&l
1行文字列の入力(line in)
- 【書式】
&l
- 【解説】
- リターンキーまたは[ESC]キーが押されるまでキー入力を受け付ける
- 【返り値】
- なし(rは破壊)
「line in」という呼び名が示すように、1行入力(【検索文字列】などの1行ウィンドウやコマンドライン)を待つときに利用します。
======== search.def by I.KAMIMURA ========
【ただちに検索】
* M
80 ^\ "search"
?.
k=ks&1, ; [SHIFT]の押し下げ状態を k に保存
#F &l (r)?. ; 【検索文字列】の1行ウィンドウ
(k)? #r ? #c ; #r…後方検索、#c…前方検索
*
======== End of search.def ========
最初に【検索文字列】の1行ウィンドウがオープンします。検索文字列を入力して、リターンで確定すると、ただちに前方または後方に検索します(VZの基本機能では、^Rまたは^Cを押す必要がある)。
【検索文字列】の1行ウィンドウで文字を入力したり、文字を削除したり、カーソルを移動したりといったキー入力を「&l
」1個で受けとめます。「&l
」自体に返り値はありませんが、[ESC]でキャンセルすると「#F
」が異常終了したものとして-1が返るので、「(r)?.
」で終了させます。
コマンドラインでの使い方も紹介しましょう。
======== dos.def by I.KAMIMURA ========
* M
80 ^\ "DOSコマンド実行"
?.
#E ; [ESC]E…コマンドラインへ
&l ; リターンまたは[ESC]を待つ
(s-2)?. ; コマンドラインでなければ終了
#95 ; console 画面へ
#U ky=1, ; コマンド開始位置へ戻る
&d #] ; 画面表示を更新
*
======== End of dos.def ========
コマンドラインにおりたところで、試しに「dir」を実行してください。コマンドが終了するとconsole(VZが保持している特殊なテキスト)に切り替わって、カーソルは最初の「dir」の位置に戻ります。(コマンドラインから手動で[SHIFT]+[x](#95
)でcosoleに切り替えると、カーソルは途中にあります)
コマンドラインを[ESC]でキャンセルしても-1は返らないようなので、システムモードが2でなければ終了させます。
VZはコマンド実行時にconsoleの最後をマークするので、「#U
」(直前のカーソル位置)で戻ることができます。カーソル行が画面の上端にくるようにkyをいじったあとは、「&d #]
」で画面表示を更新しないと、実際のカーソル位置と見かけのカーソル位置が一時的にずれて表示されます。
【入力ファイル】などファイルオープンに関連する1行ウィンドウでは、リターンの空打ちやワイルドカードの入力でファイラーが起動するので、「&l
」には向いていません。
:A (s)? { &c >A }
のように「&c
」でループさせるべきです。
また、【編集テキスト】のメニューでは、リターンキーではなく数字キーや英字キーで選択できるので、これまた「&l
」には向いていません。
&m
画面最下行へメッセージを出力(message)
- 【書式】
&m("メッセージ")
または&m(n),&m(p)
- 【解説】
- 指定の書式で画面最下行へメッセージを出力します。
- 【返り値】
- なし(rは保存)
&m("メッセージ") | 文字列「メッセージ」をそのまま出力 |
&m(n) | n番のシステムメッセージを出力(&a参照) |
&m(p) | 変数pで指し示される文字列を出力 |
状況におうじてメッセージの文字列や数値を変えたいときに役立つのが書式制御です。「%
」を前置きして、次のような制御文字を記述します。
- | 左揃え(通常は右揃え) |
0 | 出力幅に足りない分を0(ゼロ)で埋める |
10進数 | 出力幅の最小値 |
, | 3桁おきに「,」を挿入(ver1.57以降) |
d | 符号(±)付き10進数(-32768~32767) |
u | 符号(±)無し10進数(0~65535) |
x | 16進数(0~FFFF) |
c | 文字 |
s | 文字列 |
例1
┌────┬─────────────┬──────────────┐ │ 設 定 │a="VZ", b="COM", c=47970, │a="VMAP", b="COM", c=1958, │ ├────┼─────────────┴──────────────┤ │ 書 式 │ &m("%-9s%-3s%9u",a,b,c) │ ├────┼─────────────┬──────────────┤ │ 結 果 │VZ COM 47970 │VMAP COM 1958 │ └────┴─────────────┴──────────────┘ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ │ │ │ │ │ │ │ │ └─ 9 ─┴3┴─ 9 ─┘ └─ 9 ─┴3┴─ 9 ─┘ 左揃え 右揃え 左揃え 右揃え
「&m(...)
」内の引数「,a,b,c
」はそれぞれ「%-9s
」「%-3s
」「%9u
」に対応しています。
例2
┌────┬───────┬────────┬─────────┐ │ 設 定 │x=3, │x=7, │x=9, │ ├────┼───────┴────────┴─────────┤ │ 書 式 │ y="サイボーグ", (x==7)? y="殺しの番号", │ │ │ &m("%s%03d",y,x) │ ├────┼───────┬────────┬─────────┤ │ 結 果 │サイボーグ003 │殺しの番号007 │サイボーグ009 │ └────┴───────┴────────┴─────────┘
例3
┌──────┬─────────────┬────────────┐ │カーソル位置│'あ' │タブコード │ ├──────┼─────────────┴────────────┤ │ 書 式 │ &m("「%c」の文字コードは%02xh",cd,cd) │ ├──────┼─────────────┬────────────┤ │ 結 果 │「あ」の文字コードは82A0h │「→」の文字コードは09h │ └──────┴─────────────┴────────────┘
※ cd……カーソル位置の文字コード(数値)
同じ「cd」でも、「%c
」と「%02x
」で表示が違うことに注意してください。
「%02x
」は「出力幅が2桁に足りない分を0で埋める」という意味なので、「82A0」のように2桁をこえる場合には意味をもちません。(「082A0」とはならない)
「%」文字そのものは「%%
」
「%」文字そのものを表示したい場合は、「%%
」と記述してください。
「%
」を単独で記述すると、直後の1文字を制御文字とみなし、おまけに対応する引数がないので、わけのわからない表示になります。
「&s
」で画面出力を停止すると
「&s
」で画面出力を停止していても、「&m
」のメッセージは表示されます。
「&s
」で画面の書き換えを停止すると処理を速くできますが、何が起きているのか分からぬまま待つのは辛いものです。「処理中 ...」のメッセージを出しても、あまり気休めにはなりません。「ひょっとして、メッセージを出したままハングしているのでは……」
その不安をやわらげるには、動きのあるメッセージを使うとよいでしょう。メッセージを書き換えるだけなら、処理速度への影響はほとんどありません。
&m("Line:%d",ln)
のように、現在カーソルのいる行番号を知らせれば、番号の変化で動作中であると分かります。
&?
カーソル位置へ出力(print)
- 【書式】
&?("文字列")
または&?(p)
- 【解説】
- 指定の書式でカーソル位置へ文字列を出力します。
- 【返り値】
- なし(rは破壊)
書式制御は「&m
」に準じます。
「&?(pi)
」は「&?("%s",pi)
」が安全
文字列をポインタ変数で示す場合にかぎって、「&?(pi)
」のように変数だけ記述して済ませることができますが、もしその文字列内に単独の「%
」が含まれていると、対応する制御文字・引数がないので、出力結果が不定になります。「&m
」ならメッセージが乱れるだけで実害はありませんが、「&?
」では大いに問題です。多少長くなっても丁寧に「&?("%s",pi)
」と記述しておけば、単独の「%」もきちんと出力されます。
&n
10進数の取得(numeric)
- 【書式】
&n
- 【返り値】
- -32768~32767
カーソル位置の文字列 | 返り値 |
'0'~'9','-' | 数値 |
'$' | 16進数 |
''' | 文字定数 |
上記以外 | -1 |
※「65535」や「-1」は10進数とみなされません。
「'A'」の前側の「'」にカーソルをおいて、
&n &m("r=%d,",r)
を実行すると、「r=65,
」と表示されます。65は「A」の文字コードです。
&o
文字またはコマンドの出力(output)
- 【書式】
&o(c)
- 【解説】
- cで指定した文字を出力またはコマンドを実行
- 【返り値】
- なし(rは破壊:コマンドの返り値)
主として「&p
」と組み合わせて使いますが、単独で使うこともできます。文字を書き込むには文字コードをそのまま与えてやるだけです。
文字を出力
引数 | 実行 | 結果 | 補足説明 |
c=9, | &o(c) | タブ | c=$9でも同じ |
c=32, | 半角スペース | 10進数表記 | |
c=$20, | 半角スペース | 16進数表記 | |
c=$82A0, | 'あ' | 全角文字でも有効 | |
c='あ', | 'あ' | 'あ'は文字コード扱い |
VZのコマンドを実行
機能番号+256をあたえます。
引数 | 実行 | 結果 | 補足説明 |
c=268, | &o(c) | 論理行末へ | 10進数表記 |
c=$10C, | 論理行末へ | 16進数表記 | |
c=#>, | 論理行末へ | #>は12+256と同値 |
※ 「#>」の機能番号は12
この256という数字はどこからきているのかと言うと、0~255は半角の英記号やカタカナに割り当てられているのです。(巻末文字コード表を参照)
&p
文字またはコマンドの入力を待つ(pause)
- 【書式】
&p
- 【解説】
- 入力された「文字コード」または「機能番号+256」を返します。
- 【返り値】
-
キー入力 返り値 補足説明 半角文字 0~255(0~$FF) アスキーコード 全角文字 33088~($8140~) シフトJISコード コマンド 257~354($101~$162) 機能番号+256
主として「&o
」と組み合わせて使います。「&p
」の返り値をしらべて、
ある特定のキーが押されたら、通常と違う動作をさせる それ以外のキーが押されたら、通常どおりの動作をさせる
いわゆるモード型マクロを実現します。
======== free.def by I.KAMIMURA ========
【フリーカーソルモード】
* M
80 ^\ "Free Cursor"
?.
en[, en-, ; カーソルを行末以降に表示させる
:A &m("<<< Free Cursor Mode >>> [ESC]:Quit")
:B ep[, ep+, &p ep], ; 編集モードで[ESC]1打を有効にする
(s)? { &o(r) >B } ; 編集モード以外ならそのまま実行
(r==#[)? >C ; [ESC]が押されたか?
(r==#x)? { ; [CTRL]+[X] または [↓]か?
#x (r)? { #> #m } >A ; ゆきどまりなら改行をいれる
}
(ct>1)? { &o(r) >A } ; 改行上でなければそのまま実行
(r==#s && lx+lh)? { ; [←]かつ「論理行頭でない」か?
&x(lx--) >A ; 1桁左へ
}
(r==#d && lx<we-1)? { ; [→]かつ「画面幅より左」か?
&x(lx++) >A ; 1桁右へ
}
(r>$FF)? { &o(r) >A } ; 他のコマンド(r>255)ならそのまま実行
c=r, x=lx, ; rをcに代入して保存。桁位置をxに代入
#> eu[, eu+, D(x) eu], ; 改行上からx桁までスペースを挿入
#> &o(c) >A ; 文字を出力
:C en], &m("Quit") ; オプションを元に戻して終了
*
======== End of free.def ========
序章で紹介した「フリーカーソル」のモード型マクロ版です。改行以降やファイルの最後以降でカーソルが自由に動くのみならず、文字を入力すると見た目どおりの位置に書き込まれます。
「&p
」で受け取ったキー入力は、「&o(r)
」で実行しないかぎり、なんの動作もしません。rが「ある特定のキー」であるかどうか判定して、もし違ったらそのまま「&o(r)
」で実行して、ふだんと同じ動作させます。もし「ある特定のキー」だったら、分岐してふだんと違う動作をさせます。たとえば「r==#d
」で[→]が押されたかどうか判断します。(「r==#d
」は「r==264
」でも同じ)
「#x
」「#s
」「#d
」のいずれでもなかったら、今度は「コマンド」か「文字」かで分岐します。「r>$FF
」では、全角文字(r>=$8140
)まで含まれる気がしますが、VZ内部では$8000以上はマイナスの数値として扱われるので、差し支えないのです。
文字が入力された場合、現在の桁位置までスペースで埋めてから文字を書き込みます。「D(x)
」の前に「#>
」でカーソルを改行マーク上に呼び戻しておかないと、現在の桁位置とxが同じなのでスペースが挿入されません。また、「c=r,
」で返り値を保存しておかないと、「#>
」で返り値が壊れてしまいます。「c=r,
」は「&p
」の直後でもよいでしょう。
[ESC]でモードを終了させるには、epオプション(編集モード時の[ESC]の扱い)をいじる必要があります。ふだんは[ESC]はプリフィックスキー(ep-,
:他のキーと組み合わせて意味をもつ)ですが、「ep+,
」の状態では独立したキーとして「r==#[
」(r==#03
)で判定できます。ただし、なんらかのミスで「ep+,
」のままモードを終了すると、次にプリフィックスキーのつもりで[ESC]を押した瞬間にVZが終了してしまうので、くれぐれも慎重に使ってください。
不安があるなら、
:B &p
(s)? { &o(r) >B } ; 編集モード以外ならそのまま実行
(r==#Q)? >C ; [ESC]Q が押されたか?
と書き換えるとよいでしょう。[ESC]+[Q]でモードを終了します。
他のマクロはモード型マクロとは無関係に動作します
フリーカーソルモードで他のマクロを実行すると、そのマクロが終了してから「&p
」に戻ります。「&o(r)
」で実行して戻るのではなく、まったく無関係に動作します。
では、モード型マクロが監視しているキーと、他のマクロのキーアサインが同じだったらどうなるでしょうか?
モード型マクロ
(r==#d)? { ; [CTRL]+[D] または [→]か?
※ VZ.DEFの「* C コマンド」の「08」で定義されたキーを監視
グローバルマクロ
80 ^D "→"
?.
(ct>1)? #d ? &x(lx+1)
[CTRL]+[D]を押すと、グローバルマクロが優先されます。
[→]を押すと、キーが重複していないので、モード型マクロが有効になります。
モード型マクロを多重実行すると、最後に実行したモードのみ有効
フリーカーソルモードでmonogusa.def(「&f
」使用例)を多重実行すると、monogusa.defの機能(文字キーによるスクロール)だけが有効になります。monogusa.defを終了すると、フリーカーソルモードに戻ります。
&q
サブルーチンコールのネストを1レベルスキップ(quit)
- 【書式】
&q
- 【解説】
- サブルーチン(ローカルマクロ)から、さらにサブルーチンをコールしている場合など、1レベルスキップしてコール元に戻ります。
- 【返り値】
- なし(rは保存)
サブルーチンコールのネストをスキップするだけでなく、モード型マクロの二重実行を防止する使い方もできます。
======== getblock.def by I.KAMIMURA ========
【汎用・文字列の取得】
* M
80 ^L "Get Block"
?.
(cm)?? &q ; 二重実行ならネストを1レベルスキップ
(mb)? { #G. } ; ブロックモードならその範囲を取得
#b ; ブロック範囲指定を開始
:A &s ; 画面出力を停止
c=ct, #d (ct>=c)? >A ; 上位の文字タイプまで右へ移動
:B #? ; カーソル行の再表示
cm-, &p c=r, ; キー入力を待つ
(c==$20||c==$8140)? >A ; 半角/全角スペースならさらに右へ
(c==#r||c==#c)? { #B #G } ; ページアップ/ダウンなら取得して……
&o(c) ; コマンド実行
(c>#x && c<#<)? >B ; #s,#d,#a,#f ならループ
*
======== End of getblock.def ========
VZ標準の「文字列の連続取得」を改変したマクロです。
最初の[CTRL]+[L]でカーソル位置の1語が文字境界のブロックで反転します。そのままスペースキーを押すと、ブロックが伸びていきます。[←]、[→]、[SHIFT]+[←]、[SHIFT]+[→]で微調整することもできます。適当なところで、ページアップ/ページダウンのキーを押すと、プロックの範囲を検索文字列として取得して、ただちに検索します。行・ブロックとしてカットしてもよいでしょう。
このマクロは「&p
」「&o
」の連携によるモード型マクロですが、「&p
」でキー入力を待っているときに、また[CTRL]+[L]を押したらどうなるのでしょうか? なにも対策を講じないと、ネストが8レベルに達するまで多重実行が可能です。そこで、このマクロでは「&p
」の直前に「cm」(直前に実行したコマンド番号)に特定の値(この場合0)をいれておき、多重実行した場合には冒頭の「(cm)?? &q
」でネストをスキップするようにしてあります。すると、すでに範囲指定していた文字境界のブロックを「(mb)? { #G. }
」で取得するので、期せずして「適当なところでもう一度[CTRL]+[L]を押すと、検索文字列として取得する」という好都合な仕様ができあがります。
もちろん、このマクロとは無関係に範囲指定した文字列を[CTRL]+[L]で取得することもできます。
&r
乱数の発生(random)
- 【書式】
&r
- 【解説】
- 0~32767の乱数(でたらめな数値)を発生させます
- 【返り値】
- 0~32767
乱数といえども、VZ内部でなんらかの基準で決定しているはずです。
======== random.def by I.KAMIMURA ========
* M
80 ^\ "乱数と乱数の種"
&r
&m("r=%d, rn=%d,",r,rn)
*
======== End of random.def ========
rnは乱数の種と呼ばれるシステム変数で、でたらめな数値を発生させる元になる数値です。このマクロを実行すると、rとrnはたえず一致します。つまり、返り値がそのまま次回の乱数の種としてセットされるのです。
でたらめさを徹底するには、rnに刻一刻と変化する数値をあたえるとよいでしょう。
VZ添付のGAME.DEFでは、
ax=$2C00, &i($21) rn=cx+dx,
と現在の時刻をあたえて、乱数を初期化しています。
乱数で何をするのかと言うと、第一にゲームマクロで不特定の動きをさせるためです。乱数のままでは使いづらいので、適当に加工します。
======== tunnel.def by I.KAMIMURA ========
【タイムトンネル(どこが?)】
* M
80 ^\ "Time Tunnel"
ax=$2C00, &i($21) rn=cx+dx, ; 乱数の初期化
&r ; 乱数の発生
r%=3000, ; 0~2999 の数値にする
r/=100, ; 100 で割る
&m("%d世紀にやってきた",r+1) ; 1~30世紀
*
======== End of tunnel.def ========
&s
画面出力の停止(silent)
- 【書式】
&s
- 【解説】
- 画面出力を停止して、カーソル移動にともなう画面のちらつきを消します。画面の書き換えをしないで済むぶん、処理が速くなります。画面出力を再開するには、全画面なら「
&d
」、カーソル行だけでよければ「#?
」を実行します。「&d
」を使っておけば間違いでしょう。
silentフラグ(未公開システム変数ss)は1(ON)になります。 - 【返り値】
- なし(rは保存)
コマンドラインでは画面出力を停止できません。
泣く子も黙る「&s
」ですが、コマンドラインでDOSコマンドを実行すると、その処理経過は表示されます。
&t
マクロを一時停止してトレースモードに入る(trace)
- 【書式】
&t
- 【解説】
- マクロコードをワンステップずつ実行して、プログラムのバグ(ミス)を探します。
- 【返り値】
- なし(rは保存)
プログラムにバグ(bug:虫)はつきものです。怪しい場所に「&t
」を仕掛けて、害虫を駆除しましょう。と言っても、「&t
」がゴキブリホイホイのように害虫をつかまえてくれるわけではありません。マクロが「&t
」にさしかかると、一時停止してトレースモードになり、次のキーが有効になります。
スペースキー | ワンステップずつ実行 |
リターンキー | トレースモードを終了して、通常どおり実行 |
[ESC] | マクロを中止 |
画面の左下(ファンクションキー表示の左側)に、これから実行するマクロコードが表示されるはずです。スペースキーを押して、ワンステップずつ実行しながら、どこで予想外の動作をするか監視してください。
たいていのマクロは「&s
」で画面出力を停止した状態で実行するので、実際には「&t&d
」と書くことが多いでしょう。状況によっては複数の「&t
」を仕掛ける必要が出てきます。これはゴキブリホイホイと同じです。
ビープ音(&b
)やメッセージ(&m
)を併用すると効果的でしょう。
なお、PC-9801では[STOP]、IBM系マシンでは[Ctrl]+[Break]でも実行中のマクロをトレースモードにすることができます。
&u
英小文字を英大文字に変換(upper)
- 【書式】
&u(c)
- 【解説】
- cが英小文字('a'~'z')の文字コードなら、英大文字('A'~'Z')の文字コードを返します。英小文字でなければ、そのままの文字コードを返します。
cの値 | 返り値 |
'a'(61h)~'z'(7Ah)上記以外 | 'A'(41h)~'Z'(5Ah)cのまま |
======== extend.def by I.KAMIMURA ========
【拡張子は「.DEF」か?】
* M
80 ^\ "extend"
?.
m=25, ;「相違があります」
#O ;【入力ファイル】の1行ウィンドウ
#P ; ^QN「ファイル名の複写」
#s &u(cd) (r-'F')? >A ; カーソル位置の文字は「F」か?
#s &u(cd) (r-'E')? >A ; カーソル位置の文字は「E」か?
#s &u(cd) (r-'D')? >A ; カーソル位置の文字は「D」か?
#s (cd-'.')? >A ; カーソル位置の文字は「.」か?
m=24, ;「一致しました」
:A #[ &m(m)
*
======== End of extend.def ========
編集中ファイルの拡張子が「.DEF」かどうか調べます。
Dp+
(ファイル名の小文字表示ON)の環境だと、^QN「ファイル名の複写」も小文字になるので、「D」「E」「F」とそのまま比べるわけにはいきません。
(r-'F' && r-'f')? >A
でも悪くありませんが、あえて「&u
」を利用してみました。
「&f
」の使用例で示したmonogusa.defで「&u
」を活用すると、「exrcwz
」は不要になります。
======== monogusa.def by I.KAMIMURA ========
【ものぐさスクロール】
* M
80 ^\ "珈琲は右手に"
?.
&j(0) ; FEPをOFFする
:A &m("[E][X][R][C][W][Z] [ESC]:Quit")
:B ep[, ep+, &p ep], ; ep+,… [ESC]を1打で有効にする
&u(r) ; ★英小文字→英大文字
(s)? { &o(r) >B } ; 編集モード以外ならそのまま実行
(r==#[)? >C ; [ESC]なら終了
(r>$FF)? { &o(r) >A } ; コマンドならそのまま実行
&f(r,"EXRCWZイサスソテツ") ; 入力キーを文字列と比較する
(r%6)>? { #e #x #r #c #w #z } ; 見つかった位置に対応するコマンド
>A ; 見つからなければ何もせずループ
:C &j(-1) ; FEPをOFFする前の状態に戻す
&m("Quit")
*
======== End of monogusa.def ========
&v
カーソル表示のON/OFF(video)
- 【書式】
&v(0)
または&v(1)
- 【解説】
- カーソル表示を「&v(0)」でOFF、「&v(1)」でONにします。
- 【返り値】
- なし(rは保存)
ゲームマクロなどでカーソル表示が邪魔なときには、「&v(0)
」でOFFにします。
ただし、OFFにしていても、「&c
」「&l
」「&p
」などのキー入力待ちになると、表示されます。逆に、「&k
」のループ中はカーソル表示はOFFになりますが、「&v(1)
」で強引に表示できます。
&w
一定時間マクロを休止(wait)
- 【書式】
- &w(time)
- 【解説】
- time(数値)で指定した時間、マクロを休止します。
- 【返り値】
- なし(rは保存)
「&w(60)
」で約1秒間休止します。
ふざけて、とんでもなく大きな数値をいれると、痛い目にあいます。[STOP]でマクロを強制中断しても、実行中の「&w(time)
」を終えてからでないと止まりません。待ちきれないあなたはリセットボタンのお世話になるでしょう。これは「&b(time)
」も同じです。
&x
カーソルをX方向へ移動(x locate)
- 【書式】
&x(n)
- 【解説】
- カーソルをn+1桁目へ移動します。
- 【返り値】
- なし(rは破壊)
======== 40column.def by I.KAMIMURA ========
【40桁ごとに右へ移動】
* M
80 ^Q\ "40column"
?.
x=(lx/40+1)*40, ; 40の倍数にする
(x>254)? x=254, ; 254 以内に限る
&x(x) #? lx=x, ; lx=x, 全角文字上の桁位置を補正
*
======== End of 40column.def ========
カーソルを40桁ごとに右へ移動します。
┌─────┬──────┬───────────┐ │現在(lx)│移動後(lx)│ステータスラインの表示│ ├─────┼──────┼───────────┤ │0~39 │40 │41 │ │40~79 │80 │81 │ ~~~~~~~~~~~~~~~~~~~~~~~~~~ │200~239 │240 │241 │ │240~255 │254 │255 │ └─────┴──────┴───────────┘
lxの値とステータスラインの表示は1つずれているので気をつけてください。
VZ標準の^Q[「表示行頭」、^Q]「表示行末」もこの「&x
」を利用しています。右へ移動する場合、en-,
(カーソルを行末以降に表示させる)の環境だと、カーソルが改行マークより右側までとんでしまうことがありますが、「#?
」または「#]
」でカーソル行に活をいれると、改行マーク上に呼び戻すことができます。
&y
カーソルをY方向へ移動(y locate)
- 【書式】
&y(n)
- 【解説】
- カーソルを画面の最上行からn行目へ移動します。
- 【返り値】
- なし(rは破壊)
nの値 | カーソルの移動先 |
0 | 画面の上端「#39」(画面の上端)と同等 |
-1 | 前の画面へ1行スクロールして画面の上端 |
wy-2 | 画面の下端から2行目「#40」(画面の下端)と同等 |
wy | 次の画面へ1行スクロールして画面の下端から2行目 |
※ wy…編集ウィンドウの高さ
「画面の下端から2行目」に注意してください。[↓]で1行ずつスクロールすればわかりますが、ファンクションキーの表示(画面の下端)から2行目までしかカーソルは移動しません。最後の1行はメッセージに使われるので、不可侵領域となっているのでしょう。
ゲームマクロのように1画面内でカーソルを移動して文字や記号を書き換える場合によく使われます。
コマンド関数
&#r
&#c
画面のスクロール
- 【書式】
&#r(n)
または#(n)
&#c(n)
または$(n)
- 【解説】
- n行ページアップ/ダウンします。「
#r
」「#c
」のスクロール行数を引数で指定できるように拡張した機能です。 - 【返り値】
-
カーソル位置 返り値 ファイルの先頭/最後 -1 上記以外 0
「ファイルの先頭/最後」は必ずしも「これ以上スクロールできない」という意味ではありません。たとえばカーソル行以降に3行しかない状態で「&#c(22)
」でページダウンすると、カーソルはファイルの最後に移動しますが、「十分にスクロールできなかった」として-1が返ります。
======== pageout.def by I.KAMIMURA ========
【ページレイアウト】
* M
80 ^\ "Page Layout"
?.
Dn[, Dn+, ; 表示行モード
Dl[, Dl+, ; 行番号表示ON
PG[, PG=30, ; ★1ページあたり30行にする
&d #] ; 画面の再表示
:A &m("Paging [R]:Up [C]:Down [CR]:^L [ESC]:Quit")
:B ep[, ep+, &p ep], &u(r) ; ep+,([ESC]を有効にする)
(s)? { &o(r) >B } ; 編集モード以外ならそのまま実行
(r==#[)? >C ; [ESC]でモードを終了
(r=='R')? { &#r(PG) >A } ; [R]で1ページアップ
(r=='C')? { &#c(PG) >A } ; [C]で1ページダウン
(r==#m)? { &> >A } ; リターンで「0:」を実行
&o(r) >A ; その他のコマンド
:C PG], Dl], Dn], ; オプション復帰
&d #] &m("Quit")
0: ;---空行と改ページコードを挿入---
&s
ei[, ei-, ; オートインデントOFF
ej[, ej-, ; オートインデント(全角スペース)OFF
&x(0) ; 画面の左端へ
:A (ct)?? >B ; ファイルの最後なら終了
#m ; 改行
((ld-1)%pg)? >A ; ld(表示行番号)はページの第1行か?
:B ej], ei], ; オプション復帰
#s &o($0C) #d ; 前の行末に「^L」を書き込む
ky=wy/2, &d #] ; 画面の中央に表示
*
======== End of pageout.def ========
ページ単位でスクロールするモード型マクロです。1ページあたりの行数はオプションPGで指定します。★の行を適当に書き換えてください。
キー | 機能 |
---|---|
[R] | 1ページアップ |
[C] | 1ページダウン |
[Enter] | カーソル行がページの先頭行になるように空行と改ページ文字「^L」を挿入 |
[ESC] | モード終了 |
&#J
指定行番号へジャンプ
- 【書式】
&#J(n)
- 【解説】
- 行番号nへジャンプします。
- 【返り値】
- なし(rは破壊)
n=0 | 何もしない |
n>最大行数 | ファイルの最後へ |
n=-1 | 65535行目へ |
VZが認識する行番号の最大値は65535です。nに負数をあたえると、最大値から逆算した行番号へジャンプします。
論理行/表示行モードによって動作がことなるので気をつけてください。
論理行モード | 論理行番号の第n行へジャンプ(ln=n) |
表示行モード | 表示行番号の第n行へジャンプ(ld=n) |
&#M
&#U
カーソル位置マーク/マーク位置へジャンプ
- 【書式】
&#M(n)
または,(n)
&#U(n)
または+(n)
- 【解説】
- n(0~4)で指定したマーク番号にカーソル位置を記憶したり、ジャンプしたりします。
- 【返り値】
- なし(rは破壊)
VZ.DEFで使用されています。
16 ^K0 "マーク(1-4)"
?. i=r, &#M(r) (r)?. &m("マーク #%d",i)
17 ^Q0 "マーク位置へジャンプ"
?. &#U(r)
マーク位置(#1~#4)はマクロで実現されているのです。
「マクロに関する特記事項」(マニュアル11-37)により、キーアサインがプリフィックスキー+0の場合、プリフィックスキーのあとに押した数字がrにセットされます。
[0],[5]~[9]が空いているので、なにか機能を割り付ければ、キーアサインを増やすことができます。簡単な定型句など書いておくとよいでしょう。
16 ^K0 "Set Marker(1..4)"
?. i=r,
(i)?? >00
(i-5)>? { >05 >06 >07 >08 >09 }
&#M(i) &m("マーク #%d",i)
0: "IDと氏名"
5: "「」" #s
6: "()" #s
7: "『』" #s
8: "【】" #s
9: "《》" #s
17 ^Q0 "Jump to Marker"
?. i=r,
(i)?? >00
(i-5)>? { >05 >06 >07 >08 >09 }
&#U(i)
0: "ID and Name"
5: "■"
6: "■■"
7: "■■■"
8: &s (78){ "-" } &d
9: &s (39){ "-" } &d
「#M
」「#U
」だと、ジャンプ系のコマンドで「直前のカーソル位置」が変わるので、思わぬ誤動作を招くことがありますが、「&#M(n)
」「&#U(n)
」なら確実です。
&#T
編集テキストの切り替え
- 【書式】
&#T(n)
または?(n)
- 【解説】
- 編集テキストをn番に切り替えます。
- 【返り値】
- なし(rは破壊)
n=0 | consoleに切り替える(ver1.57以降) |
n<0 | 不定 |
n>wc | nをwcで割ったテキスト番号に切り替える |
======== savemem.def by I.KAMIMURA ========
【未修正/修正テキストを一括クローズ】
* M
80 [ESC]Z "Save Memory"
?.
k=ks&1, ; [SHIFT]の押し下げ状態を k に保存
#83 ; プロファイル情報のセーブ
t=wn, ; 実行時のテキスト番号を t に代入
c=wc, ; テキスト数を c に代入
:A &s &#T(c) ; テキスト番号 c に切り替え
(wc<2)? &d ; 残りテキストが1つなら画面表示を再開
(k)? >B ; シフト実行か?
(mr-1)? #C ; 未修正テキストならクローズ
>C
:B (mr==1)? { ; 修正テキストならクローズ
&d #C (s==4)? &c ; 「~を出力しますか? (Y/N)」
}
:C (c--)? >A ; c から 1 引いて 0 になるまで繰り返し
(s)?. ; 編集モードでなければ終了
(t>wc)? t=wc, ; 実行時のテキストをクローズした場合
&d &#T(t) &b(3) ; 実行時のテキストに戻る
*
======== End of savemem.def ========
大きなファイルをたくさんオープンすると、メモリが不足してVZがウンともスンとも言わなくなることがあります。そんなときは、このマクロで未修正テキストを一括クローズして、メモリを節約してください。シフト実行すると、逆に修正テキストについて「~を出力しますか? (Y/N)」と問い合わせながら連続クローズできます。最初に「#83
」でプロファイル情報をセーブしているので、まちがってクローズした場合には、【入力ファイル】の1行ウィンドウで「@」を入力すれば、VZ.DEFのディレクトリにある「editfile」を参照して再オープンできます。
&#Y
画面分割モードの切り替え
- 【書式】
&#Y(n)
または@(n)
- 【解説】
- nで指定した画面分割モードに切り替えます
- 【返り値】
- なし(rは破壊)
n=0 | 全画面 |
n=2,3 | 横分割(カーソルは上側) |
n=4,5 | 横分割(カーソルは左側) |
システム変数wtとは食い違いがあるので、気をつけてください。カーソルを下側や右側に移すには、よぶんに「#W
」(ウィンドウ切替え)を実行しなくてはなりません。この仕様は中途半端なので、VZの対応に期待したいところです。
未公開のシステム変数wh(横分割位置)とwv(縦分割位置)に任意の数値をいれて、分割モードにすると、分割位置をダイレクトに変更できます。
======== border.def by I.KAMIMURA ========
【分割位置のワンタッチ変更】
* M
80 ^KF "Border"
?.
(ks&1)? { #65. } ; シフト実行なら「分割位置の変更」
(wt)? { ; 画面分割しているか?
wh=12, ; 横分割位置の初期値
wv=40, ; 縦分割位置の初期値
&#Y(0). ; 全画面
}
wv=70, ; 縦分割位置を70桁目にする
&#Y(4) ; 縦分割(「#Y #Y」でも可)
*
======== End of border.def ========
全画面モードで実行すると、70桁目で縦分割します。画面分割モードで実行すると、分割位置を初期値に戻して、全画面モードにします。シフト実行すると、基本機能の「分割位置の変更」を実行します。分割位置の数値など適当に書き換えてください。
D
- 【書式】
D(x)
- 【解説】
- カーソル位置からx桁目まで半角スペースまたはタブで埋めます。
- 【返り値】
- なし(rは破壊)
eu+
([TAB]でスペースコードを入力ON)の場合は、タブの長さと同数の半角スペースを出力します。上書きモードでも動作は変わりません。xが現在の桁位置(lx)以下の場合、何もしません。
「#21
」(タブ)とちがって、カーソル位置が変わらないので、必要なら「#f
」や「#>
」で移動してください。また、lh
(カーソル位置の論理行の先頭からのY位置)が0でない場合、カーソルは先頭の行へ移動するので要注意です。
多くの桁数を半角スペースで埋めたい場合、
(n){' '}
でループするよりも、
eu[, eu+, D(n) eu],
で半角スペースを挿入したほうが若干速いようです。
======== instab.def by I.KAMIMURA ========
【カーソル位置までタブを挿入】
* M
80 ^I "Insert Tab"
?.
x=lx, ; 現在の桁位置を x に代入
#? ; 改行マーク上へ呼び戻す
(lx==x)? { #21. } ; カーソル位置が不変なら通常のタブ
D(x) ; x桁目までタブで埋める
#> ; 論理行末へ
*
======== End of instab.def ========
カーソルが改行マークより右側にあるときに実行すると、カーソル位置までタブで埋めます。「フリーカーソル」マクロと併用すると効果的でしょう。
#?
カーソル行の再表示
- 【書式】
#?
または#29
- 【解説】
- 「
&s
」で停止した画面出力を再開して、カーソル行を再表示します。 - 【返り値】
- なし(rは破壊)
silentフラグ(未公開システム変数ss)は0(OFF)になります。
カーソルが改行マークより右側にあるとき「#?
」を実行すると、改行マーク上へ呼び戻すことができます。
「コマンド関数」に分類されているものの、「#29
」と同じなので、cm(直前に実行したコマンド番号)は29になります。
#]
ステータスラインの再表示
- 【書式】
#]
または#84
- 【解説】
- ダミーコマンドを実行し、ステータスラインの再表示、カーソル行(ラインバッファ)の更新をおこないます。
- 【返り値】
- なし(rは破壊)
未修正のテキストで文字を入力した直後には、カーソルはラインバッファ(VZが行編集にもちいる作業領域)にあり、修正フラグ(mr)は立ちません。テキストが修正されているかどうか調べる前には、「#]
」を実行するべきです。
kyに値を代入してカーソル行の表示位置をダイレクトに変更すると、実際のカーソル位置と見かけのカーソル位置が一時的にずれて表示されるので、「#]
」を実行して正常化してください。
「コマンド関数」に分類されているものの、「#84
」と同じなので、cm(直前に実行したコマンド番号)は84になります。
#[
エディタの強制終了
- 【書式】
#[
または#03
- 【解説】
- エディタを強制終了します。修正テキストがある場合は「編集テキストを放棄しますか? (Y/N)」と問い合わせます。
- 【返り値】
- なし(rは破壊)
モード型マクロで[ESC]が押されたかどうか調べる場合、たんに「(r==#[)?
」としても判断できません。
ep[, ep+, &p ep],
(r==#[)? >C
のように、「&p
」の前後でep(編集モード時の[ESC]の扱い)をプッシュ・ポップしてください。
[ESC]は編集モードではプリフィックスキー([ESC]+[英記号]でワンキー)ですが、ep+,
の状態では[ESC]1打でワンキーとみなされます。