Emacs で Clojure の開発環境を構築

    Clojure の勉強を始めました。

    まずはなにより Emacs の設定からかと思うので、 Clojure の Emacs 設定を整えました. 現時点での設定をプログにスナップショット.

    優れた IDE が備える機能

    • シンタックスハイライト/ インデント clojure-mode
    • 検索・置換 たくさんあるよ.
    • タグジャンプ ggtags
    • コード補間 ac-clojure
    • エラーチェック flycheck
    • リファクタリング clj-refactor
    • インタープリタ・デバッカ cider
    • プロジェクト管理 projectile
    • ドキュメント参照 eldoc

    Clojure に特科した Elisp

    clojure-mode

    Clojure のためのメジャーモード. シンタックスハイライトとかインデントとかを正してくれるモード. これは必須.

    [sourcecode language=”emacs-lisp” title=”” ]
    (require ‘clojure-mode)
    [/sourcecode]

    cider

    Clojure のためのインタラクティブな開発環境.

    [sourcecode language=”emacs-lisp” title=”” ]
    (require ‘cider)
    ;; clojure-mode で cider を有効に
    (add-hook ‘clojure-mode-hook ‘cider-mode)
    ;; eldoc を有効にする
    (add-hook ‘cider-mode-hook ‘cider-turn-on-eldoc-mode))
    [/sourcecode]

    • cider-jack-in で repl 起動
    • cider-connect でリモート repl に接続

    repl と連携して開発を行うことができる. REPL 駆動開発!!

    4clojure

    clojure の問題集.

    [sourcecode language=”emacs-lisp” title=”” ]
    (require ‘4clojure)
    [/sourcecode]

    Emacs から問題をといたり、答え合わせができる. そのまま答えを投稿できればいいのだけれども、それは未対応.

    ac-cider

    auto-complete for cider. 強力な補完機能が手に入る.

    [sourcecode language=”emacs-lisp” title=”” ]
    (require ‘ac-cider)
    (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))))
    [/sourcecode]

    clojure-cheatsheet

    CheatSheet を参照できる.

    [sourcecode language=”emacs-lisp” title=”” ]
    (require ‘clojure-cheatsheet)
    (define-key clojure-mode-map (kbd “C-c C-h”) #’clojure-cheatsheet)
    [/sourcecode]

    clj-refactor

    Clojure 用リファクタリング支援ツール.

    できる機能か多すぎ!覚えらんない..

    [sourcecode language=”emacs-lisp” title=”” ]
    (require ‘clj-refactor)

    (defun my-clojure-mode-hook ()
    (clj-refactor-mode 1)
    (yas-minor-mode 1) ; for adding require/use/import statements
    ;; This choice of keybinding leaves cider-macroexpand-1 unbound
    (cljr-add-keybindings-with-prefix “C-c C-m”))

    (add-hook ‘clojure-mode-hook #’my-clojure-mode-hook)
    [/sourcecode]

    clojure-snippets

    Yasnipeet for Clojure

    [sourcecode language=”emacs-lisp” title=”” ]
    (require ‘clojure-snippets)
    (setq clojure-snippets-dir “~/.emacs.d/el-get/repo/clojure-snippets/”)
    [/sourcecode]

    主に Lisp 系に役立つ Elisp

    ggtags

    変数や関数の定義にタグジャンプする. ggtags-create-tags 関数を呼ぶと, ctags コマンドがコールされてタグがつくられる.

    と思ったら、つくられない。.globalrc に設定を追加する必要があるようだ. 以下のサイトを参考にした。ありがとうございます.

    タグができたら、あとはコマンドを定義するだけ.

    [sourcecode language=”emacs-lisp” title=”” ]
    (require ‘ggtags)
    (add-hook ‘clojure-mode-hook (lambda () (ggtags-mode 1)))

    ;; use helm
    (setq ggtags-completing-read-function nil)

    ;; use eldoc
    (setq-local eldoc-documentation-function #’ggtags-eldoc-function)

    ;; imenu
    (setq-local imenu-create-index-function #’ggtags-build-imenu-index)

    (define-key ggtags-mode-map (kbd “C-c g s”) ‘ggtags-find-other-symbol)
    (define-key ggtags-mode-map (kbd “C-c g h”) ‘ggtags-view-tag-history)
    (define-key ggtags-mode-map (kbd “C-c g r”) ‘ggtags-find-reference)
    (define-key ggtags-mode-map (kbd “C-c g f”) ‘ggtags-find-file)
    (define-key ggtags-mode-map (kbd “C-c g c”) ‘ggtags-create-tags)
    (define-key ggtags-mode-map (kbd “C-c g u”) ‘ggtags-update-tags)
    (define-key ggtags-mode-map (kbd “C-c g m”) ‘ggtags-find-tag-dwim)

    (define-key ggtags-mode-map (kbd “M-,”) ‘pop-tag-mark))
    [/sourcecode]

    smartparens

    カッコの移動を簡単にする elisp. 似たような機能に Paredit という elisp もある. どちらを使うかは好き嫌い.

    [sourcecode language=”emacs-lisp” title=”” ]
    (require ‘smartparens-config)
    (smartparens-global-mode t)
    [/sourcecode]

    以下、自分のキーバインドを貼り付けるけれども、キーバインドは好きに設定してよい.

    正直、あまりつかいこなせてない…

    [sourcecode language=”emacs-lisp” title=”” ]
    (define-key sp-keymap (kbd “C-M-f”) ‘sp-forward-sexp) ;; forward
    (define-key sp-keymap (kbd “C-M-b”) ‘sp-backward-sexp) ;; backward

    (define-key sp-keymap (kbd “C-M-n”) ‘sp-next-sexp) ;; next
    (define-key sp-keymap (kbd “C-M-p”) ‘sp-previous-sexp) ;; previous

    ;; 一段中の/ 外のカッコに移動.
    (define-key sp-keymap (kbd “C-M-d”) ‘sp-down-sexp) ;; down
    (define-key sp-keymap (kbd “C-M-u”) ‘sp-up-sexp) ;; up

    ;; かっこの先頭と末尾に移動.
    (define-key sp-keymap (kbd “C-M-a”) ‘sp-beginning-of-sexp)
    (define-key sp-keymap (kbd “C-M-e”) ‘sp-end-of-sexp)

    ;; カッコのなかを削除・コピー (かたまり単位)
    ;; sp-kill/copy-hiblid-sexp というものもある
    (define-key sp-keymap (kbd “C-M-k”) ‘sp-kill-sexp)
    (define-key sp-keymap (kbd “C-M-w”) ‘sp-copy-sexp)

    ;; かっこを外す
    (define-key sp-keymap (kbd “C-M-s”) ‘sp-unwrap-sexp)
    [/sourcecode]

    show-paren-mode

    対応する括弧を光らせる.

    [sourcecode language=”emacs-lisp” title=”” ]
    ;; turn on highlight matching brackets when cursor is on one
    (show-paren-mode 1)
    [/sourcecode]

    rainbow-delimiters

    かっこの深さに応じて色付けしてくれる.

    [sourcecode language=”emacs-lisp” title=”” ]
    (require ‘rainbow-delimiters)
    [/sourcecode]