sindresorhus / pure

Pretty, minimal and fast ZSH prompt
MIT License
13.22k stars 978 forks source link

Option to disable first new line #619

Closed Jaakkonen closed 2 years ago

Jaakkonen commented 2 years ago

General information

When opening a new terminal, pure first prints a prompt with first line empty and then after couple hundred milliseconds clears the terminal and writes prompt without a empty first line.

I'd like a option for it to write the prompt without the empty first line the first time it's printed.

System report (output of prompt_pure_system_report):

Minimal setup (zsh -s init.zsh) with

# init.zsh
fpath+=$HOME/.local/share/zsh/pure
autoload -U promptinit
promptinit
prompt pure

Report:

/bin/dash: 0: Illegal option --
- Zsh:  (/bin/dash)
- Operating system: Linux (5.15.10-zen1-1-zen #1 ZEN SMP PREEMPT Fri, 17 Dec 2021 11:17:39 +0000 x86_64 GNU/Linux)
- Terminal program: unknown (unknown)
- Tmux: no
- Git: git version 2.34.1
- Pure state:
    - username: `''`
    - prompt: `❯`
    - version: `1.18.0`
- zsh-async version: `1.8.4`
- PROMPT: `typeset -g PROMPT=$'%F{${prompt_pure_colors[path]}}%~%f
%}%(12V.%F{$prompt_pure_colors[virtualenv]}%12v%f .)%(?.%F{$prompt_pure_colors[prompt:success]}.%F{$prompt_pure_colors[prompt:error]})${prompt_pure_state[prompt]}%f '`
- Colors: `typeset -g -A prompt_pure_colors=( [execution_time]=yellow [git:action]=yellow [git:arrow]=cyan [git:branch]=242 [git:branch:cached]=red [git:dirty]=218 [git:stash]=cyan [host]=242 [path]=blue [prompt:continuation]=242 [prompt:error]=red [prompt:success]=magenta [user]=242 [user:root]=default [virtualenv]=242 )`
- TERM: `export TERM=alacritty`
- Virtualenv: `export VIRTUAL_ENV_DISABLE_PROMPT=12`
- Conda: `export CONDA_CHANGEPS1=no`
- Detected frameworks: None

The problem also happens with zsh-snap setup using

# .zshrc
source ~/.local/share/zsh/zsh-snap/znap.zsh
znap prompt sindresorhus/pure

System report:

/bin/dash: 0: Illegal option --
- Zsh:  (/bin/dash)
- Operating system: Linux (5.15.10-zen1-1-zen #1 ZEN SMP PREEMPT Fri, 17 Dec 2021 11:17:39 +0000 x86_64 GNU/Linux)
- Terminal program: unknown (unknown)
- Tmux: no
- Git: git version 2.34.1
- Pure state:
    - username: `''`
    - prompt: `❯`
    - version: `1.18.0`
- zsh-async version: `1.8.4`
- PROMPT: `typeset -g PROMPT=$'%F{${prompt_pure_colors[path]}}%~%f
%}%(12V.%F{$prompt_pure_colors[virtualenv]}%12v%f .)%(?.%F{$prompt_pure_colors[prompt:success]}.%F{$prompt_pure_colors[prompt:error]})${prompt_pure_state[prompt]}%f '`
- Colors: `typeset -g -A prompt_pure_colors=( [execution_time]=yellow [git:action]=yellow [git:arrow]=cyan [git:branch]=242 [git:branch:cached]=red [git:dirty]=218 [git:stash]=cyan [host]=242 [path]=blue [prompt:continuation]=242 [prompt:error]=red [prompt:success]=magenta [user]=242 [user:root]=default [virtualenv]=242 )`
- TERM: `export TERM=alacritty`
- Virtualenv: `export VIRTUAL_ENV_DISABLE_PROMPT=12`
- Conda: `export CONDA_CHANGEPS1=no`
- Detected frameworks: None

Other information

I have:

Problem description

When running Zsh in a terminal with the first minimal config

$ python
>>> import time
>>> from ptyprocess import PtyProcessUnicode
>>> p = PtyProcessUnicode.spawn(['zsh', '-s', '/tmp/init.zsh'])
>>> time.sleep(2)
>>> out = p.read()
>>> out
'\x1b[?25l\x1b7\x1b7\x1b]0;~\x07\r\n\x1b[34m~\x1b[39m\r\n\r\x1b[35m❯\x1b[39m \x1b[?12l\x1b[?25h\x1b[?25l\x1b8\x1b[0m\x1b[27m\x1b[24m\x1b[J\x1b[34m~\x1b[39m\r\n\r\x1b[35m❯\x1b[39m \x1b[K\x1b[?12l\x1b[?25h\x1b[?2004h'

we see that it outputs the prompt 2 times with the later erasing the another.

>>> print(out[:73])

~
❯
>>> print(out[73:])
~
❯
>>> exit()

In a real terminal you can see that the first part is printed out really fast but the other part follows couple hundred milliseconds late.

Reproduction steps

Run pure prompt in a fresh terminal/pty and shell. See that it first creates a empty line and a 2 line prompt and then removes those 3 lines and inserts a 2 line prompt.

My .zshrc:

fpath+=$HOME/.local/share/zsh/pure
autoload -U promptinit
promptinit
prompt pure
mafredri commented 2 years ago

When opening a new terminal, pure first prints a prompt with first line empty and then after couple hundred milliseconds clears the terminal and writes prompt without a empty first line.

The Pure prompt should not re-render itself unless you are in a git repo (and the actual prompt line changed). Also, the initial newline being erased sounds weird, it's almost as if your prompt setup/terminal is triggering a clear screen event.

A few thoughts:

I'd like a option for it to write the prompt without the empty first line the first time it's printed.

See https://github.com/sindresorhus/pure/issues/233#issuecomment-248549416 as to why we can't support this.

Jaakkonen commented 2 years ago

Environment details It looks like the prompt_pure_system_report reports dash as my zsh as it's my /bin/sh. Here I'm invoking zsh for a interactive shell directly when launching a terminal.

Zsh version is 5.8 (x86_64-pc-linux-gnu). Arch linux package.

No other Zsh config files in these tests (ZDOTDIR was placed to a test directory with the .zshrc and global /etc/zsh/* and /etc/{zprofile,zshrc,zlogin} do not exist)

I also tried the python PTY debug process in a docker container (archlinux, zsh 5.8, latest pure main branch tag v1.18.0) with pure cloned to /usr/share/zsh/pure and zshrc file as follows

# /etc/zsh/zshrc
fpath+=/usr/share/zsh/pure
autoload -U promptinit
promptinit
prompt pure

with this setup I only got one prompt

>>> from ptyprocess import PtyProcessUnicode
>>> p = PtyProcessUnicode.spawn(['zsh', '-i'])
>>> p.read()
'\x1b]0;(7cac67499309) /\x07\r\n\x1b[0m\x1b[27m\x1b[24m\x1b[J\x1b[39mroot\x1b[39m\x1b[39m@7cac67499309\x1b[39m \x1b[34m/\x1b[39m\r\n\r\x1b[35m❯\x1b[39m \x1b[K\x1b[?2004h'

so the issue seems to be somewhere in my local setup.

Anyway, I cannot reproduce the prompt getting written twice in the docker setup. I'll create a new ticket/reopen/comment if I find a way to reproduce the issue in a simple container.

See #233 (comment) as to why we can't support this.

That makes sense. I cannot come up with a trivial way to distinguish the case where a new empty terminal is launched from the other cases such as ssh and launching zsh from other shell.

This answers my question pretty well, for some reason I couldn't find the existing issues that well with GH issue search. Thanks! :)