Powerlevel9k / powerlevel9k

Powerlevel9k was a tool for building a beautiful and highly functional CLI, customized for you. P9k had a substantial impact on CLI UX, and its legacy is now continued by P10k.
https://github.com/romkatv/powerlevel10k
MIT License
13.46k stars 948 forks source link

Extra space added to left of commands (right of left prompt) after auto-completion #1289

Closed Teknitix closed 5 years ago

Teknitix commented 5 years ago

I spent hours trying to fix this issue but was not able to figure it out after extensive searching and troubleshooting.

Configuration:

# Font
POWERLEVEL9K_MODE='nerdfont-complete'
# Prompt
POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(os_icon dir dir_writable vcs)
POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(status ssh background_jobs history vi_mode time)
POWERLEVEL9K_MULTILINE_FIRST_PROMPT_PREFIX=$'%K{white}%k'
POWERLEVEL9K_MULTILINE_LAST_PROMPT_PREFIX=$'%K{green}%F{black} %% %f%F{green}%k\ue0b0 %f '
POWERLEVEL9K_PROMPT_ON_NEWLINE=true
POWERLEVEL9K_PROMPT_ADD_NEWLINE=true
POWERLEVEL9K_RPROMPT_ON_NEWLINE=true
POWERLEVEL9K_SHORTEN_DIR_LENGTH=5
POWERLEVEL9K_SHORTEN_STRATEGY="truncate_beginning"
# The rest
POWERLEVEL9K_TIME_FORMAT='%D{%H:%M}'
POWERLEVEL9K_STATUS_OK_IN_NON_VERBOSE=true
POWERLEVEL9K_STATUS_VERBOSE=false
POWERLEVEL9K_OS_ICON_BACKGROUND="black"
POWERLEVEL9K_OS_ICON_FOREGROUND="white"
POWERLEVEL9K_FOLDER_ICON=''
POWERLEVEL9K_BACKGROUND_JOBS_FOREGROUND='black'
POWERLEVEL9K_BACKGROUND_JOBS_BACKGROUND='178'
POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD=0
POWERLEVEL9K_STATUS_FOREGROUND="black"
POWERLEVEL9K_STATUS_BACKGROUND="cyan"
POWERLEVEL9K_SHOW_CHANGESET=true
POWERLEVEL9K_CHANGESET_HASH_LENGTH=6
POWERLEVEL9K_VCS_CLEAN_FOREGROUND='black'
POWERLEVEL9K_VCS_CLEAN_BACKGROUND='green'
POWERLEVEL9K_VCS_UNTRACKED_FOREGROUND='black'
POWERLEVEL9K_VCS_UNTRACKED_BACKGROUND='yellow'
POWERLEVEL9K_VCS_MODIFIED_FOREGROUND='black'
POWERLEVEL9K_VCS_MODIFIED_BACKGROUND='blue'
POWERLEVEL9K_VCS_UNTRACKED_ICON='\u25CF'
POWERLEVEL9K_VCS_UNSTAGED_ICON='\u00b1'
POWERLEVEL9K_VCS_INCOMING_CHANGES_ICON='\u2193'
POWERLEVEL9K_VCS_OUTGOING_CHANGES_ICON='\u2191'
POWERLEVEL9K_VI_MODE_INSERT_FOREGROUND='white'
POWERLEVEL9K_VI_MODE_INSERT_BACKGROUND='cyan'
POWERLEVEL9K_VI_MODE_NORMAL_FOREGROUND='white'
POWERLEVEL9K_VI_MODE_NORMAL_BACKGROUND='blue'

I started my powerlevel9k settings by basing it off of someone's settings from this wiki page: Andrea's Config. I edited it to turn Andrea's dollar sign into a % symbol (since this is what vanilla zsh uses without any plugins). My .zshrc is fairly straightforward with nothing that really deviates from the examples here on GitHub.

Describe Your Issue

What is happening? When I type any command or line and hit to auto-complete, the completion dots appear but then afterwards a space is inserted to the left of the command (shifting everything over to the right by 1 column-width). Subsequently, all of my edits to that same line are shifted over by 1 character but they don't show up properly: the terminal shows my edits shifted over by one space apart from where they my edits actually take place. This also happens when there's an autocomplete suggestion (such as cd /tmp/) and I hit the right-arrow key to fill in the suggestion and hit enter.

