Spec-Zone.ru › Elisp

Примеры правил отступов

Вот пример функции отступа:

(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 стараться быть более умным, когда разделитель запятых располагается в начале строк. Оно пытается сдвинуть разделитель влево, чтобы выровнять код после запятой; например:
    x = longfunctionname (
            arg1
          , arg2
        );
    
  • Правило для отступа после ":=" существует, потому что в противном случае SMIE воспринимал бы ":=" как инфиксный оператор и выравнивал бы правое операнд с левым.
  • Правило для отступа перед "begin" — пример использования виртуального отступа. Это правило используется только тогда, когда "begin" висит (что может произойти только в том случае, когда "begin" не находится в начале строки). Поэтому оно не используется при отступе самого "begin", а только при отступе чего-либо относительно этого "begin". Конкретно, это правило изменяет отступ с:
        if x > 0 then begin
                dosomething(x);
            end
    

    на

        if x > 0 then begin
            dosomething(x);
        end
    
  • Правило для отступа перед "if" аналогично правилу для "begin", но с целью рассматривать "else if" как единое целое, чтобы выровнять последовательность тестов, а не увеличивать отступ каждого теста вправо. Эта функция делает это только в том случае, если "if" не находится на отдельной строке, отсюда и проверка smie-rule-bolp.

    Если известно, что "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)))))
    

    Преимущества такой формулировки в том, что она повторно использует отступ предыдущего "else", а не возвращается к первому "if" последовательности.

Copyright © 1990-1996, 1998-2022 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/SMIE-Indentation-Example.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API