editor/format: add org src-block support

Src blocks can now be reformatted. `+format/buffer` will reformat the
whole src block at point. `+format/region` will format only the
selection (even a subset of a src block).

Closes #3484
This commit is contained in:
Henrik Lissner 2020-08-06 15:14:35 -04:00
parent f0ad8cca25
commit 72da7a3f04
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395

View file

@ -201,10 +201,33 @@ See `+format/buffer' for the interactive version of this function, and
;; ;;
;;; Commands ;;; Commands
(defun +format--org-region (beg end)
"Reformat the region within BEG and END.
If nil, BEG and/or END will default to the boundaries of the src block at point."
(let ((element (org-element-at-point)))
(save-excursion
(let* ((block-beg (save-excursion
(goto-char (org-babel-where-is-src-block-head element))
(line-beginning-position 2)))
(block-end (save-excursion
(goto-char (org-element-property :end element))
(skip-chars-backward " \t\n")
(line-beginning-position)))
(beg (if beg (max beg block-beg) block-beg))
(end (if end (min end block-end) block-end))
(lang (org-element-property :language element))
(major-mode (org-src-get-lang-mode lang)))
(if (eq major-mode 'org-mode)
(user-error "Cannot reformat an org src block in org-mode")
(+format/region beg end))))))
;;;###autoload ;;;###autoload
(defun +format/buffer () (defun +format/buffer ()
"Reformat the current buffer using LSP or `format-all-buffer'." "Reformat the current buffer using LSP or `format-all-buffer'."
(interactive) (interactive)
(if (and (eq major-mode 'org-mode)
(org-in-src-block-p t))
(+format--org-region nil nil)
(call-interactively (call-interactively
(cond ((and +format-with-lsp (cond ((and +format-with-lsp
(bound-and-true-p lsp-mode) (bound-and-true-p lsp-mode)
@ -214,7 +237,7 @@ See `+format/buffer' for the interactive version of this function, and
(bound-and-true-p eglot--managed-mode) (bound-and-true-p eglot--managed-mode)
(eglot--server-capable :documentFormattingProvider)) (eglot--server-capable :documentFormattingProvider))
#'eglot-format-buffer) #'eglot-format-buffer)
(#'format-all-buffer)))) (#'format-all-buffer)))))
;;;###autoload ;;;###autoload
(defun +format/region (beg end) (defun +format/region (beg end)
@ -224,6 +247,9 @@ WARNING: this may not work everywhere. It will throw errors if the region
contains a syntax error in isolation. It is mostly useful for formatting contains a syntax error in isolation. It is mostly useful for formatting
snippets or single lines." snippets or single lines."
(interactive "rP") (interactive "rP")
(if (and (eq major-mode 'org-mode)
(org-in-src-block-p t))
(+format--org-region beg end)
(cond ((and +format-with-lsp (cond ((and +format-with-lsp
(bound-and-true-p lsp-mode) (bound-and-true-p lsp-mode)
(lsp-feature? "textDocument/rangeFormatting")) (lsp-feature? "textDocument/rangeFormatting"))
@ -235,7 +261,7 @@ snippets or single lines."
((save-restriction ((save-restriction
(narrow-to-region beg end) (narrow-to-region beg end)
(let ((+format-region-p t)) (let ((+format-region-p t))
(+format/buffer)))))) (+format/buffer)))))))
;;;###autoload ;;;###autoload
(defun +format/region-or-buffer () (defun +format/region-or-buffer ()