2016年02月28日追記: こちらの内容は古いです
というわけで、この記事ではなく2016年2月時点の最新情報である以下をご覧ください。
新: Emacs を使うモダンな Clojure 開発環境
ただ、kibitの導入等の一部の設定は上記リンク先では対象外としておりますので、その辺りの設定が必要な場合はこちらに書かれている内容も使える…かも知れません(ただし最新バージョンへのキャッチアップはできておりません)。
事前準備 / Emacsの前に
OSにleiningen
がインストールされている必要あり。
apt-get、brew、yaourt等で入れておくこと。
ClojureやJVMのパッケージは、その依存パッケージとして入ってくる気がするが、そうでなければこれらは先に入れておく。
leiningenの設定
~/.lein/profiles.clj
として以下の内容のファイルを設置する。
{:user {:dependencies [[org.clojure/tools.nrepl "0.2.7"]
[slamhound "RELEASE"]
[org.clojure/tools.trace "RELEASE"]]
:aliases {"slamhound" ["run" "-m" "slam.hound"]}
:plugins [[lein-kibit "RELEASE"]
[cider/cider-nrepl "0.10.0-SNAPSHOT"]]}}
これはグローバルに以下のClojureライブラリが必要となるため。
- slamhound:
require
の中身を自動で解決する - tools.trace: 関数やマクロに何が渡っているかをトレースする
- kibit: コードの静的解析
- tools.nrepl と cider-nrepl は後述の CIDER が依存している模様で、入れていないと警告が出る
Emacs設定
必要なパッケージは以下である。いずれもMELPAで入る。
折角なのでCaskの形式で記載。
(depends-on "clojure-mode")
(depends-on "cider")
(depends-on "ac-cider")
(depends-on "clojure-cheatsheet")
(depends-on "slamhound")
;; Clojureに用途が限定されたパッケージではないが必要なもの
(depends-on "smartparens")
(depends-on "rainbow-delimiters")
それぞれ順に説明していく。
なお、本家でrequire
による設定が提示されている場合でも、autoload
が使えれば優先的にそちらを使い、Emacsの起動を高速化するようにしている。
基本のclojure-mode
シンタックスハイライトやらインデントやら。
.emacs.d配下の設定は不要である。
REPLおよびIDE的環境 CIDER
Emacs上でのLisp開発で使われる、slime。
かつてはswank-clojureだったりnrepl.elが使われていたが、今はそれらのよりベターなものとしてこれがある模様。
自分は.emacs.dにて以下の設定をしている。
(add-hook 'clojure-mode-hook 'cider-mode)
;; mini bufferに関数の引数を表示させる
(add-hook 'cider-mode-hook 'cider-turn-on-eldoc-mode)
;; 'C-x b' した時に *nrepl-connection* と *nrepl-server* のbufferを一覧に表示しない
(setq nrepl-hide-special-buffers t)
;; RELPのbuffer名を 'project名:nREPLのport番号' と表示する
;; project名は project.clj で defproject した名前
(setq nrepl-buffer-name-show-port t)
他にも色々な設定がある。詳細はGitHub上のREADME.mdにてBasic configuration
を参照。
使用方法も多岐に渡るが、これもREADMEに譲る。
テストの実行について
clojure-test-modeはCIDER 0.7の時点でCIDERに吸収されてdepricatedとなった。
CIDER上でテストを実行する一番単純な方法は、REPLでテストコードを評価した上で、テスト対象のファイルを開いたバッファにてC-c ,
することだ。
そうすると、同ファイルに対応するテストが実行される。
注意点は以下である。
- Read, Evalをしていないテストコードは実行対象にならない
- namespaceにルールがある
- テスト対象ファイルのnamespaceが
foo.bar
だとすると、foo.bar-test
といnamespaceでテストが書いてある必要がある - namespaceのルールを変えたい場合は、Emacsの設定にて
cider-test-infer-test-ns
を書き換える
- テスト対象ファイルのnamespaceが
詳細は、CIDERのREADMEを参照。
inspectorについて
※profile.cljにcider-nreplを含めていないとエラーになるかも。注意。
C-c M-i
すると、カーソル位置にある式の中身がインスペクトされる。
具体的に言うと
(def hoge (+ 1 2))
hoge
を評価しておいて、hoge
のところで上記コマンドを実行すると、以下のように型や値等の情報が表示される。
Type: java.lang.Long
Value: "3"
---
Fields:
"serialVersionUID" = 4290774380558885855
"SIZE" = 64
"value" = 3
"TYPE" = long
"MAX_VALUE" = 9223372036854775807
"MIN_VALUE" = -9223372036854775808
READMEによるとcider-inspector-modeというものあるので、上記よりもインスペクトに特化した機能が用意されている模様。
ac-cider
auto-complete.elを使った自動補完。
https://github.com/clojure-emacs/ac-cider
cider-jack-in
していないと有効にならないので注意。
設定は以下。
(autoload 'ac-cider "ac-cider" nil t)
(add-hook 'cider-mode-hook 'ac-flyspell-workaround)
(add-hook 'cider-mode-hook 'ac-cider-setup)
(add-hook 'cider-repl-mode-hook 'ac-cider-setup)
(eval-after-load "auto-complete"
'(progn
(add-to-list 'ac-modes 'cider-mode)
(add-to-list 'ac-modes 'cider-repl-mode)))
clojure-cheatsheet
M-x clojure-cheatsheet
で以下のサイトにある情報(同じもの?)を参照できる。
http://clojure.org/cheatsheet
調べたい対象は、helmで絞り込みが可能。
slamhound
必要なpackageを自動でrequrieしてくれるツール。
M-x slamhound
すると、実行される。
設定は上記すでに行っている以下の2点のみでよい。
- slamhound.el の導入
- .lein/profiles.clj の記述
kibit
コードの静的解析を行い、ベターな書き方をサジェストしてくれる。
単純な警告ツールというより、実際に書き直した後のコードが出力される。
上記の .lein/profiles.clj の設定に加え、以下を .emacs.d 配下で定義すると、M-x compile``M-x kibit``M-x kibit-current-file
で結果が別バッファ上に表示される。
;; Teach compile the syntax of the kibit output
(autoload 'compile "compile" nil t)
(add-to-list 'compilation-error-regexp-alist-alist
'(kibit "At \\([^:]+\\):\\([[:digit:]]+\\):" 1 2 nil 0))
(add-to-list 'compilation-error-regexp-alist 'kibit)
;; A convenient command to run "lein kibit" in the project to which
;; the current emacs buffer belongs to.
(defun kibit ()
"Run kibit on the current project.
Display the results in a hyperlinked *compilation* buffer."
(interactive)
(compile "lein kibit"))
(defun kibit-current-file ()
"Run kibit on the current file.
Display the results in a hyperlinked *compilation* buffer."
(interactive)
(compile (concat "lein kibit " buffer-file-name)))
kibit-modeについて (使用を断念)
kibitの結果をflycheckと連動してくれる kibit-mode.el も存在はしている。
https://github.com/aredington/kibit-mode
だがこれを試してみたところ、Emacsが固まる現象に見舞われた。
加えて、flycheckの結果をpopupで出すように自分はしているだが、イマイチその表示が崩れて見にくかった。
リファクタされたコードが表示されることで、横に長くなったり改行が入ったりするため。
ちなみに、この辺のコミッタである@bbatsov氏によると、「kibitは旧来の静的解析とは違うから、flycheckとはあまり相性が良くない」らしい。
https://twitter.com/lunaryorn/status/341471670378299392
この「相性が良くない」というのは、上記のようなことを指している、と勝手に解釈した。
Compojure用の設定
Clojure用のWebフレームワークであるCompojureにおいて、ルーティングのマクロを使った時のインデントがかっこ良くなるように以下を設定する。
(add-hook 'clojure-mode-hook
(lambda()
(define-clojure-indent
(defroutes 'defun)
(GET 2)
(POST 2)
(PUT 2)
(DELETE 2)
(HEAD 2)
(ANY 2)
(context 2))))
tracing
tracingが何をするものか、というと以下の記事が分かりやすい。
http://athos.hatenablog.com/entry/tracing_execution_with_tools_trace
使っているツールは以下である。
https://github.com/clojure/tools.trace
実はEmacsとは直接的に連動させていない。
上記ブログ記事で書かれているようなtrace-vars
等の式を、直接CIDERのREPLに渡して使ってみている。
トレース周りの連動は茨の道だった。。
茨の道について (断念の記録)
troncleが機能的に優れているらしい。
https://github.com/coventry/troncle
しかし、troncle.elがREADMEに反してMELPAから消えている、設定はしてみたけど動かない、というところで断念した。
仕方ないので、機能的には劣るというcider-tracingを使ってみた。
https://github.com/clojure-emacs/cider-tracing
インストールはできたが、Emacsが固まる…。
括弧の操作を便利にする
smartparens
よく使われているであろう、pareditを包括したもの。
pareditとは若干操作感が違うので注意。
rainbow-delimiters
括弧を色分けして見やすくする。
https://github.com/jlr/rainbow-delimiters
デフォルトだとコントラストが低くて見やすくないと個人的に思ったので、コメント欄でいただいたアドバイスを元にuse-package.elとdash.elを使いつつ以下の設定を行っている。
(use-package rainbow-delimiters
:config
(use-package color
:config
(--each (number-sequence 1 rainbow-delimiters-max-face-count)
(let ((face (intern (format "rainbow-delimiters-depth-%d-face" it))))
(callf color-saturate-name (face-foreground face) 90)))))