Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A possibly needed workaround for <( ) process substitution #364

Closed
psprint opened this issue Aug 7, 2018 · 18 comments
Closed

A possibly needed workaround for <( ) process substitution #364

psprint opened this issue Aug 7, 2018 · 18 comments

Comments

@psprint
Copy link

psprint commented Aug 7, 2018

Hello,
in branch develop there's currently use of <( ... ) process substitution to do asynchronous calls:

exec {_ZSH_AUTOSUGGEST_ASYNC_FD}< <(
# Tell parent process our pid
echo $sysparams[pid]
# Fetch and print the suggestion
local suggestion
_zsh_autosuggest_fetch_suggestion "$1"
echo -nE "$suggestion"
)

I use the same technique in fast-syntax-highlighting, however, I add command sleep 0 (could make it command true) after the exec: https://github.com/zdharma/fast-syntax-highlighting/blob/e06288a617b12e8038fdf5bc4bd40b6a25ef5332/fast-highlight#L917-L918

The reason for this additional call are severe problems with Ctrl-C that occur when using {MYFD}< construct, as my investigation showed.

So in this issue I just want to mention that in case of any Ctrl-C problems, command true after exec should help.

@ericfreese
Copy link
Member

Thanks for this! I was actually having issues with Ctrl-C on develop but wasn't sure exactly why and hadn't yet put in the effort to figure out what was going on. I'm busy for the next few weeks but I'll take a closer look at this before cutting a release from develop.

@ericfreese
Copy link
Member

@psprint Did you ever figure out why exactly this was necessary? I'm really curious what's going on that makes ctrl-c stop working.

@ericfreese
Copy link
Member

ericfreese commented Sep 19, 2018

I've found something interesting that you may have also found. At least in my case, it seems the problem only occurs with the monitor option set (does not occur with it unset).

@psprint
Copy link
Author

psprint commented Sep 20, 2018

Interesting. I was tracking this for many days and when workaround appeared I was too tired to continue, so I dont know why this problem occurs

@ericfreese
Copy link
Member

Fair enough. I'll see what I can find...

@ericfreese
Copy link
Member

@psprint I've submitted a patch that fixes this issue upstream

http://www.zsh.org/mla/workers/2019/msg00252.html

ericfreese added a commit that referenced this issue Apr 9, 2019
See technique used in `fast-syntax-highlighting`:
- zdharma/fast-syntax-highlighting@ca2e18b
- http://www.zsh.org/mla/users/2018/msg00424.html

Also see http://www.zsh.org/mla/users/2018/msg00432.html

In async response handler:
- We only want to read data in case of POLLIN or POLLHUP. Not POLLNVAL
  or select error.
- We always want to remove the handler, so it doesn't get called in an
  infinite loop when error is nval or err.

There is an upstream bug that prevents ctrl-c from resetting the prompt
immediately after a suggestion has been fetched asynchronously. A patch
has been submitted, but a workaround for now is to add `command true`
after the exec.

See #364
ericfreese added a commit that referenced this issue Apr 9, 2019
See technique used in `fast-syntax-highlighting`:
- zdharma/fast-syntax-highlighting@ca2e18b
- http://www.zsh.org/mla/users/2018/msg00424.html

Also see http://www.zsh.org/mla/users/2018/msg00432.html

In async response handler:
- We only want to read data in case of POLLIN or POLLHUP. Not POLLNVAL
  or select error.
- We always want to remove the handler, so it doesn't get called in an
  infinite loop when error is nval or err.

There is an upstream bug that prevents ctrl-c from resetting the prompt
immediately after a suggestion has been fetched asynchronously. A patch
has been submitted, but a workaround for now is to add `command true`
after the exec.

See #364
ericfreese added a commit that referenced this issue Apr 9, 2019
See technique used in `fast-syntax-highlighting`:
- zdharma/fast-syntax-highlighting@ca2e18b
- http://www.zsh.org/mla/users/2018/msg00424.html

Also see http://www.zsh.org/mla/users/2018/msg00432.html

In async response handler:
- We only want to read data in case of POLLIN or POLLHUP. Not POLLNVAL
  or select error.
- We always want to remove the handler, so it doesn't get called in an
  infinite loop when error is nval or err.

There is an upstream bug that prevents ctrl-c from resetting the prompt
immediately after a suggestion has been fetched asynchronously. A patch
has been submitted, but a workaround for now is to add `command true`
after the exec.

See #364
ericfreese added a commit that referenced this issue Apr 9, 2019
See technique used in `fast-syntax-highlighting`:
- zdharma/fast-syntax-highlighting@ca2e18b
- http://www.zsh.org/mla/users/2018/msg00424.html

Also see http://www.zsh.org/mla/users/2018/msg00432.html

In async response handler:
- We only want to read data in case of POLLIN or POLLHUP. Not POLLNVAL
  or select error.
- We always want to remove the handler, so it doesn't get called in an
  infinite loop when error is nval or err.

