yasnippets с % заканчивающим строку после $0 ведет себя странно при использовании с AUCTeX

Фрагменты Yasnippet со знаком процента, %, заканчивающие строку последней точкой фрагмента, $0, перед знаком процента ведут себя странно, поскольку курсор помещается после знака процента, а не перед ним. Интересно, как я могу избежать этого странного поведения.

Рассмотрим следующий фрагмент:

# -*- mode: snippet -*-
# name: test snippet
# key: ts
# --
{
$0%
}

Я так понимаю, что при активации он должен вставить три строки, где первая содержит {, последняя строка } и вторая строка %, и поместить курсор перед % во второй строке, как в следующем примере:

{
[cursor]%
}

Но происходит следующее:

{
  % [cursor]
}

Как мне сделать так, чтобы сниппет вел себя так, как я думаю?

Я предполагаю, что это связано с чем-то в AUCTeX, потому что это происходит с активированным AUCTeX, но не в основном режиме Lisp Interaction.


person N.N.    schedule 09.11.2011    source источник


Ответы (1)


Это правильно работает с моей конфигурацией, но я подозреваю, что это связано с автоматическим отступом (мой сильно настроен, так что может быть разница). Вы все еще видите проблему, если добавите

# expand-env: ((yas/indent-line 'fixed))

or

# expand-env: ((yas/indent-line t))

в заголовок фрагмента? Вы также можете попробовать добавить $> к строке (строкам), для которых вы хотите сделать отступ, чтобы увидеть, имеет ли это значение (если это так, это сильно сузит круг). В коде yasnippet есть примечание о некоторых проблемах со сменой маркеров местами, но похоже, что это было исправлено несколько лет назад.

Вы также должны проверить, что indent-line-function имеет правильное значение, а именно LaTeX-indent-line.

Вы можете добавить несколько sit-for к определению yas/indent-according-to-mode, чтобы увидеть, где точка находится на разных этапах. Например, поместите следующее в временной буфер, поместите курсор после его конца и введите C-x C-e. Затем вставьте свой фрагмент, как обычно, и он будет останавливаться на 1 секунду каждый раз, когда в коде вы видите (sit-for 1). Поэтому, если курсор начинается не в том месте, то вы знаете, что проблема связана с отступом и т. д. Вам придется следить за каждой строкой с отступом, поэтому вы можете отключить отступ, за исключением проблемной строки через $> . Добавление или удаление sit-for позволит вам сузить круг поиска.

(defun yas/indent-according-to-mode (snippet-markers)
  "Indent current line according to mode, preserving
SNIPPET-MARKERS."
  (sit-for 1)
  (goto-char (yas/real-line-beginning))
  (sit-for 1)
  (let ((trouble-markers (remove-if-not #'(lambda (marker)
                                            (= marker (point)))
                                        snippet-markers)))
    (save-restriction
      (widen)
      (sit-for 1)
      (condition-case err
          (indent-according-to-mode)
        (error (message "[yas] warning: yas/indent-according-to-mode habing problems running %s" indent-line-function)
               nil)))
    (sit-for 1)
    (mapc #'(lambda (marker)
              (set-marker marker (point)))
          trouble-markers)))
person Ivan Andrus    schedule 14.11.2011
comment
Оба работают. Однако второй не будет правильно обнаруживать и делать отступы при использовании в каком-то отступе. Первый из них будет правильно вставлять отступы, но не правильно отступит курсор. - person N.N.; 15.11.2011
comment
Ну, это, кажется, указывает на то, что это связано с отступами. Значение indent-line-function для меня равно LaTeX-indent-line. Я обновил ответ некоторыми дополнительными способами отладки. - person Ivan Andrus; 16.11.2011
comment
Использование $>$0% во второй последней строке фрагмента вместе с ((yas/indent-line 'fixed)) приводит к отступу, но курсор, кажется, дает тот же результат, что и при использовании ни $>, ни ((yas/indent-line 'fixed)). Мой indent-line-function установлен на LaTeX-indent-line. - person N.N.; 16.11.2011