- Emacs Lisp を書いているときに自動インデントしたいときは C-M-a(beginning-of-defun)で関数の頭に移動して C-M-q(indent-pp-sexp)しているが、2ストロークなので面倒くさくなってきた
- 1つにまとめよう
- どうせだから save-excursion で囲んだらいいんじゃね?
- どうせだから自分が良く使う他の言語でも同じフィーリングで使えるようにしたらいいんじゃね?
というわけで以下のようになりました。
言語によっては beginning-of-defun や indent-pp-sexp に相当するコマンド・関数が使えないこともあるので、その場合は
- ルールで指定された関数を使ってブロックの先頭に移動した後で
- ルールで指定された関数を使ってブロックの末尾に移動し、
- その間をインデント
するようにしました。
なので、移動する関数を適当にいじるとカーソル位置などをもとに好きな範囲をインデントできます。
;; block-indent.el ;; author: sonota ;; license: GPL ;;;; ;; ルールの書式: ;; ((modes) ; 関連付けるメジャーモードのリスト ;; ブロック先頭に移動する関数 ;; ブロック末尾に移動する関数 ;; インデントを行う関数 ;; 引数に開始・終了位置が必要なら non-nil) ;; .emacs で次のようにルールを追加する ;; (add-to-list ;; 'block-indent:rules ;; '((ruby-mode) ;; ruby-beginning-of-defun ;; nil ;; ruby-indent-exp nil)) ;; (add-to-list ;; 'block-indent:rules ;; '((js2-mode) ;; beginning-of-defun ;; forward-sexp ;; indent-region t)) (defvar block-indent:default-rule '(nil backward-paragraph forward-paragraph indent-region t) "デフォルトのルール(ルールが見つからなかったときに使われる)") (defvar block-indent:rules '(((emacs-lisp-mode lisp-interaction-mode) beginning-of-defun nil indent-pp-sexp nil)) "ルールのリスト") (defun block-indent:select-rule () "メジャーモードをもとにルールを選択" (let (rule modes) (setq rule (car (remove-if-not (lambda (x) (memq major-mode (nth 0 x))) block-indent:rules))) (unless rule (setq rule block-indent:default-rule)) rule)) (defun block-indent:sub (rule) (let ((beginning-func (nth 1 rule)) (forward-func (nth 2 rule)) (indent-func (nth 3 rule)) (region-args-p (nth 4 rule)) (beg nil)) (funcall beginning-func) ; ブロックの先頭に移動 (setq beg (point)) ; 先頭位置を保存 (when forward-func (funcall forward-func)) ; ブロック末尾に移動 ;; インデント (if region-args-p (funcall indent-func beg (point)) (funcall indent-func)))) (defun block-indent () (interactive) (save-excursion (block-indent:sub (block-indent:select-rule)))) (provide 'block-indent)