2010-12-30 1 views
6

Я ищу, чтобы написать шаблон yasnippet, который позволит мне добавить заголовок лицензии в буфер сценария в Emacs. Любопытное нравится this, но немного улучшилась:комментарии в блочном стиле с yasnippet

  1. Заголовок должен включать для каждого пользователя данные, такие как имя дата и адрес электронной почты владельца авторских прав, , который может быть получен с embedded elisp expansion из yasnippet.
  2. Заголовок должен быть прокомментирован с синтаксисом в зависимости от режима программирования, в котором находится файл. Уже есть a gist of a snippet that does all that. В основном это сводится к вложению (comment-region (point-min) (point)) в конец вашего фрагмента.
  3. Я хочу изменить комментарий в поле. См. Документацию emacs для переменной comment-style или, если вы хотите посмотреть, как выглядит комментарий в стиле коробки, просто позвоните M-x comment-box в активный регион: он вызывает comment-region с правильными параметрами.

Первый подход, чтобы сделать это настроить стиль, изменив конец предыдущего фрагмента кода на:

(let ((comment-style 'box)) 
      (comment-region (point-min) (point))) 

К сожалению, отступы портится, и моя коробка не прямоугольная. Если я начну с сниппета:

Copyright (c) ${1:`(nth 5 (decode-time))`} 
All rights reserved. 

Redistribution and use in source and binary forms, with or 
without modification, are permitted` 
     (let ((comment-style 'box)) 
      (comment-region (point-min) (point)))` 

Расширение этого фрагмента «разбивает окно» (я отладки этого фрагмента с OCaml синтаксису комментариев, не то, что это имеет значение):

(**************************************************************) 
(* Copyright (c) 2010         *) 
(* All rights reserved.          *) 
(*               *) 
(* Redistribution and use in source and binary forms, with or *) 
(* without modification, are permitted  *) 
(**************************************************************) 
  • Сначала я подумал, что вторая строка была отступом на основе размера встроенного кода с предварительным расширением, но в этом случае он должен сделать окончательный *) этой линии, если он скоро появится 25, а не 4.
  • Если это с отступом на основе нет текст присутствует в точке внедрения, окончательный *) должен также прибыть 4 места конец, не слишком скоро.
  • И, наконец, я не понимаю, что происходит с последней строкой, в которой есть нет встроенного расширения кода: Обычно у меня нет проблем с получением квадратного поля комментариев из абзаца с короткой последней строкой (либо с помощью comment-box, или функцию Elisp в 1-й комментарий-блока этого вопроса.

Я попытался сделать комментарий произойдет после расширения сниппета, чтобы избежать какой-либо побочный эффект, добавив его в yas/after-exit-snippet-hook, заменив последняя функция фрагмента выше:

(add-hook 'yas/after-exit-snippet-hook 
     (let ((comment-style 'box)) 
      (comment-region (point-min) (point))) nil t) 

Но это не помогло. Даже если бы это было так, это оставило бы меня с расширением, который комментировал бы все фрагменты, которые я хотел бы использовать в этом буфере, чего-то, чего я, конечно, не хочу.

Я хотел бы также добавить, что я попытался установить yas/indent-line в fixed, добавив

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

в начале моего сниппет, но это ничего не изменило. Любые идеи о том, как получить прямоугольник box?


Edit: Мы a very nice answer, along with a proposed fix, (! Престижность & спасибо, Сейджи), но остается вопрос о том, как адаптировать его к случаю, когда один хотел бы повторно использовать поле, скажем, как повторное использование $1 в :

Copyright (c) ${1:`(nth 5 (decode-time))`} 
All rights reserved. 

Redistribution and use in $1, in source and binary forms 
`(let ((comment-style 'box)) 
     (comment-region (point-min) (point-at-eol 0)))` 

В этом случае копия шаблона двигателя значение (переменная длина), полученная для поля $1, а именно 2011, к последней строке, при расширении шаблона (после вдавливания), давая комментарий по линии 2 чара слишком широкие. Трудно предсказать при написании шаблона, который должен быть удалить символов в этой строке. Возможно, повторное использование полей и правильное отступы слишком много для запроса одновременно. Кто-нибудь видит способ сделать это?

ответ

5

Изменение вашего фрагмента к этому исправлению последней строки.

Copyright (c) ${1:`(nth 5 (decode-time))`} 
All rights reserved. 

Redistribution and use in source and binary forms, with or 
without modification, are permitted 
`(let ((comment-style 'box))(comment-region (point-min) (point-at-eol 0)))` 

Обратите внимание, что существует разрыв строки между лицензией («... разрешены») и встроенные Emacs Lisp код.

Что касается второй строки, я сначала объясню, почему это происходит, а затем предложит (уродливое) исправление. Когда ваш фрагмент вставляется в файл, встроенные блоки lisp последовательно оцениваются от начала буфера до конца. Это означает, что (nth 5 (decode-time)) был заменен на 2011, когда оценивается следующий блок, (comment-region ...).

В результате comment-region видит вторую линию как

Copyright (c) ${1:2011} 

Так, comment-region ставит достаточно пробелы для этой строки. Затем механизм шаблонов преобразует ${1:2011} в 2011, и это преобразование сокращает строку на 5 символов. Это объясняет преждевременный внешний вид *) на 5 символов во второй строке.

Один из способов исправить эту ситуацию, это положить 5 пробельные назад после того, как comment-region оценивается --- Что-то вдоль линии:

Copyright (c) ${1:`(nth 5 (decode-time))`} @ 
All rights reserved. 

Redistribution and use in source and binary forms, with or 
without modification, are permitted. 
`(let ((comment-style 'box))(comment-region (point-min) (point-at-eol 0)))`` 
(replace-string "@" "  " nil (point-min) (point))`$0 
+0

Спасибо за предложение «point-at-eol», оно полностью исправило проблему Последняя линия. ** Отличное ** объяснение, спасибо. Ваше исправление работает, но больно обобщать многие поля в строке (где вам нужно вручную подсчитать шаблон для каждого шаблона) и невозможно распространить на * повторное использование * поля $ 1 в другом месте шаблона (где вы бы необходимо ** удалить ** столько пробелов, сколько было сделано при создании встроенного lisp). Я подожду немного, и если никто не придумает решение для этого, я «приму» ваш ответ. – huitseeker

+1

Я согласен, что мое решение для второй строки неоптимально. Было бы здорово, если бы «yas/after-exit-snipeet-hook» работал над текстом, который мы видим. Тем не менее, кажется, что крючок работает с базовым текстом (например, '$ {1: ...}'). Кстати, если вы установите крючок в '# expand-env', крючок влияет только на фрагмент, а не на другие фрагменты --- добавив' # expand-env: ((yas/after-exit-snippet-hook (list (let ((comment-style)) (comment-region (point-min) (point-max) nil))))) ' –

1

Это может быть полезен для вас:

# -*- mode: snippet -*- 
# name: param 
# key: param 
# -- 
m.parameter :${1:arg},${1:$(make-string (- 14 (string-width text)) ?\ 
         )}:${2:type}$> 

В нем используется зеркало с функцией для создания пропусков позиционирования. Итак, для вас, это может означать что-то вроде этого:

(* Copyright (c) ${1:2011}${1:$(make-string (- 72 (string-width text)) ?\)} *) 
(* ${2}${2:$(make-string (- 72 (string-width text)))}*) 

Другим вариантом может быть использование yas/after-exit-snippet-hook, но это, кажется устаревшим.(ах, и я хотел отфильтровать текст самостоятельно, область комментариев, которую вы уже пробовали, умнее. Попробуйте область отступа?)

+0

Это умно, но, к сожалению, как объяснено в ответе [Seiji] (http : //stackoverflow.com/questions/4563788/box-style-comments-with-yasnippet/4583535#4583535), механизм шаблонов заменяет поля * после * выполнением блоков, что означает, что пробел, вставленный '(make-string ...) 'в два раза меньше 5 символов (для' $ {1:} $ {1:} '). (спасибо за предложение крючка, но я уже упомянул о моих неудачных попытках в исходном вопросе) – huitseeker