What I want to happen: I need tab to auto-complete without it shifting everything over by a character.

Picture: https://upload.vaa.red/2cSX5E#8f1923f4cff56cd59343dfd4440ae0a7 I couldn't get ttystudio to reproduce the problem on an animated gif, so I put together an infographic-like image that shows the problem by several screenshots

Have you tried to debug or fix it?

I've tried many combinations of things, some of which are listed below. No solution found after searching online, searching PowerLevel9k's GitHub issues.

  1. Deleted all of my zplug plugins that were not prezto modules. Did not work.

  2. Turned off the add newline prompt variables. Did not work.

    POWERLEVEL9K_PROMPT_ON_NEWLINE="false"
    POWERLEVEL9K_PROMPT_ADD_NEWLINE="false"
    POWERLEVEL9K_PROMPT_RPROMPT_ON_NEWLINE="false"
  3. Turned off auto-completion waiting dots (as per Troubleshooting page). Did not work. COMPLETION_WAITING_DOTS="false"

  4. Tried to add terminal control characters to try not to confuse zsh on where the cursor is. Did not work. Link: https://unix.stackexchange.com/questions/85058/zsh-adds-tab-character-when-autocompleting

    POWERLEVEL9K_MULTILINE_FIRST_PROMPT_PREFIX=$'%{%K{white}%k%}'
    POWERLEVEL9K_MULTILINE_LAST_PROMPT_PREFIX=$'%{%K{green}%}%{%F{black}%} %% %f%{%F{green}%k%}\ue0b0 %f '

    When using the 'get_icon_names' command on these two prompt lines above, it shows:

    POWERLEVEL9K_MULTILINE_FIRST_PROMPT_PREFIX: %{%K{white}%k%}
    POWERLEVEL9K_MULTILINE_LAST_PROMPT_PREFIX: %{%K{green}%}%{%F{black}%} %% %f%{%F{green}%k%}$ue0b0 %f

Environment Information

This information will help us understand your configuration.

romkatv commented 5 years ago

Does the problem go away if you remove all POWERLEVEL9K options from your config? If no, then does it go away if you don't use powerlevel9k theme at all?

Teknitix commented 5 years ago

When I comment out all the POWERLEVEL9K variables, the problem remains. When I also additionally comment out the powerlevel10k theme line (zplug romkatv/powerlevel10k, use:powerlevel10k.zsh-theme) and run zplug clean to remove it, then restart the terminal, it reduces down to a simpler prompt and the problem actually goes away.

(I also uploaded a better image instead of the previous one that shows up clearer): https://upload.vaa.red/2cSX5E#8f1923f4cff56cd59343dfd4440ae0a7

How can I get auto-completion to work properly with the powerlevel{9,10}k theme?

romkatv commented 5 years ago

Oh, you are using Powerlevel10k. Do you get this problem with Powerlevel9k as well, or only with Powerlevel10k? If only with Powerlevel10k, please open an issue against Powerlevel10k and we'll continue there. If this problem affects both themes, we can stay here.

Either way, we need to figure out what's messing up your environment. Try the following.

  1. Type zsh -df.
  2. Type source /path/to/powerlevel10k/powerlevel10k.zsh-theme (replace the path first).

Do you still see the problem?

Teknitix commented 5 years ago

Yes, it affects both themes. When I run zplug clean and remove powerlevel10k and install powerlevel9k with zplug install, 9k also has the problem, unfortunately.

Okay so when I reinstall powerlevel10k, removing powerlevel9k (and with the previous POWERLEVEL9K settings still commented out), and then run those two commands you gave to me, the problem goes away.

romkatv commented 5 years ago

Okay so when I reinstall powerlevel10k, removing powerlevel9k, and run those two commands on powerlevel10k, the problem goes away.

That's good. Now we need to figure out whether zplug + powerlevel9k/10k is enough to cause the problem or whether it's something extra you added. Do the following.

  1. Run zsh -df (this gives you a pristine ZSH, by the way, without sourcing any of your config files).
  2. Paste this humongous command:
