romkatv / powerlevel10k

A Zsh theme
MIT License
45.75k stars 2.16k forks source link

Startup performance is noticeably slow #234

Closed maximbaz closed 4 years ago

maximbaz commented 5 years ago

Hey @romkatv,

You have sparkled my interest in https://github.com/denysdovhan/spaceship-prompt/issues/734, so first of all thanks for that šŸ˜‰

I'm very interested to give this prompt a try, so I installed it using antigen and followed the initial wizard to configure the prompt.

While the experience in general feels smooth, I noticed that the startup time is noticeably slower than what I'm used to with my async version of spaceship. I can't give you any numbers, and to be honest I didn't dig deeply into powerlevel configuration to see what can be optimized (I only tried to disable a bunch of segments to no avail), but I did ask a friend for his perception (who I know also uses my async fork) and he confirms that the startup feels slower.

To clarify, by startup I mean the period of time between when I launch a new terminal instance and when the prompt is rendered so I can start typing my commands.

So maybe to start the discussion with something, have you heard a similar feedback before? Do you have any idea what might be the cause? Have you specifically attempted to optimize the startup time, or it hasn't been your focus so far?

I'm happy to assist with whatever I can, running experiments, performing benchmarks (how?), etc. At this point I dont have a powerlevel configuration I like (so we can start with some default and use it as an example).

I'm on Arch Linux using kitty terminal, zsh 5.7.1.

To me personally it's very important to get startup time to a minimum, I launch new terminal windows all the time and it feels annoying when I can notice the "loading". This is a lot more annoying than watching slow sections load (as long as they are asynchronous and not blocking my typing), so if I had to choose, I'd rather have slower async sections but faster startup.

šŸ™‚

romkatv commented 5 years ago

See https://github.com/romkatv/powerlevel10k/blob/master/README.md#is-powerlevel10k-fast-to-load.

I've done nothing to optimize startup time because I personally don't care. My workflow is unaffected by zsh startup latency. It may be possible to significantly reduce startup time but it's not something I want to do. If you send a PR that improves startup latency without too many adverse side effects, I'll be happy to incorporate it.

maximbaz commented 5 years ago

Oh, can't believe I missed that section. Thanks for the fast reply :)

romkatv commented 5 years ago

To measure startup latency with your own config:

time (repeat 100 zsh -dfis <<< 'source ~/.p10k.zsh; source ~/powerlevel10k/powerlevel10k.zsh-theme')

Note that latency depends on the environment in which you measure it. E.g., startup latency is higher in a git repo. If you have nvm or kubernetes installed, it'll be higher still. Powerlevel10k can perform a lot of computation during initialization in order to save on prompt latency in the long run. I won't be surprised if you can get startup latency over 1s if you install everything that Powerlevel10k can possibly use. Interactive prompt will still be fast though.

maximbaz commented 5 years ago

I see, in my case I was comparing a relative startup time difference of both prompts launching in the home dir, with the same set of tools installed.

But it makes sense now, powerlevel10k is targeting to optimize the performance of long-running sessions by sacrificing a bit of startup time, and async spaceship has the opposite goal.

Thanks again šŸ™‚

romkatv commented 5 years ago

But it makes sense now, powerlevel10k is targeting to optimize the performance of long-running sessions by sacrificing a bit of startup time, and async spaceship has the opposite goal.

I don't think there is an unavoidable trade off between these goals. Maybe sometimes you have to choose one over the other but in many cases you can have both. Powerlevel10k is slow to start and fast to use simply because I optimized for the latter without caring for the former. Things you don't care about tend to be slow but it doesn't mean they cannot be made fast.

eddyg commented 5 years ago

Out of curiosity, any idea if automatically running zcompile on all the stuff in the internal directory (to generate .zwc files) help startup times?

maximbaz commented 5 years ago

I don't think there is an unavoidable trade off between these goals. Maybe sometimes you have to choose one over the other but in many cases you can have both. Powerlevel10k is slow to start and fast to use simply because I optimized for the latter without caring for the former. Things you don't care about tend to be slow but it doesn't mean they cannot be made fast.

Agreed. If you want, we can re-open the issue so that it can attract others interested in this šŸ˜‰

maximbaz commented 5 years ago

Out of curiosity, any idea if automatically running zcompile on all the stuff in the internal directory (to generate .zwc files) help startup times?

Good point, although in my specific case, I believe antigen is doing that already.

