lsp-mode icon indicating copy to clipboard operation
lsp-mode copied to clipboard

Consider using the inheritenv package

Open mrkkrp opened this issue 3 years ago • 4 comments

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 have envrc-mode enabled and also doesn’t inherit process-environment from the source buffer. The solution is probably for lsp-mode to start using my new inheritenv 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.

mrkkrp avatar Feb 04 '21 21:02 mrkkrp

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.

purcell avatar Feb 05 '21 01:02 purcell

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.

yyoncho avatar Mar 11 '21 19:03 yyoncho

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.

purcell avatar Mar 11 '21 20:03 purcell

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))

Hodapp87 avatar Jun 05 '22 15:06 Hodapp87

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

peterbecich avatar Feb 05 '23 21:02 peterbecich

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?

toniz4 avatar Mar 19 '23 12:03 toniz4