rm -rf /tmp/prompt-test
mkdir /tmp/prompt-test
cd /tmp/prompt-test
git clone https://github.com/zplug/zplug
export ZPLUG_HOME=$PWD/zplug
source zplug/init.zsh
zplug romkatv/powerlevel10k, use:powerlevel10k.zsh-theme
zplug check || zplug install
zplug load --verbose

Does it work?

Teknitix commented 5 years ago

Thanks a lot, and this is the output in WSL-terminal:

rm -rf /tmp/prompt-test
mkdir /tmp/prompt-test
cd /tmp/prompt-test
git clone https://github.com/zplug/zplug
export ZPLUG_HOME=$PWD/zplug
source zplug/init.zsh
zplug romkatv/powerlevel10k, use:powerlevel10k.zsh-theme
zplug check || zplug install
zplug load --verbose
Cloning into 'zplug'...
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 5452 (delta 0), reused 0 (delta 0), pack-reused 5448
Receiving objects: 100% (5452/5452), 1.10 MiB | 9.23 MiB/s, done.
Resolving deltas: 100% (3383/3383), done.
Checking out files: 100% (212/212), done.
__load__:47: nice(5) failed: operation not permitted
 Load "~/.zplug/repos/romkatv/powerlevel10k/powerlevel10k.zsh-theme" (romkatv/powerlevel10k)
zsh compinit: insecure directories, run compaudit for list.
Ignore insecure directories and continue [y] or abort compinit [n]? y[zplug] Run compinit

Then after that, yes it actually works and the problem goes away.

romkatv commented 5 years ago

So we know that the combination of zplug + powerlevel10k works, but your setup doesn't. It means it has something extra that breaks stuff. You can either add things on by one to the setup that works until it breaks, or remove things one by one from your setup until it starts working. If you can post your whole config, I can also try to figure out the problem.

Teknitix commented 5 years ago

Okay I did a complete erasure of everything and started with nothing. I deleted ~/.zprezto and its symlinks as well as ~/.zplug and other ancillary .z files. I made sure between each step that the problem was not there. Then zsh gave me the new user screen. I deleted the default .zshrc file it created. Then, I installed Prezto. The problem was not there. Then, I installed zplug, and the problem wasn't there.

From this step I put into the default .zshrc file created by Prezto the previous .zshrc file BUT commented out EVERY line. Then, line by line I started testing each one to determine when the problem re-occurs. What I found was that the problem comes back after this:

#
# Executes commands at the start of an interactive session.
#
# Authors:
#   Sorin Ionescu <sorin.ionescu@gmail.com>
#

# Source Prezto.
if [[ -s "${ZDOTDIR:-$HOME}/.zprezto/init.zsh" ]]; then
  source "${ZDOTDIR:-$HOME}/.zprezto/init.zsh"
fi

# Customize to your needs...
POWERLEVEL9K_MODE='nerdfont-complete'
POWERLEVEL9K_TIME_FORMAT='%D{%H:%M}'
ZLE_RPROMPT_INDENT=0
POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD=0
POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(os_icon dir dir_writable vcs)
POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(status context ssh background_jobs history vi_mode time)
POWERLEVEL9K_PROMPT_ON_NEWLINE=true
POWERLEVEL9K_PROMPT_ADD_NEWLINE=true
POWERLEVEL9K_RPROMPT_ON_NEWLINE=true
POWERLEVEL9K_MULTILINE_FIRST_PROMPT_PREFIX=$'%K{white}%k'
POWERLEVEL9K_MULTILINE_LAST_PROMPT_PREFIX=$'%K{green}%F{black} %% %f%F{green}%k\ue0b0 %f '

