番号 | 記号 | 初期キー | 機能 |
---|---|---|---|
#50 | #p | ^KC \[F09] | 行・ブロック貼付 |
【注】IBM-PC用VZIBMJ.DEFには@[INS]のシフト起動で#pを実行するマクロが初期導入されている。
行・ブロック貼付(ペースト:上書きモード時でも挿入される)
戻り値 r:複写したブロックのモード(ブロック種別)
戻り値rの値 | 貼付したブロックのモード |
---|---|
r = 0 | 非ブロック1行 |
r = 1 | 行ブロック |
r = 2 | 文字ブロック |
無効
無効
無効
無効
テキストスタックから出す「挿入(insert)」(#48
/#i
)と,「貼付(paste)」(#50)が別個のコマンドになっていることが理由と思われるが,これらのコマンドの拡張はあまり見られない。テキストスタックを自由に扱いたいのであれば,Emmett氏の stkmenu.def,高橋洋光氏の改造版 stkmenut.def を利用することが推奨される。#50が出力できるのは最新の行・ブロックだけだが,これらのマクロはテキストスタックに存在する行・ブロックであれば出力できるだけでなく,不要アイテムの一括削除などの管理もできる。
50 ^KC "" ;Ins[\Ek!] H_ear
?. (ks&1)? ek!, #p ?. ek!,
編集スイッチEkはブロック挿入後のカーソル位置をブロックの先頭/末尾で切り替えるオプションである。Ekは初期設定では無効であり,ブロック方向にかかわらずブロック挿入後のカーソル位置はブロックの先頭に位置する。つまり挿入したブロック内に留まる。Ek+
の場合は挿入を実行する前のカーソル行に留まる。
ブロック挿入した部分に編集を加える必要がなく,すぐに次行の編集にとりかかりときはEk+
の方が都合がよい。あるいは,文字ブロックを続けて切除/複写したのち,もとの順序で連結的に挿入したい場合もEk+
であるのがよい。
なお,非ブロックで行切除/複写したものの挿入時はEk+
の影響を受けない。
テキストボックスなど非編集モードで,テキストスタックに格納した文字列出力したいというケースはままあるはずだ。一般的にこのような場合は,削除バッファに入れておいて^Uで出力するということになるわけだが,一旦文字列を複写し,空行に貼り付け,^[BS](^QT)で削除バッファに取り込んでおくという準備を経なければならない。テキストスタックから直接出力できれば,かなり手数を省けることになる。
= stkpaste.def v0.10 = by H_ear
#if 0
全天候型スタック1行出力(高橋版専用)
#endif
* mad for vz!
1 ^^ ""
&> b=r, ;[b]uffer80
(kp)??. ;スタックは空か?
dz[=kz,
l=kp..-1, ;[l]ength
t=kp-3-l, ;[t]op
dz],
(l>80)?l80, ;サイズ制限
&Sp(b,"%*Fs",l,t,kz) ;サイズ分転送
&Jk(b.l--) (r)?b.l-, ;終端の直前が漢字1バイト目なら切断
; &Sf(b,$0d) r..0-, ;途中に改行があれば切断
r=b,
:n &Sf(r,$0d) (r)?{ r..0='n\',>n } ;途中に改行があれば\nに差替え
&?("%s",b)
:z ; ---- exit ----
.
0: (5+$)."$(50,0)$[80]"
*
[Variables]
b [b]uffer80
l [l]ength
t [t]op
[Buffers]
b history buffer 80
[History]
2008/12/11 0.10 初版 コマンド拡張マクロ入門用
[Notes]
作ってみたら GetBuffs でスタックも対象にしてた
テキストスタックには改行を含む長大なテキストが格納されている場合もあるので,文字数制限が必要である。このため確保したヒストリーバッファのサイズ以内に納まらないときは問答無用でぶち切る点に注意が必要だが,改行を含む文字列にも「気持ち」対応している。その必要がなければコメントアウトの行と差し替えればよい。
なお,高橋版VZの書式制御と異セグメント間転送機能拡張に依存しているため,高橋版専用である。高橋版でない場合は,機械語で〈Far Memory Copy〉のルーチンを仕込めばよいだろう。
dz[=kz, ……kzはテキストスタックのセグメントである。kzのオフセットアドレスを取得するため,一時的にdzの指すセグメントをデータセグメントからテキストスタックにすり替えている。オフセットアドレスの取得後は直ちに元に戻す必要がある。
l=kp..-1 ……kpはテキストスタックのエンドオフセットアドレスである。その直前(kp..-1)の2バイト(word値)に最後に格納したテキストの長さが記録されている。
t=kp-3-l ……テキストスタックに最後に格納された文字列の先頭アドレス。kpからサイズ情報等3バイトを加えたサイズ分を引いたアドレスを算出したもの。
テキストスタックのイメージは次の図のようになっている。
↓セグメントKZの先頭 0 ↓(1) ↓kp ┌────┬─┬──┬─…─┬────┬─┬──┬────┬─┬──┬─── │文字列X│型│長さ│ … │文字列2│型│長さ│文字列1│型│長さ│※ └────┴─┴──┴─…─┴────┴─┴──┴────┴─┴──┴─── ↑(3) ↑(2)
(1) kp.-3 : ブロックタイプ(0:行,1:行境界,2:字境界,他:矩形)=&Bmの返り値
(2) kp..-1 : ブロックサイズ(文字列の長さ)単位byte
(3) kp-3-kp..-1 : テキストスタック最後の文字列の先頭アドレス
直前の3バイトに,さらにひとつ前の文字列の型・長さ情報がある。例えば,このアドレスをkpに代入すれば,履歴をひとつ遡ることができることになる。元のkpの値(アドレス)を保存しておいて履歴を遡り,処理の後にkpの値を元に戻せば原状に復帰させられる。