Função para excluir todos os comentários de um buffer, sem movê-los para eliminar o anel

9

Eu preciso ser capaz de remover todos os comentários de um buffer do código elisp. Por enquanto, estou usando:

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

No entanto, comment-killé uma função interativa e seu uso principal é excluir um comentário de cada vez. Além disso, tem efeitos colaterais visíveis irritantes, uma vez que adiciona todos os comentários que matou ao ringue.

Existe uma função que permita excluir (não matar) alguns ou todos os comentários de um buffer?

T. Verron
fonte
Você poderia fazer M-x flush-lines ^\s-*\/\/ou algo nesse sentido. Não é perfeito, mas pode funcionar algumas vezes.
wvxvw
@wvxvw Obrigado pela sugestão! No entanto, eu pensei brevemente em ir por esse caminho e concluí que seria muito complicado: as linhas de descarga não funcionam, porque os comentários podem não ocupar toda a linha (substituir-regexp seria bom, eu acho); mais irritantemente, existem várias sintaxes para comentários e elas podem ser aninhadas, tornando-a (provavelmente) fora do alcance dos regexps.
T. Verron
Por curiosidade, você deseja que os comentários sejam removidos permanentemente ou apenas para removê-los temporariamente? Você talvez só queira escondê-los?
Tirou

Respostas:

11

Em geral, não há nada de errado em usar comandos como parte do código elisp. As funções destinadas apenas ao uso interativo o alertarão (ou deveriam) sobre isso. Veja next-linepor exemplo.

Para excluir, em vez de matar, verifique se kill-ringnão mudou:

(goto-char (point-min))
(let (kill-ring)
  (comment-kill (count-lines (point-min) (point-max))))
Malabarba
fonte
Sim, entendi. Meu principal problema com este comando é o kill-ring (que você responde) e os possíveis problemas de otimização (que permanecerão em potencial se não houver nada para comparar).
T. Verron
7

A resposta de @ Malabarba parece a solução mais simples e elegante. No entanto, se você fizer isso o suficiente para garantir sua própria função, também poderá se adaptar comment-killà exclusão sem modificar o anel de morte. Aqui está o código fonte da comment-killalteração de linha única para definir 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))))

E aqui está uma função (NB: minimamente testada) que fornece algumas funcionalidades adicionais, permitindo excluir comentários na linha atual, na região ativa ou em todo o buffer:

(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)))))

Não verifiquei problemas de desempenho, mas talvez haja um pequeno inchaço por não tocar no anel de morte. Independentemente disso, duvido que você notará problemas de desempenho, a menos que esteja trabalhando com um buffer realmente grande. Mas como é improvável que você use essa função com muita frequência, parece que não valeria a pena o esforço de trabalhar na otimização.

Dan
fonte
Ah, a função é executada com bastante frequência e, às vezes, em buffers grandes. Mas o maquinário do qual ele faz parte tem alguns gargalos piores, pelo menos por enquanto.
16114 T. Verron