Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

注意事項

今なら素直に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 などの拡張子に対応します。
  • clojurescript-mode
    • ClojureScript を書くためのモードで .cljs に対応しています。
  • clojurec-mode
  • 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)

しかし、現実的には yasnippetsubwordclojure-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-modeclojure-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 を実行することで登録していた関数をデバッグ対象から外すことができます。

cider-debug.png

また #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 とした後に関数を評価して実行すると以下のように表示されます。

cider-enlithin.png

詳細は Enlighten (display local values) - README を確認してください。

その他の機能について

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

clj-refactor

clj-refactor とは

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

clj-refactor-comb.gif

インストール

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

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

セットアップ

次のように cider-modeclojure-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 で設定したショートカットを起点に、コマンドの頭文字ふたつで様々なコマンドを実行できます。例えば cnClean 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 とは

どちらも括弧のバランスをとるためのパッケージです。 pareditsmartparens を使うことによって括弧のバランスを壊すことなく操作ができます。 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 の日本語ガイド に書いていくつもりですので、そちらも楽しみにしておいてください。

ayato_p
ブログ記事を流すくらいしかしないと思います。
http://ayato.hateblo.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away