Clojure の勉強を始めました。

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

優れた IDE が備える機能

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

Clojure に特科した Elisp

clojure-mode

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

https://github.com/clojure-emacs/clojure-mode

(require ‘clojure-mode)

cider

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

(require 'cider) 

;; clojure-mode で cider を有効に 
(add-hook   'clojure-mode-hook 'cider-mode)

;; eldoc を有効にする (add-hook 'cider-mode-hook 'cider-turn-on-eldoc-mode))
  • cider-jack-in で repl 起動
  • cider-connect でリモート repl に接続

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

4clojure

clojure の問題集.

(require ‘4clojure)

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

ac-cider

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

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

clojure-cheatsheet

CheatSheet を参照できる.

(require 'clojure-cheatsheet)
(define-key clojure-mode-map (kbd "C-c C-h") #'clojure-cheatsheet)

clj-refactor

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

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

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

clojure-snippets

Yasnipeet for Clojure

(require 'clojure-snippets)
(setq clojure-snippets-dir "~/.emacs.d/el-get/repo/clojure-snippets/")

主に Lisp 系に役立つ Elisp

ggtags

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

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

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

(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 もある. どちらを使うかは好き嫌い.

(require 'smartparens-config) (smartparens-global-mode t)

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

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

(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

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

;; turn on highlight matching brackets when cursor is on one 
(show-paren-mode 1)

rainbow-delimiters

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

(require 'rainbow-delimiters)