astoff / buffer-env

Buffer-local process environments for Emacs
61 stars 9 forks source link

Fails to activate virtualenv interactively #22

Closed jgarte closed 1 year ago

jgarte commented 1 year ago

You can also call buffer-env-activate interactively and select the activate script directly.

Hi,

buffer-env-update fails to set up .venv/vin/activate at all.

I am using the version of buffer-env currently in elpa.

What should I try to debug this further?

GNU Emacs 28.2 (build 1, x86_64-redhat-linux-gnu, GTK+ Version 3.24.38, cairo version 1.17.8) of 2023-06-05

Here is the relevant config for buffer-env in my init.el:

;;; Handle Python virtualenvs and Guix manifests.
(unless (package-installed-p 'buffer-env)
  (package-install 'buffer-env))

I then attempt to run buffer-env-update on .venv/bin/activate interactively in my project directory where I created the virtualenv but that fails.

I use virtualenvs successfully on a daily basis with pyvenv but would like to use buffer-env instead.

astoff commented 1 year ago

How does it fail? Note that the interactive command only sets the buffer env of the current buffer, not the entire project.

jgarte commented 1 year ago

Hi,

It fails silently. That is, no pip installed packages are available in my current buffer from the virtualenv that I set up.

The package I usually test this out with is jedi-language-server.

I call eglot and eglot does not find the said language server.

When I try with pyvenv, it works fine.

I'm aware of the issue with having to use inheritenv in conjunction with buffer-env in order for environments to propagate across buffers (comint, etc).

jgarte commented 1 year ago

In the meantime I stopped using buffer-env, but let me know if you'd like me to reproduce anything in particular.

If you share a config or steps for me to try, that might be the best approach to testing this and seeing where the problem may be.

Do virtualenv's work for you currently? What is your workflow? How do you have buffer-env set up to use Python virtualenv's?

astoff commented 1 year ago

Okay, Eglot is a bit complicated since it starts a process asynchronously, but nonetheless it works fine for me (no need for any inheritenv advices). A simple test you can do is, after updating the environment, is M-! env RET. If you see the right PATH, then buffer-env is working.

All I have in my config is this:

(add-hook 'hack-local-variables-hook 'buffer-env-update)
(setq buffer-env-script-name '(".envrc" ".venv/bin/activate"))
;; Plus the inheritenv advice around `python-shell-make-comint'.
quotuva commented 1 year ago

I have seemingly the same problem, which can be fixed by changing the (sit-for 0) line to (sit-for 1).

jgarte commented 1 year ago

@quotuva

That sounds like a plausible cause.

I'll do some more testing this week with your change to see if it also fixes it for me.

jgarte commented 1 year ago

Okay, Eglot is a bit complicated since it starts a process asynchronously, but nonetheless it works fine for me (no need for any inheritenv advices). A simple test you can do is, after updating the environment, is M-! env RET. If you see the right PATH, then buffer-env is working.

All I have in my config is this:

(add-hook 'hack-local-variables-hook 'buffer-env-update)
(setq buffer-env-script-name '(".envrc" ".venv/bin/activate"))
;; Plus the inheritenv advice around `python-shell-make-comint'.

@astoff This didn't work for me.

astoff commented 1 year ago

@quotuva Can you reproduce this with emacs -q and using a minimal .envrc file? Also, which OS are you on?

(One more thing you could try: keep (sit-for 1) in buffer-env.el but add sleep 5 in your .envrc file.)

quotuva commented 1 year ago

Can you reproduce this with emacs -q

I can't. :D

The only explanation I can think of is that using all the packages slows down the system to cause this.

add sleep 5 in your .envrc file

I don't use direnv. I simply add .venv/bin/activate to buffer-env-script-name.

EDIT:

Also, which OS are you on?

Ubuntu 22

EDIT2:

Just FYI: When this happens, the vars local variable is nil because the temporary buffer is empty. But the process-live-p part does not happen.

astoff commented 1 year ago

the vars local variable is nil because the temporary buffer is empty

Okay, I should add an error message in this case. But I still don't get why your temp buffer ends up empty.

I don't use direnv. I simply add .venv/bin/activate to buffer-env-script-name.

It's still a shell script, you could add a long sleep to check if buffer-env is actually waiting for the process to end (I'm staring at the code and can't see how this could go wrong)

quotuva commented 1 year ago

But I still don't get why your temp buffer ends up empty.

I'm just guessing: The process exit status is 0, but Emacs hasn't updated the buffer yet. I don't know if that's impossible.

It's still a shell script, you could add a long sleep

Yes, I did that and it works fine then.

astoff commented 1 year ago

I guess you're right, see "this loop contains a bug" here: https://www.gnu.org/software/emacs/manual/html_node/elisp/Accepting-Output.html

What if you replace this:

https://github.com/astoff/buffer-env/blob/e0152203116424446eb1f24f7f83396a7b81f498/buffer-env.el#L215-L216

by this:

                           (sit-for 0)
                           (if (not (process-live-p proc)) (accept-process-output proc 1)
quotuva commented 1 year ago

What if you replace this: ... by this:

Works! Thank you! I hope @jgarte can also confirm (if this is indeed his problem).