From 7543b04e15661f0c9cc58dcdff68efce1a434b73 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 14 Jul 2024 01:48:11 -0400 Subject: [PATCH] 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 --- lisp/lib/text.el | 13 +++++ modules/editor/format/autoload/format.el | 27 +--------- modules/editor/format/autoload/org.el | 64 ++++++++++++++++++++++++ modules/lang/org/autoload/org.el | 14 +++++- 4 files changed, 91 insertions(+), 27 deletions(-) create mode 100644 modules/editor/format/autoload/org.el diff --git a/lisp/lib/text.el b/lisp/lib/text.el index dc00d2e45..e44e127c4 100644 --- a/lisp/lib/text.el +++ b/lisp/lib/text.el @@ -135,6 +135,19 @@ Uses `evil-visual-end' if available." (marker-position evil-visual-end)) (region-end))) +;;;###autoload +(defun doom-region (&optional as-list) + "Return the bounds of the current seelction. + +If AS-LIST is non-nil, returns (BEG END). Otherwise returns a cons cell (BEG . +END)." + (let* ((active (doom-region-active-p)) + (beg (if active (doom-region-beginning))) + (end (if active (doom-region-end)))) + (if as-list + (list beg end) + (cons beg end)))) + ;;;###autoload (defun doom-thing-at-point-or-region (&optional thing prompt) "Grab the current selection, THING at point, or xref identifier at point. diff --git a/modules/editor/format/autoload/format.el b/modules/editor/format/autoload/format.el index fe2492d2e..42642a3c3 100644 --- a/modules/editor/format/autoload/format.el +++ b/modules/editor/format/autoload/format.el @@ -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 diff --git a/modules/editor/format/autoload/org.el b/modules/editor/format/autoload/org.el new file mode 100644 index 000000000..11b7043a3 --- /dev/null +++ b/modules/editor/format/autoload/org.el @@ -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 diff --git a/modules/lang/org/autoload/org.el b/modules/lang/org/autoload/org.el index 499b1dddb..d6e80959d 100644 --- a/modules/lang/org/autoload/org.el +++ b/modules/lang/org/autoload/org.el @@ -344,7 +344,19 @@ If in an org table, realign the cells with `org-table-align'. Otherwise, falls back to `org-fill-paragraph' to reflow paragraphs." (interactive) (let ((element (org-element-at-point))) - (cond ((org-in-src-block-p nil element) + (cond ((doom-region-active-p) + ;; TODO Perform additional formatting? + ;; (save-restriction + ;; (narrow-to-region beg end) + ;; (org-table-recalculate t) + ;; (org-table-map-tables #'org-table-align) + ;; (org-align-tags t) + ;; (org-update-statistics-cookies t) + ;; ...) + (if (modulep! :editor format) + (call-interactively #'+format/org-block-in-region) + (message ":editor format is disabled, skipping reformatting of org-blocks"))) + ((org-in-src-block-p nil element) (unless (modulep! :editor format) (user-error ":editor format module is disabled, ignoring reformat...")) (call-interactively #'+format/org-block))