Goodbye lsp-mode
I knew this day would come. I have uninstalled lsp-mode
and made the transition to eglot
.
I've been using lsp-mode
since long enough ago that eglot
was fairly barebones and it was not obvious which one was the "better" client. Maybe it still isn't obvious.
I tend to prefer a more batteries-included solution; time is short. I picked lsp-mode
.
But lsp-mode
was always kind of janky, to be honest, even if it was very functional. And eglot
got upstreamed. It's just an Emacs feature, now. That's not something that happens super often.
The community had spoken. lsp-mode
's days were numbered, and now, quite a while actually after the upstreaming of eglot
, I have gotten around to removing lsp-mode
. eglot
was already there, I just needed to start using it.
Taking lsp-mode
out of my configuration meant giving up dap-mode
too, for some reason that I haven't investigated. They must have been related projects, but I don't use a debugger very often, so it's not something I bothered to look into. It was kind of janky too. Maybe eglot
enables something better?
In any case, the overall change was a reduction in complexity and code in my config, and I'm happy about that. And it wasn't too much work.
Some Highlights
eglot
requires a lot less configuration than I was expecting because it overloads less of the functionality already present in Emacs. I had read this was the case but I guess I understimated how much of a benefit it is. mea culpa.
After removing all of my lsp-mode
-related configuration I only needed to add a couple of things to get functionality the way I like it, with behavior reasonably close to what I am used to from lsp-ui-mode
.
Automatic Import Organization and Formatting
For now I only set up Go to start eglot
automatically. M-x eglot
is not unergonomic, and it keeps surprises down.
Go is where I want LSP the most and where I understand best how eglot
is going to behave for now:
- :hook ((go-mode . yas-minor-mode))
+ :hook ((go-mode . yas-minor-mode)
+ (go-mode . eglot-ensure))
I borrowed some code from a GitHub issue comment thread (as you do) to get automatic import organization and formatting on save in Go files β I am spoiled and never think about these things.
(defun my-eglot-organize-imports () (interactive)
(eglot-code-actions nil nil "source.organizeImports" t))
(defun install-my-eglot-organize-imports ()
(add-hook 'before-save-hook 'my-eglot-organize-imports nil t)
(add-hook 'before-save-hook 'eglot-format-buffer))
(add-hook 'go-mode-hook #'install-my-eglot-organize-imports)
Documentation Popups
I was never a huge fan of how eldoc
pops up on the bottom of the frame, and it's a big reason why I didn't choose eglot
from the beginning. This is a petty personal preference and I am not going to insist that it is a superior preference, however, I want the documentation to pop up at point after a pause. That's what I prefer, so be it.
This code was inspired by (not stolen from) a different GitHub comment which I have unfortunately lost, but good riddance β it was telling me not to use this feature! Hilarious β I have not experienced the alleged performance issues, and in fact, the feature does what I want!
Sometimes it is best to just try things for yourself π€ You can't believe everything you read on the Internet!
(use-package eldoc-box)
; delay before the pop-up appears
(setq eldoc-idle-delay 1.5)
; load when appropriate
(add-hook 'eglot-managed-mode-hook #'eldoc-box-hover-at-point-mode t)
The comment (and the docs!) mention the performance impact of eldoc-box-hover-at-point-mode
but I haven't noticed it. If I do encounter it, I'll bind it to a key instead of doing the hover.
I like the way elbox-doc
looks better than lsp-ui
's popups. Woohoo! π
Keybindings
I'm pretty sure it's a bug in my config (π
), so I'm not sure if it's standard or not, but I did have to rebind gd
(back?) to evil-goto-definition
.
But other than that I haven't found the need to rebind anything so far, which means people who don't already have a configuration with bugs.. might not need any custom keybindings. It seems to integrate well with evil
and that sort of thing too, so I think this applies to people with nonstandard setups as well.
Everything I had a custom lsp-mode
keybinding set up for, there's a sane default. It might be something a little different than what I had, but something I'm happy enough to learn. For the most part this is because evil-mode
already has bindings for certain common actions in code, and eglot
is using the key maps that Emacs uses, so evil
Just Works with it. The keybindings might be a little different than what I had, but it's likely they will carry over to other Emacs modes and features in the future.
Stuff like gr
instead of ,fr
to find references, and a greater chance I won't have to change again, and I can maintain less config? That's fine. I'll get used to it.
First Impressions of eglot
After setting up the above features β my must-haves from lsp-mode
and lsp-ui
..
.. it's nice. It's real nice. I haven't needed to recreate many of my custom lsp-mode
keybindings because the defaults Just Workβ’.
I should have switched sooner. I just needed to start using it. It was already installed..