jorgebucaran / nvm.fish

The Node.js version manager you'll adore, crafted just for Fish
https://git.io/nvm.fish
MIT License
2.06k stars 69 forks source link

Default version is only set in the interactive shell #219

Closed docmg closed 5 months ago

docmg commented 6 months ago

Hello,

I have a question: Why do we check if the shell is interactive before setting the default node version?

I had the Problem with my SublimeText, because it is using non-interactive shell session to check if node is installed. After removing status is-interactive && everything worked fine, but it was pain to find out what is causing the problem. :) https://github.com/jorgebucaran/nvm.fish/blob/c69e5d1017b21bcfca8f42c93c7e89fff6141a8a/conf.d/nvm.fish#L26


Some others Sublime-Users had the same Problem. For example:

jorgebucaran commented 5 months ago

@docmg Apologies for the delay in responding.

We conditionally set the node environment based on the interactive status because initializing Node can take a bit of time (even if it's "fast" enough, it's non-trivial). When launching a new terminal or using Fish in a subshell, nvm.fish sets the default Node only if nvm_default_version has been explicitly set. Setting the default Node in non-interactive sessions is 👎 for two main reasons:

Think about it: having nvm.fish set Node behind the scenes in non-interactive sessions introduces a sneaky dependency. Looks like that might've been what you were going for in a simple, one-time setup, but as things get more complex with your shell, you could run into scenarios where you're scratching your head, wondering why your Node version was set and don't know what set it. My rule of thumb is: do the fancy stuff only if interactive.

If you absolutely must set your Node version automatically in every shell session, interactive or not, you can always make a configuration snippet and throw in an nvm use VERSION in it. But I claim you'll quickly find that approach limiting, and soon be looking for a way to tweak when and how your Node gets set with a bit more precision.

jorgebucaran commented 5 months ago

To tackle the ST issue, it looks like it spawns a non-interactive shell to check the environment. This means it won't automatically pick up the Node version you've set as your default in nvm_default_version; instead, it falls back to the system default or none at all. To me, that seems like a smart default. It's pretty much doing what it should, and it's kind of the flip side of the point I made earlier about the concern of having nvm.fish set Node in the background for non-interactive shells, which introduces a weak dependency.

Your interactive shell is like a "private" Fish REPL session, and a non-interactive shell a "global" one. Obviously, you'll want to keep the global's environment as clean as possible.

To sort out the issue with ST, they might set a specific variable in the environment when they spawn that non-interactive Fish session (I don't know if they do, but it would made sense if they did). You can check for this variable in a configuration snippet. That way, you'll know when you're in one of those non-interactive sessions created by ST, and then you can set Node then. You can use nvm use default, a shorthand supported by nvm.fish that sets the default version based on the $nvm_default_version.