diff options
Diffstat (limited to 'devdocs/elisp/smie-indentation-example.html')
| -rw-r--r-- | devdocs/elisp/smie-indentation-example.html | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/devdocs/elisp/smie-indentation-example.html b/devdocs/elisp/smie-indentation-example.html new file mode 100644 index 00000000..91dbad87 --- /dev/null +++ b/devdocs/elisp/smie-indentation-example.html @@ -0,0 +1,45 @@ + <h4 class="subsubsection">Sample Indentation Rules</h4> <p>Here is an example of an indentation function: </p> <div class="example"> <pre class="example">(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))))) +</pre> +</div> <p>A few things to note: </p> <ul> <li> The first case indicates the basic indentation increment to use. If <code>sample-indent-basic</code> is <code>nil</code>, then SMIE uses the global setting <code>smie-indent-basic</code>. The major mode could have set <code>smie-indent-basic</code> buffer-locally instead, but that is discouraged. </li> +<li> The rule for the token <code>","</code> make SMIE try to be more clever when the comma separator is placed at the beginning of lines. It tries to outdent the separator so as to align the code after the comma; for example: <div class="example"> <pre class="example">x = longfunctionname ( + arg1 + , arg2 + ); +</pre> +</div> </li> +<li> The rule for indentation after <code>":="</code> exists because otherwise SMIE would treat <code>":="</code> as an infix operator and would align the right argument with the left one. </li> +<li> The rule for indentation before <code>"begin"</code> is an example of the use of virtual indentation: This rule is used only when <code>"begin"</code> is hanging, which can happen only when <code>"begin"</code> is not at the beginning of a line. So this is not used when indenting <code>"begin"</code> itself but only when indenting something relative to this <code>"begin"</code>. Concretely, this rule changes the indentation from: <div class="example"> <pre class="example"> if x > 0 then begin + dosomething(x); + end +</pre> +</div> <p>to </p> +<div class="example"> <pre class="example"> if x > 0 then begin + dosomething(x); + end +</pre> +</div> </li> +<li> The rule for indentation before <code>"if"</code> is similar to the one for <code>"begin"</code>, but where the purpose is to treat <code>"else if"</code> as a single unit, so as to align a sequence of tests rather than indent each test further to the right. This function does this only in the case where the <code>"if"</code> is not placed on a separate line, hence the <code>smie-rule-bolp</code> test. <p>If we know that the <code>"else"</code> is always aligned with its <code>"if"</code> and is always at the beginning of a line, we can use a more efficient rule: </p> +<div class="example"> <pre class="example">((equal token "if") + (and (not (smie-rule-bolp)) + (smie-rule-prev-p "else") + (save-excursion + (sample-smie-backward-token) + (cons 'column (current-column))))) +</pre> +</div> <p>The advantage of this formulation is that it reuses the indentation of the previous <code>"else"</code>, rather than going all the way back to the first <code>"if"</code> of the sequence. </p> +</li> +</ul><div class="_attribution"> + <p class="_attribution-p"> + Copyright © 1990-1996, 1998-2022 Free Software Foundation, Inc. <br>Licensed under the GNU GPL license.<br> + <a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/SMIE-Indentation-Example.html" class="_attribution-link">https://www.gnu.org/software/emacs/manual/html_node/elisp/SMIE-Indentation-Example.html</a> + </p> +</div> |
