powerlevel10k: `reset-prompt` doesn't show changed directory

How to reproduce it: 1.

docker run -e LANG=C.UTF-8 -e LC_ALL=C.UTF-8 -e TERM=$TERM -it --rm ubuntu bash -uexc '
  cd
  apt update && apt install -y zsh git vim
  git clone https://github.com/romkatv/powerlevel10k.git
  echo "
    cd_pp() {
      cd ..
      zle .reset-prompt && zle -R
    }
    zle -N cd_pp
    bindkey '\''^[[1;5A'\'' cd_pp
    source ~/powerlevel10k/powerlevel10k.zsh-theme" >~/.zshrc
  exec zsh'
  1. press <ctrl-up>
  2. press <enter> or type pwd

image

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 94 (90 by maintainers)

Most upvoted comments

Not sure if this is helpful but I just discovered:

zle push-line
zle accept-line

For redrawing the prompt without executing the line and maintaining the contents of the line and not setting the error code to 1 😃

This is now fixed. Here’s a summary of the ZSH bug.

Bug introduced in https://github.com/zsh-users/zsh/commit/d8d9fee137a5aa2cf9bf8314b06895bfc2a05518. ZSH_PATCHLEVEL=zsh-5.4.2-159-gd8d9fee13. Released in 5.5.

Bug fixed in https://github.com/zsh-users/zsh/commit/64d13738357c9b9c212adbe17f271716abbcf6ea. ZSH_PATCHLEVEL=zsh-5.7.1-50-g64d137383. Not released yet.

Test (fails on buggy ZSH, passes on correct ZSH):

PROMPT="${(pl:$((COLUMNS))::-:)}<%1(l.%2(l.FAIL.PASS).FAIL)> " zsh -dfis <<<exit

Workaround (passes on buggy ZSH, fails on correct ZSH):

PROMPT="${(pl:$((COLUMNS))::-:)}%{%G%}<%1(l.%2(l.FAIL.PASS).FAIL)> " zsh -dfis <<<exit

Unfortunately, the workaround cannot be applied unconditionally. Doing so would break p10k on ZSH without the bug. So now there is a branch in p10k to apply the workaround if and only if ZSH has the bug. Code: https://github.com/romkatv/powerlevel10k/blob/8b8743c8edc548981274184cfc922757e99df0ea/powerlevel9k.zsh-theme#L2331

I also enabled the display of the number of staged and unstaged changes in git prompt in Pure Power. It’s a new feature I implemented last week when a user asked for it. I haven’t used it myself yet. Not sure it’s worth the real estate. You might like it as you generally prefer more bells and whistles in the prompt.

These are controlled by POWERLEVEL9K_VCS_MAX_NUM_{STAGED,UNSTAGED,UNTRACKED}. In Pure Power I set them like this:

POWERLEVEL9K_VCS_MAX_NUM_STAGED=-1
POWERLEVEL9K_VCS_MAX_NUM_UNSTAGED=-1
POWERLEVEL9K_VCS_MAX_NUM_UNTRACKED=1  # this is the default

It’ll show all staged and unstaged but only an icon for untracked. Make sure to not set POWERLEVEL9K_VCS_MAX_NUM_UNTRACKED=-1 as it’ll cause massive performance issues in some cases. If you want to see the number of untracked files, use POWERLEVEL9K_VCS_MAX_NUM_UNTRACKED=99.

In case you missed it, ZSH_AUTOSUGGEST_MANUAL_REBIND=1 is a great way to reduce latency with no adverse side effects.

What does it do? From the name I would guess it enables to rebind stuff, which - as far as I know - I don’t do.

With ZSH_AUTOSUGGEST_MANUAL_REBIND=1 zsh-autosuggestions behaves like a regular plugin – it wraps all zle widgets only once during initialization.

With ZSH_AUTOSUGGEST_MANUAL_REBIND=0 it wraps them during initialization but also on every precmd. This allows you to define new zle widgets in an interactive prompt (rather than in ~/.zshrc) and have them instantly be recognized by zsh-autosuggestions. Needless to say, no one does that, and no one expects changes made to zle widgets in an interactive prompt to propagate into plugins without restarting zsh or at least re-sourcing ~/.zshrc.This extravagance costs a lot though.

It’s almost certain that there would not even be an option like ZSH_AUTOSUGGEST_MANUAL_REBIND=0 right now if the default behavior of zsh-autosuggestions was ZSH_AUTOSUGGEST_MANUAL_REBIND=1 to begin with. Case in point is zsh-syntax-highlighting. It also needs to wrap all zle widgets to work correctly but doesn’t have the option to do it on every precmd. So even if you don’t set ZSH_AUTOSUGGEST_MANUAL_REBIND=1, you still cannot define widgets in an interactive session, because no plugins other than zsh-autosuggestions will pick them up.

tl;dr: Set ZSH_AUTOSUGGEST_MANUAL_REBIND=1. The only difference you’ll notice is faster prompt.

Now that I think of it, writing my own i3blocks script with the same logic as the battery segment might solve these issues. Same for vpn_ip.

☝️

Are there any other functions beside powerlevel9k_prepare_prompts that should be called to reset it properly?

This is an internal function. You technically can call internal functions but if you do, you are on your own.

By refreshing the prompt I meant calling zle accept-line. This will do everything that’s necessary to refresh prompt and will work with any theme.

Thanks for the high-quality bug report. The docker command is especially appreciated.

reset-prompt doesn’t show changed directory

In this formulation I’m tempted to say this is not an issue. Powerlevel10k indeed doesn’t reevaluate the whole prompt on reset-prompt. It’s not just dir prompt, either. If you add git something in cd_pp, git prompt won’t be updated. Same thing for pyenv local system and pyenv prompt. In fact, every theme that installs a precmd can be “broken” in this way by changing external environment from a zle widget.

The fact that Powerlevel10k doesn’t reevaluate some parts of the prompt is a feature. This enables things like responsive vi_mode that would be be impossible to provide if reset-prompt reevaluated the whole prompt.

Does the example you gave represent a real problem you are trying to solve? If so, there are solutions. The simple solution is this:

cd_pp() {
  cd ..
  BUFFER=
  zle accept-line
}

The downside is that it’ll clear your buffer, so you cannot type a command, press <ctrl-up> and then execute the command in the new directory. This can be solved with some extra code. In my dotfiles I bind <alt-left> to go to the previous directory, <alt-right> to go to the next, <alt-up> to cd .. (the same as you have on <ctrl-up>) and <alt-down> to print directory history (to know where <alt-left> and <alt-right> will go). None of these clear the buffer. The code isn’t complex but I have it in a rather messy state, so it can be difficult to read.

Here’s a demo: https://asciinema.org/a/CKhNEndylHW7uOxFmWcKoESfQ.

I first populate directory history by executing cd a bunch of times. Then I show this history with dirs -v and again by pressing <alt-down>. Then I type p and press <alt-left> (go back in history) and <alt-right> (go forward in history) and finish with another <alt-down>.

I forgot to mention that <alt-left>, <alt-right> and <alt-up> print directory history but it’s truncated at 3 entires. <alt-down> prints longer history (truncated at 20).

Notice that it plays nice with zsh-autosuggestions and zsh-syntax-highlighting. The color of p in the prompt changes depending on whether the current directory has a subdirectory whose name starts with p or not, so it has the same color as if I typed p in that directory.

If these workarounds are good enough for you, I suggest to close the issue. If not, please describe what you are trying to achieve.