2010-09-14
xyzzyでArcのifのインデント
ArcのifはLisp/Schemeのcondの括弧が少ない版といった感じで
(if pred1 exp1 pred2 exp2 ... ... else-value)
という風に複数の条件を続けて書ける。このオートインデントをxyzzyで実現しようと思うと元々のlispmodeのインデント計算のままではうまくいかない。lispmodeのインデント計算はifなどのシンボルによって、引数の何個目までは*lisp-body-indent*の2倍、それ以降は*lisp-body-indent*、となってしまっていて融通が利かない。
そこで、シンボルに関数を設定できるようにする。lispmode.lのcalc-lisp-indent関数内でシンボルのlisp-indent-hookに設定された値の型が関数だったら、その関数を呼び出してインデントを決定するようにする:
(defun calc-lisp-indent (opoint) ... (cond ((numberp method) ...) ;追加 ((functionp method) (let ((count -1)) (while (< (point) opoint) ; 何個目の引数かを数える (skip-white-forward) (setq count (+ count 1)) (or (forward-sexp 1 t) (return))) (+ column -1 (funcall method count)))) (method ...
こうして、ifのlisp-indent-hookに関数を設定する:
(setf (get 'if 'lisp-indent-hook) #'(lambda (count) (if (zerop (mod count 2)) *lisp-body-indent* (* *lisp-body-indent* 2))))
でOK。
注意点は、M-x byte-compile-file で lispmode.l をバイトコンパイルするだけじゃなく、いったんxyzzy.wxpを削除しないと反映されなくてハマった。
コメントを書く
トラックバック - http://cadr.g.hatena.ne.jp/mokehehe/20100914