Function: org-comment-or-uncomment-region
org-comment-or-uncomment-region is a byte-compiled function defined in
org.el.gz.
Signature
(org-comment-or-uncomment-region BEG END &rest _)
Documentation
Comment or uncomment each non-blank line in the region.
Uncomment each non-blank line between BEG and END if it only contains commented lines. Otherwise, comment them. If region is strictly within a source block, use appropriate comment syntax.
Source Code
;; Defined in /usr/src/emacs/lisp/org/org.el.gz
(defvar comment-empty-lines) ; From newcomment.el.
(defun org-comment-or-uncomment-region (beg end &rest _)
"Comment or uncomment each non-blank line in the region.
Uncomment each non-blank line between BEG and END if it only
contains commented lines. Otherwise, comment them. If region is
strictly within a source block, use appropriate comment syntax."
(if (let ((element (org-element-at-point)))
(and (eq (org-element-type element) 'src-block)
(< (save-excursion
(goto-char (org-element-property :post-affiliated element))
(line-end-position))
beg)
(>= (save-excursion
(goto-char (org-element-property :end element))
(skip-chars-backward " \r\t\n")
(line-beginning-position))
end)))
;; Translate region boundaries for the Org buffer to the source
;; buffer.
(let ((offset (- end beg)))
(save-excursion
(goto-char beg)
(org-babel-do-in-edit-buffer
(comment-or-uncomment-region (point) (+ offset (point))))))
(save-restriction
;; Restrict region
(narrow-to-region (save-excursion (goto-char beg)
(skip-chars-forward " \r\t\n" end)
(line-beginning-position))
(save-excursion (goto-char end)
(skip-chars-backward " \r\t\n" beg)
(line-end-position)))
(let ((uncommentp
;; UNCOMMENTP is non-nil when every non blank line between
;; BEG and END is a comment.
(save-excursion
(goto-char (point-min))
(while (and (not (eobp))
(let ((element (org-element-at-point)))
(and (eq (org-element-type element) 'comment)
(goto-char (min (point-max)
(org-element-property
:end element)))))))
(eobp))))
(if uncommentp
;; Only blank lines and comments in region: uncomment it.
(save-excursion
(goto-char (point-min))
(while (not (eobp))
(when (looking-at "[ \t]*\\(#\\(?: \\|$\\)\\)")
(replace-match "" nil nil nil 1))
(forward-line)))
;; Comment each line in region.
(let ((min-indent (point-max)))
;; First find the minimum indentation across all lines.
(save-excursion
(goto-char (point-min))
(while (and (not (eobp)) (not (zerop min-indent)))
(unless (looking-at "[ \t]*$")
(setq min-indent (min min-indent (org-current-text-indentation))))
(forward-line)))
;; Then loop over all lines.
(save-excursion
(goto-char (point-min))
(while (not (eobp))
(unless (and (not comment-empty-lines) (looking-at "[ \t]*$"))
;; Don't get fooled by invisible text (e.g. link path)
;; when moving to column MIN-INDENT.
(let ((buffer-invisibility-spec nil))
(org-move-to-column min-indent t))
(insert comment-start))
(forward-line)))))))))