romkatv commented 5 years ago

Out of curiosity, any idea if automatically running zcompile on all the stuff in the internal directory (to generate .zwc files) help startup times?

Last time I checked, it had no effect. There isn't that much source code and parsing is relatively fast.

If I recall correctly, about 60ms is spent on starting gitstatusd and 70ms on converting POWERLEVEL9K configuration options into chunks of precomputed code. The rest of the time is spent calling external programs such as kubectl and dotnet.

Note that p10k is also async. This fact isn't advertised on the homepage because it's almost never relevant. However, if your machine is very slow and you end up in a very large git repo, you'll notice it. The async Git UI is superb. It's a shame almost no p10k users have ever seen it.

romkatv commented 5 years ago

Agreed. If you want, we can re-open the issue so that it can attract others interested in this

I've an idea that might speed up startup quite a bit without too many code changes. I'll give it a shot some time next week. Will report here whether it works or not.

sinetoami commented 5 years ago

Interesting seeing this thread here. I feel the same thing as @maximbaz feels. Actually that's the one thing which tiny bothering me. Zinc prompt, by robobenklein, have a great startup performance and it's fast like powerlevel10k. But haven't some features that a like... and powerlevel10k is waaay mature and stable. For someone that constantly launch new terminal instances or tmux panes(and have a slow machine) i think this point make difference.

romkatv commented 4 years ago

I've made p10k startup about 2.5-3 times faster. It's still not super fast but certainly better than before. Please give it a try and let me know if you see an improvement and whether startup latency is good enough now.

Here are some benchmarks. All runs are from my desktop running Ubuntu. Current directory is powerlevel10k Git repo. 100 runs per benchmarks. Reported numbers are for a single run.

Baseline: 5.01ms.

time (repeat 100 zsh -dfis <<<'true')

Powerlevel9k with default settings: 171ms

time (repeat 100 zsh -dfis <<< 'source ~/powerlevel9k/powerlevel9k.zsh-theme')

Powerlevel10k with default settings: 59.7ms

With these settings p10k looks the same as p9k.

time (repeat 100 zsh -dfis <<< 'source ~/powerlevel10k/powerlevel10k.zsh-theme')

Powerlevel10k with ~/.p10k.zsh: 78.6ms

~/.p10k.zsh was generated by p10k configure. The choices don't seem to have much of an effect on startup performance. The reported number is from what I suppose is the slowest configuration with the maximum number of bells and whistles. Here's the config's header:

# Generated by Powerlevel10k configuration wizard on 2019-10-02 at 15:42 CEST.
# Based on romkatv/powerlevel10k/config/p10k-classic.zsh, checksum 47547.
# Wizard options: nerdfont-complete + powerline, small icons, classic, dark, time,
# slanted separators, blurred heads, blurred tails, 2 lines, dotted, right frame,
# sparse, many icons, fluent.
time (repeat 100 zsh -dfis <<< 'source ~/.p10k.zsh; source ~/powerlevel10k/powerlevel10k.zsh-theme') 

I believe the last benchmark is the most important. For comparison, the same benchmark before my optimizations reports 231ms startup latency. Now it's 2.9 times faster.

romkatv commented 4 years ago

P.S.

After zcompiling all sources the last benchmark has gotten 15% faster (68.1 ms). Here's the command I used to zcompile.