There is an upstream bug that prevents ctrl-c from resetting the prompt
immediately after a suggestion has been fetched asynchronously. A patch
has been submitted, but a workaround for now is to add `command true`
after the exec.

See #364
@ericfreese
Copy link
Member

FYI @psprint it looks like this workaround doesn't work for zsh versions older than 5.0.8.

ericfreese added a commit that referenced this issue Apr 9, 2019
See technique used in `fast-syntax-highlighting`:
- zdharma/fast-syntax-highlighting@ca2e18b
- http://www.zsh.org/mla/users/2018/msg00424.html

Also see http://www.zsh.org/mla/users/2018/msg00432.html

In async response handler:
- We only want to read data in case of POLLIN or POLLHUP. Not POLLNVAL
  or select error.
- We always want to remove the handler, so it doesn't get called in an
  infinite loop when error is nval or err.

There is an upstream bug that prevents ctrl-c from resetting the prompt
immediately after a suggestion has been fetched asynchronously. A patch
has been submitted, but a workaround for now is to add `command true`
after the exec.

See #364
@ericfreese
Copy link
Member

Closing this. I've added the workaround with PR #417

@psprint
Copy link
Author

psprint commented Apr 10, 2019 via email

@abcdw
Copy link
Contributor

abcdw commented Apr 14, 2021

Can we use command -v true instead of command true here?

command true breaks, when I have no true binary in my $PATH, it is relatively often use case for me, because I have pure environment for various build tasks using guix environment --pure.

BTW, Thank you very much for your great work.

@danielshahaf
Copy link
Member

Can we use command -v true instead of command true here?

Probably not, given that the comment just above that line of code says a fork is needed, and command -v true doesn't fork. (Also, it spams stdout, so a > /dev/null would be required.)

# There's a weird bug here where ^C stops working unless we force a fork
# See https://github.com/zsh-users/zsh-autosuggestions/issues/364
command true

command true breaks, when I have no true binary in my $PATH, it is relatively often use case for me, because I have pure environment for various build tasks using guix environment --pure.

Your setup violates POSIX (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap01.html#tag_17_06) and therefore is likely to break other upstreams too:

However, all of the standard utilities, including [true] shall be implemented in a manner so that they can be accessed via the exec family of functions [...]

(I'm not a z-asug developer.)

@abcdw
Copy link
Contributor

abcdw commented Apr 15, 2021

@danielshahaf Thank you for the reply!

However, all of the standard utilities, including [true] shall be implemented in a manner so that they can be accessed via the exec family of functions [...]

Not sure if it violates, exec true works perfectly fine just out of the box.

>> which true
true: shell built-in command
>> command true
zsh: command not found: true
>> setopt posixbuiltins
>> command true
>>

Probably not, given that the comment just above that line of code says a fork is needed.

I'm not sure how this workaround works, but maybe something like $(true) will work too?

I get a lot of _zsh_autosuggest_async_request:41: command not found: true when I'm in pure environment without true binary. It's quite annoying. For now I disabled async for pure shells with [ -n $GUIX_ENVIRONMENT ] || ZSH_AUTOSUGGEST_USE_ASYNC=true, but looks a little hacky. Would be glad to have more robust solution, but I'm not very into shells development and do not know all the tricky things related to it(

@ericfreese
Copy link
Member

There is a test for this workaround here

describe 'pressing ^C after fetching a suggestion' do

If you can get the tests running, you can try some alternatives to command true to see if we can work around the issue in a different way.

The upstream bug has also been fixed in more recent versions of zsh so at this point we may be able to only run the command true for certain older versions. I know that the workaround doesn’t work for versions older than 5.0.8 but I would have to look into the exact version that the bug was fixed in.

@danielshahaf
Copy link
Member

Not sure if it violates, exec true works perfectly fine just out of the box.

The quoted sentence refers to the execvp(3) C function, not to the exec utility/builtin.

Incidentally, zsh's exec can only be used to execute the true builtin when POSIX_BUILTINS is unset; see the third paragraph of POSIX_BUILTINS' documentation.

Would be glad to have more robust solution, but I'm not very into shells development and do not know all the tricky things related to it(

I recommend to install in the build environment whichever package provides a true executable in $PATH.

The upstream bug has also been fixed in more recent versions of zsh so at this point we may be able to only run the command true for certain older versions. I know that the workaround doesn’t work for versions older than 5.0.8 but I would have to look into the exact version that the bug was fixed in.

https://zsh.org/workers/44214 is zsh commit zsh-5.7.1-46-g5c165453a, first released in 5.8.

@abcdw
Copy link
Contributor

abcdw commented May 15, 2021 via email

@abcdw
Copy link
Contributor

abcdw commented Jun 3, 2021 via email

@ericfreese
Copy link
Member

Hi, thanks for the patch! Yeah, we should be able to apply this. I'm sorry I haven't had much time for this project lately but should be able to get this in soon. I've also been meaning to cut a new release for some time.

Can you send a pull request to develop branch with these changes?

@abcdw
Copy link
Contributor

abcdw commented Jun 3, 2021 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants