Using LSP in Emacs and Debian
The Language Server Protocol (LSP) is a neat mechanism that provides a common interface to what used to be language-specific lookup mechanisms (like, say, running a Python interpreter in the background to find function definitions).
There is also ctags shipped with UNIX since forever, but that doesn't support looking backwards ("who uses this function"), linting, or refactoring. In short, LSP rocks, and how do I use it right now in my editor of choice (Emacs, in my case) and OS (Debian) please?
Editor (emacs) setup
First, you need to setup your editor. The Emacs LSP mode has pretty good installation instructions which, for me, currently mean:
apt install elpa-lsp-mode
and this .emacs
snippet:
(use-package lsp-mode
:commands (lsp lsp-deferred)
:hook ((python-mode go-mode) . lsp-deferred)
:demand t
:init
(setq lsp-keymap-prefix "C-c l")
;; TODO: https://emacs-lsp.github.io/lsp-mode/page/performance/
;; also note re "native compilation": <+varemara> it's the
;; difference between lsp-mode being usable or not, for me
:config
(setq lsp-auto-configure t))
(use-package lsp-ui
:config
(setq lsp-ui-flycheck-enable t)
(add-to-list 'lsp-ui-doc-frame-parameters '(no-accept-focus . t))
(define-key lsp-ui-mode-map [remap xref-find-definitions] #'lsp-ui-peek-find-definitions)
(define-key lsp-ui-mode-map [remap xref-find-references] #'lsp-ui-peek-find-references))
Note: this configuration might have changed since I wrote this, see my init.el configuration for the most recent config.
The main reason for choosing lsp-mode
over eglot is that it's in
Debian (and eglot is not). (Apparently, eglot has more chance of being
upstreamed, "when it's done", but I guess I'll cross that bridge when
I get there.)
I already had lsp-mode
partially setup in Emacs so I only had to do
this small tweak to switch and change the prefix key
(because s-l or mod is used by my window
manager). I also had to pin LSP packages to bookworm here so that
it properly detects pylsp
(the older version in Debian bullseye only
supports pyls
, not packaged in Debian).
This won't do anything by itself: Emacs will need something to talk with to provide the magic. Those are called "servers" and are basically different programs, for each programming language, that provide the magic.
Servers setup
The Emacs package provides a way (M-x lsp-install-server)
to install some of them, but I prefer to manage those tools through
Debian packages if possible, just like lsp-mode
itself. Those are
the servers I currently know of in Debian:
package | languages |
---|---|
ccls |
C, C++, ObjectiveC |
clangd |
C, C++, ObjectiveC |
elpa-lsp-haskell |
Haskell |
fortran-language-server |
Fortran |
gopls |
Golang |
python3-pyls |
Python |
There might be more such packages, but those are surprisingly hard to
find. I found a few with apt search "Language Server Protocol"
, but
that didn't find ccls
, for example, because that just said "Language
Server" in the description (which also found a few more pyls
plugins,
e.g. black
support).
Note that the Python packages, in particular, need to be upgraded to their bookworm releases to work properly (here). It seems like there's some interoperability problems there that I haven't quite figured out yet. See also my Puppet configuration for LSP.
Finally, note that I have now completely switched away from Elpy
to pyls, and I'm quite happy with the results. lsp-mode
feels slower
than elpy
but I haven't done any of the performance tuning
and this will improve even more with native compilation. And
lsp-mode
is much more powerful. I particularly like the "rename
symbol" functionality, which ... mostly works.
Remaining work
Puppet and Ruby
I still have to figure how to actually use this: I mostly spend my time in Puppet these days, there is no server listed in the Emacs lsp-mode language list, but there is one listed over at the upstream language list, the puppet-editor-services server.
But it's not packaged in Debian, and seems somewhat... involved. It could still be a good productivity boost. The Voxpupuli team have vim install instructions which also suggest installing solargraph, the Ruby language server, also not packaged in Debian.
Bash
I guess I do a bit of shell scripting from time to time nowadays, even though I don't like it. So the bash-language-server may prove useful as well.
Other languages
Here are more language servers available:
- upstream language list: all servers known to upstream
- Emacs lsp-mode language list: all servers known to the Emacs mode
Thank you for featuring the emacs lsp setup. My goal is to have a usable Haskell development environment in Debian only one
apt install
away.Unfortunately the elpa-lsp-haskell package is not the Haskell language server but only a small emacs package to connect to it, see this RFP instead:
#968373 RFP: hls+ghcide -- Haskell Development Environment and Language Server