一括表示

− 野ざらし言 −

[2886] ファイル末を改行文字2つにする

文太 2008/09/25(Thu) 21:20
 純粋マクロのロジックというかコーディングのご相談なのですが。

 タイトルの如く、ファイル末を改行文字2字にしたいのです。置換でヌル2つ
に変換して、ヒストリーバッファに送って、バッファ終端にしようという魂胆です。
 できたら、モバでも遅くないようにと願っています。

 下では最後の行のところで、カーソルを激しく動かしていますが、その
部分は無視していただいてよいのですが、これより速いやり方や、短い書き方、
あるいはこんなときに使えるコマンドなど、何かありましたらお教えいただけない
でしょうか。

 けっこう情けないくらい泥臭いと思うのですが、これ。


12:	;-----keep 2 '\n's at the end of the file
	ei[-, #_ #> #s
	(ct==1)?? {#d #m #m >s}	;ない場合、2つ付ける。
	#s (ct==1)? #s		;1つあった。その前は?2つ目あり。1つ前へ
  :t	(ct==1)? {#g #s >t}	;ありすぎは削る
  :s	ei],
	#^ #<

[2887] Re: ファイル末を改行文字2つにする

めざら 2008/09/27(Sat) 00:22
[2886]へのコメント <mezala@nifty.com> http://homepage3.nifty.com/mezala/
ヒストリバッファに転送してから末尾にヌルを書き込む方が簡単かと思います。
その行がラインバッファにあれば,行頭オフセットと行末オフセットから,
実質的な行の長さを求められるので,その位置にヌルを2個書き込みます。

改行をヌルに置換すると,行が連結されて1行になりますね。
その1行を丸ごとラインバッファに入れて,標的のバッファに転送します。
ラインバッファから出ずに行の長さを計算して,そこをバッファの終端にします。
既に最後にひとつヌルがあったときはヌルが3個になりますが,2個も3個も
終端になることは変わりはないので,手を抜くことができるのです。

= test = by H_ear
#if 0
ファイル/行をヌル区切りのデータにしてバッファに転送
#endif
* mad for vz!
1 ^\ "" ?.
        (mr==$80)?{ &m(32,nm) . }       ;リードオンリーです
        #56 "\n" #m &o($0) #m "ay"      ;改行をヌルに置換
        &> a=r,
        b=wm+230,
        #28
        ;ラインバッファの内容をバッファサイズを限度に指定バッファに書込み
        &Sm(a,b,a..-1)
        ;;ラインバッファにいるうちに長さを算出しヌル2個でバッファ終端にする
        ((a+(wa..19-wa..18))..0-,       ;bend-btop==length

 :z     ; ---- exit ----
        
        &d #] .

00:     ; ---- buffer ----
        (5+$)."$(50,0)$[82]"
*

 wa..19-, というのは危険ぽいから止めておきましょう。

[2888] Re^2: ファイル末を改行文字2つにする

文太 2008/09/27(Sat) 01:22
[2887]へのコメント
めざらさん、

 ありがとうございました。ラインバッファか! この算出法を理解するには、
少々時間がかかるかもしれませんし、つまらない質問をしてしまうかもしれませ
んが、でも、以下は、なるほど、あ、考えもつかなかったと、深く、深く納得で
す。やっぱ、マクロ師が考えることが違う。すごい。目から鱗。耳から…何?

 明後日には多くの問題が片づくでしょう。ありがとうございました。

> ヒストリバッファに転送してから末尾にヌルを書き込む方が簡単かと思います。
> その行がラインバッファにあれば,行頭オフセットと行末オフセットから,
> 実質的な行の長さを求められるので,その位置にヌルを2個書き込みます。
>
> 改行をヌルに置換すると,行が連結されて1行になりますね。
> その1行を丸ごとラインバッファに入れて,標的のバッファに転送します。
> ラインバッファから出ずに行の長さを計算して,そこをバッファの終端にします。
> 既に最後にひとつヌルがあったときはヌルが3個になりますが,2個も3個も
> 終端になることは変わりはないので,手を抜くことができるのです。

 この手抜きについては、近いことを考えていたのです。ここがすごいな。ライ
ンバッファか。どうしてテキストバッファまで飛んでしまっていたのでしょう?
 まったく甘い。どうも、どうも、ありがとうございました。m(__)m

 もっと手前。Vzはうまいことできてるキカイダーなんだから。多謝。
                                  文太

[2889] Re: ファイル末を改行文字2つにする

YASAT 2008/09/27(Sat) 11:58
[2886]へのコメント
ヒストリバッファの中身を気にせずまっさらなバッファとして使いたい、
ということでよろしいでしょうか。
でしたら、こういう方法はどうでしょう。

&Sc(pa,"test1234")
pa.0-,
&Sh(pa,"test")

[2890] Re^2: ファイル末を改行文字2つにする

めざら 2008/09/27(Sat) 12:52
[2889]へのコメント <mezala@nifty.com> http://homepage3.nifty.com/mezala/
 『サンダーバード2号』計画なんだそうです。

 ファイルに書き出したバッファの内容をヂカ書きで編集して戻すとか,環境に応じた初期文字列を取り込むとか。

 プロファイル機能を乗っ取ればいいようにも思いますが,ほれ,そこは特化したマクロを作りたいという要求もあるのでしょう。

 しかし,別に古かったり壊れているような履歴でも,別に残っていて害はなさそうな気もしますけどね。無害・有害の範囲が有用・無用と同じと考えるのであれば初期化は必要なのでしょうけど。

[2892] Re^3: ファイル末を改行文字2つにする

文太 2008/09/27(Sat) 13:10
[2890]へのコメント
たぶん、YASATさんに解説してくださったのだろうと。m(__)m

>  プロファイル機能を乗っ取ればいいようにも思いますが,ほれ,そこは特化し
> たマクロを作りたいという要求もあるのでしょう。

 うーん、pf だけとか pw だけとか出せないし、出して消すのも…。 バッファ
に送るほうも…。
 間違えたか?>俺。

>  しかし,別に古かったり壊れているような履歴でも,別に残っていて害はなさ
> そうな気もしますけどね。無害・有害の範囲が有用・無用と同じと考えるのであ
> れば初期化は必要なのでしょうけど。

 わ、わかんにゃい。ワンワン。
 自分が書いていることに筋が通っているのか、自信なし。

[2894] Re^4: ファイル末を改行文字2つにする

めざら 2008/09/28(Sun) 06:42
[2892]へのコメント <mezala@nifty.com> http://homepage3.nifty.com/mezala/
> たぶん、YASATさんに解説してくださったのだろうと。m(__)m

 YASAT さんに解説なんて必要ありませんので,一般的な世間話をしました。
 一般的には,要するにマクロを作らないで既存のマクロで済ませようとする一般の人なら,おそらく環境交換マクロを使うでしょう。用途を特化するマクロは小物の醍醐味ですから,大いに支持しますよ。ですからわたしもいくつかの方向から考えてみて,自分としては一番好きだと思える方法を提案したわけです。達人が考えたらもっと美しくスパッといけるのかもしれません。あるいはファイルを直接ハンドルでオープンして機械語でセグメントまたぎで複写するのが美しいと考える人なら,迷わずそうするでしょう。

>  わ、わかんにゃい。ワンワン。
>  自分が書いていることに筋が通っているのか、自信なし。

 自分の目指す方法に無理に同期させなくていいんですよ。要するに「初期化」がどこまで必要かは個人の感覚ですから。
 転送時に転送分の末尾をターミネータにぶっつり切断させておくよう処理するのは普通の感覚です。別にそんなことしなくても,そのゴミを有害と感じなければ構わないわけですが,これも蛇足でした。

 最近,余計なことを考え,言ってしまう。病気のせいかも。キーボードに向かう時間を減らして頭の中だけで考えようとするからでしょうね。

 うー,これも蛇足かも。

[2898] Re^5: ファイル末を改行文字2つにする

文太 2008/09/28(Sun) 20:12
[2894]へのコメント
めざらさん(どこにレスをつけてよいのやら)

>  もちろん、危険です。コピーしたほうを加工し転送します。
 ここから「文太が何をどう勘違いしているのか分からない」と考えるのは普通
です。すいません、勘違いしてました。

 で、YASAT さんあてにも書きましたが、YASAT さんが一番普通であり、めざら
さんがちょっと知恵があり、僕が病気だったのですね。よく分かりました。

 それでも、「ヒストリバッファに転送してから末尾にヌルを書き込む方が簡単
かと思います」。これが答ですよね。なるほど、なるほど。

 と言いつつ、今日は、まだ bhis.def を開けられてもいない。最初の仕様固め
で失敗しました。bhis2.def とスクラッチからだな。いえ、もちろん僕はテキス
トバッファ派のままですけれど、最初で失敗してしまった。めざらさんが仰って
ましたよね、「仕様とインターフェイスが全てみたいなマクロ」って。その通り!
素朴な工具でいきたいのですが…。

 2回とも蛇足ではないです。よく分かりましたから。多謝です。m(__)m

[2895] Re^3: ファイル末を改行文字2つにする

YASAT 2008/09/28(Sun) 12:39
[2890]へのコメント
書き込んでから嫌な予感がしましたがやはり外してましたか。
自分、プロファイル機能って使ってないものでどうもピンと来ないんですよね。

#サンダーバードは1号が好き。垂直離陸のVTOLとかかっこ良すぎる。

[2891] Re^2: ファイル末を改行文字2つにする

文太 2008/09/27(Sat) 13:04
[2889]へのコメント
YASATさん

 僕には、 いつも慎重な YASAT さんが僕の意図を取り違えていると想像しにく
いのです。
 ですから、 めざらさんが「さすが YASAT さん、いつもどおりシャープだね」
とおっしゃるのじゃないかと怯えているのですが、YASAT さんの意図が読めませ
ん。
 恐れながら暫定的に僕が抱いている結論は、YASAT さんに僕の欲しいものが伝
わっていなかった、です。つまり、下のマクロの意味が分かんにゃいのよん。


=== Macro Tmp by Bunta ===;
* Macro
50 ^^ "mactest"

&Sc(pa,"test1234")	;ヒストリーでない文字列コピー		(1)
pa.0-,			;バッファ・クリア			(2)
&Sh(pa,"test")		;ヒストリー復活(?)で文字列コピー	(3)

*

(1)とりあえず、バッファの普通の状態みたいにすべく文字列を入れておいた。
(2)クリアするなら、これだけでいいじゃん。
(3)ほら、ふつうにヒスト・コピーだよ。

 はい。でもそういう意図?

 なのですが、ファイル(ラインバッファ状態でもテキストバッファ状態でもよ
い)をヒストリーバッファに送るというのが趣旨で、そのために改行を全てヌル
に置換して(1行1アイテム)、ファイル終端だけ2つの改行文字、というか2
つのヌルにしてヒストリーバッファの終端の形にして転送、というのが目論見の
全体です。
 これがディスコミュニケーションの発端かな?
 僕の完全読み間違い?


 >めざらさん

 酔ってない頭ならマクロ読めました。完璧。
> wa..19-, というのは危険ぽいから止めておきましょう。
 試してないのですが、意図は「wa..19+2-,」なのかな、と思いました。ライン
バッファの終端って何か決まった文字が入ってるんでしたっけ? あ、改行文字
が入ってるのか? (何かsedの話みたいだ)…基本的知識が足りない。

 もちろん、危険です。コピーしたほうを加工し転送します。

[2893] Re^3: ファイル末を改行文字2つにする

めざら 2008/09/27(Sat) 18:47
[2891]へのコメント <mezala@nifty.com> http://homepage3.nifty.com/mezala/
>  試してないのですが、意図は「wa..19+2-,」なのかな、と思いました。ライン
> バッファの終端って何か決まった文字が入ってるんでしたっけ? あ、改行文字

 ええ。ですから直接ラインバッファを弄って下手に書き戻してしまうと,テキストバッファを壊すかもしれません。いや,おそらく壊れるでしょう。#54を使えばよいですが,余計なことをやって余計にコマンドを発行しなくちゃいけないなら,ヌルを書き込んでも安全な場所で作業したほうがよいでしょうね。いずれにしても蛇足でしかありませんでした。

[2896] Re^3: ファイル末を改行文字2つにする

YASAT 2008/09/28(Sun) 12:52
[2891]へのコメント
いえ、私が文太さんの意図を考慮せず横着な説明をしたようですのでお気になさらぬよう。

私が考えていたのは、オープンテキストの最終行から一つずつヒストリバッファに格納していくかたちです。
ファイルからちょくせつ読み込むのでしたら私の説明したコードは役に立たないです。
混乱させてごめんなさい。

[2897] Re^4: ファイル末を改行文字2つにする

文太 2008/09/28(Sun) 19:55
[2896]へのコメント
 了解、分かりました! これが普通のやり方ですよね。僕は異セグ対応 &Sn(),
&Sm() なんてのがすでに手元にあったので、「普通でない」方法を考えてしまっ
たのです。テキストバッファまで行くと異セグなんですね。
 いいえ、とても勉強になりました。m(__)m

>  私が考えていたのは、オープンテキストの最終行から一つずつヒストリバッファ
> に格納していくかたちです。

[2899] Re^5: ファイル末を改行文字2つにする

めざら 2008/09/29(Mon) 08:06
[2897]へのコメント
 YASATさんのヒントは、現在の文太さんのレベルに適切なアドバイスだったと思います。わたしは自分勝手に自分の好きなやり方を書いただけ。
 文太さんはテキスト処理に通じている分、テキストの面相を読むことに長けていますが、そこから異セグメント間コピーに発想が飛躍してしまっています。途中の段階が一切なかった。もちろん一段一段昇る必要はなくて、一足飛びという段階があって当たり前なのですが、VZはあくまでもエディタなのですから基本的コマンドで手を抜けないか考えるのが普通だと思います。
 その意味で、YASATさんの示した「尻から責める」方式は段階を踏まえたものだったと思います。「尻から」というのは、わたしも好きでよくやります。なんと言ってもロジックが簡潔で美しい傾向があります。

[2900] Re^6: ファイル末を改行文字2つにする

文太 2008/09/29(Mon) 12:43
[2899]へのコメント
めざらさん

>  YASAT さんのヒントは、現在の文太さんのレベルに適切なアドバイスだったと
> 思います。わたしは自分勝手に自分の好きなやり方を書いただけ。

 実に実に。 それで、「なぜ YASAT さんが考えていることが分からないんだろ
う、たとえ何かのディスコミュニケーションがあったにしても」と強く思ってい
たのです。単なる勘違いではないとは確信してました。自分の中に足りないもの
があるのは知ってたのです。無知の知。
 謎が解けて、ああ、それが筋というものだよなぁ、と。
 バッファ内というメモリー上のデータと、切った貼ったする「ファイル」上の
データのふな渡し的なところにハードルがあるようなんですよね。ポインタやラ
インバッファに行く前に便利なもの(考え方)があるはずなんだけど、的に。
 それでも、めざらさんの考え方も、とても勉強になりました(ちょっと調べる
のがまだ終わってないことがないではないですが)。多謝です。m(__)m

 あ、そろそろ既存マクロをお教えいただけます? もちろん、bhis.defは完成
させますけれど。

[2901] Re^7: ファイル末を改行文字2つにする

めざら 2008/10/02(Thu) 22:11
[2900]へのコメント <mezala@nifty.com> http://homepage3.nifty.com/mezala/
 あれからしばらく考えていますが,単純にラインバッファにおける行サイズを
算出して,書き込み先バッファ先頭からの位置を終端処理するのは結構危険とい
うことに思い至りました。

ラインバッファ(行サイズが書込先バッファサイズよりも大きい場合)
↓先頭            ↓末尾
■■■■■■■■■■■■■■■■□□□□□□□□□□□□□

↓ 複写されるサイズ ↓	&Sm(a,b,a..-1) ;バッファサイズを限度にコピー
           ヌル→次の領域
■■■■■■■■■■■○○△△××△△△△△△△△△△△△
               ↑↑((a+(wa..19-wa..18))..0=0, ;ヌル埋込位置
書込先バッファ

 既存のヒストリバッファが書込先になっている場合は,次のヒストリバッファ
の中途にヌルが埋め込まれて終端処理されてしまいます。サンプルマクロのよう
に自前バッファがマクロの最後尾に配置されている場合は最悪で,次のマクロの
ヘッダ部分を壊したり,マクロコードの中にあれば実行がその位置で中断される
ことになります。これは非常にまずい。

 サイズ計算でヌルを書き込むコードを使うのであれば,それより前に測定サイ
ズが書込先バッファより大きければ,警告を出して中断させるというのもひとつ
の手かもしれません。変なところで切られるよりも親切というところでしょうか。
        #> (cp>a..-1)?{ &m(11) . }      ;*1 バッファがいっぱいです

 あるいは,複写先のバッファの終端を強制終端処理するという手もあります。
入り切らなかったものはそもそも欠けている状態ですからさらに1,2バイト余
計に切れても問題はないでしょう。
        ((a+a..-1)..0-,                 ;バッファの末尾を終端化
 この処理は複写前にサイズチェックを行う場合は不要になります。(あっても
害はなく,ゴミ箱をゆすってみるようなもの。)

↑ このページの先頭