jdx / mise

dev tools, env vars, task runner
https://mise.jdx.dev
MIT License
9.17k stars 248 forks source link

`mise activate` switch between interactive script and shims #1886

Open texastoland opened 5 months ago

texastoland commented 5 months ago

I found a dead simple pattern (confirmed in both zsh and bash):

if [[ -t 0 ]]; then # terminal has stdin i.e. interactive
  eval "$(mise activate "$SHELL_NAME")"
else
  eval "$(mise activate --shims)"
fi

Explained in my tweets:

Modern editors either receive their environment from the command line or more often read it similar to zsh -ilc env. That session is "interactive" (and login) in order to trigger all user configs. But that broke my dotfile's assumption. But how to check "interactive"? AFAICT [[ -t 0 ]] might be what I'm looking for because it fails (false) when editors are reading the environment

Would you be interested in either PR:

kjkent commented 5 months ago

if it helps anyone, $shell_name (I use lowercase vars in scripts to avoid global env clashes) can be pulled from $SHELL with:

echo -n "$SHELL" | sed 's>.*/>>'

I believe -n (no newline) isn't portable, but I'm unsure if it's necessary.

My .zshenv includes:

if type mise &> /dev/null; then
        if [[ -t 0 ]]; then # terminal has stdin i.e. interactive
                shell_name="$(echo "$SHELL" | sed -E 's>.*/>>')"
                eval "$(mise activate "$shell_name")"
        else
                eval "$(mise activate --shims)"
        fi
fi

Thanks for the tip :)

texastoland commented 5 months ago

$shell_name ... can be pulled from $SHELL

Yeah there are a few ways. Some of them had unexpected behavior in subshells for example. I chose the following in my .zshrc:

SHELL_NAME=${ZSH_VERSION:+zsh}${BASH_VERSION:+bash} # also sourced in .bashrc

A hypothetical --auto flag might be able to do that too.