feat(format): add +format/org-block-in-region

Also updates `+org/reformat-at-point` to call
`+format/org-block-in-region` if selection is active.

Fix: #7936
This commit is contained in:
Henrik Lissner 2024-07-14 01:48:11 -04:00
parent 378d0b8db6
commit 7543b04e15
No known key found for this signature in database
GPG key ID: B60957CA074D39A3
4 changed files with 91 additions and 27 deletions

View file

@ -83,29 +83,4 @@ may not always work. Keep your undo keybind handy!"
#'+format/region
#'+format/buffer)))
;;;###autoload
(defun +format/org-block (&optional point)
"Reformat the org src block at POINT with a mode approriate formatter."
(interactive (list (point)))
(unless (derived-mode-p 'org-mode)
(user-error "Not an org-mode buffer!"))
(let ((element (org-element-at-point point)))
(unless (org-in-src-block-p nil element)
(user-error "Not in an org src block"))
(cl-destructuring-bind (beg end _) (org-src--contents-area element)
(let* ((lang (org-element-property :language element))
(mode (org-src-get-lang-mode lang)))
(save-excursion
(if (provided-mode-derived-p mode 'org-mode)
(user-error "Cannot reformat an org-mode or org-derived src block")
(let* ((major-mode mode)
(after-change-functions
;; HACK: Silence excessive and unhelpful warnings about
;; 'org-element-at-point being used in non-org-mode
;; buffers'.
(remq 'org-indent-refresh-maybe after-change-functions))
(apheleia-formatter
(or (apheleia--get-formatters 'interactive)
(apheleia--get-formatters 'prompt)
(user-error "No formatter configured for language: %s" lang))))
(+format-region beg end))))))))
;;; format.el ends here

View file

@ -0,0 +1,64 @@
;;; editor/format/autoload/org.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +format/org-block (&optional point)
"Reformat the org src block at POINT with a mode appropriate formatter."
(interactive (list (point)))
(unless (derived-mode-p 'org-mode)
(user-error "Not an org-mode buffer!"))
(let ((element (org-element-at-point point)))
(unless (org-in-src-block-p nil element)
(user-error "Not in an org src block"))
(cl-destructuring-bind (beg end _) (org-src--contents-area element)
(let* ((lang (or (org-element-property :language element)
(user-error "Cannot reformat src block without a valid language")))
(mode (org-src-get-lang-mode lang)))
(save-excursion
(if (provided-mode-derived-p mode 'org-mode)
(user-error "Cannot reformat an org-mode or org-derived src block")
(let* ((major-mode mode)
(after-change-functions
;; HACK: Silence excessive and unhelpful warnings about
;; 'org-element-at-point being used in non-org-mode
;; buffers'.
(remq 'org-indent-refresh-maybe after-change-functions))
(apheleia-formatter
(or (apheleia--get-formatters)
(user-error "No formatter configured for language: %s" lang))))
(+format-region beg end))))))))
;;;###autoload
(defun +format/org-block-in-region (beg end)
"Calls `+format/org-block' in each src block between BEG and END (inclusive)."
(interactive (doom-region t))
(unless (derived-mode-p 'org-mode)
(user-error "Not an org-mode buffer!"))
(unless (and beg end)
(user-error "No active selection"))
(let ((n 0))
(org-block-map
(lambda ()
(let ((element (org-element-at-point)))
(when (and (org-in-src-block-p nil element)
(org-element-property :language element))
(with-demoted-errors "+format/org-block: %s"
(call-interactively #'+format/org-block))
(cl-incf n))))
(save-excursion
(goto-char beg)
(when (org-in-src-block-p)
(org-previous-block 1))
(point))
end)
(message "Formatted %d src block(s)" n)))
;;;###autoload
(defun +format/org-block-at-point-or-in-region ()
"See `+format/org-block' and `+format/org-block-in-region'."
(interactive)
(call-interactively
(if (doom-region-active-p)
#'+format/org-block-in-region
#'+format/org-block)))
;;; org.ell ends here