LoginSignup
9
4

More than 5 years have passed since last update.

Emacsバッファ内のRustコードを手軽に実行する

Last updated at Posted at 2016-12-06

シュッと実行するという記事を読んで、掲題のようなことをやりたかったことを思い出し、cargo-scriptのインストールを試してみたところ、手元のWindows環境だとgccがないために失敗してしまったので、代替物を作ってみた、という話。

まあ、これだけであればgccをインストールすれば良いだけなのですが、自分の要件的にはcargo-scriptほど本格的なものは必要なく、逆により手軽な記述ができた方が嬉しかった、というのも作った理由(後付け)の一つ。

作成物はevalrs。コード行数的には100行くらいの短いもの。

以降は使い方などの簡単な説明。

インストール

コマンドのインストールはcargoを使えばOK:

$ cargo install evalrs

使い方

コマンドとしては標準入力から受け取ったRustコードを評価・実装するだけの単機能なもの:

$ echo 'println!("Hello World!")' | evalrs
   Compiling evalrs_temp v0.0.0 (file:///tmp/evalrs_temp.zseDeaC77GHQ)
    Finished debug [unoptimized + debuginfo] target(s) in 0.22 secs
     Running `target\debug\evalrs_temp.exe`
Hello World!

extern crate ${CRATE}がコード中に含まれる場合には${CRATE}の最新バージョン("*")を使用して実行される:

$ echo 'extern crate num_cpus; println!("{} logical CPUs", num_cpus::get())' | evalrs
    Updating registry `https://github.com/rust-lang/crates.io-index`
 Downloading num_cpus v1.2.0
 Downloading libc v0.2.18
   Compiling libc v0.2.18
   Compiling num_cpus v1.2.0
   Compiling evalrs_temp v0.0.0 (file:///tmp/evalrs_temp.4alAAhU4VF8J)
    Finished debug [unoptimized + debuginfo] target(s) in 0.57 secs
     Running `target\debug\evalrs_temp.exe`
4 logical CPUs

一度取得およびビルドされたcrateはstd::env::temp_dir().join("evalrs_cache/")以下に保存され、次回以降はそれが再利用される (正確にはダウンロードのキャッシュはcargoの標準機能に含まれているので、evalrsが行っているのはビルド物のキャッシュのみ):

$ echo 'extern crate num_cpus; println!("{} logical CPUs", num_cpus::get())' | evalrs
    Updating registry `https://github.com/rust-lang/crates.io-index`
   Compiling evalrs_temp v0.0.0 (file:///tmp/evalrs_temp.R9D7QQUinyBM)
    Finished debug [unoptimized + debuginfo] target(s) in 0.23 secs
     Running `target\debug\evalrs_temp.exe`
4 logical CPUs

Emacsから使う

quickrunパッケージを使う場合の方法の紹介。
まず上のリンク先のドキュメントに従って、Emacsにインストールしておく。

その後、(例えば)以下の設定を.emacsファイルに追加しevalrsコマンドがquickrun経由で実行可能なようにする:

.emacs
(quickrun-add-command
 "evalrs"
 '((:command . "evalrs")
   (:exec . ("cat %s | %c %a")))
 :default "evalrs")

; ビルド or 実行に時間が掛かる(10秒以上)場合は、以下の行をコメントアウトしてタイムアウト時間を延ばす
; (setq-default quickrun-timeout-seconds 180)

これで準備は整ったので、後は適当なEmacsバッファにRustのコードを入力し、quickrunを叩けばOK:

*rust-eval-buffer*
fn fib (n: usize) -> usize {
    if n < 2 {
        n
    } else {
        fib(n - 1) + fib(n - 2)
    }
}

println!("fib(10) = {}", fib(10));

// 以下を実行:
//     M-x quickrun RET evalrs RET
//
// 出力結果:
//   Compiling evalrs_temp v0.0.0 (file:///tmp/evalrs_temp.PCwV9N95yi5o)
//    Finished debug [unoptimized + debuginfo] target(s) in 0.26 secs
//     Running `target\debug\evalrs_temp.exe`
// fib(10) = 55

現状はかなり限られた機能しかないですが、とりあえずこれでEmacs上から手軽にcrateや関数の挙動が試せるようになったので、結構満足しています。

追記: 2016-12-07

quickrunの実行を以下のようにキーボードショートカットに登録したら、だいぶ利便性が上がりました。
(ついでにrustfmtも合わせて適用)

(global-set-key
 (kbd "C-c C-c C-q")
 '(lambda ()
    (interactive)
    (rust-format-buffer)
    (quickrun :source
              '((:command . "evalrs")
                (:exec . ("cat %s | %c %a"))))))
9
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
4