lsp-mode
lsp-mode copied to clipboard
Consider using the inheritenv package
This is not strictly a bug per se, but perhaps an opportunity for improvement. I have recently tried to use lsp-mode
in conjunction with direnv-mode
. A directory-specific environment provided ocamllsp
—OCaml LSP executable and the two modes worked together nicely. Later, I became frustrated with delays that happen when one switches between buffers with direnv-mode
enabled. Fortunately, there exists an alternative to direnv-mode
that solves exactly that problem. It is called envrc
by @purcell. Unfortunately, when I tried to pair lsp-mode
with envrc-mode
it did not work. The locally provided ocamllsp
was not visible to lsp-mode
and I suspect the rest of local environment was ignored, too. I contacted @purcell and here is what he told me:
In short,
lsp-mode
probably starts process in a temp buffer which doesn't haveenvrc-mode
enabled and also doesn’t inherit process-environment from the source buffer. The solution is probably forlsp-mode
to start using my newinheritenv
package so that it respects any buffer-local environment preferences the user might have.
I do not have good understanding of what is going on and what should be changed. I just thought that maybe it'd be good to open an issue and mention @purcell in it so that a discussion can be started.
Yes, basically the issue is that if a user has a buffer-local process-environment
, then that is the environment that should be used when finding and starting an LSP backend process for that buffer. It's easy to mess this up by starting processes in other (particularly temporary) buffers, though, and inheritenv
makes it a bit easier for authors to propagate the environment variables to those buffers.
It seems to me that the only thing that we do that might affect this is to bind default-directory to the project root when starting the process. I am not sure how to reproduce the issue though and how to fix it.
I don't use lsp-mode myself, but I guess the way to test it without setting up direnv etc. locally would be to set the exec-path
and process-environment
buffer-locally in a source code buffer and then start the lsp backend. The executable and environment used by lsp-mode to start the backend should be the buffer-local one if everything is working correctly.
e.g.
(setq-local process-environment '("PATH=foobar"))
(setq-local exec-path '("foobar"))
then start the LSP backend. With these settings, the result should be that the executable is not found.
To add a note to this since I was also running into issues with trying to use lsp-mode
and envrc
: I followed what https://github.com/purcell/envrc/issues/31 said and using lsp-deferred
seemed to solve my issue:
(use-package lsp-mode
:hook (python-mode . lsp-deferred)
:commands (lsp lsp-deferred))
I agree lsp-deferred
fixes it.
In my case it is clangd
:
(use-package lsp-mode
:hook (
(c++-mode . lsp-deferred)
...
)
:commands (lsp-deferred)
...)
With this configuration, lsp-mode
finds the clangd
provided by .envrc
.
With the standard configuration, lsp-mode
installs clangd
and is unaware of the .envrc
.
Thanks
I have the same problem, but with the dap mode, when trying to run the dap debugger on a flutter project, it does not find the java executable nor the JAVA_HOME variable. Both are visible in the envrc env.
Should I open a issue at dap-mode?