Scheme で vim バッファにテキスト出力
Vim に Scheme インターフェースを追加して真っ先に確認したかった事が、バッファにテキストを追加する方法です。
新しい情報を画面の末尾に追加していく、という至極当たり前の作業なんですが、これがなかなか難しかったのでメモしておきたいと思います。
まずヘルプ (:h mzs) をあたって:
(insert-buff-line-list {linenr} {string/string-list} [buffer])
というプロシージャがあることが分かりました。
ここでちょっと難しいのが、vim 用のプロシージャは、MzScheme のそれとの衝突を避けるため "vim-" という接頭辞を付ける、というのが慣わしになっているようです (自分で、です)。
しかも、その設定はバッファ毎に行わなくてはならないらしく、そのための方法がヘルプに書いてあります (端折ります)。
設定が出来たところで、
:mz (vim-insert-buff-line-list
までタイプしたんですが、まだ最後の行番号を得る方法が分かってませんでした。
ヘルプを見てもそのためのプロシージャは無さそうです。そんな時は vim-eval で vim の関数を呼び出せば良い、ということで
:mz (vim-insert-buff-line-list (vim-eval "line('$')") "Hello, World!")
とすると、エラーが出ました:
insert-buff-line-list: expects type <integer> as 1st argument, given: #"24"; other arguments were: "Hello, World!"
なるほど、型に厳しいわけですね。vim-eval の戻り値を数値 (整数) に変換しなければいけない、と。
ということで、
:mz (string->number (vim-eval "line('$')"))
としてみると、エラーです:
string->number: expects argument of type <string>; given #"24"
どうやら #"24" は string 型では無いらしいですね。
ここで大いに嵌りました。
:mz (char? #"24") #f
:mz (number? #"24") #f
:mz (symbol? #"24") #f
色々と試したんですが、全て #f という判定で、結局 bytes という型であることを知ったのは次の日になってからでした。
ようやく型が分かったところで、変換の方法を調べてみたところ、どうも直接数値に変換する方法は無さそうです。結果
:mz (vim-insert-buff-line-list (string->number (bytes->string/latin-1 (vim-eval "line('$')"))) "Hello, World!")
と二段構えで変換することで上手くいきました。