header

ラベル Nim の投稿を表示しています。 すべての投稿を表示
ラベル Nim の投稿を表示しています。 すべての投稿を表示

2016年7月6日水曜日

Nimlang の関数を Emacs から呼び出す②

結構時間があいてしまってあれなのですが、以前 Nimlang の関数を Emacs から呼び出す(途中までしかできてない) という記事を書いてそのまま放置だったけれど、Nim のバージョンが上がってから試したらすんなり動いたというのと、el-get に登録したので紹介します。(Nim の lambda_lifting に関するバグがなおったあと良くなったとおもいますが、詳しいバージョンや Issue 番号など忘れてしまいました)

おさらい

Emacs25 から追加される dynamic module という機能で C の関数を呼び出すという機能を利用して、C にコンパイル可能な Nim で Emacs 用の拡張を作るという試みです。

その他日本語記事:

確認している Emacs と Nim

以下のバージョンで確認しています。

  • emacs-version(master branch): 25.1.50.1
  • Nim version(devel branch): 0.14.02

インストール

el-get に登録したので`el-get-list-package` とかでインストールできます。dynamic module を利用した拡張は(MELPA などで簡単にインストールして使える形で提供しているのは)まだないので、他の Dynamic Module の拡張のやり方を真似しようかな思っているので MELPA にはまだ登録していません。なので、位置づけとしては、Nim で Emacs の拡張を書くお遊びパッケージという感じです。

使い方

インストールが終わったら、

(el-get 'sync 'nim-emacs-module)

でロードパスの登録と autoload を使えるようにして、M-x `nim-emacs-module-init`で~/.emacs.d/に nim-emacs-module ディレクトリを作ります。(確認してないけど、別に手動でも OK です)

あとは作りたいパッケージ名の名前でファイルを作ります。例えば sample-xxx 関数を持つなら、sample.nim というファイル名になります。ここでつけるファイル名が Nim では(Nim でいう)モジュール名になり、なおかつ Emacs 用の関数の prefix 名となります。(便宜上そうなるように設計してるだけで Emacs 側にそれを強制するルールはありませんが)

あとは開いたファイルで, M-x nim-emacs-module-insert-template で必要な設定がファイルに挿入されます。

現在の nim-emacs-module では以下のようなコードが挿入されます。 (挿入されるものは将来的に変更されるかもしれないので、こんなニュアンスなんだという理解のほうがいいかもです。)