POWERLEVEL9K_OS_ICON_BACKGROUND="white"
POWERLEVEL9K_OS_ICON_FOREGROUND="black"
POWERLEVEL9K_SHORTEN_DIR_LENGTH=5
POWERLEVEL9K_SHORTEN_STRATEGY="truncate_beginning"
POWERLEVEL9K_FOLDER_ICON=''
POWERLEVEL9K_VCS_CLEAN_FOREGROUND='black'
POWERLEVEL9K_VCS_CLEAN_BACKGROUND='yellow'
POWERLEVEL9K_VCS_UNTRACKED_FOREGROUND='black'
POWERLEVEL9K_VCS_UNTRACKED_BACKGROUND='green'
POWERLEVEL9K_VCS_MODIFIED_FOREGROUND='black'
POWERLEVEL9K_VCS_MODIFIED_BACKGROUND='blue'
POWERLEVEL9K_VCS_UNTRACKED_ICON='\u25CF'
POWERLEVEL9K_VCS_UNSTAGED_ICON='\u00b1'
POWERLEVEL9K_VCS_INCOMING_CHANGES_ICON='\u2193'
POWERLEVEL9K_VCS_OUTGOING_CHANGES_ICON='\u2191'
POWERLEVEL9K_SHOW_CHANGESET=true
POWERLEVEL9K_CHANGESET_HASH_LENGTH=6
POWERLEVEL9K_STATUS_VERBOSE=false
POWERLEVEL9K_STATUS_OK_IN_NON_VERBOSE=true
POWERLEVEL9K_STATUS_FOREGROUND="black"
POWERLEVEL9K_STATUS_BACKGROUND="blue"
POWERLEVEL9K_VI_MODE_INSERT_FOREGROUND='black'
POWERLEVEL9K_VI_MODE_INSERT_BACKGROUND='green'
POWERLEVEL9K_VI_MODE_NORMAL_FOREGROUND='black'
POWERLEVEL9K_VI_MODE_NORMAL_BACKGROUND='blue'
POWERLEVEL9K_BACKGROUND_JOBS_FOREGROUND='black'
POWERLEVEL9K_BACKGROUND_JOBS_BACKGROUND='178'
source ~/.zplug/init.zsh
zplug "zplug/zplug", hook-build:"zplug --self-manage"
zplug "modules/environment", from:prezto
zplug "modules/terminal", from:prezto
zplug "modules/prompt", from:prezto
#zplug "modules/editor", from:prezto
#zplug "modules/directory", from:prezto
#zplug "modules/utility", from:prezto
#zplug "modules/completion", from:prezto
zplug "modules/syntax-highlighting", from:prezto
#zplug "modules/autosuggestions", from:prezto
#zplug "modules/history", from:prezto
#zplug "modules/history-substring-search", from:prezto

The problem comes back after the syntax-highlighting module is loaded. With just the environment, terminal, and prompt modules loaded by zplug, when I remove the syntax-highlighting module, the problem doesn't seem to re-occur. I'm not sure why that is. I'm going to try to install other modules and see what happens.

Edit: It also happens after I install the previous 3 + the modules/completion (without the syntax highlighting module plugin -- I'm using zplug clean to remove the plugins inbetween then reinstall them with zplug). It's interesting because it works initially. But then when I type in more commands, the problem happens.

Edit: It appears to happen after I type in a command that gives an error code that shows up in the right prompt. For example, when I enter zplug install, the plugin returns:

~ ❯❯❯ zplug install
[zplug] no packages to install

And this makes sense, since ~/.zshrc has no new plugins. But, the programmer made it return an error code. With such a minimal setup: when any error code is returned: that is when the space problem happens, and it continues for all subsequent commands. Could the problem be because of something that has to do with the way error codes are returned? Or the right prompt's characters for the error codes?

Edit: I forgot to mention that I also have had the Powerlevel10k line in the .zshrc this whole time also: zplug romkatv/powerlevel10k, use:powerlevel10k.zsh-theme

Edit: Just to be clear, the problem occurs with the following in the .zshrc: the Powerlevel9K variables, 4 modules from Prezto installed via zplug (environment, terminal, prompt, and completion), and the Powerlevel10k plugin installed via zplug.

romkatv commented 5 years ago

Remove ZLE_RPROMPT_INDENT. Does it help?

romkatv commented 5 years ago

@Teknitix I see you've made lots of updates in you last comment. Do you still have ZLE_RPROMPT_INDENT=0 in your config? If yes, remove it. It's most likely the source of your troubles.

This option is broken in ZSH. If you really want it, you can build ZSH form my fork where I have it fixed: https://github.com/romkatv/zsh/tree/rprompt-indent (hint: it's not worth it). Or just wait until my patch gets merged: https://www.zsh.org/mla/workers//2019/msg00391.html (waiting is cheap).

Teknitix commented 5 years ago

Wow, that was it, Roman! Thank you!

Do you suppose I'll just have to live with that gap on the right-hand side of certain terminals/no other solution for the gap that is fixed by the variable I took out? (It's a lot better than having this strange problem if so.)

