emacsのdefmacroメモ。

( ´_ゝ`)ノシ
yoshitiaです。

evil-modeのdefmacro読もうとした時に?となった点をメモ。

defmacroの中に入ってる良くわからないもの

(declare (indent defun))
というコードがあって
macroexpandでマクロを展開しても
出力結果がインデント調整されてるわけでもないので
かなり謎でした。

init.el読書会で解決

丁度2016/12/24のinit.el読書会で出てきたinit.elで
defmacroが出てきたので@poginさんに聞いたら即答でした。

(declare (indent defun))で調整されるもの

defmacroでマクロを定義した後、
マクロを書くタイミングで効果が出ます。
式の途中で改行を行った時のインデント方式の指定を
行っているようです。

@poginさんに出してもらった例

;; (declare (indent defun))無し
(defmacro after1 (mode &rest body)
  "`eval-after-load' MODE evaluate BODY."
  `(eval-after-load ,mode
     '(progn ,@body)))

;; (declare (indent defun))あり
(defmacro after2 (mode &rest body)
  "`eval-after-load' MODE evaluate BODY."
  (declare (indent defun))
  `(eval-after-load ,mode
     '(progn ,@body)))

上記マクロ2つを評価した後に書いたコード

;; (declare (indent defun)) なし
(after1 'dired
        (define-key dired-mode-map (kbd "M-p") 'dired-back-to-top)
        (define-key dired-mode-map (kbd "M-n") 'dired-jump-to-bottom)
        (define-key dired-mode-map (kbd "C-a") 'dired-back-to-start-of-files))

;; (declare (indent defun))あり
(after2 'dired
  (define-key dired-mode-map (kbd "M-p") 'dired-back-to-top)
  (define-key dired-mode-map (kbd "M-n") 'dired-jump-to-bottom)
  (define-key dired-mode-map (kbd "C-a") 'dired-back-to-start-of-files))

それぞれ2行目以降のインデントはemacsが自動で調整したものです。
indent後ろにdefunや1やら値を指定するとそれに応じて
マクロのインデントの方式が決まるようです。

参考:
GNU Emacs Lisp Reference Manual: Indenting Macros