注意事項
今なら素直にSpacemacsを使ったほうが手軽に環境構築できます。
この記事はある程度当時の状況を網羅したもので、今でも利用されているパッケージはあまり変わっていないので、そういう意味では参考になりますがセットアップ方法や設定などはかなり変わってきているので、参考にならない部分も多いです。
Spacemacsを僕の好みに合わせて設定したものを、以下に解説と合わせてのせているので参考にしてみてください。
はじめに
Clojure の開発環境というのはどんどん新しくなっていくので、最近の開発環境事情について解説しようと思います。
この記事は次の記事の置き換えを狙ったもので、出来るだけ新しい情報を提供することを目的としています。
また何か間違っているという場合は気軽に編集リクエストを送ってもらって構いませんし、コメントなどで教えてもらえれば修正します。
前提条件
この記事で要求するものは次の通りです。
- Emacs 24.3 or newer
- Java 7 or newer
- Leiningen 2.6.1 or newer
Emacs の設定について書いているところでは use-package を使って説明していますが、 use-package については特に解説していませんのでご注意ください。
またこの記事ではまだ開発版である CIDER の次のバージョンについて言及していきます。
- CIDER 0.11.0 (現在
snapshot
)
正式にリリースされるまでバグなどがあるかもしれないので積極的に snapshot
の使用を勧めるものではありませんが、 0.11.0
以降ではココに書いたことが当然のように使えるようになっていると思うので正式にリリースされたときに是非この記事を参考にしてほしいと思います。勿論、それ以前のバージョンでも基本的な部分に関しては違わないので参考にはなると思います。
また、 CIDER 0.11.0 以降では Clojure(Script) 1.7 以上を要求するようになっているので気をつけてください。
Leiningen のインストールと準備
Leiningen は必須なのでインストールされていることを前提としますが、もしまだインストールされていないのであれば次の記事を参照してインストールしてください。
また、今迄 $HOME/.lein/profiles.clj
に CIDER などで使う nREPL の依存関係などを記述していましたが、 0.11.0
以降それらの記述は不要となっています。
よって、現在 $HOME/.lein/profiles.clj
に記述をする必要はあまりありませんが、 CIDER はローカルにある Javadoc を引くことができるので私は以下の記述だけ行っています。
{:user {:resource-paths ["/usr/share/doc/openjdk-8-jdk/api/"]}}
もちろん、このパスについては各個人の使っている OS などに依存するので一概にこう設定すれば動くというものではないので注意してください。
Boot ユーザーについて
Boot ユーザーでも Leiningen ユーザーと特に違いはなく CIDER を利用することができます。 CIDER は自動的にプロジェクトルート以下を見て、 project.clj
, build.boot
のどちらかがあればそれに従って cider-jack-in
を実行しています。
Emacs の設定
まず Clojure 開発において必須となるパッケージは以下の通りです。
- Clojure Mode
- CIDER
- clj-refactor
これ以外のもので Clojure 開発する上であると便利なものは次の通りです。
- company-mode
- paredit, smartparens
- RainbowDelimiters
他にも幾つかあるオプショナルなものはこの記事の最後で言及しようと思います。
今回、 CIDER の開発版である 0.11.0
に言及するために私は melpa リポジトリを package-archives
に追加していますが、 CIDER の開発版は高確率でバグを孕んでいるのでこれから CIDER を使いたい方は melpa リポジトリを使わずに melpa-stable のみを package-archives
に追加するのをお勧めします(もしくは Emacs 24.4 以降では package-pinned-packages
という変数が設定可能なのでそちらを設定して CIDER だけ melpa-stable を利用するなどしてください。 See also Using ELPA with pinned packages in GNU Emacs 24.4 / The Lone C++ Coder's Blog )。
以下に例を示しておきます。
(require 'package)
(add-to-list 'package-archives '("melpa-stable" . "http://stable.melpa.org/packages/") t)
(add-to-list 'package-archives '("marmalade" . "http://marmalade-repo.org/packages/"))
(package-initialize)
(unless package-archive-contents (package-refresh-contents))
ここより先はひとつずつパッケージの説明と簡易な設定と幾つか重要な機能について触れていきますが、以前私が作った設定がここで紹介しているものを全て含んでいるのでそちらも合わせて参照すると理解が容易だと思います。
Clojure mode
Clojure mode とは
このモードは一番基本となるモードです。これは次の 4 つのメジャーモードをバンドルしています。
-
clojure-mode
- 一般的な Clojure を書くためのモードで
.clj
,.edn
などの拡張子に対応します。
- 一般的な Clojure を書くためのモードで
-
clojurescript-mode
- ClojureScript を書くためのモードで
.cljs
に対応しています。
- ClojureScript を書くためのモードで
-
clojurec-mode
-
.cljc
に対応しています。 -
.cljc
についての詳細は The Reader - Reader Conditionals / Clojure を参照してください。
-
-
clojurex-mode
-
.cljx
に対応しています。
-
いずれのモードも clojure-mode
から派生しているので一般的には clojure-mode
だけを設定すれば他の派生した各モードにも適用されますが、各モードのときだけ設定したいものがあればそれぞれのモードに対して設定を行ないます。 例えば clojurescript-mode
のときだけ有効にしたいショートカットがあれば clojurescript-mode-map
を設定するなど。
インストール
melpa と melpa-stable からインストールできます。
M-x package-install [RET] clojure-mode [RET]
セットアップ
clojure-mode
で設定すべき項目は特にないので次のような記述のみで十分です。
(use-package clojure-mode)
しかし、現実的には yasnippet
や subword
を clojure-mode
になったときに有効化したいので次のように設定すると良いと思います。
(use-package clojure-mode
:init
(add-hook 'clojure-mode-hook #'yas-minor-mode)
(add-hook 'clojure-mode-hook #'subword-mode))
インデントについて
基本的にはこのモードで設定するようなことはせずデフォルト設定のまま使うほうが良いでしょう(他人のコーディングスタイルと衝突しがちなのであまり積極的に設定をしないほうがいいという程度です)。 デフォルトのインデントルールはコミュニティ Clojure Style Guide を元にしています。もし設定したい場合は indentation-options - README に従ってください。
フォームを整列させる
また、 clojure-mode
では let
フォームなどを整列させる機能が提供されています。
(let [long-long-var 10
v 99])
(def m {:some-key 1
:key2 10})
具体的にはこのようなコードを次のようにできます。
(let [long-long-var 10
v 99])
(def m {:some-key 1
:key2 10})
デフォルトでこの機能は C-c SPC
に割りあてられています。自動的に行うには clojure-align-forms-automatically
を設定すると良いです。
CIDER
CIDER とは
CIDER は Clojure のインタラクティブなプログラミングをサポートしてくれる Emacs 拡張です。 cider-mode
は clojure-mode
のマイナーモードとして実装していて、主な機能としては起動している Clojure プロセスを利用した編集機能、デバッグ機能、ドキュメントや関数などのルックアップ、テストの実行などです。
CIDER は SLIME + swank-clojure の後継として開発されてきました。何故、 CIDER が作られたのかなどといった話は次の動画を見ると面白いです。
インストール
melpa と melpa-stable からインストールできます。
M-x package-install [RET] cider [RET]
セットアップ
CIDER は特に設定をしなくても動くので次のような設定だけでも起動させることが出来ます。
(use-package cider)
一般的な設定は次の例や README を参照してください。
(use-package cider
:init
(add-hook 'cider-mode-hook #'clj-refactor-mode)
(add-hook 'cider-mode-hook #'company-mode)
(add-hook 'cider-mode-hook #'eldoc-mode)
(add-hook 'cider-repl-mode-hook #'company-mode)
(add-hook 'cider-repl-mode-hook #'eldoc-mode)
:diminish subword-mode
:config
(setq nrepl-log-messages t
cider-repl-display-in-current-window t
cider-repl-use-clojure-font-lock t
cider-prompt-save-file-on-load 'always-save
cider-font-lock-dynamically '(macro core function var)
cider-overlays-use-font-lock t)
(cider-repl-toggle-pretty-printing))
CIDER は cdier-jack-in
でコネクションが確立されている場合に自動的に cider-mode
が有効になります。 clojure-mode
をフックして cider-mode
を有効にする必要はありません。
また今回は CIDER 0.11.0
を対象に説明しているので $HOME/.lein/profiles.clj
の記述をしていませんが、それ以前の場合次のように $HOME/.lein/profiles.clj
を記述する必要があります。
{:repl {:plugins [[cider/cider-nrepl "0.10.2"]]}}
基本的な使い方
全ては Clojure(Script) ファイルを開き M-x cider-jack-in(or cider-connect)
を実行して CIDER コネクションを確立するところから始まります。
覚えておいた方が良いコマンドは次の通りです。
ショートカット | コマンド名 | 簡易説明 |
---|---|---|
C-c C-e | cider-eval-last-sexp | カーソルの手前にあるフォームを評価して結果をミニバッファ(と/か)オーバーレイに表示する |
C-c C-d d | cider-doc | カーソルの下にあるシンボルのドキュメントをひく |
M-. | cider-find-var | カーソルの下にあるシンボルの定義へとジャンプする |
最低でもこれだけ知っていればそれなりに十分です(勿論、普段開発している上で使うコマンドはこれだけではないです)。これら以外にも沢山便利なコマンドがあるので Using cider-mode - README を参照してください。
デバッグ
一番シンプルな方法はデバッグしたい関数のフォームの上で C-u C-M-x
を実行することです。これによって関数をデバッグ対象として登録することができ、その後その関数を実行すると関数の上にデバッグメニューが表示されるので表示されたデバッグメニューに従うことです。 また登録した関数のフォーム上で C-M-x
を実行することで登録していた関数をデバッグ対象から外すことができます。
また #break
とブレークポイントにしたいフォームの直前に書いておくことで、その関数が実行された場合自動的にデバッグモードとなりブレークポイントに止まります。
(defn foo [x y z]
(let [a (+ x y)
b (+ y z)]
#break (+ a b)))
詳細は Debugging - README を確認してください。
テスト実行
CIDER は clojure.test
のテストを簡単に実行することが出来ます。 C-c C-t n
で現在開いているソースのネームスペースに対応したテストが実行され、 C-c C-t p
でプロジェクトの全てのテストケースが実行されます。
some.foons
というネームスペースがあるときにそれに対応するテストのネームスペースは some.foons-test
という風につけるので、それに倣うようにしてください。このルールが好みではないとき cider-test-infer-test-ns
変数を設定することで変更することが出来ます。
詳細は Running tests - README を確認してください。
Enlighten mode
Light Table のようにローカル変数にどのような値が入っているのか簡単に表示させることが出来るモードです。 M-x cider-enlighten-mode
とした後に関数を評価して実行すると以下のように表示されます。
詳細は Enlighten (display local values) - README を確認してください。
その他の機能について
他にもマクロ展開やインスペクター, Grimoire ドキュメントといった機能がありますが、全てをここで説明するには多過ぎるので割愛します。また、以前に Lisp Meet Up でもこの話をしたので資料を参照してください(動画もあります)。
clj-refactor
clj-refactor とは
clj-refactor
は Clojure プロジェクトに対してリファクタリング機能を追加してくれるマイナーモードです。
インストール
melpa と melpa-stable からインストールできます。
M-x package-install [RET] clj-refactor [RET]
セットアップ
次のように cider-mode
か clojure-mode
でフックして自動的に有効化されるようにしておくと良いでしょう。
(use-package cider
:init
(add-hook 'cider-mode-hook #'clj-refactor-mode)
;; 略
)
(use-package clj-refactor
:diminish clj-refactor-mode
:config (cljr-add-keybindings-with-prefix "C-c j"))
cljr-add-keybindings-with-prefix
変数はデフォルトで C-!
になっていますが自由にしてください。
また、 CIDER が 0.10.0
以下であれば次の記述が $HOME/.lein/profiles.clj
に必要です。
{:repl {:plugins [[cider/cider-nrepl "0.10.2"]
[refactor-nrepl "2.0.0"]]}}
基本的な使い方
基本は cljr-add-keybindings-with-prefix
で設定したショートカットを起点に、コマンドの頭文字ふたつで様々なコマンドを実行できます。例えば cn
で Clean namespace form
を実行できます。デフォルトプレフィックスの場合は C-! cn
という具合です。
実行可能なコマンドは Wiki にリストアップされているのでそちらを参照してください。
company-mode
company-mode とは
古くからある補完プラグインで一時期はあまりメンテナンスがされていなかったようですが、最近は活発に開発が行われているのと海外ではこちらが主流になりつつあるようです。
何故、このプラグインをここで紹介しているかというと CIDER では company-mode
を使っている場合、補完候補にアノテーションをつけてくれるので auto-complete
よりも使い勝手がいいためです。
インストール
M-x package-install [RET] company [RET]
セットアップ
セットアップ例です。
(use-package company
:config
(global-company-mode)
(setq company-idle-delay 0.1
company-minimum-prefix-length 2
company-selection-wrap-around t)
(bind-keys :map company-mode-map
("C-i" . company-complete))
(bind-keys :map company-active-map
("C-n" . company-select-next)
("C-p" . company-select-previous)
("C-s" . company-search-words-regexp))
(bind-keys :map company-search-map
("C-n" . company-select-next)
("C-p" . company-select-previous)))
基本的に (global-company-mode)
でグローバルに有効にするか、 (add-hook 'cider-mode-hook #'company-mode)
のようにしてフックして有効にします。これだけで CIDER と一緒に使う場合は十分です。
paredit, smartparens
paredit, smartparens とは
どちらも括弧のバランスをとるためのパッケージです。 paredit
か smartparens
を使うことによって括弧のバランスを壊すことなく操作ができます。 Lisper であれば必須と言っても過言ではないパッケージですが、慣れないと括弧を消すことも難しいですが、慣れてくるとこれ無しにはコードを書けなくなります。 ちなみにどちらを使うかですが、私は paredit
を使っていますが最近であれば smartparens
の方が良いかもしれないです。
インストール
ここでは paredit
について書きます。 melpa, melpa-stable からインストールできます。
M-x package-install [RET] paredit [RET]
セットアップ
セットアップ例です。
(use-package paredit
:config
(bind-keys :map paredit-mode-map
("C-h" . paredit-backward-delete)))
(use-package clojure-mode
:init
(add-hook 'clojure-mode-hook #'paredit-mode)
;; 略
)
RainbowDelimiters
RainbowDelimiters とは
括弧に色が付きます。括弧がネストしている場合にそれぞれ違う色が付くので多少見易くなりますが、そこまでの効果はないのであったら多少嬉しいくらいに思ってもらえたらいいです(結局、括弧なんて見てないですし、 (show-paren-mode 1)
としているだけで比較的十分ではあると思います)。
インストール
melpa, melpa-stable からインストールできます。
M-x package-install RET rainbow-delimiters RET
セットアップ
セットアップ例です。
(use-package rainbow-delimiters)
(use-package clojure-mode
:init
(add-hook 'clojure-mode-hook #'rainbow-delimiters-mode)
;; 略
)
言及しなかったパッケージについて
幾つか言及しなかったものがあるので、それらについて補足しておきます。
- clojure-mode-extra-font-locking
- CIDER が動的に font-locking してくれるので CIDER を使っているときは基本的に不要です。
- align-cljlet
- 元々は独立していましたが、 Clojure mode がこれを実装したため不要です。
- slamhound
- clj-refactor の clean namespace と add missing libspec が使えるので必要なくなりました。
- kibit-mode
- Clojure ぽく書きたいのであればあったほうが良いかもしれませんが私は慣れてしまったので不要と感じています。
- squiggly-clojure
- eastwood, kibit のフロントになるものですが、設定が異常に面倒臭かったのと昔使ったときに不安定だったので使用するのを断念しました。
- clojure-cheatsheet
- これも私個人としては覚えてしまったので不要となっています。
- cider-eval-sexp-fu
- 評価したフォームが光って楽しいですが、別にここで言及するほどのものでもないのでしませんでした。
- midje-mode
- midje を使っている場合、あると嬉しいです。
最後に
最新の Emacs 用の Clojure 開発環境について解説しました。最近では少し前に比べても随分と設定が簡単になったと思います。現在、 Clojure を書く開発環境 Cursive を始めとして幾つもありますが、 2016 年現在でも世界中にいる Clojurian の約半数が Clojure を書くために Emacs + CIDER を使っています( STATE OF CLOJURE 2015 SURVEY RESULTS / cognitect blog )。幾つか私も開発環境として使ってみましたが、 Emacs + CIDER がやっぱり抜きんでているなという印象を持っています。
また今回は設定に終始しましたが、詳しい使い方などを近々 Clojure の日本語ガイド に書いていくつもりですので、そちらも楽しみにしておいてください。