Next: SMIE Customization, Previous: SMIE Indentation Helpers, Up: SMIE [Contents][Index]
以下は、インデント関数の例です:
(defun sample-smie-rules (kind token)
(pcase (cons kind token)
(`(:elem . basic) sample-indent-basic)
(`(,_ . ",") (smie-rule-separator kind))
(`(:after . ":=") sample-indent-basic)
(`(:before . ,(or `"begin" `"(" `"{")))
(if (smie-rule-hanging-p) (smie-rule-parent)))
(`(:before . "if")
(and (not (smie-rule-bolp)) (smie-rule-prev-p "else")
(smie-rule-parent)))))
注意すべき点がいくつかあります:
sample-indent-basicがnilの場合、SMIEはグローバルセッティングsmie-indent-basicを使用する。メジャーモードがかわりにsmie-indent-basicをバッファーローカルにセットするかもしれないが、これは勧められない。
","にたいするルールにより、カンマセパレーターが行頭にある場合に、SMIEをより賢明に振る舞わせようとしている。これはセパレーターのインデントを解除(outdent)、カンマの後のコードにアラインされるよう試みる。たとえば:
x = longfunctionname (
arg1
, arg2
);
":="の後のインデントのルールは、そうしなければSMIEが":="を2項演算子として扱い、左の引数に併せて右の引数をアラインするであろうから、このルールが存在する。
"begin"の前のインデントのルールは、バーチャルインデントの使用例である。このルールは"begin"がhangingのときだけ使用され、これは"begin"が行頭にないときのみ発生し得る。そのため、これは"begin"自体のインデントには使用されないが、この"begin"に関連する何かをインデントするときだけ使用される。このルールは、具体的には以下のフォームを:
if x > 0 then begin
dosomething(x);
end
以下に変更する
if x > 0 then begin
dosomething(x);
end
"if"の前のインデントのルールは"begin"のインデントルールと似ているが、ここでの目的は"else
if"を1単位として扱うことにあり、それにより各テストより右にインデントされずに、一連のテストにアラインされる。この関数はsmie-rule-bolpをテストして、"if"が別の行にないときだけこれを行う。
"else"が、それの属する"if"にたいして常にアラインされ、かつそれが常に行頭であるることが判っている場合は、より効果的なルールを使用できる:
((equal token "if")
(and (not (smie-rule-bolp))
(smie-rule-prev-p "else")
(save-excursion
(sample-smie-backward-token)
(cons 'column (current-column)))))
この式の利点は、これがシーケンスの最初の"if"まで戻ってすべてをやり直すのではなく、前の"else"のインデントを再利用することである。