楽しい人生

紙 おいしいな〜!

.NET CoreでC#スクリプトを素早く実行するためのQuickSharpをリリースした

tl;dr

  • VimEmacsC#のquickrunができるようになります

記事執筆時の環境

  • dotnet cli version 1.0.4(.NET Coreのバージョンではない)

筆者がVimを使用していた頃はvim-quickrunを、Emacsを利用している今はemacs-quickrunを愛用しています。

これは、現在エディタで開いているバッファの内容をその場で処理系に渡して実行し、結果をエディタ内で確認できるというプラグインです。

新しい言語の入門書片手に書き捨てのファイルをその場でサッと書いて実行したい時、言語仕様のちょっとした確認をしたい時、プロジェクトを作るほどでもない簡単な計算を行いたい時など活躍の場は多く、筆者の必須プラグインの一つと言えます。

そういった訳で今まで快適なquickrun生活を送ってきた筆者ですが、最近C#に入門したところ、quickrunがデフォルトではC#の実行(ここでは.NET Core CLRを想定します)に対応していないことがわかりました。

理由として推測できるのは、dotnetコマンドが単一.csファイルの実行を想定した作りになっていないからでしょう。基本的には、.csprojファイルを用意し、プロジェクトとして構成したものを実行することが想定されています。

そういったわけでC#のコードをquickrunで実行することは難しいのですが、quickrun愛用者としてはなんとか書捨てのC#ファイルを実行できるようにしてみたいものです。dotnetコマンドについて調査してみたところ、どうやら昔はreplというサブコマンドが用意されており、対話的にC#のコードを実行したり、引数として与えた単一ファイルをその場で実行したりできた様です。残念ながら現在は廃止されてしまったコマンドの様ですが、その実装を追えば同じような仕組みを構築する事は可能でしょう。

そういった訳で実装を調べた所、これらの機能はMicrosoft.CodeAnalysis.CSharp.Scriptingライブラリで実装できるようです。これは実際には標準のC#コードを実行するものではなく、C#スクリプトという仕様に基いて書かれたコードを実行するためのものである様です。

C#スクリプトによる主な仕様の違いは以下のサイトで詳しく解説されています。

ufcpp.net

C#スクリプトは標準のC#との仕様の違いはありますが、さっとコード片を書いて実行するには十分適したものと言えるでしょう。そこで、C#スクリプトファイルを簡単に実行することができる薄いラッパーコマンドを作成しました。それがQuickSharpです。

github.com

NuGetでもリリースしていますが、npmやrubygemsなどの文化圏とは違いNuGetはグローバルにインストールするコマンドラインツールなどの配布は想定されていない様ですので、基本的にはリポジトリにあるREADMEに従って各自好きな場所にビルドしたdllを配置して頂く形になります。

dllのビルドが完了すれば、以下のようにcsxファイルを簡単に実行できるようになります。

using System;
Console.WriteLine("Hello, World!");
> dotnet [path/to/dotnet-quicksharp.dll] ./sample.csx
Hello, World!

そうすれば、あとはvim-quickrunやemacs-quickrunに、quicksharpを呼び出すコマンドを設定すればエディタ内で快適に書捨てのC#スクリプトを実行できるようになります。

以下はEmacsでの設定例です。

(quickrun-add-command "dotnet"
  `((:command . ,(concat
                  "dotnet "
                  (expand-file-name "~/Develops/QuickSharp/QuickSharp/bin/Release/netcoreapp1.1/dotnet-quicksharp.dll")))
    (:exec . ("%c %s"))))
(add-to-list 'quickrun-file-alist '("\\.csx$" . "dotnet"))
(add-to-list 'quickrun-file-alist '("\\.cs$" . "dotnet"))

すごく便利(すごく)