Comments (8)
Hey! I can't reproduce. Which theme are you using?
from ohmyzsh.
ZSH_THEME="muse"
COMPLETION_WAITING_DOTS="true"
plugins=(git)
I don't expect the git plugin or the theme to have any effect, as I can reproduce by registering handlers in ~/.zshrc
(and I don't need to be in a git repository to see the freezes).
I just discovered that for terminal panels opened in Kate or Dolphin, it's even worse than Konsole / VT !
In these applications, even one _omz_register_handler
is enough to freeze the terminal for a few seconds on launch.
I still need at least two to reproduce the issue when pressing enter quickly.
from ohmyzsh.
With the two empty _omz_register_handler
in my example, I see :
- on each prompt,
/usr/bin/true
and/usr/bin/cat
are executed - when the shell is frozen, it is reading on the read end of a pipe connected to the stdout of
cat
With set -x
, the last line is +_omz_async_callback:15> _OMZ_ASYNC_OUTPUT[$handler]=+_omz_async_callback:15> cat
.
So it's the _OMZ_ASYNC_OUTPUT[$handler]="$(cat <&$fd)"
.
With echo aaa
in function foo()
, I see with set -x
that when I get the issue the +foo:2> echo aaa
doesn't appear : it looks like the handler process is blocked.
Replacing (exit $ret)
by () { return $ret }
seems to fix the issue when using the empty handlers at least (and it is faster).
I don't know why the subshell would block (so delay the handler) when I have the issue.
But I don't understand how the async_prompt.zsh
is supposed to work.
builtin echo $handler
triggers _omz_async_callback
: it reads handler
, and then run the cat <&$fd
which waits for the handler process to exit (or close stdout).
With a slow handler (for example sleep 2
), I clearly see the shell blocking on almost all prompts, so it doesn't seem to be asynchronous at all !
Without this issue maybe the (exit $ret)
could still cause problems, but it would be a delay for the async handler, not the shell being frozen.
Ideally the callback would only run on HUP
(when the handler process exits), but zle -F
doesn't allow to select what we want.
Btw, the two exec could probably be avoided :
- the
$(cat <&$fd)
could be replaced by something likeread -r -d '' -u $fd
. - It seems the
command true
is no longer needed on zsh >= 5.8 : zsh-users/zsh-autosuggestions#612
from ohmyzsh.
Hi Loïc, thanks for the thorough report and the improvement pointers!
I've been testing out your reproduction and I can see the same issue. It looks like zle
is calling the _omz_async_callback
function even though the fd has no data ready to read, which is not what we intended to happen.
For example, with this modification
# Called when new data is ready to be read from the pipe
function _omz_async_callback() {
emulate -L zsh
+ zmodload zsh/zselect
local fd=$1 # First arg will be fd ready for reading
local err=$2 # Second arg will be passed in case of error
@@ -116,18 +113,23 @@ function _omz_async_callback() {
if [[ -z "$err" || "$err" == "hup" ]]; then
# Get handler name from first line
local handler
- read handler <&$fd
+ read -u $fd handler
# Store old output which is supposed to be already printed
local old_output="${_OMZ_ASYNC_OUTPUT[$handler]}"
# Read output from fd
- _OMZ_ASYNC_OUTPUT[$handler]="$(cat <&$fd)"
-
- # Repaint prompt if output has changed
- if [[ "$old_output" != "${_OMZ_ASYNC_OUTPUT[$handler]}" ]]; then
- zle reset-prompt
- zle -R
+ if ! zselect -t 0 -r $fd; then
+ zle -M "$fd ($handler): no data to read
+$(ls -l /proc/$$/fd)"
+ else
+ read -u $fd -r -d '' "_OMZ_ASYNC_OUTPUT[$handler]"
+
+ # Repaint prompt if output has changed
+ if [[ "$old_output" != "${_OMZ_ASYNC_OUTPUT[$handler]}" ]]; then
+ zle reset-prompt
+ zle -R
+ fi
fi
# Close the fd
I can see printed that the pipe does not yet have any data to read, even though it is readable (and therefore zle calls the callback):
➜ ohmyzsh git:(master) ✗
12 (foo): no data to read
We'll have to research this further and find the proper way to go about this before a full release. Thanks again for the report!
from ohmyzsh.
I can see printed that the pipe does not yet have any data to read, even though it is readable (and therefore zle calls the callback):
It has data to read when _omz_async_callback
is called : the handler name (read by read handler <&$fd
).
In my PR, I stored the handler name in an associative array (to get it back from the fd), instead of writing it to the pipe.
The PID is still written, but it is read before setting the callback, so now _omz_async_callback
is only called when the completion function writes its output (ideally right at the end).
I still don't know what happens with the subshell (which created the full shell freeze, even with empty async handlers, when combined with the wait in _omz_async_callback
).
Most of the time it only delays the prompt update by about 10-20ms (compared to using a function).
But on the first prompt (in Dolphin / Kate especially), I can still sometimes see a 10s delay for the first handler, and a 18-20s delay for the second one (and if I press Ctrl+D, the terminal panel only closes after the delay).
That's why my PR is still in draft : replacing (exit $ret)
by () { return $ret }
is faster and avoids the issue, but I would like to understand why (especially since async handler might to use subshells).
I will create separate PRs for the optimization (true
/ cat
) and to make git_prompt_status
asynchronous.
from ohmyzsh.
It has data to read when
_omz_async_callback
is called : the handler name (read byread handler <&$fd
).
That's such an obvious mistake 😅
For now, I'm going to un-draft #12304 (and make a small improvement), and since you are still noticing delays, let's open a second issue for that with a reproducible build, as well as maybe a recording of the issue whilst tracing the functions with functions -t <function_name>
.
from ohmyzsh.
For now, I'm going to un-draft #12304 (and make a small improvement), and since you are still noticing delays, let's open a second issue for that with a reproducible build, as well as maybe a recording of the issue whilst tracing the functions with
functions -t <function_name>
.
I don't see any delay with the PR.
Since I replaced the subshell by a function (which should always be better anyway), the issue is fixed, but I don't know why it happened in the first place.
I'm currently daily-driving the PR, with also two other commits (avoiding true
/cat
, and making git_prompt_status
async), and everything seems to work perfectly.
from ohmyzsh.
Oh nice, then that's going to be the end of the issue. I just pushed 2 improvements, I'll test in the oldest versions we support and if all's good I'll merge it.
from ohmyzsh.
Related Issues (20)
- TAB auto-complete not work well HOT 1
- add conda-zsh-completion plugin HOT 1
- Prompt string always showing [_omz_git_prompt_info] after update HOT 7
- lib/git depends on lib/async_prompt but does not source it HOT 3
- git information not appearing in rprompt HOT 1
- Last update git untracked status is gone within the prompt HOT 3
- git async prompt does not appear HOT 15
- Avoid cluttering main `~/.zshrc`file with lots of lines HOT 2
- VS CODE terminal cannot start, after udpate oh-my-zsh HOT 26
- Command is printed before the output of said cmd HOT 10
- WHY HOT 2
- omz_history -p doesn't work as expected HOT 5
- how to update ZSH_THEME_GIT_PROMPT_PREFIX when git status changed? HOT 4
- [Plugin] ollama autocomplete support? HOT 2
- gitfast duplicates the dirty state indicator, duplicated indicator doesn't respect GIT_PS1_SHOWCOLORHINTS HOT 4
- vi-mode inner quote motions HOT 1
- Terminal shows "core dumped" when the directory is a git repo HOT 1
- pygmalion.zsh-theme lost git branch naming and ⚡️emoji HOT 1
- git_prompt_info not work HOT 1
- fzf plugin fails to "find fzf installation directory" (because of changes in fzf) HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ohmyzsh.