Add lsp-booster
This commit is contained in:
parent
bcd279b56d
commit
0bfa64b4ba
7 changed files with 204 additions and 8 deletions
124
ext/doom/autoload/eglot-booster.el
Normal file
124
ext/doom/autoload/eglot-booster.el
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
;;; eglot-booster.el --- Boost eglot using lsp-booster -*- lexical-binding: t; -*-
|
||||||
|
;; Copyright (C) 2024 J.D. Smith
|
||||||
|
|
||||||
|
;; Author: J.D. Smith
|
||||||
|
;; Homepage: https://github.com/jdtsmith/eglot-booster
|
||||||
|
;; Package-Requires: ((emacs "29.1") (jsonrpc "1.0") (eglot "1.0") (seq "2.24"))
|
||||||
|
;; Version: 0.0.1
|
||||||
|
;; Keywords: convenience, programming
|
||||||
|
;; Prefix: eglot-booster
|
||||||
|
;; Separator: -
|
||||||
|
|
||||||
|
;; eglot-booster is free software: you can redistribute it and/or
|
||||||
|
;; modify it under the terms of the GNU General Public License as
|
||||||
|
;; published by the Free Software Foundation, either version 3 of the
|
||||||
|
;; License, or (at your option) any later version.
|
||||||
|
|
||||||
|
;; eglot-booster is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
;; General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; This small minor mode boosts eglot with emacs-lsp-booster.
|
||||||
|
;; Using it is simple:
|
||||||
|
;;
|
||||||
|
;; 1. Download/build a recent emacs-lsp-booster from
|
||||||
|
;; https://github.com/blahgeek/emacs-lsp-booster using the
|
||||||
|
;; instructions there.
|
||||||
|
;; 2. Enable eglot-booster-mode either in your init or, interactively,
|
||||||
|
;; use M-x eglot-booster-mode.
|
||||||
|
;; 3. Use eglot like normal.
|
||||||
|
;;
|
||||||
|
;; You can disable boosting by turning the minor mode off; any boosted
|
||||||
|
;; eglot servers will need to be restarted. Note: boosting works only
|
||||||
|
;; with local lsp servers programs which communicate via standard
|
||||||
|
;; input/output, not remote or network-port LSP servers.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
(require 'eglot)
|
||||||
|
(require 'jsonrpc)
|
||||||
|
|
||||||
|
(defcustom eglot-booster-no-remote-boost nil
|
||||||
|
"If non-nil, do not boost remote hosts."
|
||||||
|
:group 'eglot
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defun eglot-booster-plain-command (com)
|
||||||
|
"Test if command COM is a plain eglot server command."
|
||||||
|
(and (consp com)
|
||||||
|
(not (integerp (cadr com)))
|
||||||
|
(not (memq :autoport com))))
|
||||||
|
|
||||||
|
(defvar-local eglot-booster-boosted nil)
|
||||||
|
(defun eglot-booster--jsonrpc--json-read (orig-func)
|
||||||
|
"Read JSON or bytecode, wrapping the ORIG-FUNC JSON reader."
|
||||||
|
(if eglot-booster-boosted ; local to process-buffer
|
||||||
|
(or (and (= (following-char) ?#)
|
||||||
|
(let ((bytecode (read (current-buffer))))
|
||||||
|
(when (byte-code-function-p bytecode)
|
||||||
|
(funcall bytecode))))
|
||||||
|
(funcall orig-func))
|
||||||
|
;; Not in a boosted process, fallback
|
||||||
|
(funcall orig-func)))
|
||||||
|
|
||||||
|
(defun eglot-booster--init (server)
|
||||||
|
"Register eglot SERVER as boosted if it is."
|
||||||
|
(when-let ((server)
|
||||||
|
(proc (jsonrpc--process server))
|
||||||
|
(com (process-command proc))
|
||||||
|
(buf (process-buffer proc)))
|
||||||
|
(unless (and (file-remote-p default-directory) eglot-booster-no-remote-boost)
|
||||||
|
(if (file-remote-p default-directory) ; com will likely be /bin/sh -i or so
|
||||||
|
(when (seq-find (apply-partially #'string-search "emacs-lsp-booster")
|
||||||
|
(process-get proc 'remote-command)) ; tramp applies this
|
||||||
|
(with-current-buffer buf (setq eglot-booster-boosted t)))
|
||||||
|
(when (string-search "emacs-lsp-booster" (car-safe com))
|
||||||
|
(with-current-buffer buf (setq eglot-booster-boosted t)))))))
|
||||||
|
|
||||||
|
(defvar eglot-booster--boost
|
||||||
|
'("emacs-lsp-booster" "--json-false-value" ":json-false" "--"))
|
||||||
|
|
||||||
|
(defun eglot-booster--wrap-contact (args)
|
||||||
|
"Wrap contact within ARGS if possible."
|
||||||
|
(let ((contact (nth 3 args)))
|
||||||
|
(cond
|
||||||
|
((and eglot-booster-no-remote-boost (file-remote-p default-directory)))
|
||||||
|
((functionp contact)
|
||||||
|
(setf (nth 3 args)
|
||||||
|
(lambda (&optional interactive)
|
||||||
|
(let ((res (funcall contact interactive)))
|
||||||
|
(if (eglot-booster-plain-command res)
|
||||||
|
(append eglot-booster--boost res)
|
||||||
|
res)))))
|
||||||
|
((eglot-booster-plain-command contact)
|
||||||
|
(setf (nth 3 args) (append eglot-booster--boost contact))))
|
||||||
|
args))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(define-minor-mode eglot-booster-mode
|
||||||
|
"Minor mode which boosts 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."
|
||||||
|
:global t
|
||||||
|
:group 'eglot
|
||||||
|
(cond
|
||||||
|
(eglot-booster-mode
|
||||||
|
(unless (executable-find "emacs-lsp-booster")
|
||||||
|
(setq eglot-booster-mode nil)
|
||||||
|
(user-error "The emacs-lsp-booster program is not installed"))
|
||||||
|
(advice-add 'jsonrpc--json-read :around #'eglot-booster--jsonrpc--json-read)
|
||||||
|
(advice-add 'eglot--connect :filter-args #'eglot-booster--wrap-contact)
|
||||||
|
(add-hook 'eglot-server-initialized-hook #'eglot-booster--init))
|
||||||
|
(t
|
||||||
|
(advice-remove 'jsonrpc--json-read #'eglot-booster--jsonrpc--json-read)
|
||||||
|
(advice-remove 'eglot--connect #'eglot-booster--wrap-contact)
|
||||||
|
(remove-hook 'eglot-server-initialized-hook #'eglot-booster--init))))
|
||||||
|
|
||||||
|
(provide 'eglot-booster)
|
||||||
|
;;; eglot-booster.el ends here
|
33
ext/doom/autoload/lsp-booster.el
Normal file
33
ext/doom/autoload/lsp-booster.el
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
;;; lsp-booster.el --- Boost emacs-lsp using lsp-booster -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
(defun lsp-booster--advice-json-parse (old-fn &rest args)
|
||||||
|
"Try to parse bytecode instead of json."
|
||||||
|
(or
|
||||||
|
(when (equal (following-char) ?#)
|
||||||
|
(let ((bytecode (read (current-buffer))))
|
||||||
|
(when (byte-code-function-p bytecode)
|
||||||
|
(funcall bytecode))))
|
||||||
|
(apply old-fn args)))
|
||||||
|
(advice-add (if (progn (require 'json)
|
||||||
|
(fboundp 'json-parse-buffer))
|
||||||
|
'json-parse-buffer
|
||||||
|
'json-read)
|
||||||
|
:around
|
||||||
|
#'lsp-booster--advice-json-parse)
|
||||||
|
|
||||||
|
(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
|
||||||
|
lsp-use-plists
|
||||||
|
(not (functionp 'json-rpc-connection)) ;; native json-rpc
|
||||||
|
(executable-find "emacs-lsp-booster"))
|
||||||
|
(progn
|
||||||
|
(message "Using emacs-lsp-booster for %s!" orig-result)
|
||||||
|
(cons "emacs-lsp-booster" orig-result))
|
||||||
|
orig-result)))
|
||||||
|
(advice-add 'lsp-resolve-final-command :around #'lsp-booster--advice-final-command)
|
||||||
|
|
||||||
|
(provide 'lsp-booster)
|
||||||
|
;;; lsp-booster.el ends here
|
|
@ -131,6 +131,17 @@
|
||||||
:config
|
:config
|
||||||
(global-activity-watch-mode))
|
(global-activity-watch-mode))
|
||||||
|
|
||||||
|
;; lsp-booster
|
||||||
|
|
||||||
|
(use-package lsp-booster
|
||||||
|
:after lsp)
|
||||||
|
|
||||||
|
|
||||||
|
(use-package eglot-booster
|
||||||
|
:after eglot
|
||||||
|
:config
|
||||||
|
(eglot-booster-mode))
|
||||||
|
|
||||||
;; rust
|
;; rust
|
||||||
(setq! lsp-inlay-hint-enable t)
|
(setq! lsp-inlay-hint-enable t)
|
||||||
(setq! lsp-rust-analyzer-cargo-run-build-scripts t)
|
(setq! lsp-rust-analyzer-cargo-run-build-scripts t)
|
||||||
|
|
29
flake.lock
generated
29
flake.lock
generated
|
@ -201,6 +201,26 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"emacs-lsp-booster": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1716274896,
|
||||||
|
"narHash": "sha256-WsyEkdt8ReGQ40+yV4Cb99A2MEmV0O/i6rmFQura5ww=",
|
||||||
|
"owner": "slotThe",
|
||||||
|
"repo": "emacs-lsp-booster-flake",
|
||||||
|
"rev": "7d110295988fc9bf7fd43bb0cabfbe58a4a5ecf8",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "slotThe",
|
||||||
|
"repo": "emacs-lsp-booster-flake",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"emacs-overlay": {
|
"emacs-overlay": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-utils": [
|
"flake-utils": [
|
||||||
|
@ -214,17 +234,17 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1723799695,
|
"lastModified": 1724662747,
|
||||||
"narHash": "sha256-8W/xxCpwQC9LOnwUO0Q7aGAF463ozaxcwQ6/toqtz0M=",
|
"narHash": "sha256-8ehh6fm5C7TRNc3HmTr9KCyi7FqfFR1MqlqdynLKrMA=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "emacs-overlay",
|
"repo": "emacs-overlay",
|
||||||
"rev": "3b4f8179de2b4950540d70161854e43fe1010eae",
|
"rev": "3052bb01d404ee9bd03b040c9ae898febca05b81",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "emacs-overlay",
|
"repo": "emacs-overlay",
|
||||||
"rev": "3b4f8179de2b4950540d70161854e43fe1010eae",
|
"rev": "3052bb01d404ee9bd03b040c9ae898febca05b81",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -806,6 +826,7 @@
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"chaotic": "chaotic",
|
"chaotic": "chaotic",
|
||||||
"disko": "disko",
|
"disko": "disko",
|
||||||
|
"emacs-lsp-booster": "emacs-lsp-booster",
|
||||||
"emacs-overlay": "emacs-overlay",
|
"emacs-overlay": "emacs-overlay",
|
||||||
"envfs": "envfs",
|
"envfs": "envfs",
|
||||||
"flake-compat": "flake-compat",
|
"flake-compat": "flake-compat",
|
||||||
|
|
|
@ -61,11 +61,15 @@
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
emacs-overlay = {
|
emacs-overlay = {
|
||||||
url = "github:nix-community/emacs-overlay/3b4f8179de2b4950540d70161854e43fe1010eae";
|
url = "github:nix-community/emacs-overlay/3052bb01d404ee9bd03b040c9ae898febca05b81";
|
||||||
inputs.flake-utils.follows = "flake-utils";
|
inputs.flake-utils.follows = "flake-utils";
|
||||||
inputs.nixpkgs-stable.follows = "nixpkgs-stable";
|
inputs.nixpkgs-stable.follows = "nixpkgs-stable";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
emacs-lsp-booster = {
|
||||||
|
url = "github:slotThe/emacs-lsp-booster-flake";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
disko = {
|
disko = {
|
||||||
url = "github:nix-community/disko";
|
url = "github:nix-community/disko";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
@ -128,6 +132,7 @@
|
||||||
, home-manager
|
, home-manager
|
||||||
, plasma-manager
|
, plasma-manager
|
||||||
, emacs-overlay
|
, emacs-overlay
|
||||||
|
, emacs-lsp-booster
|
||||||
, nur
|
, nur
|
||||||
, nix-index-database
|
, nix-index-database
|
||||||
, disko
|
, disko
|
||||||
|
@ -147,6 +152,7 @@
|
||||||
overlays = [
|
overlays = [
|
||||||
my-overlay
|
my-overlay
|
||||||
emacs-overlay.overlay
|
emacs-overlay.overlay
|
||||||
|
emacs-lsp-booster.overlays.default
|
||||||
inputs.nix-alien.overlays.default
|
inputs.nix-alien.overlays.default
|
||||||
inputs.nix-ld-rs.overlays.default
|
inputs.nix-ld-rs.overlays.default
|
||||||
];
|
];
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
};
|
};
|
||||||
programs.thunderbird = {
|
programs.thunderbird = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = pkgs.betterbird;
|
package = pkgs.thunderbird-128;
|
||||||
profiles."main" = {
|
profiles."main" = {
|
||||||
isDefault = true;
|
isDefault = true;
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,14 +9,14 @@ let
|
||||||
doomemacsSrc = builtins.fetchGit {
|
doomemacsSrc = builtins.fetchGit {
|
||||||
url = "https://github.com/doomemacs/doomemacs";
|
url = "https://github.com/doomemacs/doomemacs";
|
||||||
ref = "master";
|
ref = "master";
|
||||||
rev = "1912571c9cec35d06f869637573e75ec529f6c7c";
|
rev = "c862968f4843fa7c30b9dbca688d8e400729196b";
|
||||||
};
|
};
|
||||||
neofetchThemesSrc = builtins.fetchGit {
|
neofetchThemesSrc = builtins.fetchGit {
|
||||||
url = "https://github.com/Chick2D/neofetch-themes";
|
url = "https://github.com/Chick2D/neofetch-themes";
|
||||||
ref = "main";
|
ref = "main";
|
||||||
rev = "c7392136bed264258c9b8788b14410e1ff06d602";
|
rev = "c7392136bed264258c9b8788b14410e1ff06d602";
|
||||||
};
|
};
|
||||||
myEmacs = (pkgs.emacsPackagesFor pkgs.emacs-pgtk).emacsWithPackages (epkgs:
|
myEmacs = (pkgs.emacsPackagesFor pkgs.emacs-unstable-pgtk).emacsWithPackages (epkgs:
|
||||||
with epkgs; [
|
with epkgs; [
|
||||||
vterm
|
vterm
|
||||||
treesit-grammars.with-all-grammars
|
treesit-grammars.with-all-grammars
|
||||||
|
@ -317,6 +317,7 @@ in
|
||||||
# TODO Disable gui apps & switch to emacs-git instead of pgtk on headless systems
|
# TODO Disable gui apps & switch to emacs-git instead of pgtk on headless systems
|
||||||
packages = with pkgs; [
|
packages = with pkgs; [
|
||||||
myEmacs
|
myEmacs
|
||||||
|
emacs-lsp-booster
|
||||||
any-nix-shell
|
any-nix-shell
|
||||||
atool
|
atool
|
||||||
aspell
|
aspell
|
||||||
|
|
Loading…
Add table
Reference in a new issue