旧: Emacs を使うモダンな Clojure 開発環境

注意事項
======

今なら素直にSpacemacsを使ったほうが手軽に環境構築できます。
この記事はある程度当時の状況を網羅したもので、今でも利用されているパッケージはあまり変わっていないので、そういう意味では参考になりますがセットアップ方法や設定などはかなり変わってきているので、参考にならない部分も多いです。
Spacemacsを僕の好みに合わせて設定したものを、以下に解説と合わせてのせているので参考にしてみてください。

- [SpacemacsでClojureを書くために僕が行った設定](https://scrapbox.io/ayato-p/Spacemacs%E3%81%A7Clojure%E3%82%92%E6%9B%B8%E3%81%8F%E3%81%9F%E3%82%81%E3%81%AB%E5%83%95%E3%81%8C%E8%A1%8C%E3%81%A3%E3%81%9F%E8%A8%AD%E5%AE%9A)

はじめに
========

Clojure の開発環境というのはどんどん新しくなっていくので、最近の開発環境事情について解説しようと思います。

この記事は次の記事の置き換えを狙ったもので、出来るだけ新しい情報を提供することを目的としています。

-   [EmacsでモダンClojure開発環境構築](http://qiita.com/xorphitus/items/a1f433fa6ba2489ff9cf)

また何か間違っているという場合は気軽に編集リクエストを送ってもらって構いませんし、コメントなどで教えてもらえれば修正します。

前提条件
========

この記事で要求するものは次の通りです。

-   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 は必須なのでインストールされていることを前提としますが、もしまだインストールされていないのであれば次の記事を参照してインストールしてください。

-   [Leiningenの導入(1): 概要とインストール / clojournal](http://clojournal.com/entry/54e42e79e4b07686596991c1)

また、今迄 `$HOME/.lein/profiles.clj` に CIDER などで使う nREPL の依存関係などを記述していましたが、 `0.11.0` 以降それらの記述は不要となっています。

-   [Cider should inject its own dependencies/plugins automatically at cider-jack-in \#1531](https://github.com/clojure-emacs/cider/issues/1531)

よって、現在 `$HOME/.lein/profiles.clj` に記述をする必要はあまりありませんが、 CIDER はローカルにある Javadoc を引くことができるので私は以下の記述だけ行っています。

``` clojure
{: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](http://www.lonecpluspluscoder.com/2014/11/using-elpa-pinned-packages-gnu-emacs-24-4/) )。

以下に例を示しておきます。

``` commonlisp
(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))
```

ここより先はひとつずつパッケージの説明と簡易な設定と幾つか重要な機能について触れていきますが、以前私が作った設定がここで紹介しているものを全て含んでいるのでそちらも合わせて参照すると理解が容易だと思います。

-   [:book: ayato-p/emacs-config-for-newbie-clojurian](https://github.com/ayato-p/emacs-config-for-newbie-clojurian)

Clojure mode
------------

### Clojure mode とは

このモードは一番基本となるモードです。これは次の 4 つのメジャーモードをバンドルしています。

-   `clojure-mode`
    -   一般的な Clojure を書くためのモードで `.clj`, `.edn` などの拡張子に対応します。
-   `clojurescript-mode`
    -   ClojureScript を書くためのモードで `.cljs` に対応しています。
-   `clojurec-mode`
    -   `.cljc` に対応しています。
    -   `.cljc` についての詳細は [The Reader - Reader Conditionals / Clojure](http://clojure.org/reference/reader#_reader_conditionals) を参照してください。
-   `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` で設定すべき項目は特にないので次のような記述のみで十分です。

``` commonlisp
(use-package clojure-mode)
```

しかし、現実的には `yasnippet` や `subword` を `clojure-mode` になったときに有効化したいので次のように設定すると良いと思います。

``` commonlisp
(use-package clojure-mode
  :init
  (add-hook 'clojure-mode-hook #'yas-minor-mode)
  (add-hook 'clojure-mode-hook #'subword-mode))
```

### インデントについて

基本的にはこのモードで設定するようなことはせずデフォルト設定のまま使うほうが良いでしょう(他人のコーディングスタイルと衝突しがちなのであまり積極的に設定をしないほうがいいという程度です)。 デフォルトのインデントルールは[コミュニティ Clojure Style Guide](https://github.com/bbatsov/clojure-style-guide) を元にしています。もし設定したい場合は [indentation-options - README](https://github.com/clojure-emacs/clojure-mode#indentation-options) に従ってください。

### フォームを整列させる

また、 `clojure-mode` では `let` フォームなどを整列させる機能が提供されています。

``` clojure
(let [long-long-var 10
      v 99])

(def m {:some-key 1
        :key2 10})
```

具体的にはこのようなコードを次のようにできます。

``` clojure
(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 が作られたのかなどといった話は次の動画を見ると面白いです。

-   [:movie_camera: Bozhidar Batsov - The evolution of the Emacs tooling for Clojure / YouTube](https://youtu.be/4X-1fJm25Ww)

### インストール

melpa と melpa-stable からインストールできます。

`M-x package-install [RET] cider [RET]`

### セットアップ

CIDER は特に設定をしなくても動くので次のような設定だけでも起動させることが出来ます。

``` commonlisp
(use-package cider)
```

一般的な設定は次の例や [README](https://github.com/clojure-emacs/cider#configuration) を参照してください。

``` commonlisp
(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` を記述する必要があります。

``` clojure
{: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](https://github.com/clojure-emacs/cider#using-cider-mode) を参照してください。

### デバッグ

一番シンプルな方法はデバッグしたい関数のフォームの上で `C-u C-M-x` を実行することです。これによって関数をデバッグ対象として登録することができ、その後その関数を実行すると関数の上にデバッグメニューが表示されるので表示されたデバッグメニューに従うことです。 また登録した関数のフォーム上で `C-M-x` を実行することで登録していた関数をデバッグ対象から外すことができます。

![cider-debug.png](https://qiita-image-store.s3.amazonaws.com/0/14889/85f94d4f-9847-a5a5-6a0a-818905b48618.png)

また `#break` とブレークポイントにしたいフォームの直前に書いておくことで、その関数が実行された場合自動的にデバッグモードとなりブレークポイントに止まります。

``` clojure
(defn foo [x y z]
  (let [a (+ x y)
        b (+ y z)]
    #break (+ a b)))
```

詳細は [Debugging - README](https://github.com/clojure-emacs/cider#debugging) を確認してください。

### テスト実行

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](https://github.com/clojure-emacs/cider#running-tests) を確認してください。

### Enlighten mode

Light Table のようにローカル変数にどのような値が入っているのか簡単に表示させることが出来るモードです。 `M-x cider-enlighten-mode` とした後に関数を評価して実行すると以下のように表示されます。

![cider-enlithin.png](https://qiita-image-store.s3.amazonaws.com/0/14889/f0c3d7a2-12f5-fec0-2d4c-de359449d16a.png)

詳細は [Enlighten (display local values) - README](https://github.com/clojure-emacs/cider#enlighten-display-local-values) を確認してください。

### その他の機能について

他にもマクロ展開やインスペクター, Grimoire ドキュメントといった機能がありますが、全てをここで説明するには多過ぎるので割愛します。また、以前に [Lisp Meet Up](http://lisp.connpass.com/event/27144/) でもこの話をしたので資料を参照してください(動画もあります)。

clj-refactor
------------

### clj-refactor とは

`clj-refactor` は Clojure プロジェクトに対してリファクタリング機能を追加してくれるマイナーモードです。

![clj-refactor-comb.gif](https://github.com/ayato-p/emacs-config-for-newbie-clojurian/raw/master/img/clj-refactor-comb.gif)

### インストール

melpa と melpa-stable からインストールできます。

`M-x package-install [RET] clj-refactor [RET]`

### セットアップ

次のように `cider-mode` か `clojure-mode` でフックして自動的に有効化されるようにしておくと良いでしょう。

``` commonlisp
(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` に必要です。

``` clojure
{: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 にリストアップされているのでそちらを参照してください。

-   [Wiki - clj-refactor.el](https://github.com/clojure-emacs/clj-refactor.el/wiki)

company-mode
------------

### company-mode とは

古くからある補完プラグインで一時期はあまりメンテナンスがされていなかったようですが、最近は活発に開発が行われているのと海外ではこちらが主流になりつつあるようです。

何故、このプラグインをここで紹介しているかというと CIDER では `company-mode` を使っている場合、補完候補にアノテーションをつけてくれるので `auto-complete` よりも使い勝手がいいためです。

### インストール

`M-x package-install [RET] company [RET]`

### セットアップ

セットアップ例です。

``` commonlisp
(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]`

### セットアップ

セットアップ例です。

``` commonlisp
(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`

### セットアップ

セットアップ例です。

``` commonlisp
(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 ](http://blog.cognitect.com/blog/2016/1/28/state-of-clojure-2015-survey-results))。幾つか私も開発環境として使ってみましたが、 Emacs + CIDER がやっぱり抜きんでているなという印象を持っています。

また今回は設定に終始しましたが、詳しい使い方などを近々 [Clojure の日本語ガイド](http://ayato-p.github.io/clojure-beginner/) に書いていくつもりですので、そちらも楽しみにしておいてください。