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
|
||||
(global-activity-watch-mode))
|
||||
|
||||
;; lsp-booster
|
||||
|
||||
(use-package lsp-booster
|
||||
:after lsp)
|
||||
|
||||
|
||||
(use-package eglot-booster
|
||||
:after eglot
|
||||
:config
|
||||
(eglot-booster-mode))
|
||||
|
||||
;; rust
|
||||
(setq! lsp-inlay-hint-enable t)
|
||||
(setq! lsp-rust-analyzer-cargo-run-build-scripts t)
|
||||
|
|
29
flake.lock
generated
29
flake.lock
generated
|
@ -201,6 +201,26 @@
|
|||
"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": {
|
||||
"inputs": {
|
||||
"flake-utils": [
|
||||
|
@ -214,17 +234,17 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1723799695,
|
||||
"narHash": "sha256-8W/xxCpwQC9LOnwUO0Q7aGAF463ozaxcwQ6/toqtz0M=",
|
||||
"lastModified": 1724662747,
|
||||
"narHash": "sha256-8ehh6fm5C7TRNc3HmTr9KCyi7FqfFR1MqlqdynLKrMA=",
|
||||
"owner": "nix-community",
|
||||
"repo": "emacs-overlay",
|
||||
"rev": "3b4f8179de2b4950540d70161854e43fe1010eae",
|
||||
"rev": "3052bb01d404ee9bd03b040c9ae898febca05b81",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "emacs-overlay",
|
||||
"rev": "3b4f8179de2b4950540d70161854e43fe1010eae",
|
||||
"rev": "3052bb01d404ee9bd03b040c9ae898febca05b81",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
|
@ -806,6 +826,7 @@
|
|||
"inputs": {
|
||||
"chaotic": "chaotic",
|
||||
"disko": "disko",
|
||||
"emacs-lsp-booster": "emacs-lsp-booster",
|
||||
"emacs-overlay": "emacs-overlay",
|
||||
"envfs": "envfs",
|
||||
"flake-compat": "flake-compat",
|
||||
|
|
|
@ -61,11 +61,15 @@
|
|||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
emacs-overlay = {
|
||||
url = "github:nix-community/emacs-overlay/3b4f8179de2b4950540d70161854e43fe1010eae";
|
||||
url = "github:nix-community/emacs-overlay/3052bb01d404ee9bd03b040c9ae898febca05b81";
|
||||
inputs.flake-utils.follows = "flake-utils";
|
||||
inputs.nixpkgs-stable.follows = "nixpkgs-stable";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
emacs-lsp-booster = {
|
||||
url = "github:slotThe/emacs-lsp-booster-flake";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
disko = {
|
||||
url = "github:nix-community/disko";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
@ -128,6 +132,7 @@
|
|||
, home-manager
|
||||
, plasma-manager
|
||||
, emacs-overlay
|
||||
, emacs-lsp-booster
|
||||
, nur
|
||||
, nix-index-database
|
||||
, disko
|
||||
|
@ -147,6 +152,7 @@
|
|||
overlays = [
|
||||
my-overlay
|
||||
emacs-overlay.overlay
|
||||
emacs-lsp-booster.overlays.default
|
||||
inputs.nix-alien.overlays.default
|
||||
inputs.nix-ld-rs.overlays.default
|
||||
];
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
};
|
||||
programs.thunderbird = {
|
||||
enable = true;
|
||||
package = pkgs.betterbird;
|
||||
package = pkgs.thunderbird-128;
|
||||
profiles."main" = {
|
||||
isDefault = true;
|
||||
};
|
||||
|
|
|
@ -9,14 +9,14 @@ let
|
|||
doomemacsSrc = builtins.fetchGit {
|
||||
url = "https://github.com/doomemacs/doomemacs";
|
||||
ref = "master";
|
||||
rev = "1912571c9cec35d06f869637573e75ec529f6c7c";
|
||||
rev = "c862968f4843fa7c30b9dbca688d8e400729196b";
|
||||
};
|
||||
neofetchThemesSrc = builtins.fetchGit {
|
||||
url = "https://github.com/Chick2D/neofetch-themes";
|
||||
ref = "main";
|
||||
rev = "c7392136bed264258c9b8788b14410e1ff06d602";
|
||||
};
|
||||
myEmacs = (pkgs.emacsPackagesFor pkgs.emacs-pgtk).emacsWithPackages (epkgs:
|
||||
myEmacs = (pkgs.emacsPackagesFor pkgs.emacs-unstable-pgtk).emacsWithPackages (epkgs:
|
||||
with epkgs; [
|
||||
vterm
|
||||
treesit-grammars.with-all-grammars
|
||||
|
@ -317,6 +317,7 @@ in
|
|||
# TODO Disable gui apps & switch to emacs-git instead of pgtk on headless systems
|
||||
packages = with pkgs; [
|
||||
myEmacs
|
||||
emacs-lsp-booster
|
||||
any-nix-shell
|
||||
atool
|
||||
aspell
|
||||
|
|
Loading…
Add table
Reference in a new issue