Last active
February 16, 2024 18:17
-
-
Save jdtsmith/d936801a4d7fd981bedf2e59dacd675e to your computer and use it in GitHub Desktop.
eglot-booster: boost eglot with emacs-lsp-booster. ****NOTE: USE THIS PACKAGE INSTEAD: https://github.com/jdtsmith/eglot-booster
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;; eglot-booster.el --- boost eglot using emacs-lsp-booster -*- lexical-binding: t; -*- | |
;; Copyright (C) 2024 J.D. Smith | |
;;; Commentary: | |
;; **UPDATE** This has been superseded by the following package: | |
;; https://github.com/jdtsmith/eglot-booster | |
;; | |
;; Boost eglot with emacs-lsp-booster. | |
;; 1. Download a recent emacs-lsp-booster from | |
;; https://github.com/blahgeek/emacs-lsp-booster | |
;; 2. In the cloned directory, build with cargo (rust): | |
;; cargo build --release | |
;; 3. place the target/release/emacs-lsp-booster program somewhere on | |
;; `exec-path'. | |
;; 4. M-x eglot-booster | |
;; 5. Use eglot like normal | |
;; | |
;; Note: works only with local lsp servers via standard input/output, | |
;; not remote LSP servers. | |
;;; Code: | |
(eval-when-compile (require 'cl-lib)) | |
(require 'seq) | |
(require 'eglot) | |
(require 'jsonrpc) | |
(defun eglot-booster-plain-command (com) | |
"Test if command COM is a plain eglot server command." | |
(and (consp com) | |
(not (integerp (cadr com))) | |
(not (seq-intersection '(:initializationOptions :autoport) com)))) | |
(defun eglot-booster () | |
"Boost plain eglot server programs with emacs-lsp-booster. | |
The emacs-lsp-booster program must be compiled and available on | |
variable `exec-path'. Only local stdin/out based lsp servers can | |
be boosted." | |
(interactive) | |
(unless (executable-find "emacs-lsp-booster") | |
(user-error "The emacs-lsp-booster program is not installed")) | |
(if (get 'eglot-server-programs 'lsp-booster-p) | |
(message "eglot-server-programs already boosted.") | |
(let ((cnt 0) | |
(orig-read (symbol-function 'jsonrpc--json-read)) | |
(boost '("emacs-lsp-booster" "--json-false-value" ":json-false" "--"))) | |
(dolist (entry eglot-server-programs) | |
(cond | |
((functionp (cdr entry)) | |
(cl-incf cnt) | |
(let ((fun (cdr entry))) | |
(setcdr entry (lambda (&rest r) ; wrap function | |
(let ((res (apply fun r))) | |
(if (eglot-booster-plain-command res) | |
(append boost res) | |
res)))))) | |
((eglot-booster-plain-command (cdr entry)) | |
(cl-incf cnt) | |
(setcdr entry (append boost (cdr entry)))))) | |
(defalias 'jsonrpc--json-read | |
(lambda () | |
(or (and (= (following-char) ?#) | |
(let ((bytecode (read (current-buffer)))) | |
(when (byte-code-function-p bytecode) | |
(funcall bytecode)))) | |
(funcall orig-read)))) | |
(message "Boosted %d eglot-server-programs" cnt)) | |
(put 'eglot-server-programs 'lsp-booster-p t))) | |
(defun eglot-booster-reset () | |
(put 'eglot-server-programs 'lsp-booster-p nil)) | |
(provide 'eglot-booster) | |
;;; eglot-booster.el ends here |
Hello @jdtsmith, thank you for the nice work! May I suggest using the "advice" mechanism instead of simply overwriting jsonrpc--json-read
?
(defun eglot-booster--jsonrpc-handle-bytecode (orig-func)
"Handle bytecode in the JSON stream.
Necessary for using `emacs-lsp-booster'."
(if (= (following-char) ?#)
(let ((bytecode (read (current-buffer))))
(when (byte-code-function-p bytecode)
(funcall bytecode)))
(funcall orig-func)))
(advice-add 'jsonrpc--json-read :around #'eglot-booster--jsonrpc-handle-bytecode)
Update: I turned this into a tiny package which you should use instead of the gist.
Awesome, thanks!
Update: I turned this into a tiny package which you should use instead of the gist.
Amazing ! thanks !
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To evaluate this code, put it in an elisp buffer (like
*scratch*
) andM-x eval-buffer
, or put it somewhere onload-path
and(require 'eglot-booster)
. Do not simply copy this code into your.emacs
file (unless you have enabled lexical binding there).