for f in ~/powerlevel10k/{*.zsh-theme,**/*.zsh} ~/.p10k.zsh; do zcompile $f; done

If you care about startup latency, update powerlevel10k and zcompile its sources and your ~/.p10k.zsh. It'll be over 3x faster to load than before.

eddyg commented 4 years ago

Thanks for the continued work on making powerlevel10k awesome, Roman!

Any reason not to just have the configuration wizard run your command above to compile everything? According to the zsh docs:

If a file named file.zwc is found, is newer than file, and is the compiled form (created with the zcompile builtin) of file, then commands are read from that file instead of file.

So even if somebody later modifies a file that the wizard compiled, the compiled version would be properly ignored.

romkatv commented 4 years ago

Any reason not to just have the configuration wizard run your command above to compile everything?

I was thinking the same thing.

It's certainly possible. One non-trivial aspect is handling different combinations of permissions and file/directory ownership. Not too difficult. The thing that is stopping me from implementing this right now is potential interaction with plugin managers.

I'll wait for the fallout from my recent optimizations to subside and then add zcompile once bug reports stop pouring in.

romkatv commented 4 years ago

FYI: I've reverted my optimizations as they were causing some issues and I don't have the time to debug them right now. Will debug and roll forward later this week.

romkatv commented 4 years ago

I've fixed bugs in my previous implementation and rolled it forward. I had to disable some optimizations for zsh < 5.4 due to bugs in quoting that I don't want to write workarounds for. I implemented a few extra optimizations.

Now p10k loads in 37 ms on my machine (6x improvement). Not instant but decently fast. This time includes starting zsh, sourcing ~/p10k.zsh, loading the theme and rendering the first prompt. Note that the first prompt is complete, unlike with some other themes that will give you just the current directory and then repaint prompt asynchronously when extra data becomes available.

I think it's possible to shave off another 10 ms or so but more than that will be difficult. Unless someone complains loudly enough, I'll leave the code be.

I also might have to revert the change if I broke something again. The changes are quite complex, so there is non-trivial risk of breakage.

I would appreciate if someone on this issue could update powerlevel10k and verify that loading has gotten faster.

sinetoami commented 4 years ago

@romkatv, let me ask you a newbie question (sorry for my bad english, btw). If you split up all segments in their own files, and then load only these which want to use (in this case, not that all them)... this would improve performance at some level? Or would it be the same as already is?

romkatv commented 4 years ago

@sinetoami Yes, this kind of refactoring can improve performance. By my estimate you can save about 0.5 ms for the typical config if you make the right decisions about what to factor out and what to keep in the main file.

By the way, this sort of guessing game is a terribly inefficient way to optimize code. Here's a better way:

  1. Write a benchmark.
  2. Run the benchmark. If it's fast enough, you are done.
  3. Profile the code.
  4. Optimize the main bottleneck.
  5. Go to 2.
sinetoami commented 4 years ago

I would appreciate if someone on this issue could update powerlevel10k and verify that loading has gotten faster.

Yes, for me it's got faster! :+1:

@sinetoami Yes, this kind of refactoring can improve performance. By my estimate you can save about 0.5 ms for the typical config if you make the right decisions about what to factor out and what to keep in the main file.

I want to give a try to this in a fork. Probably I will have some headaches trying to call the parts of segments from a main file... But thanks for your advice about this :+1: .

EDIT I notice you are a way technical than me. But, I don't know if you will "feel" how fast zinc prompt is on load, but I've made a video intend to show you. Ignore the issues, please. asciicast

romkatv commented 4 years ago

Yes, for me it's got faster! šŸ‘

Thanks for the confirmation!

@sinetoami Yes, this kind of refactoring can improve performance. By my estimate you can save about 0.5 ms for the typical config if you make the right decisions about what to factor out and what to keep in the main file.

I want to give a try to this in a fork. Probably I will have some headaches trying to call the parts of segments from a main file... But thanks for your advice about this šŸ‘ .

Didn't expect you to become enthusiastic about potentially reducing zsh startup latency by 0.5 ms. But what the hell, if that's the sort of thing you want to do, who am I to judge?

EDIT I notice you are a way technical than me. But, I don't know if you will "feel" how fast zinc prompt is on load, but I've made a video intend to show you. Ignore the issues, please. asciicast

I don't understand what's going on in that screencast. If you are saying that loading p10k is noticeably slower than loading zinc on your machine, it would be more useful if you describe your machine (OS, CPU, zsh version) and attach benchmark results for both themes, with their full configs, so that I (and everyone else) can replicate these results.

For example, to benchmark p10k with your config:

time (repeat 100 zsh -dfis <<< 'source ~/.p10k-pure.zsh; source ~/powerlevel10k/powerlevel10k.zsh-theme') 

Run this command several times to avoid contamination due to cold IO caches and the like. Please don't use zplugin in these benchmarks.

If the latency is high, I can debug it provided that you provide the information I mentioned above.

sinetoami commented 4 years ago

It was very interesting to notice that zinc prompt visually load really faster and smoother than powerlevel10k on these benchmarks what I did. However, the gitstatus on powerlevel10k it's more stable and faster than zinc. I'm not sure if it had some significant difference, but I actually think that zinc prompt load faster than powerlevel10k.

OS: Arch Linux 5.3.1-arch1 Zsh Version: 5.7.1 CPU: Intel Core i5 3210M

zinc - first time: 23.13s user 13.29s system 98% cpu 36.809 total zinc - second time: 23.19s user 13.75s system 98% cpu 37.521 total zinc - third time: 23.16s user 13.43s system 98% cpu 36.972 total

p10k - first time: 27.07s user 12.35s system 117% cpu 33.437 total p10k - second time: 26.87s user 12.48s system 115% cpu 33.977 total p10k - third time: 27.15s user 12.59s system 114% cpu 34.753 total

romkatv commented 4 years ago

@sinetoami Your benchmark results indicate that p10k loads slightly faster than zinc.

Now, since the results of this benchmark don't match your experience when using zsh with your real zsh config files, it means there is something in them that makes it different from the benchmark. Something that causes p10k load slower than it does in the benchmark. You can try to figure out what it is by removing parts of your config and checking when loading time improves. The first thing I would suggest is to load p10k without zplugin. Simply clone powerlevel10k repository and put source ~/.p10k-pure.zsh and source ~/powerlevel10k/powerlevel10k.zsh-theme in your ~/.zshrc.

romkatv commented 4 years ago

I've watched your screencast a few more times and I think I understand what's going on there. I see that your zsh isn't very fast to load but I cannot say whether there is difference in latency between zinc and p10k.

Is it possible that you perceive difference in latency because zinc is printing an empty line when it starts up? Maybe you can tell it not to print it? Or, alternatively, you can print the empty line when using p10k. I don't know at which point zinc prints the empty line so you might want to try several things in order to replicate the same delays.

  1. Print an empty line from ~/.zshrc.

Add echo somewhere in ~/.zshrc. Perhaps before p10k zplugin ice.

  1. Print an empty line right before sourcing p10k.

Add echo to p10k zplugin ice.

  1. Print an empty line right before p10k initialization.

Add print-line() { echo; add-zsh-hook -D precmd print-line }; add-zsh-hook precmd print-line to the p10k zplugin ice.


I've attempted to check whether zplugin might be making things slower than they should be. The short answer is no. When powerlevel10k is the only loaded plugin, sourcing it directly is 11ms faster than loading it with zplugin. It's expected to be faster because it must take some time to load zplugin itself. The extra 11ms added by zplugin isn't much, and it might pay off if zplugin reduces the total loading time when using many plugins (I haven't tried to verify this).

I've recorded a screencast showing what I've measured and how:

asciicast

The screencast starts with the following docker command:

docker run -e LANG=C.UTF-8 -e TERM -it --rm debian:buster bash -uec '
  apt update && apt install -y curl git zsh sudo nano
  useradd -ms /bin/zsh me
  sudo -u me sh -c "$(curl -fsSL \
    https://raw.githubusercontent.com/zdharma/zplugin/master/doc/install.sh)"
  >>~me/.zshrc echo "zplugin ice atload\"source config/p10k-pure.zsh\" lucid
zplugin light romkatv/powerlevel10k
# source ~/.zplugin/plugins/romkatv---powerlevel10k/config/p10k-pure.zsh
# source ~/.zplugin/plugins/romkatv---powerlevel10k/powerlevel10k.zsh-theme"
  exec su - me'

It installs zsh and zplugin on Debian and logs in as a user with the following ~/.zshrc:

### Added by Zplugin's installer
source '/home/me/.zplugin/bin/zplugin.zsh'
autoload -Uz _zplugin
(( ${+_comps} )) && _comps[zplugin]=_zplugin
### End of Zplugin installer's chunk

zplugin ice atload"source config/p10k-pure.zsh" lucid
zplugin light romkatv/powerlevel10k

# source ~/.zplugin/plugins/romkatv---powerlevel10k/config/p10k-pure.zsh
# source ~/.zplugin/plugins/romkatv---powerlevel10k/powerlevel10k.zsh-theme

Note that powerlevel10k and its config are loaded with zplugin.

After logging in, the current directory is changed to ~/.zplugin/plugins/romkatv---powerlevel10k because it's more interesting to observe what happens next if you are in a Git repository. You can see that true is instant while exec zsh is almost instant.

The following command is used to measure zsh startup latency:

time ( repeat 100 zsh -is <<< '' )

It repeatedly starts interacive zsh sessions and exits them once the first prompt renders. The command takes 5.115s (51ms per run).

Then ~/.zshrc is edited so that powerlevel10k and its config are sourced directly, without zplugin. Here's the new ~/.zshrc.

source ~/.zplugin/plugins/romkatv---powerlevel10k/config/p10k-pure.zsh
source ~/.zplugin/plugins/romkatv---powerlevel10k/powerlevel10k.zsh-theme

After starting a new zsh session everything proceeds as before. This time the benchmark completes in 4.016s (40ms per run).

Thanks to docker, it should be relatively straightforward to reproduce this screencast for everyone who wishes to do so.

maximbaz commented 4 years ago

@romkatv I've just tested and it is now significantly better, nice work! I haven't performed any measurements or comparisons against spaceship, but the terminal startup now feels sufficiently fast that I don't feel any inconvenience. I will give it a longer try and let you know if I spot anything weird.

romkatv commented 4 years ago

@romkatv I've just tested and it is now significantly better, nice work!

Thanks for verifying! With two confirmations and no complaints I consider this issue resolved.

(@sinetoami We can still continue the discussion here if you like.)

I haven't performed any measurements or comparisons against spaceship

I have. Your Spaceship fork loads 15-20ms faster. To convert it to relative zsh startup latency improvement you need to know your total zsh startup latency. It's easy to measure.

time (repeat 100 zsh -is </dev/null)

Look at total at the end of the output and divide it by 100. On my system total is 18.7 seconds, which means it takes 187ms to start zsh with all my user configs. I think this is considered high but as I mentioned earlier I don't care.

With Spaceship (async) I get 170ms, meaning that zsh starts 10% faster. Your numbers may be different, and the speedup may or may not matter to you.

but the terminal startup now feels sufficiently fast that I don't feel any inconvenience. I will give it a longer try and let you know if I spot anything weird.

Awesome. Do let me know if anything is broken, missing, inconvenient or just feels off. High-quality bug reports and feature requests are gold to me. They are the only means I have for discovering what users want.

sinetoami commented 4 years ago

@romkatv, following your advice I notice you were right. I found some issues in my .zshrc file and solve them. For some reason, parts of my configs blocked the prompt from being drawn fast on the screen... my guess is that probably loaded in background before drawn on the screen. There was a minimal reduction of speed on my benchmarks, 1-2ms more or less. But reorganizing my .zshrc as you suggested, now it loads fast as it should be. Apparently the order as we load our settings matters.

Thanks a lot for your patience and complete explanations about it, man. For now, to me, this issue is done too.

romkatv commented 4 years ago

@sinetoami Glad to hear you've made your zsh load faster :grin: Thanks for feedback, keep it coming.

P.S.

The "lean" style that you can choose in p10k configure is really much better than p10-pure.zsh. The latter is an exact replication of Pure, which isn't that good.

romkatv commented 4 years ago

Guys, check it out: https://gist.github.com/romkatv/8b318a610dc302bdbe1487bb1847ad99. Instant prompt! :grin:

asciicast

It's a bit gimmicky but it does reduce the perceived ZSH startup latency a lot. You'll need to define a "loading" prompt that matches your real prompt to achieve best results. For example, I'm using the stock "lean" two-line prompt, so I have this as my loading prompt:

"%B%39F${${(V)${(%):-%~}//\%/%%}//\//%b%31F/%B%39F}%b%f"$'\n'"%76FāÆ%f "

For @maximbaz this should work, I think:

"%B%3F%D{%H:%M:%S}%b%f%(#. as %1F%n%f.) in %B%6F${${(V)${(%):-%~}//\%/%%}//\//%b%65F/%B%6F}%b%f"$'\n'"%2FāÆ%f "

Check out the gist. It has instructions at the top. To make it more interesting, add sleep 1 at the bottom of your ~/.zshrc. Let me know what you think.

maximbaz commented 4 years ago

Hahaha this is amazing! šŸ˜„ I'm definitely keeping this!

BTW: it turns out my terminal doesn't support $+terminfo[u7] so while I can report this issue, I commented out the whole "cursor position check" block and it works well for me, can you please clarify what is it for? Is it to catch when you switch to root session with sudo -s? I guess I could replace that commented block with simply (( EUID )) || return 0...

romkatv commented 4 years ago

I went back and forth several times on the implementation. With one implementation there are issues if the "loading" prompt is created at the bottom of the terminal window and causes new lines to be created there (so that the window content scrolls up). In another implementation there are issues if you press enter while the loading prompt is active. When these problems happen, the real prompt gets printed on the wrong line, which usually means there is some crap on the screen left from the "loading" prompt.

I've now reverted to the implementation that simply calls clear. Please curl the new version and use it like this:

# at the top
if (( EUID )); then
  source ~/instant-zsh.zsh
  instant-zsh-pre "%B%3F%D{%H:%M:%S}%b%f%(#. as %1F%n%f.) in %B%6F${${(V)${(%):-%~}//\%/%%}//\//%b%65F/%B%6F}%b%f"$'\n'"%2FāÆ%f "
else
  echo
fi

...

# at the bottom
(( ! $+functions[instant-zsh-post] )) || instant-zsh-post
maximbaz commented 4 years ago

I still cannot believe my eyes how awesomely fast this is šŸ˜‚

The current implementation works for me out of the box šŸ‘

Just out of curiosity, how did you find the argument to instant-zsh-pre for me (which is perfect btw), did you compose it by hand or there is a way to get this string out of the rendered prompt?

romkatv commented 4 years ago

I still cannot believe my eyes how awesomely fast this is

Frankly, me too :-)

The current implementation works for me out of the box

Great :+1:

Just out of curiosity, how did you find the argument to instant-zsh-pre for me (which is perfect btw), did you compose it by hand or there is a way to get this string out of the rendered prompt?

I looked at your dotfiles and wrote it by hand.

sinetoami commented 4 years ago

One question: how can I simulate the truncate_from_right strategy on instant-zsh-pre ? I actually don't know how can I do it.

romkatv commented 4 years ago

@sinetoami Sorry, I'm not signing up for writing loading prompts for everyone. You might try it without truncation and see if it's good enough. You cannot define exactly the same prompt -- the goal is to use something that's close enough.

sinetoami commented 4 years ago

@sinetoami Sorry, I'm not signing up for writing loading prompts for everyone.

It's ok! No problem :+1:

I still cannot believe my eyes how awesomely fast this is

Me too! Man, this is so good that I'm laughing. This trick is really awesome! :smile: :smile: :smile: All my desires about a nice zsh prompt it's done now. hahahaah

thanks @romkatv ! Nice work

romkatv commented 4 years ago

I rewrote the whole thing with a different implementation. This one seems to be quite reliable. It doesn't call clear anymore. If you guys could update and let me know whether it still work, that would be helpful. @maximbaz, you should now be able to call instant-zsh-pre unconditionally, even when root.

maximbaz commented 4 years ago

It works šŸ‘ ~For me the interesting consequence of not calling clear anymore is that I don't have to limit using this instant prompt in only if (( EUID )) block - now it equally well works for root prompt.~

UPDATE: OMG you wrote this in your message about instant-zsh-pre and I've completely overlooked it and "discovered on my own", I guess it's time for me to go and sleep šŸ˜„

There's only one minor bug, when the prompt is near the bottom of the terminal window and instant-zsh is being run, content jumps up. If you want to investigate, here's how it looks when I'm pressing sudo -s and Ctrl+D in a loop:

jump

My .zshrc at this point is:

. ~/.zsh/instant-zsh.zsh

(( EUID )) || echo
instant-zsh-pre "%B%3F%D{%H:%M:%S}%b%f%(#. as %1F%n%f.) in %B%6F${${(V)${(%):-%~}//\%/%%}//\//%b%65F/%B%6F}%b%f"$'\n'"%2FāÆ%f "

...

instant-zsh-post
sinetoami commented 4 years ago

It works for me too.

And just for information to anyone wants to know, I found a way to actually truncate the path like truncate_from_right strategy. What I did was source the shrink-path plugin from oh-my-zsh and use --fish flag. That's it. It works like magic.

romkatv commented 4 years ago

There's only one minor bug, when the prompt is near the bottom of the terminal window and instant-zsh is being run, content jumps up.

This is intentional. It's the best way I found to avoid the problems I mentioned earlier. I figured this is better than calling clear because it gives users freedom. Anyone who liked the previous behavior can simply call clear on their own before calling instant-zsh-pre.

I'm gonna try to integrate instant-zsh into p10k. Not sure how hard it is but worth a try.

maximbaz commented 4 years ago

This is intentional. It's the best way I found to avoid the problems I mentioned earlier.

I added sleep 1 and tried to reproduce problems with pressing Enter, to be honest this seems work for me equally well, without prompt jumping:

-    print -r ${(%):-$eol_mark${(pl.$fill.. .)}$'\r'%b%k%f%E}$'\n\n\n\n\n\n\n\n\n'
-    echoti cuu 10
+    print -r ${(%):-$eol_mark${(pl.$fill.. .)}$'\r'%b%k%f%E}$'\n'
+    echoti cuu 2

Do I understand correctly that the number of \n is just an educated guess of how many time a user is able to press Enter while waiting for the real prompt to initialize?

romkatv commented 4 years ago

Do I understand correctly that the number of \n is just an educated guess of how many time a user is able to press Enter while waiting for the real prompt to initialize?

Correct. If you make your window scroll while zsh is still loading, the "loading" prompt won't be properly erased.

Ideally, it should be prompt-height + n where n is configurable. I'll do it this way in p10k.

romkatv commented 4 years ago

Folks, I've added instant prompt to powerlevel10k. To use it, remove your current instant prompt (both at the top and at the bottom of zshrc) and add this at the very 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

Update powerlevel10k and restart zsh. It's no longer necessary to manually define your "loading" prompt. Note: It won't do anything if your zsh is older than 5.4.

The implementation is very complex. Please give a holler if you notice anything weird. I'd like to enable it by default after having a few confirmations that it doesn't break anything.

Ideally, it should be prompt-height + n where n is configurable. I'll do it this way in p10k.

This is controlled by POWERLEVEL9K_INSTANT_PROMPT_COMMAND_LINES (defaults to 3). If you want to override it, put it together with your other POWERLEVEL9K parameters.

maximbaz commented 4 years ago

Great work, and thanks for integrating this in p10k itself!

Please give a holler if you notice anything weird.

I've only noticed one weird thing: the cursor seems to be visibly jumping to the next line and back, I can see % or # symbols briefly appearing (depending if I'm root or not). Here's a gif:

demo

sinetoami commented 4 years ago

I've only noticed one weird thing: the cursor seems to be visibly jumping to the next line and back, I > can see % or # symbols briefly appearing (depending if I'm root or not).

I noticed that too... in my case some times don't clear the prompt. 2019-10-19-143744_177x130_scrot

romkatv commented 4 years ago

I've only noticed one weird thing: the cursor seems to be visibly jumping to the next line and back, I can see % or # symbols briefly appearing (depending if I'm root or not).

This can happen if you setopt prompt_sp prompt_cr after sourcing powerlevel10k. Try sourcing powerlevel10k at the very end of zshrc. Does it help?

I can detect this issue in powerlevel10k but I cannot fix it. I could print a warning telling the users to fix it but I'm afraid that most users won't be able to.

P.S.

What software do you use to create gifs?

romkatv commented 4 years ago

in my case some times don't clear the prompt.

Could you describe in more detail what happens? What do you do and what do you observe?

maximbaz commented 4 years ago

This can happen if you setopt prompt_sp prompt_cr after sourcing powerlevel10k. Try sourcing powerlevel10k at the very end of zshrc. Does it help?

It doesn't (maybe these are default options?), however what does help is putting this in the very top of my .zshrc: unsetopt prompt_sp prompt_cr

What if you add these to ~/.cache/p10k-instant-prompt-*.zsh file?

What software do you use to create gifs?

https://github.com/phw/peek

sinetoami commented 4 years ago

Could you describe in more detail what happens? What do you do and what do you observe?

Happens a few times when I open tmux panes in any direction and with tiling window terminals. I think that's have relation with prompt resizing... Peek 2019-10-19 15-09

romkatv commented 4 years ago

This can happen if you setopt prompt_sp prompt_cr after sourcing powerlevel10k. Try sourcing powerlevel10k at the very end of zshrc. Does it help?

It doesn't (maybe these are default options?), however what does help is putting this in the very top of my .zshrc: unsetopt prompt_sp prompt_cr

What if you add these to ~/.cache/p10k-instant-prompt-*.zsh file?

Used to have it there but then moved to https://github.com/romkatv/powerlevel10k/blob/master/powerlevel10k.zsh-theme because it reduces the amount of code where users can fuck up the options. I think antigen is the culprit. It reverts options after sourcing https://github.com/romkatv/powerlevel10k/blob/master/powerlevel10k.zsh-theme. I've added unsetopt back to p10k-instant-prompt. The more the merrier. What I really need is to unset these options after zshrc finishes sourcing but I don't think there is a hook for that.

Please update powerlevel10k, remove unsetopt prompt_sp prompt_cr that you've added earlier to zshrc and try again. Let me know if it works.