The usual behavior of comment-line is to move point to the next line. When commenting code within an Org source block, however, the point will jump to some previous line.

For example, say that point is at |:

#+begin_src emacs-lisp
  (defun hello ()
    "Say hi."
    (message "Hello, world!"))

When comment-line is called, the current line is commented, but point also moves to the indent of the previous line:

#+begin_src emacs-lisp
  (defun hello ()
    |"Say hi."
    ;; (interactive)
    (message "Hello, world!"))

Ideally, I would like point to not move at all (relative to the adjacent characters prior to (un)commenting) but would at least like comment-line to behave in a source block like it does outside of one.

I've tried a variety of suggested answers. They all move point similarly. It looks like comment-or-uncomment-region is the typical entry point. This function leads down quite a labyrinth. AFAIK, it ultimately hinges on the comment-region-function which is comment-region-default-1 by default. Stepping through, it's not clear to me which part moves point to a previous line.

  • 2
    FWIW, I can reproduce this. Maybe report it to the ML?
    – NickD
    Apr 7, 2021 at 13:00

2 Answers 2


The behavior that I see is even worse when doing C-x C-; in an org emacs-lisp source block:

After comment-line adds the ";;" characters at line start, the cursor jumps to the line after the defun declaration, which could be several lines above. Note that this does not happen when doing the same thing when editing elisp code in an emacs-lisp buffer.

The only work-around that I've come up with is: C-a C-@ C-e C-f M-;

Alternatively, create a macro and bind a key to it:

(fset 'comment-line-goto-next
   (kmacro-lambda-form [?\C-a ?\C-@ ?\C-e ?\C-f ?\M-\;] 0 "%d"))

Hope this helps.


It looks like this issue has been noticed and addressed by the org-comment-dwim-2 function within the comment-dwim-2 package.

(defun org-comment-dwim-2 (&optional arg)
  "Call `comment-dwim-2' inside source blocks. Else, fallback to `org-toggle-comment'."
  (interactive "*P")
  (if (org-in-src-block-p t)
      (org-babel-do-in-edit-buffer (call-interactively 'comment-dwim-2))
    (call-interactively 'org-toggle-comment)))

What it does is open the source block in an editing buffer (like with C-c '), does the comment stuff, and then backs out. It also will call org-toggle-comment when not in a source block. For me, that changes the section header to a comment.

To have the org-comment-dwim-2 fall back to comment-dwim-2 instead, you can do something like:

(global-set-key (kbd "C-;") (lambda () 
                              (if (org-in-src-block-p t)
                                (call-interactively 'org-comment-dwim-2)
                               (call-interactively 'comment-dwim-2))))

This will call org-comment-dwim-2 in org source blocks and call comment-dwim-2 otherwise.

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.