romkatv/powerlevel10k

Direnv and instant prompt: Minor question

Closed this issue ยท 14 comments

I have my zshrc set up as such:

# Enable direnv
eval "$(direnv hook zsh)"

# Enable Powerlevel10k instant prompt. Should stay at the top of ~/.zshrc.
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
  source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi

This works for standard prompts, however, when using TMUX or opening a new terminal tab, it seems to trigger the following error in powerlevel10k's instant prompt initialization

[WARNING]: Console output during zsh initialization detected.

When using Powerlevel10k with instant prompt, console output during zsh
initialization may indicate issues.

You can:

  - Recommended: Change ~/.zshrc so that it does not perform console I/O
    after the instant prompt preamble. See the link below for details.

    * You will not see this error message again.
    * Zsh will start quickly and prompt will update smoothly.

  - Suppress this warning either by running p10k configure or by manually
    defining the following parameter:

      typeset -g POWERLEVEL9K_INSTANT_PROMPT=quiet

    * You will not see this error message again.
    * Zsh will start quickly but prompt will jump down after initialization.

  - Disable instant prompt either by running p10k configure or by manually
    defining the following parameter:

      typeset -g POWERLEVEL9K_INSTANT_PROMPT=off

    * You will not see this error message again.
    * Zsh will start slowly.

  - Do nothing.

    * You will see this error message every time you start zsh.
    * Zsh will start quickly but prompt will jump down after initialization.

For details, see:
https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt

-- console output produced during zsh initialization follows --

direnv: loading ~/Repositories/lab/interactive_physics/.envrc
direnv: export +POETRY_ACTIVE +VIRTUAL_ENV ~PATH

I'm not quite sure why instant prompt would only fail in tmux or a new tab, and not when opening a normal shell. Sorry if this is a configuration issue that has been noted! I tried a search but didn't find anything. Edit, this makes sense in retrospect, because direnv only outputs to stdout during prompt initialization when there is a .envrc in the current directory the shell is being initialized in.

Please read the error message. What isn't clear?

Sorry, I should have phrased differently, I'm aware that direnv outputs to stdout when there is a detected envrc. Is there currently no way to use both direnv and instant prompt concurrently without running into this issue? Given this:

  - Recommended: Change ~/.zshrc so that it does not perform console I/O
    after the instant prompt preamble. See the link below for details

I assumed that sourcing the direnv hook before initializing instant prompt would fix the issue, but it did not.

I assumed that sourcing the direnv hook before initializing instant prompt would fix the issue, but it did not.

The output isn't produced by the line you put at the top. It's produced later, from precmd.

I suggest you do the following.

emulate zsh -c "$(direnv export zsh)"

if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
  source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi

emulate zsh -c "$(direnv hook zsh)"

In addition, since you've read and understood the warning from instant prompt, I advise you to set POWERLEVEL9K_INSTANT_PROMPT=quiet in ~/.p10k.zsh.

emulate zsh -c "$(direnv hook zsh)"

That fixed it! I like keeping the warning in case I accidentally add something that slows down my shell (like this haha). Thank you :)

I know this is closed, but it's the first hit I found when searching for this issue.

I run into this when I start a tmux session within a Direnv. Rather than disabling the warning globally, you can disable only within the environment.

e.g. in your .envrc, put:

export POWERLEVEL9K_INSTANT_PROMPT=quiet

Now if you're in a Direnv and spawn another shell, it will disable the warning. But verbose is still enabled globally.

export POWERLEVEL9K_INSTANT_PROMPT=quiet

Since you know what the warning says, you can disable it globally. It doesn't suppress output, only removes the warning. Whenever you see output, you can imagine you are seeing the warning too.

@jameskyle Have you noticed the solution in #702 (comment)?

Yeah, seemed a bit 'heavy'. I put the prompt disable export in my .direnvrc as a layout_p10k function. Seemed simple and would only effect Direnv's.

Yeah, seemed a bit 'heavy'.

???

Yeah, seemed a bit 'heavy'.

???

So the emulate calls would throw an error if direnv isn't installed. So you'd want to wrap them in a check for the command. It would also run and source the cache in all new shells, but I was only seeing the warning when I'd create a tmux pane in a direnv.

By creating a hook in the direnvrc, my zsh config remain the same, there's no cache sourcing, no need to test if direnv command exists, and the only time anything changes from default is in the narrow case where I saw the warning.

Should #702 (comment) get added to doc somewhere?

I agree with @mjlbach that setting export POWERLEVEL9K_INSTANT_PROMPT=quiet seems like it could risk masking future configuration mistakes.

@matschaffer Good idea. I've added this FAQ entry: https://github.com/romkatv/powerlevel10k#how-do-i-initialize-direnv-when-using-instant-prompt

Note that direnv adds non-trivial amount of latency to every command even when it's not loading/unloading anything. Powerlevel10k cannot help you with it on its own. There is much faster integration with direnv in zsh4humans.

Looks great @romkatv ! And thanks for the tip. I hadn't noticed zsh4humans yet. Will have to give it a try :)

muraii commented

I know this is closed, but it's the first hit I found when searching for this issue.

I run into this when I start a tmux session within a Direnv. Rather than disabling the warning globally, you can disable only within the environment.

e.g. in your .envrc, put:

export POWERLEVEL9K_INSTANT_PROMPT=quiet

Now if you're in a Direnv and spawn another shell, it will disable the warning. But verbose is still enabled globally.

Thank you. This worked a treat.