diff options
author | Bart Schaefer <schaefer@zsh.org> | 2024-02-03 20:10:52 -0800 |
---|---|---|
committer | Bart Schaefer <schaefer@zsh.org> | 2024-02-03 20:10:52 -0800 |
commit | 2744208ab3eab1741157e01484d08095bd8ef528 (patch) | |
tree | 165e370de30f748bbb9b58afda8bd39ce2b9aaf3 | |
parent | c039a74e094bb6a4d965899f67fe34d2b84dda8d (diff) | |
download | zsh-2744208ab3eab1741157e01484d08095bd8ef528.tar.gz zsh-2744208ab3eab1741157e01484d08095bd8ef528.tar.xz zsh-2744208ab3eab1741157e01484d08095bd8ef528.zip |
unposted: elaboration on Roman's "slurp" implementation from zsh-users
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | Functions/Misc/zslurp | 31 |
2 files changed, 34 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog index 386ef3ab9..238c12c16 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-02-03 Bart Schaefer <schaefer@zsh.org> + * unposted: cf. Roman in users/29472: Functions/Misc/zslurp: + Efficient lossless read of stdin into $REPLY + * unposted: Src/Zle/zle_tricky.c, Src/parse.c, Src/pattern.c: Record as comments some notes about namespace usage exceptions. diff --git a/Functions/Misc/zslurp b/Functions/Misc/zslurp new file mode 100644 index 000000000..84df0c948 --- /dev/null +++ b/Functions/Misc/zslurp @@ -0,0 +1,31 @@ +#!/bin/zsh -f + +# Read stdin verbatim and as efficiently as possible into $REPLY, +# stopping without any change to $REPLY in the event of any error. +# Benchmarked by Roman Perepelitsa in zsh-users/29472 + +# Although this function faithfully records the input stream, later +# references to $REPLY with the multibyte option back in effect will +# (re-)interpret the content as multibyte characters. This may not be +# what is desired. + +emulate -L zsh -o no_multibyte + +### Alternate formulation, faster on bigger files +# # /dev/fd/0 is treated specially by -f so also check /dev/fd +# if [[ -d /dev/fd && -f /dev/fd/0 ]] && zmodload zsh/mapfile +# then +# local +h -Ar mapfile +# typeset -g REPLY="${mapfile[/dev/fd/0]}" && return +# fi +# # else fall through to read from pipe/socket + +zmodload zsh/system || return +local -a content +local -i i=0 +while true; do + sysread 'content[++i]' && continue + (( $? == 5 )) || return + break +done +typeset -g REPLY=${(j::)content} |