# `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 emacs_module # Primitive wrapper for emacs_module.h
import emextra      # Helper library
init(emacs)
# Example(Create a file named `mod_test.nim`):
emacs.defun(return_t, 1):
  env.intern(env, \"t\".cstring)
# Provide functions registered by above from here.
emacs.provide()
# How to test the example's code:
#
#   $ emacs -Q -L .
#
# and then in *scratch* buffer, evaluate those lines:
#
#   The file name ‘ mod-test ‘ is added as prefix name of each functions and
#   its package name.
#   (require 'mod-test)
#   (mod-test-return-t)

Nim では#がコメントなので実質数行のコードですが、なんとなく Emacs で拡張作ってる方には Nim を知らなくてもわかるのではと思います。

この例では、ファイル名が mod-test.nim で関数名が return_t、引数の数が1つの Emacs の関数`mod-test-return-t`が作られます。

コンパイルの方法は nim-mode で C-c C-c でコンパイルできるようにしていますが、M-x nim-emacs-module-compile でもコンパイルできるはずです。

コンパイル後は上記コメントのように mod-test パッケージを require して、関数を試すという感じです。

今後

Emacs の dynamic module 機能がまだ始まったばかりなので今後どうなるかわかりませんが、多言語で複数パッケージを管理するスキームができたら真似してみたいなぁとおもいます。あと C、Nim とも初心者なので、まだ Nim<->Emacs Module 間でのメモリの扱いがどうなるのかわからなくてプリミティブなテストしか作ってないので時間があればもうちょっとなんとかしたいなぁという感じです。(Pull Requests 大歓迎です)

2016年1月18日月曜日

Nimlang 用の Emacs おすすめ設定

Nimlang 公式?の emacs メジャーモードは nim-mode でコード補完や eldoc サポートはこのリポジトリに入っているのですが、それ以外にあったほうがよいものとか

※注意 nim-mode はすでにインストール済みを前提に書いています。

なにはなくとも nimsuggest

nimsuggest は nim 用の IDE(or text editor)支援ツールでこれがないとコード補完と eldoc の機能が使えないので、Emacs で nim を書くにはほぼ必須ツールです。

リンク先にインストール方法は書いているとおもいますが、nim 本体と同じディレクトリに git clone して nimsuggest のディレクトリで

nim e ./compile_without_nimble.nims

をすればよかったと思います。ちなみに.nims ファイルは nimscript の略です。ghq を使っている場合は、同.nims ファイルの–path:../nim を Nim にしないとダメでした

無事ビルドしたら以下を emacs に設定することで eldoc と company-mode が使えるようになります。

(setq nim-nimsuggest-path "nimsuggest のバイナリへのパス")
(add-to-list 'company-backends 'company-nim)

flycheck (MELPA からインストール可能)

https://github.com/ALSchwalm/flycheck-nim

特にそのままでも使えますが、前述の nimscript の機能が新しいので syntax チェック機能がまだ未対応のようので nims や nimble ファイルを書くのであれば今のところ下の設定で flycheck は無視したほうがいいかもしれません。(おそらく syntax チェックは公式がそのうち対応するので)

(defun my-turn-on-flycheck-nim ()
  (when (and buffer-file-name
             (not (member
                   (file-name-extension buffer-file-name)
                   '("nims" "nimble"))))
    (flycheck-mode t)))
(add-to-list 'nim-mode-map 'my-turn-on-flycheck-nim)

indent-guide (MELPA からインストール可能)

インデント構造を見やすくする拡張です。リンク先に screenshot があるのでそれを見たほうがわかりやすいです。 https://github.com/zk-phi/indent-guide

quickrun (MELPA からインストール可能)

自分が紹介しなくてもみなさん知っているかもしれないですが、ワンコマンドで現在ファイルを実行する拡張です。多(プログラミング)言語に対応していますが nim も入っています。 https://github.com/syohex/emacs-quickrun

おわり

自分が使っているのはだいたいこんな感じです。他に便利拡張が教えてください。

2016年1月5日火曜日

Blogger に post するコマンドラインツールを作った

このブログの更新には googlecl というコマンドラインツール経由で emacs から記事を書いていたけれど、結構前から googlecl が oauth2 に対応してなくてブログが更新できなかった。自分がなんか作った途端マーフィーの法則でもっといいツールが出たりすぐ治るのではという恐れがあってずっと googlecl の github Issues が更新されるのを待つ日々が続いたが、更新されなそうなので、シンプルに google blogger にポストするだけのコマンドラインツールを作った。実装には勉強ついでに nimlang を使ってみた。 (自分用に Emacs から post するコードも入っているので興味がある人は後半の方もみてみてください。)

前準備

nim の実行環境がない人は、先に ここから nim をインストールしてください。あと、 nimble という nim 用のパッケージマネージャもあったほうが管理が楽です。

あと Google の Blogger 用の API 利用するのに Google Developper Console で登録する必要があります。 もはや記憶の彼方でどうやったかあまり思い出せないのですが、多分ググればいろいろ情報があるのでは、、、(適当)

とりあえず、client id と client secret というのが必要です。

インストール

準備ができたら、

git clone https://github.com/yuutayamada/nim-blogger
cd CLONED DIRECTORY
nimble make

で nimblogger という実行ファイルが作れます。

ホントは nimble install でインストールできるようにしたかったけど、-d:ssl というフラグをつけないとビルドできず install のときどうやって指定するのかよくわからなかったので、このようになってしまいました。

# たぶん Google Developper Console の API manager から
# みつけられるとおもいます
export GOOGLE_API_CLIENT_ID="developper console から client_id をコピペしてください"
export GOOGLE_API_CLIENT_SECRET="developper console から client_secret をコピペしてください"

のあと

nimblogger --help

で使い方がでるとおもいます。 (注意 Refresh token なんちゃらってでたらもう一回やると成功するかもしれません。)

Emacs から

自分用なので使いたい人は使ってというスタンスで、misc ディレクトリに org-mode のドキュメントから html に変換してポストするコードが入ってます。

使いたい人は、下のような設定をしたあと`nimblogger:post-article`関数で投稿できるとおもいます。

(load "path/to/misc/nimblogger")
(setq nimblogger:blog-name "blog の名前"
      ;; binary file へのパス
      nimblogger:command "path/to/nim-blogger/nimblogger")
(define-key org-mode-map (kbd "C-S-p") 'nimblogger:post-article)

おわりに

自分が必要な最低限はできたけど、Google の更新についてく自信がないいので、いいツールがあれば教えてください。

2015年12月30日水曜日

Nimlang の関数を Emacs から呼び出す(途中までしかできてない)

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 以外できたのは、ちょっと感動しました。

Popular Posts

Blogger templates

Blogger news