romkatv commented 5 years ago

Do you suppose I'll just have to live with that gap on the right-hand side of certain terminals/no other solution for the gap that is fixed by the variable I took out?

Basically yes. Once my patch gets makes into the next ZSH release, you'll be able to upgrade and set ZLE_RPROMPT_INDENT=0.

Or, if you used Pure Power, you wouldn't have had this issue. Frankly, the config you chose as the base of yours isn't very good.

P9K_MULTILINE_FIRST_PROMPT_PREFIX_ICON=$'%K{white}%k'

What's that weird-looking value? Hm... Let's print it.

print -P $'%K{white}%k'

That's odd. Nothing comes out. Oh, that's right. It's an empty string! If a config writes an empty string as $'%K{white}%k', you gotta be suspicious of its quality.

It's also not a very good idea to put % in your prompt the way you did. It can confuse people who are used to the standard ZSH prompt which shows % when you are a regular user and # when you are root. Try it for yourself. Compare the prompt in zsh -df vs sudo zsh -df. When your prompt shows %, it sends a signal that your aren't root, which can be a disaster when you really are root. (By the way, it's the same in the default Bash prompt: $ for regular user, # for root.)

If you used Pure Power, you wouldn't need vi_mode because its function is built into the prompt symbol. The angle bracket rotates when you switch mode. This same angle bracket also turns red on error. Thus, a single character can replace two prompt segments and also serve as prompt terminator. (I stole this great idea from Pure.)

Anyway, I'm glad your off-by-one-char problem got resolved and I hope you find the config that works well for you.

Teknitix commented 5 years ago

Those are very good points to remember -- I suppose what I could try to do is create a condition that switches the variable that changes the % to a # when it's root (and even change the color perhaps for the root user). I'm new to zsh and will have to figure all of that out. Thank you once again!

romkatv commented 5 years ago

@Teknitix This should do it:

POWERLEVEL9K_MULTILINE_LAST_PROMPT_PREFIX='%F{%(?.076.196)}%#%f '
Teknitix commented 5 years ago

That's very interesting how that works: I plugged in the code and logged into root to see how it works. I couldn't get it to show red for some reason, but that's okay - is there a place where I can learn more about the %F, %f, and color codes, etc., commands? However, you had a point, Roman, about the quality of configurations. For the previous prompt setup that this issue fixes, whenever I source ~/.zshrc in an existing terminal, the background colors for the prompts disappear and only the arrow symbols at the end show up: https://upload.vaa.red/2qKnXK#69aaca946dea5ab4c7032d4e4dd1a28e

I don't know why that happens and am suspecting it has to do in some way with the configuration but I don't quite get what could be causing it.

romkatv commented 5 years ago

I couldn't get it to show red for some reason

Type false and hit <enter>. You can try it even without a theme:

PROMPT='%F{%(?.076.196)}%#%f ' zsh -f

is there a place where I can learn more about the %F, %f, and color codes, etc., commands?

http://zsh.sourceforge.net/Doc/Release/Prompt-Expansion.html

For the previous prompt setup that this issue fixes, whenever I source ~/.zshrc in an existing terminal, the background colors for the prompts disappear and only the arrow symbols at the end show up: https://upload.vaa.red/2qKnXK#69aaca946dea5ab4c7032d4e4dd1a28e

Are you saying you are typing source ~/.zshrc in an interactive zsh session? Don't do that. If you need to apply configuration changes, type exec zsh. If that doesn't work, exit from zsh and create a new session.

Teknitix commented 5 years ago

Ah I see -- this documentation page appears to have been the missing component to allow me to understand what was going on in the prompt line and what you were saying about the privilege shell state.

I see -- yes, exec zsh works a lot better. Wow, there's quite a lot for me to learn/relearn with zsh. Thank you. Edit: I got it to work properly (the prompt changing the symbol color) -- that's a really cool feature.