EmacsでUnity開発(c#)するための環境構築

  • 32
    いいね
  • 2
    コメント
この記事は最終更新日から1年以上が経過しています。

2015/9/2〜〜〜〜〜〜〜〜〜〜〜
ここで紹介している以下の機能を入れるより
omnisharpを入れた方が幸せになれますので
そちらをお勧めします。
- C#用のメジャーモードを導入
- imenu
- 自動補完
- シンタックスチェック

omnisharpの導入手順は以下を参考しました
- EmacsでUnity開発をする
- Emacs で C# を書こう
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

EmacsでUnityの実践的な開発を行うにあたっては
以下の機能を入れると楽になります。

導入する機能

  • C#用のメジャーモードを導入
  • imenu
  • 自動補完
  • tagジャンプ
  • コードスタイルチェック
  • シンタックスチェック
  • カジュアルな実行環境

C#用のメジャーモードを導入

Emacsには、デフォルトでC#用のメジャーモードは用意されていません。
なので、Google Codeのcsharpmodeプロジェクトが出してるcsharp-modeを入れます
(もう開発はされてないようですが..)
https://code.google.com/p/csharpmode/downloads/list

imenu

クラス、メソッド、アクセッサーの一覧を表示し、インクリントサーチで絞り込みジャンプできる機能です。
csharp-modeにimenuは用意されてますが、以下を修正しないと動かなかったです。

csharp-mode.el
@@ -5561,8 +5561,8 @@ Key bindings:
         ;; `imenu-generic-expression'; imenu will do a "generic scan" for you.
         ;; csharp-mode uses the former method.
         ;;
-        (setq imenu-create-index-function 'csharp-imenu-create-index)
-        (imenu-add-menubar-index)))
+        (setq imenu-create-index-function 'csharp-imenu-create-index)))
+        ;; (imenu-add-menubar-index)))

※ 注意
- 2000行以上くらいのコードになると、一覧表示するまでに数秒かかります
- ジェネリックで定義してるメソッドとクラスは、imenuからは対象外になってます

自動補完

auto-complete-modeを使用すれば、開いて保持してるバッファの単語と
csharp-mode用の辞書は補完候補として表示できます。
Emacsでdllの中まで見て補完候補を探してくれる機能はまだ実現できてないです。

※ omnisharpというelispを使用するとdllを中まで見て補完候補を出してくれるようで
試したのですが出なかったです...。(できた方いらしたら教えてほしいです)

tagジャンプ

tagジャンプは、gtagsを利用します。
以下のlispとGTAGSの作成スクリプトをcronで設定します

my-csharp-mode.el
(require 'gtags)
(global-set-key (kbd "C-'") 'gtags-find-tag-other-window)  ; (別バッファで)関数の定義元(関数の実体)へジャンプ
(global-set-key (kbd "C-M-'") 'gtags-find-tag)             ; 変数等のジャンプ
update_gtags.sh
#!/bin/bash

PROJ1=$HOME/projects/proj1
PROJ2=$HOME/projects/proj2
for project_path in ${PROJ1} ${PROJ2}
do
    cd $project_path
    rm GPATH GRTAGS GTAGS
    find . -name "*.cs" -follow -print | /usr/local/bin/gtags --gtagslabel=plugin-example -f -
done

コードスタイルチェック、シンタックスチェック

コードスタイルチェックについて

C#のコードスタイルはstylecopが一般的らしいです。(pythonでいうpep8みたいなやつ)
flymakeを利用するので、mac環境のコマンドラインから結果を返してるもの探してて、
stylecop CLIっというのを見つけたのでこちらを導入手順を紹介します。

導入手順
準備として、MonoDevelopインストールしておく必要があります

  1. 以下のサイトからバイナリをダウンロード
    http://sourceforge.net/projects/stylecopcli/files/Binary/

  2. MonoDevelopのアドオンマネージャーからsytlecopを追加
    メニューのアドオンマネージャー→gallery →IDE extentions →sytlecop supportからインストール

  3. flymakeに設定
    これで StyleCopCLI.exe が動作できるようになるので
    flymakeのチェックスクリプト、エラー文言の検出パターンを設定します

シンタックスチェックについて

シンタックスチェックは以下を実行することで確認できます

/usr/bin/mcs -r:ライブラリpath $1 -target:Library

ただ、シンタックスが正しいかは判断できるけど、エラーかどうかまでは判断してくれないみたい
たとえば、以下のような判定が下る

System.Console.WriteLine("hoge");  // flymakeでは正常扱い
tem.Console.WriteLine("hoge");     // flymakeでは正常扱い
Sys tem.Console.WriteLine("hoge"); // flymakeでは異常扱い

コードスタイルとシンタックスのチェックの設定

csharp-checker.sh
#! /bin/bash

# シンタックスチェック
/usr/bin/mcs -r:/Applications/Unity/Unity.app/Contents/Frameworks/Managed/UnityEngine.dll,/Applications/Unity/Unity.app/Contents/Frameworks/Managed/UnityEditor.dll,~/projects/proj1/Library/ScriptAssemblies/Assembly-CSharp.dll,~/projects/proj1/Library/ScriptAssemblies/Assembly-CSharp-Editor.dll $1 -target:library
dll_file=`echo $1 | sed -e "s/\.cs/.dll/"`
ls ${dll_file} && rm ${dll_file}

# コードスタイルチェック
/usr/bin/mono ~/.emacs.d/bin/StyleCopCLI.exe -cs $PWD/$1 -out /tmp/stylecop.log
# エラーとして扱いたくないものは、grepに追加していく
cat /tmp/stylecop.log | sed -e "s/\"//g" | sed -e "s/>/ /g" | grep -v "SA1001\|SA1202\|SA15013"
ls $PWD/StyleCop.Cache && rm $PWD/StyleCop.Cache
my-csharp-mode.el
;; Flymake
(defun flymake-csharp-init ()
  (let* ((temp-file (flymake-init-create-temp-buffer-copy
                     'flymake-create-temp-inplace))
         (local-file (file-relative-name
                      temp-file
                      (file-name-directory buffer-file-name))))
    (list "~/.emacs.d/bin/csharp-checker" (list local-file))))
(add-to-list 'flymake-allowed-file-name-masks
             '("\\.cs$" flymake-csharp-init))
(add-to-list 'flymake-err-line-patterns
             '("cs\(\\([0-9]+\\),\\([0-9]+\\)\)\: \\(error\\|warning\\) \\(.+\\)$" nil 1 2 4))
(add-to-list 'flymake-err-line-patterns
             '("LineNumber=\\([0-9]+\\) .* RuleId=\\(.+\\)</Violation" nil 1 1 2))

カジュアルな実行環境

quickrunを利用するとEmacs上からC#をインタラクディブっぽく実行できるようになります。
ちょっと関数とか書いて動作確認するときに便利です。

quickrun.elを入れて M-x quickrun を実行すると、以下のように動作確認できます。

スクリーンショット 2014-03-21 18.12.05.png

最終的なcsharp-mode設定は以下になります

my-csharp-mode.el
(require 'csharp-mode)
(setq auto-mode-alist
   (append '(("\\.cs$" . csharp-mode)) auto-mode-alist))

;; C#モードフック
(add-hook 'csharp-mode-hook
          '(lambda()
             (setq comment-column 40)
             (setq c-basic-offset 4)
             ;; (font-lock-add-magic-number)
             ;; オフセットの調整
             (c-set-offset 'substatement-open 0)
             (c-set-offset 'case-label '+)
             (c-set-offset 'arglist-intro '+)
             (c-set-offset 'arglist-close 0)
             (hl-line-mode)
             (auto-complete-mode)
             (flymake-mode)
             )
          )

;; Gtags設定
(require 'gtags)
(global-set-key (kbd "C-'") 'gtags-find-tag-other-window)  ; (別バッファで)関数の定義元(関数の実体)へジャンプ
(global-set-key (kbd "C-M-'") 'gtags-find-tag)             ; 変数等のジャンプ

;; Flymake
(defun flymake-csharp-init ()
  (let* ((temp-file (flymake-init-create-temp-buffer-copy
                     'flymake-create-temp-inplace))
         (local-file (file-relative-name
                      temp-file
                      (file-name-directory buffer-file-name))))
    (list "~/.emacs.d/bin/csharp-checker" (list local-file))))
(add-to-list 'flymake-allowed-file-name-masks
             '("\\.cs$" flymake-csharp-init))
(add-to-list 'flymake-err-line-patterns
             '("cs\(\\([0-9]+\\),\\([0-9]+\\)\)\: \\(error\\|warning\\) \\(.+\\)$" nil 1 2 4))
(add-to-list 'flymake-err-line-patterns
             '("LineNumber=\\([0-9]+\\) .* RuleId=\\(.+\\)</Violation" nil 1 1 2))