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"
のインデントを再利用することである。