Vz Resources
Commands
2018-10-07T21:05:28+09:00

コマンド拡張で学ぶVZマクロ入門 #44

番号記号初期キー機能
#44#M^QMカーソル位置のマーク

カーソル位置の保存を行う。ジャンプ系のコマンドを使用するたびにマーク位置の更新が発生するため,限られた2点間の往復など,あくまでも一時的に使用されるものと割り切るべきである。4ヶ所のマーク位置を保持できる標準組込マクロ(初期キー:^K[1-4])のほか,マーク位置の文字列を表示する拡張マクロや,無限にちかいマークを記憶可能なマクロの導入を検討されたい。

以下の命令(ジャンプ系コマンド及びコマンド関数)を最後に実行した位置にカーソルを移動する。

実行時にカーソル位置をマークする命令一覧
コマンド機能
#41/#^ファイルの先頭行へジャンプ
#42/#_ファイルの最終行へジャンプ
#43/U直前のカーソル位置へジャンプ
#44/#Mカーソル位置のマーク
#45/#J指定行番号ジャンプ
#55/#F検索文字列の設定
&#43(n)/&#U(n)指定マーク位置へジャンプ

これらの命令が記録するマーク位置は wa..63(下位),wa..64(上位) にロング整数で保存される。

戻り値 r:常に0

s==0(編集モード)

カーソル位置のマーク

s==1(文字列入力モード)

無効

s==2(コマンドラインモード)

無効

s==3(ファイラーモード)

無効

s==4(メニュー)

戻り値rの内容

s==4(1文字入力モード)

無効

マクロによる拡張

このコマンドは対となるマーク位置にジャンプするコマンドが存在して初めて意味があると同様に,コマンド拡張においても対のマクロが求められるだろう。そのためには,マーク位置のロング整数の値を保存・復帰させるための手法を知る必要がある。

この節では,値保存用バッファの確保,基本動作に影響を与えずに値を読み書きするための手順について説明する。

= MarkTest.def = by H_ear
#if 0
拡張マーク:マーク位置を取得するサンプル(個々のファイルには非対応)
マーク5-15はグローバル・マーク(ファイル共通)
#endif
* mad for vz!
22 ^K0 ""       ;Mark
        ?. i=r, (i>=0 && i<5)?{ &#M(i) (r)?. >m }
        (i<0 || i>15)?{ &m("数字【0-9】と記号【:;<=>?】のみ使えます.") . }
        &> p=r,                         ;自前バッファの先頭アドレスを取得
        &Le(p,wa+126)                   ;mark0の値をp先頭に擬似プッシュ
        &#M(0)                          ;カーソル位置をマーク
        &Le(p+(i-4)*4,wa+126)           ;mark0の値をiに応じて保存 p+4+(i-5)*4
        &Le(wa+126,p)                   ;mark0の値を擬似ポップ
 :m     &m("MARK #%d",i)
;;      バッファサイズは (拡張マーク数+1)*4 を確保
0:      (3+$)."$[48]"
*
[Variables]
        i       マーク番号
        p       自前バッファ先頭オフセット
[Buffers]
        [48]    自前(4+4*11)
[History]
2018/06/05 0.10 テスト版
[Notes]
グローバル・マークって言うとなんだか格好よいが,要するに手抜き仕様であって,ほとんどバグみたいなもの。

先に断りを入れなければならないが,このマクロは自前マークを設定するためのサンプルであって,不完全なものである。これを理解するためには,そもそもVZのマークが何故4つしかないのか,ということを知る必要があるだろう。その理由はもちろんひとつではないが,重要な側面であることは疑いようもないのが「メモリ」の問題だ。

VZは同時に開いておけるテキストには限りがある。オプションTC(初期値10)によるものだが,ひとつ増やすごとに222バイトメモリを消費する。この222バイトのうちに1マークあたり4バイト合計20バイトの領域を占有しており,際限なく増やせるものでないことは理解できるだろう。変数は言い換えれば決まった大きさの箱であり,とにかくメモリ食いの代物なのだ。

閑話休題。逐次解説に戻る。

mark1-4(製品版サンプルの処理と同じ)の保存と,自前バッファの確保については省略する。なお,拡張マークの数に加えて1マーク分のバッファを確保する理由は,現カーソル位置を保存するためにマーク0を利用するため,実行前のマーク0の値を保存・復帰する必要があるからだ。

        &Le(p,wa+126)                   ;mark0の値をp先頭に擬似プッシュ

頻繁に値が書き換えられるmark0の値を保存する必要があるかどうかは,意見の別れるところだろう。保存する必要がないと判断すれば,一時保存用バッファの確保も,このコードも不要だ。&Le(*p,*q)はロング演算関数で,*qにあるロング整数の値を*pに代入する。値を代入するということは,アドレス*qからアドレス*pへの値の「転送」を行うことと同じである。

        &#M(0)                          ;カーソル位置をマーク

カーソル位置のアドレスを保存するには#M(#44)でもよい。ここでは明示的にmark0を示しているだけだ。mark0は前の行で値を保存したwa+126を先頭とする4バイトに上書き保存される。

        &Le(p+(i-4)*4,wa+126)           ;mark0の値をiに応じて保存 p+4+(i-5)*4

起動キーで得られた戻り値iに応じたアドレスのバッファに,mark0に格納された値を保存する。バッファの先頭4バイトは,元のmark0の値を格納するために確保されているので,実際にマークしたアドレスを格納するのは,バッファの先頭から4バイト先になる。起動キーの戻り値のうち0-4の分は元々テキストワークに確保されているので,iから5を引いておくわけだが,バッファ先頭に1枠をとっているので,実際にはi-4でよい。

        &Le(wa+126,p)                   ;mark0の値を擬似ポップ

保管しておいた元のmark0の値をテキストワークに戻してやる。保管を省略した場合は,この処理は必要ない。

 :m     &m("MARK #%d",i)

製品版サンプルにあるとおり,マーク番号を表示してみせる。別個の処理なのでラベルに飛ばしているが,逆にグローバル・マークである旨の警告表示をしてもよいだろう。


コマンド拡張で学ぶVZマクロ入門 #44
The VZ resources, valid XHTML 1.0 Strict. ©2007-2018 by mezala.