13

I need to be able to remove all comments from a buffer from elisp code. For now, I am using:

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

However, comment-kill is an interactive function, and its primary usage is to delete one comment at a time. Additionally, it has annoying visible side-effects, since it adds all the comments it killed to the kill-ring.

Is there a function allowing to delete (not kill) some or all comments from a buffer?

3
  • 1
    You could do M-x flush-lines ^\s-*\/\/ or something to that effect. Not perfect, but could work some times.
    – wvxvw
    Commented Dec 16, 2014 at 13:55
  • @wvxvw Thank you for the suggestion! However, I had briefly considered going this way, and concluded that it would be too complicated: flush-lines won't do, because comments may not take the entire line (replace-regexp would be OK I guess); more annoyingly, there are several syntax for comments, and they can be nested, making it (probably) out of the reach of regexps.
    – T. Verron
    Commented Dec 16, 2014 at 14:19
  • Out of curiosity, do you want the comments removed permanently or do you just want to get them out of the way temporarily? Do you perhaps just want to hide them?
    – Drew
    Commented Dec 16, 2014 at 16:46

2 Answers 2

12

In general, there's nothing wrong with using commands as part of elisp code. Those functions which are only meant for interactive use will (or should) warn you about that. See next-line for instance.

In order to delete, instead of killing, just make sure the kill-ring isn't changed:

(goto-char (point-min))
(let (kill-ring)
  (comment-kill (count-lines (point-min) (point-max))))
1
  • Yes, I get that. My main issue with this command is the kill-ring (which you answer), and potential optimization issues (which will remain potential if there is nothing to compare against).
    – T. Verron
    Commented Dec 16, 2014 at 14:14
7

@Malabarba's answer looks like the simplest and most elegant solution. However, if you do this enough that it warrants its own function, you can also adapt comment-kill to delete without modifying the kill ring. Here's the source code of comment-kill with the single-line change to define 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))))

And here's a function (NB: minimally tested) that provides some additional functionality, allowing you to delete comments on the current line, in the active region, or in the entire 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)))))

I haven't checked performance issues, but perhaps there's a tiny bump from not touching the kill ring. Regardless, I doubt you'll notice performance problems unless you're working with a truly massive buffer. But since you're unlikely to use this function very frequently, it seems like it would not be worth the effort to work on optimization.

1
  • Oh, the function is run pretty often, and sometimes on large buffers. But the machinery that it is part of has some worse bottlenecks, at least for now.
    – T. Verron
    Commented Dec 16, 2014 at 16:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.