fix(lsp): shutdown deferral for multiple LSP clients

If a buffer had multiple LSP servers active,
`+lsp-defer-server-shutdown-a` would only shut down the first. This
adjusts it to not only defer shutdown of all servers, but also ensures
`+lsp-optimization-mode` is only disabled when there are no lsp-mode
sessions left.

Fix: #5409
This commit is contained in:
Henrik Lissner
2025-07-13 19:26:22 +02:00
parent 9219fa7c08
commit d63a15eba7
2 changed files with 21 additions and 14 deletions

View File

@@ -97,7 +97,11 @@ Can be a list of backends; accepts any value `company-backends' accepts.")
(setq-local flycheck-checker old-checker))
(apply fn args)))
(add-hook 'lsp-mode-hook #'+lsp-optimization-mode)
(add-hook 'lsp-before-initialize-hook #'+lsp-optimization-mode)
(add-hook! 'lsp-after-uninitialized-functions
(defun +lsp--disable-optimization-mode-if-no-workspaces-h (_workspace)
(unless (lsp--session-workspaces lsp--session)
(+lsp-optimization-mode -1))))
(when (modulep! :completion company)
(add-hook! 'lsp-completion-mode-hook
@@ -119,20 +123,20 @@ server getting expensively restarted when reverting buffers."
restart
(null +lsp-defer-shutdown)
(= +lsp-defer-shutdown 0))
(prog1 (funcall fn restart)
(+lsp-optimization-mode -1))
(funcall fn restart)
(when (timerp +lsp--deferred-shutdown-timer)
(cancel-timer +lsp--deferred-shutdown-timer))
(setq +lsp--deferred-shutdown-timer
(run-at-time
(if (numberp +lsp-defer-shutdown) +lsp-defer-shutdown 3)
nil (lambda (workspace)
(with-lsp-workspace workspace
(unless (lsp--workspace-buffers workspace)
(let ((lsp-restart 'ignore))
(funcall fn))
(+lsp-optimization-mode -1))))
lsp--cur-workspace))))
nil (lambda (workspaces)
(dolist (ws workspaces)
(or (cl-some #'lsp-buffer-live-p
(lsp--workspace-buffers ws))
(with-lsp-workspace ws
(let ((lsp-restart 'ignore))
(funcall fn))))))
lsp--buffer-workspaces))))
(when (modulep! :ui modeline +light)
(defvar-local lsp-modeline-icon nil)

View File

@@ -21,10 +21,13 @@ killing and opening many LSP/eglot-powered buffers.")
:global t
:init-value nil
(if (not +lsp-optimization-mode)
(setq-default read-process-output-max +lsp--default-read-process-output-max
gcmh-high-cons-threshold +lsp--default-gcmh-high-cons-threshold
+lsp--optimization-init-p nil)
;; Only apply these settings once!
;; Only apply these settings once! A minor mode's body is triggered each
;; time it is called, even if it's already in the desired state.
(when +lsp--optimization-init-p
(setq-default read-process-output-max +lsp--default-read-process-output-max
gcmh-high-cons-threshold +lsp--default-gcmh-high-cons-threshold
+lsp--optimization-init-p nil))
;; See above.
(unless +lsp--optimization-init-p
(setq +lsp--default-read-process-output-max (default-value 'read-process-output-max)
+lsp--default-gcmh-high-cons-threshold (default-value 'gcmh-high-cons-threshold))