Замените символ перед расширением yasnippet

#emacs #code-snippets

#emacs #фрагменты кода

Вопрос:

Возможно ли заменить символ перед расширением yasnippet?

Допустим, у меня есть следующий фрагмент:

 # -*- mode: snippet -*-
# name: foo
# key: foo
# --
~bar$0
  

Я пишу foo и нажимаю Tab, чтобы развернуть его, и я получаю ~bar или явно показано, где первая строка находится перед расширением, а вторая после расширения:

 foo[Tab]
~bar
  

Теперь представьте, что я хочу, чтобы фрагмент удалял все возможные пробелы непосредственно перед курсором (то есть 1-n пробелов, непосредственно предшествующих пробелам) перед расширением фрагмента.

Скажем, что у меня есть следующий текст

 word word
  

и что я размещаю курсор как таковой

 word [cursor]word
  

и введите ключ фрагмента

 word foo[cursor]word
  

теперь я разворачиваю фрагмент, нажимая Tab, и я хочу, чтобы произошло следующее

 word~bar[cursor]word
  

Обратите внимание, что пробел перед фрагментом удален, так что фрагмент вставляется непосредственно после первого слова. Как я могу это сделать? Этого не происходит с указанным выше фрагментом. Что происходит, так это

 word ~bar[cursor]word
  

Ответ №1:

Похоже, вы можете встроить некоторый код lisp в свои шаблоны, используя `. Итак, я думаю, вы могли бы сделать что-то вроде:

 `(if (string= " " (string (preceding-char))) (backward-delete-char))`
  

Комментарии:

1. Я пытался ${1:`(if (string= " " (string (preceding-char))) (backward-delete-char))`}~bar$0 , но он ведет себя не так, как я хочу. Он не удаляет предшествующие пробелы, он только помещает курсор перед первой буквой bar .

Ответ №2:

Это работает с последней версией yasnippet отсюда:

 # -*- mode: snippet -*-
# name: foo
# key: foo
# --
~bar${0:$$(save-excursion (goto-char (overlay-start (yas/snippet-control-overlay (first (yas/snippets-at-point)))))
                          (delete-char (- (skip-chars-backward " "))))}
  

Комментарии:

1. Боюсь, это не сработает. Он вставляет весь код, а не выполняет его. Я думаю, что код lisp должен быть написан внутри ` , но выполнение этого для вашего кода выдает ошибку elisp.

2. какую версию yasnippet вы используете? обновите, если вы не используете последнюю версию от VCS.

3. Кроме того, на странице проекта yasnippet есть очень хорошая документация. Хотя мне пришлось немного покопаться в исходном коде.

4. Я не вижу элегантного надежного способа сделать это без поддержки $ (…). Есть ли какая-то причина, по которой вы не можете выполнить обновление?

5. У меня нет причин не обновлять, за исключением того, что я предпочитаю использовать то, что находится в репозиториях Ubuntu. Так что, нет способа заставить это работать с моей версией yasnippet?

Ответ №3:

Это должно сработать:

 # -*- mode: snippet -*-
# name: foo
# key: foo
# --
`(delete-backward-char 1)`~bar$0
  

но обычно выдает предупреждение о том, что фрагмент изменил буфер, чего можно избежать, включив

 (add-to-list 'warning-suppress-types '(yasnippet backquote-change))
  

в вашем config.el .