2024-07-06 21:03:12 -04:00
|
|
|
;;; editor/format/autoload/lsp.el -*- lexical-binding: t; -*-
|
|
|
|
;;;###if (modulep! :tools lsp)
|
|
|
|
|
2024-07-07 20:44:33 -04:00
|
|
|
(defvar +format-lsp--last nil)
|
2024-07-06 21:03:12 -04:00
|
|
|
;;;###autoload
|
2024-07-07 20:44:33 -04:00
|
|
|
(define-minor-mode +format-with-lsp-mode
|
|
|
|
"Toggles `lsp-mode'/`eglot' integration with `apheleia-mode' in this buffer.
|
2024-07-06 21:03:12 -04:00
|
|
|
|
2024-07-07 20:44:33 -04:00
|
|
|
When enabled, it changes `+format-with' to `lsp', and back to its old value when
|
|
|
|
disabled. Use `+format-wtih-lsp-maybe-h' to activate it, to ensure it only
|
|
|
|
activates if lsp-mode/eglot are on and connected to a valid client, and so this
|
|
|
|
mode won't conflict with pre-existing user config on `+format-with'."
|
|
|
|
:init-value nil
|
|
|
|
(unless (local-variable-p '+format-lsp--last)
|
|
|
|
(setq-local +format-lsp--last +format-with))
|
|
|
|
(setq-local +format-with
|
|
|
|
(if +format-with-lsp-mode
|
|
|
|
(cl-remove-duplicates (cons 'lsp +format-with) :test #'eq)
|
|
|
|
(prog1 (remq 'lsp (ensure-list +format-lsp--last))
|
|
|
|
(kill-local-variable '+format-lsp--last)))))
|
|
|
|
|
|
|
|
(defvar +format--lsp-alist
|
|
|
|
'((lsp-managed-mode . +format--with-lsp-mode)
|
|
|
|
(eglot--managed-mode . +format--with-eglot))
|
|
|
|
"A list of LSP formatter functions to try on `+format-lsp-buffer'.")
|
|
|
|
|
|
|
|
(defun +format--lsp-fn ()
|
|
|
|
(cl-loop for (sym . fn) in +format--lsp-alist
|
|
|
|
if (and (boundp sym) (symbol-value sym))
|
|
|
|
return fn))
|
2024-07-06 21:03:12 -04:00
|
|
|
|
|
|
|
;;;###autoload
|
2024-07-07 20:44:33 -04:00
|
|
|
(defun +format-with-lsp-toggle-h ()
|
|
|
|
"Toggle `+format-with-lsp-mode' depending on the state of lsp-mode/eglot.
|
|
|
|
|
|
|
|
Does not activate the mode if `+format-with' is already set. To activate the
|
|
|
|
mode unconditionally, call `+format-with-lsp-mode' instead."
|
|
|
|
(when (or (null +format-with) +format-with-lsp-mode)
|
|
|
|
(+format-with-lsp-mode (if (+format--lsp-fn) +1 -1))))
|
2024-07-06 21:03:12 -04:00
|
|
|
|
|
|
|
|
|
|
|
;;
|
|
|
|
;;; Apheleia formatters
|
|
|
|
|
|
|
|
;;;###autoload
|
2024-07-08 21:18:49 -04:00
|
|
|
(cl-defun +format-lsp-buffer (&rest plist &key buffer callback &allow-other-keys)
|
2024-07-07 20:44:33 -04:00
|
|
|
"Format the current buffer with any available lsp-mode or eglot formatter."
|
2024-07-08 21:18:49 -04:00
|
|
|
(if-let* ((fn (with-current-buffer buffer (+format--lsp-fn)))
|
2024-08-21 18:47:14 -04:00
|
|
|
((apply fn (car +format--region-p) (cdr +format--region-p)
|
|
|
|
plist)))
|
2024-07-07 20:44:33 -04:00
|
|
|
(funcall callback)
|
|
|
|
(funcall callback "LSP server doesn't support formatting")))
|
|
|
|
|
2024-08-21 18:47:14 -04:00
|
|
|
(cl-defun +format--with-lsp-mode (beg end &key buffer &allow-other-keys)
|
|
|
|
"Format the current buffer or region with any available lsp-mode formatter.
|
|
|
|
|
|
|
|
Won't forward the buffer to chained formatters if successful."
|
2024-07-06 21:03:12 -04:00
|
|
|
(with-current-buffer buffer
|
|
|
|
(let ((edits
|
2024-08-21 18:47:14 -04:00
|
|
|
(cond ((and (null beg) (lsp-feature? "textDocument/formatting"))
|
|
|
|
(lsp-request "textDocument/formatting"
|
|
|
|
(lsp--make-document-formatting-params)))
|
|
|
|
((lsp-feature? "textDocument/rangeFormatting")
|
|
|
|
(lsp-request "textDocument/rangeFormatting"
|
|
|
|
(lsp--make-document-range-formatting-params
|
|
|
|
(or beg (point-min)) (or end (point-max)))))
|
|
|
|
;; try next chained formatter(s)
|
|
|
|
((cl-return (ignore (funcall callback)))))))
|
|
|
|
(unless (seq-empty-p edits)
|
|
|
|
(lsp--apply-text-edits edits 'format))
|
2024-07-07 20:44:33 -04:00
|
|
|
t)))
|
2024-07-06 21:03:12 -04:00
|
|
|
|
2024-08-21 18:47:14 -04:00
|
|
|
(cl-defun +format--with-eglot (beg end &key buffer callback &allow-other-keys)
|
|
|
|
"Format the current buffer or region with any available eglot formatter.
|
|
|
|
|
|
|
|
Won't forward the buffer to chained formatters if successful."
|
|
|
|
(with-current-buffer buffer
|
|
|
|
(or (with-demoted-errors "%s"
|
|
|
|
(always (eglot-format beg end)))
|
|
|
|
;; try next chained formatter(s)
|
|
|
|
(ignore (funcall callback)))))
|
|
|
|
|
2024-07-06 21:03:12 -04:00
|
|
|
;;; lsp.el ends here
|