Endless Parentheses

Ramblings on productivity and technical subjects.

profile for Malabarba on Stack Exchange

Implementing comment-line

Why we don't have a comment/uncomment-line function is beyond me. While we fix that, might as well make it as complete as possible.

(defun endless/comment-line (n)
  "Comment or uncomment current line and leave point after it.
With positive prefix, apply to N lines including current one.
With negative prefix, apply to -N lines above."
  (interactive "p")
  (let ((range (list (line-beginning-position)
                     (goto-char (line-end-position n)))))
    (comment-or-uncomment-region
     (apply #'min range)
     (apply #'max range)))
  (forward-line 1)
  (back-to-indentation))

Short and sweet, isn't it? In analogy to M-;. I find C-; to be a great binding for it. This way I can quickly comment 3 lines by hitting C-3 C-;.

(global-set-key (kbd "C-;") #'endless/comment-line)

Also, because it moves forward after commenting, you can conveniently do things like comment every other line by repeatedly doing C-; C-n.

Update <2015-02-01 Sun>

The previous version didn't quite work for negative prefix arguments, so I've updated the above snippet to fix that.

Also, quite a few people requested (or proposed) a version which acts on region if active. I already use M-; for that (and I also its other modes of operation), but I can see why people would want that so I've added it below. It's similar to the one suggested by Kaushal Modi.

(defun endless/comment-line-or-region (n)
  "Comment or uncomment current line and leave point after it.
With positive prefix, apply to N lines including current one.
With negative prefix, apply to -N lines above.
If region is active, apply to active region instead."
  (interactive "p")
  (if (use-region-p)
      (comment-or-uncomment-region
       (region-beginning) (region-end))
    (let ((range
           (list (line-beginning-position)
                 (goto-char (line-end-position n)))))
      (comment-or-uncomment-region
       (apply #'min range)
       (apply #'max range)))
    (forward-line 1)
    (back-to-indentation)))
comments powered by Disqus