Syohex さんの Emacs に mruby を組み込んでみた 記事を参考に Emacs の dynamic module 機能(Emacs 25.1 から導入予定)で Nimlang の関数を Emacs から呼べるか試してみた。ここ においてありますが、結論からいうと Emacs から nim の関数呼び出しには成功したが、引数を読み込もうとすると これ に近いエラーがでてコンパイルに失敗する。というわけでタイトルの通り途中までしかできていません。
上記の Nim の github issues を見ると作者の方が問題のコードリライトしてるらしく待ってればそのうちなおるのではという感じなのでしばらく待ってみようと思います。
これだけだと、あれなのでこんな感じになったよという報告だけ(だれに?)
# `plugin_is_GPL_compatible' indicates that its code is # released under the GPL or compatible license; Emacs will refuse to # load modules that don't export such a symbol. {.emit:"int plugin_is_GPL_compatible;".} import strutils import emacs_module as emacs emacs.addFunc(Fmod_test_return_t, 0): env.intern(env, "t".cstring) emacs.defuns("libsample", """ DEFUN ("mod-test-return-t", Fmod_test_return_t, 1, 1, NULL, NULL); """)
emacs_module というのは emacs-module.h の nim 用の wrapper で nim の練習ついでに作ってみました。(env.intern しか動くの確認できてないんですが、、、) 上記の nim のコードは引数がなんであれ t を返すというものです。なんかこれだけエラー起きずにコンパイルできました。`env.intern`の部分から Fmod_test_return_t 関数の中身を記述しています。addFunc というのは nim の template で次のように展開されます。
proc Fmod_test_return_t*(env: ptr emacs_env, nargs: ptrdiff_t, args: ptr array[0..0, emacs_value], data: pointer): emacs_value {.exportc.} = env.intern(env, "t".cstring)
自分の理解が正しければ、Emacs の dynamic module で C の関数を読み出す場合は引数と戻り値はすべて同じようなので(型が決まってるので) template で省略するようにしてみました。
まぁ特にまとめはありませんが、時間をおいてまた挑戦してみようと思います。ありきたりな感想ですが Emacs の拡張が Emacs Lisp 以外できたのは、ちょっと感動しました。