tweak(lsp): switch to eglot
This commit is contained in:
parent
39ae89c284
commit
fd9180eb9c
1 changed files with 57 additions and 51 deletions
108
config.org
108
config.org
|
|
@ -1485,27 +1485,6 @@ We'll also define a word targeter, since that case was previously handled by the
|
|||
(pushnew! embark-target-finders #'embark-target-word-at-point))
|
||||
#+end_src
|
||||
|
||||
*** LSP Integration
|
||||
|
||||
The provided action types related to programming only apply to Emacs Lisp code, so we'll add a new one that integrates with LSP.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun embark-target-lsp-symbol-at-point ()
|
||||
"Target the LSP symbol at point."
|
||||
(when (bound-and-true-p lsp-mode)
|
||||
(require 'lsp-ui-doc)
|
||||
;; Use hover request (meant for highlighting) to get the current symbol
|
||||
(when-let ((bounds (lsp-ui-doc--extract-bounds
|
||||
(lsp-request "textDocument/hover"
|
||||
(lsp--text-document-position-params)))))
|
||||
(cons 'lsp-symbol
|
||||
(cons (buffer-substring (car bounds) (cdr bounds))
|
||||
bounds)))))
|
||||
|
||||
(after! embark
|
||||
(pushnew! embark-target-finders #'embark-target-lsp-symbol-at-point))
|
||||
#+end_src
|
||||
|
||||
*** Hooks
|
||||
|
||||
The hook ~embark--mark-target~ normally sets the mark to the end and puts the point at the beginning. This is the opposite of the usual order, so let's patch it to flip the order.
|
||||
|
|
@ -4247,29 +4226,29 @@ I prefer 2-space indentation in all circumstances. Unfortunately, Emacs's indent
|
|||
The =lsp-java= package provides LSP support using the standard Java language server, the Eclipse server ~jdtls~. Unfortunately, this package isn't designed for Nix, so it fails to find the server script in our Nix store. We need to do a bit of legwork to patch in this support, as well as some related considerations, such as per-project config directories.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun +lsp-java-server-store-path ()
|
||||
"Return the Nix store derivation path to the Java language server."
|
||||
(require 'lsp-java)
|
||||
(string-remove-suffix
|
||||
(concat "/bin/" lsp-java-jdt-ls-command)
|
||||
(or
|
||||
(executable-find lsp-java-jdt-ls-command)
|
||||
(user-error "Could not find Java language server"))))
|
||||
;; (defun +lsp-java-server-store-path ()
|
||||
;; "Return the Nix store derivation path to the Java language server."
|
||||
;; (require 'lsp-java)
|
||||
;; (string-remove-suffix
|
||||
;; (concat "/bin/" lsp-java-jdt-ls-command)
|
||||
;; (or
|
||||
;; (executable-find lsp-java-jdt-ls-command)
|
||||
;; (user-error "Could not find Java language server"))))
|
||||
|
||||
(after! lsp-java
|
||||
(setq lsp-java-jdt-ls-prefer-native-command t))
|
||||
(add-hook! java-mode
|
||||
(setq-local lsp-java-server-install-dir
|
||||
(f-slash (+lsp-java-server-store-path))))
|
||||
;; (after! lsp-java
|
||||
;; (setq lsp-java-jdt-ls-prefer-native-command t))
|
||||
;; (add-hook! java-mode
|
||||
;; (setq-local lsp-java-server-install-dir
|
||||
;; (f-slash (+lsp-java-server-store-path))))
|
||||
|
||||
;; The relative locations of the binary and jar file are different
|
||||
;; on NixOS than on most other Linux distros
|
||||
;; ;; The relative locations of the binary and jar file are different
|
||||
;; ;; on NixOS than on most other Linux distros
|
||||
|
||||
(defadvice! ~/lsp-java-locate-server-jar (old-fn)
|
||||
:around #'lsp-java--locate-server-jar
|
||||
(let ((lsp-java-server-install-dir
|
||||
(concat lsp-java-server-install-dir "share/java/jdtls/")))
|
||||
(funcall old-fn)))
|
||||
;; (defadvice! ~/lsp-java-locate-server-jar (old-fn)
|
||||
;; :around #'lsp-java--locate-server-jar
|
||||
;; (let ((lsp-java-server-install-dir
|
||||
;; (concat lsp-java-server-install-dir "share/java/jdtls/")))
|
||||
;; (funcall old-fn)))
|
||||
#+end_src
|
||||
|
||||
*** Project File Conflict
|
||||
|
|
@ -4287,26 +4266,53 @@ Doom's standard library allows for an empty =.project= file to mark the root of
|
|||
#+call: confpkg("Mode: LSP")
|
||||
|
||||
#+begin_src emacs-lisp :noweb-ref doom-module
|
||||
:tools lsp
|
||||
:tools (lsp +eglot +booster)
|
||||
#+end_src
|
||||
|
||||
The emacs package =lsp-mode= is the package of choice for general LSP integration in Emacs. The Doom Emacs module =:tools lsp= handles most of the configuration for it, but there's one annoyance it doesn't cover: when a server isn't found for a particular language, =lsp-mode= tries to install it itself, which is a complete waste of time for my purposes since I use NixOS.
|
||||
The language server protocol (LSP) standardizes modern IDE features and brings them to any text editor with a compatible client plugin. There are multiple of these for Emacs, but the simplest and most performant is Eglot.
|
||||
|
||||
There is luckily a configuration variable to disable this suggestion:
|
||||
*** Help Window
|
||||
|
||||
Doom by default sets Eglot's help window (used for documentation and the like) way, way too small. Here's a simple fix.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(after! lsp-mode
|
||||
(setq lsp-enable-suggest-server-download nil))
|
||||
(after! eglot
|
||||
(replace-popup-rule! "^\\*eglot-help" :size 0.4 :quit t :select t))
|
||||
#+end_src
|
||||
|
||||
*** Bindings
|
||||
*** Server Booster
|
||||
|
||||
Some more convenient leader key bindings would be nice to prevent having to trawl through the =lsp-command-map=.
|
||||
Eglot is already a pretty fast client, but the single-threaded nature of Emacs can cause it to slow down the UI when sending I/O. The =+booster= flag fixes this issue by utilizing an external program, ~emacs-lsp-booster~, to handle I/O asynchronously. This program needs to be available for the package to function properly.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(map! :leader
|
||||
:desc "Select LSP code lens"
|
||||
"c L" #'lsp-avy-lens)
|
||||
(after! eglot-booster
|
||||
(let* ((booster (nix-build-out-path-gcroot
|
||||
"emacs-lsp-booster"
|
||||
"nixpkgs#emacs-lsp-booster"))
|
||||
(booster-exec (concat booster "/bin/emacs-lsp-booster")))
|
||||
(setf (car eglot-booster--boost) booster-exec
|
||||
(car eglot-booster--boost-io-only) booster-exec)
|
||||
|
||||
;; Advise `eglot-booster-mode' to prevent it from complaining
|
||||
;; about the program not being in the PATH
|
||||
(defadvice! ~/silence-eglot-booster-mode (orig-fun &rest args)
|
||||
:around #'eglot-booster-mode
|
||||
(letf! ((#'executable-find #'always))
|
||||
(apply orig-fun args)))))
|
||||
#+end_src
|
||||
|
||||
*** Appearance
|
||||
|
||||
Eglot highlights variable names and other symbols while the user is hovering over them, to show where they are used elsewhere in the program. This is useful, but all it does is bold the text, which is a bit hard to notice. We can add a brighter background to the face in order to make it easier to see.
|
||||
|
||||
Eglot also uses a face to signal to the programmer that a symbol is being unused, which makes the symbol slightly darker. This is hard to notice, so I'm setting it to be even darker, the same color as comments.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(custom-set-faces!
|
||||
`(eglot-highlight-symbol-face
|
||||
:background ,(doom-color 'base0) :inherit bold)
|
||||
`(eglot-diagnostic-tag-unnecessary-face
|
||||
:foreground ,(doom-color 'comments) :inherit unspecified))
|
||||
#+end_src
|
||||
|
||||
** Latex
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue