-
Notifications
You must be signed in to change notification settings - Fork 321
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
perf(shell/zsh.rs): avoid hook-env execution on Enter without command #2861
Conversation
Some zsh configuration are intentionally optimized to work really fast and it's important to keep it feels this way. And while `mise hook-env` is really fast (0.008 sec on my system) and slowdown isn't noticeable when running any command (even builtin one like `echo` or `true`) it still result in _noticeable_ slowdown when just pressing Enter without any command. At a glance proposed optimization shouldn't break any functionality, and it fixes mentioned above noticeable slowdown.
Fixes an issue when directory is changed after empty command (just Enter) using keyboard shortcut (e.g. Ctrl-PgUp/Down) instead of `cd` command - in this case hook wasn't triggered which result in showing other project's env variables to first command executed in non-project dir.
This fixes two cases: - Optimization bug: first command in a new shell won't get right env. - Adds support for `zsh -i -c '...'` which also won't get right env.
src/shell/zsh.rs
Outdated
@@ -20,6 +20,8 @@ impl Shell for Zsh { | |||
export MISE_SHELL=zsh | |||
export __MISE_ORIG_PATH="$PATH" | |||
|
|||
eval "$({exe} hook-env{flags} -s zsh)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fixes two issues:
- One is related to this PR: first command in a new zsh won't get right env because of this PR's optimization.
- Another issue is not related to this PR and fixes
zsh -i -c '...'
- current mise implementation won't provide right env to the command executed inside child zsh.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't remember why but there is a reason I chose not to run hook-env automatically
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't remember why but there is a reason I chose not to run hook-env automatically
Sometimes only way to recall it is to change a code and wait until something breaks.
I'm not sure is missing env in a zsh -i -c '...'
considered a real issue. This is probably a real "corner" case and might not worth supporting: without -i
it won't load Mise anyway, but -i
with -c
makes not much sense and in my experience it used mostly for testing zsh performance - how fast it loads user configs in interactive mode.
Still, your doc example in https://mise.jdx.dev/dev-tools/shims.html#zshrc-bashrc-files ask user to run it manually after activation - which has exactly same effect as my change to run it automatically but require extra manual change in user's config. Also, same 2-command example is repeated in https://mise.jdx.dev/troubleshooting.html#mise-isn-t-working-when-calling-from-tmux-or-another-shell-initialization-script.
So, I'm not joking here: if you can't remember why you chose not to run hook-env automatically then in current situation I think it makes sense to start running it automatically - this way it either will work and let you simplify UX and clean up docs, or breaks and this time you'll add a comment somewhere describing why it's bad idea to run it automatically on activation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this was the reason: #204 (comment)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If that dotenv conflict is still actual, then you probably need to mention needs to manually add second line with hook-env in shell rc files at https://mise.jdx.dev/getting-started.html#_2-activate-mise (and maybe with a note about direnv and what to do between these two lines to avoid conflict with dotenv.
Also, if |
It could be my particular setup, but I'm finding that the source <(mise activate zsh)
function _mise_hook {
source <(mise hook-env -s zsh)
ZLAST_COMMANDS="" # prevent precmd hook also triggering
}
ZLAST_COMMANDS="_" # ensure the precmd hook executes initially |
I think it's better to do
This may breaks other things which use +typeset -g mise_skip_hook_cmd
_mise_hook() {
eval "$(mise hook-env -s zsh)";
+ mise_skip_hook_cmd=1
}
_mise_hook_cmd() {
- if [[ -n "$ZLAST_COMMANDS" ]]; then
+ if [[ -n "$ZLAST_COMMANDS" && -z "$mise_skip_hook_cmd" ]]; then
_mise_hook;
fi
+ mise_skip_hook_cmd=
} If you like to avoid this extra complexity then this one will works too in most (but not all) cases: - if [[ -n "$ZLAST_COMMANDS" ]]; then
+ if [[ -n "$ZLAST_COMMANDS" && "$ZLAST_COMMANDS" != "cd" ]]; then |
Good point, @powerman I ended up with this solution, which seems to work well for me, and doesn't rely on _last_mise_hook_trigger=""
function _mise_hook_chpwd {
_mise_hook
_last_mise_hook_trigger="chpwd"
}
chpwd_functions[1]=_mise_hook_chpwd
function _mise_hook_precmd {
if [[ ${_last_mise_hook_trigger} == "precmd" ]]; then
_mise_hook
fi
_last_mise_hook_trigger="precmd"
}
precmd_functions[1]=_mise_hook_precmd |
Some zsh configuration are intentionally optimized to work really fast and it's important to keep it feels this way. And while
mise hook-env
is really fast (0.008 sec on my system) and slowdown isn't noticeable when running any command (even builtin one likeecho
ortrue
) it still result in noticeable slowdown when just pressing Enter without any command.At a glance proposed optimization shouldn't break any functionality, and it fixes mentioned above noticeable slowdown.