2

This question is about changing the behavior of comment-dwim when no active region is defined. The current behavior is defined below (from C-h k), which is kind of complicated and not what doing what I mean:

comment-dwim is an interactive compiled Lisp function.

It is bound to M-;.

(comment-dwim ARG)

Call the comment command you want (Do What I Mean). If the region is active and ‘transient-mark-mode’ is on, call ‘comment-region’ (unless it only consists of comments, in which case it calls ‘uncomment-region’).

Else, if the current line is empty, call ‘comment-insert-comment-function’ if it is defined, otherwise insert a comment and indent it. ...

What I find useful is to just comment out the current line (i.e. use the current line as the region) if no active region is defined. This is similar to other IDEs such as Eclipse and VS code. The current behavior in some modes break a line where the point is, and inserts a new comment line, which is not really what I need. Probably it has its use cases, but I would find it more natural just to comment out the whole line if there is no defined region.

I know very little elisp, and especially don't know how to change the behavior of an existing function such as comment-dwim (maybe by using a hook function somehow?).

Could someone help explain how to modify the behavior of comment-dwim so that the current line is used as the region when no region is defined?

This is with Emacs 28, and the specific function is paredit-comment-dwim, which I guess is a derived function of comment-dwim.

1 Answer 1

2

Instead of fiddling with comment-dwim (someone else can do that for you, if you really want the rest of the comment-dwim behavior), I tweaked my function comment-region-lines, so it uses the current line if the region isn't active.

This should do what you want. Note that for a single line, with no active region, repeating the command alternates between commenting and uncommenting, as you requested. However, when the region is active, repeating the command comments further -- nested block comment. To uncomment when the region is active, use a prefix arg. The doc string refers to the doc of comment-region -- see that.

(defun my-comment-region-lines (&optional beg end arg)
  "Like `comment-region' (which see), but comment or uncomment whole lines.
If the region isn't active, or there is no mark in the buffer, then
just comment the current line, or uncomment it if it is commented."
  (interactive (progn (barf-if-buffer-read-only)
                      (list (and (mark)  (region-beginning))
                            (and (mark)  (region-end))
                            current-prefix-arg)))
  (if (not (and beg  end  mark-active))
      (comment-or-uncomment-region (line-beginning-position) (line-beginning-position 2) arg)
    (when (> beg end) (setq beg  (prog1 end (setq end  beg))))
    (let ((bol  (save-excursion (goto-char beg) (line-beginning-position)))
          (eol  (save-excursion (goto-char end) (if (bolp) (point) (line-end-position)))))
      (comment-region bol eol arg))))

FYI - comment-region-lines is defined in library misc-cmds.el.

I bind comment-region-lines to C-x C-;, and I leave comment-dwim bound to M-;. I use comment-dwim only for an end-of-line comment, never for uncommenting a block of lines. comment-region is better than comment-dwim, IMO, as it gives you more control - e.g. nesting/unnesting comment blocks.


Wrt your comment that in a buffer where the mark has not been set an error is raised: This is because of the Emacs implementation of (interactive "r"). It always returns the region bounds, whether or not the region is active (selected/highlighted). But if the mark has not been set then it raises an error.

3
  • Thanks! The function works but there seems to be a small issue: if used after a fresh emacs start, it gives an error: ` The mark is not set now, so there is no region`. Seems related to: emacs.stackexchange.com/questions/47657, but I am not sure.
    – tinlyx
    Commented Nov 23, 2022 at 23:03
  • Also, another issue is that applying the function on a commented line does not seem to uncomment it.
    – tinlyx
    Commented Nov 23, 2022 at 23:14
  • Updated the code to do what you wanted wrt uncommenting when the region isn't active.
    – Drew
    Commented Nov 25, 2022 at 17:36

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.