Как вы комментируете все или часть Lisp s-exp с помощью Paredit?

При редактировании кода Lisp иногда полезно полностью прокомментировать определение верхнего уровня, например:

;(defun some-fn-which-is-broken (x)
;  ...)

... или закомментируйте только часть s-выражения, например:

(foo x
;    y
     z)

... а затем перекомпилируйте файл и проверьте что-то в REPL и т.д.

При включенном режиме paredit это не работает. Здесь, что происходит, если точка находится прямо перед первым парнем ниже:

(defun some-fn (x)
  ...)

и вы вводите точку с запятой, вводится точка с запятой и новая строка:

;
(defun some-fn (x)
  ...)

То же самое с комментариями части s-выражения:

(foo x
;    
     y
     z)

Я думаю, что если определение все в одной строке, это работает:

;(defparameter *foo* 10)

... но в противном случае я не могу узнать, как это сделать. Paredit отлично, я бы очень хотел продолжать использовать его. Есть ли какие-нибудь Lispерсы, которые знают об этом, или волшебники Emacs, которые могут взломать немного Emacs Lisp, чтобы связать что-то вроде paredit-comment-out-s-expr?

Если есть еще один способ Lispy или Emacsy выполнить практически одно и то же, комментируя части источника для перекомпиляции, пожалуйста, не стесняйтесь предлагать их!

Ответы

Ответ 1

Поместите точку на первом символе всего sexp, отметьте весь sexp с помощью C-M-space и введите M-;, чтобы сделать комментирование. Если это необходимо сделать, ваш исходный код также будет переформатирован так, что только комментарий sexp, который вы отметили, и ничего, что было также на той же строке, находится в комментарии.

Вы можете легко сделать простую команду или даже макрос для этого:

(defun comment-sexp ()
  "Comment out the sexp at point."
  (interactive)
  (save-excursion
    (mark-sexp)
    (paredit-comment-dwim)))

Ответ 2

Просто примечание:

Макросы чтения #+ и #- довольно приятны для комментирования sexps. Они позволяют игнорировать следующий sexp, если данный символ не находится/находится в *FEATURES*. Просто выберите символ не в *FEATURES* и используйте его с #+ следующим образом:

#+nil
(defun foo ()
  ...)

Теперь определение функции будет проигнорировано (если NIL не находится в *FEATURES*, что маловероятно).

Ответ 3

Как мера остановки, вы можете использовать C-q (quoted-insert) для вставки произвольного символа без запуска любой магии, связанной с режимом. Например, в java-режиме печатные круглые скобки задерживают текущую строку, что не всегда то, что я хочу; в таких случаях я вставляю скобки с C-q, чтобы сохранить мой отступ. (Или чаще я набираю скобки, наблюдаю за изменением отступа, проклинаю, отменю и снова вводим с помощью C-q.)

Для комментирования в общем случае было бы проще использовать M-; (comment-dwim), а не вручную вводить точки с запятой.

Ответ 4

Вы можете использовать C-M-SPC M-; для обозначения S-выражения (C-M-SPC для mark-sexp), а затем прокомментировать его (M-; для comment-dwim).

В paredit 23 просто набрав ; не будет толкать что-либо, что ему не нужно отключать. Так что это будет правильно для вашего второго примера. И если вы хотите прокомментировать z вместо y, он будет только ограничивать замыкание на другую строку.