purcell / exec-path-from-shell

Make Emacs use the $PATH set up by the user's shell
Other
1.43k stars 82 forks source link

does not work with nvm and zsh. #115

Closed jleonard-r7 closed 10 months ago

jleonard-r7 commented 1 year ago

I tried the following nvm setup logic in both .zprofile and .zshenv:

export NVM_DIR="$HOME/.nvm"
[ -s "/opt/homebrew/opt/nvm/nvm.sh" ] && \. "/opt/homebrew/opt/nvm/nvm.sh"  # This loads nvm

Both options work fine for a regular shell but neither works for exec-path-from-shell.

I also tried both:

    (setq exec-path-from-shell-arguments nil)

and

    (setq exec-path-from-shell-arguments "-i")

for interactive and non-interactive options.

purcell commented 1 year ago

When you set exec-path-from-shell-debug to t, what information do you get in the *Messages* buffer?

purcell commented 1 year ago
 (setq exec-path-from-shell-arguments "-i")

This would have been invalid, by the way — the value would have needed to be '("-i"). But in any case, it seems like that's not the issue.

jleonard-r7 commented 1 year ago
```emacs-lisp
 (setq exec-path-from-shell-arguments "-i")

This would have been invalid, by the way — the value would have needed to be '("-i"). But in any case, it seems like that's not the issue.

Ah yea. I wasn't sure about that. Thought it may have needed to be a collection but, as you said, since I ruled out that being the issue, didn't look further into it.

jleonard-r7 commented 1 year ago

When you set exec-path-from-shell-debug to t, what information do you get in the *Messages* buffer?

Invoking shell /bin/sh with args ("-l" "-i" "-c" "/usr/bin/printf '__RESULT\\000%s\\000%s\\000__RESULT' \"${PATH-1ddf68632ff867b3cab1759db88f31b5}\" \"${MANPATH-1ddf68632ff867b3cab1759db88f31b5}\"")
Shell execution took 68ms
Shell printed: "Restored session: Tue Jun 13 16:40:15 PDT 2023
__RESULT/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/Users/jleonard/.cargo/bin:/Users/jleonard/Library/Python/3.10/bin:/Users/jleonard/Library/Python/2.7/bin:/Users/jleonard/activator:/Users/jleonard/bin:/usr/local/mysql/bin:/opt/local/bin:/opt/local/sbin:/usr/local/mongodb/bin:/usr/local/scheme/bin:/usr/local/sbin:/Users/jleonard/.rvm/bin:/opt/homebrew/opt/fzf/bin:/opt/homebrew/Cellar/emacs-plus@29/29.0.90/libexec/emacs/29.0.91/aarch64-apple-darwin22.5.0/usr/share/man:/usr/local/share/man:/opt/homebrew/share/man:__RESULT-ne 
Saving session...
-ne 
...copying shared history...
-ne 
...saving history...
-ne 
...
completed.
"
purcell commented 1 year ago

Okay, so consider what does nvm.sh actually does. It's a script that is sourced, not executed, so presumably it overrides behaviour in the parent shell. It doesn't seem to modify $PATH directly, because that effect would be visible in the output above and would be picked up by exec-path-from-shell. Instead, it looks like it uses aliases in the host shell. Aliases are never visible beyond the host shell, so these can't ever affect exec-path-from-shell. Indeed, the nvm README says

Please note that which nvm will not work, since nvm is a sourced shell function, not an executable binary.

Since the goal here is to potentially have different node versions per project, an alternative approach for you here is to use direnv, which I personally use extensively via my popular envrc.el package to get per-project environments. Here's an example of how to set it up with nvm.