When LSP gets lost
A quick win that has saved me minutes of searching online documentation while I'm deep in a Ruby codebase is combining the power of a language server with predecessors like Robe.
Most of the time, LSP via eglot
in Emacs is hugely empowering. The wealth of
available server implementations provide some combination of formatting buffers,
navigating code, and other capabilities.
Not all servers are equal however, and sometimes the most desirable of operations aren’t available. In those cases one can rely on language-specific tooling that came before Microsoft standardised so much off the back of VSCode.
The solution below is specific to Doom as it relies on the lookup
module to
maintain a list of functions capable of satisfying our requests. One by one,
functions are applied until a non-nil response indicates a capable link in the
chain.
(after! eglot
(add-to-list 'eglot-server-programs
`((ruby-mode ruby-ts-mode)
. ,(eglot-alternatives '(("ruby-lsp")
("solargraph" "socket" "--port" :autoport)))))
(after! ruby-mode
(when (featurep! :tools lookup)
(add-to-list '+lookup-definition-functions #'robe-jump 'append))))
The key is we append robe-jump
to allow eglot
its shot. Only if our language
server fails miserably do we lean on a running Ruby process to navigate deep
into the internals of Rails to find a function surprisingly lacking in
transactionality.
As my heart sinks, I kinda wish I hadn’t seen that implementation now.