From 1ede94c88a3b0d91f1c2923f8c75fc42aa93ba46 Mon Sep 17 00:00:00 2001 From: Sergei Nizovtsev Date: Tue, 19 Aug 2025 16:29:26 +0200 Subject: [PATCH] feat(lsp): add `+booster` flag Adds support for LSP IO performance booster. This may reduce UI-blocking time in case of unresponsive LSP backend. --- modules/tools/lsp/+eglot.el | 7 +++++++ modules/tools/lsp/+lsp.el | 18 +++++++++++++++++- modules/tools/lsp/doctor.el | 4 ++++ modules/tools/lsp/packages.el | 6 +++++- 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/modules/tools/lsp/+eglot.el b/modules/tools/lsp/+eglot.el index 0990f8a1e..badcd61dc 100644 --- a/modules/tools/lsp/+eglot.el +++ b/modules/tools/lsp/+eglot.el @@ -67,3 +67,10 @@ server an expensive restart when its buffer is reverted." (use-package! flycheck-eglot :when (modulep! :checkers syntax -flymake) :hook (eglot-managed-mode . flycheck-eglot-mode)) + +(use-package! eglot-booster + :when (modulep! +eglot +booster) + :after eglot + :config (eglot-booster-mode) + :init + (setq eglot-booster-io-only t)) diff --git a/modules/tools/lsp/+lsp.el b/modules/tools/lsp/+lsp.el index 2be1beee3..c7b4ed1ad 100644 --- a/modules/tools/lsp/+lsp.el +++ b/modules/tools/lsp/+lsp.el @@ -161,7 +161,23 @@ server getting expensively restarted when reverting buffers." (when (modulep! :completion corfu) (setq lsp-completion-provider :none) - (add-hook 'lsp-mode-hook #'lsp-completion-mode))) + (add-hook 'lsp-mode-hook #'lsp-completion-mode)) + + (when (modulep! +booster) + (defun lsp-booster--advice-final-command (old-fn cmd &optional test?) + "Prepend emacs-lsp-booster command to lsp CMD." + (let ((orig-result (funcall old-fn cmd test?))) + (if (and (not test?) ;; for check lsp-server-present? + (not (file-remote-p default-directory)) ;; see lsp-resolve-final-command, it would add extra shell wrapper + (not (functionp 'json-rpc-connection)) ;; native json-rpc + (executable-find "emacs-lsp-booster")) + (progn + (when-let ((command-from-exec-path (executable-find (car orig-result)))) ;; resolve command from exec-path (in case not found in $PATH) + (setcar orig-result command-from-exec-path)) + (message "Using emacs-lsp-booster for %s!" orig-result) + (append '("emacs-lsp-booster" "--disable-bytecode" "--") orig-result)) + orig-result))) + (advice-add 'lsp-resolve-final-command :around #'lsp-booster--advice-final-command))) (use-package! lsp-ui :hook (lsp-mode . lsp-ui-mode) diff --git a/modules/tools/lsp/doctor.el b/modules/tools/lsp/doctor.el index 42c59f33c..9b67ae95c 100644 --- a/modules/tools/lsp/doctor.el +++ b/modules/tools/lsp/doctor.el @@ -6,3 +6,7 @@ (unless (modulep! +eglot) (unless (executable-find "npm") (warn! "Couldn't find npm. `lsp-mode' needs npm to auto-install some LSP servers. For more information, see https://emacs-lsp.github.io/lsp-mode/page/languages/."))) + +(when (modulep! +booster) + (unless (executable-find "emacs-lsp-booster") + (warn! "Couldn't find emacs-lsp-booster executable."))) diff --git a/modules/tools/lsp/packages.el b/modules/tools/lsp/packages.el index 259b19714..1fc85b9f4 100644 --- a/modules/tools/lsp/packages.el +++ b/modules/tools/lsp/packages.el @@ -7,7 +7,11 @@ (when (modulep! :completion vertico) (package! consult-eglot :pin "2816f8aad7d6a1e6d5e5b4a5e04c1d74b82b26b8")) (when (modulep! :checkers syntax -flymake) - (package! flycheck-eglot :pin "0d7f0afc9bf08fce4a3ee225ec6540a91f8cfd76"))) + (package! flycheck-eglot :pin "0d7f0afc9bf08fce4a3ee225ec6540a91f8cfd76")) + (when (modulep! +booster) + (package! eglot-booster + :recipe (:host github :repo "jdtsmith/eglot-booster") + :pin "cab7803c4f0adc7fff9da6680f90110674bb7a22"))) (package! lsp-mode :pin "65a414ddeb84d0282eda357cbd41ea674a42fd0b") (package! lsp-ui :pin "bbb1aa0192cce1ee39c2f36953cc5256d49534a4") (when (modulep! :completion ivy)