Функция для удаления всех комментариев из буфера, не перемещая их, чтобы убить кольцо

9

Мне нужно иметь возможность удалить все комментарии из буфера из кода elisp. На данный момент я использую:

(goto-char (point-min))
(comment-kill (count-lines (point-min) (point-max)))

Однако comment-killэто интерактивная функция, и ее основным назначением является удаление одного комментария за раз. Кроме того, он имеет раздражающие видимые побочные эффекты, поскольку добавляет все убитые комментарии в список уничтожений.

Есть ли функция, позволяющая удалять (не убивать) некоторые или все комментарии из буфера?

Т. Веррон
источник
Вы могли бы сделать M-x flush-lines ^\s-*\/\/или что-то на этот счет. Не идеально, но может работать несколько раз.
wvxvw
@wvxvw Спасибо за предложение! Тем не менее, я вкратце подумал о том, чтобы пойти по этому пути, и пришел к выводу, что это будет слишком сложно: flush-lines не сработает, потому что комментарии могут занимать не всю строку (думаю, будет заменить replace-regexp); более досадно, что есть несколько синтаксисов для комментариев, и они могут быть вложенными, что делает его (вероятно) недоступным для регулярных выражений.
Т. Веррон
Из любопытства, вы хотите, чтобы комментарии были удалены навсегда или вы просто хотите временно убрать их? Вы, возможно, просто хотите скрыть их?
Дрю

Ответы:

11

В общем, нет ничего плохого в использовании команд как части кода elisp. Те функции, которые предназначены только для интерактивного использования, будут (или должны) предупреждать вас об этом. Смотри next-lineнапример.

Чтобы удалить, а не убивать, просто убедитесь, что kill-ringэто не изменилось:

(goto-char (point-min))
(let (kill-ring)
  (comment-kill (count-lines (point-min) (point-max))))
Malabarba
источник
Да, я понял. Моя главная проблема с этой командой - kill-ring (который вы отвечаете) и потенциальные проблемы оптимизации (которые останутся потенциальными, если не с чем будет сравнивать).
Т. Веррон
7

Ответ @ Малабарбы выглядит как самое простое и элегантное решение. Однако, если вы сделаете это достаточно для того, чтобы это оправдывало его собственную функцию, вы также можете адаптироваться comment-killк удалению без изменения списка уничтожений. Вот исходный код comment-killс однострочным изменением для определения comment-delete:

(defun comment-delete (arg)
  "Delete the first comment on this line, if any.  Don't touch
the kill ring.  With prefix ARG, delete comments on that many
lines starting with this one."
  (interactive "P")
  (comment-normalize-vars)
  (dotimes (_i (prefix-numeric-value arg))
    (save-excursion
      (beginning-of-line)
      (let ((cs (comment-search-forward (line-end-position) t)))
    (when cs
      (goto-char cs)
      (skip-syntax-backward " ")
      (setq cs (point))
      (comment-forward)
      ;; (kill-region cs (if (bolp) (1- (point)) (point))) ; original
      (delete-region cs (if (bolp) (1- (point)) (point)))  ; replace kill-region with delete-region
      (indent-according-to-mode))))
    (if arg (forward-line 1))))

А вот функция (примечание: минимально проверено), которая предоставляет некоторые дополнительные функции, позволяющие удалять комментарии в текущей строке, в активной области или во всем буфере:

(defun comment-delete-dwim (beg end arg)
  "Delete comments without touching the kill ring.  With active
region, delete comments in region.  With prefix, delete comments
in whole buffer.  With neither, delete comments on current line."
  (interactive "r\nP")
  (let ((lines (cond (arg
                      (count-lines (point-min) (point-max)))
                     ((region-active-p)
                      (count-lines beg end)))))
    (save-excursion
      (when lines
        (goto-char (if arg (point-min) beg)))
      (comment-delete (or lines 1)))))

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

Дэн
источник
О, функция будет работать довольно часто, а иногда и на больших буферов. Но машина, частью которой он является, имеет некоторые более узкие места, по крайней мере, на данный момент.
Т. Веррон