Fonction pour supprimer tous les commentaires d'un tampon, sans les déplacer pour tuer l'anneau

9

J'ai besoin de pouvoir supprimer tous les commentaires d'un tampon du code elisp. Pour l'instant, j'utilise:

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

Cependant, comment-killest une fonction interactive, et son utilisation principale est de supprimer un commentaire à la fois. De plus, il a des effets secondaires visibles ennuyeux, car il ajoute tous les commentaires qu'il a tués à l'anneau de mise à mort.

Existe-t-il une fonction permettant de supprimer (pas de tuer) certains ou tous les commentaires d'un tampon?

T. Verron
la source
Vous pourriez faire M-x flush-lines ^\s-*\/\/ou quelque chose à cet effet. Pas parfait, mais pourrait fonctionner quelques fois.
wvxvw
@wvxvw Merci pour la suggestion! Cependant, j'avais brièvement envisagé de suivre cette voie, et conclu que ce serait trop compliqué: les lignes de vidage ne suffiront pas, car les commentaires peuvent ne pas prendre toute la ligne (replace-regexp serait OK je suppose); plus ennuyeux, il existe plusieurs syntaxes pour les commentaires, et elles peuvent être imbriquées, ce qui les rend (probablement) hors de portée des expressions régulières.
T. Verron
Par curiosité, souhaitez-vous que les commentaires soient supprimés définitivement ou souhaitez-vous simplement les supprimer temporairement? Voulez-vous simplement les cacher?
Drew

Réponses:

11

En général, il n'y a rien de mal à utiliser des commandes dans le cadre du code elisp. Les fonctions qui sont uniquement destinées à une utilisation interactive vous (ou devraient) vous en avertir. Voir next-linepar exemple.

Afin de supprimer, au lieu de tuer, assurez-vous simplement que le kill-ringn'est pas modifié:

(goto-char (point-min))
(let (kill-ring)
  (comment-kill (count-lines (point-min) (point-max))))
Malabarba
la source
Oui, je comprends. Mon principal problème avec cette commande est le kill-ring (auquel vous répondez) et les problèmes d'optimisation potentiels (qui resteront potentiels s'il n'y a rien à comparer).
T. Verron
7

@ La réponse de Malabarba ressemble à la solution la plus simple et la plus élégante. Cependant, si vous faites cela suffisamment pour qu'il justifie sa propre fonction, vous pouvez également vous adapter comment-killpour supprimer sans modifier le kill ring. Voici le code source de comment-killla modification sur une seule ligne à définir 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))))

Et voici une fonction (NB: testé de façon minimale) qui fournit des fonctionnalités supplémentaires, vous permettant de supprimer des commentaires sur la ligne actuelle, dans la région active ou dans le tampon entier:

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

Je n'ai pas vérifié les problèmes de performances, mais il y a peut-être une petite bosse de ne pas toucher l'anneau de destruction. Quoi qu'il en soit, je doute que vous remarquerez des problèmes de performances, sauf si vous travaillez avec un tampon vraiment massif. Mais comme il est peu probable que vous utilisiez cette fonction très fréquemment, il semble que cela ne vaut pas la peine de travailler sur l'optimisation.

Dan
la source
Oh, la fonction est exécutée assez souvent, et parfois sur de grands tampons. Mais le mécanisme dont il fait partie présente des goulots d'étranglement plus graves, du moins pour l'instant.
T. Verron